diff --git a/source/ChangeLog b/source/ChangeLog index 681437b64fd36bcf022372ec41f69cddb59098f5..05fb9244eb6875c4b1bf60876fdef2630d9ec974 100644 --- a/source/ChangeLog +++ b/source/ChangeLog @@ -1,3 +1,7 @@ +2017-03-10 Karl Berry <karl@tug.org> + + * Makefile.am (reauto): convenience target. + 2016-11-16 Karl Berry <karl@tug.org> * Makefile.am (install-exec-hook): warn that the @@ -40,19 +44,10 @@ * tardate.ac: Switch to 2015-03-07. -2015-02-16 Peter Breitenlohner <peb@mppmu.mpg.de> - - * am/dist_hook.am (new): Makefile fragment for dist-hook target. - * Makefile.am: Use the fragment am/dist_hook.am. - 2014-11-24 Peter Breitenlohner <peb@mppmu.mpg.de> * tardate.ac: Switch to 2014-11-24. -2014-11-17 Karl Berry <karl@tug.org> - - * am/script_links.am: Use w32_wrapper or w64_wrapper. - 2014-10-21 Karl Berry <karl@tug.org> * configure.ac: report CC/CXX values, with --version output @@ -122,21 +117,9 @@ * Makefile.am: Add the make target 'texlinks'. -2013-07-16 Peter Breitenlohner <peb@mppmu.mpg.de> - - * am/rebuild.am: Avoid still more 'parallel make' problems. - -2013-07-15 Peter Breitenlohner <peb@mppmu.mpg.de> - - * am/rebuild.am: Avoid more 'parallel make' problems. - 2013-07-06 Peter Breitenlohner <peb@mppmu.mpg.de> - * am/*.am: Moved Makefile fragments from libs/am/ and tekk/am/. - * am/rebuild.am: New Makefile fragment to rebuild a library. - * am/reconfig.am: New Makefile fragment to reconfigure. - * am/recurse.am: New Makefile fragment to recurse into subdirs. - + * am: new subdirectory. * Makefile.am, configure.ac: Use am/recurse.am. 2013-06-24 Peter Breitenlohner <peb@mppmu.mpg.de> @@ -591,4 +574,4 @@ (sup_main_memory, sup_save_size): increase per tex.ch. From Akira. -(This ChangeLog file public domain.) +(This file public domain.) diff --git a/source/Makefile.am b/source/Makefile.am index 3807c07d0a1b7c918c2c4434cfafb1f382b0a4bc..9751f860e69d4e139837142ac294c2c3801214c4 100644 --- a/source/Makefile.am +++ b/source/Makefile.am @@ -1,4 +1,4 @@ -## $Id$ +## $Id: Makefile.am 43448 2017-03-10 00:14:50Z karl $ ## Makefile.am for the TeX Live top-level ## ## Copyright 2016 Karl Berry <tex-live@tug.org> @@ -76,11 +76,15 @@ endif !cross skip: .PHONY: skip -# Directly run texlinks. +# Convenience targets to run texlinks and reautoconf. .PHONY: texlinks texlinks: cd $(texlinks_dir) && $(MAKE) $(AM_MAKEFLAGS) run-texlinks +.PHONY: triptrap +reauto: + ./reautoconf + # Special target to run TRIP and TRAP tests and create diffs. .PHONY: triptrap triptrap: diff --git a/source/Makefile.in b/source/Makefile.in index d4bc06fa094fc051f61302a7bc43327bf9dc9133..0a882cc5b7825f5910ca0ded35d2317eb8988902 100644 --- a/source/Makefile.in +++ b/source/Makefile.in @@ -129,8 +129,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/kpse-cairo-flags.m4 \ $(top_srcdir)/libs/poppler/ac/withenable.ac \ $(top_srcdir)/libs/mpfr/ac/withenable.ac \ $(top_srcdir)/libs/gmp/ac/withenable.ac \ - $(top_srcdir)/libs/cairo/ac/withenable.ac \ - $(top_srcdir)/libs/pixman/ac/withenable.ac \ $(top_srcdir)/libs/libpng/ac/withenable.ac \ $(top_srcdir)/libs/luajit/ac/withenable.ac \ $(top_srcdir)/libs/lua52/ac/withenable.ac \ @@ -140,8 +138,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/kpse-cairo-flags.m4 \ $(top_srcdir)/texk/kpathsea/ac/kpathsea.ac \ $(top_srcdir)/libs/zlib/ac/zlib.ac \ $(top_srcdir)/libs/libpng/ac/libpng.ac \ - $(top_srcdir)/libs/pixman/ac/pixman.ac \ - $(top_srcdir)/libs/cairo/ac/cairo.ac \ $(top_srcdir)/libs/gmp/ac/gmp.ac \ $(top_srcdir)/libs/mpfr/ac/mpfr.ac \ $(top_srcdir)/libs/poppler/ac/poppler.ac \ @@ -218,9 +214,10 @@ am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/am/dist_hook.am \ $(top_srcdir)/build-aux/install-sh \ $(top_srcdir)/build-aux/ltmain.sh \ $(top_srcdir)/build-aux/missing ChangeLog README \ - build-aux/compile build-aux/config.guess build-aux/config.sub \ - build-aux/depcomp build-aux/install-sh build-aux/ltmain.sh \ - build-aux/missing build-aux/texinfo.tex build-aux/ylwrap + build-aux/ar-lib build-aux/compile build-aux/config.guess \ + build-aux/config.sub build-aux/depcomp build-aux/install-sh \ + build-aux/ltmain.sh build-aux/missing build-aux/texinfo.tex \ + build-aux/ylwrap DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) @@ -425,11 +422,18 @@ DIST_SUBDIRS = auxdir/auxsub doc $(CONF_SUBDIRS) libs utils texk recurse_this = recurse_top = -# We must configure all subdirs since 'make dist' needs the Makefile. -# For those not required for the current set of configure options +# $Id: recurse.am 43261 2017-02-17 22:37:44Z karl $ +# +# Requires $(recurse_this) and $(recurse_top). +# Uses CONF_SUBDIRS and MAKE_SUBDIRS (set by kpse-setup.m4). +# +# For subdirs not required for the current set of configure options # we append '--disable-build' so they can skip tests that would # fail because, e.g., some required libraries were not built. +# (By manually testing $enable_build in configure, e.g., dvisvgm/configure.) +# # Code inspired by automake's way to handle recursive targets. +# cf_silent = $(cf_silent_@AM_V@) cf_silent_ = $(cf_silent_@AM_DEFAULT_V@) cf_silent_0 = --silent @@ -971,11 +975,15 @@ install-exec-hook: skip: .PHONY: skip -# Directly run texlinks. +# Convenience targets to run texlinks and reautoconf. .PHONY: texlinks texlinks: cd $(texlinks_dir) && $(MAKE) $(AM_MAKEFLAGS) run-texlinks +.PHONY: triptrap +reauto: + ./reautoconf + # Special target to run TRIP and TRAP tests and create diffs. .PHONY: triptrap triptrap: diff --git a/source/README b/source/README index 4505bbada6a5abd9448e4d3ab7fbe9a67b3d5cb0..81e38d387ae4a49e491df77cde8051427b3d10cb 100644 --- a/source/README +++ b/source/README @@ -1,21 +1,27 @@ -$Id: README 42179 2016-09-29 16:19:03Z karl $ +$Id: README 43261 2017-02-17 22:37:44Z karl $ Public domain. Originally written 2005 by Karl Berry. For a high-level overview of building TeX Live, see http://tug.org/texlive/build.html. In brief: -To configure and make the source tree, run ./Build. -To build (mostly) without optimization, run ./Build --debug. -To make without configuring, run TL_CONFIGURE=true ./Build. +- To configure and make the source tree, run ./Build. + This builds in subdirectory Work/, and installs into subdirectory inst/. + +- To build (mostly) without optimization, run ./Build --debug. + +- If the make fails and you want to rebuild without starting from scratch: + cd Work/whatever/subdir && make + Email tlbuild@tug.org if problems. (Nearly everything the Build script does can be overridden via environment variables; just take a look to see the names.) Many more details about the TL build system, such as configuring to work -on a single program, adding new programs or libraries, recompiling after -fixing problems, etc., are in the doc/tlbuild* document and the sibling -README* files here (which are generated from that document). +on a single program, adding new programs or libraries, documentation +about the many pieces of the system, etc., are in the doc/tlbuild* +document and the sibling README* files here (which are generated from +that document). Build information for some of the platforms. diff --git a/source/am/ChangeLog b/source/am/ChangeLog new file mode 100644 index 0000000000000000000000000000000000000000..6b72cb9fc35d3f8be41607de83d29e4ab10e03ef --- /dev/null +++ b/source/am/ChangeLog @@ -0,0 +1,34 @@ +2017-02-17 Karl Berry <karl@freefriends.org> + + * recurse.am: doc fixes. + +2017-02-16 Karl Berry <karl@tug.org> + + * bin_links.am: $(MKDIR_P) $(DESTDIR)$(bindir) to be sure, + since this can end up being called first with --disable-all-pkgs. + +2015-02-16 Peter Breitenlohner <peb@mppmu.mpg.de> + + * dist_hook.am (new): Makefile fragment for dist-hook target. + * Makefile.am: Use the fragment dist_hook.am. + +2014-11-17 Karl Berry <karl@tug.org> + + * script_links.am: Use w32_wrapper or w64_wrapper. + +2013-07-16 Peter Breitenlohner <peb@mppmu.mpg.de> + + * rebuild.am: Avoid still more 'parallel make' problems. + +2013-07-15 Peter Breitenlohner <peb@mppmu.mpg.de> + + * rebuild.am: Avoid more 'parallel make' problems. + +2013-07-06 Peter Breitenlohner <peb@mppmu.mpg.de> + + * *.am: Moved Makefile fragments from libs/ and tekk/. + * rebuild.am: New Makefile fragment to rebuild a library. + * reconfig.am: New Makefile fragment to reconfigure. + * recurse.am: New Makefile fragment to recurse into subdirs. + +(This file public domain.) diff --git a/source/am/README b/source/am/README new file mode 100644 index 0000000000000000000000000000000000000000..8a026a81834c1e381c35cc30e5d443b8e8b8f735 --- /dev/null +++ b/source/am/README @@ -0,0 +1,7 @@ +$Id: README 43261 2017-02-17 22:37:44Z karl $ +Public domain. Originally written 2017 by Karl Berry. + +This top-level am/ directory contains fragments which are ultimately used +in Makefile.am files by automake (a.k.a. the top-level reautoconf). + +See also the sibling top-level m4/ directory. diff --git a/source/am/bin_links.am b/source/am/bin_links.am index 3cb7406b603c283e1a1b6d1de353cb56f2a111e2..58c10a4e9665151976197ab853ade878338d367a 100644 --- a/source/am/bin_links.am +++ b/source/am/bin_links.am @@ -1,6 +1,8 @@ -## am/bin_links.am: Makefile fragment for bindir links. +# $Id: bin_links.am 43248 2017-02-16 21:38:29Z karl $ +# am/bin_links.am: Makefile fragment for bindir links. ## -## Copyright (C) 2011-2013 Peter Breitenlohner <tex-live@tug.org> +## Copyright 2017 Karl Berry <tex-live@tug.org> +## Copyright 2011-2013 Peter Breitenlohner <tex-live@tug.org> ## You may freely use, modify and/or distribute this file. ## ## requires conditional WIN32 @@ -15,6 +17,7 @@ install-bin-links: if !WIN32 + $(MKDIR_P) $(DESTDIR)$(bindir) @cd $(DESTDIR)$(bindir) && \ for s in $(bin_links); do \ link=`echo $$s | sed 's,.*:,,'`; \ diff --git a/source/am/recurse.am b/source/am/recurse.am index 158fb658655b88f1e4674822ff155c00a33110b1..964897a4b9e2911f109cc88ea193212d0f68f32c 100644 --- a/source/am/recurse.am +++ b/source/am/recurse.am @@ -1,16 +1,20 @@ +# $Id: recurse.am 43261 2017-02-17 22:37:44Z karl $ ## am/recurse.am: Makefile fragment to configure and build subdirs. ## -## Copyright (C) 2013 Peter Breitenlohner <tex-live@tug.org> +## Copyright 2017 Karl Berry <tex-live@tug.org> +## Copyright 2013 Peter Breitenlohner <tex-live@tug.org> ## You may freely use, modify and/or distribute this file. -## -## requires $(recurse_this) and $(recurse_top). -## -# We must configure all subdirs since 'make dist' needs the Makefile. -# For those not required for the current set of configure options +# +# Requires $(recurse_this) and $(recurse_top). +# Uses CONF_SUBDIRS and MAKE_SUBDIRS (set by kpse-setup.m4). +# +# For subdirs not required for the current set of configure options # we append '--disable-build' so they can skip tests that would # fail because, e.g., some required libraries were not built. +# (By manually testing $enable_build in configure, e.g., dvisvgm/configure.) +# # Code inspired by automake's way to handle recursive targets. -## +# cf_silent = $(cf_silent_@AM_V@) cf_silent_ = $(cf_silent_@AM_DEFAULT_V@) cf_silent_0 = --silent @@ -52,4 +56,3 @@ recurse: $(CONFIG_AUX) $(CONFIG_AUX): @echo "configure in $(recurse_top)auxdir/auxsub failed to create the file $@" exit 1 - diff --git a/source/auxdir/auxsub/Makefile.in b/source/auxdir/auxsub/Makefile.in index f7771a2576835299d8ba70db53579d81a85fc0ca..1cdfe8297fbb90620cb0f2d3cbe8c416e6531325 100644 --- a/source/auxdir/auxsub/Makefile.in +++ b/source/auxdir/auxsub/Makefile.in @@ -119,11 +119,12 @@ am__can_run_installinfo = \ am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/../../build-aux/install-sh \ - $(top_srcdir)/../../build-aux/missing ../../build-aux/compile \ - ../../build-aux/config.guess ../../build-aux/config.sub \ - ../../build-aux/depcomp ../../build-aux/install-sh \ - ../../build-aux/ltmain.sh ../../build-aux/missing \ - ../../build-aux/texinfo.tex ../../build-aux/ylwrap README + $(top_srcdir)/../../build-aux/missing ../../build-aux/ar-lib \ + ../../build-aux/compile ../../build-aux/config.guess \ + ../../build-aux/config.sub ../../build-aux/depcomp \ + ../../build-aux/install-sh ../../build-aux/ltmain.sh \ + ../../build-aux/missing ../../build-aux/texinfo.tex \ + ../../build-aux/ylwrap README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) diff --git a/source/build-aux/ar-lib b/source/build-aux/ar-lib new file mode 100755 index 0000000000000000000000000000000000000000..05094d34c696249b10c58ac61f381a3f3b54f501 --- /dev/null +++ b/source/build-aux/ar-lib @@ -0,0 +1,270 @@ +#! /bin/sh +# Wrapper for Microsoft lib.exe + +me=ar-lib +scriptversion=2012-03-01.08; # UTC + +# Copyright (C) 2010-2017 Free Software Foundation, Inc. +# Written by Peter Rosin <peda@lysator.liu.se>. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to <bug-automake@gnu.org> or send patches to +# <automake-patches@gnu.org>. + + +# func_error message +func_error () +{ + echo "$me: $1" 1>&2 + exit 1 +} + +file_conv= + +# func_file_conv build_file +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv in + mingw) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_at_file at_file operation archive +# Iterate over all members in AT_FILE performing OPERATION on ARCHIVE +# for each of them. +# When interpreting the content of the @FILE, do NOT use func_file_conv, +# since the user would need to supply preconverted file names to +# binutils ar, at least for MinGW. +func_at_file () +{ + operation=$2 + archive=$3 + at_file_contents=`cat "$1"` + eval set x "$at_file_contents" + shift + + for member + do + $AR -NOLOGO $operation:"$member" "$archive" || exit $? + done +} + +case $1 in + '') + func_error "no command. Try '$0 --help' for more information." + ;; + -h | --h*) + cat <<EOF +Usage: $me [--help] [--version] PROGRAM ACTION ARCHIVE [MEMBER...] + +Members may be specified in a file named with @FILE. +EOF + exit $? + ;; + -v | --v*) + echo "$me, version $scriptversion" + exit $? + ;; +esac + +if test $# -lt 3; then + func_error "you must specify a program, an action and an archive" +fi + +AR=$1 +shift +while : +do + if test $# -lt 2; then + func_error "you must specify a program, an action and an archive" + fi + case $1 in + -lib | -LIB \ + | -ltcg | -LTCG \ + | -machine* | -MACHINE* \ + | -subsystem* | -SUBSYSTEM* \ + | -verbose | -VERBOSE \ + | -wx* | -WX* ) + AR="$AR $1" + shift + ;; + *) + action=$1 + shift + break + ;; + esac +done +orig_archive=$1 +shift +func_file_conv "$orig_archive" +archive=$file + +# strip leading dash in $action +action=${action#-} + +delete= +extract= +list= +quick= +replace= +index= +create= + +while test -n "$action" +do + case $action in + d*) delete=yes ;; + x*) extract=yes ;; + t*) list=yes ;; + q*) quick=yes ;; + r*) replace=yes ;; + s*) index=yes ;; + S*) ;; # the index is always updated implicitly + c*) create=yes ;; + u*) ;; # TODO: don't ignore the update modifier + v*) ;; # TODO: don't ignore the verbose modifier + *) + func_error "unknown action specified" + ;; + esac + action=${action#?} +done + +case $delete$extract$list$quick$replace,$index in + yes,* | ,yes) + ;; + yesyes*) + func_error "more than one action specified" + ;; + *) + func_error "no action specified" + ;; +esac + +if test -n "$delete"; then + if test ! -f "$orig_archive"; then + func_error "archive not found" + fi + for member + do + case $1 in + @*) + func_at_file "${1#@}" -REMOVE "$archive" + ;; + *) + func_file_conv "$1" + $AR -NOLOGO -REMOVE:"$file" "$archive" || exit $? + ;; + esac + done + +elif test -n "$extract"; then + if test ! -f "$orig_archive"; then + func_error "archive not found" + fi + if test $# -gt 0; then + for member + do + case $1 in + @*) + func_at_file "${1#@}" -EXTRACT "$archive" + ;; + *) + func_file_conv "$1" + $AR -NOLOGO -EXTRACT:"$file" "$archive" || exit $? + ;; + esac + done + else + $AR -NOLOGO -LIST "$archive" | sed -e 's/\\/\\\\/g' | while read member + do + $AR -NOLOGO -EXTRACT:"$member" "$archive" || exit $? + done + fi + +elif test -n "$quick$replace"; then + if test ! -f "$orig_archive"; then + if test -z "$create"; then + echo "$me: creating $orig_archive" + fi + orig_archive= + else + orig_archive=$archive + fi + + for member + do + case $1 in + @*) + func_file_conv "${1#@}" + set x "$@" "@$file" + ;; + *) + func_file_conv "$1" + set x "$@" "$file" + ;; + esac + shift + shift + done + + if test -n "$orig_archive"; then + $AR -NOLOGO -OUT:"$archive" "$orig_archive" "$@" || exit $? + else + $AR -NOLOGO -OUT:"$archive" "$@" || exit $? + fi + +elif test -n "$list"; then + if test ! -f "$orig_archive"; then + func_error "archive not found" + fi + $AR -NOLOGO -LIST "$archive" || exit $? +fi diff --git a/source/build-aux/config.guess b/source/build-aux/config.guess index bbd48b60e88b94f7390c2df90b73bea12bff1979..69ed3e573bb3fa14476b0b539805850159eb23e0 100755 --- a/source/build-aux/config.guess +++ b/source/build-aux/config.guess @@ -2,7 +2,7 @@ # Attempt to guess a canonical system name. # Copyright 1992-2017 Free Software Foundation, Inc. -timestamp='2017-01-01' +timestamp='2017-03-05' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -837,10 +837,11 @@ EOF UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) - echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; esac + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin @@ -1343,6 +1344,9 @@ EOF NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; + NSX-?:NONSTOP_KERNEL:*:*) + echo nsx-tandem-nsk${UNAME_RELEASE} + exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; diff --git a/source/build-aux/config.sub b/source/build-aux/config.sub index 7e792b4ae17baca8c9d3dec17764b1c21302737d..87abeab6cdfce092f2abdf58f18ef18f496ba255 100755 --- a/source/build-aux/config.sub +++ b/source/build-aux/config.sub @@ -2,7 +2,7 @@ # Configuration validation subroutine script. # Copyright 1992-2017 Free Software Foundation, Inc. -timestamp='2017-01-01' +timestamp='2017-02-07' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -948,6 +948,9 @@ case $basic_machine in nsr-tandem) basic_machine=nsr-tandem ;; + nsx-tandem) + basic_machine=nsx-tandem + ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf diff --git a/source/build-aux/texinfo.tex b/source/build-aux/texinfo.tex index 338bcf650404822b3d1655f49ec0d1a9b655ce15..970d8784688cbf50e29ec145dc45436601a64908 100644 --- a/source/build-aux/texinfo.tex +++ b/source/build-aux/texinfo.tex @@ -3,7 +3,7 @@ % Load plain if necessary, i.e., if running under initex. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % -\def\texinfoversion{2017-01-14.15} +\def\texinfoversion{2017-03-07.20} % % Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, % 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, @@ -5888,8 +5888,8 @@ end \divide\doublecolumnhsize by 2 \hsize = \doublecolumnhsize % - % Double the \vsize as well. (We don't need a separate register here, - % since nobody clobbers \vsize.) + % Double the \vsize as well. + \advance\vsize by -\ht\partialpage \vsize = 2\vsize % % For the benefit of balancing columns @@ -5907,12 +5907,12 @@ end % previous page. \dimen@ = \vsize \divide\dimen@ by 2 - \advance\dimen@ by -\ht\partialpage % % box0 will be the left-hand column, box2 the right. - \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@ + \setbox0=\vsplit\PAGE to\dimen@ \setbox2=\vsplit\PAGE to\dimen@ + \global\advance\vsize by 2\ht\partialpage \onepageout\pagesofar - \unvbox255 + \unvbox\PAGE \penalty\outputpenalty } % @@ -5976,9 +5976,9 @@ end % % \pagegoal was set to the doubled \vsize above, since we restarted % the current page. We're now back to normal single-column - % typesetting, so reset \pagegoal to the normal \vsize (after the - % \endgroup where \vsize got restored). - \pagegoal = \vsize + % typesetting, so reset \pagegoal to the normal \vsize. + \global\vsize = \txipageheight % + \pagegoal = \txipageheight % } \newbox\balancedcolumns \setbox\balancedcolumns=\vbox{shouldnt see this}% @@ -5986,7 +5986,7 @@ end % Only called for the last of the double column material. \doublecolumnout % does the others. \def\balancecolumns{% - \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120. + \setbox0 = \vbox{\unvbox\PAGE}% like \box255 but more efficient, see p.120. \dimen@ = \ht0 \advance\dimen@ by \topskip \advance\dimen@ by-\baselineskip @@ -11274,6 +11274,7 @@ directory should work if nowhere else does.} \pdfvorigin = 1 true in \else \ifx\XeTeXrevision\thisisundefined + \special{papersize=#8,#7}% \else \pdfpageheight #7\relax \pdfpagewidth #8\relax diff --git a/source/configure b/source/configure index 587a6fd1265c817f7c092953b26fa83d69a76504..5cec2b1539d4220d7722ad910f28c0886d3453d9 100755 --- a/source/configure +++ b/source/configure @@ -637,14 +637,14 @@ ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS +subdirs cross_FALSE cross_TRUE ICU_CONFIG FT2_CONFIG PKG_CONFIG -CONF_SUBDIRS MAKE_SUBDIRS -subdirs +CONF_SUBDIRS CXXCPP WARNING_CXXFLAGS am__fastdepCXX_FALSE @@ -840,8 +840,6 @@ with_mpfr_libdir with_system_gmp with_gmp_includes with_gmp_libdir -with_system_cairo -with_system_pixman with_system_libpng with_system_zlib with_zlib_includes @@ -885,8 +883,7 @@ CXX CXXFLAGS CCC CXXCPP' -ac_subdirs_all='texk/kpathsea -auxdir/auxsub libs utils texk' +ac_subdirs_all='auxdir/auxsub libs utils texk' # Initialize some variables set by options. ac_init_help= @@ -1608,10 +1605,6 @@ Optional Packages: --with-system-gmp use installed gmp headers and library --with-gmp-includes=DIR gmp headers installed in DIR --with-gmp-libdir=DIR gmp library installed in DIR - --with-system-cairo use installed cairo headers and library (requires - pkg-config) - --with-system-pixman use installed pixman headers and library (requires - pkg-config) --with-system-libpng use installed libpng headers and library (requires pkg-config) --with-system-zlib use installed zlib headers and library @@ -4202,7 +4195,6 @@ esac test "x$enable_web2c:$enable_luatex" = xyes:yes && { need_poppler=yes need_mpfr=yes - need_cairo=yes need_libpng=yes need_zziplib=yes need_lua52=yes @@ -4221,7 +4213,6 @@ esac test "x$enable_web2c:$enable_luajittex" = xyes:yes && { need_poppler=yes need_mpfr=yes - need_cairo=yes need_libpng=yes need_zziplib=yes need_luajit=yes @@ -4628,80 +4619,6 @@ $as_echo "$as_me: Using \`gmp' headers and library from TL tree" >&6;} fi fi -## libs/cairo/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/cairo/ -## configure options and TL libraries required for cairo - -# Check whether --with-system-cairo was given. -if test "${with_system_cairo+set}" = set; then : - withval=$with_system_cairo; -fi -if test "x$with_system_cairo" = x; then - if test -f $srcdir/libs/cairo/configure; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Assuming \`cairo' headers and library from TL tree" >&5 -$as_echo "$as_me: Assuming \`cairo' headers and library from TL tree" >&6;} - with_system_cairo=no - else - { $as_echo "$as_me:${as_lineno-$LINENO}: Assuming installed \`cairo' headers and library" >&5 -$as_echo "$as_me: Assuming installed \`cairo' headers and library" >&6;} - with_system_cairo=yes - fi - ac_configure_args="$ac_configure_args '--with-system-cairo=$with_system_cairo'" -elif test "x$with_system_cairo" = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Using installed \`cairo' headers and library" >&5 -$as_echo "$as_me: Using installed \`cairo' headers and library" >&6;} -else - { $as_echo "$as_me:${as_lineno-$LINENO}: Using \`cairo' headers and library from TL tree" >&5 -$as_echo "$as_me: Using \`cairo' headers and library from TL tree" >&6;} - if test "x$with_system_cairo" != xno; then - with_system_cairo=no - ac_configure_args="$ac_configure_args '--without-system-cairo'" - fi -fi -if test "x$with_system_cairo" = xyes; then - if test "x$with_system_pixman" = x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: -> installed \`pixman' headers and library" >&5 -$as_echo "$as_me: -> installed \`pixman' headers and library" >&6;} - with_system_pixman=yes - ac_configure_args="$ac_configure_args '--with-system-pixman'" - elif test "x$with_system_pixman" != xyes; then - as_fn_error $? "Sorry, \`--with-system-cairo' requires \`--with-system-pixman'" "$LINENO" 5 - fi -fi - -test "x$need_cairo" = xyes && { - need_pixman=yes -} - -## libs/pixman/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/pixman/ -## configure options and TL libraries required for pixman - -# Check whether --with-system-pixman was given. -if test "${with_system_pixman+set}" = set; then : - withval=$with_system_pixman; -fi -if test "x$with_system_pixman" = x; then - if test -f $srcdir/libs/pixman/configure; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Assuming \`pixman' headers and library from TL tree" >&5 -$as_echo "$as_me: Assuming \`pixman' headers and library from TL tree" >&6;} - with_system_pixman=no - else - { $as_echo "$as_me:${as_lineno-$LINENO}: Assuming installed \`pixman' headers and library" >&5 -$as_echo "$as_me: Assuming installed \`pixman' headers and library" >&6;} - with_system_pixman=yes - fi - ac_configure_args="$ac_configure_args '--with-system-pixman=$with_system_pixman'" -elif test "x$with_system_pixman" = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Using installed \`pixman' headers and library" >&5 -$as_echo "$as_me: Using installed \`pixman' headers and library" >&6;} -else - { $as_echo "$as_me:${as_lineno-$LINENO}: Using \`pixman' headers and library from TL tree" >&5 -$as_echo "$as_me: Using \`pixman' headers and library from TL tree" >&6;} - if test "x$with_system_pixman" != xno; then - with_system_pixman=no - ac_configure_args="$ac_configure_args '--without-system-pixman'" - fi -fi - ## libs/libpng/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/libpng/ ## configure options and TL libraries required for libpng @@ -19423,19 +19340,13 @@ $as_echo "$as_me: which requires to locate the <kpathsea/paths.h> header fil fi fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TeX specific libraries to build" >&5 $as_echo_n "checking for TeX specific libraries to build... " >&6; } -MAKE_SUBDIRS= CONF_SUBDIRS= -if test -x $srcdir/texk/kpathsea/configure; then - test "x$with_system_kpathsea" != xyes && test "x$need_kpathsea" = xyes && MAKE_SUBDIRS="texk/kpathsea $MAKE_SUBDIRS" +MAKE_SUBDIRS= +if test -x $srcdir/texk/kpathsea/configure && test "x$with_system_kpathsea" != xyes && test "x$need_kpathsea" = xyes; then CONF_SUBDIRS="texk/kpathsea $CONF_SUBDIRS" - if false; then - subdirs="$subdirs texk/kpathsea" - - fi + MAKE_SUBDIRS="texk/kpathsea $MAKE_SUBDIRS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAKE_SUBDIRS" >&5 @@ -19962,64 +19873,6 @@ rm -f core conftest.err conftest.$ac_objext \ $as_echo "$kpse_res" >&6; } fi -## libs/pixman/ac/pixman.ac: configure.ac fragment for the TeX Live subdirectory libs/pixman/ -## basic check of system pixman -if test "x$need_pixman:$with_system_pixman" = xyes:yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking requested system \`pixman' library" >&5 -$as_echo_n "checking requested system \`pixman' library... " >&6; } - CPPFLAGS="$PIXMAN_INCLUDES $CPPFLAGS" - LIBS="$PIXMAN_LIBS $LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <pixman.h> -int -main () -{ -const char *s = pixman_version_string(); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - syslib_used=yes kpse_res=ok -else - syslib_status=no kpse_res=failed -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 -$as_echo "$kpse_res" >&6; } -fi - -## libs/cairo/ac/cairo.ac: configure.ac fragment for the TeX Live subdirectory libs/cairo/ -## basic check of system cairo -if test "x$need_cairo:$with_system_cairo" = xyes:yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking requested system \`cairo' library" >&5 -$as_echo_n "checking requested system \`cairo' library... " >&6; } - CPPFLAGS="$CAIRO_INCLUDES $CPPFLAGS" - LIBS="$CAIRO_LIBS $LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <cairo.h> -int -main () -{ -const char *s = cairo_version_string(); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - syslib_used=yes kpse_res=ok -else - syslib_status=no kpse_res=failed -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $kpse_res" >&5 -$as_echo "$kpse_res" >&6; } -fi - ## libs/gmp/ac/gmp.ac: configure.ac fragment for the TeX Live subdirectory libs/gmp/ ## basic check of system gmp if test "x$need_gmp:$with_system_gmp" = xyes:yes; then @@ -20165,6 +20018,8 @@ else fi + + subdirs="$subdirs auxdir/auxsub libs utils texk" diff --git a/source/doc/Makefile.in b/source/doc/Makefile.in index 70d7c4282dbc920f3811294464230d553e9d217b..984aa89caf95d891e73a2878b3a6cd50ee82e732 100644 --- a/source/doc/Makefile.in +++ b/source/doc/Makefile.in @@ -129,8 +129,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/kpse-cairo-flags.m4 \ $(top_srcdir)/libs/poppler/ac/withenable.ac \ $(top_srcdir)/libs/mpfr/ac/withenable.ac \ $(top_srcdir)/libs/gmp/ac/withenable.ac \ - $(top_srcdir)/libs/cairo/ac/withenable.ac \ - $(top_srcdir)/libs/pixman/ac/withenable.ac \ $(top_srcdir)/libs/libpng/ac/withenable.ac \ $(top_srcdir)/libs/luajit/ac/withenable.ac \ $(top_srcdir)/libs/lua52/ac/withenable.ac \ @@ -140,8 +138,6 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/kpse-cairo-flags.m4 \ $(top_srcdir)/texk/kpathsea/ac/kpathsea.ac \ $(top_srcdir)/libs/zlib/ac/zlib.ac \ $(top_srcdir)/libs/libpng/ac/libpng.ac \ - $(top_srcdir)/libs/pixman/ac/pixman.ac \ - $(top_srcdir)/libs/cairo/ac/cairo.ac \ $(top_srcdir)/libs/gmp/ac/gmp.ac \ $(top_srcdir)/libs/mpfr/ac/mpfr.ac \ $(top_srcdir)/libs/poppler/ac/poppler.ac \ diff --git a/source/doc/build-tools.txt b/source/doc/build-tools.txt index 4da14b3889a0e39a47f06f759b840173ae0a7965..67eeb3c627049319ab11208700147e2727874f95 100644 --- a/source/doc/build-tools.txt +++ b/source/doc/build-tools.txt @@ -3,5 +3,5 @@ automake (GNU automake) 1.15 bison (GNU Bison) 3.0.4 flex 2.6.0 ltmain.sh (GNU libtool) 2.4.6 -m4 (GNU M4) 1.4.17 +m4 (GNU M4) 1.4.18 makeinfo (GNU texinfo) 6.1 diff --git a/source/doc/tlbuild.info b/source/doc/tlbuild.info index e30d2b914c1c85af5884a57c7b653fd7213909f0..98e2d5b8ef6b2440cb8317488cf7853d581c8384 100644 --- a/source/doc/tlbuild.info +++ b/source/doc/tlbuild.info @@ -3,8 +3,8 @@ tlbuild.texi. This file documents the TeX Live build system and more. - Copyright (C) 2016 Karl Berry. -Copyright (C) 2013, 2014, 2015 Karl Berry & Peter Breitenlohner. +Copyright (C) 2016-2017 Karl Berry. +Copyright (C) 2013-2015 Karl Berry & Peter Breitenlohner. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are @@ -53,7 +53,8 @@ File: tlbuild.info, Node: Introduction, Next: Overview of build system, Prev: 1 Introduction ************** -This manual (dated April 2016) corresponds to the TeX Live 2016 release. +This manual (dated February 2017) corresponds to the TeX Live 2016 +release. This manual is aimed at system installers and programmers, and focuses on how to configure, build, and develop the TeX Live (TL) @@ -90,8 +91,8 @@ found in other TL documentation resources, such as: As an exception, the full documentation for 'install-tl' and 'tlmgr' is included here, just because it is convenient to do so. The same text is available online (linked from <http://tug.org/texlive/doc.html>, or -by invoking the program with '--help' (or look at the end of the source -file). +by invoking the program with '--help' (or look at the end of the +source). File: tlbuild.info, Node: Overview of build system, Next: Prerequisites, Prev: Introduction, Up: Top @@ -127,8 +128,8 @@ list of all 'configure' options. program and library module (or package) specifies its own requirements and properties, such as required libraries, whether an installed (system) version of a library can be used, 'configure' options to be -seen at the top-level, and more. An explicit list of all available -modules is kept in only one, central, place ('m4/kpse-pkgs.m4'). +seen at the top level, and more. An explicit list of all available +modules is kept in only one central place, namely 'm4/kpse-pkgs.m4'. A second, related goal is to configure and build each library before configuring any other (program or library) module which uses that @@ -140,9 +141,9 @@ version of that library. independently. The corresponding modules use (most of) the distributed source tree and document any modifications of that source. - All this is for the sake of simplifying both upgrading of modules -maintained independently and integrating new modules into the TL build -system. (Not to say that either task is trivial.) + All this is for the sake of simplifying both upgrading of modules and +integrating new modules into the TL build system. (Not to say that +either task is trivial.) File: tlbuild.info, Node: Prerequisites, Next: Building, Prev: Overview of build system, Up: Top @@ -155,13 +156,17 @@ the TL source tree, requires only C and C++ compilers and GNU 'make'. (If 'make' from your 'PATH' is not GNU make, you can set 'MAKE' in the environment to whatever is necessary.) - Indeed, GNU 'make' is required only because of some third-party -libraries, notably FreeType; all the TL-maintained directories (and + GNU 'make' is required only because of some third-party libraries, +notably FreeType; all the TL-maintained directories (and Automake/Autoconf output in general) should work with any reasonable 'make'. However, a few programs in the tree have additional requirements: +'dvisvgm' + requires a C++11 compiler, such as gcc 4.8.1 (or later) or clang + 3.3 (or later). + 'web2c' requires 'perl' for some tests run by 'make check'. @@ -267,7 +272,7 @@ File: tlbuild.info, Node: Build problems, Next: Build in parallel, Prev: Buil If configuring or building a module fails, you should first find and fix the problem, then perhaps remove the subdirectory for that module from -the build tree, and finally rerun the top-level 'make' (or 'Build' with +the build tree, and finally rerun the top level 'make' (or 'Build' with '--no-clean' as its first argument). @@ -291,7 +296,7 @@ File: tlbuild.info, Node: Build distribution, Next: Build one package, Prev: 4.4 Build distribution ====================== -Running 'make dist' at the top-level creates a tarball +Running 'make dist' at the top level creates a tarball 'tex-live-YYYY-MM-DD.tar.xz' from the TL source tree. Running 'make distcheck' also verifies that this tarball suffices to build and install all of TL. @@ -557,12 +562,12 @@ build and install them together with some of their support files. * Menu: -* Build system tools:: If modifying infrastructure files. -* Top-level directories:: -* Autoconf macros:: TL-specific Autoconf macros. -* Library modules:: Details on some specific libraries, -* Program modules:: and on some programs. -* Extending TeX Live:: Adding a new module. +* Build system tools:: Modifying infrastructure files. +* Top-level directories:: libs texk utils; am auxdir build-aux m4; doc extra. +* Autoconf macros:: TL-specific Autoconf macros. +* Library modules:: Handling libraries, with examples. +* Program modules:: Handling programs, with examples. +* Extending TeX Live:: Adding a new module. File: tlbuild.info, Node: Build system tools, Next: Top-level directories, Up: Layout and infrastructure @@ -589,7 +594,7 @@ many extra hassles, so don't do that, tempting as it may be. bison (GNU Bison) 3.0.4 flex 2.6.0 ltmain.sh (GNU libtool) 2.4.6 - m4 (GNU M4) 1.4.17 + m4 (GNU M4) 1.4.18 makeinfo (GNU texinfo) 6.1 These versions should be used to update the generated files (e.g., @@ -623,11 +628,11 @@ the main source directories are 'texk/' (TeX-specific programs and libraries), 'utils/' (additional programs), and 'libs/' (generic libraries). - The top-level directories 'am/' and 'm4/' contain 'Makefile.am' -fragments and Autoconf macros, respectively, used in many places. -Specifically, the file 'm4/kpse-pkgs.m4' contains lists of all program -and library modules; missing modules are silently ignored. (This helps -in creating cut-down source trees.) + In addition, the top-level directories 'am/' and 'm4/' contain +'Makefile.am' fragments and Autoconf macros, respectively, used in many +places. Specifically, the file 'm4/kpse-pkgs.m4' contains lists of all +program and library modules; missing modules are silently ignored. +(This helps in creating cut-down source trees.) Each module contributes fragments (in separate files) defining its capabilities and requirements to the 'configure.ac' scripts at the @@ -640,17 +645,23 @@ configured for the benefit of 'make' targets such as 'dist' or 'distcheck'. The top-level 'build-aux/' directory contains the common files -'compile', 'config.guess', 'config.sub', 'depcomp', etc. for most -packages, pulled from the GNU Gnulib sources +'compile', 'config.guess', 'config.sub', 'depcomp', etc. used by most +packages. These are from the GNU Gnulib sources (<http://www.gnu.org/software/gnulib>), which in turn synchronizes with the appropriate ultimate upstream repository. There are, however, independent copies in, e.g., 'libs/freetype2/freetype-*/builds/unix/', -and similar places. The 'reautoconf' script does not touch those, but a -TL cron job keeps them in sync (nightly). +and a few other places. The 'reautoconf' script does not touch those, +but a TL cron job keeps them in sync (nightly). The directory 'extra/' contains things which are not part of the TL -build, but are present just for (someone's) convenience, e.g., -'epstopdf' which is developed here. +build, but are present just for (someone's) convenience, e.g., is +'epstopdf' development source is here. + + When the top-level './Build' script is used to build TL, two more two +more top-level directories appear: 'Work/' for the build tree, and +'inst/' for the install tree (from 'make install'). These names (and +everything else about 'Build''s operation) can be changed by setting +environment variables before running it; see the script file. File: tlbuild.info, Node: Autoconf macros, Next: Library modules, Prev: Top-level directories, Up: Layout and infrastructure @@ -881,9 +892,8 @@ File: tlbuild.info, Node: png library, Next: zlib library, Up: Library module ---------------------------------------- This generic library uses the source tree in, e.g., the subdirectory -'libpng-1.6.16' with all modifications for TL recorded in -'libpng-1.6.16-PATCHES/*'. The 'configure.ac' fragment -'ac/withenable.ac' contains +'libpng-src/' with all modifications for TL recorded in 'TLPATCHES/*'. +The 'configure.ac' fragment 'ac/withenable.ac' contains KPSE_WITH_LIB([libpng], [zlib]) @@ -1002,9 +1012,9 @@ File: tlbuild.info, Node: t1utils package, Next: xindy package, Up: Program m 6.5.1 The 't1utils' package in 'utils/t1utils' ---------------------------------------------- -Once again we use the distributed source tree 't1utils-1.39' with -modifications documented in 't1utils-1.39-PATCHES/*' and a proxy build -system consisting of 'configure.ac' and 'Makefile.am'. The fragment +Once again we use the distributed source tree 't1utils-src' with +modifications documented in 'TLPATCHES/*' and a proxy build system +consisting of 'configure.ac' and 'Makefile.am'. The fragment 'ac/withenable.ac' contains KPSE_ENABLE_PROG([t1utils]) @@ -1018,12 +1028,11 @@ File: tlbuild.info, Node: xindy package, Next: xdvik package, Prev: t1utils p 6.5.2 The 'xindy' package in 'utils/xindy' ------------------------------------------ -This module uses the distributed source tree 'xindy-2.5.1' with -modifications documented in 'xindy-2.5.1-PATCHES/*', a proxy -'configure.ac', and a wrapper 'Makefile.am' that descends into -'xindy-2.5.1'. The 'xindy' build requires that the distributed -'Makefile's allow a 'VPATH' build, can handle all targets, and do not -refer to '${top_srcdir}' or '${top_builddir}'. The fragment +This module uses the distributed source tree 'xindy-src/' with +modifications documented in 'TLPATCHES/*', a proxy 'configure.ac', and a +wrapper 'Makefile.am' that descends into 'xindy-src'. The 'xindy' build +requires a 'make' that supports a 'VPATH' build, can handle all targets, +and do not refer to '${top_srcdir}' or '${top_builddir}'. The fragment 'ac/withenable.ac' contains KPSE_ENABLE_PROG([xindy], , [disable native]) @@ -1083,6 +1092,13 @@ File: tlbuild.info, Node: Extending TeX Live, Prev: Program modules, Up: Layo This section outlines the basic process for adding new packages to the TL build system. + In any case, a new package directory 'foo' should contain the +original sources, as modified for TL, in 'foo/foo-src', and the changes +should be documented in 'foo/TLPATCHES/*'; changes should also be +submitted upstream whenever reasonable, of course. In addition, 'foo/' +will need the usual Automake build-related files ('configure.ac', +'Makefile.am', etc. Please keep a 'ChangeLog' for all TL changes. + * Menu: * Adding a new program module:: @@ -1857,8 +1873,9 @@ should produce no (GCC) compiler warnings at all. In spite of considerable efforts into that direction we are still far from that goal and there are reasons that we may never fully reach it. Below are some rules about declarations of functions or variables and the use of -'const'. These rules should be applied to all parts of the TeX Live -tree, except some of those maintained independently. +'const'. These rules should be applied to most of the TeX Live tree, +the exception being code that is maintained independently and whose +maintainers don't want to accept patches. * Menu: @@ -4510,7 +4527,7 @@ Index * ANSI C: Declarations and definitions. (line 6) * ApplicationServices Mac framework, required by xetex: Prerequisites. - (line 27) + (line 31) * asymptote: Linked scripts. (line 22) * asymptote <1>: asymptote. (line 6) * Autoconf: Overview of build system. @@ -4534,10 +4551,13 @@ Index * Build script: Building. (line 6) * build system, design of: Overview of build system. (line 6) +* build-aux/ top-level directory: Top-level directories. + (line 30) * BUILDCC, BUILDCFLAGS, ...: Cross configuring. (line 42) * building: Building. (line 6) * building a distribution: Build distribution. (line 6) * building in parallel: Build in parallel. (line 6) +* C++11, required by dvisvgm: Prerequisites. (line 19) * C, ANSI, required: Declarations and definitions. (line 6) * C99, avoided: Declarations and definitions. @@ -4558,11 +4578,11 @@ Index (line 17) * CLISP <1>: Configure options for utils/xindy. (line 14) -* clisp, required by xindy: Prerequisites. (line 31) -* Cocoa Mac framework, required by xetex: Prerequisites. (line 27) +* clisp, required by xindy: Prerequisites. (line 35) +* Cocoa Mac framework, required by xetex: Prerequisites. (line 31) * coding conventions: Coding conventions. (line 6) * compilers, C and C++: Prerequisites. (line 6) -* config.guess, config.sub: Top-level directories. +* config.guess, config.sub, ...: Top-level directories. (line 30) * configure options: Configure options. (line 6) * configure options, for bibtex-x: Configure options for texk/bibtex-x. @@ -4604,7 +4624,7 @@ Index * CXX: Variables for configure. (line 11) * CXX=C++-COMPILER: Build one package. (line 74) -* Debian installation of build prerequisites: Prerequisites. (line 56) +* Debian installation of build prerequisites: Prerequisites. (line 60) * declarations and definitions, in source code: Declarations and definitions. (line 6) * dependencies, with several output files: Build in parallel. (line 6) @@ -4622,6 +4642,7 @@ Index (line 6) * dvisvgm: Configure options for texk/dvisvgm. (line 6) +* dvisvgm requirement for C++11: Prerequisites. (line 19) * environment variables, for configure: Configure options. (line 16) * exec_prefix: --enable-multiplatform. (line 6) @@ -4631,10 +4652,10 @@ Index * extra/ top-level directory: Top-level directories. (line 39) * failure to build: Build problems. (line 6) -* ffcall, required by xindy: Prerequisites. (line 31) +* ffcall, required by xindy: Prerequisites. (line 35) * flags, macros for library and header: Macros for library and header flags. (line 6) -* fontconfig library, required by xetex: Prerequisites. (line 27) +* fontconfig library, required by xetex: Prerequisites. (line 31) * FreeType: Prerequisites. (line 11) * freetype cross compiling: Cross problems. (line 13) * freetype library: freetype library. (line 6) @@ -4663,6 +4684,8 @@ Index * ICU_CONFIG: Variables for configure. (line 22) * infrastructure, tools needed for: Build system tools. (line 6) +* inst/ top-level directory: Top-level directories. + (line 43) * install-tl, TeX Live installer: Installing. (line 8) * installation directories: Installation directories. (line 6) @@ -4674,7 +4697,7 @@ Index (line 6) * kpathsea library: kpathsea library. (line 6) * kpathsea.ac: kpathsea library. (line 20) -* kpse-libpng-flags.m4: png library. (line 43) +* kpse-libpng-flags.m4: png library. (line 42) * kpse-pkgs.m4: Overview of build system. (line 30) * kpse-zlib-flags.m4: zlib library. (line 6) @@ -4707,7 +4730,7 @@ Index * KPSE_LARGEFILE: Macros for libraries. (line 8) * KPSE_LIBPNG_FLAGS: Macros for library and header flags. (line 10) -* KPSE_LIBPNG_FLAGS <1>: png library. (line 43) +* KPSE_LIBPNG_FLAGS <1>: png library. (line 42) * kpse_libs_pkgs: Adding a new generic library module. (line 6) * KPSE_LIB_FLAGS: Macros for library and header flags. @@ -4723,10 +4746,10 @@ Index (line 6) * kpse_texlibs_pkgs: Adding a new TeX-specific library module. (line 11) -* KPSE_TRY_LIB: png library. (line 18) +* KPSE_TRY_LIB: png library. (line 17) * KPSE_TRY_LIB <1>: Adding a new generic library module. (line 20) -* KPSE_TRY_LIBXX: png library. (line 31) +* KPSE_TRY_LIBXX: png library. (line 30) * KPSE_TRY_LIBXX <1>: Adding a new generic library module. (line 20) * kpse_utils_pkgs: Adding a new program module. @@ -4803,7 +4826,7 @@ Index (line 41) * PERL: Variables for configure. (line 39) -* perl, required by web2c, etc.: Prerequisites. (line 19) +* perl, required by web2c, etc.: Prerequisites. (line 23) * PKG_CONFIG: Variables for configure. (line 23) * plain.tex, not in source tree: Installing. (line 8) @@ -4884,11 +4907,13 @@ Index * Windows, macros for: Macros for Windows. (line 6) * withenable.ac, for new modules: Adding a new program module. (line 14) +* Work/ top-level directory: Top-level directories. + (line 43) * wrapper binary for scripts on Windows: Linked scripts. (line 6) * X toolkit: Configure options for texk/web2c. (line 22) * X11 headers, and const: Const. (line 21) -* X11, required by X clients: Prerequisites. (line 23) +* X11, required by X clients: Prerequisites. (line 27) * xasy: asymptote. (line 6) * xaw: Configure options for texk/xdvik. (line 9) @@ -4914,313 +4939,313 @@ Index Tag Table: -Node: Top1030 -Node: Introduction1948 -Node: Overview of build system3705 -Node: Prerequisites5769 -Node: Building8073 -Node: Build iteration9321 -Node: Build problems10393 -Node: Build in parallel10796 -Node: Build distribution11388 -Node: Build one package11959 -Node: Installing15545 -Node: Installation directories16560 -Node: Linked scripts18376 -Node: Distro builds19857 -Node: Layout and infrastructure22247 -Node: Build system tools23036 -Node: Top-level directories25045 -Node: Autoconf macros27086 -Node: General setup macros27787 -Node: Macros for programs28654 -Node: Macros for compilers29466 -Node: Macros for libraries30900 -Node: Macros for library and header flags31326 -Node: Macros for Windows33206 -Node: Library modules34783 -Node: png library35272 -Node: zlib library37561 -Node: freetype library38076 -Node: kpathsea library38604 -Node: Program modules40003 -Node: t1utils package40431 -Node: xindy package40994 -Node: xdvik package42173 -Node: asymptote43246 -Node: Extending TeX Live43697 -Node: Adding a new program module44065 -Node: Adding a new generic library module45584 -Node: Adding a new TeX-specific library module47797 -Node: Configure options48484 -Node: Global configure options49866 -Node: --disable-native-texlive-build50408 -Node: --prefix --bindir ...51398 -Node: --disable-largefile51938 -Node: --disable-missing52623 -Node: --enable-compiler-warnings=LEVEL53024 -Node: --enable-cxx-runtime-hack53763 -Node: --enable-maintainer-mode54190 -Node: --enable-multiplatform54719 -Node: --enable-shared55257 -Node: --enable-silent-rules55628 -Node: --without-ln-s56084 -Node: --without-x56435 -Node: Program-specific configure options56623 -Node: --enable-PROG --disable-PROG57266 -Node: --disable-all-pkgs57543 -Node: Configure options for texk/web2c58529 -Node: Configure options for texk/bibtex-x61047 -Node: Configure options for texk/dvipdfm-x61590 -Node: Configure options for texk/dvisvgm62363 -Node: Configure options for texk/texlive63249 -Node: Configure options for texk/xdvik63670 -Node: Configure options for utils/xindy64274 -Node: Library-specific configure options65175 -Node: Configure options for kpathsea66186 -Node: Configure options for system poppler66895 -Node: Variables for configure67686 -Node: Cross compilation69114 -Node: Cross configuring70413 -Node: Cross problems72086 -Node: Coding conventions73733 -Node: Declarations and definitions74402 -Node: Const76584 -Node: install-tl78447 -Node: install-tl NAME78788 -Node: install-tl SYNOPSIS78946 -Node: install-tl DESCRIPTION79154 -Node: install-tl REFERENCES80155 -Node: install-tl OPTIONS80671 -Ref: install-tl *-gui* [[=]_module_]81025 -Ref: install-tl text81234 -Ref: install-tl wizard81357 -Ref: install-tl perltk81511 -Ref: install-tl *-no-gui*81945 -Ref: install-tl *-lang* _llcode_82026 -Ref: install-tl *-repository* _url|path_82713 -Ref: install-tl *-select-repository*84524 -Ref: install-tl *-all-options*84960 -Ref: install-tl *-custom-bin* _path_85267 -Ref: install-tl *-debug-translation*85922 -Ref: install-tl *-force-platform* _platform_86141 -Ref: install-tl *-help*, *--help*, *-?*86385 -Ref: install-tl *-in-place*86778 -Ref: install-tl *-logfile* _file_87305 -Ref: install-tl *-no-cls*87656 -Ref: install-tl *-non-admin*87787 -Ref: install-tl *--persistent-downloads*87892 -Ref: install-tl *--no-persistent-downloads*87920 -Ref: install-tl *-portable*88528 -Ref: install-tl *-print-platform*88667 -Ref: install-tl *-profile* _profile_88860 -Ref: install-tl *-q*90354 -Ref: install-tl *-scheme* _scheme_90416 -Ref: install-tl *-v*90890 -Ref: install-tl *-version*, *--version*91051 -Node: install-tl ENVIRONMENT VARIABLES91182 -Ref: install-tl TEXLIVE_INSTALL_ENV_NOCHECK91571 -Ref: install-tl TEXLIVE_INSTALL_NO_CONTEXT_CACHE91773 -Ref: install-tl TEXLIVE_INSTALL_PREFIX91879 -Ref: install-tl TEXLIVE_INSTALL_TEXMFCONFIG91910 -Ref: install-tl TEXLIVE_INSTALL_TEXMFHOME91939 -Ref: install-tl TEXLIVE_INSTALL_TEXMFLOCAL91969 -Ref: install-tl TEXLIVE_INSTALL_TEXMFSYSCONFIG92003 -Ref: install-tl TEXLIVE_INSTALL_TEXMFSYSVAR92034 -Ref: install-tl TEXLIVE_INSTALL_TEXMFVAR92062 -Ref: install-tl NOPERLDOC92117 -Node: install-tl AUTHORS AND COPYRIGHT92181 -Node: tlmgr92539 -Node: tlmgr NAME92976 -Node: tlmgr SYNOPSIS93101 -Node: tlmgr DESCRIPTION93291 -Node: tlmgr EXAMPLES94387 -Ref: tlmgr tlmgr option repository http://mirror.ctan.org/systems/texlive/tlnet94678 -Ref: tlmgr tlmgr update --list94859 -Ref: tlmgr tlmgr update --all94952 -Ref: tlmgr tlmgr info _pkg_95108 -Node: tlmgr OPTIONS95314 -Ref: tlmgr *--repository* _url|path_95834 -Ref: tlmgr *--gui* [_action_]96559 -Ref: tlmgr *--gui-lang* _llcode_96966 -Ref: tlmgr *--debug-translation*97649 -Ref: tlmgr *--machine-readable*97852 -Ref: tlmgr *--no-execute-actions*98120 -Ref: tlmgr *--package-logfile* _file_98313 -Ref: tlmgr *--pause*98568 -Ref: tlmgr *--persistent-downloads*98723 -Ref: tlmgr *--no-persistent-downloads*98751 -Ref: tlmgr *--pin-file*99245 -Ref: tlmgr *--usermode*99463 -Ref: tlmgr *--usertree* _dir_99583 -Node: tlmgr ACTIONS100133 -Node: tlmgr help101365 -Node: tlmgr version101841 -Node: tlmgr backup [--clean[=_N_]] [--backupdir _dir_] [--all | _pkg_]...102159 -Ref: tlmgr *--backupdir* _directory_103253 -Ref: tlmgr *--all*103450 -Ref: tlmgr *--clean*[=_N_]103672 -Ref: tlmgr *--dry-run*103969 -Node: tlmgr candidates _pkg_104089 -Ref: tlmgr *candidates _pkg_* 1104376 -Node: tlmgr check [_option_]... [files|depends|executes|runfiles|all]104520 -Ref: tlmgr *files*104963 -Ref: tlmgr *depends*105098 -Ref: tlmgr *executes*105440 -Ref: tlmgr *runfiles*105558 -Ref: tlmgr *--use-svn*105670 -Node: tlmgr conf [texmf|tlmgr|updmap [--conffile _file_] [--delete] [_key_ [_value_]]]105787 -Node: tlmgr dump-tlpdb [--local|--remote]107859 -Ref: tlmgr *--local*108369 -Ref: tlmgr *--remote*108408 -Node: tlmgr generate [_option_]... _what_108830 -Ref: tlmgr *generate language*109071 -Ref: tlmgr *generate language.dat*109096 -Ref: tlmgr *generate language.def*109121 -Ref: tlmgr *generate language.dat.lua*109150 -Ref: tlmgr *generate fmtutil*109170 -Ref: tlmgr *--dest* _output_file_111407 -Ref: tlmgr *--localcfg* _local_conf_file_111983 -Ref: tlmgr *--rebuild-sys*112106 -Node: tlmgr gui112967 -Node: tlmgr info [_option_...] [collections|schemes|_pkg_...]113211 -Ref: tlmgr *--list*114416 -Ref: tlmgr *--only-installed*114695 -Ref: tlmgr *--taxonomy*114910 -Ref: tlmgr *--keyword*114922 -Ref: tlmgr *--functionality*114940 -Ref: tlmgr *--characterization*114961 -Node: tlmgr init-usertree115174 -Node: tlmgr install [_option_]... _pkg_...115600 -Ref: tlmgr *--file*115964 -Ref: tlmgr *--reinstall*116190 -Ref: tlmgr *--no-depends*116570 -Ref: tlmgr *--no-depends-at-all*116729 -Ref: tlmgr *--dry-run* 1117127 -Ref: tlmgr *--force*117245 -Node: tlmgr option117451 -Ref: tlmgr *option [show]*117624 -Ref: tlmgr *option showall*117642 -Ref: tlmgr *option _key_ [_value_]*117668 -Node: tlmgr paper121516 -Ref: tlmgr *paper [a4|letter]*121701 -Ref: tlmgr *[xdvi|pdftex|dvips|dvipdfmx|context|psutils] paper [_papersize_|--list]*121775 -Node: tlmgr path [--w32mode=user|admin] [add|remove]122802 -Node: tlmgr pinning124285 -Ref: tlmgr pinning show124592 -Ref: tlmgr pinning add _repo_ _pkgglob_...124665 -Ref: tlmgr pinning remove _repo_ _pkgglob_...124784 -Ref: tlmgr pinning remove _repo_ --all124937 -Node: tlmgr platform list|add|remove _platform_...124991 -Node: tlmgr platform set _platform_125239 -Node: tlmgr platform set auto125467 -Ref: tlmgr *--dry-run* 2126584 -Node: tlmgr postaction [--w32mode=user|admin] [--fileassocmode=1|2] [--all] [install|remove] [shortcut|fileassoc|script] [_pkg_]...126693 -Node: tlmgr print-platform127995 -Node: tlmgr restore [--backupdir _dir_] [--all | _pkg_ [_rev_]]128467 -Ref: tlmgr *--all* 1129363 -Ref: tlmgr *--backupdir* _directory_ 1129557 -Ref: tlmgr *--dry-run* 3129713 -Ref: tlmgr *--force* 1129830 -Node: tlmgr remove [_option_]... _pkg_...129858 -Ref: tlmgr *--no-depends* 1130381 -Ref: tlmgr *--no-depends-at-all* 1130443 -Ref: tlmgr *--force* 2130499 -Ref: tlmgr *--dry-run* 4130971 -Node: tlmgr repository131078 -Ref: tlmgr *repository list*131286 -Ref: tlmgr *repository list _path|tag_*131316 -Ref: tlmgr *repository add _path_ [_tag_]*131349 -Ref: tlmgr *repository remove _path|tag_*131381 -Ref: tlmgr *repository set _path_[#_tag_] [_path_[#_tag_] ...]*131435 -Node: tlmgr search [_option_...] _what_132519 -Node: tlmgr search [_option_...] --file _what_133030 -Node: tlmgr search [_option_...] --taxonomy _what_133281 -Node: tlmgr search [_option_...] --keyword _what_133592 -Node: tlmgr search [_option_...] --functionality _what_133910 -Node: tlmgr search [_option_...] --characterization _what_134248 -Node: tlmgr search [_option_...] --all _what_134588 -Ref: tlmgr *--global*135036 -Ref: tlmgr *--word*135148 -Ref: tlmgr *--list* 1135387 -Ref: tlmgr *--file* 1135733 -Ref: tlmgr *--taxonomy* 1135790 -Ref: tlmgr *--keyword* 1135802 -Ref: tlmgr *--functionality* 1135820 -Ref: tlmgr *--characterization* 1135841 -Ref: tlmgr *--all* 2135996 -Node: tlmgr uninstall136079 -Ref: tlmgr *--force* 3136333 -Node: tlmgr update [_option_]... [_pkg_]...136389 -Ref: tlmgr *--all* 3136760 -Ref: tlmgr *--self*138501 -Ref: tlmgr *--dry-run* 5139265 -Ref: tlmgr *--list* [_pkg_]139442 -Ref: tlmgr *--exclude* _pkg_140131 -Ref: tlmgr *--no-auto-remove* [_pkg_]...140824 -Ref: tlmgr *--no-auto-install* [_pkg_]...141275 -Ref: tlmgr *--reinstall-forcibly-removed*141931 -Ref: tlmgr *--backup* and *--backupdir* _directory_142495 -Ref: tlmgr *--no-depends* 2143676 -Ref: tlmgr *--no-depends-at-all* 2143879 -Ref: tlmgr *--force* 4143935 -Node: tlmgr USER MODE144361 -Node: tlmgr user mode install147172 -Node: tlmgr user mode backup; restore; remove; update148119 -Node: tlmgr user mode generate; option; paper148561 -Node: tlmgr CONFIGURATION FILE FOR TLMGR148937 -Node: tlmgr TAXONOMIES150028 -Ref: tlmgr --keyword 2150654 -Ref: tlmgr --functionality 2150739 -Ref: tlmgr --characterization 2150895 -Ref: tlmgr --taxonomy 2151036 -Node: tlmgr MULTIPLE REPOSITORIES151577 -Node: tlmgr Pinning153298 -Node: tlmgr GUI FOR TLMGR155273 -Node: tlmgr Main display156495 -Node: tlmgr Display configuration area156747 -Ref: tlmgr Status157108 -Ref: tlmgr Category157272 -Ref: tlmgr Match157458 -Ref: tlmgr Selection157718 -Ref: tlmgr Display configuration buttons157922 -Node: tlmgr Package list area158105 -Ref: tlmgr a checkbox158689 -Ref: tlmgr package name158825 -Ref: tlmgr local revision (and version)158924 -Ref: tlmgr remote revision (and version)159299 -Ref: tlmgr short description159596 -Node: tlmgr Main display action buttons159641 -Ref: tlmgr Update all installed159907 -Ref: tlmgr Update160279 -Ref: tlmgr Install160329 -Ref: tlmgr Remove160515 -Ref: tlmgr Backup160693 -Node: tlmgr Menu bar160850 -Ref: tlmgr tlmgr menu161047 -Ref: tlmgr Options menu161355 -Ref: tlmgr Actions menu162438 -Ref: tlmgr Help menu162866 -Node: tlmgr MACHINE-READABLE OUTPUT162999 -Node: tlmgr Machine-readable update and install output163809 -Ref: tlmgr location-url _location_165085 -Ref: tlmgr total-bytes _count_165301 -Ref: tlmgr _pkgname_165711 -Ref: tlmgr _status_165921 -Ref: tlmgr d165999 -Ref: tlmgr f166059 -Ref: tlmgr u166238 -Ref: tlmgr r166284 -Ref: tlmgr a166407 -Ref: tlmgr i166585 -Ref: tlmgr I166704 -Ref: tlmgr _localrev_166806 -Ref: tlmgr _serverrev_166913 -Ref: tlmgr _size_167025 -Ref: tlmgr _runtime_167194 -Ref: tlmgr _esttot_167264 -Node: tlmgr Machine-readable option output167297 -Node: tlmgr AUTHORS AND COPYRIGHT167809 -Node: Index168156 +Node: Top1025 +Node: Introduction1943 +Node: Overview of build system3698 +Node: Prerequisites5741 +Node: Building8139 +Node: Build iteration9387 +Node: Build problems10459 +Node: Build in parallel10862 +Node: Build distribution11454 +Node: Build one package12025 +Node: Installing15611 +Node: Installation directories16626 +Node: Linked scripts18442 +Node: Distro builds19923 +Node: Layout and infrastructure22313 +Node: Build system tools23141 +Node: Top-level directories25150 +Node: Autoconf macros27564 +Node: General setup macros28265 +Node: Macros for programs29132 +Node: Macros for compilers29944 +Node: Macros for libraries31378 +Node: Macros for library and header flags31804 +Node: Macros for Windows33684 +Node: Library modules35261 +Node: png library35750 +Node: zlib library38024 +Node: freetype library38539 +Node: kpathsea library39067 +Node: Program modules40466 +Node: t1utils package40894 +Node: xindy package41445 +Node: xdvik package42595 +Node: asymptote43668 +Node: Extending TeX Live44119 +Node: Adding a new program module44896 +Node: Adding a new generic library module46415 +Node: Adding a new TeX-specific library module48628 +Node: Configure options49315 +Node: Global configure options50697 +Node: --disable-native-texlive-build51239 +Node: --prefix --bindir ...52229 +Node: --disable-largefile52769 +Node: --disable-missing53454 +Node: --enable-compiler-warnings=LEVEL53855 +Node: --enable-cxx-runtime-hack54594 +Node: --enable-maintainer-mode55021 +Node: --enable-multiplatform55550 +Node: --enable-shared56088 +Node: --enable-silent-rules56459 +Node: --without-ln-s56915 +Node: --without-x57266 +Node: Program-specific configure options57454 +Node: --enable-PROG --disable-PROG58097 +Node: --disable-all-pkgs58374 +Node: Configure options for texk/web2c59360 +Node: Configure options for texk/bibtex-x61878 +Node: Configure options for texk/dvipdfm-x62421 +Node: Configure options for texk/dvisvgm63194 +Node: Configure options for texk/texlive64080 +Node: Configure options for texk/xdvik64501 +Node: Configure options for utils/xindy65105 +Node: Library-specific configure options66006 +Node: Configure options for kpathsea67017 +Node: Configure options for system poppler67726 +Node: Variables for configure68517 +Node: Cross compilation69945 +Node: Cross configuring71244 +Node: Cross problems72917 +Node: Coding conventions74564 +Node: Declarations and definitions75291 +Node: Const77473 +Node: install-tl79336 +Node: install-tl NAME79677 +Node: install-tl SYNOPSIS79835 +Node: install-tl DESCRIPTION80043 +Node: install-tl REFERENCES81044 +Node: install-tl OPTIONS81560 +Ref: install-tl *-gui* [[=]_module_]81914 +Ref: install-tl text82123 +Ref: install-tl wizard82246 +Ref: install-tl perltk82400 +Ref: install-tl *-no-gui*82834 +Ref: install-tl *-lang* _llcode_82915 +Ref: install-tl *-repository* _url|path_83602 +Ref: install-tl *-select-repository*85413 +Ref: install-tl *-all-options*85849 +Ref: install-tl *-custom-bin* _path_86156 +Ref: install-tl *-debug-translation*86811 +Ref: install-tl *-force-platform* _platform_87030 +Ref: install-tl *-help*, *--help*, *-?*87274 +Ref: install-tl *-in-place*87667 +Ref: install-tl *-logfile* _file_88194 +Ref: install-tl *-no-cls*88545 +Ref: install-tl *-non-admin*88676 +Ref: install-tl *--persistent-downloads*88781 +Ref: install-tl *--no-persistent-downloads*88809 +Ref: install-tl *-portable*89417 +Ref: install-tl *-print-platform*89556 +Ref: install-tl *-profile* _profile_89749 +Ref: install-tl *-q*91243 +Ref: install-tl *-scheme* _scheme_91305 +Ref: install-tl *-v*91779 +Ref: install-tl *-version*, *--version*91940 +Node: install-tl ENVIRONMENT VARIABLES92071 +Ref: install-tl TEXLIVE_INSTALL_ENV_NOCHECK92460 +Ref: install-tl TEXLIVE_INSTALL_NO_CONTEXT_CACHE92662 +Ref: install-tl TEXLIVE_INSTALL_PREFIX92768 +Ref: install-tl TEXLIVE_INSTALL_TEXMFCONFIG92799 +Ref: install-tl TEXLIVE_INSTALL_TEXMFHOME92828 +Ref: install-tl TEXLIVE_INSTALL_TEXMFLOCAL92858 +Ref: install-tl TEXLIVE_INSTALL_TEXMFSYSCONFIG92892 +Ref: install-tl TEXLIVE_INSTALL_TEXMFSYSVAR92923 +Ref: install-tl TEXLIVE_INSTALL_TEXMFVAR92951 +Ref: install-tl NOPERLDOC93006 +Node: install-tl AUTHORS AND COPYRIGHT93070 +Node: tlmgr93428 +Node: tlmgr NAME93865 +Node: tlmgr SYNOPSIS93990 +Node: tlmgr DESCRIPTION94180 +Node: tlmgr EXAMPLES95276 +Ref: tlmgr tlmgr option repository http://mirror.ctan.org/systems/texlive/tlnet95567 +Ref: tlmgr tlmgr update --list95748 +Ref: tlmgr tlmgr update --all95841 +Ref: tlmgr tlmgr info _pkg_95997 +Node: tlmgr OPTIONS96203 +Ref: tlmgr *--repository* _url|path_96723 +Ref: tlmgr *--gui* [_action_]97448 +Ref: tlmgr *--gui-lang* _llcode_97855 +Ref: tlmgr *--debug-translation*98538 +Ref: tlmgr *--machine-readable*98741 +Ref: tlmgr *--no-execute-actions*99009 +Ref: tlmgr *--package-logfile* _file_99202 +Ref: tlmgr *--pause*99457 +Ref: tlmgr *--persistent-downloads*99612 +Ref: tlmgr *--no-persistent-downloads*99640 +Ref: tlmgr *--pin-file*100134 +Ref: tlmgr *--usermode*100352 +Ref: tlmgr *--usertree* _dir_100472 +Node: tlmgr ACTIONS101022 +Node: tlmgr help102254 +Node: tlmgr version102730 +Node: tlmgr backup [--clean[=_N_]] [--backupdir _dir_] [--all | _pkg_]...103048 +Ref: tlmgr *--backupdir* _directory_104142 +Ref: tlmgr *--all*104339 +Ref: tlmgr *--clean*[=_N_]104561 +Ref: tlmgr *--dry-run*104858 +Node: tlmgr candidates _pkg_104978 +Ref: tlmgr *candidates _pkg_* 1105265 +Node: tlmgr check [_option_]... [files|depends|executes|runfiles|all]105409 +Ref: tlmgr *files*105852 +Ref: tlmgr *depends*105987 +Ref: tlmgr *executes*106329 +Ref: tlmgr *runfiles*106447 +Ref: tlmgr *--use-svn*106559 +Node: tlmgr conf [texmf|tlmgr|updmap [--conffile _file_] [--delete] [_key_ [_value_]]]106676 +Node: tlmgr dump-tlpdb [--local|--remote]108748 +Ref: tlmgr *--local*109258 +Ref: tlmgr *--remote*109297 +Node: tlmgr generate [_option_]... _what_109719 +Ref: tlmgr *generate language*109960 +Ref: tlmgr *generate language.dat*109985 +Ref: tlmgr *generate language.def*110010 +Ref: tlmgr *generate language.dat.lua*110039 +Ref: tlmgr *generate fmtutil*110059 +Ref: tlmgr *--dest* _output_file_112296 +Ref: tlmgr *--localcfg* _local_conf_file_112872 +Ref: tlmgr *--rebuild-sys*112995 +Node: tlmgr gui113856 +Node: tlmgr info [_option_...] [collections|schemes|_pkg_...]114100 +Ref: tlmgr *--list*115305 +Ref: tlmgr *--only-installed*115584 +Ref: tlmgr *--taxonomy*115799 +Ref: tlmgr *--keyword*115811 +Ref: tlmgr *--functionality*115829 +Ref: tlmgr *--characterization*115850 +Node: tlmgr init-usertree116063 +Node: tlmgr install [_option_]... _pkg_...116489 +Ref: tlmgr *--file*116853 +Ref: tlmgr *--reinstall*117079 +Ref: tlmgr *--no-depends*117459 +Ref: tlmgr *--no-depends-at-all*117618 +Ref: tlmgr *--dry-run* 1118016 +Ref: tlmgr *--force*118134 +Node: tlmgr option118340 +Ref: tlmgr *option [show]*118513 +Ref: tlmgr *option showall*118531 +Ref: tlmgr *option _key_ [_value_]*118557 +Node: tlmgr paper122405 +Ref: tlmgr *paper [a4|letter]*122590 +Ref: tlmgr *[xdvi|pdftex|dvips|dvipdfmx|context|psutils] paper [_papersize_|--list]*122664 +Node: tlmgr path [--w32mode=user|admin] [add|remove]123691 +Node: tlmgr pinning125174 +Ref: tlmgr pinning show125481 +Ref: tlmgr pinning add _repo_ _pkgglob_...125554 +Ref: tlmgr pinning remove _repo_ _pkgglob_...125673 +Ref: tlmgr pinning remove _repo_ --all125826 +Node: tlmgr platform list|add|remove _platform_...125880 +Node: tlmgr platform set _platform_126128 +Node: tlmgr platform set auto126356 +Ref: tlmgr *--dry-run* 2127473 +Node: tlmgr postaction [--w32mode=user|admin] [--fileassocmode=1|2] [--all] [install|remove] [shortcut|fileassoc|script] [_pkg_]...127582 +Node: tlmgr print-platform128884 +Node: tlmgr restore [--backupdir _dir_] [--all | _pkg_ [_rev_]]129356 +Ref: tlmgr *--all* 1130252 +Ref: tlmgr *--backupdir* _directory_ 1130446 +Ref: tlmgr *--dry-run* 3130602 +Ref: tlmgr *--force* 1130719 +Node: tlmgr remove [_option_]... _pkg_...130747 +Ref: tlmgr *--no-depends* 1131270 +Ref: tlmgr *--no-depends-at-all* 1131332 +Ref: tlmgr *--force* 2131388 +Ref: tlmgr *--dry-run* 4131860 +Node: tlmgr repository131967 +Ref: tlmgr *repository list*132175 +Ref: tlmgr *repository list _path|tag_*132205 +Ref: tlmgr *repository add _path_ [_tag_]*132238 +Ref: tlmgr *repository remove _path|tag_*132270 +Ref: tlmgr *repository set _path_[#_tag_] [_path_[#_tag_] ...]*132324 +Node: tlmgr search [_option_...] _what_133408 +Node: tlmgr search [_option_...] --file _what_133919 +Node: tlmgr search [_option_...] --taxonomy _what_134170 +Node: tlmgr search [_option_...] --keyword _what_134481 +Node: tlmgr search [_option_...] --functionality _what_134799 +Node: tlmgr search [_option_...] --characterization _what_135137 +Node: tlmgr search [_option_...] --all _what_135477 +Ref: tlmgr *--global*135925 +Ref: tlmgr *--word*136037 +Ref: tlmgr *--list* 1136276 +Ref: tlmgr *--file* 1136622 +Ref: tlmgr *--taxonomy* 1136679 +Ref: tlmgr *--keyword* 1136691 +Ref: tlmgr *--functionality* 1136709 +Ref: tlmgr *--characterization* 1136730 +Ref: tlmgr *--all* 2136885 +Node: tlmgr uninstall136968 +Ref: tlmgr *--force* 3137222 +Node: tlmgr update [_option_]... [_pkg_]...137278 +Ref: tlmgr *--all* 3137649 +Ref: tlmgr *--self*139390 +Ref: tlmgr *--dry-run* 5140154 +Ref: tlmgr *--list* [_pkg_]140331 +Ref: tlmgr *--exclude* _pkg_141020 +Ref: tlmgr *--no-auto-remove* [_pkg_]...141713 +Ref: tlmgr *--no-auto-install* [_pkg_]...142164 +Ref: tlmgr *--reinstall-forcibly-removed*142820 +Ref: tlmgr *--backup* and *--backupdir* _directory_143384 +Ref: tlmgr *--no-depends* 2144565 +Ref: tlmgr *--no-depends-at-all* 2144768 +Ref: tlmgr *--force* 4144824 +Node: tlmgr USER MODE145250 +Node: tlmgr user mode install148061 +Node: tlmgr user mode backup; restore; remove; update149008 +Node: tlmgr user mode generate; option; paper149450 +Node: tlmgr CONFIGURATION FILE FOR TLMGR149826 +Node: tlmgr TAXONOMIES150917 +Ref: tlmgr --keyword 2151543 +Ref: tlmgr --functionality 2151628 +Ref: tlmgr --characterization 2151784 +Ref: tlmgr --taxonomy 2151925 +Node: tlmgr MULTIPLE REPOSITORIES152466 +Node: tlmgr Pinning154187 +Node: tlmgr GUI FOR TLMGR156162 +Node: tlmgr Main display157384 +Node: tlmgr Display configuration area157636 +Ref: tlmgr Status157997 +Ref: tlmgr Category158161 +Ref: tlmgr Match158347 +Ref: tlmgr Selection158607 +Ref: tlmgr Display configuration buttons158811 +Node: tlmgr Package list area158994 +Ref: tlmgr a checkbox159578 +Ref: tlmgr package name159714 +Ref: tlmgr local revision (and version)159813 +Ref: tlmgr remote revision (and version)160188 +Ref: tlmgr short description160485 +Node: tlmgr Main display action buttons160530 +Ref: tlmgr Update all installed160796 +Ref: tlmgr Update161168 +Ref: tlmgr Install161218 +Ref: tlmgr Remove161404 +Ref: tlmgr Backup161582 +Node: tlmgr Menu bar161739 +Ref: tlmgr tlmgr menu161936 +Ref: tlmgr Options menu162244 +Ref: tlmgr Actions menu163327 +Ref: tlmgr Help menu163755 +Node: tlmgr MACHINE-READABLE OUTPUT163888 +Node: tlmgr Machine-readable update and install output164698 +Ref: tlmgr location-url _location_165974 +Ref: tlmgr total-bytes _count_166190 +Ref: tlmgr _pkgname_166600 +Ref: tlmgr _status_166810 +Ref: tlmgr d166888 +Ref: tlmgr f166948 +Ref: tlmgr u167127 +Ref: tlmgr r167173 +Ref: tlmgr a167296 +Ref: tlmgr i167474 +Ref: tlmgr I167593 +Ref: tlmgr _localrev_167695 +Ref: tlmgr _serverrev_167802 +Ref: tlmgr _size_167914 +Ref: tlmgr _runtime_168083 +Ref: tlmgr _esttot_168153 +Node: tlmgr Machine-readable option output168186 +Node: tlmgr AUTHORS AND COPYRIGHT168698 +Node: Index169045 End Tag Table diff --git a/source/doc/tlbuild.texi b/source/doc/tlbuild.texi index da48523a166e00f44eb0daeb1f2ce8032cf7fd4f..ca6177acb979c45edfaf3220cbc89f14c56b2bb0 100644 --- a/source/doc/tlbuild.texi +++ b/source/doc/tlbuild.texi @@ -2,7 +2,7 @@ @setfilename tlbuild.info @set version 2016 -@set month-year April 2016 +@set month-year February 2017 @set mytitle Building @TeX{} Live (@value{version}) @settitle @value{mytitle} @@ -14,8 +14,9 @@ @copying This file documents the @TL{} build system and more. -Copyright @copyright{} 2016 Karl Berry.@* -Copyright @copyright{} 2013, 2014, 2015 Karl Berry & Peter Breitenlohner. +@noindent +Copyright @copyright{} 2016--2017 Karl Berry.@* +Copyright @copyright{} 2013--2015 Karl Berry & Peter Breitenlohner. Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are @@ -138,7 +139,7 @@ As an exception, the full documentation for @code{install-tl} and @code{tlmgr} is included here, just because it is convenient to do so. The same text is available online (linked from @url{http://tug.org/texlive/doc.html}, or by invoking the program with -@samp{--help} (or look at the end of the source file). +@samp{--help} (or look at the end of the source). @c The first word of the chapter/section title here is used to @@ -185,8 +186,8 @@ The primary design goal of the build system is modularity. Each program and library module (or package) specifies its own requirements and properties, such as required libraries, whether an installed (system) version of a library can be used, @code{configure} options to -be seen at the top-level, and more. An explicit list of all available -modules is kept in only one, central, place (@file{m4/kpse-pkgs.m4}). +be seen at the top level, and more. An explicit list of all available +modules is kept in only one central place, namely @file{m4/kpse-pkgs.m4}. A second, related goal is to configure and build each library before configuring any other (program or library) module which uses that @@ -198,9 +199,9 @@ All generic libraries and several programs are maintained independently. The corresponding modules use (most of) the distributed source tree and document any modifications of that source. -All this is for the sake of simplifying both upgrading of modules -maintained independently and integrating new modules into the -TL build system. (Not to say that either task is trivial.) +All this is for the sake of simplifying both upgrading of modules and +integrating new modules into the TL build system. (Not to say that +either task is trivial.) @node Prerequisites @@ -218,14 +219,20 @@ you can set @code{MAKE} in the environment to whatever is necessary.) @cindex GNU @code{make}, required @cindex @code{gmake}, required @cindex FreeType -Indeed, GNU @code{make} is required only because of some -third-party libraries, notably FreeType; all the TL-maintained -directories (and Automake/Autoconf output in general) should work with -any reasonable @code{make}. +GNU @code{make} is required only because of some third-party +libraries, notably FreeType; all the TL-maintained directories (and +Automake/Autoconf output in general) should work with any reasonable +@code{make}. However, a few programs in the tree have additional requirements: @table @file +@item dvisvgm +@cindex @code{dvisvgm} requirement for C++11 +@cindex C++11, required by @code{dvisvgm} +requires a C++11 compiler, such as gcc 4.8.1 (or later) or clang 3.3 +(or later). + @item web2c @cindex @code{perl}, required by @code{web2c}, etc. requires @code{perl} for some tests run by @code{make check}. @@ -367,7 +374,7 @@ to be done unless some source files have been modified. @vindex --no-clean Build @r{option} If configuring or building a module fails, you should first find and fix the problem, then perhaps remove the subdirectory for that module from the build -tree, and finally rerun the top-level @code{make} (or @file{Build} with +tree, and finally rerun the top level @code{make} (or @file{Build} with @code{--no-clean} as its first argument). @@ -400,7 +407,7 @@ by using a configure cache file, i.e., with the option @code{-C} @cindex distribution tarball, making @cindex @code{dist} and @code{distcheck} targets for @code{make} -Running @code{make dist} at the top-level creates a tarball +Running @code{make dist} at the top level creates a tarball @file{tex-live-@var{yyyy}-@var{mm}-@var{dd}.tar.xz} from the TL source tree. Running @code{make distcheck} also verifies that this tarball suffices to build and install all of TL. @@ -724,12 +731,12 @@ rules to build and install them together with some of their support files. @menu -* Build system tools:: If modifying infrastructure files. -* Top-level directories:: -* Autoconf macros:: TL-specific Autoconf macros. -* Library modules:: Details on some specific libraries, -* Program modules:: and on some programs. -* Extending @TL{}:: Adding a new module. +* Build system tools:: Modifying infrastructure files. +* Top-level directories:: libs texk utils; am auxdir build-aux m4; doc extra. +* Autoconf macros:: TL-specific Autoconf macros. +* Library modules:: Handling libraries, with examples. +* Program modules:: Handling programs, with examples. +* Extending @TL{}:: Adding a new module. @end menu @@ -804,11 +811,12 @@ programs), and @file{libs/} (generic libraries). @cindex @file{am/} top-level directory @cindex @file{m4/} top-level directory -The top-level directories @file{am/} and @file{m4/} contain -@file{Makefile.am} fragments and Autoconf macros, respectively, used -in many places. Specifically, the file @file{m4/kpse-pkgs.m4} -contains lists of all program and library modules; missing modules are -silently ignored. (This helps in creating cut-down source trees.) +In addition, the top-level directories @file{am/} and @file{m4/} +contain @file{Makefile.am} fragments and Autoconf macros, +respectively, used in many places. Specifically, the file +@file{m4/kpse-pkgs.m4} contains lists of all program and library +modules; missing modules are silently ignored. (This helps in +creating cut-down source trees.) Each module contributes fragments (in separate files) defining its capabilities and requirements to the @file{configure.ac} scripts at @@ -820,22 +828,32 @@ library can be used. This ultimately determines which modules need to be built---although all modules must be configured for the benefit of @file{make} targets such as @code{dist} or @code{distcheck}. -@pindex config.guess@r{,} config.sub +@cindex @file{build-aux/} top-level directory +@pindex config.guess@r{,} config.sub, @dots{} @cindex Gnulib, used for common files The top-level @file{build-aux/} directory contains the common files @file{compile}, @file{config.guess}, @file{config.sub}, -@file{depcomp}, etc.@ for most packages, pulled from the GNU Gnulib -sources (@url{http://www.gnu.org/software/gnulib}), which in turn -synchronizes with the appropriate ultimate upstream repository. There -are, however, independent copies in, e.g., -@file{libs/freetype2/freetype-*/builds/unix/}, and similar places. +@file{depcomp}, etc.@ used by most packages. These are from the GNU +Gnulib sources (@url{http://www.gnu.org/software/gnulib}), which in +turn synchronizes with the appropriate ultimate upstream repository. +There are, however, independent copies in, e.g., +@file{libs/freetype2/freetype-*/builds/unix/}, and a few other places. The @code{reautoconf} script does not touch those, but a TL cron job keeps them in sync (nightly). @cindex @file{extra/} top-level directory The directory @file{extra/} contains things which are not part of the TL build, but are present just for (someone's) convenience, e.g., -@file{epstopdf} which is developed here. +is @file{epstopdf} development source is here. + +@cindex @file{Work/} top-level directory +@cindex @file{inst/} top-level directory +When the top-level @file{./Build} script is used to build TL, two more +two more top-level directories appear: @file{Work/} for the build tree, +and @file{inst/} for the install tree (from @code{make install}). +These names (and everything else about @file{Build}'s operation) can +be changed by setting environment variables before running it; see the +script file. @node Autoconf macros @@ -1121,10 +1139,9 @@ structure and variation. @pindex png @r{library} @pindex libpng @r{library} -@set libpngversion libpng-1.6.16 This generic library uses the source tree in, e.g., the subdirectory -@file{@value{libpngversion}} with all modifications for TL recorded in -@file{@value{libpngversion}-PATCHES/*}. The @file{configure.ac} fragment +@file{libpng-src/} with all modifications for TL recorded in +@file{TLPATCHES/*}. The @file{configure.ac} fragment @file{ac/withenable.ac} contains @example @@ -1267,10 +1284,9 @@ details for a few of the programs in TL. @subsection The @code{t1utils} package in @file{utils/t1utils} @pindex t1utils @r{package} -@set t1utilsversion t1utils-1.39 -Once again we use the distributed source tree @file{@value{t1utilsversion}} -with modifications documented in @file{@value{t1utilsversion}-PATCHES/*} and +Once again we use the distributed source tree @file{t1utils-src} +with modifications documented in @file{TLPATCHES/*} and a proxy build system consisting of @file{configure.ac} and @file{Makefile.am}. The fragment @file{ac/withenable.ac} contains @@ -1286,15 +1302,14 @@ supplies the configure option @code{--disable-t1utils}. @subsection The @code{xindy} package in @file{utils/xindy} @pindex xindy -@set xindyversion xindy-2.5.1 -This module uses the distributed source tree @file{@value{xindyversion}} -with modifications documented in @file{@value{xindyversion}-PATCHES/*}, a -proxy @file{configure.ac}, and a wrapper @file{Makefile.am} that descends -into @file{@value{xindyversion}}. The @code{xindy} build requires that the -distributed @file{Makefile}s allow a @code{VPATH} build, can handle all -targets, and do not refer to @code{$@{top_srcdir@}} or -@code{$@{top_builddir@}}. The fragment @code{ac/withenable.ac} contains +This module uses the distributed source tree @file{xindy-src/} with +modifications documented in @file{TLPATCHES/*}, a proxy +@file{configure.ac}, and a wrapper @file{Makefile.am} that descends +into @file{xindy-src}. The @code{xindy} build requires a @file{make} +that supports a @code{VPATH} build, can handle all targets, and do not +refer to @code{$@{top_srcdir@}} or @code{$@{top_builddir@}}. The +fragment @code{ac/withenable.ac} contains @example KPSE_ENABLE_PROG([xindy], , [disable native]) @@ -1366,6 +1381,14 @@ their support files. This section outlines the basic process for adding new packages to the TL build system. +In any case, a new package directory @file{foo} should contain the +original sources, as modified for TL, in @file{foo/foo-src}, and the +changes should be documented in @file{foo/TLPATCHES/*}; changes should +also be submitted upstream whenever reasonable, of course. In +addition, @file{foo/} will need the usual Automake build-related files +(@file{configure.ac}, @file{Makefile.am}, etc. Please keep a +@file{ChangeLog} for all TL changes. + @menu * Adding a new program module:: * Adding a new generic library module:: @@ -2284,8 +2307,9 @@ should produce no (GCC) compiler warnings at all. In spite of considerable efforts into that direction we are still far from that goal and there are reasons that we may never fully reach it. Below are some rules about declarations of functions or variables and the use of @code{const}. -These rules should be applied to all parts of the @TL{} tree, except some of -those maintained independently. +These rules should be applied to most of the @TL{} tree, the exception +being code that is maintained independently and whose maintainers +don't want to accept patches. @menu * Declarations and definitions:: diff --git a/source/libs/Makefile.in b/source/libs/Makefile.in index bf6f649508fc42ae529a867914dacb457ded973e..ceb171a1ca329a2dace5d7e80247dc5c60d49b31 100644 --- a/source/libs/Makefile.in +++ b/source/libs/Makefile.in @@ -89,8 +89,7 @@ build_triplet = @build@ host_triplet = @host@ subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/../m4/kpse-cairo-flags.m4 \ - $(top_srcdir)/../m4/kpse-common.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/../m4/kpse-common.m4 \ $(top_srcdir)/../m4/kpse-cxx-hack.m4 \ $(top_srcdir)/../m4/kpse-gmp-flags.m4 \ $(top_srcdir)/../m4/kpse-kpathsea-flags.m4 \ @@ -99,7 +98,6 @@ am__aclocal_m4_deps = $(top_srcdir)/../m4/kpse-cairo-flags.m4 \ $(top_srcdir)/../m4/kpse-mktex.m4 \ $(top_srcdir)/../m4/kpse-mpfr-flags.m4 \ $(top_srcdir)/../m4/kpse-options.m4 \ - $(top_srcdir)/../m4/kpse-pixman-flags.m4 \ $(top_srcdir)/../m4/kpse-pkgs.m4 \ $(top_srcdir)/../m4/kpse-poppler-flags.m4 \ $(top_srcdir)/../m4/kpse-setup.m4 \ @@ -117,8 +115,6 @@ am__aclocal_m4_deps = $(top_srcdir)/../m4/kpse-cairo-flags.m4 \ $(top_srcdir)/../libs/poppler/ac/withenable.ac \ $(top_srcdir)/../libs/mpfr/ac/withenable.ac \ $(top_srcdir)/../libs/gmp/ac/withenable.ac \ - $(top_srcdir)/../libs/cairo/ac/withenable.ac \ - $(top_srcdir)/../libs/pixman/ac/withenable.ac \ $(top_srcdir)/../libs/libpng/ac/withenable.ac \ $(top_srcdir)/../libs/luajit/ac/withenable.ac \ $(top_srcdir)/../libs/lua52/ac/withenable.ac \ @@ -196,11 +192,12 @@ am__DIST_COMMON = $(srcdir)/../am/dist_hook.am \ $(top_srcdir)/../build-aux/config.guess \ $(top_srcdir)/../build-aux/config.sub \ $(top_srcdir)/../build-aux/install-sh \ - $(top_srcdir)/../build-aux/missing ../build-aux/compile \ - ../build-aux/config.guess ../build-aux/config.sub \ - ../build-aux/depcomp ../build-aux/install-sh \ - ../build-aux/ltmain.sh ../build-aux/missing \ - ../build-aux/texinfo.tex ../build-aux/ylwrap ChangeLog README + $(top_srcdir)/../build-aux/missing ../build-aux/ar-lib \ + ../build-aux/compile ../build-aux/config.guess \ + ../build-aux/config.sub ../build-aux/depcomp \ + ../build-aux/install-sh ../build-aux/ltmain.sh \ + ../build-aux/missing ../build-aux/texinfo.tex \ + ../build-aux/ylwrap ChangeLog README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) @@ -334,7 +331,6 @@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ -subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ @@ -351,11 +347,18 @@ NEVER_NAMES_LT = -o -name .libs -o -name '*.lo' recurse_this = libs/ recurse_top = ../ -# We must configure all subdirs since 'make dist' needs the Makefile. -# For those not required for the current set of configure options +# $Id: recurse.am 43261 2017-02-17 22:37:44Z karl $ +# +# Requires $(recurse_this) and $(recurse_top). +# Uses CONF_SUBDIRS and MAKE_SUBDIRS (set by kpse-setup.m4). +# +# For subdirs not required for the current set of configure options # we append '--disable-build' so they can skip tests that would # fail because, e.g., some required libraries were not built. +# (By manually testing $enable_build in configure, e.g., dvisvgm/configure.) +# # Code inspired by automake's way to handle recursive targets. +# cf_silent = $(cf_silent_@AM_V@) cf_silent_ = $(cf_silent_@AM_DEFAULT_V@) cf_silent_0 = --silent diff --git a/source/libs/README b/source/libs/README index d75d45240420ef8fd8eaaa52a7aa6b53048acef1..5e77bbc914513cc10d950dea3a5d8eb234619087 100644 --- a/source/libs/README +++ b/source/libs/README @@ -1,4 +1,4 @@ -$Id: README 43298 2017-02-22 04:06:22Z kakuto $ +$Id: README 43412 2017-03-06 14:22:59Z kakuto $ Public domain. Originally created by Karl Berry, 2005. Libraries we compile for TeX Live. @@ -24,7 +24,7 @@ gmp 6.1.2 - checked 16dec16 graphite2 1.3.9 - checked 13nov16 http://sourceforge.net/projects/silgraphite/files/graphite2/ -harfbuzz 1.4.2 - checked 25jan17 +harfbuzz 1.4.4 - checked 06mar17 http://www.freedesktop.org/software/harfbuzz/release/ icu 57.1 (release) - checked 27mar16 diff --git a/source/libs/aclocal.m4 b/source/libs/aclocal.m4 index 4415289d78cc49af68e39e5d25ba3298a5ac6650..aed27c46ff0b2d5593740bbd7e752acaf7529a91 100644 --- a/source/libs/aclocal.m4 +++ b/source/libs/aclocal.m4 @@ -1186,7 +1186,6 @@ AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR -m4_include([../m4/kpse-cairo-flags.m4]) m4_include([../m4/kpse-common.m4]) m4_include([../m4/kpse-cxx-hack.m4]) m4_include([../m4/kpse-gmp-flags.m4]) @@ -1196,7 +1195,6 @@ m4_include([../m4/kpse-lt-hack.m4]) m4_include([../m4/kpse-mktex.m4]) m4_include([../m4/kpse-mpfr-flags.m4]) m4_include([../m4/kpse-options.m4]) -m4_include([../m4/kpse-pixman-flags.m4]) m4_include([../m4/kpse-pkgs.m4]) m4_include([../m4/kpse-poppler-flags.m4]) m4_include([../m4/kpse-setup.m4]) diff --git a/source/libs/cairo/ChangeLog b/source/libs/cairo/ChangeLog deleted file mode 100644 index 587e1a7fc462c8674e29334758fae9c50eb14ec9..0000000000000000000000000000000000000000 --- a/source/libs/cairo/ChangeLog +++ /dev/null @@ -1,106 +0,0 @@ -2016-12-09 Akira Kakuto <kakuto@fuk.kindai.ac.jp> - - Import cairo-1.14.8. - * version.ac: Adapted. - -2016-02-15 Karl Berry <karl@tug.org> - - * cairo-PATCHES: rename from cairo-src-PATCHES. - * Makefile.am (EXTRA_DIST): likewise. - -2015-12-28 Akira Kakuto <kakuto@fuk.kindai.ac.jp> - - Import cairo-1.14.6. - * configure.ac: new source-tree-naming convention per Karl. - * version.ac: Adapted. - -2015-07-06 Peter Breitenlohner <peb@mppmu.mpg.de> - - * Makefile.am: Better dependencies for 'make check'. - -2015-03-11 Peter Breitenlohner <peb@mppmu.mpg.de> - - Import cairo-1.14.2. - * Makefile.am, version.ac: Adapted. - -2015-02-16 Peter Breitenlohner <peb@mppmu.mpg.de> - - * Makefile.am: Use the fragment ../../am/dist_hook.am. - -2014-12-02 Peter Breitenlohner <peb@mppmu.mpg.de> - - * configure.ac: Added KPSE_COMPILER_VISIBILITY. - * Makefile.am [AM_CFLAGS]: Added $(VISIBILITY_CFLAGS). - -2014-10-15 Peter Breitenlohner <peb@mppmu.mpg.de> - - Import cairo-1.14.0. - * Makefile.am, version.ac: Adapted. - -2014-02-04 Peter Breitenlohner <peb@mppmu.mpg.de> - - * configure.ac: Use -Wno-attributes only for gcc Version 4.2 and - better (unsupported in 4.0.1). - -2013-10-31 Peter Breitenlohner <peb@mppmu.mpg.de> - - * Makefile.am, configure.ac, cairo/Makefile.am: Prepare for SVG. - -2013-10-29 Peter Breitenlohner <peb@mppmu.mpg.de> - - * cairotst.c: Print more info. - -2013-09-10 Peter Breitenlohner <peb@mppmu.mpg.de> - - Import cairo-1.12.16. - * Makefile.am, version.ac: Adapted. - -2013-09-02 Peter Breitenlohner <peb@mppmu.mpg.de> - - * Makefile.am: Drop ACLOCAL_AMFLAGS. - * configure.ac: Use AC_CONFIG_MACRO_DIRS. - -2012-07-06 Peter Breitenlohner <peb@mppmu.mpg.de> - - * Makefile.am: Use ../../am/reconfig.am and ../../am/rebuild.am. - -2013-07-05 Peter Breitenlohner <peb@mppmu.mpg.de> - - * cairo/Makefile.am: Moved Makefile fragments to ../../am/. - -2013-06-26 Peter Breitenlohner <peb@mppmu.mpg.de> - - * Makefile.am (SUBDIRS): Build the library first. - -2013-05-25 Peter Breitenlohner <peb@mppmu.mpg.de> - - Import cairo-1.12.14. - * Makefile.am, version.ac: Adapted. - -2013-03-29 Peter Breitenlohner <peb@mppmu.mpg.de> - - * Makefile.am, configure.ac: Convert to proxy build system. - * cairo.test: Shell script for a basic test. - * cairotst.c: Source code for test program. - -2012-12-15 Peter Breitenlohner <peb@mppmu.mpg.de> - - * configure.ac: Use KPSE_BASIC to enable silent rules. - -2012-11-22 Peter Breitenlohner <peb@mppmu.mpg.de> - - * configure.ac: Make sure 'config.status --recheck' leaves the - generated Makefile unchanged. - -2012-11-16 Peter Breitenlohner <peb@mppmu.mpg.de> - - Import cairo-1.12.8. - * version.ac: Adapted. - -2012-11-15 Peter Breitenlohner <peb@mppmu.mpg.de> - - Import cairo-1.10.2. - -2012-11-10 Taco Hoekwater <taco@metatex.org> - - Import cairo-1.12.8. diff --git a/source/libs/cairo/Makefile.am b/source/libs/cairo/Makefile.am deleted file mode 100644 index 42c0ecefd0048712a27b79524e6c9b3d54008723..0000000000000000000000000000000000000000 --- a/source/libs/cairo/Makefile.am +++ /dev/null @@ -1,253 +0,0 @@ -## Proxy Makefile.am to build cairo for TeX Live. -## -## Copyright (C) 2016 Karl Berry <tex-live@tug.org> -## Copyright (C) 2013-2015 Peter Breitenlohner <tex-live@tug.org> -## Copyright (C) 2012 Taco Hoekwater <taco@metatex.org> -## -## This file is free software; the copyright holder -## gives unlimited permission to copy and/or distribute it, -## with or without modifications, as long as this notice is preserved. -## -## We want to re-distribute the whole cairo source tree. -## -EXTRA_DIST = $(CAIRO_TREE) - -## Changes applied to the original source tree -## -EXTRA_DIST += cairo-PATCHES - -CAIRO_SRC = $(CAIRO_TREE)/src - -# Files not to be distributed -include $(srcdir)/../../am/dist_hook.am -NEVER_NAMES += $(NEVER_NAMES_SUB) - -SUBDIRS = . cairo - -AM_CPPFLAGS = -I$(top_srcdir)/$(CAIRO_SRC) $(PIXMAN_INCLUDES) -DCAIRO_NO_MUTEX -AM_CFLAGS = $(CAIRO_ATTRIBUTE_FLAG) $(VISIBILITY_CFLAGS) # $(WARNING_CFLAGS) - -noinst_LIBRARIES = libcairo.a - -libcairo_a_SOURCES = \ - @CAIRO_TREE@/src/cairo-analysis-surface.c \ - @CAIRO_TREE@/src/cairo-arc.c \ - @CAIRO_TREE@/src/cairo-array.c \ - @CAIRO_TREE@/src/cairo-atomic.c \ - @CAIRO_TREE@/src/cairo-base64-stream.c \ - @CAIRO_TREE@/src/cairo-base85-stream.c \ - @CAIRO_TREE@/src/cairo-bentley-ottmann.c \ - @CAIRO_TREE@/src/cairo-bentley-ottmann-rectangular.c \ - @CAIRO_TREE@/src/cairo-bentley-ottmann-rectilinear.c \ - @CAIRO_TREE@/src/cairo-botor-scan-converter.c \ - @CAIRO_TREE@/src/cairo-boxes.c \ - @CAIRO_TREE@/src/cairo-boxes-intersect.c \ - @CAIRO_TREE@/src/cairo.c \ - @CAIRO_TREE@/src/cairo-cache.c \ - @CAIRO_TREE@/src/cairo-clip.c \ - @CAIRO_TREE@/src/cairo-clip-boxes.c \ - @CAIRO_TREE@/src/cairo-clip-polygon.c \ - @CAIRO_TREE@/src/cairo-clip-region.c \ - @CAIRO_TREE@/src/cairo-clip-surface.c \ - @CAIRO_TREE@/src/cairo-color.c \ - @CAIRO_TREE@/src/cairo-composite-rectangles.c \ - @CAIRO_TREE@/src/cairo-compositor.c \ - @CAIRO_TREE@/src/cairo-contour.c \ - @CAIRO_TREE@/src/cairo-damage.c \ - @CAIRO_TREE@/src/cairo-debug.c \ - @CAIRO_TREE@/src/cairo-default-context.c \ - @CAIRO_TREE@/src/cairo-device.c \ - @CAIRO_TREE@/src/cairo-error.c \ - @CAIRO_TREE@/src/cairo-fallback-compositor.c \ - @CAIRO_TREE@/src/cairo-fixed.c \ - @CAIRO_TREE@/src/cairo-font-face.c \ - @CAIRO_TREE@/src/cairo-font-face-twin.c \ - @CAIRO_TREE@/src/cairo-font-face-twin-data.c \ - @CAIRO_TREE@/src/cairo-font-options.c \ - @CAIRO_TREE@/src/cairo-freelist.c \ - @CAIRO_TREE@/src/cairo-freed-pool.c \ - @CAIRO_TREE@/src/cairo-gstate.c \ - @CAIRO_TREE@/src/cairo-hash.c \ - @CAIRO_TREE@/src/cairo-hull.c \ - @CAIRO_TREE@/src/cairo-image-compositor.c \ - @CAIRO_TREE@/src/cairo-image-info.c \ - @CAIRO_TREE@/src/cairo-image-source.c \ - @CAIRO_TREE@/src/cairo-image-surface.c \ - @CAIRO_TREE@/src/cairo-line.c \ - @CAIRO_TREE@/src/cairo-lzw.c \ - @CAIRO_TREE@/src/cairo-matrix.c \ - @CAIRO_TREE@/src/cairo-mask-compositor.c \ - @CAIRO_TREE@/src/cairo-mesh-pattern-rasterizer.c \ - @CAIRO_TREE@/src/cairo-mempool.c \ - @CAIRO_TREE@/src/cairo-misc.c \ - @CAIRO_TREE@/src/cairo-mono-scan-converter.c \ - @CAIRO_TREE@/src/cairo-mutex.c \ - @CAIRO_TREE@/src/cairo-no-compositor.c \ - @CAIRO_TREE@/src/cairo-observer.c \ - @CAIRO_TREE@/src/cairo-output-stream.c \ - @CAIRO_TREE@/src/cairo-paginated-surface.c \ - @CAIRO_TREE@/src/cairo-path-bounds.c \ - @CAIRO_TREE@/src/cairo-path.c \ - @CAIRO_TREE@/src/cairo-path-fill.c \ - @CAIRO_TREE@/src/cairo-path-fixed.c \ - @CAIRO_TREE@/src/cairo-path-in-fill.c \ - @CAIRO_TREE@/src/cairo-path-stroke.c \ - @CAIRO_TREE@/src/cairo-path-stroke-boxes.c \ - @CAIRO_TREE@/src/cairo-path-stroke-polygon.c \ - @CAIRO_TREE@/src/cairo-path-stroke-traps.c \ - @CAIRO_TREE@/src/cairo-path-stroke-tristrip.c \ - @CAIRO_TREE@/src/cairo-pattern.c \ - @CAIRO_TREE@/src/cairo-pen.c \ - @CAIRO_TREE@/src/cairo-polygon.c \ - @CAIRO_TREE@/src/cairo-polygon-intersect.c \ - @CAIRO_TREE@/src/cairo-polygon-reduce.c \ - @CAIRO_TREE@/src/cairo-raster-source-pattern.c \ - @CAIRO_TREE@/src/cairo-recording-surface.c \ - @CAIRO_TREE@/src/cairo-rectangle.c \ - @CAIRO_TREE@/src/cairo-rectangular-scan-converter.c \ - @CAIRO_TREE@/src/cairo-region.c \ - @CAIRO_TREE@/src/cairo-rtree.c \ - @CAIRO_TREE@/src/cairo-scaled-font.c \ - @CAIRO_TREE@/src/cairo-shape-mask-compositor.c \ - @CAIRO_TREE@/src/cairo-slope.c \ - @CAIRO_TREE@/src/cairo-spans.c \ - @CAIRO_TREE@/src/cairo-spans-compositor.c \ - @CAIRO_TREE@/src/cairo-spline.c \ - @CAIRO_TREE@/src/cairo-stroke-dash.c \ - @CAIRO_TREE@/src/cairo-stroke-style.c \ - @CAIRO_TREE@/src/cairo-surface.c \ - @CAIRO_TREE@/src/cairo-surface-clipper.c \ - @CAIRO_TREE@/src/cairo-surface-fallback.c \ - @CAIRO_TREE@/src/cairo-surface-observer.c \ - @CAIRO_TREE@/src/cairo-surface-offset.c \ - @CAIRO_TREE@/src/cairo-surface-snapshot.c \ - @CAIRO_TREE@/src/cairo-surface-subsurface.c \ - @CAIRO_TREE@/src/cairo-surface-wrapper.c \ - @CAIRO_TREE@/src/cairo-time.c \ - @CAIRO_TREE@/src/cairo-tor-scan-converter.c \ - @CAIRO_TREE@/src/cairo-tor22-scan-converter.c \ - @CAIRO_TREE@/src/cairo-clip-tor-scan-converter.c \ - @CAIRO_TREE@/src/cairo-toy-font-face.c \ - @CAIRO_TREE@/src/cairo-traps.c \ - @CAIRO_TREE@/src/cairo-tristrip.c \ - @CAIRO_TREE@/src/cairo-traps-compositor.c \ - @CAIRO_TREE@/src/cairo-unicode.c \ - @CAIRO_TREE@/src/cairo-user-font.c \ - @CAIRO_TREE@/src/cairo-version.c \ - @CAIRO_TREE@/src/cairo-wideint.c - -if CAIRO_HAS_XLIB_SURFACE -libcairo_a_SOURCES += \ - @CAIRO_TREE@/src/cairo-xlib-display.c \ - @CAIRO_TREE@/src/cairo-xlib-core-compositor.c \ - @CAIRO_TREE@/src/cairo-xlib-fallback-compositor.c \ - @CAIRO_TREE@/src/cairo-xlib-render-compositor.c \ - @CAIRO_TREE@/src/cairo-xlib-screen.c \ - @CAIRO_TREE@/src/cairo-xlib-source.c \ - @CAIRO_TREE@/src/cairo-xlib-surface.c \ - @CAIRO_TREE@/src/cairo-xlib-surface-shm.c \ - @CAIRO_TREE@/src/cairo-xlib-visual.c \ - @CAIRO_TREE@/src/cairo-xlib-xcb-surface.c -endif CAIRO_HAS_XLIB_SURFACE - -if CAIRO_HAS_XLIB_XRENDER_SURFACE -libcairo_a_SOURCES += \ - @CAIRO_TREE@/src/cairo-xcb-connection.c \ - @CAIRO_TREE@/src/cairo-xcb-connection-core.c \ - @CAIRO_TREE@/src/cairo-xcb-connection-render.c \ - @CAIRO_TREE@/src/cairo-xcb-connection-shm.c \ - @CAIRO_TREE@/src/cairo-xcb-resources.c \ - @CAIRO_TREE@/src/cairo-xcb-screen.c \ - @CAIRO_TREE@/src/cairo-xcb-shm.c \ - @CAIRO_TREE@/src/cairo-xcb-surface.c \ - @CAIRO_TREE@/src/cairo-xcb-surface-core.c \ - @CAIRO_TREE@/src/cairo-xcb-surface-render.c -endif CAIRO_HAS_XLIB_XRENDER_SURFACE - -if CAIRO_HAS_XCB_SURFACE -libcairo_a_SOURCES += \ - @CAIRO_TREE@/src/cairo-xcb-connection.c \ - @CAIRO_TREE@/src/cairo-xcb-connection-core.c \ - @CAIRO_TREE@/src/cairo-xcb-connection-render.c \ - @CAIRO_TREE@/src/cairo-xcb-connection-shm.c \ - @CAIRO_TREE@/src/cairo-xcb-screen.c \ - @CAIRO_TREE@/src/cairo-xcb-shm.c \ - @CAIRO_TREE@/src/cairo-xcb-surface.c \ - @CAIRO_TREE@/src/cairo-xcb-surface-core.c \ - @CAIRO_TREE@/src/cairo-xcb-surface-render.c -endif CAIRO_HAS_XCB_SURFACE - -if CAIRO_HAS_QUARTZ_SURFACE -libcairo_a_SOURCES += @CAIRO_TREE@/src/cairo-quartz-surface.c -endif CAIRO_HAS_QUARTZ_SURFACE - -if CAIRO_HAS_QUARTZ_FONT -libcairo_a_SOURCES += @CAIRO_TREE@/src/cairo-quartz-font.c -endif CAIRO_HAS_QUARTZ_FONT - -if CAIRO_HAS_QUARTZ_IMAGE_SURFACE -libcairo_a_SOURCES += @CAIRO_TREE@/src/cairo-quartz-image-surface.c -endif CAIRO_HAS_QUARTZ_IMAGE_SURFACE - -if CAIRO_HAS_OS2_SURFACE -libcairo_a_SOURCES += @CAIRO_TREE@/src/cairo-os2-surface.c -endif CAIRO_HAS_OS2_SURFACE - -if CAIRO_HAS_PNG_FUNCTIONS -libcairo_a_SOURCES += @CAIRO_TREE@/src/cairo-png.c -endif CAIRO_HAS_PNG_FUNCTIONS - -if CAIRO_HAS_GL_SURFACE -libcairo_a_SOURCES += \ - @CAIRO_TREE@/src/cairo-gl-composite.c \ - @CAIRO_TREE@/src/cairo-gl-device.c \ - @CAIRO_TREE@/src/cairo-gl-dispatch.c \ - @CAIRO_TREE@/src/cairo-gl-glyphs.c \ - @CAIRO_TREE@/src/cairo-gl-gradient.c \ - @CAIRO_TREE@/src/cairo-gl-info.c \ - @CAIRO_TREE@/src/cairo-gl-operand.c \ - @CAIRO_TREE@/src/cairo-gl-shaders.c \ - @CAIRO_TREE@/src/cairo-gl-msaa-compositor.c \ - @CAIRO_TREE@/src/cairo-gl-spans-compositor.c \ - @CAIRO_TREE@/src/cairo-gl-traps-compositor.c \ - @CAIRO_TREE@/src/cairo-gl-source.c \ - @CAIRO_TREE@/src/cairo-gl-surface.c -endif CAIRO_HAS_GL_SURFACE - -if CAIRO_HAS_SVG_SURFACE -libcairo_a_SOURCES += @CAIRO_TREE@/src/cairo-svg-surface.c -endif CAIRO_HAS_SVG_SURFACE - -$(libcairo_a_OBJECTS): config.force - -if build -check_PROGRAMS = cairotst -dist_check_SCRIPTS = cairo.test -TESTS = cairo.test -endif build -cairo.log: cairotst$(EXEEXT) - -cairotst_SOURCES = cairotst.c - -cairotst_CPPFLAGS = $(PIXMAN_INCLUDES) -Icairo - -cairotst_DEPENDENCIES = $(PIXMAN_DEPEND) - -LDADD = libcairo.a $(PIXMAN_LIBS) - -## Rebuild pixman -@PIXMAN_RULE@ - -# Reconfig -reconfig_prereq = $(PIXMAN_DEPEND) -DISTCLEANFILES = - -include $(srcdir)/../../am/reconfig.am - -# Rebuild -rebuild_prereq = -rebuild_target = all -CLEANFILES = - -include $(srcdir)/../../am/rebuild.am - diff --git a/source/libs/cairo/Makefile.in b/source/libs/cairo/Makefile.in deleted file mode 100644 index 2bc53c82d15e4f129e56b506088b99cc14582ff5..0000000000000000000000000000000000000000 --- a/source/libs/cairo/Makefile.in +++ /dev/null @@ -1,2376 +0,0 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2014 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -@CAIRO_HAS_XLIB_SURFACE_TRUE@am__append_1 = \ -@CAIRO_HAS_XLIB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xlib-display.c \ -@CAIRO_HAS_XLIB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xlib-core-compositor.c \ -@CAIRO_HAS_XLIB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xlib-fallback-compositor.c \ -@CAIRO_HAS_XLIB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xlib-render-compositor.c \ -@CAIRO_HAS_XLIB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xlib-screen.c \ -@CAIRO_HAS_XLIB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xlib-source.c \ -@CAIRO_HAS_XLIB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xlib-surface.c \ -@CAIRO_HAS_XLIB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xlib-surface-shm.c \ -@CAIRO_HAS_XLIB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xlib-visual.c \ -@CAIRO_HAS_XLIB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xlib-xcb-surface.c - -@CAIRO_HAS_XLIB_XRENDER_SURFACE_TRUE@am__append_2 = \ -@CAIRO_HAS_XLIB_XRENDER_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-connection.c \ -@CAIRO_HAS_XLIB_XRENDER_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-connection-core.c \ -@CAIRO_HAS_XLIB_XRENDER_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-connection-render.c \ -@CAIRO_HAS_XLIB_XRENDER_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-connection-shm.c \ -@CAIRO_HAS_XLIB_XRENDER_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-resources.c \ -@CAIRO_HAS_XLIB_XRENDER_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-screen.c \ -@CAIRO_HAS_XLIB_XRENDER_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-shm.c \ -@CAIRO_HAS_XLIB_XRENDER_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-surface.c \ -@CAIRO_HAS_XLIB_XRENDER_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-surface-core.c \ -@CAIRO_HAS_XLIB_XRENDER_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-surface-render.c - -@CAIRO_HAS_XCB_SURFACE_TRUE@am__append_3 = \ -@CAIRO_HAS_XCB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-connection.c \ -@CAIRO_HAS_XCB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-connection-core.c \ -@CAIRO_HAS_XCB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-connection-render.c \ -@CAIRO_HAS_XCB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-connection-shm.c \ -@CAIRO_HAS_XCB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-screen.c \ -@CAIRO_HAS_XCB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-shm.c \ -@CAIRO_HAS_XCB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-surface.c \ -@CAIRO_HAS_XCB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-surface-core.c \ -@CAIRO_HAS_XCB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-surface-render.c - -@CAIRO_HAS_QUARTZ_SURFACE_TRUE@am__append_4 = @CAIRO_TREE@/src/cairo-quartz-surface.c -@CAIRO_HAS_QUARTZ_FONT_TRUE@am__append_5 = @CAIRO_TREE@/src/cairo-quartz-font.c -@CAIRO_HAS_QUARTZ_IMAGE_SURFACE_TRUE@am__append_6 = @CAIRO_TREE@/src/cairo-quartz-image-surface.c -@CAIRO_HAS_OS2_SURFACE_TRUE@am__append_7 = @CAIRO_TREE@/src/cairo-os2-surface.c -@CAIRO_HAS_PNG_FUNCTIONS_TRUE@am__append_8 = @CAIRO_TREE@/src/cairo-png.c -@CAIRO_HAS_GL_SURFACE_TRUE@am__append_9 = \ -@CAIRO_HAS_GL_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-gl-composite.c \ -@CAIRO_HAS_GL_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-gl-device.c \ -@CAIRO_HAS_GL_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-gl-dispatch.c \ -@CAIRO_HAS_GL_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-gl-glyphs.c \ -@CAIRO_HAS_GL_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-gl-gradient.c \ -@CAIRO_HAS_GL_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-gl-info.c \ -@CAIRO_HAS_GL_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-gl-operand.c \ -@CAIRO_HAS_GL_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-gl-shaders.c \ -@CAIRO_HAS_GL_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-gl-msaa-compositor.c \ -@CAIRO_HAS_GL_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-gl-spans-compositor.c \ -@CAIRO_HAS_GL_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-gl-traps-compositor.c \ -@CAIRO_HAS_GL_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-gl-source.c \ -@CAIRO_HAS_GL_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-gl-surface.c - -@CAIRO_HAS_SVG_SURFACE_TRUE@am__append_10 = @CAIRO_TREE@/src/cairo-svg-surface.c -@build_TRUE@check_PROGRAMS = cairotst$(EXEEXT) -subdir = . -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/cairo-bigendian.m4 \ - $(top_srcdir)/m4/cairo-features.m4 $(top_srcdir)/m4/float.m4 \ - $(top_srcdir)/../../m4/kpse-common.m4 \ - $(top_srcdir)/../../m4/kpse-pixman-flags.m4 \ - $(top_srcdir)/../../m4/kpse-visibility.m4 \ - $(top_srcdir)/../../m4/kpse-warnings.m4 \ - $(top_srcdir)/version.ac $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ - $(am__configure_deps) $(am__dist_check_SCRIPTS_DIST) \ - $(am__DIST_COMMON) -am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ - configure.lineno config.status.lineno -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = config.h cairo-features.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -LIBRARIES = $(noinst_LIBRARIES) -AR = ar -ARFLAGS = cru -AM_V_AR = $(am__v_AR_@AM_V@) -am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) -am__v_AR_0 = @echo " AR " $@; -am__v_AR_1 = -libcairo_a_AR = $(AR) $(ARFLAGS) -libcairo_a_LIBADD = -am__libcairo_a_SOURCES_DIST = \ - @CAIRO_TREE@/src/cairo-analysis-surface.c \ - @CAIRO_TREE@/src/cairo-arc.c @CAIRO_TREE@/src/cairo-array.c \ - @CAIRO_TREE@/src/cairo-atomic.c \ - @CAIRO_TREE@/src/cairo-base64-stream.c \ - @CAIRO_TREE@/src/cairo-base85-stream.c \ - @CAIRO_TREE@/src/cairo-bentley-ottmann.c \ - @CAIRO_TREE@/src/cairo-bentley-ottmann-rectangular.c \ - @CAIRO_TREE@/src/cairo-bentley-ottmann-rectilinear.c \ - @CAIRO_TREE@/src/cairo-botor-scan-converter.c \ - @CAIRO_TREE@/src/cairo-boxes.c \ - @CAIRO_TREE@/src/cairo-boxes-intersect.c \ - @CAIRO_TREE@/src/cairo.c @CAIRO_TREE@/src/cairo-cache.c \ - @CAIRO_TREE@/src/cairo-clip.c \ - @CAIRO_TREE@/src/cairo-clip-boxes.c \ - @CAIRO_TREE@/src/cairo-clip-polygon.c \ - @CAIRO_TREE@/src/cairo-clip-region.c \ - @CAIRO_TREE@/src/cairo-clip-surface.c \ - @CAIRO_TREE@/src/cairo-color.c \ - @CAIRO_TREE@/src/cairo-composite-rectangles.c \ - @CAIRO_TREE@/src/cairo-compositor.c \ - @CAIRO_TREE@/src/cairo-contour.c \ - @CAIRO_TREE@/src/cairo-damage.c @CAIRO_TREE@/src/cairo-debug.c \ - @CAIRO_TREE@/src/cairo-default-context.c \ - @CAIRO_TREE@/src/cairo-device.c @CAIRO_TREE@/src/cairo-error.c \ - @CAIRO_TREE@/src/cairo-fallback-compositor.c \ - @CAIRO_TREE@/src/cairo-fixed.c \ - @CAIRO_TREE@/src/cairo-font-face.c \ - @CAIRO_TREE@/src/cairo-font-face-twin.c \ - @CAIRO_TREE@/src/cairo-font-face-twin-data.c \ - @CAIRO_TREE@/src/cairo-font-options.c \ - @CAIRO_TREE@/src/cairo-freelist.c \ - @CAIRO_TREE@/src/cairo-freed-pool.c \ - @CAIRO_TREE@/src/cairo-gstate.c @CAIRO_TREE@/src/cairo-hash.c \ - @CAIRO_TREE@/src/cairo-hull.c \ - @CAIRO_TREE@/src/cairo-image-compositor.c \ - @CAIRO_TREE@/src/cairo-image-info.c \ - @CAIRO_TREE@/src/cairo-image-source.c \ - @CAIRO_TREE@/src/cairo-image-surface.c \ - @CAIRO_TREE@/src/cairo-line.c @CAIRO_TREE@/src/cairo-lzw.c \ - @CAIRO_TREE@/src/cairo-matrix.c \ - @CAIRO_TREE@/src/cairo-mask-compositor.c \ - @CAIRO_TREE@/src/cairo-mesh-pattern-rasterizer.c \ - @CAIRO_TREE@/src/cairo-mempool.c @CAIRO_TREE@/src/cairo-misc.c \ - @CAIRO_TREE@/src/cairo-mono-scan-converter.c \ - @CAIRO_TREE@/src/cairo-mutex.c \ - @CAIRO_TREE@/src/cairo-no-compositor.c \ - @CAIRO_TREE@/src/cairo-observer.c \ - @CAIRO_TREE@/src/cairo-output-stream.c \ - @CAIRO_TREE@/src/cairo-paginated-surface.c \ - @CAIRO_TREE@/src/cairo-path-bounds.c \ - @CAIRO_TREE@/src/cairo-path.c \ - @CAIRO_TREE@/src/cairo-path-fill.c \ - @CAIRO_TREE@/src/cairo-path-fixed.c \ - @CAIRO_TREE@/src/cairo-path-in-fill.c \ - @CAIRO_TREE@/src/cairo-path-stroke.c \ - @CAIRO_TREE@/src/cairo-path-stroke-boxes.c \ - @CAIRO_TREE@/src/cairo-path-stroke-polygon.c \ - @CAIRO_TREE@/src/cairo-path-stroke-traps.c \ - @CAIRO_TREE@/src/cairo-path-stroke-tristrip.c \ - @CAIRO_TREE@/src/cairo-pattern.c @CAIRO_TREE@/src/cairo-pen.c \ - @CAIRO_TREE@/src/cairo-polygon.c \ - @CAIRO_TREE@/src/cairo-polygon-intersect.c \ - @CAIRO_TREE@/src/cairo-polygon-reduce.c \ - @CAIRO_TREE@/src/cairo-raster-source-pattern.c \ - @CAIRO_TREE@/src/cairo-recording-surface.c \ - @CAIRO_TREE@/src/cairo-rectangle.c \ - @CAIRO_TREE@/src/cairo-rectangular-scan-converter.c \ - @CAIRO_TREE@/src/cairo-region.c @CAIRO_TREE@/src/cairo-rtree.c \ - @CAIRO_TREE@/src/cairo-scaled-font.c \ - @CAIRO_TREE@/src/cairo-shape-mask-compositor.c \ - @CAIRO_TREE@/src/cairo-slope.c @CAIRO_TREE@/src/cairo-spans.c \ - @CAIRO_TREE@/src/cairo-spans-compositor.c \ - @CAIRO_TREE@/src/cairo-spline.c \ - @CAIRO_TREE@/src/cairo-stroke-dash.c \ - @CAIRO_TREE@/src/cairo-stroke-style.c \ - @CAIRO_TREE@/src/cairo-surface.c \ - @CAIRO_TREE@/src/cairo-surface-clipper.c \ - @CAIRO_TREE@/src/cairo-surface-fallback.c \ - @CAIRO_TREE@/src/cairo-surface-observer.c \ - @CAIRO_TREE@/src/cairo-surface-offset.c \ - @CAIRO_TREE@/src/cairo-surface-snapshot.c \ - @CAIRO_TREE@/src/cairo-surface-subsurface.c \ - @CAIRO_TREE@/src/cairo-surface-wrapper.c \ - @CAIRO_TREE@/src/cairo-time.c \ - @CAIRO_TREE@/src/cairo-tor-scan-converter.c \ - @CAIRO_TREE@/src/cairo-tor22-scan-converter.c \ - @CAIRO_TREE@/src/cairo-clip-tor-scan-converter.c \ - @CAIRO_TREE@/src/cairo-toy-font-face.c \ - @CAIRO_TREE@/src/cairo-traps.c \ - @CAIRO_TREE@/src/cairo-tristrip.c \ - @CAIRO_TREE@/src/cairo-traps-compositor.c \ - @CAIRO_TREE@/src/cairo-unicode.c \ - @CAIRO_TREE@/src/cairo-user-font.c \ - @CAIRO_TREE@/src/cairo-version.c \ - @CAIRO_TREE@/src/cairo-wideint.c \ - @CAIRO_TREE@/src/cairo-xlib-display.c \ - @CAIRO_TREE@/src/cairo-xlib-core-compositor.c \ - @CAIRO_TREE@/src/cairo-xlib-fallback-compositor.c \ - @CAIRO_TREE@/src/cairo-xlib-render-compositor.c \ - @CAIRO_TREE@/src/cairo-xlib-screen.c \ - @CAIRO_TREE@/src/cairo-xlib-source.c \ - @CAIRO_TREE@/src/cairo-xlib-surface.c \ - @CAIRO_TREE@/src/cairo-xlib-surface-shm.c \ - @CAIRO_TREE@/src/cairo-xlib-visual.c \ - @CAIRO_TREE@/src/cairo-xlib-xcb-surface.c \ - @CAIRO_TREE@/src/cairo-xcb-connection.c \ - @CAIRO_TREE@/src/cairo-xcb-connection-core.c \ - @CAIRO_TREE@/src/cairo-xcb-connection-render.c \ - @CAIRO_TREE@/src/cairo-xcb-connection-shm.c \ - @CAIRO_TREE@/src/cairo-xcb-resources.c \ - @CAIRO_TREE@/src/cairo-xcb-screen.c \ - @CAIRO_TREE@/src/cairo-xcb-shm.c \ - @CAIRO_TREE@/src/cairo-xcb-surface.c \ - @CAIRO_TREE@/src/cairo-xcb-surface-core.c \ - @CAIRO_TREE@/src/cairo-xcb-surface-render.c \ - @CAIRO_TREE@/src/cairo-quartz-surface.c \ - @CAIRO_TREE@/src/cairo-quartz-font.c \ - @CAIRO_TREE@/src/cairo-quartz-image-surface.c \ - @CAIRO_TREE@/src/cairo-os2-surface.c \ - @CAIRO_TREE@/src/cairo-png.c \ - @CAIRO_TREE@/src/cairo-gl-composite.c \ - @CAIRO_TREE@/src/cairo-gl-device.c \ - @CAIRO_TREE@/src/cairo-gl-dispatch.c \ - @CAIRO_TREE@/src/cairo-gl-glyphs.c \ - @CAIRO_TREE@/src/cairo-gl-gradient.c \ - @CAIRO_TREE@/src/cairo-gl-info.c \ - @CAIRO_TREE@/src/cairo-gl-operand.c \ - @CAIRO_TREE@/src/cairo-gl-shaders.c \ - @CAIRO_TREE@/src/cairo-gl-msaa-compositor.c \ - @CAIRO_TREE@/src/cairo-gl-spans-compositor.c \ - @CAIRO_TREE@/src/cairo-gl-traps-compositor.c \ - @CAIRO_TREE@/src/cairo-gl-source.c \ - @CAIRO_TREE@/src/cairo-gl-surface.c \ - @CAIRO_TREE@/src/cairo-svg-surface.c -am__dirstamp = $(am__leading_dot)dirstamp -@CAIRO_HAS_XLIB_SURFACE_TRUE@am__objects_1 = @CAIRO_TREE@/src/cairo-xlib-display.$(OBJEXT) \ -@CAIRO_HAS_XLIB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xlib-core-compositor.$(OBJEXT) \ -@CAIRO_HAS_XLIB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xlib-fallback-compositor.$(OBJEXT) \ -@CAIRO_HAS_XLIB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xlib-render-compositor.$(OBJEXT) \ -@CAIRO_HAS_XLIB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xlib-screen.$(OBJEXT) \ -@CAIRO_HAS_XLIB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xlib-source.$(OBJEXT) \ -@CAIRO_HAS_XLIB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xlib-surface.$(OBJEXT) \ -@CAIRO_HAS_XLIB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xlib-surface-shm.$(OBJEXT) \ -@CAIRO_HAS_XLIB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xlib-visual.$(OBJEXT) \ -@CAIRO_HAS_XLIB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xlib-xcb-surface.$(OBJEXT) -@CAIRO_HAS_XLIB_XRENDER_SURFACE_TRUE@am__objects_2 = @CAIRO_TREE@/src/cairo-xcb-connection.$(OBJEXT) \ -@CAIRO_HAS_XLIB_XRENDER_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-connection-core.$(OBJEXT) \ -@CAIRO_HAS_XLIB_XRENDER_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-connection-render.$(OBJEXT) \ -@CAIRO_HAS_XLIB_XRENDER_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-connection-shm.$(OBJEXT) \ -@CAIRO_HAS_XLIB_XRENDER_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-resources.$(OBJEXT) \ -@CAIRO_HAS_XLIB_XRENDER_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-screen.$(OBJEXT) \ -@CAIRO_HAS_XLIB_XRENDER_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-shm.$(OBJEXT) \ -@CAIRO_HAS_XLIB_XRENDER_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-surface.$(OBJEXT) \ -@CAIRO_HAS_XLIB_XRENDER_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-surface-core.$(OBJEXT) \ -@CAIRO_HAS_XLIB_XRENDER_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-surface-render.$(OBJEXT) -@CAIRO_HAS_XCB_SURFACE_TRUE@am__objects_3 = @CAIRO_TREE@/src/cairo-xcb-connection.$(OBJEXT) \ -@CAIRO_HAS_XCB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-connection-core.$(OBJEXT) \ -@CAIRO_HAS_XCB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-connection-render.$(OBJEXT) \ -@CAIRO_HAS_XCB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-connection-shm.$(OBJEXT) \ -@CAIRO_HAS_XCB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-screen.$(OBJEXT) \ -@CAIRO_HAS_XCB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-shm.$(OBJEXT) \ -@CAIRO_HAS_XCB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-surface.$(OBJEXT) \ -@CAIRO_HAS_XCB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-surface-core.$(OBJEXT) \ -@CAIRO_HAS_XCB_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-xcb-surface-render.$(OBJEXT) -@CAIRO_HAS_QUARTZ_SURFACE_TRUE@am__objects_4 = @CAIRO_TREE@/src/cairo-quartz-surface.$(OBJEXT) -@CAIRO_HAS_QUARTZ_FONT_TRUE@am__objects_5 = @CAIRO_TREE@/src/cairo-quartz-font.$(OBJEXT) -@CAIRO_HAS_QUARTZ_IMAGE_SURFACE_TRUE@am__objects_6 = @CAIRO_TREE@/src/cairo-quartz-image-surface.$(OBJEXT) -@CAIRO_HAS_OS2_SURFACE_TRUE@am__objects_7 = @CAIRO_TREE@/src/cairo-os2-surface.$(OBJEXT) -@CAIRO_HAS_PNG_FUNCTIONS_TRUE@am__objects_8 = @CAIRO_TREE@/src/cairo-png.$(OBJEXT) -@CAIRO_HAS_GL_SURFACE_TRUE@am__objects_9 = @CAIRO_TREE@/src/cairo-gl-composite.$(OBJEXT) \ -@CAIRO_HAS_GL_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-gl-device.$(OBJEXT) \ -@CAIRO_HAS_GL_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-gl-dispatch.$(OBJEXT) \ -@CAIRO_HAS_GL_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-gl-glyphs.$(OBJEXT) \ -@CAIRO_HAS_GL_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-gl-gradient.$(OBJEXT) \ -@CAIRO_HAS_GL_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-gl-info.$(OBJEXT) \ -@CAIRO_HAS_GL_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-gl-operand.$(OBJEXT) \ -@CAIRO_HAS_GL_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-gl-shaders.$(OBJEXT) \ -@CAIRO_HAS_GL_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-gl-msaa-compositor.$(OBJEXT) \ -@CAIRO_HAS_GL_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-gl-spans-compositor.$(OBJEXT) \ -@CAIRO_HAS_GL_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-gl-traps-compositor.$(OBJEXT) \ -@CAIRO_HAS_GL_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-gl-source.$(OBJEXT) \ -@CAIRO_HAS_GL_SURFACE_TRUE@ @CAIRO_TREE@/src/cairo-gl-surface.$(OBJEXT) -@CAIRO_HAS_SVG_SURFACE_TRUE@am__objects_10 = @CAIRO_TREE@/src/cairo-svg-surface.$(OBJEXT) -am_libcairo_a_OBJECTS = \ - @CAIRO_TREE@/src/cairo-analysis-surface.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-arc.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-array.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-atomic.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-base64-stream.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-base85-stream.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-bentley-ottmann.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-bentley-ottmann-rectangular.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-bentley-ottmann-rectilinear.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-botor-scan-converter.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-boxes.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-boxes-intersect.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-cache.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-clip.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-clip-boxes.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-clip-polygon.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-clip-region.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-clip-surface.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-color.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-composite-rectangles.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-compositor.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-contour.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-damage.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-debug.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-default-context.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-device.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-error.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-fallback-compositor.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-fixed.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-font-face.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-font-face-twin.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-font-face-twin-data.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-font-options.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-freelist.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-freed-pool.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-gstate.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-hash.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-hull.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-image-compositor.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-image-info.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-image-source.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-image-surface.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-line.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-lzw.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-matrix.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-mask-compositor.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-mesh-pattern-rasterizer.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-mempool.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-misc.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-mono-scan-converter.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-mutex.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-no-compositor.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-observer.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-output-stream.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-paginated-surface.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-path-bounds.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-path.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-path-fill.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-path-fixed.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-path-in-fill.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-path-stroke.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-path-stroke-boxes.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-path-stroke-polygon.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-path-stroke-traps.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-path-stroke-tristrip.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-pattern.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-pen.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-polygon.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-polygon-intersect.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-polygon-reduce.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-raster-source-pattern.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-recording-surface.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-rectangle.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-rectangular-scan-converter.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-region.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-rtree.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-scaled-font.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-shape-mask-compositor.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-slope.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-spans.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-spans-compositor.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-spline.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-stroke-dash.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-stroke-style.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-surface.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-surface-clipper.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-surface-fallback.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-surface-observer.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-surface-offset.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-surface-snapshot.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-surface-subsurface.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-surface-wrapper.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-time.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-tor-scan-converter.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-tor22-scan-converter.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-clip-tor-scan-converter.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-toy-font-face.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-traps.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-tristrip.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-traps-compositor.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-unicode.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-user-font.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-version.$(OBJEXT) \ - @CAIRO_TREE@/src/cairo-wideint.$(OBJEXT) $(am__objects_1) \ - $(am__objects_2) $(am__objects_3) $(am__objects_4) \ - $(am__objects_5) $(am__objects_6) $(am__objects_7) \ - $(am__objects_8) $(am__objects_9) $(am__objects_10) -libcairo_a_OBJECTS = $(am_libcairo_a_OBJECTS) -am_cairotst_OBJECTS = cairotst-cairotst.$(OBJEXT) -cairotst_OBJECTS = $(am_cairotst_OBJECTS) -cairotst_LDADD = $(LDADD) -am__DEPENDENCIES_1 = -am__dist_check_SCRIPTS_DIST = cairo.test -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -depcomp = $(SHELL) $(top_srcdir)/../../build-aux/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(libcairo_a_SOURCES) $(cairotst_SOURCES) -DIST_SOURCES = $(am__libcairo_a_SOURCES_DIST) $(cairotst_SOURCES) -RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ - ctags-recursive dvi-recursive html-recursive info-recursive \ - install-data-recursive install-dvi-recursive \ - install-exec-recursive install-html-recursive \ - install-info-recursive install-pdf-recursive \ - install-ps-recursive install-recursive installcheck-recursive \ - installdirs-recursive pdf-recursive ps-recursive \ - tags-recursive uninstall-recursive -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ - distclean-recursive maintainer-clean-recursive -am__recursive_targets = \ - $(RECURSIVE_TARGETS) \ - $(RECURSIVE_CLEAN_TARGETS) \ - $(am__extra_recursive_targets) -AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ - cscope check recheck distdir dist dist-all distcheck -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ - $(LISP)config.h.in cairo-features.h.in -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -CSCOPE = cscope -am__tty_colors_dummy = \ - mgn= red= grn= lgn= blu= brg= std=; \ - am__color_tests=no -am__tty_colors = { \ - $(am__tty_colors_dummy); \ - if test "X$(AM_COLOR_TESTS)" = Xno; then \ - am__color_tests=no; \ - elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ - am__color_tests=yes; \ - elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ - am__color_tests=yes; \ - fi; \ - if test $$am__color_tests = yes; then \ - red='[0;31m'; \ - grn='[0;32m'; \ - lgn='[1;32m'; \ - blu='[1;34m'; \ - mgn='[0;35m'; \ - brg='[1m'; \ - std='[m'; \ - fi; \ -} -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__recheck_rx = ^[ ]*:recheck:[ ]* -am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* -am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* -# A command that, given a newline-separated list of test names on the -# standard input, print the name of the tests that are to be re-run -# upon "make recheck". -am__list_recheck_tests = $(AWK) '{ \ - recheck = 1; \ - while ((rc = (getline line < ($$0 ".trs"))) != 0) \ - { \ - if (rc < 0) \ - { \ - if ((getline line2 < ($$0 ".log")) < 0) \ - recheck = 0; \ - break; \ - } \ - else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ - { \ - recheck = 0; \ - break; \ - } \ - else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ - { \ - break; \ - } \ - }; \ - if (recheck) \ - print $$0; \ - close ($$0 ".trs"); \ - close ($$0 ".log"); \ -}' -# A command that, given a newline-separated list of test names on the -# standard input, create the global log from their .trs and .log files. -am__create_global_log = $(AWK) ' \ -function fatal(msg) \ -{ \ - print "fatal: making $@: " msg | "cat >&2"; \ - exit 1; \ -} \ -function rst_section(header) \ -{ \ - print header; \ - len = length(header); \ - for (i = 1; i <= len; i = i + 1) \ - printf "="; \ - printf "\n\n"; \ -} \ -{ \ - copy_in_global_log = 1; \ - global_test_result = "RUN"; \ - while ((rc = (getline line < ($$0 ".trs"))) != 0) \ - { \ - if (rc < 0) \ - fatal("failed to read from " $$0 ".trs"); \ - if (line ~ /$(am__global_test_result_rx)/) \ - { \ - sub("$(am__global_test_result_rx)", "", line); \ - sub("[ ]*$$", "", line); \ - global_test_result = line; \ - } \ - else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ - copy_in_global_log = 0; \ - }; \ - if (copy_in_global_log) \ - { \ - rst_section(global_test_result ": " $$0); \ - while ((rc = (getline line < ($$0 ".log"))) != 0) \ - { \ - if (rc < 0) \ - fatal("failed to read from " $$0 ".log"); \ - print line; \ - }; \ - printf "\n"; \ - }; \ - close ($$0 ".trs"); \ - close ($$0 ".log"); \ -}' -# Restructured Text title. -am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } -# Solaris 10 'make', and several other traditional 'make' implementations, -# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it -# by disabling -e (using the XSI extension "set +e") if it's set. -am__sh_e_setup = case $$- in *e*) set +e;; esac -# Default flags passed to test drivers. -am__common_driver_flags = \ - --color-tests "$$am__color_tests" \ - --enable-hard-errors "$$am__enable_hard_errors" \ - --expect-failure "$$am__expect_failure" -# To be inserted before the command running the test. Creates the -# directory for the log if needed. Stores in $dir the directory -# containing $f, in $tst the test, in $log the log. Executes the -# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and -# passes TESTS_ENVIRONMENT. Set up options for the wrapper that -# will run the test scripts (or their associated LOG_COMPILER, if -# thy have one). -am__check_pre = \ -$(am__sh_e_setup); \ -$(am__vpath_adj_setup) $(am__vpath_adj) \ -$(am__tty_colors); \ -srcdir=$(srcdir); export srcdir; \ -case "$@" in \ - */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ - *) am__odir=.;; \ -esac; \ -test "x$$am__odir" = x"." || test -d "$$am__odir" \ - || $(MKDIR_P) "$$am__odir" || exit $$?; \ -if test -f "./$$f"; then dir=./; \ -elif test -f "$$f"; then dir=; \ -else dir="$(srcdir)/"; fi; \ -tst=$$dir$$f; log='$@'; \ -if test -n '$(DISABLE_HARD_ERRORS)'; then \ - am__enable_hard_errors=no; \ -else \ - am__enable_hard_errors=yes; \ -fi; \ -case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ - am__expect_failure=yes;; \ - *) \ - am__expect_failure=no;; \ -esac; \ -$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) -# A shell command to get the names of the tests scripts with any registered -# extension removed (i.e., equivalently, the names of the test logs, with -# the '.log' extension removed). The result is saved in the shell variable -# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, -# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", -# since that might cause problem with VPATH rewrites for suffix-less tests. -# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. -am__set_TESTS_bases = \ - bases='$(TEST_LOGS)'; \ - bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ - bases=`echo $$bases` -RECHECK_LOGS = $(TEST_LOGS) -TEST_SUITE_LOG = test-suite.log -TEST_EXTENSIONS = @EXEEXT@ .test -am__test_logs1 = $(TESTS:=.log) -am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) -TEST_LOGS = $(am__test_logs2:.test.log=.log) -TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/../../build-aux/test-driver -TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ - $(TEST_LOG_FLAGS) -am__set_b = \ - case '$@' in \ - */*) \ - case '$*' in \ - */*) b='$*';; \ - *) b=`echo '$@' | sed 's/\.log$$//'`; \ - esac;; \ - *) \ - b='$*';; \ - esac -DIST_SUBDIRS = $(SUBDIRS) -am__DIST_COMMON = $(srcdir)/../../am/dist_hook.am \ - $(srcdir)/../../am/rebuild.am $(srcdir)/../../am/reconfig.am \ - $(srcdir)/Makefile.in $(srcdir)/cairo-features.h.in \ - $(srcdir)/config.h.in $(top_srcdir)/../../build-aux/compile \ - $(top_srcdir)/../../build-aux/config.guess \ - $(top_srcdir)/../../build-aux/config.sub \ - $(top_srcdir)/../../build-aux/depcomp \ - $(top_srcdir)/../../build-aux/install-sh \ - $(top_srcdir)/../../build-aux/missing \ - $(top_srcdir)/../../build-aux/test-driver \ - ../../build-aux/compile ../../build-aux/config.guess \ - ../../build-aux/config.sub ../../build-aux/depcomp \ - ../../build-aux/install-sh ../../build-aux/ltmain.sh \ - ../../build-aux/missing ../../build-aux/texinfo.tex \ - ../../build-aux/ylwrap ChangeLog README -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -distdir = $(PACKAGE)-$(VERSION) -top_distdir = $(distdir) -am__remove_distdir = \ - if test -d "$(distdir)"; then \ - find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ - && rm -rf "$(distdir)" \ - || { sleep 5 && rm -rf "$(distdir)"; }; \ - else :; fi -am__post_remove_distdir = $(am__remove_distdir) -am__relativize = \ - dir0=`pwd`; \ - sed_first='s,^\([^/]*\)/.*$$,\1,'; \ - sed_rest='s,^[^/]*/*,,'; \ - sed_last='s,^.*/\([^/]*\)$$,\1,'; \ - sed_butlast='s,/*[^/]*$$,,'; \ - while test -n "$$dir1"; do \ - first=`echo "$$dir1" | sed -e "$$sed_first"`; \ - if test "$$first" != "."; then \ - if test "$$first" = ".."; then \ - dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ - dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ - else \ - first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ - if test "$$first2" = "$$first"; then \ - dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ - else \ - dir2="../$$dir2"; \ - fi; \ - dir0="$$dir0"/"$$first"; \ - fi; \ - fi; \ - dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ - done; \ - reldir="$$dir2" -DIST_ARCHIVES = $(distdir).tar.gz -GZIP_ENV = --best -DIST_TARGETS = dist-gzip -distuninstallcheck_listfiles = find . -type f -print -am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ - | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' -distcleancheck_listfiles = find . -type f -print -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CAIRO_ATTRIBUTE_FLAG = @CAIRO_ATTRIBUTE_FLAG@ -CAIRO_TREE = @CAIRO_TREE@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PIXMAN_DEPEND = @PIXMAN_DEPEND@ -PIXMAN_INCLUDES = @PIXMAN_INCLUDES@ -PIXMAN_LIBS = @PIXMAN_LIBS@ -PKG_CONFIG = @PKG_CONFIG@ -RANLIB = @RANLIB@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -VISIBILITY_CFLAGS = @VISIBILITY_CFLAGS@ -WARNING_CFLAGS = @WARNING_CFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -EXTRA_DIST = $(CAIRO_TREE) cairo-PATCHES -CAIRO_SRC = $(CAIRO_TREE)/src -NEVER_DIST = `find . $(NEVER_NAMES)` - -# Files not to be distributed -NEVER_NAMES = -name .svn $(NEVER_NAMES_SUB) -NEVER_NAMES_SUB = -o -name .deps -o -name .dirstamp -o -name '*.$(OBJEXT)' -NEVER_NAMES_LT = -o -name .libs -o -name '*.lo' -SUBDIRS = . cairo -AM_CPPFLAGS = -I$(top_srcdir)/$(CAIRO_SRC) $(PIXMAN_INCLUDES) -DCAIRO_NO_MUTEX -AM_CFLAGS = $(CAIRO_ATTRIBUTE_FLAG) $(VISIBILITY_CFLAGS) # $(WARNING_CFLAGS) -noinst_LIBRARIES = libcairo.a -libcairo_a_SOURCES = @CAIRO_TREE@/src/cairo-analysis-surface.c \ - @CAIRO_TREE@/src/cairo-arc.c @CAIRO_TREE@/src/cairo-array.c \ - @CAIRO_TREE@/src/cairo-atomic.c \ - @CAIRO_TREE@/src/cairo-base64-stream.c \ - @CAIRO_TREE@/src/cairo-base85-stream.c \ - @CAIRO_TREE@/src/cairo-bentley-ottmann.c \ - @CAIRO_TREE@/src/cairo-bentley-ottmann-rectangular.c \ - @CAIRO_TREE@/src/cairo-bentley-ottmann-rectilinear.c \ - @CAIRO_TREE@/src/cairo-botor-scan-converter.c \ - @CAIRO_TREE@/src/cairo-boxes.c \ - @CAIRO_TREE@/src/cairo-boxes-intersect.c \ - @CAIRO_TREE@/src/cairo.c @CAIRO_TREE@/src/cairo-cache.c \ - @CAIRO_TREE@/src/cairo-clip.c \ - @CAIRO_TREE@/src/cairo-clip-boxes.c \ - @CAIRO_TREE@/src/cairo-clip-polygon.c \ - @CAIRO_TREE@/src/cairo-clip-region.c \ - @CAIRO_TREE@/src/cairo-clip-surface.c \ - @CAIRO_TREE@/src/cairo-color.c \ - @CAIRO_TREE@/src/cairo-composite-rectangles.c \ - @CAIRO_TREE@/src/cairo-compositor.c \ - @CAIRO_TREE@/src/cairo-contour.c \ - @CAIRO_TREE@/src/cairo-damage.c @CAIRO_TREE@/src/cairo-debug.c \ - @CAIRO_TREE@/src/cairo-default-context.c \ - @CAIRO_TREE@/src/cairo-device.c @CAIRO_TREE@/src/cairo-error.c \ - @CAIRO_TREE@/src/cairo-fallback-compositor.c \ - @CAIRO_TREE@/src/cairo-fixed.c \ - @CAIRO_TREE@/src/cairo-font-face.c \ - @CAIRO_TREE@/src/cairo-font-face-twin.c \ - @CAIRO_TREE@/src/cairo-font-face-twin-data.c \ - @CAIRO_TREE@/src/cairo-font-options.c \ - @CAIRO_TREE@/src/cairo-freelist.c \ - @CAIRO_TREE@/src/cairo-freed-pool.c \ - @CAIRO_TREE@/src/cairo-gstate.c @CAIRO_TREE@/src/cairo-hash.c \ - @CAIRO_TREE@/src/cairo-hull.c \ - @CAIRO_TREE@/src/cairo-image-compositor.c \ - @CAIRO_TREE@/src/cairo-image-info.c \ - @CAIRO_TREE@/src/cairo-image-source.c \ - @CAIRO_TREE@/src/cairo-image-surface.c \ - @CAIRO_TREE@/src/cairo-line.c @CAIRO_TREE@/src/cairo-lzw.c \ - @CAIRO_TREE@/src/cairo-matrix.c \ - @CAIRO_TREE@/src/cairo-mask-compositor.c \ - @CAIRO_TREE@/src/cairo-mesh-pattern-rasterizer.c \ - @CAIRO_TREE@/src/cairo-mempool.c @CAIRO_TREE@/src/cairo-misc.c \ - @CAIRO_TREE@/src/cairo-mono-scan-converter.c \ - @CAIRO_TREE@/src/cairo-mutex.c \ - @CAIRO_TREE@/src/cairo-no-compositor.c \ - @CAIRO_TREE@/src/cairo-observer.c \ - @CAIRO_TREE@/src/cairo-output-stream.c \ - @CAIRO_TREE@/src/cairo-paginated-surface.c \ - @CAIRO_TREE@/src/cairo-path-bounds.c \ - @CAIRO_TREE@/src/cairo-path.c \ - @CAIRO_TREE@/src/cairo-path-fill.c \ - @CAIRO_TREE@/src/cairo-path-fixed.c \ - @CAIRO_TREE@/src/cairo-path-in-fill.c \ - @CAIRO_TREE@/src/cairo-path-stroke.c \ - @CAIRO_TREE@/src/cairo-path-stroke-boxes.c \ - @CAIRO_TREE@/src/cairo-path-stroke-polygon.c \ - @CAIRO_TREE@/src/cairo-path-stroke-traps.c \ - @CAIRO_TREE@/src/cairo-path-stroke-tristrip.c \ - @CAIRO_TREE@/src/cairo-pattern.c @CAIRO_TREE@/src/cairo-pen.c \ - @CAIRO_TREE@/src/cairo-polygon.c \ - @CAIRO_TREE@/src/cairo-polygon-intersect.c \ - @CAIRO_TREE@/src/cairo-polygon-reduce.c \ - @CAIRO_TREE@/src/cairo-raster-source-pattern.c \ - @CAIRO_TREE@/src/cairo-recording-surface.c \ - @CAIRO_TREE@/src/cairo-rectangle.c \ - @CAIRO_TREE@/src/cairo-rectangular-scan-converter.c \ - @CAIRO_TREE@/src/cairo-region.c @CAIRO_TREE@/src/cairo-rtree.c \ - @CAIRO_TREE@/src/cairo-scaled-font.c \ - @CAIRO_TREE@/src/cairo-shape-mask-compositor.c \ - @CAIRO_TREE@/src/cairo-slope.c @CAIRO_TREE@/src/cairo-spans.c \ - @CAIRO_TREE@/src/cairo-spans-compositor.c \ - @CAIRO_TREE@/src/cairo-spline.c \ - @CAIRO_TREE@/src/cairo-stroke-dash.c \ - @CAIRO_TREE@/src/cairo-stroke-style.c \ - @CAIRO_TREE@/src/cairo-surface.c \ - @CAIRO_TREE@/src/cairo-surface-clipper.c \ - @CAIRO_TREE@/src/cairo-surface-fallback.c \ - @CAIRO_TREE@/src/cairo-surface-observer.c \ - @CAIRO_TREE@/src/cairo-surface-offset.c \ - @CAIRO_TREE@/src/cairo-surface-snapshot.c \ - @CAIRO_TREE@/src/cairo-surface-subsurface.c \ - @CAIRO_TREE@/src/cairo-surface-wrapper.c \ - @CAIRO_TREE@/src/cairo-time.c \ - @CAIRO_TREE@/src/cairo-tor-scan-converter.c \ - @CAIRO_TREE@/src/cairo-tor22-scan-converter.c \ - @CAIRO_TREE@/src/cairo-clip-tor-scan-converter.c \ - @CAIRO_TREE@/src/cairo-toy-font-face.c \ - @CAIRO_TREE@/src/cairo-traps.c \ - @CAIRO_TREE@/src/cairo-tristrip.c \ - @CAIRO_TREE@/src/cairo-traps-compositor.c \ - @CAIRO_TREE@/src/cairo-unicode.c \ - @CAIRO_TREE@/src/cairo-user-font.c \ - @CAIRO_TREE@/src/cairo-version.c \ - @CAIRO_TREE@/src/cairo-wideint.c $(am__append_1) \ - $(am__append_2) $(am__append_3) $(am__append_4) \ - $(am__append_5) $(am__append_6) $(am__append_7) \ - $(am__append_8) $(am__append_9) $(am__append_10) -@build_TRUE@dist_check_SCRIPTS = cairo.test -@build_TRUE@TESTS = cairo.test -cairotst_SOURCES = cairotst.c -cairotst_CPPFLAGS = $(PIXMAN_INCLUDES) -Icairo -cairotst_DEPENDENCIES = $(PIXMAN_DEPEND) -LDADD = libcairo.a $(PIXMAN_LIBS) - -# Reconfig -reconfig_prereq = $(PIXMAN_DEPEND) -DISTCLEANFILES = config.force - -# Rebuild -rebuild_prereq = -rebuild_target = all -CLEANFILES = rebuild.stamp -all: config.h cairo-features.h - $(MAKE) $(AM_MAKEFLAGS) all-recursive - -.SUFFIXES: -.SUFFIXES: .c .log .o .obj .test .test$(EXEEXT) .trs -am--refresh: Makefile - @: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/../../am/dist_hook.am $(srcdir)/../../am/reconfig.am $(srcdir)/../../am/rebuild.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ - $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - echo ' $(SHELL) ./config.status'; \ - $(SHELL) ./config.status;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ - esac; -$(srcdir)/../../am/dist_hook.am $(srcdir)/../../am/reconfig.am $(srcdir)/../../am/rebuild.am $(am__empty): - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - $(SHELL) ./config.status --recheck - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - $(am__cd) $(srcdir) && $(AUTOCONF) -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) -$(am__aclocal_m4_deps): - -config.h: stamp-h1 - @test -f $@ || rm -f stamp-h1 - @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 - -stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status - @rm -f stamp-h1 - cd $(top_builddir) && $(SHELL) ./config.status config.h -$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) - rm -f stamp-h1 - touch $@ - -cairo-features.h: stamp-h2 - @test -f $@ || rm -f stamp-h2 - @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h2 - -stamp-h2: $(srcdir)/cairo-features.h.in $(top_builddir)/config.status - @rm -f stamp-h2 - cd $(top_builddir) && $(SHELL) ./config.status cairo-features.h - -distclean-hdr: - -rm -f config.h stamp-h1 cairo-features.h stamp-h2 - -clean-noinstLIBRARIES: - -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) -@CAIRO_TREE@/src/$(am__dirstamp): - @$(MKDIR_P) @CAIRO_TREE@/src - @: > @CAIRO_TREE@/src/$(am__dirstamp) -@CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) @CAIRO_TREE@/src/$(DEPDIR) - @: > @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-analysis-surface.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-arc.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-array.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-atomic.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-base64-stream.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-base85-stream.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-bentley-ottmann.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-bentley-ottmann-rectangular.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-bentley-ottmann-rectilinear.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-botor-scan-converter.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-boxes.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-boxes-intersect.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo.$(OBJEXT): @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-cache.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-clip.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-clip-boxes.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-clip-polygon.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-clip-region.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-clip-surface.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-color.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-composite-rectangles.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-compositor.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-contour.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-damage.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-debug.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-default-context.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-device.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-error.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-fallback-compositor.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-fixed.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-font-face.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-font-face-twin.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-font-face-twin-data.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-font-options.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-freelist.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-freed-pool.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-gstate.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-hash.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-hull.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-image-compositor.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-image-info.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-image-source.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-image-surface.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-line.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-lzw.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-matrix.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-mask-compositor.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-mesh-pattern-rasterizer.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-mempool.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-misc.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-mono-scan-converter.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-mutex.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-no-compositor.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-observer.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-output-stream.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-paginated-surface.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-path-bounds.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-path.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-path-fill.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-path-fixed.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-path-in-fill.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-path-stroke.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-path-stroke-boxes.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-path-stroke-polygon.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-path-stroke-traps.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-path-stroke-tristrip.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-pattern.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-pen.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-polygon.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-polygon-intersect.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-polygon-reduce.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-raster-source-pattern.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-recording-surface.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-rectangle.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-rectangular-scan-converter.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-region.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-rtree.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-scaled-font.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-shape-mask-compositor.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-slope.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-spans.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-spans-compositor.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-spline.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-stroke-dash.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-stroke-style.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-surface.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-surface-clipper.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-surface-fallback.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-surface-observer.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-surface-offset.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-surface-snapshot.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-surface-subsurface.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-surface-wrapper.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-time.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-tor-scan-converter.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-tor22-scan-converter.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-clip-tor-scan-converter.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-toy-font-face.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-traps.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-tristrip.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-traps-compositor.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-unicode.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-user-font.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-version.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-wideint.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-xlib-display.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-xlib-core-compositor.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-xlib-fallback-compositor.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-xlib-render-compositor.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-xlib-screen.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-xlib-source.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-xlib-surface.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-xlib-surface-shm.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-xlib-visual.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-xlib-xcb-surface.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-xcb-connection.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-xcb-connection-core.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-xcb-connection-render.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-xcb-connection-shm.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-xcb-resources.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-xcb-screen.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-xcb-shm.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-xcb-surface.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-xcb-surface-core.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-xcb-surface-render.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-quartz-surface.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-quartz-font.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-quartz-image-surface.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-os2-surface.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-png.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-gl-composite.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-gl-device.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-gl-dispatch.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-gl-glyphs.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-gl-gradient.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-gl-info.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-gl-operand.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-gl-shaders.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-gl-msaa-compositor.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-gl-spans-compositor.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-gl-traps-compositor.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-gl-source.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-gl-surface.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) -@CAIRO_TREE@/src/cairo-svg-surface.$(OBJEXT): \ - @CAIRO_TREE@/src/$(am__dirstamp) \ - @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) - -libcairo.a: $(libcairo_a_OBJECTS) $(libcairo_a_DEPENDENCIES) $(EXTRA_libcairo_a_DEPENDENCIES) - $(AM_V_at)-rm -f libcairo.a - $(AM_V_AR)$(libcairo_a_AR) libcairo.a $(libcairo_a_OBJECTS) $(libcairo_a_LIBADD) - $(AM_V_at)$(RANLIB) libcairo.a - -clean-checkPROGRAMS: - -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS) - -cairotst$(EXEEXT): $(cairotst_OBJECTS) $(cairotst_DEPENDENCIES) $(EXTRA_cairotst_DEPENDENCIES) - @rm -f cairotst$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(cairotst_OBJECTS) $(cairotst_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -rm -f @CAIRO_TREE@/src/*.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cairotst-cairotst.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-analysis-surface.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-arc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-array.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-atomic.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-base64-stream.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-base85-stream.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-bentley-ottmann-rectangular.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-bentley-ottmann-rectilinear.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-bentley-ottmann.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-botor-scan-converter.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-boxes-intersect.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-boxes.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-cache.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-clip-boxes.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-clip-polygon.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-clip-region.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-clip-surface.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-clip-tor-scan-converter.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-clip.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-color.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-composite-rectangles.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-compositor.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-contour.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-damage.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-debug.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-default-context.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-device.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-error.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-fallback-compositor.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-fixed.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-font-face-twin-data.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-font-face-twin.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-font-face.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-font-options.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-freed-pool.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-freelist.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-gl-composite.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-gl-device.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-gl-dispatch.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-gl-glyphs.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-gl-gradient.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-gl-info.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-gl-msaa-compositor.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-gl-operand.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-gl-shaders.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-gl-source.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-gl-spans-compositor.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-gl-surface.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-gl-traps-compositor.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-gstate.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-hash.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-hull.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-image-compositor.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-image-info.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-image-source.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-image-surface.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-line.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-lzw.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-mask-compositor.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-matrix.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-mempool.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-mesh-pattern-rasterizer.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-misc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-mono-scan-converter.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-mutex.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-no-compositor.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-observer.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-os2-surface.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-output-stream.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-paginated-surface.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-path-bounds.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-path-fill.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-path-fixed.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-path-in-fill.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-path-stroke-boxes.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-path-stroke-polygon.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-path-stroke-traps.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-path-stroke-tristrip.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-path-stroke.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-path.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-pattern.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-pen.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-png.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-polygon-intersect.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-polygon-reduce.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-polygon.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-quartz-font.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-quartz-image-surface.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-quartz-surface.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-raster-source-pattern.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-recording-surface.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-rectangle.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-rectangular-scan-converter.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-region.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-rtree.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-scaled-font.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-shape-mask-compositor.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-slope.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-spans-compositor.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-spans.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-spline.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-stroke-dash.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-stroke-style.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-surface-clipper.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-surface-fallback.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-surface-observer.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-surface-offset.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-surface-snapshot.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-surface-subsurface.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-surface-wrapper.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-surface.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-svg-surface.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-time.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-tor-scan-converter.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-tor22-scan-converter.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-toy-font-face.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-traps-compositor.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-traps.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-tristrip.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-unicode.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-user-font.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-version.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-wideint.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-xcb-connection-core.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-xcb-connection-render.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-xcb-connection-shm.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-xcb-connection.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-xcb-resources.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-xcb-screen.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-xcb-shm.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-xcb-surface-core.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-xcb-surface-render.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-xcb-surface.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-xlib-core-compositor.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-xlib-display.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-xlib-fallback-compositor.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-xlib-render-compositor.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-xlib-screen.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-xlib-source.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-xlib-surface-shm.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-xlib-surface.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-xlib-visual.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo-xlib-xcb-surface.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@CAIRO_TREE@/src/$(DEPDIR)/cairo.Po@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -cairotst-cairotst.o: cairotst.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cairotst_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cairotst-cairotst.o -MD -MP -MF $(DEPDIR)/cairotst-cairotst.Tpo -c -o cairotst-cairotst.o `test -f 'cairotst.c' || echo '$(srcdir)/'`cairotst.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cairotst-cairotst.Tpo $(DEPDIR)/cairotst-cairotst.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cairotst.c' object='cairotst-cairotst.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cairotst_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cairotst-cairotst.o `test -f 'cairotst.c' || echo '$(srcdir)/'`cairotst.c - -cairotst-cairotst.obj: cairotst.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cairotst_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cairotst-cairotst.obj -MD -MP -MF $(DEPDIR)/cairotst-cairotst.Tpo -c -o cairotst-cairotst.obj `if test -f 'cairotst.c'; then $(CYGPATH_W) 'cairotst.c'; else $(CYGPATH_W) '$(srcdir)/cairotst.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/cairotst-cairotst.Tpo $(DEPDIR)/cairotst-cairotst.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cairotst.c' object='cairotst-cairotst.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cairotst_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cairotst-cairotst.obj `if test -f 'cairotst.c'; then $(CYGPATH_W) 'cairotst.c'; else $(CYGPATH_W) '$(srcdir)/cairotst.c'; fi` - -# This directory's subdirectories are mostly independent; you can cd -# into them and run 'make' without going through this Makefile. -# To change the values of 'make' variables: instead of editing Makefiles, -# (1) if the variable is set in 'config.status', edit 'config.status' -# (which will cause the Makefiles to be regenerated when you run 'make'); -# (2) otherwise, pass the desired values on the 'make' command line. -$(am__recursive_targets): - @fail=; \ - if $(am__make_keepgoing); then \ - failcom='fail=yes'; \ - else \ - failcom='exit 1'; \ - fi; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - for subdir in $$list; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ - fi; test -z "$$fail" - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-recursive -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ - include_option=--etags-include; \ - empty_fix=.; \ - else \ - include_option=--include; \ - empty_fix=; \ - fi; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test ! -f $$subdir/TAGS || \ - set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ - fi; \ - done; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-recursive - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscope: cscope.files - test ! -s cscope.files \ - || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) -clean-cscope: - -rm -f cscope.files -cscope.files: clean-cscope cscopelist -cscopelist: cscopelist-recursive - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -rm -f cscope.out cscope.in.out cscope.po.out cscope.files - -# Recover from deleted '.trs' file; this should ensure that -# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create -# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells -# to avoid problems with "make -n". -.log.trs: - rm -f $< $@ - $(MAKE) $(AM_MAKEFLAGS) $< - -# Leading 'am--fnord' is there to ensure the list of targets does not -# expand to empty, as could happen e.g. with make check TESTS=''. -am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) -am--force-recheck: - @: - -$(TEST_SUITE_LOG): $(TEST_LOGS) - @$(am__set_TESTS_bases); \ - am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ - redo_bases=`for i in $$bases; do \ - am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ - done`; \ - if test -n "$$redo_bases"; then \ - redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ - redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ - if $(am__make_dryrun); then :; else \ - rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ - fi; \ - fi; \ - if test -n "$$am__remaking_logs"; then \ - echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ - "recursion detected" >&2; \ - elif test -n "$$redo_logs"; then \ - am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ - fi; \ - if $(am__make_dryrun); then :; else \ - st=0; \ - errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ - for i in $$redo_bases; do \ - test -f $$i.trs && test -r $$i.trs \ - || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ - test -f $$i.log && test -r $$i.log \ - || { echo "$$errmsg $$i.log" >&2; st=1; }; \ - done; \ - test $$st -eq 0 || exit 1; \ - fi - @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ - ws='[ ]'; \ - results=`for b in $$bases; do echo $$b.trs; done`; \ - test -n "$$results" || results=/dev/null; \ - all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ - pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ - fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ - skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ - xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ - xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ - error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ - if test `expr $$fail + $$xpass + $$error` -eq 0; then \ - success=true; \ - else \ - success=false; \ - fi; \ - br='==================='; br=$$br$$br$$br$$br; \ - result_count () \ - { \ - if test x"$$1" = x"--maybe-color"; then \ - maybe_colorize=yes; \ - elif test x"$$1" = x"--no-color"; then \ - maybe_colorize=no; \ - else \ - echo "$@: invalid 'result_count' usage" >&2; exit 4; \ - fi; \ - shift; \ - desc=$$1 count=$$2; \ - if test $$maybe_colorize = yes && test $$count -gt 0; then \ - color_start=$$3 color_end=$$std; \ - else \ - color_start= color_end=; \ - fi; \ - echo "$${color_start}# $$desc $$count$${color_end}"; \ - }; \ - create_testsuite_report () \ - { \ - result_count $$1 "TOTAL:" $$all "$$brg"; \ - result_count $$1 "PASS: " $$pass "$$grn"; \ - result_count $$1 "SKIP: " $$skip "$$blu"; \ - result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ - result_count $$1 "FAIL: " $$fail "$$red"; \ - result_count $$1 "XPASS:" $$xpass "$$red"; \ - result_count $$1 "ERROR:" $$error "$$mgn"; \ - }; \ - { \ - echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ - $(am__rst_title); \ - create_testsuite_report --no-color; \ - echo; \ - echo ".. contents:: :depth: 2"; \ - echo; \ - for b in $$bases; do echo $$b; done \ - | $(am__create_global_log); \ - } >$(TEST_SUITE_LOG).tmp || exit 1; \ - mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ - if $$success; then \ - col="$$grn"; \ - else \ - col="$$red"; \ - test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ - fi; \ - echo "$${col}$$br$${std}"; \ - echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ - echo "$${col}$$br$${std}"; \ - create_testsuite_report --maybe-color; \ - echo "$$col$$br$$std"; \ - if $$success; then :; else \ - echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ - if test -n "$(PACKAGE_BUGREPORT)"; then \ - echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ - fi; \ - echo "$$col$$br$$std"; \ - fi; \ - $$success || exit 1 - -check-TESTS: - @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list - @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list - @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - @set +e; $(am__set_TESTS_bases); \ - log_list=`for i in $$bases; do echo $$i.log; done`; \ - trs_list=`for i in $$bases; do echo $$i.trs; done`; \ - log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ - $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ - exit $$?; -recheck: all $(check_PROGRAMS) $(dist_check_SCRIPTS) - @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - @set +e; $(am__set_TESTS_bases); \ - bases=`for i in $$bases; do echo $$i; done \ - | $(am__list_recheck_tests)` || exit 1; \ - log_list=`for i in $$bases; do echo $$i.log; done`; \ - log_list=`echo $$log_list`; \ - $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ - am__force_recheck=am--force-recheck \ - TEST_LOGS="$$log_list"; \ - exit $$? -.test.log: - @p='$<'; \ - $(am__set_b); \ - $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -@am__EXEEXT_TRUE@.test$(EXEEXT).log: -@am__EXEEXT_TRUE@ @p='$<'; \ -@am__EXEEXT_TRUE@ $(am__set_b); \ -@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ -@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ -@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ -@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) - -distdir: $(DISTFILES) - $(am__remove_distdir) - test -d "$(distdir)" || mkdir "$(distdir)" - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - $(am__make_dryrun) \ - || test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ - $(am__relativize); \ - new_distdir=$$reldir; \ - dir1=$$subdir; dir2="$(top_distdir)"; \ - $(am__relativize); \ - new_top_distdir=$$reldir; \ - echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ - echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ - ($(am__cd) $$subdir && \ - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$$new_top_distdir" \ - distdir="$$new_distdir" \ - am__remove_distdir=: \ - am__skip_length_check=: \ - am__skip_mode_fix=: \ - distdir) \ - || exit 1; \ - fi; \ - done - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$(top_distdir)" distdir="$(distdir)" \ - dist-hook - -test -n "$(am__skip_mode_fix)" \ - || find "$(distdir)" -type d ! -perm -755 \ - -exec chmod u+rwx,go+rx {} \; -o \ - ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ - || chmod -R a+r "$(distdir)" -dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__post_remove_distdir) - -dist-bzip2: distdir - tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 - $(am__post_remove_distdir) - -dist-lzip: distdir - tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz - $(am__post_remove_distdir) - -dist-xz: distdir - tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz - $(am__post_remove_distdir) - -dist-tarZ: distdir - @echo WARNING: "Support for distribution archives compressed with" \ - "legacy program 'compress' is deprecated." >&2 - @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__post_remove_distdir) - -dist-shar: distdir - @echo WARNING: "Support for shar distribution archives is" \ - "deprecated." >&2 - @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz - $(am__post_remove_distdir) - -dist-zip: distdir - -rm -f $(distdir).zip - zip -rq $(distdir).zip $(distdir) - $(am__post_remove_distdir) - -dist dist-all: - $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' - $(am__post_remove_distdir) - -# This target untars the dist file and tries a VPATH configuration. Then -# it guarantees that the distribution is self-contained by making another -# tarfile. -distcheck: dist - case '$(DIST_ARCHIVES)' in \ - *.tar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ - *.tar.bz2*) \ - bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.lz*) \ - lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ - *.tar.xz*) \ - xz -dc $(distdir).tar.xz | $(am__untar) ;;\ - *.tar.Z*) \ - uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ - *.shar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ - *.zip*) \ - unzip $(distdir).zip ;;\ - esac - chmod -R a-w $(distdir) - chmod u+w $(distdir) - mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst - chmod a-w $(distdir) - test -d $(distdir)/_build || exit 0; \ - dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ - && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ - && am__cwd=`pwd` \ - && $(am__cd) $(distdir)/_build/sub \ - && ../../configure \ - $(AM_DISTCHECK_CONFIGURE_FLAGS) \ - $(DISTCHECK_CONFIGURE_FLAGS) \ - --srcdir=../.. --prefix="$$dc_install_base" \ - && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) dvi \ - && $(MAKE) $(AM_MAKEFLAGS) check \ - && $(MAKE) $(AM_MAKEFLAGS) install \ - && $(MAKE) $(AM_MAKEFLAGS) installcheck \ - && $(MAKE) $(AM_MAKEFLAGS) uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ - distuninstallcheck \ - && chmod -R a-w "$$dc_install_base" \ - && ({ \ - (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ - distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ - } || { rm -rf "$$dc_destdir"; exit 1; }) \ - && rm -rf "$$dc_destdir" \ - && $(MAKE) $(AM_MAKEFLAGS) dist \ - && rm -rf $(DIST_ARCHIVES) \ - && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ - && cd "$$am__cwd" \ - || exit 1 - $(am__post_remove_distdir) - @(echo "$(distdir) archives ready for distribution: "; \ - list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ - sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' -distuninstallcheck: - @test -n '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: trying to run $@ with an empty' \ - '$$(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - $(am__cd) '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left after uninstall:" ; \ - if test -n "$(DESTDIR)"; then \ - echo " (check DESTDIR support)"; \ - fi ; \ - $(distuninstallcheck_listfiles) ; \ - exit 1; } >&2 -distcleancheck: distclean - @if test '$(srcdir)' = . ; then \ - echo "ERROR: distcleancheck can only run from a VPATH build" ; \ - exit 1 ; \ - fi - @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left in build directory after distclean:" ; \ - $(distcleancheck_listfiles) ; \ - exit 1; } >&2 -check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) \ - $(dist_check_SCRIPTS) - $(MAKE) $(AM_MAKEFLAGS) check-TESTS -check: check-recursive -all-am: Makefile $(LIBRARIES) config.h cairo-features.h -installdirs: installdirs-recursive -installdirs-am: -install: install-recursive -install-exec: install-exec-recursive -install-data: install-data-recursive -uninstall: uninstall-recursive - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-recursive -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) - -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) - -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - -clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f @CAIRO_TREE@/src/$(DEPDIR)/$(am__dirstamp) - -rm -f @CAIRO_TREE@/src/$(am__dirstamp) - -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-recursive - -clean-am: clean-checkPROGRAMS clean-generic clean-noinstLIBRARIES \ - mostlyclean-am - -distclean: distclean-recursive - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf ./$(DEPDIR) @CAIRO_TREE@/src/$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-hdr distclean-tags - -dvi: dvi-recursive - -dvi-am: - -html: html-recursive - -html-am: - -info: info-recursive - -info-am: - -install-data-am: - -install-dvi: install-dvi-recursive - -install-dvi-am: - -install-exec-am: - -install-html: install-html-recursive - -install-html-am: - -install-info: install-info-recursive - -install-info-am: - -install-man: - -install-pdf: install-pdf-recursive - -install-pdf-am: - -install-ps: install-ps-recursive - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-recursive - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf $(top_srcdir)/autom4te.cache - -rm -rf ./$(DEPDIR) @CAIRO_TREE@/src/$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-recursive - -mostlyclean-am: mostlyclean-compile mostlyclean-generic - -pdf: pdf-recursive - -pdf-am: - -ps: ps-recursive - -ps-am: - -uninstall-am: - -.MAKE: $(am__recursive_targets) all check-am install-am install-strip - -.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ - am--refresh check check-TESTS check-am clean \ - clean-checkPROGRAMS clean-cscope clean-generic \ - clean-noinstLIBRARIES cscope cscopelist-am ctags ctags-am dist \ - dist-all dist-bzip2 dist-gzip dist-hook dist-lzip dist-shar \ - dist-tarZ dist-xz dist-zip distcheck distclean \ - distclean-compile distclean-generic distclean-hdr \ - distclean-tags distcleancheck distdir distuninstallcheck dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs installdirs-am \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ - recheck tags tags-am uninstall uninstall-am - -.PRECIOUS: Makefile - -dist-hook: - cd "$(distdir)" && rm -rf $(NEVER_DIST) - -$(libcairo_a_OBJECTS): config.force -cairo.log: cairotst$(EXEEXT) - -@PIXMAN_RULE@ -config.force: $(reconfig_prereq) - @if test -f $@; then :; else \ - trap 'rm -rf reconfig.lock' 1 2 13 15; \ - if mkdir reconfig.lock 2>/dev/null; then \ - echo timestamp >$@; \ - $(SHELL) ./config.status --recheck; \ - rmdir reconfig.lock; \ - else \ - while test -d rebuild.lock && test -z "$$dry"; do sleep 1; done; \ - test -f $@; \ - fi; \ - fi -rebuild.stamp: $(rebuild_target) - echo timestamp >$@ - -.PHONY: rebuild -rebuild: $(rebuild_prereq) - @dry=; for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=*|--*);; \ - *n*) dry=:;; \ - esac; \ - done; \ - if test -f rebuild.stamp; then :; else \ - $$dry trap 'rm -rf rebuild.lock' 1 2 13 15; \ - if $$dry mkdir rebuild.lock 2>/dev/null; then \ - $(MAKE) $(AM_MAKEFLAGS) rebuild.stamp; \ - $$dry rmdir rebuild.lock; \ - else \ - while test -d rebuild.lock && test -z "$$dry"; do sleep 1; done; \ - fi; \ - $$dry test -f rebuild.stamp; exit $$?; \ - fi - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/source/libs/cairo/README b/source/libs/cairo/README deleted file mode 100644 index f4f61554b629207cf112625e644efe956f2f8c70..0000000000000000000000000000000000000000 --- a/source/libs/cairo/README +++ /dev/null @@ -1,15 +0,0 @@ - Building cairo-1.14.8 as part of the TL tree - ============================================ - -This directory libs/cairo/ uses a proxy Makefile.am to build the cairo -library 'libcairo' from the unmodified source tree in -libs/cairo/cairo-src/, bypassing the original build system. - -As far as applicable, the tests in libs/cairo/cairo-src/configure have -been translated into equivalent test in libs/cairo/configure.ac. - -============================= - -2012-11-10 Taco Hoekwater <taco@metatex.org> -2013-04-15 Peter Breitenlohner <peb@mppmu.mpg.de> -2016-12-09 Akira Kakuto <kakuto@fuk.kindai.ac.jp> diff --git a/source/libs/cairo/TLpatches/ChangeLog b/source/libs/cairo/TLpatches/ChangeLog deleted file mode 100644 index 6f5e722812f709e77f8af6192456d3cd6ef9254b..0000000000000000000000000000000000000000 --- a/source/libs/cairo/TLpatches/ChangeLog +++ /dev/null @@ -1,37 +0,0 @@ -2016-12-09 Akira Kakuto <kakuto@fuk.kindai.ac.jp> - - Import cairo-1.14.8. - -2015-12-28 Akira Kakuto <kakuto@fuk.kindai.ac.jp> - - Import cairo-1.14.6. - -2015-03-11 Peter Breitenlohner <peb@mppmu.mpg.de> - - Import cairo-1.14.2. - -2014-10-15 Peter Breitenlohner <peb@mppmu.mpg.de> - - Import cairo-1.14.0. - -2013-09-10 Peter Breitenlohner <peb@mppmu.mpg.de> - - Import cairo-1.12.16. - -2013-05-25 Peter Breitenlohner <peb@mppmu.mpg.de> - - Import cairo-1.12.14. - -2012-11-16 Peter Breitenlohner <peb@mppmu.mpg.de> - - Import cairo-1.12.8. - * patch-01-mingw (removed): Obsolete. - -2012-11-15 Peter Breitenlohner <peb@mppmu.mpg.de> - - Import cairo-1.10.2. - * patch-01-mingw (new): Build fix for MinGW. - -2012-11-10 Taco Hoekwater <taco@metatex.org> - - Import cairo-1.12.8. diff --git a/source/libs/cairo/TLpatches/TL-Changes b/source/libs/cairo/TLpatches/TL-Changes deleted file mode 100644 index 05c12b8a4ffec35d2a4db5a8dc1d9adcb50117ff..0000000000000000000000000000000000000000 --- a/source/libs/cairo/TLpatches/TL-Changes +++ /dev/null @@ -1,33 +0,0 @@ -Changes applied to the cairo-1.14.8/ tree as obtained from: - http://cairographics.org/releases/cairo-1.14.8.tar.xz - -Removed: - Makefile.in - ChangeLog* - aclocal.m4 - build/ar-lib - build/compile - build/config.guess - build/config.sub - build/depcomp - build/install-sh - build/libtool.m4 - build/ltmain.sh - build/ltoptions.m4 - build/ltsugar.m4 - build/ltversion.m4 - build/lt~obsolete.m4 - build/missing - build/test-driver - configure - src/Makefile.in - -Removed unused dirs: - boilerplate - doc - perf - src/drm - src/skia - src/win32 - test - util diff --git a/source/libs/cairo/ac/cairo.ac b/source/libs/cairo/ac/cairo.ac deleted file mode 100644 index 0b7eadee8ebf4ba89e16b7a5b49526bb0c1d3607..0000000000000000000000000000000000000000 --- a/source/libs/cairo/ac/cairo.ac +++ /dev/null @@ -1,9 +0,0 @@ -## libs/cairo/ac/cairo.ac: configure.ac fragment for the TeX Live subdirectory libs/cairo/ -dnl -dnl Copyright (C) 2012 Peter Breitenlohner <tex-live@tug.org> -dnl You may freely use, modify and/or distribute this file. -dnl -## basic check of system cairo -KPSE_TRY_LIB([cairo], - [#include <cairo.h>], - [const char *s = cairo_version_string();]) diff --git a/source/libs/cairo/ac/withenable.ac b/source/libs/cairo/ac/withenable.ac deleted file mode 100644 index 781d311a69552069c344d52bc65b34227bd4063b..0000000000000000000000000000000000000000 --- a/source/libs/cairo/ac/withenable.ac +++ /dev/null @@ -1,7 +0,0 @@ -## libs/cairo/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/cairo/ -dnl -dnl Copyright (C) 2012 Peter Breitenlohner <tex-live@tug.org> -dnl You may freely use, modify and/or distribute this file. -dnl -## configure options and TL libraries required for cairo -KPSE_WITH_LIB([cairo], [pixman]) diff --git a/source/libs/cairo/aclocal.m4 b/source/libs/cairo/aclocal.m4 deleted file mode 100644 index dd0c689297631adf62c05487a3ec7edb1e308b95..0000000000000000000000000000000000000000 --- a/source/libs/cairo/aclocal.m4 +++ /dev/null @@ -1,1195 +0,0 @@ -# generated automatically by aclocal 1.15 -*- Autoconf -*- - -# Copyright (C) 1996-2014 Free Software Foundation, Inc. - -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) -m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, -[m4_warning([this file was generated for autoconf 2.69. -You have another version of autoconf. It may work, but is not guaranteed to. -If you have problems, you may need to regenerate the build system entirely. -To do so, use the procedure documented by the package, typically 'autoreconf'.])]) - -# Copyright (C) 2002-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_AUTOMAKE_VERSION(VERSION) -# ---------------------------- -# Automake X.Y traces this macro to ensure aclocal.m4 has been -# generated from the m4 files accompanying Automake X.Y. -# (This private macro should not be called outside this file.) -AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.15' -dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to -dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.15], [], - [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl -]) - -# _AM_AUTOCONF_VERSION(VERSION) -# ----------------------------- -# aclocal traces this macro to find the Autoconf version. -# This is a private macro too. Using m4_define simplifies -# the logic in aclocal, which can simply ignore this definition. -m4_define([_AM_AUTOCONF_VERSION], []) - -# AM_SET_CURRENT_AUTOMAKE_VERSION -# ------------------------------- -# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. -# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. -AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.15])dnl -m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) - -# AM_AUX_DIR_EXPAND -*- Autoconf -*- - -# Copyright (C) 2001-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets -# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to -# '$srcdir', '$srcdir/..', or '$srcdir/../..'. -# -# Of course, Automake must honor this variable whenever it calls a -# tool from the auxiliary directory. The problem is that $srcdir (and -# therefore $ac_aux_dir as well) can be either absolute or relative, -# depending on how configure is run. This is pretty annoying, since -# it makes $ac_aux_dir quite unusable in subdirectories: in the top -# source directory, any form will work fine, but in subdirectories a -# relative path needs to be adjusted first. -# -# $ac_aux_dir/missing -# fails when called from a subdirectory if $ac_aux_dir is relative -# $top_srcdir/$ac_aux_dir/missing -# fails if $ac_aux_dir is absolute, -# fails when called from a subdirectory in a VPATH build with -# a relative $ac_aux_dir -# -# The reason of the latter failure is that $top_srcdir and $ac_aux_dir -# are both prefixed by $srcdir. In an in-source build this is usually -# harmless because $srcdir is '.', but things will broke when you -# start a VPATH build or use an absolute $srcdir. -# -# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, -# iff we strip the leading $srcdir from $ac_aux_dir. That would be: -# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` -# and then we would define $MISSING as -# MISSING="\${SHELL} $am_aux_dir/missing" -# This will work as long as MISSING is not called from configure, because -# unfortunately $(top_srcdir) has no meaning in configure. -# However there are other variables, like CC, which are often used in -# configure, and could therefore not use this "fixed" $ac_aux_dir. -# -# Another solution, used here, is to always expand $ac_aux_dir to an -# absolute PATH. The drawback is that using absolute paths prevent a -# configured tree to be moved without reconfiguration. - -AC_DEFUN([AM_AUX_DIR_EXPAND], -[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl -# Expand $ac_aux_dir to an absolute path. -am_aux_dir=`cd "$ac_aux_dir" && pwd` -]) - -# AM_CONDITIONAL -*- Autoconf -*- - -# Copyright (C) 1997-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_CONDITIONAL(NAME, SHELL-CONDITION) -# ------------------------------------- -# Define a conditional. -AC_DEFUN([AM_CONDITIONAL], -[AC_PREREQ([2.52])dnl - m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], - [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl -AC_SUBST([$1_TRUE])dnl -AC_SUBST([$1_FALSE])dnl -_AM_SUBST_NOTMAKE([$1_TRUE])dnl -_AM_SUBST_NOTMAKE([$1_FALSE])dnl -m4_define([_AM_COND_VALUE_$1], [$2])dnl -if $2; then - $1_TRUE= - $1_FALSE='#' -else - $1_TRUE='#' - $1_FALSE= -fi -AC_CONFIG_COMMANDS_PRE( -[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then - AC_MSG_ERROR([[conditional "$1" was never defined. -Usually this means the macro was only invoked conditionally.]]) -fi])]) - -# Copyright (C) 1999-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - - -# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be -# written in clear, in which case automake, when reading aclocal.m4, -# will think it sees a *use*, and therefore will trigger all it's -# C support machinery. Also note that it means that autoscan, seeing -# CC etc. in the Makefile, will ask for an AC_PROG_CC use... - - -# _AM_DEPENDENCIES(NAME) -# ---------------------- -# See how the compiler implements dependency checking. -# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". -# We try a few techniques and use that to set a single cache variable. -# -# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was -# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular -# dependency, and given that the user is not expected to run this macro, -# just rely on AC_PROG_CC. -AC_DEFUN([_AM_DEPENDENCIES], -[AC_REQUIRE([AM_SET_DEPDIR])dnl -AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl -AC_REQUIRE([AM_MAKE_INCLUDE])dnl -AC_REQUIRE([AM_DEP_TRACK])dnl - -m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], - [$1], [CXX], [depcc="$CXX" am_compiler_list=], - [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], - [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], - [$1], [UPC], [depcc="$UPC" am_compiler_list=], - [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], - [depcc="$$1" am_compiler_list=]) - -AC_CACHE_CHECK([dependency style of $depcc], - [am_cv_$1_dependencies_compiler_type], -[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named 'D' -- because '-MD' means "put the output - # in D". - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_$1_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` - fi - am__universal=false - m4_case([$1], [CC], - [case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac], - [CXX], - [case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac]) - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with - # Solaris 10 /bin/sh. - echo '/* dummy */' > sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with '-c' and '-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle '-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs. - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # After this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested. - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok '-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_$1_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_$1_dependencies_compiler_type=none -fi -]) -AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) -AM_CONDITIONAL([am__fastdep$1], [ - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) -]) - - -# AM_SET_DEPDIR -# ------------- -# Choose a directory name for dependency files. -# This macro is AC_REQUIREd in _AM_DEPENDENCIES. -AC_DEFUN([AM_SET_DEPDIR], -[AC_REQUIRE([AM_SET_LEADING_DOT])dnl -AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl -]) - - -# AM_DEP_TRACK -# ------------ -AC_DEFUN([AM_DEP_TRACK], -[AC_ARG_ENABLE([dependency-tracking], [dnl -AS_HELP_STRING( - [--enable-dependency-tracking], - [do not reject slow dependency extractors]) -AS_HELP_STRING( - [--disable-dependency-tracking], - [speeds up one-time build])]) -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' - am__nodep='_no' -fi -AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) -AC_SUBST([AMDEPBACKSLASH])dnl -_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl -AC_SUBST([am__nodep])dnl -_AM_SUBST_NOTMAKE([am__nodep])dnl -]) - -# Generate code to set up dependency tracking. -*- Autoconf -*- - -# Copyright (C) 1999-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - - -# _AM_OUTPUT_DEPENDENCY_COMMANDS -# ------------------------------ -AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], -[{ - # Older Autoconf quotes --file arguments for eval, but not when files - # are listed without --file. Let's play safe and only enable the eval - # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac - shift - for mf - do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`AS_DIRNAME("$mf")` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`AS_DIRNAME(["$file"])` - AS_MKDIR_P([$dirpart/$fdir]) - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done - done -} -])# _AM_OUTPUT_DEPENDENCY_COMMANDS - - -# AM_OUTPUT_DEPENDENCY_COMMANDS -# ----------------------------- -# This macro should only be invoked once -- use via AC_REQUIRE. -# -# This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each '.P' file that we will -# need in order to bootstrap the dependency handling code. -AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], -[AC_CONFIG_COMMANDS([depfiles], - [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], - [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) -]) - -# Do all the work for Automake. -*- Autoconf -*- - -# Copyright (C) 1996-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This macro actually does too much. Some checks are only needed if -# your package does certain things. But this isn't really a big deal. - -dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. -m4_define([AC_PROG_CC], -m4_defn([AC_PROG_CC]) -[_AM_PROG_CC_C_O -]) - -# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) -# AM_INIT_AUTOMAKE([OPTIONS]) -# ----------------------------------------------- -# The call with PACKAGE and VERSION arguments is the old style -# call (pre autoconf-2.50), which is being phased out. PACKAGE -# and VERSION should now be passed to AC_INIT and removed from -# the call to AM_INIT_AUTOMAKE. -# We support both call styles for the transition. After -# the next Automake release, Autoconf can make the AC_INIT -# arguments mandatory, and then we can depend on a new Autoconf -# release and drop the old call support. -AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.65])dnl -dnl Autoconf wants to disallow AM_ names. We explicitly allow -dnl the ones we care about. -m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl -AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl -AC_REQUIRE([AC_PROG_INSTALL])dnl -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi -AC_SUBST([CYGPATH_W]) - -# Define the identity of the package. -dnl Distinguish between old-style and new-style calls. -m4_ifval([$2], -[AC_DIAGNOSE([obsolete], - [$0: two- and three-arguments forms are deprecated.]) -m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl - AC_SUBST([PACKAGE], [$1])dnl - AC_SUBST([VERSION], [$2])], -[_AM_SET_OPTIONS([$1])dnl -dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. -m4_if( - m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), - [ok:ok],, - [m4_fatal([AC_INIT should be called with package and version arguments])])dnl - AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl - AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl - -_AM_IF_OPTION([no-define],, -[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) - AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl - -# Some tools Automake needs. -AC_REQUIRE([AM_SANITY_CHECK])dnl -AC_REQUIRE([AC_ARG_PROGRAM])dnl -AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) -AM_MISSING_PROG([AUTOCONF], [autoconf]) -AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) -AM_MISSING_PROG([AUTOHEADER], [autoheader]) -AM_MISSING_PROG([MAKEINFO], [makeinfo]) -AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl -AC_REQUIRE([AC_PROG_MKDIR_P])dnl -# For better backward compatibility. To be removed once Automake 1.9.x -# dies out for good. For more background, see: -# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> -# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> -AC_SUBST([mkdir_p], ['$(MKDIR_P)']) -# We need awk for the "check" target (and possibly the TAP driver). The -# system "awk" is bad on some platforms. -AC_REQUIRE([AC_PROG_AWK])dnl -AC_REQUIRE([AC_PROG_MAKE_SET])dnl -AC_REQUIRE([AM_SET_LEADING_DOT])dnl -_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], - [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], - [_AM_PROG_TAR([v7])])]) -_AM_IF_OPTION([no-dependencies],, -[AC_PROVIDE_IFELSE([AC_PROG_CC], - [_AM_DEPENDENCIES([CC])], - [m4_define([AC_PROG_CC], - m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_CXX], - [_AM_DEPENDENCIES([CXX])], - [m4_define([AC_PROG_CXX], - m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_OBJC], - [_AM_DEPENDENCIES([OBJC])], - [m4_define([AC_PROG_OBJC], - m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], - [_AM_DEPENDENCIES([OBJCXX])], - [m4_define([AC_PROG_OBJCXX], - m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl -]) -AC_REQUIRE([AM_SILENT_RULES])dnl -dnl The testsuite driver may need to know about EXEEXT, so add the -dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This -dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. -AC_CONFIG_COMMANDS_PRE(dnl -[m4_provide_if([_AM_COMPILER_EXEEXT], - [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl - -# POSIX will say in a future version that running "rm -f" with no argument -# is OK; and we want to be able to make that assumption in our Makefile -# recipes. So use an aggressive probe to check that the usage we want is -# actually supported "in the wild" to an acceptable degree. -# See automake bug#10828. -# To make any issue more visible, cause the running configure to be aborted -# by default if the 'rm' program in use doesn't match our expectations; the -# user can still override this though. -if rm -f && rm -fr && rm -rf; then : OK; else - cat >&2 <<'END' -Oops! - -Your 'rm' program seems unable to run without file operands specified -on the command line, even when the '-f' option is present. This is contrary -to the behaviour of most rm programs out there, and not conforming with -the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> - -Please tell bug-automake@gnu.org about your system, including the value -of your $PATH and any error possibly output before this message. This -can help us improve future automake versions. - -END - if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then - echo 'Configuration will proceed anyway, since you have set the' >&2 - echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 - echo >&2 - else - cat >&2 <<'END' -Aborting the configuration process, to ensure you take notice of the issue. - -You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: <http://www.gnu.org/software/coreutils/>. - -If you want to complete the configuration process using your problematic -'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM -to "yes", and re-run configure. - -END - AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) - fi -fi -dnl The trailing newline in this macro's definition is deliberate, for -dnl backward compatibility and to allow trailing 'dnl'-style comments -dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. -]) - -dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not -dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further -dnl mangled by Autoconf and run in a shell conditional statement. -m4_define([_AC_COMPILER_EXEEXT], -m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) - -# When config.status generates a header, we must update the stamp-h file. -# This file resides in the same directory as the config header -# that is generated. The stamp files are numbered to have different names. - -# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the -# loop where config.status creates the headers, so we can generate -# our stamp files there. -AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], -[# Compute $1's index in $config_headers. -_am_arg=$1 -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $_am_arg | $_am_arg:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) - -# Copyright (C) 2001-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_INSTALL_SH -# ------------------ -# Define $install_sh. -AC_DEFUN([AM_PROG_INSTALL_SH], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -if test x"${install_sh+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi -AC_SUBST([install_sh])]) - -# Copyright (C) 2003-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# Check whether the underlying file-system supports filenames -# with a leading dot. For instance MS-DOS doesn't. -AC_DEFUN([AM_SET_LEADING_DOT], -[rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null -AC_SUBST([am__leading_dot])]) - -# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- -# From Jim Meyering - -# Copyright (C) 1996-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_MAINTAINER_MODE([DEFAULT-MODE]) -# ---------------------------------- -# Control maintainer-specific portions of Makefiles. -# Default is to disable them, unless 'enable' is passed literally. -# For symmetry, 'disable' may be passed as well. Anyway, the user -# can override the default with the --enable/--disable switch. -AC_DEFUN([AM_MAINTAINER_MODE], -[m4_case(m4_default([$1], [disable]), - [enable], [m4_define([am_maintainer_other], [disable])], - [disable], [m4_define([am_maintainer_other], [enable])], - [m4_define([am_maintainer_other], [enable]) - m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) -AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) - dnl maintainer-mode's default is 'disable' unless 'enable' is passed - AC_ARG_ENABLE([maintainer-mode], - [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], - am_maintainer_other[ make rules and dependencies not useful - (and sometimes confusing) to the casual installer])], - [USE_MAINTAINER_MODE=$enableval], - [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) - AC_MSG_RESULT([$USE_MAINTAINER_MODE]) - AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) - MAINT=$MAINTAINER_MODE_TRUE - AC_SUBST([MAINT])dnl -] -) - -# Check to see how 'make' treats includes. -*- Autoconf -*- - -# Copyright (C) 2001-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_MAKE_INCLUDE() -# ----------------- -# Check to see how make treats includes. -AC_DEFUN([AM_MAKE_INCLUDE], -[am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo this is the am__doit target -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -AC_MSG_CHECKING([for style of include used by $am_make]) -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi -AC_SUBST([am__include]) -AC_SUBST([am__quote]) -AC_MSG_RESULT([$_am_result]) -rm -f confinc confmf -]) - -# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- - -# Copyright (C) 1997-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_MISSING_PROG(NAME, PROGRAM) -# ------------------------------ -AC_DEFUN([AM_MISSING_PROG], -[AC_REQUIRE([AM_MISSING_HAS_RUN]) -$1=${$1-"${am_missing_run}$2"} -AC_SUBST($1)]) - -# AM_MISSING_HAS_RUN -# ------------------ -# Define MISSING if not defined so far and test if it is modern enough. -# If it is, set am_missing_run to use it, otherwise, to nothing. -AC_DEFUN([AM_MISSING_HAS_RUN], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([missing])dnl -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac -fi -# Use eval to expand $SHELL -if eval "$MISSING --is-lightweight"; then - am_missing_run="$MISSING " -else - am_missing_run= - AC_MSG_WARN(['missing' script is too old or missing]) -fi -]) - -# Helper functions for option handling. -*- Autoconf -*- - -# Copyright (C) 2001-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_MANGLE_OPTION(NAME) -# ----------------------- -AC_DEFUN([_AM_MANGLE_OPTION], -[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) - -# _AM_SET_OPTION(NAME) -# -------------------- -# Set option NAME. Presently that only means defining a flag for this option. -AC_DEFUN([_AM_SET_OPTION], -[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) - -# _AM_SET_OPTIONS(OPTIONS) -# ------------------------ -# OPTIONS is a space-separated list of Automake options. -AC_DEFUN([_AM_SET_OPTIONS], -[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) - -# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) -# ------------------------------------------- -# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. -AC_DEFUN([_AM_IF_OPTION], -[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) - -# Copyright (C) 1999-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_PROG_CC_C_O -# --------------- -# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC -# to automatically call this. -AC_DEFUN([_AM_PROG_CC_C_O], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([compile])dnl -AC_LANG_PUSH([C])dnl -AC_CACHE_CHECK( - [whether $CC understands -c and -o together], - [am_cv_prog_cc_c_o], - [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) - # Make sure it works both with $CC and with simple cc. - # Following AC_PROG_CC_C_O, we do the test twice because some - # compilers refuse to overwrite an existing .o file with -o, - # though they will create one. - am_cv_prog_cc_c_o=yes - for am_i in 1 2; do - if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ - && test -f conftest2.$ac_objext; then - : OK - else - am_cv_prog_cc_c_o=no - break - fi - done - rm -f core conftest* - unset am_i]) -if test "$am_cv_prog_cc_c_o" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi -AC_LANG_POP([C])]) - -# For backward compatibility. -AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) - -# Copyright (C) 2001-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_RUN_LOG(COMMAND) -# ------------------- -# Run COMMAND, save the exit status in ac_status, and log it. -# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) -AC_DEFUN([AM_RUN_LOG], -[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD - ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - (exit $ac_status); }]) - -# Check to make sure that the build environment is sane. -*- Autoconf -*- - -# Copyright (C) 1996-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_SANITY_CHECK -# --------------- -AC_DEFUN([AM_SANITY_CHECK], -[AC_MSG_CHECKING([whether build environment is sane]) -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[[\\\"\#\$\&\'\`$am_lf]]*) - AC_MSG_ERROR([unsafe absolute working directory name]);; -esac -case $srcdir in - *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) - AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; -esac - -# Do 'set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken - alias in your environment]) - fi - if test "$[2]" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$[2]" = conftest.file - ) -then - # Ok. - : -else - AC_MSG_ERROR([newly created file is older than distributed files! -Check your system clock]) -fi -AC_MSG_RESULT([yes]) -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & - am_sleep_pid=$! -fi -AC_CONFIG_COMMANDS_PRE( - [AC_MSG_CHECKING([that generated files are newer than configure]) - if test -n "$am_sleep_pid"; then - # Hide warnings about reused PIDs. - wait $am_sleep_pid 2>/dev/null - fi - AC_MSG_RESULT([done])]) -rm -f conftest.file -]) - -# Copyright (C) 2009-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_SILENT_RULES([DEFAULT]) -# -------------------------- -# Enable less verbose build rules; with the default set to DEFAULT -# ("yes" being less verbose, "no" or empty being verbose). -AC_DEFUN([AM_SILENT_RULES], -[AC_ARG_ENABLE([silent-rules], [dnl -AS_HELP_STRING( - [--enable-silent-rules], - [less verbose build output (undo: "make V=1")]) -AS_HELP_STRING( - [--disable-silent-rules], - [verbose build output (undo: "make V=0")])dnl -]) -case $enable_silent_rules in @%:@ ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; -esac -dnl -dnl A few 'make' implementations (e.g., NonStop OS and NextStep) -dnl do not support nested variable expansions. -dnl See automake bug#9928 and bug#10237. -am_make=${MAKE-make} -AC_CACHE_CHECK([whether $am_make supports nested variables], - [am_cv_make_support_nested_variables], - [if AS_ECHO([['TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi]) -if test $am_cv_make_support_nested_variables = yes; then - dnl Using '$V' instead of '$(V)' breaks IRIX make. - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AC_SUBST([AM_V])dnl -AM_SUBST_NOTMAKE([AM_V])dnl -AC_SUBST([AM_DEFAULT_V])dnl -AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl -AC_SUBST([AM_DEFAULT_VERBOSITY])dnl -AM_BACKSLASH='\' -AC_SUBST([AM_BACKSLASH])dnl -_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl -]) - -# Copyright (C) 2001-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_INSTALL_STRIP -# --------------------- -# One issue with vendor 'install' (even GNU) is that you can't -# specify the program used to strip binaries. This is especially -# annoying in cross-compiling environments, where the build's strip -# is unlikely to handle the host's binaries. -# Fortunately install-sh will honor a STRIPPROG variable, so we -# always use install-sh in "make install-strip", and initialize -# STRIPPROG with the value of the STRIP variable (set by the user). -AC_DEFUN([AM_PROG_INSTALL_STRIP], -[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. -dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. -if test "$cross_compiling" != no; then - AC_CHECK_TOOL([STRIP], [strip], :) -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" -AC_SUBST([INSTALL_STRIP_PROGRAM])]) - -# Copyright (C) 2006-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_SUBST_NOTMAKE(VARIABLE) -# --------------------------- -# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. -# This macro is traced by Automake. -AC_DEFUN([_AM_SUBST_NOTMAKE]) - -# AM_SUBST_NOTMAKE(VARIABLE) -# -------------------------- -# Public sister of _AM_SUBST_NOTMAKE. -AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) - -# Check how to create a tarball. -*- Autoconf -*- - -# Copyright (C) 2004-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_PROG_TAR(FORMAT) -# -------------------- -# Check how to create a tarball in format FORMAT. -# FORMAT should be one of 'v7', 'ustar', or 'pax'. -# -# Substitute a variable $(am__tar) that is a command -# writing to stdout a FORMAT-tarball containing the directory -# $tardir. -# tardir=directory && $(am__tar) > result.tar -# -# Substitute a variable $(am__untar) that extract such -# a tarball read from stdin. -# $(am__untar) < result.tar -# -AC_DEFUN([_AM_PROG_TAR], -[# Always define AMTAR for backward compatibility. Yes, it's still used -# in the wild :-( We should find a proper way to deprecate it ... -AC_SUBST([AMTAR], ['$${TAR-tar}']) - -# We'll loop over all known methods to create a tar archive until one works. -_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' - -m4_if([$1], [v7], - [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], - - [m4_case([$1], - [ustar], - [# The POSIX 1988 'ustar' format is defined with fixed-size fields. - # There is notably a 21 bits limit for the UID and the GID. In fact, - # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 - # and bug#13588). - am_max_uid=2097151 # 2^21 - 1 - am_max_gid=$am_max_uid - # The $UID and $GID variables are not portable, so we need to resort - # to the POSIX-mandated id(1) utility. Errors in the 'id' calls - # below are definitely unexpected, so allow the users to see them - # (that is, avoid stderr redirection). - am_uid=`id -u || echo unknown` - am_gid=`id -g || echo unknown` - AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) - if test $am_uid -le $am_max_uid; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - _am_tools=none - fi - AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) - if test $am_gid -le $am_max_gid; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - _am_tools=none - fi], - - [pax], - [], - - [m4_fatal([Unknown tar format])]) - - AC_MSG_CHECKING([how to create a $1 tar archive]) - - # Go ahead even if we have the value already cached. We do so because we - # need to set the values for the 'am__tar' and 'am__untar' variables. - _am_tools=${am_cv_prog_tar_$1-$_am_tools} - - for _am_tool in $_am_tools; do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break - - # tar/untar a dummy directory, and stop if the command works. - rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) - rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar <conftest.tar]) - AM_RUN_LOG([cat conftest.dir/file]) - grep GrepMe conftest.dir/file >/dev/null 2>&1 && break - fi - done - rm -rf conftest.dir - - AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) - AC_MSG_RESULT([$am_cv_prog_tar_$1])]) - -AC_SUBST([am__tar]) -AC_SUBST([am__untar]) -]) # _AM_PROG_TAR - -m4_include([m4/cairo-bigendian.m4]) -m4_include([m4/cairo-features.m4]) -m4_include([m4/float.m4]) -m4_include([../../m4/kpse-common.m4]) -m4_include([../../m4/kpse-pixman-flags.m4]) -m4_include([../../m4/kpse-visibility.m4]) -m4_include([../../m4/kpse-warnings.m4]) diff --git a/source/libs/cairo/cairo-features.h.in b/source/libs/cairo/cairo-features.h.in deleted file mode 100644 index 6ee6aec48f94e6bb3c6b07fa16f625582742860f..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-features.h.in +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef CAIRO_FEATURES_H -#define CAIRO_FEATURES_H - -#undef CAIRO_HAS_FC_FONT -#undef CAIRO_HAS_FT_FONT -#undef CAIRO_HAS_QUARTZ_FONT -#undef CAIRO_HAS_USER_FONT -#undef CAIRO_HAS_WIN32_FONT - -#undef CAIRO_HAS_EGL_FUNCTIONS -#undef CAIRO_HAS_GLX_FUNCTIONS -#undef CAIRO_HAS_GOBJECT_FUNCTIONS -#undef CAIRO_HAS_PNG_FUNCTIONS -#undef CAIRO_HAS_WGL_FUNCTIONS -#undef CAIRO_HAS_WIN32_SURFACE -#undef CAIRO_HAS_XCB_SHM_FUNCTIONS - -#undef CAIRO_HAS_IMAGE_SURFACE -#undef CAIRO_HAS_MIME_SURFACE -#undef CAIRO_HAS_OBSERVER_SURFACE -#undef CAIRO_HAS_RECORDING_SURFACE -#undef CAIRO_HAS_PDF_SURFACE -#undef CAIRO_HAS_PS_SURFACE -#undef CAIRO_HAS_QUARTZ_SURFACE -#undef CAIRO_HAS_SCRIPT_SURFACE -#undef CAIRO_HAS_SVG_SURFACE -#undef CAIRO_HAS_WIN32_SURFACE -#undef CAIRO_HAS_XCB_SURFACE -#undef CAIRO_HAS_XLIB_SURFACE -#undef CAIRO_HAS_XLIB_XRENDER_SURFACE - -#endif diff --git a/source/libs/cairo/cairo-src/AUTHORS b/source/libs/cairo/cairo-src/AUTHORS deleted file mode 100644 index d85696fa81c665e8f0f43e9a8cc4545ae83fcf99..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/AUTHORS +++ /dev/null @@ -1,115 +0,0 @@ -Josh Aas <joshmoz@gmail.com> Memory leak fix for quartz backend -Daniel Amelang <dan@amelang.net> Many (magic) floating-point optimizations -Shawn T. Amundson <amundson@gtk.org> Build fix -Olivier Andrieu <oliv__a@users.sourceforge.net> PNG backend -Peter Dennis Bartok <peter@novonyx.com> Bug fix for clipping -Dave Beckett <dajobe@debian.org> Build fixes, Debian packaging -Kai-Uwe Behrmann <ku.b@gmx.de> SVG bug fixes -Christian Biesinger <cbiesinger@web.de> BeOS backend -Billy Biggs <vektor@dumbterm.net> Pixman code merge. Optimization. Fixes for subtle rendering bugs. -Hans Breuer <hans@breuer.org> win32 bug fixes, build fixes, and improvements -Brian Cameron <brian.cameron@sun.com> Flag bug in Sun's X server -Carlos Garcia Campos <carlosgc@gnome.org> libspectre integration into the test-suite -Andrea Canciani <ranma42@gmail.com> Bugs, quartz backend improvements and type 6/7 patterns. -Damien Carbery <damien.carbery@sun.com> Build fixes -Andrew Chant <andrew.chant@utoronto.ca> Adding const where needed -Steve Chaplin <stevech1097@yahoo.com.au> Bug fixes for PNG reading -Tomasz Cholewo <cholewo@ieee-cis.org> Bug fixes -Manu Cornet <manu@manucornet.net> SVG build fix -Frederic Crozat <fcrozat@mandriva.com> Fix test suite for OPD platforms (IA64 or PPC64) -Julien Danjou <julien@danjou.info> XCB fixes -Radek DoulÃk <rodo@novell.com> Bug report and test case -John Ehresman <jpe@wingide.com> Build fixes for win32 -John Ellson <ellson@research.att.com> First font/glyph extents functions -Michael Emmel <mike.emmel@gmail.com> DirectFB backend -Miklós Erdélyi <erdelyim@gmail.com> Fix typo leading to a crash -Behdad Esfahbod <behdad@behdad.org> Huge piles of bug fixes, improvements, and general maintenance -Gilles Espinasse <g.esp@free.fr> Font related fixes -Larry Ewing <lewing@novell.com> Test case for group-clip -Brian Ewins <Brian.Ewins@gmail.com> ATSUI maintenance (first success at making it really work) -Bertram Felgenhauer <int-e@gmx.de> Fixes for subtle arithmetic errors -Damian Frank <damian.frank@gmail.com> Build system improvements for win32 -Bdale Garbee <bdale@gag.com> Provided essential support for cairo achitecture sessions -Jens Granseuer <jensgr@gmx.net> Fixes to generate proper compiler flags -Laxmi Harikumar <laxmi.harikumar@digital.com> Build fix -J. Ali Harlow <ali@avrc.city.ac.uk> win32 backend updates -Bryce Harrington <bryce@osg.samsung.com> Test cases, bug/typo fixes -Mathias Hasselmann <mathias.hasselmann@gmx.de> Significant reduction of calls to malloc -Richard Henderson <rth@twiddle.net> "slim" macros for better shared libraries -James Henstridge <james@daa.com.au> Build fixes related to freetype -Graydon Hoare <graydon@redhat.com> Support for non-render X server, first real text support -Thomas Hunger <info@teh-web.de> Initial version of cairo_in_stroke/fill -Thomas Jaeger <ThJaeger@gmail.com> Extended repeat modes for X -Björn Lindqvist <bjourne@gmail.com> Performance test cases -Kristian Høgsberg <krh@redhat.com> PDF backend, PS backend with meta-surfaces -Amaury Jacquot <sxpert@esitcom.org> Documentation review, appplication testing -Adrian Johnson <ajohnson@redneon.com> PDF backend improvement -Michael Johnson <ahze@ahze.net> Bug fix for pre-C99 compilers -Jonathon Jongsma <jonathon.jongsma@gmail.com> Fix documentation typos -Øyvind KolÃ¥s <pippin@freedesktop.org> OpenVG backend, Bug fixes. Better default values. -Martin Kretzschmar <martink@gnome.org> Arithmetic fix for 64-bit architectures -Mathieu Lacage <Mathieu.Lacage@sophia.inria.fr> several bug/typo fixes -Dominic Lachowicz <domlachowicz@gmail.com> PDF conformance fix, fix image surface to zero out contents -Alexander Larsson <alexl@redhat.com> Profiling and performance fixes. -Sylvestre Ledru <sylvestre@mozilla.com> Static analysis fixes. -Tor Lillqvist <tml@novell.com> win32 build fixes, build scripts -Jinghua Luo <sunmoon1997@gmail.com> Add bitmap glyph transformation, many freetype and glitz fixes -Luke-Jr <luke-jr@utopios.org> Build fix for cross-compiling -Kjartan Maraas <kmaraas@gnome.org> Several fixes for sparse, lots of debug help for multi-thread bugs -Nis Martensen <nis.martensen@web.de> Bug fix for sub paths -Jordi Mas <jordi@ximian.com> Bug fix for cairo_show_text -Nicholas Miell <nmiell@gmail.com> Fixes for linking bugs on AMD64 -Eugeniy Meshcheryakov <eugen@debian.org> PS/PDF font subsetting improvements -Zakharov Mikhail <zmey20000@yahoo.com> Build fix for HP-UX -Christopher (Monty) Montgomery <xiphmont@gmail.com> Performnace fix (subimage_copy), multi-thread testing -Tim Mooney <enchanter@users.sourceforge.net> Fix test suite to compile with Solaris compiler -Jeff Muizelaar <jeff@infidigm.net> Patient, painful, pixman code merge. Many fixes for intricacies of dashing. -Yevgen Muntyan <muntyan@tamu.edu> win32 build fix -Ravi Nanjundappa <nravi.n@samsung.com> Static analysis fixes, test cases, skia backend update/fixes -Declan Naughton <piratepenguin@gmail.com> Fix documentation typos -Peter Nilsson <c99pnn@cs.umu.se> Glitz backend -Henning Noren <henning.noren.402@student.lu.se> Fix memory leak -Geoff Norton <gnorton@customerdna.com> Build fixes -Robert O'Callahan <rocallahan@novell.com> Const-correctness fixes, several new API functions for completeness (and to help mozilla) -Ian Osgood <iano@quirkster.com> XCB backend maintenance -Benjamin Otte <otte@gnome.org> Refinements to cairo/perf timing, OpenGL backend fixups, random fixes -Mike Owens <etc@filespanker.com> Bug fixes -Emmanuel Pacaud <emmanuel.pacaud@lapp.in2p3.fr> SVG backend -Keith Packard <keithp@keithp.com> Original concept, polygon tessellation, dashing, font metrics rewrite -Stuart Parmenter <pavlov@pavlov.net> Original GDI+ backend, win32 fixes -Alfred Peng <alfred.peng@sun.com> Fixes for Sun compilers and for a memory leak -Christof Petig <christof@petig-baender.de> Build fixes related to freetype -Joonas Pihlaja <jpihlaja@cc.helsinki.fi> Huge improvements to the tessellator performance -Mart Raudsepp <leio@dustbite.net> Build fixes -David Reveman <davidr@novell.com> New pattern API, glitz backend -Calum Robinson <calumr@mac.com> Quartz backend -Pavel Roskin <proski@gnu.org> Several cleanups to eliminate warnings -Tim Rowley <tim.rowley@gmail.com> Quartz/ATSUI fixes, X server workarounds, win32 glyph path support, test case to expose gradient regression -Soeren Sandmann <sandmann@daimi.au.dk> Lots of MMX love for pixman compositing -Uli Schlachter <psychon@znc.in> Some more XCB fixes -Torsten Schönfeld <kaffeetisch@gmx.de> Build fixes -Jamey Sharp <jamey@minilop.net> Surface/font backend virtualization, XCB backend -Jason Dorje Short <jdorje@users.sf.net> Build fixes and bug fixes -Jeff Smith <whydoubt@yahoo.com> Fixes for intricacies of stroking code -Travis Spencer <tspencer@cs.pdx.edu> XCB backend fix -Bill Spitzak <spitzak@d2.com> Build fix to find Xrender.h without xrender.pc, downscaling support -Zhe Su <james.su@gmail.com> Add support for fontconfig's embeddedbitmap option -Owen Taylor <otaylor@redhat.com> Font rewrite, documentation, win32 backend -Pierre Tardy <tardyp@gmail.com> EGL support and testing, OpenVG backend -Karl Tomlinson <karlt+@karlt.net> Optimisation and obscure bug fixes (mozilla) -Alp Toker <alp@atoker.com> Fix several code/comment typos -Malcolm Tredinnick <malcolm@commsecure.com.au> Documentation fixes -David Turner <david@freetype.org> Optimize gradient calculations -Kalle Vahlman <kalle.vahlman@gmail.com> Allow perf reports to be compared across different platforms -Sasha Vasko <sasha@aftercode.net> Build fix to compile without xlib backend -Vladimir Vukicevic <vladimir@pobox.com> Quartz backend rewrite, win32/quartz maintenance -Jonathan Watt <jwatt@jwatt.org> win32 fixes -Peter Weilbacher <pmw@avila.aip.de> OS/2 backend -Dan Williams <dcbw@redhat.com> Implemnt MMX function to help OLPC -Chris Wilson <chris@chris-wilson.co.uk> Large-scale robustness improvements, (warn_unsed_result and malloc failure injection) -Carl Worth <cworth@isi.edu> Original library, support for paths, images -Richard D. Worth <richard@theworths.org> Build fixes for cygwin -Kent Worsnop <kworsnop@accesswave.ca> Fix PDF dashing bug -Dave Yeo <daveryeo@telus.net> Build fix for win32 - -(please let us know if we have missed anyone) diff --git a/source/libs/cairo/cairo-src/BIBLIOGRAPHY b/source/libs/cairo/cairo-src/BIBLIOGRAPHY deleted file mode 100644 index 90a6cef205b8b58c1f28ef837f066c0d0f34c23d..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/BIBLIOGRAPHY +++ /dev/null @@ -1,109 +0,0 @@ -Here's an effort to document some of the academic work that was -referenced during the implementation of cairo. It is presented in the -context of operations as they would be performed by either -cairo_stroke() or cairo_fill(): - -Given a Bézier path, approximate it with line segments: - - The deCasteljau algorithm - "Outillages methodes calcul", P de Casteljau, technical - report, - Andre Citroen Automobiles SA, Paris, 1959 - - That technical report might be "hard" to find, but fortunately - this algorithm will be described in any reasonable textbook on - computational geometry. Two that have been recommended by - cairo contributors are: - - "Computational Geometry, Algorithms and Applications", M. de - Berg, M. van Kreveld, M. Overmars, M. Schwarzkopf; - Springer-Verlag, ISBN: 3-540-65620-0. - - "Computational Geometry in C (Second Edition)", Joseph - O'Rourke, Cambridge University Press, ISBN 0521640105. - -Then, if stroking, construct a polygonal representation of the pen -approximating a circle (if filling skip three steps): - - "Good approximation of circles by curvature-continuous Bezier - curves", Tor Dokken and Morten Daehlen, Computer Aided - Geometric Design 8 (1990) 22-41. - -Add points to that pen based on the initial/final path faces and take -the convex hull: - - Convex hull algorithm - - [Again, see your favorite computational geometry - textbook. Should cite the name of the algorithm cairo uses - here, if it has a name.] - -Now, "convolve" the "tracing" of the pen with the tracing of the path: - - "A Kinetic Framework for Computational Geometry", Leonidas - J. Guibas, Lyle Ramshaw, and Jorge Stolfi, Proceedings of the - 24th IEEE Annual Symposium on Foundations of Computer Science - (FOCS), November 1983, 100-111. - -The result of the convolution is a polygon that must be filled. A fill -operations begins here. We use a very conventional Bentley-Ottmann -pass for computing the intersections, informed by some hints on robust -implementation courtesy of John Hobby: - - John D. Hobby, Practical Segment Intersection with Finite - Precision Output, Computation Geometry Theory and - Applications, 13(4), 1999. - - http://cm.bell-labs.com/who/hobby/93_2-27.pdf - -Hobby's primary contribution in that paper is his "tolerance square" -algorithm for robustness against edges being "bent" due to restricting -intersection coordinates to the grid available by finite-precision -arithmetic. This is one algorithm we have not implemented yet. - -We use a data-structure called Skiplists in the our implementation -of Bentley-Ottmann: - - W. Pugh, Skip Lists: a Probabilistic Alternative to Balanced Trees, - Communications of the ACM, vol. 33, no. 6, pp.668-676, 1990. - - http://citeseer.ist.psu.edu/pugh90skip.html - -The random number generator used in our skip list implementation is a -very small generator by Hars and Petruska. The generator is based on -an invertable function on Z_{2^32} with full period and is described -in - - Hars L. and Petruska G., - ``Pseudorandom Recursions: Small and Fast Pseurodandom - Number Generators for Embedded Applications'', - Hindawi Publishing Corporation - EURASIP Journal on Embedded Systems - Volume 2007, Article ID 98417, 13 pages - doi:10.1155/2007/98417 - - http://www.hindawi.com/getarticle.aspx?doi=10.1155/2007/98417&e=cta - -From the result of the intersection-finding pass, we are currently -computing a tessellation of trapezoids, (the exact manner is -undergoing some work right now with some important speedup), but we -may want to rasterize directly from those edges at some point. - -Given the set of tessellated trapezoids, we currently execute a -straightforward, (and slow), point-sampled rasterization, (and -currently with a near-pessimal regular 15x17 grid). - -We've now computed a mask which gets fed along with the source and -destination into cairo's fundamental rendering equation. The most -basic form of this equation is: - - destination = (source IN mask) OP destination - -with the restriction that no part of the destination outside the -current clip region is affected. In this equation, IN refers to the -Porter-Duff "in" operation, while OP refers to a any user-selected -Porter-Duff operator: - - T. Porter & T. Duff, Compositing Digital Images Computer - Graphics Volume 18, Number 3 July 1984 pp 253-259 - - http://keithp.com/~keithp/porterduff/p253-porter.pdf diff --git a/source/libs/cairo/cairo-src/BUGS b/source/libs/cairo/cairo-src/BUGS deleted file mode 100644 index ef044046d3e8119ec878b0d3931488cc56ba7820..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/BUGS +++ /dev/null @@ -1,85 +0,0 @@ -If you find a bug in cairo we would love to hear about it. We're also -trying to make cairo better, and learning about the bugs that users -encounter is an essential part of that. So we really appreciate the -extra effort users put in to providing high-quality bug reports. - -There are two acceptable ways to report cairo bugs, and you can choose -which you prefer: - -1) Bugzilla bug tracking database: - - You can use the following web interface to report new bugs, follow - up on previous bug reports, and search for existing, known - bugs. Just use the "cairo" product: - - http://bugs.freedesktop.org - - It is necessary to go through a quick account creation process, - (with email address verification), in order to be able to report - new bugs in bugzilla. We apologize for any inconvenience that might - cause, and hope it won't prevent you from reporting bugs. - -2) Cairo mailing list: - - For people who cannot stand the bugzilla interface, you can just - send an email to cairo mailing list (cairo@cairographics.org). The - mailing list only allows posting from subscribers, so use the - following page for subscription instructions: - - http://cairographics.org/lists - - Again, we apologize for any inconvenience this subscription step - might cause, but we've found it necessary to require this in order - to enjoy spam-free discussions on the list. - - If you don't actually _want_ to be a subscriber to the mailing - list, but just want to be able to send a message, the easiest thing - to do is to go through the subscription process, and then use the - preferences page to disable message delivery to your address. - -Which of the above you use to report bugs depends on your own -preferences. Some people find just typing an email message much easier -than using the web-based forms on bugzilla. Others greatly prefer the -ability to check back on a specific bug entry in bugzilla without -having to ask on the mailing list if an issue has been resolved. - -Regardless of which method you use, here are some general tips that -will help you improve the quality of your bug report, (which will help -in getting the bug fixed sooner): - -1) Check to see if the bug has been reported already. It's pretty easy - to run a search or two against the cairo product in the - http://bugs.freedesktop.org bugzilla database. Another place to - look for known bugs is the cairo ROADMAP: - - http://cairographics.org/ROADMAP - - which shows a planned schedule of releases and which bug fixes are - being planned for each release. - -2) Provide an accurate description of the bug with detailed steps for - how we can reproduce the problem. - -3) If possible provide a minimal test case demonstrating the bug. A - great test case would be a minimal self-contained function in C or - python or whatever language you are using for cairo. The function - might accept nothing more than a cairo context, (cairo_t* in C). - -4) If you feel like being particularly helpful, you could craft this - minimal test case in the form necessary for cairo's test - suite. This isn't much more work than writing a minimal - function. Just look at the cairo/test/README file and imitate the - style of existing test cases. - - If you do submit a test case, be sure to include Copyright - information, (with the standard MIT licensing blurb if you want us - to include your test in the test case). Also, including a reference - image showing the expected result will be extremely useful. - -5) Finally, the best bug report also comes attached with a patch to - cairo to fix the bug. So send this too if you have it! Otherwise, - don't worry about it and we'll try to fix cairo when we can. - -Thanks, and have fun with cairo! - --Carl diff --git a/source/libs/cairo/cairo-src/CODING_STYLE b/source/libs/cairo/cairo-src/CODING_STYLE deleted file mode 100644 index 95ceac04d8472e8fd3040e1742dee39f5502e751..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/CODING_STYLE +++ /dev/null @@ -1,291 +0,0 @@ -Cairo coding style. - -This document is intended to be a short description of the preferred -coding style for the cairo source code. Good style requires good -taste, which means this can't all be reduced to automated rules, and -there are exceptions. - -We want the code to be easy to understand and maintain, and consistent -style plays an important part in that, even if some of the specific -details seem trivial. If nothing else, this document gives a place to -put consistent answers for issues that would otherwise be arbitrary. - -Most of the guidelines here are demonstrated by examples, (which means -this document is quicker to read than it might appear given its -length). Most of the examples are positive examples that you should -imitate. The few negative examples are clearly marked with a comment -of /* Yuck! */. Please don't submit code to cairo that looks like any -of these. - -Indentation ------------ -Each new level is indented 4 more spaces than the previous level: - - if (condition) - do_something (); - -This may be achieved with space characters or a combination of tab -characters and space characters. It may not be achieved with tab -characters exclusively (see below). - -Tab characters --------------- -The tab character must always be interpreted according to its -traditional meaning: - - Advance to the next column which is a multiple of 8. - -With this definition, even levels of indentation can be achieved with -a sequence of tab characters, while odd levels of indentation may -begin with a sequence of tab character but must end with 4 space -characters. - -Some programmers have been misled by certain text editors into -thinking that 4-space indentation can be achieved with tab characters -exclusively by changing the meaning of tab character to be "advance to -the next column which is a multiple of 4". Code formatted in this way, -making an assumption of a fictitious 4-character-tab will not be -accepted into cairo. - -The rationale here is that tabs are used in the code for lining things -up other than indentation, (see the Whitespace section below), and -changing the interpretation of tab from its traditional meaning will -break this alignment. - -Braces ------- -Most of the code in cairo uses bracing in the style of K&R: - - if (condition) { - do_this (); - do_that (); - } else { - do_the_other (); - } - -but some of the code uses an alternate style: - - if (condition) - { - do_this (); - do_that (); - } - else - { - do_the_other (); - } - -and that seems just fine. We won't lay down any strict rule on this -point, (though there should be some local consistency). If you came -here hoping to find some guidance, then use the first form above. - -If all of the substatements of an if statement are single statements, -the optional braces should not usually appear: - - if (condition) - do_this (); - else - do_that (); - -But the braces are mandatory when mixing single statement and compound -statements in the various clauses. For example, do not do this: - - if (condition) { - do_this (); - do_that (); - } else /* Yuck! */ - do_the_other (); - -And of course, there are exceptions for when the code just looks -better with the braces: - - if (condition) { - /* Note that we have to be careful here. */ - do_something_dangerous (with_care); - } - - if (condition && - other_condition && - yet_another) - { - do_something (); - } - -And note that this last example also shows a situation in which the -opening brace really needs to be on its own line. The following looks awful: - - if (condition && - other_condition && - yet_another) { /* Yuck! */ - do_something (); - } - -As we said above, legible code that is easy to understand and maintain -is the goal, not adherence to strict rules. - -Whitespace ----------- -Separate logically distinct chunks with a single newline. This -obviously applies between functions, but also applies within a -function or block and can even be used to good effect within a -structure definition: - - struct _cairo_gstate { - cairo_operator_t op; - - double tolerance; - - /* stroke style */ - double line_width; - cairo_line_cap_t line_cap; - cairo_line_join_t line_join; - double miter_limit; - - cairo_fill_rule_t fill_rule; - - double *dash; - int num_dashes; - double dash_offset; - - ... - } - -Use a single space before a left parenthesis, except where the -standard will not allow it, (eg. when defining a parameterized macro). - -Don't eliminate newlines just because things would still fit on one -line. This breaks the expected visual structure of the code making it -much harder to read and understand: - - if (condition) foo (); else bar (); /* Yuck! */ - -Do eliminate trailing whitespace (space or tab characters) on any -line. Also, avoid putting initial or final blank lines into any file, -and never use multiple blank lines instead of a single blank line. - -Do enable the default git pre-commit hook that detect trailing -whitespace for you and help you to avoid corrupting cairo's tree with -it. Do that as follows: - - chmod a+x .git/hooks/pre-commit - -You might also find the git-stripspace utility helpful which acts as a -filter to remove trailing whitespace as well as initial, final, and -duplicate blank lines. - -As a special case of the bracing and whitespace guidelines, function -definitions should always take the following form: - - void - my_function (argument) - { - do_my_things (); - } - -And function prototypes should similarly have the return type (and -associated specifiers and qualifiers) on a line above the function, so -that the function name is flush left. - -Break up long lines (> ~80 characters) and use whitespace to align -things nicely. For example the arguments in a long list to a function -call should all be aligned with each other: - - align_function_arguments (argument_the_first, - argument_the_second, - argument_the_third); - -And as a special rule, in a function prototype, (as well as in the -definition), whitespace should be inserted between the parameter types -and names so that the names are aligned: - - void - align_parameter_names_in_prototypes (const char *char_star_arg, - int int_arg, - double *double_star_arg, - double double_arg); - -Note that parameters with a * prefix are aligned one character to the -left so that the actual names are aligned. - -Managing nested blocks ----------------------- -Long blocks that are deeply nested make the code very hard to -read. Fortunately such blocks often indicate logically distinct chunks -of functionality that are begging to be split into their own -functions. Please listen to the blocks when they beg. - -In other cases, gratuitous nesting comes about because the primary -functionality gets buried in a nested block rather than living at the -primary level where it belongs. Consider the following: - - foo = malloc (sizeof (foo_t)); - if (foo) { /* Yuck! */ - ... - /* lots of code to initialize foo */ - ... - return SUCCESS; - } - return FAILURE; - -This kind of gratuitous nesting can be avoided by following a pattern -of handling exceptional cases early and returning: - - foo = malloc (sizeof (foo_t)); - if (foo == NULL) - return FAILURE; - - ... - /* lots of code to initialize foo */ - ... - return SUCCESS; - -The return statement is often the best thing to use in a pattern like -this. If it's not available due to additional nesting above which -require some cleanup after the current block, then consider splitting -the current block into a new function before using goto. - -Memory allocation ------------------ - -Because much of cairo's data consists of dynamically allocated arrays, -it's very easy to introduce integer overflow issues whenever malloc() -is called. Use the _cairo_malloc2(), _cairo_malloc3(), and -_cairo_malloc2_add1 macros to avoid these cases; these macros check -for overflow and will return NULL in that case. - - malloc (n * size) => _cairo_malloc_ab (n, size) - e.g. malloc (num_elts * sizeof(some_type)) => - _cairo_malloc2 (num_elts, sizeof(some_type)) - - malloc (a * b * size) => _cairo_malloc_abc (a, b, size) - e.g. malloc (width * height * 4) => - _cairo_malloc3 (width, height, 4) - - malloc (n * size + k) => _cairo_malloc_ab_plus_c (n, size, k) - e.g. malloc (num * sizeof(entry) + sizeof(header)) => - _cairo_malloc2k (num, sizeof(entry), sizeof(header)) - -In general, be wary of performing any arithmetic operations in an -argument to malloc. You should explicitly check for integer overflow -yourself in any more complex situations. - -Mode lines ----------- - -So given the rules above, what is the best way to simplify one's life as -a code monkey? Get your editor to do most of the tedious work of -beautifying your code! - -As a reward for reading this far, here are some mode lines for the more -popular editors: -/* - * vim:sw=4:sts=4:ts=8:tw=78:fo=tcroq:cindent:cino=\:0,(0 - * vim:isk=a-z,A-Z,48-57,_,.,-,> - */ - - -TODO ----- - -Write rules for common editors to use this style. Also cleanup/unify -the modelines in the source files. diff --git a/source/libs/cairo/cairo-src/COPYING b/source/libs/cairo/cairo-src/COPYING deleted file mode 100644 index f54969f1c9472aba9004394e46fa4355aa4d77a7..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/COPYING +++ /dev/null @@ -1,33 +0,0 @@ -Cairo is free software. - -Every source file in the implementation[*] of cairo is available to be -redistributed and/or modified under the terms of either the GNU Lesser -General Public License (LGPL) version 2.1 or the Mozilla Public -License (MPL) version 1.1. Some files are available under more -liberal terms, but we believe that in all cases, each file may be used -under either the LGPL or the MPL. - -See the following files in this directory for the precise terms and -conditions of either license: - - COPYING-LGPL-2.1 - COPYING-MPL-1.1 - -Please see each file in the implementation for copyright and licensing -information, (in the opening comment of each file). - -[*] The implementation of cairo is contained entirely within the "src" -directory of the cairo source distribution. There are other components -of the cairo source distribution (such as the "test", "util", and "perf") -that are auxiliary to the library itself. None of the source code in these -directories contributes to a build of the cairo library itself, (libcairo.so -or cairo.dll or similar). - -These auxiliary components are also free software, but may be under -different license terms than cairo itself. For example, most of the -test cases in the perf and test directories are made available under -an MIT license to simplify any use of this code for reference purposes -in using cairo itself. Other files might be available under the GNU -General Public License (GPL), for example. Again, please see the COPYING -file under each directory and the opening comment of each file for copyright -and licensing information. diff --git a/source/libs/cairo/cairo-src/COPYING-LGPL-2.1 b/source/libs/cairo/cairo-src/COPYING-LGPL-2.1 deleted file mode 100644 index f1ed6182c52833b498109b1a9403ea83fc8bf465..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/COPYING-LGPL-2.1 +++ /dev/null @@ -1,510 +0,0 @@ - - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations -below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it -becomes a de-facto standard. To achieve this, non-free programs must -be allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control -compilation and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at least - three years, to give the same user the materials specified in - Subsection 6a, above, for a charge no more than the cost of - performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply, and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License -may add an explicit geographical distribution limitation excluding those -countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms -of the ordinary General Public License). - - To apply these terms, attach the following notices to the library. -It is safest to attach them to the start of each source file to most -effectively convey the exclusion of warranty; and each file should -have at least the "copyright" line and a pointer to where the full -notice is found. - - - <one line to give the library's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or -your school, if any, to sign a "copyright disclaimer" for the library, -if necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James - Random Hacker. - - <signature of Ty Coon>, 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/source/libs/cairo/cairo-src/COPYING-MPL-1.1 b/source/libs/cairo/cairo-src/COPYING-MPL-1.1 deleted file mode 100644 index 7714141d154290f53e9e60c615a8edc9b51a8df7..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/COPYING-MPL-1.1 +++ /dev/null @@ -1,470 +0,0 @@ - MOZILLA PUBLIC LICENSE - Version 1.1 - - --------------- - -1. Definitions. - - 1.0.1. "Commercial Use" means distribution or otherwise making the - Covered Code available to a third party. - - 1.1. "Contributor" means each entity that creates or contributes to - the creation of Modifications. - - 1.2. "Contributor Version" means the combination of the Original - Code, prior Modifications used by a Contributor, and the Modifications - made by that particular Contributor. - - 1.3. "Covered Code" means the Original Code or Modifications or the - combination of the Original Code and Modifications, in each case - including portions thereof. - - 1.4. "Electronic Distribution Mechanism" means a mechanism generally - accepted in the software development community for the electronic - transfer of data. - - 1.5. "Executable" means Covered Code in any form other than Source - Code. - - 1.6. "Initial Developer" means the individual or entity identified - as the Initial Developer in the Source Code notice required by Exhibit - A. - - 1.7. "Larger Work" means a work which combines Covered Code or - portions thereof with code not governed by the terms of this License. - - 1.8. "License" means this document. - - 1.8.1. "Licensable" means having the right to grant, to the maximum - extent possible, whether at the time of the initial grant or - subsequently acquired, any and all of the rights conveyed herein. - - 1.9. "Modifications" means any addition to or deletion from the - substance or structure of either the Original Code or any previous - Modifications. When Covered Code is released as a series of files, a - Modification is: - A. Any addition to or deletion from the contents of a file - containing Original Code or previous Modifications. - - B. Any new file that contains any part of the Original Code or - previous Modifications. - - 1.10. "Original Code" means Source Code of computer software code - which is described in the Source Code notice required by Exhibit A as - Original Code, and which, at the time of its release under this - License is not already Covered Code governed by this License. - - 1.10.1. "Patent Claims" means any patent claim(s), now owned or - hereafter acquired, including without limitation, method, process, - and apparatus claims, in any patent Licensable by grantor. - - 1.11. "Source Code" means the preferred form of the Covered Code for - making modifications to it, including all modules it contains, plus - any associated interface definition files, scripts used to control - compilation and installation of an Executable, or source code - differential comparisons against either the Original Code or another - well known, available Covered Code of the Contributor's choice. The - Source Code can be in a compressed or archival form, provided the - appropriate decompression or de-archiving software is widely available - for no charge. - - 1.12. "You" (or "Your") means an individual or a legal entity - exercising rights under, and complying with all of the terms of, this - License or a future version of this License issued under Section 6.1. - For legal entities, "You" includes any entity which controls, is - controlled by, or is under common control with You. For purposes of - this definition, "control" means (a) the power, direct or indirect, - to cause the direction or management of such entity, whether by - contract or otherwise, or (b) ownership of more than fifty percent - (50%) of the outstanding shares or beneficial ownership of such - entity. - -2. Source Code License. - - 2.1. The Initial Developer Grant. - The Initial Developer hereby grants You a world-wide, royalty-free, - non-exclusive license, subject to third party intellectual property - claims: - (a) under intellectual property rights (other than patent or - trademark) Licensable by Initial Developer to use, reproduce, - modify, display, perform, sublicense and distribute the Original - Code (or portions thereof) with or without Modifications, and/or - as part of a Larger Work; and - - (b) under Patents Claims infringed by the making, using or - selling of Original Code, to make, have made, use, practice, - sell, and offer for sale, and/or otherwise dispose of the - Original Code (or portions thereof). - - (c) the licenses granted in this Section 2.1(a) and (b) are - effective on the date Initial Developer first distributes - Original Code under the terms of this License. - - (d) Notwithstanding Section 2.1(b) above, no patent license is - granted: 1) for code that You delete from the Original Code; 2) - separate from the Original Code; or 3) for infringements caused - by: i) the modification of the Original Code or ii) the - combination of the Original Code with other software or devices. - - 2.2. Contributor Grant. - Subject to third party intellectual property claims, each Contributor - hereby grants You a world-wide, royalty-free, non-exclusive license - - (a) under intellectual property rights (other than patent or - trademark) Licensable by Contributor, to use, reproduce, modify, - display, perform, sublicense and distribute the Modifications - created by such Contributor (or portions thereof) either on an - unmodified basis, with other Modifications, as Covered Code - and/or as part of a Larger Work; and - - (b) under Patent Claims infringed by the making, using, or - selling of Modifications made by that Contributor either alone - and/or in combination with its Contributor Version (or portions - of such combination), to make, use, sell, offer for sale, have - made, and/or otherwise dispose of: 1) Modifications made by that - Contributor (or portions thereof); and 2) the combination of - Modifications made by that Contributor with its Contributor - Version (or portions of such combination). - - (c) the licenses granted in Sections 2.2(a) and 2.2(b) are - effective on the date Contributor first makes Commercial Use of - the Covered Code. - - (d) Notwithstanding Section 2.2(b) above, no patent license is - granted: 1) for any code that Contributor has deleted from the - Contributor Version; 2) separate from the Contributor Version; - 3) for infringements caused by: i) third party modifications of - Contributor Version or ii) the combination of Modifications made - by that Contributor with other software (except as part of the - Contributor Version) or other devices; or 4) under Patent Claims - infringed by Covered Code in the absence of Modifications made by - that Contributor. - -3. Distribution Obligations. - - 3.1. Application of License. - The Modifications which You create or to which You contribute are - governed by the terms of this License, including without limitation - Section 2.2. The Source Code version of Covered Code may be - distributed only under the terms of this License or a future version - of this License released under Section 6.1, and You must include a - copy of this License with every copy of the Source Code You - distribute. You may not offer or impose any terms on any Source Code - version that alters or restricts the applicable version of this - License or the recipients' rights hereunder. However, You may include - an additional document offering the additional rights described in - Section 3.5. - - 3.2. Availability of Source Code. - Any Modification which You create or to which You contribute must be - made available in Source Code form under the terms of this License - either on the same media as an Executable version or via an accepted - Electronic Distribution Mechanism to anyone to whom you made an - Executable version available; and if made available via Electronic - Distribution Mechanism, must remain available for at least twelve (12) - months after the date it initially became available, or at least six - (6) months after a subsequent version of that particular Modification - has been made available to such recipients. You are responsible for - ensuring that the Source Code version remains available even if the - Electronic Distribution Mechanism is maintained by a third party. - - 3.3. Description of Modifications. - You must cause all Covered Code to which You contribute to contain a - file documenting the changes You made to create that Covered Code and - the date of any change. You must include a prominent statement that - the Modification is derived, directly or indirectly, from Original - Code provided by the Initial Developer and including the name of the - Initial Developer in (a) the Source Code, and (b) in any notice in an - Executable version or related documentation in which You describe the - origin or ownership of the Covered Code. - - 3.4. Intellectual Property Matters - (a) Third Party Claims. - If Contributor has knowledge that a license under a third party's - intellectual property rights is required to exercise the rights - granted by such Contributor under Sections 2.1 or 2.2, - Contributor must include a text file with the Source Code - distribution titled "LEGAL" which describes the claim and the - party making the claim in sufficient detail that a recipient will - know whom to contact. If Contributor obtains such knowledge after - the Modification is made available as described in Section 3.2, - Contributor shall promptly modify the LEGAL file in all copies - Contributor makes available thereafter and shall take other steps - (such as notifying appropriate mailing lists or newsgroups) - reasonably calculated to inform those who received the Covered - Code that new knowledge has been obtained. - - (b) Contributor APIs. - If Contributor's Modifications include an application programming - interface and Contributor has knowledge of patent licenses which - are reasonably necessary to implement that API, Contributor must - also include this information in the LEGAL file. - - (c) Representations. - Contributor represents that, except as disclosed pursuant to - Section 3.4(a) above, Contributor believes that Contributor's - Modifications are Contributor's original creation(s) and/or - Contributor has sufficient rights to grant the rights conveyed by - this License. - - 3.5. Required Notices. - You must duplicate the notice in Exhibit A in each file of the Source - Code. If it is not possible to put such notice in a particular Source - Code file due to its structure, then You must include such notice in a - location (such as a relevant directory) where a user would be likely - to look for such a notice. If You created one or more Modification(s) - You may add your name as a Contributor to the notice described in - Exhibit A. You must also duplicate this License in any documentation - for the Source Code where You describe recipients' rights or ownership - rights relating to Covered Code. You may choose to offer, and to - charge a fee for, warranty, support, indemnity or liability - obligations to one or more recipients of Covered Code. However, You - may do so only on Your own behalf, and not on behalf of the Initial - Developer or any Contributor. You must make it absolutely clear than - any such warranty, support, indemnity or liability obligation is - offered by You alone, and You hereby agree to indemnify the Initial - Developer and every Contributor for any liability incurred by the - Initial Developer or such Contributor as a result of warranty, - support, indemnity or liability terms You offer. - - 3.6. Distribution of Executable Versions. - You may distribute Covered Code in Executable form only if the - requirements of Section 3.1-3.5 have been met for that Covered Code, - and if You include a notice stating that the Source Code version of - the Covered Code is available under the terms of this License, - including a description of how and where You have fulfilled the - obligations of Section 3.2. The notice must be conspicuously included - in any notice in an Executable version, related documentation or - collateral in which You describe recipients' rights relating to the - Covered Code. You may distribute the Executable version of Covered - Code or ownership rights under a license of Your choice, which may - contain terms different from this License, provided that You are in - compliance with the terms of this License and that the license for the - Executable version does not attempt to limit or alter the recipient's - rights in the Source Code version from the rights set forth in this - License. If You distribute the Executable version under a different - license You must make it absolutely clear that any terms which differ - from this License are offered by You alone, not by the Initial - Developer or any Contributor. You hereby agree to indemnify the - Initial Developer and every Contributor for any liability incurred by - the Initial Developer or such Contributor as a result of any such - terms You offer. - - 3.7. Larger Works. - You may create a Larger Work by combining Covered Code with other code - not governed by the terms of this License and distribute the Larger - Work as a single product. In such a case, You must make sure the - requirements of this License are fulfilled for the Covered Code. - -4. Inability to Comply Due to Statute or Regulation. - - If it is impossible for You to comply with any of the terms of this - License with respect to some or all of the Covered Code due to - statute, judicial order, or regulation then You must: (a) comply with - the terms of this License to the maximum extent possible; and (b) - describe the limitations and the code they affect. Such description - must be included in the LEGAL file described in Section 3.4 and must - be included with all distributions of the Source Code. Except to the - extent prohibited by statute or regulation, such description must be - sufficiently detailed for a recipient of ordinary skill to be able to - understand it. - -5. Application of this License. - - This License applies to code to which the Initial Developer has - attached the notice in Exhibit A and to related Covered Code. - -6. Versions of the License. - - 6.1. New Versions. - Netscape Communications Corporation ("Netscape") may publish revised - and/or new versions of the License from time to time. Each version - will be given a distinguishing version number. - - 6.2. Effect of New Versions. - Once Covered Code has been published under a particular version of the - License, You may always continue to use it under the terms of that - version. You may also choose to use such Covered Code under the terms - of any subsequent version of the License published by Netscape. No one - other than Netscape has the right to modify the terms applicable to - Covered Code created under this License. - - 6.3. Derivative Works. - If You create or use a modified version of this License (which you may - only do in order to apply it to code which is not already Covered Code - governed by this License), You must (a) rename Your license so that - the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", - "MPL", "NPL" or any confusingly similar phrase do not appear in your - license (except to note that your license differs from this License) - and (b) otherwise make it clear that Your version of the license - contains terms which differ from the Mozilla Public License and - Netscape Public License. (Filling in the name of the Initial - Developer, Original Code or Contributor in the notice described in - Exhibit A shall not of themselves be deemed to be modifications of - this License.) - -7. DISCLAIMER OF WARRANTY. - - COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, - WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF - DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. - THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE - IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, - YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE - COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER - OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF - ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. - -8. TERMINATION. - - 8.1. This License and the rights granted hereunder will terminate - automatically if You fail to comply with terms herein and fail to cure - such breach within 30 days of becoming aware of the breach. All - sublicenses to the Covered Code which are properly granted shall - survive any termination of this License. Provisions which, by their - nature, must remain in effect beyond the termination of this License - shall survive. - - 8.2. If You initiate litigation by asserting a patent infringement - claim (excluding declatory judgment actions) against Initial Developer - or a Contributor (the Initial Developer or Contributor against whom - You file such action is referred to as "Participant") alleging that: - - (a) such Participant's Contributor Version directly or indirectly - infringes any patent, then any and all rights granted by such - Participant to You under Sections 2.1 and/or 2.2 of this License - shall, upon 60 days notice from Participant terminate prospectively, - unless if within 60 days after receipt of notice You either: (i) - agree in writing to pay Participant a mutually agreeable reasonable - royalty for Your past and future use of Modifications made by such - Participant, or (ii) withdraw Your litigation claim with respect to - the Contributor Version against such Participant. If within 60 days - of notice, a reasonable royalty and payment arrangement are not - mutually agreed upon in writing by the parties or the litigation claim - is not withdrawn, the rights granted by Participant to You under - Sections 2.1 and/or 2.2 automatically terminate at the expiration of - the 60 day notice period specified above. - - (b) any software, hardware, or device, other than such Participant's - Contributor Version, directly or indirectly infringes any patent, then - any rights granted to You by such Participant under Sections 2.1(b) - and 2.2(b) are revoked effective as of the date You first made, used, - sold, distributed, or had made, Modifications made by that - Participant. - - 8.3. If You assert a patent infringement claim against Participant - alleging that such Participant's Contributor Version directly or - indirectly infringes any patent where such claim is resolved (such as - by license or settlement) prior to the initiation of patent - infringement litigation, then the reasonable value of the licenses - granted by such Participant under Sections 2.1 or 2.2 shall be taken - into account in determining the amount or value of any payment or - license. - - 8.4. In the event of termination under Sections 8.1 or 8.2 above, - all end user license agreements (excluding distributors and resellers) - which have been validly granted by You or any distributor hereunder - prior to termination shall survive termination. - -9. LIMITATION OF LIABILITY. - - UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT - (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL - DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, - OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR - ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY - CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, - WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER - COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN - INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF - LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY - RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW - PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE - EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO - THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. - -10. U.S. GOVERNMENT END USERS. - - The Covered Code is a "commercial item," as that term is defined in - 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer - software" and "commercial computer software documentation," as such - terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 - C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), - all U.S. Government End Users acquire Covered Code with only those - rights set forth herein. - -11. MISCELLANEOUS. - - This License represents the complete agreement concerning subject - matter hereof. If any provision of this License is held to be - unenforceable, such provision shall be reformed only to the extent - necessary to make it enforceable. This License shall be governed by - California law provisions (except to the extent applicable law, if - any, provides otherwise), excluding its conflict-of-law provisions. - With respect to disputes in which at least one party is a citizen of, - or an entity chartered or registered to do business in the United - States of America, any litigation relating to this License shall be - subject to the jurisdiction of the Federal Courts of the Northern - District of California, with venue lying in Santa Clara County, - California, with the losing party responsible for costs, including - without limitation, court costs and reasonable attorneys' fees and - expenses. The application of the United Nations Convention on - Contracts for the International Sale of Goods is expressly excluded. - Any law or regulation which provides that the language of a contract - shall be construed against the drafter shall not apply to this - License. - -12. RESPONSIBILITY FOR CLAIMS. - - As between Initial Developer and the Contributors, each party is - responsible for claims and damages arising, directly or indirectly, - out of its utilization of rights under this License and You agree to - work with Initial Developer and Contributors to distribute such - responsibility on an equitable basis. Nothing herein is intended or - shall be deemed to constitute any admission of liability. - -13. MULTIPLE-LICENSED CODE. - - Initial Developer may designate portions of the Covered Code as - "Multiple-Licensed". "Multiple-Licensed" means that the Initial - Developer permits you to utilize portions of the Covered Code under - Your choice of the NPL or the alternative licenses, if any, specified - by the Initial Developer in the file described in Exhibit A. - -EXHIBIT A -Mozilla Public License. - - ``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/ - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the - License for the specific language governing rights and limitations - under the License. - - The Original Code is ______________________________________. - - The Initial Developer of the Original Code is ________________________. - Portions created by ______________________ are Copyright (C) ______ - _______________________. All Rights Reserved. - - Contributor(s): ______________________________________. - - Alternatively, the contents of this file may be used under the terms - of the _____ license (the "[___] License"), in which case the - provisions of [______] License are applicable instead of those - above. If you wish to allow use of your version of this file only - under the terms of the [____] License and not to allow others to use - your version of this file under the MPL, indicate your decision by - deleting the provisions above and replace them with the notice and - other provisions required by the [___] License. If you do not delete - the provisions above, a recipient may use your version of this file - under either the MPL or the [___] License." - - [NOTE: The text of this Exhibit A may differ slightly from the text of - the notices in the Source Code files of the Original Code. You should - use the text of this Exhibit A rather than the text found in the - Original Code Source Code for Your Modifications.] - diff --git a/source/libs/cairo/cairo-src/HACKING b/source/libs/cairo/cairo-src/HACKING deleted file mode 100644 index aba2c545bb9f490cb5aa6d1a1a0c828c61d5a60a..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/HACKING +++ /dev/null @@ -1,185 +0,0 @@ -Hacking Cairo -============= - -This is a high-level guide to how the cairo distribution is organized -and how to get started hacking on it. Make sure you read through the -file README before continuing. - - -Coding Style ------------- - -The easiest way to write code in the cairo style is to follow code close -to the place you are hacking, but if you want a written down set of -rules, see file CODING_STYLE. - -Files for backends that depend on languages other than C (C++ or -Objective C for example) may use features specific to those languages. -For example, "//" comments are allowed, though discouraged, in those files. - - -Contact -------- - -Various ways to get in touch with other cairo developers and maintainers -have been enumerated at: - - http://cairographics.org/contact/ - -Most of that information is also reflected in the following sections. - - -Mailing Lists -------------- - -There are various mailing lists that are useful when developing cairo -code. A complete list is always available at: - - http://cairographics.org/lists/ - -It is recommended that cairo developers subscribe to all those lists. -The cairo list by itself generates much more traffic than the others -combined, so developers and contributors should not be intimidated by -the -commit and -bugs lists. - - -Bug Tracking System -------------------- - -We use a standard bugzilla bug tracking system available at: - - http://bugs.freedesktop.org/ - -See file named BUGS for detailed information on reporting bugs. In short, -for straight bug reports, it's best to report them there such that they -are not lost or forgotten. For discussion of new features or -complicated issues, use the mailing list. - - -IRC ---- - -It's a great idea to hang around the cairo IRC channel if you have any -interest in cairo. We use the #cairo channel on irc.freenode.net. - -Make sure you introduce yourself if your nick is not easy to match to -the name you use on the mailing list. - - -Version Control System ----------------------- - -We use /git/ for version control. See: - - http://cairographics.org/download/ - -For more information on using git, see: - - http://freedesktop.org/wiki/Infrastructure/git/ - - -Build System ------------- - -We use the autotools build system with cairo, but with various -customizations and advanced features. Reading configure.in is your -best bet to understanding it, or just ask on IRC. - -To bootstrap the build system run ./autogen.sh. After that the -regular "./configure; make; make install" sequence can be used. -See file named INSTALL for more details. - -There is limited support for a win32 build system. -See README.win32 and Makefile.win32 files in various directories. - - -ChangeLog ---------- - -We generate ChangeLog files automatically from the git commit log. -No manual ChangeLog writing is necessary. - - -Copyrights and Licensing ------------------------- - -The cairo library is dual-licensed under LGPL and MPL. See the file -named COPYING for details. The test suites are more liberal, and are -allowed to include GPL code. - -When writing new code, update the file headers to add your (or your -employers) copyright line and contributor line. If adding new files -or splitting a file, copy the file header from other files. - - -Source Code ------------ - -The library source code and headers live in the src/ directory. -See src/README for more information. - - -Regression Test Suite ---------------------- - -Cairo has a fairly extensive regression-testing suite. Indeed, without -these tests it would be impossible to make a cairo release without -introducing tens of regressions. We still manage to introduce -regressions with each release even with the hundreds of tests we already -have. - -The regression test suite is located under the test/ directory. -See test/README for more information. - - -Performance Test Suite ----------------------- - -There is a performance test suite located under the perf/ directory. -A collection of traces of real-world behavior are also available in the -cairo-traces repository, which can be used in isolation or hooked in -with the main performance test suite. See perf/README for more -information. - - -Boilerplate ------------ - -The cairo-boilerplate is a small private library used by the regression -and performance test suites. It includes the boilerplace code needed -to initialize various backends for the test suites, as well as allow -tweaking some of the internal workings of the backends for more testing. - -The boilerplate code is localted under the boilerplate/ directory. -See boilerplate/README for more information. - - -Documentation -------------- - -Cairo uses the gtk-doc system for reference API documentation. - -The reference documentation is located under doc/public. -See doc/public/README for more information. - -For more documentation including frequently asked questions, tutorials, -samples, roadmap, todo list, etc visit: - - http://cairographics.org/documentation/ - -Some of those should gradually be moved to doc/. - - -Utilities ---------- - -We have developed several utilities useful for writing cairo or code -that uses cairo. These tools can be found under the util/ directory. -See util/README for more information. - - -Releasing ---------- - -Now you are a cairo maintainer, so what? See file named RELEASING. - diff --git a/source/libs/cairo/cairo-src/INSTALL b/source/libs/cairo/cairo-src/INSTALL deleted file mode 100644 index 9db68dee2ba4f5ad9feb242b905c881df380b75a..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/INSTALL +++ /dev/null @@ -1,184 +0,0 @@ -Quick-start build instructions ------------------------------- -1) Configure the package: - - ./configure - -2) Compile it: - - make - -3) Install it: - - make install - -This final step may require temporary root access (eg. with sudo) if -you don't have write permission to the directory in which cairo will -be installed. - -NOTE: If you are working with source from git/cvs rather than from a tar -file, then you should use ./autogen.sh in place of ./configure -anywhere it is mentioned in these instructions. - -More detailed build instructions --------------------------------- -1) Configure the package - - The first step in building cairo is to configure the package by - running the configure script. [Note: if you don't have a configure - script, skip down below to the Extremely detailed build - instructions.] - - The configure script attempts to automatically detect as much as - possible about your system. So, you should primarily just accept - its defaults by running: - - ./configure - - The configure script does accept a large number of options for - fine-tuning its behavior. See "./configure --help" for a complete - list. The most commonly used options are discussed here. - - --prefix=PREFIX - - This option specifies the directory under which the software - should be installed. By default configure will choose a - directory such as /usr/local. If you would like to install - cairo to some other location, pass the director to configure - with the --prefix option. For example: - - ./configure --prefix=/opt/cairo - - would install cairo into the /opt/cairo directory. You could - also choose a prefix directory within your home directory if - you don't have write access to any system-wide directory. - - After installing into a custom prefix, you will need to set - some environment variables to allow the software to be - found. Assuming the /opt/cairo prefix and assuming you are - using the bash shell, the following environment variables - should be set: - - PKG_CONFIG_PATH=/opt/cairo/lib/pkgconfig - LD_LIBRARY_PATH=/opt/cairo/lib - export PKG_CONFIG_PATH LD_LIBRARY_PATH - - (NOTE: On Mac OS X, at least, use DYLD_LIBRARY_PATH in place - of LD_LIBRARY_PATH above.) - - --enable-XYZ - --enable-XYZ=yes - --enable-XYZ=auto - --enable-XYZ=no - --disable-XYZ - - Cairo's various font and surface backends and other features can be - enabled or disabled at configure time. Features can be divided into - three categories based on their default state: - - * default=yes: These are the recommended features like PNG functions - and PS/PDF/SVG backends. It is highly recommended to not disable - these features but if that's really what one wants, they can be - disabled using --disable-XYZ. - - * default=auto: These are the "native" features, that is, they are - platform specific, like the Xlib surface backend. You probably - want one or two of these. They will be automatically enabled if - all their required facilities are available. Or you can use - --enable-XYZ or --disable-XYZ to make your desire clear, and then - cairo errs during configure if your intention cannot be followed. - - * default=no: These are the "experimental" features, and hence by - default off. Use --enabled-XYZ to enable them. - - The list of all features and their default state can be seen in the - output of ./configure --help. - -2) Compile the package: - - This step is very simple. Just: - - make - - The Makefiles included with cairo are designed to work on as many - different systems as possible. - - When cairo is compiled, you can also run some automated tests of - cairo with: - - make check - - NOTE: Some versions of X servers will cause the -xlib tests to - report failures in make check even when cairo is working just - fine. If you see failures in nothing but -xlib tests, please - examine the corresponding -xlib-out.png images and compare them to - the -ref.png reference images (the -xlib-diff.png images might also - be useful). If the results seem "close enough" please do not report - a bug against cairo as the "failures" you are seeing are just due - to subtle variations in X server implementations. - -3) Install the package: - - The final step is to install the package with: - - make install - - If you are installing to a system-wide location you may need to - temporarily acquire root access in order to perform this - operation. A good way to do this is to use the sudo program: - - sudo make install - -Extremely detailed build instructions -------------------------------------- -So you want to build cairo but it didn't come with a configure -script. This is probably because you have checked out the latest -in-development code via git. If you need to be on the bleeding edge, -(for example, because you're wanting to develop some aspect of cairo -itself), then you're in the right place and should read on. - -However, if you don't need such a bleeding-edge version of cairo, then -you might prefer to start by building the latest stable cairo release: - - http://cairographics.org/releases - -or perhaps the latest (unstable) development snapshot: - - http://cairographics.org/snapshots - -There you'll find nicely packaged tar files that include a configure -script so you can go back the the simpler instructions above. - -But you're still reading, so you're someone that loves to -learn. Excellent! We hope you'll learn enough to make some excellent -contributions to cairo. Since you're not using a packaged tar file, -you're going to need some additional tools beyond just a C compiler in -order to compile cairo. Specifically, you need the following utilities: - - automake - autoconf - autoheader - aclocal - libtoolize - pkg-config [at least version 0.16] - gtk-doc (recommended) - -Hopefully your platform of choice has packages readily available so -that you can easily install things with your system's package -management tool, (such as "apt-get install automake" on Debian or "yum -install automake" on Fedora, etc.). Note that Mac OS X ships with -glibtoolize instead of libtoolize. - -Once you have all of those packages installed, the next step is to run -the autogen.sh script. That can be as simple as: - - ./autogen.sh - -But before you run that command, note that the autogen.sh script -accepts all the same arguments as the configure script, (and in fact, -will generate the configure script and run it with the arguments you -provide). So go back up to step (1) above and see what additional -arguments you might want to pass, (such as prefix). Then continue with -the instructions, simply using ./autogen.sh in place of ./configure. - -Happy hacking! diff --git a/source/libs/cairo/cairo-src/KNOWN_ISSUES b/source/libs/cairo/cairo-src/KNOWN_ISSUES deleted file mode 100644 index c367f918ea3652591daf4ff35074475ee204a6c5..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/KNOWN_ISSUES +++ /dev/null @@ -1,3 +0,0 @@ -Known Issues ------------- -None diff --git a/source/libs/cairo/cairo-src/Makefile.am b/source/libs/cairo/cairo-src/Makefile.am deleted file mode 100644 index 03fa3523649fbd52a5c8807fca7a0e11d7021ef7..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/Makefile.am +++ /dev/null @@ -1,83 +0,0 @@ -include $(top_srcdir)/build/Makefile.am.common - -EXTRA_DIST += \ - KNOWN_ISSUES \ - README.win32 \ - Makefile.win32 \ - build/Makefile.win32.common \ - build/Makefile.win32.inform \ - build/Makefile.win32.features \ - build/Makefile.win32.features-h \ - $(NULL) -#MAINTAINERCLEANFILES += \ -# $(srcdir)/build/Makefile.win32.features \ -# $(srcdir)/build/Makefile.win32.features-h \ -# $(NULL) - -ACLOCAL_AMFLAGS = -I build ${ACLOCAL_FLAGS} - -DIST_SUBDIRS = src doc util boilerplate test perf -SUBDIRS = src doc util -# libpng is required for our test programs -if CAIRO_HAS_PNG_FUNCTIONS -SUBDIRS += boilerplate test perf -endif - -configure: cairo-version.h - -doc: - cd doc && $(MAKE) $(AM_MAKEFLAGS) $@ -test retest recheck: all - cd test && $(MAKE) $(AM_MAKEFLAGS) $@ -perf: all - cd perf && $(MAKE) $(AM_MAKEFLAGS) $@ -check-valgrind: all - cd test && $(MAKE) $(AM_MAKEFLAGS) check-valgrind - cd perf && $(MAKE) $(AM_MAKEFLAGS) check-valgrind -.PHONY: doc test retest recheck perf check-valgrind - - -EXTRA_DIST += \ - AUTHORS \ - BIBLIOGRAPHY \ - BUGS \ - CODING_STYLE \ - COPYING \ - COPYING-LGPL-2.1 \ - COPYING-MPL-1.1 \ - HACKING \ - INSTALL \ - NEWS \ - PORTING_GUIDE \ - README \ - RELEASING \ - autogen.sh \ - cairo-version.h \ - $(NULL) - -DISTCLEANFILES += config.cache - -MAINTAINERCLEANFILES += \ - $(srcdir)/aclocal.m4 \ - $(srcdir)/autoscan.log \ - $(srcdir)/build/compile \ - $(srcdir)/build/config.guess \ - $(srcdir)/build/config.sub \ - $(srcdir)/build/depcomp \ - $(srcdir)/build/install-sh \ - $(srcdir)/build/ltmain.sh \ - $(srcdir)/build/missing \ - $(srcdir)/build/mkinstalldirs \ - $(srcdir)/config.h.in \ - $(srcdir)/configure.scan \ - $(NULL) - -DISTCHECK_CONFIGURE_FLAGS = \ - --enable-gtk-doc \ - --enable-test-surfaces \ - --enable-full-testing \ - $(NULL) - -include $(srcdir)/build/Makefile.am.changelog -include $(srcdir)/build/Makefile.am.releasing -include $(srcdir)/build/Makefile.am.analysis diff --git a/source/libs/cairo/cairo-src/Makefile.win32 b/source/libs/cairo/cairo-src/Makefile.win32 deleted file mode 100644 index fbad7f3e4c91ecad74dc4fedd69e5387c77b2544..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/Makefile.win32 +++ /dev/null @@ -1,24 +0,0 @@ -default: all - -# Do not edit this file. -# Edit build/Makefile.win32.common for customization - -top_srcdir = . -include $(top_srcdir)/build/Makefile.win32.inform - -all: cairo - -cairo: inform - @$(MAKE) -C src -f Makefile.win32 - -perf: inform - @$(MAKE) -C perf -f Makefile.win32 perf - -test: inform - @$(MAKE) -C test -f Makefile.win32 test - -clean: - @$(MAKE) -C boilerplate -f Makefile.win32 clean - @$(MAKE) -C perf -f Makefile.win32 clean - @$(MAKE) -C src -f Makefile.win32 clean - @$(MAKE) -C test -f Makefile.win32 clean diff --git a/source/libs/cairo/cairo-src/NEWS b/source/libs/cairo/cairo-src/NEWS deleted file mode 100644 index 08889d2d054e5ecd1050b7964a2d34373b8a327e..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/NEWS +++ /dev/null @@ -1,7528 +0,0 @@ -Release 1.14.8 (2016-12-07 Bryce Harrington <bryce@osg.samsung.com>) -======================================================================== -Bugfix release rolling up backported fixes for the past year. - -For a complete log of changes since 1.14.6, please see: - - http://cairographics.org/releases/ChangeLog.cairo-1.14.8 - -Features --------- -None - -API Changes ------------ -None - -Dependency Changes ------------------- -None - -Performance Optimizations -------------------------- -None - -Bug Fixes ---------- -* Fix "invalidfont" error on some printers when printing PDFs with - embedded fonts that have glyphs (such as spaces) with - num_contours == 0. (Bug #79897) -* Fix deadlock when destruction of a scaled font indirectly triggers - destruction of a second scaled font, causing the global cache to be - locked twice. (Bug #93891) -* Fix X errors reported to applications when shmdt() is called before - the Attach request is processed, due to missing xcb and xlib calls. -* Fix random failure in record-paint-alpha-clip-mast test case, caused - by an incorrect assumption that a deferred clear can be skipped. - (Bug #84330) -* Fix crash when dealing with an XShmGetImage() failure, caused by a - double free in _get_image_surface(). (Bug #91967) -* Fix build issue when using non-GNU strings utility. (Bug #88639) -* Cleanup debugging text sent to stdout instead of log. (Bug #95227) - - -Release 1.14.6 (2015-12-09 Bryce Harrington <bryce@osg.samsung.com>) -======================================================================== -Simple bugfix release to fix one Windows issue. - -For a complete log of changes since 1.14.4, please see: - - http://cairographics.org/releases/ChangeLog.cairo-1.14.6 - -Features --------- -None - -API Changes ------------ -None - -Dependency Changes ------------------- -None - -Performance Optimizations -------------------------- -None - -Bug Fixes ---------- -* Fix failure on Windows due to reference of the function - cairo_win32_surface_create_with_format(), which isn't included in the - 1.14.4 release. (Bug #92771) - - -Release 1.14.4 (2015-10-28 Bryce Harrington <bryce@osg.samsung.com>) -======================================================================== -Just in time for Halloween we see another bug-fix release for Cairo. -This brings a few dozen straightforward bug fixes with no API changes. - -In addition, this includes a typical assortment of fixes to tests, -cleanup of warnings and memory leaks, correction of misspellings, -updates to documentation, etc. - -For a complete log of changes since 1.14.2, please see: - - http://cairographics.org/releases/ChangeLog.cairo-1.14.4 - - -Features --------- -None - -API Changes ------------ -None - -Dependency Changes ------------------- -None - -Performance Optimizations -------------------------- -None - -Bug Fixes ---------- -* Avoid appending empty slots to user data arrays. Fixes a memory - consumption regression since commit 9341c254a. - -* Return a better error (file-not-found) when setting up pango on - devices where the font files don't have read permissions. - -* Fix regression in the font size of canvas text in Inkscape when - compiled with the Quartz backend. (Bug #84324) - -* Fix _cairo_gl_shader_bind_matrix() to maintain compatibility with - OpenGL ES 2.0. Manually transpose the matrix. - -* Fix incorrect font descriptor conversion when the font matrix yy is - negative. (Bug #90538) - -* Fix crash when using a complex path for clip and stroke due to - discarding the intersection exactly at the top edge. - (Bug #74779) - -* Fix cairo_get_locale_decimal_point() on Android - -* Fix compilation problem on AIX due to conflicting usage of symbol - 'jmpbuf'. (Bug #89339) - -* Fix broken rendering with XCB due to snapshotting of uploaded part of - surfaces. (Bug #67505) - -* Fix loss of alpha when copying a mask for a cairo recording surface, - resulting in a double copy. (Bugs #73038, #73901) - -* Fix incorrect recording of certain paths with script surfaces. - (Bug #91054) - -* Fix typo in definition of MAYBE_WARN in configure script. - (Bug #89750) - -* Fix use of filename variable after it's been freed. - (Bug #91206) - -* Fix out of bounds access when printing pattern. - (Bug #91266) - -* Fix incorrect size calculation in glyph cache unlocking for Cairo GL - compositor. - (Bug #91321) - -* Fix memory leak in _cairo_gl_pattern_texture_setup() - (Bug #91537) - -* Fix transparent images in win32-print. - (Bug #91835) - -* Fix _put_shm_image_boxes and _put_image_boxes when no SHM available - with XCB. - - -Release 1.14.2 (2014-03-09 Bryce Harrington <bryce@osg.samsung.com>) -==================================================================== -This release provides collected bug fixes, along with one feature -enhancement for the xcb backend, and a small performance improvement for -fonts. - -The running theme of the bug fixes is platform-specific issues, both -build and run-time. Platforms with fixes include Sparc, AIX, Windows -(mingw), and Windows (MSVC8). Memory leaks, valgrind issues, and PDF -issues round out our list. - -It's come to light that changes in cairo 1.14 resulted in breakage on -MacOS X 10.4. We've not yet determined whether to fix up the support, -or excise the 10.4-specific code and support only OS X 10.5 or newer. -Meantime, we'll only advertise cairo as working on OS X 10.5. - -Features --------- - * Improve xcb's handling of per-screen subpixel ordering. If no - Xft.rgba property is specified, default to the screen's subpixel - order. - -API Changes ------------ -None - -Dependency Changes ------------------- -None - -Performance Optimizations -------------------------- - * Improve performance of cpu_to_be32 and be32_to_cpu, making truetype - subsetting of large fonts run about 15% faster. - -Bug Fixes ---------- - * Fix unaligned access on sparc with the compact font format (CFF). - Unlike truetype, all data in CFF is not aligned. - (Debian bug #712836) - * Fix unaligned access on sparc with tor-scan-converter's memory pool. - * Fix crash when loading a PDF with a transformed image. - (fdo bug #85151) - * Fix regression on mingw for bigendian test due to removal of file - extension for executables. - (fdo bug #85120) - * Fix handling of backslash in PDF interpreter - (fdo bug #85662) - * Fix crash in xlib and xcb renderers when swapping a 0-sized glyph - * Fix bug with RTL text in PDF operators - (fdo bug #86461) - * Fix compilation 'cairo-path-stroke-traps.c' with MSVC8 - (fdo bug #84908) - * Fix crash in _fill_xrgb32_lerp_opaque_spans when a span length is - negative. - * Fix valgrind error by releasing pattern created by - cairo_pattern_create_rgb(). - * Fix valgrind errors when running cairo-test-suite. - * Fix memory leak in recording surface replays - (fdo bug #87898) - * Fix destruction of fonts in api-special-cases test. - (fdo bug #87567) - * Fix duplicated surface push on similar-image, preventing trivial GTK3 - program traces from being replayable, with an error message about - invalid values for the size of the input. - (fdo bug #73580) - * Fix crash when win32 surface's image size does not cover the entire - surface. - (fdo bug #53121) - * Fix crash due to obsolete CGFontGetGlyphPath call - (fdo bug #84324) - * Fix several build issues on AIX - (fdo bugs #89338, #89340, #89356, #89354) - * Fix various documentation warnings and errors - -Release 1.14.0 (2014-10-13 Bryce Harrington <bryce@osg.samsung.com>) -==================================================================== -Hard to believe it's been over a year since our last release, but it's -not for lack of activity. This release includes contributions of a wide -assortment of bug fixes, build system improvements, warnings cleanups, -codebase refactoring, test suite repairs, and static analysis work. - -This release is lighter on features (compared with 1.12.10) but includes -a highly demanded rehaul of our image downscaling functionality, which -solves a serious problem experienced by Inkscape users when shrinking -embedded bitmaps in SVG files. The new scaling algorithms are used by -the image backend and by other backends as needed for fallbacks. - - -Features --------- - - Filtering improvements for the image backend, in particular - down-scaling of images produces filtered images that depend on all the - pixels of the source. When using the image backend you get the - following settings: - - CAIRO_FILTER_GOOD: uses a box filter for scales less than .75 in - either direction. For scales larger than this, the same filter as - CAIRO_FILTER_BILINEAR is used. - - CAIRO_FILTER_BEST: uses a Catmull-Rom filter always. When upscaling - more than 2x this will produce anti-aliased square pixels, similar - to OS/X. - - CAIRO_FILTER_GAUSSIAN: uses PIXMAN_FILTER_BEST, which in current - pixman is the same as BILINEAR. (This is subject to change in the - future). - - xlib and xcb also use the image fallback for GOOD/BEST filters, but - note that other backends do not implement these filtering fixes yet, - however other actions may cause them to use an image fallback which - will cause these filters to be used. - - Improve handling of device transformation and scaling, allowing Cairo - to now support scaling at a device level, permitting easier, more - transparent HiDPI support. - - Support JBIG2 mime data in PDF. This allows embedding of more - compressed JPEG formats within PDF, rather than including the full - uncompressed image. Also, reduce the number of transparency groups - used by PDF to keep the file size small and viewing/printing of the - PDF fast. - - Expand the embedding section to include stencil mask support. - - Reorder font declarations to be in natural order. - - Update the Skia backend to build against current Skia (as of June - 2014). - - Drop Link-Time Optimization (LTO) support from build system. This - seems to have caused much trouble for unclear benefit, and most - distros are reverting or disabling it anyway. - - Optimize VBO size on GL to 1M and to 16k for EGL. This improves - (theoretical) performance for desktop GLX use cases while avoiding - hitting VBO memory size limitations on embedded devices. - -API Changes ------------ - - cairo_surface_set_device_scale, cairo_surface_get_device_scale: - - Sets a scale that is multiplied to the device coordinates - determined by the CTM when drawing to @surface. One common use for - this is to render to very high resolution display devices at a scale - factor, so that code that assumes 1 pixel will be a certain size - will still work. - - cairo_egl_device_get_display, cairo_egl_device_get_context: - - Support get/set of EGLContext and EGLDisplay for egl-based cairo - devices, similar to GLX. - -Dependency Changes ------------------- - - Cairo now requires glib 2.14 for its gobject helper functions, - and pixman 0.30 for downscaling. - - -Bug fixes ---------- - - Don't embed CMYK Jpeg images in svg. - - Fix tests to place output in proper location. - - Fix determination of alpha for all surfaces when recording. - - Extend oversize check to cairo_gl_surface_create_for_texture, so an - error surface is returned if the texture is too large to render to. - - Fix embedding of mime data in PDF and PS files. - - Remove useless error handling in *_reply() functions in XCB. - - Fix a double-free exposed by multithreaded apps creating and - destroying the same font concurrently. - https://bugs.freedesktop.org/show_bug.cgi?id=69470 - - Fix corrupt stacks produced by bugs in operand emission for trace. - - Fix out of bounds array access in format cache for xlib - - Don't rename glyphs used by seac operator. This can cause certain - combined characters to use their decorations (e.g. umlauts on ö) to be - lost during printing of PDFs using evince. - https://bugs.freedesktop.org/show_bug.cgi?id=70364 - - Fix crash on calling cairo_create with a finished surface - - Fix SSIZE_T definition problem when making with MSYS on Windows7 - - Fix one off issue in gl context cleanup - - Fix usage of CAIRO_STACK_ARRAY_LENGTH - - Fix rectangle stroke with non rectilinear pen - - Fix imagemask with pattern source failure on some printers. This bug - could cause files converted using pdftops to fail for example on Ricoh - printers, or opening in Adobe Distiller on Windows. - https://bugs.freedesktop.org/show_bug.cgi?id=69485 - - Fix whitespace in font names - - Fix page size in generated PDFs. When printing using pdftocairo on - larger page sizes, such as 11x17, the image would be cropped to letter - size. - https://bugs.freedesktop.org/show_bug.cgi?id=73452 - - Fix path-currentpoint test by preserving current-point in - copy_path()/append_path() sequence - - Fix generation of HTML in code docs for - cairo-format-stride-for-width. Raw HTML code was being passed - to the browser, instead of displaying normally. - https://bugs.freedesktop.org/show_bug.cgi?id=63257 - - Fix spelling of "tessellator" throughout code. We're using the - American rather than British spelling of this word. - https://bugs.freedesktop.org/show_bug.cgi?id=50411 - - Fix crash in pixman_image_composite32 - - Fix crash when trying to modify a (const) all-clipped cairo_clip_t - https://bugs.freedesktop.org/show_bug.cgi?id=75819 - - Add check_composite method to all compositors, to fix crashes in the - test suite. - - Fix crash in Firefox when scrolling on certain pages. - - Fix memory leaks found by static analysis. - - Fix build of any2ppm if fork is not available. - - Fix broken build for Qt backend, due to missing libstdc++. - - Fix typo in two cairo_uint128 functions. Fixes potential build issues - on systems without a uint128 type. - - Fix build when --enable-pdf=no - - Fix cache_frozen assertions for Win32 print. - - Correctly check for xcb image surface for inplace upload - - Fix webkit-based web browser crashes due to empty boxes by skipping - over them when tesselating. - - Make pixman, libpng, and zlib paths commandline configurable for win32 - builds. - - Fix image scale on Win32 when GDI scale is not identity. - - Fix float endian configure test when using clang -O4 - - Fix compilation with Android bionic libc - - Don't try to build util/sphinx on Windows - - Fix loss of precision when emitting joins. This was caused by - discrepancies in line gradients when passing trapezoids around. - - Fix loss of precision and associated rendering issues in - cairo-tor-scan-converter from projection onto sample grid. - - Fix pixman oversampling of neighbouring edges within a cell by - eliminating self-intersections for the pixman traps compositor. - - Fix multi-line string splitting in PDFs - - Various cleanups and fixes to warnings, documentation, tests, and - build system. Improve error handling and return value checks. - Cleanup XFAIL tests and reference images. Cover recently added - functionality. - - -Release 1.12.16 (2013-08-21 Chris Wilson <chris@chris-wilson.co.uk>) -=================================================================== -Thanks to everybody who reported a bug and helped us develop a fix, -we have amassed quite a few bug fixes. There are still more outstanding -bugs that seek attention and a little bit of TLC, but this release has -been delayed long enough... - -Bug fixes ---------- - - Set the correct orientation for simple boxes with a negative scale - factor. - - Fix the creation of the shading dictionary in PDF. - - Fix a crash in PDF when incorporating an image with CAIRO_EXTEND_PAD. - https://bugs.freedesktop.org/show_bug.cgi?id=61451 - - Avoid upscaling bitmap fonts if possible. - - Fix an assertion failure within the mempool allocator for shared memory. - - Fix allocation size for CFF subsets. - - Export cairo_matrix_t for GObject bindings. - - Fix a double free in the Quartz backend. - https://bugs.freedesktop.org/show_bug.cgi?id=62885 - - Fix origin of GDI StretchBlits for the Windows backend - https://bugs.freedesktop.org/show_bug.cgi?id=61876 - - Fix error propagation for requests to create a similar surface with - negative size. - https://bugs.freedesktop.org/show_bug.cgi?id=63196 - - Fix complex clipping of trapezoids with regions - https://bugzilla.gnome.org/show_bug.cgi?id=697357 - - Stop leaking the image data when loading PNGs - - Fix unbounded operations with a clip mask through the span compositor - https://bugs.freedesktop.org/show_bug.cgi?id=61592 - - Add missing checks before rendering to a finished surface - so we return - an error rather than hit an assert. - https://bugs.freedesktop.org/show_bug.cgi?id=68014 - - Prevent an assertion failure when creating similar GL surfaces larger - than supported by hardware. - - Prevent a double free of a similar image under Windows. - https://bugs.freedesktop.org/show_bug.cgi?id=63787 - - -Release 1.12.14 (2013-02-10 Chris Wilson <chris@chris-wilson.co.uk>) -=================================================================== -In the last week we had a few more bugs reported and promptly resolved. -As these are a combination of regressions and stability issues, it is -time for a prompt update and release. Many thanks to everyone for -testing and reporting issues, and helping to make Cairo better. - -Bug fixes ---------- - - Prevent user callbacks accessing user-data during destroy to prevent - use-after-free bugs. - https://bugzilla.mozilla.org/show_bug.cgi?id=722975 - - Use standard names for glyphs in subset fonts (PDF). - https://bugs.freedesktop.org/show_bug.cgi?id=60248 - - Fix detection of Win98. The logic for detecting Win98 (and its broken - AlphaBlend()) was inverted, disabling AlphaBlend() for everyone. - - Prevent numeric overflow from extrapolating polygon edges to the clip - boundary and causing severe render artifacts. - https://bugs.freedesktop.org/show_bug.cgi?id=60489 - - Fix computation of glyph string coordinates when breaking up runs - for xlib. - - Fix an assertion in the win32 backend for failing to clear its - similar-images. - https://bugs.freedesktop.org/show_bug.cgi?id=60519 - - -Release 1.12.12 (2013-01-31 Chris Wilson <chris@chris-wilson.co.uk>) -=================================================================== -The goal of this release is to fix the synchronisation problems that -were exhibited in the SHM transport for cairo-xlib. This cropped up -any place that tried to rapidly push fresh pixel data to the X server -through an ordinary image surface, such as gimp-2.9 and evince. - -Bug fixes ---------- - - Avoid replacing the entire image when uploading subimages - https://bugs.freedesktop.org/show_bug.cgi?id=59635 - - Force synchronisation for scratch SHM image buffers, so that we do - not overwrite data as it is being read by X. - https://bugs.freedesktop.org/show_bug.cgi?id=59635 (also) - - Fix typos in detecting multisampling for the GL (MSAA) backend. - - Fix a memory leak in the GL (MSAA) backend. - - Fix a reference counting bug when mapping a GL surface to an image. - - -Release 1.12.10 (2013-01-16 Chris Wilson <chris@chris-wilson.co.uk>) -=================================================================== -A heap of bug fixes everywhere, and the gradual completion of the MSAA -backend for cairo-gl. Perhaps the most noteworthy set of the bugfixes -was the crusage lead by Behdad Eshfabod to make font handling by -pango/cairo/fontconfig fully threadsafe. This testing revealed a couple -of races that needed fixing in Cairo's scaled-font and glyph cache. - -Bug fixes ---------- - - Append coincident elements to the recording's surface bbtree so that - the list is not corrupted and the overlapping elements lost. - - Fix cairo-trace to correctly record map-to-image/unmap-image and then - replay them. - - Ignore MappingNotifies when running the XCB testsuite as they are sent - to all clients when the keyboard changes. The testsuite would detect - the unexpected event and complain. - - Handle very large images in the XCB backend. - - Fix a memory leak in the xlib/shm layer, and prevent use of the SHM - surfaces after the display is closed. - https://bugs.freedesktop.org/show_bug.cgi?id=58253 - - Handle resizing of bitmap fonts, in preparation for a fix to - fontconfig to correctly pass on the user request for scaling. - - Always include subroutine 4 (hint replacement idion) when subsetting - type 1 fonts in order to prevent a crash in cgpdftops on Mac OS/X - - Fix a couple of typos in the cairo-gobject.h header files for - introspection. - - Prevent a mutex deadlock when freeing a scaled-glyph containing a - recording-surface that itself references another scaled-glyph. - https://bugs.freedesktop.org/show_bug.cgi?id=54950 - - Make scaled-font cache actually thread-safe and prevent - use-after-frees. - - Restore support for older versions of XRender. A couple of typos and a - few forgotten chunks prevented the xlib compositor from running - correctly with XRender < 0.10. Note that there are still a few - regressions remaining. - - -Release 1.12.8 (2012-11-24 Chris Wilson <chris@chris-wilson.co.uk>) -=================================================================== -Another couple of weeks and a few more bugs have been found and fixed, -it is time to push the next point release. Many thanks to everyone who -reported their issues and helped us track down the bugs and helped -testing the fixes. - -Bug fixes ---------- - - Expand the sanity checking for broken combinations of XSendEvent and - ShmCompletionEvent. - - Notice that "The X.Org Foundation" sometimes also identifies itself - as "The Xorg Foundation". - - Handle various ages of libXext and its Shm headers. - - Fix the invalid clipping of the source drawable when using SHM - transport to upload images. - https://bugs.freedesktop.org/show_bug.cgi?id=56547 - - Handle all Type1 postscript operators for better font compatibility. - https://bugs.freedesktop.org/show_bug.cgi?id=56265 - - Fix a couple of memory leaks in Type1 font subsetting - https://bugs.freedesktop.org/show_bug.cgi?id=56566 - - Tighten the evaluation of the start/stop pen vertices, and catch a few - instances where we would use a fan instead of a bevel. - https://bugs.freedesktop.org/show_bug.cgi?id=56432 - - Fix assumption that geometric clipping always succeeds with the - span-compositor. - https://bugs.freedesktop.org/show_bug.cgi?id=56574 - - Fix call to spline intersection when evaluating whether a stoke is - visible. - - Remember to copy inferior sources when using SHM to readback the - surface for use as a source. - -Release 1.12.6 (2012-10-22 Chris Wilson <chris@chris-wilson.co.uk>) -=================================================================== -Thanks to everyone who download cairo-1.12.4 and gave us their feedback. -It truly was invaluable and has helped us to fix many portability issues -that crept in with some of the new features. This release aims to fix -those stability issues and run on a wider range of systems. - -Bug fixes ---------- - - Fix the recording surface to actually snapshot the source and so fix - PDF drawing. - - Calling XSendEvent with an XShmCompletionEvent is incompatabile with - older Xorg servers. - - Reorder CloseDisplay chain so that XShm is not reinstantiated after - shutdown, causing a potential crash if the Display was immediately - recreated using the same memory address. - - Make sure that the Xserver has attached to the SHM segment before - deleting it from the global namespace on systems that do not support - deferred deletion. - - Type1 subsetting support for PDF (and PS) was once again improved to - work with a larger number of PDF readers. - - GLESv2 build fixes and improved support for embedded GPUs. - - Tweak the invisible pen detection for applications that are currently - using too large values for geometric tolerance. - - A build fix for older freetype libraries. - - -Release 1.12.4 (2012-10-05 Chris Wilson <chris@chris-wilson.co.uk>) -=================================================================== -More bugs, and more importantly, more fixes. On the cairo-gl side, we -have refinements to the MSAA compositor which enables hardware -acceleration of comparatively low-quality antialiasing - which is useful -in animations and on very high density screens. For cairo-xlib, we have -finally enabled SHM transport for image transfers to and from the X -server. A long standing required feature, SHM transport offers a notable -reduction in rendering latency by reducing the number of copies -required to upload image data - given hardware and driver support, -cairo-xlib can now perform zero copy uploads onto the GPU. And as usual -Adrian Johnson has been very busy fixing many different corner cases in -cairo-pdf, impoving opacity groups and font subsetting. Last, but not -least, for cairo-image Søren Sandmann Pedersen added support for -rendering glyphs to pixman and using that from within cairo. The new -glyph rendering facility reduces the overhead for setting up the -compositing operation, improving glyph thoughput for the image backend -by a factor of about 4. And before he did so, he also fixed up a few -bugs in the existing glyph rendering code. So many thanks to Andrea -Canciani, Adrian Johnson, Chuanbo Weng, Dongyeon Kim, Henry Song, Martin -Robinson, Søren Sandmann Pedersen and Uli Schlachter for their -contributions, finding and fixing bugs. - -Bug fixes ---------- - - Interior boxes were being dropped when amalgamating regions during - tesselation. - https://bugs.freedesktop.org/show_bug.cgi?id=49446 - - Allow building without gtk-doc installed - - Invalid edge generation whilst reducing complex polygons. - https://bugs.freedesktop.org/show_bug.cgi?id=50852 - - Stroking around tight cusps - - Use locale correct formats for reading font subsetting and valid - buffers. - https://bugs.freedesktop.org/show_bug.cgi?id=51443 - - Ensure that the type1 subset includes all the glyph encodings - https://bugs.freedesktop.org/show_bug.cgi?id=53040 - - Upload the whole source for a repeating pattern. - https://bugs.freedesktop.org/show_bug.cgi?id=51910 - - Fix damage tracking to handle continuation chunks corectly and so - prevent crashes on win32. - https://bugs.freedesktop.org/show_bug.cgi?id=53384 - - Avoid emitting miter joins for degenerate line segments - https://bugzilla.mozilla.org/show_bug.cgi?id=407107 - - Convert the relative path semgents into the backend coordinates - and then back again to user coordinates (cairo_copy_path, - cairo_append_path) - https://bugs.freedesktop.org/show_bug.cgi?id=54732 - - Fix extents computations for a degenerate path consisting only of a - move-to - https://bugs.freedesktop.org/show_bug.cgi?id=54549 - - Prevent crashing on a degenerate project edge after polygon - intersection - https://bugs.freedesktop.org/show_bug.cgi?id=54822 - - - -Release 1.12.2 (2012-04-29 Chris Wilson <chris@chris-wilson.co.uk>) -=================================================================== -After such a long gestation period for the release of Cairo 1.12, we -inevitably accumulated a few bugs that were flushed out by broadening the -test base. Thanks to everybody who tried the release, apologies to any one -unfortunate enough to encounter a bug and many thanks for reporting it. As -a result Adrian Johnson, Alexandros Frantzis, Andrea Canciani, Kalev -Lember, Maarten Bosman, Marcus Meissner, Nis Martensen and Uli Schlachter -have squashed many more bugs and improved the documentation. I would -strongly recommend everyone to upgrade to cairo-1.12.2. --Chris - -Bug fixes ---------- - - Allow applications to create 0x0 xlib surfaces, such as used by LibreOffice. - https://bugs.freedesktop.org/show_bug.cgi?id=49118 - - Trim composite extents for SOURCE/CLEAR operators to the mask. - - Use fallback fonts in PDF for unhandled computed glyph widths - https://bugs.freedesktop.org/show_bug.cgi?id=48349 - - Handle snapshots of recording surfaces for analysing pattern extents. - Fixes a regression of reporting the PDF bounding box as being the page size. - - Fix allocation size for PDF pattern ids. - Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=49089 - - Fix emission of rectilinear dashed segments, with and without scaling, and - application of degenerate line joins. - - Clamp unbounded fixup polygons to the clip extents. - - Prevent infinite loop due to rounding errors whilst incrementing along dashes. - - Prevent overflow for inline a8 span filling. - - Miscellaneous build fixes for Cygwin on Windows and Solaris. - -Release 1.12.0 (2012-03-23 Chris Wilson <chris@chris-wilson.co.uk>) -=================================================================== -It's taken over 18 months, but the wait is finally over. A new cairo release! -We are pleased to annouce a new stable release of Cairo that brings many -new features and performance improvements, all whilst maintaining -compatibility with cairo-1.0 and all releases since. We recommend anyone -using a previous release of Cairo to upgrade to 1.12.0. - -The major feature of this release is the introduction of a new procedural -pattern; the mesh gradient. This, albeit complex, gradient is constructed -from a set of cubic Bezier patches and is a superset of all other gradient -surfaces which allows for the construction of incredibily detailed patterns. -In PDF parlance, the mesh gradient corresponds with type 7 patterns. Many -thanks to Andrea Canciani for bringing this to Cairo, and for his work on -making gradient handling robust. - -Not content with just adding another procedural pattern, Cairo 1.12 also -adds new API to create a callback pattern, -cairo_pattern_create_raster_source, that allows the application to -provide the pixel data for the region of interest at the time of -rendering. This can be used for instance, by an application to decode -compressed images on demand and to keep a cache of those decompressed -images, independently of Cairo. When combined with the recording -surface, it should form a useful basis for a deferred renderer. - -With the release of cairo-1.12, we also introduce a new supported -backend for interoperating with X using XCB. Uli Schlachter, also -maintainer of awesome and contributor to libxcb, has volunteered to -maintain cairo-xcb for us. Thanks Uli! - -For cairo-1.12, we have also added some common API to address any -surface as an image and so allow direct modification of the raster data. -Previously, only the Quartz and Win32 backends supported a very narrow -interface to allow for efficient pixel upload. Now with -cairo_surface_create_similar_image, cairo_surface_map_to_image, and -cairo_surface_unmap_image, Cairo exports a consistent method for -treating those surfaces as an image and so allow modification inplace. -These are the same routines used internally, and should support -efficient transfer or direct mapping of the target surfaces as -applicable. - -Another focus over the past year has been to address many performance -issues, without sacrificing the composition model. To accomplish the -goal, once again the rasterisation pipeline was overhauled and made -explicit, giving the backends the freedom to implement their own -specific pipeline whilst also providing a library of common routines -from which to build the pipeline. For instance, this allows the image -backend and the gl backend to composite scan line primitives inplace, -and to then implement custom fallbacks to catch the corner cases that do -not map onto their fastest paths. Similarly, this allows for the Xlib -backend to implement trapezoidation without compromising the other -backends, yet still allow for the pipeline to be used elsewhere for -testing and fallbacks. Clipping was once again overhauled, so that the -common cases for the raster pipelines could be captured and processed -with fast paths with the emphasis on performing geometric clipping to -reduce the frequency of using multi-pass clipmasks. Stroking was made -faster, both by providing specialised fast-paths for simple, yet frequent, -cases (such as stroking around a rectangle) and by reducing the number -of edges generated by the general stroker. - -As part of the focus on performance, Cairo 1.12 introduces some -antialias hints (NONE, FAST, GOOD, BEST) that are interpolated by the -rasterisers to fine tune their performance versus quality. Cairo 1.12 -also introduces a new observation architecture, -cairo_surface_observer_t, which can be used to analyse the amount of -time consumed by drawing commands and help identify inefficiencies in -both Cairo and the application. - -Last, but by no means least, the OpenGL backend has seen significant -work including the port to GLESv2 and the exploitation of advanced -hardware features. Interesting times. - -As always, I would like to thank everyone who contributed to Cairo, -not only through writing code, but also submitting documentation, bug -reports, suggestions and generally having fun with Cairo! In particular -though this release could not have happened without the efforts of -Adrian Johnson, Alexandros Frantiz, Andrea Canicani, Martin Robinson, -Nis Martensen, and Uli Schlachter. Thanks. --Chris - -Snapshot 1.11.4 (2012-13-12) -============================ -The cairo community is pleased to finally announce the long aniticpated -release candidate for 1.12, 1.11.4, of the cairo graphics library. This -is the first major update to cairo in over a year and brings a large -number of new features; undoubtably a few bugs as well. - -While many people have contributed and have helped to test the release, -providing feedback on 1.10 and suggesting improvements, this release -is the result of a few persevering souls who deserve recognition for their -outstanding contributions: Andrea Canciani (all round bug fixing, -performance tuning and master of the gradients), Adrian Johnson (PDF -supremo) and Uli Schlachter (who stepped forward as maintainer for the -XCB backend). - -Major additions since 1.11.2: - - * cairo_surface_map_to_image API for pixel level access to any surface - - * New antialias hints to control the trade-off between speed and quality - - * A callback pattern, cairo_pattern_create_raster_source, for lazy - decoding of image data. - - * cairo_surface_observer_t, a new type of surface to gather performance - statistics - - * XCB as a supported backend - - * A rewritten compositor pipeline for performance improvements for, but not - limited to, the xlib and image backends. - From ION and PineView through to SandyBridge, every machine I have shows - across the board performance improvement on the cairo-traces: - - i5-2520m gnome-system-monitor: 5.97x speedup - pnv gnome-system-monitor: 4.86x speedup - i5-2520m firefox-asteroids: 4.66x speedup - pnv firefox-asteroids: 4.43x speedup - image firefox-canvas: 3.82x speedup - i5-2520m firefox-canvas-alpha: 3.49x speedup - image firefox-asteroids: 2.87x speedup - pnv firefox-talos-svg: 2.83x speedup - ion grads-heat-map: 2.75x speedup - pnv firefox-canvas-alpha: 2.66x speedup - image gnome-system-monitor: 2.66x speedup - image swfdec-giant-steps: 2.46x speedup - image firefox-canvas-alpha: 2.14x speedup - i5-2520m firefox-talos-svg: 2.03x speedup - image grads-heat-map: 2.02x speedup - ion gnome-system-monitor: 2.00x speedup - pnv firefox-particles: 1.99x speedup - i5-2520m grads-heat-map: 1.96x speedup - pnv firefox-canvas: 1.92x speedup - ion firefox-particles: 1.80x speedup - image poppler-reseau: 1.77x speedup - pnv xfce4-terminal-a1: 1.72x speedup - image firefox-talos-svg: 1.65x speedup - pnv grads-heat-map: 1.63x speedup - i5-2520m firefox-canvas: 1.63x speedup - pnv swfdec-youtube: 1.62x speedup - image ocitysmap: 1.59x speedup - i5-2520m firefox-fishbowl: 1.56x speedup - i5-2520m poppler-reseau: 1.50x speedup - i5-2520m evolution: 1.50x speedup - i5-2520m midori-zoomed: 1.43x speedup - pnv firefox-planet-gnome: 1.42x speedup - i5-2520m firefox-talos-gfx: 1.41x speedup - i5-2520m gvim: 1.41x speedup - pnv ocitysmap: 1.37x speedup - image poppler: 1.31x speedup - ion firefox-canvas-alpha: 1.35x speedup - ion firefox-talos-svg: 1.34x speedup - i5-2520m ocitysmap: 1.32x speedup - pnv poppler-reseau: 1.31x speedup - i5-2520m firefox-planet-gnome: 1.31x speedup - pnv firefox-fishbowl: 1.30x speedup - pnv evolution: 1.28x speedup - image gvim: 1.27x speedup - i5-2520m swfdec-youtube: 1.25x speedup - pnv gnome-terminal-vim: 1.27x speedup - pnv gvim: 1.25x speedup - image firefox-planet-gnome: 1.25x speedup - image swfdec-youtube: 1.25x speedup - ... - -And a plethora of minor improvements everywhere! --Chris - -Snapshot 1.11.2 (2011-01-23) -=========================== - -In this first snapshot along the way to cairo-1.12.0, we are very excited -to announce the introduction of Bezier surface gradients, known as type -6/7 gradients in PS/PDF parlance. This is the culmination of much work by -the dynamic duo: Adrian Johnson and Andrea Canciani. Thanks guys! - -Also, I want to warmly welcome Uli Schlachter who recently joined the -Cairo community on a mission. That mission is to make cairo-xcb a -supported backend for 1.12. And for this snapshot he has made great -strides in fixing all the bugs I had left behind. Thanks Uli! - -And we have also seen a new contributor, Alexandros Frantzis, who has -begun bringing up cairo-gl for GLESv2 devices. Thanks Alex! - -And lastly, I must also thank Adrian and Andrea for the vast numbers of -bugs that they have tackled between them, fixing all those little corner -cases that lie hidden until too late. - -API additions: - -The ability to construct piece-wise Bezier surface gradients: - - cairo_pattern_create_mesh - - constructs a pattern of type CAIRO_PATTERN_TYPE_MESH using - - cairo_pattern_mesh_begin_patch - cairo_pattern_mesh_end_patch - cairo_pattern_mesh_curve_to - cairo_pattern_mesh_line_to - cairo_pattern_mesh_move_to - cairo_pattern_mesh_set_control_point - cairo_pattern_mesh_set_corner_color_rgb - cairo_pattern_mesh_set_corner_color_rgba - cairo_pattern_mesh_get_patch_count - cairo_pattern_mesh_get_path - cairo_pattern_mesh_get_corner_color_rgba - cairo_pattern_mesh_get_control_point - -The introduction of a unique ID accessible via the mime data type: - CAIRO_MIME_TYPE_UNIQUE_ID - - - - - -Release 1.10.2 (2010-12-25 Chris Wilson <chris@chris-wilson.co.uk>) -=================================================================== -The cairo community is pleased to announce the 1.10.2 release of the -cairo graphics library. This is the first update to cairo's stable 1.10 -series and contains a large number of bug fixes. - -While many people have contributed and have help to test the release, -2 people deserve special recognition for their efforts in tracking down -and fixing bugs, Andrea Canciani and Adrian Johnson. Thanks to their -tremendous efforts, and of all cairo contributors, it is much -appreciated. - -We recommend everyone upgrade to cairo 1.10.2 and hope that everyone -will continue to have lots of fun with cairo! - --Chris - -Bug fixes ---------- - - Fix embedding of grayscale jpegs in PS. - https://bugs.freedesktop.org/show_bug.cgi?id=31632 - - Fix the reported path of extents containing a curve. - - Fix the compositing of unaligned boxes. - - Reset the clipper in PDF upon finish. - - Fix degenerates arcs to become a degenerate line. - - Build support for autoconf 2.67 - - Fix painting of transformed patterns in PS - - Fix the EPS bounding box for PS - https://bugs.freedesktop.org/show_bug.cgi?id=24688 - - Fix the missing content for EPS - https://bugs.freedesktop.org/show_bug.cgi?id=24688 - - Fix regression upon changing page size in PS/PDF - https://bugs.freedesktop.org/show_bug.cgi?id=24691 - - Only use ActualText with PDF-1.5 documents - - Fix the bbox for type1 fallbacks. - - Reset the color after ending the context in PDF - https://bugs.freedesktop.org/show_bug.cgi?id=31140 - - Fix the advance of subsetted type1 fonts - https://bugs.freedesktop.org/show_bug.cgi?id=31062 - - Fix handling of EXTEND_NONE gradients for PDF - - Restrict in-place optimisation for a8 image masks with SOURCE - - -Release 1.10.0 (2010-09-06 Chris Wilson <chris@chris-wilson.co.uk>) -=================================================================== -The cairo community is astounded (and flabbergast) to finally announce -the 1.10.0 release of the cairo graphics library. This is a major update -to cairo, with new features and enhanced functionality which maintains -compatibility for applications written using any previous major cairo -release, (1.8, 1.6, 1.4, 1.2, or 1.0). We recommend that anybody using -a previous version of cairo upgrade to cairo 1.10.0. - -One of the more interesting departures for cairo for this release is the -inclusion of a tracing utility, cairo-trace. cairo-trace generates a -human-readable, replayable, compact representation of the sequences of -drawing commands made by an application. This can be used to inspecting -applications to understand issues and as a means for profiling -real-world usage of cairo. - -The traces generated by cairo-trace have been collected in - - git://git.cairographics.org/git/cairo-traces - -and have driven the performance tuning of cairo over the last couple of -years. In particular, the image backend is much faster with a new -polygon rasterisation and a complete overhaul of the tessellator. Not -only is this faster, but also eliminates visual artifacts from -self-intersecting strokes. Not only has cairo-trace been driving -performance improvements within cairo, but as a repeatable means of -driving complex graphics it has been used to tune OpenGL, DDX, and -pixman. - -Cairo's API has been extended to better support printing, notably -through the ability to include a single compressed representation of an -image for patterns used throughout a document, leading to dramatic file -size reductions. Also the meta-surface used to record the vector -commands compromising a drawing sequence is now exposed as a -CAIRO_SURFACE_TYPE_RECORDING, along with a new surface that is a child of a -larger surface, CAIRO_SURFACE_TYPE_SUBSURFACE. One typical usage of a -subsurface would be as a source glyph in a texture atlas, or as a -restricted subwindow within a canvas. - -Cairo's API has also resurrected the RGB16 format from the past as -the prevalence of 16-bit framebuffers has not diminished and is a -fore-taste of the extended format support we anticipate in the future. -Increasing cairo's utility, we introduce the cairo_region_t for handling -sets of pixel aligned rectangles commonly used in graphics applications. -This is a merger of the GdkRegion and the pixman_region_t, hopefully -providing the utility of the former with the speed of the latter. - -Furthermore cairo has been reworked to interoperate more closely with -various acceleration architectures, gaining the ability to share -those hardware resources through the new cairo_device_t. For instance, -with the new OpenGL backend that supersedes the Glitz backend, hardware -and rendering operations can be shared between a classic OpenGL -application mixing libVA for the hardware assisted video decode with -cairo for high quality overlays all within the same OpenGL canvas. - -Many thanks for the hard work of Adrian Johnson, Andrea Canciani, Behdad -Esfahbod, Benjamin Otte, Carl Worth, Carlos Garcia Campos, Chris Wilson, -Eric Anholt, Jeff Muizelaar, Karl Tomlinson, M Joonas Pihlaja, Søren -Sandmann Pedersen and many others that have contributed over the last -couple of years to cairo. Thank you all! - -Snapshot 1.9.14 (2010-07-26) -============================ - - A quiet couple of weeks, hopefully Cairo is seeing widescale deployment and - we are being to see the results of the stabilisation effort. Clipping bugs - seems to have been the order of the last couple of weeks, with a couple - reported and duly fixed. Thank you Igor Nikitin and Karl Tomlinsion for - finding those regressions. At this point all that seems to remain to do is - to fix the outstanding regressions in the PDF backend... - -Bugs fixes ----------- - - Clip doesn't work for text on the image backend - https://bugs.freedesktop.org/show_bug.cgi?id=29008 - - Add explicit dependency for cxx - https://bugs.freedesktop.org/show_bug.cgi?id=29114 - - Fix regressions in reporting clip extents - https://bugs.freedesktop.org/show_bug.cgi?id=29120 - https://bugs.freedesktop.org/show_bug.cgi?id=29121 - https://bugs.freedesktop.org/show_bug.cgi?id=29122 - https://bugs.freedesktop.org/show_bug.cgi?id=29124 - https://bugs.freedesktop.org/show_bug.cgi?id=29125 - - -Snapshot 1.9.12 (2010-07-12) -============================ - - A couple of weeks spent fixing those annoying bugs and cleaning up the build - system; the list of outstanding tasks to complete for the stable release is - finally shrinking. The chief bug fixer has been Benjamin Otte who not only - made sure that the public API is consistent and being tested for its - consistency, but also ensured that the documentation was up-to-date and - spent time clarifying cases where even the Cairo developers have come - unstuck in the past. Many thanks, Benjamin. However, he was not alone, - as Andrea Canciani continued his fine work in isolating broken corner cases - and proceeding to fix them, and tidying up the quartz backend. And last, but - definitely not least, M Joonas Pihlaja tried building Cairo across a - perverse range of systems and fixed up all the loose bits of code that came - unravelled. Thanks everybody! - -API Changes ------------ - - cairo_surface_set_mime_data, cairo_surface_get_mime_data: - - The length parameter is now an unsigned long (as opposed to an unsigned - int). The parameter is intended to be an equivalent to a size_t without - requiring POSIX types and be large enough to store the size of the - largest possible allocation. - - cairo_gl_surface_create_for_texture: - - This a new surface constructor for cairo-gl that explicitly enables - render-to-texture for foreign, i.e. application, textures. - - cairo_region_xor, cairo_region_xor_rectangle - - A couple of utility routines add to the region handling interface for - the purpose of replacing existing GdkRegion functionality. - -Bugs fixes ----------- - - https://bugs.launchpad.net/ubuntu/+source/cairo/+bug/600622 - - Inkscape was caught in the act of attempting to modify a finished surface. - Unfortunately, we had the ordering of our guards and assertions wrong and - so an ordinary application error was triggering an assert in Cairo. This - lead Benjamin to add a test case to ensure that the entire public API - could handle erroneous input and then proceeded to fix a whole slew of - uncovered bugs. - - - https://bugs.freedesktop.org/show_bug.cgi?id=28888 - - A regression introduced by the special casing of uploading images to an - xlib surface in-place which was ignoring the translation applied to the - image. - - -Snapshot 1.9.10 (2010-06-26) -============================ - - The first "quick" snapshot in the run up to the stable release. The - last snapshot was picked up by the bleeding edge distributions and so the - bug reports have to started to roll in. The most frequent of these are the - introduction of rendering errors by applications that modify a surface - without subsequently calling cairo_surface_mark_dirty(). Make sure the - application developers are aware of increased reliance on strict use of the - Cairo API before 1.10 is released! - - The usual slew of bugs reported and we would like to thank Zoxc for - contributing the WGL interface for cairo-gl, and finding more build - failures on win32. And it just wouldn't be a 1.9 snapshot unless - Benjamin Otte improved the error handling within cairo-gl, as well as - isolating and fixing some more errors in the test suite. The biggest bug of - the snapshot turned out to be a major sign extension issue that had lain - hidden for many years and was suddenly exposed by incorrectly rounding - rectangles when performing non-antialiased rendering. Also to the relief - of many we have included the downstream patch to honour the user's LCD - filtering preferences for subpixel rendering of fonts. The interface - remains private for the time being, whilst the proposed public API is - finalized. - -API changes ------------ - None. - -Snapshot 1.9.8 (2010-06-12) -=========================== - - One major API changes since the last snapshot, and a whole slew of bugs - fixed and inconsistencies eliminated. Far too many bugs fixed to - individually identify. We need to thank Benjamin Otte for his fantastic - work on the cairo-gl backend making it faster and more robust, Andrea - Canciani for finding so many bugs and developing test cases for them, as - well fixing them. And last but not least we must all thank Adrian Johnson for - continuing to eliminate bugs and improving the PostScript and PDF backends. - - This snapshot represents almost 4 months of bug fixing, bringing Cairo to - a point where we consider it almost ready to be a candidate for release. - There are a few known bugs left to be fixed, being tracked in - https://bugs.freedesktop.org/show_bug.cgi?id=24384, so please give Cairo a - whirl and report any regressions. The plan is to release a new snapshot - every other week leading to a 1.10 release with a target date of - 2010-08-16. - -API additions -------------- - CAIRO_FORMAT_RGB16_565 - - 16 bit devices still remain popular, and so with great demand, - CAIRO_FORMAT_RGB16_565 has been restored enabling applications to create - and use 16 bit images as sources and render targets. - - cairo_surface_create_for_rectangle() - - It is common practice to cut an image up into many smaller pieces and use - each of those as a source - a technique called texture atlasing. - cairo_surface_create_for_rectangle() extends Cairo to directly support use - of these subregions of another cairo_surface_t both as a source and as a - render target. - - cairo_region_create() - cairo_region_create_rectangle() - cairo_region_create_rectangles() - cairo_region_copy() - cairo_region_reference() - cairo_region_destroy() - cairo_region_equal() - cairo_region_status() - cairo_region_get_extents() - cairo_region_num_rectangles() - cairo_region_get_rectangle() - cairo_region_is_empty() - cairo_region_contains_rectangle() - cairo_region_contains_point() - cairo_region_translate() - cairo_region_subtract() - cairo_region_subtract_rectangle() - cairo_region_intersect() - cairo_region_intersect_rectangle() - cairo_region_union() - cairo_region_union_rectangle() - - The Cairo region API was actually added a couple of snapshots ago, but we - forgot to mention it at the time. A simple API for the handling of - rectangular pixel-aligned regions by Soeren Sandmann. - - -Backend-specific improvements ------------------------------ -cairo-gl - - Benjamin Otte made more than 200 commits in which he refactored the cairo-gl - backend, reducing a lot of code duplication and enabled him to begin working - on improving performance by reducing state changes and associated overhead. - -cairo-xlib - - Access to the underlying connection to the Display is now thread-safe - enabling cairo-xlib to be used in a multi-threaded application without fear - of random corruption. Thanks Benjamin Otte! - - cairo-xlib will now attempt to use PolyModeImprecise when compositing - trapezoids (i.e. a fill or a stroke operation with a non-trivial path) which - should allow hardware drivers more scope for accelerating the operation at - the cost of potentially incurring minute rendering errors. The mode can be - forced back to PolyModePrecise by setting the antialias parameter to - CAIRO_ANTIALIAS_SUBPIXEL. - -cairo-svg - - A notable improvement was contributed by Alexander Shulgin to enable SVG to - reference external image through the use an extended MIME data type. - -Snapshot 1.9.6 (2010-02-19) -=========================== -API additions -------------- - Add cairo_device_t - - The device is a generic method for accessing the underlying interface - with the native graphics subsystem, typically the X connection or - perhaps the GL context. By exposing a cairo_device_t on a surface and - its various methods we enable finer control over interoperability with - external interactions of the device by applications. The use case in - mind is, for example, a multi-threaded gstreamer which needs to serialise - its own direct access to the device along with Cairo's across many - threads. - - Secondly, the cairo_device_t is a unifying API for the mismash of - backend specific methods for controlling creation of surfaces with - explicit devices and a convenient hook for debugging and introspection. - - The principal components of the API are the memory management of: - - cairo_device_reference(), - cairo_device_finish() and - cairo_device_destroy(); - - along with a pair of routines for serialising interaction: - - cairo_device_acquire() and - cairo_device_release() - - and a method to flush any outstanding accesses: - - cairo_device_flush(). - - The device for a particular surface may be retrieved using: - - cairo_surface_get_device(). - - The device returned is owned by the surface. - -API changes (to API new in the cairo 1.9.x series) --------------------------------------------------- - cairo_recording_surface_create() - cairo_recording_surface_ink_extents() - - These are the replacement names for the functions previously named - cairo_meta_surface_create and cairo_meta_surface_ink_extents. - - cairo_surface_set_mime_data - - This interface is now changed such that the MIME data will be - detached if the surface is modified at all. This guarantees that - the MIME data will not become out of synch due to surface - modifications, and also means that for the MIME data to be useful, - it must be set after all modifications to the surface are - complete. - -API removal (of experiment API) -------------------------------- - The cairo-glitz backend is removed entirely, (in favor of the new - cairo-gl backend). See below for more on cairo-gl. - -Generic fixes -------------- - - Many improvements for drawing of dashed strokes - - Fix incorrect handling of negative offset - Faster computation of first dash (avoids near-infinite looping) - Approximate extremely fine dash patterns with appropriate alpha value - - Optimize spans-based renderers for repeated rows, (such as in a rounded rectangle) - -Backend-specific improvements ------------------------------ -cairo-drm - - This is a new, direct-rendering backend that supports Intel graphics - chipsets in the i915 and i965 families. It's still experimental and - will likely remain that way for a while. It's already got extremely - good performance on the hardware it supports, so if nothing else - provides a working proof and performance target for the cairo-gl - work for Intel graphics. - -cairo-gl - - Start using GLSL to accelerate many operations. Many thanks to Eric - Anholt and T. Zachary Laine for this work. For the first time, we - have what looks like what will be a very compelling OpenGL-based - backend for cairo (in terms of both quality and performance). - - See this writeup from Eric for more details on recent progress of - cairo-gl (which he presented at FOSDEM 2010): - - http://anholt.livejournal.com/42146.html - -cairo-image - - The image backend is made dramatically faster (3-5 times faster for - benchmarks consisting primarily of glyph rendering). - -cairo-quartz fixes: - - Many fixes from Robert O'Callahan and Andrea Canciani including: - - Fixed gradient pattern painting - Improved A8 image handling - Fixes for "unbounded" and other compositing operators - -cairo-pdf fixes: - - Improvements to embedding of JPEG and JPEG2000 data. - -cairo-ps fixes: - - Fix printing of rotated user fonts. - -Snapshot 1.9.4 (2009-10-15) -=========================== -API additions: - - cairo_meta_surface_create() - cairo_meta_surface_ink_extents() - - Finally exporting the internal meta-surface so that applications - have a method to record and replay a sequence of drawing commands. - - cairo_in_clip() - - Determines whether a given point is inside the current clip. - ??? Should this be called cairo_in_paint() instead? in-clip is the test - that is performed, but in-paint would be similar to in-fill and in-stroke. - -New utilities: - - cairo-test-trace - - A companion to cairo-perf-trace, this utility replays a trace against - multiple targets in parallel and looks for differences in the output, - and then records any drawing commands that cause a failure. - Future plans: - Further minimisation of the fail trace using "delta debugging". - More control over test/reference targets. - -Backend improvements: - - xlib - - Server-side gradients. The theory is that we can offload computation - of gradients to the GPU and avoid pushing large images over the - connection. Even if the driver has to fallback and use pixman to render - a temporary source, it should be able to do so in a more efficient manner - than Cairo itself. However, cairo-perf suggests otherwise: - - On tiny, Celeron/i915: - - before: firefox-20090601 211.585 - after: firefox-20090601 270.939 - - and on tiger, CoreDuo/nvidia: - - before: firefox-20090601 70.143 - after: firefox-20090601 87.326 - - In particular, looking at tiny: - - xlib-rgba paint-with-alpha_linear-rgba_over-512 47.11 (47.16 0.05%) -> 123.42 (123.72 0.13%): 2.62x slowdown - █▋ - xlib-rgba paint-with-alpha_linear3-rgba_over-512 47.27 (47.32 0.04%) -> 123.78 (124.04 0.13%): 2.62x slowdown - █▋ - - -New experimental backends: - - QT - - OpenVG - The initial work was done by Øyvind KolÃ¥s, and made ready for - inclusion by Pierre Tardy. - - OpenGL - An advanced OpenGL compositor. The aim is to write a integrate - directed rendering using OpenGL at a high-level into Cairo. In - contrast to the previous attempt using Glitz which tried to - implement the RENDER protocol on top of OpenGL, using the - high-level interface should permit greater flexibility and - more offloading onto the GPU. - The initial work on the backend was performed by Eric Anholt. - -Long standing bugs fixed: - - Self-intersecting strokes. - - A long standing bug where the coverage from overlapping semi-opaque - strokes (including neighbouring edges) was simply summed in lieu of - a costly global calculation has been fixed (by performing the costly - global calculation!) In order to mitigate the extra cost, the - tessellator has been overhauled and tune, which handles the fallback - for when we are unable to use the new span rasteriser on the stroke - (e.g. when using the current RENDER protocol). The large number of - pixel artefacts that implementing self-intersection elimination - removes is ample justification for the potential performance - regression. If you unfortunately do suffer a substantial performance - regression in your application, please consider obtaining a - cairo-trace and submitting it to us for analysis and inclusion into - our performance suite. - -Special thanks: - - To the AuroraUX team for providing access to one of their OpenSolaris - machines for cairo and pixman development. http://www.auroraux.org/ - -Snapshot 1.9.2 (2009-06-12) -=========================== -API additions: - - cairo_surface_set_mime_data() - cairo_surface_get_mime_data() - - Should this take unsigned int, unsigned long or size_t for the length - parameter? (Some datasets may be >4GiB in size.) - - Associate an alternate, compressed, representation for a surface. - Currently: - "image/jp2" (JPEG2000) is understood by PDF >= 1.5 - "image/jpeg" is understood by PDF,PS,SVG,win32-printing. - "image/png" is understood by SVG. - - cairo_pdf_version_t - cairo_pdf_surface_restrict_to_version() - cairo_pdf_get_versions() - cairo_pdf_version_to_string() - - Similar to restrict to version and level found in SVG and PS, - these limit the features used in the output to comply with the PDF - specification for that version. - - CAIRO_STATUS_INVALID_SIZE - Indicates that the request surface size is not supported by the - backend. This generally indicates that the request is too large. - - CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED - Indicates that a required callback for a user-font was not implemented. - - CAIRO_STATUS_LAST_STATUS - This is a special value to indicate the number of status values enumerated - at compile time. (This may differ to the number known at run-time.) - - The built-in twin font is now called "@cairo:" and supports a limited set - of options like "@cairo:mono". Where are these specified? - - cairo_in_fill() now uses HTML Canvas semantics, all edges are inside. - -New experimental backends: - - CairoScript - -New utility: - - cairo-trace and cairo-perf-trace - - cairo-trace generates a human-readable, replayable, compact(-ish!) - representation of the sequences of drawing commands made by an - application. - - Under the util/cairo-script directory is a library to replay traces. - - perf/cairo-perf-trace replays traces against multiple backends - and makes useful benchmark reports. This is integrated with - 'make perf'. You may collect your own traces or take advantage - of traces collected by the community: - - git://git.cairographics.org/git/cairo-traces - - (Put this into perf/cairo-traces to run these as part of "make perf".) - - There is additional WIP in building a debugging tool for cairo applications - based on CairoScript (currently very preliminary, mostly serves to show - that GtkSourceView is too slow) : - - people.freedesktop.org:~ickle/sphinx - -Test suite overhaul: - - The test suite is undergoing an overhaul, primarily to improve its speed - and utility. (Expect more changes in the near future to improve XFAIL - handling.) - -Optimisations: - polygon rasterisation! Joonas implemented the Tor polygon scan converter, - on typical geometry is about 30% faster for the image backend. - - Bovine Polaroids! For those not in on the joke, this is the long - awaited "copy-on-write snapshot" or "COW snapshot" support. The - user-visible feature is that including the same image multiple times - into a PDF file should result in only a single instance of that - image in the final output. This is unlike previous versions of cairo - which would generate very large PDF files with multiple copies of - the same image. Adrian says that the PDF is not quite working as - well as it should yet, so we hope for further improvements before - cairo 1.10. - -Bug fixes: - - EXTEND_PAD. - - Better handling of large scale-factors on image patterns. - - Emit /Interpolate for PS,PDF images. - - Global glyph cache - cap on the total number of inactive glyphs, - should prove fairer for fonts with larger glyph sets. - - Compilation without fontconfig - - Improved handling of low-bitdepth sources (e.g. copying the contents - of 16-bit xserver windows) - -Regressions: - - cairo_traps_extract_region >10x slower. Fix pending. - -Still to come: - - Region tracking API (ssp) for damage tracking, hit testing etc - mime-surface - - An expiremental OpenGL backend? - - Tweaks to tessellator, allocations of patterns, delayed - initialisation of the xlib backend (reduce the cairo overhead of - render_bench by ~80%). - - -Release 1.8.8 (2009-06-16 Chris Wilson <chris@chris-wilson.co.uk>) -================================================================== -The cairo community is pleased to announce the 1.8.8 release of the -cairo graphics library. This is the fourth update to cairo's stable -1.8 series and contains a small number of bug fixes (in particular a -few corrections to the documentation and a few fixes in the FreeType font -backend). This is being released just over six months after cairo 1.8.6. - -We recommend that everyone using cairo upgrade to 1.8.8. - --Chris - -Build fixes ------------ -There were reports of incompatibilities with the autotools bundled in with -the 1.8.6 tarball. This release has been built with automake-1.10.2 and -autoconf-2.63. - -The configure check for FreeType has been improved: - - typo in check for version of freetype in configure script - https://bugs.freedesktop.org/show_bug.cgi?id=19283 - -Compilation on 64-bit MacOS/X fixes: - - Cannot build cairo_quartz_font_face_create_for_atsu_font_id on 64-bit Mac OS X - https://bugs.freedesktop.org/show_bug.cgi?id=15702 - -Bug fixes ---------- -Uninitialised status return within _cairo_clip_intersect_mask(). This caused -random crashes and general mayhem as an error could be generated causing all -rendering to the context to stop. - -Avoid transforming nearly-degenerate matrices into degenerate matrices: - - Painting stops in this case, using -moz-transform: scale, rotate and video - https://bugzilla.mozilla.org/show_bug.cgi?id=467423 - -A few FreeType font handling bugs were fixed: - - Rendering with PANGO_GRAVITY_EAST leads to different results with image and pdf - https://bugs.freedesktop.org/show_bug.cgi?id=21985 - - Don't call FT_Done_Face() on faces we did not create - - zombie ft_font_face / ft_unscaled_font mutual referencing problems - http://bugs.freedesktop.org/show_bug.cgi?id=21706 - -Ensure win32 font backend sets the return value to -1 (indicating the absent -glyph) if the font index lookup for the unicode character fails. And -similarly fix a bug where a fatal error was raised for an invalid glyph. - - cairo_scaled_font_glyph_extents breaks with invalid glyph id - http://bugs.freedesktop.org/show_bug.cgi?id=20255 - -Various improvements to the documentation, reported by Truc Troung: - - https://bugs.freedesktop.org/show_bug.cgi?id=20095 - https://bugs.freedesktop.org/show_bug.cgi?id=20154 - https://bugs.freedesktop.org/show_bug.cgi?id=20180 - https://bugs.freedesktop.org/show_bug.cgi?id=20183 - https://bugs.freedesktop.org/show_bug.cgi?id=20182 - https://bugs.freedesktop.org/show_bug.cgi?id=20441 - - -Release 1.8.6 (2008-12-13 Chris Wilson <chris@chris-wilson.co.uk>) -================================================================== -The cairo community is pleased to announce the 1.8.6 release of the -cairo graphics library. This is the third update to cairo's stable -1.8 series and contains a small number of bug fixes (in particular a -few fixes for failures of cairo 1.8.4 on Quartz and PDF, and build fixes for -a couple of backends). This is being released just under a month after -cairo 1.8.4. - -We recommend that everyone using cairo upgrade to 1.8.6. - --Chris - -Build fixes ------------ -Fix build of DirectFB backend with debugging enabled: - - Bug in _cairo_directfb_surface_release_source_image function - http://bugs.freedesktop.org/show_bug.cgi?id=18322 - -Fix build on OS/2. - -Bug fixes ---------- -Workaround a mis-compilation of cairo_matrix_invert() that generated invalid -matrices and triggered assertion failures later. The issue was reported by -Peter Hercek. - -Invalid computation of the modulus: - - https://bugzilla.mozilla.org/show_bug.cgi?id=466258 - -Invalid referencing of patterns in the Quartz backend: - - Failed assertion `CAIRO_REFERENCE_COUNT_HAS_REFERENCE - (&pattern->ref_count)' when using cairo quartz backend - http://bugs.freedesktop.org/show_bug.cgi?id=18632 - -Invalid references to glyphs after early culling, causing segmentation faults -in the PDF backend: - - http://lists.cairographics.org/archives/cairo/2008-December/015976.html - -Check for XRender in the XCB backend, or else we may attempt an invalid memory -access: - - XCB backend fails with missing render. - https://bugs.freedesktop.org/show_bug.cgi?id=18588 - -Release 1.8.4 (2008-11-14 Carl Worth <cworth@cworth.org>) -========================================================= -The cairo community is pleased to announce the 1.8.4 release of the -cairo graphics library. This is the second update to cairo's stable -1.8 series and contains a small number of bug fixes, (in particular a -few fixes for build failures of cairo 1.8.2 on various systems). This -is being released just over two weeks after cairo 1.8.2. - -We recommend that everyone using cairo upgrade to 1.8.4. - --Carl - -Build fixes ------------ -Fix build with older XRender that doesn't define RepeatNone: - - Build of xlib backend fails against old XRender (RepeatNone undeclared) - https://bugs.freedesktop.org/show_bug.cgi?id=18385 - -Fix build with bash version <= 3.0: - - doltlibtool broken on linux with bash 3.00.0 - https://bugs.freedesktop.org/show_bug.cgi?id=18363 - -Bug fixes ---------- -Avoid triggering a bug in X.org server 6.9 resulting in a hung machine -requiring a reboot: - - https://bugs.freedesktop.org/show_bug.cgi?id=15628#c2 - -Fix display of user fonts as exercised by proposed support for type3 -fonts in poppler (unsigned promotion fixes): - - Use cairo user-font for Type 3 fonts - http://lists.freedesktop.org/archives/poppler/2008-October/004181.html - -Avoid miscomputing size of fallback images required when rendering -with CLEAR, IN, or SOURCE operator to vector surfaces, (PS, PDF, SVG, -etc.). - -Be more tolerant of broken fonts when subsetting type1 fonts: - - Error handling in cairo_type1_font_subset_get_glyph_names_and_widths - http://lists.cairographics.org/archives/cairo/2008-October/015569.html - -Fix cairo_fill_extents, cairo_stroke_extents, cairo_path_extents, to -correctly allow NULL parameters as documented. - -Fix potential crash on emitting a type3 glyph after having drawn text -paths from the same font, (for example with cairo_text_path). - -Release 1.8.2 (2008-10-29 Carl Worth <cworth@cworth.org>) -========================================================= -The cairo community is pleased to announce the 1.8.2 release of the -cairo graphics library. This is the first update to cairo's stable 1.8 -series and contains a large number of bug fixes. It is being released -just over one month since cairo 1.8.0. - -This release consists primarily of bug fixes, but there is one notable -new feature, (the ability to build cairo without an external font -backend), and there are a few optimizations as well. See below for -details on these changes and the most important bug fixes. - -While many people have contributed to this release, Chris Wilson -deserves particular mention. He has contributed well over twice as -many changes to cairo since 1.8.0 than everyone else combined. We -greatly appreciate the tremendous efforts of Chris and all cairo -contributors. - -We recommend everyone upgrade to cairo 1.8.2 and hope that everyone -will have lots of fun with cairo! - --Carl - -New feature ------------ -It is now possible to build cairo without any font backend, (such as -freetype, win32 or quartz). This is most useful when the application -provides custom font rendering through the user-font API. But in the -case where no external font backend is available, and no user-font is -provided, cairo will render with a failsafe font, (a stroked font -covering visible ASCII character). (Behdad Esfahbod) - -Optimizations -------------- -Dramatically speed up compilation with dolt (removes much of the -libtool overhead) (Behdad Esfahbod with thanks to Josh Triplett). - -Several minor optimizations to tessellator (special-cased comparisons, -faster insert for skiplist, etc.) (Chris Wilson). - -Optimize away fractional translation component when doing -EXTEND_NEAREST filtering, (for better performance). - -General bug fixes ------------------ -Allow cloning sub-regions of similar surfaces to fix this bug -(Chris Wilson): - - Crafted gif file will crash firefox - [XError: 'BadAlloc (insufficient resources for operation)'] - https://bugzilla.mozilla.org/show_bug.cgi?id=424333 - -Fix some matrix confusion to fix this regression (Chris Wilson): - - Translucent star exports in a wrong way to PDF - https://bugs.launchpad.net/inkscape/+bug/234546 - -Fix some long-standing bugs with respect to properly computing the -extents of transformed, filtered surfaces (Owen Taylor, Carl Worth, -and Chris Wilson): - - Bad clipping with EXTEND_NONE - http://bugs.freedesktop.org/show_bug.cgi?id=15349 - - Improve filtering handling in cairo-pattern.c - http://bugs.freedesktop.org/show_bug.cgi?id=15367 - - Many thanks to Chris Wilson for digging out and cleaning up - these fixes. - -Fix compilation on Solaris 10 (Chris Wilson): - - Cairo requires -DREENTRANT (along with -D_POSIX_THREAD_SEMANTICS) - to compile on Solaris 10 with pthreads - https://bugs.freedesktop.org/show_bug.cgi?id=18010 - -Fix very old bug causing dashes to be rendered at the wrong length in -fallback images (Adrian Johnson) - - Dashed strokes too long in fallback images - https://bugs.freedesktop.org/show_bug.cgi?id=9189 - -Fix broken dashing when a dashed path starts outside the clip region -(Chris Wilson). - -Avoid range overflow when computing large patterns (Benjamin Otte and -Chris Wilson). - -Avoid crashing due to an invalid font with an incorrect entry in its -CMAP table (Adrian Johnson). - -Fix bugs in computing maximum size of text requests that can be sent -with the Render extension, (avoiding potential crashes when rendering -large amounts of text) (Behdad Esfahbod and Chris Wilson). - -Fix rendering of operators unbounded by the mask (Chris Wilson). - -Fix compilation on systems without compiler support for a native -64-bit type (Chris Wilson). - -Fix several cases of missing error-status propagation. (Chris Wilson, -doing the work he seems to never tire of). - -Fix several locking issues found with the lockdep valgrind skin (Chris -Wilson). - -Backend-specific bug fixes --------------------------- -xlib: Avoid crash due to attempting XRender calls on pixmaps with -formats not supported by the Render extension (Chris Wilson): - - XRender crashes due to NULL pointer from Cairo on SGI O2 - https://bugs.freedesktop.org/show_bug.cgi?id=11734 - -xlib: Add support for XImages with depth of 4, 20, 24, or 28 bits -(Chris Wilson): - - cairo doesn't support 24 bits per pixel mode on X11 - https://bugs.freedesktop.org/show_bug.cgi?id=9102 - -xlib: Avoid mistakenly considering two surfaces as similar just -because their depths match (while their Render formats do not) (Karl -Tomlinson). - -ps: Fix slight mis-scaling of bitmapped fonts (Adrian Johnson) - -svg: Correctly emit comp-op for paint, mask, and show_glyphs -operations (Emmanuel Pacaud). - -svg: Use finer-grained fallbacks for SVG 1.2 (as PS and PDF backends -have been doing since 1.6.0) (Chris Wilson). - -win32: Fallback to DIB if DDB create fails for -cairo_surface_create_similar (Vladimir Vukicevic). - -win32: Fix compatibility with Windows Mobile (Vladimir Vukicevic). - -win32: Fix static builds to not do __declspec(dllimport) on public -functions. This requires the user to set a CAIRO_WIN32_STATIC_BUILD -environment variable when compiling (Behdad Esfahbod). - -Release 1.8.0 (2008-09-25 Carl Worth <cworth@cworth.org>) -========================================================= -The cairo community is happy (and relieved) to announce the 1.8.0 -release of the cairo graphics library. This is a major update to -cairo, with new features and enhanced functionality which maintains -compatibility for applications written using any previous major cairo -release, (1.6, 1.4, 1.2, or 1.0). We recommend that anybody using a -previous version of cairo upgrade to cairo 1.8.0. - -The dominant theme of this release is improvements to cairo's ability -to handle text. The highlights include a new "user fonts" feature as -well as a new cairo_show_text_glyphs API which allows glyphs to be -embedded in PDF output along with their original text, (for searching, -selection, and copy-and-paste). Another major feature is a revamp of -cairo's build system making it much easier to build cairo on various -platforms. - -See below for more details. - -User fonts ----------- -This new API allows the user of cairo API to provide drawings for -glyphs in a font. A common use for this is implementing fonts in -non-standard formats, like SVG fonts and Flash fonts. This API can -also be used by applications to provide custom glyph shapes for fonts -while still getting access to cairo's glyph caches. See -test/user-font.c and test/user-font-proxy.c for usage examples. This -is based on early work by Kristian Høgsberg. Thanks Kristian! - -This new API consists of the following functions (and corresponding -_get functions): - - cairo_user_font_face_create - - cairo_user_font_face_set_init_func - cairo_user_font_face_set_render_glyph_func - cairo_user_font_face_set_text_to_glyphs_func - cairo_user_font_face_set_unicode_to_glyph_func - -An additional, new API is - - cairo_scaled_font_text_to_glyphs - -We were previously reluctant to provide this function as -text-to-glyphs support in cairo was limited to "toy" font -functionality, not really interesting for real-world text -processing. However, with user fonts landing, this API is needed to -expose full access to how user fonts convert text to glyphs. This is -expected to be used by text toolkits like Pango, as well as "proxy" -user-font implementations. - -cairo_show_text_glyphs ----------------------- -This new API allows the caller of cairo to provide text data -corresponding to glyphs being drawn. The PDF backend implements this -new API so that complex text can be copied out of cairo's PDF output -correctly and reliably, (assuming the user of cairo calls -cairo_show_text_glyphs). The cairo_show_text_glyphs API is definitely -the most daunting API to debut in cairo. It is anticipated that pango -(and similar high-level text libraries) will be the primary users of -this API. In fact, pango 1.22 already uses cairo_show_text_glyphs. -Behdad was the architect and implementor of this effort. Thanks, -Behdad! - -The cairo_show_text_glyphs API includes the following new functions: - - cairo_show_text_glyphs - - cairo_glyph_allocate - cairo_glyph_free - - cairo_text_cluster_allocate - cairo_text_cluster_free - - cairo_surface_has_show_text_glyphs - -Build system revamp -------------------- -The primary goal of the revamp is to make the build system less -fragile, (particularly for non-Linux platforms). For example, now -people building on win32 will no longer need to maintain a -platform-specific list of files to be built. See the new README.win32 -for details. Also, the .so file will now be installed with a different -naming scheme, (for example, 1.7.6 will install with a .10800 -suffix). Many thanks to Behdad and his small army of helpers! - -Assorted API additions ----------------------- -For API completeness, several missing "getter" functions were added: - - cairo_scaled_font_get_scale_matrix - - cairo_surface_get_fallback_resolution - - cairo_toy_font_face_create - cairo_toy_font_face_get_family - cairo_toy_font_face_get_slant - cairo_toy_font_face_get_weight - -The new cairo_toy_font_face functions provide access to functionality -and settings provided by cairo_select_font_face(). Thanks Behdad! - -cairo-ps/cairo-pdf: More efficient output ------------------------------------------ -Adrian Johnson has been busy fixing all kinds of bugs in PS and PDF -backends, as well making them generate much more compact output by -avoiding things like re-emitting the color or linestyle on every -drawing operation. Thanks Adrian! - -cairo-xlib: dithering ---------------------- -Dithering: Cairo now does simple dithering when rendering to legacy X -servers. This is most visible with 8-bit visuals. Thanks Behdad! - -cairo-xlib: Avoid rendering glyphs out of surface bounds --------------------------------------------------------- -This seemingly harmless optimization exposed a bug in OpenOffice.org 3 -versions where OO.o was passing bogus surface extents to cairo, -resulting in no text rendered in OO.o. Please contact your -distribution's OO.o maintainers if you see this bug and point them to -the following URL: - - https://bugs.freedesktop.org/show_bug.cgi?id=16209 - -cairo-xlib: Improved performance with X server without Render -------------------------------------------------------------- -Cairo now performs better on remote X servers that lack the Render -extension by being smarter about using X core protocol facilities -instead of falling back to doing all rendering on the client side. - -cairo-ft: respecting FC_FT_FACE -------------------------------- -Previously it was impossible to instruct cairo to do emboldening on a -font face object created from an FT_Face. Cairo now respects and uses -the FC_FT_FACE fontconfig pattern element, so emboldening can be -achieved by using cairo_ft_font_face_create_for_pattern() and a -carefully crafted pattern using FC_FT_FACE and FC_EMBOLDEN. Thanks -Behdad! - -cairo-directfb: backend improvements ------------------------------------- -The directfb backend, though still unsupported, has seen a good deal -of improvements. Thanks Vlad! - -Bug fixing and optimizations ----------------------------- -xlib: Faster bookkeeping (Karl Tomlinson) - https://bugzilla.mozilla.org/show_bug.cgi?id=453199#c5 - -PS: Fix gradients with non-constant alpha (Chris Wilson) - -Fix deadlock in user-font code (Richard Hughes and Behdad Esfahbod) - http://bugs.freedesktop.org/show_bug.cgi?id=16819 - -Countless other bugs have been fixed and optimizations made, many of -them thanks to Chris Wilson. Thanks Chris and others! - -Note also that the code that had been in cairo 1.7.x calling into -freetype's optional lcd_filter function was removed from cairo before -the 1.8.0 release. We do expect this code to come back in some form in -the future. - -Snapshot 1.7.6 (2008-09-17 Carl Worth <cworth@cworth.org>) -========================================================== -The cairo community is happy to announce the 1.7.6 snapshot of the -cairo graphics library. This is a "release candidate" for the upcoming -1.8.0 release, so we will greatly appreciate any reports of problems -in this release, and no major changes are currently planned before -1.8. - -Notable changes in 1.7.6 ------------------------- -The largest number of changes since 1.7.4 did not change the -implementation of cairo itself, but instead revamped cairo's build -system. The primary goal of the revamp is to make the build system -less fragile, (particularly for non-Linux platforms). For example, now -people building on win32 will no longer need to maintain a -platform-specific list of files to be built. Also, the .so file will -now be installed with a different naming scheme, (for example, 1.7.6 -will install with a .10706 suffix). Much thanks, Behdad! - -And, as usual, Chris Wilson has made another large round of robustness -improvements, (eliminating dead code, fixing propagation of error -status values, test suite improvements, etc. etc.). Thanks as always, -Chris! - -API changes since 1.7.4 ------------------------ -There have been a few changes of API that was new during the 1.7 -series: - -* Remove cairo_font_options_set_lcd_filter - and cairo_font_options_get_lcd_filter - - Motivation: At the Cairo Summit, this API was determined to be too - specific to the freetype font backend to be in the general - API. A similar API with a cairo_ft prefix might be introduced - in the future. Note that cairo will still respect the - corresponding fontconfig settings for these options. - -* Replace cairo_has_show_glyphs - with cairo_surface_has_show_glyphs - - Motivation: This really is a surface-specific interface, and the - convenience function on the cairo_t is not obviously - necessary. An application can easily call: - - cairo_surface_has_show_glyphs (cairo_get_target (cr)); - - as needed. - -* Add cairo_text_cluster_flags_t - to cairo_show_text_glyphs - cairo_scaled_font_text_to_glyphs - cairo_user_scaled_font_text_to_glyphs_func_t - - Motivation: This flag, (and specifically the - CAIRO_TEXT_CLUSTER_FLAG_BACKWARD value), replaces the - cairo_bool_t backward argument in each of the above - interfaces. This leads to more readable user code, and also - allows future extensibility. - -As always, there are no changes to any API from any major cairo -release, (1.0.x, 1.2.x, 1.4.x, 1.6.x). Cairo maintains the same -compatibility promise it always has. - -Bug fixes since 1.7.4 ---------------------- -xlib: Faster bookkeeping (Karl Tomlinson) - https://bugzilla.mozilla.org/show_bug.cgi?id=453199#c5 - -PS: Fix gradients with non-constant alpha (Chris Wilson) - -Fix deadlock in user-font code (Richard Hughes and Behdad Esfahbod) - http://bugs.freedesktop.org/show_bug.cgi?id=16819 - -Several other minor fixes. - -Snapshot 1.7.4 (2008-08-11 Behdad Esfahbod <behdad@behdad.org>) -=============================================================== -The cairo community is embarrassed to announce availability of the 1.7.4 -snapshot of the cairo graphics library. This is a followup release to the -1.7.2 snapshot to ship a tarball that can actually be built. The only -change since 1.7.4 is including the missing header file -cairo-user-font-private.h in the distribution. - -Snapshot 1.7.2 (2008-08-11 Behdad Esfahbod <behdad@behdad.org>) -=============================================================== -The cairo community is finally ready to announce availability of the 1.7.2 -snapshot of the cairo graphics library. This is embarrassingly the first -snapshot in the 1.7 unstable series of cairo, leading to the eventual release -of cairo 1.8, currently planned for late September. - -This snapshot comes four months after the 1.6.4 release. We have done a -really bad job on getting development snapshots out this cycle, but -hopefully all the API changes for 1.8 are now finished and the remaining -weeks will be spent on bug-fixing. There is more than 400 commits worth -of changes in this snapshot, and those can use some testing. Read on! - -Text, text, and more text! --------------------------- -The dominant theme of this release, and 1.8 in general, is improvements -around cairo text API. Here is a high-level list of changes with text -handling: - -User fonts ----------- -This is new API allowing the user of cairo API to provide drawings for glyphs -in a font. This is most useful in implementing fonts in non-standard formats, -like SVG fonts and Flash fonts, but can also be used by games and other -applications to draw "funky" fonts. See test/user-font.c and -test/user-font-proxy.c for usage examples. This is based on early work by -Kristian Høgsberg. Thanks Kristian! - -show_text_glyphs ----------------- -This new API allows the caller of cairo to mark text glyphs with their -original text. The PDF backend implements this new API and latest Pango -master uses it. The result is (when bugs are fixed) that complex text can be -copied out of pangocairo's PDF output correctly and reliably. There are bugs -to fix though. A few poppler bugs, and some more in cairo and pango. - -To test show_text_glyph, just grab pango master and this cairo snapshot and -print text in gedit. Open in acroread or evince, select all, copy, paste -in gedit and compare. The Arabic text with diacritic marks is particularly -showing bad. Try with pango/pango-view/HELLO.txt if you are brave -enough. The Indic text is showing improvements, but is still coming out -buggy. - -LCD subpixel filtering using FreeType -------------------------------------- -FreeType 2.3.5 added support for various LCD subpixel filtering, and -fontconfig 2.6.0 added support for configuring LCD filter on a font by font -basis. Cairo now relies on FreeType and fontconfig for subpixel filtering. -This work is based on David Turner's original patch to cairo, maintained -and tested by Sylvain Pasche and others. Thanks all! - -Toy font face constructor and getter ------------------------------------- -Mostly for API completion, but also useful for higher level (like Pango) to -hook into what the user has set using cairo_select_font_face(), making that -toy API a bit more useful. - -FreeType: respecting FC_FT_FACE -------------------------------- -Previously it was impossible to instruct cairo to do emboldening on a font -face object created from an FT_Face. Cairo now respects and uses the -FC_FT_FACE fontconfig pattern element, so emboldening can be achieved by -using cairo_ft_font_face_create_for_pattern() and a carefully crafted pattern -using FC_FT_FACE and FC_EMBOLDEN. - - -PS/PDF: More efficient output ------------------------------ -Adrian Johnson has been busy fixing all kinds of bugs in PS and PDF -backends, as well making them generate much more compact output by avoiding -things like re-emitting the color or linestyle on every drawing operation. -Thanks Adrian! - - -Xlib: Dithering ---------------- -Cairo now does simple dithering when rendering to legacy X servers. This is -mostly visible with 8-bit visuals. - -Xlib: Avoid rendering glyphs out of surface bounds --------------------------------------------------- -This seemingly harmless change manifested a bug with OpenOffice.org 3 versions -where OO.o was passing bogus surface extents to cairo, resulting in no text -rendered in OO.o. Please contact your distro's OO.o maintainers if you see -this bug and point them to the following URL: - - https://bugs.freedesktop.org/show_bug.cgi?id=16209 - -Xlib: Improved performance with Xrender-less X servers ------------------------------------------------------- -Cairo now performs better on remote, Xrender-less X servers by being smarter -about using X core protocol facilities instead of falling back to doing all -rendering on the client side. - - -Directfb: backend improvements ------------------------------- -The directfb backend, though still unsupported, has seen a good deal of -improvements. Thanks Vlad! - - -Bug fixing and optimizations ----------------------------- -Countless bugs have been fixed and optimizations made, many of them thanks to -Chris Wilson. Thanks Chris! - - -API additions -------------- - -cairo_show_text_glyphs - - This is a new text rendering API. Being a more advanced version of - cairo_show_glyphs(), it is aimed for use by higher-level text toolkits like - Pango, and enables better text extraction from output generated by backends - like PDF and SVG. The PDF backend already implements it, and the upcoming - Pango release will use it. - - To make that API work, a bunch of other additions were made: - -cairo_glyph_allocate -cairo_glyph_free -cairo_text_cluster_t -cairo_text_cluster_allocate -cairo_text_cluster_free -cairo_surface_has_show_text_glyphs - - -cairo_user_font_face_create - - This is the "user" font face constructor, accompanied by a variety of method - signatures, getters, and setters for a callback-based font backend: - -CAIRO_FONT_TYPE_USER -cairo_user_scaled_font_init_func_t -cairo_user_scaled_font_render_glyph_func_t -cairo_user_scaled_font_text_to_glyphs_func_t -cairo_user_scaled_font_unicode_to_glyph_func_t -cairo_user_font_face_set_init_func -cairo_user_font_face_set_render_glyph_func -cairo_user_font_face_set_text_to_glyphs_func -cairo_user_font_face_set_unicode_to_glyph_func -cairo_user_font_face_get_init_func -cairo_user_font_face_get_render_glyph_func -cairo_user_font_face_get_text_to_glyphs_func -cairo_user_font_face_get_unicode_to_glyph_func - - -cairo_scaled_font_text_to_glyphs - - We were previously reluctant to provide this function as text-to-glyphs - support in cairo was limited to "toy" font functionality, not really - interesting for real-world text processing. However, with user-fonts - landing, this API is needed to expose full access to how user-fonts - convert text to glyphs. This is expected to be used by text toolkits like - Pango, as well as "proxy" user-font implementations. - - -cairo_lcd_filter_t -cairo_font_options_set_lcd_filter -cairo_font_options_get_lcd_filter - - These add the possibility to choose between various available LCD subpixel - filters. The available filter values are modelled after what FreeType - provides. - - -cairo_toy_font_face_create -cairo_toy_font_face_get_family -cairo_toy_font_face_get_slant -cairo_toy_font_face_get_weight - - These provide access to functionality and settings provided by - cairo_select_font_face(). - - -cairo_scaled_font_get_scale_matrix -cairo_surface_get_fallback_resolution - - For API completeness. - - -Various new values for cairo_status_t enum - - -Known issues: - -- Type3 fonts generated by cairo's PDF backend may show up in poppler/Evince - in a different color than expected. This is fixed in poppler master branch. - This mostly affects cairo user fonts. The test case test/user-font.c - demonstrates this. - -- User fonts using other fonts in their rendering are currently embedded in - PDF as fallback bitmap glyphs. This will be (hopefully) fixed before 1.8. - The test case test/user-font-proxy.c demonstrates this. - - -Release 1.6.4 (2008-04-11 Carl Worth <cworth@cworth.org>) -========================================================= -The cairo community is wildly embarrassed to announce the 1.6.4 -release of the cairo graphics library. This release reverts the xlib -locking change introduced in 1.6.4, (and the application crashes that -it caused). The community would be glad to sack its current release -manager and is accepting applications for someone who could do the job -with more discipline. - -Revert 'add missing locking in cairo-xlib' ------------------------------------------- -This change was introduced in cairo 1.6.2, but also introduced a bug -which causes many cairo-xlib applications to crash, (with a -segmentation fault inside of XSetClipMask). Instead of attempting -another fix for the broken fix, the change in 1.6.2 has been -reverted. The original bug which the change was addressing has been -present since at least cairo 1.4, so it is not expected that leaving -this bug unfixed will cause any new problems for applications moving -from cairo 1.4 to cairo 1.6. - -At this point, the code of cairo 1.6.4 differs from cairo 1.6.0 only -in the fix for the PostScript-printer crashes. - -Tweak build to avoid linking with g++ -------------------------------------- -Cairo 1.6.4 avoids a quirk in automake that was causing the cairo -library to be linked with g++ and linked against libstdc++ even when -only C source files were compiled for the library. - -Release 1.6.2 (2008-04-11 Carl Worth <cworth@cworth.org>) -========================================================= -The cairo community is pleased (but somewhat sheepish) to announce the -1.6.2 release of the cairo graphics library. This is an update to -yesterday's 1.6.0 release with an important fix to prevent cairo's -PostScript output from crashing some printers. This release also -includes a locking fix for cairo's xlib backend to improve thread -safety. There are no changes beyond these two fixes. - -Fix for PostScript printer crash --------------------------------- -Adrian Johnson discovered that cairo 1.6.0 was being a bit hard on -PostScript printers, by changing the font matrix very frequently. This -causes some PostScript interpreters to allocate new font objects every -few glyphs, eventually exhausting available resources. The fix -involves leaving translational components of the font matrix as zero, -so that the PostScript interpreter sees an identical font matrix -repeatedly, and can more easily share internal font object resources. - -This fix has been tested to resolve the bugs posted here, (for both -Xerox and Dell printers): - - Printing some PDFs from evince is crashing our Xerox printer - http://bugs.freedesktop.org/show_bug.cgi?id=15348 - - Cairo-generated postscript blocks Dell 5100cn - http://bugs.freedesktop.org/show_bug.cgi?id=15445 - -Add missing locking in cairo-xlib ---------------------------------- -Chris Wilson noticed that cairo 1.6.0 was manipulating an internal -cache of GC object within cairo's Xlib backend without proper -locking. The missing locking could cause failures for multi-threaded -applications. He fixed this in 1.6.2 by adding the missing locks. - -Release 1.6.0 (2008-04-10 Carl Worth <cworth@cworth.org>) -========================================================= -The cairo community is quite pleased to announce the 1.6.0 release of -the cairo graphics library. This is a major update to cairo, with new -features and enhanced functionality which maintains compatibility for -applications written using cairo 1.4, 1.2, or 1.0. We recommend that -anybody using a previous version of cairo upgrade to cairo 1.6.0. - -The most significant new features in this release are dramatically -improved PDF and PostScript[*] output, support for arbitrary X server -visuals (including PseudoColor), a new Quartz backend, and and a new -"win32 printing" backend. See below for more details on these and -other new features. - -New dependency on external pixman library (Thanks, Søren!) ----------------------------------------------------------- -As of cairo 1.6, cairo now depends on the pixman library, for which -the latest release can be obtained alongside cairo: - - http://cairographics.org/releases/pixman-0.10.0.tar.gz - -This library provides all software rendering for cairo, (the -implementation of the image backend as well as any image fallbacks -required for other backends). This is the same code that was -previously included as part of cairo itself, but is now an external -library so that it can be shared by both cairo and by the X server, -(which is where the code originated). - -Improved PDF, PostScript, and SVG output (Thanks, Adrian!) ----------------------------------------------------------- -Users of the cairo-pdf, cairo-ps, and cairo-svg should see a dramatic -improvement from cairo 1.2/1.4 to 1.6. With this release there are now -almost no operations that will result in unnecessary rasterization in -the PDF and PostScript. Rasterized "image fallbacks" are restricted -only to minimal portions of the document where something is being -drawn with cairo that is beyond the native capabilities of the -document, (this is rare for PDF or SVG, but occurs when blending -translucent objects for PostScript). - -This means that the final output will be of higher quality, and will -also be much smaller, and therefore will print more quickly. The -machinery for doing analysis and minimal fallbacks also benefits the -win32-printing surface described below. - -In addition to doing less rasterization, the PostScript and PDF output -also has several other improvements to make the output more efficient -and more compatible with specifications. - -[*] Note: Just before this release, a bug has been reported that the -PostScript output from cairo can crash some printers, (so far the -following models have been reported as problematic Xerox Workcentre -7228 or 7328 and Dell 5100cn). We will implement a workaround as soon -as we can learn exactly what in cairo's output these printers object -to, (and we could use help from users that have access to misbehaving -printers). This bug is being tracked here: - - Printing some PDFs from evince is crashing our Xerox printer - http://bugs.freedesktop.org/show_bug.cgi?id=15348 - -New support for arbitrary X server visuals (Thanks, Keith and Behdad!) ----------------------------------------------------------------------- -As of cairo 1.6, cairo should now work with an arbitrary TrueColor or -8-bit PseudoColor X server visual. Previous versions of cairo did not -support these X servers and refused to draw anything. We're pleased to -announce that this limitation has been lifted and people stuck with -ancient display systems need no longer be stuck with ancient software -just because of cairo. - -New, supported Quartz backend for Mac OS X (Thanks, Brian and Vladimir!) ------------------------------------------------------------------------- -As of cairo 1.6, the cairo-quartz backend is now marked as "supported" -rather than "experimental" as in previous cairo releases. Its API now -has guarantees of API stability into future cairo releases, and its -output quality is comparable to other backends. There have been -significant improvements to cairo-quartz since 1.4. It now uses many -fewer image fallbacks, (meaning better performance), and has greatly -improved text rendering. - -New, "win32 printing" backend (Thanks, Adrian and Vladimir!) ------------------------------------------------------------- -A new win32-printing surface has been added with an interface very -similar to the original win32 surface, (both accept an HDC -parameter). But this new surface should only be called with a printing -DC, and will result in all drawing commands being stored into a -meta-surface and emitted after each page is complete. This allows -cairo to analyze the contents, (as it does with PDF, PostScript, and -SVG backends), and to do minimal image-based fallbacks as -necessary. The analysis keeps things as efficient as possible, while -the presence of fallbacks, (when necessary), ensure the consistent, -high-quality output expected from cairo. - -Robustness fixes (Thanks, Chris!) ---------------------------------- -There has been a tremendous number of improvements to cairo's -robustness. Areas that have been improved include: - - * Proper reporting of errors - - * Responding correctly to invalid input - - * Avoiding integer overflows - - * Avoiding memory leaks on error-recovery paths - - * Making reference counting thread safe - - * Exhaustive testing of memory allocation points - -Other fixes (Thanks, everybody!) --------------------------------- -Cairo's internal fixed-point representation has been changed from -16.16 to 24.8. This has a direct impact on applications as it allows -much larger objects to be drawn before internal limits in cairo make -the drawing not work. - -The CAIRO_EXTEND_PAD mode is now fully supported by surface -patterns. This mode allows applications to use cairo_rectangle and -cairo_fill to draw scaled images with high-quality bilinear filtering -for the internal of the image, but without any objectionably blurry -edges, (as would happen with the default EXTEND_NONE and cairo_paint). - -Rendering with CAIRO_ANTIALIAS_NONE has been fixed to be more -predictable, (previously image rendering and geometry rendering would -be slightly misaligned with respect to each other). - -The reference manual at http://cairographics.org/manual now documents -100% of the functions and types in cairo's public API. - -API additions -------------- -Several small features have been added to cairo with new API functions: - -cairo_format_stride_for_width - - Must be called to compute a properly aligned stride value before - calling cairo_image_surface_create_for_data. - -cairo_has_current_point - - Allows querying if there is a current point defined for the - current path. - -cairo_path_extents - - Allows querying for path extents, (independent of any fill or - stroke parameters). - -cairo_surface_copy_page -cairo_surface_show_page - - Allow beginning a new document page without requiring a cairo_t - object. - -cairo_ps_surface_restrict_to_level -cairo_ps_get_levels -cairo_ps_level_to_string -cairo_ps_surface_set_eps - - Allow controlling the Post PostScript level, (2 or 3), to - target, as well as to generate Encapsulated PostScript (EPS). - -cairo_quartz_font_face_create_for_cgfont - - Create a quartz-specific cairo_font_face_t from a CGFontRef. - -cairo_win32_font_face_create_for_logfontw_hfont - - Create a win32-specific cairo_font_face from a LOGFONTW and an - HFONT together. - -Thanks, Everyone! ------------------ -I've accounted for 32 distinct people with attributed code added to -cairo between 1.4.14 and 1.6.0, (their names are below). That's an -impressive number, but there are certainly dozens more that -contributed with testing, suggestions, clarifying questions, and -encouragement. I'm grateful for the friendships that have developed as -we have worked on cairo together. Thanks to everyone for making this -all so much fun! - -Adrian Johnson, Alp Toker, Antoine Azar, Behdad Esfahbod, -Benjamin Otte, Bernardo Innocenti, Bertram Felgenhauer, -Boying Lu, Brian Ewins, Carl Worth, Chris Heath, Chris Wilson, -Claudio Ciccani, Emmanuel Pacaud, Jeff Muizelaar, Jeremy Huddleston, -Jim Meyering, Jinghua Luo, Jody Goldberg, Jonathan Gramain, -Keith Packard, Ken Herron, Kouhei Sutou, Kristian Høgsberg, -Larry Ewing, Martin Ejdestig, Nis Martensen, Peter Weilbacher, -Richard Hult, Shailendra Jain, Søren Sandmann Pedersen, -Vladimir Vukicevic - -Snapshot 1.5.20 (2008-04-04 Carl Worth <cworth@cworth.org>) -=========================================================== -This is the tenth snapshot in cairo's unstable 1.5 series. It comes -just two days (and only one working day) after the 1.5.18 -snapshot. The quick snapshot is due to two embarrassing bugs (both -affecting cairo-xlib) that had been introduced in the 1.5.18 -snapshot. The fixes for these are described below along with a few -other fixes, (which hopefully aren't introducing new bugs this time). - -cairo-xlib ----------- -Revert fix from 1.5.18 to allow pattern expansion based on the filter -mode. This fix seemed so boring, (the use case it addresses is almost -never used in practice), that it didn't even get mentioned in the -1.5.18 release notes. However, the "fix" happened to break rendering -that is always used resulting in corrupt image rendering in mozilla, -evolution, and probably everything else that uses cairo. - -Fix to avoid BadMatch errors in cairo_surface_create_similar. These -were introduced, (inadvertently, of course), as part of the fix in -1.5.18 for creating similar surfaces without the Render -extension. Again, thanks to mozilla, (and Vladimir Vukicevic in -particular), for noticing our mistake. - -general -------- -Correctly handle an in-error surface in -cairo_surface_write_to_png. Previously this function would cause an -assertion failure if you gave it a finished surface. Now it cleanly -returns a CAIRO_STATUS_SURFACE_FINISHED result instead. - -Avoid potentially infinite wandering through memory inside -_cairo_hull_prev_valid. Thanks to Jonathan Watt for noticing this -problem: - - https://bugzilla.mozilla.org/show_bug.cgi?id=306649#c21 - -cairo-pdf ---------- -Fix generation of "soft" masks made by drawing to a similar surface -and then calling cairo_mask_surface() with it. - -cairo-svg ---------- -Fix for code that uses cairo_mask() on an intermediate surface which -is later passed to cairo_mask_surface(). - -Snapshot 1.5.18 (2008-04-05 Carl Worth <cworth@cworth.org>) -=========================================================== -This is the ninth snapshot in cairo's unstable 1.5 series. It comes -just 4 days after the 1.5.16 snapshot. We had hoped to not need -another snapshot before the final 1.6.0 release, but several critical -bugs were found and fixed in the last few days, so we thought it -important to let people test the fixes with this snapshot. See below -for details. - -documentation -------------- -The README now lists necessary dependencies. - -Various graphics state defaults are now documented, (source pattern is -opaque black, line width is 2.0, line join is miter, line cap is butt, -miter limit is 10.0, etc.). - -general -------- -Several cleanups have been made along many error-path returns, -(carefully propagating up the original error status values, cleaning -up memory leaks during error recovery, etc.). This is yet another in -Chris "ickle" Wilson's long series of error-handling cleanups during -the 1.5 series. - -Avoid undesired clipping when drawing scaled surface patterns with -bilinear filtering. - -cairo-pdf ---------- -Fix emission of 1-bit alpha masks in PDF output. - -Fix a bug that would cause glyphs to be misplaced along the Y axis: - - http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=%23474136 - - Originally, an issue about a crash, but later leading to the - misplaced glyphs issue being discovered. - -cairo-ps --------- -Fix misplaced glyphs in cairo's PostScript output. - - This issue occurs when consecutive glyphs are placed far - apart. This case is exercised by the new ft-show-glyphs-table test - case, which was originally inspired by the Debian bug #23474136 - mentioned above. - -Fix more misplaced glyphs in cairo's PostScript output: - - The issue here showed up under very particular circumstance, (when - converting a PDF file with a CFF font with CID Identity-H encoding - and using glyph 0, (defined by the CFF specification as .notdef) - as a space instead). More concretely, this problem appeared when - converting the UbuntuDesktop.pdf file mentioned in this bug - report: - - https://bugs.freedesktop.org/show_bug.cgi?id=15348#c3 - - As usual with arcane font-encoding-specific bugs like this, many - thanks to Adrian Johnson for his magical ability to dive into - specifications and emerge almost instantaneously with fixes. And - thanks to Sebastien Bacher for bringing the bug to our attention. - -cairo-xlib ----------- -Fix serious failure on X servers without the Render extension. - - Since the 1.5.14 snapshot (with support for PseudoColor visuals), - any application attempting to create a "similar" xlib surface would - fail on an X server without the Render extension. Thanks to - Frederic Crozat for pointing out that cairo's test suite was - entirely failing when run against Xvfb. - -Avoid crashing cairo-xlib applications for too-large glyphs - - Naively sending glyphs of any size to the X server will eventually - violate the X limit on maximum request sizes. We now properly - detect when a glyph would be too large and use existing fallbacks - to render the glyph rather than trying to send it to the X server. - -Enable the buggy_repeat workaround for Xorg servers < 1.4 - - We have determined that Xorg 1.3.0 (as packaged in Fedora 8 at - least) has a bug that can result in an X server crash when cairo - uses certain X Render repeat operations, (as exercised by cairo's - extend-reflect test). We avoid this crash by using fallbacks - whenever a repeating surface is needed for any Xorg server with a - version less than 1.4. This is slower, but should prevent the - crash. - - (Meanwhile, there appears to be a separate bug where some X - servers or specific X-server drivers will use random pixmap data - when asked to draw a repeating surface. The buggy_repeat - workaround would also avoid those problems, but we have not yet - characterized whether the new "version < 1.4" is a good - characterization of those problems or not.) - -cairo-quartz-font ------------------ -Implement cairo_font_extents for this backend. - -The cairo-quartz-font implementation added in the 1.5.14 snapshot was -entirely missing support for the cairo_font_extents function. Thanks to -Richard Hult for pointing out this obvious shortcoming, (and obvious -lack of coverage in our test suite): - - CGFont backend returns 0 font extents - https://bugs.freedesktop.org/show_bug.cgi?id=15319 - -Snapshot 1.5.16 (2008-04-01 Carl Worth <cworth@cworth.org>) -=========================================================== -This is the eighth snapshot in cairo's unstable 1.5 series. It comes -less than two weeks after the 1.5.14 snapshot and it really is a -legitimate snapshot, (in spite of sharing this date with that of many -bogus announcements). The major change in this snapshot is that the -cairo-quartz backend is now officially "supported", including new API -to construct a font face from a CGFontRef . Also several bug fixes -have been fixed in many backends. See below for details. - -general -------- -Cairo now depends on pixman 0.10.0 which was recently released. The -latest pixman release can always be found alongside cairo releases at: - - http://cairographics.org/releases - -Increase the precision of color stops for gradients. This fixes a -regression in gradient rendering that had been present since the -1.5.12 snapshot. - -paginated (all of ps, pdf, svg, and win32-printing) ---------------------------------------------------- -Fix assertion failure when some drawing elements are outside the page -boundaries, (this bug was noticed when using Inkscape to print a -drawing with landscape orientation to a portrait-oriented piece of -paper). - -cairo-ps --------- -Fix of bug causing incorrect glyph positioning. - -Fix handling of CAIRO_OPERATOR_SOURCE. - -cairo-pdf ---------- -More reduction of unnecessary digits of precision in PDF output. - -Fix handling of CAIRO_OPERATOR_SOURCE. - -cairo-svg ---------- -Fix bug in usage of libpng that was preventing cairo_mask from working -with the svg backend. - -Fix transformation of source pattern for cairo_stroke(). - -cairo-win32-printing --------------------- -Fix fallback resolution, (thanks again to inkscape users/developers -for helping us find this one). - -cairo-quartz ------------- -Mark the cairo-quartz backend as "supported" rather than -"experimental". This means the following: - - * The backend will now be built by default (if possible). - - * We are committing that the backend-specific API (as published in - cairo-quartz.h) are stable and will be supported in all future - cairo 1.x releases. - - * We are committing that the output quality of this backend - compares favorably with other cairo backends, (and that quality - is ensured by good results from the cairo test suite). - - * We recommend that distributions build and distribute this - backend when possible. - -Note that the cairo_quartz_image API (in cairo-quartz-image.h) is -still experimental, will not build by default, (pass ---enable-quartz-image to configure to build it), and may see API -changes before it is marked as "supported" in a future release. - -Put the CAIRO_FONT_TYPE_ATSUI name back into -cairo-deprecated.h. Without this, the cairo 1.5.14 snapshot broke all -builds for applications using the C++ cairomm bindings (and perhaps -others) which have the CAIRO_FONT_TYPE_ATSUI name in their header -files. This breakage happened even for applications not using -cairo-quartz at all. - - Note: Even though the CAIRO_FONT_TYPE_ATSUI name is provided to - avoid this build breakage, we still recommend that bindings and - applications move to the new, and more accurate, - CAIRO_FONT_TYPE_QUARTZ name. - -Replace the implementation of cairo-quartz-font to use CFFont instead -of ATSUI. The CGFont API is a better fit than ATSUI, and this new -implementation is also more correct than the old one as well. - -This also adds the following new API call: - - cairo_public cairo_font_face_t * - cairo_quartz_font_face_create_for_cgfont (CGFontRef font); - -The previous cairo_quartz_font_face_create_for_atsu_font_id function -continues to exist and is part of the supported API going -forward. (However, the old name of that same function, which was -cairo_atsui_font_face_create_for_atsu_font_id is officially -deprecated. Any source code using the old name should be updated to -use the new name.) - -Fix transformation of source pattern for cairo_stroke(). - -cairo-win32 ------------ -Avoid crash in create_similar is cairo_win32_surface_create fails. - -Snapshot 1.5.14 (2008-03-20 Carl Worth <cworth@cworth.org>) -=========================================================== -This is the seventh snapshot in cairo's unstable 1.5 series. It comes -3 weeks after the 1.5.12 snapshot. This snapshot includes support for -arbitrary X server visuals, (including PseudoColor), which was the -final remaining cairo-specific item on the cairo 1.6 roadmap. It also -includes a huge number of improvements to the cairo-quartz backend. So -this is effectively a cairo 1.6 release candidate. We expect very few -changes from now until 1.6 and only for specific bug fixes. - -API Change ----------- -Rename ATSUI font backend to Quartz font backend. This affects the -following usage: - - --enable-atsui -> --enable-quartz-font - CAIRO_HAS_ATSUI_FONT -> CAIRO_HAS_QUARTZ_FONT - CAIRO_FONT_TYPE_ATSUI -> CAIRO_FONT_TYPE_QUARTZ - - cairo_atsui_font_face_create_for_atsu_font_id -> - cairo_quartz_font_font_create_for_atsu_font_id - -This API change is justified by the cairo-quartz backend still be -marked as "experimental" rather than "supported", (though this is one -step toward making the change to "supported" before 1.6). Cairo will -still provide ABI compatibility with the old symbol name, however. - -paginated (all of ps, pdf, svg, and win32-printing) ---------------------------------------------------- -Optimize by not analyzing an image surface for transparency more than -once, (previously all images were analyzed twice). - -cairo-ps and cairo-pdf ----------------------- -Avoiding emitting a matrix into the stroke output when unnecessary, -(making output size more efficient). - -Reduce rounding error of path shapes by factoring large scale factors -out of the path matrix, (ensuring that a fixed-number of printed -digits for path coordinates contains as much information as possible). - -Reduce excess digits for text position coordinates. This makes the -output file size much smaller without making the result any less -correct. - -cairo-ps --------- -Eliminate bug causing extraneous text repetition on Linux PostScript -output in some cases. - - See: Mozilla Bug 419917 – Printed page contents are reflected - inside bordered tables (Linux-only) - - https://bugzilla.mozilla.org/show_bug.cgi?id=419917 - -Optimize output when EXTEND_PAD is used. - -cairo-pdf ---------- -Fix to not use fill-stroke operator with transparent fill, (else PDF -output doesn't match the cairo-defined correct result). See: - - https://bugs.launchpad.net/inkscape/+bug/202096 - -cairo-svg ---------- -Fix stroke of path with a non-solid-color source pattern: - - http://bugs.freedesktop.org/show_bug.cgi?id=14556 - -cairo-quartz ------------- -Fix text rendering with gradient or image source pattern. - -Handling antialiasing correctly for cairo_stroke(), cairo_clip(), and -cairo_show_text()/cairo_show_glyphs(). - -Correctly handle gradients with non-identity transformations: - - Fixes http://bugs.freedesktop.org/show_bug.cgi?id=14248 - -Add native implementation of REPEAT and REFLECT extend modes for -gradients. - -Fix implementation for the "unbounded" operators, (CAIRO_OPERATOR_OUT, -_IN, _DEST_IN, and _DEST_ATOP). - -Correctly handle endiannees in multi-architecture compiles on Mac OS -X. - -Avoid behavior which would cause Core Graphics to print warnings to -the console in some cases. - -cairo-win32 ------------ -Fix handling of miter limit. - -cairo-win32-printing --------------------- -Fix to not use a 1bpp temporary surface in some cases while printing, -(so grayscale data is preserved rather than just becoming black and -white). - -cairo-xlib ----------- -Add support for rendering to arbitrary TrueColor X server -visuals. This fixes at least the following bugs: - - cairo doesn't support 8-bit truecolor visuals - https://bugs.freedesktop.org/show_bug.cgi?id=7735 - - cairo doesn't support 655 xlib format - https://bugs.freedesktop.org/show_bug.cgi?id=9719 - -Add support for rendering to 8-bit PseudoColor X server visuals. This -fixes the following bug: - - Cairo doesn't support 8-bit pseudocolor visuals - https://bugs.freedesktop.org/show_bug.cgi?id=4945 - -Snapshot 1.5.12 (2008-02-28 Carl Worth <cworth@cworth.org>) -=========================================================== -This is the sixth snapshot in cairo's unstable 1.5 series. It comes 1 -week after the 1.5.10 snapshot. This snapshot includes the -long-awaited change from 16.16 to 24.8 fixed-point values, (see below -for why you should care). It also includes several backend-specific -bug fixes. - -24.8 fixed-point format ------------------------ -Cairo has always converted path coordinates to a fixed-point -representation very early in its processing. Historically, this has -been a 32-bit representation with 16 bits of integer for the -device-pixel grid and 16 bits of sub-pixel positioning. The choice of -16 bits for the integer coordinate space was based on the 16-bit limit -for X Window drawables. - -This 16-bit limit has proven problematic for many applications. It's -an especially vexing problem when targeting non-X backends that don't -have any 16-bit restriction. But even when targeting cairo-xlib, it's -often desirable to draw a large shape, (say a background rectangle), -that extends beyond the surface bounds and expect it to fill the -surface completely, (rather than overflowing and triggering random -behavior). - -Meanwhile, nobody has ever really needed 16 bits of sub-pixel -precision. - -With this snapshot, the fixed-point system is still in place and is -still using a 32-bit representation, (future versions of cairo might -move entirely to floating-point when targeting PDF output for -example). But the representation now provides 24 bits of pixel -addressing and only 8 bits of sub-pixel positioning. This should give -a much less stifling space to many applications. - -However, the underlying pixman library still has 16-bit limitations in -many places, (it has its roots in the X server as well). Until those -are also fixed, applications targeting cairo image surfaces, or -hitting software fallbacks when targeting other surfaces will still -encounter problems with device-space values needing more than 16 -integer bits. - -generic fixes -------------- -Add a few tests to the test suite to increase coverage. - -Cleanup a few error-handling paths, (propagate error correctly). - -cairo-ft --------- -Fix handling of font sizes smaller than 1 device pixel. - -cairo-pdf ---------- -Fix to properly save/restore clip when analyzing meta-surface -patterns, (fixing a couple of test-suite failures). - -Implement native support for CAIRO_OPERATOR_SOURCE when the source -pattern is opaque. - -Emit rectangles as PDF rectangles ("re" operator) rather than as -general paths. - -cairo-ps --------- -Fix to work properly with the 16.16->24.8 change. - -cairo-svg ---------- -Fix CAIRO_EXTEND_REFLECT by using an image fallback, (there's no -direct SVG support for reflected patterns). - -Fix the use of alpha-only masks, (such as CAIRO_FORMAT_A8). - -cairo-quartz ------------- -Add new API for efficiently using image data as a source: - - cairo_surface_t * - cairo_quartz_image_surface_create (cairo_surface_t *image_surface); - - cairo_surface_t * - cairo_quartz_image_surface_get_image (cairo_surface_t *surface); - -For full documentation, see: - - http://cairographics.org/manual/cairo-Quartz-Surfaces.html#cairo-quartz-image-surface-create - -Several fixes for cairo_mask(). - -cairo-atsui ------------ -Change default from from Monaco to Helvetica to be more consistent -with other font backends. - -Snapshot 1.5.10 (2008-02-20 Carl Worth <cworth@cworth.org>) -=========================================================== -This is the fifth snapshot in cairo's unstable 1.5 series. It comes 3 -weeks after the 1.5.8 snapshot. This snapshot adds one new API -function, (cairo_has_current_point), and the usual mix of -improvements, (more efficient PostScript/PDF output, optimized -stroking), and fixes (more robust error-handling, etc.). See below for -details. - -New API -------- -Add a new function to query if there is a current point: - - cairo_bool_t - cairo_has_current_point (cairo_t *cr); - -There is no current point immediately after cairo_create(), nor after -cairo_new_path() or cairo_new_sub_path(). There is a current point -after any of the path-creation functions, (cairo_move_to, -cairo_line_to, cairo_curve_to, etc.). - -With this new function, we also revert the change of the return type -of cairo_get_current_point from cairo 1.5.8, (it's now a void function -again). - -Optimizations -------------- -Optimize stroking code to avoid repeated calculation of redundant -values, (particularly significant for very large, offscreen paths). - -General fixes -------------- -Patch a few more potential buffer overruns, (due to integer -overflow). - -Many fixes and improvements to cairo's error-handling, (ensure that -correct error values are returned, clean up memory leaks on -error-handling paths, etc.). - -Fix a potential infinite loop when stroking a spline with a pen that -has been transformed to a line segment. - -Remove treating NULL as a synonym for a valid cairo_font_options_t* -with default values, (a change that had been introduced as of cairo -1.5.8). - -Remove the altered handling of tolerance and fallback-resolution that -had been introduced as of cairo 1.5.4. - -cairo-xlib ----------- -Pass the original Drawable, (as opposed to the root window), to -XCreatePixmap when creating a similar surface. This gives the X server -more information so that it can be clever and efficient. - -cairo-pdf ---------- -Fix the rendering of repeating and reflecting patterns. - -Ensure miter limit is always >= 1, (smaller limits are not meaningful, -but they can cause some PDF viewers to fail to display pages). - -Generate more efficient output when the same path is used for both -fill and stroke. - -cairo-ps --------- -Start sharing much of the cairo-pdf code rather than implementing very -similar code in cairo-ps. - -Implement native support for repeating and reflecting linear -gradients. - -Implement reflected surface patterns. - -Ensure miter limit is always >= 1, (smaller limits are not meaningful, -but they can cause some PostScript viewers to crash). - -Generate PostScript that will perform more efficiently and use less -memory on printers, (use currentfile instead of a giant string array -for image data, and avoid using PostScript patterns for paint() and -fill() when possible). - -cairo-svg ---------- -Avoid unnecessary rasterization when copying a "similar" surface to -another svg surface, (allow the SOURCE operator to be implemented with -all-vector operations if there are no underlying objects). - -cairo-atsui ------------ -Eliminate infinite loop when attempting to render an empty string. - -Snapshot 1.5.8 (2008-01-30 Carl Worth <cworth@cworth.org>) -========================================================== -This is the fourth snapshot in cairo's unstable 1.5 series. It comes 2 -weeks after the 1.5.6 snapshot. It adds a few new API functions. Most -notably all callers of cairo_image_surface_create_for_data should now -be calling cairo_format_stride_for_width to compute a legal stride -value. See below for more details. - -New API in cairo 1.5.8 ----------------------- -We've added a new function that should be called to compute a legal -stride value before allocating data to be used with -cairo_image_surface_create_for_data: - - int - cairo_format_stride_for_width (cairo_format_t format, - int width); - -We've also added a new cairo_path_extents function that can be used to -compute a bounding box for geometry such as a single line segment, -(contrast with cairo_path_extents and cairo_stroke_extents): - - void - cairo_path_extents (cairo_t *cr, - double *x1, double *y1, - double *x2, double *y2); - -And finally, we've added a function to allow for querying the -XRenderPictFormat of a cairo-xlib surface: - - XRenderPictFormat * - cairo_xlib_surface_get_xrender_format (cairo_surface_t *surface); - -API changes ------------ -Fix return types of cairo_surface_show_page and -cairo_surface_copy_page. This is an API change to functions that are -new in the 1.5 series, so not an API break compared to any stable -cairo release, (1.0.x, 1.2.x, 1.4.x). - -Change the return type of cairo_get_current_point() from void to -cairo_status_t. This allows the caller to receive a -CAIRO_STATUS_NO_CURRENT_POINT value to distinguish the a current point -at the origin from no current point existing. - -Performance improvement ------------------------ -Improve performance of clipping by using an optimized code path -internally, (with the ADD operator instead of IN). - -General bug fixes ------------------ -Fix various cairo_*_extents functions to initialize the return-value -variables even in the case of a cairo_t in error. - -Treat NULL as a legitimate value for cairo_font_options_t*. [NOTE: -On discussion afterwards, we decided against this change so it has -been removed as of cairo 1.5.10.] - -Fix rendering with CAIRO_ANTIALIAS_NONE to be more predictable, (that -is, to avoid seams appearing when geometry and imagery share an -identical edge). Portions of this fix are in the pixman library and -will appear in a future release of that library. - -Avoid triggering an error for a font size of 0. - -Miscellaneous changes ---------------------- -Require pixman >= 0.9.6. - -There has been a tremendous amount improvement to cairo's -documentation. We're delighted that 100% of the public API has at -least some documentation in the API reference manual. Many thanks to -Behdad Esfahbod and Nis Martensen for leading this effort. - -cairo-pdf and cairo-ps ----------------------- -Eliminate failure when a Type 1 font is embedded with an explicit -glyph 0. - -cairo-pdf ---------- -Implement a more correct and more efficient approach for patterns with -an extend mode of CAIRO_EXTEND_REFLECT. - -cairo-ps --------- -Fix image masks to properly pack and pad mask bits. - -cairo-quartz ------------- -Take care to only use DrawTiledImage for integer-aligned images, (and -use slower paths to get the correct result in other cases). - -cairo-win32 ------------ -Fix for older versions of mingw. - -Improve the handling of the clipping with the win32 and win32-printing -surfaces. - -Fix rendering of non black/white text. - -Snapshot 1.5.6 (2008-01-15 Carl Worth <cworth@cworth.org>) -========================================================== -This is the third snapshot in cairo's unstable 1.5 series. It comes -about 6 weeks after the 1.5.4 snapshot. The only API addition compared -to 1.5.4 is very minor, (a new value CAIRO_STATUS_TEMP_FILE_ERROR). -The remainder of the changes are the usual accumulation of bug fixes -and improvements. See below for details. - -General bug fixes ------------------ -Fix handling of fonts that contain a mixture of outline and bitmapped -glyphs. There was a change in this handling in 1.5.4 that improved -some cases and also regressed other cases. Now, all cases should be -handled quite well. - -Fix alignment issues that were causing SIGBUS failures on SPARC. - -Fix a regression (which first appeared in 1.5.2) where stroking under -a large scale would sometimes incorrectly replace a miter join with a -bevel join. (Thanks to Keith Packard.) - -Fix reporting of zero-sized extents to be {0,0} rather than -{INT_MAX,INT_MIN}. This avoids several integer overflow and -allocations of massive regions in some cases. - -Fix failures of gradients with no stops, (quartz, ps, and pdf). - -Fix handling of Type 1 fonts on Windows platforms. - -Fix handling of Type 1 fonts with no specific family name in the font -itself, (generate a CairoFont-x-y name). - -Handle NULL string values in cairo_show_text, cairo_show_glyphs, and -friends. - -Many robustness improvements along error-handling paths, (thanks as -always, to Chris "ickle" Wilson). - -Various other minor fixes. - -Paginated backends (PDF/PostScript/win32-printing) --------------------------------------------------- -Avoid unnecessary rasterization when using a paginated surface as a -source, (such as drawing from one pdf surface to another). - -Fix replaying of paginated surface with more than one level of push/pop -group. - -cairo-xlib ----------- -Fix xlib backend to not consider recent X server release as having a -buggy repeat implementation in the Render extension. - -cairo-pdf ---------- -Fix PDF output to avoid triggering very slow rendering in PDF viewers, -(avoid starting and stopping the content stream for each pattern -emission). - -Support CAIRO_OPERATOR_SOURCE in cases where there is nothing below -the object being drawn. - -Fix to avoid seams appearing between multiple fallback regions. - -cairo-ps (PostScript) ---------------------- -Use correct bounding box in Type 3 fonts. - -Fix several bugs in cairo's PostScript output. These include making -the PostScript output more compatible with recent versions of -ghostscript that are more strict about Type 3 fonts, for -example. - -Fix for win32 to not attempt to create temporary files in the root -directory, (where the user may not have write permission). - -Avoid generating Level 3 PostScript if Level 2 is sufficient. Also, -add code in output documents to alert the user if Level 3 PostScript -is handed to a device that cannot handle PostScript beyond Level -2. - -cairo-directfb --------------- -Various performance optimizations. - -Fixed support for small surfaces (less than 8x8). - -Provide support for environment variables CAIRO_DIRECTFB_NO_ACCEL to -disable acceleration and CAIRO_DIRECTFB_ARGB_FONT to enable ARGB fonts -instead of A8. - -cairo-os2 ---------- -Allow OS/2 APIs instead of C library allocation functions. - -Snapshot 1.5.4 (2007-12-05 Carl Worth <cworth@cworth.org>) -========================================================== -This is the second snapshot in cairo's unstable 1.5 series. It comes -just over 1 month after the 1.5.2 snapshot. There are no API changes -or additions in 1.5.4 compared to 1.5.2, but there are several bug -fixes, and some optimizations. Most of these apply to particular -backends. See below for details. - -General improvements --------------------- -Use less memory for spline approximation calculations. - -Change how the tolerance value is interpreted with regard to -fallback-resolution. [Note: On further discussion, we decided against -this change for now. It is removed as of cairo 1.5.10.] - -Fix precision of floating-point values in vector-output backends to -avoid rounding errors with very small numbers. - -Xlib improvements ------------------ -Fix bug in glyph rendering with xlib, (due to everything being clipped -out). This was a regression in the 1.5.2 snapshot that was visible in -the GIMP, for example. See: - - cairo 1.5.2 causes font problems in GIMP 2.4 status bar and evolution 2.12.1 - https://bugs.freedesktop.org/show_bug.cgi?id=13084 - -PostScript improvements ------------------------ -Fix bug leading to invalid PostScript files when rendering -text, (need "0 0 xyshow" instead of "0 xyshow"). - -Fix many issues with Type 3 fonts, including making the resulting text -extractable. - -Quartz improvements -------------------- -Fix font metrics height value for ATSUI, (helps webkit on GTK+ OS X -layout nicely). - -Fix gradients. - -Fix EXTEND_NONE mode for patterns. - -Fix cairo_quartz_surface_create to properly clear the new surface -in cairo_quartz_surface_create. - -Fix to correctly handle 0x0 sized surfaces. - -Optimize drawing of EXTEND_REPEAT patterns for OS X 10.5. - -Snapshot 1.5.2 (2007-10-30 Carl Worth <cworth@cworth.org>) -========================================================== -This is the first snapshot in cairo's unstable 1.5 series. It comes 4 -months after the 1.4.10 release. This snapshot includes significant -improvements to PDF and PostScript output, which is one of the things -in which we're most interested in getting feedback. There are a couple -of minor API additions, and several optimizations, (primarily in the -"print/vector" backends). And there are dozens of bug fixes and -robustness improvements. - -New dependency on external pixman library ------------------------------------------ -A significant change in this snapshot compared to all previous cairo -releases is that cairo now depends on an external "pixman" library for -its software rendering. Previously this same code was compiled -internally as part of cairo, but now the code is separate so that both -cairo and the X server can now share common code, (thanks very much to -Søren Sandmann for his work on separating pixman and maintaining it). - -So users will need to acquire and build pixman before being able to -build cairo. The current release is 0.9.6 and can be obtained from -here: - - http://cairographics.org/releases/pixman-0.9.6.tar.gz - - which can be verified with: - - http://cairographics.org/releases/pixman-0.9.6.tar.gz.sha1 - 66f01a682c64403a3d7a855ba5aa609ed93bcb9e pixman-0.9.6.tar.gz - - http://cairographics.org/releases/pixman-0.9.6.tar.gz.sha1.asc - (signed by Carl Worth) - -Major PDF/PostScript improvements ---------------------------------- -Adrian Johnson has done some long-awaited work to make cairo's PDF and -PostScript output more interesting than ever before. First, many -operations that previously triggered image fallbacks will now be -rendered as native vectors. These operations include: - - PDF: cairo_push_group, cairo_surface_create_similar, - cairo_mask, A8/A1 surface sources, repeating/reflecting linear - gradients. - - PostScript: cairo_push_group, cairo_surface_create_similar, - gradients, bilevel alpha masks, (for example, all values either 0 or - 255 for an A8 mask). - -Not only that, but when an image fallback is required, it will now be -limited to only the necessary region. For example, a tiny translucent -image overlaying a small portion of text would previously caused an -entire PostScript page to be rendered as a giant image. Now, the -majority of that page will be nice text, and there will only be a tiny -image in the output. - -Additionally, the PostScript output now carefully encodes text so that -if it is subsequently converted to PDF, the text will be -selectable. - -This is very exciting progress, and we're hoping to hear from users -during the 1.5 series about how things have improved, (for example, -inkscape users doing cairo-based PDF export: please let us know how -things look). And feel free to pass your thanks along to Adrian for his excellent work. - -NOTE: This much improved PDF output makes more sophisticated use of -functionality in the PDF specification. This means that cairo's output -will sometimes expose bugs in some free software PDF viewers, (evince, -poppler, and xpdf, for example), that are not yet ready for such PDF -files. We're working with the poppler maintainers to get these bugs -fixed as quickly as possible. In the meantime, please double-check -with other PDF viewers if cairo-generated PDF files are not being -rendered correctly. It may be due to a bug in the viewer rather than -in the PDF file that cairo has created. - -Robustness improvements ------------------------ -Chris Wilson has made the largest contribution by far to cairo 1.5.2, -(in number of commits). His more than 150 commits include a huge -number of fixes to increase cairo's robustness. These fixes make cairo -more robust against invalid and degenerate input, (NaN, empty path, -etc.), against size-0 malloc calls, against memory leaks on -error-recovery paths, and against other failures during error -handling. He also implemented atomic operations to cairo, and used -them to fix cairo's previously non-thread-safe reference counting, -again improving robustness. - -Chris has put a tremendous amount of time and effort into writing -analysis tools for this work, and in running those tools and fixing -the problems they report. We're very grateful for this work, and hope -that all cairo users appreciate the more robust implementation that -results from it. - -This work is largely thankless, so it might make sense to notice -sometime that cairo has been running quite smoothly for you, and when -you do, send a quick "thank you" off to Chris Wilson, since it -is all definitely running smoother thanks to his work. - -New API -------- -There are no major additions to cairo's core API. The only new, -generic functions are: - - void - cairo_surface_copy_page (cairo_surface_t *surface); - - void - cairo_surface_show_page (cairo_surface_t *surface); - -which can now be used much more conveniently than the existing -cairo_copy_page and cairo_show_page functions in some -situations. These functions act identically, but require only a -cairo_surface_t* and not a cairo_t*. - -All other API additions are specific to particular backends. - -New cairo-win32 API (new font face function and "win32 printing" surface) -------------------------------------------------------------------------- -There is a new function for creating a win32 font face for both a -logfontw and an hfont together. This complements the existing -functions for creating a font face from one or the other: - - cairo_font_face_t * - cairo_win32_font_face_create_for_logfontw_hfont (LOGFONTW *logfont, - HFONT font); - -There is also a new "win32 printing" surface: - - cairo_surface_t * - cairo_win32_printing_surface_create (HDC hdc); - -This interface looks identical to the original -cairo_win32_surface_create, (both accept and HDC), but the behavior of -this new surface is very different. It should only be called with a -printing DC, and will result in all drawing commands being stored into -a meta-surface and emitted after each page is complete, with analysis -to do as minimal image-based fallbacks as necessary. The behavior and -implementation shares much with the PDF and PostScript backends. - -New cairo-ps API (EPS and PostScript level control) ---------------------------------------------------- -An often requested feature has been the ability to generate -Encapsulated PostScript (EPS) with cairo. We have that now with the -following very simple API. Just do cairo_ps_surface_create as usual -then call this function with a true value: - - void - cairo_ps_surface_set_eps (cairo_surface_t *surface, - cairo_bool_t eps); - -[NOTE: As always with snapshots, it's possible---though not very -likely---that the API could still be modified before a final -release. For example, this is the first public cairo function that -accepts a Boolean parameter. I'm generally opposed to Boolean -parameters, but this is probably the one case where I'm willing to -accept one, (namely a "set" function that accepts a single Boolean).] - -Also, it is now possible to control what PostScript level to target, -(either level 2 or level 3), with the following new API: - - typedef enum _cairo_ps_level { - CAIRO_PS_LEVEL_2, - CAIRO_PS_LEVEL_3 - } cairo_ps_level_t; - - void - cairo_ps_surface_restrict_to_level (cairo_surface_t *surface, - cairo_ps_level_t level); - - void - cairo_ps_get_levels (cairo_ps_level_t const **levels, - int *num_levels); - - const char * - cairo_ps_level_to_string (cairo_ps_level_t level); - -Improvement for cairo-quartz ----------------------------- -Brian Ewins had contributed several improvements to cairo-quartz. These -include an implementation of EXTEND_NONE for linear and radial -gradients, (so this extend mode will no longer trigger image fallbacks -for these gradients), as well as native surface-mask clipping, (only -on OS X 10.4+ where the CGContextClipToMask function is available). - -He also fixed a semantic mismatch between cairo and quartz for dashing -with an odd number of entries in the dash array. - -We're grateful for Brian since not many quartz-specific improvements -to cairo would be happening without him. - -Optimizations -------------- -Optimize SVG output for when the same path is both filled and stroked, -and avoid unnecessary identity matrix in SVG output. (Emmanuel Pacaud). - -Optimize PS output to take less space (Ken Herron). - -Make PS output more compliant with DSC recommendations (avoid initclip -and copy_page) (Adrian Johnson). - -Make PDF output more compact (Adrian Johnson). - -Release glyph surfaces after uploading them to the X server, (should -save some memory for many xlib-using cairo application). (Behdad -Esfahbod). - -Optimize cairo-win32 to use fewer GDI objects (Vladimir Vukicevic). - -win32-printing: Avoid falling back to images when alpha == 255 -everywhere. (Adrian Johnson). - -win32-printing: Avoid falling back for cairo_push_group and -cairo_surface_create_similar. (Adrian Johnson) - -Bug fixes ---------- -Avoid potential integer overflows when allocating large buffers -(Vladimir Vukicevic). - -Preparations to allow the 16.16 fixed-point format to change to -24.8 (Vladimir Vukicevic). - -Fix bugs for unsupported X server visuals (rgb565, rgb555, bgr888, and -abgr8888). (Carl Worth and Vladimir Vukicevic) - -Fix bugs in PDF gradients (Adrian Johnson). - -Fix cairo-xlib to build without requiring Xrender header -files (Behdad Esfahbod). - -Make cairo more resilient in the case of glyphs not being available in -the current font. (Behdad Esfahbod) - -Prevent crashes when both atsui and ft font backends are compiled in -(Brian Ewins). - -Make font subsetting code more robust against fonts that don't include -optional tables (Adrian Johnson). - -Fix CFF subsetting bug, (which manifested by generating PDF files that -Apple's Preview viewer could not read) (Adrian Johnson). - -Fixed error handling for quartz and ATSUI backends (Brian Ewins). - -Avoid rounding problems by pre-transforming to avoid integer-only -restrictions on transformation in GDI (Adrian Johnson). - -Fixed an obscure bug (#7245) computing extents for some stroked -paths (Carl Worth). - -Fix crashes due to extreme transformation of the pen, (seems to show -up in many .swf files for some reason) (Carl Worth). - -Release 1.4.10 (2007-06-27 Carl Worth <cworth@cworth.org>) -========================================================== -This is the fifth update in cairo's stable 1.4 series. It comes -roughly three weeks after the 1.4.8 release. The most significant -change in this release is a fix to avoid an X error in certain cases, -(that were causing OpenOffice.org to crash in Fedora). There is also a -semantic change to include child window contents when using an xlib -surface as a source, an optimization when drawing many rectangles, and -several minor fixes. - -Eliminate X errors that were killing OO.o (Chris Wilson) --------------------------------------------------------- -Cairo is fixed to avoid the X errors propagated when cleaning up -Render Pictures after the application had already destroyed the -Drawable they reference. (It would be nice if the X server wouldn't -complain that some cleanup work is already done, but there you have -it.) This fixes the bug causing OpenOffice.org to crash as described -here: - - XError on right click menus in OOo. - https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=243811 - -Use IncludeInferiors when using xlib surface as a source (Ryan Lortie) ----------------------------------------------------------------------- -When an xlib surface is used as the source of a draw operation the -contents of child windows are now included in the source data. The -semantics of drawing to xlib surfaces are unchanged (ie: draws are -still clipped by child windows overlapping the destination window). - -Optimize drawing of many rectangles (Vladimir Vukicevic) --------------------------------------------------------- -Avoid O(N*N) loop when filling many axis-aligned rectangles, (either -many rectangles as separate sub-paths or due to dashing). - -Miscellaneous fixes -------------------- -Fix cairo-perf on Solaris by linking to librt. (Behdad Esfahbod) - -Fix make check for systems that require executable files to have a -particular extension. (Behdad Esfahbod) - -Eliminate some warnings in cairo-quartz. (Brian Ewins) - -Fix build-breaking typo for cairo-directfb. (Chris Wilson) - -Release 1.4.8 (2007-06-07 Carl Worth <cworth@cworth.org>) -========================================================= -This is the fourth update in cairo's stable 1.4 series. It comes just -over five weeks after the 1.4.6 release. This release includes a -thread-safe surface-cache for solid patterns which significantly -improves text rendering with the xlib backend. Also, dozens of error -paths in cairo have been fixed thanks to extensive fault-injection -testing by Chris Wilson. - -Surface cache for solid patterns --------------------------------- -Originally written by Jorn Baayen, the introduction of a small cache -for surfaces created for solid patterns improves performance -dramatically. For example, this reduces the volume of X requests -during text rendering to the same level as Xft. - -This cache first made its appearance in a 1.3.x snapshot, but was -removed before appearing in any previous major release due to -complications with multi-threaded programs. For example, programs like -evince that would carefully restrict usage of cairo-xlib to a single -thread were unpleasantly surprised to find that using cairo-image in a -separate thread could trigger X requests. - -Behdad Esfahbod designed a fix which was implemented by Chris -Wilson. Now, the necessary X requests are queued up until the next -time the application directly operates on an xlib surface. - -Improved error handling paths ------------------------------- -Chris Wilson continued the excellent work he started in cairo 1.4.4 to -make cairo much more robust against out-of-memory and other errors. He -applied his memory allocation fault injection cairo's main test suite, -(previously he had applied it to cairo's performance suite). - -Chris's testing found dozens of bugs which he fixed. Many of these -bugs had perhaps never been hit by any users. But at least one was -hit by the gnome-about program which resulted in dozens of duplicated -bug reports against that program: - - http://bugzilla.gnome.org/show_bug.cgi?id=431990 - -We were very pleasantly surprised to see this bug get fixed as a -side-effect of Chris's work. Well done, Chris! - -Other fixes ------------ -Cleanup of mutex declarations (Behdad Esfahbod) - -Remove unnecessary clip region from SVG output (Emmanuel Pacaud) - -Remove Xsun from the buggy_repeat blacklist (Elaine Xiong) - -ATSUI: Fix glyph measurement: faster and more correct (Brian Ewins) - -Quartz: fixed 'extend' behaviour for patterns, improved pattern performance, -and a few smaller correctness fixes. (Brian Ewins, Vladimir Vukicevic) - -Release 1.4.6 (2007-05-01 Carl Worth <cworth@cworth.org>) -========================================================= -This is the third update in cairo's stable 1.4 series. It comes a -little less than three weeks since the 1.4.4 release. This release -fixes the broken mutex initialization that made cairo 1.4.4 unusable -on win32, OS/2, and BeOS systems. This release also adds significant -improvements to cairo's PDF backend, (native gradients!), and a couple -of performance optimizations, (one of which is very significant for -users of the xlib backend). See below for more details. - -Repaired mutex initialization ------------------------------ -We apologize that cairo 1.4.4 did little more than crash on many -platforms which are less-frequently used by the most regular cairo -maintainers, (win32, OS/2, and BeOS). The mutex initialization -problems that caused those crashes should be fixed now. And to avoid -similar problems in the future, we've now started posting pre-release -snapshots to get better testing, (subscribe to cairo@cairographics.org -if you're interested in getting notified of those and testing them). - -PDF Improvements ----------------- -Thanks to Adrian Johnson, (cairo PDF hacker extraordinaire), we have -several improvements to cairo's PDF backend to announce: - -Native gradients: - - As of cairo 1.4.6, cairo will now generate native PDF gradients in - many cases, (previously, the presence of a gradient on any page - would force rasterized output for that page). Currently, only - gradients with extend types of PAD (the default) or NONE will - generate native PDF gradients---others will still trigger - rasterization, (but look for support for other extend modes in a - future release). Many thanks to Miklós Erdélyi as well, who did the - initial work for this support. - -Better compatibility with PDF viewers: - - The PDF output from cairo should now be displayed correctly by a - wider range of PDF viewers. Adrian tested cairo's PDF output against - many PDF viewers, identified a common bug in many of those viewers - (ignoring the CTM matrix in some cases), and modified cairo's output - to avoid triggering that bugs (pre-transforming coordinates and - using an identity matrix). - -Better OpenType/CFF subsetting: - - Cairo will now embed CFF and TrueType fonts as CID fonts. - -Performance optimizations -------------------------- -Faster cairo_paint_with_alpha: - - The cairo_paint_with_alpha call is used to apply a uniform alpha - mask to a pattern. For example, it can be used to gradually fade an - image out or in. Jeff Muizelaar fixed some missing/broken - optimizations within the implementation of this function resulting - in cairo_paint_with_alpha being up to 4 times faster when using - cairo's image backend. - -Optimize rendering of "off-screen" geometry: - - Something that applications often do is to ask cairo to render - things that are either partially or wholly outside the current clip - region. Since 1.4.0 the image backend has been fixed to not waste - too much time in this case. But other backends have still been - suffering. - - In particular, the xlib backend has often performed quite badly in - this situation. This is due to a bug in the implementation of - trapezoid rasterization in many X servers. - - Now, in cairo 1.4.6 there is a higher-level fix for this - situation. Cairo now eliminates or clips trapezoids that are wholly - or partially outside the clip region before handing the trapezoids - to the backend. This means that the X server's performance bug is - avoided in almost all cases. - - The net result is that doing an extreme zoom-in of vector-based - objects drawn with cairo might have previously brought the X server - to its knees as it allocated buffers large enough to fit all of the - geometry, (whether visible or not). But now the memory usage should - be bounded and performance should be dramatically better. - -Miscellaneous -------------- -Behdad contributed an impressively long series of changes that -organizes cairo's internals in several ways that will be very -beneficial to cairo developers. Thanks, Behdad! - -Behdad has also provided a utility for generating malloc statistics, -(which was used during the great malloc purges of 1.4.2 and -1.4.4). This utility isn't specific to cairo so may be of benefit to -others. It is found in cairo/util/malloc-stats.c and here are Behdad's -notes on using it: - - To build, do: - - make malloc-stats.so - - inside util/, and to use, run: - - LD_PRELOAD=malloc-stats.so some-program - - For binaries managed by libtool, eg, cairo-perf, do: - - ../libtool --mode=execute /bin/true ./cairo-perf - LD_PRELOAD="../util/malloc-stats.so" .libs/lt-cairo-perf - -Finally, the cairo-perf-diff-files utility was enhanced to allow for -generating performance reports from several runs of the same backend -while some system variables were changed. For example, this is now -being used to allow cairo-perf to measure the performance of various -different acceleration architectures and configuration options of the -X.org X server. - -Release 1.4.4 (2007-04-13 Carl Worth <cworth@cworth.org>) -========================================================= -This is the second update release in cairo's stable 1.4 series. It -comes just less than a month after 1.4.2. The changes since 1.4.2 -consist primarily of bug fixes, but also include at least one -optimization. See below for details. - -Of all the work that went into the 1.4.4 release - -There have been lots of individuals doing lots of great work on cairo, -but two efforts during the 1.4.4 series deserve particular mention: - -Internal cleanup of error handling, (Chris Wilson) --------------------------------------------------- -Chris contributed a tremendous series of patches (74 patches!) to -improve cairo's handling of out-of-memory and other errors. He began -by adding gcc's warn_unused_attribute to as many functions as -possible, and then launched into the ambitious efforts of adding -correct code to quiet the dozens of resulting warnings. - -Chris also wrote a custom valgrind skin to systematically inject -malloc failures into cairo, and did all the work necessary to verify -that cairo's performance test suite runs to completion without -crashing. - -The end result is a much more robust implementation. Previously, many -error conditions would have gone unnoticed and would have led to -assertion failures, segmentation faults, or other harder-to-diagnose -problems. Now, more than ever, cairo should cleanly let the user know -of problems through cairo_status and other similar status -functions. Well done, Chris! - -More malloc reduction, (Mathias Hasselmann) -------------------------------------------- -After 1.4.0, Behdad launched an effort to chase down excessive calls -to malloc within the implementation of cairo. He fixed a lot of -malloc-happy objects for 1.4.2, but one of the worst offenders, -(pixman regions), was left around. Mathias contributed an excellent -series of 15 patches to finish off this effort. - -The end result is a cairo that calls malloc much less often than it -did before. Compared to 1.4.2, 55% of the calls to malloc have been -eliminate, (and 60% have been eliminated compared to 1.4.0). Well -done, Mathias! - -Other improvements since 1.4.2 ------------------------------- -• Centralize mutex declarations (will reduce future build breaks), - (Mathias Hasselmann) - -• Reduce malloc by caching recently freed pattern objects (Chris - Wilson) - -• Fix some broken composite operations (David Reveman) - https://bugs.freedesktop.org/show_bug.cgi?id=5777 - -Backend-specific fixes ----------------------- -PDF: - • Use TJ operator for more compact representation of glyphs (Adrian - Johnson) - - • Fix glyph positioning bug when glyphs are not horizontal - http://lists.freedesktop.org/archives/cairo/2007-April/010337.html - -win32: - • Fix crash when rendering with bitmap fonts (Carl Worth) - https://bugzilla.mozilla.org/show_bug.cgi?id=376498 - -xlib: - • Turn metrics-hinting on by default (Behdad Esfahbod) - - • Fix edge-effect problem with transformed images drawn to xlib - (Behdad Esfahbod) - https://bugs.freedesktop.org/show_bug.cgi?id=10508 - - • Avoid dereferencing a NULL screen. (Chris Wilson) - https://bugs.freedesktop.org/show_bug.cgi?id=10517 - -Quartz/ATSUI: - • Fix scaling of glyph surfaces - (Brian Ewins) - https://bugs.freedesktop.org/show_bug.cgi?id=9568 - - • Fix compilation failure when both xlib and quartz enabled - (Brian Ewins) - - • Fix rounding bug leading to incorrectly positioned glyphs - (Robert O'Callahan) - https://bugs.freedesktop.org/show_bug.cgi?id=10531 - -Release 1.4.2 (2007-03-19 Carl Worth <cworth@cworth.org>) -========================================================= -This is the first update release in cairo's stable 1.4 series. It -comes just less than 2 weeks after 1.4.0. We hadn't anticipated an -update this early, but we've managed to collect some important fixes -that we wanted to get out to cairo users as soon as possible, (6 fixes -for crashes, 1 case where graphical elements would not be drawn at -all, a handful of backend-specific bugs, and several important build -fixes). - -There's almost nothing but bug fixes in this release, (see below one -optimization that Behdad did sneak in), so we recommend that everyone -upgrade to this release when possible. - -Thanks to the many people that worked to fix these bugs, and those -that did the work to report them and to test the fixes, (wherever -possible both names are credited below). - -Critical fixes --------------- -• Fix a crash due to a LOCK vs. UNLOCK typo (M. Drochner fixing Carl - Worth's embarrassing typo). - - http://bugs.freedesktop.org/show_bug.cgi?id=10235 - -• Fix potential buffer overflow, which on some systems with a checking - variant of snprintf would lead to a crash (Adrian Johnson, Stanislav - Brabec, and sangu). - - https://bugs.freedesktop.org/show_bug.cgi?id=10267 - https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=232576 - -• Fix a crash in cairo_stroke_extents or cairo_in_stroke when line - width is 0.0. (Carl Worth and Sebastien Bacher) - - https://bugs.freedesktop.org/show_bug.cgi?id=10231 - -• Fix a crash on certain combinations of X server/video drivers (Carl - Worth and Tomas Carnecky). - - https://bugs.freedesktop.org/show_bug.cgi?id=10250 - -• Fix a crash due to mishandling of invalid user input (Carl Worth and - Alexander Darovsky). - - https://bugs.freedesktop.org/show_bug.cgi?id=9844 - -• xlib: Cleanup server-side glyph caches on XCloseDisplay. This - eliminated a crash detected by the perf suite, (and that - applications could have run into as well). (Chris Wilson) - -Other bug fixes ---------------- -• Fix for some geometry which simply disappeared under some - transformations---a stroked line with an extreme skew in X, for - example (Carl Worth and Jonathan Watt). - - https://bugzilla.mozilla.org/show_bug.cgi?id=373632 - -• SVG: Fix radial gradients for CAIRO_EXTEND_REFLECT and when r0 > r1 - (Emmanuel Pacaud). - -• PDF: Set page group color space to DeviceRGB. - - This fixes incorrect (muddy) transparent colors when rendering cairo - PDF output in some viewers. (Adrian Johnson, Adam Goode, and - MenTaLguY). - - http://lists.freedesktop.org/archives/cairo/2006-November/008551.html - -• win32: Return correct metrics when hinting is off, and fix font - descent computation (Behdad Esfahbod). - -• quartz: Fix glyph interfaces to correctly return user-space rather - than device-space coordinates (Brian Ewins). - - https://bugs.freedesktop.org/show_bug.cgi?id=9568 - -• xcb: Fix parameter-order confusion with xcb_create_pixmap, which now - makes all tests that pass with xlib now pass with xcb (Carl Worth, - Jamey Sharp). - -• Fix some memory leaks in the perf suite (Chris Wilson). - -• Fix perf suite to consider changes in pixman/src (Mathias - Hasselmann). - -Build fixes ------------ -• Don't include pre-generated cairo-features.h file. This was causing - build failures when building with the directfb backend enabled - (Behdad Esfahbod). - - https://bugs.freedesktop.org/show_bug.cgi?id=10189 - -• Eliminate use of maintainer mode from cairo's automake/configure - script. This means that updates to files such as Makefile.am will - take effect, (by rerunning automake and friends as necessary) when - invoking make rather than being silently ignored. (Behdad Esfahbod) - -• Don't compile cairo-deflate-stream.c, which depends on zlib, unless - building the pdf backend which requires it. (Carl Worth, Tor - Lillqvist) - - https://bugs.freedesktop.org/show_bug.cgi?id=10202 - -• Don't make the ps backend link against zlib anymore, since it - doesn't require it (Carl Worth). - -• Use "find !" rather than "find -not" for better portability (Thomas - Klausner). - - https://bugs.freedesktop.org/show_bug.cgi?id=10226 - -• Don't use unsupported visibility attribute "hidden" on Solaris - (Gilles Dauphin, Thomas Klausner). - - https://bugs.freedesktop.org/show_bug.cgi?id=10227 - -Optimization ------------- -• It was Behdad that suggested we focus strictly on bug fixes now that - we shipped so many performance improvements in 1.4.0, but it was - also Behdad that got distracted by the chance to remove a lot of - mallocs from cairo. Paths, gstates, trapezoids, splines, polygons, - and gradient color stops will now use small, stack-allocated buffers - in the most common cases rather than calling malloc as - often. (Behdad Esfahbod). And look for more from Mathias Hasselmann - soon. - -Release 1.4.0 (2007-03-06 Carl Worth <cworth@cworth.org>) -========================================================= -The many people[*] who have been working hard on cairo are very -pleased to announce the long-awaited release of cairo 1.4. This -release comes 4 months after the last stable update release (1.2.6) -and 9 months since the initial release of 1.2.0. - -The release notes below are intended to capture the highlights of the -changes that have occurred from the 1.2 series to the new 1.4.0 -release. - -Performance improvements ------------------------- -Within the cairo project, the last 6 months or so has seen an intense -effort focusing on the performance of cairo itself. That effort has -paid off considerably, as can be seen in the following highlights of -some of the performance differences from cairo 1.2.6 to cairo 1.4.0. - -(Note: The performance results reported here were measured on an x86 -laptop. Many of the improvements in 1.4---particular those involving -text rendering---are even more dramatic on embedded platforms without -hardware floating-point units. Such devices played an important part -of many of the optimizations that found their way into cairo over the -last few months.) - -• Dramatic improvement when drawing objects that are mostly off-screen - with the image backend (with the xlib backend this case is still - slow due to an X server bug): - - image-rgba long-lines-uncropped-100 479.64 -> 4.98: 96.24x speedup - ███████████████████████████████████████████████▋ - -• Dramatic improvement when copying a small fraction of an image - surface to an xlib surface: - - xlib-rgba subimage_copy-512 3.93 -> 0.07: 54.52x speedup - ██████████████████████████▊ - -• Dramatic improvement to tessellation speed for complex objects: - - image-rgb tessellate-256-100 874.16 -> 34.79: 25.13x speedup - ████████████■- xlib-rgba zrusin_another_fill-415 148.40 -> 13.85: 10.72x speedup - ████▉ - xlib-rgb world_map-800 680.20 -> 345.54: 1.97x speedup - â–Œ - -• Dramatic improvement to the speed of stroking rectilinear shapes, - (such as the outline of a rectangle or "box"): - - image-rgb box-outline-stroke-100 0.18 -> 0.01: 24.22x speedup - ███████████▋ - xlib-rgb box-outline-stroke-100 0.46 -> 0.06: 8.05x speedup - ███▌ - - -• Dramatic improvements to text rendering speeds: - - xlib-rgba text_image_rgba_over-256 63.12 -> 9.61: 6.57x speedup - ██▊ - -• 3x improvements to floating-point to fixed-point conversion speeds: - - image-rgba pattern_create_radial-16 9.29 -> 3.44: 2.70x speedup - â–‰ - -• 2x improvements to linear gradient computation: - - image-rgb paint_linear_rgb_source-512 26.22 -> 11.61: 2.26x speedup - â–‹ - -• 2x improvement to a case common in PDF rendering: - - image-rgb unaligned_clip-100 0.10 -> 0.06: 1.81x speedup - â– - -• 1.3x improvement to rectangle filling speed (note: this improvement - is new since 1.3.16---previously this test case was a 1.3x slowdown - compared to 1.2.6): - - image-rgba rectangles-512 6.19 -> 4.37: 1.42x speedup - â–Ž - xlib-rgba rectangles-512 7.48 -> 5.58: 1.34x speedup - â– - -NOTE: In spite of our best efforts, there are some measurable -performance regressions in 1.4 compared to 1.2. It appears that the -primary problem is the increased overhead of the new tessellator when -drawing many, very simple shapes. The following test cases capture -some of that slowdown: - - image-rgba mosaic_tessellate_lines-800 11.03 -> 14.29: 1.30x slowdown - â– - image-rgba box-outline-fill-100 0.01 -> 0.01: 1.26x slowdown - â– - image-rgba fill_solid_rgb_over-64 0.20 -> 0.22: 1.12x slowdown - - image-rgba fill_image_rgba_over-64 0.23 -> 0.25: 1.10x slowdown - - xlib-rgb paint_image_rgba_source-256 3.24 -> 3.47: 1.07x slowdown - -We did put some special effort into eliminating this slowdown for the -very common case of drawing axis-aligned rectangles with an identity -matrix (see the box-outline-stroke and rectangles speedup numbers -above). Eliminating the rest of this slowdown will be a worthwhile -project going forward. - -Also note that the "box-outline-fill" case is a slowdown while -"box-outline-stroke" is a (huge) speedup. These two test cases -resulted from the fact that some GTK+ theme authors were filling -between two rectangles to avoid slow performance from the more natural -means of achieving the same shape by stroking a single rectangle. With -1.4 that workaround should definitely be eliminated as it will now -cause things to perform more slowly. - -Greatly improved PDF output ---------------------------- -We are very happy to be able to announce that cairo-generated PDF -output will now have text that can be selected, cut-and-pasted, and -searched with most capable PDF viewer applications. This is something -that was not ever possible with cairo 1.2. - -Also, the PDF output now has much more compact encoding of text than -before. Cairo is now much more careful to not embed multiple copies of -the same font at different sizes. It also compresses text and font -streams within the PDF output. - -API additions -------------- -There are several new functions available in 1.4 that were not -available in 1.2. Curiously, almost all of the new functions simply -allow the user to query state that has been set in cairo (many new -"get" functions) rather than providing any fundamentally new -operations. The new functionality is: - -• Getting information about the current clip region - - cairo_clip_extents - cairo_copy_clip_rectangle_list - cairo_rectangle_list_destroy - -• Getting information about the current dash setting - - cairo_get_dash_count - cairo_get_dash - -• Getting information from a pattern - - cairo_pattern_get_rgba - cairo_pattern_get_surface - cairo_pattern_get_color_stop_rgba - cairo_pattern_get_color_stop_count - cairo_pattern_get_linear_points - cairo_pattern_get_radial_circles - -• Getting the current scaled font - - cairo_get_scaled_font - -• Getting reference counts - - cairo_get_reference_count - cairo_surface_get_reference_count - cairo_pattern_get_reference_count - cairo_font_face_get_reference_count - cairo_scaled_font_get_reference_count - -• Setting/getting user data on objects - - cairo_set_user_data - cairo_get_user_data - cairo_pattern_set_user_data - cairo_pattern_get_user_data - cairo_scaled_font_set_user_data - cairo_scaled_font_get_user_data - -• New cairo-win32 functions: - - cairo_win32_surface_create_with_ddb - cairo_win32_surface_get_image - cairo_win32_scaled_font_get_logical_to_device - cairo_win32_scaled_font_get_device_to_logical - -API deprecation ---------------- -The CAIRO_FORMAT_RGB16_565 enum value has been deprecated. It never -worked as a format value for cairo_image_surface_create, and it wasn't -necessary for supporting 16-bit 565 X server visuals. - -A sampling of bug fixes in cairo 1.4 ------------------------------------- - • Fixed radial gradients - • Fixed dashing (degenerate and "leaky" cases) - • Fixed transformed images in PDF/PS output (eliminate bogus repeating) - • Eliminate errors from CAIRO_EXTEND_REFLECT and CAIRO_EXTEND_PAD - • cairo_show_page no longer needed for single-page output - • SVG: Fix bug preventing text from appearing in many viewers - • cairo-ft: Return correct metrics when hinting is off - • Eliminate crash in cairo_create_similar if nil surface is returned - • Eliminate crash after INVALID_RESTORE error - • Fix many bugs related to multi-threaded use and locking - • Fix for glyph spacing 32 times larger than desired (cairo-win32) - • Fixed several problems in cairo-atsui (assertion failures) - • Fix PDF output to avoid problems when printing from Acrobat Reader - • Fix segfault on Mac OS X (measuring a zero-length string) - • Fix text extents to not include the size of non-inked characters - • Fix for glyph cache race condition in glitz backend (Jinghua Luo) - • Fix make check to work on OPD platforms (IA64 or PPC64) - • Fix compilation problems of cairo "wideint" code on some platforms - • Many, many others... - -Experimental backends (quartz, XCB, OS/2, BeOS, directfb) ---------------------------------------------------------- -None of cairo's experimental backends are graduating to "supported" -status with 1.4.0, but two of them in particular (quartz and xcb), are -very close. - -The quartz baceknd has been entirely rewritten and is now much more -efficient. The XCB backend has been updated to track the latest XCB -API (which recently had a 1.0 release). - -We hope to see these backends become supported in a future release, -(once they are passing all the tests in cairo's test suite). - -The experimental OS/2 backend is new in cairo 1.4 compared to cairo -1.2. - -Documentation improvements --------------------------- -We have added documentation for several functions and types that -were previously undocumented, and improved documentation on other -ones. As of this release, there remain only two undocumented -symbols: cairo_filter_t and cairo_operator_t. - -[*]Thanks to everyone ---------------------- -I've accounted for 41 distinct people with attributed code added to -cairo between 1.2.6 and 1.4.0, (their names are below). That's an -impressive number, but there are certainly dozens more that -contributed with testing, suggestions, clarifying questions, and -encouragement. I'm grateful for the friendships that have developed as -we have worked on cairo together. Thanks to everyone for making this -all so much fun! - -Adrian Johnson, Alfred Peng, Alp Toker, Behdad Esfahbod, -Benjamin Otte, Brian Ewins, Carl Worth, Christian Biesinger, -Christopher (Monty) Montgomery, Daniel Amelang, Dan Williams, -Dave Yeo, David Turner, Emmanuel Pacaud, Eugeniy Meshcheryakov, -Frederic Crozat, Hans Breuer, Ian Osgood, Jamey Sharp, Jeff Muizelaar, -Jeff Smith, Jinghua Luo, Jonathan Watt, Joonas Pihlaja, Jorn Baayen, -Kalle Vahlman, Kjartan Maraas, Kristian Høgsberg, M Joonas Pihlaja, -Mathias Hasselmann, Mathieu Lacage, Michael Emmel, Nicholas Miell, -Pavel Roskin, Peter Weilbacher, Robert O'Callahan, -Soren Sandmann Pedersen, Stuart Parmenter, T Rowley, -Vladimir Vukicevic - -Snapshot 1.3.16 (2007-03-02 Carl Worth <cworth@cworth.org>) -=========================================================== -New API functions ------------------ -A few new public functions have been added to the cairo API since the -1.3.14 snapshot. These include a function to query the current scaled -font: - - cairo_get_scaled_font - -New functions to query the reference count of all cairo objects: - - cairo_get_reference_count - - cairo_surface_get_reference_count - cairo_pattern_get_reference_count - - cairo_font_face_get_reference_count - cairo_scaled_font_get_reference_count - -And new functions to allow the use of user_data with any cairo object, -(previously these were only available on cairo_surface_t and -cairo_font_face_t objects): - - cairo_set_user_data - cairo_get_user_data - - cairo_pattern_set_user_data - cairo_pattern_get_user_data - - cairo_scaled_font_set_user_data - cairo_scaled_font_get_user_data - -Usability improvement for PDF/PS/SVG generation ------------------------------------------------ -In previous versions of cairo, generating single-page output with the -cairo-pdf, cairo-ps, or cairo-svg backends required a final call to -cairo_show_page. This was often quite confusing as people would port -functional code from a non-paginated backend and be totally mystified -as to why the output was blank until they learned to add this call. - -Now that call to cairo_show_page is optional, (it will be generated -implicitly if the user does not call it). So cairo_show_page is only -needed to explicitly separate multiple pages. - -Greatly improved PDF output ---------------------------- -We are very happy to be able to announce that cairo-generated PDF -output will now have text that can be selected, cut-and-paste, and -searched with most capable PDF viewer applications. This is something -that was not ever possible with cairo 1.2. - -Also, the PDF output now has much more compact encoding of text than -before. Cairo is now much more careful to not embed multiple copies of -the same font at different sizes. It also compresses text and font -streams within the PDF output. - -Major bug fixes ---------------- - • Fixed radial gradients - - The rendering of radial gradients has been greatly improved. In - the cairo 1.2 series, there was a serious regression affecting - radial gradients---results would be very incorrect unless one of - the gradient circles had a radius of 0.0 and a center point within - the other circle. These bugs have now been fixed. - - • Fixed dashing - - Several fixes have been made to the implementation of dashed - stroking. Previously, some dashed, stroked rectangles would - mis-render and fill half of the rectangle with a large triangular - shape. This bug has now been fixed. - - • Fixed transformed images in PDF/PS output - - In previous versions of cairo, painting with an image-based source - surface pattern to the PDF or PS backends would cause many kinds - of incorrect results. One of the most common problems was that an - image would be repeated many times even when the user had - explicitly requested no repetition with CAIRO_EXTEND_NONE. These - bugs have now been fixed. - - • Eliminate errors from CAIRO_EXTEND_REFLECT and CAIRO_EXTEND_PAD - - In the 1.2 version of cairo any use of CAIRO_EXTEND_REFLECT or - CAIRO_EXTEND_PAD with a surface-based pattern resulted in an - error, (cairo would stop rendering). This bug has now been - fixed. - - Now, CAIRO_EXTEND_REFLECT should work properly with surface - patterns. - - CAIRO_EXTEND_PAD is still not working correctly, but it will now - simply behave as CAIRO_EXTEND_NONE rather than triggering the - error. - -New rewrite of quartz backend (still experimental) --------------------------------------------------- -Cairo's quartz backend has been entirely rewritten and is now much -more efficient. This backend is still marked as experimental, not -supported, but it is now much closer to becoming an officially -supported backend. (For people that used the experimental nquartz -backend in previous snapshots, that implementation has now been -renamed from "nquartz" to "quartz" and has replaced the old quartz -backend.) - -Documentation improvements --------------------------- -We have added documentation for several functions and types that -were previously undocumented, and improved documentation on other -ones. As of this release, there remain only two undocumented -symbols: cairo_filter_t and cairo_operator_t. - -Other bug fixes ---------------- - • cairo-svg: Fix bug that was preventing text from appearing in many - viewers - - • cairo-ft: Return correct metrics when hinting is off - - • Cairo 1.3.14 deadlocks in cairo_scaled_font_glyph_extents or - _cairo_ft_unscaled_font_lock_face - - https://bugs.freedesktop.org/show_bug.cgi?id=10035 - - • cairo crashes in cairo_create_similar if nil surface returned by - other->backend->create_similar - - https://bugs.freedesktop.org/show_bug.cgi?id=9844 - - • evolution crash in _cairo_gstate_backend_to_user() - https://bugs.freedesktop.org/show_bug.cgi?id=9906 - - • Fix memory leak in rectilinear stroking code - -Things not in this release --------------------------- - • Solid-surface-pattern cache: This patch had been applied during - the 1.3.x series, but it was reverted due to some inter-thread - problems it caused. The patch is interesting since it made a big - benefit for text rendering performance---so we'll work to bring a - corrected version of this patch back as soon as possible. - -Snapshot 1.3.14 (2006-02-13 Carl Worth <cworth@cworth.org>) -=========================================================== -This is the seventh development snapshot in the 1.3 series, (and there -likely won't be many more before the 1.4.0 release). It comes just -over 3 weeks after the 1.3.12 snapshot. - -Since we're so close to the 1.4.0 release, there are not a lot of new -features nor even a lot of new performance improvements in this -snapshot. Instead, there are a great number of bug fixes. Some are -long-standing bugs that we're glad to say goodbye to, and several are -fixes for regressions that were introduced as part of the optimization -efforts during the 1.3.x series. - -PDF text selection fixed ------------------------- -The inability to correctly select text in cairo-generated PDF has been -a defect ever since the initial support for the PDF backend in the -cairo 1.2.0 release. With the 1.3.14 snapshot, in most situations, and -with most PDF viewer applications, the PDF generated by cairo will -allow text to be correctly selected for copy-and-paste, (as well as -searching). - -We're very excited about this new functionality, (and very grateful to -Adrian Johnson, Behdad Esfahbod, and others that have put a lot of -work into this lately). Please test this new ability and give feedback -on the cairo@cairographics.org list. - -Many thread-safety issues fixed -------------------------------- -We've discovered that no release of cairo has ever provided safe text -rendering from a multi-threaded application. With the 1.3.14 snapshot -a huge number of the bugs in this area have been fixed, and multiple -application dvelopers have now reported success at writing -multi-threaded applications with cairo. - -Other fixes ------------ -Fixed a bug that was causing glyph spacing to be 32 times larger than -desired when using cairo-win32. - -Fixed a regression in the rendering of linear gradients that had been -present since the 1.3.8 snapshot. - -Fixed several problems in cairo-atsui that were leading to assertion -failures when rendering text. - -Fix corrupted results when rendering a transformed source image -surface to an xlib surface. This was a regression that had been -present since the 1.3.2 snapshot. - -Fixed PDF output to prevent problems printing from some versions of -Acrobat Reader, (a single glyph was being substituted for every -glyph). - -And many other fixes as well, (see the logs for details). - -Snapshot 1.3.12 (2007-01-20 Carl Worth <cworth@cworth.org>) -=========================================================== -The relentless march toward the cairo 1.4 release continues, (even if -slightly late out of the starting blocks in 2007). This is the sixth -development snapshot in the 1.3 series. It comes 4 weeks after the -1.3.10 snapshot. - -Performance ------------ -As usual, this snapshot has some fun performance improvements to show -off: - -image-rgba long-lines-uncropped-100 470.08 -> 4.95: 94.91x speedup -███████████████████████████████████████████████ -image-rgb long-lines-uncropped-100 461.60 -> 4.96: 93.02x speedup -██████████████████████████████████████████████ - -This 100x improvement, (and yes, that's 100x, not 100%), in the image -backend occurs when drawing large shapes where only a fraction of the -shape actually appears in the final result, (the rest being outside -the bounds of the destination surface). Many applications should see -speedups here, and the actual amount of speedup depends on the ratio -of non-visible to visible portions of geometry. - -[Note: There remains a similar performance bug when drawing mostly -non-visible objects with the xlib backend. This is due to a similar -bug in the X server itself, but we hope a future cairo snapshot will -workaround that bug to get a similar speedup with the xlib backend.] - -image-rgba unaligned_clip-100 0.09 -> 0.06: 1.67x speedup -â– -image-rgb unaligned_clip-100 0.09 -> 0.06: 1.66x speedup -â– - -This speedup is due to further MMX optimization by Soeren Sandmann for -a case commonly hit when rendering PDF files, (and thanks to Jeff -Muizelaar for writing code to extract the test case for us). - -There's another MMX optimization in this snapshot (without a fancy -speedup chart) by Dan Williams which improves compositing performance -specifically for the OLPC machine. - -Thanks to Adrian Johnson, cairo's PDF output is now much more -efficient in the way it encodes text output. By reducing redundant -information and adding compression to text output streams, Adrian -achieved a ~25x improvement in the efficiency of encoding text in PDF -files, (was ~45 bytes per glyph and is now ~1.6 bytes per glyph). - -Bug fixes ---------- -In addition to those performance improvements, this snapshot includes -several bug fixes: - - * A huge number of bug fixes for cairo-atsui text rendering, (for mac - OS X). These bugs affect font selection, glyph positioning, glyph - rendering, etc. One noteworthy bug fixes is that - cairo_select_font_face will no longer arbitrarily select bold nor - italic when not requested, (at least not when using a standard CSS2 - font family name such as "serif", "sans-serif", "monospace", etc.). - All these fixes are thanks to Brian Ewins who continues to do a - great job as the new cairo-atsui maintainer. - - * Fix PDF output so that images that are scaled down no longer - mysteriously repeat (Carl Worth). - - * Fix segfault on Mac OS X dues to attempt to measure extents of a - zero-length string (Behdad Esfahbod). - - * Fix text extents to not include the size of initial/trailing - non-inked characters (Behdad Esfahbod). - -API tweaks ----------- -Three functions have had API changes to improve consistency. Note that -the API functions being changed here are all functions that were -introduced as new functions during these 1.3.x snapshots. As always, -there will not be any API changes to functions included in a major -release (1.2.x, 1.4.x, etc.) of cairo. - -The changes are as follows: - - * Rename of cairo_copy_clip_rectangles to cairo_copy_clip_rectangle_list. - - * Change cairo_get_dash_count to return an int rather than accepting a - pointer to an int for the return value. - - * Change cairo_get_dash to have a void return type rather than - returning cairo_status_t. - -It's possible there will be one more round of changes to these -functions, (and perhaps cairo_get_color_stop as well), as we seek to -establish a unifying convention for returning lists of values. - -Snapshot 1.3.10 (2006-12-23 Carl Worth <cworth@cworth.org>) -=========================================================== -Santa Claus is coming just a little bit early this year, and he's -bringing a shiny new cairo snapshot for all the good little boys and -girls to play with. - -This is the fifth development snapshot in the 1.3 series. It comes 9 -days after the 1.3.8 snapshot, and still well within our goal of -having a new snapshot every week, (though don't expect one next -week---we'll all be too stuffed with sugar plums). - -Speaking of sugar plums, there's a sweet treat waiting in this cairo -snapshot---greatly improved performance for stroking rectilinear -shapes, like the ever common rectangle: - -image-rgb box-outline-stroke-100 0.18 -> 0.01: 25.58x speedup -████████████████████████▋ -image-rgba box-outline-stroke-100 0.18 -> 0.01: 25.57x speedup -████████████████████████▋ -xlib-rgb box-outline-stroke-100 0.49 -> 0.06: 8.67x speedup -███████▋ -xlib-rgba box-outline-stroke-100 0.22 -> 0.04: 5.39x speedup -████■- -In past releases of cairo, some people had noticed that using -cairo_stroke to draw rectilinear shapes could be awfully slow. Many -people had worked around this by using cairo_fill with a more complex -path and gotten a 5-15x performance benefit from that. - -If you're one of those people, please rip that workaround out, as now -the more natural use of cairo_stroke should be 1.2-2x faster than the -unnatural use of cairo_fill. - -And if you hadn't ever implemented that workaround, then you just -might get to see your stroked rectangles now get drawn 5-25x faster. - -Beyond that performance fix, there are a handful of bug fixes in this -snapshot: - - * Fix for glyph cache race condition in glitz backend (Jinghua Luo) - - * Many fixes for ATSUI text rendering (Brian Ewins) - - * Un-break recent optimization-triggered regression in rendering text - with a translation in the font matrix (Behdad Esfahbod) - - * Fix make check to work on OPD platforms (IA64 or PPC64) - (Frederic Crozat) - - * Fix a couple of character spacing issues on Windows - (Jonathan Watt) - -Have fun with that, everybody, and we'll be back for more in the new -year, (with a plan to add the last of our performance improvements in -this round, fix a few bad, lingering bugs, and then finish off a nice, -stable 1.4 release before the end of January). - --Carl - -Snapshot 1.3.8 (2006-12-14 Carl Worth <cworth@cworth.org>) -========================================================== -This is the fourth development snapshot in the 1.3 series. It comes -just slightly more than one week after the 1.3.6 snapshot. - -After the bug fixes in 1.3.6, we're back to our original program of -weekly snapshots, each one faster than the one from the week -before. Cairo 1.3.8 brings a 2x improvement in the speed of rendering -linear gradients (thanks to David Turner), and a significant reduction -in X traffic when rendering text (thanks to Xan Lopez and Behdad -Esfahbod), making cairo behave very much like Xft does. - -A few other things in the 1.3.8 snapshot worth noting include a more -forgiving image comparator in the test suite, (using the "perceptual -diff" metric and GPL implementation by Hector Yee[*]), a bug fix for -broken linking on x86_64 (thanks to M Joonas Pihlaja) and an even -better implementation of _cairo_lround, (not faster, but supporting a -more complete input range), from Daniel Amelang. - -[*] http://pdiff.sourceforge.net/ - -Snapshot 1.3.6 (2006-12-06 Carl Worth <cworth@cworth.org>) -========================================================== -This is the third development snapshot in the 1.3 series. It comes two -weeks after the 1.3.4 snapshot. - -We don't have fancy performance charts this week as the primary -changes in this snapshot are bug fixes. The performance work continues -and the next snapshot (planned for one week from today) should include -several improvements. The bug fixes in this snapshot include: - - * Fix undesirable rounding in glyph positioning (Dan Amelang) - - This bug was noticed by several users, most commonly by seeing - improper text spacing or scrambled glyphs as drawn by nautilus. For - example: - - Update to cairo-1.3.4 worsen font rendering - https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=217819 - - * Fix reduced range of valid input coordinates to tessellator - (M Joonas Pihlaja) - - This bug was causing lots of assertion failures in mozilla as - mentioned here: - - CAIRO_BO_GUARD_BITS and coordinate space? - http://lists.freedesktop.org/archives/cairo/2006-December/008743.html - - * Fix several regressions in new tessellator (M Joonas Pihlaja) - - Joonas just had a good eye for detail here. I don't think any - external cairo users had noticed any of these bugs yet. - - * Fix compilation problems of cairo "wideint" code on some platforms - (Mathieu Lacage) - - * Fix failed configure due to broken grep (Dan Amelang) - - This bug was reported here: - - AX_C_FLOAT_WORDS_BIGENDIAN doesn't work because grep doesn't - work with binary file - https://bugs.freedesktop.org/show_bug.cgi?id=9124 - - * Remove the pkg-config minimum version requirement (Behdad Esfahbod) - - Some systems ship with pkg-config 0.15 and there was really no good - reason for cairo to insist on having version 0.19 before it would - build. - -There is also one new (but inert) feature in this snapshot. There's a -new option that can be passed to cairo's configure script: - - --disable-some-floating-point - - Disable certain code paths that rely heavily on double precision - floating-point calculation. This option can improve - performance on systems without a double precision floating-point - unit, but might degrade performance on those that do. - -As of this snapshot, this option does not make any change to cairo, -but it is possible that future versions of cairo will respect this -option and change the implementation of various functions as -appropriate. - -Snapshot 1.3.4 (2006-11-22 Carl Worth <cworth@cworth.org>) -========================================================== -This is the second development snapshot in the 1.3 series. It comes -one week after the 1.3.2 snapshot. - -This snapshot has a couple of significant performance improvements, -and also adds new support for producing multi-page SVG output, (when -targeting SVG 1.2)---thanks to Emmanuel Pacaud. The details of the -performance improvements are as follows: - -1. The long-awaited "new tessellator". - - The credit for this being an improvement goes to Joonas Pihlaja. He - took my really slow code and really put it through its paces to get - the dramatic performance improvement seen below (up to 38x faster - on realistic cases, and more than 10x faster for the zrusin_another - test). - - His own writeup of the work he did is quite thorough, but more than - can be quoted here. Please see his post for the interesting details: - - http://lists.freedesktop.org/archives/cairo/2006-November/008483.html - - (Though note that this snapshot also includes some additional, - significant improvements that were only sketched out in that - email---see "Generating fewer trapezoids"). - -2. More floating-point improvements - - Daniel Amelang continues to work the magic he began in the 1.3.2 - snapshot. This time he short-circuits floating-point - transformations by identity matrices and applies the earlier - floating-to-fixed-point technique to the problem of rounding. - - The improvements here will primarily benefit text performance, and - will benefit platforms without hardware floating-point more than - those that have it, (some text tests show 20% improvement on an x86 - machine and closer to 80% improvement on arm). - -The performance chart comparing 1.3.2 to 1.3.4 really speaks for -itself, (this is on an x86 laptop). This is quite a lot of progress -for one week: - - xlib-rgb stroke_similar_rgba_over-256 74.99 1.45% -> 2.03 68.38%: 36.86x speedup -███████████████████████████████████▉ - xlib-rgb stroke_similar_rgba_source-256 78.23 1.43% -> 3.30 67.05%: 23.71x speedup -██████████████████████▊ - xlib-rgba tessellate-256-100 820.42 0.15% -> 35.06 2.84%: 23.40x speedup -██████████████████████■-image-rgba tessellate-256-100 819.55 0.32% -> 35.04 3.56%: 23.39x speedup -██████████████████████■- xlib-rgb stroke_image_rgba_over-256 78.10 1.43% -> 4.33 65.56%: 18.04x speedup -█████████████████ - xlib-rgb stroke_image_rgba_source-256 80.11 1.63% -> 5.75 63.99%: 13.94x speedup -█████████████ - xlib-rgba zrusin_another_tessellate-415 89.22 0.35% -> 8.38 5.23%: 10.65x speedup -█████████▋ -image-rgba zrusin_another_tessellate-415 87.38 0.89% -> 8.37 5.22%: 10.44x speedup -█████████■-image-rgba zrusin_another_fill-415 117.67 1.34% -> 12.88 2.77%: 9.14x speedup -████████■- xlib-rgba zrusin_another_fill-415 140.52 1.57% -> 15.79 2.88%: 8.90x speedup -███████▉ -image-rgba tessellate-64-100 9.68 3.42% -> 1.42 0.60%: 6.82x speedup -█████▉ - xlib-rgba tessellate-64-100 9.78 4.35% -> 1.45 0.83%: 6.72x speedup -█████▊ - xlib-rgb stroke_linear_rgba_over-256 46.01 2.44% -> 7.74 54.51%: 5.94x speedup -█████ - xlib-rgb stroke_linear_rgba_source-256 48.09 2.15% -> 9.14 53.00%: 5.26x speedup -████▎ - xlib-rgb stroke_radial_rgba_over-256 50.96 2.34% -> 12.46 47.99%: 4.09x speedup -███■- xlib-rgb stroke_radial_rgba_source-256 53.06 1.57% -> 13.96 46.57%: 3.80x speedup -██▊ -image-rgba paint_similar_rgba_source-256 0.12 1.57% -> 0.08 9.92%: 1.42x speedup -â– -image-rgba paint_image_rgba_source-256 0.12 2.49% -> 0.08 10.70%: 1.41x speedup -â– -image-rgba world_map-800 356.28 0.46% -> 275.72 1.15%: 1.29x speedup -â–Ž - xlib-rgba world_map-800 456.81 0.39% -> 357.95 1.39%: 1.28x speedup -â–Ž -image-rgb tessellate-16-100 0.09 0.57% -> 0.07 3.43%: 1.23x speedup -â–Ž -image-rgba tessellate-16-100 0.09 0.06% -> 0.07 2.46%: 1.23x speedup -â–Ž -image-rgba text_solid_rgb_over-256 5.39 4.01% -> 4.47 0.70%: 1.21x speedup -â–Ž -image-rgba text_solid_rgba_over-256 5.37 0.82% -> 4.45 0.75%: 1.21x speedup -â–Ž -image-rgba text_image_rgb_over-64 0.78 0.10% -> 0.65 0.74%: 1.20x speedup -â–Ž -image-rgba text_image_rgba_over-64 0.78 0.29% -> 0.65 0.68%: 1.19x speedup -â–Ž -image-rgb text_solid_rgb_over-64 0.76 2.45% -> 0.63 0.81%: 1.19x speedup -â–Ž -image-rgba text_solid_rgba_over-64 0.76 0.33% -> 0.64 0.66%: 1.19x speedup -â–Ž -image-rgba text_similar_rgba_over-256 5.99 4.72% -> 5.04 1.09%: 1.19x speedup -â–Ž - -We should point out that there is some potential for slowdown in this -snapshot. The following are the worst slowdowns reported by the cairo -performance suite when comparing 1.3.2 to 1.3.4: - -image-rgba subimage_copy-256 0.01 0.87% -> 0.01 3.61%: 1.45x slowdown -â–Œ - xlib-rgb paint_solid_rgb_over-256 0.31 10.23% -> 0.38 0.33%: 1.26x slowdown -â–Ž -image-rgba box-outline-fill-100 0.01 0.30% -> 0.01 2.52%: 1.21x slowdown -â–Ž -image-rgba fill_solid_rgb_over-64 0.20 1.22% -> 0.22 1.59%: 1.12x slowdown -â– -image-rgb fill_similar_rgb_over-64 0.21 1.04% -> 0.24 1.06%: 1.11x slowdown -â– -image-rgba fill_image_rgb_over-64 0.21 1.19% -> 0.24 0.72%: 1.11x slowdown -â– -image-rgba fill_similar_rgb_over-64 0.21 0.18% -> 0.24 0.30%: 1.11x slowdown -â– -image-rgb fill_solid_rgba_over-64 0.22 1.66% -> 0.24 1.15%: 1.11x slowdown -â– -image-rgb fill_image_rgb_over-64 0.21 0.14% -> 0.24 0.80%: 1.11x slowdown -â– -image-rgba fill_image_rgba_over-64 0.22 1.34% -> 0.25 0.20%: 1.11x slowdown -â– -image-rgba fill_solid_rgba_over-64 0.22 1.48% -> 0.24 0.95%: 1.11x slowdown -â– -image-rgb fill_similar_rgba_over-64 0.22 1.13% -> 0.25 1.25%: 1.10x slowdown -â– - -The 45% slowdown for subimage_copy is an extreme case. It's unlikely -to hit many applications unless they often use cairo_rectangle; -cairo_fill to copy a single pixel at a time. In any case, it shows a -worst-case impact of the overhead of the new tessellator. The other -slowdowns (~ 10%) are probably more realistic, and still very -concerning. - -We will work to ensure that performance regressions like these are not -present from one major release of cairo to the next, (for example, -from 1.2 to 1.4). - -But we're putting this 1.3.4 snapshot out there now, even with this -potential slowdown so that people can experiment with it. If you've -got complex geometry, we hope you will see some benefit from the new -tessellator. If you've got primarily simple geometry, we hope things -won't slowdown too much, but please let us know what slowdown you see, -if any, so we can calibrate our performance suite against real-world -impacts. - -Thanks, and have fun with cairo! - -Snapshot 1.3.2 (2006-11-14 Carl Worth <cworth@cworth.org>) -========================================================== -This is the first development snapshot since the 1.2 stable series -branched off shortly after the 1.2.4 release in August 2006. - -This snapshot includes all the bug fixes from the 1.2.6 release, -(since they originated here on the 1.3 branch first and were -cherry-picked over to 1.2). But more importantly, it contains some new -API in preparation for a future 1.4 release, and most importantly, it -contains several performance improvements. - -The bug fixes will not be reviewed here, as most of them are already -described in the 1.2.6 release notes. But details for the new API and -some performance improvements are included here. - -As with all snapshots, this is experimental code, and the new API -added here is still experimental and is not guaranteed to appear -unchanged in any future release of cairo. - -API additions -------------- -Several new API additions are available in this release. There is a -common theme among all the additions in that they allow cairo to -advertise information about its state that it was refusing to -volunteer earlier. So this isn't groundbreaking new functionality, but -it is essential for easily achieving several tasks. - -The new functions can be divided into three categories: - - Getting information about the current clip region - ------------------------------------------------- - cairo_clip_extents - cairo_copy_clip_rectangles - cairo_rectangle_list_destroy - - Getting information about the current dash setting - -------------------------------------------------- - cairo_get_dash_count - cairo_get_dash - - Getting information from a pattern - ---------------------------------- - cairo_pattern_get_rgba - cairo_pattern_get_surface - cairo_pattern_get_color_stop_rgba - cairo_pattern_get_color_stop_count - cairo_pattern_get_linear_points - cairo_pattern_get_radial_circles - -In each of these areas, we have new API for providing a list of -uniform values from cairo. The closest thing we had to this before was -cairo_copy_path, (which is rather unique in providing a list of -non-uniform data). - -The copy_clip_rectangles/rectangle_list_destroy functions follow a -style similar to that of cairo_copy_path. Meanwhile, the dash and -pattern color stop functions introduce a new style in which there is a -single call to return the number of elements available (get_dash_count -and get_color_stop_count) and then a function to be called once to get -each element (get_dash and get_color_stop_rgba). - -I'm interested in hearing feedback from users of these new API -functions, particularly from people writing language bindings. One -open question is whether the clip "getter" functionality should adopt -a style similar to that of the new dash and color_stop interfaces. - -API deprecation ---------------- -The CAIRO_FORMAT_RGB16_565 enum value has been deprecated. It never -worked as a format value for cairo_image_surface_create, and it wasn't -necessary for supporting 16-bit 565 X server visuals. - -XCB backend changes -------------------- -The XCB backend has been updated to track the latest XCB API (which -recently had a 1.0 release). - -New quartz backend ------------------- -Vladimir Vukicevic has written a new "native quartz" backend which -will eventually replace the current "image-surface wrapping" quartz -backend. For now, both backends are available, (the old one is -"quartz" and the new one is "nquartz"). But it is anticipated that the -new backend will replace the old one and take on the "quartz" name -before this backend is marked as supported in a release of cairo. - -New OS/2 backend ----------------- -Doodle and Peter Weilbacher have contributed a new, experimental -backend for using cairo on OS/2 systems. - -Performance improvements ------------------------- -Here are some highlights from cairo's performance suite showing -improvements from cairo 1.2.6 to cairo 1.3.2. The command used to -generate this data is: - - ./cairo-perf-diff 1.2.6 HEAD - -available in the perf/ directory of a recent checkout of cairo's -source, (the cairo-perf-diff script does require a git checkout and -will not work from a tar file---though ./cairo-perf can still be used -to generate a single report there and ./cairo-perf-diff-files can be -used to compare two reports). - -Results are described below both for an x86 laptop (with an old Radeon -video card, recent X.org build, XAA, free software drivers), as well -as for a Nokia 770. First the x86 results with comments on each, (all -times are reported in milliseconds). - -Copying subsets of an image surface to an xlib surface (much faster) --------------------------------------------------------------------- - xlib-rgba subimage_copy-512 10.50 -> : 53.97x speedup -█████████████████████████████████████████████████████ - -Thanks to Christopher (Monty) Montgomery for this big performance -improvement. Any application which has a large image surface and is -copying small pieces of it at a time to an xlib surface, (imagine an -application that loads a single image containing all the "sprites" for -that application), will benefit from this fix. The larger the ratio of -the image surface to the portion being copied, the larger the benefit. - -Floating-point conversion (3x faster) -------------------------------------- - xlib-rgba pattern_create_radial-16 27.75 -> 3.93 : 2.94x speedup -██ -image-rgb pattern_create_radial-16 26.06 -> 3.74 : 2.90x speedup -█▉ - -Thanks to Daniel Amelang, (and others who had contributed the idea -earlier), for this nice improvement in the speed of converting -floating-point values to fixed-point. - -Text rendering (1.3 - 2x faster) ------------------------------- - xlib-rgba text_image_rgba_source-256 319.73 -> 62.40 : 2.13x speedup -█■-image-rgb text_solid_rgba_over-64 2.85 -> 0.88 : 1.35x speedup -â– - -I don't think we've ever set out to improve text performance -specifically, but we did it a bit anyway. I believe the extra -improvement in the xlib backend is due to Monty's image copying fix -above, and the rest is due to the floating-point conversion speedup. - -Thin stroke improvements (1.5x faster) ---------------------------------------------- -image-rgb world_map-800 1641.09 -> 414.77 : 1.65x speedup -â–‹ - xlib-rgba world_map-800 1939.66 -> 529.94 : 1.52x speedup -â–Œ - -The most modest stuff to announce in this release is the 50% -improvement I made in the world_map case. This is in improvement that -should help basically anything that is doing strokes with many -straight line segments, (and the thinner the better, since that makes -tessellation dominate rasterization). The fixes here are to use a -custom quadrilateral tessellator rather than the generic tessellator -for straight line segments and the miter joins. - -Performance results from the Nokia 770 --------------------------------------- - xlib-rgba subimage_copy-512 55.88 -> 2.04 : 27.34x speedup -██████████████████████████■- xlib-rgb text_image_rgb_over-256 1487.58 -> 294.43 : 5.05x speedup -████ -image-rgb pattern_create_radial-16 187.13 -> 91.86 : 2.04x speedup -â–ˆ - xlib-rgba world_map-800 21261.41 -> 15628.02 : 1.36x speedup -â– - -Here we see that the subimage_copy improvement was only about half as -large as the corresponding improvement on my laptop, (27x faster -compared to 54x) and the floating-point conversion fix also was quite -as significant, (2x compared to 3x). Oddly the improvement to text -rendering performance was more than twice as good (5x compared to -2x). I don't know what the reason for that is, but I don't think it's -anything anybody should complain about. - -Release 1.2.6 (2006-11-02 Behdad Esfahbod <behdad@behdad.org>) -============================================================== -This is the third bug fix release in the 1.2 series, coming less than -two months after the 1.2.4 release made on August 18. - -The 1.2.4 release turned out to be a pretty solid one, except for a crasher -bug when forwarding an X connection where the client and the server have -varying byte orders, eg. from a PPC to an i686. Other than that, various -other small bugs have been fixed. - -Various improvements have been made in the testing infrastructure to prevent -false positives, and to make sure the generated cairo shared object behaves as -expected in terms of exported symbols and relocations. - -There were a total of 89 changes since 1.2.4. The following list the most -important ones: - -Common fixes ------------- -- Avoid unsigned loop control variable to eliminate infinite, - memory-scribbling loop. (#7593) -- Fix cairo_image_surface_create to report INVALID_FORMAT errors. - Previously the detected error was being lost and a nil surface was - returned that erroneously reported CAIRO_STATUS_NO_MEMORY. -- Change _cairo_color_compute_shorts to not rely on any particular - floating-point epsilon value. (#7497) -- Fix infinite-join test case (bug #8379) -- Pass correct surface to create_similar in _cairo_clip_init_deep_copy(). - -PS/PDF fixes ------------- -- Fix Type 1 embedding in PDF. -- Correct the value of /LastChar in the PDF Type 1 font dictionary. -- Improve error checking in TrueType subsetting. -- Compute right index when looking up left side bearing. (bug #8180) -- Correct an unsigned to signed conversion problem in truetype subsetting - bbox. -- Type1 subsetting: Don't put .notdef in Encoding when there are 256 glyphs. -- Add cairo version to PS header / PDF document info dictionary. -- Set CTM before path construction. - -Win32 fixes ------------ -- Get correct unhinted outlines on win32. (bug 7603) -- Make cairo as a win32 static library possible. -- Use CAIRO_FORMAT_RGB24 for BITSPIXEL==32 surfaces too. - -Build system fixes ------------------- -- Define WINVER if it's not defined. (bug 6456) -- Fix the AMD64 final link by removing SLIM from pixman. -- Misc win32 compilation fixes. -- Add Sun Pro C definition of pixman_private. -- Use pixman_private consistently as prefix not suffix. -- Added three tests check-plt.sh, check-def.sh, and check-header.sh that check - that the shared object, the .def file, and the public headers agree about - the exported symbols. -- Require pkg-config 0.19. (#8686) - - -Release 1.2.4 (2006-08-18 Carl Worth <cworth@cworth.org>) -========================================================= -This is the second bug fix release in the 1.2 series, coming less than -two weeks after the 1.2.2 release made on August 8. - -The big motivation for a quick release was that there were a log of -build system snags that people ran into with the 1.2.2 release. But, -by the time we got those all done, we found that we had a bunch of -fixes for cairo's rendering as well. So there's a lot of goodness in -here for such a short time period. - -Rendering fixes ---------------- -Fix image surfaces to not be clipped when used as a source (Vladimir Vukicevic) -http://gitweb.freedesktop.org/?p=cairo;a=commit;h=72e25648c4c4bc82ddd938aa4e05887a293f0d8b - -Fix a couple of corner cases in dashing degenerate paths (Jeff Muizelaar) -http://gitweb.freedesktop.org/?p=cairo;a=commit;h=fbb1758ba8384650157b2bbbc93d161b0c2a05f0 - -Fix support for type1 fonts on win32 (Adrian Johnson) -http://gitweb.freedesktop.org/?p=cairo;a=commit;h=da1019c9138695cb838a54f8b871bbfd0e8996d7 - -Fix assertion failure when rotating bitmap fonts (Carl Worth) -http://gitweb.freedesktop.org/?p=cairo;a=commit;h=0bfa6d4f33b8ddb5dc55bbe419c15df4af856ff9 - -Fix assertion failure when calling cairo_text_path with bitmap fonts (Carl Worth) -http://gitweb.freedesktop.org/?p=cairo;a=commit;h=9878a033531e6b96b5f27e69e10e90dee7440cd9 - -Fix mis-handling of cairo_close_path in some situations (Tim Rowley, Carl Worth) -http://gitweb.freedesktop.org/?p=cairo;a=commit;h=53f74e59faf1af78f2f0741ccf1f23aa5dad4efc - -Respect font_matrix translation in _cairo_gstate_glyph_path (Behdad Esfahbod) -http://gitweb.freedesktop.org/?p=cairo;a=commit;h=f183b835b111d23e838889178aa8106ec84663b3 - -Fix vertical metrics adjustment to work with non-identity shapes (Behdad Esfahbod) -http://gitweb.freedesktop.org/?p=cairo;a=commit;h=b7bc263842a798d657a95e539e1693372448837f - -[PS] Set correct ImageMatrix in _cairo_ps_surface_emit_bitmap_glyph_data (Behdad Esfahbod) -http://gitweb.freedesktop.org/?p=cairo;a=commit;h=d47388ad759b0a1a0869655a87d9b5eb6ae2445d - -Build system fixes ------------------- -Fix xlib detection to prefer pkg-config to avoid false libXt dependency (Behdad Esfahbod) -http://gitweb.freedesktop.org/?p=cairo;a=commit;h=0e78e7144353703cbd28aae6a67cd9ca261f1d68 - -Fix typos causing win32 build problem with PS,PDF, and SVG backends (Behdad Esfahbod) -http://gitweb.freedesktop.org/?p=cairo;a=commit;h=aea83b908d020e26732753830bb3056e6702a774 - -Fix configure cache to not use stale results (Behdad Esfahbod) -http://gitweb.freedesktop.org/?p=cairo;a=commit;h=6d0e3260444a2d5b6fb0cb223ac79f1c0e7b3a6e - -Fix to not pass unsupported warning options to the compiler (Jens Granseuer) -http://gitweb.freedesktop.org/?p=cairo;a=commit;h=97524a8fdb899de1ae4a3e920fb7bda6d76c5571 - -Fix to allow env. variables such as png_REQUIRES to override configure detection (Jens Granseuer) -http://gitweb.freedesktop.org/?p=cairo;a=commit;h=abd16e47d6331bd3811c908e524b4dcb6bd23bf0 - -Fix test suite to not use an old system cairo when converting svg2png (Behdad Esfahbod) -http://gitweb.freedesktop.org/?p=cairo;a=commit;h=6122cc85c8f71b1ba2df3ab86907768edebe1781 - -Fix test suite to not require signal.h to be present (Behdad Esfahbod) -http://gitweb.freedesktop.org/?p=cairo;a=commit;h=6f8cf53b1e1ccdbe1ab6a275656b19c6e5120e40 - -Code cleanups -------------- -Many useful warnings cleanups from sparse, valgrind, and careful eyes -(Kjartan Maraas, Pavel Roskin) - -Release 1.2.2 (2006-08-08 Carl Worth <cworth@cworth.org>) -========================================================= -This is the first bug fix release in the 1.2 series since the original -1.2.0 release made six weeks ago. - -There were some very serious bugs in the 1.2.0 release, (see below), -so everybody is encouraged to upgrade from 1.2.0 to 1.2.2. The 1.2.2 -release maintains source and binary compatibility with 1.2.0 and does -not make any API additions. - -Fix crashes with BGR X servers ------------------------------- -With cairo 1.2.0 many people reported problems with all cairo-using -programs, (including all GTK+ programs with GTK+ >= 2.8) immediately -crashing with a complaint about an unsupported image format. This bug -affected X servers that do not provide the Render extension and that -provide a visual with BGR rather than RGB channel order. - -report: https://bugs.freedesktop.org/show_bug.cgi?id=7294 -fix: http://gitweb.freedesktop.org/?p=cairo;a=commit;h=9ae66174e774b57f16ad791452ed44efc2770a59 - -Fix the "disappearing text" bug -------------------------------- -With cairo 1.2.0 many people reported that text would disappear from -applications, sometimes reappearing with mouse motion or -selection. The text would disappear after the first space in a string -of text. This bug was caused by an underlying bug in (very common) X -servers, and only affected text rendered without antialiasing, (either -a bitmap font or a vector font with antialiasing disabled). The bug -was also exacerbated by a KDE migration bug that caused antialiasing -to be disabled more than desired. - -report: https://bugs.freedesktop.org/show_bug.cgi?id=7494 -fix: http://gitweb.freedesktop.org/?p=cairo;a=commit;h=456cdb3058f3b416109a9600167cd8842300ae14 -see also: -Xorg: https://bugs.freedesktop.org/show_bug.cgi?id=7681 -KDE: http://qa.mandriva.com/show_bug.cgi?id=23990 - -Fix broken image fallback scaling (aka. "broken printing") ----------------------------------------------------------- -The various "print" backends, (pdf, ps, and svg), sometimes fallback -to using image-based rendering for some operations. In cairo 1.2.0 -these image fallbacks were scaled improperly. Applications using cairo -can influence the resolution of the image fallbacks with -cairo_surface_set_fallback_resolution. With the bug, any value other -than 72.0 would lead to incorrect results, (larger values would lead -to increasingly shrunken output). - -report: https://bugs.freedesktop.org/show_bug.cgi?id=7533 -fix: http://gitweb.freedesktop.org/?p=cairo;a=commit;h=1feb4291cf7813494355459bb547eec604c54ffb - -Fix inadvertent semantic change of font matrix translation (Behdad Esfahbod) ----------------------------------------------------------------------------- -The 1.2.0 release introduced an inadvertent change to how the -translation components of a font matrix are interpreted. In the 1.0 -series, font matrix translation could be used to offset the glyph -origin, (though glyph metrics were reported incorrectly in -1.0). However in 1.2.0, the translation was applied to the advance -values between each glyph. The 1.2.0 behavior is fairly useless in -practice, and it was not intentional to introduce a semantic -change. With 1.2.2 we return to the 1.0 semantics, with a much better -implementation that provides correct glyph metrics. - -fix: http://gitweb.freedesktop.org/?p=cairo;a=commit;h=84840e6bba6e72aa88fad7a0ee929e8955ba9051 - -Fix create_similar to preserve fallback resolution and font options (Behdad Esfahbod) -------------------------------------------------------------------------------------- -There has been a long-standing issue with cairo_surface_create_similar -such that font options and other settings from the original -destination surface would not be preserved to the intermediate -"similar" surface. This could result in incorrect rendering -(particularly with respect to text hinting/antialiasing) with -fallbacks, for example. - -report: https://bugs.freedesktop.org/show_bug.cgi?id=4106 -fixes: http://gitweb.freedesktop.org/?p=cairo;a=commit;h=9fcb3c32c1f16fe6ab913e27eb54d18b7d9a06b0 - http://gitweb.freedesktop.org/?p=cairo;a=commit;h=bdb4e1edadb78a2118ff70b28163f8bd4317f1ec - -xlib: Fix text performance regression from 1.0 to 1.2.0 (Vladimir Vukicevic) ----------------------------------------------------------------------------- -Several people noticed that upgrading from cairo 1.0 to cairo 1.2.0 -caused a significant performance regression when using the xlib -backend. This performance regression was particularly noticeable when -doing lots of text rendering and when using a high-latency connection -to the X server, (such as a remote X server over an ssh -connection). The slowdown was identified and fixed in 1.2.2. - -report: https://bugs.freedesktop.org/show_bug.cgi?id=7514 -fix: http://gitweb.freedesktop.org/?p=cairo;a=commit;h=b7191885c88068dad57d68ced69a752d1162b12c - -PDF: Eliminate dependency on FreeType library dependency (Adrian Johnson) -------------------------------------------------------------------------- -The cairo 1.2 series adds a supported pdf backend to cairo. In cairo -1.2.0 this backend required the freetype library, which was an -undesirable dependency on systems such as win32, (cairo is designed to -always prefer the "native" font system). As of cairo 1.2.2 the -freetype library is not required to use the pdf backend on the win32 -platform. - -report: https://bugs.freedesktop.org/show_bug.cgi?id=7538 -fix: http://gitweb.freedesktop.org/?p=cairo;a=commit;h=a0989f427be87c60415963dd6822b3c5c3781691 - -PDF: Fix broken output on amd64 (Adrian Johnson) ------------------------------------------------- -report: http://bugzilla.gnome.org/show_bug.cgi?id=349826 -fix: http://gitweb.freedesktop.org/?p=cairo;a=commit;h=f4b12e497b7ac282b2f6831b8fb68deebc412e60 - -PS: Fix broken output for truetype fonts > 64k (Adrian Johnson) ---------------------------------------------------------------- -fix: http://gitweb.freedesktop.org/?p=cairo;a=commit;h=067d97eb1793a6b0d0dddfbd0b54117844511a94 - -PDF: Fix so that dashing doesn't get stuck on (Kent Worsnop) ------------------------------------------------------------- -Kent notices that with the PDF backend in cairo 1.2.0 as soon as a -stroke was performed with dashing, all subsequent strokes would also -be dashed. There was no way to turn dashing off again. - -fix: http://gitweb.freedesktop.org/?p=cairo;a=commit;h=778c4730a86296bf0a71080cf7008d7291792256 - -Fix memory leaks in failure paths in gradient creation (Alfred Peng) --------------------------------------------------------------------- -fix: http://gitweb.freedesktop.org/?p=cairo;a=commit;h=db06681b487873788b51a6766894fc619eb8d8f2 - -Fix memory leak in _cairo_surface_show_glyphs (Chris Wilson) ------------------------------------------------------------- -report: https://bugs.freedesktop.org/show_bug.cgi?id=7766 -fix: http://gitweb.freedesktop.org/?p=cairo;a=commit;h=e2fddcccb43d06486d3680a19cfdd5a54963fcbd - -Solaris: Add definition of cairo_private for some Sun compilers (Alfred Peng) ------------------------------------------------------------------------------ -report: https://bugzilla.mozilla.org/show_bug.cgi?id=341874 -fix: http://gitweb.freedesktop.org/?p=cairo;a=commit;h=04757a3aa8deeff3265719ebe01b021638990ec6 - -Solaris: Change version number of Sun's Xorg server with buggy repeat (Brian Cameron) -------------------------------------------------------------------------------------- -report: https://bugs.freedesktop.org/show_bug.cgi?id=7483 -fix: http://gitweb.freedesktop.org/?p=cairo;a=commit;h=e0ad1aa995bcec4246c0b8ab0d5a5a79871ce235 - -Various memory leak fixes -------------------------- -Fix memory leak in _cairo_surface_show_glyphs (bug 7766) -Fix file handle leak in failure path (bug 7616) -Fix some memory leaks in the test cases. -Fix some memory leaks in font subsetting code used in print backends. - -Documentation improvements (Behdad Esfahbod) --------------------------------------------- -Added new documentation for several functions (cairo_show_page, -cairo_copy_page, cairo_in_stroke, cairo_in_fill). - -Fixed some syntax errors that were preventing some existing -documentation from being published. - -Fixed several minor typographical errors. - -Added an index for new symbols in 1.2. - -Release 1.2.0 (2006-06-27 Carl Worth <cworth@cworth.org>) -========================================================= -This is the culmination of the work that has gone on within the 1.1 -branch of cairo. - -There has been one API addition since the cairo 1.1.10 snapshot: - - cairo_xlib_surface_get_width - cairo_xlib_surface_get_height - -There's also a new feature without any API change: - - Dots can now be drawn by using CAIRO_LINE_CAP_ROUND with - degenerate sub-paths, (cairo_move_to() followed by either - cairo_close_path() or a cairo_line_to() to the same location). - -And at least the following bugs have been fixed: - - 6759 fontconfig option AntiAlias doesn't work in cairo 1.1.2 - 6955 Some characters aren't displayed when using xlib (cache u... - 7268 positive device_offset values don't work as source - * PDF emit_glyph function needs to support bitmapped glyphs - * PS emit_glyph function needs to support bitmapped glyphs - * SVG emit_glyph function needs to support bitmapped glyphs - * PDF: minefield page one is falling back unnecessarily - * PS/PDF: Fix broken placement for vertical glyphs - * PS: Fix to not draw BUTT-capped zero-length dash segments - * Do device offset before float->fixed conversion - http://bugzilla.gnome.org/show_bug.cgi?id=332266 - * PS: Fix source surfaces with transformations - * PS: Fix to not draw BUTT-capped degnerate sub-paths - * PS: Don't walk off end of array when printing "~>" - * Fix some memory leaks in the test suite rig - * SVG: Fix memory leak when using cairo_mask - * Fix EXTEND_REFLECT and EXTEND_PAD to not crash (though these are - still not yet fully implemented for surface patterns). - -This has been a tremendous effort by everyone, and I'm proud to have -been a part of it. Congratulations to all contributors to cairo! - -Snapshot 1.1.10 (2006-06-16 Carl Worth <cworth@cworth.org>) -=========================================================== -This is the fifth in a series of snapshots working toward the 1.2 -release of cairo. - -The primary motivation for this snapshot is to fix a long-standing bug -that had long been silent, but as of the 1.1.8 snapshot started -causing crashes when run against 16-bit depth X servers, (often Xvnc -or Xnest). The fix for this adds a new CAIRO_FORMAT_RGB16_565 to the -API. - -This snapshot also includes a rewrite of cairo's SVG backend to -eliminate the dependency on libxml2. With this in place, cairo 1.2 -will not depend on any libraries that cairo 1.0 did not. - -As usual, there are also a few fixes for minor bugs. - -Snapshot 1.1.8 (2006-06-14 Carl Worth <cworth@cworth.org>) -========================================================== -This is the fourth in a series of snapshots working toward the 1.2 -release of cairo. At this point, all major features of the 1.2 release -are in place, leaving just a few bug fixes left. - -In particular, there well be no additional API changes between this -1.1.8 snapshot and the 1.2 release. - -The announcement for 1.1.6 mentioned several API changes being -considered. Only one of these changes was actually implemented -(set_dpi -> fallback_resolution). This change does introduce one -source-level incompatibility with respect to previous 1.1.x snapshots, -so see below for details. - -Here is an abbreviated summary of changes since the 1.1.6 snapshot: - -** API Change ** ----------------- -According to the plan mentioned in the 1.1.6 notes, one source-level -incompatible change has been implemented. The following three -functions have been removed from cairo's API: - - cairo_pdf_surface_set_dpi - cairo_ps_surface_set_dpi - cairo_svg_surface_set_dpi - -and in their place the following function has been added: - - cairo_surface_set_fallback_resolution - -The signature and semantics of the function remains the same, so it is -a simple matter of changing the name of the function when calling -it. As a transition mechanism, this snapshot will (on many systems) -build to include the old symbols so that code previously compiled will -still run. However, all source code using the old names must be -updated before it will compile. And the upcoming 1.2 release is not -anticipated to include the old symbols. - -Finally, it should be pointed out that the old symbols never existed -in the supported API of any stable release of cairo. (In the stable -1.0 releases the PDF, PS, and SVG backends were advertised as -experimental and unstable.) - -And, as always, cairo continues to maintain source and binary -compatibility between major releases. So applications compiled against -supported backends in a stable release of cairo (1.0.4 say) will -continue to compile and run without modification against new major -releases (1.2.0 say) without modification. - -API additions -------------- -The following new functions have been added to cairo's API: - - cairo_surface_get_content - cairo_debug_reset_static_data - cairo_image_surface_get_data - cairo_image_surface_get_format - cairo_image_surface_get_stride - cairo_win32_font_face_create_for_hfont - -New, backend-specific pkg-config files --------------------------------------- -In addition to the original cairo.pc file, cairo will also now install -a pkg-config files for each configured backend, (for example -cairo-pdf.pc, cairo-svg.pc, cairo-xlib.pc, cairo-win32.pc, etc.) this -also includes optional font backends (such as cairo-ft.pc) and the -optional png functionality (cairo-png.pc). - -These new pkg-config files should be very convenient for allowing -cairo-using code to easily check for the existing of optional -functionality in cairo without having to write complex rules to grub -through cairo header files or the compiled library looking for -symbols. - -Printing backend (PS, PDF, and SVG) ------------------------------------ -Improving the quality of the "printing" backends has been a priority -of the development between cairo 1.1.6 and cairo 1.1.8. - -The big improvement here is in the area of text output. Previously, at -best, text was output as paths without taking advantage of any font -support available in the output file format. - -Now, at the minimum text paths will be shared by using type3 fonts -(for PS and PDF---and similarly, defs for SVG). Also, if possible, -type3 and truetype fonts will be embedded in PostScript and PDF -output. There are still some known bugs with this, (for example, -selecting text in a cairo-generated PDF file with an embedded truetype -font does not work). So there will be some more changes in this area -before cairo 1.2, but do try test this feature out as it exists so -far. - -Many thanks to Kristian Høgsberg for the truetype and type1 font -embedding. - -win32 backend -------------- -Performance improvements by preferring GDI over pixman rendering when possible. -Fixes for text rendering. - -xlib backend ------------- -Fix potentially big performance bug by making xlib's create_similar -try harder to create a pixmap of a depth matching that of the screen. - -Bug fixes ---------- -Among various other fixes, the following bugs listed in bugzilla have -been fixed: - - Bug 2488: Patch to fix pixman samping location bug (#2488). - https://bugs.freedesktop.org/show_bug.cgi?id=2488 - - Bug 4196: undef MIN an MAX before defining to avoid duplicate definition - https://bugs.freedesktop.org/show_bug.cgi?id=4196 - - Bug 4723: configure.in: Fix m4 quoting when examining pkg-config version - https://bugs.freedesktop.org/show_bug.cgi?id=4723 - - Bug 4882: Flag Sun's X server has having buggy_repeat. - https://bugs.freedesktop.org/show_bug.cgi?id=4882 - - Bug 5306: test/pdf2png: Add missing include of stdio.h - https://bugs.freedesktop.org/show_bug.cgi?id=5306 - - Bug 7075: Fix make clean to remove cairo.def - https://bugs.freedesktop.org/show_bug.cgi?id=7075 - -(Many thanks to Behdad Esfahbod for helping us track down and fix many -of these.) - -Snapshot 1.1.6 (2006-05-04 Carl Worth <cworth@cworth.org>) -========================================================== -This is the third in a series of snapshots working toward the imminent -1.2 release of cairo. For a list of items still needing work on the -cairo 1.2 roadmap, please see: - - http://cairographics.org/ROADMAP - -As can be seen in that list, there are no longer any API additions -left on the roadmap. Instead, there is a feature (PDF type 3 fonts) a -performance optimization (X server gradients) and a list of bug -fixes. This gives us a fair amount of freedom to cut the 1.2 release -at almost any point by deciding to defer remaining bug fixes to -subsequent maintenance releases such as 1.2.2 and 1.2.4. - -Before we will do that, we must first be wiling to commit to all the -new API additions. As a heads-up, there are a couple of potential API -changes being considered. (Note that these are changes to new API -introduced during 1.1 so these will not introduce API -incompatibilities compared to the stable 1.0 series). The changes -being considered are: - - cairo_get_group_target: may acquire x and y offset return - parameters. May also be eliminated in favor of - cairo_get_target assuming its role - - cairo_pdf_surface_set_dpi: - cairo_ps_surface_set_dpi: - cairo_svg_surface_set_dpi: These functions may be removed in favor - of a new cairo_surface_set_fallback_resolution - -Additionally there is the possibility of a slight change in the -semantics of cairo_set_line_width. We believe the current behavior of the sequence: - - cairo_set_line_width; ... change CTM ...; cairo_stroke; - -is buggy. It is currently behaving the same as: - - ... change CTM ...; cairo_set_line_width; cairo_stroke; - -We are considering fixing this bug before 1.2 with the hope that -nobody is already relying on the buggy behavior described here. Do -shout if you suspect you might be in that position. - -The items included in this snapshot (since the 1.1.4 snapshot) are -described below. - -API additions -------------- -The long-awaited group-rendering support is now available with the -following function calls: - - cairo_push_group - cairo_push_group_with_content - cairo_pop_group - cairo_pop_group_to_source - cairo_get_group_target - -This API provides a much more convenient mechanism for doing rendering -to an intermediate surface without the need to manually create a -temporary cairo_surface_t and a temporary cairo_t and clean them up -afterwards. - -Add the following missing get function to complement -cairo_surface_set_device_offset: - - cairo_surface_get_device_offset - -PDF backend (API addition) --------------------------- -The PDF backend now provides for per-page size changes, (similar to -what the PostScript backend got in the 1.1.4 snapshot). The new API -is: - - cairo_pdf_surface_set_size - -Xlib backend (API additions) ----------------------------- -The following functions have been added to allow the extraction of -Xlib surface: - - cairo_xlib_surface_get_display - cairo_xlib_surface_get_drawable - cairo_xlib_surface_get_screen - cairo_xlib_surface_get_visual - cairo_xlib_surface_get_depth - -XCB backend (experimental) --------------------------- -Update backend so that it now compiles with the recent XCB 0.9 release. - -Bug fixes and memory leak cleanup ---------------------------------- -Various little things, nothing too significant though. - -Snapshot 1.1.4 (2006-05-03 Carl Worth <cworth@cworth.org>) -========================================================== -This is the second in a series of snapshots working toward the -upcoming 1.2 release of cairo. For a list of items still needing work -on the cairo 1.2 roadmap, please see: - - http://cairographics.org/ROADMAP - -The items included in this snapshot (since the 1.1.2 snapshot) are -described below. - -PostScript backend: new printing-oriented API ---------------------------------------------- -We anticipate that with cairo 1.2, toolkits will begin to use cairo -for printing on systems that use PostScript as the spool format. To -support this use case, we have added 4 new function calls that are -specific to the PostScript backend: - - cairo_ps_surface_set_size - cairo_ps_surface_dsc_comment - cairo_ps_surface_dsc_begin_setup - cairo_ps_surface_dsc_begin_page_setup - -These functions allow variation of the page size/orientation from one -page to the next in the PostScript output. They also allow the toolkit -to provide per-document and per-page printer control options in a -device-independent way, (for example, by using PPD options and -emitting them as DSC comments into the PostScript output). This should -allow toolkits to provide very fine-grained control of many options -available in printers, (media size, media type, tray selection, etc.). - -SVG backend: builds by default, version control ------------------------------------------------ -The SVG backend continues to see major improvements. It is expected -that the SVG backend will be a supported backend in the 1.2 -release. This backend will now be built by default if its dependencies -(freetype and libxml2) are met. - -Additionally, the SVG backend now has flexibility with regard to what -version of SVG it targets. It will target SVG 1.1 by default, which -will require image fallbacks for some of the "fancier" cairo -compositing operators. Or with the following new function calls: - - cairo_svg_surface_restrict_to_version - cairo_svg_get_versions - cairo_svg_version_to_string - -it can be made to target SVG 1.2 in which there is native support for -these compositing operators. - -Bug fixes ---------- -At least the following bugs have been fixed since the 1.1.2 snapshot: - -crash at XRenderAddGlyphs -https://bugs.freedesktop.org/show_bug.cgi?id=4705 - -Can't build cairo-1.1.2 on opensolaris due to " void function cannot return value" -https://bugs.freedesktop.org/show_bug.cgi?id=6792 - -Missing out-of-memory check at gfx/cairo/cairo/src/cairo-atsui-font.c:185 -https://bugzilla.mozilla.org/show_bug.cgi?id=336129 - -A couple of memory leaks. - -Snapshot 1.1.2 (2006-04-25 Carl Worth <cworth@cworth.org>) -========================================================== -This is the first in a series of snapshots working toward the upcoming -1.2 release of cairo. (Subsequent snapshot will use successive even -numbers for the third digit, 1.1.4, 1.1.6, etc.) This snapshot is -backwards-compatible with the 1.0 series---it makes a few API -additions but does not remove any API. - -PostScript and PDF backends are no longer "experimental" --------------------------------------------------------- -The major theme of the 1.2 release is improved PostScript and PDF -backends for cairo. Unlike the 1.0 series, in the 1.2 series these -backends will not be marked as experimental and will be enabled by -default. We encourage people to test this snapshot and the PS/PDF -backends in particular as much as possible. - -The PostScript and PDF output is not yet ideal. - - * One major problem with the PostScript output is that image - fallbacks are used more often than strictly necessary, and the - image fallbacks are at a lower resolution than desired, (the - cairo_ps_surface_set_dpi call is ignored). - - * The major drawback of the current PDF backend implementation is - its text support. Every glyph is represented by a filled path in - the PDF file. The causes file sizes to be much larger and - rendering to be much slower than desired. - -It is anticipated that both of these shortcomings will see some -improvements before the final 1.2 release. - -In spite of those shortcomings, we hope that the PS and PDF backends -will yield faithful results for pretty much any cairo operations you -can throw at them. Please let us know if you are getting obviously -"different" results from the PS/PDF backends than from the image or -xlib backends. - -Other new experimental backends -------------------------------- -This snapshot includes three new backends that did not exist in the -1.0 series: - - * beos backend - - * directfb backend - - * svg backend - -These are all currently marked "experimental" and are disabled by -default. But the SVG backend in particular has seen a lot of recent -development and is very close to passing the entire cairo test -suite. It is possible that this backend will become a fully supported -backend by the time of the cairo 1.2 release. - -Public API additions --------------------- -There have been a few new API functions added to cairo, including: - -New get_type functions for querying sub-types of object: - - cairo_surface_get_type - cairo_pattern_get_type - cairo_font_face_get_type - cairo_scaled_font_get_type - -More convenience in working with cairo_scaled_font_t with new getter -functions: - - cairo_scaled_font_get_font_face - cairo_scaled_font_get_font_matrix - cairo_scaled_font_get_ctm - cairo_scaled_font_get_font_options - -As well as a convenience function for setting a scaled font into a -cairo context: - - cairo_set_scaled_font - -and a function to allow text extents to be queried directly from a -scaled font, (without requiring a cairo_surface_t or a cairo_t): - - cairo_scaled_font_text_extents - -These new scaled font functions were motivated by the needs of the -pango library. - -Finally, a new path-construction function was added which clears the -current point in preparation for a new sub path. This makes cairo_arc -easier to use in some situations: - - cairo_new_sub_path - -Before the 1.2 release is final we do still plan a few more API -additions specifically motivated by the needs of Mozilla/Firefox. - -Optimizations and bug fixes ---------------------------- -Shortly after the 1.0 maintenance series branched off the mainline -there was a major rework of the cairo font internals. This should -provide some good performance benefits, but it's also another area -people should look at closely for potential regressions. - -There has not yet been any widespread, systematic optimization of -cairo, but various performance improvements have been made, (and some -of them are fairly significant). So if some things seem faster than -1.0 then things are good. If there are any performance regressions -compared to 1.0 then there is a real problem and we would like to hear -about that. - -There has been a huge number of bug fixes---too many to mention in -detail. Again, things should be better, and never worse compared to -1.0. Please let us know if your testing shows otherwise. - -Release 1.0.2 (2005-10-03 Carl Worth <cworth@cworth.org>) -========================================================= -For each bug number XXXX below, see: - - https://bugs.freedesktop.org/show_bug.cgi?id=XXXX - -for more details. - -General bug fixes ------------------ - * 4408 - Add support for dashing of stroked curves - (Carl Worth) - - * 4409 - Fix dashing so that each dash is capped on both ends - (Carl Worth) - - * 4414 - Prevent SIGILL failures (proper use of -mmmx and -msse flags) - (Sebastien Bacher, Billy Biggs) - - * 4299 - Fix crashes with text display in multi-threaded program - (Alexey Shabalin, Carl Worth) - - * 4401 - Do not use sincos function since it is buggy on some platforms) - (Tim Mooney, Carl Worth) - - * 4245 - Fix several bugs in the test suite exposed by amd64 systems - (Seemant Kulleen, Carl Worth) - - * 4321 - Add missing byteswapping on GetImage/PutImage - (Sjoerd Simons, Owen Taylor) - - * 4220 - Make the check for rectangular trapezoids simpler and more accurate - (Richard Stellingwerff, Owen Taylor) - - * 4260 - Add missing channel-order swapping for antialised fonts - (Barbie LeVile, Owen Taylor) - - * 4283 - Fix compilation failure with aggressive inlining (gcc -O3) - (Marco Manfredini, Owen Taylor) - - * 4208 - Fix some warnings from sparse - (Kjartan Maraas, Billy Biggs) - - * 4269 - Fix to not crash when compiled with -fomit-frame-pointer - (Ronald Wahl, Owen Taylor) - - * 4263 - Improve performance for vertical gradients - (Richard Stellingwerff, Owen Taylor) - - * 4231 - * 4298 - Accommodate gentoo and Mandriva versions in X server vendor string check - (Billy Biggs, Frederic Crozat, Owen Taylor) - -win32-specific fixes --------------------- - * 4599 - Fix "missing wedges" on some stroked paths (win32) - (Tim Rowley, Jonathan Watt, Bertram Felgenhauer, Carl Worth, Keith Packard) - - * 4612 - Fix disappearing text if first character out of surface (win32) - (Tim Rowley) - - * 4602 - Fix shutdown of cairo from failing intermediate, size-0 bitmaps (win32) - Aka. the "white rectangles" bug from mozilla-svg testing - (Tim Rowley) - - * Various portability improvements for win32 - (Hans Breuer, Owen Taylor, Carl Worth) - - * 4593 - Fix font sizes to match user expectations (win32) - (Tor Lillqvist, Owen Taylor) - - * 3927 - Fix to report metrics of size 0 for glyph-not-available (win32) - (Hans Breuer, Owen Taylor, Tor Lillqvist) - - * Add locking primitives for win32 - (Hans Breuer) - -xlib-specific fixes -------------------- - * Fix crash from size-0 pixmap due to empty clip region (xlib) - (Radek DoulÃk, Carl Worth) - -Release 1.0.0 (2005-08-24 Carl Worth <cworth@cworth.org>) -========================================================= -Experimental backends ---------------------- - * The Glitz, PS, PDF, Quartz, and XCB backends have been declared - experimental, and are not part of the API guarantees that accompany - this release. They are not built by default, even when the required - libraries are available, and must be enabled explicitly with - --enable-ps, --enable-pdf, --enable-quartz or --enable-xcb. - - It is very painful for us to be pushing out a major release without - these backends enabled. There has been a tremendous amount of work - put into each one and all are quite functional to some - extent. However, each also has some limitations. And none of these - backends have been tested to the level of completeness and - correctness that we expect from cairo backends. - - We do encourage people to experiment with these backends and report - success, failure, or means of improving them. - -Operator behavior ------------------ - * Prior to 0.9.0 the SOURCE, CLEAR and a number of other operators - behaved in an inconsistent and buggy fashion and could affect areas - outside the clip mask. In 0.9.0, these six "unbounded" operators - were fixed to consistently clear areas outside the shape but within - the clip mask. This is useful behavior for an operator such as IN, - but not what was expected for SOURCE and CLEAR. So, in this release - the behavior of SOURCE and CLEAR has been changed again. They now - affect areas only within both the source and shape. We can write - the new operators as: - - SOURCE: dest' = (mask IN clip) ? source : dest - CLEAR: dest' = (mask IN clip) ? 0 : dest - -Behavior and API changes ------------------------- - * Setting the filter on a gradient pattern would change the - interpolation between color stops away from the normal linear - interpolation. This dubious behavior has been removed. - - * The CAIRO_CONTENT_VALID() and CAIRO_FORMAT_VALID() macros -- - implementation details that leaked into cairo.h -- have been moved - into an internal header. - - * The cairo_show_text function now advances the current point - according to the total advance values of the string. - -API additions -------------- - * cairo_set_dash can now detect error and can set - CAIRO_STATUS_INVALID_DASH. - -Features --------- - * When compiled against recent versions of fontconfig and FreeType, - artificial bold fonts can now be turned on from fonts.conf using - the FC_EMBOLDEN fontconfig key. - -Optimization ------------- - * The compositing code from the 'xserver' code tree has now been - completely merged into libpixman. This includes MMX optimization of - common operations. - - * The image transformation code in libpixman has been improved and - now performs significantly faster. - -Bug fixes ---------- - * Several crashes related to corruption in the font caches have been - fixed. - - * All test cases now match pixel-for-pixel on x86 and PPC; this - required fixing bugs in the compositing, stroking, and pattern - rendering code. - - * Negative dash offsets have been fixed to work correctly. - - * The stroking of paths with mutiple subpaths has now been fixed to - apply caps to all subpaths rather than just the last one. - - * Many build fixes for better portability on various systems. - - * Lots of other bug fixes, but we're too tired to describe them in - more detail here. - -Release 0.9.2 (2005-08-13 Carl Worth <cworth@cworth.org>) -========================================================= -Release numbering ------------------ - * You will notice that this release jumped from 0.9.0 to 0.9.2. We've - decided to use an odd micro version number (eg. 0.9.1) to indicate - in-progress development between releases. As soon as 0.9.2 is - tagged, the version will be incremented in CVS to 0.9.3 where it - will stay until just before 0.9.4 is built, uploaded, and tagged. - - So, even-micro == a released version, odd-micro == something in-between. - -Libpixman dependency dropped ----------------------------- - * As of this release, the dependency on an external libpixman has - been dropped. Instead, the code from libpixman needed for cairo has - been incorporated into the cairo source tree. The motivation for - this change is that while cairo's API is stable and ready to be - maintained after the 1.0 release, libpixman's API is not, so we do - not want to expose it at this time. - - Also, the incorporation of libpixman into cairo also renames all - previously-public libpixman symbols in order to avoid any conflict - with a future release of libpixman - -API additions -------------- - * Macros and functions have been added so that the version of cairo - can be queried at either compile-time or at run-time. The version - is made available as both a human-readable string and as a single - integer: - - CAIRO_VERSION_STRING eg. "0.9.2" - CAIRO_VERSION eg. 000902 - - const char* - cairo_version_string (void); /* eg. "0.9.2" */ - - int - cairo_version (void); /* eg. 000902 */ - - A macro is provided to convert a three-part component version into - the encoded single-integer form: - - CAIRO_VERSION_ENCODE(X,Y,Z) - - For example, the CAIRO_VERSION value of 000902 is obtained as - CAIRO_VERSION_ENCODE(0,9,2). The intent is to make version - comparisons easy, either at compile-time: - - #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(0,9,2) - ... - #endif - - Or at run-time: - - if (cairo_version() >= CAIRO_VERSION_ENCODE(0,9,2)) { /* ... */ } - -Thread safety -------------- - * This release adds pthread-based locking (when available) to make - the caches used by cairo safe for threaded programs. Some may - remember a failed experiment with this locking between the 0.5.1 - and 0.5.2 snapshots, (where even single-threaded programs that - linked with -lpthread would deadlock). We believe that that problem - has been fixed, so we are looking forward to testing and reports - from users with threaded applications. - -Bug fixes ---------- - * The XCB and Quartz backends failed to compiled in the 0.9.0 release - due to minor syntax errors. These have now been fixed. - - * Various crashes in glitz and pixman due to size 0 glyphs have been - fixed. - -Release 0.9.0 (2005-08-08 Carl Worth <cworth@cworth.org>) -========================================================= -Soname change -------------- - * In all prior snapshots, the libtool library versioning was set to - 1:0:0. As this release is intended to mark the beginning of - backwards-compatible releases, the versioning has been incremented - to 2:0:0. You will notice that the numeric extension on the - installed library filename will change similarly. - - This change will also require all cairo-using applications to be - recompiled. We recognize that this may cause some frustration since - this release is backwards-compatible with 0.6.0 and in that sense - "shouldn't" require re-compilation. However, since all historical - snapshots have used the same 1:0:0 version in spite of incompatible - API changes between them, it was essential that the upcoming 1.0 - release series have distinct library versioning. - - All future releases will use the library versioning to properly - indicate compatibility between releases. So, any application - re-compiled now to work with the 0.9.0 will not need to be - recompiled when a compatible 1.0 release of cairo is made in the - future. - -API additions -------------- - * Add new function calls to set/get the current antialiasing mode in - the graphics state: - - cairo_set_antialias - cairo_get_antialias - - This call accepts the same modes recently added for font options - (NONE or GRAY) but affects the rendering of geometry other than - text. The intent of this call is to enable more precise control of - which pixels are affected by each operation, for example to allow - for full-scene antialiasing for seam-free rendering. It is not - expected that non-antialiased rendering will perform better than - anti-aliased rendering. - - * Three new functions were added to provide support for mixed cairo- - and non-cairo drawing to the same surface: - - cairo_surface_mark_dirty - cairo_surface_mark_dirty_rectangle - cairo_surface_flush - - * The return type of the several "reference" functions was change, - (API compatibly), from void to the same type as the argument. The - affected functions are: - - cairo_font_face_reference - cairo_scaled_font_reference - cairo_pattern_reference - cairo_surface_reference - cairo_reference - - This allows a convenient way to assign and reference in a single - statement. - -Semantic changes ----------------- - * The behavior of cairo_set_source with a pattern with a non-identity - matrix was previously not well-defined. The new behavior is as - follows: - - The pattern's transformation matrix will be locked to the - user space in effect at the time of cairo_set_source(). This means - that further modifications of the CTM will not affect the source - pattern. - -cairo-win32 ------------ - * Some portability improvements, (eg. workaround for missing stdint.h). - -cairo-ft --------- - * Updated to allow compilation with older versions of freetype. - -Bug fixes ---------- - * Fix the unbounded operators to actually produce a correct result, - (previously the results were artificially restricted to the - bounding box of whatever shape was being drawn rather than - extending out infinitely). The fixed operators are: - - CAIRO_OPERATOR_CLEAR - CAIRO_OPERATOR_SOURCE - CAIRO_OPERATOR_OUT - CAIRO_OPERATOR_IN - CAIRO_OPERATOR_DEST_IN - CAIRO_OPERATOR_DEST_ATOP - - * Fix cairo_mask and cairo_mask_surface to transform the mask by the - current transformation matrix (CTM). - - * Fix cairo_set_source to lock the CTM used to transform the pattern. - - * Workaround for X server Render bug involving repeating patterns - with a general transformation matrix. - - * cairo_get_font_face fixed to return a "nil" font face object rather - than NULL on error. - - * cairo_set_font_face fixed to not crash if given a NULL font face, - (which is the documented interface for restoring the default font - face). - - * Fix xlib glyphset caching to not try to free a NULL glyph. - -Snapshot 0.6.0 (2005-07-28 Carl Worth <cworth@cworth.org>) -========================================================== -API changes ------------ -* The prototypes of the following functions have changed: - - cairo_xlib_surface_create_with_xrender_format - cairo_xlib_surface_create_for_bitmap - - A Screen* parameter has been added to each. This allows the cairo - xlib backend to work correctly with multi-head X servers. - -* The following function has been modified: - - cairo_scaled_font_create - - to accept a cairo_font_options_t*. See below fore more details. - -* All opaque, reference-counted cairo objects have now been moved to a - standard error-handling scheme. The new objects to receive this - treatment are cairo_font_face_t, cairo_scaled_font_t, and - cairo_surface_t. (Previous snapshots already provided this scheme - for cairo_t, cairo_path_t, and cairo_pattern_t.) - - This changes two functions to have a return type of void rather than - cairo_status_t: - - cairo_scaled_font_extent - cairo_surface_finish - - And significantly, none of the create functions for any of the - objects listed above will return NULL. The pointer returned from any - function will now always be a valid pointer and should always be - passed to the corresponding destroy function when finished - - The simplest strategy for porting code is to switch from: - - object = cairo_<object>_create (); - if (object == NULL) - goto BAILOUT; - - /* act on object */ - - cairo_<object>_destroy (object); - - to: - - object = cairo_<object>_create (); - if (cairo_<object>_status (object)) - goto BAILOUT; - - /* act on object */ - - cairo_<object>_destroy (object); - - But significantly, it is not required to check for an error status - before the "act on object" portions of the code above. All - operations on an object with an error status are, by definition, - no-ops without side effect. So new code might be written in an - easier-to-read style of: - - object = cairo_<object>_create (); - - /* act on object */ - - cairo_<object>_destroy (object); - - with cairo_<object>_status checks placed only at strategic - locations. For example, passing an error object to another object, - (eg. cairo_set_source with an in-error pattern), will propagate the - error to the subsequent object (eg. the cairo_t). This means that - error checking can often be deferred even beyond the destruction of - a temporary object. - -API additions -------------- -* New functions for checking the status of objects that have been - switched to the common error-handling scheme: - - cairo_font_face_status - cairo_scaled_font_status - cairo_surface_status - -* The _cairo_error function which was added in 0.5.1 has now been made - much more useful. In 0.5.1 only errors on cairo_t objects passed - through _cairo_error. Now, an error on any object should pass - through _cairo_error making it much more reliable as a debugging - mechanism for finding when an error first occurs. - -* Added new font options support with a myriad of functions: - - cairo_font_options_create - cairo_font_options_copy - cairo_font_options_destroy - - cairo_font_options_status - - cairo_font_options_merge - cairo_font_options_equal - cairo_font_options_hash - - cairo_font_options_set_antialias - cairo_font_options_get_antialias - cairo_font_options_set_subpixel_order - cairo_font_options_get_subpixel_order - cairo_font_options_set_hint_style - cairo_font_options_get_hint_style - cairo_font_options_set_hint_metrics - cairo_font_options_get_hint_metrics - - cairo_surface_get_font_options - - cairo_ft_font_options_substitute - - cairo_set_font_options - cairo_get_font_options - - This new font options support allows the application to have much - more fine-grained control over how fonts are rendered. - Significantly, it also allows surface backends to have some - influence over the process. For example, the xlib backend now - queries existing Xft properties to set font option defaults. - -* New function: - - cairo_xlib_surface_set_drawable - - which allows the target drawable for an xlib cairo_surface_t to be - changed to another with the same format, screen, and display. This - is necessary in certain double-buffering techniques. - -New features ------------- -* Sub-pixel text antialiasing is now supported. - -Bug fixes ---------- -* Fixed assertion failure in cairo_surface_create_similar when - application commits an error by passing a cairo_format_t rather than - a cairo_content_t. - -* Avoid division by zero in various places (cairo-ft). - -* Fix infinite loop when using non-default visuals (cairo-xlib). - -* Eliminate segfault in cairo_image_surface_create_from_png_stream. - -* Prevent errant sign-extension of masks on 64-bit architectures - (cairo-xlib and cairo-xcb). - -* Other miscellaneous fixes. - -Snapshot 0.5.2 (2005-07-18 Carl Worth <cworth@cworth.org>) -========================================================== -API changes ------------ -* New functions for creating patterns of a single color: - - cairo_pattern_create_rgb - cairo_pattern_create_rgba - -* Change cairo_surface_create_similar to accept a new type of - cairo_content_t rather than cairo_format_t: - - typedef enum _cairo_content { - CAIRO_CONTENT_COLOR = 0x1000, - CAIRO_CONTENT_ALPHA = 0x2000, - CAIRO_CONTENT_COLOR_ALPHA = 0x3000 - } cairo_content_t; - -* Add new CAIRO_FORMAT_VALID and CAIRO_CONTENT_VALID macros. - -* Remove unused status value: - - CAIRO_STATUS_NO_TARGET_SURFACE - -* Add new status values: - - CAIRO_STATUS_INVALID_STATUS - -* Require libpixman >= 0.1.5 (for necessary bug fixes) - -Bug fixes ---------- -* Fix cairo_surface_write_to_png for RGB24 images. - -* Fix broken metrics and rendering for bitmap fonts. Add mostly - useless bitmap glyph transformation. - -* Fix glyph caches to not eject entries that might be immediately - needed, (fixing intermittent crashes when rendering text). - -* Fix all memory leaks found by running "make check-valgrind". - -ATSUI backend changes ---------------------- -* Allow building against < 10.3 SDK. - -* Prevent crash on empty strings. - -Glitz backend changes ---------------------- -* Require glitz >= 0.4.4. - -* Use frame buffer objects instead of pbuffers for accelerated - offscreen drawing. - -* Minor improvement to gradient pattern creation. - -PostScript backend fixes ------------------------- -* Rewrite of the PS backend to generate more interesting output that - the old big-image implementation. - -Win32 backend fixes -------------------- -* Implement glyph path support. - -* Fix swap of blue and green values in the fill_rectangles path. - -Xlib backend fixes ------------------- -* Add optimization to use XCopyArea rather than XRenderComposite when - transforming only with an integer translation, and using SOURCE - operator or OVER with a source pattern without alpha. - -Snapshot 0.5.1 (2005-06-20 Carl Worth <cworth@cworth.org>) -========================================================== -API changes ------------ -* Removed cairo_status_string(cairo_t*) and add - cairo_status_to_string(cairo_status_t) in its place. Code using - cairo_status_string can be ported forward as follows: - - cairo_status (cr); - -> - cairo_status_to_string (cairo_status (cr)); - -* Removed the BAD_NESTING restriction which means that two different - cairo_t objects can now interleave drawing to the same - cairo_surface_t without causing an error. - -* The following functions which previously had a return type of - cairo_status_t now have a return type of void: - - cairo_pattern_add_color_stop_rgba - cairo_pattern_set_matrix - cairo_pattern_get_matrix - cairo_pattern_set_extend - cairo_pattern_set_filter - - See discussion of cairo_pattern_status below for more details. - -API additions -------------- -* Improved error handling: - - cairo_status_t - cairo_pattern_status (cairo_pattern_t *pattern); - - This snapshot expands the status-based error handling scheme from - cairo_t to cairo_path_t and cairo_pattern_t. It also expands the - scheme so that object-creating functions, (cairo_create, - cairo_pattern_create_*, cairo_copy_path_*), are now guaranteed to - not return NULL. Instead, in the case of out-of-memory these - functions will return a static object with - status==CAIRO_STATUS_NO_MEMORY. The status can be checked with the - functions cairo_status and cairo_pattern_status, or by direct - inspection of the new status field in cairo_path_t. - - Please note that some objects, including cairo_surface_t and all of - the font-related objects have not been converted to this - error-handling scheme. - -* In addition to the above changes, a new private function has been added: - - _cairo_error - - This function can be used to set a breakpoint in a debugger to make - it easier to find programming error in cairo-using code. (Currently, - _cairo_error is called when any error is detected within a cairo_t - context, but is not called for non-cairo_t errors such as for - cairo_path_t and cairo_pattern_t). - -* Fixed cairo_path_data_t so that its enum is visible to C++ code, (as - cairo_path_data_type_t). - -Performance improvements ------------------------- -* Made a minor performance improvement for clipping, (restrict clip - surface to the new intersected bounds). - -* Optimize rendering of a solid source pattern with a pixel-aligned - rectangular path to use backend clipping rather than rasterization - and backend compositing. - -* Optimize cairo_paint_with_alpha to defer to cairo_paint when alpha - is 1.0. - -Bug fixes ---------- -* Fixed memory leak in cairo_copy_path. - -* A build fix for non-srcdir builds. - -PDF backend fixes ------------------ -* New support for path-based clipping. - -* Fix for text rotated to angles other than multiples of Ï€/2. - -Win32 backend fixes -------------------- -* Fix for text extents. - -Xlib backend ------------- -* Implemented a complex workaround for X server bug[*] related to - Render-based compositing with untransformed, repeating source - pictures. The workaround uses core Xlib when possible for - performance, (ie. with CAIRO_OPERATOR_SOURCE or CAIRO_OPERATOR_OVER - with an opaque source surface), and falls back to the pixman - image-based compositing otherwise. - - [*] https://bugs.freedesktop.org/show_bug.cgi?id=3566 - -* Various bug fixes, particularly in the fallback paths. - -Snapshot 0.5.0 (2005-05-17 Carl Worth <cworth@cworth.org>) -========================================================== -This is a pretty big, and fairly significant snapshot. It represents -between 2 and 3 months of solid work from a lot of people on improving -the API as much as possible. I'd like to express my appreciation and -congratulations to everyone who has worked on the big API Shakeup, -(whether in email battles over names, or fixing my silly bugs). - -This snapshot will require some effort on the part of users, since -there are a _lot_ of API changes (ie. no cairo program ever written is -safe --- they're all broken now in at least one way). But, in spite of -that, we do encourage everyone to move their code to this snapshot as -soon as possible. And we're doing everything we can think of to make -the transition as smooth as possible. - -The idea behind 0.5 is that we've tried to make every good API change -we could want now, and get them all done with. That is, between now -and the 1.0 release of cairo, we expect very few new API changes, -(though some will certainly sneak in). We will have some significant -additions, but the pain of moving code from cairo 0.4 to cairo 0.5 -should be a one time experience, and things should be much smoother as -we continue to move toward cairo 1.0. - -And with so many changes coming out for the first time in this 0.5 -release, we really do need a lot of people trying this out to make -sure the ideas are solid before we freeze the API in preparation for -the 1.0 release. - -OK, enough introduction. Here is a (not-quite-complete) description of -the API removals, changes and additions in this snapshot, (compared to -0.4.0) - -API removals -============ -The following public functions have been removed: - -- cairo_set_target_* - - This is a big change. See the description of cairo_create in - the API changes section for how to deal with this. - -- cairo_set_alpha - - Alpha blending hasn't gone away; there's just a much more - unified rendering model now. Almost all uses of - cairo_set_alpha will be trivially replaced with - cairo_set_source_rgba and a few others will be replaced just - as easily with cairo_paint_with_alpha. - -- cairo_show_surface - - Another useful function that we realized was muddling up the - rendering model. The replacement is quite easy: - cairo_set_source_surface and cairo_paint. - -- cairo_matrix_create -- cairo_matrix_destroy -- cairo_matrix_copy -- cairo_matrix_get_affine - - These functions supported an opaque cairo_matrix_t. We now - have an exposed cairo_matrix_t structure, so these can be - dropped. - -- cairo_surface_set_repeat -- cairo_surface_set_matrix -- cairo_surface_set_filter - - These properties don't belong on surfaces. If you were using - them, you'll just want to instead use - cairo_pattern_create_for_surface and then set these properties - on the pattern. - -- cairo_copy - - This was a confusing function and hopefully nobody will miss - it. But if you really don't find cairo_save/restore adequate, - let us know and we have another idea for a potential - replacement. - -And while we're on the subject of removals, we carefully tightened up -the cairo header files so they no longer gratuitously include header -files that are not strictly necessary, (stdio.h, stdint.h, pixman.h, -Xrender.h, etc. and their dependencies). This may lead to some -surprising errors, so keep your eyes open for that. - -API changes -=========== -Here are some of the API changes that have occurred: - -~ cairo_create(void) -> cairo_create(cairo_surface_t *) - - This is the big change that breaks every program. The ability - to re-target a cairo_t was not particularly useful, but it did - introduce a lot of muddy semantic questions. To eliminate - that, cairo_create now requires its target surface to be - passed in at creation time. This isn't too hard to cope with - as the typical first operation after cairo_create was often - cairo_set_target_foo. So the order of those two swap and the - application instead has cairo_foo_surface_create, then - cairo_create. - -~ cairo_current_* -> cairo_get_* - - We had a strange mixture of cairo_get and cairo_current - functions. They've all been standardized on cairo_get, (though - note one is cairo_get_current_point). - -~ CAIRO_OPERATOR_SRC -> CAIRO_OPERATOR_SOURCE -~ CAIRO_OPERATOR_OVER_REVERSE -> CAIRO_OPERATOR_DEST_OVER - - Many of the cairo_operator_t symbolic values were renamed to - reduce the amount of abbreviation. The confusing "OP_REVERSE" - naming was also changed to use "DEST_OP" instead which is - easier to read and has wider acceptance in other - libraries/languages. - -~ cairo_set_pattern -> cairo_set_source -~ cairo_set_rgb_color -> cairo_set_source_rgb - - All of the various functions that changed the source - color/pattern were unified to use cairo_set_source names to - make the relation more clear. - -~ cairo_transform_point -> cairo_user_to_device -~ cairo_transform_distance -> cairo_user_to_device_distance -~ cairo_inverse_transform_point -> cairo_device_to_user -~ cairo_inverse_transform_distance -> cairo_device_to_user_distance - - These names just seemed a lot more clear. - -~ cairo_init_clip -> cairo_reset_clip -~ cairo_concat_matrix -> cairo_transform - - More abbreviation elimination - -~ cairo_current_path -> cairo_copy_path -~ cairo_current_path_flat -> cairo_copy_path_flat - - The former mechanism for examining the current path was a - function that required 3 or 4 callbacks. This was more - complexity than warranted in most situations. The new - cairo_copy_path function copies the current path into an - exposed data structure, and the documentation provides a - convenient idiom for navigating the path data. - -API additions -------------- -+ cairo_paint - - A generalized version of the painting operators cairo_stroke - and cairo_fill. The cairo_paint call applies the source paint - everywhere within the current clip region. Very useful for - clearing a surface to a solid color, or painting an image, - (see cairo_set_source_surface). - -+ cairo_paint_with_alpha - - Like cairo_paint but applying some alpha to the source, - (making the source paint translucent, eg. to blend an image on - top of another). - -+ cairo_mask - - A more generalized version of cairo_paint_with_alpha which - allows a pattern to specify the amount of translucence at each - point rather than using a constant value everywhere. - -+ cairo_mask_surface - - A convenience function on cairo_mask for when the mask pattern - is already contained within a surface. - -+ cairo_surface_set_user_data -+ cairo_surface_get_user_data -+ cairo_font_face_set_user_data -+ cairo_font_face_get_user_data - - Associate arbitrary data with a surface or font face for later - retrieval. Get notified when a surface or font face object is - destroyed. - -+ cairo_surface_finish - - Allows the user to instruct cairo to finish all of its - operations for a given surface. This provides a safe point for - doing things such as flushing and closing files that the - surface may have had open for writing. - -+ cairo_fill_preserve -+ cairo_stroke_preserve -+ cairo_clip_preserve - - One interesting change in cairo is that the path is no longer - part of the graphics state managed by - cairo_save/restore. This allows functions to construct paths - without interfering with the graphics state. But it prevents - the traditional idiom for fill-and-stroke: - - cairo_save; cairo_fill; cairo_restore; cairo_stroke - - Instead we know have alternate versions cairo cairo_fill, - cairo_stroke, and cairo_clip that preserve the current path - rather than consuming it. So the idiom now becomes simply: - - cairo_fill_preserve; cairo_stroke - -+ cairo_surface_write_to_png -+ cairo_surface_write_to_png_stream - - In place of a single PNG backend, now a surface created - through any backend (except PDF currently) can be written out - to a PNG image. - -+ cairo_image_surface_create_from_png -+ cairo_image_surface_create_from_png_stream - - And its just as easy to load a PNG image into a surface as well. - -+ cairo_append_path - - With the new, exposed path data structure, it's now possible - to append bulk path data to the current path, (rather than - issuing a long sequence of cairo_move_to/line_to/curve_to - function calls). - -Xlib and XCB backends ---------------------- - -Any cairo_format_t and Colormap arguments have been dropped from -cairo_xlib_surface_create. There are also two new -cairo_xlib|xcb_surface_create functions: - - cairo_xlib|xcb_surface_create_for_bitmap - (Particular for creating A1 surfaces) - cairo_xlib|xcb_surface_create_with_xrender_format - (For any other surface types, not described by a Visual*) - -All of these surface create functions now accept width and height. In -addition, there are new cairo_xlib|xcb_surface_set_size functions -which must be called each time a window that is underlying a surface -changes size. - -Print backends (PS and PDF) ---------------------------- -The old FILE* based interfaces have been eliminated. In their place we -have two different functions. One accepts a simple const char -*filename. The other is a more general function which accepts a -callback write function and a void* closure. This should allow the -flexibility needed to hook up with various stream object in many -languages. - -In addition, when specifying the surface size during construction, the -units are now device-space units (ie. points) rather than inches. This -provides consistency with all the other surface types and also makes -it much easier to reason about the size of the surface when drawing to -it with the default identity matrix. - -Finally, the DPI parameters, which are only needed to control the -quality of fallbacks, have been made optional. Nothing is required -during surface_create (300 DPI is assumed) and -cairo_ps|pdf_surface_set_dpi can be used to set alternate values if -needed. - -Font system ------------ -Owen very graciously listened to feedback after the big font rework he -had done for 0.4, and came up with way to improve it even more. In 0.4 -there was a cairo_font_t that was always pre-scaled. Now, there is an -unscaled cairo_font_face_t which is easier to construct, (eg. no -scaling matrix required) and work with, (it can be scaled and -transformed after being set on the graphics state). And the font size -manipulation functions are much easier. You can set an explicit size -and read/modify/write the font matrix with: - - cairo_set_font_size - cairo_get_font_matrix - cairo_set_font_matrix - -(Previously you could only multiply in a scale factor or a matrix.) A -pleasant side effect is that we can (and do) now have a default font -size that is reasonable, as opposed to the old default height of one -device-space unit which was useless until scaled. - -Of course, the old pre-scaled font had allowed some performance -benefits when getting many metrics for a font. Those benefits are -still made available through the new cairo_scaled_font_t. And a -cairo_font_face_t can be "promoted" to a cairo_scaled_font_t by -suppling a font_matrix and the desired CTM. - -Quartz backend --------------- -Tim Rowley put in the work to bring the Quartz backend back after it -had been disabled in the 0.4.0 snapshot. He was not able to bring back -the function that allows one to create a cairo_font_t from an ATSUI -style: - - cairo_font_t * - cairo_atsui_font_create (ATSUStyle style); - -because he didn't have a test case for it. If you care about this -function, please provide a fairly minimal test and we'll try to bring -it back in an upcoming snapshot. - -Snapshot 0.4.0 (2005-03-08 Carl Worth <cworth@cworth.org>) -========================================================== -New documentation ------------------ -Owen Taylor has converted cairo's documentation system to gtk-doc and -has begun some long-needed work on the documentation, which can now be -viewed online here: - - http://cairographics.org/manual/ - -New backend: win32 ------------------- -This is the first snapshot to include a functional win32 backend, -(thanks to Owen Taylor). The interface is as follows: - - #include <cairo-win32.h> - - void - cairo_set_target_win32 (cairo_t *cr, - HDC hdc); - - cairo_surface_t * - cairo_win32_surface_create (HDC hdc); - - cairo_font_t * - cairo_win32_font_create_for_logfontw (LOGFONTW *logfont, - cairo_matrix_t *scale); - - cairo_status_t - cairo_win32_font_select_font (cairo_font_t *font, - HDC hdc); - - void - cairo_win32_font_done_font (cairo_font_t *font); - - double - cairo_win32_font_get_scale_factor (cairo_font_t *font); - -And see also the documentation at: - -http://cairographics.org/manual/cairo-Microsoft-Windows-Backend.html - -Disabled backend: quartz ------------------------- -Unfortunately, the quartz backend code is currently out of date with -respect to some recent backend interface changes. So, the quartz -backend is disabled in this snapshot. - -If the quartz backend is brought up-to-date before the next snapshot, -we would be glad to make a 0.4.1 snapshot that re-enables it, (we do -not expect many more big backend interface changes). - -API Changes ------------ -The font system has been revamped, (as Owen Taylor's work with -integrating pango and cairo gave us the first serious usage of the -non-toy font API). - -One fundamental, user-visible change is that the cairo_font_t object -now represents a font that is scaled to a particular device -resolution. Further changes are described below. - - cairo.h - ------- - Removed cairo_font_set_transform and cairo_font_current_transform. - - Added cairo_font_extents and cairo_font_glyph_extents. See - documentation for details: - - http://cairographics.org/manual/cairo-cairo-t.html#cairo-font-extents - - cairo-ft.h - ---------- - The cairo_ft_font API changed considerably. Please see the - documentation for details: - - http://cairographics.org/manual/cairo-FreeType-Fonts.html - -Performance ------------ -Make the fast-path clipping (pixel-aligned rectangles) faster. - -Add optimization for applying a constant alpha to a pattern. - -Optimize gradients that are horizontal or vertical in device space. - -Xlib: When RENDER is not available, use image surfaces for -intermediate surfaces rather than xlib surfaces. - -Backend-specific changes ------------------------- - Glitz - ----- - Major update to glitz backend. The output quality should now be just - as good as the image and xlib backends. - - Track changes to glitz 0.4.0. - - PDF - --- - Various improvements to produce more conformant output. - -Internals ---------- -David Reveman contributed a large re-work of the cairo_pattern_t -implementation, providing cleaner code and more optimization -opportunities. - - Backend interface changes - ------------------------- - Rework backend interface to accept patterns, not surfaces for source - and mask. - - Remove set_matrix, set_filter, and set_repeat functions. - - More sophisticated backend interface for image fallbacks, - ({acquire,release}_{source,dest}_image() and clone_similar). - -Bug fixes ---------- -Only install header files for backends that have been compiled. - -Fixed some rounding errors leading to incorrectly placed glyphs. - -Many other minor fixes. - -Snapshot 0.3.0 (2005-01-21 Carl Worth <cworth@cworth.org>) -========================================================== -Major API changes ------------------ -1) The public header files will no longer be directly installed into - the system include directory. They will now be installed in a - subdirectory named "cairo", (eg. in /usr/include/cairo rather than - in /usr/include). - - As always, the easiest way for applications to discover the - location of the header file is to let pkg-config generate the - necessary -I CFLAGS and -L/-l LDFLAGS. For example: - - cc `pkg-config --cflags --libs cairo` -o foo foo.c - - IMPORTANT: Users with old versions of cairo installed will need to - manually remove cairo.h and cairo-features.h from the - system include directories in order to prevent the old - headers from being used in preference to the new ones. - -2) The backend-specific portions of the old monolithic cairo.h have - been split out into individual public header files. The new files - are: - - cairo-atsui.h - cairo-ft.h - cairo-glitz.h - cairo-pdf.h - cairo-png.h - cairo-ps.h - cairo-quartz.h - cairo-xcb.h - cairo-xlib.h - - Applications will need to be modified to explicitly include the new - header files where appropriate. - -3) There are two new graphics backends in this snapshot, a PDF - backend, and a Quartz backend. There is also one new font backend, - ATSUI. - -PDF backend ------------ -Kristian Høgsberg has contributed a new backend to allow cairo-based -applications to generate PDF output. The interface for creating a PDF -surface is similar to that of the PS backend, as can be seen in -cairo-pdf.h: - - void - cairo_set_target_pdf (cairo_t *cr, - FILE *file, - double width_inches, - double height_inches, - double x_pixels_per_inch, - double y_pixels_per_inch); - - cairo_surface_t * - cairo_pdf_surface_create (FILE *file, - double width_inches, - double height_inches, - double x_pixels_per_inch, - double y_pixels_per_inch); - -Once a PDF surface has been created, applications can draw to it as -any other cairo surface. - -This code is still a bit rough around the edges, and does not yet -support clipping, surface patterns, or transparent gradients. Text -only works with TrueType fonts at this point and only black text is -supported. Also, the size of the generated PDF files is currently -quite big. - -Kristian is still actively developing this backend, so watch this -space for future progress. - -Quartz backend --------------- -Calum Robinson has contributed a new backend to allow cairo -applications to target native Mac OS X windows through the Quartz -API. Geoff Norton integrated this backend into the current -configure-based build system, while Calum also provided Xcode build -support in the separate "macosx" module available in CVS. - -The new interface, available in cairo-quartz.h, is as follows: - - void - cairo_set_target_quartz_context (cairo_t *cr, - CGContextRef context, - int width, - int height); - - cairo_surface_t * - cairo_quartz_surface_create (CGContextRef context, - int width, - int height); - -There is an example program available in CVS in cairo-demo/quartz. It -is a port of Keith Packard's fdclock program originally written for -the xlib backend. A screenshot of this program running on Mac OS X is -available here: - - http://cairographics.org/~cworth/images/fdclock-quartz.png - -ATSUI font backend ------------------- -This new font backend complements the Quartz backend by allowing -applications to use native font selection on Mac OS X. The interface -is a single new function: - - cairo_font_t * - cairo_atsui_font_create (ATSUStyle style); - -Minor API changes ------------------ -Prototype for non-existent function "cairo_ft_font_destroy" removed. - -Now depends on libpixman 0.1.2 or newer, (0.1.3 is being released -concurrently and has some useful performance improvements). - -Default paint color is now opaque black, (was opaque white). Default -background color is transparent (as before). - -Renamed "struct cairo" to "struct _cairo" to free up the word "cairo" -from the C++ identifier name space. - -Functions returning multiple return values through provided pointers, -(cairo_matrix_get_affine, cairo_current_point, and -cairo_current_color_rgb), will now accept NULL for values the user -wants to ignore. - -CAIRO_HAS_FREETYPE_FONT has now been renamed to CAIRO_HAS_FT_FONT. - -Performance improvements ------------------------- -Alexander Larsson provided some fantastic performance improvements -yielding a 10000% performance improvement in his application, (when -also including his performance work in libpixman-0.1.3). These include - - * Fixed handling of cache misses. - - * Creating intermediate clip surfaces at the minimal size required. - - * Eliminating roundtrips when creating intermediate Xlib surfaces. - -Implementation --------------- -Major re-work of font metrics system by Keith Packard. Font metrics -should now be much more reliable. - -Glitz backend -------------- -Updated for glitz-0.3.0. -Bug fixes in reference counting. - -Test suite ----------- -New tests for cache crashing, rotating text, improper filling of -complex polygons, and leaky rasterization. - -Bug fixes ---------- -Fixed assertion failure when selecting the same font multiple times in -sequence. - -Fixed reference counting so cache_destroy functions work. - -Remove unintended copyright statement from files generated with -PostScript backend. - -Fixed to eliminate new warnings from gcc 3.4 and gcc 4. - -Snapshot 0.2.0 (2004-10-27 Carl Worth <cworth@cworth.org>) -=========================================================== -New license: LGPL/MPL ---------------------- -The most significant news with this release is that the license of -cairo has changed. It is now dual-licensed under the LGPL and the -MPL. For details see the COPYING file as well as COPYING-LGPL-2.1 and -COPYING-MPL-1.1. - -I express my thanks to everyone involved in the license change process -for their patience and support! - -New font and glyph internals ----------------------------- -Graydon Hoare has put a tremendous amount of work into new internals -for handling fonts and glyphs, including caches where appropriate. -This work has no impact on the user-level API, but should result in -great performance improvements for applications using text. - -New test suite --------------- -This snapshot of cairo includes a (small) test suite in -cairo/test. The tests can be run with "make check". The test suite was -designed to make it very easy to add new tests, and we hope to see -many contributions here. As you find bugs, please try adding a minimal -test case to the suite, and submit it with the bug report to the -cairo@cairographics.org mailing list. This will make it much easier -for us to track progress in fixing bugs. - -New name for glitz backend --------------------------- -The gl backend has now been renamed to the glitz backend. This means -that the following names have changed: - - CAIRO_HAS_GL_SURFACE -> CAIRO_HAS_GLITZ_SURFACE - cairo_set_target_gl -> cairo_set_target_glitz - cairo_gl_surface_create -> cairo_glitz_surface_create - -This change obviously breaks backwards compatibility for applications -using the old gl backend. - -Up-to-date with latest glitz snapshots --------------------------------------- -This snapshot of cairo is now up to date with the latest glitz -snapshot, (currently 0.2.3). We know that the latest cairo and glitz -snapshots have been incompatible for a very long time. We've finally -fixed that now and we're determined to not let that happen again. - -Revert some tessellation regression bugs ----------------------------------------- -People that have been seeing some tessellation bugs, (eg. leaked -fills), in the CVS version of cairo may have better luck with this -release. A change since the last snapshot was identified to trigger -some of these bugs and was reverted before making the snapshot. The -behavior should be the same as the previous (0.1.23) snapshot. - -Miscellaneous changes ---------------------- -Changed CAIRO_FILTER_DEFAULT to CAIRO_FILTER_BEST to make gradients -easier. - -Track XCB API change regarding iterators. - -Various bug fixes ------------------ -Fix calculation of required number of vertices for pen. - -Fix to avoid zero-dimensioned pixmaps. - -Fix broken sort of pen vertices. - -Fix bug when cairo_show_text called with a NULL string. - -Fix clipping bugs. - -Fix bug in computing image length with XCB. - -Fix infinite loop bug in cairo_arc. - -Fix memory management interactions with libpixman. - -Snapshot 0.1.23 (2004-05-11 Carl Worth <cworth@isi.edu>) -======================================================== -Fixes for gcc 3.4 ------------------ -Fix prototype mismatches so that cairo can be built by gcc 3.4. - -Updates to track glitz ----------------------- -Various fixes to support the latest glitz snapshot (0.1.2). - -Gradient updates ----------------- -Radial gradients now support both inner and outer circles. -Transformed linear gradients are now properly handled. -Fixes for extend type reflect. - -Glitz updates -------------- -Converted shading routines to use fixed point values and introduced a -shading operator structure for more efficient shading calculations. -Support compositing with mask surface when mask is solid or -multi-texturing is available. - -PNG backend cleanups --------------------- -Fix output to properly compensate for pre-multiplied alpha format in cairo. -Add support for A8 and A1 image formats. - -Bug fixes ---------- -Avoid crash or infinite loop on null strings and degeneratively short -splines. - -New? bugs in cairo_clip ------------------------ -There are some fairly serious bugs in cairo_clip. It is sometimes -causing an incorrect result. And even when it does work, it is -sometimes so slow as to be unusable. Some of these bugs may not be -new, (indeed cairo_clip has only ever had a braindead-slow -implementation), but I think they're worth mentioning here. - -Snapshot 0.1.22 (2004-04-16 Carl Worth <cworth@isi.edu>) -======================================================== -Cairo was updated to track the changes in libpixman, and now depends -on libpixman version 0.1.1. - -Snapshot 0.1.21 (2004-04-09 David Reveman <c99drn@cs.umu.se>) -============================================================= -New OpenGL backend ------------------- -The OpenGL backend provides hardware accelerated output for -X11 and OS X. The significant new functions are: - - cairo_set_target_gl - cairo_gl_surface_create - -Automatic detection of available backends ------------------------------------------ -The configure script now automatically detect what backends are -available, (use ./configure --disable-`backend' to prevent -compilation of specific backends). - -Snapshot 0.1.20 (2004-04-06 Carl Worth <cworth@isi.edu>) -======================================================== -New pattern API ---------------- -David Reveman has contributed a new pattern API which enable linear -and radial gradient patterns in addition to the original surface-based -patterns. The significant new top-level functions are: - - cairo_pattern_create_linear - cairo_pattern_create_radial - cairo_pattern_create_for_surface - cairo_pattern_add_color_stop - cairo_set_pattern - -Any code using the old cairo_set_pattern, (which accepted a -cairo_surface_t rather than a cairo_pattern_t), will need to be -updated. - -Update to XCB backend ---------------------- -The XCB backend is now enabled by default, (use ./configure ---disable-xcb to turn it off). - -Faster clipping ---------------- -Graydon Hoare has added optimizations that make cairo_clip much faster -when the path is a pixel-aligned, rectangular region. - -Bug fixes. - -Snapshot 0.1.19 (2004-02-24 Carl Worth <cworth@isi.edu>) -======================================================== -New PNG backend ---------------- -Olivier Andrieu contributed a new PNG backend. It builds on the -existing image backend to make it easy to render "directly" to a -.png file. The user never needs to deal with the actual image -buffer. The significant new functions are: - - cairo_set_target_png - cairo_png_surface_create - -The PNG backend is not enabled by default so that by default there is -not a new dependency on libpng. Use ./configure --enable-png to enable -this backend. - -Snapshot 0.1.18 (2004-02-17 Carl Worth <cworth@isi.edu>) -======================================================== -Path query functionality ------------------------- -It's now possible to query the current path. The two new functions -are: - - cairo_current_path - cairo_current_path_flat - -Each function accepts a number of callback functions that will be -called for each element in the path (move_to, line_to, curve_to, -close_path). The cairo_current_path_flat function does not accept a -curve_to callback. Instead, all curved portions of the path will be -converted to line segments, (within the current tolerance value). This -can be handy for doing things like text-on-path without having to -manually interpolate Bézier splines. - -New XCB backend ---------------- -Jamey Sharp has contributed a second X backend that uses the new, lean -XCB library rather than Xlib. It cannot currently be compiled at the -same time as the Xlib backend. See ./configure --enable-xcb. - -Build fixes for cygwin. - -Bug fixes. - -Snapshot 0.1.17 (2003-12-16 Carl Worth <cworth@isi.edu>) -======================================================== - -Better text support -------------------- -This snapshot provides much better text support by implementing the -following four functions: - - cairo_text_extents - cairo_glyph_extents - cairo_text_path - cairo_glyph_path - -The text/glyph_extents functions can be used to determine the bounding -box (and advance) for text as if drawn by show_text/glyphs. - -The text/glyph_path objects functions place text shapes on the current -path, where they can be subsequently manipulated. For example, -following these functions with cairo_stroke allows outline text to be -drawn. Calling cairo_clip allows clipping to a text-shaped region. - -Combined dependencies ---------------------- -The cairo core now depends only on the libpixman library. This single -library replaces the three previous libraries libic, libpixregion, and -slim. Thanks to Dave Beckett <dave.beckett@bristol.ac.uk> for all of -the heavy lifting with this renaming effort. - -Conditional compilation of backends ------------------------------------ -Cairo now allows optional backends to be disabled at compile time. The -following options may now be passed to the configure script: - - --disable-xlib - --disable-ps - -Note that the first option is a change from the old --without-x option -which will no longer have any effect. - -OS X supported - several byte-order issues resolved ---------------------------------------------------- -Cairo has now been successfully compiled under OS X. Testing revealed -that there were some byte-order problems in the PostScript backend and -the PNG generation in the demos. These have now been resolved. - -2003-10 -======= -Graydon Hoare <graydon@redhat.com> implemented the first real text -support using Freetype/fontconfig, (previous versions of cairo used -Xft and could only draw text when using an X backend). - -2003-09 -======= -Graydon Hoare <graydon@redhat.com> added the first real support for -running cairo with a non-render-aware X server. - -Jamey Sharp <jamey@minilop.net> virtualized the backend font and -surface interfaces in September, 2003. - -2003-06 -======= -Xr is renamed cairo to avoid confusion since it no longer had a strict -dependence on X. - -2003-05 -======= -A new image surface backend is added to Xr. Keith Packard -<keithp@keithp.com> wrote the image compositing code in libic that is -used for the image_surface backend. This code was originally written -as the software fallback for the render extension within the X -server. - -2002-06 -======= -Carl Worth <cworth@isi.edu> wrote the first lines of Xr, after Keith -Packard <keithp@keithp.com> proposed the plan for a stateful drawing -library in C providing a PostScript-like rendering model. - - LocalWords: mutex BeOS extraordinaire distro's URL lcd bool tarball diff --git a/source/libs/cairo/cairo-src/PORTING_GUIDE b/source/libs/cairo/cairo-src/PORTING_GUIDE deleted file mode 100644 index 7488173c46b237af77bbe390b7d52a10d2c2c3d0..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/PORTING_GUIDE +++ /dev/null @@ -1,265 +0,0 @@ - ...-----=======-----... - Cairo 1.0 Porting Guide - ...-----=======-----... - -Here are some notes on more easily porting cairo_code from cairo 0.4 -to cairo 1.0. It is sorted roughly in order of importance, (the items -near the top are expected to affect the most people). - -Automated API renamings -======================= -There have been a lot of simple renamings where the functionality is -the same but the name of the symbol is different. We have provided a -script to automate the conversion of these symbols. It can be found -within the cairo distribution in: - - util/cairo-api-update - -This script is used by installing it somewhere on your PATH, and the -running it and providing the names of your source files on the command -line. For example: - - cairo-api-update *.[ch] - -The script will first save backup copies of each file (renamed with a -.bak extension) and then will perform all of the simple renamings. - -For your benefit, the script also produces messages giving filenames -and line numbers for several of the manual API updates that you will -need to perform as described below. - - -Manual API changes -================== -This section of the porting guide describes changes you will have to -manually make to your source code. In addition to the information in -this guide, the cairo-api-update script will notify you of some of -these issues as described above. - -Cairo's deprecation warnings ----------------------------- -Also, if your compiler provides warnings for implicit declarations of -functions, (eg. "gcc -Wall"), then simply attempting to compile your -program will cause cairo to generate messages intended to guide you -through the porting process. - -For example, if you neglect to update an old call to -cairo_set_target_drawable, you might see an error message as follows: - - foo.c:10: warning: implicit declaration of function - ‘cairo_set_target_drawable_DEPRECATED_BY_cairo_xlib_surface_create’ - -This message is indicating to you that the deprecatd function -cairo_set_target_drawable appears in your program foo.c on line 10, -and you should rewrite your program to call cairo_xlib_surface_create -instead. - -The remainder of this porting guide is arranged as a set of common -code patterns that appear in old (cairo-0.4) code and how it should be -transformed to new (cairo-0.5) code. - -cairo_create ------------- -Was: cr = cairo_create (); - cairo_set_target_foo (cr, args); - /* draw */ - cairo_destroy (cr); - -Now: cairo_surface_t *surface; - - surface = cairo_foo_surface_create (args); - cr = cairo_create (surface); - /* draw */ - cairo_destroy (cr); - cairo_surface_destroy (surface); - -Or: cairo_surface_t *surface; - - surface = cairo_foo_surface_create (args); - cr = cairo_create (surface); - cairo_surface_destroy (surface); - /* draw */ - cairo_destroy (cr); - -NOTE: Many of the cairo_foo_surface_create functions accept the - identical arguments as the the old cairo_set_target_foo - functions, (minus the cairo_t*), making this transformation - quite easy. One notable exception is cairo_set_target_drawable - which, when it becomes cairo_xlib_surface_create must pickup new - arguments for the Visual*, the width, and the height. - -cairo_set_alpha (1) -------------------- -Was: cairo_set_rgb_color (cr, red, green, blue); - cairo_set_alpha (cr, alpha); - -Now: cairo_set_source_rgba (cr, red, green, blue, alpha); - -cairo_show_surface ------------------- -Was: cairo_show_surface (cr, surface, width, height); - -Now: cairo_set_source_surface (cr, surface, x, y); - cairo_paint (cr); - -NOTE: The type signatures of cairo_show_surface and cairo_set_source - are the same, but pay attention that cairo_show_surface required - the width and height, while cairo_set_source_surface requires - the X,Y location to where the surface will be placed. - -cairo_set_alpha (2) -------------------- -Was: cairo_set_alpha (cr, alpha); - cairo_show_surface (cr, surface, width, height); - -Now: cairo_set_source_surface (cr, surface, x, y); - cairo_paint_with_alpha (cr, alpha); - -filling and stroking --------------------- -Was: cairo_save (cr); - /* set fill color */ - cairo_fiill (cr); - cairo_restore (cr); - /* set stroke color */ - cairo_stroke (cr); - -Now: /* set fill color */ - cairo_fill_preserve (cr); - /* set stroke color */ - cairo_stroke (cr); - -NOTE: The current path is no longer saved/restored by - cairo_save/cairo_restore. This can lead to some subtle - surprises, so look out. - -cairo_matrix_t --------------- -Was: cairo_matrix_t *matrix; - - matrix = cairo_matrix_create (); - /* Do stuff with matrix */ - cairo_matrix_destroy (matrix); - -Now: cairo_matrix_t matrix; - cairo_matrix_init_identity (&matrix); - /* Do stuff with &matrix */ - -NOTE: If you are really lazy, you can still use a cairo_matrix_t* and - avoid putting the &matrix all over by just replacing - cairo_matrix_create() with malloc() and cairo_matrix_destroy() - with free(). That's not as nice, and you still need to be - careful to see if you need to initialize it to an identity - matrix as cairo_matrix_create() did for you. - -Rendering to a temporary surface --------------------------------- -Was: cairo_save (cr); - { - cairo_set_target_surface (cr, temporary); - /* draw through cr onto temporary */ - } - cairo_restore (cr); - /* use temporary as source on cr */ - -Now: { - cr2 = cairo_create (temporary); - /* draw through cr2 onto temporary */ - cairo_destory (cr2); - } - /* use temporary as source on cr */ - -NOTE: Having to create another cairo_t is a bit annoying, but having - to invent a new name for it is just awful, (imagine a deeply - nested version of this code). Fortunately, the style above is - just a stop-gap measure until the new group API comes along. - -Iterating over a path ---------------------- -Was: cairo_current_path (cr, - my_move_to, - my_line_to, - my_curve_to, - my_close_path, - closure); - -Now: int i; - cairo_path_t *path; - cairo_path_data_t *data; - - path = cairo_copy_path (cr); - - for (i=0; i < path->num_data; i += path->data[i].header.length) { - data = &path->data[i]; - switch (data->header.type) { - case CAIRO_PATH_MOVE_TO: - my_move_to (closure, data[1].point.x, data[1].point.y); - break; - case CAIRO_PATH_LINE_TO: - my_line_to (closure, data[1].point.x, data[1].point.y); - break; - case CAIRO_PATH_CURVE_TO: - my_curve_to (closure, data[1].point.x, data[1].point.y, - data[2].point.x, data[2].point.y, - data[3].point.x, data[3].point.y); - break; - case CAIRO_PATH_CLOSE_PATH: - my_close_path (closure); - break; - } - } - cairo_path_destroy (path); - -NOTE: This version makes it looks like the new form is a _lot_ more - verbose than the old version. But realize that the old version - required the support of 4 additional functions. The new approach - allows great flexibility including the ability to inline the - entire operation within the switch statement when appropriate. - -Erasing a surface to transparent --------------------------------- -Was: cairo_set_rgb_color (cr, 0., 0., 0.); - cairo_set_alpha (cr, 0.) - cairo_set_operator (cr, CAIRO_OPERATOR_SRC); - cairo_rectangle (cr, 0., 0., surface_width, surface_height); - cairo_fill (cr); - - or: cairo_set_rgb_color (cr, 0., 0., 0.); - cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); - cairo_rectangle (cr, 0., 0., surface_width, surface_height); - cairo_fill (cr); - -Now: cairo_set_source_rgba (cr, 0., 0., 0., 0.); - cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); - cairo_paint (cr); - - or: cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); - cairo_paint (cr); - -NOTE: Using cairo_rectangle and fill would still work just fine. It's - just a lot more convenient to use cairo_paint now, (particularly - as it doesn't require you to even know what the bounds of the - target surface are). - -Drawing to a PNG file ---------------------- -Was: file = fopen (filename, "w"); - cr = cairo_create (); - cairo_set_target_png (cr, file, format, width, height); - /* draw image */ - cairo_destroy (cr); - fclose (file); - -Now: surface = cairo_image_surface_create (format, width, height); - cr = cairo_create (surface); - /* draw image */ - cairo_surface_write_to_png (surface, filename); - cairo_destroy (cr); - cairo_surface_destroy (surface); - -NOTE: The png backend is gone. So there is no cairo_png_surface_create - to take the place of cairo_set_target_png. And notice that we - used an image surface here, but it is just as easy to use - cairo_surface_write_to_png with an xlib or other surface, (but - not PDF at the moment). This is one of the big advantages of - this approach as opposed to a PNG surface. diff --git a/source/libs/cairo/cairo-src/README b/source/libs/cairo/cairo-src/README deleted file mode 100644 index 0be9947d548d8a16eeef06df90be40c8eee66d43..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/README +++ /dev/null @@ -1,204 +0,0 @@ -Cairo - Multi-platform 2D graphics library -http://cairographics.org - -What is cairo -============= -Cairo is a 2D graphics library with support for multiple output -devices. Currently supported output targets include the X Window -System (via both Xlib and XCB), quartz, win32, and image buffers, -as well as PDF, PostScript, and SVG file output. Experimental backends -include OpenGL, BeOS, OS/2, and DirectFB. - -Cairo is designed to produce consistent output on all output media -while taking advantage of display hardware acceleration when available -(for example, through the X Render Extension). - -The cairo API provides operations similar to the drawing operators of -PostScript and PDF. Operations in cairo include stroking and filling -cubic Bézier splines, transforming and compositing translucent images, -and antialiased text rendering. All drawing operations can be -transformed by any affine transformation (scale, rotation, shear, -etc.). - -Cairo has been designed to let you draw anything you want in a modern -2D graphical user interface. At the same time, the cairo API has been -designed to be as fun and easy to learn as possible. If you're not -having fun while programming with cairo, then we have failed -somewhere---let us know and we'll try to fix it next time around. - -Cairo is free software and is available to be redistributed and/or -modified under the terms of either the GNU Lesser General Public -License (LGPL) version 2.1 or the Mozilla Public License (MPL) version -1.1. - -Where to get more information about cairo -========================================= -The primary source of information about cairo is: - - http://cairographics.org/ - -The latest versions of cairo can always be found at: - - http://cairographics.org/download - -Documentation on using cairo and frequently-asked questions: - - http://cairographics.org/documentation - http://cairographics.org/FAQ - -Mailing lists for contacting cairo users and developers: - - http://cairographics.org/lists - -Roadmap and unscheduled things to do, (please feel free to help out): - - http://cairographics.org/roadmap - http://cairographics.org/todo - -Dependencies -============ -The set of libraries needed to compile cairo depends on which backends -are enabled when cairo is configured. So look at the list below to -determine which dependencies are needed for the backends of interest. - -For the surface backends, we have both "supported" and "experimental" -backends. Further, the supported backends can be divided into the -"standard" backends which can be easily built on any platform, and the -"platform" backends which depend on some underlying platform-specific -system, (such as the X Window System or some other window system). - -As an example, for a standard Linux build similar to what's shipped by -your distro, (with image, png, pdf, PostScript, svg, and xlib surface -backends, and the freetype font backend), the following sample commands -will install necessary dependencies: - - Debian (and similar): - - apt-get build-dep cairo - - Fedora (and similar): - - yum install libpng-devel zlib-devel libXrender-devel fontconfig-devel - -Technically you probably don't need pixman from the distribution since -if you're manually compiling Cairo you probably want an updated pixman -as well. However, if you follow the default settings and install pixman -to /usr/local, your Cairo build should properly use it in preference to -the system pixman. - - -Supported, "standard" surface backends ------------------------------------- - image backend (required) - ------------------------ - pixman >= 0.30.0 http://cairographics.org/releases - - png support (can be left out if desired, but many - ----------- applications expect it to be present) - libpng http://www.libpng.org/pub/png/libpng.html - - pdf backend - ----------- - zlib http://www.gzip.org/zlib - - postscript backend - ------------------ - zlib http://www.gzip.org/zlib - - svg backend - ----------- - [none] - -Supported, "platform" surface backends ------------------------------------ - xlib backend - ------------ - X11 http://freedesktop.org/Software/xlibs - - xlib-xrender backend - -------------------- - Xrender >= 0.6 http://freedesktop.org/Software/xlibs - - quartz backend - -------------- - MacOS X >= 10.5 with Xcode >= 3.0 - - win32 backend - ------------- - Microsoft Windows 2000 or newer[*]. - - xcb backend - ----------- - XCB http://xcb.freedesktop.org - -Font backends (required to have at least one) ---------------------------------------------- - freetype font backend - --------------------- - freetype >= 2.1.9 http://freetype.org - fontconfig http://fontconfig.org - - quartz-font backend - ------------------- - MacOS X >= 10.4 with Xcode >= 2.4 - - win32 font backend - ------------------ - Microsoft Windows 2000 or newer[*]. - - [*] The Win32 backend should work on Windows 2000 and newer - (excluding Windows Me.) Most testing has been done on - Windows XP. While some portions of the code have been - adapted to work on older versions of Windows, considerable - work still needs to be done to get cairo running in those - environments. - - Cairo can be compiled on Windows with either the gcc - toolchain (see http://www.mingw.org) or with Microsoft - Visual C++. If the gcc toolchain is used, the standard - build instructions using configure apply, (see INSTALL). - If Visual C++ is desired, GNU make is required and - Makefile.win32 can be used via 'make -f Makefile.win32'. - The compiler, include paths, and library paths must be set - up correctly in the environment. - - MSVC versions earlier than 7.1 are known to miscompile - parts of cairo and pixman, and so should be avoided. MSVC - 7.1 or later, including the free Microsoft Visual Studio - Express editions, produce correct code. - -Experimental surface backends ------------------------------ - beos backend - ------------ - No dependencies in itself other than an installed BeOS system, but cairo - requires a font backend. See the freetype dependency list. - - os2 backend - ----------- - Cairo should run on any recent version of OS/2 or eComStation, but it - requires a font backend. See the freetype dependency list. Ready to use - packages and developer dependencies are available at Netlabs: - ftp://ftp.netlabs.org/pub/cairo - - skia backend - ------------ - Requires the skia library as of June 2014. Since skia is not - API stable, building against newer (or older) versions of skia - will probably fail. - - -Compiling -========= -See the INSTALL document for build instructions. - - -History -======= -Cairo was originally developed by Carl Worth <cworth@cworth.org> and -Keith Packard <keithp@keithp.com>. Many thanks are due to Lyle Ramshaw -without whose patient help our ignorance would be much more apparent. - -Since the original development, many more people have contributed to -cairo. See the AUTHORS files for as complete a list as we've been able -to compile so far. diff --git a/source/libs/cairo/cairo-src/README.win32 b/source/libs/cairo/cairo-src/README.win32 deleted file mode 100644 index ff962b72a6894a0f80133ab1d9ee3811bc3e68ef..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/README.win32 +++ /dev/null @@ -1,66 +0,0 @@ -Building Cairo on Windows -========================= -There are two primary ways to build Cairo on Windows. You can use a -UNIX emulation based setup, such as Cygwin or MSYS, with the -conventional configure script shipped with Cairo releases. In this -configuration, you will build with GCC and (implicitly) libtool. In -the Cygwin case you end up with a DLL that depends on Cygwin and -should be used only from Cygwin applications. In the MSYS case you end -up with a "normal" Win32 DLL that can be used either from GCC- or -Microsoft Visual C++-compiled code. In theory, this technique is no -different than the ordinary build process for the Cairo library. In -practise there are lots of small details that can go wrong. - -The second way is to use a GNU-compatible make, but build using -Microsoft's Visual C++ compiler to produce native libraries. This is -the setup this README.win32 is written for. Also the DLL produced this -way is usable either from GCC- or MSVC-compiled code. - -Tools required -============== -You will need GNU make, version 3.80 or later. Earlier versions or -other modern make implementations may work, but are not guaranteed to. - -You will also need Microsoft Visual C++. Version 7 has been most -heavily tested, but other versions are likely to work fine. - -Libraries required -================== -Cairo requires a compatible version of the pixman library. Full build -instructions are beyond the scope of this document; however, using the -same tools, it should be possible to build pixman simply by entering -the pixman/src directory and typing: - - make -f Makefile.win32 CFG=release - -Depending on your feature set, you may also need zlib and libpng. - -Building -======== -There are a few files that you will need to edit. First, you must -determine which features will be built. Edit -build/Makefile.win32.features and set the features as desired. Note -that most features have external dependencies; specifically, -CAIRO_HAS_PNG_FUNCTIONS requires libpng to be present, and -CAIRO_HAS_PS_SURFACE and CAIRO_HAS_PDF_SURFACE both require zlib. - -To ensure that the compiler can find all dependencies, you may need to -edit build/Makefile.win32.common. In particular, ensure that -PIXMAN_CFLAGS contains a -I parameter pointing to the location of -your pixman header files and that PIXMAN_LIBS points to the actual -location of your pixman-1.lib file. You may also need to edit the -various occurrences of CAIRO_LIBS to point to other libraries -correctly. Note also that if you wish to link statically with zlib, -you should replace zdll.lib with zlib.lib. - -Finally, from the top Cairo directory, type: - - make -f Makefile.win32 CFG=release - -If this command succeeds, you will end up with src/release/cairo.dll. -To successfully use Cairo from your own programs, you will probably -want to move this file to some central location. You will also -probably want to copy the Cairo header files. These should be placed -in a cairo subdirectory (for instance, c:/code/common/include/cairo). -The exact set to copy depends on your features and is reported to you -at the end of the build. diff --git a/source/libs/cairo/cairo-src/RELEASING b/source/libs/cairo/cairo-src/RELEASING deleted file mode 100644 index 641ac1fc4a58700491f368de1a3b19fa6aaf8275..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/RELEASING +++ /dev/null @@ -1,138 +0,0 @@ -Here are the steps to follow to create a new cairo release: - -1) Ensure that there are no local, uncommitted/unpushed - modifications. You're probably in a good state if both "git diff - HEAD" and "git log master..origin/master" give no output. Also make - sure you have libglib2.0-doc installed (else you'll get excessive - gtk-doc cross reference warnings in the next step). - -2) Verify that the code passes "make distcheck" - - First, make sure you have 'nm' and 'readelf' commands in PATH. - this should be OK with any Linux distro. - - Running "make distcheck" should result in no warnings or - errors and end with a message of the form: - - ============================================= - cairo-X.Y.Z archives ready for distribution: - cairo-X.Y.Z.tar.gz - ============================================= - - (But the tar file isn't actually ready yet, as we still have - some more steps to follow). - - Note that it's allowed (and perhaps recommended) to run the - "make distcheck" step against an all-software X server such as - Xvfb to avoid getting tripped up by any X-server-driver-specific - bugs. See test/README for details - - If you get errors about local PLT entries, you get the list of - cairo entries with the error. For each of these, a call to - slim_hidden_def and slim_hidden_proto is needed in the cairo - implementation in the style of other similar calls. - - In the unfortunate case that you have to push a snapshot out - (note, I said snapshot, not release) without the entire test - suite passing, here's the magic env vars to set when doing - 'make distcheck' and 'make release-publish' that will let you - get away with it. At any cost, never ever release without - (implied) distchecking. Every time we got around it, it turned - out to be a disaster. Anyway, here's the pass code: - - DISPLAY= CAIRO_TEST_TARGET=" " - -3) Fill out an entry in the NEWS file - - Sift through the logs since the last release. This is most - easily done with a command such as: - - git log --stat X.Y.Z.. - - where X.Y.Z is the previous release version. - - Summarize major changes briefly in a style similar to other - entries in NEWS. Take special care to note any additions in - the API. These should be easy to find by noting modifications - to .h files in the log command above. And more specifically, - the following command will show each patch that has changed a - public header file since the given version: - - find src/ -name '*.h' ! -name '*-private.h' ! -name 'cairoint.h' ! -name 'cairo-*features*.h' | \ - xargs git diff X.Y.Z.. -- - -4) Increment cairo_version_{minor|micro} in cairo-version.h: - - If there are backward-incompatible changes in the API, stop - now and don't release. Go back and fix the API instead. Cairo - is intended to remain backwards-compatible as far as API. - - So cairo_version_major will not be incremented unless we come - up with a new versioning scheme to take advantage of it. - - If there are API additions, then increment cairo_version_minor - and reset cairo_version_micro to 0. NOTE: The minor version is - only incremented for releases, not for snapshots. - - Otherwise, (i.e. there are only bug fixes), increment - cairo_version_micro to the next larger (even) number. - -5) Commit the changes to NEWS and cairo-version.h - - 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: - - * Generate ChangeLog files out of git repository - * Check that ChangeLog files were generated properly - * Check that the version number ends with an even micro component - * Check that no release exists with the current version - * Verify that make distcheck completes successfully - * Generate the final tar file - * Generate an sha1sum file - * Sign the sha1sum using your GPG setup (asks for your GPG password) - * scp the three files to appear on http://cairographics.org/releases - * Generate a versioned manual and upload it to appear as both: - http://cairographics.org/manual-X.Y.Z - http://cairographics.org/manual - * 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 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 - cairo-version.h, commit, and push. - -8) Push the newly created tag out to the central tree with a command - something like: - - git push origin master X.Y.Z - -9) Edit the cairo bugzilla product and add the new version numbers. Note - that you need to add two versions. One for the release/snapshot (with - an even micro version), another with the post-release version (with an - odd micro version). - -10) Send a message to cairo-announce@cairographics.org and CC - cairo@cairographics.org, gnome-announce-list@gnome.org and - ftp-release@lists.freedesktop.org (pr@lwn.net as well for major - releases) to announce the new release using the text provided from - "make release-publish", adding the excerpt from NEWS, your - signature, followed by the standard "What is cairo" and "Where to - get more information about cairo" blurbs from README, and finally - the shortlog of all changes since last release, generated by: - - git shortlog X.Y.Z... - - where X.Y.Z is the last released version. - -11) Edit the cairo wiki to add the announcement to the NEWS page and - the front page. (just the parts before your signature). - diff --git a/source/libs/cairo/cairo-src/acinclude.m4 b/source/libs/cairo/cairo-src/acinclude.m4 deleted file mode 100644 index dcf54f9357d66bf2f25b44b60833197f379af4fc..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/acinclude.m4 +++ /dev/null @@ -1,55 +0,0 @@ -dnl -*- mode: autoconf -*- - -dnl [m4_newline] didn't appear until autoconf 2.62 -m4_ifdef([m4_newline],,[m4_define([m4_newline],[ -])]) - -dnl These are not available in autoconf 2.59 - -m4_ifdef([m4_foreach_w],,[m4_define([m4_foreach_w], -[m4_foreach([$1], m4_split(m4_normalize([$2]), [ ]), [$3])])]) - -m4_ifdef([AS_CASE],,[ -m4_define([_AS_CASE], -[m4_if([$#], 0, [m4_fatal([$0: too few arguments: $#])], - [$#], 1, [ *) $1 ;;], - [$#], 2, [ $1) m4_default([$2], [:]) ;;], - [ $1) m4_default([$2], [:]) ;; -$0(m4_shift2($@))])dnl -]) -m4_defun([AS_CASE], -[m4_ifval([$2$3], -[case $1 in -_AS_CASE(m4_shift($@)) -esac -])dnl -])# AS_CASE -]) - -m4_ifdef([m4_shift2],, [m4_define([m4_shift2], [m4_shift(m4_shift($@))])]) - - -dnl ========================================================================== - -dnl This has to be in acinclude.m4 as it includes other files - -dnl Parse Version.mk and declare m4 variables out of it -m4_define([CAIRO_PARSE_VERSION],dnl - m4_translit(dnl - m4_bpatsubst(m4_include(cairo-version.h), - [^.define \([a-zA-Z0-9_]*\) *\([0-9][0-9]*\)], - [[m4_define(\1, \2)]]), - [A-Z], [a-z])dnl -)dnl - -dnl ========================================================================== - -m4_pattern_forbid([^cr_]) - -dnl AC_AUTOCONF_VERSION was introduced in 2.62, so its definition works as -dnl a conditional on version >= 2.62. Older versions did not call -dnl m4_pattern_allow from AC_DEFINE and friends. To avoid lots of warnings we -dnl only forbid CAIRO_ if autoconf is recent enough. -m4_ifdef([AC_AUTOCONF_VERSION], -[m4_pattern_forbid([CAIRO])], -[m4_pattern_forbid([_CAIRO])]) diff --git a/source/libs/cairo/cairo-src/autogen.sh b/source/libs/cairo/cairo-src/autogen.sh deleted file mode 100755 index 4d113f8be5f748fd21e711abb02544b5ea094f31..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/autogen.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/sh -# Run this to generate all the initial makefiles, etc. - -test -n "$srcdir" || srcdir=`dirname "$0"` -test -n "$srcdir" || srcdir=. - -ORIGDIR=`pwd` -cd $srcdir - -AUTORECONF=`which autoreconf` -if test -z $AUTORECONF; then - echo "*** No autoreconf found, please intall it ***" - exit 1 -fi - -GTKDOCIZE=`which gtkdocize` -if test -z $GTKDOCIZE; then - echo "*** No GTK-Doc found, documentation won't be generated ***" -else - gtkdocize || exit $? -fi - -# create dummy */Makefile.am.features and ChangeLog to make automake happy -> boilerplate/Makefile.am.features -> src/Makefile.am.features -touch ChangeLog - -autoreconf --install --verbose || exit $? - -cd $ORIGDIR -test -n "$NOCONFIGURE" || "$srcdir/configure" "$@" diff --git a/source/libs/cairo/cairo-src/build/Makefile.am.analysis b/source/libs/cairo/cairo-src/build/Makefile.am.analysis deleted file mode 100644 index a44077ab45374318a26d9ecbaa3a8f07623581cf..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/build/Makefile.am.analysis +++ /dev/null @@ -1,37 +0,0 @@ -if CAIRO_HAS_LCOV -# use recursive makes in order to ignore errors during check/perf -lcov: - -$(MAKE) $(AM_MAKEFLAGS) check - $(MAKE) $(AM_MAKEFLAGS) genlcov -lcov-perf: - -$(MAKE) $(AM_MAKEFLAGS) perf - $(MAKE) $(AM_MAKEFLAGS) genlcov - -# we have to massage the lcov.info file slightly to hide the effect of libtool -# placing the objects files in the .libs/ directory separate from the *.c -genlcov: - $(LTP) --directory $(top_builddir) --path $(top_builddir) --capture --output-file cairo-lcov.info --test-name CAIRO_TEST --no-checksum - $(SED) -e 's#.libs/##' \ - -e 's#boilerplate/src#src#' \ - -e 's#$(shell pwd)#$(shell cd $(top_srcdir) && pwd)#' \ - < cairo-lcov.info > cairo-lcov.info.tmp - LANG=C $(LTP_GENHTML) --prefix $(top_builddir) --output-directory cairo-lcov --title "Cairo Code Coverage" --show-details cairo-lcov.info.tmp - $(RM) cairo-lcov.info.tmp - -html-local: lcov -else -lcov lcov-perf genlcov: - @echo You need to configure Cairo with support for gcov enabled. - @echo e.g, ./configure --enable-gcov -endif - -lcov-clean: -if CAIRO_HAS_LCOV - -$(LTP) --directory $(top_builddir) -z -endif - -$(RM) -r cairo-lcov.info cairo-lcov - -$(FIND) -name '*.gcda' -print | $(XARGS) $(RM) - -distclean-local: lcov-clean - -.PHONY: lcov lcov-perf genlcov lcov-clean diff --git a/source/libs/cairo/cairo-src/build/Makefile.am.changelog b/source/libs/cairo/cairo-src/build/Makefile.am.changelog deleted file mode 100644 index 07e603695cfc77056040c33e8cc5078101a02bd9..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/build/Makefile.am.changelog +++ /dev/null @@ -1,82 +0,0 @@ -# Creating ChangeLog files from git log: - -# We always create a ChangeLog that contains the most recent changes, and -# multiple others for changes between major releases (other than the last such -# segment that we put in 'ChangeLog'. The old ones are named -# ChangeLog.pre-X.Y where X.Y is the version number of the major release. - -CURR_CHANGELOG_VERSION=$(CAIRO_VERSION_MAJOR).$$(echo "($(CAIRO_VERSION_MINOR)+1)/2*2" | bc) -# examines $version -PREV_CHANGELOG_VERSION=$$(if test "x$$(echo "($$version-0.1)*2/2"|bc)" = "x$$(echo "$$version*2/2"|bc)"; \ - then echo "$$version-$$(echo "$$version" | sed 's/[0-9]/0/g;s/[0-9]$$/2/')"; \ - else echo "$$version-1.0"; \ - fi | bc | sed 's/[.]0*/./;s/^0[.]\?$$/initial/;s/[.]$$/.0/') - -CHANGELOGS = ChangeLog \ - `version=$(CURR_CHANGELOG_VERSION); \ - version=$(PREV_CHANGELOG_VERSION); \ - while test "x$$version" != xinitial; do \ - echo ChangeLog.pre-$$version; \ - version=$(PREV_CHANGELOG_VERSION); \ - done` - -MAINTAINERCLEANFILES += $(srcdir)/ChangeLog $(srcdir)/ChangeLog.pre-* -DISTCLEANFILES += $(srcdir)/ChangeLog.cache-* - -changelogs: - @$(MAKE) $(AM_MAKEFLAGS) $(CHANGELOGS) - -dist-hook: changelogs - changelogs="$(CHANGELOGS)"; \ - for changelog in $$changelogs; do \ - cp $(srcdir)/$$changelog $(distdir)/ 2>/dev/null || \ - cp $$changelog $(distdir)/; \ - done - -$(srcdir)/ChangeLog: - @if test -d "$(srcdir)/.git"; then \ - version=$(CURR_CHANGELOG_VERSION); \ - prev=$(PREV_CHANGELOG_VERSION).0; \ - nearest_tag=`git describe | sed 's/-.*//'`; \ - before=$(srcdir)/ChangeLog.cache-$$prev..$$nearest_tag; \ - after=$(srcdir)/ChangeLog.cache-$$nearest_tag..; \ - $(MAKE) $(AM_MAKEFLAGS) $$before $$after && \ - echo Creating $@ && \ - { echo '# Generated by configure. Do not edit.'; echo; \ - cat $$after; echo; cat $$before; } > $@; \ - else \ - test -f $@ || \ - (echo A git checkout is required to generate $@ >&2 && \ - echo A git checkout is required to generate this file >> $@); \ - fi - -DISTCLEANFILES += ChangeLog.cache-* - -ChangeLog.cache-*..: .git - -ChangeLog%: $(srcdir)/ChangeLog% - -$(srcdir)/ChangeLog.cache-% $(srcdir)/ChangeLog.pre-%: - @echo Creating $@ - @if test -d "$(srcdir)/.git"; then \ - (cd "$(srcdir)" && \ - version=$$(echo "$@" | sed 's/.*ChangeLog\([.].*-\)\?//'); \ - if echo "$@" | grep -q '^ChangeLog[.]cache'; then \ - spec=$$version; \ - else \ - to=$$version; \ - test "x$$version" = x && version=$(CURR_CHANGELOG_VERSION); \ - from=$(PREV_CHANGELOG_VERSION); \ - test "x$$to" = x || to=$$to.0; \ - test "x$$from" = xinitial || from=$$from.0; \ - spec=$$from..$$to; \ - fi; \ - $(top_srcdir)/build/missing --run git log --stat "$$spec") > $@.tmp \ - && mv -f $@.tmp $@ \ - || ($(RM) $@.tmp; \ - echo Failed to generate $@, your $@ may be outdated >&2); \ - else \ - echo A git checkout is required to generate $@ >&2; \ - fi - -.PHONY: changelogs ChangeLog $(srcdir)/ChangeLog diff --git a/source/libs/cairo/cairo-src/build/Makefile.am.common b/source/libs/cairo/cairo-src/build/Makefile.am.common deleted file mode 100644 index b955af58fdf328819f83cbc07ee1113c81e5cc93..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/build/Makefile.am.common +++ /dev/null @@ -1,14 +0,0 @@ -BUILT_SOURCES = -CLEANFILES = -DISTCLEANFILES = -EXTRA_DIST = -EXTRA_LTLIBRARIES = -EXTRA_PROGRAMS = -MAINTAINERCLEANFILES = -TESTS = -check_PROGRAMS = - -CLEANFILES += *.i *.s *.gch -CLEANFILES += $(EXTRA_LTLIBRARIES) $(EXTRA_PROGRAMS) $(check_PROGRAMS) -DISTCLEANFILES += $(BUILT_SOURCES) -MAINTAINERCLEANFILES += Makefile.in diff --git a/source/libs/cairo/cairo-src/build/Makefile.am.gtk-doc b/source/libs/cairo/cairo-src/build/Makefile.am.gtk-doc deleted file mode 100644 index c3d642b097b630e037b9dc14281b17ad917eb30c..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/build/Makefile.am.gtk-doc +++ /dev/null @@ -1,190 +0,0 @@ -# BEFORE MODIFYING THIS FILE: -# -# This file is a descendant of an old copy of gtk-doc.make, modified for cairo minimally: -# -# - Moved to build/ -# - Made it append to EXTRA_DIST and CLEANFILES -# - Instead of all-local, make "doc" build docs, and err if gtk-doc not enabled -# - Some other changed introduced in 7f114b781f5c530d57530e5f76402e41cdabac6b -# -# Before changing it, check to see if a newer gtk-doc.make has fixed the issue you are facing. -# From time to time, it would be nice to udpate this to the latest copy of gtk-doc.make, but -# please do review all the differences and port our modifications forward. -# - -# -*- mode: makefile -*- - -#################################### -# Everything below here is generic # -#################################### - -if GTK_DOC_USE_LIBTOOL -GTKDOC_CC = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -GTKDOC_LD = $(LIBTOOL) --tag=CC --mode=link $(CC) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -else -GTKDOC_CC = $(CC) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -GTKDOC_LD = $(CC) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -endif - -# We set GPATH here; this gives us semantics for GNU make -# which are more like other make's VPATH, when it comes to -# whether a source that is a target of one rule is then -# searched for in VPATH/GPATH. -# -GPATH = $(srcdir) - -TARGET_DIR=$(HTML_DIR)/$(DOC_MODULE) - -EXTRA_DIST += \ - $(content_files) \ - $(HTML_IMAGES) \ - $(DOC_MAIN_SGML_FILE) \ - $(DOC_MODULE)-sections.txt \ - $(DOC_MODULE)-overrides.txt - -DOC_STAMPS=scan-build.stamp tmpl-build.stamp sgml-build.stamp html-build.stamp \ - $(srcdir)/tmpl.stamp $(srcdir)/sgml.stamp $(srcdir)/html.stamp - -SCANOBJ_FILES = \ - $(DOC_MODULE).args \ - $(DOC_MODULE).hierarchy \ - $(DOC_MODULE).interfaces \ - $(DOC_MODULE).prerequisites \ - $(DOC_MODULE).signals - -REPORT_FILES = \ - $(DOC_MODULE)-undocumented.txt \ - $(DOC_MODULE)-undeclared.txt \ - $(DOC_MODULE)-unused.txt - -CLEANFILES += $(SCANOBJ_FILES) $(REPORT_FILES) $(DOC_STAMPS) - -if ENABLE_GTK_DOC -doc: html-build.stamp -else -doc: - @echo "*** gtk-doc must be installed (and --enable-gtk-doc) in order to make doc" - @false -endif - -docs: html-build.stamp - -#### scan #### - -scan-build.stamp: $(HFILE_GLOB) $(CFILE_GLOB) $(EXTRA_HFILES) - @echo 'gtk-doc: Scanning header files' - @-chmod -R u+w $(srcdir) - gtkdoc-scan --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --ignore-headers="$(IGNORE_HFILES)" $(SCAN_OPTIONS) $(EXTRA_HFILES) --output-dir=$(srcdir) - if grep -l '^..*$$' $(srcdir)/$(DOC_MODULE).types > /dev/null 2>&1 ; then \ - CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" CFLAGS="$(GTKDOC_CFLAGS)" LDFLAGS="$(GTKDOC_LIBS)" gtkdoc-scangobj $(SCANGOBJ_OPTIONS) --module=$(DOC_MODULE) --output-dir=$(srcdir) ; \ - else \ - cd $(srcdir) ; \ - for i in $(SCANOBJ_FILES) ; do \ - test -f $$i || touch $$i ; \ - done \ - fi - touch scan-build.stamp - -$(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt: scan-build.stamp - @true - -#### templates #### - -tmpl-build.stamp: $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt - @echo 'gtk-doc: Rebuilding template files' - @-chmod -R u+w $(srcdir) - cd $(srcdir) && gtkdoc-mktmpl --module=$(DOC_MODULE) $(MKTMPL_OPTIONS) - touch tmpl-build.stamp - -tmpl.stamp: tmpl-build.stamp - @true - -tmpl/*.sgml: - @true - - -#### xml #### - -# gtkdoc-mkdb is broken and requires a --root-dir=$(srcdir) option -# The _srcdir diversion is fragile but works for make check; make distcheck -sgml-build.stamp: tmpl.stamp $(HFILE_GLOB) $(CFILE_GLOB) $(DOC_MODULE)-sections.txt $(srcdir)/tmpl/*.sgml $(expand_content_files) - @echo 'gtk-doc: Building XML' - @-chmod -R u+w $(srcdir) - _srcdir="`pwd`/$(DOC_SOURCE_DIR)"; \ - cd $(srcdir) && gtkdoc-mkdb --module=$(DOC_MODULE) --source-dir=$$_srcdir --output-format=xml --expand-content-files="$(expand_content_files)" --main-sgml-file=$(DOC_MAIN_SGML_FILE) $(MKDB_OPTIONS) - touch sgml-build.stamp - -sgml.stamp: sgml-build.stamp - @true - -#### html #### - -html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) - @echo 'gtk-doc: Building HTML' - @-chmod -R u+w $(srcdir) - rm -rf $(srcdir)/html - mkdir $(srcdir)/html - cd $(srcdir)/html && gtkdoc-mkhtml $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE) - test "x$(HTML_IMAGES)" = "x" || ( cd $(srcdir) && cp $(HTML_IMAGES) html ) - @echo 'gtk-doc: Fixing cross-references' - cd $(srcdir) && gtkdoc-fixxref --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS) - touch html-build.stamp - -############## - -clean-local: - rm -f *~ *.bak - rm -rf .libs - -distclean-local: - cd $(srcdir) && \ - rm -rf xml $(REPORT_FILES) \ - $(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt - -maintainer-clean-local: clean - cd $(srcdir) && rm -rf xml html - -install-data-local: - -installfiles=`echo $(srcdir)/html/*`; \ - if test "$$installfiles" = '$(srcdir)/html/*'; \ - then echo '-- Nothing to install' ; \ - else \ - $(mkinstalldirs) $(DESTDIR)$(TARGET_DIR); \ - for i in $$installfiles; do \ - echo '-- Installing '$$i ; \ - $(INSTALL_DATA) $$i $(DESTDIR)$(TARGET_DIR); \ - done; \ - echo '-- Installing $(srcdir)/html/index.sgml' ; \ - $(INSTALL_DATA) $(srcdir)/html/index.sgml $(DESTDIR)$(TARGET_DIR) || :; \ - which gtkdoc-rebase >/dev/null && \ - gtkdoc-rebase --relative --dest-dir=$(DESTDIR) --html-dir=$(DESTDIR)$(TARGET_DIR) ; \ - fi - - -uninstall-local: - rm -f $(DESTDIR)$(TARGET_DIR)/* - -# -# Require gtk-doc when making dist -# -if ENABLE_GTK_DOC -dist-check-gtkdoc: -else -dist-check-gtkdoc: - @echo "*** gtk-doc must be installed (and --enable-gtk-doc) in order to make dist" - @false -endif - -dist-hook: dist-check-gtkdoc dist-hook-local - mkdir $(distdir)/tmpl - mkdir $(distdir)/xml - mkdir $(distdir)/html - -cp $(srcdir)/tmpl/*.sgml $(distdir)/tmpl - -cp $(srcdir)/xml/*.xml $(distdir)/xml - cp $(srcdir)/html/* $(distdir)/html - -cp $(srcdir)/$(DOC_MODULE).types $(distdir)/ - -cp $(srcdir)/$(DOC_MODULE)-sections.txt $(distdir)/ - cd $(distdir) && rm -f $(DISTCLEANFILES) - -gtkdoc-rebase --online --relative --html-dir=$(distdir)/html - -.PHONY : dist-hook-local docs diff --git a/source/libs/cairo/cairo-src/build/Makefile.am.releasing b/source/libs/cairo/cairo-src/build/Makefile.am.releasing deleted file mode 100644 index b17faabce2f5b34d0f0c6015d5b3b7c0219168fe..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/build/Makefile.am.releasing +++ /dev/null @@ -1,194 +0,0 @@ -# Some custom targets to make it easier to release things. -# -# To make real stable releases or devel snapshots, use either: -# make release-check -# or make release-publish -# -# To make a quick properly named (date and git hash stamped) tarball: -# make snapshot - - -TAR_OPTIONS = --owner=0 --group=0 - -dist-hook: dist-clear-sticky-bits - -# Clean up any sticky bits we may inherit from parent dir -dist-clear-sticky-bits: - chmod -R a-s $(distdir) - - -snapshot: - distdir="$(distdir)-`date '+%Y%m%d'`"; \ - test -d "$(srcdir)/.git" && distdir=$$distdir-`cd "$(srcdir)" && git rev-parse HEAD | cut -c 1-6`; \ - TAR_OPTIONS="$(TAR_OPTIONS)" $(MAKE) $(AM_MAKEFLAGS) distdir="$$distdir" snapshot-dist - -snapshot-dist: dist - @(echo "$(distdir) archives ready for distribution: "; \ - list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ - sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' - -RELEASE_OR_SNAPSHOT = $$(if test "x$(CAIRO_VERSION_MINOR)" = "x$$(echo "$(CAIRO_VERSION_MINOR)/2*2" | bc)" ; then echo release; else echo snapshot; fi) -RELEASE_UPLOAD_HOST = cairographics.org -RELEASE_UPLOAD_BASE = /srv/cairo.freedesktop.org/www -RELEASE_UPLOAD_DIR = $(RELEASE_UPLOAD_BASE)/$(RELEASE_OR_SNAPSHOT)s -RELEASE_URL_BASE = http://cairographics.org/$(RELEASE_OR_SNAPSHOT)s -RELEASE_ANNOUNCE_LIST = cairo-announce@cairographics.org (and CC gnome-announce-list@gnome.org) - -MANUAL_VERSIONED = manual-$(VERSION) -MANUAL_TAR_FILE = $(MANUAL_VERSIONED).tar.gz -MANUAL_UPLOAD_DIR = $(RELEASE_UPLOAD_BASE) - -tar_file = $(PACKAGE)-$(VERSION).tar.xz -sha1_file = $(tar_file).sha1 -gpg_file = $(sha1_file).asc - -$(sha1_file): $(tar_file) - sha1sum $^ > $@ - -$(gpg_file): $(sha1_file) - @echo "Please enter your GPG password to sign the checksum." - gpg --armor --sign $^ - -release-verify-sane-changelogs: changelogs - @echo -n "Checking that the ChangeLog files are sane..." - @if grep -q "is required to generate" $(CHANGELOGS); then \ - (echo "Ouch." && echo "Some of the ChangeLogs are not generated correctly." \ - && echo "Remove ChangeLog* and make changelogs" \ - && false); else :; fi - @echo "Good." - -release-verify-sane-tests: - @echo "Checking that the test suite is sane..." - @cd test && $(MAKE) $(AM_MAKEFLAGS) release-verify-sane-tests - -release-verify-even-micro: - @echo -n "Checking that $(VERSION) has an even micro component..." - @test "$(CAIRO_VERSION_MICRO)" = "`echo $(CAIRO_VERSION_MICRO)/2*2 | bc`" \ - || (echo "Ouch." && echo "The version micro component '$(CAIRO_VERSION_MICRO)' is not an even number." \ - && echo "The version in configure.in must be incremented before a new release." \ - && false) - @echo "Good." - -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 checkout?" \ - && echo "This should never happen." \ - && false) - @echo "Good." - -release-remove-old: - $(RM) $(tar_file) $(sha1_file) $(gpg_file) - - -# Strict ordering enforced for parallel make to work -release-check: \ - release-verify-even-micro \ - release-verify-sane-changelogs \ - release-verify-sane-tests \ - release-verify-newer \ - $(NULL) - $(MAKE) $(AM_MAKEFLAGS) release-remove-old - TAR_OPTIONS="$(TAR_OPTIONS)" $(MAKE) $(AM_MAKEFLAGS) distcheck - -release-upload: $(tar_file) $(sha1_file) $(gpg_file) - mkdir -p releases - 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)" - git tag -s -m "cairo $(CAIRO_VERSION_MAJOR).$(CAIRO_VERSION_MINOR).$(CAIRO_VERSION_MICRO) release" $(CAIRO_VERSION_MAJOR).$(CAIRO_VERSION_MINOR).$(CAIRO_VERSION_MICRO) - -release-publish-message: releases/$(sha1_file) - @echo "Please follow the instructions in RELEASING to push stuff out and" - @echo "send out the announcement mails. Here is the excerpt you need:" - @echo "" - @echo "Subject: $(PACKAGE) $(RELEASE_OR_SNAPSHOT) $(VERSION) now available" - @echo "" - @echo "============================== CUT HERE ==============================" - @echo "A new $(PACKAGE) $(RELEASE_OR_SNAPSHOT) $(VERSION) is now available from:" - @echo "" - @echo " $(RELEASE_URL_BASE)/$(tar_file)" - @echo "" - @echo " which can be verified with:" - @echo "" - @echo " $(RELEASE_URL_BASE)/$(sha1_file)" - @echo -n " " - @cat releases/$(sha1_file) - @echo "" - @echo " $(RELEASE_URL_BASE)/$(gpg_file)" - @echo " (signed by `getent passwd "$$USER" | cut -d: -f 5 | cut -d, -f 1`)" - @echo "" - @echo " Additionally, a git clone of the source tree:" - @echo "" - @echo " git clone git://git.cairographics.org/git/cairo" - @echo "" - @echo " will include a signed $(VERSION) tag which points to a commit named:" - @echo " `git cat-file tag $(VERSION) | grep ^object | sed -e 's,object ,,'`" - @echo "" - @echo " which can be verified with:" - @echo " git verify-tag $(VERSION)" - @echo "" - @echo " and can be checked out with a command such as:" - @echo " git checkout -b build $(VERSION)" - @echo "" - @echo "============================== CUT HERE ==============================" - -doc-publish-versioned: doc - rm -rf ./$(MANUAL_VERSIONED) - cp -a doc/public/html $(MANUAL_VERSIONED) - tar czf $(MANUAL_TAR_FILE) $(MANUAL_VERSIONED) - scp $(MANUAL_TAR_FILE) $(RELEASE_UPLOAD_HOST):$(MANUAL_UPLOAD_DIR) - ssh $(RELEASE_UPLOAD_HOST) "cd $(MANUAL_UPLOAD_DIR) && tar xzf $(MANUAL_TAR_FILE) && ln -sf $(MANUAL_TAR_FILE) cairo-$(MANUAL_TAR_FILE)" - -doc-publish-symlinks: - ssh $(RELEASE_UPLOAD_HOST) "cd $(MANUAL_UPLOAD_DIR) && rm -f manual && ln -s $(MANUAL_VERSIONED) manual && ln -sf $(MANUAL_TAR_FILE) cairo-manual.tar.gz" - -doc-publish: - $(MAKE) $(AM_MAKEFLAGS) doc-publish-versioned - @if test "$(RELEASE_OR_SNAPSHOT)" = release; then $(MAKE) $(AM_MAKEFLAGS) doc-publish-symlinks; fi - -# Strict ordering enforced for parallel make to work -release-publish: release-check - $(MAKE) $(AM_MAKEFLAGS) release-upload - $(MAKE) $(AM_MAKEFLAGS) doc-publish - $(MAKE) $(AM_MAKEFLAGS) release-publish-message - -if OS_WIN32 - -# Win32 package zipfiles -runtime_zip_file = $(PACKAGE)-$(VERSION).zip -developer_zip_file = $(PACKAGE)-dev-$(VERSION).zip - -$(runtime_zip_file): install - -$(RM) $@ - pwd=`pwd`; cd $(prefix); \ - zip "$$pwd"/$@ bin/libcairo-$(CAIRO_VERSION_SONUM).dll - -$(developer_zip_file): install - -$(RM) $@ - pwd=`pwd`; cd $(prefix); \ - zip -r "$$pwd"/$@ include/cairo lib/libcairo.dll.a lib/cairo.lib lib/pkgconfig/cairo.pc lib/pkgconfig/cairo-*.pc share/gtk-doc/html/cairo - -zips: $(runtime_zip_file) $(developer_zip_file) - -endif - - -.PHONY: \ - dist-clear-sticky-bits \ - doc-publish \ - doc-publish-symlinks \ - doc-publish-versioned \ - release-check \ - release-publish \ - release-publish-message \ - release-remove-old \ - release-upload \ - release-verify-even-micro \ - release-verify-newer \ - release-verify-sane-changelogs \ - release-verify-sane-tests \ - snapshot \ - snapshot-dist \ - $(NULL) diff --git a/source/libs/cairo/cairo-src/build/Makefile.win32.common b/source/libs/cairo/cairo-src/build/Makefile.win32.common deleted file mode 100644 index 7d7e9735f15d6620d804b6acaa88863f694a993d..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/build/Makefile.win32.common +++ /dev/null @@ -1,74 +0,0 @@ -default: all - -# -# Edit build/Makefile.win32.features to enable features to build -# -include $(top_srcdir)/build/Makefile.win32.inform -include $(top_srcdir)/build/Makefile.win32.features -include $(top_srcdir)/build/Makefile.win32.features-h - -ifeq ($(top_builddir),) -top_builddir = $(top_srcdir) -endif - -CC := cl -LD := link -AR := lib - -ifeq ($(CFG),debug) -CFG_CFLAGS := -MDd -Od -Zi -CFG_LDFLAGS := -DEBUG -else -CFG_CFLAGS := -MD -O2 -CFG_LDFLAGS := -endif - -ifeq ($(PIXMAN_PATH),) -PIXMAN_PATH := $(top_builddir)/../pixman -endif -PIXMAN_CFLAGS := -I$(PIXMAN_PATH)/pixman/ -PIXMAN_LIBS := $(PIXMAN_PATH)/pixman/$(CFG)/pixman-1.lib - -CAIRO_LIBS = gdi32.lib msimg32.lib user32.lib - -ifeq ($(CAIRO_HAS_PNG_FUNCTIONS),1) -ifeq ($(LIBPNG_PATH),) -LIBPNG_PATH := $(top_builddir)/../libpng -endif -LIBPNG_CFLAGS += -I$(LIBPNG_PATH)/ -CAIRO_LIBS += $(LIBPNG_PATH)/libpng.lib -endif - -ifeq ($(CAIRO_HAS_PS_SURFACE)$(CAIRO_HAS_PDF_SURFACE),00) -else -ifeq ($(ZLIB_PATH),) -ZLIB_PATH := $(top_builddir)/../zlib -endif -ZLIB_CFLAGS += -I$(ZLIB_PATH)/ -CAIRO_LIBS += $(ZLIB_PATH)/zdll.lib -endif - -DEFAULT_CFLAGS = -nologo $(CFG_CFLAGS) -DEFAULT_CFLAGS += -I. -I$(top_srcdir) -I$(top_srcdir)/src -DEFAULT_CFLAGS += $(PIXMAN_CFLAGS) $(LIBPNG_CFLAGS) $(ZLIB_CFLAGS) - -CAIRO_CFLAGS = $(DEFAULT_CFLAGS) $(CFLAGS) - -DEFAULT_LDFLAGS = -nologo $(CFG_LDFLAGS) -DEFAULT_ARFLAGS = -nologo - -CAIRO_LDFLAGS = $(DEFAULT_LDFLAGS) $(LDFLAGS) -CAIRO_ARFLAGS = $(DEFAULT_ARFLAGS) $(LDFLAGS) - -# Some generic rules - -$(CFG)/%.obj: %.c $(top_srcdir)/src/cairo-features.h - @mkdir -p $(CFG)/`dirname $<` - @$(CC) $(CAIRO_CFLAGS) -c -Fo"$@" $< - -$(CFG)/%-static.obj: %.c $(top_srcdir)/src/cairo-features.h - @mkdir -p $(CFG)/`dirname $<` - @$(CC) $(CAIRO_CFLAGS) -c -DCAIRO_WIN32_STATIC_BUILD=1 -Fo"$@" $< - -clean: - @rm -f $(CFG)/*.obj $(CFG)/*.dll $(CFG)/*.lib $(CFG)/*.pdb $(CFG)/*.ilk || exit 0 diff --git a/source/libs/cairo/cairo-src/build/Makefile.win32.features b/source/libs/cairo/cairo-src/build/Makefile.win32.features deleted file mode 100644 index 8cb155dc0847fa86ee4eb44cc49e45abaf8a1f0a..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/build/Makefile.win32.features +++ /dev/null @@ -1,41 +0,0 @@ -# Generated by configure. Modify to customize. - -CAIRO_HAS_XLIB_SURFACE=0 -CAIRO_HAS_XLIB_XRENDER_SURFACE=0 -CAIRO_HAS_XCB_SURFACE=0 -CAIRO_HAS_XLIB_XCB_FUNCTIONS=0 -CAIRO_HAS_XCB_SHM_FUNCTIONS=0 -CAIRO_HAS_QT_SURFACE=0 -CAIRO_HAS_QUARTZ_SURFACE=0 -CAIRO_HAS_QUARTZ_FONT=0 -CAIRO_HAS_QUARTZ_IMAGE_SURFACE=0 -CAIRO_HAS_WIN32_SURFACE=1 -CAIRO_HAS_WIN32_FONT=1 -CAIRO_HAS_SKIA_SURFACE=0 -CAIRO_HAS_OS2_SURFACE=0 -CAIRO_HAS_BEOS_SURFACE=0 -CAIRO_HAS_DRM_SURFACE=0 -CAIRO_HAS_GALLIUM_SURFACE=0 -CAIRO_HAS_PNG_FUNCTIONS=1 -CAIRO_HAS_GL_SURFACE=0 -CAIRO_HAS_GLESV2_SURFACE=0 -CAIRO_HAS_COGL_SURFACE=0 -CAIRO_HAS_DIRECTFB_SURFACE=0 -CAIRO_HAS_VG_SURFACE=0 -CAIRO_HAS_EGL_FUNCTIONS=0 -CAIRO_HAS_GLX_FUNCTIONS=0 -CAIRO_HAS_WGL_FUNCTIONS=0 -CAIRO_HAS_SCRIPT_SURFACE=1 -CAIRO_HAS_FT_FONT=0 -CAIRO_HAS_FC_FONT=0 -CAIRO_HAS_PS_SURFACE=1 -CAIRO_HAS_PDF_SURFACE=1 -CAIRO_HAS_SVG_SURFACE=1 -CAIRO_HAS_TEST_SURFACES=0 -CAIRO_HAS_TEE_SURFACE=0 -CAIRO_HAS_XML_SURFACE=0 -CAIRO_HAS_PTHREAD=0 -CAIRO_HAS_GOBJECT_FUNCTIONS=0 -CAIRO_HAS_TRACE=0 -CAIRO_HAS_INTERPRETER=1 -CAIRO_HAS_SYMBOL_LOOKUP=0 diff --git a/source/libs/cairo/cairo-src/build/Makefile.win32.features-h b/source/libs/cairo/cairo-src/build/Makefile.win32.features-h deleted file mode 100644 index 13904cfa9f0287e3c45f3d6c4a28003d4258da91..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/build/Makefile.win32.features-h +++ /dev/null @@ -1,130 +0,0 @@ -# Generated by configure. Do not edit. - -$(top_srcdir)/src/cairo-features.h: $(top_srcdir)/build/Makefile.win32.features - @echo "Generating src/cairo-features.h" - @echo "/* Generated by Makefile.win32.features-h. Do not edit. */" > $(top_srcdir)/src/cairo-features.h - @echo "#ifndef CAIRO_FEATURES_H" >> $(top_srcdir)/src/cairo-features.h - @echo "#define CAIRO_FEATURES_H 1" >> $(top_srcdir)/src/cairo-features.h -ifeq ($(CAIRO_HAS_XLIB_SURFACE),1) - @echo "#define CAIRO_HAS_XLIB_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_XLIB_XRENDER_SURFACE),1) - @echo "#define CAIRO_HAS_XLIB_XRENDER_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_XCB_SURFACE),1) - @echo "#define CAIRO_HAS_XCB_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_XLIB_XCB_FUNCTIONS),1) - @echo "#define CAIRO_HAS_XLIB_XCB_FUNCTIONS 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_XCB_SHM_FUNCTIONS),1) - @echo "#define CAIRO_HAS_XCB_SHM_FUNCTIONS 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_QT_SURFACE),1) - @echo "#define CAIRO_HAS_QT_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_QUARTZ_SURFACE),1) - @echo "#define CAIRO_HAS_QUARTZ_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_QUARTZ_FONT),1) - @echo "#define CAIRO_HAS_QUARTZ_FONT 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_QUARTZ_IMAGE_SURFACE),1) - @echo "#define CAIRO_HAS_QUARTZ_IMAGE_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_WIN32_SURFACE),1) - @echo "#define CAIRO_HAS_WIN32_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_WIN32_FONT),1) - @echo "#define CAIRO_HAS_WIN32_FONT 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_SKIA_SURFACE),1) - @echo "#define CAIRO_HAS_SKIA_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_OS2_SURFACE),1) - @echo "#define CAIRO_HAS_OS2_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_BEOS_SURFACE),1) - @echo "#define CAIRO_HAS_BEOS_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_DRM_SURFACE),1) - @echo "#define CAIRO_HAS_DRM_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_GALLIUM_SURFACE),1) - @echo "#define CAIRO_HAS_GALLIUM_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_PNG_FUNCTIONS),1) - @echo "#define CAIRO_HAS_PNG_FUNCTIONS 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_GL_SURFACE),1) - @echo "#define CAIRO_HAS_GL_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_GLESV2_SURFACE),1) - @echo "#define CAIRO_HAS_GLESV2_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_COGL_SURFACE),1) - @echo "#define CAIRO_HAS_COGL_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_DIRECTFB_SURFACE),1) - @echo "#define CAIRO_HAS_DIRECTFB_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_VG_SURFACE),1) - @echo "#define CAIRO_HAS_VG_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_EGL_FUNCTIONS),1) - @echo "#define CAIRO_HAS_EGL_FUNCTIONS 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_GLX_FUNCTIONS),1) - @echo "#define CAIRO_HAS_GLX_FUNCTIONS 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_WGL_FUNCTIONS),1) - @echo "#define CAIRO_HAS_WGL_FUNCTIONS 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_SCRIPT_SURFACE),1) - @echo "#define CAIRO_HAS_SCRIPT_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_FT_FONT),1) - @echo "#define CAIRO_HAS_FT_FONT 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_FC_FONT),1) - @echo "#define CAIRO_HAS_FC_FONT 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_PS_SURFACE),1) - @echo "#define CAIRO_HAS_PS_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_PDF_SURFACE),1) - @echo "#define CAIRO_HAS_PDF_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_SVG_SURFACE),1) - @echo "#define CAIRO_HAS_SVG_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_TEST_SURFACES),1) - @echo "#define CAIRO_HAS_TEST_SURFACES 1" >> $(top_srcdir)/src/cairo-features.h -endif - @echo "#define CAIRO_HAS_IMAGE_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h - @echo "#define CAIRO_HAS_MIME_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h - @echo "#define CAIRO_HAS_RECORDING_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h - @echo "#define CAIRO_HAS_OBSERVER_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h -ifeq ($(CAIRO_HAS_TEE_SURFACE),1) - @echo "#define CAIRO_HAS_TEE_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_XML_SURFACE),1) - @echo "#define CAIRO_HAS_XML_SURFACE 1" >> $(top_srcdir)/src/cairo-features.h -endif - @echo "#define CAIRO_HAS_USER_FONT 1" >> $(top_srcdir)/src/cairo-features.h -ifeq ($(CAIRO_HAS_PTHREAD),1) - @echo "#define CAIRO_HAS_PTHREAD 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_GOBJECT_FUNCTIONS),1) - @echo "#define CAIRO_HAS_GOBJECT_FUNCTIONS 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_TRACE),1) - @echo "#define CAIRO_HAS_TRACE 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_INTERPRETER),1) - @echo "#define CAIRO_HAS_INTERPRETER 1" >> $(top_srcdir)/src/cairo-features.h -endif -ifeq ($(CAIRO_HAS_SYMBOL_LOOKUP),1) - @echo "#define CAIRO_HAS_SYMBOL_LOOKUP 1" >> $(top_srcdir)/src/cairo-features.h -endif - @echo "#endif" >> $(top_srcdir)/src/cairo-features.h diff --git a/source/libs/cairo/cairo-src/build/Makefile.win32.inform b/source/libs/cairo/cairo-src/build/Makefile.win32.inform deleted file mode 100644 index ba11165050a06574eec927a97393b378666674f5..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/build/Makefile.win32.inform +++ /dev/null @@ -1,13 +0,0 @@ -inform: - @echo -ifneq ($(CFG),release) -ifneq ($(CFG),debug) - @echo "Invalid configuration "$(CFG)" specified." - @echo -n "You must specify a configuration when " - @echo "running make, e.g. make CFG=debug" - @echo - @echo -n "Possible choices for configuration are " - @echo "'release' and 'debug'" - @exit 1 -endif -endif diff --git a/source/libs/cairo/cairo-src/build/aclocal.cairo.m4 b/source/libs/cairo/cairo-src/build/aclocal.cairo.m4 deleted file mode 100644 index 44ba5fdf6f5d092db87db4c94325930673f522ff..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/build/aclocal.cairo.m4 +++ /dev/null @@ -1,228 +0,0 @@ -dnl ========================================================================== -dnl -dnl Cairo-specific macros -dnl - -dnl ========================================================================== - -dnl Usage: -dnl CAIRO_BIGENDIAN -dnl -AC_DEFUN([CAIRO_BIGENDIAN], -[dnl - case $host_os in - darwin*) - AH_VERBATIM([X_BYTE_ORDER], -[ -/* Deal with multiple architecture compiles on Mac OS X */ -#ifdef __APPLE_CC__ -#ifdef __BIG_ENDIAN__ -#define WORDS_BIGENDIAN 1 -#define FLOAT_WORDS_BIGENDIAN 1 -#else -#undef WORDS_BIGENDIAN -#undef FLOAT_WORDS_BIGENDIAN -#endif -#endif -]) - ;; - *) - AC_C_BIGENDIAN - AX_C_FLOAT_WORDS_BIGENDIAN - ;; - esac -]) - -dnl CAIRO_CHECK_FUNCS_WITH_FLAGS(FUNCTION..., CFLAGS, LIBS -dnl [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) -dnl Like AC_CHECK_FUNCS but with additional CFLAGS and LIBS -dnl -------------------------------------------------------------------- -AC_DEFUN([CAIRO_CHECK_FUNCS_WITH_FLAGS], -[dnl - _save_cflags="$CFLAGS" - _save_libs="$LIBS" - CFLAGS="$CFLAGS $2" - LIBS="$LIBS $3" - AC_CHECK_FUNCS($1, $4, $5) - CFLAGS="$_save_cflags" - LIBS="$_save_libs" -]) - -dnl CAIRO_CONFIG_COMMANDS is like AC_CONFIG_COMMANDS, except that: -dnl -dnl 1) It redirects the stdout of the command to the file. -dnl 2) It does not recreate the file if contents didn't change. -dnl -AC_DEFUN([CAIRO_CONFIG_COMMANDS], -[dnl - AC_CONFIG_COMMANDS($1, - [ - _config_file=$1 - _tmp_file=cairoconf.tmp - AC_MSG_NOTICE([creating $_config_file]) - { - $2 - } >> "$_tmp_file" || - AC_MSG_ERROR([failed to write to $_tmp_file]) - - if cmp -s "$_tmp_file" "$_config_file"; then - AC_MSG_NOTICE([$_config_file is unchanged]) - rm -f "$_tmp_file" - else - mv "$_tmp_file" "$_config_file" || - AC_MSG_ERROR([failed to update $_config_file]) - fi - ], $3) -]) - -dnl CAIRO_CC_TRY_LINK_WITH_ENV_SILENT(env-setup, program, -dnl true-action, false-action) -dnl -dnl Compile and link the program with the given environment setup. -dnl The global cairo_cc_flag is set to "yes" or "no" according as -dnl the link succeeded or not. The link step must complete without -dnl warnings or errors to stderr. -dnl -dnl Perform true-action on success and false-action on failure. -dnl The values of CFLAGS, LIBS, LDFLAGS are saved before env-setup -dnl is executed and restored right before the end of the macro. -AC_DEFUN([CAIRO_CC_TRY_LINK_WITH_ENV_SILENT],[dnl - # AC_LANG_PROGRAM() produces a main() w/o args, - # but -Wold-style-definition doesn't like that. - # We need _some_ program so that we don't get - # warnings about empty compilation units, so always - # append a reasonable main(). - _compile_program="$2"' - int main(int c, char **v) { (void)c; (void)v; return 0; }' - - _save_cflags="$CFLAGS" - _save_ldflags="$LDFLAGS" - _save_libs="$LIBS" - $1 - AC_LINK_IFELSE( - [AC_LANG_SOURCE([$_compile_program])], - [cairo_cc_stderr=`test -f conftest.err && cat conftest.err` - cairo_cc_flag=yes], - [cairo_cc_stderr=`test -f conftest.err && cat conftest.err` - cairo_cc_flag=no]) - - if test "x$cairo_cc_stderr" != "x"; then - cairo_cc_flag=no - fi - - if test "x$cairo_cc_flag" = "xyes"; then - ifelse([$3], , :, [$3]) - else - ifelse([$4], , :, [$4]) - fi - CFLAGS="$_save_cflags" - LDFLAGS="$_save_ldflags" - LIBS="$_save_libs" -]) - -dnl check compiler flags with a program and no muttering. -AC_DEFUN([CAIRO_CC_TRY_FLAG_SILENT], -[dnl (flags..., optional program, true-action, false-action) - CAIRO_CC_TRY_LINK_WITH_ENV_SILENT([CFLAGS="$CFLAGS $1"], - [$2], [$3], [$4]) -]) - -dnl find a -Werror equivalent -AC_DEFUN([CAIRO_CC_CHECK_WERROR], -[dnl - _test_WERROR=${WERROR+set} - if test "z$_test_WERROR" != zset; then - WERROR="" - for _werror in -Werror -errwarn; do - AC_MSG_CHECKING([whether $CC supports $_werror]) - CAIRO_CC_TRY_FLAG_SILENT( - [$_werror],, - [WERROR="$WERROR $_werror"], - [:]) - AC_MSG_RESULT($cairo_cc_flag) - done - fi -]) - -dnl check compiler flags possibly using -Werror if available. -AC_DEFUN([CAIRO_CC_TRY_FLAG], -[dnl (flags..., optional program, true-action, false-action) - CAIRO_CC_CHECK_WERROR - AC_MSG_CHECKING([whether $CC supports $1]) - CAIRO_CC_TRY_FLAG_SILENT([$WERROR $1], [$2], [$3], [$4]) - AC_MSG_RESULT([$cairo_cc_flag]) -]) - -dnl Usage: -dnl CAIRO_CHECK_NATIVE_ATOMIC_PRIMITIVES -AC_DEFUN([CAIRO_CHECK_NATIVE_ATOMIC_PRIMITIVES], -[dnl - AC_CACHE_CHECK([for native atomic primitives], cairo_cv_atomic_primitives, - [ - cairo_cv_atomic_primitives="none" - - AC_TRY_LINK([ -int atomic_add(int i) { return __sync_fetch_and_add (&i, 1); } -int atomic_cmpxchg(int i, int j, int k) { return __sync_val_compare_and_swap (&i, j, k); } -], [], - cairo_cv_atomic_primitives="Intel" - ) - - AC_TRY_LINK([ -int atomic_add(int i) { return __atomic_fetch_add(&i, 1, __ATOMIC_SEQ_CST); } -int atomic_cmpxchg(int i, int j, int k) { return __atomic_compare_exchange_n(&i, &j, k, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); } -], [], - cairo_cv_atomic_primitives="cxx11" - ) - - if test "x$cairo_cv_atomic_primitives" = "xnone"; then - AC_CHECK_HEADER([atomic_ops.h], - cairo_cv_atomic_primitives="libatomic-ops") - fi - - if test "x$cairo_cv_atomic_primitives" = "xnone"; then - AC_CHECK_HEADER([libkern/OSAtomic.h], - cairo_cv_atomic_primitives="OSAtomic") - fi - ]) - if test "x$cairo_cv_atomic_primitives" = xcxx11; then - AC_DEFINE(HAVE_CXX11_ATOMIC_PRIMITIVES, 1, - [Enable if your compiler supports the GCC __atomic_* atomic primitives]) - fi - - if test "x$cairo_cv_atomic_primitives" = xIntel; then - AC_DEFINE(HAVE_INTEL_ATOMIC_PRIMITIVES, 1, - [Enable if your compiler supports the Intel __sync_* atomic primitives]) - fi - - if test "x$cairo_cv_atomic_primitives" = "xlibatomic-ops"; then - AC_DEFINE(HAVE_LIB_ATOMIC_OPS, 1, - [Enable if you have libatomic-ops-dev installed]) - fi - - if test "x$cairo_cv_atomic_primitives" = xOSAtomic; then - AC_DEFINE(HAVE_OS_ATOMIC_OPS, 1, - [Enable if you have MacOS X atomic operations]) - fi -]) - -dnl Usage: -dnl CAIRO_CHECK_ATOMIC_OP_NEEDS_MEMORY_BARRIER -AC_DEFUN([CAIRO_CHECK_ATOMIC_OP_NEEDS_MEMORY_BARRIER], -[dnl - AC_CACHE_CHECK([whether atomic ops require a memory barrier], cairo_cv_atomic_op_needs_memory_barrier, - [ - case $host_cpu in - i?86) cairo_cv_atomic_op_needs_memory_barrier="no" ;; - x86_64) cairo_cv_atomic_op_needs_memory_barrier="no" ;; - arm*) cairo_cv_atomic_op_needs_memory_barrier="no" ;; - *) cairo_cv_atomic_op_needs_memory_barrier="yes" ;; - esac - ]) - if test "x$cairo_cv_atomic_op_needs_memory_barrier" = "xyes"; then - AC_DEFINE_UNQUOTED(ATOMIC_OP_NEEDS_MEMORY_BARRIER, 1, - [whether memory barriers are needed around atomic operations]) - fi -]) - -AC_DEFUN([CAIRO_TEXT_WRAP], [m4_text_wrap([$1], [$2],, 78)]) diff --git a/source/libs/cairo/cairo-src/build/aclocal.compare.m4 b/source/libs/cairo/cairo-src/build/aclocal.compare.m4 deleted file mode 100644 index bd6c51b289dcfe2b384d06006eb5183036cf0cab..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/build/aclocal.compare.m4 +++ /dev/null @@ -1,162 +0,0 @@ -dnl @synopsis AX_COMPARE_VERSION(VERSION_A, OP, VERSION_B, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) -dnl -dnl This macro compares two version strings. It is used heavily in the -dnl macro _AX_PATH_BDB for library checking. Due to the various number -dnl of minor-version numbers that can exist, and the fact that string -dnl comparisons are not compatible with numeric comparisons, this is -dnl not necessarily trivial to do in a autoconf script. This macro -dnl makes doing these comparisons easy. -dnl -dnl The six basic comparisons are available, as well as checking -dnl equality limited to a certain number of minor-version levels. -dnl -dnl The operator OP determines what type of comparison to do, and can -dnl be one of: -dnl -dnl eq - equal (test A == B) -dnl ne - not equal (test A != B) -dnl le - less than or equal (test A <= B) -dnl ge - greater than or equal (test A >= B) -dnl lt - less than (test A < B) -dnl gt - greater than (test A > B) -dnl -dnl Additionally, the eq and ne operator can have a number after it to -dnl limit the test to that number of minor versions. -dnl -dnl eq0 - equal up to the length of the shorter version -dnl ne0 - not equal up to the length of the shorter version -dnl eqN - equal up to N sub-version levels -dnl neN - not equal up to N sub-version levels -dnl -dnl When the condition is true, shell commands ACTION-IF-TRUE are run, -dnl otherwise shell commands ACTION-IF-FALSE are run. The environment -dnl variable 'ax_compare_version' is always set to either 'true' or -dnl 'false' as well. -dnl -dnl Examples: -dnl -dnl AX_COMPARE_VERSION([3.15.7],[lt],[3.15.8]) -dnl AX_COMPARE_VERSION([3.15],[lt],[3.15.8]) -dnl -dnl would both be true. -dnl -dnl AX_COMPARE_VERSION([3.15.7],[eq],[3.15.8]) -dnl AX_COMPARE_VERSION([3.15],[gt],[3.15.8]) -dnl -dnl would both be false. -dnl -dnl AX_COMPARE_VERSION([3.15.7],[eq2],[3.15.8]) -dnl -dnl would be true because it is only comparing two minor versions. -dnl -dnl AX_COMPARE_VERSION([3.15.7],[eq0],[3.15]) -dnl -dnl would be true because it is only comparing the lesser number of -dnl minor versions of the two values. -dnl -dnl Note: The characters that separate the version numbers do not -dnl matter. An empty string is the same as version 0. OP is evaluated -dnl by autoconf, not configure, so must be a string, not a variable. -dnl -dnl The author would like to acknowledge Guido Draheim whose advice -dnl about the m4_case and m4_ifvaln functions make this macro only -dnl include the portions necessary to perform the specific comparison -dnl specified by the OP argument in the final configure script. -dnl -dnl @category Misc -dnl @author Tim Toolan <toolan@ele.uri.edu> -dnl @version 2004-03-01 -dnl @license GPLWithACException - -dnl ######################################################################### -AC_DEFUN([AX_COMPARE_VERSION], [ - # Used to indicate true or false condition - ax_compare_version=false - - # Convert the two version strings to be compared into a format that - # allows a simple string comparison. The end result is that a version - # string of the form 1.12.5-r617 will be converted to the form - # 0001001200050617. In other words, each number is zero padded to four - # digits, and non digits are removed. - AS_VAR_PUSHDEF([A],[ax_compare_version_A]) - A=`echo "$1" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \ - -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \ - -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \ - -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \ - -e 's/[[^0-9]]//g'` - - AS_VAR_PUSHDEF([B],[ax_compare_version_B]) - B=`echo "$3" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \ - -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \ - -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \ - -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \ - -e 's/[[^0-9]]//g'` - - dnl # In the case of le, ge, lt, and gt, the strings are sorted as necessary - dnl # then the first line is used to determine if the condition is true. - dnl # The sed right after the echo is to remove any indented white space. - m4_case(m4_tolower($2), - [lt],[ - ax_compare_version=`echo "x$A -x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/false/;s/x${B}/true/;1q"` - ], - [gt],[ - ax_compare_version=`echo "x$A -x$B" | sed 's/^ *//' | sort | sed "s/x${A}/false/;s/x${B}/true/;1q"` - ], - [le],[ - ax_compare_version=`echo "x$A -x$B" | sed 's/^ *//' | sort | sed "s/x${A}/true/;s/x${B}/false/;1q"` - ], - [ge],[ - ax_compare_version=`echo "x$A -x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/true/;s/x${B}/false/;1q"` - ],[ - dnl Split the operator from the subversion count if present. - m4_bmatch(m4_substr($2,2), - [0],[ - # A count of zero means use the length of the shorter version. - # Determine the number of characters in A and B. - ax_compare_version_len_A=`echo "$A" | awk '{print(length)}'` - ax_compare_version_len_B=`echo "$B" | awk '{print(length)}'` - - # Set A to no more than B's length and B to no more than A's length. - A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"` - B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"` - ], - [[0-9]+],[ - # A count greater than zero means use only that many subversions - A=`echo "$A" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"` - B=`echo "$B" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"` - ], - [.+],[ - AC_WARNING( - [illegal OP numeric parameter: $2]) - ],[]) - - # Pad zeros at end of numbers to make same length. - ax_compare_version_tmp_A="$A`echo $B | sed 's/./0/g'`" - B="$B`echo $A | sed 's/./0/g'`" - A="$ax_compare_version_tmp_A" - - # Check for equality or inequality as necessary. - m4_case(m4_tolower(m4_substr($2,0,2)), - [eq],[ - test "x$A" = "x$B" && ax_compare_version=true - ], - [ne],[ - test "x$A" != "x$B" && ax_compare_version=true - ],[ - AC_WARNING([illegal OP parameter: $2]) - ]) - ]) - - AS_VAR_POPDEF([A])dnl - AS_VAR_POPDEF([B])dnl - - dnl # Execute ACTION-IF-TRUE / ACTION-IF-FALSE. - if test "$ax_compare_version" = "true" ; then - m4_ifvaln([$4],[$4],[:])dnl - m4_ifvaln([$5],[else $5])dnl - fi -]) dnl AX_COMPARE_VERSION diff --git a/source/libs/cairo/cairo-src/build/aclocal.enable.m4 b/source/libs/cairo/cairo-src/build/aclocal.enable.m4 deleted file mode 100644 index f3522b9832cc75a33b911bf77bd10ada301a4baa..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/build/aclocal.enable.m4 +++ /dev/null @@ -1,409 +0,0 @@ -dnl -dnl These are the facilities for enable/disabling various features, -dnl and for collecting CFLAGS/LIBS and generating per feature .pc -dnl files, assembling list of source files to compile, creating -dnl cairo-features.h and other generated files, etc... -dnl - -dnl =========================================================================== - -dnl -dnl Define a macro to enable features -dnl - Macro: _CAIRO_ENABLE (ID, NAME, WHAT, DEFAULT, COMMANDS) -dnl -dnl where: -dnl -dnl ID is the sub-namespace in function names, eg. "ft" for cairo_ft_... -dnl NAME is the human-readable name of the feature, eg. "FreeType font" -dnl WHAT is the type of feature: -dnl "surface" for surface backends -dnl "font" for font backends -dnl "functions" for set of functions -dnl "" for private configurations -dnl DEFAULT is the default state of the feature: -dnl "no" for experimental features, eg. your favorite new backend -dnl "yes" for recommended features, eg. png functions -dnl "auto" for other supported features, eg. xlib surface backend -dnl "always" for mandatory features (can't be disabled), eg. image surface backend -dnl COMMANDS are run to check whether the feature can be enabled. -dnl They should set use_$(ID) to something other than yes if the -dnl feature cannot be built, eg. "no (requires SomeThing)". It then -dnl should also set $(ID)_REQUIRES/CFLAGS/LIBS/... -dnl appropriately. Look at the macro definition for more details, -dnl or ask if in doubt. -dnl -AC_DEFUN([_CAIRO_ENABLE], -[dnl - dnl Sanity check ID - m4_if( - [$1], - m4_tolower(AS_TR_SH([$1])), - , - [m4_fatal([invalid feature name `$1'])] - )dnl - m4_pushdef([cr_feature], [$1])dnl - m4_pushdef([cr_feature_name], m4_normalize([$2]))dnl - m4_pushdef([cr_feature_what], m4_normalize([$3]))dnl - m4_pushdef([cr_feature_default], m4_normalize([$4]))dnl - m4_pushdef([cr_feature_commands], [$5])dnl - dnl - m4_pushdef([cr_feature_arg], m4_translit([$1],_,-))dnl - dnl - dnl Sanity check default - m4_case( - cr_feature_default, - [no],, - [yes],, - [auto],, - [always],, - [m4_fatal([Invalid default value `]cr_feature_default[' for feature `]cr_feature['])] - )dnl - dnl - m4_if(cr_feature_default, [always], - [dnl - enable_$1=yes - ],[dnl - AC_ARG_ENABLE(cr_feature_arg, - AS_HELP_STRING([--enable-]cr_feature_arg[=@<:@no/auto/yes@:>@], - [Enable cairo's ]cr_feature_name[ feature @<:@default=]cr_feature_default[@:>@]), - enable_$1=$enableval, enable_$1=cr_feature_default) - ])dnl - dnl - AS_CASE([$enable_$1], - [no],[dnl - use_$1="no (disabled, use --enable-cr_feature_arg to enable)" - ],dnl - [yes|auto],[dnl - AC_MSG_CHECKING([for cairo's ]cr_feature_name[ feature]) - echo - - use_[]$1=yes - CAIRO_FEATURE_VARS_FOREACH(cr_var, [cr_feature[_]cr_var[=]_CAIRO_SH_ESCAPE_UNQUOTED(m4_do([cr_var_default_]cr_var[_value]))]m4_newline) - - cr_feature_commands - - AC_MSG_CHECKING([whether cairo's ]cr_feature_name[ feature could be enabled]) - AC_MSG_RESULT([$use_$1]) - - AS_IF([test "x$enable_$1" = "xyes" -a "x$use_$1" != xyes], - [dnl - AC_MSG_ERROR( - m4_case(cr_feature_default, - [always], [mandatory], - [yes], [recommended], - , [requested] - ) cr_feature_name[ feature could not be enabled]) - ])dnl - ],dnl - [dnl - AC_MSG_ERROR([invalid argument passed to --enable-]cr_feature_arg[: `$use_$1', should be one of @<:@no/auto/yes@:>@]) - ])dnl - - AS_IF([test "x$use_$1" = "xyes"], - [dnl - CAIRO_ACCUMULATED_FEATURE_VARS_FOREACH([cr_var], - [dnl - CAIRO_ACCUMULATE_UNQUOTED_BEFORE(cr_var, [$]cr_feature[_]cr_var) - ])dnl - ],[dnl - dnl If not enabled, empty the vars so no one accidentally uses them. - CAIRO_FEATURE_VARS_FOREACH([cr_var], [unset cr_feature[_]cr_var]m4_newline) - ])dnl - - _CAIRO_FEATURE_HOOKS(cr_feature, cr_feature_name, cr_feature_default, cr_feature_what)dnl - - m4_popdef([cr_feature])dnl - m4_popdef([cr_feature_name])dnl - m4_popdef([cr_feature_what])dnl - m4_popdef([cr_feature_default])dnl - m4_popdef([cr_feature_commands])dnl - m4_popdef([cr_feature_arg])dnl -]) - - -dnl =========================================================================== - -m4_define([_CAIRO_FEATURE_VARS]) - -dnl -dnl CAIRO_FEATURE_VARS_REGISTER(VARS, DEFAULT-VALUE=[]) -dnl -dnl Registers variables to be collected from feature-enabling code segments. -dnl VARS should be a whitespace-separate list of variable names. -dnl -dnl DEFAULT-VALUE is m4 macros to set default value of VARS -dnl -AC_DEFUN([CAIRO_FEATURE_VARS_REGISTER], -[dnl - m4_foreach_w([cr_var], [$1], - [m4_append_uniq([_CAIRO_FEATURE_VARS], cr_var, [ ],, - [m4_fatal([Feature variable `]cr_var[' already registered])])])dnl - m4_foreach_w([cr_var], [$1], - [dnl - m4_define([cr_var_default_]cr_var[_value], m4_default([$2],[[$ac_env_[]]cr_feature[[]_]]cr_var[[_value]]))dnl - ])dnl -]) - -dnl -dnl CAIRO_FEATURE_VARS_FOREACH(VAR, COMMANDS) -dnl -dnl Run COMMANDS for each registered feature variable. -dnl Defines VAR to the variable being processed. -dnl -AC_DEFUN([CAIRO_FEATURE_VARS_FOREACH], -[dnl - m4_foreach_w([$1], _CAIRO_FEATURE_VARS, [$2])dnl -]) - - -dnl =========================================================================== - -m4_define([_CAIRO_ACCUMULATORS])dnl - -m4_define([_CAIRO_ACCUMULATORS_REGISTER], -[dnl - m4_foreach_w([cr_var], [$1], - [m4_append_uniq([_CAIRO_ACCUMULATORS], cr_var, [ ],, - [m4_fatal([Accumulator `]cr_var[' already registered])])])dnl - m4_foreach_w([cr_var], [$1], [m4_define([cr_acc_]cr_var[_sep], [$2])])dnl - m4_foreach_w([cr_var], [$1], [[CAIRO_]cr_var[=$3]]m4_newline)dnl - m4_foreach_w([cr_var], [$1], [m4_pattern_allow([CAIRO_]cr_var)])dnl -])dnl - -m4_define([_CAIRO_SH_ESCAPE],['m4_bpatsubst([$1],['],[\\'])'])dnl -m4_define([_CAIRO_SH_ESCAPE_UNQUOTED],["m4_bpatsubst([$1],["],[\\"])"])dnl - -dnl -dnl CAIRO_ACCUMULATORS_REGISTER(VARS, SEPARATOR=[], INITIAL-VALUE=[]) -dnl -dnl Registers accumulators. An accumulator is a shell variable that can -dnl be accumulated to. The macros take care of adding a SEPARATOR between -dnl accumulated values. -dnl -dnl VARS should be a whitespace-separate list of variable names. The actual -dnl shell variable resulting for each variable is prefixed with CAIRO_. -dnl -AC_DEFUN([CAIRO_ACCUMULATORS_REGISTER], -[dnl - _CAIRO_ACCUMULATORS_REGISTER([$1],[$2],_CAIRO_SH_ESCAPE([$3]))dnl -])dnl - -dnl -dnl Like CAIRO_ACCUMULATORS_REGISTER but INITIAL-VALUE is left unquoted, -dnl so it can reference other shell variables for example. -dnl -AC_DEFUN([CAIRO_ACCUMULATORS_REGISTER_UNQUOTED], -[dnl - _CAIRO_ACCUMULATORS_REGISTER([$1],[$2],_CAIRO_SH_ESCAPE_UNQUOTED([$3]))dnl -])dnl - -m4_define([_CAIRO_ACCUMULATOR_CHECK], -[dnl - m4_ifdef([cr_acc_$1_sep],,[m4_fatal([Accumulator `]$1[' not defined.])])dnl -])dnl - -m4_define([_CAIRO_ACCUMULATE], -[dnl - _CAIRO_ACCUMULATOR_CHECK([$1])dnl - m4_ifval([$2], [$3]m4_newline)dnl -])dnl - -dnl -dnl CAIRO_ACCUMULATE(VAR, VALUE) -dnl -dnl Appends VALUE to accumulator VAR -dnl -AC_DEFUN([CAIRO_ACCUMULATE], -[dnl - _CAIRO_ACCUMULATE([$1], [$2], [CAIRO_$1="${CAIRO_$1}]m4_do([cr_acc_$1_sep])["_CAIRO_SH_ESCAPE([$2])])dnl -])dnl - -dnl -dnl CAIRO_ACCUMULATE_BEFORE(VAR, VALUE) -dnl -dnl Prepends VALUE to accumulator VAR -dnl -AC_DEFUN([CAIRO_ACCUMULATE_BEFORE], -[dnl - _CAIRO_ACCUMULATE([$1], [$2], [CAIRO_$1=_CAIRO_SH_ESCAPE([$2])"]m4_do([cr_acc_$1_sep])[${CAIRO_$1}"])dnl -])dnl - -m4_define([_CAIRO_ACCUMULATE_UNQUOTED], -[dnl - _CAIRO_ACCUMULATOR_CHECK([$1])dnl - m4_ifval([$2], [m4_bmatch([$2],[[$]],[test -n "$2" &&]) $3]m4_newline)dnl -])dnl - -dnl -dnl CAIRO_ACCUMULATE_UNQUOTED(VAR, VALUE) -dnl -dnl Like CAIRO_ACCUMULATE but VALUE is left unquoted, -dnl so it can reference other shell variables for example. -dnl -AC_DEFUN([CAIRO_ACCUMULATE_UNQUOTED], -[dnl - _CAIRO_ACCUMULATE_UNQUOTED([$1], [$2], [CAIRO_$1="${CAIRO_$1}]m4_do([cr_acc_$1_sep])["]_CAIRO_SH_ESCAPE_UNQUOTED([$2]))dnl -])dnl - -dnl -dnl CAIRO_ACCUMULATE_UNQUOTED_BEFORE(VAR, VALUE) -dnl -dnl Like CAIRO_ACCUMULATE_BEFORE but VALUE is left unquoted, -dnl so it can reference other shell variables for example. -dnl -AC_DEFUN([CAIRO_ACCUMULATE_UNQUOTED_BEFORE], -[dnl - _CAIRO_ACCUMULATE_UNQUOTED([$1], [$2], [CAIRO_$1=]_CAIRO_SH_ESCAPE_UNQUOTED([$2])["]m4_do([cr_acc_$1_sep])[${CAIRO_$1}"])dnl -])dnl - -dnl -dnl CAIRO_ACCUMULATE_UNQUOTED_UNCHECKED(VAR, VALUE) -dnl -dnl Like CAIRO_ACCUMULATE_UNQUOTED but VALUE is not tested for emptiness. -dnl -AC_DEFUN([CAIRO_ACCUMULATE_UNQUOTED_UNCHECKED], -[dnl - _CAIRO_ACCUMULATE([$1], [$2], [CAIRO_$1="${CAIRO_$1}]m4_do([cr_acc_$1_sep])["]_CAIRO_SH_ESCAPE_UNQUOTED([$2]))dnl -])dnl - -dnl -dnl CAIRO_ACCUMULATE_UNQUOTED_UNCHECKED_BEFORE(VAR, VALUE) -dnl -dnl Like CAIRO_ACCUMULATE_UNQUOTED_BEFORE but VALUE is not tested for emptiness. -dnl -AC_DEFUN([CAIRO_ACCUMULATE_UNQUOTED_BEFORE], -[dnl - _CAIRO_ACCUMULATE([$1], [$2], [CAIRO_$1=]_CAIRO_SH_ESCAPE_UNQUOTED([$2])["]m4_do([cr_acc_$1_sep])[${CAIRO_$1}"])dnl -])dnl - -dnl -dnl CAIRO_ACCUMULATORS_FOREACH(VAR, COMMANDS) -dnl -dnl Run COMMANDS for each registered accumulator. -dnl Defines VAR to the accumulator being processed. -dnl -AC_DEFUN([CAIRO_ACCUMULATORS_FOREACH], -[dnl - m4_foreach_w([$1], _CAIRO_ACCUMULATORS, [$2])dnl -])dnl - - -dnl =========================================================================== - -m4_define([_CAIRO_ACCUMULATED_FEATURE_VARS])dnl - -dnl -dnl CAIRO_ACCUMULATED_FEATURE_VARS_REGISTER(VARS, DEFAULT-VALUE=[], SEPARATOR=[], INITIAL-VALUE=[]) -dnl -dnl Defines VARS as feature variables and accumulators. Also accumulates -dnl (prepending, not appending) feature values for VARS. -dnl -AC_DEFUN([CAIRO_ACCUMULATED_FEATURE_VARS_REGISTER], -[dnl - m4_foreach_w([cr_var], [$1], - [m4_append_uniq([_CAIRO_ACCUMULATED_FEATURE_VARS], cr_var, [ ],, - [m4_fatal([Accumulated feature variable `]cr_var[' already registered])])])dnl - CAIRO_FEATURE_VARS_REGISTER([$1],[$2])dnl - CAIRO_ACCUMULATORS_REGISTER_UNQUOTED([$1],[$3],[$4])dnl -])dnl - -dnl -dnl CAIRO_ACCUMULATED_FEATURE_VARS_FOREACH(VAR, COMMANDS) -dnl -dnl Run COMMANDS for each registered accumulated feature variable. -dnl Defines VAR to the variable being processed. -dnl -AC_DEFUN([CAIRO_ACCUMULATED_FEATURE_VARS_FOREACH], -[dnl - m4_foreach_w([$1], _CAIRO_ACCUMULATED_FEATURE_VARS, [$2])dnl -])dnl - -dnl =========================================================================== - -dnl -dnl CAIRO_FEATURE_IF_ENABLED(FEATURE=cr_feature, COMMANDS) -dnl -dnl Run COMMANDS if FEATURE is enabled. -dnl -AC_DEFUN([CAIRO_FEATURE_IF_ENABLED], -[dnl - AS_IF([test "x$use_]m4_default([$1], cr_feature)[" = xyes], [$2], [$3])dnl -])dnl - -m4_define([_CAIRO_FEATURE_HOOK_MATCH_SH_BOOL], -[dnl - m4_case([$1], - [*], [$3], - [no], [AS_IF([test "x$2" != xyes], [:m4_newline()$3])], - [yes], [AS_IF([test "x$2" = xyes], [:m4_newline()$3])], - [m4_fatal([Invalid ENABLED value `]$1['])])dnl -])dnl - -m4_define([_CAIRO_FEATURE_HOOK_MATCH_M4], -[dnl - m4_case([$1], - [*], [$3], - [$2], [$3], - [!$2], , - [m4_bmatch([$1], [^!], [$3])])dnl -])dnl - -m4_define([_CAIRO_FEATURE_HOOKS])dnl - -dnl -dnl CAIRO_FEATURE_HOOK_REGISTER(ENABLED, DEFAULT, WHAT, COMMANDS) -dnl -dnl ENABLED is the feature enabledness to match -dnl DEFAULT is the default value of features to match -dnl WHAT is the type of features to match -dnl COMMANDS is commands to run for matched features. -dnl -dnl Runs COMMANDS for features matching ENABLED, DEFAULT, and WHAT. -dnl Hooks are run for each feature in the order they are added. -dnl -dnl DEFAULT and WHAT are matched like this: -dnl [*] matches all values -dnl [val] matches [val] -dnl [!val] matches anything other than [val] -dnl -dnl ENABLED is matched like this: -dnl [yes] matches enabled features -dnl [no] matches disabled features -dnl [*] matches all features -dnl -dnl The following macros can be used in COMMANDS: -dnl -dnl cr_feature expands to the feature id, eg "ft" -dnl cr_feature_name expands to the human-readable name of the feature, eg. "FreeType font" -dnl cr_feature_default expands to the default state of the feature: -dnl "no" for experimental features, eg. your favorite new backend -dnl "yes" for recommended features, eg. png functions -dnl "auto" for other supported features, eg. xlib surface backend -dnl "always" for mandatory features (can't be disabled), eg. image surface backend -dnl cr_what expands to the type of feature: -dnl "surface" for surface backends -dnl "font" for font backends -dnl "functions" for set of functions -dnl "" for private configurations -dnl -dnl These four values are also set as $1 to $4. To know if feature was -dnl enabled from within COMMANDS, use CAIRO_FEATURE_IF_ENABLED: -dnl -dnl CAIRO_FEATURE_IF_ENABLED($1, [IF-ENABLED], [IF-DISABLED]) -dnl -dnl or compare $use_$1 to string "yes". As in: -dnl -dnl AS_IF([test "x$use_$1" = "xyes"], [IF-ENABLED], [IF-DISABLED]) -dnl -AC_DEFUN([CAIRO_FEATURE_HOOK_REGISTER], -[dnl - m4_append([_CAIRO_FEATURE_HOOKS], - [dnl - _CAIRO_FEATURE_HOOK_MATCH_M4([$2], cr_feature_default, - [_CAIRO_FEATURE_HOOK_MATCH_M4([$3], cr_feature_what, - [_CAIRO_FEATURE_HOOK_MATCH_SH_BOOL([$1], [$use_]cr_feature, - [$4] - )])])dnl - ], m4_newline)dnl -])dnl - diff --git a/source/libs/cairo/cairo-src/build/aclocal.float.m4 b/source/libs/cairo/cairo-src/build/aclocal.float.m4 deleted file mode 100644 index ca14ea377071222deddbe195dd8f4258dcdef2be..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/build/aclocal.float.m4 +++ /dev/null @@ -1,65 +0,0 @@ -# AX_C_FLOAT_WORDS_BIGENDIAN ([ACTION-IF-TRUE], [ACTION-IF-FALSE], -# [ACTION-IF-UNKNOWN]) -# -# Checks the ordering of words within a multi-word float. This check -# is necessary because on some systems (e.g. certain ARM systems), the -# float word ordering can be different from the byte ordering. In a -# multi-word float context, "big-endian" implies that the word containing -# the sign bit is found in the memory location with the lowest address. -# This implemenation was inspired by the AC_C_BIGENDIAN macro in autoconf. -# ------------------------------------------------------------------------- -AC_DEFUN([AX_C_FLOAT_WORDS_BIGENDIAN], - [AC_CACHE_CHECK(whether float word ordering is bigendian, - ax_cv_c_float_words_bigendian, [ - -# The endianess is detected by first compiling C code that contains a special -# double float value, then grepping the resulting object file for certain -# strings of ascii values. The double is specially crafted to have a -# binary representation that corresponds with a simple string. In this -# implementation, the string "noonsees" was selected because the individual -# word values ("noon" and "sees") are palindromes, thus making this test -# byte-order agnostic. If grep finds the string "noonsees" in the object -# file, the target platform stores float words in big-endian order. If grep -# finds "seesnoon", float words are in little-endian order. If neither value -# is found, the user is instructed to specify the ordering. - -ax_cv_c_float_words_bigendian=unknown -AC_LINK_IFELSE([AC_LANG_SOURCE([[ - -double d __attribute__((used)) = 90904234967036810337470478905505011476211692735615632014797120844053488865816695273723469097858056257517020191247487429516932130503560650002327564517570778480236724525140520121371739201496540132640109977779420565776568942592.0; -int main() { return 0; } - -]])], [ - -if strings -a conftest$ac_exeext | grep noonsees >/dev/null ; then - ax_cv_c_float_words_bigendian=yes -fi -if strings -a conftest$ac_exeext | grep seesnoon >/dev/null ; then - if test "$ax_cv_c_float_words_bigendian" = unknown; then - ax_cv_c_float_words_bigendian=no - else - ax_cv_c_float_words_bigendian=unknown - fi -fi - -])]) - -case $ax_cv_c_float_words_bigendian in - yes) - m4_default([$1], - [AC_DEFINE([FLOAT_WORDS_BIGENDIAN], 1, - [Define to 1 if your system stores words within floats - with the most significant word first])]) ;; - no) - $2 ;; - *) - m4_default([$3], - [AC_MSG_ERROR([ - -Unknown float word ordering. You need to manually preset -ax_cv_c_float_words_bigendian=no (or yes) according to your system. - - ])]) ;; -esac - -])# AX_C_FLOAT_WORDS_BIGENDIAN diff --git a/source/libs/cairo/cairo-src/build/aclocal.makefile.m4 b/source/libs/cairo/cairo-src/build/aclocal.makefile.m4 deleted file mode 100644 index 70777810d14d1a36aa51a873b80eff8c6e6e91b7..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/build/aclocal.makefile.m4 +++ /dev/null @@ -1,234 +0,0 @@ -dnl -dnl These are the facilities for generating Makefile.am.features and -dnl Makefile.win32.features files. -dnl - -dnl =========================================================================== - -dnl -dnl Define cr_feature_tag ala other cr_feature_* macros -dnl Expands to CAIRO_HAS_FEATURE_ID -dnl -m4_define([_CAIRO_BUILD_FEATURE_TAG_NORMALIZED], - [CAIRO_HAS_[$1]m4_bmatch([$1],[$2$],,[$2])])dnl -m4_define([_CAIRO_BUILD_FEATURE_TAG], - [_CAIRO_BUILD_FEATURE_TAG_NORMALIZED(AS_TR_CPP([$1]),AS_TR_CPP(m4_ifval([$2],[ $2])))])dnl -m4_define([cr_feature_tag], - [_CAIRO_BUILD_FEATURE_TAG(cr_feature,cr_feature_what)])dnl - - -dnl =========================================================================== -dnl -dnl CAIRO_INIT_MAKEFILES([AUX-DIR]) -dnl -dnl Sets up automake and win32 conditionals for all features -dnl -AC_DEFUN([CAIRO_INIT_MAKEFILES], -[dnl - dnl Allow feature tags in the output - m4_pattern_allow(^CAIRO_HAS_)dnl - - dnl Automake conditionals for non-builtin features - CAIRO_FEATURE_HOOK_REGISTER(*,!always,*, - [dnl - AM_CONDITIONAL(cr_feature_tag, [test "x$use_]cr_feature[" = xyes])dnl - ])dnl - - CAIRO_CONFIG_MAKEFILE_PRIVATE_WIN32([_],[$1],[],[[# Generated by configure. Modify to customize.]])dnl - CAIRO_MAKEFILE_ACCUMULATE_FEATURE([_],*,!always,*,[cr_feature_tag=m4_if(cr_feature_default,[yes],1,[m4_bmatch(cr_feature,[win32],1,0)])])dnl -])dnl - -dnl =========================================================================== - -m4_define([_CAIRO_MAKEFILES])dnl - -dnl -dnl CAIRO_CONFIG_MAKEFILE(TAG, DIR, [SUFFIX], [HEADER]) -dnl -dnl Create DIR/Makefile.{am,win32}.SUFFIX files -dnl TAG is a TAG used by other CAIRO_MAKEFILE_* macros to append to these -dnl Makefile's. -dnl -dnl HEADER is appended at the top of the Makefile's. If HEADER is not -dnl set, the generic "Generated by configure. Do not edit." comment -dnl is added. -dnl -AC_DEFUN([CAIRO_CONFIG_MAKEFILE], -[dnl - m4_append_uniq([_CAIRO_MAKEFILES], [$1], [ ])dnl - CAIRO_CONFIG_MAKEFILE_PRIVATE([$1], [$2], [$3], [$4])dnl -])dnl - -dnl Like CAIRO_CONFIG_MAKEFILE but only generate win32 makefile -AC_DEFUN([CAIRO_CONFIG_MAKEFILE_WIN32], -[dnl - m4_append_uniq([_CAIRO_MAKEFILES], [$1], [ ])dnl - CAIRO_CONFIG_MAKEFILE_PRIVATE_WIN32([$1], [$2], [$3], [$4])dnl -])dnl - -dnl Like CAIRO_CONFIG_MAKEFILE but only generate automake makefile -AC_DEFUN([CAIRO_CONFIG_MAKEFILE_AMAKE], -[dnl - m4_append_uniq([_CAIRO_MAKEFILES], [$1], [ ])dnl - CAIRO_CONFIG_MAKEFILE_PRIVATE_AMAKE([$1], [$2], [$3], [$4])dnl -])dnl - -dnl -dnl CAIRO_CONFIG_MAKEFILE_PRIVATE(TAG, DIR, [SUFFIX], [HEADER]) -dnl -dnl Like CAIRO_CONFIG_MAKEFILE but this makefile tag won't match -dnl against '*' in makefile accumulators. -dnl -AC_DEFUN([CAIRO_CONFIG_MAKEFILE_PRIVATE], -[dnl - m4_ifdef([cr_make_$1_dir], - [m4_fatal([Makefile `$1' already registered])])dnl - m4_define([cr_make_$1_dir],[$2])dnl - - CAIRO_CONFIG_MAKEFILE_PRIVATE_AMAKE([$1], [$2], [$3], [$4])dnl - CAIRO_CONFIG_MAKEFILE_PRIVATE_WIN32([$1], [$2], [$3], [$4])dnl -])dnl - -dnl Like CAIRO_CONFIG_MAKEFILE_PRIVATE but only generate automake makefile -AC_DEFUN([CAIRO_CONFIG_MAKEFILE_PRIVATE_AMAKE], -[dnl - m4_ifdef([cr_make_$1_dir_amake], - [m4_fatal([Automake makefile `$1' already registered])])dnl - m4_define([cr_make_$1_dir_amake],[$2])dnl - m4_define([cr_make_$1_dir_any],[$2])dnl - - dnl Accumulators - CAIRO_ACCUMULATORS_REGISTER(MAKEFILE_$1_AMAKE, m4_newline, m4_default([$4],[[# Generated by configure. Do not edit.]])m4_newline)dnl - - dnl Generate - CAIRO_CONFIG_COMMANDS([$srcdir/]m4_if([$2],[.],,[$2/])[Makefile.am.]m4_default([$3],[features]), - [echo "$CAIRO_MAKEFILE_$1_AMAKE"], - [CAIRO_MAKEFILE_$1_AMAKE='$CAIRO_MAKEFILE_$1_AMAKE'])dnl -])dnl - -dnl Like CAIRO_CONFIG_MAKEFILE_PRIVATE but only generate win32 makefile -AC_DEFUN([CAIRO_CONFIG_MAKEFILE_PRIVATE_WIN32], -[dnl - m4_ifdef([cr_make_$1_dir_win32], - [m4_fatal([Win32 makefile `$1' already registered])])dnl - m4_define([cr_make_$1_dir_win32],[$2])dnl - m4_define([cr_make_$1_dir_any],[$2])dnl - - dnl Accumulators - CAIRO_ACCUMULATORS_REGISTER(MAKEFILE_$1_WIN32, m4_newline, m4_default([$4],[[# Generated by configure. Do not edit.]])m4_newline)dnl - - dnl Generate - CAIRO_CONFIG_COMMANDS([$srcdir/]m4_if([$2],[.],,[$2/])[Makefile.win32.]m4_default([$3],[features]), - [echo "$CAIRO_MAKEFILE_$1_WIN32"], - [CAIRO_MAKEFILE_$1_WIN32='$CAIRO_MAKEFILE_$1_WIN32'])dnl -])dnl - - -m4_define([_CAIRO_MAKEFILE_CHECK], -[dnl - m4_ifdef([cr_make_$1_dir_any],,[m4_fatal([Makefile `]$1[' not defined.])])dnl -])dnl - - -dnl -dnl CAIRO_MAKEFILE_INCLUDE(TAG, FILE) -dnl -dnl Include FILE from Makefile's for TAG. FILE should be placed -dnl relative to directory for TAG. If TAG is *, FILE is included from -dnl all Makefile's. -dnl -AC_DEFUN([CAIRO_MAKEFILE_INCLUDE], -[dnl - m4_if([$1],[*],,[_CAIRO_MAKEFILE_CHECK([$1])])dnl - m4_foreach_w([cr_makefile], m4_if([$1],[*],_CAIRO_MAKEFILES,[$1]), - [dnl - m4_ifdef([cr_make_]cr_makefile[_dir_amake],dnl - [CAIRO_ACCUMULATE([MAKEFILE_]cr_makefile[_AMAKE],[include $(top_srcdir)/cr_make_]cr_makefile[_dir_amake/$2]m4_newline)] - )dnl - m4_ifdef([cr_make_]cr_makefile[_dir_win32],dnl - [CAIRO_ACCUMULATE([MAKEFILE_]cr_makefile[_WIN32],[ifeq ($(top_srcdir),)]m4_newline[include $2]m4_newline[else]m4_newline[include $(top_srcdir)/cr_make_]cr_makefile[_dir_win32/$2]m4_newline[endif]m4_newline)] - )dnl - ])dnl -])dnl - - -m4_pattern_allow([cr_make_tmp]) - -dnl -dnl CAIRO_MAKEFILE_ACCUMULATE(TAG, CONTENT) -dnl -dnl Accumulates CONTENT to Makefile's for TAG. If TAG is *, -dnl CONTENT is added to all Makefile's. -dnl -AC_DEFUN([CAIRO_MAKEFILE_ACCUMULATE], -[dnl - m4_if([$1],[*],,[_CAIRO_MAKEFILE_CHECK([$1])])dnl - m4_foreach_w([cr_makefile], m4_if([$1],[*],_CAIRO_MAKEFILES,[$1]), - [dnl - m4_pushdef([cr_make_acc_contents],[$2])dnl - cr_make_tmp=_CAIRO_SH_ESCAPE(cr_make_acc_contents(cr_makefile)) - m4_popdef([cr_make_acc_contents])dnl - m4_ifdef([cr_make_]cr_makefile[_dir_amake],dnl - [CAIRO_ACCUMULATE_UNQUOTED_UNCHECKED([MAKEFILE_]cr_makefile[_AMAKE], [$cr_make_tmp])] - )dnl - m4_ifdef([cr_make_]cr_makefile[_dir_win32],dnl - [CAIRO_ACCUMULATE_UNQUOTED_UNCHECKED([MAKEFILE_]cr_makefile[_WIN32], [$cr_make_tmp])] - )dnl - ])dnl -])dnl - -m4_define([_CAIRO_MAKEFILE_ACCUMULATE_FEATURE], -[dnl - dnl Don't do a conditional for default=always features - m4_pushdef([cr_mk_acc_feat_enabled],m4_if([$2],[yes],[m4_if(cr_feature_default,[always],[*],[$2])],[$2]))dnl - m4_case(cr_mk_acc_feat_enabled, - [*],, - [yes], [CAIRO_ACCUMULATE([$1], [$3])], - [no], [CAIRO_ACCUMULATE([$1], [$3]m4_newline[$4])], - [m4_fatal([Invalid ENABLED value `]$2['])])dnl - CAIRO_ACCUMULATE_UNQUOTED_UNCHECKED([$1], [$6])dnl - m4_case(cr_mk_acc_feat_enabled, - [*],, - [yes], [CAIRO_ACCUMULATE([$1], [$5])], - [no], [CAIRO_ACCUMULATE([$1], [$5])], - [m4_fatal([Invalid ENABLED value `]$2['])])dnl - m4_popdef([cr_mk_acc_feat_enabled])dnl -])dnl - -dnl -dnl CAIRO_MAKEFILE_ACCUMULATE_FEATURE(TAG, ENABLED, DEFAULT, WHAT, CONTENT) -dnl -dnl Accumulates CONTENT to Makefile's for TAG for each feature matching -dnl ENABLED, DEFAULT, and WHAT. Those parameters are similar to those -dnl passed to CAIRO_FEATURE_HOOK_REGISTER. -dnl If TAG is *, CONTENT is added to all Makefile's. -dnl -AC_DEFUN([CAIRO_MAKEFILE_ACCUMULATE_FEATURE], -[dnl - m4_if([$1],[*],,[_CAIRO_MAKEFILE_CHECK([$1])])dnl - m4_append([cr_make_acc_counter],[1],[])dnl - m4_define([cr_make_acc_contents]m4_len(cr_make_acc_counter), [$5])dnl - CAIRO_FEATURE_HOOK_REGISTER(*,[$3],[$4], - [dnl - m4_foreach_w([cr_makefile], m4_if([$1],[*],_CAIRO_MAKEFILES,[$1]), - [dnl - cr_make_tmp=_CAIRO_SH_ESCAPE(cr_make_acc_contents]]m4_len(cr_make_acc_counter)([[cr_makefile,]][$][1],[$][2],[$][3],[$][4])[[) - m4_ifdef([cr_make_]cr_makefile[_dir_amake], - [_CAIRO_MAKEFILE_ACCUMULATE_FEATURE( - [MAKEFILE_]cr_makefile[_AMAKE], - [$2], - [if ]cr_feature_tag, [else], [endif], - [$cr_make_tmp]) - ])dnl - m4_ifdef([cr_make_]cr_makefile[_dir_win32], - [_CAIRO_MAKEFILE_ACCUMULATE_FEATURE( - [MAKEFILE_]cr_makefile[_WIN32], - [$2], - [ifeq ($(]cr_feature_tag[),1)], [else], [endif], - [$cr_make_tmp])dnl - ])dnl - ])dnl - ])dnl -])dnl - -m4_define([cr_make_acc_counter])dnl diff --git a/source/libs/cairo/cairo-src/build/aclocal.pkg.m4 b/source/libs/cairo/cairo-src/build/aclocal.pkg.m4 deleted file mode 100644 index cf90a9678807d5acf72aac3c9e3bb3d8a55684cb..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/build/aclocal.pkg.m4 +++ /dev/null @@ -1,157 +0,0 @@ -# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -# -# Copyright © 2004 Scott James Remnant <scott@netsplit.com>. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# PKG_PROG_PKG_CONFIG([MIN-VERSION]) -# ---------------------------------- -AC_DEFUN([PKG_PROG_PKG_CONFIG], -[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) -m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) -AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl -if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then - AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) -fi -if test -n "$PKG_CONFIG"; then - _pkg_min_version=m4_default([$1], [0.9.0]) - AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) - if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - PKG_CONFIG="" - fi - -fi[]dnl -])# PKG_PROG_PKG_CONFIG - -# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) -# -# Check to see whether a particular set of modules exists. Similar -# to PKG_CHECK_MODULES(), but does not set variables or print errors. -# -# -# Similar to PKG_CHECK_MODULES, make sure that the first instance of -# this or PKG_CHECK_MODULES is called, or make sure to call -# PKG_CHECK_EXISTS manually -# -------------------------------------------------------------- -AC_DEFUN([PKG_CHECK_EXISTS], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -if test -n "$PKG_CONFIG" && \ - AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then - m4_ifval([$2], [$2], [:]) -m4_ifvaln([$3], [else - $3])dnl -fi]) - - -# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) -# --------------------------------------------- -m4_define([_PKG_CONFIG], -[if test -n "$$1"; then - pkg_cv_[]$1="$$1" - elif test -n "$PKG_CONFIG"; then - PKG_CHECK_EXISTS([$3], - [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], - [pkg_failed=yes]) - else - pkg_failed=untried -fi[]dnl -])# _PKG_CONFIG - -# _PKG_SHORT_ERRORS_SUPPORTED -# ----------------------------- -AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi[]dnl -])# _PKG_SHORT_ERRORS_SUPPORTED - - -# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], -# [ACTION-IF-NOT-FOUND]) -# -# ACTION-IF-NOT-FOUND is not allowed to be empty, that trigger PKG_CONFIG_PATH error message. -# Use : or set a dummy variable to avoid that behavior. -# -# Note that if there is a possibility the first call to -# PKG_CHECK_MODULES might not happen, you should be sure to include an -# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac -# -# -# -------------------------------------------------------------- -AC_DEFUN([PKG_CHECK_MODULES], -[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl -AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl -AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl - -pkg_failed=no -AC_MSG_CHECKING([for $1]) - -_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) -_PKG_CONFIG([$1][_LIBS], [libs], [$2]) - -m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS -and $1[]_LIBS to avoid the need to call pkg-config. -See the pkg-config man page for more details.]) - -if test $pkg_failed = yes; then - _PKG_SHORT_ERRORS_SUPPORTED - if test $_pkg_short_errors_supported = yes; then - $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "$2" 2>&1` - else - $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors "$2" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD - - ifelse([$4], , [AC_MSG_ERROR(dnl -[Package requirements ($2) were not met: - -$$1_PKG_ERRORS - -Consider adjusting the PKG_CONFIG_PATH environment variable if you -installed software in a non-standard prefix. - -_PKG_TEXT -])], - [AC_MSG_RESULT([no]) - $4]) -elif test $pkg_failed = untried; then - ifelse([$4], , [AC_MSG_FAILURE(dnl -[The pkg-config script could not be found or is too old. Make sure it -is in your PATH or set the PKG_CONFIG environment variable to the full -path to pkg-config. - -_PKG_TEXT - -To get pkg-config, see <http://pkg-config.freedesktop.org/>.])], - [$4]) -else - $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS - $1[]_LIBS=$pkg_cv_[]$1[]_LIBS - AC_MSG_RESULT([yes]) - ifelse([$3], , :, [$3]) -fi[]dnl -])# PKG_CHECK_MODULES diff --git a/source/libs/cairo/cairo-src/build/configure.ac.analysis b/source/libs/cairo/cairo-src/build/configure.ac.analysis deleted file mode 100644 index 11c52e70d6ea2d983078d1f08e7f2f0c7e47e319..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/build/configure.ac.analysis +++ /dev/null @@ -1,106 +0,0 @@ -dnl =========================================================================== -dnl -dnl LCOV -dnl -cairo_has_lcov=no -AC_ARG_ENABLE(gcov, - AS_HELP_STRING([--enable-gcov], - [Enable gcov]), - [use_gcov=$enableval], [use_gcov=no]) - -if test "x$use_gcov" = "xyes"; then - dnl we need gcc: - if test "$GCC" != "yes"; then - AC_MSG_ERROR([GCC is required for --enable-gcov]) - fi - - dnl Check if ccache is being used - AC_CHECK_PROG(SHTOOL, shtool, shtool) - case `$SHTOOL path $CC` in - *ccache*[)] gcc_ccache=yes;; - *[)] gcc_ccache=no;; - esac - - if test "$gcc_ccache" = "yes" && (test -z "$CCACHE_DISABLE" || test "$CCACHE_DISABLE" != "1"); then - AC_MSG_ERROR([ccache must be disabled when --enable-gcov option is used. You can disable ccache by setting environment variable CCACHE_DISABLE=1.]) - fi - - ltp_version_list="1.7 1.6 1.5 1.4" - AC_CHECK_PROG(LTP, lcov, lcov) - AC_CHECK_PROG(LTP_GENHTML, genhtml, genhtml) - - if test "$LTP"; then - AC_CACHE_CHECK([for ltp version], cairo_cv_ltp_version, [ - cairo_cv_ltp_version=invalid - ltp_version=`$LTP -v 2>/dev/null | $SED -e 's/^.* //'` - for ltp_check_version in $ltp_version_list; do - if test "$ltp_version" = "$ltp_check_version"; then - cairo_cv_ltp_version="$ltp_check_version (ok)" - fi - done - ]) - fi - - case $cairo_cv_ltp_version in - ""|invalid[)] - ;; - *) - cairo_has_lcov=yes - ;; - esac - - if test "x$cairo_has_lcov" != "xyes"; then - AC_MSG_ERROR([[To enable code coverage reporting you must have one of the following LTP versions installed: $ltp_version_list. -Please install the Linux Test Project [http://ltp.sourceforge.net/], and try again.]]) - fi - - if test -z "$LTP_GENHTML"; then - AC_MSG_ERROR([[Could not find genhtml from the LTP package. -Please install the Linux Test Project [http://ltp.sourceforge.net/], and try again.]]) - fi - - AC_DEFINE(HAVE_GCOV, 1, [Whether you have gcov]) -dnl PHP_ADD_MAKEFILE_FRAGMENT($abs_srcdir/Makefile.gcov, $abs_srcdir) - - dnl Remove all optimization flags from CFLAGS - changequote({,}) - CFLAGS=`echo "$CFLAGS" | $SED -e 's/-O[0-9]*//g'` - CAIRO_CFLAGS=`echo "$CAIRO_CFLAGS" | $SED -e 's/-O[0-9]*//g'` - changequote([,]) - - dnl Add the special gcc flags - dnl In order to workaround a debian bug in libtool where they strip - dnl $dependency_libs from the link line and CFLAGS, we need to pass - dnl --coverage via LDFLAGS. - CAIRO_CC_TRY_FLAG([--coverage],, - [ - CAIRO_CFLAGS="$CAIRO_CFLAGS -O0 --coverage" - CAIRO_LDFLAGS="$CAIRO_LDFLAGS -O0 --coverage" - ]) -fi -AM_CONDITIONAL(CAIRO_HAS_LCOV, test "x$cairo_has_lcov" = "xyes") - -dnl =========================================================================== -dnl Check for some custom valgrind modules -AC_ARG_ENABLE(valgrind, - AS_HELP_STRING([--disable-valgrind], - [Disable valgrind support]), - [use_valgrind=$enableval], [use_valgrind=yes]) - -if test "x$use_valgrind" = "xyes"; then - PKG_CHECK_MODULES(VALGRIND, valgrind, [ - _save_CFLAGS="$CFLAGS" - _save_CPPFLAGS="$CPPFLAGS" - CFLAGS="$CFLAGS $VALGRIND_CFLAGS" - CPPFLAGS="$CPPFLAGS $VALGRIND_CFLAGS" - AC_CHECK_HEADER([valgrind.h], [AC_DEFINE([HAVE_VALGRIND], [1], - [Define to 1 if you have Valgrind])]) - AC_CHECK_HEADER([lockdep.h], [AC_DEFINE([HAVE_LOCKDEP], [1], - [Define to 1 if you have the Valgrind lockdep tool])]) - AC_CHECK_HEADER([memfault.h], [AC_DEFINE([HAVE_MEMFAULT], [1], - [Define to 1 if you have the Valgrind memfault tool])]) - CAIRO_CFLAGS="$VALGRIND_CFLAGS $CAIRO_CFLAGS" - CFLAGS="$_save_CFLAGS" - CPPFLAGS="$_save_CPPFLAGS" - ], AC_MSG_RESULT(no)) -fi diff --git a/source/libs/cairo/cairo-src/build/configure.ac.features b/source/libs/cairo/cairo-src/build/configure.ac.features deleted file mode 100644 index 77f20358889c53a13d5a1925fae5bad073beb9ff..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/build/configure.ac.features +++ /dev/null @@ -1,427 +0,0 @@ - -dnl -dnl Define macros to enable various features. -dnl - Macro: CAIRO_ENABLE_* (ID, NAME, DEFAULT, COMMANDS) -dnl -dnl where: -dnl -dnl ID is the feature id, eg. "ft" for cairo_ft_... -dnl NAME is the human-readable name of the feature, eg. "FreeType" -dnl DEFAULT is the default state of the feature: -dnl "no" for experimental backends, eg. your favorite new backend -dnl "yes" for mandatory backends, eg. png -dnl "auto" for other supported backends, eg. xlib -dnl COMMANDS are run to check whether the feature can be enabled. Their -dnl result may be cached, so user should not count on them being run. -dnl They should set use_$(ID) to something other than yes if the -dnl feature cannot be built, eg. "no (requires SomeThing)". It then -dnl should also set $(ID)_REQUIRES/CFLAGS/LIBS/... -dnl appropriately. Look at the macro definition for more details, -dnl or ask if in doubt. -dnl - -AC_DEFUN([CAIRO_ENABLE], - [_CAIRO_ENABLE([$1], [$2], , [$3],[$4])])dnl - -AC_DEFUN([CAIRO_ENABLE_SURFACE_BACKEND], - [_CAIRO_ENABLE([$1], [$2 surface backend], surface, [$3],[$4])])dnl - -AC_DEFUN([CAIRO_ENABLE_FONT_BACKEND], - [_CAIRO_ENABLE([$1], [$2 font backend], font, [$3],[$4])])dnl - -AC_DEFUN([CAIRO_ENABLE_FUNCTIONS], - [_CAIRO_ENABLE([$1], [$2 functions], functions, [$3],[$4])])dnl - - -dnl -dnl Define cr_feature_pc and friends ala other cr_feature_* macros -dnl -m4_define([cr_pc_modname], - [[cairo-]m4_translit([$1],_,-)])dnl -m4_define([cr_feature_pc], - [cr_pc_modname(cr_feature)[.pc]])dnl -m4_define([cr_feature_uninstalled_pc], - [cr_pc_modname(cr_feature)[-uninstalled.pc]])dnl - - -dnl =========================================================================== -dnl -dnl Hooks -dnl -dnl =========================================================================== - - -dnl =========================================================================== -dnl -dnl Generate {src,boilerplate}/Makefile.{am,win32}.config -dnl - -CAIRO_INIT_MAKEFILES([build]) -CAIRO_CONFIG_MAKEFILE([cairo], [src])dnl -CAIRO_CONFIG_MAKEFILE([cairo_boilerplate], [boilerplate])dnl -CAIRO_MAKEFILE_INCLUDE(*,[Makefile.sources])dnl -dnl An empty line per feature for readability -CAIRO_MAKEFILE_ACCUMULATE_FEATURE(*,*,*,*,[])dnl - - -dnl Collect list of all supported public headers -CAIRO_MAKEFILE_ACCUMULATE(*, -[supported_$1_headers = $($1_headers)]dnl -)dnl -CAIRO_MAKEFILE_ACCUMULATE_FEATURE(*,*,!no,!, -[supported_$1_headers += $($1_$2_headers)]dnl -)dnl - -dnl Collect list of all unsupported public headers -CAIRO_MAKEFILE_ACCUMULATE(*, -[unsupported_$1_headers =]dnl -)dnl -CAIRO_MAKEFILE_ACCUMULATE_FEATURE(*,*,no,!, -[unsupported_$1_headers += $($1_$2_headers)]dnl -)dnl - -dnl Collect list of source files for all public features -CAIRO_MAKEFILE_ACCUMULATE(*, -[dnl -all_$1_headers = $($1_headers) -all_$1_private = $($1_private) -all_$1_cxx_sources = $($1_cxx_sources) -all_$1_sources = $($1_sources) -])dnl -CAIRO_MAKEFILE_ACCUMULATE_FEATURE(*,*,*,!, -[dnl -all_$1_headers += $($1_$2_headers) -all_$1_private += $($1_$2_private) -all_$1_cxx_sources += $($1_$2_cxx_sources) -all_$1_sources += $($1_$2_sources)]dnl -)dnl - -dnl Collect list of source files for enabled public features -CAIRO_MAKEFILE_ACCUMULATE(*, -[dnl -enabled_$1_headers = $($1_headers) -enabled_$1_private = $($1_private) -enabled_$1_cxx_sources = $($1_cxx_sources) -enabled_$1_sources = $($1_sources) -])dnl -CAIRO_MAKEFILE_ACCUMULATE_FEATURE(*,yes,*,!, -[dnl -enabled_$1_headers += $($1_$2_headers) -enabled_$1_private += $($1_$2_private) -enabled_$1_cxx_sources += $($1_$2_cxx_sources) -enabled_$1_sources += $($1_$2_sources)]dnl -)dnl - -dnl No public headers for private features - -dnl Collect list of source files for all private features -CAIRO_MAKEFILE_ACCUMULATE_FEATURE(*,*,*,, -[dnl -all_$1_private += $($1_$2_private) $($1_$2_headers) -all_$1_cxx_sources += $($1_$2_cxx_sources) -all_$1_sources += $($1_$2_sources)]dnl -)dnl - -dnl Collect list of source files for enabled private features -CAIRO_MAKEFILE_ACCUMULATE_FEATURE(*,yes,*,, -[dnl -enabled_$1_private += $($1_$2_private) $($1_$2_headers) -enabled_$1_cxx_sources += $($1_$2_cxx_sources) -enabled_$1_sources += $($1_$2_sources)]dnl -)dnl - - -dnl =========================================================================== -dnl -dnl Generate .pc files -dnl - -dnl All .pc files are generated automatically except for this one -AC_CONFIG_FILES([src/cairo.pc])dnl -AC_CONFIG_FILES([cairo-uninstalled.pc:src/cairo-uninstalled.pc.in])dnl - -dnl pkg-config requires, non-pkgconfig cflags and libs, and total cflags and libs -CAIRO_FEATURE_VARS_REGISTER([BASE],[cairo])dnl -CAIRO_ACCUMULATED_FEATURE_VARS_REGISTER([REQUIRES],,[ ])dnl -CAIRO_ACCUMULATED_FEATURE_VARS_REGISTER([CFLAGS NONPKGCONFIG_CFLAGS],,[ ])dnl -CAIRO_ACCUMULATED_FEATURE_VARS_REGISTER([LIBS NONPKGCONFIG_LIBS],,[ ],[$LIBS])dnl -CAIRO_FEATURE_VARS_REGISTER([NONPKGCONFIG_EXTRA_LIBS])dnl -AC_SUBST(CAIRO_REQUIRES)dnl -AC_SUBST(CAIRO_CFLAGS)dnl -AC_SUBST(CAIRO_LDFLAGS)dnl -AC_SUBST(CAIRO_NONPKGCONFIG_CFLAGS)dnl -AC_SUBST(CAIRO_LIBS)dnl -AC_SUBST(CAIRO_NONPKGCONFIG_LIBS)dnl - -dnl add non-pkgconfig values -AC_CONFIG_COMMANDS_PRE( -[dnl -CAIRO_CFLAGS="$CAIRO_CFLAGS $CAIRO_NONPKGCONFIG_CFLAGS" -CAIRO_LIBS="$CAIRO_LIBS $CAIRO_NONPKGCONFIG_LIBS" -])dnl - -m4_define([_CAIRO_FEATURE_CONFIG_PKGCONFIG_FILE], -[dnl - AC_CONFIG_FILES([$3:$4], - [dnl - mv "$3" "$3.tmp" && - $SED "dnl - s%@FEATURE_PC@%]cr_pc_modname([$1])[%g;dnl - s%@FEATURE_NAME@%$2%g;dnl - s%@FEATURE_BASE@%$$1_BASE%g;dnl - s%@FEATURE_REQUIRES@%$$1_REQUIRES%g;dnl - s%@FEATURE_NONPKGCONFIG_LIBS@%$$1_NONPKGCONFIG_LIBS%g;dnl - s%@FEATURE_NONPKGCONFIG_EXTRA_LIBS@%$$1_NONPKGCONFIG_EXTRA_LIBS%g;dnl - s%@FEATURE_NONPKGCONFIG_CFLAGS@%$$1_NONPKGCONFIG_CFLAGS%g;dnl - " < "$3.tmp" > "$3" && rm -f "$3.tmp" || - AC_MSG_ERROR(failed to update $3) - ],[dnl - SED='$SED' - $1_BASE='$$1_BASE' - $1_REQUIRES='$$1_REQUIRES' - $1_NONPKGCONFIG_LIBS='$$1_NONPKGCONFIG_LIBS' - $1_NONPKGCONFIG_EXTRA_LIBS='$$1_NONPKGCONFIG_EXTRA_LIBS' - $1_NONPKGCONFIG_CFLAGS='$$1_NONPKGCONFIG_CFLAGS' - ])dnl -])dnl - -dnl Generate .pc files for enabled non-builtin public features -CAIRO_FEATURE_HOOK_REGISTER(yes,!always,!, -[dnl - _CAIRO_FEATURE_CONFIG_PKGCONFIG_FILE( - [$1], - cr_feature_name, - [src/]cr_feature_pc, - [src/cairo-features.pc.in] - )dnl -])dnl - -dnl Generate -uninstalled.pc files for enabled non-builtin public features -CAIRO_FEATURE_HOOK_REGISTER(yes,!always,!, -[dnl - _CAIRO_FEATURE_CONFIG_PKGCONFIG_FILE( - [$1], - cr_feature_name, - cr_feature_uninstalled_pc, - [src/cairo-features-uninstalled.pc.in] - )dnl -])dnl - - -dnl Collect list of .pc files for all non-builtin public features -CAIRO_MAKEFILE_ACCUMULATE(cairo, -[all_$1_pkgconf = cairo.pc])dnl -CAIRO_MAKEFILE_ACCUMULATE_FEATURE(cairo,*,!always,!, -[all_$1_pkgconf += cr_feature_pc])dnl - -dnl Collect list of .pc files for enabled non-builtin public features -CAIRO_MAKEFILE_ACCUMULATE(cairo, -[enabled_$1_pkgconf = cairo.pc])dnl -CAIRO_MAKEFILE_ACCUMULATE_FEATURE(cairo,yes,!always,!, -[enabled_$1_pkgconf += cr_feature_pc])dnl - - -dnl =========================================================================== -dnl -dnl Generate src/cairo-features.h, src/cairo-supported-features.h, and -dnl src/cairo-features-win32.h -dnl - -dnl Collect list of enabled public features -CAIRO_ACCUMULATORS_REGISTER(FEATURES,[ ])dnl -CAIRO_FEATURE_HOOK_REGISTER(yes,*,!,dnl -[dnl - CAIRO_ACCUMULATE(FEATURES, cr_feature_tag)dnl -])dnl -dnl Collect list of all supported public features -CAIRO_ACCUMULATORS_REGISTER(SUPPORTED_FEATURES,[ ])dnl -CAIRO_FEATURE_HOOK_REGISTER(*,!no,!,dnl -[dnl - CAIRO_ACCUMULATE(SUPPORTED_FEATURES, cr_feature_tag) -])dnl -dnl Collect list of all supported disabled public features -CAIRO_ACCUMULATORS_REGISTER(NO_FEATURES,[ ])dnl -CAIRO_FEATURE_HOOK_REGISTER(no,*,!, -[dnl - CAIRO_ACCUMULATE(NO_FEATURES, cr_feature_tag) -])dnl - -dnl Generate src/cairo-features.h -CAIRO_CONFIG_COMMANDS([src/cairo-features.h], -[dnl - echo '/* Generated by configure. Do not edit. */' - echo '#ifndef CAIRO_FEATURES_H' - echo '#define CAIRO_FEATURES_H' - echo '' - for FEATURE in $CAIRO_FEATURES; do - echo "#define $FEATURE 1" - done | LANG=C sort - echo '' - for FEATURE in $CAIRO_NO_FEATURES; do - echo "/*#undef $FEATURE */" - done | LANG=C sort - echo '' - echo '#endif' -],[dnl - CAIRO_FEATURES='$CAIRO_FEATURES' - CAIRO_NO_FEATURES='$CAIRO_NO_FEATURES' -])dnl -dnl Generate src/cairo-supported-features.h -CAIRO_CONFIG_COMMANDS([src/cairo-supported-features.h], -[dnl - echo '/* Generated by configure. Do not edit. */' - echo '#ifndef CAIRO_SUPPORTED_FEATURES_H' - echo '#define CAIRO_SUPPORTED_FEATURES_H' - echo '' - echo '/* This is a dummy header, to trick gtk-doc only */' - echo '' - for FEATURE in $CAIRO_SUPPORTED_FEATURES; do - echo "#define $FEATURE 1" - done - echo '' - echo '#endif' -],[dnl - CAIRO_SUPPORTED_FEATURES='$CAIRO_SUPPORTED_FEATURES' -])dnl - -dnl For enabled private features just define them in config.h. No fanfare! -CAIRO_FEATURE_HOOK_REGISTER(yes,*,, -[dnl - AC_DEFINE(cr_feature_tag, 1, [Define to 1 to enable cairo's ]cr_feature_name[ feature]) -])dnl - - -dnl Generate build/Makefile.win32.features-h that generates src/cairo-features.h -CAIRO_CONFIG_MAKEFILE_PRIVATE_WIN32([win32_features_h],[build],[features-h]) -dnl -CAIRO_MAKEFILE_ACCUMULATE([win32_features_h], -[$(top_srcdir)/src/cairo-features.h: $(top_srcdir)/build/Makefile.win32.features - @echo "Generating src/cairo-features.h" - @echo "/* Generated by Makefile.win32.features-h. Do not edit. */" > $(top_srcdir)/src/cairo-features.h - @echo "[#]ifndef CAIRO_FEATURES_H" >> $(top_srcdir)/src/cairo-features.h - @echo "[#]define CAIRO_FEATURES_H 1" >> $(top_srcdir)/src/cairo-features.h]dnl -) -AC_CONFIG_COMMANDS_PRE( -[dnl - CAIRO_MAKEFILE_ACCUMULATE([win32_features_h], [ @echo "[#]endif" >> $(top_srcdir)/src/cairo-features.h]) -])dnl -CAIRO_MAKEFILE_ACCUMULATE_FEATURE([win32_features_h],yes,*,*,dnl -[ @echo "[#]define cr_feature_tag 1" >> $(top_srcdir)/src/cairo-features.h]dnl -)dnl - - -dnl =========================================================================== -dnl -dnl Report -dnl - -CAIRO_ACCUMULATORS_REGISTER([WARNING_MESSAGE],m4_newline()m4_newline)dnl - -dnl Collect warning message for enabled unsupported public features -CAIRO_FEATURE_HOOK_REGISTER(yes,no,!, -[dnl - CAIRO_ACCUMULATE([WARNING_MESSAGE], CAIRO_TEXT_WRAP([The ]cr_feature_name[ feature is still under active development and is included in this release only as a preview. It does NOT fully work yet and incompatible changes may yet be made to ]cr_feature_name[ specific API.], [--- ])) -])dnl - -dnl Collect warning message for disabled recommended features -CAIRO_FEATURE_HOOK_REGISTER(no,yes,*, -[dnl - CAIRO_ACCUMULATE([WARNING_MESSAGE], CAIRO_TEXT_WRAP([It is strongly recommended that you do NOT disable the ]cr_feature_name[ feature.], [+++ ])) -])dnl - - -dnl Collect enabled native surface/font backend features -CAIRO_ACCUMULATORS_REGISTER([NATIVE_SURFACE_BACKENDS])dnl -CAIRO_ACCUMULATORS_REGISTER([NATIVE_FONT_BACKENDS])dnl -CAIRO_FEATURE_HOOK_REGISTER(yes,auto,surface, -[dnl - CAIRO_ACCUMULATE([NATIVE_SURFACE_BACKENDS], [$1]) -])dnl -CAIRO_FEATURE_HOOK_REGISTER(yes,auto,font, -[dnl - CAIRO_ACCUMULATE([NATIVE_FONT_BACKENDS], [$1]) -])dnl - -dnl Collect warning message if no native surface/font backend feature enabled -AC_CONFIG_COMMANDS_PRE(dnl -[dnl - AS_IF([test -z "$CAIRO_NATIVE_SURFACE_BACKENDS"],dnl - [dnl - CAIRO_ACCUMULATE([WARNING_MESSAGE], CAIRO_TEXT_WRAP([No native surface backends enabled for your platform. It is strongly recommended that you enable the native surface backend feature for your platform.], [*** ])) - ]) - AS_IF([test -z "$CAIRO_NATIVE_FONT_BACKENDS"],dnl - [dnl - CAIRO_ACCUMULATE([WARNING_MESSAGE], CAIRO_TEXT_WRAP([No native font backends enabled for your platform. It is strongly recommended that you enable the native font backend feature for your platform.], [*** ])) - ]) -])dnl - - -AC_DEFUN([CAIRO_REPORT], -[dnl - V="$CAIRO_VERSION_MAJOR.$CAIRO_VERSION_MINOR.$CAIRO_VERSION_MICRO" - echo "" - echo "cairo (version $V [[$CAIRO_RELEASE_STATUS]]) will be compiled with:" - echo "" - echo "The following surface backends:" - echo " Image: yes (always builtin)" - echo " Recording: yes (always builtin)" - echo " Observer: yes (always builtin)" - echo " Mime: yes (always builtin)" - echo " Tee: $use_tee" - echo " XML: $use_xml" - echo " Skia: $use_skia" - echo " Xlib: $use_xlib" - echo " Xlib Xrender: $use_xlib_xrender" - echo " Qt: $use_qt" - echo " Quartz: $use_quartz" - echo " Quartz-image: $use_quartz_image" - echo " XCB: $use_xcb" - echo " Win32: $use_win32" - echo " OS2: $use_os2" - echo " CairoScript: $use_script" - echo " PostScript: $use_ps" - echo " PDF: $use_pdf" - echo " SVG: $use_svg" - echo " OpenGL: $use_gl" - echo " OpenGL ES 2.0: $use_glesv2" - echo " BeOS: $use_beos" - echo " DirectFB: $use_directfb" - echo " OpenVG: $use_vg" - echo " DRM: $use_drm" - echo " Cogl: $use_cogl" - echo "" - echo "The following font backends:" - echo " User: yes (always builtin)" - echo " FreeType: $use_ft" - echo " Fontconfig: $use_fc" - echo " Win32: $use_win32_font" - echo " Quartz: $use_quartz_font" - echo "" - echo "The following functions:" - echo " PNG functions: $use_png" - echo " GLX functions: $use_glx" - echo " WGL functions: $use_wgl" - echo " EGL functions: $use_egl" - echo " X11-xcb functions: $use_xlib_xcb" - echo " XCB-shm functions: $use_xcb_shm" - echo "" - echo "The following features and utilities:" - echo " cairo-trace: $use_trace" - echo " cairo-script-interpreter: $use_interpreter" - echo "" - echo "And the following internal features:" - echo " pthread: $use_pthread" - echo " gtk-doc: $enable_gtk_doc" - echo " gcov support: $use_gcov" - echo " symbol-lookup: $use_symbol_lookup" - echo " test surfaces: $use_test_surfaces" - echo " ps testing: $test_ps" - echo " pdf testing: $test_pdf" - echo " svg testing: $test_svg" - if test x"$use_win32" = "xyes"; then - echo " win32 printing testing: $test_win32_printing" - fi - echo "$CAIRO_WARNING_MESSAGE" - echo "" -])dnl - diff --git a/source/libs/cairo/cairo-src/build/configure.ac.noversion b/source/libs/cairo/cairo-src/build/configure.ac.noversion deleted file mode 100644 index 18c4bd5f7ae317d8cabbdcbc9952e4cc59193f28..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/build/configure.ac.noversion +++ /dev/null @@ -1,23 +0,0 @@ -dnl -dnl Version stuff -dnl - -dnl Disable autoconf's version macros. We try hard to not rebuild the entire -dnl library just because version changed. The PACKAGE_VERSION* stuff in -dnl config.h is negating all the effort. -dnl -dnl We're not actually supposed to be doing this, and indeed adding the -dnl AC_DEFINEs below causes confdefs.h to contain duplicate incompatible -dnl #defines for the same PACKAGE_* symbols. Those are provoking warnings -dnl from the compiler, and that throws our CAIRO_TRY_LINK_*_ checks off, -dnl because they think that there's something wrong with some flag they're -dnl testing rather than confdefs.h! So let's do the gross thing and puke -dnl into confdefs.h some #undefs. -echo '#undef PACKAGE_VERSION' >>confdefs.h -echo '#undef PACKAGE_STRING' >>confdefs.h -echo '#undef PACKAGE_NAME' >>confdefs.h -echo '#undef PACKAGE_TARNAME' >>confdefs.h -AC_DEFINE(PACKAGE_VERSION, [USE_cairo_version_OR_cairo_version_string_INSTEAD]) -AC_DEFINE(PACKAGE_STRING, [USE_cairo_version_OR_cairo_version_string_INSTEAD]) -AC_DEFINE(PACKAGE_NAME, [USE_cairo_INSTEAD]) -AC_DEFINE(PACKAGE_TARNAME, [USE_cairo_INSTEAD]) diff --git a/source/libs/cairo/cairo-src/build/configure.ac.pthread b/source/libs/cairo/cairo-src/build/configure.ac.pthread deleted file mode 100644 index 29c930da93213c6edd7a198b77dbd2adfe321d5b..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/build/configure.ac.pthread +++ /dev/null @@ -1,253 +0,0 @@ -dnl Defines the macro CAIRO_CONFIGURE_PTHREAD to find a suitable -dnl pthread implementation. There are two levels of pthread conformance -dnl we are looking for: -dnl -dnl a) A minimal level denoted by -DCAIRO_HAS_PTHREAD=1: This level -dnl requires mutex and recursive mutexattr support. If possible we try -dnl to use weakly linked stubs from libc over the real pthread library. -dnl This level is required by the cairo library proper. If the user -dnl invokes configure with --enable-pthread=yes or -dnl --enable-pthread=always then we avoid trying to use weak stubs. -dnl -dnl b) A full level denoted by -DCAIRO_HAS_REAL_PTHREAD=1: This level -dnl requires full support from a real pthread library, including thread -dnl creation, joins, thread attribtues, etc. This level is required by -dnl multithreaded applications using cairo, such as the test suite -dnl binaries and cairo utilities. -dnl -dnl Usage: -dnl CAIRO_ENABLE(pthread, pthread, <default yes|no|auto|always>, -dnl [CAIRO_CONFIGURE_PTHREAD]) -dnl -dnl This should be invoked near the end of configure.ac so that -dnl the pthread specific CFLAGS and LIBS end up at the front -dnl of CAIRO_CFLAGS and CAIRO_LIBS -- this helps ensure that we -dnl really do get non-weak symbols from the actual pthread library -dnl rather than possible stubs in other libraries. -dnl -dnl The user can override the choices made by -dnl CAIRO_CONFIGURE_PTHREAD by using --enable-pthread=yes and -dnl giving PTHREAD_CFLAGS and PTHREAD_LIBS to configure. -dnl -dnl Sets environment variables: -dnl use_pthread="yes" | "no (<errmsg>)" -dnl have_pthread="yes" | "no (<errmsg)" -dnl have_real_pthread="yes" | "no (<errmsg)" -dnl pthread_{CFLAGS,LIBS,REQUIRES} -dnl real_pthread_{CFLAGS,LIBS} -dnl -dnl Autoconfigured defines in config.h (conditional): -dnl CAIRO_HAS_PTHREAD -dnl CAIRO_HAS_REAL_PTHREAD -dnl - -dnl ----------------------------------------------------------------------- -dnl A program to test all the pthread features we need to be able to -dnl compile libcairo itself. We could test the features independently, -dnl but we need all of them anyway. -m4_define([libcairo_pthread_program],[dnl -#ifndef _GNU_SOURCE -#define _GNU_SOURCE /* for PTHREAD_MUTEX_INITIALIZER under linux */ -#endif -#include <pthread.h> - -pthread_mutex_t test_mutex_initializer = PTHREAD_MUTEX_INITIALIZER; -int test_mutex (void) -{ - int x = 0; - pthread_mutex_t mutex; - x |= pthread_mutex_init (&mutex, NULL); - x |= pthread_mutex_lock (&mutex); - x |= pthread_mutex_unlock (&mutex); - x |= pthread_mutex_destroy (&mutex); - return 0; -} - -int test_mutex_attr (void) -{ - int x = 0; - pthread_mutexattr_t attr; - pthread_mutex_t mutex; - x |= pthread_mutexattr_init (&attr); - x |= pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); - x |= pthread_mutex_init (&mutex, &attr); - x |= pthread_mutex_lock (&mutex); - x |= pthread_mutex_unlock (&mutex); - x |= pthread_mutex_destroy (&mutex); - x |= pthread_mutexattr_destroy (&attr); - return x; -}]) - -dnl ----------------------------------------------------------------------- -dnl A program to test all the features we want to be able to run the test -dnl suite or other thready cairo applications that want real threads. -m4_define([testsuite_pthread_program],[dnl -libcairo_pthread_program - -pthread_once_t once_control = PTHREAD_ONCE_INIT; -void test_once_init (void) {} -int test_once (void) -{ - return pthread_once (&once_control, test_once_init); -} - -pthread_key_t test_specific_key; -int test_specific (void) -{ - int x = 0; - x |= pthread_key_create (&test_specific_key, NULL); - x |= pthread_setspecific (test_specific_key, NULL); - x |= pthread_getspecific (test_specific_key) != NULL; - return x; -} - -void cleaner (void *arg) { (void)arg; } - -void * -test_thread_main (void *arg) -{ - pthread_cleanup_push (cleaner, arg); - pthread_exit (arg); - pthread_cleanup_pop (1); - return arg; -} - -int -test_threads (void) -{ - int x = 0; - pthread_t thread; - pthread_attr_t attr; - void *arg = NULL; - x |= pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); - x |= pthread_create (&thread, &attr, test_thread_main, arg); - x |= pthread_equal (pthread_self(), thread); - x |= pthread_join (thread, &arg); - x |= pthread_attr_destroy (&attr); - return x; -}]) - -dnl ----------------------------------------------------------------------- - -dnl CAIRO_CHECK_PTHREAD(tag, cflags, libs, program, true-action, false-action) -dnl Set <tag>_{CFLAGS,LIBS} to {<cflags>,<libs>} if we can compile and link -dnl <program> with the given flags and libs. Execute <true-action> on -dnl success and <false-action> on failure. -AC_DEFUN([CAIRO_CHECK_PTHREAD],[dnl - CAIRO_CC_TRY_LINK_WITH_ENV_SILENT( - [CFLAGS="$CFLAGS $2"; - LIBS="$LIBS $3"], - [$4], - [$1_CFLAGS="$2"; - $1_LIBS="$3"; - $5], - [$1_CFLAGS=""; - $1_LIBS=""; - $6]) -]) - -dnl CAIRO_CONFIGURE_PTHREADS(): Look for pthreads. -dnl -dnl If the user specifies PTHREAD_CFLAGS and PTHREAD_LIBS then we use -dnl those. Otherwise we try CFLAGS=-D_REENTRANT and LIBS=-lpthread for -dnl full pthread support, and look for stubs in libc for the minimal -dnl pthread support. -dnl -dnl CFLAGS=-D_REENTRANT LIBS=-lpthread has been tested to work on: -dnl -dnl Solaris 9 (5.9) Sun C 5.8 Patch 121015-04 2007/01/10 -dnl OpenSolaris (5.11) Sun C 5.9 Patch 124868-08 2008/11/25 -dnl OpenSolaris (5.11) clang version 1.1 (trunk 90017) -dnl Tru64/OSF1 V5.1 Compaq C V6.5-003 -dnl Mac OS X 10.5.5 gcc 4.0.1 (Apple Inc. build 5465) -dnl Mac OS X 10.6 gcc 4.2.1 (Apple Inc. build 5659) -dnl FreeBSD 7.2 gcc 4.2 -dnl OpenBSD 4.5 gcc 3.3.5 (propolice) -dnl Debian Linux (Etch) gcc 4.3 -dnl -dnl Thread support is also in various libcs directly, so often using no -dnl flags at all works as well, but unfortunately Solaris 9 has -dnl practically _all_ of libpthread stubbed out in libc, so we cannot -dnl distinguish between a working libpthread and a stubbed out one by a -dnl link-only test. -dnl -dnl We also explicitly do not link to pthread-stubs or whatever other -dnl third-party stubs library, since that forces cairo clients to be -dnl extra careful when giving both libcairo and libpthread on the -dnl command line: the user would have to use "-lpthread -lcairo" rather -dnl than the more common "-lcairo -lpthread" to not accidentally use -dnl stubs pulled in by libcairo everywhere in the application. We -dnl might also need to have a way to teach pkg-config about library -dnl ordering constraints which aren't actual dependencies, and at this -dnl point it just starts doing my head in. -dnl -dnl If your unix-like doesn't work with the secret handshake -dnl -D_REENTRANT -lpthread and you can actually compile the rest of -dnl cairo just fine otherwise, please take a moment complain loudly -dnl to the cairo mailing list! -dnl -AC_DEFUN([CAIRO_CONFIGURE_PTHREAD],[dnl - dnl Try to use the user's PTHREAD_LIBS/CFLAGS - dnl if they're available. - if test "x$PTHREAD_CFLAGS" = "x"; then - PTHREAD_CFLAGS="-D_REENTRANT" - fi - if test "x$PTHREAD_LIBS" = "x"; then - PTHREAD_LIBS="-lpthread" - fi - - dnl First try to find the real pthreads. - CAIRO_CHECK_PTHREAD( - [real_pthread], [$PTHREAD_CFLAGS], [$PTHREAD_LIBS], - [testsuite_pthread_program], - [have_real_pthread=yes], - [have_real_pthread=no]) - if test "x$have_real_pthread" != "xyes"; then - dnl Give -pthread a go. - CAIRO_CHECK_PTHREAD( - [real_pthread], [-pthread], [], - [testsuite_pthread_program], - [have_real_pthread=yes], - [have_real_pthread="no (can't link with -lpthread or -pthread)"]) - fi - PTHREAD_CFLAGS= - PTHREAD_LIBS= - - dnl Check if we can use libc's stubs in libcairo. - dnl Only do this if the user hasn't explicitly enabled - dnl pthreads, but is relying on automatic configuration. - have_pthread="no" - if test "x$enable_pthread" != "xyes"; then - CAIRO_CHECK_PTHREAD( - [pthread], [-D_REENTRANT], [], - [libcairo_pthread_program], - [have_pthread=yes], - []) - fi - - dnl Default to using the real pthreads for libcairo. - if test "x$have_pthread" != "xyes"; then - have_pthread="$have_real_pthread"; - pthread_CFLAGS="$real_pthread_CFLAGS"; - pthread_LIBS="$real_pthread_LIBS"; - fi - - dnl Tell autoconf about the results. - if test "x$have_real_pthread" = "xyes"; then - AC_DEFINE([CAIRO_HAS_REAL_PTHREAD], 1, - [Define to 1 if we have full pthread support]) - fi - if test "x$have_pthread" = "xyes"; then - AC_DEFINE([CAIRO_HAS_PTHREAD], 1, - [Define to 1 f we have minimal pthread support]) - fi - - dnl Make sure we scored some pthreads. - if test "x$enable_pthread" = "xyes" -a "x$have_pthread" != "xyes"; then - AC_MSG_ERROR([pthread requested but not found]) - fi - - dnl Set the output variables for CAIRO_ENABLE. - use_pthread="$have_pthread" - pthread_REQUIRES="" -]) diff --git a/source/libs/cairo/cairo-src/build/configure.ac.system b/source/libs/cairo/cairo-src/build/configure.ac.system deleted file mode 100644 index b9d71c8d783605ddb485b1dff5376093a5128095..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/build/configure.ac.system +++ /dev/null @@ -1,160 +0,0 @@ -dnl -dnl Non-failing checks for functions, headers, libraries, etc go here -dnl - -dnl ==================================================================== -dnl Feature checks -dnl ==================================================================== - -AM_CONDITIONAL(CROSS_COMPILING, test "x$cross_compiling" = "xyes") -CAIRO_BIGENDIAN -AC_ARG_ENABLE(atomic, - [AS_HELP_STRING([--disable-atomic], - [disable use of native atomic operations])], - [use_atomic=$enableval], [use_atomic=yes]) -AS_IF([test "x$use_atomic" = "xyes"], [ - CAIRO_CHECK_NATIVE_ATOMIC_PRIMITIVES - CAIRO_CHECK_ATOMIC_OP_NEEDS_MEMORY_BARRIER -]) -AC_CHECK_SIZEOF(void *) -AC_CHECK_SIZEOF(int) -AC_CHECK_SIZEOF(long) -AC_CHECK_SIZEOF(long long) -AC_CHECK_SIZEOF(size_t) - -AC_MSG_CHECKING([for native Win32]) -case "$host" in - *-*-mingw*) - cairo_os_win32=yes - ;; - *) - cairo_os_win32=no - ;; -esac -AC_MSG_RESULT([$cairo_os_win32]) -AM_CONDITIONAL(OS_WIN32, test "$cairo_os_win32" = "yes") - -AC_MSG_CHECKING([for Sun Solaris (non-POSIX ctime_r)]) -case "$host" in - *-*-solaris*) - CFLAGS="$CFLAGS -D_POSIX_PTHREAD_SEMANTICS" - solaris_posix_pthread=yes - ;; - *) - solaris_posix_pthread=no - ;; -esac -AC_MSG_RESULT([$solaris_posix_pthread]) - -dnl ==================================================================== -dnl Library checks -dnl ==================================================================== - -AC_CHECK_LIBM -LIBS="$LIBS $LIBM" - -AC_CHECK_LIB(rt, sched_yield) - -has_shm_open= -AC_CHECK_LIB(rt, shm_open, [ - SHM_LIBS=-lrt - has_shm_open=yes - ], [SHM_LIBS=]) -AM_CONDITIONAL(HAVE_SHM, test "x$has_shm_open" = "xyes") -AC_SUBST(SHM_LIBS) - -AC_CHECK_LIB(socket, connect, [SOCKET_LIBS=-lsocket], [SOCKET_LIBS=]) -CAIROBOILERPLATE_LIBS=$SOCKET_LIBS -AC_SUBST(CAIROBOILERPLATE_LIBS) - -dnl ==================================================================== -dnl Header/function checks -dnl ==================================================================== - -dnl check if we have a __builtin_return_address for the cairo-trace -dnl utility. -AC_MSG_CHECKING([for __builtin_return_address(0)]) -AC_TRY_COMPILE([],[__builtin_return_address(0);], - [have_builtin_return_address=yes], - [have_builtin_return_address=no]) -AC_MSG_RESULT($have_builtin_return_address) -if test "x$have_builtin_return_address" = "xyes"; then - AC_DEFINE(HAVE_BUILTIN_RETURN_ADDRESS, 1, - [Define to 1 if your compiler supports the __builtin_return_address() intrinsic.]) -fi - -dnl Checks for precise integer types -AC_CHECK_HEADERS([stdint.h inttypes.h sys/int_types.h]) -AC_CHECK_TYPES([uint64_t, uint128_t, __uint128_t]) - -dnl Check for socket support for any2ppm daemon -AC_CHECK_HEADERS([fcntl.h unistd.h signal.h sys/stat.h sys/socket.h sys/poll.h sys/un.h]) - -dnl Check for infinite loops -AC_CHECK_FUNCS([alarm]) - -dnl check for CPU affinity support -AC_CHECK_HEADERS([sched.h], [AC_CHECK_FUNCS([sched_getaffinity])]) - -dnl check for mmap support -AC_CHECK_HEADERS([sys/mman.h], [AC_CHECK_FUNCS([mmap])]) - -dnl check for clock_gettime() support -AC_CHECK_HEADERS([time.h], [AC_CHECK_FUNCS([clock_gettime])]) - -dnl check for GNU-extensions to fenv -AC_CHECK_HEADER(fenv.h, - [AC_CHECK_FUNCS(feenableexcept fedisableexcept feclearexcept)]) - -dnl check for misc headers and functions -AC_CHECK_HEADERS([libgen.h byteswap.h signal.h setjmp.h fenv.h sys/wait.h]) -AC_CHECK_FUNCS([ctime_r drand48 flockfile funlockfile getline link strndup]) - -dnl check for win32 headers (this detects mingw as well) -AC_CHECK_HEADERS([windows.h], have_windows=yes, have_windows=no) - - -dnl Possible headers for mkdir -AC_CHECK_HEADERS([sys/stat.h io.h]) -AC_CHECK_FUNC(mkdir, - [AC_MSG_CHECKING([mkdir variant]) - mkdir_variant="unknown" - save_CFLAGS="$CFLAGS" - CFLAGS=$WARN_CFLAGS - AC_TRY_COMPILE([ -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif -#ifdef HAVE_IO_H -#include <io.h> -#endif - ], - [mkdir ("hello.world", 0777)], - mkdir_variant="mkdir(path, mode)", - [AC_TRY_COMPILE([ -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif -#ifdef HAVE_IO_H -#include <io.h> -#endif - ], - [mkdir ("hello.world")], - mkdir_variant="mkdir(path)")]) - AC_MSG_RESULT([$mkdir_variant]) - CFLAGS="$save_CFLAGS" - if test "x$mkdir_variant" = "xmkdir(path, mode)"; then - AC_DEFINE(HAVE_MKDIR, 2, - [Define to non-zero if your system has mkdir, and to 2 if your version of mkdir requires a mode parameter]) - else - AC_DEFINE(HAVE_MKDIR, 1, - [Define to non-zero if your system has mkdir, and to 2 if your version of mkdir requires a mode parameter]) - fi]) - -dnl =========================================================================== -dnl -dnl Test for the tools required for building one big test binary -dnl - -AC_CHECK_FUNCS(fork waitpid raise) - diff --git a/source/libs/cairo/cairo-src/build/configure.ac.tools b/source/libs/cairo/cairo-src/build/configure.ac.tools deleted file mode 100644 index a24dbcecb913983f26d7b0915b7866d0358af7ed..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/build/configure.ac.tools +++ /dev/null @@ -1,25 +0,0 @@ - -AC_PATH_PROG(FIND, find) -AC_PATH_PROG(XARGS, xargs) - -AC_PROG_CC -AC_PROG_CPP -AC_PROG_CXX dnl required for BeOS (and cannot be a conditional dependency) -AM_PROG_CC_C_O -AC_C_INLINE - -dnl =========================================================================== - -PKG_PROG_PKG_CONFIG() -if test "x$PKG_CONFIG" = x; then - AC_MSG_ERROR([pkg-config >= $PKGCONFIG_REQUIRED required but not found (http://pkgconfig.freedesktop.org/)]) -fi - -dnl Check for recent pkg-config which supports Requires.private -case `$PKG_CONFIG --version` in -[0.?|0.?.?|0.1[0-7]|0.1[0-7].?]) PKGCONFIG_REQUIRES="Requires"; ;; -*) PKGCONFIG_REQUIRES="Requires.private"; ;; -esac - -AC_SUBST(PKGCONFIG_REQUIRES) - diff --git a/source/libs/cairo/cairo-src/build/configure.ac.version b/source/libs/cairo/cairo-src/build/configure.ac.version deleted file mode 100644 index a91cee39eef6406ca5161e920226517f0de50cff..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/build/configure.ac.version +++ /dev/null @@ -1,42 +0,0 @@ -dnl -dnl Version stuff -dnl - -dnl This macro expands to one of 'git', 'snapshot', or 'release' -m4_define([cairo_release_status], - [m4_if(m4_eval(cairo_version_micro % 2), [1], [git], - [m4_if(m4_eval(cairo_version_minor % 2), [1], [snapshot], - [release])])]) - -dnl This is the .so/dll number. 2 for cairo-1.x.x -m4_define([cairo_version_sonum], m4_eval(cairo_version_major + 1)) - -dnl The libtool shared library version stuff -m4_define([cairo_version], - m4_eval(cairo_version_major*10000 + cairo_version_minor*100 + cairo_version_micro)) -m4_if(m4_eval(cairo_version_minor % 2), [1], - [ - dnl for unstable releases - m4_define([cairo_libtool_revision], 0) - ], - [ - dnl for stable releases - m4_define([cairo_libtool_revision], cairo_version_micro) - ]) -m4_define([cairo_libtool_current], - m4_eval(cairo_version_sonum + cairo_version - cairo_libtool_revision)) -m4_define([cairo_libtool_age], - m4_eval(cairo_libtool_current - cairo_version_sonum)) - -CAIRO_VERSION_MAJOR=cairo_version_major -CAIRO_VERSION_MINOR=cairo_version_minor -CAIRO_VERSION_MICRO=cairo_version_micro -CAIRO_VERSION_SONUM=cairo_version_sonum -CAIRO_RELEASE_STATUS=cairo_release_status -CAIRO_LIBTOOL_VERSION_INFO=cairo_libtool_current:cairo_libtool_revision:cairo_libtool_age -AC_SUBST(CAIRO_VERSION_MAJOR) -AC_SUBST(CAIRO_VERSION_MINOR) -AC_SUBST(CAIRO_VERSION_MICRO) -AC_SUBST(CAIRO_VERSION_SONUM) -AC_SUBST(CAIRO_RELEASE_STATUS) -AC_SUBST(CAIRO_LIBTOOL_VERSION_INFO) diff --git a/source/libs/cairo/cairo-src/build/configure.ac.warnings b/source/libs/cairo/cairo-src/build/configure.ac.warnings deleted file mode 100644 index 96c7f6f6d03a3152faf2555ba8bb8a794e5dd400..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/build/configure.ac.warnings +++ /dev/null @@ -1,99 +0,0 @@ -dnl Use lots of warning flags with with gcc and compatible compilers - -dnl Note: if you change the following variable, the cache is automatically -dnl skipped and all flags rechecked. So there's no need to do anything -dnl else. If for any reason you need to force a recheck, just change -dnl MAYBE_WARN in an ignorable way (like adding whitespace) - -# -Wcast-align generates lots of false positive reports we need to -# cast image data from uint8_t to uin32_t. - -# -Wlogical-op causes too much noise from strcmp("literal", str) - -MAYBE_WARN="-Wall -Wextra \ --Wmissing-declarations -Werror-implicit-function-declaration \ --Wpointer-arith -Wwrite-strings -Wsign-compare -Wpacked \ --Wswitch-enum -Wmissing-format-attribute -Wvolatile-register-var \ --Wstrict-aliasing=2 -Winit-self -Wunsafe-loop-optimizations \ --Wno-missing-field-initializers -Wno-unused-parameter \ --Wno-attributes -Wno-long-long -Winline" - -MAYBE_C_SPECIFIC_WARN="-Wold-style-definition \ --Wdeclaration-after-statement -Wstrict-prototypes \ --Wmissing-prototypes -Wbad-function-cast -Wnested-externs" - -# New -Wno options should be added here -# gcc-4.4 and later accept every -Wno- option but may complain later that this -# option is unknow each time another warning happen. -# -Wunused-but-set-variable is too noisy at present -NO_WARN="unused-but-set-variable" - -dnl Sun Studio 12 likes to rag at us for abusing enums like -dnl having cairo_status_t variables hold cairo_int_status_t -dnl values. It's bad, we know. Now please be quiet. -MAYBE_WARN="$MAYBE_WARN -erroff=E_ENUM_TYPE_MISMATCH_ARG \ - -erroff=E_ENUM_TYPE_MISMATCH_OP" - -dnl We also abuse the warning-flag facility to enable other compiler -dnl options. Namely, the following: -MAYBE_WARN="$MAYBE_WARN -fno-strict-aliasing -fno-common" - -dnl Also to turn various gcc/glibc-specific preprocessor checks -MAYBE_WARN="$MAYBE_WARN -Wp,-D_FORTIFY_SOURCE=2" - -# invalidate cached value if MAYBE_WARN has changed -if test "x$cairo_cv_warn_maybe" != "x$MAYBE_WARN"; then - unset cairo_cv_warn_cflags -fi -AC_CACHE_CHECK([for supported warning flags], cairo_cv_warn_cflags, [ - echo - WARN_CFLAGS="" - - # Some warning options are not supported by all versions of - # gcc, so test all desired options against the current - # compiler. - # - # Note that there are some order dependencies - # here. Specifically, an option that disables a warning will - # have no net effect if a later option then enables that - # warnings, (perhaps implicitly). So we put some grouped - # options (-Wall and -Wextra) up front and the -Wno options - # last. - - for W in $MAYBE_WARN; do - CAIRO_CC_TRY_FLAG([$W],, [WARN_CFLAGS="$WARN_CFLAGS $W"]) - done - for W in $NO_WARN; do - CAIRO_CC_TRY_FLAG([-W$W -Wno-$W],, [WARN_CFLAGS="$WARN_CFLAGS -Wno-$W"]) - done - cairo_cv_warn_cflags=$WARN_CFLAGS - cairo_cv_warn_maybe="$MAYBE_WARN $MAYBE_C_SPECIFIC_WARN" - - AC_MSG_CHECKING([which warning flags were supported]) -]) -WARN_CFLAGS="$cairo_cv_warn_cflags" -CAIRO_CFLAGS="$CAIRO_CFLAGS $WARN_CFLAGS" - -# We only wish to enable attribute(warn_unused_result) if we can prevent -# gcc from generating thousands of warnings about the misapplication of the -# attribute to void functions and variables. -AC_CACHE_CHECK([how to enable unused result warnings], cairo_cv_warn_unused_result, [ - AC_REQUIRE([AC_PROG_GREP]) - cairo_cv_warn_unused_result="" - if echo $WARN_CFLAGS | $GREP -e '-Wno-attributes' >/dev/null; then - CAIRO_CC_TRY_FLAG_SILENT( - [-Wno-attributes], - [__attribute__((__warn_unused_result__)) void f (void) {} - __attribute__((__warn_unused_result__)) int g;], - [cairo_cv_warn_unused_result="__attribute__((__warn_unused_result__))"]) - fi -]) -AC_DEFINE_UNQUOTED([WARN_UNUSED_RESULT], [$cairo_cv_warn_unused_result], - [Define to the value your compiler uses to support the warn-unused-result attribute]) - -dnl check linker flags -AC_CACHE_CHECK([how to allow undefined symbols in shared libraries used by test suite], cairo_cv_test_undefined_ldflags, - [CAIRO_CC_TRY_FLAG_SILENT([-Wl,--allow-shlib-undefined], [], - [cairo_cv_test_undefined_ldflags="-Wl,--allow-shlib-undefined]")]) -CAIRO_TEST_UNDEFINED_LDFLAGS="$cairo_cv_test_undefined_ldflags" -AC_SUBST(CAIRO_TEST_UNDEFINED_LDFLAGS) diff --git a/source/libs/cairo/cairo-src/build/gtk-doc.m4 b/source/libs/cairo/cairo-src/build/gtk-doc.m4 deleted file mode 100644 index 36755432b50175c5e83f76841bc1bb63239ef20e..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/build/gtk-doc.m4 +++ /dev/null @@ -1,88 +0,0 @@ -dnl -*- mode: autoconf -*- - -# serial 2 - -dnl Usage: -dnl GTK_DOC_CHECK([minimum-gtk-doc-version]) -AC_DEFUN([GTK_DOC_CHECK], -[ - AC_REQUIRE([PKG_PROG_PKG_CONFIG]) - AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first - AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first - - ifelse([$1],[],[gtk_doc_requires="gtk-doc"],[gtk_doc_requires="gtk-doc >= $1"]) - AC_MSG_CHECKING([for gtk-doc]) - PKG_CHECK_EXISTS([$gtk_doc_requires],[have_gtk_doc=yes],[have_gtk_doc=no]) - AC_MSG_RESULT($have_gtk_doc) - - if test "$have_gtk_doc" = "no"; then - AC_MSG_WARN([ - You will not be able to create source packages with 'make dist' - because $gtk_doc_requires is not found.]) - fi - - dnl check for tools we added during development - dnl Use AC_CHECK_PROG to avoid the check target using an absolute path that - dnl may not be writable by the user. Currently, automake requires that the - dnl test name must end in '.test'. - dnl https://bugzilla.gnome.org/show_bug.cgi?id=701638 - AC_CHECK_PROG([GTKDOC_CHECK],[gtkdoc-check],[gtkdoc-check.test]) - AC_PATH_PROG([GTKDOC_CHECK_PATH],[gtkdoc-check]) - AC_PATH_PROGS([GTKDOC_REBASE],[gtkdoc-rebase],[true]) - AC_PATH_PROG([GTKDOC_MKPDF],[gtkdoc-mkpdf]) - - dnl for overriding the documentation installation directory - AC_ARG_WITH([html-dir], - AS_HELP_STRING([--with-html-dir=PATH], [path to installed docs]),, - [with_html_dir='${datadir}/gtk-doc/html']) - HTML_DIR="$with_html_dir" - AC_SUBST([HTML_DIR]) - - dnl enable/disable documentation building - AC_ARG_ENABLE([gtk-doc], - AS_HELP_STRING([--enable-gtk-doc], - [use gtk-doc to build documentation [[default=no]]]),, - [enable_gtk_doc=no]) - - AC_MSG_CHECKING([whether to build gtk-doc documentation]) - AC_MSG_RESULT($enable_gtk_doc) - - if test "x$enable_gtk_doc" = "xyes" && test "$have_gtk_doc" = "no"; then - AC_MSG_ERROR([ - You must have $gtk_doc_requires installed to build documentation for - $PACKAGE_NAME. Please install gtk-doc or disable building the - documentation by adding '--disable-gtk-doc' to '[$]0'.]) - fi - - dnl don't check for glib if we build glib - if test "x$PACKAGE_NAME" != "xglib"; then - dnl don't fail if someone does not have glib - PKG_CHECK_MODULES(GTKDOC_DEPS, glib-2.0 >= 2.10.0 gobject-2.0 >= 2.10.0,,[:]) - fi - - dnl enable/disable output formats - AC_ARG_ENABLE([gtk-doc-html], - AS_HELP_STRING([--enable-gtk-doc-html], - [build documentation in html format [[default=yes]]]),, - [enable_gtk_doc_html=yes]) - AC_ARG_ENABLE([gtk-doc-pdf], - AS_HELP_STRING([--enable-gtk-doc-pdf], - [build documentation in pdf format [[default=no]]]),, - [enable_gtk_doc_pdf=no]) - - if test -z "$GTKDOC_MKPDF"; then - enable_gtk_doc_pdf=no - fi - - if test -z "$AM_DEFAULT_VERBOSITY"; then - AM_DEFAULT_VERBOSITY=1 - fi - AC_SUBST([AM_DEFAULT_VERBOSITY]) - - AM_CONDITIONAL([HAVE_GTK_DOC], [test x$have_gtk_doc = xyes]) - AM_CONDITIONAL([ENABLE_GTK_DOC], [test x$enable_gtk_doc = xyes]) - AM_CONDITIONAL([GTK_DOC_BUILD_HTML], [test x$enable_gtk_doc_html = xyes]) - AM_CONDITIONAL([GTK_DOC_BUILD_PDF], [test x$enable_gtk_doc_pdf = xyes]) - AM_CONDITIONAL([GTK_DOC_USE_LIBTOOL], [test -n "$LIBTOOL"]) - AM_CONDITIONAL([GTK_DOC_USE_REBASE], [test -n "$GTKDOC_REBASE"]) -]) diff --git a/source/libs/cairo/cairo-src/cairo-version.h b/source/libs/cairo/cairo-src/cairo-version.h deleted file mode 100644 index 6c0b0902d3f7967073d096e842b1727a1a76e77d..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/cairo-version.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef CAIRO_VERSION_H -#define CAIRO_VERSION_H - -#define CAIRO_VERSION_MAJOR 1 -#define CAIRO_VERSION_MINOR 14 -#define CAIRO_VERSION_MICRO 8 - -#endif diff --git a/source/libs/cairo/cairo-src/config.h.in b/source/libs/cairo/cairo-src/config.h.in deleted file mode 100644 index 96345a8df6516368c828a991d0fece91e88ee6fe..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/config.h.in +++ /dev/null @@ -1,416 +0,0 @@ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define if building universal (internal helper macro) */ -#undef AC_APPLE_UNIVERSAL_BUILD - -/* whether memory barriers are needed around atomic operations */ -#undef ATOMIC_OP_NEEDS_MEMORY_BARRIER - -/* Define to 1 if the PDF backend can be tested (need poppler and other - dependencies for pdf2png) */ -#undef CAIRO_CAN_TEST_PDF_SURFACE - -/* Define to 1 if the PS backend can be tested (needs ghostscript) */ -#undef CAIRO_CAN_TEST_PS_SURFACE - -/* Define to 1 if the SVG backend can be tested */ -#undef CAIRO_CAN_TEST_SVG_SURFACE - -/* Define to 1 if the Win32 Printing backend can be tested (needs ghostscript) - */ -#undef CAIRO_CAN_TEST_WIN32_PRINTING_SURFACE - -/* Define to 1 if dlsym is available */ -#undef CAIRO_HAS_DLSYM - -/* Define to 1 to enable cairo's cairo-script-interpreter feature */ -#undef CAIRO_HAS_INTERPRETER - -/* Define to 1 to enable cairo's pthread feature */ -#undef CAIRO_HAS_PTHREAD - -/* Define to 1 if we have full pthread support */ -#undef CAIRO_HAS_REAL_PTHREAD - -/* Define to 1 if libspectre is available */ -#undef CAIRO_HAS_SPECTRE - -/* Define to 1 to enable cairo's symbol-lookup feature */ -#undef CAIRO_HAS_SYMBOL_LOOKUP - -/* Define to 1 to enable cairo's test surfaces feature */ -#undef CAIRO_HAS_TEST_SURFACES - -/* Define to 1 to enable cairo's cairo-trace feature */ -#undef CAIRO_HAS_TRACE - -/* Define to 1 to disable certain code paths that rely heavily on double - precision floating-point calculation */ -#undef DISABLE_SOME_FLOATING_POINT - -/* Define to 1 if your system stores words within floats with the most - significant word first */ -#undef FLOAT_WORDS_BIGENDIAN - -/* Enable pixman glyph cache */ -#undef HAS_PIXMAN_GLYPHS - -/* Define to 1 if you have the `alarm' function. */ -#undef HAVE_ALARM - -/* Define to 1 if you have the binutils development files installed */ -#undef HAVE_BFD - -/* Define to 1 if your compiler supports the __builtin_return_address() - intrinsic. */ -#undef HAVE_BUILTIN_RETURN_ADDRESS - -/* Define to 1 if you have the <byteswap.h> header file. */ -#undef HAVE_BYTESWAP_H - -/* Define to 1 if you have the `clock_gettime' function. */ -#undef HAVE_CLOCK_GETTIME - -/* Define to 1 if you have the `ctime_r' function. */ -#undef HAVE_CTIME_R - -/* Enable if your compiler supports the GCC __atomic_* atomic primitives */ -#undef HAVE_CXX11_ATOMIC_PRIMITIVES - -/* Define to 1 if you have the <dlfcn.h> header file. */ -#undef HAVE_DLFCN_H - -/* Define to 1 if you have the `drand48' function. */ -#undef HAVE_DRAND48 - -/* Define to 1 if you have the `FcFini' function. */ -#undef HAVE_FCFINI - -/* Define to 1 if you have the `FcInit' function. */ -#undef HAVE_FCINIT - -/* Define to 1 if you have the <fcntl.h> header file. */ -#undef HAVE_FCNTL_H - -/* Define to 1 if you have the `feclearexcept' function. */ -#undef HAVE_FECLEAREXCEPT - -/* Define to 1 if you have the `fedisableexcept' function. */ -#undef HAVE_FEDISABLEEXCEPT - -/* Define to 1 if you have the `feenableexcept' function. */ -#undef HAVE_FEENABLEEXCEPT - -/* Define to 1 if you have the <fenv.h> header file. */ -#undef HAVE_FENV_H - -/* Define to 1 if you have the `flockfile' function. */ -#undef HAVE_FLOCKFILE - -/* Define to 1 if you have the `fork' function. */ -#undef HAVE_FORK - -/* Define to 1 if you have the `FT_Get_X11_Font_Format' function. */ -#undef HAVE_FT_GET_X11_FONT_FORMAT - -/* Define to 1 if you have the `FT_GlyphSlot_Embolden' function. */ -#undef HAVE_FT_GLYPHSLOT_EMBOLDEN - -/* Define to 1 if you have the `FT_GlyphSlot_Oblique' function. */ -#undef HAVE_FT_GLYPHSLOT_OBLIQUE - -/* Define to 1 if you have the `FT_Library_SetLcdFilter' function. */ -#undef HAVE_FT_LIBRARY_SETLCDFILTER - -/* Define to 1 if you have the `FT_Load_Sfnt_Table' function. */ -#undef HAVE_FT_LOAD_SFNT_TABLE - -/* Define to 1 if you have the `funlockfile' function. */ -#undef HAVE_FUNLOCKFILE - -/* Whether you have gcov */ -#undef HAVE_GCOV - -/* Define to 1 if you have the `getline' function. */ -#undef HAVE_GETLINE - -/* Enable if your compiler supports the Intel __sync_* atomic primitives */ -#undef HAVE_INTEL_ATOMIC_PRIMITIVES - -/* Define to 1 if you have the <inttypes.h> header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if you have the <io.h> header file. */ -#undef HAVE_IO_H - -/* Define to 1 if you have the <libgen.h> header file. */ -#undef HAVE_LIBGEN_H - -/* Define to 1 if you have the `rt' library (-lrt). */ -#undef HAVE_LIBRT - -/* Enable if you have libatomic-ops-dev installed */ -#undef HAVE_LIB_ATOMIC_OPS - -/* Define to 1 if you have the `link' function. */ -#undef HAVE_LINK - -/* Define to 1 if you have the Valgrind lockdep tool */ -#undef HAVE_LOCKDEP - -/* Define to 1 if you have lzo available */ -#undef HAVE_LZO - -/* Define to 1 if you have the Valgrind memfault tool */ -#undef HAVE_MEMFAULT - -/* Define to 1 if you have the <memory.h> header file. */ -#undef HAVE_MEMORY_H - -/* Define to non-zero if your system has mkdir, and to 2 if your version of - mkdir requires a mode parameter */ -#undef HAVE_MKDIR - -/* Define to 1 if you have the `mmap' function. */ -#undef HAVE_MMAP - -/* Enable if you have MacOS X atomic operations */ -#undef HAVE_OS_ATOMIC_OPS - -/* Define to 1 if you have the `poppler_page_render' function. */ -#undef HAVE_POPPLER_PAGE_RENDER - -/* Define to 1 if you have the `raise' function. */ -#undef HAVE_RAISE - -/* Define to 1 if you have the `rsvg_pixbuf_from_file' function. */ -#undef HAVE_RSVG_PIXBUF_FROM_FILE - -/* Define to 1 if you have the `sched_getaffinity' function. */ -#undef HAVE_SCHED_GETAFFINITY - -/* Define to 1 if you have the <sched.h> header file. */ -#undef HAVE_SCHED_H - -/* Define to 1 if you have the <setjmp.h> header file. */ -#undef HAVE_SETJMP_H - -/* Define to 1 if you have the <signal.h> header file. */ -#undef HAVE_SIGNAL_H - -/* Define to 1 if you have the <stdint.h> header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the <stdlib.h> header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the <strings.h> header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the <string.h> header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the `strndup' function. */ -#undef HAVE_STRNDUP - -/* Define to 1 if you have the <sys/int_types.h> header file. */ -#undef HAVE_SYS_INT_TYPES_H - -/* Define to 1 if you have the <sys/ioctl.h> header file. */ -#undef HAVE_SYS_IOCTL_H - -/* Define to 1 if you have the <sys/mman.h> header file. */ -#undef HAVE_SYS_MMAN_H - -/* Define to 1 if you have the <sys/poll.h> header file. */ -#undef HAVE_SYS_POLL_H - -/* Define to 1 if you have the <sys/socket.h> header file. */ -#undef HAVE_SYS_SOCKET_H - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the <sys/types.h> header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the <sys/un.h> header file. */ -#undef HAVE_SYS_UN_H - -/* Define to 1 if you have the <sys/wait.h> header file. */ -#undef HAVE_SYS_WAIT_H - -/* Define to 1 if you have the <time.h> header file. */ -#undef HAVE_TIME_H - -/* Define to 1 if the system has the type `uint128_t'. */ -#undef HAVE_UINT128_T - -/* Define to 1 if the system has the type `uint64_t'. */ -#undef HAVE_UINT64_T - -/* Define to 1 if you have the <unistd.h> header file. */ -#undef HAVE_UNISTD_H - -/* Define to 1 if you have Valgrind */ -#undef HAVE_VALGRIND - -/* Define to 1 if you have the `waitpid' function. */ -#undef HAVE_WAITPID - -/* Define to 1 if you have the <windows.h> header file. */ -#undef HAVE_WINDOWS_H - -/* Define to 1 if you have the <X11/extensions/shmproto.h> header file. */ -#undef HAVE_X11_EXTENSIONS_SHMPROTO_H - -/* Define to 1 if you have the <X11/extensions/shmstr.h> header file. */ -#undef HAVE_X11_EXTENSIONS_SHMSTR_H - -/* Define to 1 if you have the <X11/extensions/XShm.h> header file. */ -#undef HAVE_X11_EXTENSIONS_XSHM_H - -/* Define to 1 if you have the `XRenderCreateConicalGradient' function. */ -#undef HAVE_XRENDERCREATECONICALGRADIENT - -/* Define to 1 if you have the `XRenderCreateLinearGradient' function. */ -#undef HAVE_XRENDERCREATELINEARGRADIENT - -/* Define to 1 if you have the `XRenderCreateRadialGradient' function. */ -#undef HAVE_XRENDERCREATERADIALGRADIENT - -/* Define to 1 if you have the `XRenderCreateSolidFill' function. */ -#undef HAVE_XRENDERCREATESOLIDFILL - -/* Define to 1 if you have zlib available */ -#undef HAVE_ZLIB - -/* Define to 1 if the system has the type `__uint128_t'. */ -#undef HAVE___UINT128_T - -/* Define to 1 if shared memory segments are released deferred. */ -#undef IPC_RMID_DEFERRED_RELEASE - -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ -#undef LT_OBJDIR - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the home page for this package. */ -#undef PACKAGE_URL - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* Shared library file extension */ -#undef SHARED_LIB_EXT - -/* The size of `int', as computed by sizeof. */ -#undef SIZEOF_INT - -/* The size of `long', as computed by sizeof. */ -#undef SIZEOF_LONG - -/* The size of `long long', as computed by sizeof. */ -#undef SIZEOF_LONG_LONG - -/* The size of `size_t', as computed by sizeof. */ -#undef SIZEOF_SIZE_T - -/* The size of `void *', as computed by sizeof. */ -#undef SIZEOF_VOID_P - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* Enable extensions on AIX 3, Interix. */ -#ifndef _ALL_SOURCE -# undef _ALL_SOURCE -#endif -/* Enable GNU extensions on systems that have them. */ -#ifndef _GNU_SOURCE -# undef _GNU_SOURCE -#endif -/* Enable threading extensions on Solaris. */ -#ifndef _POSIX_PTHREAD_SEMANTICS -# undef _POSIX_PTHREAD_SEMANTICS -#endif -/* Enable extensions on HP NonStop. */ -#ifndef _TANDEM_SOURCE -# undef _TANDEM_SOURCE -#endif -/* Enable general extensions on Solaris. */ -#ifndef __EXTENSIONS__ -# undef __EXTENSIONS__ -#endif - - -/* Define to the value your compiler uses to support the warn-unused-result - attribute */ -#undef WARN_UNUSED_RESULT - -/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most - significant byte first (like Motorola and SPARC, unlike Intel). */ -#if defined AC_APPLE_UNIVERSAL_BUILD -# if defined __BIG_ENDIAN__ -# define WORDS_BIGENDIAN 1 -# endif -#else -# ifndef WORDS_BIGENDIAN -# undef WORDS_BIGENDIAN -# endif -#endif - - -/* Deal with multiple architecture compiles on Mac OS X */ -#ifdef __APPLE_CC__ -#ifdef __BIG_ENDIAN__ -#define WORDS_BIGENDIAN 1 -#define FLOAT_WORDS_BIGENDIAN 1 -#else -#undef WORDS_BIGENDIAN -#undef FLOAT_WORDS_BIGENDIAN -#endif -#endif - - -/* Define to 1 if the X Window System is missing or not being used. */ -#undef X_DISPLAY_MISSING - -/* Enable large inode numbers on Mac OS X 10.5. */ -#ifndef _DARWIN_USE_64_BIT_INODE -# define _DARWIN_USE_64_BIT_INODE 1 -#endif - -/* Number of bits in a file offset, on hosts where this is settable. */ -#undef _FILE_OFFSET_BITS - -/* Define for large files, on AIX-style hosts. */ -#undef _LARGE_FILES - -/* Define to 1 if on MINIX. */ -#undef _MINIX - -/* Define to 2 if the system does not provide POSIX.1 features except with - this defined. */ -#undef _POSIX_1_SOURCE - -/* Define to 1 if you need to in order for `stat' and other things to work. */ -#undef _POSIX_SOURCE - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -#undef inline -#endif diff --git a/source/libs/cairo/cairo-src/configure.ac b/source/libs/cairo/cairo-src/configure.ac deleted file mode 100644 index 2ce19599e30964961c8585b95522a2dd80b374f2..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/configure.ac +++ /dev/null @@ -1,878 +0,0 @@ -AC_PREREQ([2.63]) -CAIRO_PARSE_VERSION -AC_INIT([cairo], - [cairo_version_major.cairo_version_minor.cairo_version_micro], - [http://bugs.freedesktop.org/enter_bug.cgi?product=cairo], - [cairo], - [http://cairographics.org/]) -AC_CONFIG_AUX_DIR(build) -AC_CONFIG_MACRO_DIR(build) -AC_USE_SYSTEM_EXTENSIONS -AC_CONFIG_SRCDIR(src/cairo.h) -AC_CONFIG_HEADERS(config.h) - -AC_CHECK_HEADERS([unistd.h sys/ioctl.h]) - -AM_INIT_AUTOMAKE([1.11 foreign -Wall no-define no-dist-gzip dist-xz]) -AM_SILENT_RULES([yes]) -m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) dnl Workaround for Automake 1.12 - -# Initialize libtool -LT_PREREQ([2.2]) -LT_INIT([win32-dll]) - -# Api documentation -GTK_DOC_CHECK([1.15],[--flavour no-tmpl]) - -AC_SYS_LARGEFILE - -dnl =========================================================================== -dnl -dnl The order of the includes here is rather important -dnl -m4_include(build/configure.ac.version) dnl macros setting up various version declares -m4_include(build/configure.ac.tools) dnl checks for tools we use -m4_include(build/configure.ac.features) dnl macros for backend/feature handling -m4_include(build/configure.ac.warnings) dnl checks for compiler warning -m4_include(build/configure.ac.system) dnl checks for system functions, headers, libs -m4_include(build/configure.ac.analysis) dnl checks for analysis tools (lcov, etc) -m4_include(build/configure.ac.noversion) dnl disable builtin libtool versioning -m4_include(build/configure.ac.pthread) dnl checks for pthreads -AC_CACHE_SAVE - -dnl =========================================================================== - -AC_CHECK_LIB(z, compress, - [AC_CHECK_HEADER(zlib.h, [ - have_libz=yes - AC_DEFINE(HAVE_ZLIB, 1, [Define to 1 if you have zlib available]) - ], - [have_libz="no (requires zlib http://www.gzip.org/zlib/)"])], - [have_libz="no (requires zlib http://www.gzip.org/zlib/)"]) - -save_LIBS="$LIBS" -AC_CHECK_LIB(lzo2, lzo2a_decompress, - [AC_CHECK_HEADER(lzo/lzo2a.h, [ - have_lzo=yes - AC_DEFINE(HAVE_LZO, 1, [Define to 1 if you have lzo available]) - lzo_LIBS="-llzo2" - ], - [have_lzo="no (requires lzpo http://www.oberhumer.com/opensource/lzo/)"])], - [have_lzo="no (requires lzpo http://www.oberhumer.com/opensource/lzo/)"]) -AC_SUBST(lzo_LIBS) -LIBS="$save_LIBS" - -AC_CHECK_LIB(dl, dlsym, - [have_dlsym=yes; have_dl=yes], - [have_dlsym=no; have_dl=no]) -if test "x$have_dlsym" = "xno"; then - AC_CHECK_FUNC(dlsym, [have_dlsym=yes], [have_dlsym=no]) -fi -AC_CHECK_HEADERS(dlfcn.h, [have_dlsym=yes], [have_dlsym=no]) -AM_CONDITIONAL(CAIRO_HAS_DL, test "x$have_dl" = "xyes") -if test "x$have_dlsym" = "xyes"; then - AC_DEFINE([CAIRO_HAS_DLSYM], 1, [Define to 1 if dlsym is available]) -fi -AM_CONDITIONAL(CAIRO_HAS_DLSYM, test "x$have_dlsym" = "xyes") - -dnl =========================================================================== - -CAIRO_ENABLE_SURFACE_BACKEND(xlib, Xlib, auto, [ - xlib_REQUIRES="x11 xext" - PKG_CHECK_MODULES(xlib, $xlib_REQUIRES, , - [xlib_REQUIRES="" - AC_PATH_XTRA - if test "x$no_x" = xyes; then - use_xlib="no (requires X development libraries)" - else - xlib_NONPKGCONFIG_LIBS="$X_PRE_LIBS $X_LIBS -lX11 -lXext $X_EXTRA_LIBS" - xlib_NONPKGCONFIG_CFLAGS=$X_CFLAGS - fi]) - - AC_CHECK_HEADER(sys/ipc.h) - AC_CHECK_HEADER(sys/shm.h) - - if test "$ac_cv_header_sys_ipc_h" = "yes" -a "$ac_cv_header_sys_shm_h" = "yes"; then - AC_MSG_CHECKING(whether shmctl IPC_RMID allowes subsequent attaches) - AC_TRY_RUN([ - #include <sys/types.h> - #include <sys/ipc.h> - #include <sys/shm.h> - int main() - { - char *shmaddr; - int id = shmget (IPC_PRIVATE, 4, IPC_CREAT | 0600); - if (id == -1) return 2; - shmaddr = shmat (id, 0, 0); - shmctl (id, IPC_RMID, 0); - if ((char*) shmat (id, 0, 0) == (char*) -1) { - shmdt (shmaddr); - return 1; - } - shmdt (shmaddr); - shmdt (shmaddr); - return 0; - } - ], - AC_DEFINE(IPC_RMID_DEFERRED_RELEASE, 1, - [Define to 1 if shared memory segments are released deferred.]) - AC_MSG_RESULT(yes), - AC_MSG_RESULT(no), - AC_MSG_RESULT(assuming no)) - fi - - AC_CHECK_HEADERS([X11/extensions/XShm.h X11/extensions/shmproto.h X11/extensions/shmstr.h], [], [], - [#include <X11/Xlibint.h> - #include <X11/Xproto.h>]) -]) - -CAIRO_ENABLE_SURFACE_BACKEND(xlib_xrender, Xlib Xrender, auto, [ - if test "x$use_xlib" != "xyes"; then - use_xlib_xrender="no (requires --enable-xlib)" - else - dnl Check for Xrender header files if the Xrender package is not installed: - xlib_xrender_BASE=cairo-xlib - xlib_xrender_REQUIRES="xrender >= 0.6" - PKG_CHECK_MODULES(xlib_xrender, $xlib_xrender_REQUIRES, , - [xlib_xrender_REQUIRES="" - old_CPPFLAGS=$CPPFLAGS - CPPFLAGS="$CPPFLAGS $xlib_CFLAGS $xlib_NONPKGCONFIG_CFLAGS" - AC_CHECK_HEADER(X11/extensions/Xrender.h, - [xlib_xrender_NONPKGCONFIG_LIBS="-lXrender"], - [use_xlib_xrender="no (requires $xlib_xrender_REQUIRES http://freedesktop.org/Software/xlibs)"], - [#include <X11/X.h>]) - CPPFLAGS=$old_CPPFLAGS - ]) - - old_CFLAGS=$CFLAGS - old_LIBS=$LIBS - CFLAGS="$CFLAGS $xlib_CFLAGS $xlib_NONPKGCONFIG_CFLAGS $xlib_xrender_CFLAGS $xlib_xrender_NONPKGCONFIG_CFLAGS" - LIBS="$LIBS $xlib_LIBS $xlib_NONPKGCONFIG_LIBS $xlib_xrender_LIBS $xlib_xrender_NONPKGCONFIG_LIBS" - AC_CHECK_FUNCS([XRenderCreateSolidFill XRenderCreateLinearGradient XRenderCreateRadialGradient XRenderCreateConicalGradient]) - CFLAGS=$old_CFLAGS - LIBS=$old_LIBS - - fi -]) - -dnl =========================================================================== - -CAIRO_ENABLE_SURFACE_BACKEND(xcb, XCB, auto, [ - xcb_REQUIRES="xcb >= 1.6 xcb-render >= 1.6" - PKG_CHECK_MODULES(xcb, $xcb_REQUIRES, , - [use_xcb="no (requires $xcb_REQUIRES http://xcb.freedesktop.org)"]) -]) - -CAIRO_ENABLE_FUNCTIONS(xlib_xcb, Xlib/XCB, no, [ - if test "x$use_xcb" = "xyes" -a "x$use_xlib" = "xyes"; then - xlib_xcb_REQUIRES="x11-xcb" - PKG_CHECK_MODULES(xlib_xcb, $xlib_xcb_REQUIRES, , - [use_xlib_xcb="no (requires $xlib_xcb_REQUIRES http://xcb.freedesktop.org)"]) - else - use_xlib_xcb="no (requires both --enable-xlib and --enable-xcb)" - fi -]) - -CAIRO_ENABLE_FUNCTIONS(xcb_shm, XCB/SHM, auto, [ - if test "x$use_xcb" = "xyes"; then - xcb_shm_REQUIRES="xcb-shm" - PKG_CHECK_MODULES(xcb_shm, $xcb_shm_REQUIRES, , - [use_xcb_shm="no (requires $xcb_shm http://xcb.freedesktop.org)"]) - else - use_xcb_shm="no (requires --enable-xcb)" - fi -]) - -dnl =========================================================================== - -CAIRO_ENABLE_SURFACE_BACKEND(qt, Qt, no, [ - qt_REQUIRES="QtGui >= 4.4.0" - PKG_CHECK_MODULES(qt, $qt_REQUIRES, , - [qt_REQUIRES="" - use_qt="no (requires Qt4 development libraries)" - ]) - qt_NONPKGCONFIG_LIBS="-lstdc++" -]) - -dnl =========================================================================== - -CAIRO_ENABLE_SURFACE_BACKEND(quartz, Quartz, auto, [ - dnl There is no pkgconfig for quartz; lets do a header check - AC_CHECK_HEADER(ApplicationServices/ApplicationServices.h, , [use_quartz="no (requires ApplicationServices framework)"]) - if test "x$use_quartz" != "xyes" ; then - dnl check for CoreGraphics as a separate framework - AC_CHECK_HEADER(CoreGraphics/CoreGraphics.h, , [use_quartz="no (requires CoreGraphics framework)"]) - quartz_LIBS="-Xlinker -framework -Xlinker CoreGraphics" - else - quartz_LIBS="-Xlinker -framework -Xlinker ApplicationServices" - fi -]) - -CAIRO_ENABLE_FONT_BACKEND(quartz_font, Quartz, auto, [ - use_quartz_font=$use_quartz -]) - -CAIRO_ENABLE_SURFACE_BACKEND(quartz_image, Quartz Image, no, [ - use_quartz_image=$use_quartz -]) - -dnl =========================================================================== - -CAIRO_ENABLE_SURFACE_BACKEND(win32, Microsoft Windows, auto, [ - if test "x$have_windows" != xyes; then - use_win32="no (requires a Win32 platform)" - fi - win32_LIBS="-lgdi32 -lmsimg32" -]) - -CAIRO_ENABLE_FONT_BACKEND(win32_font, Microsoft Windows, auto, [ - use_win32_font=$use_win32 -]) - -test_win32_printing=no -if test "x$use_win32" = "xyes"; then - AC_CHECK_PROG(GS, gs, gs) - if test "$GS"; then - AC_DEFINE([CAIRO_CAN_TEST_WIN32_PRINTING_SURFACE], 1, [Define to 1 if the Win32 Printing backend can be tested (needs ghostscript)]) - test_win32_printing="yes" - else - AC_MSG_WARN([Win32 Printing backend will not be tested since ghostscript is not available]) - test_win32_printing="no (requires ghostscript)" - fi -fi - -AM_CONDITIONAL(CAIRO_CAN_TEST_WIN32_PRINTING_SURFACE, test "x$test_win32_printing" = "xyes") - -dnl =========================================================================== - -CAIRO_ENABLE_SURFACE_BACKEND(skia, Skia, no, [ - AC_ARG_WITH([skia], - [AS_HELP_STRING([--with-skia=/path/to/skia], - [directory to find compiled skia sources])], - [skia_DIR="$withval"], - [skia_DIR="`pwd`/../skia"]) - AC_ARG_WITH([skia-build-type], - [AS_HELP_STRING([--with-skia-build-type=(Release|Debug)] - [build of skia to link with, default is Release])], - [skia_BUILD_TYPE="$withval"], - [skia_BUILD_TYPE="Release"]) - skia_NONPKGCONFIG_CFLAGS="-I$skia_DIR/include/config -I$skia_DIR/include/core -I$skia_DIR/include/effects" - if test "x$skia_BUILD_TYPE" = "xRelease"; then - skia_NONPKGCONFIG_CFLAGS="-DSK_RELEASE -DSK_CAN_USE_FLOAT $skia_NONPKGCONFIG_CFLAGS" - fi - skia_NONPKGCONFIG_LIBS="-L$skia_DIR/out/$skia_BUILD_TYPE/lib.target/ -lskia -lstdc++" - AC_SUBST(skia_DIR) -]) - -dnl =========================================================================== - -CAIRO_ENABLE_SURFACE_BACKEND(os2, OS/2, no, [ - case "$host" in - *-*-os2*) - : - ;; - *) - use_os2="no (requires an OS/2 platform)" - ;; - esac -]) - -dnl =========================================================================== - -CAIRO_ENABLE_SURFACE_BACKEND(beos, BeOS/Zeta, no, [ - case "$host" in - *-*-beos) - beos_LIBS="" - dnl Add libbe and libzeta if available - AC_CHECK_LIB(be,main,beos_LIBS="$beos_LIBS -lbe") - AC_CHECK_LIB(zeta,main,beos_LIBS="$beos_LIBS -lzeta") - ;; - *) - use_beos="no (requires a BeOS platform)" - ;; - esac -]) - -dnl =========================================================================== - -CAIRO_ENABLE_SURFACE_BACKEND(drm, DRM, no, [ - drm_REQUIRES="libudev >= 136" - PKG_CHECK_MODULES(drm, $drm_REQUIRES, , - [use_drm="no (requires $drm_REQUIRES, udev is available from git://git.kernel.org/pub/scm/linux/hotplug/udev.git)"]) -]) - -CAIRO_ENABLE_SURFACE_BACKEND(gallium, Gallium3D, no, [ - if test "x$use_drm" = "xyes"; then - AC_ARG_WITH([gallium], - [AS_HELP_STRING([--with-gallium=/path/to/mesa], - [directory to find gallium enabled mesa])], - [mesa_DIR="$withval"], - [mesa_DIR="`pwd`/../mesa"]) - gallium_DIR="$mesa_DIR/src/gallium" - gallium_NONPKGCONFIG_CFLAGS="-I$mesa_DIR/include -I$mesa_DIR/src/mesa -I$gallium_DIR/include -I$gallium_DIR/auxiliary" - gallium_NONPKGCONFIG_LIBS="-lGL" - AC_SUBST(mesa_DIR) - AC_SUBST(gallium_DIR) - else - use_gallium="no (requires --enable-drm)" - fi -]) - -dnl =========================================================================== - -CAIRO_ENABLE_FUNCTIONS(png, PNG, yes, [ - use_png=no - AC_ARG_VAR([png_REQUIRES], [module name for libpng to search for using pkg-config]) - if test "x$png_REQUIRES" = x; then - # libpng13 is GnuWin32's libpng-1.2.8 :-( - for l in libpng libpng14 libpng12 libpng13 libpng10; do - if $PKG_CONFIG --exists $l ; then - png_REQUIRES=$l - use_png=yes - break - fi - done - else - use_png=yes - fi - - if test "x$use_png" = "xyes" ; then - PKG_CHECK_MODULES(png, $png_REQUIRES, , : ) - else - AC_MSG_WARN([Could not find libpng in the pkg-config search path]) - fi -]) - -dnl =========================================================================== -CAIRO_ENABLE_SURFACE_BACKEND(gl, OpenGL, no, [ - gl_REQUIRES="gl" - PKG_CHECK_MODULES(gl, $gl_REQUIRES,, [ - dnl Fallback to searching for headers - AC_CHECK_HEADER(GL/gl.h,, [use_gl="no (gl.pc nor OpenGL headers not found)"]) - if test "x$use_gl" = "xyes"; then - gl_NONPKGCONFIG_CFLAGS= - gl_NONPKGCONFIG_LIBS="-lGL" - fi]) - - if test "x$have_dl" = "xyes" -a "x$have_dlsym" = "xyes"; then - gl_LIBS="$gl_LIBS -ldl" - fi - - need_glx_functions=yes - need_wgl_functions=yes - need_egl_functions=yes -]) - -dnl =========================================================================== -CAIRO_ENABLE_SURFACE_BACKEND(glesv2, OpenGLESv2, no, [ - glesv2_REQUIRES="glesv2" - PKG_CHECK_MODULES(glesv2, $glesv2_REQUIRES,, [ - dnl Fallback to searching for headers - AC_CHECK_HEADER(GLES2/gl2.h,, [use_glesv2="no (glesv2.pc nor OpenGL ES 2.0 headers not found)"]) - if test "x$use_glesv2" = "xyes"; then - glesv2_NONPKGCONFIG_CFLAGS= - glesv2_NONPKGCONFIG_LIBS="-lGLESv2" - fi]) - - if test "x$have_dl" = "xyes" -a "x$have_dlsym" = "xyes"; then - glesv2_LIBS="$glesv2_LIBS -ldl" - fi - - if test "x$use_glesv2" = "xyes" -a "x$use_gl" = "xyes"; then - AC_MSG_ERROR([use either --enable-gl=yes or --enable-glesv2=yes. Not both at the same time.]) - fi - - need_egl_functions=yes -]) - -dnl =========================================================================== -CAIRO_ENABLE_SURFACE_BACKEND(cogl, Cogl, no, [ - cogl_REQUIRES="cogl-2.0-experimental" - PKG_CHECK_MODULES(cogl, $cogl_REQUIRES,, [use_cogl="no"]) -]) - -dnl =========================================================================== - -CAIRO_ENABLE_SURFACE_BACKEND(directfb, directfb, no, [ - directfb_REQUIRES=directfb - PKG_CHECK_MODULES(directfb, $directfb_REQUIRES, , - [use_directfb="no (requires $directfb_REQUIRES http://www.directfb.org)"]) -]) - -dnl =========================================================================== - -CAIRO_ENABLE_SURFACE_BACKEND(vg, OpenVG, no, [ - dnl There is no pkgconfig for OpenVG; lets do a header check - AC_CHECK_HEADER(VG/openvg.h,, [use_vg="no (OpenVG headers not found)"]) - if test "x$use_vg" = "xyes"; then - vg_NONPKGCONFIG_CFLAGS= - vg_NONPKGCONFIG_LIBS="-lOpenVG" - need_egl_functions=yes - need_glx_functions=yes - fi -]) - -CAIRO_ENABLE_FUNCTIONS(egl, EGL, auto, [ - if test "x$need_egl_functions" = "xyes"; then - egl_REQUIRES="egl" - PKG_CHECK_MODULES(egl, $egl_REQUIRES, , - [egl_REQUIRES="" - AC_CHECK_HEADER(EGL/egl.h,, [use_egl="no (EGL headers not found)"]) - if test "x$use_egl" = "xyes"; then - egl_NONPKGCONFIG_CFLAGS= - egl_NONPKGCONFIG_LIBS= - save_LIBS="$LIBS" - other_egl_LIBS="" - # Temporary workaround for missing link from egl13 - AC_CHECK_LIB(csi, csi_stream_attachresource, other_egl_LIBS="-lcsi") - LIBS="$other_egl_LIBS $LIBS" - for egl_lib in EGL egl13 egl12 egl11; do - if test -z "$egl_NONPKGCONFIG_LIBS"; then - AC_CHECK_LIB($egl_lib, eglGetError, egl_NONPKGCONFIG_LIBS="-l$egl_lib") - fi - done - if test -z "$egl_NONPKGCONFIG_LIBS"; then - use_egl="no (EGL library not found)" - else - egl_NONPKGCONFIG_LIBS="$egl_NONPKGCONFIG_LIBS $other_egl_LIBS" - fi - LIBS="$save_LIBS" - fi - ]) - else - use_egl="no (not required by any backend)" - fi -]) - -CAIRO_ENABLE_FUNCTIONS(glx, GLX, auto, [ - if test "x$need_glx_functions" = "xyes"; then - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $gl_CFLAGS $gl_NONPKGCONFIG_CFLAGS" - AC_CHECK_HEADER(GL/glx.h,, [use_glx="no (GLX headers not found)"]) - glx_NONPKGCONFIG_CFLAGS= - glx_NONPKGCONFIG_LIBS="-lGL" - CFLAGS="$save_CFLAGS" - else - use_glx="no (not required by any backend)" - fi -]) - -CAIRO_ENABLE_FUNCTIONS(wgl, WGL, auto, [ - if test "x$need_wgl_functions" = "xyes"; then - AC_CHECK_HEADER(windows.h,, [use_wgl="no (WGL headers not found)"]) - else - use_wgl="no (not required by any backend)" - fi -]) - -dnl =========================================================================== - -any2ppm_cs=no -CAIRO_ENABLE_SURFACE_BACKEND(script, script, yes, [ - any2ppm_cs=yes -]) - -dnl =========================================================================== - -# We use pkg-config to look for freetype2, but fall back to -# freetype-config if it fails. We prefer pkg-config, since we can -# then just put freetype2 >= $FREETYPE_MIN_VERSION in -# Requires.private, but at least up to 2003-06-07, there was no -# freetype2.pc in the release. -# -# FreeType versions come in three forms: -# release (such as 2.1.9) -# libtool (such as 9.7.3) (returned by freetype-config and pkg-config) -# platform-specific/soname (such as 6.3.4) -# and they recommend you never use the platform-specific version -# (see docs/VERSION.DLL in freetype2 sources) -# -# Set these as appropriate: - -# release number - for information only -FREETYPE_MIN_RELEASE=2.1.9 -# libtool-specific version - this is what is checked -FREETYPE_MIN_VERSION=9.7.3 - -CAIRO_ENABLE_FONT_BACKEND(ft, FreeType, auto, [ - - PKG_CHECK_MODULES(FREETYPE, freetype2 >= $FREETYPE_MIN_VERSION, - [freetype_pkgconfig=yes], - [freetype_pkgconfig=no]) - - if test "x$freetype_pkgconfig" = "xyes"; then - ft_REQUIRES="freetype2 >= $FREETYPE_MIN_VERSION $ft_REQUIRES" - else - - if test -z "$FREETYPE_CONFIG"; then - AC_PATH_PROG(FREETYPE_CONFIG, freetype-config, no) - fi - if test "x$FREETYPE_CONFIG" = "xno" ; then - use_ft='no (freetype-config not found in path or $FREETYPE_CONFIG)' - else - AC_MSG_CHECKING(freetype2 libtool version) - - FREETYPE_VERSION=`$FREETYPE_CONFIG --version` - AX_COMPARE_VERSION([$FREETYPE_VERSION], [gt], [$FREETYPE_MIN_VERSION], - [AC_MSG_RESULT($FREETYPE_VERSION - OK) - ft_NONPKGCONFIG_CFLAGS=`$FREETYPE_CONFIG --cflags` - ft_NONPKGCONFIG_LIBS=`$FREETYPE_CONFIG --libs`], - [AC_MSG_RESULT($FREETYPE_VERSION - Too old) - use_ft="no ($FREETYPE_VERSION found; version $FREETYPE_MIN_VERSION from release $FREETYPE_MIN_RELEASE required)"]) - fi - fi - - ft_CFLAGS="$FREETYPE_CFLAGS" - ft_LIBS="$FREETYPE_LIBS" -]) - -FONTCONFIG_MIN_VERSION=2.2.95 -CAIRO_ENABLE_FONT_BACKEND(fc, Fontconfig, auto, [ - use_fc=$use_ft - if test "x$use_fc" = "xyes"; then - fc_REQUIRES="fontconfig >= $FONTCONFIG_MIN_VERSION" - PKG_CHECK_MODULES(FONTCONFIG, $fc_REQUIRES,, - [use_fc="no (requires $fc_REQUIRES)"]) - fi - fc_CFLAGS="$FONTCONFIG_CFLAGS" - fc_LIBS="$FONTCONFIG_LIBS" -]) - -if test "x$use_ft" = "xyes"; then - _save_libs="$LIBS" - _save_cflags="$CFLAGS" - LIBS="$LIBS $ft_LIBS" - CFLAGS="$CFLAGS $ft_CFLAGS" - - AC_CHECK_FUNCS(FT_Get_X11_Font_Format FT_GlyphSlot_Embolden FT_GlyphSlot_Oblique FT_Load_Sfnt_Table FT_Library_SetLcdFilter) - - LIBS="$_save_libs" - CFLAGS="$_save_cflags" -fi - -if test "x$use_fc" = "xyes"; then - CAIRO_CHECK_FUNCS_WITH_FLAGS(FcInit FcFini, [$FONTCONFIG_CFLAGS], [$FONTCONFIG_LIBS]) -fi - -dnl =========================================================================== - -CAIRO_ENABLE_SURFACE_BACKEND(ps, PostScript, yes, [ - # The ps backend requires zlib. - use_ps=$have_libz - ps_NONPKGCONFIG_LIBS=-lz -]) - -dnl =========================================================================== - -SPECTRE_VERSION_REQUIRED=0.2.0 -test_ps=no -any2ppm_ps=no -if test "x$use_ps" = "xyes"; then - AC_CHECK_PROG(GS, gs, gs) - if test "$GS"; then - AC_DEFINE([CAIRO_CAN_TEST_PS_SURFACE], 1, [Define to 1 if the PS backend can be tested (needs ghostscript)]) - test_ps="yes" - else - AC_MSG_WARN([PS backend will not be tested since ghostscript is not available]) - test_ps="no (requires ghostscript)" - fi - - libspectre_DEPENDENCY="libspectre >= $SPECTRE_VERSION_REQUIRED" - PKG_CHECK_MODULES(LIBSPECTRE, $libspectre_DEPENDENCY, - [any2ppm_ps=yes], - [test_ps="no (requires libspectre)"]) -fi - -AM_CONDITIONAL(CAIRO_CAN_TEST_PS_SURFACE, test "x$test_ps" = "xyes") -AM_CONDITIONAL(CAIRO_HAS_SPECTRE, test "x$any2ppm_ps" = "xyes") -if test "x$any2ppm_ps" = "xyes"; then - AC_DEFINE([CAIRO_HAS_SPECTRE], 1, [Define to 1 if libspectre is available]) -fi -AC_SUBST(LIBSPECTRE_CFLAGS) -AC_SUBST(LIBSPECTRE_LIBS) - -dnl =========================================================================== - -CAIRO_ENABLE_SURFACE_BACKEND(pdf, PDF, yes, [ - # The pdf backend requires zlib. - use_pdf=$have_libz - pdf_NONPKGCONFIG_LIBS=-lz -]) - -dnl =========================================================================== - -# poppler-0.17.4 fixes text-pattern and text-transform -POPPLER_VERSION_REQUIRED=0.17.4 -test_pdf=no -any2ppm_pdf=no -if test "x$use_pdf" = "xyes"; then - poppler_DEPENDENCY="poppler-glib >= $POPPLER_VERSION_REQUIRED" - PKG_CHECK_MODULES(POPPLER, $poppler_DEPENDENCY, - [CAIRO_CHECK_FUNCS_WITH_FLAGS(poppler_page_render, [$POPPLER_CFLAGS], [$POPPLER_LIBS], - [test_pdf=yes; any2ppm_pdf=yes], - [test_pdf="no (requires $poppler_DEPENDENCY)"])], - [test_pdf="no (requires $poppler_DEPENDENCY)"]) - if test "x$test_pdf" = "xyes"; then - AC_DEFINE([CAIRO_CAN_TEST_PDF_SURFACE], 1, [Define to 1 if the PDF backend can be tested (need poppler and other dependencies for pdf2png)]) - else - AC_MSG_WARN([PDF backend will not be tested since poppler >= $POPPLER_VERSION_REQUIRED is not available]) - fi -fi - -AM_CONDITIONAL(CAIRO_CAN_TEST_PDF_SURFACE, test "x$test_pdf" = "xyes") -AC_SUBST(POPPLER_CFLAGS) -AC_SUBST(POPPLER_LIBS) - -AM_CONDITIONAL(CAIRO_HAS_MULTI_PAGE_SURFACES, test "x$use_ps" = "xyes" -o "x$use_pdf" = "xyes") - -dnl =========================================================================== - -CAIRO_ENABLE_SURFACE_BACKEND(svg, SVG, yes, [ - if test "x$use_png" != "xyes"; then - use_svg="no (requires --enable-png)" - fi -]) - -LIBRSVG_VERSION_REQUIRED=2.35.0 -test_svg=no -any2ppm_svg=no -if test "x$use_svg" = "xyes"; then - librsvg_DEPENDENCY="librsvg-2.0 >= $LIBRSVG_VERSION_REQUIRED" - PKG_CHECK_MODULES(LIBRSVG, $librsvg_DEPENDENCY gdk-2.0, - [CAIRO_CHECK_FUNCS_WITH_FLAGS(rsvg_pixbuf_from_file, [$LIBRSVG_CFLAGS], [$LIBRSVG_LIBS], - [test_svg=yes; any2ppm_svg=yes], - [test_svg="no (requires $librsvg_DEPENDENCY)"])], - [test_svg="no (requires $librsvg_DEPENDENCY)"]) - if test "x$test_svg" = "xyes"; then - AC_DEFINE([CAIRO_CAN_TEST_SVG_SURFACE], 1, [Define to 1 if the SVG backend can be tested]) - else - AC_MSG_WARN([SVG backend will not be tested since librsvg >= $LIBRSVG_VERSION_REQUIRED is not available]) - fi -fi - -AM_CONDITIONAL(CAIRO_CAN_TEST_SVG_SURFACE, test "x$test_svg" = "xyes") -AC_SUBST(LIBRSVG_CFLAGS) -AC_SUBST(LIBRSVG_LIBS) - -dnl =========================================================================== - -dnl XXX make this a private feature? -CAIRO_ENABLE(test_surfaces, test surfaces, no) - -dnl =========================================================================== - -CAIRO_ENABLE_SURFACE_BACKEND(image, image, always, [ - pixman_REQUIRES="pixman-1 >= 0.30.0" - PKG_CHECK_MODULES(pixman, $pixman_REQUIRES, , - [use_image="no (requires $pixman_REQUIRES http://cairographics.org/releases/)"]) - image_REQUIRES=$pixman_REQUIRES - image_CFLAGS=$pixman_CFLAGS - image_LIBS=$pixman_LIBS -]) - -if pkg-config --exists 'pixman-1 >= 0.27.1'; then - AC_DEFINE([HAS_PIXMAN_GLYPHS], 1, [Enable pixman glyph cache]) -fi - - -dnl =========================================================================== - -CAIRO_ENABLE_SURFACE_BACKEND(mime, mime, always) -CAIRO_ENABLE_SURFACE_BACKEND(recording, recording, always) -CAIRO_ENABLE_SURFACE_BACKEND(observer, observer, always) -CAIRO_ENABLE_SURFACE_BACKEND(tee, tee, no) -CAIRO_ENABLE_SURFACE_BACKEND(xml, xml, no, [ - use_xml=$have_libz - xml_NONPKGCONFIG_LIBS=-lz -]) - -dnl =========================================================================== - -CAIRO_ENABLE_FONT_BACKEND(user, user, always) - -dnl =========================================================================== -dnl -dnl This needs to be last on our list of features so that the pthread libs and flags -dnl gets prefixed in front of everything else in CAIRO_{CFLAGS,LIBS}. -dnl -have_real_pthread=no -have_pthread=no -CAIRO_ENABLE(pthread, pthread, auto, [CAIRO_CONFIGURE_PTHREAD]) -AM_CONDITIONAL(HAVE_REAL_PTHREAD, test "x$use_pthread" = "xyes" -a "x$have_real_pthread" = "xyes") -AM_CONDITIONAL(HAVE_PTHREAD, test "x$use_pthread" = "xyes") -AC_SUBST(pthread_CFLAGS) -AC_SUBST(pthread_LIBS) -AC_SUBST(real_pthread_CFLAGS) -AC_SUBST(real_pthread_LIBS) - - -dnl =========================================================================== -dnl Build gobject integration library - -CAIRO_ENABLE_FUNCTIONS(gobject, gobject, auto, [ - gobject_REQUIRES="gobject-2.0 glib-2.0 >= 2.14" - PKG_CHECK_MODULES(GOBJECT, $gobject_REQUIRES, , - [use_gobject="no (requires $gobject_REQUIRES http://download.gnome.org/pub/GNOME/sources/glib/)"]) - gobject_NONPKGCONFIG_EXTRA_LIBS="-L\${libdir} -lcairo-gobject" -]) -dnl I'm too lazy to fix the caching properly -if test "x$use_gobject" = "xyes"; then - PKG_CHECK_MODULES(GOBJECT, $gobject_REQUIRES, : ) -fi - -dnl =========================================================================== -dnl Default to quick testing during development, but force a full test before -dnl release - -AC_ARG_ENABLE(full-testing, - AS_HELP_STRING([--enable-full-testing], - [Sets the test suite to perform full testing by default, which - will dramatically slow down make check, but is a - *requirement* before release.]), [ -if test "x$enableval" = "xyes"; then - CAIRO_TEST_MODE=full - AC_SUBST(CAIRO_TEST_MODE) -fi -]) - -dnl =========================================================================== -dnl Build the external converter if we have any of the test backends -AM_CONDITIONAL(BUILD_ANY2PPM, - test "x$any2ppm_svg" = "xyes" \ - -o "x$any2ppm_pdf" = "xyes" \ - -o "x$any2ppm_ps" = "xyes" \ - -o "x$any2ppm_cs" = "xyes") - -dnl =========================================================================== -dnl Some utilities need to dlopen the shared libraries, so they need to -dnl know how libtools will name them - -case $host in -*-*-darwin*) - SHLIB_EXT="dylib" - ;; -*) - SHLIB_EXT="so" - ;; -esac -AC_DEFINE_UNQUOTED(SHARED_LIB_EXT, "${SHLIB_EXT}", [Shared library file extension]) -AC_SUBST(SHLIB_EXT) - -dnl =========================================================================== -dnl The tracing utility requires LD_PRELOAD, so only build it for systems -dnl that are known to work. - -case $host in -*-linux*|*-*bsd*|*-solaris*|*-*-darwin*|*-dragonfly*|*-*-gnu*) - have_ld_preload="yes" - ;; -*) - have_ld_preload="no" - ;; -esac - -CAIRO_ENABLE(trace, cairo-trace, auto, [ - if test "x$have_ld_preload" != "xyes" -o \ - "x$have_libz" != "xyes" -o \ - "x$have_real_pthread" != "xyes" -o \ - "x$have_dlsym" != "xyes"; then - use_trace="no (requires dynamic linker and zlib and real pthreads)" - fi -]) - -CAIRO_ENABLE(interpreter, cairo-script-interpreter, yes, [ - if test "x$have_libz" != "xyes"; then - use_interpreter="no (requires zlib)" - fi -]) - -AC_CHECK_LIB(bfd, bfd_openr, - [AC_CHECK_HEADER(bfd.h, [have_bfd=yes], - [have_bfd=no])], [have_bfd=no]) -AC_CHECK_HEADER(libiberty.h,, [have_bfd=no]) -if test "x$have_bfd" = "xyes"; then - AC_DEFINE([HAVE_BFD], [1], [Define to 1 if you have the binutils development files installed]) - BFD_LIBS=-lbfd - AC_SUBST(BFD_LIBS) -fi - -CAIRO_ENABLE(symbol_lookup, symbol-lookup, auto, [ - if test "x$have_bfd" != "xyes"; then - use_symbol_lookup="no (requires bfd)" - fi -]) - -PKG_CHECK_MODULES(glib, glib-2.0, have_glib=yes, have_glib=no) -AC_SUBST(glib_CFLAGS) -AC_SUBST(glib_LIBS) -AM_CONDITIONAL(BUILD_SPHINX, test "x$have_glib" = "xyes" -a "x$have_windows" = "xno") - -save_LIBS="$LIBS" -AC_CHECK_LIB(rt, shm_open, shm_LIBS="-lrt") -AC_SUBST(shm_LIBS) -LIBS="$save_LIBS" - -dnl =========================================================================== - -AC_ARG_ENABLE(some-floating-point, - AS_HELP_STRING([--disable-some-floating-point], - [Disable certain code paths that rely heavily on double precision - floating-point calculation. This option can improve - performance on systems without a double precision floating-point - unit, but might degrade performance on those that do.]), [ -if test "x$enableval" = "xno"; then - # A value of 'no' for $enableval means that they want to disable, which - # means 'yes' for $disable_some_floating_point. - disable_some_floating_point=yes -fi -], [disable_some_floating_point=no]) - -AM_CONDITIONAL(DISABLE_SOME_FLOATING_POINT, - test "x$disable_some_floating_point" = "xyes") -if test "x$disable_some_floating_point" = "xyes"; then - AC_DEFINE(DISABLE_SOME_FLOATING_POINT, 1, - [Define to 1 to disable certain code paths that rely heavily on - double precision floating-point calculation]) -fi - -dnl =========================================================================== - -dnl Extra stuff we need to do when building C++ code -need_cxx="no" -AS_IF([test "x$use_skia" = "xyes"], [need_cxx="yes"]) -AS_IF([test "x$use_qt" = "xyes"], [need_cxx="yes"]) -AS_IF([test "x$use_beos" = "xyes"], [need_cxx="yes"]) - -AM_CONDITIONAL(BUILD_CXX, test "x$need_cxx" = "xyes") - -dnl =========================================================================== - -# We use GTK+ for some utility/debugging tools -PKG_CHECK_MODULES(gtk, "gtk+-2.0",have_gtk=yes, have_gtk=no) -AM_CONDITIONAL(HAVE_GTK, test "x$have_gtk" = "xyes") - -AC_CONFIG_FILES([ -Makefile -boilerplate/Makefile -src/Makefile -test/Makefile -test/pdiff/Makefile -perf/Makefile -perf/micro/Makefile -util/Makefile -util/cairo-fdr/Makefile -util/cairo-gobject/Makefile -util/cairo-missing/Makefile -util/cairo-script/Makefile -util/cairo-script/examples/Makefile -util/cairo-sphinx/Makefile -util/cairo-trace/Makefile -util/cairo-trace/cairo-trace -doc/Makefile -doc/public/Makefile -]) -AC_CONFIG_COMMANDS([cairo-trace], - [chmod a+x util/cairo-trace/cairo-trace]) - -AC_OUTPUT -CAIRO_REPORT diff --git a/source/libs/cairo/cairo-src/src/Makefile.am b/source/libs/cairo/cairo-src/src/Makefile.am deleted file mode 100644 index acf0a82810057b5fb9e4ff7bf8fe33f418f36e72..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/Makefile.am +++ /dev/null @@ -1,119 +0,0 @@ -# Note: All source files are listed in Makefile.sources. - -include $(top_srcdir)/build/Makefile.am.common -include $(srcdir)/Makefile.am.features - -EXTRA_DIST += Makefile.win32 Makefile.win32.features -#MAINTAINERCLEANFILES += $(srcdir)/Makefile.win32.features - -AM_CPPFLAGS = -I$(srcdir) $(CAIRO_CFLAGS) -AM_LDFLAGS = $(CAIRO_LDFLAGS) - -if OS_WIN32 -export_symbols = -export-symbols cairo.def -cairo_def_dependency = cairo.def -endif - -$(top_builddir)/config.h: $(top_srcdir)/config.h.in - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) config.h - -cairoincludedir = $(includedir)/cairo -cairoinclude_HEADERS = $(enabled_cairo_headers) - -lib_LTLIBRARIES = libcairo.la - -if BUILD_CXX -cairo_cxx_lib = libcairo_cxx.la -else -cairo_cxx_lib = -endif - -noinst_LTLIBRARIES = $(cairo_cxx_lib) -libcairo_cxx_la_SOURCES = \ - $(enabled_cairo_headers) \ - $(enabled_cairo_private) \ - $(enabled_cairo_cxx_sources) \ - $(NULL) -libcairo_cxx_la_LDFLAGS = $(AM_LDFLAGS) $(export_symbols) -libcairo_cxx_la_LIBADD = $(CAIRO_LIBS) -libcairo_cxx_la_DEPENDENCIES = $(cairo_def_dependency) - - -libcairo_la_SOURCES = \ - $(enabled_cairo_headers) \ - $(enabled_cairo_private) \ - $(enabled_cairo_sources) \ - $(NULL) -libcairo_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(CAIRO_LIBTOOL_VERSION_INFO) -no-undefined $(export_symbols) -libcairo_la_LIBADD = $(CAIRO_LIBS) \ - $(cairo_cxx_lib) -libcairo_la_DEPENDENCIES = $(cairo_def_dependency) $(cairo_cxx_lib) - -# Special headers -cairoinclude_HEADERS += $(top_srcdir)/cairo-version.h -libcairo_la_SOURCES += cairo-version.h -nodist_cairoinclude_HEADERS = cairo-features.h -nodist_libcairo_la_SOURCES = cairo-features.h -BUILT_SOURCES += cairo-features.h cairo-supported-features.h -DISTCLEANFILES += cairo-features.h cairo-supported-features.h -cairo-features.h cairo-supported-features.h: - cd $(top_builddir) && ./config.status src/$@ - -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = $(enabled_cairo_pkgconf) - -CLEANFILES += cairo.def -cairo.def: cairo-features.h $(enabled_cairo_headers) - @echo Generating $@ - @(echo EXPORTS; \ - (cd $(srcdir); cat $(enabled_cairo_headers) || echo 'cairo_ERROR ()' ) | \ - $(EGREP) -v '^# *include' | \ - ( cat cairo-features.h - | $(CPP) -D__cplusplus - || echo 'cairo_ERROR ()' ) | \ - $(EGREP) '^cairo_.* \(' | \ - sed -e 's/[ ].*//' | \ - sort; \ - echo LIBRARY libcairo-$(CAIRO_VERSION_SONUM).dll; \ - ) >$@ - @ ! grep -q cairo_ERROR $@ || ($(RM) $@; false) - -TESTS_ENVIRONMENT = \ - srcdir="$(srcdir)" \ - MAKE="$(MAKE) $(AM_MAKEFLAGS)" \ - all_cairo_files="$(all_cairo_files)" \ - all_cairo_headers="$(all_cairo_headers)" \ - all_cairo_private="$(all_cairo_private)" \ - all_cairo_sources="$(all_cairo_sources)" \ - enabled_cairo_headers="$(enabled_cairo_headers)" \ - enabled_cairo_private="$(enabled_cairo_private)" \ - enabled_cairo_sources="$(enabled_cairo_sources)" \ - $(NULL) -TESTS_SH = \ - check-def.sh \ - check-doc-syntax.sh \ - check-headers.sh \ - check-plt.sh \ - check-preprocessor-syntax.sh \ - $(NULL) -TESTS += $(TESTS_SH) -if CROSS_COMPILING -else -TESTS += check-link$(EXEEXT) -endif - -EXTRA_DIST += $(TESTS_SH) check-has-hidden-symbols.c check-doc-syntax.awk -check_PROGRAMS += check-link -check_link_LDADD = libcairo.la - -check: headers-standalone - -PREPROCESS_ARGS = $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) -COMPILE_ARGS = $(PREPROCESS_ARGS) $(AM_CFLAGS) $(CFLAGS) - -# The pre-processed result is used by check-{def,plt}.sh to determine whether -# cairo has been compiled with symbol hiding. -.c.i: $(cairoinclude_HEADERS) $(nodist_cairoinclude_HEADERS) cairoint.h $(top_builddir)/config.h - $(CPP) $(PREPROCESS_ARGS) $< -o $@ -.c.s: $(cairoinclude_HEADERS) $(nodist_cairoinclude_HEADERS) cairoint.h $(top_builddir)/config.h - $(CC) $(COMPILE_ARGS) $< -S -o $@ - -include $(srcdir)/Makefile.am.analysis diff --git a/source/libs/cairo/cairo-src/src/Makefile.am.analysis b/source/libs/cairo/cairo-src/src/Makefile.am.analysis deleted file mode 100644 index fab4cf7a5145ce8085b78e6aec54bd4cfe1b625c..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/Makefile.am.analysis +++ /dev/null @@ -1,35 +0,0 @@ - -SPARSE = sparse -sparse: - @echo Checking enabled sources with sparse checker - @status=true; for f in $(enabled_cairo_sources) $(enabled_cairo_cxx_sources); do \ - echo $(SPARSE) $(PREPROCESS_ARGS) $(srcdir)/$$f; \ - $(SPARSE) $(PREPROCESS_ARGS) $(srcdir)/$$f || status=false; \ - done; $$status - -SPLINT = splint -badflag -splint: - @echo Checking enabled sources with splint checker - @status=true; for f in $(enabled_cairo_sources) $(enabled_cairo_cxx_sources); do \ - echo $(SPLINT) $(PREPROCESS_ARGS) $(srcdir)/$$f; \ - $(SPLINT) $(PREPROCESS_ARGS) $(srcdir)/$$f || status=false; \ - done; $$status - -UNO = uno -uno: - @echo Checking enabled sources with uno checker - cd $(srcdir); $(UNO) $(PREPROCESS_ARGS) -DHAVE_CONFIG_H -U__GNUC__ $(enabled_cairo_sources) - -headers-standalone: $(enabled_cairo_headers) $(enabled_cairo_private) - @echo Checking that enabled public/private headers can be compiled standalone - @status=true; for f in $(enabled_cairo_headers) $(enabled_cairo_private); do \ - echo " CHECK $$f"; \ - echo "#include \"$(srcdir)/$$f\"" > headers-standalone-tmp.c; \ - echo "int main(int argc, char * argv[]) { return 0; }" >> headers-standalone-tmp.c; \ - $(COMPILE) -o headers-standalone-tmp headers-standalone-tmp.c || status=false; \ - $(RM) headers-standalone-tmp headers-standalone-tmp.c; \ - done; $$status - @touch $@ -CLEANFILES += headers-standalone - -analysis: all headers-standalone sparse splint uno diff --git a/source/libs/cairo/cairo-src/src/Makefile.am.features b/source/libs/cairo/cairo-src/src/Makefile.am.features deleted file mode 100644 index c58ac23da4ecb938fec04d7ad50e174d13497968..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/Makefile.am.features +++ /dev/null @@ -1,657 +0,0 @@ -# Generated by configure. Do not edit. - -include $(top_srcdir)/src/Makefile.sources - -supported_cairo_headers = $(cairo_headers) -unsupported_cairo_headers = -all_cairo_headers = $(cairo_headers) -all_cairo_private = $(cairo_private) -all_cairo_cxx_sources = $(cairo_cxx_sources) -all_cairo_sources = $(cairo_sources) - -enabled_cairo_headers = $(cairo_headers) -enabled_cairo_private = $(cairo_private) -enabled_cairo_cxx_sources = $(cairo_cxx_sources) -enabled_cairo_sources = $(cairo_sources) - -all_cairo_pkgconf = cairo.pc -enabled_cairo_pkgconf = cairo.pc - -supported_cairo_headers += $(cairo_xlib_headers) -all_cairo_headers += $(cairo_xlib_headers) -all_cairo_private += $(cairo_xlib_private) -all_cairo_cxx_sources += $(cairo_xlib_cxx_sources) -all_cairo_sources += $(cairo_xlib_sources) -if CAIRO_HAS_XLIB_SURFACE -enabled_cairo_headers += $(cairo_xlib_headers) -enabled_cairo_private += $(cairo_xlib_private) -enabled_cairo_cxx_sources += $(cairo_xlib_cxx_sources) -enabled_cairo_sources += $(cairo_xlib_sources) -endif -all_cairo_pkgconf += cairo-xlib.pc -if CAIRO_HAS_XLIB_SURFACE -enabled_cairo_pkgconf += cairo-xlib.pc -endif - -supported_cairo_headers += $(cairo_xlib_xrender_headers) -all_cairo_headers += $(cairo_xlib_xrender_headers) -all_cairo_private += $(cairo_xlib_xrender_private) -all_cairo_cxx_sources += $(cairo_xlib_xrender_cxx_sources) -all_cairo_sources += $(cairo_xlib_xrender_sources) -if CAIRO_HAS_XLIB_XRENDER_SURFACE -enabled_cairo_headers += $(cairo_xlib_xrender_headers) -enabled_cairo_private += $(cairo_xlib_xrender_private) -enabled_cairo_cxx_sources += $(cairo_xlib_xrender_cxx_sources) -enabled_cairo_sources += $(cairo_xlib_xrender_sources) -endif -all_cairo_pkgconf += cairo-xlib-xrender.pc -if CAIRO_HAS_XLIB_XRENDER_SURFACE -enabled_cairo_pkgconf += cairo-xlib-xrender.pc -endif - -supported_cairo_headers += $(cairo_xcb_headers) -all_cairo_headers += $(cairo_xcb_headers) -all_cairo_private += $(cairo_xcb_private) -all_cairo_cxx_sources += $(cairo_xcb_cxx_sources) -all_cairo_sources += $(cairo_xcb_sources) -if CAIRO_HAS_XCB_SURFACE -enabled_cairo_headers += $(cairo_xcb_headers) -enabled_cairo_private += $(cairo_xcb_private) -enabled_cairo_cxx_sources += $(cairo_xcb_cxx_sources) -enabled_cairo_sources += $(cairo_xcb_sources) -endif -all_cairo_pkgconf += cairo-xcb.pc -if CAIRO_HAS_XCB_SURFACE -enabled_cairo_pkgconf += cairo-xcb.pc -endif - -unsupported_cairo_headers += $(cairo_xlib_xcb_headers) -all_cairo_headers += $(cairo_xlib_xcb_headers) -all_cairo_private += $(cairo_xlib_xcb_private) -all_cairo_cxx_sources += $(cairo_xlib_xcb_cxx_sources) -all_cairo_sources += $(cairo_xlib_xcb_sources) -if CAIRO_HAS_XLIB_XCB_FUNCTIONS -enabled_cairo_headers += $(cairo_xlib_xcb_headers) -enabled_cairo_private += $(cairo_xlib_xcb_private) -enabled_cairo_cxx_sources += $(cairo_xlib_xcb_cxx_sources) -enabled_cairo_sources += $(cairo_xlib_xcb_sources) -endif -all_cairo_pkgconf += cairo-xlib-xcb.pc -if CAIRO_HAS_XLIB_XCB_FUNCTIONS -enabled_cairo_pkgconf += cairo-xlib-xcb.pc -endif - -supported_cairo_headers += $(cairo_xcb_shm_headers) -all_cairo_headers += $(cairo_xcb_shm_headers) -all_cairo_private += $(cairo_xcb_shm_private) -all_cairo_cxx_sources += $(cairo_xcb_shm_cxx_sources) -all_cairo_sources += $(cairo_xcb_shm_sources) -if CAIRO_HAS_XCB_SHM_FUNCTIONS -enabled_cairo_headers += $(cairo_xcb_shm_headers) -enabled_cairo_private += $(cairo_xcb_shm_private) -enabled_cairo_cxx_sources += $(cairo_xcb_shm_cxx_sources) -enabled_cairo_sources += $(cairo_xcb_shm_sources) -endif -all_cairo_pkgconf += cairo-xcb-shm.pc -if CAIRO_HAS_XCB_SHM_FUNCTIONS -enabled_cairo_pkgconf += cairo-xcb-shm.pc -endif - -unsupported_cairo_headers += $(cairo_qt_headers) -all_cairo_headers += $(cairo_qt_headers) -all_cairo_private += $(cairo_qt_private) -all_cairo_cxx_sources += $(cairo_qt_cxx_sources) -all_cairo_sources += $(cairo_qt_sources) -if CAIRO_HAS_QT_SURFACE -enabled_cairo_headers += $(cairo_qt_headers) -enabled_cairo_private += $(cairo_qt_private) -enabled_cairo_cxx_sources += $(cairo_qt_cxx_sources) -enabled_cairo_sources += $(cairo_qt_sources) -endif -all_cairo_pkgconf += cairo-qt.pc -if CAIRO_HAS_QT_SURFACE -enabled_cairo_pkgconf += cairo-qt.pc -endif - -supported_cairo_headers += $(cairo_quartz_headers) -all_cairo_headers += $(cairo_quartz_headers) -all_cairo_private += $(cairo_quartz_private) -all_cairo_cxx_sources += $(cairo_quartz_cxx_sources) -all_cairo_sources += $(cairo_quartz_sources) -if CAIRO_HAS_QUARTZ_SURFACE -enabled_cairo_headers += $(cairo_quartz_headers) -enabled_cairo_private += $(cairo_quartz_private) -enabled_cairo_cxx_sources += $(cairo_quartz_cxx_sources) -enabled_cairo_sources += $(cairo_quartz_sources) -endif -all_cairo_pkgconf += cairo-quartz.pc -if CAIRO_HAS_QUARTZ_SURFACE -enabled_cairo_pkgconf += cairo-quartz.pc -endif - -supported_cairo_headers += $(cairo_quartz_font_headers) -all_cairo_headers += $(cairo_quartz_font_headers) -all_cairo_private += $(cairo_quartz_font_private) -all_cairo_cxx_sources += $(cairo_quartz_font_cxx_sources) -all_cairo_sources += $(cairo_quartz_font_sources) -if CAIRO_HAS_QUARTZ_FONT -enabled_cairo_headers += $(cairo_quartz_font_headers) -enabled_cairo_private += $(cairo_quartz_font_private) -enabled_cairo_cxx_sources += $(cairo_quartz_font_cxx_sources) -enabled_cairo_sources += $(cairo_quartz_font_sources) -endif -all_cairo_pkgconf += cairo-quartz-font.pc -if CAIRO_HAS_QUARTZ_FONT -enabled_cairo_pkgconf += cairo-quartz-font.pc -endif - -unsupported_cairo_headers += $(cairo_quartz_image_headers) -all_cairo_headers += $(cairo_quartz_image_headers) -all_cairo_private += $(cairo_quartz_image_private) -all_cairo_cxx_sources += $(cairo_quartz_image_cxx_sources) -all_cairo_sources += $(cairo_quartz_image_sources) -if CAIRO_HAS_QUARTZ_IMAGE_SURFACE -enabled_cairo_headers += $(cairo_quartz_image_headers) -enabled_cairo_private += $(cairo_quartz_image_private) -enabled_cairo_cxx_sources += $(cairo_quartz_image_cxx_sources) -enabled_cairo_sources += $(cairo_quartz_image_sources) -endif -all_cairo_pkgconf += cairo-quartz-image.pc -if CAIRO_HAS_QUARTZ_IMAGE_SURFACE -enabled_cairo_pkgconf += cairo-quartz-image.pc -endif - -supported_cairo_headers += $(cairo_win32_headers) -all_cairo_headers += $(cairo_win32_headers) -all_cairo_private += $(cairo_win32_private) -all_cairo_cxx_sources += $(cairo_win32_cxx_sources) -all_cairo_sources += $(cairo_win32_sources) -if CAIRO_HAS_WIN32_SURFACE -enabled_cairo_headers += $(cairo_win32_headers) -enabled_cairo_private += $(cairo_win32_private) -enabled_cairo_cxx_sources += $(cairo_win32_cxx_sources) -enabled_cairo_sources += $(cairo_win32_sources) -endif -all_cairo_pkgconf += cairo-win32.pc -if CAIRO_HAS_WIN32_SURFACE -enabled_cairo_pkgconf += cairo-win32.pc -endif - -supported_cairo_headers += $(cairo_win32_font_headers) -all_cairo_headers += $(cairo_win32_font_headers) -all_cairo_private += $(cairo_win32_font_private) -all_cairo_cxx_sources += $(cairo_win32_font_cxx_sources) -all_cairo_sources += $(cairo_win32_font_sources) -if CAIRO_HAS_WIN32_FONT -enabled_cairo_headers += $(cairo_win32_font_headers) -enabled_cairo_private += $(cairo_win32_font_private) -enabled_cairo_cxx_sources += $(cairo_win32_font_cxx_sources) -enabled_cairo_sources += $(cairo_win32_font_sources) -endif -all_cairo_pkgconf += cairo-win32-font.pc -if CAIRO_HAS_WIN32_FONT -enabled_cairo_pkgconf += cairo-win32-font.pc -endif - -unsupported_cairo_headers += $(cairo_skia_headers) -all_cairo_headers += $(cairo_skia_headers) -all_cairo_private += $(cairo_skia_private) -all_cairo_cxx_sources += $(cairo_skia_cxx_sources) -all_cairo_sources += $(cairo_skia_sources) -if CAIRO_HAS_SKIA_SURFACE -enabled_cairo_headers += $(cairo_skia_headers) -enabled_cairo_private += $(cairo_skia_private) -enabled_cairo_cxx_sources += $(cairo_skia_cxx_sources) -enabled_cairo_sources += $(cairo_skia_sources) -endif -all_cairo_pkgconf += cairo-skia.pc -if CAIRO_HAS_SKIA_SURFACE -enabled_cairo_pkgconf += cairo-skia.pc -endif - -unsupported_cairo_headers += $(cairo_os2_headers) -all_cairo_headers += $(cairo_os2_headers) -all_cairo_private += $(cairo_os2_private) -all_cairo_cxx_sources += $(cairo_os2_cxx_sources) -all_cairo_sources += $(cairo_os2_sources) -if CAIRO_HAS_OS2_SURFACE -enabled_cairo_headers += $(cairo_os2_headers) -enabled_cairo_private += $(cairo_os2_private) -enabled_cairo_cxx_sources += $(cairo_os2_cxx_sources) -enabled_cairo_sources += $(cairo_os2_sources) -endif -all_cairo_pkgconf += cairo-os2.pc -if CAIRO_HAS_OS2_SURFACE -enabled_cairo_pkgconf += cairo-os2.pc -endif - -unsupported_cairo_headers += $(cairo_beos_headers) -all_cairo_headers += $(cairo_beos_headers) -all_cairo_private += $(cairo_beos_private) -all_cairo_cxx_sources += $(cairo_beos_cxx_sources) -all_cairo_sources += $(cairo_beos_sources) -if CAIRO_HAS_BEOS_SURFACE -enabled_cairo_headers += $(cairo_beos_headers) -enabled_cairo_private += $(cairo_beos_private) -enabled_cairo_cxx_sources += $(cairo_beos_cxx_sources) -enabled_cairo_sources += $(cairo_beos_sources) -endif -all_cairo_pkgconf += cairo-beos.pc -if CAIRO_HAS_BEOS_SURFACE -enabled_cairo_pkgconf += cairo-beos.pc -endif - -unsupported_cairo_headers += $(cairo_drm_headers) -all_cairo_headers += $(cairo_drm_headers) -all_cairo_private += $(cairo_drm_private) -all_cairo_cxx_sources += $(cairo_drm_cxx_sources) -all_cairo_sources += $(cairo_drm_sources) -if CAIRO_HAS_DRM_SURFACE -enabled_cairo_headers += $(cairo_drm_headers) -enabled_cairo_private += $(cairo_drm_private) -enabled_cairo_cxx_sources += $(cairo_drm_cxx_sources) -enabled_cairo_sources += $(cairo_drm_sources) -endif -all_cairo_pkgconf += cairo-drm.pc -if CAIRO_HAS_DRM_SURFACE -enabled_cairo_pkgconf += cairo-drm.pc -endif - -unsupported_cairo_headers += $(cairo_gallium_headers) -all_cairo_headers += $(cairo_gallium_headers) -all_cairo_private += $(cairo_gallium_private) -all_cairo_cxx_sources += $(cairo_gallium_cxx_sources) -all_cairo_sources += $(cairo_gallium_sources) -if CAIRO_HAS_GALLIUM_SURFACE -enabled_cairo_headers += $(cairo_gallium_headers) -enabled_cairo_private += $(cairo_gallium_private) -enabled_cairo_cxx_sources += $(cairo_gallium_cxx_sources) -enabled_cairo_sources += $(cairo_gallium_sources) -endif -all_cairo_pkgconf += cairo-gallium.pc -if CAIRO_HAS_GALLIUM_SURFACE -enabled_cairo_pkgconf += cairo-gallium.pc -endif - -supported_cairo_headers += $(cairo_png_headers) -all_cairo_headers += $(cairo_png_headers) -all_cairo_private += $(cairo_png_private) -all_cairo_cxx_sources += $(cairo_png_cxx_sources) -all_cairo_sources += $(cairo_png_sources) -if CAIRO_HAS_PNG_FUNCTIONS -enabled_cairo_headers += $(cairo_png_headers) -enabled_cairo_private += $(cairo_png_private) -enabled_cairo_cxx_sources += $(cairo_png_cxx_sources) -enabled_cairo_sources += $(cairo_png_sources) -endif -all_cairo_pkgconf += cairo-png.pc -if CAIRO_HAS_PNG_FUNCTIONS -enabled_cairo_pkgconf += cairo-png.pc -endif - -unsupported_cairo_headers += $(cairo_gl_headers) -all_cairo_headers += $(cairo_gl_headers) -all_cairo_private += $(cairo_gl_private) -all_cairo_cxx_sources += $(cairo_gl_cxx_sources) -all_cairo_sources += $(cairo_gl_sources) -if CAIRO_HAS_GL_SURFACE -enabled_cairo_headers += $(cairo_gl_headers) -enabled_cairo_private += $(cairo_gl_private) -enabled_cairo_cxx_sources += $(cairo_gl_cxx_sources) -enabled_cairo_sources += $(cairo_gl_sources) -endif -all_cairo_pkgconf += cairo-gl.pc -if CAIRO_HAS_GL_SURFACE -enabled_cairo_pkgconf += cairo-gl.pc -endif - -unsupported_cairo_headers += $(cairo_glesv2_headers) -all_cairo_headers += $(cairo_glesv2_headers) -all_cairo_private += $(cairo_glesv2_private) -all_cairo_cxx_sources += $(cairo_glesv2_cxx_sources) -all_cairo_sources += $(cairo_glesv2_sources) -if CAIRO_HAS_GLESV2_SURFACE -enabled_cairo_headers += $(cairo_glesv2_headers) -enabled_cairo_private += $(cairo_glesv2_private) -enabled_cairo_cxx_sources += $(cairo_glesv2_cxx_sources) -enabled_cairo_sources += $(cairo_glesv2_sources) -endif -all_cairo_pkgconf += cairo-glesv2.pc -if CAIRO_HAS_GLESV2_SURFACE -enabled_cairo_pkgconf += cairo-glesv2.pc -endif - -unsupported_cairo_headers += $(cairo_cogl_headers) -all_cairo_headers += $(cairo_cogl_headers) -all_cairo_private += $(cairo_cogl_private) -all_cairo_cxx_sources += $(cairo_cogl_cxx_sources) -all_cairo_sources += $(cairo_cogl_sources) -if CAIRO_HAS_COGL_SURFACE -enabled_cairo_headers += $(cairo_cogl_headers) -enabled_cairo_private += $(cairo_cogl_private) -enabled_cairo_cxx_sources += $(cairo_cogl_cxx_sources) -enabled_cairo_sources += $(cairo_cogl_sources) -endif -all_cairo_pkgconf += cairo-cogl.pc -if CAIRO_HAS_COGL_SURFACE -enabled_cairo_pkgconf += cairo-cogl.pc -endif - -unsupported_cairo_headers += $(cairo_directfb_headers) -all_cairo_headers += $(cairo_directfb_headers) -all_cairo_private += $(cairo_directfb_private) -all_cairo_cxx_sources += $(cairo_directfb_cxx_sources) -all_cairo_sources += $(cairo_directfb_sources) -if CAIRO_HAS_DIRECTFB_SURFACE -enabled_cairo_headers += $(cairo_directfb_headers) -enabled_cairo_private += $(cairo_directfb_private) -enabled_cairo_cxx_sources += $(cairo_directfb_cxx_sources) -enabled_cairo_sources += $(cairo_directfb_sources) -endif -all_cairo_pkgconf += cairo-directfb.pc -if CAIRO_HAS_DIRECTFB_SURFACE -enabled_cairo_pkgconf += cairo-directfb.pc -endif - -unsupported_cairo_headers += $(cairo_vg_headers) -all_cairo_headers += $(cairo_vg_headers) -all_cairo_private += $(cairo_vg_private) -all_cairo_cxx_sources += $(cairo_vg_cxx_sources) -all_cairo_sources += $(cairo_vg_sources) -if CAIRO_HAS_VG_SURFACE -enabled_cairo_headers += $(cairo_vg_headers) -enabled_cairo_private += $(cairo_vg_private) -enabled_cairo_cxx_sources += $(cairo_vg_cxx_sources) -enabled_cairo_sources += $(cairo_vg_sources) -endif -all_cairo_pkgconf += cairo-vg.pc -if CAIRO_HAS_VG_SURFACE -enabled_cairo_pkgconf += cairo-vg.pc -endif - -supported_cairo_headers += $(cairo_egl_headers) -all_cairo_headers += $(cairo_egl_headers) -all_cairo_private += $(cairo_egl_private) -all_cairo_cxx_sources += $(cairo_egl_cxx_sources) -all_cairo_sources += $(cairo_egl_sources) -if CAIRO_HAS_EGL_FUNCTIONS -enabled_cairo_headers += $(cairo_egl_headers) -enabled_cairo_private += $(cairo_egl_private) -enabled_cairo_cxx_sources += $(cairo_egl_cxx_sources) -enabled_cairo_sources += $(cairo_egl_sources) -endif -all_cairo_pkgconf += cairo-egl.pc -if CAIRO_HAS_EGL_FUNCTIONS -enabled_cairo_pkgconf += cairo-egl.pc -endif - -supported_cairo_headers += $(cairo_glx_headers) -all_cairo_headers += $(cairo_glx_headers) -all_cairo_private += $(cairo_glx_private) -all_cairo_cxx_sources += $(cairo_glx_cxx_sources) -all_cairo_sources += $(cairo_glx_sources) -if CAIRO_HAS_GLX_FUNCTIONS -enabled_cairo_headers += $(cairo_glx_headers) -enabled_cairo_private += $(cairo_glx_private) -enabled_cairo_cxx_sources += $(cairo_glx_cxx_sources) -enabled_cairo_sources += $(cairo_glx_sources) -endif -all_cairo_pkgconf += cairo-glx.pc -if CAIRO_HAS_GLX_FUNCTIONS -enabled_cairo_pkgconf += cairo-glx.pc -endif - -supported_cairo_headers += $(cairo_wgl_headers) -all_cairo_headers += $(cairo_wgl_headers) -all_cairo_private += $(cairo_wgl_private) -all_cairo_cxx_sources += $(cairo_wgl_cxx_sources) -all_cairo_sources += $(cairo_wgl_sources) -if CAIRO_HAS_WGL_FUNCTIONS -enabled_cairo_headers += $(cairo_wgl_headers) -enabled_cairo_private += $(cairo_wgl_private) -enabled_cairo_cxx_sources += $(cairo_wgl_cxx_sources) -enabled_cairo_sources += $(cairo_wgl_sources) -endif -all_cairo_pkgconf += cairo-wgl.pc -if CAIRO_HAS_WGL_FUNCTIONS -enabled_cairo_pkgconf += cairo-wgl.pc -endif - -supported_cairo_headers += $(cairo_script_headers) -all_cairo_headers += $(cairo_script_headers) -all_cairo_private += $(cairo_script_private) -all_cairo_cxx_sources += $(cairo_script_cxx_sources) -all_cairo_sources += $(cairo_script_sources) -if CAIRO_HAS_SCRIPT_SURFACE -enabled_cairo_headers += $(cairo_script_headers) -enabled_cairo_private += $(cairo_script_private) -enabled_cairo_cxx_sources += $(cairo_script_cxx_sources) -enabled_cairo_sources += $(cairo_script_sources) -endif -all_cairo_pkgconf += cairo-script.pc -if CAIRO_HAS_SCRIPT_SURFACE -enabled_cairo_pkgconf += cairo-script.pc -endif - -supported_cairo_headers += $(cairo_ft_headers) -all_cairo_headers += $(cairo_ft_headers) -all_cairo_private += $(cairo_ft_private) -all_cairo_cxx_sources += $(cairo_ft_cxx_sources) -all_cairo_sources += $(cairo_ft_sources) -if CAIRO_HAS_FT_FONT -enabled_cairo_headers += $(cairo_ft_headers) -enabled_cairo_private += $(cairo_ft_private) -enabled_cairo_cxx_sources += $(cairo_ft_cxx_sources) -enabled_cairo_sources += $(cairo_ft_sources) -endif -all_cairo_pkgconf += cairo-ft.pc -if CAIRO_HAS_FT_FONT -enabled_cairo_pkgconf += cairo-ft.pc -endif - -supported_cairo_headers += $(cairo_fc_headers) -all_cairo_headers += $(cairo_fc_headers) -all_cairo_private += $(cairo_fc_private) -all_cairo_cxx_sources += $(cairo_fc_cxx_sources) -all_cairo_sources += $(cairo_fc_sources) -if CAIRO_HAS_FC_FONT -enabled_cairo_headers += $(cairo_fc_headers) -enabled_cairo_private += $(cairo_fc_private) -enabled_cairo_cxx_sources += $(cairo_fc_cxx_sources) -enabled_cairo_sources += $(cairo_fc_sources) -endif -all_cairo_pkgconf += cairo-fc.pc -if CAIRO_HAS_FC_FONT -enabled_cairo_pkgconf += cairo-fc.pc -endif - -supported_cairo_headers += $(cairo_ps_headers) -all_cairo_headers += $(cairo_ps_headers) -all_cairo_private += $(cairo_ps_private) -all_cairo_cxx_sources += $(cairo_ps_cxx_sources) -all_cairo_sources += $(cairo_ps_sources) -if CAIRO_HAS_PS_SURFACE -enabled_cairo_headers += $(cairo_ps_headers) -enabled_cairo_private += $(cairo_ps_private) -enabled_cairo_cxx_sources += $(cairo_ps_cxx_sources) -enabled_cairo_sources += $(cairo_ps_sources) -endif -all_cairo_pkgconf += cairo-ps.pc -if CAIRO_HAS_PS_SURFACE -enabled_cairo_pkgconf += cairo-ps.pc -endif - -supported_cairo_headers += $(cairo_pdf_headers) -all_cairo_headers += $(cairo_pdf_headers) -all_cairo_private += $(cairo_pdf_private) -all_cairo_cxx_sources += $(cairo_pdf_cxx_sources) -all_cairo_sources += $(cairo_pdf_sources) -if CAIRO_HAS_PDF_SURFACE -enabled_cairo_headers += $(cairo_pdf_headers) -enabled_cairo_private += $(cairo_pdf_private) -enabled_cairo_cxx_sources += $(cairo_pdf_cxx_sources) -enabled_cairo_sources += $(cairo_pdf_sources) -endif -all_cairo_pkgconf += cairo-pdf.pc -if CAIRO_HAS_PDF_SURFACE -enabled_cairo_pkgconf += cairo-pdf.pc -endif - -supported_cairo_headers += $(cairo_svg_headers) -all_cairo_headers += $(cairo_svg_headers) -all_cairo_private += $(cairo_svg_private) -all_cairo_cxx_sources += $(cairo_svg_cxx_sources) -all_cairo_sources += $(cairo_svg_sources) -if CAIRO_HAS_SVG_SURFACE -enabled_cairo_headers += $(cairo_svg_headers) -enabled_cairo_private += $(cairo_svg_private) -enabled_cairo_cxx_sources += $(cairo_svg_cxx_sources) -enabled_cairo_sources += $(cairo_svg_sources) -endif -all_cairo_pkgconf += cairo-svg.pc -if CAIRO_HAS_SVG_SURFACE -enabled_cairo_pkgconf += cairo-svg.pc -endif - -all_cairo_private += $(cairo_test_surfaces_private) $(cairo_test_surfaces_headers) -all_cairo_cxx_sources += $(cairo_test_surfaces_cxx_sources) -all_cairo_sources += $(cairo_test_surfaces_sources) -if CAIRO_HAS_TEST_SURFACES -enabled_cairo_private += $(cairo_test_surfaces_private) $(cairo_test_surfaces_headers) -enabled_cairo_cxx_sources += $(cairo_test_surfaces_cxx_sources) -enabled_cairo_sources += $(cairo_test_surfaces_sources) -endif - -supported_cairo_headers += $(cairo_image_headers) -all_cairo_headers += $(cairo_image_headers) -all_cairo_private += $(cairo_image_private) -all_cairo_cxx_sources += $(cairo_image_cxx_sources) -all_cairo_sources += $(cairo_image_sources) -enabled_cairo_headers += $(cairo_image_headers) -enabled_cairo_private += $(cairo_image_private) -enabled_cairo_cxx_sources += $(cairo_image_cxx_sources) -enabled_cairo_sources += $(cairo_image_sources) - -supported_cairo_headers += $(cairo_mime_headers) -all_cairo_headers += $(cairo_mime_headers) -all_cairo_private += $(cairo_mime_private) -all_cairo_cxx_sources += $(cairo_mime_cxx_sources) -all_cairo_sources += $(cairo_mime_sources) -enabled_cairo_headers += $(cairo_mime_headers) -enabled_cairo_private += $(cairo_mime_private) -enabled_cairo_cxx_sources += $(cairo_mime_cxx_sources) -enabled_cairo_sources += $(cairo_mime_sources) - -supported_cairo_headers += $(cairo_recording_headers) -all_cairo_headers += $(cairo_recording_headers) -all_cairo_private += $(cairo_recording_private) -all_cairo_cxx_sources += $(cairo_recording_cxx_sources) -all_cairo_sources += $(cairo_recording_sources) -enabled_cairo_headers += $(cairo_recording_headers) -enabled_cairo_private += $(cairo_recording_private) -enabled_cairo_cxx_sources += $(cairo_recording_cxx_sources) -enabled_cairo_sources += $(cairo_recording_sources) - -supported_cairo_headers += $(cairo_observer_headers) -all_cairo_headers += $(cairo_observer_headers) -all_cairo_private += $(cairo_observer_private) -all_cairo_cxx_sources += $(cairo_observer_cxx_sources) -all_cairo_sources += $(cairo_observer_sources) -enabled_cairo_headers += $(cairo_observer_headers) -enabled_cairo_private += $(cairo_observer_private) -enabled_cairo_cxx_sources += $(cairo_observer_cxx_sources) -enabled_cairo_sources += $(cairo_observer_sources) - -unsupported_cairo_headers += $(cairo_tee_headers) -all_cairo_headers += $(cairo_tee_headers) -all_cairo_private += $(cairo_tee_private) -all_cairo_cxx_sources += $(cairo_tee_cxx_sources) -all_cairo_sources += $(cairo_tee_sources) -if CAIRO_HAS_TEE_SURFACE -enabled_cairo_headers += $(cairo_tee_headers) -enabled_cairo_private += $(cairo_tee_private) -enabled_cairo_cxx_sources += $(cairo_tee_cxx_sources) -enabled_cairo_sources += $(cairo_tee_sources) -endif -all_cairo_pkgconf += cairo-tee.pc -if CAIRO_HAS_TEE_SURFACE -enabled_cairo_pkgconf += cairo-tee.pc -endif - -unsupported_cairo_headers += $(cairo_xml_headers) -all_cairo_headers += $(cairo_xml_headers) -all_cairo_private += $(cairo_xml_private) -all_cairo_cxx_sources += $(cairo_xml_cxx_sources) -all_cairo_sources += $(cairo_xml_sources) -if CAIRO_HAS_XML_SURFACE -enabled_cairo_headers += $(cairo_xml_headers) -enabled_cairo_private += $(cairo_xml_private) -enabled_cairo_cxx_sources += $(cairo_xml_cxx_sources) -enabled_cairo_sources += $(cairo_xml_sources) -endif -all_cairo_pkgconf += cairo-xml.pc -if CAIRO_HAS_XML_SURFACE -enabled_cairo_pkgconf += cairo-xml.pc -endif - -supported_cairo_headers += $(cairo_user_headers) -all_cairo_headers += $(cairo_user_headers) -all_cairo_private += $(cairo_user_private) -all_cairo_cxx_sources += $(cairo_user_cxx_sources) -all_cairo_sources += $(cairo_user_sources) -enabled_cairo_headers += $(cairo_user_headers) -enabled_cairo_private += $(cairo_user_private) -enabled_cairo_cxx_sources += $(cairo_user_cxx_sources) -enabled_cairo_sources += $(cairo_user_sources) - -all_cairo_private += $(cairo_pthread_private) $(cairo_pthread_headers) -all_cairo_cxx_sources += $(cairo_pthread_cxx_sources) -all_cairo_sources += $(cairo_pthread_sources) -if CAIRO_HAS_PTHREAD -enabled_cairo_private += $(cairo_pthread_private) $(cairo_pthread_headers) -enabled_cairo_cxx_sources += $(cairo_pthread_cxx_sources) -enabled_cairo_sources += $(cairo_pthread_sources) -endif - -supported_cairo_headers += $(cairo_gobject_headers) -all_cairo_headers += $(cairo_gobject_headers) -all_cairo_private += $(cairo_gobject_private) -all_cairo_cxx_sources += $(cairo_gobject_cxx_sources) -all_cairo_sources += $(cairo_gobject_sources) -if CAIRO_HAS_GOBJECT_FUNCTIONS -enabled_cairo_headers += $(cairo_gobject_headers) -enabled_cairo_private += $(cairo_gobject_private) -enabled_cairo_cxx_sources += $(cairo_gobject_cxx_sources) -enabled_cairo_sources += $(cairo_gobject_sources) -endif -all_cairo_pkgconf += cairo-gobject.pc -if CAIRO_HAS_GOBJECT_FUNCTIONS -enabled_cairo_pkgconf += cairo-gobject.pc -endif - -all_cairo_private += $(cairo_trace_private) $(cairo_trace_headers) -all_cairo_cxx_sources += $(cairo_trace_cxx_sources) -all_cairo_sources += $(cairo_trace_sources) -if CAIRO_HAS_TRACE -enabled_cairo_private += $(cairo_trace_private) $(cairo_trace_headers) -enabled_cairo_cxx_sources += $(cairo_trace_cxx_sources) -enabled_cairo_sources += $(cairo_trace_sources) -endif - -all_cairo_private += $(cairo_interpreter_private) $(cairo_interpreter_headers) -all_cairo_cxx_sources += $(cairo_interpreter_cxx_sources) -all_cairo_sources += $(cairo_interpreter_sources) -if CAIRO_HAS_INTERPRETER -enabled_cairo_private += $(cairo_interpreter_private) $(cairo_interpreter_headers) -enabled_cairo_cxx_sources += $(cairo_interpreter_cxx_sources) -enabled_cairo_sources += $(cairo_interpreter_sources) -endif - -all_cairo_private += $(cairo_symbol_lookup_private) $(cairo_symbol_lookup_headers) -all_cairo_cxx_sources += $(cairo_symbol_lookup_cxx_sources) -all_cairo_sources += $(cairo_symbol_lookup_sources) -if CAIRO_HAS_SYMBOL_LOOKUP -enabled_cairo_private += $(cairo_symbol_lookup_private) $(cairo_symbol_lookup_headers) -enabled_cairo_cxx_sources += $(cairo_symbol_lookup_cxx_sources) -enabled_cairo_sources += $(cairo_symbol_lookup_sources) -endif diff --git a/source/libs/cairo/cairo-src/src/Makefile.sources b/source/libs/cairo/cairo-src/src/Makefile.sources deleted file mode 100644 index fac24d79d8af2b77b7b4cd34d828a953aac6b687..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/Makefile.sources +++ /dev/null @@ -1,472 +0,0 @@ -# Makefile.sources -# -# This file is the canonical location listing all the source files used -# to build the cairo library. Every source file is categorized as one of: -# -# * public header file -# * private header file (must end in -private.h except for cairoint.h) -# * source code file -# -# Every source file should be specified exactly once, grouped with the -# feature that uses the source file. If more than one feature use the -# file (like pdf_operators or font_subset files), the files should be -# appended to to the base cairo files, and the code inside them -# enabled/disabled using C preprocessor macros defined in cairoint.h. -# See how pdf_operators or font_subset are handled. -# -# The sources are picked up according to the configured features -# by the generated file Makefile.am.features or Makefile.win32.features. -# -# These are a few special source files. Those are not included in this -# file to not confuse build systems. Each build system must handle them -# separately. These files include: -# -# * cairo-features.h: -# This file is generated by configure and includes macros signifying -# which features are enabled. This file should be installed like -# other public headers, but should NOT be distributed in the cairo -# distribution. -# -# * cairo-version.h: -# This is a dummy header file used during the build, but it should -# NOT be installed. Its sole purpose is to make sure changes in the -# cairo version do not trigger a full rebuild of the library, but -# just the functions actually using the version information. -# -# * $(top_srcdir)/cairo-version.h: -# This is the real file holding the cairo version number. This file -# should be installed like other public headers. This is used during -# the build by cairo-version.c only. -# -# * cairo-supported-features.h: -# This file is generated by configure and includes macros signifying -# all supported features. This is used by gtk-doc to generate -# documentation for all those macros, enabled or not. -# This file is NOT used during the build of the library and should -# NOT be installed or distributed. -# -# Please follow the strict syntax of this file, including keeping file -# lists sorted. -# - -cairo_headers = cairo.h cairo-deprecated.h -cairo_private = \ - cairoint.h \ - cairo-analysis-surface-private.h \ - cairo-arc-private.h \ - cairo-array-private.h \ - cairo-atomic-private.h \ - cairo-backend-private.h \ - cairo-box-inline.h \ - cairo-boxes-private.h \ - cairo-cache-private.h \ - cairo-clip-inline.h \ - cairo-clip-private.h \ - cairo-combsort-inline.h \ - cairo-compiler-private.h \ - cairo-compositor-private.h \ - cairo-contour-inline.h \ - cairo-contour-private.h \ - cairo-composite-rectangles-private.h \ - cairo-damage-private.h \ - cairo-default-context-private.h \ - cairo-device-private.h \ - cairo-error-inline.h \ - cairo-error-private.h \ - cairo-fixed-private.h \ - cairo-fixed-type-private.h \ - cairo-freelist-private.h \ - cairo-freelist-type-private.h \ - cairo-freed-pool-private.h \ - cairo-fontconfig-private.h \ - cairo-gstate-private.h \ - cairo-hash-private.h \ - cairo-image-info-private.h \ - cairo-image-surface-inline.h \ - cairo-image-surface-private.h \ - cairo-line-inline.h \ - cairo-line-private.h \ - cairo-list-inline.h \ - cairo-list-private.h \ - cairo-malloc-private.h \ - cairo-mempool-private.h \ - cairo-mutex-impl-private.h \ - cairo-mutex-list-private.h \ - cairo-mutex-private.h \ - cairo-mutex-type-private.h \ - cairo-output-stream-private.h \ - cairo-paginated-private.h \ - cairo-paginated-surface-private.h \ - cairo-path-fixed-private.h \ - cairo-path-private.h \ - cairo-pattern-inline.h \ - cairo-pattern-private.h \ - cairo-pixman-private.h \ - cairo-private.h \ - cairo-recording-surface-inline.h \ - cairo-recording-surface-private.h \ - cairo-reference-count-private.h \ - cairo-region-private.h \ - cairo-rtree-private.h \ - cairo-scaled-font-private.h \ - cairo-slope-private.h \ - cairo-spans-private.h \ - cairo-spans-compositor-private.h \ - cairo-stroke-dash-private.h \ - cairo-surface-inline.h \ - cairo-surface-private.h \ - cairo-surface-backend-private.h \ - cairo-surface-clipper-private.h \ - cairo-surface-fallback-private.h \ - cairo-surface-observer-inline.h \ - cairo-surface-observer-private.h \ - cairo-surface-offset-private.h \ - cairo-surface-subsurface-inline.h \ - cairo-surface-subsurface-private.h \ - cairo-surface-snapshot-inline.h \ - cairo-surface-snapshot-private.h \ - cairo-surface-wrapper-private.h \ - cairo-time-private.h \ - cairo-types-private.h \ - cairo-traps-private.h \ - cairo-tristrip-private.h \ - cairo-user-font-private.h \ - cairo-wideint-private.h \ - cairo-wideint-type-private.h \ - $(NULL) -cairo_sources = \ - cairo-analysis-surface.c \ - cairo-arc.c \ - cairo-array.c \ - cairo-atomic.c \ - cairo-base64-stream.c \ - cairo-base85-stream.c \ - cairo-bentley-ottmann.c \ - cairo-bentley-ottmann-rectangular.c \ - cairo-bentley-ottmann-rectilinear.c \ - cairo-botor-scan-converter.c \ - cairo-boxes.c \ - cairo-boxes-intersect.c \ - cairo.c \ - cairo-cache.c \ - cairo-clip.c \ - cairo-clip-boxes.c \ - cairo-clip-polygon.c \ - cairo-clip-region.c \ - cairo-clip-surface.c \ - cairo-color.c \ - cairo-composite-rectangles.c \ - cairo-compositor.c \ - cairo-contour.c \ - cairo-damage.c \ - cairo-debug.c \ - cairo-default-context.c \ - cairo-device.c \ - cairo-error.c \ - cairo-fallback-compositor.c \ - cairo-fixed.c \ - cairo-font-face.c \ - cairo-font-face-twin.c \ - cairo-font-face-twin-data.c \ - cairo-font-options.c \ - cairo-freelist.c \ - cairo-freed-pool.c \ - cairo-gstate.c \ - cairo-hash.c \ - cairo-hull.c \ - cairo-image-compositor.c \ - cairo-image-info.c \ - cairo-image-source.c \ - cairo-image-surface.c \ - cairo-line.c \ - cairo-lzw.c \ - cairo-matrix.c \ - cairo-mask-compositor.c \ - cairo-mesh-pattern-rasterizer.c \ - cairo-mempool.c \ - cairo-misc.c \ - cairo-mono-scan-converter.c \ - cairo-mutex.c \ - cairo-no-compositor.c \ - cairo-observer.c \ - cairo-output-stream.c \ - cairo-paginated-surface.c \ - cairo-path-bounds.c \ - cairo-path.c \ - cairo-path-fill.c \ - cairo-path-fixed.c \ - cairo-path-in-fill.c \ - cairo-path-stroke.c \ - cairo-path-stroke-boxes.c \ - cairo-path-stroke-polygon.c \ - cairo-path-stroke-traps.c \ - cairo-path-stroke-tristrip.c \ - cairo-pattern.c \ - cairo-pen.c \ - cairo-polygon.c \ - cairo-polygon-intersect.c \ - cairo-polygon-reduce.c \ - cairo-raster-source-pattern.c \ - cairo-recording-surface.c \ - cairo-rectangle.c \ - cairo-rectangular-scan-converter.c \ - cairo-region.c \ - cairo-rtree.c \ - cairo-scaled-font.c \ - cairo-shape-mask-compositor.c \ - cairo-slope.c \ - cairo-spans.c \ - cairo-spans-compositor.c \ - cairo-spline.c \ - cairo-stroke-dash.c \ - cairo-stroke-style.c \ - cairo-surface.c \ - cairo-surface-clipper.c \ - cairo-surface-fallback.c \ - cairo-surface-observer.c \ - cairo-surface-offset.c \ - cairo-surface-snapshot.c \ - cairo-surface-subsurface.c \ - cairo-surface-wrapper.c \ - cairo-time.c \ - cairo-tor-scan-converter.c \ - cairo-tor22-scan-converter.c \ - cairo-clip-tor-scan-converter.c \ - cairo-toy-font-face.c \ - cairo-traps.c \ - cairo-tristrip.c \ - cairo-traps-compositor.c \ - cairo-unicode.c \ - cairo-user-font.c \ - cairo-version.c \ - cairo-wideint.c \ - $(NULL) - -_cairo_font_subset_private = \ - cairo-scaled-font-subsets-private.h \ - cairo-truetype-subset-private.h \ - cairo-type1-private.h \ - cairo-type3-glyph-surface-private.h \ - $(NULL) -_cairo_font_subset_sources = \ - cairo-cff-subset.c \ - cairo-scaled-font-subsets.c \ - cairo-truetype-subset.c \ - cairo-type1-fallback.c \ - cairo-type1-glyph-names.c \ - cairo-type1-subset.c \ - cairo-type3-glyph-surface.c \ - $(NULL) -cairo_private += $(_cairo_font_subset_private) -cairo_sources += $(_cairo_font_subset_sources) - -cairo_egl_sources = -cairo_glx_sources = -cairo_wgl_sources = - -_cairo_pdf_operators_private = cairo-pdf-operators-private.h cairo-pdf-shading-private.h -_cairo_pdf_operators_sources = cairo-pdf-operators.c cairo-pdf-shading.c -cairo_private += $(_cairo_pdf_operators_private) -cairo_sources += $(_cairo_pdf_operators_sources) - -cairo_png_sources = cairo-png.c - -cairo_ps_headers = cairo-ps.h -cairo_ps_private = cairo-ps-surface-private.h -cairo_ps_sources = cairo-ps-surface.c - -_cairo_deflate_stream_sources = cairo-deflate-stream.c -cairo_sources += $(_cairo_deflate_stream_sources) - -cairo_pdf_headers = cairo-pdf.h -cairo_pdf_private = cairo-pdf-surface-private.h -cairo_pdf_sources = cairo-pdf-surface.c - -cairo_svg_headers = cairo-svg.h -cairo_svg_private = cairo-svg-surface-private.h -cairo_svg_sources = cairo-svg-surface.c - -cairo_ft_headers = cairo-ft.h -cairo_ft_private = cairo-ft-private.h -cairo_ft_sources = cairo-ft-font.c - -# These are private, even though they look like public headers -cairo_test_surfaces_private = \ - test-compositor-surface.h \ - test-compositor-surface-private.h \ - test-null-compositor-surface.h \ - test-paginated-surface.h \ - $(NULL) -cairo_test_surfaces_sources = \ - test-compositor-surface.c \ - test-null-compositor-surface.c \ - test-base-compositor-surface.c \ - test-paginated-surface.c \ - $(NULL) - -cairo_xlib_headers = cairo-xlib.h -cairo_xlib_private = \ - cairo-xlib-private.h \ - cairo-xlib-surface-private.h \ - cairo-xlib-xrender-private.h \ - $(NULL) -cairo_xlib_sources = \ - cairo-xlib-display.c \ - cairo-xlib-core-compositor.c \ - cairo-xlib-fallback-compositor.c \ - cairo-xlib-render-compositor.c \ - cairo-xlib-screen.c \ - cairo-xlib-source.c \ - cairo-xlib-surface.c \ - cairo-xlib-surface-shm.c \ - cairo-xlib-visual.c \ - cairo-xlib-xcb-surface.c \ - $(NULL) - -cairo_xlib_xrender_headers = cairo-xlib-xrender.h - -cairo_xcb_headers = cairo-xcb.h -cairo_xcb_private = cairo-xcb-private.h -cairo_xcb_sources = \ - cairo-xcb-connection.c \ - cairo-xcb-connection-core.c \ - cairo-xcb-connection-render.c \ - cairo-xcb-connection-shm.c \ - cairo-xcb-screen.c \ - cairo-xcb-shm.c \ - cairo-xcb-surface.c \ - cairo-xcb-surface-core.c \ - cairo-xcb-surface-render.c \ - cairo-xcb-resources.c \ - $(NULL) - -cairo_qt_headers = cairo-qt.h -cairo_qt_cxx_sources = cairo-qt-surface.cpp - -cairo_quartz_headers = cairo-quartz.h -cairo_quartz_private = cairo-quartz-private.h -cairo_quartz_sources = cairo-quartz-surface.c - -cairo_quartz_image_headers = cairo-quartz-image.h -cairo_quartz_image_sources = cairo-quartz-image-surface.c - -cairo_quartz_font_sources = cairo-quartz-font.c - -cairo_win32_headers = cairo-win32.h -cairo_win32_private = win32/cairo-win32-private.h -cairo_win32_sources = \ - win32/cairo-win32-debug.c \ - win32/cairo-win32-device.c \ - win32/cairo-win32-gdi-compositor.c \ - win32/cairo-win32-system.c \ - win32/cairo-win32-surface.c \ - win32/cairo-win32-display-surface.c \ - win32/cairo-win32-printing-surface.c \ - $(NULL) -cairo_win32_font_sources = \ - win32/cairo-win32-font.c \ - $(NULL) - -cairo_skia_headers = cairo-skia.h -cairo_skia_private = skia/cairo-skia-private.h -cairo_skia_cxx_sources = \ - skia/cairo-skia-context.cpp \ - skia/cairo-skia-surface.cpp \ - $(NULL) - -cairo_os2_headers = cairo-os2.h -cairo_os2_private = cairo-os2-private.h -cairo_os2_sources = cairo-os2-surface.c - -# automake is stupid enough to always use c++ linker if we enable the -# following lines, even if beos surface is not enabled. Disable it for now. -cairo_beos_headers = cairo-beos.h -cairo_beos_cxx_sources = cairo-beos-surface.cpp - -cairo_gl_headers = cairo-gl.h -cairo_gl_private = cairo-gl-private.h \ - cairo-gl-dispatch-private.h \ - cairo-gl-ext-def-private.h \ - cairo-gl-gradient-private.h - -cairo_gl_sources = cairo-gl-composite.c \ - cairo-gl-device.c \ - cairo-gl-dispatch.c \ - cairo-gl-glyphs.c \ - cairo-gl-gradient.c \ - cairo-gl-info.c \ - cairo-gl-operand.c \ - cairo-gl-shaders.c \ - cairo-gl-msaa-compositor.c \ - cairo-gl-spans-compositor.c \ - cairo-gl-traps-compositor.c \ - cairo-gl-source.c \ - cairo-gl-surface.c - -cairo_glesv2_headers = $(cairo_gl_headers) -cairo_glesv2_private = $(cairo_gl_private) -cairo_glesv2_sources = $(cairo_gl_sources) - -cairo_egl_sources += cairo-egl-context.c -cairo_glx_sources += cairo-glx-context.c -cairo_wgl_sources += cairo-wgl-context.c - -cairo_directfb_headers = cairo-directfb.h -cairo_directfb_sources = cairo-directfb-surface.c - -cairo_drm_headers = cairo-drm.h -cairo_drm_private = drm/cairo-drm-private.h \ - drm/cairo-drm-ioctl-private.h \ - drm/cairo-drm-intel-private.h \ - drm/cairo-drm-intel-brw-defines.h \ - drm/cairo-drm-intel-brw-structs.h \ - drm/cairo-drm-intel-brw-eu.h \ - drm/cairo-drm-intel-command-private.h \ - drm/cairo-drm-intel-ioctl-private.h \ - drm/cairo-drm-i915-private.h \ - drm/cairo-drm-i965-private.h \ - drm/cairo-drm-radeon-private.h -cairo_drm_sources = drm/cairo-drm.c \ - drm/cairo-drm-bo.c \ - drm/cairo-drm-surface.c \ - drm/cairo-drm-intel.c \ - drm/cairo-drm-intel-debug.c \ - drm/cairo-drm-intel-surface.c \ - drm/cairo-drm-i915-surface.c \ - drm/cairo-drm-i915-glyphs.c \ - drm/cairo-drm-i915-shader.c \ - drm/cairo-drm-i915-spans.c \ - drm/cairo-drm-i965-surface.c \ - drm/cairo-drm-i965-glyphs.c \ - drm/cairo-drm-i965-shader.c \ - drm/cairo-drm-i965-spans.c \ - drm/cairo-drm-intel-brw-eu.c \ - drm/cairo-drm-intel-brw-eu-emit.c \ - drm/cairo-drm-intel-brw-eu-util.c \ - drm/cairo-drm-radeon.c \ - drm/cairo-drm-radeon-surface.c -cairo_gallium_sources = drm/cairo-drm-gallium-surface.c - -cairo_script_headers = cairo-script.h -cairo_script_private = cairo-script-private.h -cairo_script_sources = cairo-script-surface.c - -cairo_tee_headers = cairo-tee.h -cairo_tee_private = cairo-tee-surface-private.h -cairo_tee_sources = cairo-tee-surface.c - -cairo_xml_headers = cairo-xml.h -cairo_xml_sources = cairo-xml-surface.c - -cairo_vg_headers = cairo-vg.h -cairo_vg_sources = cairo-vg-surface.c - -cairo_cogl_headers = cairo-cogl.h -cairo_cogl_private = cairo-cogl-private.h \ - cairo-cogl-gradient-private.h \ - cairo-cogl-context-private.h \ - cairo-cogl-utils-private.h -cairo_cogl_sources = cairo-cogl-surface.c \ - cairo-cogl-gradient.c \ - cairo-cogl-context.c \ - cairo-cogl-utils.c diff --git a/source/libs/cairo/cairo-src/src/Makefile.win32 b/source/libs/cairo/cairo-src/src/Makefile.win32 deleted file mode 100644 index 864791f377b6fea967de78620a5e744d97cee2f9..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/Makefile.win32 +++ /dev/null @@ -1,29 +0,0 @@ -top_srcdir = .. -include $(top_srcdir)/build/Makefile.win32.common -include Makefile.win32.features - -SOURCES = $(enabled_cairo_sources) - -STATIC_SOURCES = cairo-system.c - -OBJECTS = $(patsubst %.c, $(CFG)/%.obj, $(SOURCES)) -OBJECTS_STATIC = $(patsubst %cairo-system.obj, %cairo-system-static.obj, $(OBJECTS)) - -static: inform $(CFG)/cairo-static.lib -dynamic: inform $(CFG)/cairo.dll - -$(CFG)/cairo.dll: $(OBJECTS) - @$(LD) $(CAIRO_LDFLAGS) -DLL -OUT:$@ $(CAIRO_LIBS) $(PIXMAN_LIBS) $(OBJECTS) - -$(CFG)/cairo-static.lib: $(OBJECTS_STATIC) - @$(AR) $(CAIRO_ARFLAGS) -OUT:$@ $(PIXMAN_LIBS) $(OBJECTS_STATIC) - -all: inform $(CFG)/cairo.dll $(CFG)/cairo-static.lib - @echo "Built successfully!" - @echo "You should copy the following files to a proper place now:" - @echo "" - @echo " cairo-version.h (NOTE: toplevel, not the src/cairo-version.h one!)" - @echo " src/cairo-features.h" - @for x in $(enabled_cairo_headers); do echo " src/$$x"; done - @echo " src/$(CFG)/cairo.dll" - @echo " src/$(CFG)/cairo-static.lib" diff --git a/source/libs/cairo/cairo-src/src/Makefile.win32.features b/source/libs/cairo/cairo-src/src/Makefile.win32.features deleted file mode 100644 index 2274f4ad6cfb0afb36a3dc0e3715f142366af6a7..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/Makefile.win32.features +++ /dev/null @@ -1,661 +0,0 @@ -# Generated by configure. Do not edit. - -ifeq ($(top_srcdir),) -include Makefile.sources -else -include $(top_srcdir)/src/Makefile.sources -endif - -supported_cairo_headers = $(cairo_headers) -unsupported_cairo_headers = -all_cairo_headers = $(cairo_headers) -all_cairo_private = $(cairo_private) -all_cairo_cxx_sources = $(cairo_cxx_sources) -all_cairo_sources = $(cairo_sources) - -enabled_cairo_headers = $(cairo_headers) -enabled_cairo_private = $(cairo_private) -enabled_cairo_cxx_sources = $(cairo_cxx_sources) -enabled_cairo_sources = $(cairo_sources) - -all_cairo_pkgconf = cairo.pc -enabled_cairo_pkgconf = cairo.pc - -supported_cairo_headers += $(cairo_xlib_headers) -all_cairo_headers += $(cairo_xlib_headers) -all_cairo_private += $(cairo_xlib_private) -all_cairo_cxx_sources += $(cairo_xlib_cxx_sources) -all_cairo_sources += $(cairo_xlib_sources) -ifeq ($(CAIRO_HAS_XLIB_SURFACE),1) -enabled_cairo_headers += $(cairo_xlib_headers) -enabled_cairo_private += $(cairo_xlib_private) -enabled_cairo_cxx_sources += $(cairo_xlib_cxx_sources) -enabled_cairo_sources += $(cairo_xlib_sources) -endif -all_cairo_pkgconf += cairo-xlib.pc -ifeq ($(CAIRO_HAS_XLIB_SURFACE),1) -enabled_cairo_pkgconf += cairo-xlib.pc -endif - -supported_cairo_headers += $(cairo_xlib_xrender_headers) -all_cairo_headers += $(cairo_xlib_xrender_headers) -all_cairo_private += $(cairo_xlib_xrender_private) -all_cairo_cxx_sources += $(cairo_xlib_xrender_cxx_sources) -all_cairo_sources += $(cairo_xlib_xrender_sources) -ifeq ($(CAIRO_HAS_XLIB_XRENDER_SURFACE),1) -enabled_cairo_headers += $(cairo_xlib_xrender_headers) -enabled_cairo_private += $(cairo_xlib_xrender_private) -enabled_cairo_cxx_sources += $(cairo_xlib_xrender_cxx_sources) -enabled_cairo_sources += $(cairo_xlib_xrender_sources) -endif -all_cairo_pkgconf += cairo-xlib-xrender.pc -ifeq ($(CAIRO_HAS_XLIB_XRENDER_SURFACE),1) -enabled_cairo_pkgconf += cairo-xlib-xrender.pc -endif - -supported_cairo_headers += $(cairo_xcb_headers) -all_cairo_headers += $(cairo_xcb_headers) -all_cairo_private += $(cairo_xcb_private) -all_cairo_cxx_sources += $(cairo_xcb_cxx_sources) -all_cairo_sources += $(cairo_xcb_sources) -ifeq ($(CAIRO_HAS_XCB_SURFACE),1) -enabled_cairo_headers += $(cairo_xcb_headers) -enabled_cairo_private += $(cairo_xcb_private) -enabled_cairo_cxx_sources += $(cairo_xcb_cxx_sources) -enabled_cairo_sources += $(cairo_xcb_sources) -endif -all_cairo_pkgconf += cairo-xcb.pc -ifeq ($(CAIRO_HAS_XCB_SURFACE),1) -enabled_cairo_pkgconf += cairo-xcb.pc -endif - -unsupported_cairo_headers += $(cairo_xlib_xcb_headers) -all_cairo_headers += $(cairo_xlib_xcb_headers) -all_cairo_private += $(cairo_xlib_xcb_private) -all_cairo_cxx_sources += $(cairo_xlib_xcb_cxx_sources) -all_cairo_sources += $(cairo_xlib_xcb_sources) -ifeq ($(CAIRO_HAS_XLIB_XCB_FUNCTIONS),1) -enabled_cairo_headers += $(cairo_xlib_xcb_headers) -enabled_cairo_private += $(cairo_xlib_xcb_private) -enabled_cairo_cxx_sources += $(cairo_xlib_xcb_cxx_sources) -enabled_cairo_sources += $(cairo_xlib_xcb_sources) -endif -all_cairo_pkgconf += cairo-xlib-xcb.pc -ifeq ($(CAIRO_HAS_XLIB_XCB_FUNCTIONS),1) -enabled_cairo_pkgconf += cairo-xlib-xcb.pc -endif - -supported_cairo_headers += $(cairo_xcb_shm_headers) -all_cairo_headers += $(cairo_xcb_shm_headers) -all_cairo_private += $(cairo_xcb_shm_private) -all_cairo_cxx_sources += $(cairo_xcb_shm_cxx_sources) -all_cairo_sources += $(cairo_xcb_shm_sources) -ifeq ($(CAIRO_HAS_XCB_SHM_FUNCTIONS),1) -enabled_cairo_headers += $(cairo_xcb_shm_headers) -enabled_cairo_private += $(cairo_xcb_shm_private) -enabled_cairo_cxx_sources += $(cairo_xcb_shm_cxx_sources) -enabled_cairo_sources += $(cairo_xcb_shm_sources) -endif -all_cairo_pkgconf += cairo-xcb-shm.pc -ifeq ($(CAIRO_HAS_XCB_SHM_FUNCTIONS),1) -enabled_cairo_pkgconf += cairo-xcb-shm.pc -endif - -unsupported_cairo_headers += $(cairo_qt_headers) -all_cairo_headers += $(cairo_qt_headers) -all_cairo_private += $(cairo_qt_private) -all_cairo_cxx_sources += $(cairo_qt_cxx_sources) -all_cairo_sources += $(cairo_qt_sources) -ifeq ($(CAIRO_HAS_QT_SURFACE),1) -enabled_cairo_headers += $(cairo_qt_headers) -enabled_cairo_private += $(cairo_qt_private) -enabled_cairo_cxx_sources += $(cairo_qt_cxx_sources) -enabled_cairo_sources += $(cairo_qt_sources) -endif -all_cairo_pkgconf += cairo-qt.pc -ifeq ($(CAIRO_HAS_QT_SURFACE),1) -enabled_cairo_pkgconf += cairo-qt.pc -endif - -supported_cairo_headers += $(cairo_quartz_headers) -all_cairo_headers += $(cairo_quartz_headers) -all_cairo_private += $(cairo_quartz_private) -all_cairo_cxx_sources += $(cairo_quartz_cxx_sources) -all_cairo_sources += $(cairo_quartz_sources) -ifeq ($(CAIRO_HAS_QUARTZ_SURFACE),1) -enabled_cairo_headers += $(cairo_quartz_headers) -enabled_cairo_private += $(cairo_quartz_private) -enabled_cairo_cxx_sources += $(cairo_quartz_cxx_sources) -enabled_cairo_sources += $(cairo_quartz_sources) -endif -all_cairo_pkgconf += cairo-quartz.pc -ifeq ($(CAIRO_HAS_QUARTZ_SURFACE),1) -enabled_cairo_pkgconf += cairo-quartz.pc -endif - -supported_cairo_headers += $(cairo_quartz_font_headers) -all_cairo_headers += $(cairo_quartz_font_headers) -all_cairo_private += $(cairo_quartz_font_private) -all_cairo_cxx_sources += $(cairo_quartz_font_cxx_sources) -all_cairo_sources += $(cairo_quartz_font_sources) -ifeq ($(CAIRO_HAS_QUARTZ_FONT),1) -enabled_cairo_headers += $(cairo_quartz_font_headers) -enabled_cairo_private += $(cairo_quartz_font_private) -enabled_cairo_cxx_sources += $(cairo_quartz_font_cxx_sources) -enabled_cairo_sources += $(cairo_quartz_font_sources) -endif -all_cairo_pkgconf += cairo-quartz-font.pc -ifeq ($(CAIRO_HAS_QUARTZ_FONT),1) -enabled_cairo_pkgconf += cairo-quartz-font.pc -endif - -unsupported_cairo_headers += $(cairo_quartz_image_headers) -all_cairo_headers += $(cairo_quartz_image_headers) -all_cairo_private += $(cairo_quartz_image_private) -all_cairo_cxx_sources += $(cairo_quartz_image_cxx_sources) -all_cairo_sources += $(cairo_quartz_image_sources) -ifeq ($(CAIRO_HAS_QUARTZ_IMAGE_SURFACE),1) -enabled_cairo_headers += $(cairo_quartz_image_headers) -enabled_cairo_private += $(cairo_quartz_image_private) -enabled_cairo_cxx_sources += $(cairo_quartz_image_cxx_sources) -enabled_cairo_sources += $(cairo_quartz_image_sources) -endif -all_cairo_pkgconf += cairo-quartz-image.pc -ifeq ($(CAIRO_HAS_QUARTZ_IMAGE_SURFACE),1) -enabled_cairo_pkgconf += cairo-quartz-image.pc -endif - -supported_cairo_headers += $(cairo_win32_headers) -all_cairo_headers += $(cairo_win32_headers) -all_cairo_private += $(cairo_win32_private) -all_cairo_cxx_sources += $(cairo_win32_cxx_sources) -all_cairo_sources += $(cairo_win32_sources) -ifeq ($(CAIRO_HAS_WIN32_SURFACE),1) -enabled_cairo_headers += $(cairo_win32_headers) -enabled_cairo_private += $(cairo_win32_private) -enabled_cairo_cxx_sources += $(cairo_win32_cxx_sources) -enabled_cairo_sources += $(cairo_win32_sources) -endif -all_cairo_pkgconf += cairo-win32.pc -ifeq ($(CAIRO_HAS_WIN32_SURFACE),1) -enabled_cairo_pkgconf += cairo-win32.pc -endif - -supported_cairo_headers += $(cairo_win32_font_headers) -all_cairo_headers += $(cairo_win32_font_headers) -all_cairo_private += $(cairo_win32_font_private) -all_cairo_cxx_sources += $(cairo_win32_font_cxx_sources) -all_cairo_sources += $(cairo_win32_font_sources) -ifeq ($(CAIRO_HAS_WIN32_FONT),1) -enabled_cairo_headers += $(cairo_win32_font_headers) -enabled_cairo_private += $(cairo_win32_font_private) -enabled_cairo_cxx_sources += $(cairo_win32_font_cxx_sources) -enabled_cairo_sources += $(cairo_win32_font_sources) -endif -all_cairo_pkgconf += cairo-win32-font.pc -ifeq ($(CAIRO_HAS_WIN32_FONT),1) -enabled_cairo_pkgconf += cairo-win32-font.pc -endif - -unsupported_cairo_headers += $(cairo_skia_headers) -all_cairo_headers += $(cairo_skia_headers) -all_cairo_private += $(cairo_skia_private) -all_cairo_cxx_sources += $(cairo_skia_cxx_sources) -all_cairo_sources += $(cairo_skia_sources) -ifeq ($(CAIRO_HAS_SKIA_SURFACE),1) -enabled_cairo_headers += $(cairo_skia_headers) -enabled_cairo_private += $(cairo_skia_private) -enabled_cairo_cxx_sources += $(cairo_skia_cxx_sources) -enabled_cairo_sources += $(cairo_skia_sources) -endif -all_cairo_pkgconf += cairo-skia.pc -ifeq ($(CAIRO_HAS_SKIA_SURFACE),1) -enabled_cairo_pkgconf += cairo-skia.pc -endif - -unsupported_cairo_headers += $(cairo_os2_headers) -all_cairo_headers += $(cairo_os2_headers) -all_cairo_private += $(cairo_os2_private) -all_cairo_cxx_sources += $(cairo_os2_cxx_sources) -all_cairo_sources += $(cairo_os2_sources) -ifeq ($(CAIRO_HAS_OS2_SURFACE),1) -enabled_cairo_headers += $(cairo_os2_headers) -enabled_cairo_private += $(cairo_os2_private) -enabled_cairo_cxx_sources += $(cairo_os2_cxx_sources) -enabled_cairo_sources += $(cairo_os2_sources) -endif -all_cairo_pkgconf += cairo-os2.pc -ifeq ($(CAIRO_HAS_OS2_SURFACE),1) -enabled_cairo_pkgconf += cairo-os2.pc -endif - -unsupported_cairo_headers += $(cairo_beos_headers) -all_cairo_headers += $(cairo_beos_headers) -all_cairo_private += $(cairo_beos_private) -all_cairo_cxx_sources += $(cairo_beos_cxx_sources) -all_cairo_sources += $(cairo_beos_sources) -ifeq ($(CAIRO_HAS_BEOS_SURFACE),1) -enabled_cairo_headers += $(cairo_beos_headers) -enabled_cairo_private += $(cairo_beos_private) -enabled_cairo_cxx_sources += $(cairo_beos_cxx_sources) -enabled_cairo_sources += $(cairo_beos_sources) -endif -all_cairo_pkgconf += cairo-beos.pc -ifeq ($(CAIRO_HAS_BEOS_SURFACE),1) -enabled_cairo_pkgconf += cairo-beos.pc -endif - -unsupported_cairo_headers += $(cairo_drm_headers) -all_cairo_headers += $(cairo_drm_headers) -all_cairo_private += $(cairo_drm_private) -all_cairo_cxx_sources += $(cairo_drm_cxx_sources) -all_cairo_sources += $(cairo_drm_sources) -ifeq ($(CAIRO_HAS_DRM_SURFACE),1) -enabled_cairo_headers += $(cairo_drm_headers) -enabled_cairo_private += $(cairo_drm_private) -enabled_cairo_cxx_sources += $(cairo_drm_cxx_sources) -enabled_cairo_sources += $(cairo_drm_sources) -endif -all_cairo_pkgconf += cairo-drm.pc -ifeq ($(CAIRO_HAS_DRM_SURFACE),1) -enabled_cairo_pkgconf += cairo-drm.pc -endif - -unsupported_cairo_headers += $(cairo_gallium_headers) -all_cairo_headers += $(cairo_gallium_headers) -all_cairo_private += $(cairo_gallium_private) -all_cairo_cxx_sources += $(cairo_gallium_cxx_sources) -all_cairo_sources += $(cairo_gallium_sources) -ifeq ($(CAIRO_HAS_GALLIUM_SURFACE),1) -enabled_cairo_headers += $(cairo_gallium_headers) -enabled_cairo_private += $(cairo_gallium_private) -enabled_cairo_cxx_sources += $(cairo_gallium_cxx_sources) -enabled_cairo_sources += $(cairo_gallium_sources) -endif -all_cairo_pkgconf += cairo-gallium.pc -ifeq ($(CAIRO_HAS_GALLIUM_SURFACE),1) -enabled_cairo_pkgconf += cairo-gallium.pc -endif - -supported_cairo_headers += $(cairo_png_headers) -all_cairo_headers += $(cairo_png_headers) -all_cairo_private += $(cairo_png_private) -all_cairo_cxx_sources += $(cairo_png_cxx_sources) -all_cairo_sources += $(cairo_png_sources) -ifeq ($(CAIRO_HAS_PNG_FUNCTIONS),1) -enabled_cairo_headers += $(cairo_png_headers) -enabled_cairo_private += $(cairo_png_private) -enabled_cairo_cxx_sources += $(cairo_png_cxx_sources) -enabled_cairo_sources += $(cairo_png_sources) -endif -all_cairo_pkgconf += cairo-png.pc -ifeq ($(CAIRO_HAS_PNG_FUNCTIONS),1) -enabled_cairo_pkgconf += cairo-png.pc -endif - -unsupported_cairo_headers += $(cairo_gl_headers) -all_cairo_headers += $(cairo_gl_headers) -all_cairo_private += $(cairo_gl_private) -all_cairo_cxx_sources += $(cairo_gl_cxx_sources) -all_cairo_sources += $(cairo_gl_sources) -ifeq ($(CAIRO_HAS_GL_SURFACE),1) -enabled_cairo_headers += $(cairo_gl_headers) -enabled_cairo_private += $(cairo_gl_private) -enabled_cairo_cxx_sources += $(cairo_gl_cxx_sources) -enabled_cairo_sources += $(cairo_gl_sources) -endif -all_cairo_pkgconf += cairo-gl.pc -ifeq ($(CAIRO_HAS_GL_SURFACE),1) -enabled_cairo_pkgconf += cairo-gl.pc -endif - -unsupported_cairo_headers += $(cairo_glesv2_headers) -all_cairo_headers += $(cairo_glesv2_headers) -all_cairo_private += $(cairo_glesv2_private) -all_cairo_cxx_sources += $(cairo_glesv2_cxx_sources) -all_cairo_sources += $(cairo_glesv2_sources) -ifeq ($(CAIRO_HAS_GLESV2_SURFACE),1) -enabled_cairo_headers += $(cairo_glesv2_headers) -enabled_cairo_private += $(cairo_glesv2_private) -enabled_cairo_cxx_sources += $(cairo_glesv2_cxx_sources) -enabled_cairo_sources += $(cairo_glesv2_sources) -endif -all_cairo_pkgconf += cairo-glesv2.pc -ifeq ($(CAIRO_HAS_GLESV2_SURFACE),1) -enabled_cairo_pkgconf += cairo-glesv2.pc -endif - -unsupported_cairo_headers += $(cairo_cogl_headers) -all_cairo_headers += $(cairo_cogl_headers) -all_cairo_private += $(cairo_cogl_private) -all_cairo_cxx_sources += $(cairo_cogl_cxx_sources) -all_cairo_sources += $(cairo_cogl_sources) -ifeq ($(CAIRO_HAS_COGL_SURFACE),1) -enabled_cairo_headers += $(cairo_cogl_headers) -enabled_cairo_private += $(cairo_cogl_private) -enabled_cairo_cxx_sources += $(cairo_cogl_cxx_sources) -enabled_cairo_sources += $(cairo_cogl_sources) -endif -all_cairo_pkgconf += cairo-cogl.pc -ifeq ($(CAIRO_HAS_COGL_SURFACE),1) -enabled_cairo_pkgconf += cairo-cogl.pc -endif - -unsupported_cairo_headers += $(cairo_directfb_headers) -all_cairo_headers += $(cairo_directfb_headers) -all_cairo_private += $(cairo_directfb_private) -all_cairo_cxx_sources += $(cairo_directfb_cxx_sources) -all_cairo_sources += $(cairo_directfb_sources) -ifeq ($(CAIRO_HAS_DIRECTFB_SURFACE),1) -enabled_cairo_headers += $(cairo_directfb_headers) -enabled_cairo_private += $(cairo_directfb_private) -enabled_cairo_cxx_sources += $(cairo_directfb_cxx_sources) -enabled_cairo_sources += $(cairo_directfb_sources) -endif -all_cairo_pkgconf += cairo-directfb.pc -ifeq ($(CAIRO_HAS_DIRECTFB_SURFACE),1) -enabled_cairo_pkgconf += cairo-directfb.pc -endif - -unsupported_cairo_headers += $(cairo_vg_headers) -all_cairo_headers += $(cairo_vg_headers) -all_cairo_private += $(cairo_vg_private) -all_cairo_cxx_sources += $(cairo_vg_cxx_sources) -all_cairo_sources += $(cairo_vg_sources) -ifeq ($(CAIRO_HAS_VG_SURFACE),1) -enabled_cairo_headers += $(cairo_vg_headers) -enabled_cairo_private += $(cairo_vg_private) -enabled_cairo_cxx_sources += $(cairo_vg_cxx_sources) -enabled_cairo_sources += $(cairo_vg_sources) -endif -all_cairo_pkgconf += cairo-vg.pc -ifeq ($(CAIRO_HAS_VG_SURFACE),1) -enabled_cairo_pkgconf += cairo-vg.pc -endif - -supported_cairo_headers += $(cairo_egl_headers) -all_cairo_headers += $(cairo_egl_headers) -all_cairo_private += $(cairo_egl_private) -all_cairo_cxx_sources += $(cairo_egl_cxx_sources) -all_cairo_sources += $(cairo_egl_sources) -ifeq ($(CAIRO_HAS_EGL_FUNCTIONS),1) -enabled_cairo_headers += $(cairo_egl_headers) -enabled_cairo_private += $(cairo_egl_private) -enabled_cairo_cxx_sources += $(cairo_egl_cxx_sources) -enabled_cairo_sources += $(cairo_egl_sources) -endif -all_cairo_pkgconf += cairo-egl.pc -ifeq ($(CAIRO_HAS_EGL_FUNCTIONS),1) -enabled_cairo_pkgconf += cairo-egl.pc -endif - -supported_cairo_headers += $(cairo_glx_headers) -all_cairo_headers += $(cairo_glx_headers) -all_cairo_private += $(cairo_glx_private) -all_cairo_cxx_sources += $(cairo_glx_cxx_sources) -all_cairo_sources += $(cairo_glx_sources) -ifeq ($(CAIRO_HAS_GLX_FUNCTIONS),1) -enabled_cairo_headers += $(cairo_glx_headers) -enabled_cairo_private += $(cairo_glx_private) -enabled_cairo_cxx_sources += $(cairo_glx_cxx_sources) -enabled_cairo_sources += $(cairo_glx_sources) -endif -all_cairo_pkgconf += cairo-glx.pc -ifeq ($(CAIRO_HAS_GLX_FUNCTIONS),1) -enabled_cairo_pkgconf += cairo-glx.pc -endif - -supported_cairo_headers += $(cairo_wgl_headers) -all_cairo_headers += $(cairo_wgl_headers) -all_cairo_private += $(cairo_wgl_private) -all_cairo_cxx_sources += $(cairo_wgl_cxx_sources) -all_cairo_sources += $(cairo_wgl_sources) -ifeq ($(CAIRO_HAS_WGL_FUNCTIONS),1) -enabled_cairo_headers += $(cairo_wgl_headers) -enabled_cairo_private += $(cairo_wgl_private) -enabled_cairo_cxx_sources += $(cairo_wgl_cxx_sources) -enabled_cairo_sources += $(cairo_wgl_sources) -endif -all_cairo_pkgconf += cairo-wgl.pc -ifeq ($(CAIRO_HAS_WGL_FUNCTIONS),1) -enabled_cairo_pkgconf += cairo-wgl.pc -endif - -supported_cairo_headers += $(cairo_script_headers) -all_cairo_headers += $(cairo_script_headers) -all_cairo_private += $(cairo_script_private) -all_cairo_cxx_sources += $(cairo_script_cxx_sources) -all_cairo_sources += $(cairo_script_sources) -ifeq ($(CAIRO_HAS_SCRIPT_SURFACE),1) -enabled_cairo_headers += $(cairo_script_headers) -enabled_cairo_private += $(cairo_script_private) -enabled_cairo_cxx_sources += $(cairo_script_cxx_sources) -enabled_cairo_sources += $(cairo_script_sources) -endif -all_cairo_pkgconf += cairo-script.pc -ifeq ($(CAIRO_HAS_SCRIPT_SURFACE),1) -enabled_cairo_pkgconf += cairo-script.pc -endif - -supported_cairo_headers += $(cairo_ft_headers) -all_cairo_headers += $(cairo_ft_headers) -all_cairo_private += $(cairo_ft_private) -all_cairo_cxx_sources += $(cairo_ft_cxx_sources) -all_cairo_sources += $(cairo_ft_sources) -ifeq ($(CAIRO_HAS_FT_FONT),1) -enabled_cairo_headers += $(cairo_ft_headers) -enabled_cairo_private += $(cairo_ft_private) -enabled_cairo_cxx_sources += $(cairo_ft_cxx_sources) -enabled_cairo_sources += $(cairo_ft_sources) -endif -all_cairo_pkgconf += cairo-ft.pc -ifeq ($(CAIRO_HAS_FT_FONT),1) -enabled_cairo_pkgconf += cairo-ft.pc -endif - -supported_cairo_headers += $(cairo_fc_headers) -all_cairo_headers += $(cairo_fc_headers) -all_cairo_private += $(cairo_fc_private) -all_cairo_cxx_sources += $(cairo_fc_cxx_sources) -all_cairo_sources += $(cairo_fc_sources) -ifeq ($(CAIRO_HAS_FC_FONT),1) -enabled_cairo_headers += $(cairo_fc_headers) -enabled_cairo_private += $(cairo_fc_private) -enabled_cairo_cxx_sources += $(cairo_fc_cxx_sources) -enabled_cairo_sources += $(cairo_fc_sources) -endif -all_cairo_pkgconf += cairo-fc.pc -ifeq ($(CAIRO_HAS_FC_FONT),1) -enabled_cairo_pkgconf += cairo-fc.pc -endif - -supported_cairo_headers += $(cairo_ps_headers) -all_cairo_headers += $(cairo_ps_headers) -all_cairo_private += $(cairo_ps_private) -all_cairo_cxx_sources += $(cairo_ps_cxx_sources) -all_cairo_sources += $(cairo_ps_sources) -ifeq ($(CAIRO_HAS_PS_SURFACE),1) -enabled_cairo_headers += $(cairo_ps_headers) -enabled_cairo_private += $(cairo_ps_private) -enabled_cairo_cxx_sources += $(cairo_ps_cxx_sources) -enabled_cairo_sources += $(cairo_ps_sources) -endif -all_cairo_pkgconf += cairo-ps.pc -ifeq ($(CAIRO_HAS_PS_SURFACE),1) -enabled_cairo_pkgconf += cairo-ps.pc -endif - -supported_cairo_headers += $(cairo_pdf_headers) -all_cairo_headers += $(cairo_pdf_headers) -all_cairo_private += $(cairo_pdf_private) -all_cairo_cxx_sources += $(cairo_pdf_cxx_sources) -all_cairo_sources += $(cairo_pdf_sources) -ifeq ($(CAIRO_HAS_PDF_SURFACE),1) -enabled_cairo_headers += $(cairo_pdf_headers) -enabled_cairo_private += $(cairo_pdf_private) -enabled_cairo_cxx_sources += $(cairo_pdf_cxx_sources) -enabled_cairo_sources += $(cairo_pdf_sources) -endif -all_cairo_pkgconf += cairo-pdf.pc -ifeq ($(CAIRO_HAS_PDF_SURFACE),1) -enabled_cairo_pkgconf += cairo-pdf.pc -endif - -supported_cairo_headers += $(cairo_svg_headers) -all_cairo_headers += $(cairo_svg_headers) -all_cairo_private += $(cairo_svg_private) -all_cairo_cxx_sources += $(cairo_svg_cxx_sources) -all_cairo_sources += $(cairo_svg_sources) -ifeq ($(CAIRO_HAS_SVG_SURFACE),1) -enabled_cairo_headers += $(cairo_svg_headers) -enabled_cairo_private += $(cairo_svg_private) -enabled_cairo_cxx_sources += $(cairo_svg_cxx_sources) -enabled_cairo_sources += $(cairo_svg_sources) -endif -all_cairo_pkgconf += cairo-svg.pc -ifeq ($(CAIRO_HAS_SVG_SURFACE),1) -enabled_cairo_pkgconf += cairo-svg.pc -endif - -all_cairo_private += $(cairo_test_surfaces_private) $(cairo_test_surfaces_headers) -all_cairo_cxx_sources += $(cairo_test_surfaces_cxx_sources) -all_cairo_sources += $(cairo_test_surfaces_sources) -ifeq ($(CAIRO_HAS_TEST_SURFACES),1) -enabled_cairo_private += $(cairo_test_surfaces_private) $(cairo_test_surfaces_headers) -enabled_cairo_cxx_sources += $(cairo_test_surfaces_cxx_sources) -enabled_cairo_sources += $(cairo_test_surfaces_sources) -endif - -supported_cairo_headers += $(cairo_image_headers) -all_cairo_headers += $(cairo_image_headers) -all_cairo_private += $(cairo_image_private) -all_cairo_cxx_sources += $(cairo_image_cxx_sources) -all_cairo_sources += $(cairo_image_sources) -enabled_cairo_headers += $(cairo_image_headers) -enabled_cairo_private += $(cairo_image_private) -enabled_cairo_cxx_sources += $(cairo_image_cxx_sources) -enabled_cairo_sources += $(cairo_image_sources) - -supported_cairo_headers += $(cairo_mime_headers) -all_cairo_headers += $(cairo_mime_headers) -all_cairo_private += $(cairo_mime_private) -all_cairo_cxx_sources += $(cairo_mime_cxx_sources) -all_cairo_sources += $(cairo_mime_sources) -enabled_cairo_headers += $(cairo_mime_headers) -enabled_cairo_private += $(cairo_mime_private) -enabled_cairo_cxx_sources += $(cairo_mime_cxx_sources) -enabled_cairo_sources += $(cairo_mime_sources) - -supported_cairo_headers += $(cairo_recording_headers) -all_cairo_headers += $(cairo_recording_headers) -all_cairo_private += $(cairo_recording_private) -all_cairo_cxx_sources += $(cairo_recording_cxx_sources) -all_cairo_sources += $(cairo_recording_sources) -enabled_cairo_headers += $(cairo_recording_headers) -enabled_cairo_private += $(cairo_recording_private) -enabled_cairo_cxx_sources += $(cairo_recording_cxx_sources) -enabled_cairo_sources += $(cairo_recording_sources) - -supported_cairo_headers += $(cairo_observer_headers) -all_cairo_headers += $(cairo_observer_headers) -all_cairo_private += $(cairo_observer_private) -all_cairo_cxx_sources += $(cairo_observer_cxx_sources) -all_cairo_sources += $(cairo_observer_sources) -enabled_cairo_headers += $(cairo_observer_headers) -enabled_cairo_private += $(cairo_observer_private) -enabled_cairo_cxx_sources += $(cairo_observer_cxx_sources) -enabled_cairo_sources += $(cairo_observer_sources) - -unsupported_cairo_headers += $(cairo_tee_headers) -all_cairo_headers += $(cairo_tee_headers) -all_cairo_private += $(cairo_tee_private) -all_cairo_cxx_sources += $(cairo_tee_cxx_sources) -all_cairo_sources += $(cairo_tee_sources) -ifeq ($(CAIRO_HAS_TEE_SURFACE),1) -enabled_cairo_headers += $(cairo_tee_headers) -enabled_cairo_private += $(cairo_tee_private) -enabled_cairo_cxx_sources += $(cairo_tee_cxx_sources) -enabled_cairo_sources += $(cairo_tee_sources) -endif -all_cairo_pkgconf += cairo-tee.pc -ifeq ($(CAIRO_HAS_TEE_SURFACE),1) -enabled_cairo_pkgconf += cairo-tee.pc -endif - -unsupported_cairo_headers += $(cairo_xml_headers) -all_cairo_headers += $(cairo_xml_headers) -all_cairo_private += $(cairo_xml_private) -all_cairo_cxx_sources += $(cairo_xml_cxx_sources) -all_cairo_sources += $(cairo_xml_sources) -ifeq ($(CAIRO_HAS_XML_SURFACE),1) -enabled_cairo_headers += $(cairo_xml_headers) -enabled_cairo_private += $(cairo_xml_private) -enabled_cairo_cxx_sources += $(cairo_xml_cxx_sources) -enabled_cairo_sources += $(cairo_xml_sources) -endif -all_cairo_pkgconf += cairo-xml.pc -ifeq ($(CAIRO_HAS_XML_SURFACE),1) -enabled_cairo_pkgconf += cairo-xml.pc -endif - -supported_cairo_headers += $(cairo_user_headers) -all_cairo_headers += $(cairo_user_headers) -all_cairo_private += $(cairo_user_private) -all_cairo_cxx_sources += $(cairo_user_cxx_sources) -all_cairo_sources += $(cairo_user_sources) -enabled_cairo_headers += $(cairo_user_headers) -enabled_cairo_private += $(cairo_user_private) -enabled_cairo_cxx_sources += $(cairo_user_cxx_sources) -enabled_cairo_sources += $(cairo_user_sources) - -all_cairo_private += $(cairo_pthread_private) $(cairo_pthread_headers) -all_cairo_cxx_sources += $(cairo_pthread_cxx_sources) -all_cairo_sources += $(cairo_pthread_sources) -ifeq ($(CAIRO_HAS_PTHREAD),1) -enabled_cairo_private += $(cairo_pthread_private) $(cairo_pthread_headers) -enabled_cairo_cxx_sources += $(cairo_pthread_cxx_sources) -enabled_cairo_sources += $(cairo_pthread_sources) -endif - -supported_cairo_headers += $(cairo_gobject_headers) -all_cairo_headers += $(cairo_gobject_headers) -all_cairo_private += $(cairo_gobject_private) -all_cairo_cxx_sources += $(cairo_gobject_cxx_sources) -all_cairo_sources += $(cairo_gobject_sources) -ifeq ($(CAIRO_HAS_GOBJECT_FUNCTIONS),1) -enabled_cairo_headers += $(cairo_gobject_headers) -enabled_cairo_private += $(cairo_gobject_private) -enabled_cairo_cxx_sources += $(cairo_gobject_cxx_sources) -enabled_cairo_sources += $(cairo_gobject_sources) -endif -all_cairo_pkgconf += cairo-gobject.pc -ifeq ($(CAIRO_HAS_GOBJECT_FUNCTIONS),1) -enabled_cairo_pkgconf += cairo-gobject.pc -endif - -all_cairo_private += $(cairo_trace_private) $(cairo_trace_headers) -all_cairo_cxx_sources += $(cairo_trace_cxx_sources) -all_cairo_sources += $(cairo_trace_sources) -ifeq ($(CAIRO_HAS_TRACE),1) -enabled_cairo_private += $(cairo_trace_private) $(cairo_trace_headers) -enabled_cairo_cxx_sources += $(cairo_trace_cxx_sources) -enabled_cairo_sources += $(cairo_trace_sources) -endif - -all_cairo_private += $(cairo_interpreter_private) $(cairo_interpreter_headers) -all_cairo_cxx_sources += $(cairo_interpreter_cxx_sources) -all_cairo_sources += $(cairo_interpreter_sources) -ifeq ($(CAIRO_HAS_INTERPRETER),1) -enabled_cairo_private += $(cairo_interpreter_private) $(cairo_interpreter_headers) -enabled_cairo_cxx_sources += $(cairo_interpreter_cxx_sources) -enabled_cairo_sources += $(cairo_interpreter_sources) -endif - -all_cairo_private += $(cairo_symbol_lookup_private) $(cairo_symbol_lookup_headers) -all_cairo_cxx_sources += $(cairo_symbol_lookup_cxx_sources) -all_cairo_sources += $(cairo_symbol_lookup_sources) -ifeq ($(CAIRO_HAS_SYMBOL_LOOKUP),1) -enabled_cairo_private += $(cairo_symbol_lookup_private) $(cairo_symbol_lookup_headers) -enabled_cairo_cxx_sources += $(cairo_symbol_lookup_cxx_sources) -enabled_cairo_sources += $(cairo_symbol_lookup_sources) -endif diff --git a/source/libs/cairo/cairo-src/src/README b/source/libs/cairo/cairo-src/src/README deleted file mode 100644 index 03e4455ea58c085788bf206073b816b148fc1060..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/README +++ /dev/null @@ -1,69 +0,0 @@ -Cairo Library Source Code -========================= - -This directory contains the source code of the cairo library. - - -Source Code Listing -------------------- - -The canonical list of source files is the file Makefile.sources. See that -file for how it works. - - -New Backends ------------- - -The rule of the thumb for adding new backends is to see how other -backends are integrated. Pick one of the simpler, unsupported, backends -and search the entire tree for it, and go from there. - -To add new backends you need to basically: - - * Modify $(top_srcdir)/configure.in to add checks for your backend. - - * Modify Makefile.sources to add source files for your backend, - - * Modify $(top_srcdir)/boilerplate/ to add boilerplate code for - testing your new backend. - - -New API -------- - -After adding new API, run "make check" in this directory and fix any -reported issues. Also add new API to the right location in -$(top_srcdir)/doc/public/cairo-sections.txt and run "make check" -in $(top_builddir)/doc/public to make sure that any newly added -documentation is correctly hooked up. - -Do not forget to add tests for the new API. See next section. - - -Tests ------ - -There are some tests in this directory that check the source code and -the build for various issues. The tests are very quick to run, and -particularly should be run after any documentation or API changes. It -does not hurt to run them after any source modification either. Run -them simply by calling: - - make check - -There are also extensive regression tests in $(top_srcdir)/test. It is -a good idea to run that test suite for any changes made to the source -code. Moreover, for any new feature, API, or bug fix, new tests should -be added to the regression test suite to test the new code. - - -Bibliography ------------- - -A detailed list of academic publications used in cairo code is available -in the file $(top_srcdir)/BIBLIOGRAPHY. Feel free to update as you -implement more papers. - -For more technical publications (eg. Adobe technical reports) just -point them out in a comment in the header of the file implementing them. - diff --git a/source/libs/cairo/cairo-src/src/cairo-analysis-surface-private.h b/source/libs/cairo/cairo-src/src/cairo-analysis-surface-private.h deleted file mode 100644 index 1e054c209abf73698453cd883ed3ed14d2d2b4de..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-analysis-surface-private.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright © 2005 Keith Packard - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Keith Packard - * - * Contributor(s): - * Keith Packard <keithp@keithp.com> - */ - -#ifndef CAIRO_ANALYSIS_SURFACE_H -#define CAIRO_ANALYSIS_SURFACE_H - -#include "cairoint.h" - -cairo_private cairo_surface_t * -_cairo_analysis_surface_create (cairo_surface_t *target); - -cairo_private void -_cairo_analysis_surface_set_ctm (cairo_surface_t *surface, - const cairo_matrix_t *ctm); - -cairo_private void -_cairo_analysis_surface_get_ctm (cairo_surface_t *surface, - cairo_matrix_t *ctm); - -cairo_private cairo_region_t * -_cairo_analysis_surface_get_supported (cairo_surface_t *surface); - -cairo_private cairo_region_t * -_cairo_analysis_surface_get_unsupported (cairo_surface_t *surface); - -cairo_private cairo_bool_t -_cairo_analysis_surface_has_supported (cairo_surface_t *surface); - -cairo_private cairo_bool_t -_cairo_analysis_surface_has_unsupported (cairo_surface_t *surface); - -cairo_private void -_cairo_analysis_surface_get_bounding_box (cairo_surface_t *surface, - cairo_box_t *bbox); - -cairo_private cairo_int_status_t -_cairo_analysis_surface_merge_status (cairo_int_status_t status_a, - cairo_int_status_t status_b); - -cairo_private cairo_surface_t * -_cairo_null_surface_create (cairo_content_t content); - -#endif /* CAIRO_ANALYSIS_SURFACE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-analysis-surface.c b/source/libs/cairo/cairo-src/src/cairo-analysis-surface.c deleted file mode 100644 index 8516094c200e5e775e1702ad8b6c9b8f8adef423..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-analysis-surface.c +++ /dev/null @@ -1,934 +0,0 @@ -/* - * Copyright © 2006 Keith Packard - * Copyright © 2007 Adrian Johnson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Keith Packard - * - * Contributor(s): - * Keith Packard <keithp@keithp.com> - * Adrian Johnson <ajohnson@redneon.com> - */ - -#include "cairoint.h" - -#include "cairo-analysis-surface-private.h" -#include "cairo-box-inline.h" -#include "cairo-default-context-private.h" -#include "cairo-error-private.h" -#include "cairo-paginated-private.h" -#include "cairo-recording-surface-inline.h" -#include "cairo-surface-snapshot-inline.h" -#include "cairo-surface-subsurface-inline.h" -#include "cairo-region-private.h" - -typedef struct { - cairo_surface_t base; - - cairo_surface_t *target; - - cairo_bool_t first_op; - cairo_bool_t has_supported; - cairo_bool_t has_unsupported; - - cairo_region_t supported_region; - cairo_region_t fallback_region; - cairo_box_t page_bbox; - - cairo_bool_t has_ctm; - cairo_matrix_t ctm; - -} cairo_analysis_surface_t; - -cairo_int_status_t -_cairo_analysis_surface_merge_status (cairo_int_status_t status_a, - cairo_int_status_t status_b) -{ - /* fatal errors should be checked and propagated at source */ - assert (! _cairo_int_status_is_error (status_a)); - assert (! _cairo_int_status_is_error (status_b)); - - /* return the most important status */ - if (status_a == CAIRO_INT_STATUS_UNSUPPORTED || - status_b == CAIRO_INT_STATUS_UNSUPPORTED) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (status_a == CAIRO_INT_STATUS_IMAGE_FALLBACK || - status_b == CAIRO_INT_STATUS_IMAGE_FALLBACK) - return CAIRO_INT_STATUS_IMAGE_FALLBACK; - - if (status_a == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN || - status_b == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) - return CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN; - - if (status_a == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY || - status_b == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY) - return CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY; - - /* at this point we have checked all the valid internal codes, so... */ - assert (status_a == CAIRO_INT_STATUS_SUCCESS && - status_b == CAIRO_INT_STATUS_SUCCESS); - - return CAIRO_INT_STATUS_SUCCESS; -} - -struct proxy { - cairo_surface_t base; - cairo_surface_t *target; -}; - -static cairo_status_t -proxy_finish (void *abstract_surface) -{ - return CAIRO_STATUS_SUCCESS; -} - -static const cairo_surface_backend_t proxy_backend = { - CAIRO_INTERNAL_SURFACE_TYPE_NULL, - proxy_finish, -}; - -static cairo_surface_t * -attach_proxy (cairo_surface_t *source, - cairo_surface_t *target) -{ - struct proxy *proxy; - - proxy = malloc (sizeof (*proxy)); - if (unlikely (proxy == NULL)) - return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_surface_init (&proxy->base, &proxy_backend, NULL, target->content); - - proxy->target = target; - _cairo_surface_attach_snapshot (source, &proxy->base, NULL); - - return &proxy->base; -} - -static void -detach_proxy (cairo_surface_t *proxy) -{ - cairo_surface_finish (proxy); - cairo_surface_destroy (proxy); -} - -static cairo_int_status_t -_analyze_recording_surface_pattern (cairo_analysis_surface_t *surface, - const cairo_pattern_t *pattern) -{ - const cairo_surface_pattern_t *surface_pattern; - cairo_analysis_surface_t *tmp; - cairo_surface_t *source, *proxy; - cairo_matrix_t p2d; - cairo_status_t status, analysis_status; - - assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE); - surface_pattern = (const cairo_surface_pattern_t *) pattern; - assert (surface_pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING); - source = surface_pattern->surface; - - proxy = _cairo_surface_has_snapshot (source, &proxy_backend); - if (proxy != NULL) { - /* nothing untoward found so far */ - return CAIRO_STATUS_SUCCESS; - } - - tmp = (cairo_analysis_surface_t *) - _cairo_analysis_surface_create (surface->target); - if (unlikely (tmp->base.status)) - return tmp->base.status; - proxy = attach_proxy (source, &tmp->base); - - p2d = pattern->matrix; - status = cairo_matrix_invert (&p2d); - assert (status == CAIRO_STATUS_SUCCESS); - - cairo_matrix_multiply (&tmp->ctm, &p2d, &surface->ctm); - tmp->has_ctm = ! _cairo_matrix_is_identity (&tmp->ctm); - - source = _cairo_surface_get_source (source, NULL); - status = _cairo_recording_surface_replay_and_create_regions (source, - &tmp->base); - analysis_status = tmp->has_unsupported ? CAIRO_INT_STATUS_IMAGE_FALLBACK : CAIRO_INT_STATUS_SUCCESS; - detach_proxy (proxy); - cairo_surface_destroy (&tmp->base); - - if (unlikely (status)) - return status; - - return analysis_status; -} - -static cairo_int_status_t -_add_operation (cairo_analysis_surface_t *surface, - cairo_rectangle_int_t *rect, - cairo_int_status_t backend_status) -{ - cairo_int_status_t status; - cairo_box_t bbox; - - if (rect->width == 0 || rect->height == 0) { - /* Even though the operation is not visible we must be careful - * to not allow unsupported operations to be replayed to the - * backend during CAIRO_PAGINATED_MODE_RENDER */ - if (backend_status == CAIRO_INT_STATUS_SUCCESS || - backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY || - backend_status == CAIRO_INT_STATUS_NOTHING_TO_DO) - { - return CAIRO_INT_STATUS_SUCCESS; - } - else - { - return CAIRO_INT_STATUS_IMAGE_FALLBACK; - } - } - - _cairo_box_from_rectangle (&bbox, rect); - - if (surface->has_ctm) { - int tx, ty; - - if (_cairo_matrix_is_integer_translation (&surface->ctm, &tx, &ty)) { - rect->x += tx; - rect->y += ty; - - tx = _cairo_fixed_from_int (tx); - bbox.p1.x += tx; - bbox.p2.x += tx; - - ty = _cairo_fixed_from_int (ty); - bbox.p1.y += ty; - bbox.p2.y += ty; - } else { - _cairo_matrix_transform_bounding_box_fixed (&surface->ctm, - &bbox, NULL); - - if (bbox.p1.x == bbox.p2.x || bbox.p1.y == bbox.p2.y) { - /* Even though the operation is not visible we must be - * careful to not allow unsupported operations to be - * replayed to the backend during - * CAIRO_PAGINATED_MODE_RENDER */ - if (backend_status == CAIRO_INT_STATUS_SUCCESS || - backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY || - backend_status == CAIRO_INT_STATUS_NOTHING_TO_DO) - { - return CAIRO_INT_STATUS_SUCCESS; - } - else - { - return CAIRO_INT_STATUS_IMAGE_FALLBACK; - } - } - - _cairo_box_round_to_rectangle (&bbox, rect); - } - } - - if (surface->first_op) { - surface->first_op = FALSE; - surface->page_bbox = bbox; - } else - _cairo_box_add_box(&surface->page_bbox, &bbox); - - /* If the operation is completely enclosed within the fallback - * region there is no benefit in emitting a native operation as - * the fallback image will be painted on top. - */ - if (cairo_region_contains_rectangle (&surface->fallback_region, rect) == CAIRO_REGION_OVERLAP_IN) - return CAIRO_INT_STATUS_IMAGE_FALLBACK; - - if (backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY) { - /* A status of CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY indicates - * that the backend only supports this operation if the - * transparency removed. If the extents of this operation does - * not intersect any other native operation, the operation is - * natively supported and the backend will blend the - * transparency into the white background. - */ - if (cairo_region_contains_rectangle (&surface->supported_region, rect) == CAIRO_REGION_OVERLAP_OUT) - backend_status = CAIRO_INT_STATUS_SUCCESS; - } - - if (backend_status == CAIRO_INT_STATUS_SUCCESS) { - /* Add the operation to the supported region. Operations in - * this region will be emitted as native operations. - */ - surface->has_supported = TRUE; - return cairo_region_union_rectangle (&surface->supported_region, rect); - } - - /* Add the operation to the unsupported region. This region will - * be painted as an image after all native operations have been - * emitted. - */ - surface->has_unsupported = TRUE; - status = cairo_region_union_rectangle (&surface->fallback_region, rect); - - /* The status CAIRO_INT_STATUS_IMAGE_FALLBACK is used to indicate - * unsupported operations to the recording surface as using - * CAIRO_INT_STATUS_UNSUPPORTED would cause cairo-surface to - * invoke the cairo-surface-fallback path then return - * CAIRO_STATUS_SUCCESS. - */ - if (status == CAIRO_INT_STATUS_SUCCESS) - return CAIRO_INT_STATUS_IMAGE_FALLBACK; - else - return status; -} - -static cairo_status_t -_cairo_analysis_surface_finish (void *abstract_surface) -{ - cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface; - - _cairo_region_fini (&surface->supported_region); - _cairo_region_fini (&surface->fallback_region); - - cairo_surface_destroy (surface->target); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_bool_t -_cairo_analysis_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *rectangle) -{ - cairo_analysis_surface_t *surface = abstract_surface; - - return _cairo_surface_get_extents (surface->target, rectangle); -} - -static void -_rectangle_intersect_clip (cairo_rectangle_int_t *extents, const cairo_clip_t *clip) -{ - if (clip != NULL) - _cairo_rectangle_intersect (extents, _cairo_clip_get_extents (clip)); -} - -static void -_cairo_analysis_surface_operation_extents (cairo_analysis_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip, - cairo_rectangle_int_t *extents) -{ - cairo_bool_t is_empty; - - is_empty = _cairo_surface_get_extents (&surface->base, extents); - - if (_cairo_operator_bounded_by_source (op)) { - cairo_rectangle_int_t source_extents; - - _cairo_pattern_get_extents (source, &source_extents); - _cairo_rectangle_intersect (extents, &source_extents); - } - - _rectangle_intersect_clip (extents, clip); -} - -static cairo_int_status_t -_cairo_analysis_surface_paint (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - cairo_analysis_surface_t *surface = abstract_surface; - cairo_int_status_t backend_status; - cairo_rectangle_int_t extents; - - if (surface->target->backend->paint == NULL) { - backend_status = CAIRO_INT_STATUS_UNSUPPORTED; - } else { - backend_status = - surface->target->backend->paint (surface->target, - op, source, clip); - if (_cairo_int_status_is_error (backend_status)) - return backend_status; - } - - if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) - backend_status = _analyze_recording_surface_pattern (surface, source); - - _cairo_analysis_surface_operation_extents (surface, - op, source, clip, - &extents); - - return _add_operation (surface, &extents, backend_status); -} - -static cairo_int_status_t -_cairo_analysis_surface_mask (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - cairo_analysis_surface_t *surface = abstract_surface; - cairo_int_status_t backend_status; - cairo_rectangle_int_t extents; - - if (surface->target->backend->mask == NULL) { - backend_status = CAIRO_INT_STATUS_UNSUPPORTED; - } else { - backend_status = - surface->target->backend->mask (surface->target, - op, source, mask, clip); - if (_cairo_int_status_is_error (backend_status)) - return backend_status; - } - - if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) { - cairo_int_status_t backend_source_status = CAIRO_STATUS_SUCCESS; - cairo_int_status_t backend_mask_status = CAIRO_STATUS_SUCCESS; - - if (source->type == CAIRO_PATTERN_TYPE_SURFACE) { - cairo_surface_t *src_surface = ((cairo_surface_pattern_t *)source)->surface; - src_surface = _cairo_surface_get_source (src_surface, NULL); - if (_cairo_surface_is_recording (src_surface)) { - backend_source_status = - _analyze_recording_surface_pattern (surface, source); - if (_cairo_int_status_is_error (backend_source_status)) - return backend_source_status; - } - } - - if (mask->type == CAIRO_PATTERN_TYPE_SURFACE) { - cairo_surface_t *mask_surface = ((cairo_surface_pattern_t *)mask)->surface; - mask_surface = _cairo_surface_get_source (mask_surface, NULL); - if (_cairo_surface_is_recording (mask_surface)) { - backend_mask_status = - _analyze_recording_surface_pattern (surface, mask); - if (_cairo_int_status_is_error (backend_mask_status)) - return backend_mask_status; - } - } - - backend_status = - _cairo_analysis_surface_merge_status (backend_source_status, - backend_mask_status); - } - - _cairo_analysis_surface_operation_extents (surface, - op, source, clip, - &extents); - - if (_cairo_operator_bounded_by_mask (op)) { - cairo_rectangle_int_t mask_extents; - - _cairo_pattern_get_extents (mask, &mask_extents); - _cairo_rectangle_intersect (&extents, &mask_extents); - } - - return _add_operation (surface, &extents, backend_status); -} - -static cairo_int_status_t -_cairo_analysis_surface_stroke (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_analysis_surface_t *surface = abstract_surface; - cairo_int_status_t backend_status; - cairo_rectangle_int_t extents; - - if (surface->target->backend->stroke == NULL) { - backend_status = CAIRO_INT_STATUS_UNSUPPORTED; - } else { - backend_status = - surface->target->backend->stroke (surface->target, op, - source, path, style, - ctm, ctm_inverse, - tolerance, antialias, - clip); - if (_cairo_int_status_is_error (backend_status)) - return backend_status; - } - - if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) - backend_status = _analyze_recording_surface_pattern (surface, source); - - _cairo_analysis_surface_operation_extents (surface, - op, source, clip, - &extents); - - if (_cairo_operator_bounded_by_mask (op)) { - cairo_rectangle_int_t mask_extents; - cairo_int_status_t status; - - status = _cairo_path_fixed_stroke_extents (path, style, - ctm, ctm_inverse, - tolerance, - &mask_extents); - if (unlikely (status)) - return status; - - _cairo_rectangle_intersect (&extents, &mask_extents); - } - - return _add_operation (surface, &extents, backend_status); -} - -static cairo_int_status_t -_cairo_analysis_surface_fill (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_analysis_surface_t *surface = abstract_surface; - cairo_int_status_t backend_status; - cairo_rectangle_int_t extents; - - if (surface->target->backend->fill == NULL) { - backend_status = CAIRO_INT_STATUS_UNSUPPORTED; - } else { - backend_status = - surface->target->backend->fill (surface->target, op, - source, path, fill_rule, - tolerance, antialias, - clip); - if (_cairo_int_status_is_error (backend_status)) - return backend_status; - } - - if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) - backend_status = _analyze_recording_surface_pattern (surface, source); - - _cairo_analysis_surface_operation_extents (surface, - op, source, clip, - &extents); - - if (_cairo_operator_bounded_by_mask (op)) { - cairo_rectangle_int_t mask_extents; - - _cairo_path_fixed_fill_extents (path, fill_rule, tolerance, - &mask_extents); - - _cairo_rectangle_intersect (&extents, &mask_extents); - } - - return _add_operation (surface, &extents, backend_status); -} - -static cairo_int_status_t -_cairo_analysis_surface_show_glyphs (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - cairo_analysis_surface_t *surface = abstract_surface; - cairo_int_status_t status, backend_status; - cairo_rectangle_int_t extents, glyph_extents; - - /* Adapted from _cairo_surface_show_glyphs */ - if (surface->target->backend->show_glyphs != NULL) { - backend_status = - surface->target->backend->show_glyphs (surface->target, op, - source, - glyphs, num_glyphs, - scaled_font, - clip); - if (_cairo_int_status_is_error (backend_status)) - return backend_status; - } - else if (surface->target->backend->show_text_glyphs != NULL) - { - backend_status = - surface->target->backend->show_text_glyphs (surface->target, op, - source, - NULL, 0, - glyphs, num_glyphs, - NULL, 0, - FALSE, - scaled_font, - clip); - if (_cairo_int_status_is_error (backend_status)) - return backend_status; - } - else - { - backend_status = CAIRO_INT_STATUS_UNSUPPORTED; - } - - if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) - backend_status = _analyze_recording_surface_pattern (surface, source); - - _cairo_analysis_surface_operation_extents (surface, - op, source, clip, - &extents); - - if (_cairo_operator_bounded_by_mask (op)) { - status = _cairo_scaled_font_glyph_device_extents (scaled_font, - glyphs, - num_glyphs, - &glyph_extents, - NULL); - if (unlikely (status)) - return status; - - _cairo_rectangle_intersect (&extents, &glyph_extents); - } - - return _add_operation (surface, &extents, backend_status); -} - -static cairo_bool_t -_cairo_analysis_surface_has_show_text_glyphs (void *abstract_surface) -{ - cairo_analysis_surface_t *surface = abstract_surface; - - return cairo_surface_has_show_text_glyphs (surface->target); -} - -static cairo_int_status_t -_cairo_analysis_surface_show_text_glyphs (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const char *utf8, - int utf8_len, - cairo_glyph_t *glyphs, - int num_glyphs, - const cairo_text_cluster_t *clusters, - int num_clusters, - cairo_text_cluster_flags_t cluster_flags, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - cairo_analysis_surface_t *surface = abstract_surface; - cairo_int_status_t status, backend_status; - cairo_rectangle_int_t extents, glyph_extents; - - /* Adapted from _cairo_surface_show_glyphs */ - backend_status = CAIRO_INT_STATUS_UNSUPPORTED; - if (surface->target->backend->show_text_glyphs != NULL) { - backend_status = - surface->target->backend->show_text_glyphs (surface->target, op, - source, - utf8, utf8_len, - glyphs, num_glyphs, - clusters, num_clusters, - cluster_flags, - scaled_font, - clip); - if (_cairo_int_status_is_error (backend_status)) - return backend_status; - } - if (backend_status == CAIRO_INT_STATUS_UNSUPPORTED && - surface->target->backend->show_glyphs != NULL) - { - backend_status = - surface->target->backend->show_glyphs (surface->target, op, - source, - glyphs, num_glyphs, - scaled_font, - clip); - if (_cairo_int_status_is_error (backend_status)) - return backend_status; - } - - if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) - backend_status = _analyze_recording_surface_pattern (surface, source); - - _cairo_analysis_surface_operation_extents (surface, - op, source, clip, - &extents); - - if (_cairo_operator_bounded_by_mask (op)) { - status = _cairo_scaled_font_glyph_device_extents (scaled_font, - glyphs, - num_glyphs, - &glyph_extents, - NULL); - if (unlikely (status)) - return status; - - _cairo_rectangle_intersect (&extents, &glyph_extents); - } - - return _add_operation (surface, &extents, backend_status); -} - -static const cairo_surface_backend_t cairo_analysis_surface_backend = { - CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS, - - _cairo_analysis_surface_finish, - NULL, - - NULL, /* create_similar */ - NULL, /* create_similar_image */ - NULL, /* map_to_image */ - NULL, /* unmap */ - - NULL, /* source */ - NULL, /* acquire_source_image */ - NULL, /* release_source_image */ - NULL, /* snapshot */ - - NULL, /* copy_page */ - NULL, /* show_page */ - - _cairo_analysis_surface_get_extents, - NULL, /* get_font_options */ - - NULL, /* flush */ - NULL, /* mark_dirty_rectangle */ - - _cairo_analysis_surface_paint, - _cairo_analysis_surface_mask, - _cairo_analysis_surface_stroke, - _cairo_analysis_surface_fill, - NULL, /* fill_stroke */ - _cairo_analysis_surface_show_glyphs, - _cairo_analysis_surface_has_show_text_glyphs, - _cairo_analysis_surface_show_text_glyphs -}; - -cairo_surface_t * -_cairo_analysis_surface_create (cairo_surface_t *target) -{ - cairo_analysis_surface_t *surface; - cairo_status_t status; - - status = target->status; - if (unlikely (status)) - return _cairo_surface_create_in_error (status); - - surface = malloc (sizeof (cairo_analysis_surface_t)); - if (unlikely (surface == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - /* I believe the content type here is truly arbitrary. I'm quite - * sure nothing will ever use this value. */ - _cairo_surface_init (&surface->base, - &cairo_analysis_surface_backend, - NULL, /* device */ - CAIRO_CONTENT_COLOR_ALPHA); - - cairo_matrix_init_identity (&surface->ctm); - surface->has_ctm = FALSE; - - surface->target = cairo_surface_reference (target); - surface->first_op = TRUE; - surface->has_supported = FALSE; - surface->has_unsupported = FALSE; - - _cairo_region_init (&surface->supported_region); - _cairo_region_init (&surface->fallback_region); - - surface->page_bbox.p1.x = 0; - surface->page_bbox.p1.y = 0; - surface->page_bbox.p2.x = 0; - surface->page_bbox.p2.y = 0; - - return &surface->base; -} - -void -_cairo_analysis_surface_set_ctm (cairo_surface_t *abstract_surface, - const cairo_matrix_t *ctm) -{ - cairo_analysis_surface_t *surface; - - if (abstract_surface->status) - return; - - surface = (cairo_analysis_surface_t *) abstract_surface; - - surface->ctm = *ctm; - surface->has_ctm = ! _cairo_matrix_is_identity (&surface->ctm); -} - -void -_cairo_analysis_surface_get_ctm (cairo_surface_t *abstract_surface, - cairo_matrix_t *ctm) -{ - cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface; - - *ctm = surface->ctm; -} - - -cairo_region_t * -_cairo_analysis_surface_get_supported (cairo_surface_t *abstract_surface) -{ - cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface; - - return &surface->supported_region; -} - -cairo_region_t * -_cairo_analysis_surface_get_unsupported (cairo_surface_t *abstract_surface) -{ - cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface; - - return &surface->fallback_region; -} - -cairo_bool_t -_cairo_analysis_surface_has_supported (cairo_surface_t *abstract_surface) -{ - cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface; - - return surface->has_supported; -} - -cairo_bool_t -_cairo_analysis_surface_has_unsupported (cairo_surface_t *abstract_surface) -{ - cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface; - - return surface->has_unsupported; -} - -void -_cairo_analysis_surface_get_bounding_box (cairo_surface_t *abstract_surface, - cairo_box_t *bbox) -{ - cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface; - - *bbox = surface->page_bbox; -} - -/* null surface type: a surface that does nothing (has no side effects, yay!) */ - -static cairo_int_status_t -_return_success (void) -{ - return CAIRO_STATUS_SUCCESS; -} - -/* These typedefs are just to silence the compiler... */ -typedef cairo_int_status_t -(*_paint_func) (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip); - -typedef cairo_int_status_t -(*_mask_func) (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip); - -typedef cairo_int_status_t -(*_stroke_func) (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip); - -typedef cairo_int_status_t -(*_fill_func) (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip); - -typedef cairo_int_status_t -(*_show_glyphs_func) (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip); - -static const cairo_surface_backend_t cairo_null_surface_backend = { - CAIRO_INTERNAL_SURFACE_TYPE_NULL, - NULL, /* finish */ - - NULL, /* only accessed through the surface functions */ - - NULL, /* create_similar */ - NULL, /* create similar image */ - NULL, /* map to image */ - NULL, /* unmap image*/ - - NULL, /* source */ - NULL, /* acquire_source_image */ - NULL, /* release_source_image */ - NULL, /* snapshot */ - - NULL, /* copy_page */ - NULL, /* show_page */ - - NULL, /* get_extents */ - NULL, /* get_font_options */ - - NULL, /* flush */ - NULL, /* mark_dirty_rectangle */ - - (_paint_func) _return_success, /* paint */ - (_mask_func) _return_success, /* mask */ - (_stroke_func) _return_success, /* stroke */ - (_fill_func) _return_success, /* fill */ - NULL, /* fill_stroke */ - (_show_glyphs_func) _return_success, /* show_glyphs */ - NULL, /* has_show_text_glyphs */ - NULL /* show_text_glyphs */ -}; - -cairo_surface_t * -_cairo_null_surface_create (cairo_content_t content) -{ - cairo_surface_t *surface; - - surface = malloc (sizeof (cairo_surface_t)); - if (unlikely (surface == NULL)) { - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - _cairo_surface_init (surface, - &cairo_null_surface_backend, - NULL, /* device */ - content); - - return surface; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-arc-private.h b/source/libs/cairo/cairo-src/src/cairo-arc-private.h deleted file mode 100644 index a22c01ac90bf2939181390514995484c129d15fc..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-arc-private.h +++ /dev/null @@ -1,61 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Carl D. Worth <cworth@redhat.com> - */ - -#ifndef CAIRO_ARC_PRIVATE_H -#define CAIRO_ARC_PRIVATE_H - -#include "cairoint.h" - -CAIRO_BEGIN_DECLS - -cairo_private void -_cairo_arc_path (cairo_t *cr, - double xc, - double yc, - double radius, - double angle1, - double angle2); - -cairo_private void -_cairo_arc_path_negative (cairo_t *cr, - double xc, - double yc, - double radius, - double angle1, - double angle2); - -CAIRO_END_DECLS - -#endif /* CAIRO_ARC_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-arc.c b/source/libs/cairo/cairo-src/src/cairo-arc.c deleted file mode 100644 index 390397bae10426d2be99da45ae1717c7832207c4..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-arc.c +++ /dev/null @@ -1,312 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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" - -#include "cairo-arc-private.h" - -#define MAX_FULL_CIRCLES 65536 - -/* Spline deviation from the circle in radius would be given by: - - error = sqrt (x**2 + y**2) - 1 - - A simpler error function to work with is: - - e = x**2 + y**2 - 1 - - From "Good approximation of circles by curvature-continuous Bezier - curves", Tor Dokken and Morten Daehlen, Computer Aided Geometric - Design 8 (1990) 22-41, we learn: - - abs (max(e)) = 4/27 * sin**6(angle/4) / cos**2(angle/4) - - and - abs (error) =~ 1/2 * e - - Of course, this error value applies only for the particular spline - approximation that is used in _cairo_gstate_arc_segment. -*/ -static double -_arc_error_normalized (double angle) -{ - return 2.0/27.0 * pow (sin (angle / 4), 6) / pow (cos (angle / 4), 2); -} - -static double -_arc_max_angle_for_tolerance_normalized (double tolerance) -{ - double angle, error; - int i; - - /* Use table lookup to reduce search time in most cases. */ - struct { - double angle; - double error; - } table[] = { - { M_PI / 1.0, 0.0185185185185185036127 }, - { M_PI / 2.0, 0.000272567143730179811158 }, - { M_PI / 3.0, 2.38647043651461047433e-05 }, - { M_PI / 4.0, 4.2455377443222443279e-06 }, - { M_PI / 5.0, 1.11281001494389081528e-06 }, - { M_PI / 6.0, 3.72662000942734705475e-07 }, - { M_PI / 7.0, 1.47783685574284411325e-07 }, - { M_PI / 8.0, 6.63240432022601149057e-08 }, - { M_PI / 9.0, 3.2715520137536980553e-08 }, - { M_PI / 10.0, 1.73863223499021216974e-08 }, - { M_PI / 11.0, 9.81410988043554039085e-09 }, - }; - int table_size = ARRAY_LENGTH (table); - - for (i = 0; i < table_size; i++) - if (table[i].error < tolerance) - return table[i].angle; - - ++i; - do { - angle = M_PI / i++; - error = _arc_error_normalized (angle); - } while (error > tolerance); - - return angle; -} - -static int -_arc_segments_needed (double angle, - double radius, - cairo_matrix_t *ctm, - double tolerance) -{ - double major_axis, max_angle; - - /* the error is amplified by at most the length of the - * major axis of the circle; see cairo-pen.c for a more detailed analysis - * of this. */ - major_axis = _cairo_matrix_transformed_circle_major_axis (ctm, radius); - max_angle = _arc_max_angle_for_tolerance_normalized (tolerance / major_axis); - - return ceil (fabs (angle) / max_angle); -} - -/* We want to draw a single spline approximating a circular arc radius - R from angle A to angle B. Since we want a symmetric spline that - matches the endpoints of the arc in position and slope, we know - that the spline control points must be: - - (R * cos(A), R * sin(A)) - (R * cos(A) - h * sin(A), R * sin(A) + h * cos (A)) - (R * cos(B) + h * sin(B), R * sin(B) - h * cos (B)) - (R * cos(B), R * sin(B)) - - for some value of h. - - "Approximation of circular arcs by cubic polynomials", Michael - Goldapp, Computer Aided Geometric Design 8 (1991) 227-238, provides - various values of h along with error analysis for each. - - From that paper, a very practical value of h is: - - h = 4/3 * R * tan(angle/4) - - This value does not give the spline with minimal error, but it does - provide a very good approximation, (6th-order convergence), and the - error expression is quite simple, (see the comment for - _arc_error_normalized). -*/ -static void -_cairo_arc_segment (cairo_t *cr, - double xc, - double yc, - double radius, - double angle_A, - double angle_B) -{ - double r_sin_A, r_cos_A; - double r_sin_B, r_cos_B; - double h; - - r_sin_A = radius * sin (angle_A); - r_cos_A = radius * cos (angle_A); - r_sin_B = radius * sin (angle_B); - r_cos_B = radius * cos (angle_B); - - h = 4.0/3.0 * tan ((angle_B - angle_A) / 4.0); - - cairo_curve_to (cr, - xc + r_cos_A - h * r_sin_A, - yc + r_sin_A + h * r_cos_A, - xc + r_cos_B + h * r_sin_B, - yc + r_sin_B - h * r_cos_B, - xc + r_cos_B, - yc + r_sin_B); -} - -static void -_cairo_arc_in_direction (cairo_t *cr, - double xc, - double yc, - double radius, - double angle_min, - double angle_max, - cairo_direction_t dir) -{ - if (cairo_status (cr)) - return; - - assert (angle_max >= angle_min); - - if (angle_max - angle_min > 2 * M_PI * MAX_FULL_CIRCLES) { - angle_max = fmod (angle_max - angle_min, 2 * M_PI); - angle_min = fmod (angle_min, 2 * M_PI); - angle_max += angle_min + 2 * M_PI * MAX_FULL_CIRCLES; - } - - /* Recurse if drawing arc larger than pi */ - if (angle_max - angle_min > M_PI) { - double angle_mid = angle_min + (angle_max - angle_min) / 2.0; - if (dir == CAIRO_DIRECTION_FORWARD) { - _cairo_arc_in_direction (cr, xc, yc, radius, - angle_min, angle_mid, - dir); - - _cairo_arc_in_direction (cr, xc, yc, radius, - angle_mid, angle_max, - dir); - } else { - _cairo_arc_in_direction (cr, xc, yc, radius, - angle_mid, angle_max, - dir); - - _cairo_arc_in_direction (cr, xc, yc, radius, - angle_min, angle_mid, - dir); - } - } else if (angle_max != angle_min) { - cairo_matrix_t ctm; - int i, segments; - double step; - - cairo_get_matrix (cr, &ctm); - segments = _arc_segments_needed (angle_max - angle_min, - radius, &ctm, - cairo_get_tolerance (cr)); - step = (angle_max - angle_min) / segments; - segments -= 1; - - if (dir == CAIRO_DIRECTION_REVERSE) { - double t; - - t = angle_min; - angle_min = angle_max; - angle_max = t; - - step = -step; - } - - cairo_line_to (cr, - xc + radius * cos (angle_min), - yc + radius * sin (angle_min)); - - for (i = 0; i < segments; i++, angle_min += step) { - _cairo_arc_segment (cr, xc, yc, radius, - angle_min, angle_min + step); - } - - _cairo_arc_segment (cr, xc, yc, radius, - angle_min, angle_max); - } else { - cairo_line_to (cr, - xc + radius * cos (angle_min), - yc + radius * sin (angle_min)); - } -} - -/** - * _cairo_arc_path: - * @cr: a cairo context - * @xc: X position of the center of the arc - * @yc: Y position of the center of the arc - * @radius: the radius of the arc - * @angle1: the start angle, in radians - * @angle2: the end angle, in radians - * - * Compute a path for the given arc and append it onto the current - * path within @cr. The arc will be accurate within the current - * tolerance and given the current transformation. - **/ -void -_cairo_arc_path (cairo_t *cr, - double xc, - double yc, - double radius, - double angle1, - double angle2) -{ - _cairo_arc_in_direction (cr, xc, yc, - radius, - angle1, angle2, - CAIRO_DIRECTION_FORWARD); -} - -/** - * _cairo_arc_path_negative: - * @xc: X position of the center of the arc - * @yc: Y position of the center of the arc - * @radius: the radius of the arc - * @angle1: the start angle, in radians - * @angle2: the end angle, in radians - * @ctm: the current transformation matrix - * @tolerance: the current tolerance value - * @path: the path onto which the arc will be appended - * - * Compute a path for the given arc (defined in the negative - * direction) and append it onto the current path within @cr. The arc - * will be accurate within the current tolerance and given the current - * transformation. - **/ -void -_cairo_arc_path_negative (cairo_t *cr, - double xc, - double yc, - double radius, - double angle1, - double angle2) -{ - _cairo_arc_in_direction (cr, xc, yc, - radius, - angle2, angle1, - CAIRO_DIRECTION_REVERSE); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-array-private.h b/source/libs/cairo/cairo-src/src/cairo-array-private.h deleted file mode 100644 index 35b29e5fc07d62e74b591333034c5e0eae6473bd..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-array-private.h +++ /dev/null @@ -1,90 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - */ - -#ifndef CAIRO_ARRAY_PRIVATE_H -#define CAIRO_ARRAY_PRIVATE_H - -#include "cairo-compiler-private.h" -#include "cairo-types-private.h" - -CAIRO_BEGIN_DECLS - -/* cairo-array.c structures and functions */ - -cairo_private void -_cairo_array_init (cairo_array_t *array, unsigned int element_size); - -cairo_private void -_cairo_array_fini (cairo_array_t *array); - -cairo_private cairo_status_t -_cairo_array_grow_by (cairo_array_t *array, unsigned int additional); - -cairo_private void -_cairo_array_truncate (cairo_array_t *array, unsigned int num_elements); - -cairo_private cairo_status_t -_cairo_array_append (cairo_array_t *array, const void *element); - -cairo_private cairo_status_t -_cairo_array_append_multiple (cairo_array_t *array, - const void *elements, - unsigned int num_elements); - -cairo_private cairo_status_t -_cairo_array_allocate (cairo_array_t *array, - unsigned int num_elements, - void **elements); - -cairo_private void * -_cairo_array_index (cairo_array_t *array, unsigned int index); - -cairo_private const void * -_cairo_array_index_const (const cairo_array_t *array, unsigned int index); - -cairo_private void -_cairo_array_copy_element (const cairo_array_t *array, unsigned int index, void *dst); - -cairo_private unsigned int -_cairo_array_num_elements (const cairo_array_t *array); - -cairo_private unsigned int -_cairo_array_size (const cairo_array_t *array); - -CAIRO_END_DECLS - -#endif /* CAIRO_ARRAY_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-array.c b/source/libs/cairo/cairo-src/src/cairo-array.c deleted file mode 100644 index 58c9a388fa4f442f05e1256e8839987f2d5f435f..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-array.c +++ /dev/null @@ -1,529 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2004 Red Hat, Inc - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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): - * Kristian Høgsberg <krh@redhat.com> - * Carl Worth <cworth@cworth.org> - */ - -#include "cairoint.h" -#include "cairo-array-private.h" -#include "cairo-error-private.h" - -/** - * _cairo_array_init: - * - * Initialize a new #cairo_array_t object to store objects each of size - * @element_size. - * - * The #cairo_array_t object provides grow-by-doubling storage. It - * never interprets the data passed to it, nor does it provide any - * sort of callback mechanism for freeing resources held onto by - * stored objects. - * - * When finished using the array, _cairo_array_fini() should be - * called to free resources allocated during use of the array. - **/ -void -_cairo_array_init (cairo_array_t *array, unsigned int element_size) -{ - array->size = 0; - array->num_elements = 0; - array->element_size = element_size; - array->elements = NULL; -} - -/** - * _cairo_array_fini: - * @array: A #cairo_array_t - * - * Free all resources associated with @array. After this call, @array - * should not be used again without a subsequent call to - * _cairo_array_init() again first. - **/ -void -_cairo_array_fini (cairo_array_t *array) -{ - free (array->elements); -} - -/** - * _cairo_array_grow_by: - * @array: a #cairo_array_t - * - * Increase the size of @array (if needed) so that there are at least - * @additional free spaces in the array. The actual size of the array - * is always increased by doubling as many times as necessary. - **/ -cairo_status_t -_cairo_array_grow_by (cairo_array_t *array, unsigned int additional) -{ - char *new_elements; - unsigned int old_size = array->size; - unsigned int required_size = array->num_elements + additional; - unsigned int new_size; - - /* check for integer overflow */ - if (required_size > INT_MAX || required_size < array->num_elements) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - if (CAIRO_INJECT_FAULT ()) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - if (required_size <= old_size) - return CAIRO_STATUS_SUCCESS; - - if (old_size == 0) - new_size = 1; - else - new_size = old_size * 2; - - while (new_size < required_size) - new_size = new_size * 2; - - array->size = new_size; - new_elements = _cairo_realloc_ab (array->elements, - array->size, array->element_size); - - if (unlikely (new_elements == NULL)) { - array->size = old_size; - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - array->elements = new_elements; - - return CAIRO_STATUS_SUCCESS; -} - -/** - * _cairo_array_truncate: - * @array: a #cairo_array_t - * - * Truncate size of the array to @num_elements if less than the - * current size. No memory is actually freed. The stored objects - * beyond @num_elements are simply "forgotten". - **/ -void -_cairo_array_truncate (cairo_array_t *array, unsigned int num_elements) -{ - if (num_elements < array->num_elements) - array->num_elements = num_elements; -} - -/** - * _cairo_array_index: - * @array: a #cairo_array_t - * Returns: A pointer to the object stored at @index. - * - * If the resulting value is assigned to a pointer to an object of the same - * element_size as initially passed to _cairo_array_init() then that - * pointer may be used for further direct indexing with []. For - * example: - * - * <informalexample><programlisting> - * cairo_array_t array; - * double *values; - * - * _cairo_array_init (&array, sizeof(double)); - * ... calls to _cairo_array_append() here ... - * - * values = _cairo_array_index (&array, 0); - * for (i = 0; i < _cairo_array_num_elements (&array); i++) - * ... use values[i] here ... - * </programlisting></informalexample> - **/ -void * -_cairo_array_index (cairo_array_t *array, unsigned int index) -{ - /* We allow an index of 0 for the no-elements case. - * This makes for cleaner calling code which will often look like: - * - * elements = _cairo_array_index (array, 0); - * for (i=0; i < num_elements; i++) { - * ... use elements[i] here ... - * } - * - * which in the num_elements==0 case gets the NULL pointer here, - * but never dereferences it. - */ - if (index == 0 && array->num_elements == 0) - return NULL; - - assert (index < array->num_elements); - - return array->elements + index * array->element_size; -} - -/** - * _cairo_array_index_const: - * @array: a #cairo_array_t - * Returns: A pointer to the object stored at @index. - * - * If the resulting value is assigned to a pointer to an object of the same - * element_size as initially passed to _cairo_array_init() then that - * pointer may be used for further direct indexing with []. For - * example: - * - * <informalexample><programlisting> - * cairo_array_t array; - * const double *values; - * - * _cairo_array_init (&array, sizeof(double)); - * ... calls to _cairo_array_append() here ... - * - * values = _cairo_array_index_const (&array, 0); - * for (i = 0; i < _cairo_array_num_elements (&array); i++) - * ... read values[i] here ... - * </programlisting></informalexample> - **/ -const void * -_cairo_array_index_const (const cairo_array_t *array, unsigned int index) -{ - /* We allow an index of 0 for the no-elements case. - * This makes for cleaner calling code which will often look like: - * - * elements = _cairo_array_index_const (array, 0); - * for (i=0; i < num_elements; i++) { - * ... read elements[i] here ... - * } - * - * which in the num_elements==0 case gets the NULL pointer here, - * but never dereferences it. - */ - if (index == 0 && array->num_elements == 0) - return NULL; - - assert (index < array->num_elements); - - return array->elements + index * array->element_size; -} - -/** - * _cairo_array_copy_element: - * @array: a #cairo_array_t - * - * Copy a single element out of the array from index @index into the - * location pointed to by @dst. - **/ -void -_cairo_array_copy_element (const cairo_array_t *array, - unsigned int index, - void *dst) -{ - memcpy (dst, _cairo_array_index_const (array, index), array->element_size); -} - -/** - * _cairo_array_append: - * @array: a #cairo_array_t - * - * Append a single item onto the array by growing the array by at - * least one element, then copying element_size bytes from @element - * into the array. The address of the resulting object within the - * array can be determined with: - * - * _cairo_array_index (array, _cairo_array_num_elements (array) - 1); - * - * Return value: %CAIRO_STATUS_SUCCESS if successful or - * %CAIRO_STATUS_NO_MEMORY if insufficient memory is available for the - * operation. - **/ -cairo_status_t -_cairo_array_append (cairo_array_t *array, - const void *element) -{ - return _cairo_array_append_multiple (array, element, 1); -} - -/** - * _cairo_array_append_multiple: - * @array: a #cairo_array_t - * - * Append one or more items onto the array by growing the array by - * @num_elements, then copying @num_elements * element_size bytes from - * @elements into the array. - * - * Return value: %CAIRO_STATUS_SUCCESS if successful or - * %CAIRO_STATUS_NO_MEMORY if insufficient memory is available for the - * operation. - **/ -cairo_status_t -_cairo_array_append_multiple (cairo_array_t *array, - const void *elements, - unsigned int num_elements) -{ - cairo_status_t status; - void *dest; - - status = _cairo_array_allocate (array, num_elements, &dest); - if (unlikely (status)) - return status; - - memcpy (dest, elements, num_elements * array->element_size); - - return CAIRO_STATUS_SUCCESS; -} - -/** - * _cairo_array_allocate: - * @array: a #cairo_array_t - * - * Allocate space at the end of the array for @num_elements additional - * elements, providing the address of the new memory chunk in - * @elements. This memory will be unitialized, but will be accounted - * for in the return value of _cairo_array_num_elements(). - * - * Return value: %CAIRO_STATUS_SUCCESS if successful or - * %CAIRO_STATUS_NO_MEMORY if insufficient memory is available for the - * operation. - **/ -cairo_status_t -_cairo_array_allocate (cairo_array_t *array, - unsigned int num_elements, - void **elements) -{ - cairo_status_t status; - - status = _cairo_array_grow_by (array, num_elements); - if (unlikely (status)) - return status; - - assert (array->num_elements + num_elements <= array->size); - - *elements = array->elements + array->num_elements * array->element_size; - - array->num_elements += num_elements; - - return CAIRO_STATUS_SUCCESS; -} - -/** - * _cairo_array_num_elements: - * @array: a #cairo_array_t - * Returns: The number of elements stored in @array. - * - * This space was left intentionally blank, but gtk-doc filled it. - **/ -unsigned int -_cairo_array_num_elements (const cairo_array_t *array) -{ - return array->num_elements; -} - -/** - * _cairo_array_size: - * @array: a #cairo_array_t - * Returns: The number of elements for which there is currently space - * allocated in @array. - * - * This space was left intentionally blank, but gtk-doc filled it. - **/ -unsigned int -_cairo_array_size (const cairo_array_t *array) -{ - return array->size; -} - -/** - * _cairo_user_data_array_init: - * @array: a #cairo_user_data_array_t - * - * Initializes a #cairo_user_data_array_t structure for future - * use. After initialization, the array has no keys. Call - * _cairo_user_data_array_fini() to free any allocated memory - * when done using the array. - **/ -void -_cairo_user_data_array_init (cairo_user_data_array_t *array) -{ - _cairo_array_init (array, sizeof (cairo_user_data_slot_t)); -} - -/** - * _cairo_user_data_array_fini: - * @array: a #cairo_user_data_array_t - * - * Destroys all current keys in the user data array and deallocates - * any memory allocated for the array itself. - **/ -void -_cairo_user_data_array_fini (cairo_user_data_array_t *array) -{ - unsigned int num_slots; - - num_slots = array->num_elements; - if (num_slots) { - cairo_user_data_slot_t *slots; - - slots = _cairo_array_index (array, 0); - while (num_slots--) { - cairo_user_data_slot_t *s = &slots[num_slots]; - if (s->user_data != NULL && s->destroy != NULL) - s->destroy (s->user_data); - } - } - - _cairo_array_fini (array); -} - -/** - * _cairo_user_data_array_get_data: - * @array: a #cairo_user_data_array_t - * @key: the address of the #cairo_user_data_key_t the user data was - * attached to - * - * Returns user data previously attached using the specified - * key. If no user data has been attached with the given key this - * function returns %NULL. - * - * Return value: the user data previously attached or %NULL. - **/ -void * -_cairo_user_data_array_get_data (cairo_user_data_array_t *array, - const cairo_user_data_key_t *key) -{ - int i, num_slots; - cairo_user_data_slot_t *slots; - - /* We allow this to support degenerate objects such as cairo_surface_nil. */ - if (array == NULL) - return NULL; - - num_slots = array->num_elements; - slots = _cairo_array_index (array, 0); - for (i = 0; i < num_slots; i++) { - if (slots[i].key == key) - return slots[i].user_data; - } - - return NULL; -} - -/** - * _cairo_user_data_array_set_data: - * @array: a #cairo_user_data_array_t - * @key: the address of a #cairo_user_data_key_t to attach the user data to - * @user_data: the user data to attach - * @destroy: a #cairo_destroy_func_t which will be called when the - * user data array is destroyed or when new user data is attached using the - * same key. - * - * Attaches user data to a user data array. To remove user data, - * call this function with the key that was used to set it and %NULL - * for @data. - * - * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a - * slot could not be allocated for the user data. - **/ -cairo_status_t -_cairo_user_data_array_set_data (cairo_user_data_array_t *array, - const cairo_user_data_key_t *key, - void *user_data, - cairo_destroy_func_t destroy) -{ - cairo_status_t status; - int i, num_slots; - cairo_user_data_slot_t *slots, *slot, new_slot; - - if (user_data) { - new_slot.key = key; - new_slot.user_data = user_data; - new_slot.destroy = destroy; - } else { - new_slot.key = NULL; - new_slot.user_data = NULL; - new_slot.destroy = NULL; - } - - slot = NULL; - num_slots = array->num_elements; - slots = _cairo_array_index (array, 0); - for (i = 0; i < num_slots; i++) { - if (slots[i].key == key) { - slot = &slots[i]; - if (slot->destroy && slot->user_data) - slot->destroy (slot->user_data); - break; - } - if (user_data && slots[i].user_data == NULL) { - slot = &slots[i]; /* Have to keep searching for an exact match */ - } - } - - if (slot) { - *slot = new_slot; - return CAIRO_STATUS_SUCCESS; - } - - if (user_data == NULL) - return CAIRO_STATUS_SUCCESS; - - status = _cairo_array_append (array, &new_slot); - if (unlikely (status)) - return status; - - return CAIRO_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_user_data_array_copy (cairo_user_data_array_t *dst, - const cairo_user_data_array_t *src) -{ - /* discard any existing user-data */ - if (dst->num_elements != 0) { - _cairo_user_data_array_fini (dst); - _cairo_user_data_array_init (dst); - } - - return _cairo_array_append_multiple (dst, - _cairo_array_index_const (src, 0), - src->num_elements); -} - -void -_cairo_user_data_array_foreach (cairo_user_data_array_t *array, - void (*func) (const void *key, - void *elt, - void *closure), - void *closure) -{ - cairo_user_data_slot_t *slots; - int i, num_slots; - - num_slots = array->num_elements; - slots = _cairo_array_index (array, 0); - for (i = 0; i < num_slots; i++) { - if (slots[i].user_data != NULL) - func (slots[i].key, slots[i].user_data, closure); - } -} diff --git a/source/libs/cairo/cairo-src/src/cairo-atomic-private.h b/source/libs/cairo/cairo-src/src/cairo-atomic-private.h deleted file mode 100644 index 11b2887a147d1d04b5891318ab2bfeaf183ffbdc..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-atomic-private.h +++ /dev/null @@ -1,362 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2007 Chris Wilson - * Copyright © 2010 Andrea Canciani - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - * Andrea Canciani <ranma42@gmail.com> - */ - -#ifndef CAIRO_ATOMIC_PRIVATE_H -#define CAIRO_ATOMIC_PRIVATE_H - -# include "cairo-compiler-private.h" - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -/* The autoconf on OpenBSD 4.5 produces the malformed constant name - * SIZEOF_VOID__ rather than SIZEOF_VOID_P. Work around that here. */ -#if !defined(SIZEOF_VOID_P) && defined(SIZEOF_VOID__) -# define SIZEOF_VOID_P SIZEOF_VOID__ -#endif - -CAIRO_BEGIN_DECLS - -/* C++11 atomic primitives were designed to be more flexible than the - * __sync_* family of primitives. Despite the name, they are available - * in C as well as C++. The motivating reason for using them is that - * for _cairo_atomic_{int,ptr}_get, the compiler is able to see that - * the load is intended to be atomic, as opposed to the __sync_* - * version, below, where the load looks like a plain load. Having - * the load appear atomic to the compiler is particular important for - * tools like ThreadSanitizer so they don't report false positives on - * memory operations that we intend to be atomic. - */ -#if HAVE_CXX11_ATOMIC_PRIMITIVES - -#define HAS_ATOMIC_OPS 1 - -typedef int cairo_atomic_int_t; - -static cairo_always_inline cairo_atomic_int_t -_cairo_atomic_int_get (cairo_atomic_int_t *x) -{ - return __atomic_load_n(x, __ATOMIC_SEQ_CST); -} - -static cairo_always_inline void * -_cairo_atomic_ptr_get (void **x) -{ - return __atomic_load_n(x, __ATOMIC_SEQ_CST); -} - -# define _cairo_atomic_int_inc(x) ((void) __atomic_fetch_add(x, 1, __ATOMIC_SEQ_CST)) -# define _cairo_atomic_int_dec(x) ((void) __atomic_fetch_sub(x, 1, __ATOMIC_SEQ_CST)) -# define _cairo_atomic_int_dec_and_test(x) (__atomic_fetch_sub(x, 1, __ATOMIC_SEQ_CST) == 1) - -#if SIZEOF_VOID_P==SIZEOF_INT -typedef int cairo_atomic_intptr_t; -#elif SIZEOF_VOID_P==SIZEOF_LONG -typedef long cairo_atomic_intptr_t; -#elif SIZEOF_VOID_P==SIZEOF_LONG_LONG -typedef long long cairo_atomic_intptr_t; -#else -#error No matching integer pointer type -#endif - -static cairo_always_inline cairo_bool_t -_cairo_atomic_int_cmpxchg_impl(cairo_atomic_int_t *x, - cairo_atomic_int_t oldv, - cairo_atomic_int_t newv) -{ - cairo_atomic_int_t expected = oldv; - return __atomic_compare_exchange_n(x, &expected, newv, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); -} - -#define _cairo_atomic_int_cmpxchg(x, oldv, newv) \ - _cairo_atomic_int_cmpxchg_impl(x, oldv, newv) - -static cairo_always_inline cairo_atomic_int_t -_cairo_atomic_int_cmpxchg_return_old_impl(cairo_atomic_int_t *x, - cairo_atomic_int_t oldv, - cairo_atomic_int_t newv) -{ - cairo_atomic_int_t expected = oldv; - (void) __atomic_compare_exchange_n(x, &expected, newv, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); - return expected; -} - -#define _cairo_atomic_int_cmpxchg_return_old(x, oldv, newv) \ - _cairo_atomic_int_cmpxchg_return_old_impl(x, oldv, newv) - -static cairo_always_inline cairo_bool_t -_cairo_atomic_ptr_cmpxchg_impl(void **x, void *oldv, void *newv) -{ - void *expected = oldv; - return __atomic_compare_exchange_n(x, &expected, newv, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); -} - -#define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \ - _cairo_atomic_ptr_cmpxchg_impl(x, oldv, newv) - -static cairo_always_inline void * -_cairo_atomic_ptr_cmpxchg_return_old_impl(void **x, void *oldv, void *newv) -{ - void *expected = oldv; - (void) __atomic_compare_exchange_n(x, &expected, newv, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); - return expected; -} - -#define _cairo_atomic_ptr_cmpxchg_return_old(x, oldv, newv) \ - _cairo_atomic_ptr_cmpxchg_return_old_impl(x, oldv, newv) - -#endif - -#if HAVE_INTEL_ATOMIC_PRIMITIVES - -#define HAS_ATOMIC_OPS 1 - -typedef int cairo_atomic_int_t; - -#ifdef ATOMIC_OP_NEEDS_MEMORY_BARRIER -static cairo_always_inline cairo_atomic_int_t -_cairo_atomic_int_get (cairo_atomic_int_t *x) -{ - __sync_synchronize (); - return *x; -} - -static cairo_always_inline void * -_cairo_atomic_ptr_get (void **x) -{ - __sync_synchronize (); - return *x; -} -#else -# define _cairo_atomic_int_get(x) (*x) -# define _cairo_atomic_ptr_get(x) (*x) -#endif - -# define _cairo_atomic_int_inc(x) ((void) __sync_fetch_and_add(x, 1)) -# define _cairo_atomic_int_dec(x) ((void) __sync_fetch_and_add(x, -1)) -# define _cairo_atomic_int_dec_and_test(x) (__sync_fetch_and_add(x, -1) == 1) -# define _cairo_atomic_int_cmpxchg(x, oldv, newv) __sync_bool_compare_and_swap (x, oldv, newv) -# define _cairo_atomic_int_cmpxchg_return_old(x, oldv, newv) __sync_val_compare_and_swap (x, oldv, newv) - -#if SIZEOF_VOID_P==SIZEOF_INT -typedef int cairo_atomic_intptr_t; -#elif SIZEOF_VOID_P==SIZEOF_LONG -typedef long cairo_atomic_intptr_t; -#elif SIZEOF_VOID_P==SIZEOF_LONG_LONG -typedef long long cairo_atomic_intptr_t; -#else -#error No matching integer pointer type -#endif - -# define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \ - __sync_bool_compare_and_swap ((cairo_atomic_intptr_t*)x, (cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv) - -# define _cairo_atomic_ptr_cmpxchg_return_old(x, oldv, newv) \ - _cairo_atomic_intptr_to_voidptr (__sync_val_compare_and_swap ((cairo_atomic_intptr_t*)x, (cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv)) - -#endif - -#if HAVE_LIB_ATOMIC_OPS -#include <atomic_ops.h> - -#define HAS_ATOMIC_OPS 1 - -typedef AO_t cairo_atomic_int_t; - -# define _cairo_atomic_int_get(x) (AO_load_full (x)) - -# define _cairo_atomic_int_inc(x) ((void) AO_fetch_and_add1_full(x)) -# define _cairo_atomic_int_dec(x) ((void) AO_fetch_and_sub1_full(x)) -# define _cairo_atomic_int_dec_and_test(x) (AO_fetch_and_sub1_full(x) == 1) -# define _cairo_atomic_int_cmpxchg(x, oldv, newv) AO_compare_and_swap_full(x, oldv, newv) - -#if SIZEOF_VOID_P==SIZEOF_INT -typedef unsigned int cairo_atomic_intptr_t; -#elif SIZEOF_VOID_P==SIZEOF_LONG -typedef unsigned long cairo_atomic_intptr_t; -#elif SIZEOF_VOID_P==SIZEOF_LONG_LONG -typedef unsigned long long cairo_atomic_intptr_t; -#else -#error No matching integer pointer type -#endif - -# define _cairo_atomic_ptr_get(x) _cairo_atomic_intptr_to_voidptr (AO_load_full (x)) -# define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \ - _cairo_atomic_int_cmpxchg ((cairo_atomic_intptr_t*)(x), (cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv) - -#endif - -#if HAVE_OS_ATOMIC_OPS -#include <libkern/OSAtomic.h> - -#define HAS_ATOMIC_OPS 1 - -typedef int32_t cairo_atomic_int_t; - -# define _cairo_atomic_int_get(x) (OSMemoryBarrier(), *(x)) - -# define _cairo_atomic_int_inc(x) ((void) OSAtomicIncrement32Barrier (x)) -# define _cairo_atomic_int_dec(x) ((void) OSAtomicDecrement32Barrier (x)) -# define _cairo_atomic_int_dec_and_test(x) (OSAtomicDecrement32Barrier (x) == 0) -# define _cairo_atomic_int_cmpxchg(x, oldv, newv) OSAtomicCompareAndSwap32Barrier(oldv, newv, x) - -#if SIZEOF_VOID_P==4 -typedef int32_t cairo_atomic_intptr_t; -# define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \ - OSAtomicCompareAndSwap32Barrier((cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv, (cairo_atomic_intptr_t *)x) - -#elif SIZEOF_VOID_P==8 -typedef int64_t cairo_atomic_intptr_t; -# define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \ - OSAtomicCompareAndSwap64Barrier((cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv, (cairo_atomic_intptr_t *)x) - -#else -#error No matching integer pointer type -#endif - -# define _cairo_atomic_ptr_get(x) (OSMemoryBarrier(), *(x)) - -#endif - -#ifndef HAS_ATOMIC_OPS - -#if SIZEOF_VOID_P==SIZEOF_INT -typedef unsigned int cairo_atomic_intptr_t; -#elif SIZEOF_VOID_P==SIZEOF_LONG -typedef unsigned long cairo_atomic_intptr_t; -#elif SIZEOF_VOID_P==SIZEOF_LONG_LONG -typedef unsigned long long cairo_atomic_intptr_t; -#else -#error No matching integer pointer type -#endif - -typedef cairo_atomic_intptr_t cairo_atomic_int_t; - -cairo_private void -_cairo_atomic_int_inc (cairo_atomic_int_t *x); - -#define _cairo_atomic_int_dec(x) _cairo_atomic_int_dec_and_test(x) - -cairo_private cairo_bool_t -_cairo_atomic_int_dec_and_test (cairo_atomic_int_t *x); - -cairo_private cairo_atomic_int_t -_cairo_atomic_int_cmpxchg_return_old_impl (cairo_atomic_int_t *x, cairo_atomic_int_t oldv, cairo_atomic_int_t newv); - -cairo_private void * -_cairo_atomic_ptr_cmpxchg_return_old_impl (void **x, void *oldv, void *newv); - -#define _cairo_atomic_int_cmpxchg_return_old(x, oldv, newv) _cairo_atomic_int_cmpxchg_return_old_impl (x, oldv, newv) -#define _cairo_atomic_ptr_cmpxchg_return_old(x, oldv, newv) _cairo_atomic_ptr_cmpxchg_return_old_impl (x, oldv, newv) - -#ifdef ATOMIC_OP_NEEDS_MEMORY_BARRIER -cairo_private cairo_atomic_int_t -_cairo_atomic_int_get (cairo_atomic_int_t *x); -# define _cairo_atomic_ptr_get(x) (void *) _cairo_atomic_int_get((cairo_atomic_int_t *) x) -#else -# define _cairo_atomic_int_get(x) (*x) -# define _cairo_atomic_ptr_get(x) (*x) -#endif - -#else - -/* Workaround GCC complaining about casts */ -static cairo_always_inline void * -_cairo_atomic_intptr_to_voidptr (cairo_atomic_intptr_t x) -{ - return (void *) x; -} - -static cairo_always_inline cairo_atomic_int_t -_cairo_atomic_int_cmpxchg_return_old_fallback(cairo_atomic_int_t *x, cairo_atomic_int_t oldv, cairo_atomic_int_t newv) -{ - cairo_atomic_int_t curr; - - do { - curr = _cairo_atomic_int_get (x); - } while (curr == oldv && !_cairo_atomic_int_cmpxchg (x, oldv, newv)); - - return curr; -} - -static cairo_always_inline void * -_cairo_atomic_ptr_cmpxchg_return_old_fallback(void **x, void *oldv, void *newv) -{ - void *curr; - - do { - curr = _cairo_atomic_ptr_get (x); - } while (curr == oldv && !_cairo_atomic_ptr_cmpxchg (x, oldv, newv)); - - return curr; -} -#endif - -#ifndef _cairo_atomic_int_cmpxchg_return_old -#define _cairo_atomic_int_cmpxchg_return_old(x, oldv, newv) _cairo_atomic_int_cmpxchg_return_old_fallback (x, oldv, newv) -#endif - -#ifndef _cairo_atomic_ptr_cmpxchg_return_old -#define _cairo_atomic_ptr_cmpxchg_return_old(x, oldv, newv) _cairo_atomic_ptr_cmpxchg_return_old_fallback (x, oldv, newv) -#endif - -#ifndef _cairo_atomic_int_cmpxchg -#define _cairo_atomic_int_cmpxchg(x, oldv, newv) (_cairo_atomic_int_cmpxchg_return_old (x, oldv, newv) == oldv) -#endif - -#ifndef _cairo_atomic_ptr_cmpxchg -#define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) (_cairo_atomic_ptr_cmpxchg_return_old (x, oldv, newv) == oldv) -#endif - -#define _cairo_atomic_uint_get(x) _cairo_atomic_int_get(x) -#define _cairo_atomic_uint_cmpxchg(x, oldv, newv) \ - _cairo_atomic_int_cmpxchg((cairo_atomic_int_t *)x, oldv, newv) - -#define _cairo_status_set_error(status, err) do { \ - int ret__; \ - assert (err < CAIRO_STATUS_LAST_STATUS); \ - /* hide compiler warnings about cairo_status_t != int (gcc treats its as \ - * an unsigned integer instead, and about ignoring the return value. */ \ - ret__ = _cairo_atomic_int_cmpxchg ((cairo_atomic_int_t *) status, CAIRO_STATUS_SUCCESS, err); \ - (void) ret__; \ -} while (0) - -CAIRO_END_DECLS - -#endif diff --git a/source/libs/cairo/cairo-src/src/cairo-atomic.c b/source/libs/cairo/cairo-src/src/cairo-atomic.c deleted file mode 100644 index 909cfea492548216902a43c7bfbcd23d7cc95656..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-atomic.c +++ /dev/null @@ -1,106 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2007 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-atomic-private.h" -#include "cairo-mutex-private.h" - -#ifdef HAS_ATOMIC_OPS -COMPILE_TIME_ASSERT(sizeof(void*) == sizeof(int) || - sizeof(void*) == sizeof(long) || - sizeof(void*) == sizeof(long long)); -#else -void -_cairo_atomic_int_inc (cairo_atomic_intptr_t *x) -{ - CAIRO_MUTEX_LOCK (_cairo_atomic_mutex); - *x += 1; - CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex); -} - -cairo_bool_t -_cairo_atomic_int_dec_and_test (cairo_atomic_intptr_t *x) -{ - cairo_bool_t ret; - - CAIRO_MUTEX_LOCK (_cairo_atomic_mutex); - ret = --*x == 0; - CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex); - - return ret; -} - -cairo_atomic_intptr_t -_cairo_atomic_int_cmpxchg_return_old_impl (cairo_atomic_intptr_t *x, cairo_atomic_intptr_t oldv, cairo_atomic_intptr_t newv) -{ - cairo_atomic_intptr_t ret; - - CAIRO_MUTEX_LOCK (_cairo_atomic_mutex); - ret = *x; - if (ret == oldv) - *x = newv; - CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex); - - return ret; -} - -void * -_cairo_atomic_ptr_cmpxchg_return_old_impl (void **x, void *oldv, void *newv) -{ - void *ret; - - CAIRO_MUTEX_LOCK (_cairo_atomic_mutex); - ret = *x; - if (ret == oldv) - *x = newv; - CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex); - - return ret; -} - -#ifdef ATOMIC_OP_NEEDS_MEMORY_BARRIER -cairo_atomic_intptr_t -_cairo_atomic_int_get (cairo_atomic_intptr_t *x) -{ - cairo_atomic_intptr_t ret; - - CAIRO_MUTEX_LOCK (_cairo_atomic_mutex); - ret = *x; - CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex); - - return ret; -} -#endif - -#endif diff --git a/source/libs/cairo/cairo-src/src/cairo-backend-private.h b/source/libs/cairo/cairo-src/src/cairo-backend-private.h deleted file mode 100644 index b05eca59ab337faba31342752b21c827905bfc34..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-backend-private.h +++ /dev/null @@ -1,201 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2010 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Intel Corporation - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_BACKEND_PRIVATE_H -#define CAIRO_BACKEND_PRIVATE_H - -#include "cairo-types-private.h" -#include "cairo-private.h" - -typedef enum _cairo_backend_type { - CAIRO_TYPE_DEFAULT, - CAIRO_TYPE_SKIA, -} cairo_backend_type_t; - -struct _cairo_backend { - cairo_backend_type_t type; - void (*destroy) (void *cr); - - cairo_surface_t *(*get_original_target) (void *cr); - cairo_surface_t *(*get_current_target) (void *cr); - - cairo_status_t (*save) (void *cr); - cairo_status_t (*restore) (void *cr); - - cairo_status_t (*push_group) (void *cr, cairo_content_t content); - cairo_pattern_t *(*pop_group) (void *cr); - - cairo_status_t (*set_source_rgba) (void *cr, double red, double green, double blue, double alpha); - cairo_status_t (*set_source_surface) (void *cr, cairo_surface_t *surface, double x, double y); - cairo_status_t (*set_source) (void *cr, cairo_pattern_t *source); - cairo_pattern_t *(*get_source) (void *cr); - - cairo_status_t (*set_antialias) (void *cr, cairo_antialias_t antialias); - cairo_status_t (*set_dash) (void *cr, const double *dashes, int num_dashes, double offset); - cairo_status_t (*set_fill_rule) (void *cr, cairo_fill_rule_t fill_rule); - cairo_status_t (*set_line_cap) (void *cr, cairo_line_cap_t line_cap); - cairo_status_t (*set_line_join) (void *cr, cairo_line_join_t line_join); - cairo_status_t (*set_line_width) (void *cr, double line_width); - cairo_status_t (*set_miter_limit) (void *cr, double limit); - cairo_status_t (*set_opacity) (void *cr, double opacity); - cairo_status_t (*set_operator) (void *cr, cairo_operator_t op); - cairo_status_t (*set_tolerance) (void *cr, double tolerance); - - cairo_antialias_t (*get_antialias) (void *cr); - void (*get_dash) (void *cr, double *dashes, int *num_dashes, double *offset); - cairo_fill_rule_t (*get_fill_rule) (void *cr); - cairo_line_cap_t (*get_line_cap) (void *cr); - cairo_line_join_t (*get_line_join) (void *cr); - double (*get_line_width) (void *cr); - double (*get_miter_limit) (void *cr); - double (*get_opacity) (void *cr); - cairo_operator_t (*get_operator) (void *cr); - double (*get_tolerance) (void *cr); - - cairo_status_t (*translate) (void *cr, double tx, double ty); - cairo_status_t (*scale) (void *cr, double sx, double sy); - cairo_status_t (*rotate) (void *cr, double theta); - cairo_status_t (*transform) (void *cr, const cairo_matrix_t *matrix); - cairo_status_t (*set_matrix) (void *cr, const cairo_matrix_t *matrix); - cairo_status_t (*set_identity_matrix) (void *cr); - void (*get_matrix) (void *cr, cairo_matrix_t *matrix); - - void (*user_to_device) (void *cr, double *x, double *y); - void (*user_to_device_distance) (void *cr, double *x, double *y); - void (*device_to_user) (void *cr, double *x, double *y); - void (*device_to_user_distance) (void *cr, double *x, double *y); - - void (*user_to_backend) (void *cr, double *x, double *y); - void (*user_to_backend_distance) (void *cr, double *x, double *y); - void (*backend_to_user) (void *cr, double *x, double *y); - void (*backend_to_user_distance) (void *cr, double *x, double *y); - - cairo_status_t (*new_path) (void *cr); - cairo_status_t (*new_sub_path) (void *cr); - cairo_status_t (*move_to) (void *cr, double x, double y); - cairo_status_t (*rel_move_to) (void *cr, double dx, double dy); - cairo_status_t (*line_to) (void *cr, double x, double y); - cairo_status_t (*rel_line_to) (void *cr, double dx, double dy); - cairo_status_t (*curve_to) (void *cr, double x1, double y1, double x2, double y2, double x3, double y3); - cairo_status_t (*rel_curve_to) (void *cr, double dx1, double dy1, double dx2, double dy2, double dx3, double dy3); - cairo_status_t (*arc_to) (void *cr, double x1, double y1, double x2, double y2, double radius); - cairo_status_t (*rel_arc_to) (void *cr, double dx1, double dy1, double dx2, double dy2, double radius); - cairo_status_t (*close_path) (void *cr); - - cairo_status_t (*arc) (void *cr, double xc, double yc, double radius, double angle1, double angle2, cairo_bool_t forward); - cairo_status_t (*rectangle) (void *cr, double x, double y, double width, double height); - - void (*path_extents) (void *cr, double *x1, double *y1, double *x2, double *y2); - cairo_bool_t (*has_current_point) (void *cr); - cairo_bool_t (*get_current_point) (void *cr, double *x, double *y); - - cairo_path_t *(*copy_path) (void *cr); - cairo_path_t *(*copy_path_flat) (void *cr); - cairo_status_t (*append_path) (void *cr, const cairo_path_t *path); - - cairo_status_t (*stroke_to_path) (void *cr); - - cairo_status_t (*clip) (void *cr); - cairo_status_t (*clip_preserve) (void *cr); - cairo_status_t (*in_clip) (void *cr, double x, double y, cairo_bool_t *inside); - cairo_status_t (*clip_extents) (void *cr, double *x1, double *y1, double *x2, double *y2); - cairo_status_t (*reset_clip) (void *cr); - cairo_rectangle_list_t *(*clip_copy_rectangle_list) (void *cr); - - cairo_status_t (*paint) (void *cr); - cairo_status_t (*paint_with_alpha) (void *cr, double opacity); - cairo_status_t (*mask) (void *cr, cairo_pattern_t *pattern); - - cairo_status_t (*stroke) (void *cr); - cairo_status_t (*stroke_preserve) (void *cr); - cairo_status_t (*in_stroke) (void *cr, double x, double y, cairo_bool_t *inside); - cairo_status_t (*stroke_extents) (void *cr, double *x1, double *y1, double *x2, double *y2); - - cairo_status_t (*fill) (void *cr); - cairo_status_t (*fill_preserve) (void *cr); - cairo_status_t (*in_fill) (void *cr, double x, double y, cairo_bool_t *inside); - cairo_status_t (*fill_extents) (void *cr, double *x1, double *y1, double *x2, double *y2); - - cairo_status_t (*set_font_face) (void *cr, cairo_font_face_t *font_face); - cairo_font_face_t *(*get_font_face) (void *cr); - cairo_status_t (*set_font_size) (void *cr, double size); - cairo_status_t (*set_font_matrix) (void *cr, const cairo_matrix_t *matrix); - void (*get_font_matrix) (void *cr, cairo_matrix_t *matrix); - cairo_status_t (*set_font_options) (void *cr, const cairo_font_options_t *options); - void (*get_font_options) (void *cr, cairo_font_options_t *options); - cairo_status_t (*set_scaled_font) (void *cr, cairo_scaled_font_t *scaled_font); - cairo_scaled_font_t *(*get_scaled_font) (void *cr); - cairo_status_t (*font_extents) (void *cr, cairo_font_extents_t *extents); - - cairo_status_t (*glyphs) (void *cr, - const cairo_glyph_t *glyphs, int num_glyphs, - cairo_glyph_text_info_t *info); - cairo_status_t (*glyph_path) (void *cr, - const cairo_glyph_t *glyphs, int num_glyphs); - - cairo_status_t (*glyph_extents) (void *cr, - const cairo_glyph_t *glyphs, - int num_glyphs, - cairo_text_extents_t *extents); - - cairo_status_t (*copy_page) (void *cr); - cairo_status_t (*show_page) (void *cr); -}; - -static inline void -_cairo_backend_to_user (cairo_t *cr, double *x, double *y) -{ - cr->backend->backend_to_user (cr, x, y); -} - -static inline void -_cairo_backend_to_user_distance (cairo_t *cr, double *x, double *y) -{ - cr->backend->backend_to_user_distance (cr, x, y); -} - -static inline void -_cairo_user_to_backend (cairo_t *cr, double *x, double *y) -{ - cr->backend->user_to_backend (cr, x, y); -} - -static inline void -_cairo_user_to_backend_distance (cairo_t *cr, double *x, double *y) -{ - cr->backend->user_to_backend_distance (cr, x, y); -} - -#endif /* CAIRO_BACKEND_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-base64-stream.c b/source/libs/cairo/cairo-src/src/cairo-base64-stream.c deleted file mode 100644 index 636431372b588331042a4cdd7b571004863ac8e8..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-base64-stream.c +++ /dev/null @@ -1,144 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2005-2007 Emmanuel Pacaud <emmanuel.pacaud@free.fr> - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Author(s): - * Kristian Høgsberg <krh@redhat.com> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" -#include "cairo-error-private.h" -#include "cairo-output-stream-private.h" - -typedef struct _cairo_base64_stream { - cairo_output_stream_t base; - cairo_output_stream_t *output; - unsigned int in_mem; - unsigned int trailing; - unsigned char src[3]; -} cairo_base64_stream_t; - -static char const base64_table[64] = -"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -static cairo_status_t -_cairo_base64_stream_write (cairo_output_stream_t *base, - const unsigned char *data, - unsigned int length) -{ - cairo_base64_stream_t * stream = (cairo_base64_stream_t *) base; - unsigned char *src = stream->src; - unsigned int i; - - if (stream->in_mem + length < 3) { - for (i = 0; i < length; i++) { - src[i + stream->in_mem] = *data++; - } - stream->in_mem += length; - return CAIRO_STATUS_SUCCESS; - } - - do { - unsigned char dst[4]; - - for (i = stream->in_mem; i < 3; i++) { - src[i] = *data++; - length--; - } - stream->in_mem = 0; - - dst[0] = base64_table[src[0] >> 2]; - dst[1] = base64_table[(src[0] & 0x03) << 4 | src[1] >> 4]; - dst[2] = base64_table[(src[1] & 0x0f) << 2 | src[2] >> 6]; - dst[3] = base64_table[src[2] & 0xfc >> 2]; - /* Special case for the last missing bits */ - switch (stream->trailing) { - case 2: - dst[2] = '='; - case 1: - dst[3] = '='; - default: - break; - } - _cairo_output_stream_write (stream->output, dst, 4); - } while (length >= 3); - - for (i = 0; i < length; i++) { - src[i] = *data++; - } - stream->in_mem = length; - - return _cairo_output_stream_get_status (stream->output); -} - -static cairo_status_t -_cairo_base64_stream_close (cairo_output_stream_t *base) -{ - cairo_base64_stream_t *stream = (cairo_base64_stream_t *) base; - cairo_status_t status = CAIRO_STATUS_SUCCESS; - - if (stream->in_mem > 0) { - memset (stream->src + stream->in_mem, 0, 3 - stream->in_mem); - stream->trailing = 3 - stream->in_mem; - stream->in_mem = 3; - status = _cairo_base64_stream_write (base, NULL, 0); - } - - return status; -} - -cairo_output_stream_t * -_cairo_base64_stream_create (cairo_output_stream_t *output) -{ - cairo_base64_stream_t *stream; - - if (output->status) - return _cairo_output_stream_create_in_error (output->status); - - stream = malloc (sizeof (cairo_base64_stream_t)); - if (unlikely (stream == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_output_stream_t *) &_cairo_output_stream_nil; - } - - _cairo_output_stream_init (&stream->base, - _cairo_base64_stream_write, - NULL, - _cairo_base64_stream_close); - - stream->output = output; - stream->in_mem = 0; - stream->trailing = 0; - - return &stream->base; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-base85-stream.c b/source/libs/cairo/cairo-src/src/cairo-base85-stream.c deleted file mode 100644 index f81affb49ea4d56f4bcac481ebfc819750d66b85..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-base85-stream.c +++ /dev/null @@ -1,131 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Author(s): - * Kristian Høgsberg <krh@redhat.com> - */ - -#include "cairoint.h" -#include "cairo-error-private.h" -#include "cairo-output-stream-private.h" - -typedef struct _cairo_base85_stream { - cairo_output_stream_t base; - 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 (cairo_output_stream_t *base, - const unsigned char *data, - unsigned int length) -{ - cairo_base85_stream_t *stream = (cairo_base85_stream_t *) base; - 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 (cairo_output_stream_t *base) -{ - cairo_base85_stream_t *stream = (cairo_base85_stream_t *) base; - 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); - } - - return _cairo_output_stream_get_status (stream->output); -} - -cairo_output_stream_t * -_cairo_base85_stream_create (cairo_output_stream_t *output) -{ - cairo_base85_stream_t *stream; - - if (output->status) - return _cairo_output_stream_create_in_error (output->status); - - stream = malloc (sizeof (cairo_base85_stream_t)); - if (unlikely (stream == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_output_stream_t *) &_cairo_output_stream_nil; - } - - _cairo_output_stream_init (&stream->base, - _cairo_base85_stream_write, - NULL, - _cairo_base85_stream_close); - stream->output = output; - stream->pending = 0; - - return &stream->base; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann-rectangular.c b/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann-rectangular.c deleted file mode 100644 index 5541bdc3a2d15569d5995fc97b929ea8d881ed3e..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann-rectangular.c +++ /dev/null @@ -1,884 +0,0 @@ -/* - * Copyright © 2004 Carl Worth - * Copyright © 2006 Red Hat, Inc. - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Carl Worth - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -/* Provide definitions for standalone compilation */ -#include "cairoint.h" - -#include "cairo-boxes-private.h" -#include "cairo-error-private.h" -#include "cairo-combsort-inline.h" -#include "cairo-list-private.h" -#include "cairo-traps-private.h" - -#include <setjmp.h> - -typedef struct _rectangle rectangle_t; -typedef struct _edge edge_t; - -struct _edge { - edge_t *next, *prev; - edge_t *right; - cairo_fixed_t x, top; - int dir; -}; - -struct _rectangle { - edge_t left, right; - int32_t top, bottom; -}; - -#define UNROLL3(x) x x x - -/* the parent is always given by index/2 */ -#define PQ_PARENT_INDEX(i) ((i) >> 1) -#define PQ_FIRST_ENTRY 1 - -/* left and right children are index * 2 and (index * 2) +1 respectively */ -#define PQ_LEFT_CHILD_INDEX(i) ((i) << 1) - -typedef struct _sweep_line { - rectangle_t **rectangles; - rectangle_t **stop; - edge_t head, tail, *insert, *cursor; - int32_t current_y; - int32_t last_y; - int stop_size; - - int32_t insert_x; - cairo_fill_rule_t fill_rule; - - cairo_bool_t do_traps; - void *container; - - jmp_buf unwind; -} sweep_line_t; - -#define DEBUG_TRAPS 0 - -#if DEBUG_TRAPS -static void -dump_traps (cairo_traps_t *traps, const char *filename) -{ - FILE *file; - int n; - - if (getenv ("CAIRO_DEBUG_TRAPS") == NULL) - return; - - file = fopen (filename, "a"); - if (file != NULL) { - for (n = 0; n < traps->num_traps; n++) { - fprintf (file, "%d %d L:(%d, %d), (%d, %d) R:(%d, %d), (%d, %d)\n", - traps->traps[n].top, - traps->traps[n].bottom, - traps->traps[n].left.p1.x, - traps->traps[n].left.p1.y, - traps->traps[n].left.p2.x, - traps->traps[n].left.p2.y, - traps->traps[n].right.p1.x, - traps->traps[n].right.p1.y, - traps->traps[n].right.p2.x, - traps->traps[n].right.p2.y); - } - fprintf (file, "\n"); - fclose (file); - } -} -#else -#define dump_traps(traps, filename) -#endif - -static inline int -rectangle_compare_start (const rectangle_t *a, - const rectangle_t *b) -{ - return a->top - b->top; -} - -static inline int -rectangle_compare_stop (const rectangle_t *a, - const rectangle_t *b) -{ - return a->bottom - b->bottom; -} - -static inline void -pqueue_push (sweep_line_t *sweep, rectangle_t *rectangle) -{ - rectangle_t **elements; - int i, parent; - - elements = sweep->stop; - for (i = ++sweep->stop_size; - i != PQ_FIRST_ENTRY && - rectangle_compare_stop (rectangle, - elements[parent = PQ_PARENT_INDEX (i)]) < 0; - i = parent) - { - elements[i] = elements[parent]; - } - - elements[i] = rectangle; -} - -static inline void -rectangle_pop_stop (sweep_line_t *sweep) -{ - rectangle_t **elements = sweep->stop; - rectangle_t *tail; - int child, i; - - tail = elements[sweep->stop_size--]; - if (sweep->stop_size == 0) { - elements[PQ_FIRST_ENTRY] = NULL; - return; - } - - for (i = PQ_FIRST_ENTRY; - (child = PQ_LEFT_CHILD_INDEX (i)) <= sweep->stop_size; - i = child) - { - if (child != sweep->stop_size && - rectangle_compare_stop (elements[child+1], - elements[child]) < 0) - { - child++; - } - - if (rectangle_compare_stop (elements[child], tail) >= 0) - break; - - elements[i] = elements[child]; - } - elements[i] = tail; -} - -static inline rectangle_t * -rectangle_pop_start (sweep_line_t *sweep_line) -{ - return *sweep_line->rectangles++; -} - -static inline rectangle_t * -rectangle_peek_stop (sweep_line_t *sweep_line) -{ - return sweep_line->stop[PQ_FIRST_ENTRY]; -} - -CAIRO_COMBSORT_DECLARE (_rectangle_sort, - rectangle_t *, - rectangle_compare_start) - -static void -sweep_line_init (sweep_line_t *sweep_line, - rectangle_t **rectangles, - int num_rectangles, - cairo_fill_rule_t fill_rule, - cairo_bool_t do_traps, - void *container) -{ - rectangles[-2] = NULL; - rectangles[-1] = NULL; - rectangles[num_rectangles] = NULL; - sweep_line->rectangles = rectangles; - sweep_line->stop = rectangles - 2; - sweep_line->stop_size = 0; - - sweep_line->insert = NULL; - sweep_line->insert_x = INT_MAX; - sweep_line->cursor = &sweep_line->tail; - - sweep_line->head.dir = 0; - sweep_line->head.x = INT32_MIN; - sweep_line->head.right = NULL; - sweep_line->head.prev = NULL; - sweep_line->head.next = &sweep_line->tail; - sweep_line->tail.prev = &sweep_line->head; - sweep_line->tail.next = NULL; - sweep_line->tail.right = NULL; - sweep_line->tail.x = INT32_MAX; - sweep_line->tail.dir = 0; - - sweep_line->current_y = INT32_MIN; - sweep_line->last_y = INT32_MIN; - - sweep_line->fill_rule = fill_rule; - sweep_line->container = container; - sweep_line->do_traps = do_traps; -} - -static void -edge_end_box (sweep_line_t *sweep_line, edge_t *left, int32_t bot) -{ - cairo_status_t status = CAIRO_STATUS_SUCCESS; - - /* Only emit (trivial) non-degenerate trapezoids with positive height. */ - if (likely (left->top < bot)) { - if (sweep_line->do_traps) { - cairo_line_t _left = { - { left->x, left->top }, - { left->x, bot }, - }, _right = { - { left->right->x, left->top }, - { left->right->x, bot }, - }; - _cairo_traps_add_trap (sweep_line->container, left->top, bot, &_left, &_right); - status = _cairo_traps_status ((cairo_traps_t *) sweep_line->container); - } else { - cairo_box_t box; - - box.p1.x = left->x; - box.p1.y = left->top; - box.p2.x = left->right->x; - box.p2.y = bot; - - status = _cairo_boxes_add (sweep_line->container, - CAIRO_ANTIALIAS_DEFAULT, - &box); - } - } - if (unlikely (status)) - longjmp (sweep_line->unwind, status); - - left->right = NULL; -} - -/* Start a new trapezoid at the given top y coordinate, whose edges - * are `edge' and `edge->next'. If `edge' already has a trapezoid, - * then either add it to the traps in `traps', if the trapezoid's - * right edge differs from `edge->next', or do nothing if the new - * trapezoid would be a continuation of the existing one. */ -static inline void -edge_start_or_continue_box (sweep_line_t *sweep_line, - edge_t *left, - edge_t *right, - int top) -{ - if (left->right == right) - return; - - if (left->right != NULL) { - if (left->right->x == right->x) { - /* continuation on right, so just swap edges */ - left->right = right; - return; - } - - edge_end_box (sweep_line, left, top); - } - - if (left->x != right->x) { - left->top = top; - left->right = right; - } -} -/* - * Merge two sorted edge lists. - * Input: - * - head_a: The head of the first list. - * - head_b: The head of the second list; head_b cannot be NULL. - * Output: - * Returns the head of the merged list. - * - * Implementation notes: - * To make it fast (in particular, to reduce to an insertion sort whenever - * one of the two input lists only has a single element) we iterate through - * a list until its head becomes greater than the head of the other list, - * then we switch their roles. As soon as one of the two lists is empty, we - * just attach the other one to the current list and exit. - * Writes to memory are only needed to "switch" lists (as it also requires - * attaching to the output list the list which we will be iterating next) and - * to attach the last non-empty list. - */ -static edge_t * -merge_sorted_edges (edge_t *head_a, edge_t *head_b) -{ - edge_t *head, *prev; - int32_t x; - - prev = head_a->prev; - if (head_a->x <= head_b->x) { - head = head_a; - } else { - head_b->prev = prev; - head = head_b; - goto start_with_b; - } - - do { - x = head_b->x; - while (head_a != NULL && head_a->x <= x) { - prev = head_a; - head_a = head_a->next; - } - - head_b->prev = prev; - prev->next = head_b; - if (head_a == NULL) - return head; - -start_with_b: - x = head_a->x; - while (head_b != NULL && head_b->x <= x) { - prev = head_b; - head_b = head_b->next; - } - - head_a->prev = prev; - prev->next = head_a; - if (head_b == NULL) - return head; - } while (1); -} - -/* - * Sort (part of) a list. - * Input: - * - list: The list to be sorted; list cannot be NULL. - * - limit: Recursion limit. - * Output: - * - head_out: The head of the sorted list containing the first 2^(level+1) elements of the - * input list; if the input list has fewer elements, head_out be a sorted list - * containing all the elements of the input list. - * Returns the head of the list of unprocessed elements (NULL if the sorted list contains - * all the elements of the input list). - * - * Implementation notes: - * Special case single element list, unroll/inline the sorting of the first two elements. - * Some tail recursion is used since we iterate on the bottom-up solution of the problem - * (we start with a small sorted list and keep merging other lists of the same size to it). - */ -static edge_t * -sort_edges (edge_t *list, - unsigned int level, - edge_t **head_out) -{ - edge_t *head_other, *remaining; - unsigned int i; - - head_other = list->next; - - if (head_other == NULL) { - *head_out = list; - return NULL; - } - - remaining = head_other->next; - if (list->x <= head_other->x) { - *head_out = list; - head_other->next = NULL; - } else { - *head_out = head_other; - head_other->prev = list->prev; - head_other->next = list; - list->prev = head_other; - list->next = NULL; - } - - for (i = 0; i < level && remaining; i++) { - remaining = sort_edges (remaining, i, &head_other); - *head_out = merge_sorted_edges (*head_out, head_other); - } - - return remaining; -} - -static edge_t * -merge_unsorted_edges (edge_t *head, edge_t *unsorted) -{ - sort_edges (unsorted, UINT_MAX, &unsorted); - return merge_sorted_edges (head, unsorted); -} - -static void -active_edges_insert (sweep_line_t *sweep) -{ - edge_t *prev; - int x; - - x = sweep->insert_x; - prev = sweep->cursor; - if (prev->x > x) { - do { - prev = prev->prev; - } while (prev->x > x); - } else { - while (prev->next->x < x) - prev = prev->next; - } - - prev->next = merge_unsorted_edges (prev->next, sweep->insert); - sweep->cursor = sweep->insert; - sweep->insert = NULL; - sweep->insert_x = INT_MAX; -} - -static inline void -active_edges_to_traps (sweep_line_t *sweep) -{ - int top = sweep->current_y; - edge_t *pos; - - if (sweep->last_y == sweep->current_y) - return; - - if (sweep->insert) - active_edges_insert (sweep); - - pos = sweep->head.next; - if (pos == &sweep->tail) - return; - - if (sweep->fill_rule == CAIRO_FILL_RULE_WINDING) { - do { - edge_t *left, *right; - int winding; - - left = pos; - winding = left->dir; - - right = left->next; - - /* Check if there is a co-linear edge with an existing trap */ - while (right->x == left->x) { - if (right->right != NULL) { - assert (left->right == NULL); - /* continuation on left */ - left->top = right->top; - left->right = right->right; - right->right = NULL; - } - winding += right->dir; - right = right->next; - } - - if (winding == 0) { - if (left->right != NULL) - edge_end_box (sweep, left, top); - pos = right; - continue; - } - - do { - /* End all subsumed traps */ - if (unlikely (right->right != NULL)) - edge_end_box (sweep, right, top); - - /* Greedily search for the closing edge, so that we generate - * the * maximal span width with the minimal number of - * boxes. - */ - winding += right->dir; - if (winding == 0 && right->x != right->next->x) - break; - - right = right->next; - } while (TRUE); - - edge_start_or_continue_box (sweep, left, right, top); - - pos = right->next; - } while (pos != &sweep->tail); - } else { - do { - edge_t *right = pos->next; - int count = 0; - - do { - /* End all subsumed traps */ - if (unlikely (right->right != NULL)) - edge_end_box (sweep, right, top); - - /* skip co-linear edges */ - if (++count & 1 && right->x != right->next->x) - break; - - right = right->next; - } while (TRUE); - - edge_start_or_continue_box (sweep, pos, right, top); - - pos = right->next; - } while (pos != &sweep->tail); - } - - sweep->last_y = sweep->current_y; -} - -static inline void -sweep_line_delete_edge (sweep_line_t *sweep, edge_t *edge) -{ - if (edge->right != NULL) { - edge_t *next = edge->next; - if (next->x == edge->x) { - next->top = edge->top; - next->right = edge->right; - } else - edge_end_box (sweep, edge, sweep->current_y); - } - - if (sweep->cursor == edge) - sweep->cursor = edge->prev; - - edge->prev->next = edge->next; - edge->next->prev = edge->prev; -} - -static inline cairo_bool_t -sweep_line_delete (sweep_line_t *sweep, rectangle_t *rectangle) -{ - cairo_bool_t update; - - update = TRUE; - if (sweep->fill_rule == CAIRO_FILL_RULE_WINDING && - rectangle->left.prev->dir == rectangle->left.dir) - { - update = rectangle->left.next != &rectangle->right; - } - - sweep_line_delete_edge (sweep, &rectangle->left); - sweep_line_delete_edge (sweep, &rectangle->right); - - rectangle_pop_stop (sweep); - return update; -} - -static inline void -sweep_line_insert (sweep_line_t *sweep, rectangle_t *rectangle) -{ - if (sweep->insert) - sweep->insert->prev = &rectangle->right; - rectangle->right.next = sweep->insert; - rectangle->right.prev = &rectangle->left; - rectangle->left.next = &rectangle->right; - rectangle->left.prev = NULL; - sweep->insert = &rectangle->left; - if (rectangle->left.x < sweep->insert_x) - sweep->insert_x = rectangle->left.x; - - pqueue_push (sweep, rectangle); -} - -static cairo_status_t -_cairo_bentley_ottmann_tessellate_rectangular (rectangle_t **rectangles, - int num_rectangles, - cairo_fill_rule_t fill_rule, - cairo_bool_t do_traps, - void *container) -{ - sweep_line_t sweep_line; - rectangle_t *rectangle; - cairo_status_t status; - cairo_bool_t update = FALSE; - - sweep_line_init (&sweep_line, - rectangles, num_rectangles, - fill_rule, - do_traps, container); - if ((status = setjmp (sweep_line.unwind))) - return status; - - rectangle = rectangle_pop_start (&sweep_line); - do { - if (rectangle->top != sweep_line.current_y) { - rectangle_t *stop; - - stop = rectangle_peek_stop (&sweep_line); - while (stop != NULL && stop->bottom < rectangle->top) { - if (stop->bottom != sweep_line.current_y) { - if (update) { - active_edges_to_traps (&sweep_line); - update = FALSE; - } - - sweep_line.current_y = stop->bottom; - } - - update |= sweep_line_delete (&sweep_line, stop); - stop = rectangle_peek_stop (&sweep_line); - } - - if (update) { - active_edges_to_traps (&sweep_line); - update = FALSE; - } - - sweep_line.current_y = rectangle->top; - } - - do { - sweep_line_insert (&sweep_line, rectangle); - } while ((rectangle = rectangle_pop_start (&sweep_line)) != NULL && - sweep_line.current_y == rectangle->top); - update = TRUE; - } while (rectangle); - - while ((rectangle = rectangle_peek_stop (&sweep_line)) != NULL) { - if (rectangle->bottom != sweep_line.current_y) { - if (update) { - active_edges_to_traps (&sweep_line); - update = FALSE; - } - sweep_line.current_y = rectangle->bottom; - } - - update |= sweep_line_delete (&sweep_line, rectangle); - } - - return CAIRO_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_bentley_ottmann_tessellate_rectangular_traps (cairo_traps_t *traps, - cairo_fill_rule_t fill_rule) -{ - rectangle_t stack_rectangles[CAIRO_STACK_ARRAY_LENGTH (rectangle_t)]; - rectangle_t *stack_rectangles_ptrs[ARRAY_LENGTH (stack_rectangles) + 3]; - rectangle_t *rectangles, **rectangles_ptrs; - cairo_status_t status; - int i; - - if (unlikely (traps->num_traps <= 1)) - return CAIRO_STATUS_SUCCESS; - - assert (traps->is_rectangular); - - dump_traps (traps, "bo-rects-traps-in.txt"); - - rectangles = stack_rectangles; - rectangles_ptrs = stack_rectangles_ptrs; - if (traps->num_traps > ARRAY_LENGTH (stack_rectangles)) { - rectangles = _cairo_malloc_ab_plus_c (traps->num_traps, - sizeof (rectangle_t) + - sizeof (rectangle_t *), - 3*sizeof (rectangle_t *)); - if (unlikely (rectangles == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - rectangles_ptrs = (rectangle_t **) (rectangles + traps->num_traps); - } - - for (i = 0; i < traps->num_traps; i++) { - if (traps->traps[i].left.p1.x < traps->traps[i].right.p1.x) { - rectangles[i].left.x = traps->traps[i].left.p1.x; - rectangles[i].left.dir = 1; - - rectangles[i].right.x = traps->traps[i].right.p1.x; - rectangles[i].right.dir = -1; - } else { - rectangles[i].right.x = traps->traps[i].left.p1.x; - rectangles[i].right.dir = 1; - - rectangles[i].left.x = traps->traps[i].right.p1.x; - rectangles[i].left.dir = -1; - } - - rectangles[i].left.right = NULL; - rectangles[i].right.right = NULL; - - rectangles[i].top = traps->traps[i].top; - rectangles[i].bottom = traps->traps[i].bottom; - - rectangles_ptrs[i+2] = &rectangles[i]; - } - /* XXX incremental sort */ - _rectangle_sort (rectangles_ptrs+2, i); - - _cairo_traps_clear (traps); - status = _cairo_bentley_ottmann_tessellate_rectangular (rectangles_ptrs+2, i, - fill_rule, - TRUE, traps); - traps->is_rectilinear = TRUE; - traps->is_rectangular = TRUE; - - if (rectangles != stack_rectangles) - free (rectangles); - - dump_traps (traps, "bo-rects-traps-out.txt"); - - return status; -} - -cairo_status_t -_cairo_bentley_ottmann_tessellate_boxes (const cairo_boxes_t *in, - cairo_fill_rule_t fill_rule, - cairo_boxes_t *out) -{ - rectangle_t stack_rectangles[CAIRO_STACK_ARRAY_LENGTH (rectangle_t)]; - rectangle_t *stack_rectangles_ptrs[ARRAY_LENGTH (stack_rectangles) + 3]; - rectangle_t *rectangles, **rectangles_ptrs; - rectangle_t *stack_rectangles_chain[CAIRO_STACK_ARRAY_LENGTH (rectangle_t *) ]; - rectangle_t **rectangles_chain = NULL; - const struct _cairo_boxes_chunk *chunk; - cairo_status_t status; - int i, j, y_min, y_max; - - if (unlikely (in->num_boxes == 0)) { - _cairo_boxes_clear (out); - return CAIRO_STATUS_SUCCESS; - } - - if (in->num_boxes == 1) { - if (in == out) { - cairo_box_t *box = &in->chunks.base[0]; - - if (box->p1.x > box->p2.x) { - cairo_fixed_t tmp = box->p1.x; - box->p1.x = box->p2.x; - box->p2.x = tmp; - } - } else { - cairo_box_t box = in->chunks.base[0]; - - if (box.p1.x > box.p2.x) { - cairo_fixed_t tmp = box.p1.x; - box.p1.x = box.p2.x; - box.p2.x = tmp; - } - - _cairo_boxes_clear (out); - status = _cairo_boxes_add (out, CAIRO_ANTIALIAS_DEFAULT, &box); - assert (status == CAIRO_STATUS_SUCCESS); - } - return CAIRO_STATUS_SUCCESS; - } - - y_min = INT_MAX; y_max = INT_MIN; - for (chunk = &in->chunks; chunk != NULL; chunk = chunk->next) { - const cairo_box_t *box = chunk->base; - for (i = 0; i < chunk->count; i++) { - if (box[i].p1.y < y_min) - y_min = box[i].p1.y; - if (box[i].p1.y > y_max) - y_max = box[i].p1.y; - } - } - y_min = _cairo_fixed_integer_floor (y_min); - y_max = _cairo_fixed_integer_floor (y_max) + 1; - y_max -= y_min; - - if (y_max < in->num_boxes) { - rectangles_chain = stack_rectangles_chain; - if (y_max > ARRAY_LENGTH (stack_rectangles_chain)) { - rectangles_chain = _cairo_malloc_ab (y_max, sizeof (rectangle_t *)); - if (unlikely (rectangles_chain == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - memset (rectangles_chain, 0, y_max * sizeof (rectangle_t*)); - } - - rectangles = stack_rectangles; - rectangles_ptrs = stack_rectangles_ptrs; - if (in->num_boxes > ARRAY_LENGTH (stack_rectangles)) { - rectangles = _cairo_malloc_ab_plus_c (in->num_boxes, - sizeof (rectangle_t) + - sizeof (rectangle_t *), - 3*sizeof (rectangle_t *)); - if (unlikely (rectangles == NULL)) { - if (rectangles_chain != stack_rectangles_chain) - free (rectangles_chain); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - rectangles_ptrs = (rectangle_t **) (rectangles + in->num_boxes); - } - - j = 0; - for (chunk = &in->chunks; chunk != NULL; chunk = chunk->next) { - const cairo_box_t *box = chunk->base; - for (i = 0; i < chunk->count; i++) { - int h; - - if (box[i].p1.x < box[i].p2.x) { - rectangles[j].left.x = box[i].p1.x; - rectangles[j].left.dir = 1; - - rectangles[j].right.x = box[i].p2.x; - rectangles[j].right.dir = -1; - } else { - rectangles[j].right.x = box[i].p1.x; - rectangles[j].right.dir = 1; - - rectangles[j].left.x = box[i].p2.x; - rectangles[j].left.dir = -1; - } - - rectangles[j].left.right = NULL; - rectangles[j].right.right = NULL; - - rectangles[j].top = box[i].p1.y; - rectangles[j].bottom = box[i].p2.y; - - if (rectangles_chain) { - h = _cairo_fixed_integer_floor (box[i].p1.y) - y_min; - rectangles[j].left.next = (edge_t *)rectangles_chain[h]; - rectangles_chain[h] = &rectangles[j]; - } else { - rectangles_ptrs[j+2] = &rectangles[j]; - } - j++; - } - } - - if (rectangles_chain) { - j = 2; - for (y_min = 0; y_min < y_max; y_min++) { - rectangle_t *r; - int start = j; - for (r = rectangles_chain[y_min]; r; r = (rectangle_t *)r->left.next) - rectangles_ptrs[j++] = r; - if (j > start + 1) - _rectangle_sort (rectangles_ptrs + start, j - start); - } - - if (rectangles_chain != stack_rectangles_chain) - free (rectangles_chain); - - j -= 2; - } else { - _rectangle_sort (rectangles_ptrs + 2, j); - } - - _cairo_boxes_clear (out); - status = _cairo_bentley_ottmann_tessellate_rectangular (rectangles_ptrs+2, j, - fill_rule, - FALSE, out); - if (rectangles != stack_rectangles) - free (rectangles); - - return status; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann-rectilinear.c b/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann-rectilinear.c deleted file mode 100644 index 7c0be69b712a73f8826b03ce3d1f94266dfcded7..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann-rectilinear.c +++ /dev/null @@ -1,600 +0,0 @@ -/* - * Copyright © 2004 Carl Worth - * Copyright © 2006 Red Hat, Inc. - * Copyright © 2008 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Carl Worth - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -/* Provide definitions for standalone compilation */ -#include "cairoint.h" - -#include "cairo-boxes-private.h" -#include "cairo-combsort-inline.h" -#include "cairo-error-private.h" -#include "cairo-traps-private.h" - -typedef struct _cairo_bo_edge cairo_bo_edge_t; -typedef struct _cairo_bo_trap cairo_bo_trap_t; - -/* A deferred trapezoid of an edge */ -struct _cairo_bo_trap { - cairo_bo_edge_t *right; - int32_t top; -}; - -struct _cairo_bo_edge { - cairo_edge_t edge; - cairo_bo_edge_t *prev; - cairo_bo_edge_t *next; - cairo_bo_trap_t deferred_trap; -}; - -typedef enum { - CAIRO_BO_EVENT_TYPE_START, - CAIRO_BO_EVENT_TYPE_STOP -} cairo_bo_event_type_t; - -typedef struct _cairo_bo_event { - cairo_bo_event_type_t type; - cairo_point_t point; - cairo_bo_edge_t *edge; -} cairo_bo_event_t; - -typedef struct _cairo_bo_sweep_line { - cairo_bo_event_t **events; - cairo_bo_edge_t *head; - cairo_bo_edge_t *stopped; - int32_t current_y; - cairo_bo_edge_t *current_edge; -} cairo_bo_sweep_line_t; - -static inline int -_cairo_point_compare (const cairo_point_t *a, - const cairo_point_t *b) -{ - int cmp; - - cmp = a->y - b->y; - if (likely (cmp)) - return cmp; - - return a->x - b->x; -} - -static inline int -_cairo_bo_edge_compare (const cairo_bo_edge_t *a, - const cairo_bo_edge_t *b) -{ - int cmp; - - cmp = a->edge.line.p1.x - b->edge.line.p1.x; - if (likely (cmp)) - return cmp; - - return b->edge.bottom - a->edge.bottom; -} - -static inline int -cairo_bo_event_compare (const cairo_bo_event_t *a, - const cairo_bo_event_t *b) -{ - int cmp; - - cmp = _cairo_point_compare (&a->point, &b->point); - if (likely (cmp)) - return cmp; - - cmp = a->type - b->type; - if (cmp) - return cmp; - - return a - b; -} - -static inline cairo_bo_event_t * -_cairo_bo_event_dequeue (cairo_bo_sweep_line_t *sweep_line) -{ - return *sweep_line->events++; -} - -CAIRO_COMBSORT_DECLARE (_cairo_bo_event_queue_sort, - cairo_bo_event_t *, - cairo_bo_event_compare) - -static void -_cairo_bo_sweep_line_init (cairo_bo_sweep_line_t *sweep_line, - cairo_bo_event_t **events, - int num_events) -{ - _cairo_bo_event_queue_sort (events, num_events); - events[num_events] = NULL; - sweep_line->events = events; - - sweep_line->head = NULL; - sweep_line->current_y = INT32_MIN; - sweep_line->current_edge = NULL; -} - -static void -_cairo_bo_sweep_line_insert (cairo_bo_sweep_line_t *sweep_line, - cairo_bo_edge_t *edge) -{ - if (sweep_line->current_edge != NULL) { - cairo_bo_edge_t *prev, *next; - int cmp; - - cmp = _cairo_bo_edge_compare (sweep_line->current_edge, edge); - if (cmp < 0) { - prev = sweep_line->current_edge; - next = prev->next; - while (next != NULL && _cairo_bo_edge_compare (next, edge) < 0) - prev = next, next = prev->next; - - prev->next = edge; - edge->prev = prev; - edge->next = next; - if (next != NULL) - next->prev = edge; - } else if (cmp > 0) { - next = sweep_line->current_edge; - prev = next->prev; - while (prev != NULL && _cairo_bo_edge_compare (prev, edge) > 0) - next = prev, prev = next->prev; - - next->prev = edge; - edge->next = next; - edge->prev = prev; - if (prev != NULL) - prev->next = edge; - else - sweep_line->head = edge; - } else { - prev = sweep_line->current_edge; - edge->prev = prev; - edge->next = prev->next; - if (prev->next != NULL) - prev->next->prev = edge; - prev->next = edge; - } - } else { - sweep_line->head = edge; - } - - sweep_line->current_edge = edge; -} - -static void -_cairo_bo_sweep_line_delete (cairo_bo_sweep_line_t *sweep_line, - cairo_bo_edge_t *edge) -{ - if (edge->prev != NULL) - edge->prev->next = edge->next; - else - sweep_line->head = edge->next; - - if (edge->next != NULL) - edge->next->prev = edge->prev; - - if (sweep_line->current_edge == edge) - sweep_line->current_edge = edge->prev ? edge->prev : edge->next; -} - -static inline cairo_bool_t -edges_collinear (const cairo_bo_edge_t *a, const cairo_bo_edge_t *b) -{ - return a->edge.line.p1.x == b->edge.line.p1.x; -} - -static cairo_status_t -_cairo_bo_edge_end_trap (cairo_bo_edge_t *left, - int32_t bot, - cairo_bool_t do_traps, - void *container) -{ - cairo_bo_trap_t *trap = &left->deferred_trap; - cairo_status_t status = CAIRO_STATUS_SUCCESS; - - /* Only emit (trivial) non-degenerate trapezoids with positive height. */ - if (likely (trap->top < bot)) { - if (do_traps) { - _cairo_traps_add_trap (container, - trap->top, bot, - &left->edge.line, &trap->right->edge.line); - status = _cairo_traps_status ((cairo_traps_t *) container); - } else { - cairo_box_t box; - - box.p1.x = left->edge.line.p1.x; - box.p1.y = trap->top; - box.p2.x = trap->right->edge.line.p1.x; - box.p2.y = bot; - status = _cairo_boxes_add (container, CAIRO_ANTIALIAS_DEFAULT, &box); - } - } - - trap->right = NULL; - - return status; -} - -/* Start a new trapezoid at the given top y coordinate, whose edges - * are `edge' and `edge->next'. If `edge' already has a trapezoid, - * then either add it to the traps in `traps', if the trapezoid's - * right edge differs from `edge->next', or do nothing if the new - * trapezoid would be a continuation of the existing one. */ -static inline cairo_status_t -_cairo_bo_edge_start_or_continue_trap (cairo_bo_edge_t *left, - cairo_bo_edge_t *right, - int top, - cairo_bool_t do_traps, - void *container) -{ - cairo_status_t status; - - if (left->deferred_trap.right == right) - return CAIRO_STATUS_SUCCESS; - - if (left->deferred_trap.right != NULL) { - if (right != NULL && edges_collinear (left->deferred_trap.right, right)) - { - /* continuation on right, so just swap edges */ - left->deferred_trap.right = right; - return CAIRO_STATUS_SUCCESS; - } - - status = _cairo_bo_edge_end_trap (left, top, do_traps, container); - if (unlikely (status)) - return status; - } - - if (right != NULL && ! edges_collinear (left, right)) { - left->deferred_trap.top = top; - left->deferred_trap.right = right; - } - - return CAIRO_STATUS_SUCCESS; -} - -static inline cairo_status_t -_active_edges_to_traps (cairo_bo_edge_t *left, - int32_t top, - cairo_fill_rule_t fill_rule, - cairo_bool_t do_traps, - void *container) -{ - cairo_bo_edge_t *right; - cairo_status_t status; - - if (fill_rule == CAIRO_FILL_RULE_WINDING) { - while (left != NULL) { - int in_out; - - /* Greedily search for the closing edge, so that we generate the - * maximal span width with the minimal number of trapezoids. - */ - in_out = left->edge.dir; - - /* Check if there is a co-linear edge with an existing trap */ - right = left->next; - if (left->deferred_trap.right == NULL) { - while (right != NULL && right->deferred_trap.right == NULL) - right = right->next; - - if (right != NULL && edges_collinear (left, right)) { - /* continuation on left */ - left->deferred_trap = right->deferred_trap; - right->deferred_trap.right = NULL; - } - } - - /* End all subsumed traps */ - right = left->next; - while (right != NULL) { - if (right->deferred_trap.right != NULL) { - status = _cairo_bo_edge_end_trap (right, top, do_traps, container); - if (unlikely (status)) - return status; - } - - in_out += right->edge.dir; - if (in_out == 0) { - /* skip co-linear edges */ - if (right->next == NULL || - ! edges_collinear (right, right->next)) - { - break; - } - } - - right = right->next; - } - - status = _cairo_bo_edge_start_or_continue_trap (left, right, top, - do_traps, container); - if (unlikely (status)) - return status; - - left = right; - if (left != NULL) - left = left->next; - } - } else { - while (left != NULL) { - int in_out = 0; - - right = left->next; - while (right != NULL) { - if (right->deferred_trap.right != NULL) { - status = _cairo_bo_edge_end_trap (right, top, do_traps, container); - if (unlikely (status)) - return status; - } - - if ((in_out++ & 1) == 0) { - cairo_bo_edge_t *next; - cairo_bool_t skip = FALSE; - - /* skip co-linear edges */ - next = right->next; - if (next != NULL) - skip = edges_collinear (right, next); - - if (! skip) - break; - } - - right = right->next; - } - - status = _cairo_bo_edge_start_or_continue_trap (left, right, top, - do_traps, container); - if (unlikely (status)) - return status; - - left = right; - if (left != NULL) - left = left->next; - } - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_bentley_ottmann_tessellate_rectilinear (cairo_bo_event_t **start_events, - int num_events, - cairo_fill_rule_t fill_rule, - cairo_bool_t do_traps, - void *container) -{ - cairo_bo_sweep_line_t sweep_line; - cairo_bo_event_t *event; - cairo_status_t status; - - _cairo_bo_sweep_line_init (&sweep_line, start_events, num_events); - - while ((event = _cairo_bo_event_dequeue (&sweep_line))) { - if (event->point.y != sweep_line.current_y) { - status = _active_edges_to_traps (sweep_line.head, - sweep_line.current_y, - fill_rule, do_traps, container); - if (unlikely (status)) - return status; - - sweep_line.current_y = event->point.y; - } - - switch (event->type) { - case CAIRO_BO_EVENT_TYPE_START: - _cairo_bo_sweep_line_insert (&sweep_line, event->edge); - break; - - case CAIRO_BO_EVENT_TYPE_STOP: - _cairo_bo_sweep_line_delete (&sweep_line, event->edge); - - if (event->edge->deferred_trap.right != NULL) { - status = _cairo_bo_edge_end_trap (event->edge, - sweep_line.current_y, - do_traps, container); - if (unlikely (status)) - return status; - } - - break; - } - } - - return CAIRO_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_bentley_ottmann_tessellate_rectilinear_polygon_to_boxes (const cairo_polygon_t *polygon, - cairo_fill_rule_t fill_rule, - cairo_boxes_t *boxes) -{ - cairo_status_t status; - cairo_bo_event_t stack_events[CAIRO_STACK_ARRAY_LENGTH (cairo_bo_event_t)]; - cairo_bo_event_t *events; - cairo_bo_event_t *stack_event_ptrs[ARRAY_LENGTH (stack_events) + 1]; - cairo_bo_event_t **event_ptrs; - cairo_bo_edge_t stack_edges[ARRAY_LENGTH (stack_events)]; - cairo_bo_edge_t *edges; - int num_events; - int i, j; - - if (unlikely (polygon->num_edges == 0)) - return CAIRO_STATUS_SUCCESS; - - num_events = 2 * polygon->num_edges; - - events = stack_events; - event_ptrs = stack_event_ptrs; - edges = stack_edges; - if (num_events > ARRAY_LENGTH (stack_events)) { - events = _cairo_malloc_ab_plus_c (num_events, - sizeof (cairo_bo_event_t) + - sizeof (cairo_bo_edge_t) + - sizeof (cairo_bo_event_t *), - sizeof (cairo_bo_event_t *)); - if (unlikely (events == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - event_ptrs = (cairo_bo_event_t **) (events + num_events); - edges = (cairo_bo_edge_t *) (event_ptrs + num_events + 1); - } - - for (i = j = 0; i < polygon->num_edges; i++) { - edges[i].edge = polygon->edges[i]; - edges[i].deferred_trap.right = NULL; - edges[i].prev = NULL; - edges[i].next = NULL; - - event_ptrs[j] = &events[j]; - events[j].type = CAIRO_BO_EVENT_TYPE_START; - events[j].point.y = polygon->edges[i].top; - events[j].point.x = polygon->edges[i].line.p1.x; - events[j].edge = &edges[i]; - j++; - - event_ptrs[j] = &events[j]; - events[j].type = CAIRO_BO_EVENT_TYPE_STOP; - events[j].point.y = polygon->edges[i].bottom; - events[j].point.x = polygon->edges[i].line.p1.x; - events[j].edge = &edges[i]; - j++; - } - - status = _cairo_bentley_ottmann_tessellate_rectilinear (event_ptrs, j, - fill_rule, - FALSE, boxes); - if (events != stack_events) - free (events); - - return status; -} - -cairo_status_t -_cairo_bentley_ottmann_tessellate_rectilinear_traps (cairo_traps_t *traps, - cairo_fill_rule_t fill_rule) -{ - cairo_bo_event_t stack_events[CAIRO_STACK_ARRAY_LENGTH (cairo_bo_event_t)]; - cairo_bo_event_t *events; - cairo_bo_event_t *stack_event_ptrs[ARRAY_LENGTH (stack_events) + 1]; - cairo_bo_event_t **event_ptrs; - cairo_bo_edge_t stack_edges[ARRAY_LENGTH (stack_events)]; - cairo_bo_edge_t *edges; - cairo_status_t status; - int i, j, k; - - if (unlikely (traps->num_traps == 0)) - return CAIRO_STATUS_SUCCESS; - - assert (traps->is_rectilinear); - - i = 4 * traps->num_traps; - - events = stack_events; - event_ptrs = stack_event_ptrs; - edges = stack_edges; - if (i > ARRAY_LENGTH (stack_events)) { - events = _cairo_malloc_ab_plus_c (i, - sizeof (cairo_bo_event_t) + - sizeof (cairo_bo_edge_t) + - sizeof (cairo_bo_event_t *), - sizeof (cairo_bo_event_t *)); - if (unlikely (events == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - event_ptrs = (cairo_bo_event_t **) (events + i); - edges = (cairo_bo_edge_t *) (event_ptrs + i + 1); - } - - for (i = j = k = 0; i < traps->num_traps; i++) { - edges[k].edge.top = traps->traps[i].top; - edges[k].edge.bottom = traps->traps[i].bottom; - edges[k].edge.line = traps->traps[i].left; - edges[k].edge.dir = 1; - edges[k].deferred_trap.right = NULL; - edges[k].prev = NULL; - edges[k].next = NULL; - - event_ptrs[j] = &events[j]; - events[j].type = CAIRO_BO_EVENT_TYPE_START; - events[j].point.y = traps->traps[i].top; - events[j].point.x = traps->traps[i].left.p1.x; - events[j].edge = &edges[k]; - j++; - - event_ptrs[j] = &events[j]; - events[j].type = CAIRO_BO_EVENT_TYPE_STOP; - events[j].point.y = traps->traps[i].bottom; - events[j].point.x = traps->traps[i].left.p1.x; - events[j].edge = &edges[k]; - j++; - k++; - - edges[k].edge.top = traps->traps[i].top; - edges[k].edge.bottom = traps->traps[i].bottom; - edges[k].edge.line = traps->traps[i].right; - edges[k].edge.dir = -1; - edges[k].deferred_trap.right = NULL; - edges[k].prev = NULL; - edges[k].next = NULL; - - event_ptrs[j] = &events[j]; - events[j].type = CAIRO_BO_EVENT_TYPE_START; - events[j].point.y = traps->traps[i].top; - events[j].point.x = traps->traps[i].right.p1.x; - events[j].edge = &edges[k]; - j++; - - event_ptrs[j] = &events[j]; - events[j].type = CAIRO_BO_EVENT_TYPE_STOP; - events[j].point.y = traps->traps[i].bottom; - events[j].point.x = traps->traps[i].right.p1.x; - events[j].edge = &edges[k]; - j++; - k++; - } - - _cairo_traps_clear (traps); - status = _cairo_bentley_ottmann_tessellate_rectilinear (event_ptrs, j, - fill_rule, - TRUE, traps); - traps->is_rectilinear = TRUE; - - if (events != stack_events) - free (events); - - return status; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann.c b/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann.c deleted file mode 100644 index 91e41f9c3cbb89870b23bdfa7e98dacb85feacce..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-bentley-ottmann.c +++ /dev/null @@ -1,1909 +0,0 @@ -/* - * Copyright © 2004 Carl Worth - * Copyright © 2006 Red Hat, Inc. - * Copyright © 2008 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Carl Worth - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -/* Provide definitions for standalone compilation */ -#include "cairoint.h" - -#include "cairo-combsort-inline.h" -#include "cairo-error-private.h" -#include "cairo-freelist-private.h" -#include "cairo-line-inline.h" -#include "cairo-traps-private.h" - -#define DEBUG_PRINT_STATE 0 -#define DEBUG_EVENTS 0 -#define DEBUG_TRAPS 0 - -typedef cairo_point_t cairo_bo_point32_t; - -typedef struct _cairo_bo_intersect_ordinate { - int32_t ordinate; - enum { EXACT, INEXACT } exactness; -} cairo_bo_intersect_ordinate_t; - -typedef struct _cairo_bo_intersect_point { - cairo_bo_intersect_ordinate_t x; - cairo_bo_intersect_ordinate_t y; -} cairo_bo_intersect_point_t; - -typedef struct _cairo_bo_edge cairo_bo_edge_t; -typedef struct _cairo_bo_trap cairo_bo_trap_t; - -/* A deferred trapezoid of an edge */ -struct _cairo_bo_trap { - cairo_bo_edge_t *right; - int32_t top; -}; - -struct _cairo_bo_edge { - cairo_edge_t edge; - cairo_bo_edge_t *prev; - cairo_bo_edge_t *next; - cairo_bo_edge_t *colinear; - cairo_bo_trap_t deferred_trap; -}; - -/* the parent is always given by index/2 */ -#define PQ_PARENT_INDEX(i) ((i) >> 1) -#define PQ_FIRST_ENTRY 1 - -/* left and right children are index * 2 and (index * 2) +1 respectively */ -#define PQ_LEFT_CHILD_INDEX(i) ((i) << 1) - -typedef enum { - CAIRO_BO_EVENT_TYPE_STOP, - CAIRO_BO_EVENT_TYPE_INTERSECTION, - CAIRO_BO_EVENT_TYPE_START -} cairo_bo_event_type_t; - -typedef struct _cairo_bo_event { - cairo_bo_event_type_t type; - cairo_point_t point; -} cairo_bo_event_t; - -typedef struct _cairo_bo_start_event { - cairo_bo_event_type_t type; - cairo_point_t point; - cairo_bo_edge_t edge; -} cairo_bo_start_event_t; - -typedef struct _cairo_bo_queue_event { - cairo_bo_event_type_t type; - cairo_point_t point; - cairo_bo_edge_t *e1; - cairo_bo_edge_t *e2; -} cairo_bo_queue_event_t; - -typedef struct _pqueue { - int size, max_size; - - cairo_bo_event_t **elements; - cairo_bo_event_t *elements_embedded[1024]; -} pqueue_t; - -typedef struct _cairo_bo_event_queue { - cairo_freepool_t pool; - pqueue_t pqueue; - cairo_bo_event_t **start_events; -} cairo_bo_event_queue_t; - -typedef struct _cairo_bo_sweep_line { - cairo_bo_edge_t *head; - cairo_bo_edge_t *stopped; - int32_t current_y; - cairo_bo_edge_t *current_edge; -} cairo_bo_sweep_line_t; - -#if DEBUG_TRAPS -static void -dump_traps (cairo_traps_t *traps, const char *filename) -{ - FILE *file; - cairo_box_t extents; - int n; - - if (getenv ("CAIRO_DEBUG_TRAPS") == NULL) - return; - -#if 0 - if (traps->has_limits) { - printf ("%s: limits=(%d, %d, %d, %d)\n", - filename, - traps->limits.p1.x, traps->limits.p1.y, - traps->limits.p2.x, traps->limits.p2.y); - } -#endif - _cairo_traps_extents (traps, &extents); - printf ("%s: extents=(%d, %d, %d, %d)\n", - filename, - extents.p1.x, extents.p1.y, - extents.p2.x, extents.p2.y); - - file = fopen (filename, "a"); - if (file != NULL) { - for (n = 0; n < traps->num_traps; n++) { - fprintf (file, "%d %d L:(%d, %d), (%d, %d) R:(%d, %d), (%d, %d)\n", - traps->traps[n].top, - traps->traps[n].bottom, - traps->traps[n].left.p1.x, - traps->traps[n].left.p1.y, - traps->traps[n].left.p2.x, - traps->traps[n].left.p2.y, - traps->traps[n].right.p1.x, - traps->traps[n].right.p1.y, - traps->traps[n].right.p2.x, - traps->traps[n].right.p2.y); - } - fprintf (file, "\n"); - fclose (file); - } -} - -static void -dump_edges (cairo_bo_start_event_t *events, - int num_edges, - const char *filename) -{ - FILE *file; - int n; - - if (getenv ("CAIRO_DEBUG_TRAPS") == NULL) - return; - - file = fopen (filename, "a"); - if (file != NULL) { - for (n = 0; n < num_edges; n++) { - fprintf (file, "(%d, %d), (%d, %d) %d %d %d\n", - events[n].edge.edge.line.p1.x, - events[n].edge.edge.line.p1.y, - events[n].edge.edge.line.p2.x, - events[n].edge.edge.line.p2.y, - events[n].edge.edge.top, - events[n].edge.edge.bottom, - events[n].edge.edge.dir); - } - fprintf (file, "\n"); - fclose (file); - } -} -#endif - -static cairo_fixed_t -_line_compute_intersection_x_for_y (const cairo_line_t *line, - cairo_fixed_t y) -{ - cairo_fixed_t x, dy; - - if (y == line->p1.y) - return line->p1.x; - if (y == line->p2.y) - return line->p2.x; - - x = line->p1.x; - dy = line->p2.y - line->p1.y; - if (dy != 0) { - x += _cairo_fixed_mul_div_floor (y - line->p1.y, - line->p2.x - line->p1.x, - dy); - } - - return x; -} - -static inline int -_cairo_bo_point32_compare (cairo_bo_point32_t const *a, - cairo_bo_point32_t const *b) -{ - int cmp; - - cmp = a->y - b->y; - if (cmp) - return cmp; - - return a->x - b->x; -} - -/* Compare the slope of a to the slope of b, returning 1, 0, -1 if the - * slope a is respectively greater than, equal to, or less than the - * slope of b. - * - * For each edge, consider the direction vector formed from: - * - * top -> bottom - * - * which is: - * - * (dx, dy) = (line.p2.x - line.p1.x, line.p2.y - line.p1.y) - * - * We then define the slope of each edge as dx/dy, (which is the - * inverse of the slope typically used in math instruction). We never - * compute a slope directly as the value approaches infinity, but we - * can derive a slope comparison without division as follows, (where - * the ? represents our compare operator). - * - * 1. slope(a) ? slope(b) - * 2. adx/ady ? bdx/bdy - * 3. (adx * bdy) ? (bdx * ady) - * - * Note that from step 2 to step 3 there is no change needed in the - * sign of the result since both ady and bdy are guaranteed to be - * greater than or equal to 0. - * - * When using this slope comparison to sort edges, some care is needed - * when interpreting the results. Since the slope compare operates on - * distance vectors from top to bottom it gives a correct left to - * right sort for edges that have a common top point, (such as two - * edges with start events at the same location). On the other hand, - * the sense of the result will be exactly reversed for two edges that - * have a common stop point. - */ -static inline int -_slope_compare (const cairo_bo_edge_t *a, - const cairo_bo_edge_t *b) -{ - /* XXX: We're assuming here that dx and dy will still fit in 32 - * bits. That's not true in general as there could be overflow. We - * should prevent that before the tessellation algorithm - * begins. - */ - int32_t adx = a->edge.line.p2.x - a->edge.line.p1.x; - int32_t bdx = b->edge.line.p2.x - b->edge.line.p1.x; - - /* Since the dy's are all positive by construction we can fast - * path several common cases. - */ - - /* First check for vertical lines. */ - if (adx == 0) - return -bdx; - if (bdx == 0) - return adx; - - /* Then where the two edges point in different directions wrt x. */ - if ((adx ^ bdx) < 0) - return adx; - - /* Finally we actually need to do the general comparison. */ - { - int32_t ady = a->edge.line.p2.y - a->edge.line.p1.y; - int32_t bdy = b->edge.line.p2.y - b->edge.line.p1.y; - cairo_int64_t adx_bdy = _cairo_int32x32_64_mul (adx, bdy); - cairo_int64_t bdx_ady = _cairo_int32x32_64_mul (bdx, ady); - - return _cairo_int64_cmp (adx_bdy, bdx_ady); - } -} - - -/* - * We need to compare the x-coordinate of a line for a particular y wrt to a - * given x, without loss of precision. - * - * The x-coordinate along an edge for a given y is: - * X = A_x + (Y - A_y) * A_dx / A_dy - * - * So the inequality we wish to test is: - * A_x + (Y - A_y) * A_dx / A_dy ∘ X - * where ∘ is our inequality operator. - * - * By construction, we know that A_dy (and (Y - A_y)) are - * all positive, so we can rearrange it thus without causing a sign change: - * (Y - A_y) * A_dx ∘ (X - A_x) * A_dy - * - * Given the assumption that all the deltas fit within 32 bits, we can compute - * this comparison directly using 64 bit arithmetic. - * - * See the similar discussion for _slope_compare() and - * edges_compare_x_for_y_general(). - */ -static int -edge_compare_for_y_against_x (const cairo_bo_edge_t *a, - int32_t y, - int32_t x) -{ - int32_t adx, ady; - int32_t dx, dy; - cairo_int64_t L, R; - - if (x < a->edge.line.p1.x && x < a->edge.line.p2.x) - return 1; - if (x > a->edge.line.p1.x && x > a->edge.line.p2.x) - return -1; - - adx = a->edge.line.p2.x - a->edge.line.p1.x; - dx = x - a->edge.line.p1.x; - - if (adx == 0) - return -dx; - if (dx == 0 || (adx ^ dx) < 0) - return adx; - - dy = y - a->edge.line.p1.y; - ady = a->edge.line.p2.y - a->edge.line.p1.y; - - L = _cairo_int32x32_64_mul (dy, adx); - R = _cairo_int32x32_64_mul (dx, ady); - - return _cairo_int64_cmp (L, R); -} - -static inline int -_cairo_bo_sweep_line_compare_edges (const cairo_bo_sweep_line_t *sweep_line, - const cairo_bo_edge_t *a, - const cairo_bo_edge_t *b) -{ - int cmp; - - cmp = cairo_lines_compare_at_y (&a->edge.line, - &b->edge.line, - sweep_line->current_y); - if (cmp) - return cmp; - - /* We've got two collinear edges now. */ - return b->edge.bottom - a->edge.bottom; -} - -static inline cairo_int64_t -det32_64 (int32_t a, int32_t b, - int32_t c, int32_t d) -{ - /* det = a * d - b * c */ - return _cairo_int64_sub (_cairo_int32x32_64_mul (a, d), - _cairo_int32x32_64_mul (b, c)); -} - -static inline cairo_int128_t -det64x32_128 (cairo_int64_t a, int32_t b, - cairo_int64_t c, int32_t d) -{ - /* det = a * d - b * c */ - return _cairo_int128_sub (_cairo_int64x32_128_mul (a, d), - _cairo_int64x32_128_mul (c, b)); -} - -/* Compute the intersection of two lines as defined by two edges. The - * result is provided as a coordinate pair of 128-bit integers. - * - * Returns %CAIRO_BO_STATUS_INTERSECTION if there is an intersection or - * %CAIRO_BO_STATUS_PARALLEL if the two lines are exactly parallel. - */ -static cairo_bool_t -intersect_lines (cairo_bo_edge_t *a, - cairo_bo_edge_t *b, - cairo_bo_intersect_point_t *intersection) -{ - cairo_int64_t a_det, b_det; - - /* XXX: We're assuming here that dx and dy will still fit in 32 - * bits. That's not true in general as there could be overflow. We - * should prevent that before the tessellation algorithm begins. - * What we're doing to mitigate this is to perform clamping in - * cairo_bo_tessellate_polygon(). - */ - int32_t dx1 = a->edge.line.p1.x - a->edge.line.p2.x; - int32_t dy1 = a->edge.line.p1.y - a->edge.line.p2.y; - - int32_t dx2 = b->edge.line.p1.x - b->edge.line.p2.x; - int32_t dy2 = b->edge.line.p1.y - b->edge.line.p2.y; - - cairo_int64_t den_det; - cairo_int64_t R; - cairo_quorem64_t qr; - - den_det = det32_64 (dx1, dy1, dx2, dy2); - - /* Q: Can we determine that the lines do not intersect (within range) - * much more cheaply than computing the intersection point i.e. by - * avoiding the division? - * - * X = ax + t * adx = bx + s * bdx; - * Y = ay + t * ady = by + s * bdy; - * ∴ t * (ady*bdx - bdy*adx) = bdx * (by - ay) + bdy * (ax - bx) - * => t * L = R - * - * Therefore we can reject any intersection (under the criteria for - * valid intersection events) if: - * L^R < 0 => t < 0, or - * L<R => t > 1 - * - * (where top/bottom must at least extend to the line endpoints). - * - * A similar substitution can be performed for s, yielding: - * s * (ady*bdx - bdy*adx) = ady * (ax - bx) - adx * (ay - by) - */ - R = det32_64 (dx2, dy2, - b->edge.line.p1.x - a->edge.line.p1.x, - b->edge.line.p1.y - a->edge.line.p1.y); - if (_cairo_int64_negative (den_det)) { - if (_cairo_int64_ge (den_det, R)) - return FALSE; - } else { - if (_cairo_int64_le (den_det, R)) - return FALSE; - } - - R = det32_64 (dy1, dx1, - a->edge.line.p1.y - b->edge.line.p1.y, - a->edge.line.p1.x - b->edge.line.p1.x); - if (_cairo_int64_negative (den_det)) { - if (_cairo_int64_ge (den_det, R)) - return FALSE; - } else { - if (_cairo_int64_le (den_det, R)) - return FALSE; - } - - /* We now know that the two lines should intersect within range. */ - - a_det = det32_64 (a->edge.line.p1.x, a->edge.line.p1.y, - a->edge.line.p2.x, a->edge.line.p2.y); - b_det = det32_64 (b->edge.line.p1.x, b->edge.line.p1.y, - b->edge.line.p2.x, b->edge.line.p2.y); - - /* x = det (a_det, dx1, b_det, dx2) / den_det */ - qr = _cairo_int_96by64_32x64_divrem (det64x32_128 (a_det, dx1, - b_det, dx2), - den_det); - if (_cairo_int64_eq (qr.rem, den_det)) - return FALSE; -#if 0 - intersection->x.exactness = _cairo_int64_is_zero (qr.rem) ? EXACT : INEXACT; -#else - intersection->x.exactness = EXACT; - if (! _cairo_int64_is_zero (qr.rem)) { - if (_cairo_int64_negative (den_det) ^ _cairo_int64_negative (qr.rem)) - qr.rem = _cairo_int64_negate (qr.rem); - qr.rem = _cairo_int64_mul (qr.rem, _cairo_int32_to_int64 (2)); - if (_cairo_int64_ge (qr.rem, den_det)) { - qr.quo = _cairo_int64_add (qr.quo, - _cairo_int32_to_int64 (_cairo_int64_negative (qr.quo) ? -1 : 1)); - } else - intersection->x.exactness = INEXACT; - } -#endif - intersection->x.ordinate = _cairo_int64_to_int32 (qr.quo); - - /* y = det (a_det, dy1, b_det, dy2) / den_det */ - qr = _cairo_int_96by64_32x64_divrem (det64x32_128 (a_det, dy1, - b_det, dy2), - den_det); - if (_cairo_int64_eq (qr.rem, den_det)) - return FALSE; -#if 0 - intersection->y.exactness = _cairo_int64_is_zero (qr.rem) ? EXACT : INEXACT; -#else - intersection->y.exactness = EXACT; - if (! _cairo_int64_is_zero (qr.rem)) { - if (_cairo_int64_negative (den_det) ^ _cairo_int64_negative (qr.rem)) - qr.rem = _cairo_int64_negate (qr.rem); - qr.rem = _cairo_int64_mul (qr.rem, _cairo_int32_to_int64 (2)); - if (_cairo_int64_ge (qr.rem, den_det)) { - qr.quo = _cairo_int64_add (qr.quo, - _cairo_int32_to_int64 (_cairo_int64_negative (qr.quo) ? -1 : 1)); - } else - intersection->y.exactness = INEXACT; - } -#endif - intersection->y.ordinate = _cairo_int64_to_int32 (qr.quo); - - return TRUE; -} - -static int -_cairo_bo_intersect_ordinate_32_compare (cairo_bo_intersect_ordinate_t a, - int32_t b) -{ - /* First compare the quotient */ - if (a.ordinate > b) - return +1; - if (a.ordinate < b) - return -1; - /* With quotient identical, if remainder is 0 then compare equal */ - /* Otherwise, the non-zero remainder makes a > b */ - return INEXACT == a.exactness; -} - -/* Does the given edge contain the given point. The point must already - * be known to be contained within the line determined by the edge, - * (most likely the point results from an intersection of this edge - * with another). - * - * If we had exact arithmetic, then this function would simply be a - * matter of examining whether the y value of the point lies within - * the range of y values of the edge. But since intersection points - * are not exact due to being rounded to the nearest integer within - * the available precision, we must also examine the x value of the - * point. - * - * The definition of "contains" here is that the given intersection - * point will be seen by the sweep line after the start event for the - * given edge and before the stop event for the edge. See the comments - * in the implementation for more details. - */ -static cairo_bool_t -_cairo_bo_edge_contains_intersect_point (cairo_bo_edge_t *edge, - cairo_bo_intersect_point_t *point) -{ - int cmp_top, cmp_bottom; - - /* XXX: When running the actual algorithm, we don't actually need to - * compare against edge->top at all here, since any intersection above - * top is eliminated early via a slope comparison. We're leaving these - * here for now only for the sake of the quadratic-time intersection - * finder which needs them. - */ - - cmp_top = _cairo_bo_intersect_ordinate_32_compare (point->y, - edge->edge.top); - cmp_bottom = _cairo_bo_intersect_ordinate_32_compare (point->y, - edge->edge.bottom); - - if (cmp_top < 0 || cmp_bottom > 0) - { - return FALSE; - } - - if (cmp_top > 0 && cmp_bottom < 0) - { - return TRUE; - } - - /* At this stage, the point lies on the same y value as either - * edge->top or edge->bottom, so we have to examine the x value in - * order to properly determine containment. */ - - /* If the y value of the point is the same as the y value of the - * top of the edge, then the x value of the point must be greater - * to be considered as inside the edge. Similarly, if the y value - * of the point is the same as the y value of the bottom of the - * edge, then the x value of the point must be less to be - * considered as inside. */ - - if (cmp_top == 0) { - cairo_fixed_t top_x; - - top_x = _line_compute_intersection_x_for_y (&edge->edge.line, - edge->edge.top); - return _cairo_bo_intersect_ordinate_32_compare (point->x, top_x) > 0; - } else { /* cmp_bottom == 0 */ - cairo_fixed_t bot_x; - - bot_x = _line_compute_intersection_x_for_y (&edge->edge.line, - edge->edge.bottom); - return _cairo_bo_intersect_ordinate_32_compare (point->x, bot_x) < 0; - } -} - -/* Compute the intersection of two edges. The result is provided as a - * coordinate pair of 128-bit integers. - * - * Returns %CAIRO_BO_STATUS_INTERSECTION if there is an intersection - * that is within both edges, %CAIRO_BO_STATUS_NO_INTERSECTION if the - * intersection of the lines defined by the edges occurs outside of - * one or both edges, and %CAIRO_BO_STATUS_PARALLEL if the two edges - * are exactly parallel. - * - * Note that when determining if a candidate intersection is "inside" - * an edge, we consider both the infinitesimal shortening and the - * infinitesimal tilt rules described by John Hobby. Specifically, if - * the intersection is exactly the same as an edge point, it is - * effectively outside (no intersection is returned). Also, if the - * intersection point has the same - */ -static cairo_bool_t -_cairo_bo_edge_intersect (cairo_bo_edge_t *a, - cairo_bo_edge_t *b, - cairo_bo_point32_t *intersection) -{ - cairo_bo_intersect_point_t quorem; - - if (! intersect_lines (a, b, &quorem)) - return FALSE; - - if (! _cairo_bo_edge_contains_intersect_point (a, &quorem)) - return FALSE; - - if (! _cairo_bo_edge_contains_intersect_point (b, &quorem)) - return FALSE; - - /* Now that we've correctly compared the intersection point and - * determined that it lies within the edge, then we know that we - * no longer need any more bits of storage for the intersection - * than we do for our edge coordinates. We also no longer need the - * remainder from the division. */ - intersection->x = quorem.x.ordinate; - intersection->y = quorem.y.ordinate; - - return TRUE; -} - -static inline int -cairo_bo_event_compare (const cairo_bo_event_t *a, - const cairo_bo_event_t *b) -{ - int cmp; - - cmp = _cairo_bo_point32_compare (&a->point, &b->point); - if (cmp) - return cmp; - - cmp = a->type - b->type; - if (cmp) - return cmp; - - return a - b; -} - -static inline void -_pqueue_init (pqueue_t *pq) -{ - pq->max_size = ARRAY_LENGTH (pq->elements_embedded); - pq->size = 0; - - pq->elements = pq->elements_embedded; -} - -static inline void -_pqueue_fini (pqueue_t *pq) -{ - if (pq->elements != pq->elements_embedded) - free (pq->elements); -} - -static cairo_status_t -_pqueue_grow (pqueue_t *pq) -{ - cairo_bo_event_t **new_elements; - pq->max_size *= 2; - - if (pq->elements == pq->elements_embedded) { - new_elements = _cairo_malloc_ab (pq->max_size, - sizeof (cairo_bo_event_t *)); - if (unlikely (new_elements == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - memcpy (new_elements, pq->elements_embedded, - sizeof (pq->elements_embedded)); - } else { - new_elements = _cairo_realloc_ab (pq->elements, - pq->max_size, - sizeof (cairo_bo_event_t *)); - if (unlikely (new_elements == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - pq->elements = new_elements; - return CAIRO_STATUS_SUCCESS; -} - -static inline cairo_status_t -_pqueue_push (pqueue_t *pq, cairo_bo_event_t *event) -{ - cairo_bo_event_t **elements; - int i, parent; - - if (unlikely (pq->size + 1 == pq->max_size)) { - cairo_status_t status; - - status = _pqueue_grow (pq); - if (unlikely (status)) - return status; - } - - elements = pq->elements; - - for (i = ++pq->size; - i != PQ_FIRST_ENTRY && - cairo_bo_event_compare (event, - elements[parent = PQ_PARENT_INDEX (i)]) < 0; - i = parent) - { - elements[i] = elements[parent]; - } - - elements[i] = event; - - return CAIRO_STATUS_SUCCESS; -} - -static inline void -_pqueue_pop (pqueue_t *pq) -{ - cairo_bo_event_t **elements = pq->elements; - cairo_bo_event_t *tail; - int child, i; - - tail = elements[pq->size--]; - if (pq->size == 0) { - elements[PQ_FIRST_ENTRY] = NULL; - return; - } - - for (i = PQ_FIRST_ENTRY; - (child = PQ_LEFT_CHILD_INDEX (i)) <= pq->size; - i = child) - { - if (child != pq->size && - cairo_bo_event_compare (elements[child+1], - elements[child]) < 0) - { - child++; - } - - if (cairo_bo_event_compare (elements[child], tail) >= 0) - break; - - elements[i] = elements[child]; - } - elements[i] = tail; -} - -static inline cairo_status_t -_cairo_bo_event_queue_insert (cairo_bo_event_queue_t *queue, - cairo_bo_event_type_t type, - cairo_bo_edge_t *e1, - cairo_bo_edge_t *e2, - const cairo_point_t *point) -{ - cairo_bo_queue_event_t *event; - - event = _cairo_freepool_alloc (&queue->pool); - if (unlikely (event == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - event->type = type; - event->e1 = e1; - event->e2 = e2; - event->point = *point; - - return _pqueue_push (&queue->pqueue, (cairo_bo_event_t *) event); -} - -static void -_cairo_bo_event_queue_delete (cairo_bo_event_queue_t *queue, - cairo_bo_event_t *event) -{ - _cairo_freepool_free (&queue->pool, event); -} - -static cairo_bo_event_t * -_cairo_bo_event_dequeue (cairo_bo_event_queue_t *event_queue) -{ - cairo_bo_event_t *event, *cmp; - - event = event_queue->pqueue.elements[PQ_FIRST_ENTRY]; - cmp = *event_queue->start_events; - if (event == NULL || - (cmp != NULL && cairo_bo_event_compare (cmp, event) < 0)) - { - event = cmp; - event_queue->start_events++; - } - else - { - _pqueue_pop (&event_queue->pqueue); - } - - return event; -} - -CAIRO_COMBSORT_DECLARE (_cairo_bo_event_queue_sort, - cairo_bo_event_t *, - cairo_bo_event_compare) - -static void -_cairo_bo_event_queue_init (cairo_bo_event_queue_t *event_queue, - cairo_bo_event_t **start_events, - int num_events) -{ - event_queue->start_events = start_events; - - _cairo_freepool_init (&event_queue->pool, - sizeof (cairo_bo_queue_event_t)); - _pqueue_init (&event_queue->pqueue); - event_queue->pqueue.elements[PQ_FIRST_ENTRY] = NULL; -} - -static cairo_status_t -_cairo_bo_event_queue_insert_stop (cairo_bo_event_queue_t *event_queue, - cairo_bo_edge_t *edge) -{ - cairo_bo_point32_t point; - - point.y = edge->edge.bottom; - point.x = _line_compute_intersection_x_for_y (&edge->edge.line, - point.y); - return _cairo_bo_event_queue_insert (event_queue, - CAIRO_BO_EVENT_TYPE_STOP, - edge, NULL, - &point); -} - -static void -_cairo_bo_event_queue_fini (cairo_bo_event_queue_t *event_queue) -{ - _pqueue_fini (&event_queue->pqueue); - _cairo_freepool_fini (&event_queue->pool); -} - -static inline cairo_status_t -_cairo_bo_event_queue_insert_if_intersect_below_current_y (cairo_bo_event_queue_t *event_queue, - cairo_bo_edge_t *left, - cairo_bo_edge_t *right) -{ - cairo_bo_point32_t intersection; - - if (MAX (left->edge.line.p1.x, left->edge.line.p2.x) <= - MIN (right->edge.line.p1.x, right->edge.line.p2.x)) - return CAIRO_STATUS_SUCCESS; - - if (cairo_lines_equal (&left->edge.line, &right->edge.line)) - return CAIRO_STATUS_SUCCESS; - - /* The names "left" and "right" here are correct descriptions of - * the order of the two edges within the active edge list. So if a - * slope comparison also puts left less than right, then we know - * that the intersection of these two segments has already - * occurred before the current sweep line position. */ - if (_slope_compare (left, right) <= 0) - return CAIRO_STATUS_SUCCESS; - - if (! _cairo_bo_edge_intersect (left, right, &intersection)) - return CAIRO_STATUS_SUCCESS; - - return _cairo_bo_event_queue_insert (event_queue, - CAIRO_BO_EVENT_TYPE_INTERSECTION, - left, right, - &intersection); -} - -static void -_cairo_bo_sweep_line_init (cairo_bo_sweep_line_t *sweep_line) -{ - sweep_line->head = NULL; - sweep_line->stopped = NULL; - sweep_line->current_y = INT32_MIN; - sweep_line->current_edge = NULL; -} - -static void -_cairo_bo_sweep_line_insert (cairo_bo_sweep_line_t *sweep_line, - cairo_bo_edge_t *edge) -{ - if (sweep_line->current_edge != NULL) { - cairo_bo_edge_t *prev, *next; - int cmp; - - cmp = _cairo_bo_sweep_line_compare_edges (sweep_line, - sweep_line->current_edge, - edge); - if (cmp < 0) { - prev = sweep_line->current_edge; - next = prev->next; - while (next != NULL && - _cairo_bo_sweep_line_compare_edges (sweep_line, - next, edge) < 0) - { - prev = next, next = prev->next; - } - - prev->next = edge; - edge->prev = prev; - edge->next = next; - if (next != NULL) - next->prev = edge; - } else if (cmp > 0) { - next = sweep_line->current_edge; - prev = next->prev; - while (prev != NULL && - _cairo_bo_sweep_line_compare_edges (sweep_line, - prev, edge) > 0) - { - next = prev, prev = next->prev; - } - - next->prev = edge; - edge->next = next; - edge->prev = prev; - if (prev != NULL) - prev->next = edge; - else - sweep_line->head = edge; - } else { - prev = sweep_line->current_edge; - edge->prev = prev; - edge->next = prev->next; - if (prev->next != NULL) - prev->next->prev = edge; - prev->next = edge; - } - } else { - sweep_line->head = edge; - edge->next = NULL; - } - - sweep_line->current_edge = edge; -} - -static void -_cairo_bo_sweep_line_delete (cairo_bo_sweep_line_t *sweep_line, - cairo_bo_edge_t *edge) -{ - if (edge->prev != NULL) - edge->prev->next = edge->next; - else - sweep_line->head = edge->next; - - if (edge->next != NULL) - edge->next->prev = edge->prev; - - if (sweep_line->current_edge == edge) - sweep_line->current_edge = edge->prev ? edge->prev : edge->next; -} - -static void -_cairo_bo_sweep_line_swap (cairo_bo_sweep_line_t *sweep_line, - cairo_bo_edge_t *left, - cairo_bo_edge_t *right) -{ - if (left->prev != NULL) - left->prev->next = right; - else - sweep_line->head = right; - - if (right->next != NULL) - right->next->prev = left; - - left->next = right->next; - right->next = left; - - right->prev = left->prev; - left->prev = right; -} - -#if DEBUG_PRINT_STATE -static void -_cairo_bo_edge_print (cairo_bo_edge_t *edge) -{ - printf ("(0x%x, 0x%x)-(0x%x, 0x%x)", - edge->edge.line.p1.x, edge->edge.line.p1.y, - edge->edge.line.p2.x, edge->edge.line.p2.y); -} - -static void -_cairo_bo_event_print (cairo_bo_event_t *event) -{ - switch (event->type) { - case CAIRO_BO_EVENT_TYPE_START: - printf ("Start: "); - break; - case CAIRO_BO_EVENT_TYPE_STOP: - printf ("Stop: "); - break; - case CAIRO_BO_EVENT_TYPE_INTERSECTION: - printf ("Intersection: "); - break; - } - printf ("(%d, %d)\t", event->point.x, event->point.y); - _cairo_bo_edge_print (event->e1); - if (event->type == CAIRO_BO_EVENT_TYPE_INTERSECTION) { - printf (" X "); - _cairo_bo_edge_print (event->e2); - } - printf ("\n"); -} - -static void -_cairo_bo_event_queue_print (cairo_bo_event_queue_t *event_queue) -{ - /* XXX: fixme to print the start/stop array too. */ - printf ("Event queue:\n"); -} - -static void -_cairo_bo_sweep_line_print (cairo_bo_sweep_line_t *sweep_line) -{ - cairo_bool_t first = TRUE; - cairo_bo_edge_t *edge; - - printf ("Sweep line from edge list: "); - first = TRUE; - for (edge = sweep_line->head; - edge; - edge = edge->next) - { - if (!first) - printf (", "); - _cairo_bo_edge_print (edge); - first = FALSE; - } - printf ("\n"); -} - -static void -print_state (const char *msg, - cairo_bo_event_t *event, - cairo_bo_event_queue_t *event_queue, - cairo_bo_sweep_line_t *sweep_line) -{ - printf ("%s ", msg); - _cairo_bo_event_print (event); - _cairo_bo_event_queue_print (event_queue); - _cairo_bo_sweep_line_print (sweep_line); - printf ("\n"); -} -#endif - -#if DEBUG_EVENTS -static void CAIRO_PRINTF_FORMAT (1, 2) -event_log (const char *fmt, ...) -{ - FILE *file; - - if (getenv ("CAIRO_DEBUG_EVENTS") == NULL) - return; - - file = fopen ("bo-events.txt", "a"); - if (file != NULL) { - va_list ap; - - va_start (ap, fmt); - vfprintf (file, fmt, ap); - va_end (ap); - - fclose (file); - } -} -#endif - -#define HAS_COLINEAR(a, b) ((cairo_bo_edge_t *)(((uintptr_t)(a))&~1) == (b)) -#define IS_COLINEAR(e) (((uintptr_t)(e))&1) -#define MARK_COLINEAR(e, v) ((cairo_bo_edge_t *)(((uintptr_t)(e))|(v))) - -static inline cairo_bool_t -edges_colinear (cairo_bo_edge_t *a, const cairo_bo_edge_t *b) -{ - unsigned p; - - if (HAS_COLINEAR(a->colinear, b)) - return IS_COLINEAR(a->colinear); - - if (HAS_COLINEAR(b->colinear, a)) { - p = IS_COLINEAR(b->colinear); - a->colinear = MARK_COLINEAR(b, p); - return p; - } - - p = 0; - p |= (a->edge.line.p1.x == b->edge.line.p1.x) << 0; - p |= (a->edge.line.p1.y == b->edge.line.p1.y) << 1; - p |= (a->edge.line.p2.x == b->edge.line.p2.x) << 3; - p |= (a->edge.line.p2.y == b->edge.line.p2.y) << 4; - if (p == ((1 << 0) | (1 << 1) | (1 << 3) | (1 << 4))) { - a->colinear = MARK_COLINEAR(b, 1); - return TRUE; - } - - if (_slope_compare (a, b)) { - a->colinear = MARK_COLINEAR(b, 0); - return FALSE; - } - - /* The choice of y is not truly arbitrary since we must guarantee that it - * is greater than the start of either line. - */ - if (p != 0) { - /* colinear if either end-point are coincident */ - p = (((p >> 1) & p) & 5) != 0; - } else if (a->edge.line.p1.y < b->edge.line.p1.y) { - p = edge_compare_for_y_against_x (b, - a->edge.line.p1.y, - a->edge.line.p1.x) == 0; - } else { - p = edge_compare_for_y_against_x (a, - b->edge.line.p1.y, - b->edge.line.p1.x) == 0; - } - - a->colinear = MARK_COLINEAR(b, p); - return p; -} - -/* Adds the trapezoid, if any, of the left edge to the #cairo_traps_t */ -static void -_cairo_bo_edge_end_trap (cairo_bo_edge_t *left, - int32_t bot, - cairo_traps_t *traps) -{ - cairo_bo_trap_t *trap = &left->deferred_trap; - - /* Only emit (trivial) non-degenerate trapezoids with positive height. */ - if (likely (trap->top < bot)) { - _cairo_traps_add_trap (traps, - trap->top, bot, - &left->edge.line, &trap->right->edge.line); - -#if DEBUG_PRINT_STATE - printf ("Deferred trap: left=(%x, %x)-(%x,%x) " - "right=(%x,%x)-(%x,%x) top=%x, bot=%x\n", - left->edge.line.p1.x, left->edge.line.p1.y, - left->edge.line.p2.x, left->edge.line.p2.y, - trap->right->edge.line.p1.x, trap->right->edge.line.p1.y, - trap->right->edge.line.p2.x, trap->right->edge.line.p2.y, - trap->top, bot); -#endif -#if DEBUG_EVENTS - event_log ("end trap: %lu %lu %d %d\n", - (long) left, - (long) trap->right, - trap->top, - bot); -#endif - } - - trap->right = NULL; -} - - -/* Start a new trapezoid at the given top y coordinate, whose edges - * are `edge' and `edge->next'. If `edge' already has a trapezoid, - * then either add it to the traps in `traps', if the trapezoid's - * right edge differs from `edge->next', or do nothing if the new - * trapezoid would be a continuation of the existing one. */ -static inline void -_cairo_bo_edge_start_or_continue_trap (cairo_bo_edge_t *left, - cairo_bo_edge_t *right, - int top, - cairo_traps_t *traps) -{ - if (left->deferred_trap.right == right) - return; - - assert (right); - if (left->deferred_trap.right != NULL) { - if (edges_colinear (left->deferred_trap.right, right)) - { - /* continuation on right, so just swap edges */ - left->deferred_trap.right = right; - return; - } - - _cairo_bo_edge_end_trap (left, top, traps); - } - - if (! edges_colinear (left, right)) { - left->deferred_trap.top = top; - left->deferred_trap.right = right; - -#if DEBUG_EVENTS - event_log ("begin trap: %lu %lu %d\n", - (long) left, - (long) right, - top); -#endif - } -} - -static inline void -_active_edges_to_traps (cairo_bo_edge_t *pos, - int32_t top, - unsigned mask, - cairo_traps_t *traps) -{ - cairo_bo_edge_t *left; - int in_out; - - -#if DEBUG_PRINT_STATE - printf ("Processing active edges for %x\n", top); -#endif - - in_out = 0; - left = pos; - while (pos != NULL) { - if (pos != left && pos->deferred_trap.right) { - /* XXX It shouldn't be possible to here with 2 deferred traps - * on colinear edges... See bug-bo-rictoz. - */ - if (left->deferred_trap.right == NULL && - edges_colinear (left, pos)) - { - /* continuation on left */ - left->deferred_trap = pos->deferred_trap; - pos->deferred_trap.right = NULL; - } - else - { - _cairo_bo_edge_end_trap (pos, top, traps); - } - } - - in_out += pos->edge.dir; - if ((in_out & mask) == 0) { - /* skip co-linear edges */ - if (pos->next == NULL || ! edges_colinear (pos, pos->next)) { - _cairo_bo_edge_start_or_continue_trap (left, pos, top, traps); - left = pos->next; - } - } - - pos = pos->next; - } -} - -/* Execute a single pass of the Bentley-Ottmann algorithm on edges, - * generating trapezoids according to the fill_rule and appending them - * to traps. */ -static cairo_status_t -_cairo_bentley_ottmann_tessellate_bo_edges (cairo_bo_event_t **start_events, - int num_events, - unsigned fill_rule, - cairo_traps_t *traps, - int *num_intersections) -{ - cairo_status_t status; - int intersection_count = 0; - cairo_bo_event_queue_t event_queue; - cairo_bo_sweep_line_t sweep_line; - cairo_bo_event_t *event; - cairo_bo_edge_t *left, *right; - cairo_bo_edge_t *e1, *e2; - - /* convert the fill_rule into a winding mask */ - if (fill_rule == CAIRO_FILL_RULE_WINDING) - fill_rule = (unsigned) -1; - else - fill_rule = 1; - -#if DEBUG_EVENTS - { - int i; - - for (i = 0; i < num_events; i++) { - cairo_bo_start_event_t *event = - ((cairo_bo_start_event_t **) start_events)[i]; - event_log ("edge: %lu (%d, %d) (%d, %d) (%d, %d) %d\n", - (long) &events[i].edge, - event->edge.edge.line.p1.x, - event->edge.edge.line.p1.y, - event->edge.edge.line.p2.x, - event->edge.edge.line.p2.y, - event->edge.top, - event->edge.bottom, - event->edge.edge.dir); - } - } -#endif - - _cairo_bo_event_queue_init (&event_queue, start_events, num_events); - _cairo_bo_sweep_line_init (&sweep_line); - - while ((event = _cairo_bo_event_dequeue (&event_queue))) { - if (event->point.y != sweep_line.current_y) { - for (e1 = sweep_line.stopped; e1; e1 = e1->next) { - if (e1->deferred_trap.right != NULL) { - _cairo_bo_edge_end_trap (e1, - e1->edge.bottom, - traps); - } - } - sweep_line.stopped = NULL; - - _active_edges_to_traps (sweep_line.head, - sweep_line.current_y, - fill_rule, traps); - - sweep_line.current_y = event->point.y; - } - -#if DEBUG_EVENTS - event_log ("event: %d (%ld, %ld) %lu, %lu\n", - event->type, - (long) event->point.x, - (long) event->point.y, - (long) event->e1, - (long) event->e2); -#endif - - switch (event->type) { - case CAIRO_BO_EVENT_TYPE_START: - e1 = &((cairo_bo_start_event_t *) event)->edge; - - _cairo_bo_sweep_line_insert (&sweep_line, e1); - - status = _cairo_bo_event_queue_insert_stop (&event_queue, e1); - if (unlikely (status)) - goto unwind; - - /* check to see if this is a continuation of a stopped edge */ - /* XXX change to an infinitesimal lengthening rule */ - for (left = sweep_line.stopped; left; left = left->next) { - if (e1->edge.top <= left->edge.bottom && - edges_colinear (e1, left)) - { - e1->deferred_trap = left->deferred_trap; - if (left->prev != NULL) - left->prev = left->next; - else - sweep_line.stopped = left->next; - if (left->next != NULL) - left->next->prev = left->prev; - break; - } - } - - left = e1->prev; - right = e1->next; - - if (left != NULL) { - status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, e1); - if (unlikely (status)) - goto unwind; - } - - if (right != NULL) { - status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, e1, right); - if (unlikely (status)) - goto unwind; - } - - break; - - case CAIRO_BO_EVENT_TYPE_STOP: - e1 = ((cairo_bo_queue_event_t *) event)->e1; - _cairo_bo_event_queue_delete (&event_queue, event); - - left = e1->prev; - right = e1->next; - - _cairo_bo_sweep_line_delete (&sweep_line, e1); - - /* first, check to see if we have a continuation via a fresh edge */ - if (e1->deferred_trap.right != NULL) { - e1->next = sweep_line.stopped; - if (sweep_line.stopped != NULL) - sweep_line.stopped->prev = e1; - sweep_line.stopped = e1; - e1->prev = NULL; - } - - if (left != NULL && right != NULL) { - status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, right); - if (unlikely (status)) - goto unwind; - } - - break; - - case CAIRO_BO_EVENT_TYPE_INTERSECTION: - e1 = ((cairo_bo_queue_event_t *) event)->e1; - e2 = ((cairo_bo_queue_event_t *) event)->e2; - _cairo_bo_event_queue_delete (&event_queue, event); - - /* skip this intersection if its edges are not adjacent */ - if (e2 != e1->next) - break; - - intersection_count++; - - left = e1->prev; - right = e2->next; - - _cairo_bo_sweep_line_swap (&sweep_line, e1, e2); - - /* after the swap e2 is left of e1 */ - - if (left != NULL) { - status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, e2); - if (unlikely (status)) - goto unwind; - } - - if (right != NULL) { - status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, e1, right); - if (unlikely (status)) - goto unwind; - } - - break; - } - } - - *num_intersections = intersection_count; - for (e1 = sweep_line.stopped; e1; e1 = e1->next) { - if (e1->deferred_trap.right != NULL) { - _cairo_bo_edge_end_trap (e1, e1->edge.bottom, traps); - } - } - status = traps->status; - unwind: - _cairo_bo_event_queue_fini (&event_queue); - -#if DEBUG_EVENTS - event_log ("\n"); -#endif - - return status; -} - -cairo_status_t -_cairo_bentley_ottmann_tessellate_polygon (cairo_traps_t *traps, - const cairo_polygon_t *polygon, - cairo_fill_rule_t fill_rule) -{ - int intersections; - cairo_bo_start_event_t stack_events[CAIRO_STACK_ARRAY_LENGTH (cairo_bo_start_event_t)]; - cairo_bo_start_event_t *events; - cairo_bo_event_t *stack_event_ptrs[ARRAY_LENGTH (stack_events) + 1]; - cairo_bo_event_t **event_ptrs; - cairo_bo_start_event_t *stack_event_y[64]; - cairo_bo_start_event_t **event_y = NULL; - int i, num_events, y, ymin, ymax; - cairo_status_t status; - - num_events = polygon->num_edges; - if (unlikely (0 == num_events)) - return CAIRO_STATUS_SUCCESS; - - if (polygon->num_limits) { - ymin = _cairo_fixed_integer_floor (polygon->limit.p1.y); - ymax = _cairo_fixed_integer_ceil (polygon->limit.p2.y) - ymin; - - if (ymax > 64) - event_y = _cairo_malloc_ab(sizeof (cairo_bo_event_t*), ymax); - else - event_y = stack_event_y; - memset (event_y, 0, ymax * sizeof(cairo_bo_event_t *)); - } - - events = stack_events; - event_ptrs = stack_event_ptrs; - if (num_events > ARRAY_LENGTH (stack_events)) { - events = _cairo_malloc_ab_plus_c (num_events, - sizeof (cairo_bo_start_event_t) + - sizeof (cairo_bo_event_t *), - sizeof (cairo_bo_event_t *)); - if (unlikely (events == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - event_ptrs = (cairo_bo_event_t **) (events + num_events); - } - - for (i = 0; i < num_events; i++) { - events[i].type = CAIRO_BO_EVENT_TYPE_START; - events[i].point.y = polygon->edges[i].top; - events[i].point.x = - _line_compute_intersection_x_for_y (&polygon->edges[i].line, - events[i].point.y); - - events[i].edge.edge = polygon->edges[i]; - events[i].edge.deferred_trap.right = NULL; - events[i].edge.prev = NULL; - events[i].edge.next = NULL; - events[i].edge.colinear = NULL; - - if (event_y) { - y = _cairo_fixed_integer_floor (events[i].point.y) - ymin; - events[i].edge.next = (cairo_bo_edge_t *) event_y[y]; - event_y[y] = (cairo_bo_start_event_t *) &events[i]; - } else - event_ptrs[i] = (cairo_bo_event_t *) &events[i]; - } - - if (event_y) { - for (y = i = 0; y < ymax && i < num_events; y++) { - cairo_bo_start_event_t *e; - int j = i; - for (e = event_y[y]; e; e = (cairo_bo_start_event_t *)e->edge.next) - event_ptrs[i++] = (cairo_bo_event_t *) e; - if (i > j + 1) - _cairo_bo_event_queue_sort (event_ptrs+j, i-j); - } - if (event_y != stack_event_y) - free (event_y); - } else - _cairo_bo_event_queue_sort (event_ptrs, i); - event_ptrs[i] = NULL; - -#if DEBUG_TRAPS - dump_edges (events, num_events, "bo-polygon-edges.txt"); -#endif - - /* XXX: This would be the convenient place to throw in multiple - * passes of the Bentley-Ottmann algorithm. It would merely - * require storing the results of each pass into a temporary - * cairo_traps_t. */ - status = _cairo_bentley_ottmann_tessellate_bo_edges (event_ptrs, num_events, - fill_rule, traps, - &intersections); -#if DEBUG_TRAPS - dump_traps (traps, "bo-polygon-out.txt"); -#endif - - if (events != stack_events) - free (events); - - return status; -} - -cairo_status_t -_cairo_bentley_ottmann_tessellate_traps (cairo_traps_t *traps, - cairo_fill_rule_t fill_rule) -{ - cairo_status_t status; - cairo_polygon_t polygon; - int i; - - if (unlikely (0 == traps->num_traps)) - return CAIRO_STATUS_SUCCESS; - -#if DEBUG_TRAPS - dump_traps (traps, "bo-traps-in.txt"); -#endif - - _cairo_polygon_init (&polygon, traps->limits, traps->num_limits); - - for (i = 0; i < traps->num_traps; i++) { - status = _cairo_polygon_add_line (&polygon, - &traps->traps[i].left, - traps->traps[i].top, - traps->traps[i].bottom, - 1); - if (unlikely (status)) - goto CLEANUP; - - status = _cairo_polygon_add_line (&polygon, - &traps->traps[i].right, - traps->traps[i].top, - traps->traps[i].bottom, - -1); - if (unlikely (status)) - goto CLEANUP; - } - - _cairo_traps_clear (traps); - status = _cairo_bentley_ottmann_tessellate_polygon (traps, - &polygon, - fill_rule); - -#if DEBUG_TRAPS - dump_traps (traps, "bo-traps-out.txt"); -#endif - - CLEANUP: - _cairo_polygon_fini (&polygon); - - return status; -} - -#if 0 -static cairo_bool_t -edges_have_an_intersection_quadratic (cairo_bo_edge_t *edges, - int num_edges) - -{ - int i, j; - cairo_bo_edge_t *a, *b; - cairo_bo_point32_t intersection; - - /* We must not be given any upside-down edges. */ - for (i = 0; i < num_edges; i++) { - assert (_cairo_bo_point32_compare (&edges[i].top, &edges[i].bottom) < 0); - edges[i].line.p1.x <<= CAIRO_BO_GUARD_BITS; - edges[i].line.p1.y <<= CAIRO_BO_GUARD_BITS; - edges[i].line.p2.x <<= CAIRO_BO_GUARD_BITS; - edges[i].line.p2.y <<= CAIRO_BO_GUARD_BITS; - } - - for (i = 0; i < num_edges; i++) { - for (j = 0; j < num_edges; j++) { - if (i == j) - continue; - - a = &edges[i]; - b = &edges[j]; - - if (! _cairo_bo_edge_intersect (a, b, &intersection)) - continue; - - printf ("Found intersection (%d,%d) between (%d,%d)-(%d,%d) and (%d,%d)-(%d,%d)\n", - intersection.x, - intersection.y, - a->line.p1.x, a->line.p1.y, - a->line.p2.x, a->line.p2.y, - b->line.p1.x, b->line.p1.y, - b->line.p2.x, b->line.p2.y); - - return TRUE; - } - } - return FALSE; -} - -#define TEST_MAX_EDGES 10 - -typedef struct test { - const char *name; - const char *description; - int num_edges; - cairo_bo_edge_t edges[TEST_MAX_EDGES]; -} test_t; - -static test_t -tests[] = { - { - "3 near misses", - "3 edges all intersecting very close to each other", - 3, - { - { { 4, 2}, {0, 0}, { 9, 9}, NULL, NULL }, - { { 7, 2}, {0, 0}, { 2, 3}, NULL, NULL }, - { { 5, 2}, {0, 0}, { 1, 7}, NULL, NULL } - } - }, - { - "inconsistent data", - "Derived from random testing---was leading to skip list and edge list disagreeing.", - 2, - { - { { 2, 3}, {0, 0}, { 8, 9}, NULL, NULL }, - { { 2, 3}, {0, 0}, { 6, 7}, NULL, NULL } - } - }, - { - "failed sort", - "A test derived from random testing that leads to an inconsistent sort --- looks like we just can't attempt to validate the sweep line with edge_compare?", - 3, - { - { { 6, 2}, {0, 0}, { 6, 5}, NULL, NULL }, - { { 3, 5}, {0, 0}, { 5, 6}, NULL, NULL }, - { { 9, 2}, {0, 0}, { 5, 6}, NULL, NULL }, - } - }, - { - "minimal-intersection", - "Intersection of a two from among the smallest possible edges.", - 2, - { - { { 0, 0}, {0, 0}, { 1, 1}, NULL, NULL }, - { { 1, 0}, {0, 0}, { 0, 1}, NULL, NULL } - } - }, - { - "simple", - "A simple intersection of two edges at an integer (2,2).", - 2, - { - { { 1, 1}, {0, 0}, { 3, 3}, NULL, NULL }, - { { 2, 1}, {0, 0}, { 2, 3}, NULL, NULL } - } - }, - { - "bend-to-horizontal", - "With intersection truncation one edge bends to horizontal", - 2, - { - { { 9, 1}, {0, 0}, {3, 7}, NULL, NULL }, - { { 3, 5}, {0, 0}, {9, 9}, NULL, NULL } - } - } -}; - -/* - { - "endpoint", - "An intersection that occurs at the endpoint of a segment.", - { - { { 4, 6}, { 5, 6}, NULL, { { NULL }} }, - { { 4, 5}, { 5, 7}, NULL, { { NULL }} }, - { { 0, 0}, { 0, 0}, NULL, { { NULL }} }, - } - } - { - name = "overlapping", - desc = "Parallel segments that share an endpoint, with different slopes.", - edges = { - { top = { x = 2, y = 0}, bottom = { x = 1, y = 1}}, - { top = { x = 2, y = 0}, bottom = { x = 0, y = 2}}, - { top = { x = 0, y = 3}, bottom = { x = 1, y = 3}}, - { top = { x = 0, y = 3}, bottom = { x = 2, y = 3}}, - { top = { x = 0, y = 4}, bottom = { x = 0, y = 6}}, - { top = { x = 0, y = 5}, bottom = { x = 0, y = 6}} - } - }, - { - name = "hobby_stage_3", - desc = "A particularly tricky part of the 3rd stage of the 'hobby' test below.", - edges = { - { top = { x = -1, y = -2}, bottom = { x = 4, y = 2}}, - { top = { x = 5, y = 3}, bottom = { x = 9, y = 5}}, - { top = { x = 5, y = 3}, bottom = { x = 6, y = 3}}, - } - }, - { - name = "hobby", - desc = "Example from John Hobby's paper. Requires 3 passes of the iterative algorithm.", - edges = { - { top = { x = 0, y = 0}, bottom = { x = 9, y = 5}}, - { top = { x = 0, y = 0}, bottom = { x = 13, y = 6}}, - { top = { x = -1, y = -2}, bottom = { x = 9, y = 5}} - } - }, - { - name = "slope", - desc = "Edges with same start/stop points but different slopes", - edges = { - { top = { x = 4, y = 1}, bottom = { x = 6, y = 3}}, - { top = { x = 4, y = 1}, bottom = { x = 2, y = 3}}, - { top = { x = 2, y = 4}, bottom = { x = 4, y = 6}}, - { top = { x = 6, y = 4}, bottom = { x = 4, y = 6}} - } - }, - { - name = "horizontal", - desc = "Test of a horizontal edge", - edges = { - { top = { x = 1, y = 1}, bottom = { x = 6, y = 6}}, - { top = { x = 2, y = 3}, bottom = { x = 5, y = 3}} - } - }, - { - name = "vertical", - desc = "Test of a vertical edge", - edges = { - { top = { x = 5, y = 1}, bottom = { x = 5, y = 7}}, - { top = { x = 2, y = 4}, bottom = { x = 8, y = 5}} - } - }, - { - name = "congruent", - desc = "Two overlapping edges with the same slope", - edges = { - { top = { x = 5, y = 1}, bottom = { x = 5, y = 7}}, - { top = { x = 5, y = 2}, bottom = { x = 5, y = 6}}, - { top = { x = 2, y = 4}, bottom = { x = 8, y = 5}} - } - }, - { - name = "multi", - desc = "Several segments with a common intersection point", - edges = { - { top = { x = 1, y = 2}, bottom = { x = 5, y = 4} }, - { top = { x = 1, y = 1}, bottom = { x = 5, y = 5} }, - { top = { x = 2, y = 1}, bottom = { x = 4, y = 5} }, - { top = { x = 4, y = 1}, bottom = { x = 2, y = 5} }, - { top = { x = 5, y = 1}, bottom = { x = 1, y = 5} }, - { top = { x = 5, y = 2}, bottom = { x = 1, y = 4} } - } - } -}; -*/ - -static int -run_test (const char *test_name, - cairo_bo_edge_t *test_edges, - int num_edges) -{ - int i, intersections, passes; - cairo_bo_edge_t *edges; - cairo_array_t intersected_edges; - - printf ("Testing: %s\n", test_name); - - _cairo_array_init (&intersected_edges, sizeof (cairo_bo_edge_t)); - - intersections = _cairo_bentley_ottmann_intersect_edges (test_edges, num_edges, &intersected_edges); - if (intersections) - printf ("Pass 1 found %d intersections:\n", intersections); - - - /* XXX: Multi-pass Bentley-Ottmmann. Preferable would be to add a - * pass of Hobby's tolerance-square algorithm instead. */ - passes = 1; - while (intersections) { - int num_edges = _cairo_array_num_elements (&intersected_edges); - passes++; - edges = _cairo_malloc_ab (num_edges, sizeof (cairo_bo_edge_t)); - assert (edges != NULL); - memcpy (edges, _cairo_array_index (&intersected_edges, 0), num_edges * sizeof (cairo_bo_edge_t)); - _cairo_array_fini (&intersected_edges); - _cairo_array_init (&intersected_edges, sizeof (cairo_bo_edge_t)); - intersections = _cairo_bentley_ottmann_intersect_edges (edges, num_edges, &intersected_edges); - free (edges); - - if (intersections){ - printf ("Pass %d found %d remaining intersections:\n", passes, intersections); - } else { - if (passes > 3) - for (i = 0; i < passes; i++) - printf ("*"); - printf ("No remainining intersections found after pass %d\n", passes); - } - } - - if (edges_have_an_intersection_quadratic (_cairo_array_index (&intersected_edges, 0), - _cairo_array_num_elements (&intersected_edges))) - printf ("*** FAIL ***\n"); - else - printf ("PASS\n"); - - _cairo_array_fini (&intersected_edges); - - return 0; -} - -#define MAX_RANDOM 300 - -int -main (void) -{ - char random_name[] = "random-XX"; - cairo_bo_edge_t random_edges[MAX_RANDOM], *edge; - unsigned int i, num_random; - test_t *test; - - for (i = 0; i < ARRAY_LENGTH (tests); i++) { - test = &tests[i]; - run_test (test->name, test->edges, test->num_edges); - } - - for (num_random = 0; num_random < MAX_RANDOM; num_random++) { - srand (0); - for (i = 0; i < num_random; i++) { - do { - edge = &random_edges[i]; - edge->line.p1.x = (int32_t) (10.0 * (rand() / (RAND_MAX + 1.0))); - edge->line.p1.y = (int32_t) (10.0 * (rand() / (RAND_MAX + 1.0))); - edge->line.p2.x = (int32_t) (10.0 * (rand() / (RAND_MAX + 1.0))); - edge->line.p2.y = (int32_t) (10.0 * (rand() / (RAND_MAX + 1.0))); - if (edge->line.p1.y > edge->line.p2.y) { - int32_t tmp = edge->line.p1.y; - edge->line.p1.y = edge->line.p2.y; - edge->line.p2.y = tmp; - } - } while (edge->line.p1.y == edge->line.p2.y); - } - - sprintf (random_name, "random-%02d", num_random); - - run_test (random_name, random_edges, num_random); - } - - return 0; -} -#endif diff --git a/source/libs/cairo/cairo-src/src/cairo-beos-surface.cpp b/source/libs/cairo/cairo-src/src/cairo-beos-surface.cpp deleted file mode 100644 index c97641685fc0a3f7ffb6ae32d35ba4363a7f6610..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-beos-surface.cpp +++ /dev/null @@ -1,984 +0,0 @@ -/* vim:set ts=8 sw=4 noet cin: */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2005 Christian Biesinger <cbiesinger@web.de> - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Christian Biesinger - * <cbiesinger@web.de> - * - * Contributor(s): - */ - -// This is a C++ file in order to use the C++ BeOS API - -#include "cairoint.h" - -#include "cairo-beos.h" - -#include "cairo-error-private.h" -#include "cairo-image-surface-inline.h" - -#include <new> - -#include <Bitmap.h> -#include <Region.h> -#if 0 -#include <DirectWindow.h> -#endif -#include <Screen.h> -#include <Window.h> -#include <Locker.h> - -/** - * SECTION:beos-surface - * @Title: BeOS Surfaces - * @Short_Description: BeOS surface support - * @See_Also: #cairo_surface_t - * - * The BeOS surface is used to render cairo graphics to BeOS views - * and bitmaps. - **/ - -#define CAIRO_INT_STATUS_SUCCESS (cairo_int_status_t)(CAIRO_STATUS_SUCCESS) - -struct cairo_beos_surface_t { - cairo_surface_t base; - - cairo_region_t *clip_region; - - BView* view; - - /* - * A view is either attached to a bitmap, a window, or unattached. - * If it is attached to a window, we can copy data out of it using BScreen. - * If it is attached to a bitmap, we can read the bitmap data. - * If it is not attached, it doesn't draw anything, we need not bother. - * - * Since there doesn't seem to be a way to get the bitmap from a view if it - * is attached to one, we have to use a special surface creation function. - */ - - BBitmap* bitmap; - - // If true, surface and view should be deleted when this surface is - // destroyed - bool owns_bitmap_view; -}; - -class AutoLockView { - public: - AutoLockView(BView* view) : mView(view) { - mOK = mView->LockLooper(); - } - - ~AutoLockView() { - if (mOK) - mView->UnlockLooper(); - } - - operator bool() { - return mOK; - } - - private: - BView* mView; - bool mOK; -}; - -static cairo_surface_t * -_cairo_beos_surface_create_internal (BView* view, - BBitmap* bmp, - bool owns_bitmap_view = false); - -static inline BRect -_cairo_rectangle_to_brect (const cairo_rectangle_int_t* rect) -{ - // A BRect is one pixel wider than you'd think - return BRect (rect->x, rect->y, - rect->x + rect->width - 1, - rect->y + rect->height - 1); -} - -static inline cairo_rectangle_int_t -_brect_to_cairo_rectangle (const BRect &rect) -{ - cairo_rectangle_int_t retval; - retval.x = floor (rect.left); - retval.y = floor (rect.top); - retval.width = ceil (rect.right) - retval.x + 1; - retval.height = ceil (rect.bottom) - rectval.y + 1; - return retval; -} - -static inline rgb_color -_cairo_color_to_be_color (const cairo_color_t *color) -{ - // This factor ensures a uniform distribution of numbers - const float factor = 256 - 1e-5; - // Using doubles to have non-premultiplied colors - rgb_color be_color = { uint8(color->red * factor), - uint8(color->green * factor), - uint8(color->blue * factor), - uint8(color->alpha * factor) }; - - return be_color; -} - -enum ViewCopyStatus { - OK, - NOT_VISIBLE, // The view or the interest rect is not visible on screen - ERROR // The view was visible, but the rect could not be copied. Probably OOM -}; - -/** - * _cairo_beos_view_to_bitmap: - * @bitmap: [out] The resulting bitmap. - * @rect: [out] The rectangle that was copied, in the view's coordinate system - * @interestRect: If non-null, only this part of the view will be copied (view's coord system). - * - * Gets the contents of the view as a BBitmap*. Caller must delete the bitmap. - **/ -static ViewCopyStatus -_cairo_beos_view_to_bitmap (BView* view, - BBitmap** bitmap, - BRect* rect = NULL, - const BRect* interestRect = NULL) -{ - *bitmap = NULL; - - BWindow* wnd = view->Window(); - // If we have no window, can't do anything - if (!wnd) - return NOT_VISIBLE; - - view->Sync(); - wnd->Sync(); - -#if 0 - // Is it a direct window? - BDirectWindow* directWnd = dynamic_cast<BDirectWindow*>(wnd); - if (directWnd) { - // WRITEME - } -#endif - - // Is it visible? If so, we can copy the content off the screen - if (wnd->IsHidden()) - return NOT_VISIBLE; - - BRect rectToCopy(view->Bounds()); - if (interestRect) - rectToCopy = rectToCopy & *interestRect; - - if (!rectToCopy.IsValid()) - return NOT_VISIBLE; - - BScreen screen(wnd); - BRect screenRect(view->ConvertToScreen(rectToCopy)); - screenRect = screenRect & screen.Frame(); - - if (!screen.IsValid()) - return NOT_VISIBLE; - - if (rect) - *rect = view->ConvertFromScreen(screenRect); - - if (screen.GetBitmap(bitmap, false, &screenRect) == B_OK) - return OK; - - return ERROR; -} - -static void -unpremultiply_bgra (unsigned char* data, - int width, - int height, - int stride, - unsigned char* retdata) -{ - unsigned char* end = data + stride * height; - for (unsigned char* in = data, *out = retdata; - in < end; - in += stride, out += stride) - { - for (int i = 0; i < width; i ++) { - uint8_t *b = &out[4*i]; - uint32_t pixel; - uint8_t alpha; - - memcpy (&pixel, &data[4*i], sizeof (uint32_t)); - alpha = pixel & 0xff; - if (alpha == 0) { - b[0] = b[1] = b[2] = b[3] = 0; - } else { - b[0] = (((pixel >> 24) & 0xff) * 255 + alpha / 2) / alpha; - b[1] = (((pixel >> 16) & 0xff) * 255 + alpha / 2) / alpha; - b[2] = (((pixel >> 8) & 0xff) * 255 + alpha / 2) / alpha; - b[3] = alpha; - } - } - } -} - -static inline int -multiply_alpha (int alpha, int color) -{ - int temp = (alpha * color) + 0x80; - return ((temp + (temp >> 8)) >> 8); -} - -static unsigned char* -premultiply_bgra (unsigned char* data, - int width, - int height, - int stride) -{ - uint8_t * retdata = reinterpret_cast<unsigned char*>(_cairo_malloc_ab(height, stride)); - if (!retdata) - return NULL; - - uint8_t * end = data + stride * height; - for (uint8_t * in = data, *out = retdata; - in < end; - in += stride, out += stride) - { - for (int i = 0; i < width; i ++) { - uint8_t *base = &in[4*i]; - uint8_t alpha = base[3]; - uint32_t p; - - if (alpha == 0) { - p = 0; - } else { - uint8_t blue = base[0]; - uint8_t green = base[1]; - uint8_t red = base[2]; - - if (alpha != 0xff) { - blue = multiply_alpha (alpha, blue); - green = multiply_alpha (alpha, green); - red = multiply_alpha (alpha, red); - } - p = (alpha << 0) | (red << 8) | (green << 16) | (blue << 24); - } - memcpy (&out[4*i], &p, sizeof (uint32_t)); - } - } - return retdata; -} - -static cairo_int_status_t -_cairo_beos_surface_set_clip_region (cairo_beos_surface_t *surface, - cairo_region_t *region) -{ - cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>( - abstract_surface); - AutoLockView locker(surface->view); - assert (locker); - - if (region == surface->clip_region) - return CAIRO_INT_STATUS_SUCCESS; - - cairo_region_destroy (surface->clip_region); - surface->clip_region = cairo_region_reference (region); - - if (region == NULL) { - // No clipping - surface->view->ConstrainClippingRegion(NULL); - return CAIRO_INT_STATUS_SUCCESS; - } - - int count = cairo_region_num_rectangles (region); - BRegion bregion; - for (int i = 0; i < count; ++i) { - cairo_rectangle_int_t rect; - - cairo_region_get_rectangle (region, i, &rect); - // Have to subtract one, because for pixman, the second coordinate - // lies outside the rectangle. - bregion.Include (_cairo_rectangle_to_brect (&rect)); - } - surface->view->ConstrainClippingRegion(&bregion); - return CAIRO_INT_STATUS_SUCCESS; -} - - -/** - * _cairo_beos_bitmap_to_surface: - * - * Returns an addrefed image surface for a BBitmap. The bitmap need not outlive - * the surface. - **/ -static cairo_image_surface_t* -_cairo_beos_bitmap_to_surface (BBitmap* bitmap) -{ - color_space format = bitmap->ColorSpace(); - if (format != B_RGB32 && format != B_RGBA32) { - BBitmap bmp(bitmap->Bounds(), B_RGB32, true); - BView view(bitmap->Bounds(), "Cairo bitmap drawing view", - B_FOLLOW_ALL_SIDES, 0); - bmp.AddChild(&view); - - view.LockLooper(); - - view.DrawBitmap(bitmap, BPoint(0.0, 0.0)); - view.Sync(); - - cairo_image_surface_t* imgsurf = _cairo_beos_bitmap_to_surface(&bmp); - - view.UnlockLooper(); - bmp.RemoveChild(&view); - return imgsurf; - } - - cairo_format_t cformat = format == B_RGB32 ? - CAIRO_FORMAT_RGB24 : CAIRO_FORMAT_ARGB32; - - BRect bounds(bitmap->Bounds()); - unsigned char* bits = reinterpret_cast<unsigned char*>(bitmap->Bits()); - int width = bounds.IntegerWidth() + 1; - int height = bounds.IntegerHeight() + 1; - unsigned char* premultiplied; - if (cformat == CAIRO_FORMAT_ARGB32) { - premultiplied = premultiply_bgra (bits, width, height, - bitmap->BytesPerRow()); - } else { - premultiplied = reinterpret_cast<unsigned char*>( - _cairo_malloc_ab(bitmap->BytesPerRow(), height)); - if (premultiplied) - memcpy(premultiplied, bits, bitmap->BytesPerRow() * height); - } - if (!premultiplied) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - cairo_image_surface_t* surf = reinterpret_cast<cairo_image_surface_t*> - (cairo_image_surface_create_for_data(premultiplied, - cformat, - width, - height, - bitmap->BytesPerRow())); - if (surf->base.status) - free(premultiplied); - else - _cairo_image_surface_assume_ownership_of_data(surf); - return surf; -} - -/** - * _cairo_image_surface_to_bitmap: - * - * Converts an image surface to a BBitmap. The return value must be freed with - * delete. - **/ -static BBitmap* -_cairo_image_surface_to_bitmap (cairo_image_surface_t* surface) -{ - BRect size(0.0, 0.0, surface->width - 1, surface->height - 1); - switch (surface->format) { - case CAIRO_FORMAT_ARGB32: { - BBitmap* data = new BBitmap(size, B_RGBA32); - unpremultiply_bgra (surface->data, - surface->width, - surface->height, - surface->stride, - reinterpret_cast<unsigned char*>(data->Bits())); - return data; - } - case CAIRO_FORMAT_RGB24: { - BBitmap* data = new BBitmap(size, B_RGB32); - memcpy(data->Bits(), surface->data, surface->height * surface->stride); - return data; - } - default: - assert(0); - return NULL; - } -} - -/** - * _cairo_op_to_be_op: - * - * Converts a cairo drawing operator to a beos drawing_mode. Returns true if - * the operator could be converted, false otherwise. - **/ -static bool -_cairo_op_to_be_op (cairo_operator_t cairo_op, - drawing_mode* beos_op) -{ - switch (cairo_op) { - case CAIRO_OPERATOR_SOURCE: - *beos_op = B_OP_COPY; - return true; - case CAIRO_OPERATOR_OVER: - *beos_op = B_OP_ALPHA; - return true; - - case CAIRO_OPERATOR_ADD: - // Does not actually work - // XXX This is a fundamental compositing operator, it has to work! -#if 1 - return false; -#else - *beos_op = B_OP_ADD; - return true; -#endif - - case CAIRO_OPERATOR_CLEAR: - // Does not map to B_OP_ERASE - it replaces the dest with the low - // color, instead of transparency; could be done by setting low - // color appropriately. - - case CAIRO_OPERATOR_IN: - case CAIRO_OPERATOR_OUT: - case CAIRO_OPERATOR_ATOP: - - case CAIRO_OPERATOR_DEST: - case CAIRO_OPERATOR_DEST_OVER: - case CAIRO_OPERATOR_DEST_IN: - case CAIRO_OPERATOR_DEST_OUT: - case CAIRO_OPERATOR_DEST_ATOP: - - case CAIRO_OPERATOR_XOR: - case CAIRO_OPERATOR_SATURATE: - - default: - return false; - } -} - -static cairo_surface_t * -_cairo_beos_surface_create_similar (void *abstract_surface, - cairo_content_t content, - int width, - int height) -{ - 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: - return NULL; - 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_NOT_REACHED; - 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) -{ - 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; - } - - cairo_region_destroy (surface->clip_region); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_beos_surface_acquire_source_image (void *abstract_surface, - cairo_image_surface_t **image_out, - void **image_extra) -{ - cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>( - abstract_surface); - AutoLockView locker(surface->view); - if (!locker) - return CAIRO_STATUS_NO_MEMORY; /// XXX not exactly right, but what can we do? - - - surface->view->Sync(); - - if (surface->bitmap) { - *image_out = _cairo_beos_bitmap_to_surface (surface->bitmap); - if (unlikely ((*image_out)->base.status)) - return (*image_out)->base.status; - - *image_extra = NULL; - return CAIRO_STATUS_SUCCESS; - } - - BBitmap* bmp; - if (_cairo_beos_view_to_bitmap(surface->view, &bmp) != OK) - return CAIRO_STATUS_NO_MEMORY; /// XXX incorrect if the error was NOT_VISIBLE - - *image_out = _cairo_beos_bitmap_to_surface (bmp); - if (unlikely ((*image_out)->base.status)) { - delete bmp; - return (*image_out)->base.status; - } - *image_extra = bmp; - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_beos_surface_release_source_image (void *abstract_surface, - cairo_image_surface_t *image, - void *image_extra) -{ - cairo_surface_destroy (&image->base); - - if (image_extra != NULL) { - BBitmap* bmp = static_cast<BBitmap*>(image_extra); - delete bmp; - } -} - -static cairo_status_t -_cairo_beos_surface_acquire_dest_image (void *abstract_surface, - cairo_rectangle_int_t *interest_rect, - cairo_image_surface_t **image_out, - cairo_rectangle_int_t *image_rect, - void **image_extra) -{ - cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>( - abstract_surface); - - AutoLockView locker(surface->view); - if (!locker) { - *image_out = NULL; - *image_extra = NULL; - return (cairo_status_t) CAIRO_INT_STATUS_NOTHING_TO_DO; - } - - if (surface->bitmap) { - surface->view->Sync(); - *image_out = _cairo_beos_bitmap_to_surface(surface->bitmap); - if (unlikely ((*image_out)->base.status)) - return (*image_out)->base.status; - - image_rect->x = 0; - image_rect->y = 0; - image_rect->width = (*image_out)->width; - image_rect->height = (*image_out)->height; - - *image_extra = NULL; - return CAIRO_STATUS_SUCCESS; - } - - BRect b_interest_rect (_cairo_rectangle_to_brect (interest_rect)); - - BRect rect; - BBitmap* bitmap; - ViewCopyStatus status = _cairo_beos_view_to_bitmap(surface->view, &bitmap, - &rect, &b_interest_rect); - if (status == NOT_VISIBLE) { - *image_out = NULL; - *image_extra = NULL; - return CAIRO_STATUS_SUCCESS; - } - if (status == ERROR) - return CAIRO_STATUS_NO_MEMORY; - - *image_rect = _brect_to_cairo_rectangle(rect); - *image_out = _cairo_beos_bitmap_to_surface(bitmap); - delete bitmap; - if (unlikely ((*image_out)->base.status)) - return (*image_out)->base.status; - - *image_extra = NULL; - - return CAIRO_STATUS_SUCCESS; -} - - -static void -_cairo_beos_surface_release_dest_image (void *abstract_surface, - cairo_rectangle_int_t *intersect_rect, - cairo_image_surface_t *image, - cairo_rectangle_int_t *image_rect, - void *image_extra) -{ - 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); - - surface->view->DrawBitmap (bitmap_to_draw, - _cairo_rectangle_to_brect (image_rect)); - - surface->view->PopState(); - - delete bitmap_to_draw; - cairo_surface_destroy(&image->base); -} - -static cairo_int_status_t -_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_region_t *clip_region) -{ - cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>( - dst); - cairo_int_status_t status; - AutoLockView locker(surface->view); - if (!locker) - return CAIRO_INT_STATUS_SUCCESS; - - drawing_mode mode; - if (!_cairo_op_to_be_op(op, &mode)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - // XXX Masks are not yet supported - if (mask) - return CAIRO_INT_STATUS_UNSUPPORTED; - - // XXX should eventually support the others - if (src->type != CAIRO_PATTERN_TYPE_SURFACE || - src->extend != CAIRO_EXTEND_NONE) - { - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - // Can we maybe support other matrices as well? (scale? if the filter is right) - int itx, ity; - if (!_cairo_matrix_is_integer_translation(&src->matrix, &itx, &ity)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_beos_surface_set_clip_region (surface, clip_region); - if (unlikely (status)) - return status; - - BRect srcRect(src_x + itx, - src_y + ity, - src_x + itx + width - 1, - src_y + ity + height - 1); - BRect dstRect(dst_x, dst_y, dst_x + width - 1, dst_y + height - 1); - - cairo_surface_t* src_surface = reinterpret_cast<cairo_surface_pattern_t*>(src)-> - surface; - - // 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); - - 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; - } - } - - 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; - } - - // 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 cairo_int_status_t -_cairo_beos_surface_fill_rectangles (void *abstract_surface, - cairo_operator_t op, - const cairo_color_t *color, - cairo_rectangle_int_t *rects, - int num_rects, - cairo_region_t *clip_region) -{ - cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>( - abstract_surface); - cairo_int_status_t status; - - if (num_rects <= 0) - return CAIRO_INT_STATUS_SUCCESS; - - AutoLockView locker(surface->view); - if (!locker) - return CAIRO_INT_STATUS_SUCCESS; - - drawing_mode mode; - if (!_cairo_op_to_be_op(op, &mode)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_beos_surface_set_clip_region (surface, clip_region); - if (unlikely (status)) - return status; - - rgb_color be_color = _cairo_color_to_be_color(color); - - if (mode == B_OP_ALPHA && be_color.alpha == 0xFF) - mode = B_OP_COPY; - - // For CAIRO_OPERATOR_SOURCE, cairo expects us to use the premultiplied - // color info. This is only relevant when drawing into an rgb24 buffer - // (as for others, we can convert when asked for the image) - if (mode == B_OP_COPY && be_color.alpha != 0xFF && - (!surface->bitmap || surface->bitmap->ColorSpace() != B_RGBA32)) - { - be_color.red = color->red_short >> 8; - be_color.green = color->green_short >> 8; - be_color.blue = color->blue_short >> 8; - } - - surface->view->PushState(); - - surface->view->SetDrawingMode(mode); - surface->view->SetHighColor(be_color); - if (surface->bitmap && surface->bitmap->ColorSpace() == B_RGBA32) - surface->view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_COMPOSITE); - else - surface->view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY); - - for (int i = 0; i < num_rects; ++i) - surface->view->FillRect (_cairo_rectangle_to_brect (&rects[i])); - - surface->view->PopState(); - - return CAIRO_INT_STATUS_SUCCESS; -} - -static cairo_bool_t -_cairo_beos_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *rectangle) -{ - cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>( - abstract_surface); - AutoLockView locker(surface->view); - if (!locker) - return FALSE; - - *rectangle = _brect_to_cairo_rectangle (surface->view->Bounds()); - return TRUE; -} - -static const struct _cairo_surface_backend cairo_beos_surface_backend = { - 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_surface_composite, /* composite */ - _cairo_beos_surface_fill_rectangles, - NULL, /* composite_trapezoids */ - NULL, /* create_span_renderer */ - NULL, /* check_span_renderer */ - NULL, /* copy_page */ - NULL, /* show_page */ - _cairo_beos_surface_get_extents, - NULL, /* old_show_glyphs */ - NULL, /* get_font_options */ - NULL, /* flush */ - NULL, /* mark_dirty_rectangle */ - NULL, /* scaled_font_fini */ - NULL, /* scaled_glyph_fini */ - - NULL, /* paint */ - NULL, /* mask */ - NULL, /* stroke */ - NULL, /* fill */ - 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_content_t content = CAIRO_CONTENT_COLOR; - if (bmp && (bmp->ColorSpace() == B_RGBA32 || bmp->ColorSpace() == B_RGBA15)) - content = CAIRO_CONTENT_COLOR_ALPHA; - _cairo_surface_init (&surface->base, - &cairo_beos_surface_backend, - NULL, /* device */ - content); - - surface->view = view; - surface->bitmap = bmp; - surface->owns_bitmap_view = owns_bitmap_view; - - surface->clip_region = NULL; - - return &surface->base; -} - -/** - * cairo_beos_surface_create: - * @view: The view to draw on - * - * Creates a Cairo surface that draws onto a BeOS BView. - * The caller must ensure that the view does not get deleted before the surface. - * If the view is attached to a bitmap rather than an on-screen window, use - * cairo_beos_surface_create_for_bitmap() instead of this function. - * - * Since: TBD - **/ -cairo_surface_t * -cairo_beos_surface_create (BView* view) -{ - return cairo_beos_surface_create_for_bitmap(view, NULL); -} - -/** - * cairo_beos_surface_create_for_bitmap: - * @view: The view to draw on - * @bmp: The bitmap to which the view is attached - * - * Creates a Cairo surface that draws onto a BeOS BView which is attached to a - * BBitmap. - * The caller must ensure that the view and the bitmap do not get deleted - * before the surface. - * - * For views that draw to a bitmap (as opposed to a screen), use this function - * rather than cairo_beos_surface_create(). Not using this function WILL lead to - * incorrect behaviour. - * - * For now, only views that draw to the entire area of bmp are supported. - * The view must already be attached to the bitmap. - * - * Since: TBD - **/ -cairo_surface_t * -cairo_beos_surface_create_for_bitmap (BView* view, - BBitmap* bmp) -{ - return _cairo_beos_surface_create_internal(view, bmp); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-beos.h b/source/libs/cairo/cairo-src/src/cairo-beos.h deleted file mode 100644 index fdb89a6c4dc98988ea888f37913823e81eeae3d6..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-beos.h +++ /dev/null @@ -1,60 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2005 Christian Biesinger <cbiesinger@web.de> - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Christian Biesinger - * <cbiesinger@web.de> - * - * Contributor(s): - */ - -#ifndef CAIRO_BEOS_H -#define CAIRO_BEOS_H - -#include "cairo.h" - -#if CAIRO_HAS_BEOS_SURFACE - -#include <View.h> - -CAIRO_BEGIN_DECLS - -cairo_public cairo_surface_t * -cairo_beos_surface_create (BView* view); - -cairo_public cairo_surface_t * -cairo_beos_surface_create_for_bitmap (BView* view, - BBitmap* bmp); - -CAIRO_END_DECLS - -#else /* CAIRO_HAS_BEOS_SURFACE */ -# error Cairo was not compiled with support for the beos backend -#endif /* CAIRO_HAS_BEOS_SURFACE */ - -#endif /* CAIRO_BEOS_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-botor-scan-converter.c b/source/libs/cairo/cairo-src/src/cairo-botor-scan-converter.c deleted file mode 100644 index 515305bf24e31ba47c95998fa34a129270309e6c..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-botor-scan-converter.c +++ /dev/null @@ -1,2164 +0,0 @@ -/* - * Copyright © 2004 Carl Worth - * Copyright © 2006 Red Hat, Inc. - * Copyright © 2007 David Turner - * Copyright © 2008 M Joonas Pihlaja - * Copyright © 2008 Chris Wilson - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Carl Worth - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - * M Joonas Pihlaja <jpihlaja@cc.helsinki.fi> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -/* Provide definitions for standalone compilation */ -#include "cairoint.h" - -#include "cairo-error-private.h" -#include "cairo-list-inline.h" -#include "cairo-freelist-private.h" -#include "cairo-combsort-inline.h" - -#include <setjmp.h> - -#define STEP_X CAIRO_FIXED_ONE -#define STEP_Y CAIRO_FIXED_ONE -#define UNROLL3(x) x x x - -#define STEP_XY (2*STEP_X*STEP_Y) /* Unit area in the step. */ -#define AREA_TO_ALPHA(c) (((c)*255 + STEP_XY/2) / STEP_XY) - -typedef struct _cairo_bo_intersect_ordinate { - int32_t ordinate; - enum { EXACT, INEXACT } exactness; -} cairo_bo_intersect_ordinate_t; - -typedef struct _cairo_bo_intersect_point { - cairo_bo_intersect_ordinate_t x; - cairo_bo_intersect_ordinate_t y; -} cairo_bo_intersect_point_t; - -struct quorem { - cairo_fixed_t quo; - cairo_fixed_t rem; -}; - -struct run { - struct run *next; - int sign; - cairo_fixed_t y; -}; - -typedef struct edge { - cairo_list_t link; - - cairo_edge_t edge; - - /* Current x coordinate and advancement. - * Initialised to the x coordinate of the top of the - * edge. The quotient is in cairo_fixed_t units and the - * remainder is mod dy in cairo_fixed_t units. - */ - cairo_fixed_t dy; - struct quorem x; - struct quorem dxdy; - struct quorem dxdy_full; - - cairo_bool_t vertical; - unsigned int flags; - - int current_sign; - struct run *runs; -} edge_t; - -enum { - START = 0x1, - STOP = 0x2, -}; - -/* the parent is always given by index/2 */ -#define PQ_PARENT_INDEX(i) ((i) >> 1) -#define PQ_FIRST_ENTRY 1 - -/* left and right children are index * 2 and (index * 2) +1 respectively */ -#define PQ_LEFT_CHILD_INDEX(i) ((i) << 1) - -typedef enum { - EVENT_TYPE_STOP, - EVENT_TYPE_INTERSECTION, - EVENT_TYPE_START -} event_type_t; - -typedef struct _event { - cairo_fixed_t y; - event_type_t type; -} event_t; - -typedef struct _start_event { - cairo_fixed_t y; - event_type_t type; - edge_t *edge; -} start_event_t; - -typedef struct _queue_event { - cairo_fixed_t y; - event_type_t type; - edge_t *e1; - edge_t *e2; -} queue_event_t; - -typedef struct _pqueue { - int size, max_size; - - event_t **elements; - event_t *elements_embedded[1024]; -} pqueue_t; - -struct cell { - struct cell *prev; - struct cell *next; - int x; - int uncovered_area; - int covered_height; -}; - -typedef struct _sweep_line { - cairo_list_t active; - cairo_list_t stopped; - cairo_list_t *insert_cursor; - cairo_bool_t is_vertical; - - cairo_fixed_t current_row; - cairo_fixed_t current_subrow; - - struct coverage { - struct cell head; - struct cell tail; - - struct cell *cursor; - int count; - - cairo_freepool_t pool; - } coverage; - - struct event_queue { - pqueue_t pq; - event_t **start_events; - - cairo_freepool_t pool; - } queue; - - cairo_freepool_t runs; - - jmp_buf unwind; -} sweep_line_t; - -cairo_always_inline static struct quorem -floored_divrem (int a, int b) -{ - struct quorem qr; - qr.quo = a/b; - qr.rem = a%b; - if ((a^b)<0 && qr.rem) { - qr.quo--; - qr.rem += b; - } - return qr; -} - -static struct quorem -floored_muldivrem(int x, int a, int b) -{ - struct quorem qr; - long long xa = (long long)x*a; - qr.quo = xa/b; - qr.rem = xa%b; - if ((xa>=0) != (b>=0) && qr.rem) { - qr.quo--; - qr.rem += b; - } - return qr; -} - -static cairo_fixed_t -line_compute_intersection_x_for_y (const cairo_line_t *line, - cairo_fixed_t y) -{ - cairo_fixed_t x, dy; - - if (y == line->p1.y) - return line->p1.x; - if (y == line->p2.y) - return line->p2.x; - - x = line->p1.x; - dy = line->p2.y - line->p1.y; - if (dy != 0) { - x += _cairo_fixed_mul_div_floor (y - line->p1.y, - line->p2.x - line->p1.x, - dy); - } - - return x; -} - -/* - * We need to compare the x-coordinates of a pair of lines for a particular y, - * without loss of precision. - * - * The x-coordinate along an edge for a given y is: - * X = A_x + (Y - A_y) * A_dx / A_dy - * - * So the inequality we wish to test is: - * A_x + (Y - A_y) * A_dx / A_dy ∘ B_x + (Y - B_y) * B_dx / B_dy, - * where ∘ is our inequality operator. - * - * By construction, we know that A_dy and B_dy (and (Y - A_y), (Y - B_y)) are - * all positive, so we can rearrange it thus without causing a sign change: - * A_dy * B_dy * (A_x - B_x) ∘ (Y - B_y) * B_dx * A_dy - * - (Y - A_y) * A_dx * B_dy - * - * Given the assumption that all the deltas fit within 32 bits, we can compute - * this comparison directly using 128 bit arithmetic. For certain, but common, - * input we can reduce this down to a single 32 bit compare by inspecting the - * deltas. - * - * (And put the burden of the work on developing fast 128 bit ops, which are - * required throughout the tessellator.) - * - * See the similar discussion for _slope_compare(). - */ -static int -edges_compare_x_for_y_general (const cairo_edge_t *a, - const cairo_edge_t *b, - int32_t y) -{ - /* XXX: We're assuming here that dx and dy will still fit in 32 - * bits. That's not true in general as there could be overflow. We - * should prevent that before the tessellation algorithm - * begins. - */ - int32_t dx; - int32_t adx, ady; - int32_t bdx, bdy; - enum { - HAVE_NONE = 0x0, - HAVE_DX = 0x1, - HAVE_ADX = 0x2, - HAVE_DX_ADX = HAVE_DX | HAVE_ADX, - HAVE_BDX = 0x4, - HAVE_DX_BDX = HAVE_DX | HAVE_BDX, - HAVE_ADX_BDX = HAVE_ADX | HAVE_BDX, - HAVE_ALL = HAVE_DX | HAVE_ADX | HAVE_BDX - } have_dx_adx_bdx = HAVE_ALL; - - /* don't bother solving for abscissa if the edges' bounding boxes - * can be used to order them. */ - { - int32_t amin, amax; - int32_t bmin, bmax; - if (a->line.p1.x < a->line.p2.x) { - amin = a->line.p1.x; - amax = a->line.p2.x; - } else { - amin = a->line.p2.x; - amax = a->line.p1.x; - } - if (b->line.p1.x < b->line.p2.x) { - bmin = b->line.p1.x; - bmax = b->line.p2.x; - } else { - bmin = b->line.p2.x; - bmax = b->line.p1.x; - } - if (amax < bmin) return -1; - if (amin > bmax) return +1; - } - - ady = a->line.p2.y - a->line.p1.y; - adx = a->line.p2.x - a->line.p1.x; - if (adx == 0) - have_dx_adx_bdx &= ~HAVE_ADX; - - bdy = b->line.p2.y - b->line.p1.y; - bdx = b->line.p2.x - b->line.p1.x; - if (bdx == 0) - have_dx_adx_bdx &= ~HAVE_BDX; - - dx = a->line.p1.x - b->line.p1.x; - if (dx == 0) - have_dx_adx_bdx &= ~HAVE_DX; - -#define L _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (ady, bdy), dx) -#define A _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (adx, bdy), y - a->line.p1.y) -#define B _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (bdx, ady), y - b->line.p1.y) - switch (have_dx_adx_bdx) { - default: - case HAVE_NONE: - return 0; - case HAVE_DX: - /* A_dy * B_dy * (A_x - B_x) ∘ 0 */ - return dx; /* ady * bdy is positive definite */ - case HAVE_ADX: - /* 0 ∘ - (Y - A_y) * A_dx * B_dy */ - return adx; /* bdy * (y - a->top.y) is positive definite */ - case HAVE_BDX: - /* 0 ∘ (Y - B_y) * B_dx * A_dy */ - return -bdx; /* ady * (y - b->top.y) is positive definite */ - case HAVE_ADX_BDX: - /* 0 ∘ (Y - B_y) * B_dx * A_dy - (Y - A_y) * A_dx * B_dy */ - if ((adx ^ bdx) < 0) { - return adx; - } else if (a->line.p1.y == b->line.p1.y) { /* common origin */ - cairo_int64_t adx_bdy, bdx_ady; - - /* ∴ A_dx * B_dy ∘ B_dx * A_dy */ - - adx_bdy = _cairo_int32x32_64_mul (adx, bdy); - bdx_ady = _cairo_int32x32_64_mul (bdx, ady); - - return _cairo_int64_cmp (adx_bdy, bdx_ady); - } else - return _cairo_int128_cmp (A, B); - case HAVE_DX_ADX: - /* A_dy * (A_x - B_x) ∘ - (Y - A_y) * A_dx */ - if ((-adx ^ dx) < 0) { - return dx; - } else { - cairo_int64_t ady_dx, dy_adx; - - ady_dx = _cairo_int32x32_64_mul (ady, dx); - dy_adx = _cairo_int32x32_64_mul (a->line.p1.y - y, adx); - - return _cairo_int64_cmp (ady_dx, dy_adx); - } - case HAVE_DX_BDX: - /* B_dy * (A_x - B_x) ∘ (Y - B_y) * B_dx */ - if ((bdx ^ dx) < 0) { - return dx; - } else { - cairo_int64_t bdy_dx, dy_bdx; - - bdy_dx = _cairo_int32x32_64_mul (bdy, dx); - dy_bdx = _cairo_int32x32_64_mul (y - b->line.p1.y, bdx); - - return _cairo_int64_cmp (bdy_dx, dy_bdx); - } - case HAVE_ALL: - /* XXX try comparing (a->line.p2.x - b->line.p2.x) et al */ - return _cairo_int128_cmp (L, _cairo_int128_sub (B, A)); - } -#undef B -#undef A -#undef L -} - -/* - * We need to compare the x-coordinate of a line for a particular y wrt to a - * given x, without loss of precision. - * - * The x-coordinate along an edge for a given y is: - * X = A_x + (Y - A_y) * A_dx / A_dy - * - * So the inequality we wish to test is: - * A_x + (Y - A_y) * A_dx / A_dy ∘ X - * where ∘ is our inequality operator. - * - * By construction, we know that A_dy (and (Y - A_y)) are - * all positive, so we can rearrange it thus without causing a sign change: - * (Y - A_y) * A_dx ∘ (X - A_x) * A_dy - * - * Given the assumption that all the deltas fit within 32 bits, we can compute - * this comparison directly using 64 bit arithmetic. - * - * See the similar discussion for _slope_compare() and - * edges_compare_x_for_y_general(). - */ -static int -edge_compare_for_y_against_x (const cairo_edge_t *a, - int32_t y, - int32_t x) -{ - int32_t adx, ady; - int32_t dx, dy; - cairo_int64_t L, R; - - if (a->line.p1.x <= a->line.p2.x) { - if (x < a->line.p1.x) - return 1; - if (x > a->line.p2.x) - return -1; - } else { - if (x < a->line.p2.x) - return 1; - if (x > a->line.p1.x) - return -1; - } - - adx = a->line.p2.x - a->line.p1.x; - dx = x - a->line.p1.x; - - if (adx == 0) - return -dx; - if (dx == 0 || (adx ^ dx) < 0) - return adx; - - dy = y - a->line.p1.y; - ady = a->line.p2.y - a->line.p1.y; - - L = _cairo_int32x32_64_mul (dy, adx); - R = _cairo_int32x32_64_mul (dx, ady); - - return _cairo_int64_cmp (L, R); -} - -static int -edges_compare_x_for_y (const cairo_edge_t *a, - const cairo_edge_t *b, - int32_t y) -{ - /* If the sweep-line is currently on an end-point of a line, - * then we know its precise x value (and considering that we often need to - * compare events at end-points, this happens frequently enough to warrant - * special casing). - */ - enum { - HAVE_NEITHER = 0x0, - HAVE_AX = 0x1, - HAVE_BX = 0x2, - HAVE_BOTH = HAVE_AX | HAVE_BX - } have_ax_bx = HAVE_BOTH; - int32_t ax, bx; - - /* XXX given we have x and dx? */ - - if (y == a->line.p1.y) - ax = a->line.p1.x; - else if (y == a->line.p2.y) - ax = a->line.p2.x; - else - have_ax_bx &= ~HAVE_AX; - - if (y == b->line.p1.y) - bx = b->line.p1.x; - else if (y == b->line.p2.y) - bx = b->line.p2.x; - else - have_ax_bx &= ~HAVE_BX; - - switch (have_ax_bx) { - default: - case HAVE_NEITHER: - return edges_compare_x_for_y_general (a, b, y); - case HAVE_AX: - return -edge_compare_for_y_against_x (b, y, ax); - case HAVE_BX: - return edge_compare_for_y_against_x (a, y, bx); - case HAVE_BOTH: - return ax - bx; - } -} - -static inline int -slope_compare (const edge_t *a, - const edge_t *b) -{ - cairo_int64_t L, R; - int cmp; - - cmp = a->dxdy.quo - b->dxdy.quo; - if (cmp) - return cmp; - - if (a->dxdy.rem == 0) - return -b->dxdy.rem; - if (b->dxdy.rem == 0) - return a->dxdy.rem; - - L = _cairo_int32x32_64_mul (b->dy, a->dxdy.rem); - R = _cairo_int32x32_64_mul (a->dy, b->dxdy.rem); - return _cairo_int64_cmp (L, R); -} - -static inline int -line_equal (const cairo_line_t *a, const cairo_line_t *b) -{ - return a->p1.x == b->p1.x && a->p1.y == b->p1.y && - a->p2.x == b->p2.x && a->p2.y == b->p2.y; -} - -static inline int -sweep_line_compare_edges (const edge_t *a, - const edge_t *b, - cairo_fixed_t y) -{ - int cmp; - - if (line_equal (&a->edge.line, &b->edge.line)) - return 0; - - cmp = edges_compare_x_for_y (&a->edge, &b->edge, y); - if (cmp) - return cmp; - - return slope_compare (a, b); -} - -static inline cairo_int64_t -det32_64 (int32_t a, int32_t b, - int32_t c, int32_t d) -{ - /* det = a * d - b * c */ - return _cairo_int64_sub (_cairo_int32x32_64_mul (a, d), - _cairo_int32x32_64_mul (b, c)); -} - -static inline cairo_int128_t -det64x32_128 (cairo_int64_t a, int32_t b, - cairo_int64_t c, int32_t d) -{ - /* det = a * d - b * c */ - return _cairo_int128_sub (_cairo_int64x32_128_mul (a, d), - _cairo_int64x32_128_mul (c, b)); -} - -/* Compute the intersection of two lines as defined by two edges. The - * result is provided as a coordinate pair of 128-bit integers. - * - * Returns %CAIRO_BO_STATUS_INTERSECTION if there is an intersection or - * %CAIRO_BO_STATUS_PARALLEL if the two lines are exactly parallel. - */ -static cairo_bool_t -intersect_lines (const edge_t *a, const edge_t *b, - cairo_bo_intersect_point_t *intersection) -{ - cairo_int64_t a_det, b_det; - - /* XXX: We're assuming here that dx and dy will still fit in 32 - * bits. That's not true in general as there could be overflow. We - * should prevent that before the tessellation algorithm begins. - * What we're doing to mitigate this is to perform clamping in - * cairo_bo_tessellate_polygon(). - */ - int32_t dx1 = a->edge.line.p1.x - a->edge.line.p2.x; - int32_t dy1 = a->edge.line.p1.y - a->edge.line.p2.y; - - int32_t dx2 = b->edge.line.p1.x - b->edge.line.p2.x; - int32_t dy2 = b->edge.line.p1.y - b->edge.line.p2.y; - - cairo_int64_t den_det; - cairo_int64_t R; - cairo_quorem64_t qr; - - den_det = det32_64 (dx1, dy1, dx2, dy2); - - /* Q: Can we determine that the lines do not intersect (within range) - * much more cheaply than computing the intersection point i.e. by - * avoiding the division? - * - * X = ax + t * adx = bx + s * bdx; - * Y = ay + t * ady = by + s * bdy; - * ∴ t * (ady*bdx - bdy*adx) = bdx * (by - ay) + bdy * (ax - bx) - * => t * L = R - * - * Therefore we can reject any intersection (under the criteria for - * valid intersection events) if: - * L^R < 0 => t < 0, or - * L<R => t > 1 - * - * (where top/bottom must at least extend to the line endpoints). - * - * A similar substitution can be performed for s, yielding: - * s * (ady*bdx - bdy*adx) = ady * (ax - bx) - adx * (ay - by) - */ - R = det32_64 (dx2, dy2, - b->edge.line.p1.x - a->edge.line.p1.x, - b->edge.line.p1.y - a->edge.line.p1.y); - if (_cairo_int64_negative (den_det)) { - if (_cairo_int64_ge (den_det, R)) - return FALSE; - } else { - if (_cairo_int64_le (den_det, R)) - return FALSE; - } - - R = det32_64 (dy1, dx1, - a->edge.line.p1.y - b->edge.line.p1.y, - a->edge.line.p1.x - b->edge.line.p1.x); - if (_cairo_int64_negative (den_det)) { - if (_cairo_int64_ge (den_det, R)) - return FALSE; - } else { - if (_cairo_int64_le (den_det, R)) - return FALSE; - } - - /* We now know that the two lines should intersect within range. */ - - a_det = det32_64 (a->edge.line.p1.x, a->edge.line.p1.y, - a->edge.line.p2.x, a->edge.line.p2.y); - b_det = det32_64 (b->edge.line.p1.x, b->edge.line.p1.y, - b->edge.line.p2.x, b->edge.line.p2.y); - - /* x = det (a_det, dx1, b_det, dx2) / den_det */ - qr = _cairo_int_96by64_32x64_divrem (det64x32_128 (a_det, dx1, - b_det, dx2), - den_det); - if (_cairo_int64_eq (qr.rem, den_det)) - return FALSE; -#if 0 - intersection->x.exactness = _cairo_int64_is_zero (qr.rem) ? EXACT : INEXACT; -#else - intersection->x.exactness = EXACT; - if (! _cairo_int64_is_zero (qr.rem)) { - if (_cairo_int64_negative (den_det) ^ _cairo_int64_negative (qr.rem)) - qr.rem = _cairo_int64_negate (qr.rem); - qr.rem = _cairo_int64_mul (qr.rem, _cairo_int32_to_int64 (2)); - if (_cairo_int64_ge (qr.rem, den_det)) { - qr.quo = _cairo_int64_add (qr.quo, - _cairo_int32_to_int64 (_cairo_int64_negative (qr.quo) ? -1 : 1)); - } else - intersection->x.exactness = INEXACT; - } -#endif - intersection->x.ordinate = _cairo_int64_to_int32 (qr.quo); - - /* y = det (a_det, dy1, b_det, dy2) / den_det */ - qr = _cairo_int_96by64_32x64_divrem (det64x32_128 (a_det, dy1, - b_det, dy2), - den_det); - if (_cairo_int64_eq (qr.rem, den_det)) - return FALSE; -#if 0 - intersection->y.exactness = _cairo_int64_is_zero (qr.rem) ? EXACT : INEXACT; -#else - intersection->y.exactness = EXACT; - if (! _cairo_int64_is_zero (qr.rem)) { - /* compute ceiling away from zero */ - qr.quo = _cairo_int64_add (qr.quo, - _cairo_int32_to_int64 (_cairo_int64_negative (qr.quo) ? -1 : 1)); - intersection->y.exactness = INEXACT; - } -#endif - intersection->y.ordinate = _cairo_int64_to_int32 (qr.quo); - - return TRUE; -} - -static int -bo_intersect_ordinate_32_compare (int32_t a, int32_t b, int exactness) -{ - int cmp; - - /* First compare the quotient */ - cmp = a - b; - if (cmp) - return cmp; - - /* With quotient identical, if remainder is 0 then compare equal */ - /* Otherwise, the non-zero remainder makes a > b */ - return -(INEXACT == exactness); -} - -/* Does the given edge contain the given point. The point must already - * be known to be contained within the line determined by the edge, - * (most likely the point results from an intersection of this edge - * with another). - * - * If we had exact arithmetic, then this function would simply be a - * matter of examining whether the y value of the point lies within - * the range of y values of the edge. But since intersection points - * are not exact due to being rounded to the nearest integer within - * the available precision, we must also examine the x value of the - * point. - * - * The definition of "contains" here is that the given intersection - * point will be seen by the sweep line after the start event for the - * given edge and before the stop event for the edge. See the comments - * in the implementation for more details. - */ -static cairo_bool_t -bo_edge_contains_intersect_point (const edge_t *edge, - cairo_bo_intersect_point_t *point) -{ - int cmp_top, cmp_bottom; - - /* XXX: When running the actual algorithm, we don't actually need to - * compare against edge->top at all here, since any intersection above - * top is eliminated early via a slope comparison. We're leaving these - * here for now only for the sake of the quadratic-time intersection - * finder which needs them. - */ - - cmp_top = bo_intersect_ordinate_32_compare (point->y.ordinate, - edge->edge.top, - point->y.exactness); - if (cmp_top < 0) - return FALSE; - - cmp_bottom = bo_intersect_ordinate_32_compare (point->y.ordinate, - edge->edge.bottom, - point->y.exactness); - if (cmp_bottom > 0) - return FALSE; - - if (cmp_top > 0 && cmp_bottom < 0) - return TRUE; - - /* At this stage, the point lies on the same y value as either - * edge->top or edge->bottom, so we have to examine the x value in - * order to properly determine containment. */ - - /* If the y value of the point is the same as the y value of the - * top of the edge, then the x value of the point must be greater - * to be considered as inside the edge. Similarly, if the y value - * of the point is the same as the y value of the bottom of the - * edge, then the x value of the point must be less to be - * considered as inside. */ - - if (cmp_top == 0) { - cairo_fixed_t top_x; - - top_x = line_compute_intersection_x_for_y (&edge->edge.line, - edge->edge.top); - return bo_intersect_ordinate_32_compare (top_x, point->x.ordinate, point->x.exactness) < 0; - } else { /* cmp_bottom == 0 */ - cairo_fixed_t bot_x; - - bot_x = line_compute_intersection_x_for_y (&edge->edge.line, - edge->edge.bottom); - return bo_intersect_ordinate_32_compare (point->x.ordinate, bot_x, point->x.exactness) < 0; - } -} - -static cairo_bool_t -edge_intersect (const edge_t *a, - const edge_t *b, - cairo_point_t *intersection) -{ - cairo_bo_intersect_point_t quorem; - - if (! intersect_lines (a, b, &quorem)) - return FALSE; - - if (a->edge.top != a->edge.line.p1.y || a->edge.bottom != a->edge.line.p2.y) { - if (! bo_edge_contains_intersect_point (a, &quorem)) - return FALSE; - } - - if (b->edge.top != b->edge.line.p1.y || b->edge.bottom != b->edge.line.p2.y) { - if (! bo_edge_contains_intersect_point (b, &quorem)) - return FALSE; - } - - /* Now that we've correctly compared the intersection point and - * determined that it lies within the edge, then we know that we - * no longer need any more bits of storage for the intersection - * than we do for our edge coordinates. We also no longer need the - * remainder from the division. */ - intersection->x = quorem.x.ordinate; - intersection->y = quorem.y.ordinate; - - return TRUE; -} - -static inline int -event_compare (const event_t *a, const event_t *b) -{ - return a->y - b->y; -} - -static void -pqueue_init (pqueue_t *pq) -{ - pq->max_size = ARRAY_LENGTH (pq->elements_embedded); - pq->size = 0; - - pq->elements = pq->elements_embedded; -} - -static void -pqueue_fini (pqueue_t *pq) -{ - if (pq->elements != pq->elements_embedded) - free (pq->elements); -} - -static cairo_bool_t -pqueue_grow (pqueue_t *pq) -{ - event_t **new_elements; - pq->max_size *= 2; - - if (pq->elements == pq->elements_embedded) { - new_elements = _cairo_malloc_ab (pq->max_size, - sizeof (event_t *)); - if (unlikely (new_elements == NULL)) - return FALSE; - - memcpy (new_elements, pq->elements_embedded, - sizeof (pq->elements_embedded)); - } else { - new_elements = _cairo_realloc_ab (pq->elements, - pq->max_size, - sizeof (event_t *)); - if (unlikely (new_elements == NULL)) - return FALSE; - } - - pq->elements = new_elements; - return TRUE; -} - -static inline void -pqueue_push (sweep_line_t *sweep_line, event_t *event) -{ - event_t **elements; - int i, parent; - - if (unlikely (sweep_line->queue.pq.size + 1 == sweep_line->queue.pq.max_size)) { - if (unlikely (! pqueue_grow (&sweep_line->queue.pq))) { - longjmp (sweep_line->unwind, - _cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - } - - elements = sweep_line->queue.pq.elements; - for (i = ++sweep_line->queue.pq.size; - i != PQ_FIRST_ENTRY && - event_compare (event, - elements[parent = PQ_PARENT_INDEX (i)]) < 0; - i = parent) - { - elements[i] = elements[parent]; - } - - elements[i] = event; -} - -static inline void -pqueue_pop (pqueue_t *pq) -{ - event_t **elements = pq->elements; - event_t *tail; - int child, i; - - tail = elements[pq->size--]; - if (pq->size == 0) { - elements[PQ_FIRST_ENTRY] = NULL; - return; - } - - for (i = PQ_FIRST_ENTRY; - (child = PQ_LEFT_CHILD_INDEX (i)) <= pq->size; - i = child) - { - if (child != pq->size && - event_compare (elements[child+1], - elements[child]) < 0) - { - child++; - } - - if (event_compare (elements[child], tail) >= 0) - break; - - elements[i] = elements[child]; - } - elements[i] = tail; -} - -static inline void -event_insert (sweep_line_t *sweep_line, - event_type_t type, - edge_t *e1, - edge_t *e2, - cairo_fixed_t y) -{ - queue_event_t *event; - - event = _cairo_freepool_alloc (&sweep_line->queue.pool); - if (unlikely (event == NULL)) { - longjmp (sweep_line->unwind, - _cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - event->y = y; - event->type = type; - event->e1 = e1; - event->e2 = e2; - - pqueue_push (sweep_line, (event_t *) event); -} - -static void -event_delete (sweep_line_t *sweep_line, - event_t *event) -{ - _cairo_freepool_free (&sweep_line->queue.pool, event); -} - -static inline event_t * -event_next (sweep_line_t *sweep_line) -{ - event_t *event, *cmp; - - event = sweep_line->queue.pq.elements[PQ_FIRST_ENTRY]; - cmp = *sweep_line->queue.start_events; - if (event == NULL || - (cmp != NULL && event_compare (cmp, event) < 0)) - { - event = cmp; - sweep_line->queue.start_events++; - } - else - { - pqueue_pop (&sweep_line->queue.pq); - } - - return event; -} - -CAIRO_COMBSORT_DECLARE (start_event_sort, event_t *, event_compare) - -static inline void -event_insert_stop (sweep_line_t *sweep_line, - edge_t *edge) -{ - event_insert (sweep_line, - EVENT_TYPE_STOP, - edge, NULL, - edge->edge.bottom); -} - -static inline void -event_insert_if_intersect_below_current_y (sweep_line_t *sweep_line, - edge_t *left, - edge_t *right) -{ - cairo_point_t intersection; - - /* start points intersect */ - if (left->edge.line.p1.x == right->edge.line.p1.x && - left->edge.line.p1.y == right->edge.line.p1.y) - { - return; - } - - /* end points intersect, process DELETE events first */ - if (left->edge.line.p2.x == right->edge.line.p2.x && - left->edge.line.p2.y == right->edge.line.p2.y) - { - return; - } - - if (slope_compare (left, right) <= 0) - return; - - if (! edge_intersect (left, right, &intersection)) - return; - - event_insert (sweep_line, - EVENT_TYPE_INTERSECTION, - left, right, - intersection.y); -} - -static inline edge_t * -link_to_edge (cairo_list_t *link) -{ - return (edge_t *) link; -} - -static void -sweep_line_insert (sweep_line_t *sweep_line, - edge_t *edge) -{ - cairo_list_t *pos; - cairo_fixed_t y = sweep_line->current_subrow; - - pos = sweep_line->insert_cursor; - if (pos == &sweep_line->active) - pos = sweep_line->active.next; - if (pos != &sweep_line->active) { - int cmp; - - cmp = sweep_line_compare_edges (link_to_edge (pos), - edge, - y); - if (cmp < 0) { - while (pos->next != &sweep_line->active && - sweep_line_compare_edges (link_to_edge (pos->next), - edge, - y) < 0) - { - pos = pos->next; - } - } else if (cmp > 0) { - do { - pos = pos->prev; - } while (pos != &sweep_line->active && - sweep_line_compare_edges (link_to_edge (pos), - edge, - y) > 0); - } - } - cairo_list_add (&edge->link, pos); - sweep_line->insert_cursor = &edge->link; -} - -inline static void -coverage_rewind (struct coverage *cells) -{ - cells->cursor = &cells->head; -} - -static void -coverage_init (struct coverage *cells) -{ - _cairo_freepool_init (&cells->pool, - sizeof (struct cell)); - cells->head.prev = NULL; - cells->head.next = &cells->tail; - cells->head.x = INT_MIN; - cells->tail.prev = &cells->head; - cells->tail.next = NULL; - cells->tail.x = INT_MAX; - cells->count = 0; - coverage_rewind (cells); -} - -static void -coverage_fini (struct coverage *cells) -{ - _cairo_freepool_fini (&cells->pool); -} - -inline static void -coverage_reset (struct coverage *cells) -{ - cells->head.next = &cells->tail; - cells->tail.prev = &cells->head; - cells->count = 0; - _cairo_freepool_reset (&cells->pool); - coverage_rewind (cells); -} - -static struct cell * -coverage_alloc (sweep_line_t *sweep_line, - struct cell *tail, - int x) -{ - struct cell *cell; - - cell = _cairo_freepool_alloc (&sweep_line->coverage.pool); - if (unlikely (NULL == cell)) { - longjmp (sweep_line->unwind, - _cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - tail->prev->next = cell; - cell->prev = tail->prev; - cell->next = tail; - tail->prev = cell; - cell->x = x; - cell->uncovered_area = 0; - cell->covered_height = 0; - sweep_line->coverage.count++; - return cell; -} - -inline static struct cell * -coverage_find (sweep_line_t *sweep_line, int x) -{ - struct cell *cell; - - cell = sweep_line->coverage.cursor; - if (unlikely (cell->x > x)) { - do { - if (cell->prev->x < x) - break; - cell = cell->prev; - } while (TRUE); - } else { - if (cell->x == x) - return cell; - - do { - UNROLL3({ - cell = cell->next; - if (cell->x >= x) - break; - }); - } while (TRUE); - } - - if (cell->x != x) - cell = coverage_alloc (sweep_line, cell, x); - - return sweep_line->coverage.cursor = cell; -} - -static void -coverage_render_cells (sweep_line_t *sweep_line, - cairo_fixed_t left, cairo_fixed_t right, - cairo_fixed_t y1, cairo_fixed_t y2, - int sign) -{ - int fx1, fx2; - int ix1, ix2; - int dx, dy; - - /* Orient the edge left-to-right. */ - dx = right - left; - if (dx >= 0) { - ix1 = _cairo_fixed_integer_part (left); - fx1 = _cairo_fixed_fractional_part (left); - - ix2 = _cairo_fixed_integer_part (right); - fx2 = _cairo_fixed_fractional_part (right); - - dy = y2 - y1; - } else { - ix1 = _cairo_fixed_integer_part (right); - fx1 = _cairo_fixed_fractional_part (right); - - ix2 = _cairo_fixed_integer_part (left); - fx2 = _cairo_fixed_fractional_part (left); - - dx = -dx; - sign = -sign; - dy = y1 - y2; - y1 = y2 - dy; - y2 = y1 + dy; - } - - /* Add coverage for all pixels [ix1,ix2] on this row crossed - * by the edge. */ - { - struct quorem y = floored_divrem ((STEP_X - fx1)*dy, dx); - struct cell *cell; - - cell = sweep_line->coverage.cursor; - if (cell->x != ix1) { - if (unlikely (cell->x > ix1)) { - do { - if (cell->prev->x < ix1) - break; - cell = cell->prev; - } while (TRUE); - } else do { - UNROLL3({ - if (cell->x >= ix1) - break; - cell = cell->next; - }); - } while (TRUE); - - if (cell->x != ix1) - cell = coverage_alloc (sweep_line, cell, ix1); - } - - cell->uncovered_area += sign * y.quo * (STEP_X + fx1); - cell->covered_height += sign * y.quo; - y.quo += y1; - - cell = cell->next; - if (cell->x != ++ix1) - cell = coverage_alloc (sweep_line, cell, ix1); - if (ix1 < ix2) { - struct quorem dydx_full = floored_divrem (STEP_X*dy, dx); - - do { - cairo_fixed_t y_skip = dydx_full.quo; - y.rem += dydx_full.rem; - if (y.rem >= dx) { - ++y_skip; - y.rem -= dx; - } - - y.quo += y_skip; - - y_skip *= sign; - cell->covered_height += y_skip; - cell->uncovered_area += y_skip*STEP_X; - - cell = cell->next; - if (cell->x != ++ix1) - cell = coverage_alloc (sweep_line, cell, ix1); - } while (ix1 != ix2); - } - cell->uncovered_area += sign*(y2 - y.quo)*fx2; - cell->covered_height += sign*(y2 - y.quo); - sweep_line->coverage.cursor = cell; - } -} - -inline static void -full_inc_edge (edge_t *edge) -{ - edge->x.quo += edge->dxdy_full.quo; - edge->x.rem += edge->dxdy_full.rem; - if (edge->x.rem >= 0) { - ++edge->x.quo; - edge->x.rem -= edge->dy; - } -} - -static void -full_add_edge (sweep_line_t *sweep_line, edge_t *edge, int sign) -{ - struct cell *cell; - cairo_fixed_t x1, x2; - int ix1, ix2; - int frac; - - edge->current_sign = sign; - - ix1 = _cairo_fixed_integer_part (edge->x.quo); - - if (edge->vertical) { - frac = _cairo_fixed_fractional_part (edge->x.quo); - cell = coverage_find (sweep_line, ix1); - cell->covered_height += sign * STEP_Y; - cell->uncovered_area += sign * 2 * frac * STEP_Y; - return; - } - - x1 = edge->x.quo; - full_inc_edge (edge); - x2 = edge->x.quo; - - ix2 = _cairo_fixed_integer_part (edge->x.quo); - - /* Edge is entirely within a column? */ - if (likely (ix1 == ix2)) { - frac = _cairo_fixed_fractional_part (x1) + - _cairo_fixed_fractional_part (x2); - cell = coverage_find (sweep_line, ix1); - cell->covered_height += sign * STEP_Y; - cell->uncovered_area += sign * frac * STEP_Y; - return; - } - - coverage_render_cells (sweep_line, x1, x2, 0, STEP_Y, sign); -} - -static void -full_nonzero (sweep_line_t *sweep_line) -{ - cairo_list_t *pos; - - sweep_line->is_vertical = TRUE; - pos = sweep_line->active.next; - do { - edge_t *left = link_to_edge (pos), *right; - int winding = left->edge.dir; - - sweep_line->is_vertical &= left->vertical; - - pos = left->link.next; - do { - if (unlikely (pos == &sweep_line->active)) { - full_add_edge (sweep_line, left, +1); - return; - } - - right = link_to_edge (pos); - pos = pos->next; - sweep_line->is_vertical &= right->vertical; - - winding += right->edge.dir; - if (0 == winding) { - if (pos == &sweep_line->active || - link_to_edge (pos)->x.quo != right->x.quo) - { - break; - } - } - - if (! right->vertical) - full_inc_edge (right); - } while (TRUE); - - full_add_edge (sweep_line, left, +1); - full_add_edge (sweep_line, right, -1); - } while (pos != &sweep_line->active); -} - -static void -full_evenodd (sweep_line_t *sweep_line) -{ - cairo_list_t *pos; - - sweep_line->is_vertical = TRUE; - pos = sweep_line->active.next; - do { - edge_t *left = link_to_edge (pos), *right; - int winding = 0; - - sweep_line->is_vertical &= left->vertical; - - pos = left->link.next; - do { - if (pos == &sweep_line->active) { - full_add_edge (sweep_line, left, +1); - return; - } - - right = link_to_edge (pos); - pos = pos->next; - sweep_line->is_vertical &= right->vertical; - - if (++winding & 1) { - if (pos == &sweep_line->active || - link_to_edge (pos)->x.quo != right->x.quo) - { - break; - } - } - - if (! right->vertical) - full_inc_edge (right); - } while (TRUE); - - full_add_edge (sweep_line, left, +1); - full_add_edge (sweep_line, right, -1); - } while (pos != &sweep_line->active); -} - -static void -render_rows (cairo_botor_scan_converter_t *self, - sweep_line_t *sweep_line, - int y, int height, - cairo_span_renderer_t *renderer) -{ - cairo_half_open_span_t spans_stack[CAIRO_STACK_ARRAY_LENGTH (cairo_half_open_span_t)]; - cairo_half_open_span_t *spans = spans_stack; - struct cell *cell; - int prev_x, cover; - int num_spans; - cairo_status_t status; - - if (unlikely (sweep_line->coverage.count == 0)) { - status = renderer->render_rows (renderer, y, height, NULL, 0); - if (unlikely (status)) - longjmp (sweep_line->unwind, status); - return; - } - - /* Allocate enough spans for the row. */ - - num_spans = 2*sweep_line->coverage.count+2; - if (unlikely (num_spans > ARRAY_LENGTH (spans_stack))) { - spans = _cairo_malloc_ab (num_spans, sizeof (cairo_half_open_span_t)); - if (unlikely (spans == NULL)) { - longjmp (sweep_line->unwind, - _cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - } - - /* Form the spans from the coverage and areas. */ - num_spans = 0; - prev_x = self->xmin; - cover = 0; - cell = sweep_line->coverage.head.next; - do { - int x = cell->x; - int area; - - if (x > prev_x) { - spans[num_spans].x = prev_x; - spans[num_spans].inverse = 0; - spans[num_spans].coverage = AREA_TO_ALPHA (cover); - ++num_spans; - } - - cover += cell->covered_height*STEP_X*2; - area = cover - cell->uncovered_area; - - spans[num_spans].x = x; - spans[num_spans].coverage = AREA_TO_ALPHA (area); - ++num_spans; - - prev_x = x + 1; - } while ((cell = cell->next) != &sweep_line->coverage.tail); - - if (prev_x <= self->xmax) { - spans[num_spans].x = prev_x; - spans[num_spans].inverse = 0; - spans[num_spans].coverage = AREA_TO_ALPHA (cover); - ++num_spans; - } - - if (cover && prev_x < self->xmax) { - spans[num_spans].x = self->xmax; - spans[num_spans].inverse = 1; - spans[num_spans].coverage = 0; - ++num_spans; - } - - status = renderer->render_rows (renderer, y, height, spans, num_spans); - - if (unlikely (spans != spans_stack)) - free (spans); - - coverage_reset (&sweep_line->coverage); - - if (unlikely (status)) - longjmp (sweep_line->unwind, status); -} - -static void -full_repeat (sweep_line_t *sweep) -{ - edge_t *edge; - - cairo_list_foreach_entry (edge, edge_t, &sweep->active, link) { - if (edge->current_sign) - full_add_edge (sweep, edge, edge->current_sign); - else if (! edge->vertical) - full_inc_edge (edge); - } -} - -static void -full_reset (sweep_line_t *sweep) -{ - edge_t *edge; - - cairo_list_foreach_entry (edge, edge_t, &sweep->active, link) - edge->current_sign = 0; -} - -static void -full_step (cairo_botor_scan_converter_t *self, - sweep_line_t *sweep_line, - cairo_fixed_t row, - cairo_span_renderer_t *renderer) -{ - int top, bottom; - - top = _cairo_fixed_integer_part (sweep_line->current_row); - bottom = _cairo_fixed_integer_part (row); - if (cairo_list_is_empty (&sweep_line->active)) { - cairo_status_t status; - - status = renderer->render_rows (renderer, top, bottom - top, NULL, 0); - if (unlikely (status)) - longjmp (sweep_line->unwind, status); - - return; - } - - if (self->fill_rule == CAIRO_FILL_RULE_WINDING) - full_nonzero (sweep_line); - else - full_evenodd (sweep_line); - - if (sweep_line->is_vertical || bottom == top + 1) { - render_rows (self, sweep_line, top, bottom - top, renderer); - full_reset (sweep_line); - return; - } - - render_rows (self, sweep_line, top++, 1, renderer); - do { - full_repeat (sweep_line); - render_rows (self, sweep_line, top, 1, renderer); - } while (++top != bottom); - - full_reset (sweep_line); -} - -cairo_always_inline static void -sub_inc_edge (edge_t *edge, - cairo_fixed_t height) -{ - if (height == 1) { - edge->x.quo += edge->dxdy.quo; - edge->x.rem += edge->dxdy.rem; - if (edge->x.rem >= 0) { - ++edge->x.quo; - edge->x.rem -= edge->dy; - } - } else { - edge->x.quo += height * edge->dxdy.quo; - edge->x.rem += height * edge->dxdy.rem; - if (edge->x.rem >= 0) { - int carry = edge->x.rem / edge->dy + 1; - edge->x.quo += carry; - edge->x.rem -= carry * edge->dy; - } - } -} - -static void -sub_add_run (sweep_line_t *sweep_line, edge_t *edge, int y, int sign) -{ - struct run *run; - - run = _cairo_freepool_alloc (&sweep_line->runs); - if (unlikely (run == NULL)) - longjmp (sweep_line->unwind, _cairo_error (CAIRO_STATUS_NO_MEMORY)); - - run->y = y; - run->sign = sign; - run->next = edge->runs; - edge->runs = run; - - edge->current_sign = sign; -} - -inline static cairo_bool_t -edges_coincident (edge_t *left, edge_t *right, cairo_fixed_t y) -{ - /* XXX is compare_x_for_y() worth executing during sub steps? */ - return line_equal (&left->edge.line, &right->edge.line); - //edges_compare_x_for_y (&left->edge, &right->edge, y) >= 0; -} - -static void -sub_nonzero (sweep_line_t *sweep_line) -{ - cairo_fixed_t y = sweep_line->current_subrow; - cairo_fixed_t fy = _cairo_fixed_fractional_part (y); - cairo_list_t *pos; - - pos = sweep_line->active.next; - do { - edge_t *left = link_to_edge (pos), *right; - int winding = left->edge.dir; - - pos = left->link.next; - do { - if (unlikely (pos == &sweep_line->active)) { - if (left->current_sign != +1) - sub_add_run (sweep_line, left, fy, +1); - return; - } - - right = link_to_edge (pos); - pos = pos->next; - - winding += right->edge.dir; - if (0 == winding) { - if (pos == &sweep_line->active || - ! edges_coincident (right, link_to_edge (pos), y)) - { - break; - } - } - - if (right->current_sign) - sub_add_run (sweep_line, right, fy, 0); - } while (TRUE); - - if (left->current_sign != +1) - sub_add_run (sweep_line, left, fy, +1); - if (right->current_sign != -1) - sub_add_run (sweep_line, right, fy, -1); - } while (pos != &sweep_line->active); -} - -static void -sub_evenodd (sweep_line_t *sweep_line) -{ - cairo_fixed_t y = sweep_line->current_subrow; - cairo_fixed_t fy = _cairo_fixed_fractional_part (y); - cairo_list_t *pos; - - pos = sweep_line->active.next; - do { - edge_t *left = link_to_edge (pos), *right; - int winding = 0; - - pos = left->link.next; - do { - if (unlikely (pos == &sweep_line->active)) { - if (left->current_sign != +1) - sub_add_run (sweep_line, left, fy, +1); - return; - } - - right = link_to_edge (pos); - pos = pos->next; - - if (++winding & 1) { - if (pos == &sweep_line->active || - ! edges_coincident (right, link_to_edge (pos), y)) - { - break; - } - } - - if (right->current_sign) - sub_add_run (sweep_line, right, fy, 0); - } while (TRUE); - - if (left->current_sign != +1) - sub_add_run (sweep_line, left, fy, +1); - if (right->current_sign != -1) - sub_add_run (sweep_line, right, fy, -1); - } while (pos != &sweep_line->active); -} - -cairo_always_inline static void -sub_step (cairo_botor_scan_converter_t *self, - sweep_line_t *sweep_line) -{ - if (cairo_list_is_empty (&sweep_line->active)) - return; - - if (self->fill_rule == CAIRO_FILL_RULE_WINDING) - sub_nonzero (sweep_line); - else - sub_evenodd (sweep_line); -} - -static void -coverage_render_runs (sweep_line_t *sweep, edge_t *edge, - cairo_fixed_t y1, cairo_fixed_t y2) -{ - struct run tail; - struct run *run = &tail; - - tail.next = NULL; - tail.y = y2; - - /* Order the runs top->bottom */ - while (edge->runs) { - struct run *r; - - r = edge->runs; - edge->runs = r->next; - r->next = run; - run = r; - } - - if (run->y > y1) - sub_inc_edge (edge, run->y - y1); - - do { - cairo_fixed_t x1, x2; - - y1 = run->y; - y2 = run->next->y; - - x1 = edge->x.quo; - if (y2 - y1 == STEP_Y) - full_inc_edge (edge); - else - sub_inc_edge (edge, y2 - y1); - x2 = edge->x.quo; - - if (run->sign) { - int ix1, ix2; - - ix1 = _cairo_fixed_integer_part (x1); - ix2 = _cairo_fixed_integer_part (x2); - - /* Edge is entirely within a column? */ - if (likely (ix1 == ix2)) { - struct cell *cell; - int frac; - - frac = _cairo_fixed_fractional_part (x1) + - _cairo_fixed_fractional_part (x2); - cell = coverage_find (sweep, ix1); - cell->covered_height += run->sign * (y2 - y1); - cell->uncovered_area += run->sign * (y2 - y1) * frac; - } else { - coverage_render_cells (sweep, x1, x2, y1, y2, run->sign); - } - } - - run = run->next; - } while (run->next != NULL); -} - -static void -coverage_render_vertical_runs (sweep_line_t *sweep, edge_t *edge, cairo_fixed_t y2) -{ - struct cell *cell; - struct run *run; - int height = 0; - - for (run = edge->runs; run != NULL; run = run->next) { - if (run->sign) - height += run->sign * (y2 - run->y); - y2 = run->y; - } - - cell = coverage_find (sweep, _cairo_fixed_integer_part (edge->x.quo)); - cell->covered_height += height; - cell->uncovered_area += 2 * _cairo_fixed_fractional_part (edge->x.quo) * height; -} - -cairo_always_inline static void -sub_emit (cairo_botor_scan_converter_t *self, - sweep_line_t *sweep, - cairo_span_renderer_t *renderer) -{ - edge_t *edge; - - sub_step (self, sweep); - - /* convert the runs into coverages */ - - cairo_list_foreach_entry (edge, edge_t, &sweep->active, link) { - if (edge->runs == NULL) { - if (! edge->vertical) { - if (edge->flags & START) { - sub_inc_edge (edge, - STEP_Y - _cairo_fixed_fractional_part (edge->edge.top)); - edge->flags &= ~START; - } else - full_inc_edge (edge); - } - } else { - if (edge->vertical) { - coverage_render_vertical_runs (sweep, edge, STEP_Y); - } else { - int y1 = 0; - if (edge->flags & START) { - y1 = _cairo_fixed_fractional_part (edge->edge.top); - edge->flags &= ~START; - } - coverage_render_runs (sweep, edge, y1, STEP_Y); - } - } - edge->current_sign = 0; - edge->runs = NULL; - } - - cairo_list_foreach_entry (edge, edge_t, &sweep->stopped, link) { - int y2 = _cairo_fixed_fractional_part (edge->edge.bottom); - if (edge->vertical) { - coverage_render_vertical_runs (sweep, edge, y2); - } else { - int y1 = 0; - if (edge->flags & START) - y1 = _cairo_fixed_fractional_part (edge->edge.top); - coverage_render_runs (sweep, edge, y1, y2); - } - } - cairo_list_init (&sweep->stopped); - - _cairo_freepool_reset (&sweep->runs); - - render_rows (self, sweep, - _cairo_fixed_integer_part (sweep->current_row), 1, - renderer); -} - -static void -sweep_line_init (sweep_line_t *sweep_line, - event_t **start_events, - int num_events) -{ - cairo_list_init (&sweep_line->active); - cairo_list_init (&sweep_line->stopped); - sweep_line->insert_cursor = &sweep_line->active; - - sweep_line->current_row = INT32_MIN; - sweep_line->current_subrow = INT32_MIN; - - coverage_init (&sweep_line->coverage); - _cairo_freepool_init (&sweep_line->runs, sizeof (struct run)); - - start_event_sort (start_events, num_events); - start_events[num_events] = NULL; - - sweep_line->queue.start_events = start_events; - - _cairo_freepool_init (&sweep_line->queue.pool, - sizeof (queue_event_t)); - pqueue_init (&sweep_line->queue.pq); - sweep_line->queue.pq.elements[PQ_FIRST_ENTRY] = NULL; -} - -static void -sweep_line_delete (sweep_line_t *sweep_line, - edge_t *edge) -{ - if (sweep_line->insert_cursor == &edge->link) - sweep_line->insert_cursor = edge->link.prev; - - cairo_list_del (&edge->link); - if (edge->runs) - cairo_list_add_tail (&edge->link, &sweep_line->stopped); - edge->flags |= STOP; -} - -static void -sweep_line_swap (sweep_line_t *sweep_line, - edge_t *left, - edge_t *right) -{ - right->link.prev = left->link.prev; - left->link.next = right->link.next; - right->link.next = &left->link; - left->link.prev = &right->link; - left->link.next->prev = &left->link; - right->link.prev->next = &right->link; -} - -static void -sweep_line_fini (sweep_line_t *sweep_line) -{ - pqueue_fini (&sweep_line->queue.pq); - _cairo_freepool_fini (&sweep_line->queue.pool); - coverage_fini (&sweep_line->coverage); - _cairo_freepool_fini (&sweep_line->runs); -} - -static cairo_status_t -botor_generate (cairo_botor_scan_converter_t *self, - event_t **start_events, - cairo_span_renderer_t *renderer) -{ - cairo_status_t status; - sweep_line_t sweep_line; - cairo_fixed_t ybot; - event_t *event; - cairo_list_t *left, *right; - edge_t *e1, *e2; - int bottom; - - sweep_line_init (&sweep_line, start_events, self->num_edges); - if ((status = setjmp (sweep_line.unwind))) - goto unwind; - - ybot = self->extents.p2.y; - sweep_line.current_subrow = self->extents.p1.y; - sweep_line.current_row = _cairo_fixed_floor (self->extents.p1.y); - event = *sweep_line.queue.start_events++; - do { - /* Can we process a full step in one go? */ - if (event->y >= sweep_line.current_row + STEP_Y) { - bottom = _cairo_fixed_floor (event->y); - full_step (self, &sweep_line, bottom, renderer); - sweep_line.current_row = bottom; - sweep_line.current_subrow = bottom; - } - - do { - if (event->y > sweep_line.current_subrow) { - sub_step (self, &sweep_line); - sweep_line.current_subrow = event->y; - } - - do { - /* Update the active list using Bentley-Ottmann */ - switch (event->type) { - case EVENT_TYPE_START: - e1 = ((start_event_t *) event)->edge; - - sweep_line_insert (&sweep_line, e1); - event_insert_stop (&sweep_line, e1); - - left = e1->link.prev; - right = e1->link.next; - - if (left != &sweep_line.active) { - event_insert_if_intersect_below_current_y (&sweep_line, - link_to_edge (left), e1); - } - - if (right != &sweep_line.active) { - event_insert_if_intersect_below_current_y (&sweep_line, - e1, link_to_edge (right)); - } - - break; - - case EVENT_TYPE_STOP: - e1 = ((queue_event_t *) event)->e1; - event_delete (&sweep_line, event); - - left = e1->link.prev; - right = e1->link.next; - - sweep_line_delete (&sweep_line, e1); - - if (left != &sweep_line.active && - right != &sweep_line.active) - { - event_insert_if_intersect_below_current_y (&sweep_line, - link_to_edge (left), - link_to_edge (right)); - } - - break; - - case EVENT_TYPE_INTERSECTION: - e1 = ((queue_event_t *) event)->e1; - e2 = ((queue_event_t *) event)->e2; - - event_delete (&sweep_line, event); - if (e1->flags & STOP) - break; - if (e2->flags & STOP) - break; - - /* skip this intersection if its edges are not adjacent */ - if (&e2->link != e1->link.next) - break; - - left = e1->link.prev; - right = e2->link.next; - - sweep_line_swap (&sweep_line, e1, e2); - - /* after the swap e2 is left of e1 */ - if (left != &sweep_line.active) { - event_insert_if_intersect_below_current_y (&sweep_line, - link_to_edge (left), e2); - } - - if (right != &sweep_line.active) { - event_insert_if_intersect_below_current_y (&sweep_line, - e1, link_to_edge (right)); - } - - break; - } - - event = event_next (&sweep_line); - if (event == NULL) - goto end; - } while (event->y == sweep_line.current_subrow); - } while (event->y < sweep_line.current_row + STEP_Y); - - bottom = sweep_line.current_row + STEP_Y; - sub_emit (self, &sweep_line, renderer); - sweep_line.current_subrow = bottom; - sweep_line.current_row = sweep_line.current_subrow; - } while (TRUE); - - end: - /* flush any partial spans */ - if (sweep_line.current_subrow != sweep_line.current_row) { - sub_emit (self, &sweep_line, renderer); - sweep_line.current_row += STEP_Y; - sweep_line.current_subrow = sweep_line.current_row; - } - /* clear the rest */ - if (sweep_line.current_subrow < ybot) { - bottom = _cairo_fixed_integer_part (sweep_line.current_row); - status = renderer->render_rows (renderer, - bottom, _cairo_fixed_integer_ceil (ybot) - bottom, - NULL, 0); - } - - unwind: - sweep_line_fini (&sweep_line); - - return status; -} - -static cairo_status_t -_cairo_botor_scan_converter_generate (void *converter, - cairo_span_renderer_t *renderer) -{ - cairo_botor_scan_converter_t *self = converter; - start_event_t stack_events[CAIRO_STACK_ARRAY_LENGTH (start_event_t)]; - start_event_t *events; - event_t *stack_event_ptrs[ARRAY_LENGTH (stack_events) + 1]; - event_t **event_ptrs; - struct _cairo_botor_scan_converter_chunk *chunk; - cairo_status_t status; - int num_events; - int i, j; - - num_events = self->num_edges; - if (unlikely (0 == num_events)) { - return renderer->render_rows (renderer, - _cairo_fixed_integer_floor (self->extents.p1.y), - _cairo_fixed_integer_ceil (self->extents.p2.y) - - _cairo_fixed_integer_floor (self->extents.p1.y), - NULL, 0); - } - - events = stack_events; - event_ptrs = stack_event_ptrs; - if (unlikely (num_events >= ARRAY_LENGTH (stack_events))) { - events = _cairo_malloc_ab_plus_c (num_events, - sizeof (start_event_t) + sizeof (event_t *), - sizeof (event_t *)); - if (unlikely (events == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - event_ptrs = (event_t **) (events + num_events); - } - - j = 0; - for (chunk = &self->chunks; chunk != NULL; chunk = chunk->next) { - edge_t *edge; - - edge = chunk->base; - for (i = 0; i < chunk->count; i++) { - event_ptrs[j] = (event_t *) &events[j]; - - events[j].y = edge->edge.top; - events[j].type = EVENT_TYPE_START; - events[j].edge = edge; - - edge++, j++; - } - } - - status = botor_generate (self, event_ptrs, renderer); - - if (events != stack_events) - free (events); - - return status; -} - -static edge_t * -botor_allocate_edge (cairo_botor_scan_converter_t *self) -{ - struct _cairo_botor_scan_converter_chunk *chunk; - - chunk = self->tail; - if (chunk->count == chunk->size) { - int size; - - size = chunk->size * 2; - chunk->next = _cairo_malloc_ab_plus_c (size, - sizeof (edge_t), - sizeof (struct _cairo_botor_scan_converter_chunk)); - if (unlikely (chunk->next == NULL)) - return NULL; - - chunk = chunk->next; - chunk->next = NULL; - chunk->count = 0; - chunk->size = size; - chunk->base = chunk + 1; - self->tail = chunk; - } - - return (edge_t *) chunk->base + chunk->count++; -} - -static cairo_status_t -botor_add_edge (cairo_botor_scan_converter_t *self, - const cairo_edge_t *edge) -{ - edge_t *e; - cairo_fixed_t dx, dy; - - e = botor_allocate_edge (self); - if (unlikely (e == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - cairo_list_init (&e->link); - e->edge = *edge; - - dx = edge->line.p2.x - edge->line.p1.x; - dy = edge->line.p2.y - edge->line.p1.y; - e->dy = dy; - - if (dx == 0) { - e->vertical = TRUE; - e->x.quo = edge->line.p1.x; - e->x.rem = 0; - e->dxdy.quo = 0; - e->dxdy.rem = 0; - e->dxdy_full.quo = 0; - e->dxdy_full.rem = 0; - } else { - e->vertical = FALSE; - e->dxdy = floored_divrem (dx, dy); - if (edge->top == edge->line.p1.y) { - e->x.quo = edge->line.p1.x; - e->x.rem = 0; - } else { - e->x = floored_muldivrem (edge->top - edge->line.p1.y, - dx, dy); - e->x.quo += edge->line.p1.x; - } - - if (_cairo_fixed_integer_part (edge->bottom) - _cairo_fixed_integer_part (edge->top) > 1) { - e->dxdy_full = floored_muldivrem (STEP_Y, dx, dy); - } else { - e->dxdy_full.quo = 0; - e->dxdy_full.rem = 0; - } - } - - e->x.rem = -e->dy; - e->current_sign = 0; - e->runs = NULL; - e->flags = START; - - self->num_edges++; - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_botor_scan_converter_destroy (void *converter) -{ - cairo_botor_scan_converter_t *self = converter; - struct _cairo_botor_scan_converter_chunk *chunk, *next; - - for (chunk = self->chunks.next; chunk != NULL; chunk = next) { - next = chunk->next; - free (chunk); - } -} - -void -_cairo_botor_scan_converter_init (cairo_botor_scan_converter_t *self, - const cairo_box_t *extents, - cairo_fill_rule_t fill_rule) -{ - self->base.destroy = _cairo_botor_scan_converter_destroy; - self->base.generate = _cairo_botor_scan_converter_generate; - - self->extents = *extents; - self->fill_rule = fill_rule; - - self->xmin = _cairo_fixed_integer_floor (extents->p1.x); - self->xmax = _cairo_fixed_integer_ceil (extents->p2.x); - - self->chunks.base = self->buf; - self->chunks.next = NULL; - self->chunks.count = 0; - self->chunks.size = sizeof (self->buf) / sizeof (edge_t); - self->tail = &self->chunks; - - self->num_edges = 0; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-box-inline.h b/source/libs/cairo/cairo-src/src/cairo-box-inline.h deleted file mode 100644 index d6b994127e3a68760abc287fd3b384b9b1100a52..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-box-inline.h +++ /dev/null @@ -1,121 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2010 Andrea Canciani - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * Contributor(s): - * Andrea Canciani <ranma42@gmail.com> - */ - -#ifndef CAIRO_BOX_H -#define CAIRO_BOX_H - -#include "cairo-types-private.h" -#include "cairo-compiler-private.h" -#include "cairo-fixed-private.h" - -static inline void -_cairo_box_set (cairo_box_t *box, - const cairo_point_t *p1, - const cairo_point_t *p2) -{ - box->p1 = *p1; - box->p2 = *p2; -} - -static inline void -_cairo_box_from_integers (cairo_box_t *box, int x, int y, int w, int h) -{ - box->p1.x = _cairo_fixed_from_int (x); - box->p1.y = _cairo_fixed_from_int (y); - box->p2.x = _cairo_fixed_from_int (x + w); - box->p2.y = _cairo_fixed_from_int (y + h); -} - -/* assumes box->p1 is top-left, p2 bottom-right */ -static inline void -_cairo_box_add_point (cairo_box_t *box, - const cairo_point_t *point) -{ - if (point->x < box->p1.x) - box->p1.x = point->x; - else if (point->x > box->p2.x) - box->p2.x = point->x; - - if (point->y < box->p1.y) - box->p1.y = point->y; - else if (point->y > box->p2.y) - box->p2.y = point->y; -} - -static inline void -_cairo_box_add_box (cairo_box_t *box, - const cairo_box_t *add) -{ - if (add->p1.x < box->p1.x) - box->p1.x = add->p1.x; - if (add->p2.x > box->p2.x) - box->p2.x = add->p2.x; - - if (add->p1.y < box->p1.y) - box->p1.y = add->p1.y; - if (add->p2.y > box->p2.y) - box->p2.y = add->p2.y; -} - -/* assumes box->p1 is top-left, p2 bottom-right */ -static inline cairo_bool_t -_cairo_box_contains_point (const cairo_box_t *box, - const cairo_point_t *point) -{ - return box->p1.x <= point->x && point->x <= box->p2.x && - box->p1.y <= point->y && point->y <= box->p2.y; -} - -static inline cairo_bool_t -_cairo_box_is_pixel_aligned (const cairo_box_t *box) -{ -#if CAIRO_FIXED_FRAC_BITS <= 8 && 0 - return ((box->p1.x & CAIRO_FIXED_FRAC_MASK) << 24 | - (box->p1.y & CAIRO_FIXED_FRAC_MASK) << 16 | - (box->p2.x & CAIRO_FIXED_FRAC_MASK) << 8 | - (box->p2.y & CAIRO_FIXED_FRAC_MASK) << 0) == 0; -#else /* GCC on i7 prefers this variant (bizarrely according to the profiler) */ - cairo_fixed_t f; - - f = 0; - f |= box->p1.x & CAIRO_FIXED_FRAC_MASK; - f |= box->p1.y & CAIRO_FIXED_FRAC_MASK; - f |= box->p2.x & CAIRO_FIXED_FRAC_MASK; - f |= box->p2.y & CAIRO_FIXED_FRAC_MASK; - - return f == 0; -#endif -} - -#endif /* CAIRO_BOX_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-boxes-intersect.c b/source/libs/cairo/cairo-src/src/cairo-boxes-intersect.c deleted file mode 100644 index 96ae66334e6a068b22750e3928b697bd0e7c58bd..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-boxes-intersect.c +++ /dev/null @@ -1,690 +0,0 @@ -/* - * Copyright © 2004 Carl Worth - * Copyright © 2006 Red Hat, Inc. - * Copyright © 2009 Chris Wilson - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Carl Worth - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -/* Provide definitions for standalone compilation */ -#include "cairoint.h" - -#include "cairo-boxes-private.h" -#include "cairo-error-private.h" -#include "cairo-combsort-inline.h" -#include "cairo-list-private.h" - -#include <setjmp.h> - -typedef struct _rectangle rectangle_t; -typedef struct _edge edge_t; - -struct _edge { - edge_t *next, *prev; - edge_t *right; - cairo_fixed_t x, top; - int a_or_b; - int dir; -}; - -struct _rectangle { - edge_t left, right; - int32_t top, bottom; -}; - -#define UNROLL3(x) x x x - -/* the parent is always given by index/2 */ -#define PQ_PARENT_INDEX(i) ((i) >> 1) -#define PQ_FIRST_ENTRY 1 - -/* left and right children are index * 2 and (index * 2) +1 respectively */ -#define PQ_LEFT_CHILD_INDEX(i) ((i) << 1) - -typedef struct _pqueue { - int size, max_size; - - rectangle_t **elements; - rectangle_t *elements_embedded[1024]; -} pqueue_t; - -typedef struct _sweep_line { - rectangle_t **rectangles; - pqueue_t pq; - edge_t head, tail; - edge_t *insert_left, *insert_right; - int32_t current_y; - int32_t last_y; - - jmp_buf unwind; -} sweep_line_t; - -#define DEBUG_TRAPS 0 - -#if DEBUG_TRAPS -static void -dump_traps (cairo_traps_t *traps, const char *filename) -{ - FILE *file; - int n; - - if (getenv ("CAIRO_DEBUG_TRAPS") == NULL) - return; - - file = fopen (filename, "a"); - if (file != NULL) { - for (n = 0; n < traps->num_traps; n++) { - fprintf (file, "%d %d L:(%d, %d), (%d, %d) R:(%d, %d), (%d, %d)\n", - traps->traps[n].top, - traps->traps[n].bottom, - traps->traps[n].left.p1.x, - traps->traps[n].left.p1.y, - traps->traps[n].left.p2.x, - traps->traps[n].left.p2.y, - traps->traps[n].right.p1.x, - traps->traps[n].right.p1.y, - traps->traps[n].right.p2.x, - traps->traps[n].right.p2.y); - } - fprintf (file, "\n"); - fclose (file); - } -} -#else -#define dump_traps(traps, filename) -#endif - -static inline int -rectangle_compare_start (const rectangle_t *a, - const rectangle_t *b) -{ - return a->top - b->top; -} - -static inline int -rectangle_compare_stop (const rectangle_t *a, - const rectangle_t *b) -{ - return a->bottom - b->bottom; -} - -static inline void -pqueue_init (pqueue_t *pq) -{ - pq->max_size = ARRAY_LENGTH (pq->elements_embedded); - pq->size = 0; - - pq->elements = pq->elements_embedded; - pq->elements[PQ_FIRST_ENTRY] = NULL; -} - -static inline void -pqueue_fini (pqueue_t *pq) -{ - if (pq->elements != pq->elements_embedded) - free (pq->elements); -} - -static cairo_bool_t -pqueue_grow (pqueue_t *pq) -{ - rectangle_t **new_elements; - pq->max_size *= 2; - - if (pq->elements == pq->elements_embedded) { - new_elements = _cairo_malloc_ab (pq->max_size, - sizeof (rectangle_t *)); - if (unlikely (new_elements == NULL)) - return FALSE; - - memcpy (new_elements, pq->elements_embedded, - sizeof (pq->elements_embedded)); - } else { - new_elements = _cairo_realloc_ab (pq->elements, - pq->max_size, - sizeof (rectangle_t *)); - if (unlikely (new_elements == NULL)) - return FALSE; - } - - pq->elements = new_elements; - return TRUE; -} - -static inline void -pqueue_push (sweep_line_t *sweep, rectangle_t *rectangle) -{ - rectangle_t **elements; - int i, parent; - - if (unlikely (sweep->pq.size + 1 == sweep->pq.max_size)) { - if (unlikely (! pqueue_grow (&sweep->pq))) { - longjmp (sweep->unwind, - _cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - } - - elements = sweep->pq.elements; - for (i = ++sweep->pq.size; - i != PQ_FIRST_ENTRY && - rectangle_compare_stop (rectangle, - elements[parent = PQ_PARENT_INDEX (i)]) < 0; - i = parent) - { - elements[i] = elements[parent]; - } - - elements[i] = rectangle; -} - -static inline void -pqueue_pop (pqueue_t *pq) -{ - rectangle_t **elements = pq->elements; - rectangle_t *tail; - int child, i; - - tail = elements[pq->size--]; - if (pq->size == 0) { - elements[PQ_FIRST_ENTRY] = NULL; - return; - } - - for (i = PQ_FIRST_ENTRY; - (child = PQ_LEFT_CHILD_INDEX (i)) <= pq->size; - i = child) - { - if (child != pq->size && - rectangle_compare_stop (elements[child+1], - elements[child]) < 0) - { - child++; - } - - if (rectangle_compare_stop (elements[child], tail) >= 0) - break; - - elements[i] = elements[child]; - } - elements[i] = tail; -} - -static inline rectangle_t * -rectangle_pop_start (sweep_line_t *sweep_line) -{ - return *sweep_line->rectangles++; -} - -static inline rectangle_t * -rectangle_peek_stop (sweep_line_t *sweep_line) -{ - return sweep_line->pq.elements[PQ_FIRST_ENTRY]; -} - -CAIRO_COMBSORT_DECLARE (_rectangle_sort, - rectangle_t *, - rectangle_compare_start) - -static void -sweep_line_init (sweep_line_t *sweep_line, - rectangle_t **rectangles, - int num_rectangles) -{ - _rectangle_sort (rectangles, num_rectangles); - rectangles[num_rectangles] = NULL; - sweep_line->rectangles = rectangles; - - sweep_line->head.x = INT32_MIN; - sweep_line->head.right = NULL; - sweep_line->head.dir = 0; - sweep_line->head.next = &sweep_line->tail; - sweep_line->tail.x = INT32_MAX; - sweep_line->tail.right = NULL; - sweep_line->tail.dir = 0; - sweep_line->tail.prev = &sweep_line->head; - - sweep_line->insert_left = &sweep_line->tail; - sweep_line->insert_right = &sweep_line->tail; - - sweep_line->current_y = INT32_MIN; - sweep_line->last_y = INT32_MIN; - - pqueue_init (&sweep_line->pq); -} - -static void -sweep_line_fini (sweep_line_t *sweep_line) -{ - pqueue_fini (&sweep_line->pq); -} - -static void -end_box (sweep_line_t *sweep_line, edge_t *left, int32_t bot, cairo_boxes_t *out) -{ - if (likely (left->top < bot)) { - cairo_status_t status; - cairo_box_t box; - - box.p1.x = left->x; - box.p1.y = left->top; - box.p2.x = left->right->x; - box.p2.y = bot; - - status = _cairo_boxes_add (out, CAIRO_ANTIALIAS_DEFAULT, &box); - if (unlikely (status)) - longjmp (sweep_line->unwind, status); - } - - left->right = NULL; -} - -/* Start a new trapezoid at the given top y coordinate, whose edges - * are `edge' and `edge->next'. If `edge' already has a trapezoid, - * then either add it to the traps in `traps', if the trapezoid's - * right edge differs from `edge->next', or do nothing if the new - * trapezoid would be a continuation of the existing one. */ -static inline void -start_or_continue_box (sweep_line_t *sweep_line, - edge_t *left, - edge_t *right, - int top, - cairo_boxes_t *out) -{ - if (left->right == right) - return; - - if (left->right != NULL) { - if (right != NULL && left->right->x == right->x) { - /* continuation on right, so just swap edges */ - left->right = right; - return; - } - - end_box (sweep_line, left, top, out); - } - - if (right != NULL && left->x != right->x) { - left->top = top; - left->right = right; - } -} - -static inline int is_zero(const int *winding) -{ - return winding[0] == 0 || winding[1] == 0; -} - -static inline void -active_edges (sweep_line_t *sweep, cairo_boxes_t *out) -{ - int top = sweep->current_y; - int winding[2] = { 0 }; - edge_t *pos; - - if (sweep->last_y == sweep->current_y) - return; - - pos = sweep->head.next; - if (pos == &sweep->tail) - return; - - do { - edge_t *left, *right; - - left = pos; - do { - winding[left->a_or_b] += left->dir; - if (!is_zero (winding)) - break; - if (left->next == &sweep->tail) - goto out; - - if (unlikely (left->right != NULL)) - end_box (sweep, left, top, out); - - left = left->next; - } while (1); - - right = left->next; - do { - if (unlikely (right->right != NULL)) - end_box (sweep, right, top, out); - - winding[right->a_or_b] += right->dir; - if (is_zero (winding)) { - /* skip co-linear edges */ - if (likely (right->x != right->next->x)) - break; - } - - right = right->next; - } while (TRUE); - - start_or_continue_box (sweep, left, right, top, out); - - pos = right->next; - } while (pos != &sweep->tail); - -out: - sweep->last_y = sweep->current_y; -} - -static inline void -sweep_line_delete_edge (sweep_line_t *sweep_line, edge_t *edge, cairo_boxes_t *out) -{ - if (edge->right != NULL) { - edge_t *next = edge->next; - if (next->x == edge->x) { - next->top = edge->top; - next->right = edge->right; - } else { - end_box (sweep_line, edge, sweep_line->current_y, out); - } - } - - if (sweep_line->insert_left == edge) - sweep_line->insert_left = edge->next; - if (sweep_line->insert_right == edge) - sweep_line->insert_right = edge->next; - - edge->prev->next = edge->next; - edge->next->prev = edge->prev; -} - -static inline void -sweep_line_delete (sweep_line_t *sweep, - rectangle_t *rectangle, - cairo_boxes_t *out) -{ - sweep_line_delete_edge (sweep, &rectangle->left, out); - sweep_line_delete_edge (sweep, &rectangle->right, out); - - pqueue_pop (&sweep->pq); -} - -static inline void -insert_edge (edge_t *edge, edge_t *pos) -{ - if (pos->x != edge->x) { - if (pos->x > edge->x) { - do { - UNROLL3({ - if (pos->prev->x <= edge->x) - break; - pos = pos->prev; - }) - } while (TRUE); - } else { - do { - UNROLL3({ - pos = pos->next; - if (pos->x >= edge->x) - break; - }) - } while (TRUE); - } - } - - pos->prev->next = edge; - edge->prev = pos->prev; - edge->next = pos; - pos->prev = edge; -} - -static inline void -sweep_line_insert (sweep_line_t *sweep, rectangle_t *rectangle) -{ - edge_t *pos; - - /* right edge */ - pos = sweep->insert_right; - insert_edge (&rectangle->right, pos); - sweep->insert_right = &rectangle->right; - - /* left edge */ - pos = sweep->insert_left; - if (pos->x > sweep->insert_right->x) - pos = sweep->insert_right->prev; - insert_edge (&rectangle->left, pos); - sweep->insert_left = &rectangle->left; - - pqueue_push (sweep, rectangle); -} - -static cairo_status_t -intersect (rectangle_t **rectangles, int num_rectangles, cairo_boxes_t *out) -{ - sweep_line_t sweep_line; - rectangle_t *rectangle; - cairo_status_t status; - - sweep_line_init (&sweep_line, rectangles, num_rectangles); - if ((status = setjmp (sweep_line.unwind))) - goto unwind; - - rectangle = rectangle_pop_start (&sweep_line); - do { - if (rectangle->top != sweep_line.current_y) { - rectangle_t *stop; - - stop = rectangle_peek_stop (&sweep_line); - while (stop != NULL && stop->bottom < rectangle->top) { - if (stop->bottom != sweep_line.current_y) { - active_edges (&sweep_line, out); - sweep_line.current_y = stop->bottom; - } - - sweep_line_delete (&sweep_line, stop, out); - - stop = rectangle_peek_stop (&sweep_line); - } - - active_edges (&sweep_line, out); - sweep_line.current_y = rectangle->top; - } - - sweep_line_insert (&sweep_line, rectangle); - } while ((rectangle = rectangle_pop_start (&sweep_line)) != NULL); - - while ((rectangle = rectangle_peek_stop (&sweep_line)) != NULL) { - if (rectangle->bottom != sweep_line.current_y) { - active_edges (&sweep_line, out); - sweep_line.current_y = rectangle->bottom; - } - - sweep_line_delete (&sweep_line, rectangle, out); - } - -unwind: - sweep_line_fini (&sweep_line); - return status; -} - -static cairo_status_t -_cairo_boxes_intersect_with_box (const cairo_boxes_t *boxes, - const cairo_box_t *box, - cairo_boxes_t *out) -{ - cairo_status_t status; - int i, j; - - if (out == boxes) { /* inplace update */ - struct _cairo_boxes_chunk *chunk; - - out->num_boxes = 0; - for (chunk = &out->chunks; chunk != NULL; chunk = chunk->next) { - for (i = j = 0; i < chunk->count; i++) { - cairo_box_t *b = &chunk->base[i]; - - b->p1.x = MAX (b->p1.x, box->p1.x); - b->p1.y = MAX (b->p1.y, box->p1.y); - b->p2.x = MIN (b->p2.x, box->p2.x); - b->p2.y = MIN (b->p2.y, box->p2.y); - if (b->p1.x < b->p2.x && b->p1.y < b->p2.y) { - if (i != j) - chunk->base[j] = *b; - j++; - } - } - /* XXX unlink empty chains? */ - chunk->count = j; - out->num_boxes += j; - } - } else { - const struct _cairo_boxes_chunk *chunk; - - _cairo_boxes_clear (out); - _cairo_boxes_limit (out, box, 1); - for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) { - status = _cairo_boxes_add (out, - CAIRO_ANTIALIAS_DEFAULT, - &chunk->base[i]); - if (unlikely (status)) - return status; - } - } - } - - return CAIRO_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_boxes_intersect (const cairo_boxes_t *a, - const cairo_boxes_t *b, - cairo_boxes_t *out) -{ - rectangle_t stack_rectangles[CAIRO_STACK_ARRAY_LENGTH (rectangle_t)]; - rectangle_t *rectangles; - rectangle_t *stack_rectangles_ptrs[ARRAY_LENGTH (stack_rectangles) + 1]; - rectangle_t **rectangles_ptrs; - const struct _cairo_boxes_chunk *chunk; - cairo_status_t status; - int i, j, count; - - if (unlikely (a->num_boxes == 0 || b->num_boxes == 0)) { - _cairo_boxes_clear (out); - return CAIRO_STATUS_SUCCESS; - } - - if (a->num_boxes == 1) { - cairo_box_t box = a->chunks.base[0]; - return _cairo_boxes_intersect_with_box (b, &box, out); - } - if (b->num_boxes == 1) { - cairo_box_t box = b->chunks.base[0]; - return _cairo_boxes_intersect_with_box (a, &box, out); - } - - rectangles = stack_rectangles; - rectangles_ptrs = stack_rectangles_ptrs; - count = a->num_boxes + b->num_boxes; - if (count > ARRAY_LENGTH (stack_rectangles)) { - rectangles = _cairo_malloc_ab_plus_c (count, - sizeof (rectangle_t) + - sizeof (rectangle_t *), - sizeof (rectangle_t *)); - if (unlikely (rectangles == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - rectangles_ptrs = (rectangle_t **) (rectangles + count); - } - - j = 0; - for (chunk = &a->chunks; chunk != NULL; chunk = chunk->next) { - const cairo_box_t *box = chunk->base; - for (i = 0; i < chunk->count; i++) { - if (box[i].p1.x < box[i].p2.x) { - rectangles[j].left.x = box[i].p1.x; - rectangles[j].left.dir = 1; - - rectangles[j].right.x = box[i].p2.x; - rectangles[j].right.dir = -1; - } else { - rectangles[j].right.x = box[i].p1.x; - rectangles[j].right.dir = 1; - - rectangles[j].left.x = box[i].p2.x; - rectangles[j].left.dir = -1; - } - - rectangles[j].left.a_or_b = 0; - rectangles[j].left.right = NULL; - rectangles[j].right.a_or_b = 0; - rectangles[j].right.right = NULL; - - rectangles[j].top = box[i].p1.y; - rectangles[j].bottom = box[i].p2.y; - - rectangles_ptrs[j] = &rectangles[j]; - j++; - } - } - for (chunk = &b->chunks; chunk != NULL; chunk = chunk->next) { - const cairo_box_t *box = chunk->base; - for (i = 0; i < chunk->count; i++) { - if (box[i].p1.x < box[i].p2.x) { - rectangles[j].left.x = box[i].p1.x; - rectangles[j].left.dir = 1; - - rectangles[j].right.x = box[i].p2.x; - rectangles[j].right.dir = -1; - } else { - rectangles[j].right.x = box[i].p1.x; - rectangles[j].right.dir = 1; - - rectangles[j].left.x = box[i].p2.x; - rectangles[j].left.dir = -1; - } - - rectangles[j].left.a_or_b = 1; - rectangles[j].left.right = NULL; - rectangles[j].right.a_or_b = 1; - rectangles[j].right.right = NULL; - - rectangles[j].top = box[i].p1.y; - rectangles[j].bottom = box[i].p2.y; - - rectangles_ptrs[j] = &rectangles[j]; - j++; - } - } - assert (j == count); - - _cairo_boxes_clear (out); - status = intersect (rectangles_ptrs, j, out); - if (rectangles != stack_rectangles) - free (rectangles); - - return status; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-boxes-private.h b/source/libs/cairo/cairo-src/src/cairo-boxes-private.h deleted file mode 100644 index d1f9dfcd1e561d569a5a2664cad125bf5a0f7a03..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-boxes-private.h +++ /dev/null @@ -1,123 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_BOXES_H -#define CAIRO_BOXES_H - -#include "cairo-types-private.h" -#include "cairo-compiler-private.h" - -#include <stdio.h> -#include <stdlib.h> - -struct _cairo_boxes_t { - cairo_status_t status; - - cairo_box_t limit; - const cairo_box_t *limits; - int num_limits; - - int num_boxes; - - unsigned int is_pixel_aligned; - - struct _cairo_boxes_chunk { - struct _cairo_boxes_chunk *next; - cairo_box_t *base; - int count; - int size; - } chunks, *tail; - cairo_box_t boxes_embedded[32]; -}; - -cairo_private void -_cairo_boxes_init (cairo_boxes_t *boxes); - -cairo_private void -_cairo_boxes_init_with_clip (cairo_boxes_t *boxes, - cairo_clip_t *clip); - -cairo_private void -_cairo_boxes_init_for_array (cairo_boxes_t *boxes, - cairo_box_t *array, - int num_boxes); - -cairo_private void -_cairo_boxes_init_from_rectangle (cairo_boxes_t *boxes, - int x, int y, int w, int h); - -cairo_private void -_cairo_boxes_limit (cairo_boxes_t *boxes, - const cairo_box_t *limits, - int num_limits); - -cairo_private cairo_status_t -_cairo_boxes_add (cairo_boxes_t *boxes, - cairo_antialias_t antialias, - const cairo_box_t *box); - -cairo_private void -_cairo_boxes_extents (const cairo_boxes_t *boxes, - cairo_box_t *box); - -cairo_private cairo_box_t * -_cairo_boxes_to_array (const cairo_boxes_t *boxes, - int *num_boxes, - cairo_bool_t force_allocation); - -cairo_private cairo_status_t -_cairo_boxes_intersect (const cairo_boxes_t *a, - const cairo_boxes_t *b, - cairo_boxes_t *out); - -cairo_private void -_cairo_boxes_clear (cairo_boxes_t *boxes); - -cairo_private_no_warn cairo_bool_t -_cairo_boxes_for_each_box (cairo_boxes_t *boxes, - cairo_bool_t (*func) (cairo_box_t *box, void *data), - void *data); - -cairo_private cairo_status_t -_cairo_rasterise_polygon_to_boxes (cairo_polygon_t *polygon, - cairo_fill_rule_t fill_rule, - cairo_boxes_t *boxes); - -cairo_private void -_cairo_boxes_fini (cairo_boxes_t *boxes); - -cairo_private void -_cairo_debug_print_boxes (FILE *stream, - const cairo_boxes_t *boxes); - -#endif /* CAIRO_BOXES_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-boxes.c b/source/libs/cairo/cairo-src/src/cairo-boxes.c deleted file mode 100644 index 63b68ddfb90867d47b8ec7f6209b5ecf9b045c23..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-boxes.c +++ /dev/null @@ -1,460 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-box-inline.h" -#include "cairo-boxes-private.h" -#include "cairo-error-private.h" - -void -_cairo_boxes_init (cairo_boxes_t *boxes) -{ - boxes->status = CAIRO_STATUS_SUCCESS; - boxes->num_limits = 0; - boxes->num_boxes = 0; - - boxes->tail = &boxes->chunks; - boxes->chunks.next = NULL; - boxes->chunks.base = boxes->boxes_embedded; - boxes->chunks.size = ARRAY_LENGTH (boxes->boxes_embedded); - boxes->chunks.count = 0; - - boxes->is_pixel_aligned = TRUE; -} - -void -_cairo_boxes_init_from_rectangle (cairo_boxes_t *boxes, - int x, int y, int w, int h) -{ - _cairo_boxes_init (boxes); - - _cairo_box_from_integers (&boxes->chunks.base[0], x, y, w, h); - boxes->num_boxes = 1; -} - -void -_cairo_boxes_init_with_clip (cairo_boxes_t *boxes, - cairo_clip_t *clip) -{ - _cairo_boxes_init (boxes); - if (clip) - _cairo_boxes_limit (boxes, clip->boxes, clip->num_boxes); -} - -void -_cairo_boxes_init_for_array (cairo_boxes_t *boxes, - cairo_box_t *array, - int num_boxes) -{ - int n; - - boxes->status = CAIRO_STATUS_SUCCESS; - boxes->num_limits = 0; - boxes->num_boxes = num_boxes; - - boxes->tail = &boxes->chunks; - boxes->chunks.next = NULL; - boxes->chunks.base = array; - boxes->chunks.size = num_boxes; - boxes->chunks.count = num_boxes; - - for (n = 0; n < num_boxes; n++) { - if (! _cairo_fixed_is_integer (array[n].p1.x) || - ! _cairo_fixed_is_integer (array[n].p1.y) || - ! _cairo_fixed_is_integer (array[n].p2.x) || - ! _cairo_fixed_is_integer (array[n].p2.y)) - { - break; - } - } - - boxes->is_pixel_aligned = n == num_boxes; -} - -void -_cairo_boxes_limit (cairo_boxes_t *boxes, - const cairo_box_t *limits, - int num_limits) -{ - int n; - - boxes->limits = limits; - boxes->num_limits = num_limits; - - if (boxes->num_limits) { - boxes->limit = limits[0]; - for (n = 1; n < num_limits; n++) { - if (limits[n].p1.x < boxes->limit.p1.x) - boxes->limit.p1.x = limits[n].p1.x; - - if (limits[n].p1.y < boxes->limit.p1.y) - boxes->limit.p1.y = limits[n].p1.y; - - if (limits[n].p2.x > boxes->limit.p2.x) - boxes->limit.p2.x = limits[n].p2.x; - - if (limits[n].p2.y > boxes->limit.p2.y) - boxes->limit.p2.y = limits[n].p2.y; - } - } -} - -static void -_cairo_boxes_add_internal (cairo_boxes_t *boxes, - const cairo_box_t *box) -{ - struct _cairo_boxes_chunk *chunk; - - if (unlikely (boxes->status)) - return; - - chunk = boxes->tail; - if (unlikely (chunk->count == chunk->size)) { - int size; - - size = chunk->size * 2; - chunk->next = _cairo_malloc_ab_plus_c (size, - sizeof (cairo_box_t), - sizeof (struct _cairo_boxes_chunk)); - - if (unlikely (chunk->next == NULL)) { - boxes->status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - return; - } - - chunk = chunk->next; - boxes->tail = chunk; - - chunk->next = NULL; - chunk->count = 0; - chunk->size = size; - chunk->base = (cairo_box_t *) (chunk + 1); - } - - chunk->base[chunk->count++] = *box; - boxes->num_boxes++; - - if (boxes->is_pixel_aligned) - boxes->is_pixel_aligned = _cairo_box_is_pixel_aligned (box); -} - -cairo_status_t -_cairo_boxes_add (cairo_boxes_t *boxes, - cairo_antialias_t antialias, - const cairo_box_t *box) -{ - cairo_box_t b; - - if (antialias == CAIRO_ANTIALIAS_NONE) { - b.p1.x = _cairo_fixed_round_down (box->p1.x); - b.p1.y = _cairo_fixed_round_down (box->p1.y); - b.p2.x = _cairo_fixed_round_down (box->p2.x); - b.p2.y = _cairo_fixed_round_down (box->p2.y); - box = &b; - } - - if (box->p1.y == box->p2.y) - return CAIRO_STATUS_SUCCESS; - - if (box->p1.x == box->p2.x) - return CAIRO_STATUS_SUCCESS; - - if (boxes->num_limits) { - cairo_point_t p1, p2; - cairo_bool_t reversed = FALSE; - int n; - - /* support counter-clockwise winding for rectangular tessellation */ - if (box->p1.x < box->p2.x) { - p1.x = box->p1.x; - p2.x = box->p2.x; - } else { - p2.x = box->p1.x; - p1.x = box->p2.x; - reversed = ! reversed; - } - - if (p1.x >= boxes->limit.p2.x || p2.x <= boxes->limit.p1.x) - return CAIRO_STATUS_SUCCESS; - - if (box->p1.y < box->p2.y) { - p1.y = box->p1.y; - p2.y = box->p2.y; - } else { - p2.y = box->p1.y; - p1.y = box->p2.y; - reversed = ! reversed; - } - - if (p1.y >= boxes->limit.p2.y || p2.y <= boxes->limit.p1.y) - return CAIRO_STATUS_SUCCESS; - - for (n = 0; n < boxes->num_limits; n++) { - const cairo_box_t *limits = &boxes->limits[n]; - cairo_box_t _box; - cairo_point_t _p1, _p2; - - if (p1.x >= limits->p2.x || p2.x <= limits->p1.x) - continue; - if (p1.y >= limits->p2.y || p2.y <= limits->p1.y) - continue; - - /* Otherwise, clip the box to the limits. */ - _p1 = p1; - if (_p1.x < limits->p1.x) - _p1.x = limits->p1.x; - if (_p1.y < limits->p1.y) - _p1.y = limits->p1.y; - - _p2 = p2; - if (_p2.x > limits->p2.x) - _p2.x = limits->p2.x; - if (_p2.y > limits->p2.y) - _p2.y = limits->p2.y; - - if (_p2.y <= _p1.y || _p2.x <= _p1.x) - continue; - - _box.p1.y = _p1.y; - _box.p2.y = _p2.y; - if (reversed) { - _box.p1.x = _p2.x; - _box.p2.x = _p1.x; - } else { - _box.p1.x = _p1.x; - _box.p2.x = _p2.x; - } - - _cairo_boxes_add_internal (boxes, &_box); - } - } else { - _cairo_boxes_add_internal (boxes, box); - } - - return boxes->status; -} - -void -_cairo_boxes_extents (const cairo_boxes_t *boxes, - cairo_box_t *box) -{ - const struct _cairo_boxes_chunk *chunk; - cairo_box_t b; - int i; - - if (boxes->num_boxes == 0) { - box->p1.x = box->p1.y = box->p2.x = box->p2.y = 0; - return; - } - - b = boxes->chunks.base[0]; - for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) { - if (chunk->base[i].p1.x < b.p1.x) - b.p1.x = chunk->base[i].p1.x; - - if (chunk->base[i].p1.y < b.p1.y) - b.p1.y = chunk->base[i].p1.y; - - if (chunk->base[i].p2.x > b.p2.x) - b.p2.x = chunk->base[i].p2.x; - - if (chunk->base[i].p2.y > b.p2.y) - b.p2.y = chunk->base[i].p2.y; - } - } - *box = b; -} - -void -_cairo_boxes_clear (cairo_boxes_t *boxes) -{ - struct _cairo_boxes_chunk *chunk, *next; - - for (chunk = boxes->chunks.next; chunk != NULL; chunk = next) { - next = chunk->next; - free (chunk); - } - - boxes->tail = &boxes->chunks; - boxes->chunks.next = 0; - boxes->chunks.count = 0; - boxes->chunks.base = boxes->boxes_embedded; - boxes->chunks.size = ARRAY_LENGTH (boxes->boxes_embedded); - boxes->num_boxes = 0; - - boxes->is_pixel_aligned = TRUE; -} - -cairo_box_t * -_cairo_boxes_to_array (const cairo_boxes_t *boxes, - int *num_boxes, - cairo_bool_t force_allocation) -{ - const struct _cairo_boxes_chunk *chunk; - cairo_box_t *box; - int i, j; - - *num_boxes = boxes->num_boxes; - if (boxes->chunks.next == NULL && ! force_allocation) - return boxes->chunks.base; - - box = _cairo_malloc_ab (boxes->num_boxes, sizeof (cairo_box_t)); - if (box == NULL) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return NULL; - } - - j = 0; - for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) - box[j++] = chunk->base[i]; - } - - return box; -} - -void -_cairo_boxes_fini (cairo_boxes_t *boxes) -{ - struct _cairo_boxes_chunk *chunk, *next; - - for (chunk = boxes->chunks.next; chunk != NULL; chunk = next) { - next = chunk->next; - free (chunk); - } -} - -cairo_bool_t -_cairo_boxes_for_each_box (cairo_boxes_t *boxes, - cairo_bool_t (*func) (cairo_box_t *box, void *data), - void *data) -{ - struct _cairo_boxes_chunk *chunk; - int i; - - for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) - if (! func (&chunk->base[i], data)) - return FALSE; - } - - return TRUE; -} - -struct cairo_box_renderer { - cairo_span_renderer_t base; - cairo_boxes_t *boxes; -}; - -static cairo_status_t -span_to_boxes (void *abstract_renderer, int y, int h, - const cairo_half_open_span_t *spans, unsigned num_spans) -{ - struct cairo_box_renderer *r = abstract_renderer; - cairo_status_t status = CAIRO_STATUS_SUCCESS; - cairo_box_t box; - - if (num_spans == 0) - return CAIRO_STATUS_SUCCESS; - - box.p1.y = _cairo_fixed_from_int (y); - box.p2.y = _cairo_fixed_from_int (y + h); - do { - if (spans[0].coverage) { - box.p1.x = _cairo_fixed_from_int(spans[0].x); - box.p2.x = _cairo_fixed_from_int(spans[1].x); - status = _cairo_boxes_add (r->boxes, CAIRO_ANTIALIAS_DEFAULT, &box); - } - spans++; - } while (--num_spans > 1 && status == CAIRO_STATUS_SUCCESS); - - return status; -} - -cairo_status_t -_cairo_rasterise_polygon_to_boxes (cairo_polygon_t *polygon, - cairo_fill_rule_t fill_rule, - cairo_boxes_t *boxes) -{ - struct cairo_box_renderer renderer; - cairo_scan_converter_t *converter; - cairo_int_status_t status; - cairo_rectangle_int_t r; - - TRACE ((stderr, "%s: fill_rule=%d\n", __FUNCTION__, fill_rule)); - - _cairo_box_round_to_rectangle (&polygon->extents, &r); - converter = _cairo_mono_scan_converter_create (r.x, r.y, - r.x + r.width, - r.y + r.height, - fill_rule); - status = _cairo_mono_scan_converter_add_polygon (converter, polygon); - if (unlikely (status)) - goto cleanup_converter; - - renderer.boxes = boxes; - renderer.base.render_rows = span_to_boxes; - - status = converter->generate (converter, &renderer.base); -cleanup_converter: - converter->destroy (converter); - return status; -} - -void -_cairo_debug_print_boxes (FILE *stream, const cairo_boxes_t *boxes) -{ - const struct _cairo_boxes_chunk *chunk; - cairo_box_t extents; - int i; - - _cairo_boxes_extents (boxes, &extents); - fprintf (stream, "boxes x %d: (%f, %f) x (%f, %f)\n", - boxes->num_boxes, - _cairo_fixed_to_double (extents.p1.x), - _cairo_fixed_to_double (extents.p1.y), - _cairo_fixed_to_double (extents.p2.x), - _cairo_fixed_to_double (extents.p2.y)); - - for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) { - fprintf (stderr, " box[%d]: (%f, %f), (%f, %f)\n", i, - _cairo_fixed_to_double (chunk->base[i].p1.x), - _cairo_fixed_to_double (chunk->base[i].p1.y), - _cairo_fixed_to_double (chunk->base[i].p2.x), - _cairo_fixed_to_double (chunk->base[i].p2.y)); - } - } -} diff --git a/source/libs/cairo/cairo-src/src/cairo-cache-private.h b/source/libs/cairo/cairo-src/src/cairo-cache-private.h deleted file mode 100644 index 24b6d0b2092ff94c46480417d5cb285b66e74c68..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-cache-private.h +++ /dev/null @@ -1,145 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2004 Red Hat, Inc. - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Keith Packard <keithp@keithp.com> - * Graydon Hoare <graydon@redhat.com> - * Carl Worth <cworth@cworth.org> - */ - -#ifndef CAIRO_CACHE_PRIVATE_H -#define CAIRO_CACHE_PRIVATE_H - -#include "cairo-compiler-private.h" -#include "cairo-types-private.h" - -/** - * _cairo_cache_entry: - * - * A #cairo_cache_entry_t contains both a key and a value for - * #cairo_cache_t. User-derived types for #cairo_cache_entry_t must - * have a #cairo_cache_entry_t as their first field. For example: - * - * typedef _my_entry { - * cairo_cache_entry_t base; - * ... Remainder of key and value fields here .. - * } my_entry_t; - * - * which then allows a pointer to my_entry_t to be passed to any of - * the #cairo_cache_t functions as follows without requiring a cast: - * - * _cairo_cache_insert (cache, &my_entry->base, size); - * - * IMPORTANT: The caller is responsible for initializing - * my_entry->base.hash with a hash code derived from the key. The - * essential property of the hash code is that keys_equal must never - * return %TRUE for two keys that have different hashes. The best hash - * code will reduce the frequency of two keys with the same code for - * which keys_equal returns %FALSE. - * - * The user must also initialize my_entry->base.size to indicate - * the size of the current entry. What units to use for size is - * entirely up to the caller, (though the same units must be used for - * the max_size parameter passed to _cairo_cache_create()). If all - * entries are close to the same size, the simplest thing to do is to - * just use units of "entries", (eg. set size==1 in all entries and - * set max_size to the number of entries which you want to be saved - * in the cache). - * - * Which parts of the entry make up the "key" and which part make up - * the value are entirely up to the caller, (as determined by the - * computation going into base.hash as well as the keys_equal - * function). A few of the #cairo_cache_t functions accept an entry which - * will be used exclusively as a "key", (indicated by a parameter name - * of key). In these cases, the value-related fields of the entry need - * not be initialized if so desired. - **/ -typedef struct _cairo_cache_entry { - unsigned long hash; - unsigned long size; -} cairo_cache_entry_t; - -typedef cairo_bool_t (*cairo_cache_predicate_func_t) (const void *entry); - -struct _cairo_cache { - cairo_hash_table_t *hash_table; - - cairo_cache_predicate_func_t predicate; - cairo_destroy_func_t entry_destroy; - - unsigned long max_size; - unsigned long size; - - int freeze_count; -}; - -typedef cairo_bool_t -(*cairo_cache_keys_equal_func_t) (const void *key_a, const void *key_b); - -typedef void -(*cairo_cache_callback_func_t) (void *entry, - void *closure); - -cairo_private cairo_status_t -_cairo_cache_init (cairo_cache_t *cache, - cairo_cache_keys_equal_func_t keys_equal, - cairo_cache_predicate_func_t predicate, - cairo_destroy_func_t entry_destroy, - unsigned long max_size); - -cairo_private void -_cairo_cache_fini (cairo_cache_t *cache); - -cairo_private void -_cairo_cache_freeze (cairo_cache_t *cache); - -cairo_private void -_cairo_cache_thaw (cairo_cache_t *cache); - -cairo_private void * -_cairo_cache_lookup (cairo_cache_t *cache, - cairo_cache_entry_t *key); - -cairo_private cairo_status_t -_cairo_cache_insert (cairo_cache_t *cache, - cairo_cache_entry_t *entry); - -cairo_private void -_cairo_cache_remove (cairo_cache_t *cache, - cairo_cache_entry_t *entry); - -cairo_private void -_cairo_cache_foreach (cairo_cache_t *cache, - cairo_cache_callback_func_t cache_callback, - void *closure); - -#endif diff --git a/source/libs/cairo/cairo-src/src/cairo-cache.c b/source/libs/cairo/cairo-src/src/cairo-cache.c deleted file mode 100644 index 5c4e4caa3d005142d3dac8756e0abb14db5c7bb4..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-cache.c +++ /dev/null @@ -1,338 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2004 Red Hat, Inc. - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Keith Packard <keithp@keithp.com> - * Graydon Hoare <graydon@redhat.com> - * Carl Worth <cworth@cworth.org> - */ - -#include "cairoint.h" -#include "cairo-error-private.h" - -static void -_cairo_cache_shrink_to_accommodate (cairo_cache_t *cache, - unsigned long additional); - -static cairo_bool_t -_cairo_cache_entry_is_non_zero (const void *entry) -{ - return ((const cairo_cache_entry_t *) entry)->size; -} - - -/** - * _cairo_cache_init: - * @cache: the #cairo_cache_t to initialise - * @keys_equal: a function to return %TRUE if two keys are equal - * @entry_destroy: destroy notifier for cache entries - * @max_size: the maximum size for this cache - * Returns: the newly created #cairo_cache_t - * - * Creates a new cache using the keys_equal() function to determine - * the equality of entries. - * - * Data is provided to the cache in the form of user-derived version - * of #cairo_cache_entry_t. A cache entry must be able to hold hash - * code, a size, and the key/value pair being stored in the - * cache. Sometimes only the key will be necessary, (as in - * _cairo_cache_lookup()), and in these cases the value portion of the - * entry need not be initialized. - * - * The units for max_size can be chosen by the caller, but should be - * consistent with the units of the size field of cache entries. When - * adding an entry with _cairo_cache_insert() if the total size of - * entries in the cache would exceed max_size then entries will be - * removed at random until the new entry would fit or the cache is - * empty. Then the new entry is inserted. - * - * There are cases in which the automatic removal of entries is - * undesired. If the cache entries have reference counts, then it is a - * simple matter to use the reference counts to ensure that entries - * continue to live even after being ejected from the cache. However, - * in some cases the memory overhead of adding a reference count to - * the entry would be objectionable. In such cases, the - * _cairo_cache_freeze() and _cairo_cache_thaw() calls can be - * used to establish a window during which no automatic removal of - * entries will occur. - **/ -cairo_status_t -_cairo_cache_init (cairo_cache_t *cache, - cairo_cache_keys_equal_func_t keys_equal, - cairo_cache_predicate_func_t predicate, - cairo_destroy_func_t entry_destroy, - unsigned long max_size) -{ - cache->hash_table = _cairo_hash_table_create (keys_equal); - if (unlikely (cache->hash_table == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - if (predicate == NULL) - predicate = _cairo_cache_entry_is_non_zero; - cache->predicate = predicate; - cache->entry_destroy = entry_destroy; - - cache->max_size = max_size; - cache->size = 0; - - cache->freeze_count = 0; - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_cache_pluck (void *entry, void *closure) -{ - _cairo_cache_remove (closure, entry); -} - -/** - * _cairo_cache_fini: - * @cache: a cache to destroy - * - * Immediately destroys the given cache, freeing all resources - * associated with it. As part of this process, the entry_destroy() - * function, (as passed to _cairo_cache_init()), will be called for - * each entry in the cache. - **/ -void -_cairo_cache_fini (cairo_cache_t *cache) -{ - _cairo_hash_table_foreach (cache->hash_table, - _cairo_cache_pluck, - cache); - assert (cache->size == 0); - _cairo_hash_table_destroy (cache->hash_table); -} - -/** - * _cairo_cache_freeze: - * @cache: a cache with some precious entries in it (or about to be - * added) - * - * Disable the automatic ejection of entries from the cache. For as - * long as the cache is "frozen", calls to _cairo_cache_insert() will - * add new entries to the cache regardless of how large the cache - * grows. See _cairo_cache_thaw(). - * - * Note: Multiple calls to _cairo_cache_freeze() will stack, in that - * the cache will remain "frozen" until a corresponding number of - * calls are made to _cairo_cache_thaw(). - **/ -void -_cairo_cache_freeze (cairo_cache_t *cache) -{ - assert (cache->freeze_count >= 0); - - cache->freeze_count++; -} - -/** - * _cairo_cache_thaw: - * @cache: a cache, just after the entries in it have become less - * precious - * - * Cancels the effects of _cairo_cache_freeze(). - * - * When a number of calls to _cairo_cache_thaw() is made corresponding - * to the number of calls to _cairo_cache_freeze() the cache will no - * longer be "frozen". If the cache had grown larger than max_size - * while frozen, entries will immediately be ejected (by random) from - * the cache until the cache is smaller than max_size. Also, the - * automatic ejection of entries on _cairo_cache_insert() will resume. - **/ -void -_cairo_cache_thaw (cairo_cache_t *cache) -{ - assert (cache->freeze_count > 0); - - if (--cache->freeze_count == 0) - _cairo_cache_shrink_to_accommodate (cache, 0); -} - -/** - * _cairo_cache_lookup: - * @cache: a cache - * @key: the key of interest - * @entry_return: pointer for return value - * - * Performs a lookup in @cache looking for an entry which has a key - * that matches @key, (as determined by the keys_equal() function - * passed to _cairo_cache_init()). - * - * Return value: %TRUE if there is an entry in the cache that matches - * @key, (which will now be in *entry_return). %FALSE otherwise, (in - * which case *entry_return will be %NULL). - **/ -void * -_cairo_cache_lookup (cairo_cache_t *cache, - cairo_cache_entry_t *key) -{ - return _cairo_hash_table_lookup (cache->hash_table, - (cairo_hash_entry_t *) key); -} - -/** - * _cairo_cache_remove_random: - * @cache: a cache - * - * Remove a random entry from the cache. - * - * Return value: %TRUE if an entry was successfully removed. - * %FALSE if there are no entries that can be removed. - **/ -static cairo_bool_t -_cairo_cache_remove_random (cairo_cache_t *cache) -{ - cairo_cache_entry_t *entry; - - entry = _cairo_hash_table_random_entry (cache->hash_table, - cache->predicate); - if (unlikely (entry == NULL)) - return FALSE; - - _cairo_cache_remove (cache, entry); - - return TRUE; -} - -/** - * _cairo_cache_shrink_to_accommodate: - * @cache: a cache - * @additional: additional size requested in bytes - * - * If cache is not frozen, eject entries randomly until the size of - * the cache is at least @additional bytes less than - * cache->max_size. That is, make enough room to accommodate a new - * entry of size @additional. - **/ -static void -_cairo_cache_shrink_to_accommodate (cairo_cache_t *cache, - unsigned long additional) -{ - while (cache->size + additional > cache->max_size) { - if (! _cairo_cache_remove_random (cache)) - return; - } -} - -/** - * _cairo_cache_insert: - * @cache: a cache - * @entry: an entry to be inserted - * - * Insert @entry into the cache. If an entry exists in the cache with - * a matching key, then the old entry will be removed first, (and the - * entry_destroy() callback will be called on it). - * - * Return value: %CAIRO_STATUS_SUCCESS if successful or - * %CAIRO_STATUS_NO_MEMORY if insufficient memory is available. - **/ -cairo_status_t -_cairo_cache_insert (cairo_cache_t *cache, - cairo_cache_entry_t *entry) -{ - cairo_status_t status; - - if (entry->size && ! cache->freeze_count) - _cairo_cache_shrink_to_accommodate (cache, entry->size); - - status = _cairo_hash_table_insert (cache->hash_table, - (cairo_hash_entry_t *) entry); - if (unlikely (status)) - return status; - - cache->size += entry->size; - - return CAIRO_STATUS_SUCCESS; -} - -/** - * _cairo_cache_remove: - * @cache: a cache - * @entry: an entry that exists in the cache - * - * Remove an existing entry from the cache. - **/ -void -_cairo_cache_remove (cairo_cache_t *cache, - cairo_cache_entry_t *entry) -{ - cache->size -= entry->size; - - _cairo_hash_table_remove (cache->hash_table, - (cairo_hash_entry_t *) entry); - - if (cache->entry_destroy) - cache->entry_destroy (entry); -} - -/** - * _cairo_cache_foreach: - * @cache: a cache - * @cache_callback: function to be called for each entry - * @closure: additional argument to be passed to @cache_callback - * - * Call @cache_callback for each entry in the cache, in a - * non-specified order. - **/ -void -_cairo_cache_foreach (cairo_cache_t *cache, - cairo_cache_callback_func_t cache_callback, - void *closure) -{ - _cairo_hash_table_foreach (cache->hash_table, - cache_callback, - closure); -} - -unsigned long -_cairo_hash_string (const char *c) -{ - /* This is the djb2 hash. */ - unsigned long hash = _CAIRO_HASH_INIT_VALUE; - while (c && *c) - hash = ((hash << 5) + hash) + *c++; - return hash; -} - -unsigned long -_cairo_hash_bytes (unsigned long hash, - const void *ptr, - unsigned int length) -{ - const uint8_t *bytes = ptr; - /* This is the djb2 hash. */ - while (length--) - hash = ((hash << 5) + hash) + *bytes++; - return hash; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-cff-subset.c b/source/libs/cairo/cairo-src/src/cairo-cff-subset.c deleted file mode 100644 index 3ffe6f663f71a254d15b1f18a329301b92e114f9..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-cff-subset.c +++ /dev/null @@ -1,3440 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2006 Adrian Johnson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Adrian Johnson. - * - * Contributor(s): - * Adrian Johnson <ajohnson@redneon.com> - * Eugeniy Meshcheryakov <eugen@debian.org> - */ - -/* - * Useful links: - * http://www.adobe.com/content/dam/Adobe/en/devnet/font/pdfs/5176.CFF.pdf - * http://www.adobe.com/content/dam/Adobe/en/devnet/font/pdfs/5177.Type2.pdf - */ - -#define _BSD_SOURCE /* for snprintf(), strdup() */ -#include "cairoint.h" - -#include "cairo-array-private.h" -#include "cairo-error-private.h" - -#if CAIRO_HAS_FONT_SUBSET - -#include "cairo-scaled-font-subsets-private.h" -#include "cairo-truetype-subset-private.h" -#include <string.h> -#include <locale.h> - -/* CFF Dict Operators. If the high byte is 0 the command is encoded - * with a single byte. */ -#define BASEFONTNAME_OP 0x0c16 -#define CIDCOUNT_OP 0x0c22 -#define CHARSET_OP 0x000f -#define CHARSTRINGS_OP 0x0011 -#define COPYRIGHT_OP 0x0c00 -#define DEFAULTWIDTH_OP 0x0014 -#define ENCODING_OP 0x0010 -#define FAMILYNAME_OP 0x0003 -#define FDARRAY_OP 0x0c24 -#define FDSELECT_OP 0x0c25 -#define FONTBBOX_OP 0x0005 -#define FONTMATRIX_OP 0x0c07 -#define FONTNAME_OP 0x0c26 -#define FULLNAME_OP 0x0002 -#define LOCAL_SUB_OP 0x0013 -#define NOMINALWIDTH_OP 0x0015 -#define NOTICE_OP 0x0001 -#define POSTSCRIPT_OP 0x0c15 -#define PRIVATE_OP 0x0012 -#define ROS_OP 0x0c1e -#define UNIQUEID_OP 0x000d -#define VERSION_OP 0x0000 -#define WEIGHT_OP 0x0004 -#define XUID_OP 0x000e - -#define NUM_STD_STRINGS 391 - -/* Type 2 Charstring operators */ -#define TYPE2_hstem 0x0001 -#define TYPE2_vstem 0x0003 -#define TYPE2_callsubr 0x000a - -#define TYPE2_return 0x000b -#define TYPE2_endchar 0x000e - -#define TYPE2_hstemhm 0x0012 -#define TYPE2_hintmask 0x0013 -#define TYPE2_cntrmask 0x0014 -#define TYPE2_vstemhm 0x0017 -#define TYPE2_callgsubr 0x001d - -#define TYPE2_rmoveto 0x0015 -#define TYPE2_hmoveto 0x0016 -#define TYPE2_vmoveto 0x0004 - - -#define MAX_SUBROUTINE_NESTING 10 /* From Type2 Charstring spec */ - - -typedef struct _cff_header { - uint8_t major; - uint8_t minor; - uint8_t header_size; - uint8_t offset_size; -} cff_header_t; - -typedef struct _cff_index_element { - cairo_bool_t is_copy; - unsigned char *data; - int length; -} cff_index_element_t; - -typedef struct _cff_dict_operator { - cairo_hash_entry_t base; - - unsigned short operator; - unsigned char *operand; - int operand_length; - int operand_offset; -} cff_dict_operator_t; - -typedef struct _cairo_cff_font { - - cairo_scaled_font_subset_t *scaled_font_subset; - const cairo_scaled_font_backend_t *backend; - - /* Font Data */ - unsigned char *data; - unsigned long data_length; - unsigned char *current_ptr; - unsigned char *data_end; - cff_header_t *header; - char *font_name; - char *ps_name; - cairo_hash_table_t *top_dict; - cairo_hash_table_t *private_dict; - cairo_array_t strings_index; - cairo_array_t charstrings_index; - cairo_array_t global_sub_index; - cairo_array_t local_sub_index; - unsigned char *charset; - int num_glyphs; - cairo_bool_t is_cid; - cairo_bool_t is_opentype; - int units_per_em; - int global_sub_bias; - int local_sub_bias; - double default_width; - double nominal_width; - - /* CID Font Data */ - int *fdselect; - unsigned int num_fontdicts; - cairo_hash_table_t **fd_dict; - cairo_hash_table_t **fd_private_dict; - cairo_array_t *fd_local_sub_index; - int *fd_local_sub_bias; - double *fd_default_width; - double *fd_nominal_width; - - /* Subsetted Font Data */ - char *subset_font_name; - cairo_array_t charstrings_subset_index; - cairo_array_t strings_subset_index; - int euro_sid; - int *fdselect_subset; - unsigned int num_subset_fontdicts; - int *fd_subset_map; - int *private_dict_offset; - cairo_bool_t subset_subroutines; - cairo_bool_t *global_subs_used; - cairo_bool_t *local_subs_used; - cairo_bool_t **fd_local_subs_used; - cairo_array_t output; - - /* Subset Metrics */ - int *widths; - int x_min, y_min, x_max, y_max; - int ascent, descent; - - /* Type 2 charstring data */ - int type2_stack_size; - int type2_stack_top_value; - cairo_bool_t type2_stack_top_is_int; - int type2_num_hints; - int type2_hintmask_bytes; - int type2_nesting_level; - cairo_bool_t type2_seen_first_int; - cairo_bool_t type2_find_width; - cairo_bool_t type2_found_width; - int type2_width; - cairo_bool_t type2_has_path; - -} cairo_cff_font_t; - -/* Encoded integer using maximum sized encoding. This is required for - * operands that are later modified after encoding. */ -static unsigned char * -encode_integer_max (unsigned char *p, int i) -{ - *p++ = 29; - *p++ = i >> 24; - *p++ = (i >> 16) & 0xff; - *p++ = (i >> 8) & 0xff; - *p++ = i & 0xff; - return p; -} - -static unsigned char * -encode_integer (unsigned char *p, int i) -{ - if (i >= -107 && i <= 107) { - *p++ = i + 139; - } else if (i >= 108 && i <= 1131) { - i -= 108; - *p++ = (i >> 8)+ 247; - *p++ = i & 0xff; - } else if (i >= -1131 && i <= -108) { - i = -i - 108; - *p++ = (i >> 8)+ 251; - *p++ = i & 0xff; - } else if (i >= -32768 && i <= 32767) { - *p++ = 28; - *p++ = (i >> 8) & 0xff; - *p++ = i & 0xff; - } else { - p = encode_integer_max (p, i); - } - return p; -} - -static unsigned char * -decode_integer (unsigned char *p, int *integer) -{ - if (*p == 28) { - *integer = (int)(p[1]<<8 | p[2]); - p += 3; - } else if (*p == 29) { - *integer = (int)((p[1] << 24) | (p[2] << 16) | (p[3] << 8) | p[4]); - p += 5; - } else if (*p >= 32 && *p <= 246) { - *integer = *p++ - 139; - } else if (*p <= 250) { - *integer = (p[0] - 247) * 256 + p[1] + 108; - p += 2; - } else if (*p <= 254) { - *integer = -(p[0] - 251) * 256 - p[1] - 108; - p += 2; - } else { - *integer = 0; - p += 1; - } - return p; -} - -static char * -decode_nibble (int n, char *buf) -{ - switch (n) - { - case 0xa: - *buf++ = '.'; - break; - case 0xb: - *buf++ = 'E'; - break; - case 0xc: - *buf++ = 'E'; - *buf++ = '-'; - break; - case 0xd: - *buf++ = '-'; - break; - case 0xe: - *buf++ = '-'; - break; - case 0xf: - break; - default: - *buf++ = '0' + n; - break; - } - - return buf; -} - -static unsigned char * -decode_real (unsigned char *p, double *real) -{ - const char *decimal_point; - int decimal_point_len; - int n; - char buffer[100]; - char buffer2[200]; - char *q; - char *buf = buffer; - char *buf_end = buffer + sizeof (buffer); - - decimal_point = cairo_get_locale_decimal_point (); - decimal_point_len = strlen (decimal_point); - - assert (decimal_point_len != 0); - assert (sizeof(buffer) + decimal_point_len < sizeof(buffer2)); - - p++; - while (buf + 2 < buf_end) { - n = *p >> 4; - buf = decode_nibble (n, buf); - n = *p & 0x0f; - buf = decode_nibble (n, buf); - if ((*p & 0x0f) == 0x0f) { - p++; - break; - } - p++; - }; - *buf = 0; - - buf = buffer; - if (strchr (buffer, '.')) { - q = strchr (buffer, '.'); - strncpy (buffer2, buffer, q - buffer); - buf = buffer2 + (q - buffer); - strncpy (buf, decimal_point, decimal_point_len); - buf += decimal_point_len; - strcpy (buf, q + 1); - buf = buffer2; - } - - if (sscanf(buf, "%lf", real) != 1) - *real = 0.0; - - return p; -} - -static unsigned char * -decode_number (unsigned char *p, double *number) -{ - if (*p == 30) { - p = decode_real (p, number); - } else { - int i; - p = decode_integer (p, &i); - *number = i; - } - return p; -} - -static unsigned char * -decode_operator (unsigned char *p, unsigned short *operator) -{ - unsigned short op = 0; - - op = *p++; - if (op == 12) { - op <<= 8; - op |= *p++; - } - *operator = op; - return p; -} - -/* return 0 if not an operand */ -static int -operand_length (unsigned char *p) -{ - unsigned char *begin = p; - - if (*p == 28) - return 3; - - if (*p == 29) - return 5; - - if (*p >= 32 && *p <= 246) - return 1; - - if (*p >= 247 && *p <= 254) - return 2; - - if (*p == 30) { - while ((*p & 0x0f) != 0x0f) - p++; - return p - begin + 1; - } - - return 0; -} - -static unsigned char * -encode_index_offset (unsigned char *p, int offset_size, unsigned long offset) -{ - while (--offset_size >= 0) { - p[offset_size] = (unsigned char) (offset & 0xff); - offset >>= 8; - } - return p + offset_size; -} - -static unsigned long -decode_index_offset(unsigned char *p, int off_size) -{ - unsigned long offset = 0; - - while (off_size-- > 0) - offset = offset*256 + *p++; - return offset; -} - -static void -cff_index_init (cairo_array_t *index) -{ - _cairo_array_init (index, sizeof (cff_index_element_t)); -} - -static cairo_int_status_t -cff_index_read (cairo_array_t *index, unsigned char **ptr, unsigned char *end_ptr) -{ - cff_index_element_t element; - unsigned char *data, *p; - cairo_status_t status; - int offset_size, count, start, i; - int end = 0; - - p = *ptr; - if (p + 2 > end_ptr) - return CAIRO_INT_STATUS_UNSUPPORTED; - count = get_unaligned_be16 (p); - p += 2; - if (count > 0) { - offset_size = *p++; - if (p + (count + 1)*offset_size > end_ptr) - return CAIRO_INT_STATUS_UNSUPPORTED; - data = p + offset_size*(count + 1) - 1; - start = decode_index_offset (p, offset_size); - p += offset_size; - for (i = 0; i < count; i++) { - end = decode_index_offset (p, offset_size); - p += offset_size; - if (p > end_ptr) - return CAIRO_INT_STATUS_UNSUPPORTED; - element.length = end - start; - element.is_copy = FALSE; - element.data = data + start; - status = _cairo_array_append (index, &element); - if (unlikely (status)) - return status; - start = end; - } - p = data + end; - } - *ptr = p; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cff_index_write (cairo_array_t *index, cairo_array_t *output) -{ - int offset_size; - int offset; - int num_elem; - int i; - cff_index_element_t *element; - uint16_t count; - unsigned char buf[5]; - cairo_status_t status; - - num_elem = _cairo_array_num_elements (index); - count = cpu_to_be16 ((uint16_t) num_elem); - status = _cairo_array_append_multiple (output, &count, 2); - if (unlikely (status)) - return status; - - if (num_elem == 0) - return CAIRO_STATUS_SUCCESS; - - /* Find maximum offset to determine offset size */ - offset = 1; - for (i = 0; i < num_elem; i++) { - element = _cairo_array_index (index, i); - offset += element->length; - } - if (offset < 0x100) - offset_size = 1; - else if (offset < 0x10000) - offset_size = 2; - else if (offset < 0x1000000) - offset_size = 3; - else - offset_size = 4; - - buf[0] = (unsigned char) offset_size; - status = _cairo_array_append (output, buf); - if (unlikely (status)) - return status; - - offset = 1; - encode_index_offset (buf, offset_size, offset); - status = _cairo_array_append_multiple (output, buf, offset_size); - if (unlikely (status)) - return status; - - for (i = 0; i < num_elem; i++) { - element = _cairo_array_index (index, i); - offset += element->length; - encode_index_offset (buf, offset_size, offset); - status = _cairo_array_append_multiple (output, buf, offset_size); - if (unlikely (status)) - return status; - } - - for (i = 0; i < num_elem; i++) { - element = _cairo_array_index (index, i); - if (element->length > 0) { - status = _cairo_array_append_multiple (output, - element->data, - element->length); - } - if (unlikely (status)) - return status; - } - return CAIRO_STATUS_SUCCESS; -} - -static void -cff_index_set_object (cairo_array_t *index, int obj_index, - unsigned char *object , int length) -{ - cff_index_element_t *element; - - element = _cairo_array_index (index, obj_index); - if (element->is_copy) - free (element->data); - - element->data = object; - element->length = length; - element->is_copy = FALSE; -} - -static cairo_status_t -cff_index_append (cairo_array_t *index, unsigned char *object , int length) -{ - cff_index_element_t element; - - element.length = length; - element.is_copy = FALSE; - element.data = object; - - return _cairo_array_append (index, &element); -} - -static cairo_status_t -cff_index_append_copy (cairo_array_t *index, - const unsigned char *object, - unsigned int length) -{ - cff_index_element_t element; - cairo_status_t status; - - element.length = length; - element.is_copy = TRUE; - element.data = malloc (element.length); - if (unlikely (element.data == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - memcpy (element.data, object, element.length); - - status = _cairo_array_append (index, &element); - if (unlikely (status)) { - free (element.data); - return status; - } - - return CAIRO_STATUS_SUCCESS; -} - -static void -cff_index_fini (cairo_array_t *index) -{ - cff_index_element_t *element; - unsigned int i; - - for (i = 0; i < _cairo_array_num_elements (index); i++) { - element = _cairo_array_index (index, i); - if (element->is_copy && element->data) - free (element->data); - } - _cairo_array_fini (index); -} - -static cairo_bool_t -_cairo_cff_dict_equal (const void *key_a, const void *key_b) -{ - const cff_dict_operator_t *op_a = key_a; - const cff_dict_operator_t *op_b = key_b; - - return op_a->operator == op_b->operator; -} - -static cairo_status_t -cff_dict_init (cairo_hash_table_t **dict) -{ - *dict = _cairo_hash_table_create (_cairo_cff_dict_equal); - if (unlikely (*dict == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_dict_init_key (cff_dict_operator_t *key, int operator) -{ - key->base.hash = (unsigned long) operator; - key->operator = operator; -} - -static cairo_status_t -cff_dict_create_operator (int operator, - unsigned char *operand, - int size, - cff_dict_operator_t **out) -{ - cff_dict_operator_t *op; - - op = malloc (sizeof (cff_dict_operator_t)); - if (unlikely (op == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_dict_init_key (op, operator); - op->operand = malloc (size); - if (unlikely (op->operand == NULL)) { - free (op); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - memcpy (op->operand, operand, size); - op->operand_length = size; - op->operand_offset = -1; - - *out = op; - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cff_dict_read (cairo_hash_table_t *dict, unsigned char *p, int dict_size) -{ - unsigned char *end; - cairo_array_t operands; - cff_dict_operator_t *op; - unsigned short operator; - cairo_status_t status = CAIRO_STATUS_SUCCESS; - int size; - - end = p + dict_size; - _cairo_array_init (&operands, 1); - while (p < end) { - size = operand_length (p); - if (size != 0) { - status = _cairo_array_append_multiple (&operands, p, size); - if (unlikely (status)) - goto fail; - - p += size; - } else { - p = decode_operator (p, &operator); - status = cff_dict_create_operator (operator, - _cairo_array_index (&operands, 0), - _cairo_array_num_elements (&operands), - &op); - if (unlikely (status)) - goto fail; - - status = _cairo_hash_table_insert (dict, &op->base); - if (unlikely (status)) - goto fail; - - _cairo_array_truncate (&operands, 0); - } - } - -fail: - _cairo_array_fini (&operands); - - return status; -} - -static void -cff_dict_remove (cairo_hash_table_t *dict, unsigned short operator) -{ - cff_dict_operator_t key, *op; - - _cairo_dict_init_key (&key, operator); - op = _cairo_hash_table_lookup (dict, &key.base); - if (op != NULL) { - free (op->operand); - _cairo_hash_table_remove (dict, (cairo_hash_entry_t *) op); - free (op); - } -} - -static unsigned char * -cff_dict_get_operands (cairo_hash_table_t *dict, - unsigned short operator, - int *size) -{ - cff_dict_operator_t key, *op; - - _cairo_dict_init_key (&key, operator); - op = _cairo_hash_table_lookup (dict, &key.base); - if (op != NULL) { - *size = op->operand_length; - return op->operand; - } - - return NULL; -} - -static cairo_status_t -cff_dict_set_operands (cairo_hash_table_t *dict, - unsigned short operator, - unsigned char *operand, - int size) -{ - cff_dict_operator_t key, *op; - cairo_status_t status; - - _cairo_dict_init_key (&key, operator); - op = _cairo_hash_table_lookup (dict, &key.base); - if (op != NULL) { - free (op->operand); - op->operand = malloc (size); - if (unlikely (op->operand == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - memcpy (op->operand, operand, size); - op->operand_length = size; - } - else - { - status = cff_dict_create_operator (operator, operand, size, &op); - if (unlikely (status)) - return status; - - status = _cairo_hash_table_insert (dict, &op->base); - if (unlikely (status)) - return status; - } - - return CAIRO_STATUS_SUCCESS; -} - -static int -cff_dict_get_location (cairo_hash_table_t *dict, - unsigned short operator, - int *size) -{ - cff_dict_operator_t key, *op; - - _cairo_dict_init_key (&key, operator); - op = _cairo_hash_table_lookup (dict, &key.base); - if (op != NULL) { - *size = op->operand_length; - return op->operand_offset; - } - - return -1; -} - -typedef struct _dict_write_info { - cairo_array_t *output; - cairo_status_t status; -} dict_write_info_t; - -static void -cairo_dict_write_operator (cff_dict_operator_t *op, dict_write_info_t *write_info) -{ - unsigned char data; - - op->operand_offset = _cairo_array_num_elements (write_info->output); - write_info->status = _cairo_array_append_multiple (write_info->output, op->operand, op->operand_length); - if (write_info->status) - return; - - if (op->operator & 0xff00) { - data = op->operator >> 8; - write_info->status = _cairo_array_append (write_info->output, &data); - if (write_info->status) - return; - } - data = op->operator & 0xff; - write_info->status = _cairo_array_append (write_info->output, &data); -} - -static void -_cairo_dict_collect (void *entry, void *closure) -{ - dict_write_info_t *write_info = closure; - cff_dict_operator_t *op = entry; - - if (write_info->status) - return; - - /* The ROS operator is handled separately in cff_dict_write() */ - if (op->operator != ROS_OP) - cairo_dict_write_operator (op, write_info); -} - -static cairo_status_t -cff_dict_write (cairo_hash_table_t *dict, cairo_array_t *output) -{ - dict_write_info_t write_info; - cff_dict_operator_t key, *op; - - write_info.output = output; - write_info.status = CAIRO_STATUS_SUCCESS; - - /* The CFF specification requires that the Top Dict of CID fonts - * begin with the ROS operator. */ - _cairo_dict_init_key (&key, ROS_OP); - op = _cairo_hash_table_lookup (dict, &key.base); - if (op != NULL) - cairo_dict_write_operator (op, &write_info); - - _cairo_hash_table_foreach (dict, _cairo_dict_collect, &write_info); - - return write_info.status; -} - -static void -_cff_dict_entry_pluck (void *_entry, void *dict) -{ - cff_dict_operator_t *entry = _entry; - - _cairo_hash_table_remove (dict, &entry->base); - free (entry->operand); - free (entry); -} - -static void -cff_dict_fini (cairo_hash_table_t *dict) -{ - _cairo_hash_table_foreach (dict, _cff_dict_entry_pluck, dict); - _cairo_hash_table_destroy (dict); -} - -static cairo_int_status_t -cairo_cff_font_read_header (cairo_cff_font_t *font) -{ - if (font->data_length < sizeof (cff_header_t)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - - font->header = (cff_header_t *) font->data; - font->current_ptr = font->data + font->header->header_size; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -cairo_cff_font_read_name (cairo_cff_font_t *font) -{ - cairo_array_t index; - cairo_int_status_t status; - cff_index_element_t *element; - unsigned char *p; - int i, len; - - cff_index_init (&index); - status = cff_index_read (&index, &font->current_ptr, font->data_end); - if (!font->is_opentype) { - element = _cairo_array_index (&index, 0); - p = element->data; - len = element->length; - - /* If font name is prefixed with a subset tag, strip it off. */ - if (len > 7 && p[6] == '+') { - for (i = 0; i < 6; i++) - if (p[i] < 'A' || p[i] > 'Z') - break; - if (i == 6) { - p += 7; - len -= 7; - } - } - font->ps_name = malloc (len + 1); - if (unlikely (font->ps_name == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - memcpy (font->ps_name, p, len); - font->ps_name[len] = 0; - - status = _cairo_escape_ps_name (&font->ps_name); - } - cff_index_fini (&index); - - return status; -} - -static cairo_int_status_t -cairo_cff_font_read_private_dict (cairo_cff_font_t *font, - cairo_hash_table_t *private_dict, - cairo_array_t *local_sub_index, - int *local_sub_bias, - cairo_bool_t **local_subs_used, - double *default_width, - double *nominal_width, - unsigned char *ptr, - int size) -{ - cairo_int_status_t status; - unsigned char buf[10]; - unsigned char *end_buf; - int offset; - int i; - unsigned char *operand; - unsigned char *p; - int num_subs; - - status = cff_dict_read (private_dict, ptr, size); - if (unlikely (status)) - return status; - - operand = cff_dict_get_operands (private_dict, LOCAL_SUB_OP, &i); - if (operand) { - decode_integer (operand, &offset); - p = ptr + offset; - status = cff_index_read (local_sub_index, &p, font->data_end); - if (unlikely (status)) - return status; - - /* Use maximum sized encoding to reserve space for later modification. */ - end_buf = encode_integer_max (buf, 0); - status = cff_dict_set_operands (private_dict, LOCAL_SUB_OP, buf, end_buf - buf); - if (unlikely (status)) - return status; - } - - *default_width = 0; - operand = cff_dict_get_operands (private_dict, DEFAULTWIDTH_OP, &i); - if (operand) - decode_number (operand, default_width); - - *nominal_width = 0; - operand = cff_dict_get_operands (private_dict, NOMINALWIDTH_OP, &i); - if (operand) - decode_number (operand, nominal_width); - - num_subs = _cairo_array_num_elements (local_sub_index); - *local_subs_used = calloc (num_subs, sizeof (cairo_bool_t)); - if (unlikely (*local_subs_used == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - if (num_subs < 1240) - *local_sub_bias = 107; - else if (num_subs < 33900) - *local_sub_bias = 1131; - else - *local_sub_bias = 32768; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -cairo_cff_font_read_fdselect (cairo_cff_font_t *font, unsigned char *p) -{ - int type, num_ranges, first, last, fd, i, j; - - font->fdselect = calloc (font->num_glyphs, sizeof (int)); - if (unlikely (font->fdselect == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - type = *p++; - if (type == 0) - { - for (i = 0; i < font->num_glyphs; i++) - font->fdselect[i] = *p++; - } else if (type == 3) { - num_ranges = get_unaligned_be16 (p); - p += 2; - for (i = 0; i < num_ranges; i++) - { - first = get_unaligned_be16 (p); - p += 2; - fd = *p++; - last = get_unaligned_be16 (p); - for (j = first; j < last; j++) - font->fdselect[j] = fd; - } - } else { - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -cairo_cff_font_read_cid_fontdict (cairo_cff_font_t *font, unsigned char *ptr) -{ - cairo_array_t index; - cff_index_element_t *element; - unsigned int i; - int size; - unsigned char *operand; - int offset; - cairo_int_status_t status; - unsigned char buf[100]; - unsigned char *end_buf; - - cff_index_init (&index); - status = cff_index_read (&index, &ptr, font->data_end); - if (unlikely (status)) - goto fail; - - font->num_fontdicts = _cairo_array_num_elements (&index); - - font->fd_dict = calloc (sizeof (cairo_hash_table_t *), font->num_fontdicts); - if (unlikely (font->fd_dict == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail; - } - - font->fd_private_dict = calloc (sizeof (cairo_hash_table_t *), font->num_fontdicts); - if (unlikely (font->fd_private_dict == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail; - } - - font->fd_local_sub_index = calloc (sizeof (cairo_array_t), font->num_fontdicts); - if (unlikely (font->fd_local_sub_index == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail; - } - - font->fd_local_sub_bias = calloc (sizeof (int), font->num_fontdicts); - if (unlikely (font->fd_local_sub_bias == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail; - } - - font->fd_local_subs_used = calloc (sizeof (cairo_bool_t *), font->num_fontdicts); - if (unlikely (font->fd_local_subs_used == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail; - } - - font->fd_default_width = calloc (font->num_fontdicts, sizeof (double)); - if (unlikely (font->fd_default_width == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail; - } - - font->fd_nominal_width = calloc (font->num_fontdicts, sizeof (double)); - if (unlikely (font->fd_nominal_width == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail; - } - - for (i = 0; i < font->num_fontdicts; i++) { - status = cff_dict_init (&font->fd_dict[i]); - if (unlikely (status)) - goto fail; - - element = _cairo_array_index (&index, i); - status = cff_dict_read (font->fd_dict[i], element->data, element->length); - if (unlikely (status)) - goto fail; - - operand = cff_dict_get_operands (font->fd_dict[i], PRIVATE_OP, &size); - if (operand == NULL) { - status = CAIRO_INT_STATUS_UNSUPPORTED; - goto fail; - } - operand = decode_integer (operand, &size); - decode_integer (operand, &offset); - status = cff_dict_init (&font->fd_private_dict[i]); - if (unlikely (status)) - goto fail; - - cff_index_init (&font->fd_local_sub_index[i]); - status = cairo_cff_font_read_private_dict (font, - font->fd_private_dict[i], - &font->fd_local_sub_index[i], - &font->fd_local_sub_bias[i], - &font->fd_local_subs_used[i], - &font->fd_default_width[i], - &font->fd_nominal_width[i], - font->data + offset, - size); - if (unlikely (status)) - goto fail; - - /* Set integer operand to max value to use max size encoding to reserve - * space for any value later */ - end_buf = encode_integer_max (buf, 0); - end_buf = encode_integer_max (end_buf, 0); - status = cff_dict_set_operands (font->fd_dict[i], PRIVATE_OP, buf, end_buf - buf); - if (unlikely (status)) - goto fail; - } - - return CAIRO_STATUS_SUCCESS; - -fail: - cff_index_fini (&index); - - return status; -} - -static void -cairo_cff_font_read_font_metrics (cairo_cff_font_t *font, cairo_hash_table_t *top_dict) -{ - unsigned char *p; - unsigned char *end; - int size; - double x_min, y_min, x_max, y_max; - double xx, yx, xy, yy; - - x_min = 0.0; - y_min = 0.0; - x_max = 0.0; - y_max = 0.0; - p = cff_dict_get_operands (font->top_dict, FONTBBOX_OP, &size); - if (p) { - end = p + size; - if (p < end) - p = decode_number (p, &x_min); - if (p < end) - p = decode_number (p, &y_min); - if (p < end) - p = decode_number (p, &x_max); - if (p < end) - p = decode_number (p, &y_max); - } - font->x_min = floor (x_min); - font->y_min = floor (y_min); - font->x_max = floor (x_max); - font->y_max = floor (y_max); - font->ascent = font->y_max; - font->descent = font->y_min; - - xx = 0.001; - yx = 0.0; - xy = 0.0; - yy = 0.001; - p = cff_dict_get_operands (font->top_dict, FONTMATRIX_OP, &size); - if (p) { - end = p + size; - if (p < end) - p = decode_number (p, &xx); - if (p < end) - p = decode_number (p, &yx); - if (p < end) - p = decode_number (p, &xy); - if (p < end) - p = decode_number (p, &yy); - } - /* Freetype uses 1/abs(yy) to get units per EM */ - font->units_per_em = _cairo_round(1.0/fabs(yy)); -} - -static cairo_int_status_t -cairo_cff_font_read_top_dict (cairo_cff_font_t *font) -{ - cairo_array_t index; - cff_index_element_t *element; - unsigned char buf[20]; - unsigned char *end_buf; - unsigned char *operand; - cairo_int_status_t status; - unsigned char *p; - int size; - int offset; - - cff_index_init (&index); - status = cff_index_read (&index, &font->current_ptr, font->data_end); - if (unlikely (status)) - goto fail; - - element = _cairo_array_index (&index, 0); - status = cff_dict_read (font->top_dict, element->data, element->length); - if (unlikely (status)) - goto fail; - - if (cff_dict_get_operands (font->top_dict, ROS_OP, &size) != NULL) - font->is_cid = TRUE; - else - font->is_cid = FALSE; - - operand = cff_dict_get_operands (font->top_dict, CHARSTRINGS_OP, &size); - decode_integer (operand, &offset); - p = font->data + offset; - status = cff_index_read (&font->charstrings_index, &p, font->data_end); - if (unlikely (status)) - goto fail; - font->num_glyphs = _cairo_array_num_elements (&font->charstrings_index); - - if (font->is_cid) { - operand = cff_dict_get_operands (font->top_dict, CHARSET_OP, &size); - if (!operand) - return CAIRO_INT_STATUS_UNSUPPORTED; - - decode_integer (operand, &offset); - font->charset = font->data + offset; - if (font->charset >= font->data_end) - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - if (!font->is_opentype) - cairo_cff_font_read_font_metrics (font, font->top_dict); - - if (font->is_cid) { - operand = cff_dict_get_operands (font->top_dict, FDSELECT_OP, &size); - decode_integer (operand, &offset); - status = cairo_cff_font_read_fdselect (font, font->data + offset); - if (unlikely (status)) - goto fail; - - operand = cff_dict_get_operands (font->top_dict, FDARRAY_OP, &size); - decode_integer (operand, &offset); - status = cairo_cff_font_read_cid_fontdict (font, font->data + offset); - if (unlikely (status)) - goto fail; - } else { - operand = cff_dict_get_operands (font->top_dict, PRIVATE_OP, &size); - operand = decode_integer (operand, &size); - decode_integer (operand, &offset); - status = cairo_cff_font_read_private_dict (font, - font->private_dict, - &font->local_sub_index, - &font->local_sub_bias, - &font->local_subs_used, - &font->default_width, - &font->nominal_width, - font->data + offset, - size); - if (unlikely (status)) - goto fail; - } - - /* Use maximum sized encoding to reserve space for later modification. */ - end_buf = encode_integer_max (buf, 0); - status = cff_dict_set_operands (font->top_dict, - CHARSTRINGS_OP, buf, end_buf - buf); - if (unlikely (status)) - goto fail; - - status = cff_dict_set_operands (font->top_dict, - CHARSET_OP, buf, end_buf - buf); - if (unlikely (status)) - goto fail; - - if (font->scaled_font_subset->is_latin) { - status = cff_dict_set_operands (font->top_dict, - ENCODING_OP, buf, end_buf - buf); - if (unlikely (status)) - goto fail; - - /* Private has two operands - size and offset */ - end_buf = encode_integer_max (end_buf, 0); - cff_dict_set_operands (font->top_dict, PRIVATE_OP, buf, end_buf - buf); - if (unlikely (status)) - goto fail; - - } else { - status = cff_dict_set_operands (font->top_dict, - FDSELECT_OP, buf, end_buf - buf); - if (unlikely (status)) - goto fail; - - status = cff_dict_set_operands (font->top_dict, - FDARRAY_OP, buf, end_buf - buf); - if (unlikely (status)) - goto fail; - - cff_dict_remove (font->top_dict, ENCODING_OP); - cff_dict_remove (font->top_dict, PRIVATE_OP); - } - - /* Remove the unique identifier operators as the subsetted font is - * not the same is the original font. */ - cff_dict_remove (font->top_dict, UNIQUEID_OP); - cff_dict_remove (font->top_dict, XUID_OP); - -fail: - cff_index_fini (&index); - - return status; -} - -static cairo_int_status_t -cairo_cff_font_read_strings (cairo_cff_font_t *font) -{ - return cff_index_read (&font->strings_index, &font->current_ptr, font->data_end); -} - -static cairo_int_status_t -cairo_cff_font_read_global_subroutines (cairo_cff_font_t *font) -{ - cairo_int_status_t status; - int num_subs; - - status = cff_index_read (&font->global_sub_index, &font->current_ptr, font->data_end); - if (unlikely (status)) - return status; - - num_subs = _cairo_array_num_elements (&font->global_sub_index); - font->global_subs_used = calloc (num_subs, sizeof(cairo_bool_t)); - if (unlikely (font->global_subs_used == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - if (num_subs < 1240) - font->global_sub_bias = 107; - else if (num_subs < 33900) - font->global_sub_bias = 1131; - else - font->global_sub_bias = 32768; - - return CAIRO_STATUS_SUCCESS; -} - -typedef cairo_int_status_t -(*font_read_t) (cairo_cff_font_t *font); - -static const font_read_t font_read_funcs[] = { - cairo_cff_font_read_header, - cairo_cff_font_read_name, - cairo_cff_font_read_top_dict, - cairo_cff_font_read_strings, - cairo_cff_font_read_global_subroutines, -}; - -static cairo_int_status_t -cairo_cff_font_read_font (cairo_cff_font_t *font) -{ - cairo_int_status_t status; - unsigned int i; - - for (i = 0; i < ARRAY_LENGTH (font_read_funcs); i++) { - status = font_read_funcs[i] (font); - if (unlikely (status)) - return status; - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_cff_font_set_ros_strings (cairo_cff_font_t *font) -{ - cairo_status_t status; - unsigned char buf[30]; - unsigned char *p; - int sid1, sid2; - const char *registry = "Adobe"; - const char *ordering = "Identity"; - - sid1 = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index); - status = cff_index_append_copy (&font->strings_subset_index, - (unsigned char *)registry, - strlen(registry)); - if (unlikely (status)) - return status; - - sid2 = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index); - status = cff_index_append_copy (&font->strings_subset_index, - (unsigned char *)ordering, - strlen(ordering)); - if (unlikely (status)) - return status; - - p = encode_integer (buf, sid1); - p = encode_integer (p, sid2); - p = encode_integer (p, 0); - status = cff_dict_set_operands (font->top_dict, ROS_OP, buf, p - buf); - if (unlikely (status)) - return status; - - p = encode_integer (buf, font->scaled_font_subset->num_glyphs); - status = cff_dict_set_operands (font->top_dict, CIDCOUNT_OP, buf, p - buf); - if (unlikely (status)) - return status; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_cff_font_subset_dict_string(cairo_cff_font_t *font, - cairo_hash_table_t *dict, - int operator) -{ - int size; - unsigned char *p; - int sid; - unsigned char buf[100]; - cff_index_element_t *element; - cairo_status_t status; - - p = cff_dict_get_operands (dict, operator, &size); - if (!p) - return CAIRO_STATUS_SUCCESS; - - decode_integer (p, &sid); - if (sid < NUM_STD_STRINGS) - return CAIRO_STATUS_SUCCESS; - - element = _cairo_array_index (&font->strings_index, sid - NUM_STD_STRINGS); - sid = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index); - status = cff_index_append (&font->strings_subset_index, element->data, element->length); - if (unlikely (status)) - return status; - - p = encode_integer (buf, sid); - status = cff_dict_set_operands (dict, operator, buf, p - buf); - if (unlikely (status)) - return status; - - return CAIRO_STATUS_SUCCESS; -} - -static const int dict_strings[] = { - VERSION_OP, - NOTICE_OP, - COPYRIGHT_OP, - FULLNAME_OP, - FAMILYNAME_OP, - WEIGHT_OP, - POSTSCRIPT_OP, - BASEFONTNAME_OP, - FONTNAME_OP, -}; - -static cairo_status_t -cairo_cff_font_subset_dict_strings (cairo_cff_font_t *font, - cairo_hash_table_t *dict) -{ - cairo_status_t status; - unsigned int i; - - for (i = 0; i < ARRAY_LENGTH (dict_strings); i++) { - status = cairo_cff_font_subset_dict_string (font, dict, dict_strings[i]); - if (unlikely (status)) - return status; - } - - return CAIRO_STATUS_SUCCESS; -} - -static unsigned char * -type2_decode_integer (unsigned char *p, int *integer) -{ - if (*p == 28) { - *integer = p[1] << 8 | p[2]; - p += 3; - } else if (*p <= 246) { - *integer = *p++ - 139; - } else if (*p <= 250) { - *integer = (p[0] - 247) * 256 + p[1] + 108; - p += 2; - } else if (*p <= 254) { - *integer = -(p[0] - 251) * 256 - p[1] - 108; - p += 2; - } else { /* *p == 255 */ - /* 16.16 fixed-point number. The fraction is ignored. */ - *integer = (int16_t)((p[1] << 8) | p[2]); - p += 5; - } - return p; -} - -/* Type 2 charstring parser for finding calls to local or global - * subroutines. For non Opentype CFF fonts it also gets the glyph - * widths. - * - * When we find a subroutine operator, the subroutine is marked as in - * use and recursively followed. The subroutine number is the value on - * the top of the stack when the subroutine operator is executed. In - * most fonts the subroutine number is encoded in an integer - * immediately preceding the subroutine operator. However it is - * possible for the subroutine number on the stack to be the result of - * a computation (in which case there will be an operator preceding - * the subroutine operator). If this occurs, subroutine subsetting is - * disabled since we can't easily determine which subroutines are - * used. - * - * The width, if present, is the first integer in the charstring. The - * only way to confirm if the integer at the start of the charstring is - * the width is when the first stack clearing operator is parsed, - * check if there is an extra integer left over on the stack. - * - * When the first stack clearing operator is encountered - * type2_find_width is set to FALSE and type2_found_width is set to - * TRUE if an extra argument is found, otherwise FALSE. - */ -static cairo_status_t -cairo_cff_parse_charstring (cairo_cff_font_t *font, - unsigned char *charstring, int length, - int glyph_id, - cairo_bool_t need_width) -{ - unsigned char *p = charstring; - unsigned char *end = charstring + length; - int integer; - int hint_bytes; - int sub_num; - cff_index_element_t *element; - int fd; - - while (p < end) { - if (*p == 28 || *p >= 32) { - /* Integer value */ - p = type2_decode_integer (p, &integer); - font->type2_stack_size++; - font->type2_stack_top_value = integer; - font->type2_stack_top_is_int = TRUE; - if (!font->type2_seen_first_int) { - font->type2_width = integer; - font->type2_seen_first_int = TRUE; - } - } else if (*p == TYPE2_hstem || *p == TYPE2_vstem || - *p == TYPE2_hstemhm || *p == TYPE2_vstemhm) { - /* Hint operator. The number of hints declared by the - * operator depends on the size of the stack. */ - font->type2_stack_top_is_int = FALSE; - font->type2_num_hints += font->type2_stack_size/2; - if (font->type2_find_width && font->type2_stack_size % 2) - font->type2_found_width = TRUE; - - font->type2_stack_size = 0; - font->type2_find_width = FALSE; - p++; - } else if (*p == TYPE2_hintmask || *p == TYPE2_cntrmask) { - /* Hintmask operator. These operators are followed by a - * variable length mask where the length depends on the - * number of hints declared. The first time this is called - * it is also an implicit vstem if there are arguments on - * the stack. */ - if (font->type2_hintmask_bytes == 0) { - font->type2_stack_top_is_int = FALSE; - font->type2_num_hints += font->type2_stack_size/2; - if (font->type2_find_width && font->type2_stack_size % 2) - font->type2_found_width = TRUE; - - font->type2_stack_size = 0; - font->type2_find_width = FALSE; - font->type2_hintmask_bytes = (font->type2_num_hints+7)/8; - } - - hint_bytes = font->type2_hintmask_bytes; - p++; - p += hint_bytes; - } else if (*p == TYPE2_rmoveto) { - if (font->type2_find_width && font->type2_stack_size > 2) - font->type2_found_width = TRUE; - - font->type2_stack_size = 0; - font->type2_find_width = FALSE; - font->type2_has_path = TRUE; - p++; - } else if (*p == TYPE2_hmoveto || *p == TYPE2_vmoveto) { - if (font->type2_find_width && font->type2_stack_size > 1) - font->type2_found_width = TRUE; - - font->type2_stack_size = 0; - font->type2_find_width = FALSE; - font->type2_has_path = TRUE; - p++; - } else if (*p == TYPE2_endchar) { - if (!font->type2_has_path && font->type2_stack_size > 3) - return CAIRO_INT_STATUS_UNSUPPORTED; /* seac (Ref Appendix C of Type 2 Charstring Format */ - - if (font->type2_find_width && font->type2_stack_size > 0) - font->type2_found_width = TRUE; - - return CAIRO_STATUS_SUCCESS; - } else if (*p == TYPE2_callsubr) { - /* call to local subroutine */ - if (! font->type2_stack_top_is_int) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (++font->type2_nesting_level > MAX_SUBROUTINE_NESTING) - return CAIRO_INT_STATUS_UNSUPPORTED; - - p++; - font->type2_stack_top_is_int = FALSE; - font->type2_stack_size--; - if (font->type2_find_width && font->type2_stack_size == 0) - font->type2_seen_first_int = FALSE; - - if (font->is_cid) { - fd = font->fdselect[glyph_id]; - sub_num = font->type2_stack_top_value + font->fd_local_sub_bias[fd]; - element = _cairo_array_index (&font->fd_local_sub_index[fd], sub_num); - if (! font->fd_local_subs_used[fd][sub_num]) { - font->fd_local_subs_used[fd][sub_num] = TRUE; - cairo_cff_parse_charstring (font, element->data, element->length, glyph_id, need_width); - } - } else { - sub_num = font->type2_stack_top_value + font->local_sub_bias; - element = _cairo_array_index (&font->local_sub_index, sub_num); - if (! font->local_subs_used[sub_num] || - (need_width && !font->type2_found_width)) - { - font->local_subs_used[sub_num] = TRUE; - cairo_cff_parse_charstring (font, element->data, element->length, glyph_id, need_width); - } - } - font->type2_nesting_level--; - } else if (*p == TYPE2_callgsubr) { - /* call to global subroutine */ - if (! font->type2_stack_top_is_int) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (++font->type2_nesting_level > MAX_SUBROUTINE_NESTING) - return CAIRO_INT_STATUS_UNSUPPORTED; - - p++; - font->type2_stack_size--; - font->type2_stack_top_is_int = FALSE; - if (font->type2_find_width && font->type2_stack_size == 0) - font->type2_seen_first_int = FALSE; - - sub_num = font->type2_stack_top_value + font->global_sub_bias; - element = _cairo_array_index (&font->global_sub_index, sub_num); - if (! font->global_subs_used[sub_num] || - (need_width && !font->type2_found_width)) - { - font->global_subs_used[sub_num] = TRUE; - cairo_cff_parse_charstring (font, element->data, element->length, glyph_id, need_width); - } - font->type2_nesting_level--; - } else if (*p == 12) { - /* 2 byte instruction */ - - /* All the 2 byte operators are either not valid before a - * stack clearing operator or they are one of the - * arithmetic, storage, or conditional operators. */ - if (need_width && font->type2_find_width) - return CAIRO_INT_STATUS_UNSUPPORTED; - - p += 2; - font->type2_stack_top_is_int = FALSE; - } else { - /* 1 byte instruction */ - p++; - font->type2_stack_top_is_int = FALSE; - } - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_cff_find_width_and_subroutines_used (cairo_cff_font_t *font, - unsigned char *charstring, int length, - int glyph_id, int subset_id) -{ - cairo_status_t status; - int width; - int fd; - - font->type2_stack_size = 0; - font->type2_stack_top_value = 0;; - font->type2_stack_top_is_int = FALSE; - font->type2_num_hints = 0; - font->type2_hintmask_bytes = 0; - font->type2_nesting_level = 0; - font->type2_seen_first_int = FALSE; - font->type2_find_width = TRUE; - font->type2_found_width = FALSE; - font->type2_width = 0; - font->type2_has_path = FALSE; - - status = cairo_cff_parse_charstring (font, charstring, length, glyph_id, TRUE); - if (status) - return status; - - if (!font->is_opentype) { - if (font->is_cid) { - fd = font->fdselect[glyph_id]; - if (font->type2_found_width) - width = font->fd_nominal_width[fd] + font->type2_width; - else - width = font->fd_default_width[fd]; - } else { - if (font->type2_found_width) - width = font->nominal_width + font->type2_width; - else - width = font->default_width; - } - font->widths[subset_id] = width; - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -cairo_cff_font_get_gid_for_cid (cairo_cff_font_t *font, unsigned long cid, unsigned long *gid) -{ - unsigned char *p; - unsigned long first_gid; - unsigned long first_cid; - int num_left; - unsigned long c, g; - - if (cid == 0) { - *gid = 0; - return CAIRO_STATUS_SUCCESS; - } - - switch (font->charset[0]) { - /* Format 0 */ - case 0: - p = font->charset + 1; - g = 1; - while (g <= (unsigned)font->num_glyphs && p < font->data_end) { - c = get_unaligned_be16 (p); - if (c == cid) { - *gid = g; - return CAIRO_STATUS_SUCCESS; - } - g++; - p += 2; - } - break; - - /* Format 1 */ - case 1: - first_gid = 1; - p = font->charset + 1; - while (first_gid <= (unsigned)font->num_glyphs && p + 2 < font->data_end) { - first_cid = get_unaligned_be16 (p); - num_left = p[2]; - if (cid >= first_cid && cid <= first_cid + num_left) { - *gid = first_gid + cid - first_cid; - return CAIRO_STATUS_SUCCESS; - } - first_gid += num_left + 1; - p += 3; - } - break; - - /* Format 2 */ - case 2: - first_gid = 1; - p = font->charset + 1; - while (first_gid <= (unsigned)font->num_glyphs && p + 3 < font->data_end) { - first_cid = get_unaligned_be16 (p); - num_left = get_unaligned_be16 (p+2); - if (cid >= first_cid && cid <= first_cid + num_left) { - *gid = first_gid + cid - first_cid; - return CAIRO_STATUS_SUCCESS; - } - first_gid += num_left + 1; - p += 4; - } - break; - - default: - break; - } - return CAIRO_INT_STATUS_UNSUPPORTED; -} - -static cairo_int_status_t -cairo_cff_font_subset_charstrings_and_subroutines (cairo_cff_font_t *font) -{ - cff_index_element_t *element; - unsigned int i; - cairo_int_status_t status; - unsigned long glyph, cid; - - font->subset_subroutines = TRUE; - for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) { - if (font->is_cid) { - cid = font->scaled_font_subset->glyphs[i]; - status = cairo_cff_font_get_gid_for_cid (font, cid, &glyph); - if (unlikely (status)) - return status; - } else { - glyph = font->scaled_font_subset->glyphs[i]; - } - element = _cairo_array_index (&font->charstrings_index, glyph); - status = cff_index_append (&font->charstrings_subset_index, - element->data, - element->length); - if (unlikely (status)) - return status; - - if (font->subset_subroutines) { - status = cairo_cff_find_width_and_subroutines_used (font, - element->data, element->length, - glyph, i); - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - /* If parsing the charstrings fails we embed all the - * subroutines. But if the font is not opentype we - * need to successfully parse all charstrings to get - * the widths. */ - font->subset_subroutines = FALSE; - if (!font->is_opentype) - return status; - } else if (unlikely (status)) { - return status; - } - } - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_cff_font_subset_fontdict (cairo_cff_font_t *font) -{ - unsigned int i; - int fd; - int *reverse_map; - unsigned long cid, gid; - cairo_int_status_t status; - - font->fdselect_subset = calloc (font->scaled_font_subset->num_glyphs, - sizeof (int)); - if (unlikely (font->fdselect_subset == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - font->fd_subset_map = calloc (font->num_fontdicts, sizeof (int)); - if (unlikely (font->fd_subset_map == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - font->private_dict_offset = calloc (font->num_fontdicts, sizeof (int)); - if (unlikely (font->private_dict_offset == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - reverse_map = calloc (font->num_fontdicts, sizeof (int)); - if (unlikely (reverse_map == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - for (i = 0; i < font->num_fontdicts; i++) - reverse_map[i] = -1; - - font->num_subset_fontdicts = 0; - for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) { - cid = font->scaled_font_subset->glyphs[i]; - status = cairo_cff_font_get_gid_for_cid (font, cid, &gid); - if (unlikely (status)) { - free (reverse_map); - return status; - } - - fd = font->fdselect[gid]; - if (reverse_map[fd] < 0) { - font->fd_subset_map[font->num_subset_fontdicts] = fd; - reverse_map[fd] = font->num_subset_fontdicts++; - } - font->fdselect_subset[i] = reverse_map[fd]; - } - - free (reverse_map); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_cff_font_create_cid_fontdict (cairo_cff_font_t *font) -{ - unsigned char buf[100]; - unsigned char *end_buf; - cairo_status_t status; - - font->num_fontdicts = 1; - font->fd_dict = malloc (sizeof (cairo_hash_table_t *)); - if (unlikely (font->fd_dict == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - if (cff_dict_init (&font->fd_dict[0])) { - free (font->fd_dict); - font->fd_dict = NULL; - font->num_fontdicts = 0; - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - font->fd_subset_map = malloc (sizeof (int)); - if (unlikely (font->fd_subset_map == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - font->private_dict_offset = malloc (sizeof (int)); - if (unlikely (font->private_dict_offset == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - font->fd_subset_map[0] = 0; - font->num_subset_fontdicts = 1; - - /* Set integer operand to max value to use max size encoding to reserve - * space for any value later */ - end_buf = encode_integer_max (buf, 0); - end_buf = encode_integer_max (end_buf, 0); - status = cff_dict_set_operands (font->fd_dict[0], PRIVATE_OP, buf, end_buf - buf); - if (unlikely (status)) - return status; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_cff_font_subset_strings (cairo_cff_font_t *font) -{ - cairo_status_t status; - unsigned int i; - - status = cairo_cff_font_subset_dict_strings (font, font->top_dict); - if (unlikely (status)) - return status; - - if (font->is_cid) { - for (i = 0; i < font->num_subset_fontdicts; i++) { - status = cairo_cff_font_subset_dict_strings (font, font->fd_dict[font->fd_subset_map[i]]); - if (unlikely (status)) - return status; - - status = cairo_cff_font_subset_dict_strings (font, font->fd_private_dict[font->fd_subset_map[i]]); - if (unlikely (status)) - return status; - } - } else { - status = cairo_cff_font_subset_dict_strings (font, font->private_dict); - } - - return status; -} - -/* The Euro is the only the only character in the winansi encoding - * with a glyph name that is not a CFF standard string. As the strings - * are written before the charset, we need to check during the - * subsetting phase if the Euro glyph is required and add the - * glyphname to the list of strings to write out. - */ -static cairo_status_t -cairo_cff_font_add_euro_charset_string (cairo_cff_font_t *font) -{ - cairo_status_t status; - unsigned int i; - int ch; - const char *euro = "Euro"; - - for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) { - ch = font->scaled_font_subset->to_latin_char[i]; - if (ch == 128) { - font->euro_sid = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index); - status = cff_index_append_copy (&font->strings_subset_index, - (unsigned char *)euro, strlen(euro)); - return status; - } - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_cff_font_subset_font (cairo_cff_font_t *font) -{ - cairo_status_t status; - - if (!font->scaled_font_subset->is_latin) { - status = cairo_cff_font_set_ros_strings (font); - if (unlikely (status)) - return status; - } - - status = cairo_cff_font_subset_charstrings_and_subroutines (font); - if (unlikely (status)) - return status; - - if (!font->scaled_font_subset->is_latin) { - if (font->is_cid) - status = cairo_cff_font_subset_fontdict (font); - else - status = cairo_cff_font_create_cid_fontdict (font); - if (unlikely (status)) - return status; - } else { - font->private_dict_offset = malloc (sizeof (int)); - if (unlikely (font->private_dict_offset == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - status = cairo_cff_font_subset_strings (font); - if (unlikely (status)) - return status; - - if (font->scaled_font_subset->is_latin) - status = cairo_cff_font_add_euro_charset_string (font); - - return status; -} - -/* Set the operand of the specified operator in the (already written) - * top dict to point to the current position in the output - * array. Operands updated with this function must have previously - * been encoded with the 5-byte (max) integer encoding. */ -static void -cairo_cff_font_set_topdict_operator_to_cur_pos (cairo_cff_font_t *font, - int operator) -{ - int cur_pos; - int offset; - int size; - unsigned char buf[10]; - unsigned char *buf_end; - unsigned char *op_ptr; - - cur_pos = _cairo_array_num_elements (&font->output); - buf_end = encode_integer_max (buf, cur_pos); - offset = cff_dict_get_location (font->top_dict, operator, &size); - assert (offset > 0); - op_ptr = _cairo_array_index (&font->output, offset); - memcpy (op_ptr, buf, buf_end - buf); -} - -static cairo_status_t -cairo_cff_font_write_header (cairo_cff_font_t *font) -{ - return _cairo_array_append_multiple (&font->output, - font->header, - font->header->header_size); -} - -static cairo_status_t -cairo_cff_font_write_name (cairo_cff_font_t *font) -{ - cairo_status_t status = CAIRO_STATUS_SUCCESS; - cairo_array_t index; - - cff_index_init (&index); - - status = cff_index_append_copy (&index, - (unsigned char *) font->ps_name, - strlen(font->ps_name)); - if (unlikely (status)) - goto FAIL; - - status = cff_index_write (&index, &font->output); - if (unlikely (status)) - goto FAIL; - -FAIL: - cff_index_fini (&index); - - return status; -} - -static cairo_status_t -cairo_cff_font_write_top_dict (cairo_cff_font_t *font) -{ - uint16_t count; - unsigned char buf[10]; - unsigned char *p; - int offset_index; - int dict_start, dict_size; - int offset_size = 4; - cairo_status_t status; - - /* Write an index containing the top dict */ - - count = cpu_to_be16 (1); - status = _cairo_array_append_multiple (&font->output, &count, 2); - if (unlikely (status)) - return status; - buf[0] = offset_size; - status = _cairo_array_append (&font->output, buf); - if (unlikely (status)) - return status; - encode_index_offset (buf, offset_size, 1); - status = _cairo_array_append_multiple (&font->output, buf, offset_size); - if (unlikely (status)) - return status; - - /* Reserve space for last element of offset array and update after - * dict is written */ - offset_index = _cairo_array_num_elements (&font->output); - status = _cairo_array_append_multiple (&font->output, buf, offset_size); - if (unlikely (status)) - return status; - - dict_start = _cairo_array_num_elements (&font->output); - status = cff_dict_write (font->top_dict, &font->output); - if (unlikely (status)) - return status; - dict_size = _cairo_array_num_elements (&font->output) - dict_start; - - encode_index_offset (buf, offset_size, dict_size + 1); - p = _cairo_array_index (&font->output, offset_index); - memcpy (p, buf, offset_size); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_cff_font_write_strings (cairo_cff_font_t *font) -{ - return cff_index_write (&font->strings_subset_index, &font->output); -} - -static cairo_status_t -cairo_cff_font_write_global_subrs (cairo_cff_font_t *font) -{ - unsigned int i; - unsigned char return_op = TYPE2_return; - - /* poppler and fontforge don't like zero length subroutines so we - * replace unused subroutines with a 'return' instruction. */ - if (font->subset_subroutines) { - for (i = 0; i < _cairo_array_num_elements (&font->global_sub_index); i++) { - if (! font->global_subs_used[i]) - cff_index_set_object (&font->global_sub_index, i, &return_op, 1); - } - } - - return cff_index_write (&font->global_sub_index, &font->output); -} - -static cairo_status_t -cairo_cff_font_write_encoding (cairo_cff_font_t *font) -{ - unsigned char buf[2]; - cairo_status_t status; - unsigned int i; - - cairo_cff_font_set_topdict_operator_to_cur_pos (font, ENCODING_OP); - buf[0] = 0; /* Format 0 */ - buf[1] = font->scaled_font_subset->num_glyphs - 1; - status = _cairo_array_append_multiple (&font->output, buf, 2); - if (unlikely (status)) - return status; - - for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) { - unsigned char ch = font->scaled_font_subset->to_latin_char[i]; - status = _cairo_array_append (&font->output, &ch); - if (unlikely (status)) - return status; - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_cff_font_write_fdselect (cairo_cff_font_t *font) -{ - unsigned char data; - unsigned int i; - cairo_int_status_t status; - - cairo_cff_font_set_topdict_operator_to_cur_pos (font, FDSELECT_OP); - - if (font->is_cid) { - data = 0; - status = _cairo_array_append (&font->output, &data); - if (unlikely (status)) - return status; - - for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) { - data = font->fdselect_subset[i]; - status = _cairo_array_append (&font->output, &data); - if (unlikely (status)) - return status; - } - } else { - unsigned char byte; - uint16_t word; - - status = _cairo_array_grow_by (&font->output, 9); - if (unlikely (status)) - return status; - - byte = 3; - status = _cairo_array_append (&font->output, &byte); - assert (status == CAIRO_INT_STATUS_SUCCESS); - - word = cpu_to_be16 (1); - status = _cairo_array_append_multiple (&font->output, &word, 2); - assert (status == CAIRO_INT_STATUS_SUCCESS); - - word = cpu_to_be16 (0); - status = _cairo_array_append_multiple (&font->output, &word, 2); - assert (status == CAIRO_INT_STATUS_SUCCESS); - - byte = 0; - status = _cairo_array_append (&font->output, &byte); - assert (status == CAIRO_INT_STATUS_SUCCESS); - - word = cpu_to_be16 (font->scaled_font_subset->num_glyphs); - status = _cairo_array_append_multiple (&font->output, &word, 2); - assert (status == CAIRO_INT_STATUS_SUCCESS); - } - - return CAIRO_STATUS_SUCCESS; -} - -/* Winansi to CFF standard strings mapping for characters 128 to 255 */ -static const int winansi_to_cff_std_string[] = { - /* 128 */ - 0, 0, 117, 101, 118, 121, 112, 113, - 126, 122, 192, 107, 142, 0, 199, 0, - /* 144 */ - 0, 65, 8, 105, 119, 116, 111, 137, - 127, 153, 221, 108, 148, 0, 228, 198, - /* 160 */ - 0, 96, 97, 98, 103, 100, 160, 102, - 131, 170, 139, 106, 151, 0, 165, 128, - /* 176 */ - 161, 156, 164, 169, 125, 152, 115, 114, - 133, 150, 143, 120, 158, 155, 163, 123, - /* 192 */ - 174, 171, 172, 176, 173, 175, 138, 177, - 181, 178, 179, 180, 185, 182, 183, 184, - /* 208 */ - 154, 186, 190, 187, 188, 191, 189, 168, - 141, 196, 193, 194, 195, 197, 157, 149, - /* 224 */ - 203, 200, 201, 205, 202, 204, 144, 206, - 210, 207, 208, 209, 214, 211, 212, 213, - /* 240 */ - 167, 215, 219, 216, 217, 220, 218, 159, - 147, 225, 222, 223, 224, 226, 162, 227, -}; - -static int -cairo_cff_font_get_sid_for_winansi_char (cairo_cff_font_t *font, int ch) -{ - int sid; - - if (ch == 39) { - sid = 104; - - } else if (ch == 96) { - sid = 124; - - } else if (ch >= 32 && ch <= 126) { - sid = ch - 31; - - } else if (ch == 128) { - assert (font->euro_sid >= NUM_STD_STRINGS); - sid = font->euro_sid; - - } else if (ch >= 128 && ch <= 255) { - sid = winansi_to_cff_std_string[ch - 128]; - - } else { - sid = 0; - } - - return sid; -} - -static cairo_status_t -cairo_cff_font_write_type1_charset (cairo_cff_font_t *font) -{ - unsigned char format = 0; - unsigned int i; - int ch, sid; - cairo_status_t status; - uint16_t sid_be16; - - cairo_cff_font_set_topdict_operator_to_cur_pos (font, CHARSET_OP); - status = _cairo_array_append (&font->output, &format); - if (unlikely (status)) - return status; - - for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) { - ch = font->scaled_font_subset->to_latin_char[i]; - sid = cairo_cff_font_get_sid_for_winansi_char (font, ch); - if (unlikely (status)) - return status; - - sid_be16 = cpu_to_be16(sid); - status = _cairo_array_append_multiple (&font->output, &sid_be16, sizeof(sid_be16)); - if (unlikely (status)) - return status; - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_cff_font_write_cid_charset (cairo_cff_font_t *font) -{ - unsigned char byte; - uint16_t word; - cairo_status_t status; - - cairo_cff_font_set_topdict_operator_to_cur_pos (font, CHARSET_OP); - status = _cairo_array_grow_by (&font->output, 5); - if (unlikely (status)) - return status; - - byte = 2; - status = _cairo_array_append (&font->output, &byte); - assert (status == CAIRO_STATUS_SUCCESS); - - word = cpu_to_be16 (1); - status = _cairo_array_append_multiple (&font->output, &word, 2); - assert (status == CAIRO_STATUS_SUCCESS); - - word = cpu_to_be16 (font->scaled_font_subset->num_glyphs - 2); - status = _cairo_array_append_multiple (&font->output, &word, 2); - assert (status == CAIRO_STATUS_SUCCESS); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_cff_font_write_charstrings (cairo_cff_font_t *font) -{ - cairo_cff_font_set_topdict_operator_to_cur_pos (font, CHARSTRINGS_OP); - - return cff_index_write (&font->charstrings_subset_index, &font->output); -} - -static cairo_status_t -cairo_cff_font_write_cid_fontdict (cairo_cff_font_t *font) -{ - unsigned int i; - cairo_int_status_t status; - unsigned int offset_array; - unsigned char *offset_array_ptr; - int offset_base; - uint16_t count; - uint8_t offset_size = 4; - - cairo_cff_font_set_topdict_operator_to_cur_pos (font, FDARRAY_OP); - count = cpu_to_be16 (font->num_subset_fontdicts); - status = _cairo_array_append_multiple (&font->output, &count, sizeof (uint16_t)); - if (unlikely (status)) - return status; - status = _cairo_array_append (&font->output, &offset_size); - if (unlikely (status)) - return status; - - offset_array = _cairo_array_num_elements (&font->output); - status = _cairo_array_allocate (&font->output, - (font->num_subset_fontdicts + 1)*offset_size, - (void **) &offset_array_ptr); - if (unlikely (status)) - return status; - offset_base = _cairo_array_num_elements (&font->output) - 1; - put_unaligned_be32(1, offset_array_ptr); - offset_array += sizeof(uint32_t); - for (i = 0; i < font->num_subset_fontdicts; i++) { - status = cff_dict_write (font->fd_dict[font->fd_subset_map[i]], - &font->output); - if (unlikely (status)) - return status; - - offset_array_ptr = _cairo_array_index (&font->output, offset_array); - put_unaligned_be32 (_cairo_array_num_elements (&font->output) - offset_base, - offset_array_ptr); - offset_array += sizeof(uint32_t); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_cff_font_write_private_dict (cairo_cff_font_t *font, - int dict_num, - cairo_hash_table_t *parent_dict, - cairo_hash_table_t *private_dict) -{ - int offset; - int size; - unsigned char buf[10]; - unsigned char *buf_end; - unsigned char *p; - cairo_status_t status; - - /* Write private dict and update offset and size in top dict */ - font->private_dict_offset[dict_num] = _cairo_array_num_elements (&font->output); - status = cff_dict_write (private_dict, &font->output); - if (unlikely (status)) - return status; - - size = _cairo_array_num_elements (&font->output) - font->private_dict_offset[dict_num]; - /* private entry has two operands - size and offset */ - buf_end = encode_integer_max (buf, size); - buf_end = encode_integer_max (buf_end, font->private_dict_offset[dict_num]); - offset = cff_dict_get_location (parent_dict, PRIVATE_OP, &size); - assert (offset > 0); - p = _cairo_array_index (&font->output, offset); - memcpy (p, buf, buf_end - buf); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_cff_font_write_local_sub (cairo_cff_font_t *font, - int dict_num, - cairo_hash_table_t *private_dict, - cairo_array_t *local_sub_index, - cairo_bool_t *local_subs_used) -{ - int offset; - int size; - unsigned char buf[10]; - unsigned char *buf_end; - unsigned char *p; - cairo_status_t status; - unsigned int i; - unsigned char return_op = TYPE2_return; - - if (_cairo_array_num_elements (local_sub_index) > 0) { - /* Write local subroutines and update offset in private - * dict. Local subroutines offset is relative to start of - * private dict */ - offset = _cairo_array_num_elements (&font->output) - font->private_dict_offset[dict_num]; - buf_end = encode_integer_max (buf, offset); - offset = cff_dict_get_location (private_dict, LOCAL_SUB_OP, &size); - assert (offset > 0); - p = _cairo_array_index (&font->output, offset); - memcpy (p, buf, buf_end - buf); - - /* poppler and fontforge don't like zero length subroutines so - * we replace unused subroutines with a 'return' instruction. - */ - if (font->subset_subroutines) { - for (i = 0; i < _cairo_array_num_elements (local_sub_index); i++) { - if (! local_subs_used[i]) - cff_index_set_object (local_sub_index, i, &return_op, 1); - } - } - status = cff_index_write (local_sub_index, &font->output); - if (unlikely (status)) - return status; - } - - return CAIRO_STATUS_SUCCESS; -} - - -static cairo_status_t -cairo_cff_font_write_cid_private_dict_and_local_sub (cairo_cff_font_t *font) -{ - unsigned int i; - cairo_int_status_t status; - - if (font->is_cid) { - for (i = 0; i < font->num_subset_fontdicts; i++) { - status = cairo_cff_font_write_private_dict ( - font, - i, - font->fd_dict[font->fd_subset_map[i]], - font->fd_private_dict[font->fd_subset_map[i]]); - if (unlikely (status)) - return status; - } - - for (i = 0; i < font->num_subset_fontdicts; i++) { - status = cairo_cff_font_write_local_sub ( - font, - i, - font->fd_private_dict[font->fd_subset_map[i]], - &font->fd_local_sub_index[font->fd_subset_map[i]], - font->fd_local_subs_used[font->fd_subset_map[i]]); - if (unlikely (status)) - return status; - } - } else { - status = cairo_cff_font_write_private_dict (font, - 0, - font->fd_dict[0], - font->private_dict); - if (unlikely (status)) - return status; - - status = cairo_cff_font_write_local_sub (font, - 0, - font->private_dict, - &font->local_sub_index, - font->local_subs_used); - if (unlikely (status)) - return status; - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_cff_font_write_type1_private_dict_and_local_sub (cairo_cff_font_t *font) -{ - cairo_int_status_t status; - - status = cairo_cff_font_write_private_dict (font, - 0, - font->top_dict, - font->private_dict); - if (unlikely (status)) - return status; - - status = cairo_cff_font_write_local_sub (font, - 0, - font->private_dict, - &font->local_sub_index, - font->local_subs_used); - if (unlikely (status)) - return status; - - return CAIRO_STATUS_SUCCESS; -} - - -typedef cairo_status_t -(*font_write_t) (cairo_cff_font_t *font); - -static const font_write_t font_write_cid_funcs[] = { - cairo_cff_font_write_header, - cairo_cff_font_write_name, - cairo_cff_font_write_top_dict, - cairo_cff_font_write_strings, - cairo_cff_font_write_global_subrs, - cairo_cff_font_write_cid_charset, - cairo_cff_font_write_fdselect, - cairo_cff_font_write_charstrings, - cairo_cff_font_write_cid_fontdict, - cairo_cff_font_write_cid_private_dict_and_local_sub, -}; - -static const font_write_t font_write_type1_funcs[] = { - cairo_cff_font_write_header, - cairo_cff_font_write_name, - cairo_cff_font_write_top_dict, - cairo_cff_font_write_strings, - cairo_cff_font_write_global_subrs, - cairo_cff_font_write_encoding, - cairo_cff_font_write_type1_charset, - cairo_cff_font_write_charstrings, - cairo_cff_font_write_type1_private_dict_and_local_sub, -}; - -static cairo_status_t -cairo_cff_font_write_subset (cairo_cff_font_t *font) -{ - cairo_int_status_t status; - unsigned int i; - - if (font->scaled_font_subset->is_latin) { - for (i = 0; i < ARRAY_LENGTH (font_write_type1_funcs); i++) { - status = font_write_type1_funcs[i] (font); - if (unlikely (status)) - return status; - } - } else { - for (i = 0; i < ARRAY_LENGTH (font_write_cid_funcs); i++) { - status = font_write_cid_funcs[i] (font); - if (unlikely (status)) - return status; - } - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -cairo_cff_font_generate (cairo_cff_font_t *font, - const char **data, - unsigned long *length) -{ - cairo_int_status_t status; - - status = cairo_cff_font_read_font (font); - if (unlikely (status)) - return status; - - /* If the PS name is not found, create a CairoFont-x-y name. */ - if (font->ps_name == NULL) { - font->ps_name = malloc (30); - if (unlikely (font->ps_name == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - snprintf(font->ps_name, 30, "CairoFont-%u-%u", - font->scaled_font_subset->font_id, - font->scaled_font_subset->subset_id); - } - - status = cairo_cff_font_subset_font (font); - if (unlikely (status)) - return status; - - status = cairo_cff_font_write_subset (font); - if (unlikely (status)) - return status; - - - *data = _cairo_array_index (&font->output, 0); - *length = _cairo_array_num_elements (&font->output); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -cairo_cff_font_create_set_widths (cairo_cff_font_t *font) -{ - unsigned long size; - unsigned long long_entry_size; - unsigned long short_entry_size; - unsigned int i; - tt_hhea_t hhea; - int num_hmetrics; - uint16_t short_entry; - int glyph_index; - cairo_int_status_t status; - - size = sizeof (tt_hhea_t); - status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - TT_TAG_hhea, 0, - (unsigned char*) &hhea, &size); - if (unlikely (status)) - return status; - num_hmetrics = be16_to_cpu (hhea.num_hmetrics); - - for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) { - glyph_index = font->scaled_font_subset->glyphs[i]; - long_entry_size = 2 * sizeof (int16_t); - short_entry_size = sizeof (int16_t); - if (glyph_index < num_hmetrics) { - status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - TT_TAG_hmtx, - glyph_index * long_entry_size, - (unsigned char *) &short_entry, - &short_entry_size); - if (unlikely (status)) - return status; - } - else - { - status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - TT_TAG_hmtx, - (num_hmetrics - 1) * long_entry_size, - (unsigned char *) &short_entry, - &short_entry_size); - if (unlikely (status)) - return status; - } - font->widths[i] = be16_to_cpu (short_entry); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_bool_t -check_fontdata_is_cff (const unsigned char *data, long length) -{ - cff_header_t *header; - - if (length < (long)sizeof (cff_header_t)) - return FALSE; - - header = (cff_header_t *) data; - if (header->major == 1 && - header->minor == 0 && - header->header_size == 4) - { - return TRUE; - } - - return FALSE; -} - -static cairo_int_status_t -_cairo_cff_font_load_opentype_cff (cairo_cff_font_t *font) -{ - const cairo_scaled_font_backend_t *backend = font->backend; - cairo_status_t status; - tt_head_t head; - tt_hhea_t hhea; - unsigned long size, data_length; - - if (!backend->load_truetype_table) - return CAIRO_INT_STATUS_UNSUPPORTED; - - data_length = 0; - status = backend->load_truetype_table (font->scaled_font_subset->scaled_font, - TT_TAG_CFF, 0, NULL, &data_length); - if (status) - return status; - - size = sizeof (tt_head_t); - status = backend->load_truetype_table (font->scaled_font_subset->scaled_font, - TT_TAG_head, 0, - (unsigned char *) &head, &size); - if (unlikely (status)) - return status; - - size = sizeof (tt_hhea_t); - status = backend->load_truetype_table (font->scaled_font_subset->scaled_font, - TT_TAG_hhea, 0, - (unsigned char *) &hhea, &size); - if (unlikely (status)) - return status; - - size = 0; - status = backend->load_truetype_table (font->scaled_font_subset->scaled_font, - TT_TAG_hmtx, 0, NULL, &size); - if (unlikely (status)) - return status; - - font->x_min = (int16_t) be16_to_cpu (head.x_min); - font->y_min = (int16_t) be16_to_cpu (head.y_min); - font->x_max = (int16_t) be16_to_cpu (head.x_max); - font->y_max = (int16_t) be16_to_cpu (head.y_max); - font->ascent = (int16_t) be16_to_cpu (hhea.ascender); - font->descent = (int16_t) be16_to_cpu (hhea.descender); - font->units_per_em = (int16_t) be16_to_cpu (head.units_per_em); - if (font->units_per_em == 0) - font->units_per_em = 1000; - - font->font_name = NULL; - status = _cairo_truetype_read_font_name (font->scaled_font_subset->scaled_font, - &font->ps_name, - &font->font_name); - if (_cairo_status_is_error (status)) - return status; - - font->is_opentype = TRUE; - font->data_length = data_length; - font->data = malloc (data_length); - if (unlikely (font->data == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - TT_TAG_CFF, 0, font->data, - &font->data_length); - if (unlikely (status)) - return status; - - if (!check_fontdata_is_cff (font->data, data_length)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_cff_font_load_cff (cairo_cff_font_t *font) -{ - const cairo_scaled_font_backend_t *backend = font->backend; - cairo_status_t status; - unsigned long data_length; - - if (!backend->load_type1_data) - return CAIRO_INT_STATUS_UNSUPPORTED; - - data_length = 0; - status = backend->load_type1_data (font->scaled_font_subset->scaled_font, - 0, NULL, &data_length); - if (unlikely (status)) - return status; - - font->font_name = NULL; - font->is_opentype = FALSE; - font->data_length = data_length; - font->data = malloc (data_length); - if (unlikely (font->data == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - status = font->backend->load_type1_data (font->scaled_font_subset->scaled_font, - 0, font->data, &font->data_length); - if (unlikely (status)) - return status; - - if (!check_fontdata_is_cff (font->data, data_length)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset, - cairo_cff_font_t **font_return, - const char *subset_name) -{ - const cairo_scaled_font_backend_t *backend; - cairo_int_status_t status; - cairo_cff_font_t *font; - - backend = scaled_font_subset->scaled_font->backend; - - /* We need to use a fallback font generated from the synthesized outlines. */ - if (backend->is_synthetic && backend->is_synthetic (scaled_font_subset->scaled_font)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - font = calloc (1, sizeof (cairo_cff_font_t)); - if (unlikely (font == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - font->backend = backend; - font->scaled_font_subset = scaled_font_subset; - - status = _cairo_cff_font_load_opentype_cff (font); - if (status == CAIRO_INT_STATUS_UNSUPPORTED) - status = _cairo_cff_font_load_cff (font); - if (status) - goto fail1; - - font->data_end = font->data + font->data_length; - _cairo_array_init (&font->output, sizeof (char)); - status = _cairo_array_grow_by (&font->output, 4096); - if (unlikely (status)) - goto fail2; - - font->subset_font_name = strdup (subset_name); - if (unlikely (font->subset_font_name == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail2; - } - - font->widths = calloc (font->scaled_font_subset->num_glyphs, sizeof (int)); - if (unlikely (font->widths == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail3; - } - - if (font->is_opentype) { - status = cairo_cff_font_create_set_widths (font); - if (unlikely (status)) - goto fail4; - } - - status = cff_dict_init (&font->top_dict); - if (unlikely (status)) - goto fail4; - - status = cff_dict_init (&font->private_dict); - if (unlikely (status)) - goto fail5; - - cff_index_init (&font->strings_index); - cff_index_init (&font->charstrings_index); - cff_index_init (&font->global_sub_index); - cff_index_init (&font->local_sub_index); - cff_index_init (&font->charstrings_subset_index); - cff_index_init (&font->strings_subset_index); - font->euro_sid = 0; - font->fdselect = NULL; - font->fd_dict = NULL; - font->fd_private_dict = NULL; - font->fd_local_sub_index = NULL; - font->fd_local_sub_bias = NULL; - font->fdselect_subset = NULL; - font->fd_subset_map = NULL; - font->private_dict_offset = NULL; - font->global_subs_used = NULL; - font->local_subs_used = NULL; - font->fd_local_subs_used = NULL; - - *font_return = font; - - return CAIRO_STATUS_SUCCESS; - -fail5: - _cairo_hash_table_destroy (font->top_dict); -fail4: - free (font->widths); -fail3: - free (font->subset_font_name); -fail2: - free (font->ps_name); - _cairo_array_fini (&font->output); -fail1: - free (font->data); - free (font->font_name); - free (font); - - return status; -} - -static void -cairo_cff_font_destroy (cairo_cff_font_t *font) -{ - unsigned int i; - - free (font->widths); - free (font->font_name); - free (font->ps_name); - free (font->subset_font_name); - _cairo_array_fini (&font->output); - cff_dict_fini (font->top_dict); - cff_dict_fini (font->private_dict); - cff_index_fini (&font->strings_index); - cff_index_fini (&font->charstrings_index); - cff_index_fini (&font->global_sub_index); - cff_index_fini (&font->local_sub_index); - cff_index_fini (&font->charstrings_subset_index); - cff_index_fini (&font->strings_subset_index); - - /* If we bailed out early as a result of an error some of the - * following cairo_cff_font_t members may still be NULL */ - if (font->fd_dict) { - for (i = 0; i < font->num_fontdicts; i++) { - if (font->fd_dict[i]) - cff_dict_fini (font->fd_dict[i]); - } - free (font->fd_dict); - } - free (font->global_subs_used); - free (font->local_subs_used); - free (font->fd_subset_map); - free (font->private_dict_offset); - - if (font->is_cid) { - free (font->fdselect); - free (font->fdselect_subset); - if (font->fd_private_dict) { - for (i = 0; i < font->num_fontdicts; i++) { - if (font->fd_private_dict[i]) - cff_dict_fini (font->fd_private_dict[i]); - } - free (font->fd_private_dict); - } - if (font->fd_local_sub_index) { - for (i = 0; i < font->num_fontdicts; i++) - cff_index_fini (&font->fd_local_sub_index[i]); - free (font->fd_local_sub_index); - } - free (font->fd_local_sub_bias); - if (font->fd_local_subs_used) { - for (i = 0; i < font->num_fontdicts; i++) { - free (font->fd_local_subs_used[i]); - } - free (font->fd_local_subs_used); - } - free (font->fd_default_width); - free (font->fd_nominal_width); - } - - free (font->data); - - free (font); -} - -cairo_status_t -_cairo_cff_subset_init (cairo_cff_subset_t *cff_subset, - const char *subset_name, - cairo_scaled_font_subset_t *font_subset) -{ - cairo_cff_font_t *font = NULL; /* squelch bogus compiler warning */ - cairo_status_t status; - const char *data = NULL; /* squelch bogus compiler warning */ - unsigned long length = 0; /* squelch bogus compiler warning */ - unsigned int i; - - status = _cairo_cff_font_create (font_subset, &font, subset_name); - if (unlikely (status)) - return status; - - status = cairo_cff_font_generate (font, &data, &length); - if (unlikely (status)) - goto fail1; - - cff_subset->ps_name = strdup (font->ps_name); - if (unlikely (cff_subset->ps_name == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail1; - } - - if (font->font_name) { - cff_subset->family_name_utf8 = strdup (font->font_name); - if (cff_subset->family_name_utf8 == NULL) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail2; - } - } else { - cff_subset->family_name_utf8 = NULL; - } - - cff_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs); - if (unlikely (cff_subset->widths == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail3; - } - for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) - cff_subset->widths[i] = (double)font->widths[i]/font->units_per_em; - - cff_subset->x_min = (double)font->x_min/font->units_per_em; - cff_subset->y_min = (double)font->y_min/font->units_per_em; - cff_subset->x_max = (double)font->x_max/font->units_per_em; - cff_subset->y_max = (double)font->y_max/font->units_per_em; - cff_subset->ascent = (double)font->ascent/font->units_per_em; - cff_subset->descent = (double)font->descent/font->units_per_em; - - cff_subset->data = malloc (length); - if (unlikely (cff_subset->data == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail4; - } - - memcpy (cff_subset->data, data, length); - cff_subset->data_length = length; - - cairo_cff_font_destroy (font); - - return CAIRO_STATUS_SUCCESS; - - fail4: - free (cff_subset->widths); - fail3: - free (cff_subset->family_name_utf8); - fail2: - free (cff_subset->ps_name); - fail1: - cairo_cff_font_destroy (font); - - return status; -} - -void -_cairo_cff_subset_fini (cairo_cff_subset_t *subset) -{ - free (subset->ps_name); - free (subset->family_name_utf8); - free (subset->widths); - free (subset->data); -} - -cairo_bool_t -_cairo_cff_scaled_font_is_cid_cff (cairo_scaled_font_t *scaled_font) -{ - const cairo_scaled_font_backend_t *backend; - cairo_int_status_t status; - unsigned char *data; - unsigned long data_length; - unsigned char *current_ptr; - unsigned char *data_end; - cff_header_t *header; - cff_index_element_t *element; - cairo_hash_table_t *top_dict; - cairo_array_t index; - int size; - cairo_bool_t is_cid = FALSE; - - backend = scaled_font->backend; - data = NULL; - data_length = 0; - status = CAIRO_INT_STATUS_UNSUPPORTED; - /* Try to load an OpenType/CFF font */ - if (backend->load_truetype_table && - (status = backend->load_truetype_table (scaled_font, TT_TAG_CFF, - 0, NULL, &data_length)) == CAIRO_INT_STATUS_SUCCESS) - { - data = malloc (data_length); - if (unlikely (data == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - return FALSE; - } - - status = backend->load_truetype_table (scaled_font, TT_TAG_CFF, - 0, data, &data_length); - if (unlikely (status)) - goto fail1; - } - /* Try to load a CFF font */ - if (status == CAIRO_INT_STATUS_UNSUPPORTED && - backend->load_type1_data && - (status = backend->load_type1_data (scaled_font, - 0, NULL, &data_length)) == CAIRO_INT_STATUS_SUCCESS) - { - data = malloc (data_length); - if (unlikely (data == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - return FALSE; - } - - status = backend->load_type1_data (scaled_font, 0, data, &data_length); - if (unlikely (status)) - goto fail1; - } - if (status) - goto fail1; - - /* Check if it looks like a CFF font */ - if (!check_fontdata_is_cff (data, data_length)) - goto fail1; - - data_end = data + data_length; - - /* skip header */ - if (data_length < sizeof (cff_header_t)) - goto fail1; - - header = (cff_header_t *) data; - current_ptr = data + header->header_size; - - /* skip name */ - cff_index_init (&index); - status = cff_index_read (&index, ¤t_ptr, data_end); - cff_index_fini (&index); - - if (status) - goto fail1; - - /* read top dict */ - cff_index_init (&index); - status = cff_index_read (&index, ¤t_ptr, data_end); - if (unlikely (status)) - goto fail2; - - status = cff_dict_init (&top_dict); - if (unlikely (status)) - goto fail2; - - element = _cairo_array_index (&index, 0); - status = cff_dict_read (top_dict, element->data, element->length); - if (unlikely (status)) - goto fail3; - - /* check for ROS operator indicating a CID font */ - if (cff_dict_get_operands (top_dict, ROS_OP, &size) != NULL) - is_cid = TRUE; - -fail3: - cff_dict_fini (top_dict); - -fail2: - cff_index_fini (&index); - -fail1: - free (data); - - return is_cid; -} - -static cairo_int_status_t -_cairo_cff_font_fallback_create (cairo_scaled_font_subset_t *scaled_font_subset, - cairo_cff_font_t **font_return, - const char *subset_name) -{ - cairo_status_t status; - cairo_cff_font_t *font; - - font = malloc (sizeof (cairo_cff_font_t)); - if (unlikely (font == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - font->backend = NULL; - font->scaled_font_subset = scaled_font_subset; - - _cairo_array_init (&font->output, sizeof (char)); - status = _cairo_array_grow_by (&font->output, 4096); - if (unlikely (status)) - goto fail1; - - font->subset_font_name = strdup (subset_name); - if (unlikely (font->subset_font_name == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail1; - } - - font->ps_name = strdup (subset_name); - if (unlikely (font->ps_name == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail2; - } - font->font_name = NULL; - - font->x_min = 0; - font->y_min = 0; - font->x_max = 0; - font->y_max = 0; - font->ascent = 0; - font->descent = 0; - - font->widths = calloc (font->scaled_font_subset->num_glyphs, sizeof (int)); - if (unlikely (font->widths == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail3; - } - - font->data_length = 0; - font->data = NULL; - font->data_end = NULL; - - status = cff_dict_init (&font->top_dict); - if (unlikely (status)) - goto fail4; - - status = cff_dict_init (&font->private_dict); - if (unlikely (status)) - goto fail5; - - cff_index_init (&font->strings_index); - cff_index_init (&font->charstrings_index); - cff_index_init (&font->global_sub_index); - cff_index_init (&font->local_sub_index); - cff_index_init (&font->charstrings_subset_index); - cff_index_init (&font->strings_subset_index); - font->global_subs_used = NULL; - font->local_subs_used = NULL; - font->subset_subroutines = FALSE; - font->fdselect = NULL; - font->fd_dict = NULL; - font->fd_private_dict = NULL; - font->fd_local_sub_index = NULL; - font->fdselect_subset = NULL; - font->fd_subset_map = NULL; - font->private_dict_offset = NULL; - - *font_return = font; - - return CAIRO_STATUS_SUCCESS; - -fail5: - _cairo_hash_table_destroy (font->top_dict); -fail4: - free (font->widths); -fail3: - free (font->font_name); - free (font->ps_name); -fail2: - free (font->subset_font_name); -fail1: - _cairo_array_fini (&font->output); - free (font); - return status; -} - -static cairo_int_status_t -cairo_cff_font_fallback_generate (cairo_cff_font_t *font, - cairo_type2_charstrings_t *type2_subset, - const char **data, - unsigned long *length) -{ - cairo_int_status_t status; - cff_header_t header; - cairo_array_t *charstring; - unsigned char buf[40]; - unsigned char *end_buf, *end_buf2; - unsigned int i; - int sid; - - /* Create header */ - header.major = 1; - header.minor = 0; - header.header_size = 4; - header.offset_size = 4; - font->header = &header; - - /* Create Top Dict */ - font->is_cid = FALSE; - - snprintf((char*)buf, sizeof(buf), "CairoFont-%u-%u", - font->scaled_font_subset->font_id, - font->scaled_font_subset->subset_id); - sid = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index); - status = cff_index_append_copy (&font->strings_subset_index, - (unsigned char *)buf, - strlen((char*)buf)); - if (unlikely (status)) - return status; - - end_buf = encode_integer (buf, sid); - status = cff_dict_set_operands (font->top_dict, FULLNAME_OP, - buf, end_buf - buf); - if (unlikely (status)) - return status; - - status = cff_dict_set_operands (font->top_dict, FAMILYNAME_OP, - buf, end_buf - buf); - if (unlikely (status)) - return status; - - end_buf = encode_integer (buf, type2_subset->x_min); - end_buf = encode_integer (end_buf, type2_subset->y_min); - end_buf = encode_integer (end_buf, type2_subset->x_max); - end_buf = encode_integer (end_buf, type2_subset->y_max); - status = cff_dict_set_operands (font->top_dict, - FONTBBOX_OP, buf, end_buf - buf); - if (unlikely (status)) - return status; - - end_buf = encode_integer_max (buf, 0); - status = cff_dict_set_operands (font->top_dict, - CHARSTRINGS_OP, buf, end_buf - buf); - if (unlikely (status)) - return status; - - - if (font->scaled_font_subset->is_latin) { - status = cff_dict_set_operands (font->top_dict, - ENCODING_OP, buf, end_buf - buf); - if (unlikely (status)) - return status; - - /* Private has two operands - size and offset */ - end_buf2 = encode_integer_max (end_buf, 0); - cff_dict_set_operands (font->top_dict, PRIVATE_OP, buf, end_buf2 - buf); - if (unlikely (status)) - return status; - - } else { - status = cff_dict_set_operands (font->top_dict, - FDSELECT_OP, buf, end_buf - buf); - if (unlikely (status)) - return status; - - status = cff_dict_set_operands (font->top_dict, - FDARRAY_OP, buf, end_buf - buf); - if (unlikely (status)) - return status; - } - - status = cff_dict_set_operands (font->top_dict, - CHARSET_OP, buf, end_buf - buf); - if (unlikely (status)) - return status; - - if (!font->scaled_font_subset->is_latin) { - status = cairo_cff_font_set_ros_strings (font); - if (unlikely (status)) - return status; - - /* Create CID FD dictionary */ - status = cairo_cff_font_create_cid_fontdict (font); - if (unlikely (status)) - return status; - } else { - font->private_dict_offset = malloc (sizeof (int)); - if (unlikely (font->private_dict_offset == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - /* Create charstrings */ - for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) { - charstring = _cairo_array_index(&type2_subset->charstrings, i); - - status = cff_index_append (&font->charstrings_subset_index, - _cairo_array_index (charstring, 0), - _cairo_array_num_elements (charstring)); - - if (unlikely (status)) - return status; - } - - if (font->scaled_font_subset->is_latin) - status = cairo_cff_font_add_euro_charset_string (font); - - status = cairo_cff_font_write_subset (font); - if (unlikely (status)) - return status; - - *data = _cairo_array_index (&font->output, 0); - *length = _cairo_array_num_elements (&font->output); - - return CAIRO_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_cff_fallback_init (cairo_cff_subset_t *cff_subset, - const char *subset_name, - cairo_scaled_font_subset_t *font_subset) -{ - cairo_cff_font_t *font = NULL; /* squelch bogus compiler warning */ - cairo_status_t status; - const char *data = NULL; /* squelch bogus compiler warning */ - unsigned long length = 0; /* squelch bogus compiler warning */ - unsigned int i; - cairo_type2_charstrings_t type2_subset; - - status = _cairo_cff_font_fallback_create (font_subset, &font, subset_name); - if (unlikely (status)) - return status; - - status = _cairo_type2_charstrings_init (&type2_subset, font_subset); - if (unlikely (status)) - goto fail1; - - status = cairo_cff_font_fallback_generate (font, &type2_subset, &data, &length); - if (unlikely (status)) - goto fail2; - - cff_subset->family_name_utf8 = NULL; - cff_subset->ps_name = strdup (font->ps_name); - if (unlikely (cff_subset->ps_name == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail2; - } - - cff_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs); - if (unlikely (cff_subset->widths == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail3; - } - - for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) - cff_subset->widths[i] = (double)type2_subset.widths[i]/1000; - - cff_subset->x_min = (double)type2_subset.x_min/1000; - cff_subset->y_min = (double)type2_subset.y_min/1000; - cff_subset->x_max = (double)type2_subset.x_max/1000; - cff_subset->y_max = (double)type2_subset.y_max/1000; - cff_subset->ascent = (double)type2_subset.y_max/1000; - cff_subset->descent = (double)type2_subset.y_min/1000; - - cff_subset->data = malloc (length); - if (unlikely (cff_subset->data == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail4; - } - - memcpy (cff_subset->data, data, length); - cff_subset->data_length = length; - - _cairo_type2_charstrings_fini (&type2_subset); - cairo_cff_font_destroy (font); - - return CAIRO_STATUS_SUCCESS; - - fail4: - free (cff_subset->widths); - fail3: - free (cff_subset->ps_name); - fail2: - _cairo_type2_charstrings_fini (&type2_subset); - fail1: - cairo_cff_font_destroy (font); - - return status; -} - -void -_cairo_cff_fallback_fini (cairo_cff_subset_t *subset) -{ - free (subset->ps_name); - free (subset->widths); - free (subset->data); -} - -#endif /* CAIRO_HAS_FONT_SUBSET */ diff --git a/source/libs/cairo/cairo-src/src/cairo-clip-boxes.c b/source/libs/cairo/cairo-src/src/cairo-clip-boxes.c deleted file mode 100644 index 7bcbeb1918a73991745654fb4c7acaa104ed56fb..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-clip-boxes.c +++ /dev/null @@ -1,599 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Kristian Høgsberg <krh@redhat.com> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-box-inline.h" -#include "cairo-clip-inline.h" -#include "cairo-clip-private.h" -#include "cairo-error-private.h" -#include "cairo-freed-pool-private.h" -#include "cairo-gstate-private.h" -#include "cairo-path-fixed-private.h" -#include "cairo-pattern-private.h" -#include "cairo-composite-rectangles-private.h" -#include "cairo-region-private.h" - -static inline int -pot (int v) -{ - v--; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - v++; - return v; -} - -static cairo_bool_t -_cairo_clip_contains_rectangle_box (const cairo_clip_t *clip, - const cairo_rectangle_int_t *rect, - const cairo_box_t *box) -{ - int i; - - /* clip == NULL means no clip, so the clip contains everything */ - if (clip == NULL) - return TRUE; - - if (_cairo_clip_is_all_clipped (clip)) - return FALSE; - - /* If we have a non-trivial path, just say no */ - if (clip->path) - return FALSE; - - if (! _cairo_rectangle_contains_rectangle (&clip->extents, rect)) - return FALSE; - - if (clip->num_boxes == 0) - return TRUE; - - /* Check for a clip-box that wholly contains the rectangle */ - for (i = 0; i < clip->num_boxes; i++) { - if (box->p1.x >= clip->boxes[i].p1.x && - box->p1.y >= clip->boxes[i].p1.y && - box->p2.x <= clip->boxes[i].p2.x && - box->p2.y <= clip->boxes[i].p2.y) - { - return TRUE; - } - } - - return FALSE; -} - -cairo_bool_t -_cairo_clip_contains_box (const cairo_clip_t *clip, - const cairo_box_t *box) -{ - cairo_rectangle_int_t rect; - - _cairo_box_round_to_rectangle (box, &rect); - return _cairo_clip_contains_rectangle_box(clip, &rect, box); -} - -cairo_bool_t -_cairo_clip_contains_rectangle (const cairo_clip_t *clip, - const cairo_rectangle_int_t *rect) -{ - cairo_box_t box; - - box.p1.x = _cairo_fixed_from_int (rect->x); - box.p1.y = _cairo_fixed_from_int (rect->y); - box.p2.x = _cairo_fixed_from_int (rect->x + rect->width); - box.p2.y = _cairo_fixed_from_int (rect->y + rect->height); - - return _cairo_clip_contains_rectangle_box (clip, rect, &box); -} - -cairo_clip_t * -_cairo_clip_intersect_rectilinear_path (cairo_clip_t *clip, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - cairo_antialias_t antialias) -{ - cairo_status_t status; - cairo_boxes_t boxes; - - _cairo_boxes_init (&boxes); - status = _cairo_path_fixed_fill_rectilinear_to_boxes (path, - fill_rule, - antialias, - &boxes); - if (likely (status == CAIRO_STATUS_SUCCESS && boxes.num_boxes)) - clip = _cairo_clip_intersect_boxes (clip, &boxes); - else - clip = _cairo_clip_set_all_clipped (clip); - _cairo_boxes_fini (&boxes); - - return clip; -} - -static cairo_clip_t * -_cairo_clip_intersect_rectangle_box (cairo_clip_t *clip, - const cairo_rectangle_int_t *r, - const cairo_box_t *box) -{ - cairo_box_t extents_box; - cairo_bool_t changed = FALSE; - int i, j; - - if (clip == NULL) { - clip = _cairo_clip_create (); - if (clip == NULL) - return _cairo_clip_set_all_clipped (clip); - } - - if (clip->num_boxes == 0) { - clip->boxes = &clip->embedded_box; - clip->boxes[0] = *box; - clip->num_boxes = 1; - if (clip->path == NULL) { - clip->extents = *r; - } else { - if (! _cairo_rectangle_intersect (&clip->extents, r)) - return _cairo_clip_set_all_clipped (clip); - } - if (clip->path == NULL) - clip->is_region = _cairo_box_is_pixel_aligned (box); - return clip; - } - - /* Does the new box wholly subsume the clip? Perform a cheap check - * for the common condition of a single clip rectangle. - */ - if (clip->num_boxes == 1 && - clip->boxes[0].p1.x >= box->p1.x && - clip->boxes[0].p1.y >= box->p1.y && - clip->boxes[0].p2.x <= box->p2.x && - clip->boxes[0].p2.y <= box->p2.y) - { - return clip; - } - - for (i = j = 0; i < clip->num_boxes; i++) { - cairo_box_t *b = &clip->boxes[j]; - - if (j != i) - *b = clip->boxes[i]; - - if (box->p1.x > b->p1.x) - b->p1.x = box->p1.x, changed = TRUE; - if (box->p2.x < b->p2.x) - b->p2.x = box->p2.x, changed = TRUE; - - if (box->p1.y > b->p1.y) - b->p1.y = box->p1.y, changed = TRUE; - if (box->p2.y < b->p2.y) - b->p2.y = box->p2.y, changed = TRUE; - - j += b->p2.x > b->p1.x && b->p2.y > b->p1.y; - } - clip->num_boxes = j; - - if (clip->num_boxes == 0) - return _cairo_clip_set_all_clipped (clip); - - if (! changed) - return clip; - - extents_box = clip->boxes[0]; - for (i = 1; i < clip->num_boxes; i++) { - if (clip->boxes[i].p1.x < extents_box.p1.x) - extents_box.p1.x = clip->boxes[i].p1.x; - - if (clip->boxes[i].p1.y < extents_box.p1.y) - extents_box.p1.y = clip->boxes[i].p1.y; - - if (clip->boxes[i].p2.x > extents_box.p2.x) - extents_box.p2.x = clip->boxes[i].p2.x; - - if (clip->boxes[i].p2.y > extents_box.p2.y) - extents_box.p2.y = clip->boxes[i].p2.y; - } - - if (clip->path == NULL) { - _cairo_box_round_to_rectangle (&extents_box, &clip->extents); - } else { - cairo_rectangle_int_t extents_rect; - - _cairo_box_round_to_rectangle (&extents_box, &extents_rect); - if (! _cairo_rectangle_intersect (&clip->extents, &extents_rect)) - return _cairo_clip_set_all_clipped (clip); - } - - if (clip->region) { - cairo_region_destroy (clip->region); - clip->region = NULL; - } - - clip->is_region = FALSE; - return clip; -} - -cairo_clip_t * -_cairo_clip_intersect_box (cairo_clip_t *clip, - const cairo_box_t *box) -{ - cairo_rectangle_int_t r; - - if (_cairo_clip_is_all_clipped (clip)) - return clip; - - _cairo_box_round_to_rectangle (box, &r); - if (r.width == 0 || r.height == 0) - return _cairo_clip_set_all_clipped (clip); - - return _cairo_clip_intersect_rectangle_box (clip, &r, box); -} - -cairo_clip_t * -_cairo_clip_intersect_boxes (cairo_clip_t *clip, - const cairo_boxes_t *boxes) -{ - cairo_boxes_t clip_boxes; - cairo_box_t limits; - cairo_rectangle_int_t extents; - - if (_cairo_clip_is_all_clipped (clip)) - return clip; - - if (boxes->num_boxes == 0) - return _cairo_clip_set_all_clipped (clip); - - if (boxes->num_boxes == 1) - return _cairo_clip_intersect_box (clip, boxes->chunks.base); - - if (clip == NULL) - clip = _cairo_clip_create (); - - if (clip->num_boxes) { - _cairo_boxes_init_for_array (&clip_boxes, clip->boxes, clip->num_boxes); - if (unlikely (_cairo_boxes_intersect (&clip_boxes, boxes, &clip_boxes))) { - clip = _cairo_clip_set_all_clipped (clip); - goto out; - } - - if (clip->boxes != &clip->embedded_box) - free (clip->boxes); - - clip->boxes = NULL; - boxes = &clip_boxes; - } - - if (boxes->num_boxes == 0) { - clip = _cairo_clip_set_all_clipped (clip); - goto out; - } else if (boxes->num_boxes == 1) { - clip->boxes = &clip->embedded_box; - clip->boxes[0] = boxes->chunks.base[0]; - clip->num_boxes = 1; - } else { - clip->boxes = _cairo_boxes_to_array (boxes, &clip->num_boxes, TRUE); - } - _cairo_boxes_extents (boxes, &limits); - - _cairo_box_round_to_rectangle (&limits, &extents); - if (clip->path == NULL) { - clip->extents = extents; - } else if (! _cairo_rectangle_intersect (&clip->extents, &extents)) { - clip = _cairo_clip_set_all_clipped (clip); - goto out; - } - - if (clip->region) { - cairo_region_destroy (clip->region); - clip->region = NULL; - } - clip->is_region = FALSE; - -out: - if (boxes == &clip_boxes) - _cairo_boxes_fini (&clip_boxes); - - return clip; -} - -cairo_clip_t * -_cairo_clip_intersect_rectangle (cairo_clip_t *clip, - const cairo_rectangle_int_t *r) -{ - cairo_box_t box; - - if (_cairo_clip_is_all_clipped (clip)) - return clip; - - if (r->width == 0 || r->height == 0) - return _cairo_clip_set_all_clipped (clip); - - box.p1.x = _cairo_fixed_from_int (r->x); - box.p1.y = _cairo_fixed_from_int (r->y); - box.p2.x = _cairo_fixed_from_int (r->x + r->width); - box.p2.y = _cairo_fixed_from_int (r->y + r->height); - - return _cairo_clip_intersect_rectangle_box (clip, r, &box); -} - -struct reduce { - cairo_clip_t *clip; - cairo_box_t limit; - cairo_box_t extents; - cairo_bool_t inside; - - cairo_point_t current_point; - cairo_point_t last_move_to; -}; - -static void -_add_clipped_edge (struct reduce *r, - const cairo_point_t *p1, - const cairo_point_t *p2, - int y1, int y2) -{ - cairo_fixed_t x; - - x = _cairo_edge_compute_intersection_x_for_y (p1, p2, y1); - if (x < r->extents.p1.x) - r->extents.p1.x = x; - - x = _cairo_edge_compute_intersection_x_for_y (p1, p2, y2); - if (x > r->extents.p2.x) - r->extents.p2.x = x; - - if (y1 < r->extents.p1.y) - r->extents.p1.y = y1; - - if (y2 > r->extents.p2.y) - r->extents.p2.y = y2; - - r->inside = TRUE; -} - -static void -_add_edge (struct reduce *r, - const cairo_point_t *p1, - const cairo_point_t *p2) -{ - int top, bottom; - int top_y, bot_y; - int n; - - if (p1->y < p2->y) { - top = p1->y; - bottom = p2->y; - } else { - top = p2->y; - bottom = p1->y; - } - - if (bottom < r->limit.p1.y || top > r->limit.p2.y) - return; - - if (p1->x > p2->x) { - const cairo_point_t *t = p1; - p1 = p2; - p2 = t; - } - - if (p2->x <= r->limit.p1.x || p1->x >= r->limit.p2.x) - return; - - for (n = 0; n < r->clip->num_boxes; n++) { - const cairo_box_t *limits = &r->clip->boxes[n]; - - if (bottom < limits->p1.y || top > limits->p2.y) - continue; - - if (p2->x <= limits->p1.x || p1->x >= limits->p2.x) - continue; - - if (p1->x >= limits->p1.x && p2->x <= limits->p1.x) { - top_y = top; - bot_y = bottom; - } else { - int p1_y, p2_y; - - p1_y = _cairo_edge_compute_intersection_y_for_x (p1, p2, - limits->p1.x); - p2_y = _cairo_edge_compute_intersection_y_for_x (p1, p2, - limits->p2.x); - if (p1_y < p2_y) { - top_y = p1_y; - bot_y = p2_y; - } else { - top_y = p2_y; - bot_y = p1_y; - } - - if (top_y < top) - top_y = top; - if (bot_y > bottom) - bot_y = bottom; - } - - if (top_y < limits->p1.y) - top_y = limits->p1.y; - - if (bot_y > limits->p2.y) - bot_y = limits->p2.y; - if (bot_y > top_y) - _add_clipped_edge (r, p1, p2, top_y, bot_y); - } -} - -static cairo_status_t -_reduce_line_to (void *closure, - const cairo_point_t *point) -{ - struct reduce *r = closure; - - _add_edge (r, &r->current_point, point); - r->current_point = *point; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_reduce_close (void *closure) -{ - struct reduce *r = closure; - - return _reduce_line_to (r, &r->last_move_to); -} - -static cairo_status_t -_reduce_move_to (void *closure, - const cairo_point_t *point) -{ - struct reduce *r = closure; - cairo_status_t status; - - /* close current subpath */ - status = _reduce_close (closure); - - /* make sure that the closure represents a degenerate path */ - r->current_point = *point; - r->last_move_to = *point; - - return status; -} - -static cairo_clip_t * -_cairo_clip_reduce_to_boxes (cairo_clip_t *clip) -{ - struct reduce r; - cairo_clip_path_t *clip_path; - cairo_status_t status; - - return clip; - if (clip->path == NULL) - return clip; - - r.clip = clip; - r.extents.p1.x = r.extents.p1.y = INT_MAX; - r.extents.p2.x = r.extents.p2.y = INT_MIN; - r.inside = FALSE; - - r.limit.p1.x = _cairo_fixed_from_int (clip->extents.x); - r.limit.p1.y = _cairo_fixed_from_int (clip->extents.y); - r.limit.p2.x = _cairo_fixed_from_int (clip->extents.x + clip->extents.width); - r.limit.p2.y = _cairo_fixed_from_int (clip->extents.y + clip->extents.height); - - clip_path = clip->path; - do { - r.current_point.x = 0; - r.current_point.y = 0; - r.last_move_to = r.current_point; - - status = _cairo_path_fixed_interpret_flat (&clip_path->path, - _reduce_move_to, - _reduce_line_to, - _reduce_close, - &r, - clip_path->tolerance); - assert (status == CAIRO_STATUS_SUCCESS); - _reduce_close (&r); - } while ((clip_path = clip_path->prev)); - - if (! r.inside) { - _cairo_clip_path_destroy (clip->path); - clip->path = NULL; - } - - return _cairo_clip_intersect_box (clip, &r.extents); -} - -cairo_clip_t * -_cairo_clip_reduce_to_rectangle (const cairo_clip_t *clip, - const cairo_rectangle_int_t *r) -{ - cairo_clip_t *copy; - - if (_cairo_clip_is_all_clipped (clip)) - return (cairo_clip_t *) clip; - - if (_cairo_clip_contains_rectangle (clip, r)) - return _cairo_clip_intersect_rectangle (NULL, r); - - copy = _cairo_clip_copy_intersect_rectangle (clip, r); - if (_cairo_clip_is_all_clipped (copy)) - return copy; - - return _cairo_clip_reduce_to_boxes (copy); -} - -cairo_clip_t * -_cairo_clip_reduce_for_composite (const cairo_clip_t *clip, - cairo_composite_rectangles_t *extents) -{ - const cairo_rectangle_int_t *r; - - r = extents->is_bounded ? &extents->bounded : &extents->unbounded; - return _cairo_clip_reduce_to_rectangle (clip, r); -} - -cairo_clip_t * -_cairo_clip_from_boxes (const cairo_boxes_t *boxes) -{ - cairo_box_t extents; - cairo_clip_t *clip = _cairo_clip_create (); - if (clip == NULL) - return _cairo_clip_set_all_clipped (clip); - - /* XXX cow-boxes? */ - if(boxes->num_boxes == 1) { - clip->boxes = &clip->embedded_box; - clip->boxes[0] = boxes->chunks.base[0]; - clip->num_boxes = 1; - } else { - clip->boxes = _cairo_boxes_to_array (boxes, &clip->num_boxes, TRUE); - if (clip->boxes == NULL) - return _cairo_clip_set_all_clipped (clip); - } - - _cairo_boxes_extents (boxes, &extents); - _cairo_box_round_to_rectangle (&extents, &clip->extents); - - return clip; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-clip-inline.h b/source/libs/cairo/cairo-src/src/cairo-clip-inline.h deleted file mode 100644 index a9f23269223e2b5799111f2f8bcd846b340fe860..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-clip-inline.h +++ /dev/null @@ -1,83 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Kristian Høgsberg <krh@redhat.com> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_CLIP_INLINE_H -#define CAIRO_CLIP_INLINE_H - -#include "cairo-clip-private.h" - -static inline cairo_bool_t _cairo_clip_is_all_clipped(const cairo_clip_t *clip) -{ - return clip == &__cairo_clip_all; -} - -static inline cairo_clip_t * -_cairo_clip_set_all_clipped (cairo_clip_t *clip) -{ - _cairo_clip_destroy (clip); - return (cairo_clip_t *) &__cairo_clip_all; -} - -static inline cairo_clip_t * -_cairo_clip_copy_intersect_rectangle (const cairo_clip_t *clip, - const cairo_rectangle_int_t *r) -{ - return _cairo_clip_intersect_rectangle (_cairo_clip_copy (clip), r); -} - -static inline cairo_clip_t * -_cairo_clip_copy_intersect_clip (const cairo_clip_t *clip, - const cairo_clip_t *other) -{ - return _cairo_clip_intersect_clip (_cairo_clip_copy (clip), other); -} - -static inline void -_cairo_clip_steal_boxes (cairo_clip_t *clip, cairo_boxes_t *boxes) -{ - _cairo_boxes_init_for_array (boxes, clip->boxes, clip->num_boxes); - clip->boxes = NULL; - clip->num_boxes = 0; -} - -static inline void -_cairo_clip_unsteal_boxes (cairo_clip_t *clip, cairo_boxes_t *boxes) -{ - clip->boxes = boxes->chunks.base; - clip->num_boxes = boxes->num_boxes; -} - -#endif /* CAIRO_CLIP_INLINE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-clip-polygon.c b/source/libs/cairo/cairo-src/src/cairo-clip-polygon.c deleted file mode 100644 index f40faefba80857f84c1527c1990827c7f526a323..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-clip-polygon.c +++ /dev/null @@ -1,156 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" -#include "cairo-clip-inline.h" -#include "cairo-clip-private.h" -#include "cairo-error-private.h" -#include "cairo-freed-pool-private.h" -#include "cairo-gstate-private.h" -#include "cairo-path-fixed-private.h" -#include "cairo-pattern-private.h" -#include "cairo-composite-rectangles-private.h" -#include "cairo-region-private.h" - -static cairo_bool_t -can_convert_to_polygon (const cairo_clip_t *clip) -{ - cairo_clip_path_t *clip_path = clip->path; - cairo_antialias_t antialias = clip_path->antialias; - - while ((clip_path = clip_path->prev) != NULL) { - if (clip_path->antialias != antialias) - return FALSE; - } - - return TRUE; -} - -cairo_int_status_t -_cairo_clip_get_polygon (const cairo_clip_t *clip, - cairo_polygon_t *polygon, - cairo_fill_rule_t *fill_rule, - cairo_antialias_t *antialias) -{ - cairo_status_t status; - cairo_clip_path_t *clip_path; - - if (_cairo_clip_is_all_clipped (clip)) { - _cairo_polygon_init (polygon, NULL, 0); - return CAIRO_INT_STATUS_SUCCESS; - } - - /* If there is no clip, we need an infinite polygon */ - assert (clip && (clip->path || clip->num_boxes)); - - if (clip->path == NULL) { - *fill_rule = CAIRO_FILL_RULE_WINDING; - *antialias = CAIRO_ANTIALIAS_DEFAULT; - return _cairo_polygon_init_box_array (polygon, - clip->boxes, - clip->num_boxes); - } - - /* check that residual is all of the same type/tolerance */ - if (! can_convert_to_polygon (clip)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (clip->num_boxes < 2) - _cairo_polygon_init_with_clip (polygon, clip); - else - _cairo_polygon_init_with_clip (polygon, NULL); - - clip_path = clip->path; - *fill_rule = clip_path->fill_rule; - *antialias = clip_path->antialias; - - status = _cairo_path_fixed_fill_to_polygon (&clip_path->path, - clip_path->tolerance, - polygon); - if (unlikely (status)) - goto err; - - if (clip->num_boxes > 1) { - status = _cairo_polygon_intersect_with_boxes (polygon, fill_rule, - clip->boxes, clip->num_boxes); - if (unlikely (status)) - goto err; - } - - polygon->limits = NULL; - polygon->num_limits = 0; - - while ((clip_path = clip_path->prev) != NULL) { - cairo_polygon_t next; - - _cairo_polygon_init (&next, NULL, 0); - status = _cairo_path_fixed_fill_to_polygon (&clip_path->path, - clip_path->tolerance, - &next); - if (likely (status == CAIRO_STATUS_SUCCESS)) - status = _cairo_polygon_intersect (polygon, *fill_rule, - &next, clip_path->fill_rule); - _cairo_polygon_fini (&next); - if (unlikely (status)) - goto err; - - *fill_rule = CAIRO_FILL_RULE_WINDING; - } - - return CAIRO_STATUS_SUCCESS; - -err: - _cairo_polygon_fini (polygon); - return status; -} - -cairo_bool_t -_cairo_clip_is_polygon (const cairo_clip_t *clip) -{ - if (_cairo_clip_is_all_clipped (clip)) - return TRUE; - - /* If there is no clip, we need an infinite polygon */ - if (clip == NULL) - return FALSE; - - if (clip->path == NULL) - return TRUE; - - /* check that residual is all of the same type/tolerance */ - return can_convert_to_polygon (clip); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-clip-private.h b/source/libs/cairo/cairo-src/src/cairo-clip-private.h deleted file mode 100644 index 5fc05a64e938afcab0124c59d9da971ec94105b3..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-clip-private.h +++ /dev/null @@ -1,198 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Kristian Høgsberg <krh@redhat.com> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_CLIP_PRIVATE_H -#define CAIRO_CLIP_PRIVATE_H - -#include "cairo-types-private.h" - -#include "cairo-boxes-private.h" -#include "cairo-error-private.h" -#include "cairo-compiler-private.h" -#include "cairo-error-private.h" -#include "cairo-path-fixed-private.h" -#include "cairo-reference-count-private.h" - -extern const cairo_private cairo_rectangle_list_t _cairo_rectangles_nil; - -struct _cairo_clip_path { - cairo_reference_count_t ref_count; - cairo_path_fixed_t path; - cairo_fill_rule_t fill_rule; - double tolerance; - cairo_antialias_t antialias; - cairo_clip_path_t *prev; -}; - -struct _cairo_clip { - cairo_rectangle_int_t extents; - cairo_clip_path_t *path; - - cairo_box_t *boxes; - int num_boxes; - - cairo_region_t *region; - cairo_bool_t is_region; - - cairo_box_t embedded_box; -}; - -cairo_private cairo_clip_t * -_cairo_clip_create (void); - -cairo_private cairo_clip_path_t * -_cairo_clip_path_reference (cairo_clip_path_t *clip_path); - -cairo_private void -_cairo_clip_path_destroy (cairo_clip_path_t *clip_path); - -cairo_private void -_cairo_clip_destroy (cairo_clip_t *clip); - -cairo_private extern const cairo_clip_t __cairo_clip_all; - -cairo_private cairo_clip_t * -_cairo_clip_copy (const cairo_clip_t *clip); - -cairo_private cairo_clip_t * -_cairo_clip_copy_region (const cairo_clip_t *clip); - -cairo_private cairo_clip_t * -_cairo_clip_copy_path (const cairo_clip_t *clip); - -cairo_private cairo_clip_t * -_cairo_clip_translate (cairo_clip_t *clip, int tx, int ty); - -cairo_private cairo_clip_t * -_cairo_clip_transform (cairo_clip_t *clip, const cairo_matrix_t *m); - -cairo_private cairo_clip_t * -_cairo_clip_copy_with_translation (const cairo_clip_t *clip, int tx, int ty); - -cairo_private cairo_bool_t -_cairo_clip_equal (const cairo_clip_t *clip_a, - const cairo_clip_t *clip_b); - -cairo_private cairo_clip_t * -_cairo_clip_intersect_rectangle (cairo_clip_t *clip, - const cairo_rectangle_int_t *rectangle); - -cairo_private cairo_clip_t * -_cairo_clip_intersect_clip (cairo_clip_t *clip, - const cairo_clip_t *other); - -cairo_private cairo_clip_t * -_cairo_clip_intersect_box (cairo_clip_t *clip, - const cairo_box_t *box); - -cairo_private cairo_clip_t * -_cairo_clip_intersect_boxes (cairo_clip_t *clip, - const cairo_boxes_t *boxes); - -cairo_private cairo_clip_t * -_cairo_clip_intersect_rectilinear_path (cairo_clip_t *clip, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - cairo_antialias_t antialias); - -cairo_private cairo_clip_t * -_cairo_clip_intersect_path (cairo_clip_t *clip, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias); - -cairo_private const cairo_rectangle_int_t * -_cairo_clip_get_extents (const cairo_clip_t *clip); - -cairo_private cairo_surface_t * -_cairo_clip_get_surface (const cairo_clip_t *clip, cairo_surface_t *dst, int *tx, int *ty); - -cairo_private cairo_surface_t * -_cairo_clip_get_image (const cairo_clip_t *clip, - cairo_surface_t *target, - const cairo_rectangle_int_t *extents); - -cairo_private cairo_status_t -_cairo_clip_combine_with_surface (const cairo_clip_t *clip, - cairo_surface_t *dst, - int dst_x, int dst_y); - -cairo_private cairo_clip_t * -_cairo_clip_from_boxes (const cairo_boxes_t *boxes); - -cairo_private cairo_region_t * -_cairo_clip_get_region (const cairo_clip_t *clip); - -cairo_private cairo_bool_t -_cairo_clip_is_region (const cairo_clip_t *clip); - -cairo_private cairo_clip_t * -_cairo_clip_reduce_to_rectangle (const cairo_clip_t *clip, - const cairo_rectangle_int_t *r); - -cairo_private cairo_clip_t * -_cairo_clip_reduce_for_composite (const cairo_clip_t *clip, - cairo_composite_rectangles_t *extents); - -cairo_private cairo_bool_t -_cairo_clip_contains_rectangle (const cairo_clip_t *clip, - const cairo_rectangle_int_t *rect); - -cairo_private cairo_bool_t -_cairo_clip_contains_box (const cairo_clip_t *clip, - const cairo_box_t *box); - -cairo_private cairo_bool_t -_cairo_clip_contains_extents (const cairo_clip_t *clip, - const cairo_composite_rectangles_t *extents); - -cairo_private cairo_rectangle_list_t* -_cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate); - -cairo_private cairo_rectangle_list_t * -_cairo_rectangle_list_create_in_error (cairo_status_t status); - -cairo_private cairo_bool_t -_cairo_clip_is_polygon (const cairo_clip_t *clip); - -cairo_private cairo_int_status_t -_cairo_clip_get_polygon (const cairo_clip_t *clip, - cairo_polygon_t *polygon, - cairo_fill_rule_t *fill_rule, - cairo_antialias_t *antialias); - -#endif /* CAIRO_CLIP_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-clip-region.c b/source/libs/cairo/cairo-src/src/cairo-clip-region.c deleted file mode 100644 index e3f4891e3f258230935e5eaa40b5a1a16399cac5..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-clip-region.c +++ /dev/null @@ -1,123 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Kristian Høgsberg <krh@redhat.com> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" -#include "cairo-clip-private.h" -#include "cairo-error-private.h" -#include "cairo-freed-pool-private.h" -#include "cairo-gstate-private.h" -#include "cairo-path-fixed-private.h" -#include "cairo-pattern-private.h" -#include "cairo-composite-rectangles-private.h" -#include "cairo-region-private.h" - -static void -_cairo_clip_extract_region (cairo_clip_t *clip) -{ - cairo_rectangle_int_t stack_rects[CAIRO_STACK_ARRAY_LENGTH (cairo_rectangle_int_t)]; - cairo_rectangle_int_t *r = stack_rects; - cairo_bool_t is_region; - int i; - - if (clip->num_boxes == 0) - return; - - if (clip->num_boxes > ARRAY_LENGTH (stack_rects)) { - r = _cairo_malloc_ab (clip->num_boxes, sizeof (cairo_rectangle_int_t)); - if (r == NULL){ - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return; - } - } - - is_region = clip->path == NULL; - for (i = 0; i < clip->num_boxes; i++) { - cairo_box_t *b = &clip->boxes[i]; - if (is_region) - is_region = - _cairo_fixed_is_integer (b->p1.x | b->p1.y | b->p2.x | b->p2.y); - r[i].x = _cairo_fixed_integer_floor (b->p1.x); - r[i].y = _cairo_fixed_integer_floor (b->p1.y); - r[i].width = _cairo_fixed_integer_ceil (b->p2.x) - r[i].x; - r[i].height = _cairo_fixed_integer_ceil (b->p2.y) - r[i].y; - } - clip->is_region = is_region; - - clip->region = cairo_region_create_rectangles (r, i); - - if (r != stack_rects) - free (r); -} - -cairo_region_t * -_cairo_clip_get_region (const cairo_clip_t *clip) -{ - if (clip == NULL) - return NULL; - - if (clip->region == NULL) - _cairo_clip_extract_region ((cairo_clip_t *) clip); - - return clip->region; -} - -cairo_bool_t -_cairo_clip_is_region (const cairo_clip_t *clip) -{ - if (clip == NULL) - return TRUE; - - if (clip->is_region) - return TRUE; - - /* XXX Geometric reduction? */ - - if (clip->path) - return FALSE; - - if (clip->num_boxes == 0) - return TRUE; - - if (clip->region == NULL) - _cairo_clip_extract_region ((cairo_clip_t *) clip); - - return clip->is_region; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-clip-surface.c b/source/libs/cairo/cairo-src/src/cairo-clip-surface.c deleted file mode 100644 index 85feaa649eb33e166c570f5335ca10ecc69f5c90..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-clip-surface.c +++ /dev/null @@ -1,240 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Kristian Høgsberg <krh@redhat.com> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" -#include "cairo-clip-private.h" -#include "cairo-error-private.h" -#include "cairo-freed-pool-private.h" -#include "cairo-gstate-private.h" -#include "cairo-path-fixed-private.h" -#include "cairo-pattern-private.h" -#include "cairo-composite-rectangles-private.h" -#include "cairo-region-private.h" - -cairo_status_t -_cairo_clip_combine_with_surface (const cairo_clip_t *clip, - cairo_surface_t *dst, - int dst_x, int dst_y) -{ - cairo_clip_path_t *copy_path; - cairo_clip_path_t *clip_path; - cairo_clip_t *copy; - cairo_status_t status = CAIRO_STATUS_SUCCESS; - - copy = _cairo_clip_copy_with_translation (clip, -dst_x, -dst_y); - copy_path = copy->path; - copy->path = NULL; - - if (copy->boxes) { - status = _cairo_surface_paint (dst, - CAIRO_OPERATOR_IN, - &_cairo_pattern_white.base, - copy); - } - - clip = NULL; - if (_cairo_clip_is_region (copy)) - clip = copy; - clip_path = copy_path; - while (status == CAIRO_STATUS_SUCCESS && clip_path) { - status = _cairo_surface_fill (dst, - CAIRO_OPERATOR_IN, - &_cairo_pattern_white.base, - &clip_path->path, - clip_path->fill_rule, - clip_path->tolerance, - clip_path->antialias, - clip); - clip_path = clip_path->prev; - } - - copy->path = copy_path; - _cairo_clip_destroy (copy); - return status; -} - -static cairo_status_t -_cairo_path_fixed_add_box (cairo_path_fixed_t *path, - const cairo_box_t *box, - cairo_fixed_t fx, - cairo_fixed_t fy) -{ - cairo_status_t status; - - status = _cairo_path_fixed_move_to (path, box->p1.x + fx, box->p1.y + fy); - if (unlikely (status)) - return status; - - status = _cairo_path_fixed_line_to (path, box->p2.x + fx, box->p1.y + fy); - if (unlikely (status)) - return status; - - status = _cairo_path_fixed_line_to (path, box->p2.x + fx, box->p2.y + fy); - if (unlikely (status)) - return status; - - status = _cairo_path_fixed_line_to (path, box->p1.x + fx, box->p2.y + fy); - if (unlikely (status)) - return status; - - return _cairo_path_fixed_close_path (path); -} - -cairo_surface_t * -_cairo_clip_get_surface (const cairo_clip_t *clip, - cairo_surface_t *target, - int *tx, int *ty) -{ - cairo_surface_t *surface; - cairo_status_t status; - cairo_clip_t *copy, *region; - cairo_clip_path_t *copy_path, *clip_path; - - if (clip->num_boxes) { - cairo_path_fixed_t path; - int i; - - surface = _cairo_surface_create_scratch (target, - CAIRO_CONTENT_ALPHA, - clip->extents.width, - clip->extents.height, - CAIRO_COLOR_TRANSPARENT); - if (unlikely (surface->status)) - return surface; - - _cairo_path_fixed_init (&path); - status = CAIRO_STATUS_SUCCESS; - for (i = 0; status == CAIRO_STATUS_SUCCESS && i < clip->num_boxes; i++) { - status = _cairo_path_fixed_add_box (&path, &clip->boxes[i], - -_cairo_fixed_from_int (clip->extents.x), - -_cairo_fixed_from_int (clip->extents.y)); - } - if (status == CAIRO_STATUS_SUCCESS) - status = _cairo_surface_fill (surface, - CAIRO_OPERATOR_ADD, - &_cairo_pattern_white.base, - &path, - CAIRO_FILL_RULE_WINDING, - 1., - CAIRO_ANTIALIAS_DEFAULT, - NULL); - _cairo_path_fixed_fini (&path); - if (unlikely (status)) { - cairo_surface_destroy (surface); - return _cairo_surface_create_in_error (status); - } - } else { - surface = _cairo_surface_create_scratch (target, - CAIRO_CONTENT_ALPHA, - clip->extents.width, - clip->extents.height, - CAIRO_COLOR_WHITE); - if (unlikely (surface->status)) - return surface; - } - - copy = _cairo_clip_copy_with_translation (clip, - -clip->extents.x, - -clip->extents.y); - copy_path = copy->path; - copy->path = NULL; - - region = copy; - if (! _cairo_clip_is_region (copy)) - region = _cairo_clip_copy_region (copy); - - status = CAIRO_STATUS_SUCCESS; - clip_path = copy_path; - while (status == CAIRO_STATUS_SUCCESS && clip_path) { - status = _cairo_surface_fill (surface, - CAIRO_OPERATOR_IN, - &_cairo_pattern_white.base, - &clip_path->path, - clip_path->fill_rule, - clip_path->tolerance, - clip_path->antialias, - region); - clip_path = clip_path->prev; - } - - copy->path = copy_path; - _cairo_clip_destroy (copy); - if (region != copy) - _cairo_clip_destroy (region); - - if (unlikely (status)) { - cairo_surface_destroy (surface); - return _cairo_surface_create_in_error (status); - } - - *tx = clip->extents.x; - *ty = clip->extents.y; - return surface; -} - -cairo_surface_t * -_cairo_clip_get_image (const cairo_clip_t *clip, - cairo_surface_t *target, - const cairo_rectangle_int_t *extents) -{ - cairo_surface_t *surface; - cairo_status_t status; - - surface = cairo_surface_create_similar_image (target, - CAIRO_FORMAT_A8, - extents->width, - extents->height); - if (unlikely (surface->status)) - return surface; - - status = _cairo_surface_paint (surface, CAIRO_OPERATOR_SOURCE, - &_cairo_pattern_white.base, NULL); - if (likely (status == CAIRO_STATUS_SUCCESS)) - status = _cairo_clip_combine_with_surface (clip, surface, - extents->x, extents->y); - - if (unlikely (status)) { - cairo_surface_destroy (surface); - surface = _cairo_surface_create_in_error (status); - } - - return surface; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-clip-tor-scan-converter.c b/source/libs/cairo/cairo-src/src/cairo-clip-tor-scan-converter.c deleted file mode 100644 index e32a5a9d9c7a4e0d0460c1fc738fb9a7f3484df8..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-clip-tor-scan-converter.c +++ /dev/null @@ -1,1845 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* glitter-paths - polygon scan converter - * - * Copyright (c) 2008 M Joonas Pihlaja - * Copyright (c) 2007 David Turner - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -/* This is the Glitter paths scan converter incorporated into cairo. - * The source is from commit 734c53237a867a773640bd5b64816249fa1730f8 - * of - * - * http://gitweb.freedesktop.org/?p=users/joonas/glitter-paths - */ -/* Glitter-paths is a stand alone polygon rasteriser derived from - * David Turner's reimplementation of Tor Anderssons's 15x17 - * supersampling rasteriser from the Apparition graphics library. The - * main new feature here is cheaply choosing per-scan line between - * doing fully analytical coverage computation for an entire row at a - * time vs. using a supersampling approach. - * - * David Turner's code can be found at - * - * http://david.freetype.org/rasterizer-shootout/raster-comparison-20070813.tar.bz2 - * - * In particular this file incorporates large parts of ftgrays_tor10.h - * from raster-comparison-20070813.tar.bz2 - */ -/* Overview - * - * A scan converter's basic purpose to take polygon edges and convert - * them into an RLE compressed A8 mask. This one works in two phases: - * gathering edges and generating spans. - * - * 1) As the user feeds the scan converter edges they are vertically - * clipped and bucketted into a _polygon_ data structure. The edges - * are also snapped from the user's coordinates to the subpixel grid - * coordinates used during scan conversion. - * - * user - * | - * | edges - * V - * polygon buckets - * - * 2) Generating spans works by performing a vertical sweep of pixel - * rows from top to bottom and maintaining an _active_list_ of edges - * that intersect the row. From the active list the fill rule - * determines which edges are the left and right edges of the start of - * each span, and their contribution is then accumulated into a pixel - * coverage list (_cell_list_) as coverage deltas. Once the coverage - * deltas of all edges are known we can form spans of constant pixel - * coverage by summing the deltas during a traversal of the cell list. - * At the end of a pixel row the cell list is sent to a coverage - * blitter for rendering to some target surface. - * - * The pixel coverages are computed by either supersampling the row - * and box filtering a mono rasterisation, or by computing the exact - * coverages of edges in the active list. The supersampling method is - * used whenever some edge starts or stops within the row or there are - * edge intersections in the row. - * - * polygon bucket for \ - * current pixel row | - * | | - * | activate new edges | Repeat GRID_Y times if we - * V \ are supersampling this row, - * active list / or just once if we're computing - * | | analytical coverage. - * | coverage deltas | - * V | - * pixel coverage list / - * | - * V - * coverage blitter - */ -#include "cairoint.h" -#include "cairo-spans-private.h" -#include "cairo-error-private.h" - -#include <assert.h> -#include <stdlib.h> -#include <string.h> -#include <limits.h> -#include <setjmp.h> - -/* The input coordinate scale and the rasterisation grid scales. */ -#define GLITTER_INPUT_BITS CAIRO_FIXED_FRAC_BITS -#define GRID_X_BITS CAIRO_FIXED_FRAC_BITS -#define GRID_Y 15 - -/* Set glitter up to use a cairo span renderer to do the coverage - * blitting. */ -struct pool; -struct cell_list; - -/*------------------------------------------------------------------------- - * glitter-paths.h - */ - -/* "Input scaled" numbers are fixed precision reals with multiplier - * 2**GLITTER_INPUT_BITS. Input coordinates are given to glitter as - * pixel scaled numbers. These get converted to the internal grid - * scaled numbers as soon as possible. Internal overflow is possible - * if GRID_X/Y inside glitter-paths.c is larger than - * 1<<GLITTER_INPUT_BITS. */ -#ifndef GLITTER_INPUT_BITS -# define GLITTER_INPUT_BITS 8 -#endif -#define GLITTER_INPUT_SCALE (1<<GLITTER_INPUT_BITS) -typedef int glitter_input_scaled_t; - -/* Opaque type for scan converting. */ -typedef struct glitter_scan_converter glitter_scan_converter_t; - -/*------------------------------------------------------------------------- - * glitter-paths.c: Implementation internal types - */ -#include <stdlib.h> -#include <string.h> -#include <limits.h> - -/* All polygon coordinates are snapped onto a subsample grid. "Grid - * scaled" numbers are fixed precision reals with multiplier GRID_X or - * GRID_Y. */ -typedef int grid_scaled_t; -typedef int grid_scaled_x_t; -typedef int grid_scaled_y_t; - -/* Default x/y scale factors. - * You can either define GRID_X/Y_BITS to get a power-of-two scale - * or define GRID_X/Y separately. */ -#if !defined(GRID_X) && !defined(GRID_X_BITS) -# define GRID_X_BITS 8 -#endif -#if !defined(GRID_Y) && !defined(GRID_Y_BITS) -# define GRID_Y 15 -#endif - -/* Use GRID_X/Y_BITS to define GRID_X/Y if they're available. */ -#ifdef GRID_X_BITS -# define GRID_X (1 << GRID_X_BITS) -#endif -#ifdef GRID_Y_BITS -# define GRID_Y (1 << GRID_Y_BITS) -#endif - -/* The GRID_X_TO_INT_FRAC macro splits a grid scaled coordinate into - * integer and fractional parts. The integer part is floored. */ -#if defined(GRID_X_TO_INT_FRAC) - /* do nothing */ -#elif defined(GRID_X_BITS) -# define GRID_X_TO_INT_FRAC(x, i, f) \ - _GRID_TO_INT_FRAC_shift(x, i, f, GRID_X_BITS) -#else -# define GRID_X_TO_INT_FRAC(x, i, f) \ - _GRID_TO_INT_FRAC_general(x, i, f, GRID_X) -#endif - -#define _GRID_TO_INT_FRAC_general(t, i, f, m) do { \ - (i) = (t) / (m); \ - (f) = (t) % (m); \ - if ((f) < 0) { \ - --(i); \ - (f) += (m); \ - } \ -} while (0) - -#define _GRID_TO_INT_FRAC_shift(t, i, f, b) do { \ - (f) = (t) & ((1 << (b)) - 1); \ - (i) = (t) >> (b); \ -} while (0) - -/* A grid area is a real in [0,1] scaled by 2*GRID_X*GRID_Y. We want - * to be able to represent exactly areas of subpixel trapezoids whose - * vertices are given in grid scaled coordinates. The scale factor - * comes from needing to accurately represent the area 0.5*dx*dy of a - * triangle with base dx and height dy in grid scaled numbers. */ -typedef int grid_area_t; -#define GRID_XY (2*GRID_X*GRID_Y) /* Unit area on the grid. */ - -/* GRID_AREA_TO_ALPHA(area): map [0,GRID_XY] to [0,255]. */ -#if GRID_XY == 510 -# define GRID_AREA_TO_ALPHA(c) (((c)+1) >> 1) -#elif GRID_XY == 255 -# define GRID_AREA_TO_ALPHA(c) (c) -#elif GRID_XY == 64 -# define GRID_AREA_TO_ALPHA(c) (((c) << 2) | -(((c) & 0x40) >> 6)) -#elif GRID_XY == 128 -# define GRID_AREA_TO_ALPHA(c) ((((c) << 1) | -((c) >> 7)) & 255) -#elif GRID_XY == 256 -# define GRID_AREA_TO_ALPHA(c) (((c) | -((c) >> 8)) & 255) -#elif GRID_XY == 15 -# define GRID_AREA_TO_ALPHA(c) (((c) << 4) + (c)) -#elif GRID_XY == 2*256*15 -# define GRID_AREA_TO_ALPHA(c) (((c) + ((c)<<4) + 256) >> 9) -#else -# define GRID_AREA_TO_ALPHA(c) (((c)*255 + GRID_XY/2) / GRID_XY) -#endif - -#define UNROLL3(x) x x x - -struct quorem { - int32_t quo; - int32_t rem; -}; - -/* Header for a chunk of memory in a memory pool. */ -struct _pool_chunk { - /* # bytes used in this chunk. */ - size_t size; - - /* # bytes total in this chunk */ - size_t capacity; - - /* Pointer to the previous chunk or %NULL if this is the sentinel - * chunk in the pool header. */ - struct _pool_chunk *prev_chunk; - - /* Actual data starts here. Well aligned for pointers. */ -}; - -/* A memory pool. This is supposed to be embedded on the stack or - * within some other structure. It may optionally be followed by an - * embedded array from which requests are fulfilled until - * malloc needs to be called to allocate a first real chunk. */ -struct pool { - /* Chunk we're allocating from. */ - struct _pool_chunk *current; - - jmp_buf *jmp; - - /* Free list of previously allocated chunks. All have >= default - * capacity. */ - struct _pool_chunk *first_free; - - /* The default capacity of a chunk. */ - size_t default_capacity; - - /* Header for the sentinel chunk. Directly following the pool - * struct should be some space for embedded elements from which - * the sentinel chunk allocates from. */ - struct _pool_chunk sentinel[1]; -}; - -/* A polygon edge. */ -struct edge { - /* Next in y-bucket or active list. */ - struct edge *next; - - /* Current x coordinate while the edge is on the active - * list. Initialised to the x coordinate of the top of the - * edge. The quotient is in grid_scaled_x_t units and the - * remainder is mod dy in grid_scaled_y_t units.*/ - struct quorem x; - - /* Advance of the current x when moving down a subsample line. */ - struct quorem dxdy; - - /* Advance of the current x when moving down a full pixel - * row. Only initialised when the height of the edge is large - * enough that there's a chance the edge could be stepped by a - * full row's worth of subsample rows at a time. */ - struct quorem dxdy_full; - - /* The clipped y of the top of the edge. */ - grid_scaled_y_t ytop; - - /* y2-y1 after orienting the edge downwards. */ - grid_scaled_y_t dy; - - /* Number of subsample rows remaining to scan convert of this - * edge. */ - grid_scaled_y_t height_left; - - /* Original sign of the edge: +1 for downwards, -1 for upwards - * edges. */ - int dir; - int vertical; - int clip; -}; - -/* Number of subsample rows per y-bucket. Must be GRID_Y. */ -#define EDGE_Y_BUCKET_HEIGHT GRID_Y - -#define EDGE_Y_BUCKET_INDEX(y, ymin) (((y) - (ymin))/EDGE_Y_BUCKET_HEIGHT) - -/* A collection of sorted and vertically clipped edges of the polygon. - * Edges are moved from the polygon to an active list while scan - * converting. */ -struct polygon { - /* The vertical clip extents. */ - grid_scaled_y_t ymin, ymax; - - /* Array of edges all starting in the same bucket. An edge is put - * into bucket EDGE_BUCKET_INDEX(edge->ytop, polygon->ymin) when - * it is added to the polygon. */ - struct edge **y_buckets; - struct edge *y_buckets_embedded[64]; - - struct { - struct pool base[1]; - struct edge embedded[32]; - } edge_pool; -}; - -/* A cell records the effect on pixel coverage of polygon edges - * passing through a pixel. It contains two accumulators of pixel - * coverage. - * - * Consider the effects of a polygon edge on the coverage of a pixel - * it intersects and that of the following one. The coverage of the - * following pixel is the height of the edge multiplied by the width - * of the pixel, and the coverage of the pixel itself is the area of - * the trapezoid formed by the edge and the right side of the pixel. - * - * +-----------------------+-----------------------+ - * | | | - * | | | - * |_______________________|_______________________| - * | \...................|.......................|\ - * | \..................|.......................| | - * | \.................|.......................| | - * | \....covered.....|.......................| | - * | \....area.......|.......................| } covered height - * | \..............|.......................| | - * |uncovered\.............|.......................| | - * | area \............|.......................| | - * |___________\...........|.......................|/ - * | | | - * | | | - * | | | - * +-----------------------+-----------------------+ - * - * Since the coverage of the following pixel will always be a multiple - * of the width of the pixel, we can store the height of the covered - * area instead. The coverage of the pixel itself is the total - * coverage minus the area of the uncovered area to the left of the - * edge. As it's faster to compute the uncovered area we only store - * that and subtract it from the total coverage later when forming - * spans to blit. - * - * The heights and areas are signed, with left edges of the polygon - * having positive sign and right edges having negative sign. When - * two edges intersect they swap their left/rightness so their - * contribution above and below the intersection point must be - * computed separately. */ -struct cell { - struct cell *next; - int x; - grid_area_t uncovered_area; - grid_scaled_y_t covered_height; - grid_scaled_y_t clipped_height; -}; - -/* A cell list represents the scan line sparsely as cells ordered by - * ascending x. It is geared towards scanning the cells in order - * using an internal cursor. */ -struct cell_list { - /* Sentinel nodes */ - struct cell head, tail; - - /* Cursor state for iterating through the cell list. */ - struct cell *cursor; - - /* Cells in the cell list are owned by the cell list and are - * allocated from this pool. */ - struct { - struct pool base[1]; - struct cell embedded[32]; - } cell_pool; -}; - -struct cell_pair { - struct cell *cell1; - struct cell *cell2; -}; - -/* The active list contains edges in the current scan line ordered by - * the x-coordinate of the intercept of the edge and the scan line. */ -struct active_list { - /* Leftmost edge on the current scan line. */ - struct edge *head; - - /* A lower bound on the height of the active edges is used to - * estimate how soon some active edge ends. We can't advance the - * scan conversion by a full pixel row if an edge ends somewhere - * within it. */ - grid_scaled_y_t min_height; -}; - -struct glitter_scan_converter { - struct polygon polygon[1]; - struct active_list active[1]; - struct cell_list coverages[1]; - - /* Clip box. */ - grid_scaled_y_t ymin, ymax; -}; - -/* Compute the floored division a/b. Assumes / and % perform symmetric - * division. */ -inline static struct quorem -floored_divrem(int a, int b) -{ - struct quorem qr; - qr.quo = a/b; - qr.rem = a%b; - if ((a^b)<0 && qr.rem) { - qr.quo -= 1; - qr.rem += b; - } - return qr; -} - -/* Compute the floored division (x*a)/b. Assumes / and % perform symmetric - * division. */ -static struct quorem -floored_muldivrem(int x, int a, int b) -{ - struct quorem qr; - long long xa = (long long)x*a; - qr.quo = xa/b; - qr.rem = xa%b; - if ((xa>=0) != (b>=0) && qr.rem) { - qr.quo -= 1; - qr.rem += b; - } - return qr; -} - -static struct _pool_chunk * -_pool_chunk_init( - struct _pool_chunk *p, - struct _pool_chunk *prev_chunk, - size_t capacity) -{ - p->prev_chunk = prev_chunk; - p->size = 0; - p->capacity = capacity; - return p; -} - -static struct _pool_chunk * -_pool_chunk_create(struct pool *pool, size_t size) -{ - struct _pool_chunk *p; - - p = malloc(size + sizeof(struct _pool_chunk)); - if (unlikely (NULL == p)) - longjmp (*pool->jmp, _cairo_error (CAIRO_STATUS_NO_MEMORY)); - - return _pool_chunk_init(p, pool->current, size); -} - -static void -pool_init(struct pool *pool, - jmp_buf *jmp, - size_t default_capacity, - size_t embedded_capacity) -{ - pool->jmp = jmp; - pool->current = pool->sentinel; - pool->first_free = NULL; - pool->default_capacity = default_capacity; - _pool_chunk_init(pool->sentinel, NULL, embedded_capacity); -} - -static void -pool_fini(struct pool *pool) -{ - struct _pool_chunk *p = pool->current; - do { - while (NULL != p) { - struct _pool_chunk *prev = p->prev_chunk; - if (p != pool->sentinel) - free(p); - p = prev; - } - p = pool->first_free; - pool->first_free = NULL; - } while (NULL != p); -} - -/* Satisfy an allocation by first allocating a new large enough chunk - * and adding it to the head of the pool's chunk list. This function - * is called as a fallback if pool_alloc() couldn't do a quick - * allocation from the current chunk in the pool. */ -static void * -_pool_alloc_from_new_chunk( - struct pool *pool, - size_t size) -{ - struct _pool_chunk *chunk; - void *obj; - size_t capacity; - - /* If the allocation is smaller than the default chunk size then - * try getting a chunk off the free list. Force alloc of a new - * chunk for large requests. */ - capacity = size; - chunk = NULL; - if (size < pool->default_capacity) { - capacity = pool->default_capacity; - chunk = pool->first_free; - if (chunk) { - pool->first_free = chunk->prev_chunk; - _pool_chunk_init(chunk, pool->current, chunk->capacity); - } - } - - if (NULL == chunk) - chunk = _pool_chunk_create (pool, capacity); - pool->current = chunk; - - obj = ((unsigned char*)chunk + sizeof(*chunk) + chunk->size); - chunk->size += size; - return obj; -} - -/* Allocate size bytes from the pool. The first allocated address - * returned from a pool is aligned to sizeof(void*). Subsequent - * addresses will maintain alignment as long as multiples of void* are - * allocated. Returns the address of a new memory area or %NULL on - * allocation failures. The pool retains ownership of the returned - * memory. */ -inline static void * -pool_alloc (struct pool *pool, size_t size) -{ - struct _pool_chunk *chunk = pool->current; - - if (size <= chunk->capacity - chunk->size) { - void *obj = ((unsigned char*)chunk + sizeof(*chunk) + chunk->size); - chunk->size += size; - return obj; - } else { - return _pool_alloc_from_new_chunk(pool, size); - } -} - -/* Relinquish all pool_alloced memory back to the pool. */ -static void -pool_reset (struct pool *pool) -{ - /* Transfer all used chunks to the chunk free list. */ - struct _pool_chunk *chunk = pool->current; - if (chunk != pool->sentinel) { - while (chunk->prev_chunk != pool->sentinel) { - chunk = chunk->prev_chunk; - } - chunk->prev_chunk = pool->first_free; - pool->first_free = pool->current; - } - /* Reset the sentinel as the current chunk. */ - pool->current = pool->sentinel; - pool->sentinel->size = 0; -} - -/* Rewinds the cell list's cursor to the beginning. After rewinding - * we're good to cell_list_find() the cell any x coordinate. */ -inline static void -cell_list_rewind (struct cell_list *cells) -{ - cells->cursor = &cells->head; -} - -/* Rewind the cell list if its cursor has been advanced past x. */ -inline static void -cell_list_maybe_rewind (struct cell_list *cells, int x) -{ - struct cell *tail = cells->cursor; - if (tail->x > x) - cell_list_rewind (cells); -} - -static void -cell_list_init(struct cell_list *cells, jmp_buf *jmp) -{ - pool_init(cells->cell_pool.base, jmp, - 256*sizeof(struct cell), - sizeof(cells->cell_pool.embedded)); - cells->tail.next = NULL; - cells->tail.x = INT_MAX; - cells->head.x = INT_MIN; - cells->head.next = &cells->tail; - cell_list_rewind (cells); -} - -static void -cell_list_fini(struct cell_list *cells) -{ - pool_fini (cells->cell_pool.base); -} - -/* Empty the cell list. This is called at the start of every pixel - * row. */ -inline static void -cell_list_reset (struct cell_list *cells) -{ - cell_list_rewind (cells); - cells->head.next = &cells->tail; - pool_reset (cells->cell_pool.base); -} - -static struct cell * -cell_list_alloc (struct cell_list *cells, - struct cell *tail, - int x) -{ - struct cell *cell; - - cell = pool_alloc (cells->cell_pool.base, sizeof (struct cell)); - cell->next = tail->next; - tail->next = cell; - cell->x = x; - cell->uncovered_area = 0; - cell->covered_height = 0; - cell->clipped_height = 0; - return cell; -} - -/* Find a cell at the given x-coordinate. Returns %NULL if a new cell - * needed to be allocated but couldn't be. Cells must be found with - * non-decreasing x-coordinate until the cell list is rewound using - * cell_list_rewind(). Ownership of the returned cell is retained by - * the cell list. */ -inline static struct cell * -cell_list_find (struct cell_list *cells, int x) -{ - struct cell *tail = cells->cursor; - - while (1) { - UNROLL3({ - if (tail->next->x > x) - break; - tail = tail->next; - }); - } - - if (tail->x != x) - tail = cell_list_alloc (cells, tail, x); - return cells->cursor = tail; - -} - -/* Find two cells at x1 and x2. This is exactly equivalent - * to - * - * pair.cell1 = cell_list_find(cells, x1); - * pair.cell2 = cell_list_find(cells, x2); - * - * except with less function call overhead. */ -inline static struct cell_pair -cell_list_find_pair(struct cell_list *cells, int x1, int x2) -{ - struct cell_pair pair; - - pair.cell1 = cells->cursor; - while (1) { - UNROLL3({ - if (pair.cell1->next->x > x1) - break; - pair.cell1 = pair.cell1->next; - }); - } - if (pair.cell1->x != x1) { - struct cell *cell = pool_alloc (cells->cell_pool.base, - sizeof (struct cell)); - cell->x = x1; - cell->uncovered_area = 0; - cell->covered_height = 0; - cell->clipped_height = 0; - cell->next = pair.cell1->next; - pair.cell1->next = cell; - pair.cell1 = cell; - } - - pair.cell2 = pair.cell1; - while (1) { - UNROLL3({ - if (pair.cell2->next->x > x2) - break; - pair.cell2 = pair.cell2->next; - }); - } - if (pair.cell2->x != x2) { - struct cell *cell = pool_alloc (cells->cell_pool.base, - sizeof (struct cell)); - cell->uncovered_area = 0; - cell->covered_height = 0; - cell->clipped_height = 0; - cell->x = x2; - cell->next = pair.cell2->next; - pair.cell2->next = cell; - pair.cell2 = cell; - } - - cells->cursor = pair.cell2; - return pair; -} - -/* Add a subpixel span covering [x1, x2) to the coverage cells. */ -inline static void -cell_list_add_subspan(struct cell_list *cells, - grid_scaled_x_t x1, - grid_scaled_x_t x2) -{ - int ix1, fx1; - int ix2, fx2; - - GRID_X_TO_INT_FRAC(x1, ix1, fx1); - GRID_X_TO_INT_FRAC(x2, ix2, fx2); - - if (ix1 != ix2) { - struct cell_pair p; - p = cell_list_find_pair(cells, ix1, ix2); - p.cell1->uncovered_area += 2*fx1; - ++p.cell1->covered_height; - p.cell2->uncovered_area -= 2*fx2; - --p.cell2->covered_height; - } else { - struct cell *cell = cell_list_find(cells, ix1); - cell->uncovered_area += 2*(fx1-fx2); - } -} - -/* Adds the analytical coverage of an edge crossing the current pixel - * row to the coverage cells and advances the edge's x position to the - * following row. - * - * This function is only called when we know that during this pixel row: - * - * 1) The relative order of all edges on the active list doesn't - * change. In particular, no edges intersect within this row to pixel - * precision. - * - * 2) No new edges start in this row. - * - * 3) No existing edges end mid-row. - * - * This function depends on being called with all edges from the - * active list in the order they appear on the list (i.e. with - * non-decreasing x-coordinate.) */ -static void -cell_list_render_edge( - struct cell_list *cells, - struct edge *edge, - int sign) -{ - grid_scaled_y_t y1, y2, dy; - grid_scaled_x_t dx; - int ix1, ix2; - grid_scaled_x_t fx1, fx2; - - struct quorem x1 = edge->x; - struct quorem x2 = x1; - - if (! edge->vertical) { - x2.quo += edge->dxdy_full.quo; - x2.rem += edge->dxdy_full.rem; - if (x2.rem >= 0) { - ++x2.quo; - x2.rem -= edge->dy; - } - - edge->x = x2; - } - - GRID_X_TO_INT_FRAC(x1.quo, ix1, fx1); - GRID_X_TO_INT_FRAC(x2.quo, ix2, fx2); - - /* Edge is entirely within a column? */ - if (ix1 == ix2) { - /* We always know that ix1 is >= the cell list cursor in this - * case due to the no-intersections precondition. */ - struct cell *cell = cell_list_find(cells, ix1); - cell->covered_height += sign*GRID_Y; - cell->uncovered_area += sign*(fx1 + fx2)*GRID_Y; - return; - } - - /* Orient the edge left-to-right. */ - dx = x2.quo - x1.quo; - if (dx >= 0) { - y1 = 0; - y2 = GRID_Y; - } else { - int tmp; - tmp = ix1; ix1 = ix2; ix2 = tmp; - tmp = fx1; fx1 = fx2; fx2 = tmp; - dx = -dx; - sign = -sign; - y1 = GRID_Y; - y2 = 0; - } - dy = y2 - y1; - - /* Add coverage for all pixels [ix1,ix2] on this row crossed - * by the edge. */ - { - struct cell_pair pair; - struct quorem y = floored_divrem((GRID_X - fx1)*dy, dx); - - /* When rendering a previous edge on the active list we may - * advance the cell list cursor past the leftmost pixel of the - * current edge even though the two edges don't intersect. - * e.g. consider two edges going down and rightwards: - * - * --\_+---\_+-----+-----+---- - * \_ \_ | | - * | \_ | \_ | | - * | \_| \_| | - * | \_ \_ | - * ----+-----+-\---+-\---+---- - * - * The left edge touches cells past the starting cell of the - * right edge. Fortunately such cases are rare. - * - * The rewinding is never necessary if the current edge stays - * within a single column because we've checked before calling - * this function that the active list order won't change. */ - cell_list_maybe_rewind(cells, ix1); - - pair = cell_list_find_pair(cells, ix1, ix1+1); - pair.cell1->uncovered_area += sign*y.quo*(GRID_X + fx1); - pair.cell1->covered_height += sign*y.quo; - y.quo += y1; - - if (ix1+1 < ix2) { - struct quorem dydx_full = floored_divrem(GRID_X*dy, dx); - struct cell *cell = pair.cell2; - - ++ix1; - do { - grid_scaled_y_t y_skip = dydx_full.quo; - y.rem += dydx_full.rem; - if (y.rem >= dx) { - ++y_skip; - y.rem -= dx; - } - - y.quo += y_skip; - - y_skip *= sign; - cell->uncovered_area += y_skip*GRID_X; - cell->covered_height += y_skip; - - ++ix1; - cell = cell_list_find(cells, ix1); - } while (ix1 != ix2); - - pair.cell2 = cell; - } - pair.cell2->uncovered_area += sign*(y2 - y.quo)*fx2; - pair.cell2->covered_height += sign*(y2 - y.quo); - } -} - -static void -polygon_init (struct polygon *polygon, jmp_buf *jmp) -{ - polygon->ymin = polygon->ymax = 0; - polygon->y_buckets = polygon->y_buckets_embedded; - pool_init (polygon->edge_pool.base, jmp, - 8192 - sizeof (struct _pool_chunk), - sizeof (polygon->edge_pool.embedded)); -} - -static void -polygon_fini (struct polygon *polygon) -{ - if (polygon->y_buckets != polygon->y_buckets_embedded) - free (polygon->y_buckets); - - pool_fini (polygon->edge_pool.base); -} - -/* Empties the polygon of all edges. The polygon is then prepared to - * receive new edges and clip them to the vertical range - * [ymin,ymax). */ -static cairo_status_t -polygon_reset (struct polygon *polygon, - grid_scaled_y_t ymin, - grid_scaled_y_t ymax) -{ - unsigned h = ymax - ymin; - unsigned num_buckets = EDGE_Y_BUCKET_INDEX(ymax + EDGE_Y_BUCKET_HEIGHT-1, - ymin); - - pool_reset(polygon->edge_pool.base); - - if (unlikely (h > 0x7FFFFFFFU - EDGE_Y_BUCKET_HEIGHT)) - goto bail_no_mem; /* even if you could, you wouldn't want to. */ - - if (polygon->y_buckets != polygon->y_buckets_embedded) - free (polygon->y_buckets); - - polygon->y_buckets = polygon->y_buckets_embedded; - if (num_buckets > ARRAY_LENGTH (polygon->y_buckets_embedded)) { - polygon->y_buckets = _cairo_malloc_ab (num_buckets, - sizeof (struct edge *)); - if (unlikely (NULL == polygon->y_buckets)) - goto bail_no_mem; - } - memset (polygon->y_buckets, 0, num_buckets * sizeof (struct edge *)); - - polygon->ymin = ymin; - polygon->ymax = ymax; - return CAIRO_STATUS_SUCCESS; - - bail_no_mem: - polygon->ymin = 0; - polygon->ymax = 0; - return CAIRO_STATUS_NO_MEMORY; -} - -static void -_polygon_insert_edge_into_its_y_bucket( - struct polygon *polygon, - struct edge *e) -{ - unsigned ix = EDGE_Y_BUCKET_INDEX(e->ytop, polygon->ymin); - struct edge **ptail = &polygon->y_buckets[ix]; - e->next = *ptail; - *ptail = e; -} - -inline static void -polygon_add_edge (struct polygon *polygon, - const cairo_edge_t *edge, - int clip) -{ - struct edge *e; - grid_scaled_x_t dx; - grid_scaled_y_t dy; - grid_scaled_y_t ytop, ybot; - grid_scaled_y_t ymin = polygon->ymin; - grid_scaled_y_t ymax = polygon->ymax; - - assert (edge->bottom > edge->top); - - if (unlikely (edge->top >= ymax || edge->bottom <= ymin)) - return; - - e = pool_alloc (polygon->edge_pool.base, sizeof (struct edge)); - - dx = edge->line.p2.x - edge->line.p1.x; - dy = edge->line.p2.y - edge->line.p1.y; - e->dy = dy; - e->dir = edge->dir; - e->clip = clip; - - ytop = edge->top >= ymin ? edge->top : ymin; - ybot = edge->bottom <= ymax ? edge->bottom : ymax; - e->ytop = ytop; - e->height_left = ybot - ytop; - - if (dx == 0) { - e->vertical = TRUE; - e->x.quo = edge->line.p1.x; - e->x.rem = 0; - e->dxdy.quo = 0; - e->dxdy.rem = 0; - e->dxdy_full.quo = 0; - e->dxdy_full.rem = 0; - } else { - e->vertical = FALSE; - e->dxdy = floored_divrem (dx, dy); - if (ytop == edge->line.p1.y) { - e->x.quo = edge->line.p1.x; - e->x.rem = 0; - } else { - e->x = floored_muldivrem (ytop - edge->line.p1.y, dx, dy); - e->x.quo += edge->line.p1.x; - } - - if (e->height_left >= GRID_Y) { - e->dxdy_full = floored_muldivrem (GRID_Y, dx, dy); - } else { - e->dxdy_full.quo = 0; - e->dxdy_full.rem = 0; - } - } - - _polygon_insert_edge_into_its_y_bucket (polygon, e); - - e->x.rem -= dy; /* Bias the remainder for faster - * edge advancement. */ -} - -static void -active_list_reset (struct active_list *active) -{ - active->head = NULL; - active->min_height = 0; -} - -static void -active_list_init(struct active_list *active) -{ - active_list_reset(active); -} - -/* - * Merge two sorted edge lists. - * Input: - * - head_a: The head of the first list. - * - head_b: The head of the second list; head_b cannot be NULL. - * Output: - * Returns the head of the merged list. - * - * Implementation notes: - * To make it fast (in particular, to reduce to an insertion sort whenever - * one of the two input lists only has a single element) we iterate through - * a list until its head becomes greater than the head of the other list, - * then we switch their roles. As soon as one of the two lists is empty, we - * just attach the other one to the current list and exit. - * Writes to memory are only needed to "switch" lists (as it also requires - * attaching to the output list the list which we will be iterating next) and - * to attach the last non-empty list. - */ -static struct edge * -merge_sorted_edges (struct edge *head_a, struct edge *head_b) -{ - struct edge *head, **next; - int32_t x; - - if (head_a == NULL) - return head_b; - - next = &head; - if (head_a->x.quo <= head_b->x.quo) { - head = head_a; - } else { - head = head_b; - goto start_with_b; - } - - do { - x = head_b->x.quo; - while (head_a != NULL && head_a->x.quo <= x) { - next = &head_a->next; - head_a = head_a->next; - } - - *next = head_b; - if (head_a == NULL) - return head; - -start_with_b: - x = head_a->x.quo; - while (head_b != NULL && head_b->x.quo <= x) { - next = &head_b->next; - head_b = head_b->next; - } - - *next = head_a; - if (head_b == NULL) - return head; - } while (1); -} - -/* - * Sort (part of) a list. - * Input: - * - list: The list to be sorted; list cannot be NULL. - * - limit: Recursion limit. - * Output: - * - head_out: The head of the sorted list containing the first 2^(level+1) elements of the - * input list; if the input list has fewer elements, head_out be a sorted list - * containing all the elements of the input list. - * Returns the head of the list of unprocessed elements (NULL if the sorted list contains - * all the elements of the input list). - * - * Implementation notes: - * Special case single element list, unroll/inline the sorting of the first two elements. - * Some tail recursion is used since we iterate on the bottom-up solution of the problem - * (we start with a small sorted list and keep merging other lists of the same size to it). - */ -static struct edge * -sort_edges (struct edge *list, - unsigned int level, - struct edge **head_out) -{ - struct edge *head_other, *remaining; - unsigned int i; - - head_other = list->next; - - /* Single element list -> return */ - if (head_other == NULL) { - *head_out = list; - return NULL; - } - - /* Unroll the first iteration of the following loop (halves the number of calls to merge_sorted_edges): - * - Initialize remaining to be the list containing the elements after the second in the input list. - * - Initialize *head_out to be the sorted list containing the first two element. - */ - remaining = head_other->next; - if (list->x.quo <= head_other->x.quo) { - *head_out = list; - /* list->next = head_other; */ /* The input list is already like this. */ - head_other->next = NULL; - } else { - *head_out = head_other; - head_other->next = list; - list->next = NULL; - } - - for (i = 0; i < level && remaining; i++) { - /* Extract a sorted list of the same size as *head_out - * (2^(i+1) elements) from the list of remaining elements. */ - remaining = sort_edges (remaining, i, &head_other); - *head_out = merge_sorted_edges (*head_out, head_other); - } - - /* *head_out now contains (at most) 2^(level+1) elements. */ - - return remaining; -} - -/* Test if the edges on the active list can be safely advanced by a - * full row without intersections or any edges ending. */ -inline static int -active_list_can_step_full_row (struct active_list *active) -{ - const struct edge *e; - int prev_x = INT_MIN; - - /* Recomputes the minimum height of all edges on the active - * list if we have been dropping edges. */ - if (active->min_height <= 0) { - int min_height = INT_MAX; - - e = active->head; - while (NULL != e) { - if (e->height_left < min_height) - min_height = e->height_left; - e = e->next; - } - - active->min_height = min_height; - } - - if (active->min_height < GRID_Y) - return 0; - - /* Check for intersections as no edges end during the next row. */ - e = active->head; - while (NULL != e) { - struct quorem x = e->x; - - if (! e->vertical) { - x.quo += e->dxdy_full.quo; - x.rem += e->dxdy_full.rem; - if (x.rem >= 0) - ++x.quo; - } - - if (x.quo <= prev_x) - return 0; - - prev_x = x.quo; - e = e->next; - } - - return 1; -} - -/* Merges edges on the given subpixel row from the polygon to the - * active_list. */ -inline static void -active_list_merge_edges_from_polygon(struct active_list *active, - struct edge **ptail, - grid_scaled_y_t y, - struct polygon *polygon) -{ - /* Split off the edges on the current subrow and merge them into - * the active list. */ - int min_height = active->min_height; - struct edge *subrow_edges = NULL; - struct edge *tail = *ptail; - - do { - struct edge *next = tail->next; - - if (y == tail->ytop) { - tail->next = subrow_edges; - subrow_edges = tail; - - if (tail->height_left < min_height) - min_height = tail->height_left; - - *ptail = next; - } else - ptail = &tail->next; - - tail = next; - } while (tail); - - if (subrow_edges) { - sort_edges (subrow_edges, UINT_MAX, &subrow_edges); - active->head = merge_sorted_edges (active->head, subrow_edges); - active->min_height = min_height; - } -} - -/* Advance the edges on the active list by one subsample row by - * updating their x positions. Drop edges from the list that end. */ -inline static void -active_list_substep_edges(struct active_list *active) -{ - struct edge **cursor = &active->head; - grid_scaled_x_t prev_x = INT_MIN; - struct edge *unsorted = NULL; - struct edge *edge = *cursor; - - do { - UNROLL3({ - struct edge *next; - - if (NULL == edge) - break; - - next = edge->next; - if (--edge->height_left) { - edge->x.quo += edge->dxdy.quo; - edge->x.rem += edge->dxdy.rem; - if (edge->x.rem >= 0) { - ++edge->x.quo; - edge->x.rem -= edge->dy; - } - - if (edge->x.quo < prev_x) { - *cursor = next; - edge->next = unsorted; - unsorted = edge; - } else { - prev_x = edge->x.quo; - cursor = &edge->next; - } - } else { - *cursor = next; - } - edge = next; - }) - } while (1); - - if (unsorted) { - sort_edges (unsorted, UINT_MAX, &unsorted); - active->head = merge_sorted_edges (active->head, unsorted); - } -} - -inline static void -apply_nonzero_fill_rule_for_subrow (struct active_list *active, - struct cell_list *coverages) -{ - struct edge *edge = active->head; - int winding = 0; - int xstart; - int xend; - - cell_list_rewind (coverages); - - while (NULL != edge) { - xstart = edge->x.quo; - winding = edge->dir; - while (1) { - edge = edge->next; - if (NULL == edge) { - ASSERT_NOT_REACHED; - return; - } - - winding += edge->dir; - if (0 == winding) { - if (edge->next == NULL || edge->next->x.quo != edge->x.quo) - break; - } - } - - xend = edge->x.quo; - cell_list_add_subspan (coverages, xstart, xend); - - edge = edge->next; - } -} - -static void -apply_evenodd_fill_rule_for_subrow (struct active_list *active, - struct cell_list *coverages) -{ - struct edge *edge = active->head; - int xstart; - int xend; - - cell_list_rewind (coverages); - - while (NULL != edge) { - xstart = edge->x.quo; - - while (1) { - edge = edge->next; - if (NULL == edge) { - ASSERT_NOT_REACHED; - return; - } - - if (edge->next == NULL || edge->next->x.quo != edge->x.quo) - break; - - edge = edge->next; - } - - xend = edge->x.quo; - cell_list_add_subspan (coverages, xstart, xend); - - edge = edge->next; - } -} - -static void -apply_nonzero_fill_rule_and_step_edges (struct active_list *active, - struct cell_list *coverages) -{ - struct edge **cursor = &active->head; - struct edge *left_edge; - - left_edge = *cursor; - while (NULL != left_edge) { - struct edge *right_edge; - int winding = left_edge->dir; - - left_edge->height_left -= GRID_Y; - if (left_edge->height_left) - cursor = &left_edge->next; - else - *cursor = left_edge->next; - - while (1) { - right_edge = *cursor; - if (NULL == right_edge) { - cell_list_render_edge (coverages, left_edge, +1); - return; - } - - right_edge->height_left -= GRID_Y; - if (right_edge->height_left) - cursor = &right_edge->next; - else - *cursor = right_edge->next; - - winding += right_edge->dir; - if (0 == winding) { - if (right_edge->next == NULL || - right_edge->next->x.quo != right_edge->x.quo) - { - break; - } - } - - if (! right_edge->vertical) { - right_edge->x.quo += right_edge->dxdy_full.quo; - right_edge->x.rem += right_edge->dxdy_full.rem; - if (right_edge->x.rem >= 0) { - ++right_edge->x.quo; - right_edge->x.rem -= right_edge->dy; - } - } - } - - cell_list_render_edge (coverages, left_edge, +1); - cell_list_render_edge (coverages, right_edge, -1); - - left_edge = *cursor; - } -} - -static void -apply_evenodd_fill_rule_and_step_edges (struct active_list *active, - struct cell_list *coverages) -{ - struct edge **cursor = &active->head; - struct edge *left_edge; - - left_edge = *cursor; - while (NULL != left_edge) { - struct edge *right_edge; - - left_edge->height_left -= GRID_Y; - if (left_edge->height_left) - cursor = &left_edge->next; - else - *cursor = left_edge->next; - - while (1) { - right_edge = *cursor; - if (NULL == right_edge) { - cell_list_render_edge (coverages, left_edge, +1); - return; - } - - right_edge->height_left -= GRID_Y; - if (right_edge->height_left) - cursor = &right_edge->next; - else - *cursor = right_edge->next; - - if (right_edge->next == NULL || - right_edge->next->x.quo != right_edge->x.quo) - { - break; - } - - if (! right_edge->vertical) { - right_edge->x.quo += right_edge->dxdy_full.quo; - right_edge->x.rem += right_edge->dxdy_full.rem; - if (right_edge->x.rem >= 0) { - ++right_edge->x.quo; - right_edge->x.rem -= right_edge->dy; - } - } - } - - cell_list_render_edge (coverages, left_edge, +1); - cell_list_render_edge (coverages, right_edge, -1); - - left_edge = *cursor; - } -} - -static void -_glitter_scan_converter_init(glitter_scan_converter_t *converter, jmp_buf *jmp) -{ - polygon_init(converter->polygon, jmp); - active_list_init(converter->active); - cell_list_init(converter->coverages, jmp); - converter->ymin=0; - converter->ymax=0; -} - -static void -_glitter_scan_converter_fini(glitter_scan_converter_t *converter) -{ - polygon_fini(converter->polygon); - cell_list_fini(converter->coverages); - converter->ymin=0; - converter->ymax=0; -} - -static grid_scaled_t -int_to_grid_scaled(int i, int scale) -{ - /* Clamp to max/min representable scaled number. */ - if (i >= 0) { - if (i >= INT_MAX/scale) - i = INT_MAX/scale; - } - else { - if (i <= INT_MIN/scale) - i = INT_MIN/scale; - } - return i*scale; -} - -#define int_to_grid_scaled_x(x) int_to_grid_scaled((x), GRID_X) -#define int_to_grid_scaled_y(x) int_to_grid_scaled((x), GRID_Y) - -static cairo_status_t -glitter_scan_converter_reset(glitter_scan_converter_t *converter, - int ymin, int ymax) -{ - cairo_status_t status; - - converter->ymin = 0; - converter->ymax = 0; - - ymin = int_to_grid_scaled_y(ymin); - ymax = int_to_grid_scaled_y(ymax); - - active_list_reset(converter->active); - cell_list_reset(converter->coverages); - status = polygon_reset(converter->polygon, ymin, ymax); - if (status) - return status; - - converter->ymin = ymin; - converter->ymax = ymax; - return CAIRO_STATUS_SUCCESS; -} - -/* INPUT_TO_GRID_X/Y (in_coord, out_grid_scaled, grid_scale) - * These macros convert an input coordinate in the client's - * device space to the rasterisation grid. - */ -/* Gah.. this bit of ugly defines INPUT_TO_GRID_X/Y so as to use - * shifts if possible, and something saneish if not. - */ -#if !defined(INPUT_TO_GRID_Y) && defined(GRID_Y_BITS) && GRID_Y_BITS <= GLITTER_INPUT_BITS -# define INPUT_TO_GRID_Y(in, out) (out) = (in) >> (GLITTER_INPUT_BITS - GRID_Y_BITS) -#else -# define INPUT_TO_GRID_Y(in, out) INPUT_TO_GRID_general(in, out, GRID_Y) -#endif - -#if !defined(INPUT_TO_GRID_X) && defined(GRID_X_BITS) && GRID_X_BITS <= GLITTER_INPUT_BITS -# define INPUT_TO_GRID_X(in, out) (out) = (in) >> (GLITTER_INPUT_BITS - GRID_X_BITS) -#else -# define INPUT_TO_GRID_X(in, out) INPUT_TO_GRID_general(in, out, GRID_X) -#endif - -#define INPUT_TO_GRID_general(in, out, grid_scale) do { \ - long long tmp__ = (long long)(grid_scale) * (in); \ - tmp__ >>= GLITTER_INPUT_BITS; \ - (out) = tmp__; \ -} while (0) - -static void -glitter_scan_converter_add_edge (glitter_scan_converter_t *converter, - const cairo_edge_t *edge, - int clip) -{ - cairo_edge_t e; - - INPUT_TO_GRID_Y (edge->top, e.top); - INPUT_TO_GRID_Y (edge->bottom, e.bottom); - if (e.top >= e.bottom) - return; - - /* XXX: possible overflows if GRID_X/Y > 2**GLITTER_INPUT_BITS */ - INPUT_TO_GRID_Y (edge->line.p1.y, e.line.p1.y); - INPUT_TO_GRID_Y (edge->line.p2.y, e.line.p2.y); - if (e.line.p1.y == e.line.p2.y) - return; - - INPUT_TO_GRID_X (edge->line.p1.x, e.line.p1.x); - INPUT_TO_GRID_X (edge->line.p2.x, e.line.p2.x); - - e.dir = edge->dir; - - polygon_add_edge (converter->polygon, &e, clip); -} - -static cairo_bool_t -active_list_is_vertical (struct active_list *active) -{ - struct edge *e; - - for (e = active->head; e != NULL; e = e->next) { - if (! e->vertical) - return FALSE; - } - - return TRUE; -} - -static void -step_edges (struct active_list *active, int count) -{ - struct edge **cursor = &active->head; - struct edge *edge; - - for (edge = *cursor; edge != NULL; edge = *cursor) { - edge->height_left -= GRID_Y * count; - if (edge->height_left) - cursor = &edge->next; - else - *cursor = edge->next; - } -} - -static cairo_status_t -blit_coverages (struct cell_list *cells, - cairo_span_renderer_t *renderer, - struct pool *span_pool, - int y, int height) -{ - struct cell *cell = cells->head.next; - int prev_x = -1; - int cover = 0, last_cover = 0; - int clip = 0; - cairo_half_open_span_t *spans; - unsigned num_spans; - - assert (cell != &cells->tail); - - /* Count number of cells remaining. */ - { - struct cell *next = cell; - num_spans = 2; - while (next->next) { - next = next->next; - ++num_spans; - } - num_spans = 2*num_spans; - } - - /* Allocate enough spans for the row. */ - pool_reset (span_pool); - spans = pool_alloc (span_pool, sizeof(spans[0])*num_spans); - num_spans = 0; - - /* Form the spans from the coverages and areas. */ - for (; cell->next; cell = cell->next) { - int x = cell->x; - int area; - - if (x > prev_x && cover != last_cover) { - spans[num_spans].x = prev_x; - spans[num_spans].coverage = GRID_AREA_TO_ALPHA (cover); - spans[num_spans].inverse = 0; - last_cover = cover; - ++num_spans; - } - - cover += cell->covered_height*GRID_X*2; - clip += cell->covered_height*GRID_X*2; - area = cover - cell->uncovered_area; - - if (area != last_cover) { - spans[num_spans].x = x; - spans[num_spans].coverage = GRID_AREA_TO_ALPHA (area); - spans[num_spans].inverse = 0; - last_cover = area; - ++num_spans; - } - - prev_x = x+1; - } - - /* Dump them into the renderer. */ - return renderer->render_rows (renderer, y, height, spans, num_spans); -} - -static void -glitter_scan_converter_render(glitter_scan_converter_t *converter, - int nonzero_fill, - cairo_span_renderer_t *span_renderer, - struct pool *span_pool) -{ - int i, j; - int ymax_i = converter->ymax / GRID_Y; - int ymin_i = converter->ymin / GRID_Y; - int h = ymax_i - ymin_i; - struct polygon *polygon = converter->polygon; - struct cell_list *coverages = converter->coverages; - struct active_list *active = converter->active; - - /* Render each pixel row. */ - for (i = 0; i < h; i = j) { - int do_full_step = 0; - - j = i + 1; - - /* Determine if we can ignore this row or use the full pixel - * stepper. */ - if (GRID_Y == EDGE_Y_BUCKET_HEIGHT && ! polygon->y_buckets[i]) { - if (! active->head) { - for (; j < h && ! polygon->y_buckets[j]; j++) - ; - continue; - } - - do_full_step = active_list_can_step_full_row (active); - } - - if (do_full_step) { - /* Step by a full pixel row's worth. */ - if (nonzero_fill) - apply_nonzero_fill_rule_and_step_edges (active, coverages); - else - apply_evenodd_fill_rule_and_step_edges (active, coverages); - - if (active_list_is_vertical (active)) { - while (j < h && - polygon->y_buckets[j] == NULL && - active->min_height >= 2*GRID_Y) - { - active->min_height -= GRID_Y; - j++; - } - if (j != i + 1) - step_edges (active, j - (i + 1)); - } - } else { - grid_scaled_y_t suby; - - /* Subsample this row. */ - for (suby = 0; suby < GRID_Y; suby++) { - grid_scaled_y_t y = (i+ymin_i)*GRID_Y + suby; - - if (polygon->y_buckets[i]) { - active_list_merge_edges_from_polygon (active, - &polygon->y_buckets[i], y, - polygon); - } - - if (nonzero_fill) - apply_nonzero_fill_rule_for_subrow (active, coverages); - else - apply_evenodd_fill_rule_for_subrow (active, coverages); - - active_list_substep_edges(active); - } - } - - blit_coverages (coverages, span_renderer, span_pool, i+ymin_i, j -i); - cell_list_reset (coverages); - - if (! active->head) - active->min_height = INT_MAX; - else - active->min_height -= GRID_Y; - } -} - -struct _cairo_clip_tor_scan_converter { - cairo_scan_converter_t base; - - glitter_scan_converter_t converter[1]; - cairo_fill_rule_t fill_rule; - cairo_antialias_t antialias; - - cairo_fill_rule_t clip_fill_rule; - cairo_antialias_t clip_antialias; - - jmp_buf jmp; - - struct { - struct pool base[1]; - cairo_half_open_span_t embedded[32]; - } span_pool; -}; - -typedef struct _cairo_clip_tor_scan_converter cairo_clip_tor_scan_converter_t; - -static void -_cairo_clip_tor_scan_converter_destroy (void *converter) -{ - cairo_clip_tor_scan_converter_t *self = converter; - if (self == NULL) { - return; - } - _glitter_scan_converter_fini (self->converter); - pool_fini (self->span_pool.base); - free(self); -} - -static cairo_status_t -_cairo_clip_tor_scan_converter_generate (void *converter, - cairo_span_renderer_t *renderer) -{ - cairo_clip_tor_scan_converter_t *self = converter; - cairo_status_t status; - - if ((status = setjmp (self->jmp))) - return _cairo_scan_converter_set_error (self, _cairo_error (status)); - - glitter_scan_converter_render (self->converter, - self->fill_rule == CAIRO_FILL_RULE_WINDING, - renderer, - self->span_pool.base); - return CAIRO_STATUS_SUCCESS; -} - -cairo_scan_converter_t * -_cairo_clip_tor_scan_converter_create (cairo_clip_t *clip, - cairo_polygon_t *polygon, - cairo_fill_rule_t fill_rule, - cairo_antialias_t antialias) -{ - cairo_clip_tor_scan_converter_t *self; - cairo_polygon_t clipper; - cairo_status_t status; - int i; - - self = calloc (1, sizeof(struct _cairo_clip_tor_scan_converter)); - if (unlikely (self == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto bail_nomem; - } - - self->base.destroy = _cairo_clip_tor_scan_converter_destroy; - self->base.generate = _cairo_clip_tor_scan_converter_generate; - - pool_init (self->span_pool.base, &self->jmp, - 250 * sizeof(self->span_pool.embedded[0]), - sizeof(self->span_pool.embedded)); - - _glitter_scan_converter_init (self->converter, &self->jmp); - status = glitter_scan_converter_reset (self->converter, - clip->extents.y, - clip->extents.y + clip->extents.height); - if (unlikely (status)) - goto bail; - - self->fill_rule = fill_rule; - self->antialias = antialias; - - for (i = 0; i < polygon->num_edges; i++) - glitter_scan_converter_add_edge (self->converter, - &polygon->edges[i], - FALSE); - - status = _cairo_clip_get_polygon (clip, - &clipper, - &self->clip_fill_rule, - &self->clip_antialias); - if (unlikely (status)) - goto bail; - - for (i = 0; i < clipper.num_edges; i++) - glitter_scan_converter_add_edge (self->converter, - &clipper.edges[i], - TRUE); - _cairo_polygon_fini (&clipper); - - return &self->base; - - bail: - self->base.destroy(&self->base); - bail_nomem: - return _cairo_scan_converter_create_in_error (status); -} - diff --git a/source/libs/cairo/cairo-src/src/cairo-clip.c b/source/libs/cairo/cairo-src/src/cairo-clip.c deleted file mode 100644 index 0df9b06bf60d4ff4dde33d081277a4b673556243..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-clip.c +++ /dev/null @@ -1,838 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Kristian Høgsberg <krh@redhat.com> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" -#include "cairo-clip-inline.h" -#include "cairo-clip-private.h" -#include "cairo-error-private.h" -#include "cairo-freed-pool-private.h" -#include "cairo-gstate-private.h" -#include "cairo-path-fixed-private.h" -#include "cairo-pattern-private.h" -#include "cairo-composite-rectangles-private.h" -#include "cairo-region-private.h" - -static freed_pool_t clip_path_pool; -static freed_pool_t clip_pool; - -const cairo_clip_t __cairo_clip_all; - -static cairo_clip_path_t * -_cairo_clip_path_create (cairo_clip_t *clip) -{ - cairo_clip_path_t *clip_path; - - clip_path = _freed_pool_get (&clip_path_pool); - if (unlikely (clip_path == NULL)) { - clip_path = malloc (sizeof (cairo_clip_path_t)); - if (unlikely (clip_path == NULL)) - return NULL; - } - - CAIRO_REFERENCE_COUNT_INIT (&clip_path->ref_count, 1); - - clip_path->prev = clip->path; - clip->path = clip_path; - - return clip_path; -} - -cairo_clip_path_t * -_cairo_clip_path_reference (cairo_clip_path_t *clip_path) -{ - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&clip_path->ref_count)); - - _cairo_reference_count_inc (&clip_path->ref_count); - - return clip_path; -} - -void -_cairo_clip_path_destroy (cairo_clip_path_t *clip_path) -{ - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&clip_path->ref_count)); - - if (! _cairo_reference_count_dec_and_test (&clip_path->ref_count)) - return; - - _cairo_path_fixed_fini (&clip_path->path); - - if (clip_path->prev != NULL) - _cairo_clip_path_destroy (clip_path->prev); - - _freed_pool_put (&clip_path_pool, clip_path); -} - -cairo_clip_t * -_cairo_clip_create (void) -{ - cairo_clip_t *clip; - - clip = _freed_pool_get (&clip_pool); - if (unlikely (clip == NULL)) { - clip = malloc (sizeof (cairo_clip_t)); - if (unlikely (clip == NULL)) - return NULL; - } - - clip->extents = _cairo_unbounded_rectangle; - - clip->path = NULL; - clip->boxes = NULL; - clip->num_boxes = 0; - clip->region = NULL; - clip->is_region = FALSE; - - return clip; -} - -void -_cairo_clip_destroy (cairo_clip_t *clip) -{ - if (clip == NULL || _cairo_clip_is_all_clipped (clip)) - return; - - if (clip->path != NULL) - _cairo_clip_path_destroy (clip->path); - - if (clip->boxes != &clip->embedded_box) - free (clip->boxes); - cairo_region_destroy (clip->region); - - _freed_pool_put (&clip_pool, clip); -} - -cairo_clip_t * -_cairo_clip_copy (const cairo_clip_t *clip) -{ - cairo_clip_t *copy; - - if (clip == NULL || _cairo_clip_is_all_clipped (clip)) - return (cairo_clip_t *) clip; - - copy = _cairo_clip_create (); - - if (clip->path) - copy->path = _cairo_clip_path_reference (clip->path); - - if (clip->num_boxes) { - if (clip->num_boxes == 1) { - copy->boxes = ©->embedded_box; - } else { - copy->boxes = _cairo_malloc_ab (clip->num_boxes, sizeof (cairo_box_t)); - if (unlikely (copy->boxes == NULL)) - return _cairo_clip_set_all_clipped (copy); - } - - memcpy (copy->boxes, clip->boxes, - clip->num_boxes * sizeof (cairo_box_t)); - copy->num_boxes = clip->num_boxes; - } - - copy->extents = clip->extents; - copy->region = cairo_region_reference (clip->region); - copy->is_region = clip->is_region; - - return copy; -} - -cairo_clip_t * -_cairo_clip_copy_path (const cairo_clip_t *clip) -{ - cairo_clip_t *copy; - - if (clip == NULL || _cairo_clip_is_all_clipped (clip)) - return (cairo_clip_t *) clip; - - assert (clip->num_boxes); - - copy = _cairo_clip_create (); - copy->extents = clip->extents; - if (clip->path) - copy->path = _cairo_clip_path_reference (clip->path); - - return copy; -} - -cairo_clip_t * -_cairo_clip_copy_region (const cairo_clip_t *clip) -{ - cairo_clip_t *copy; - int i; - - if (clip == NULL || _cairo_clip_is_all_clipped (clip)) - return (cairo_clip_t *) clip; - - assert (clip->num_boxes); - - copy = _cairo_clip_create (); - copy->extents = clip->extents; - - if (clip->num_boxes == 1) { - copy->boxes = ©->embedded_box; - } else { - copy->boxes = _cairo_malloc_ab (clip->num_boxes, sizeof (cairo_box_t)); - if (unlikely (copy->boxes == NULL)) - return _cairo_clip_set_all_clipped (copy); - } - - for (i = 0; i < clip->num_boxes; i++) { - copy->boxes[i].p1.x = _cairo_fixed_floor (clip->boxes[i].p1.x); - copy->boxes[i].p1.y = _cairo_fixed_floor (clip->boxes[i].p1.y); - copy->boxes[i].p2.x = _cairo_fixed_ceil (clip->boxes[i].p2.x); - copy->boxes[i].p2.y = _cairo_fixed_ceil (clip->boxes[i].p2.y); - } - copy->num_boxes = clip->num_boxes; - - copy->region = cairo_region_reference (clip->region); - copy->is_region = TRUE; - - return copy; -} - -cairo_clip_t * -_cairo_clip_intersect_path (cairo_clip_t *clip, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_clip_path_t *clip_path; - cairo_status_t status; - cairo_rectangle_int_t extents; - cairo_box_t box; - - if (_cairo_clip_is_all_clipped (clip)) - return clip; - - /* catch the empty clip path */ - if (_cairo_path_fixed_fill_is_empty (path)) - return _cairo_clip_set_all_clipped (clip); - - if (_cairo_path_fixed_is_box (path, &box)) { - if (antialias == CAIRO_ANTIALIAS_NONE) { - box.p1.x = _cairo_fixed_round_down (box.p1.x); - box.p1.y = _cairo_fixed_round_down (box.p1.y); - box.p2.x = _cairo_fixed_round_down (box.p2.x); - box.p2.y = _cairo_fixed_round_down (box.p2.y); - } - - return _cairo_clip_intersect_box (clip, &box); - } - if (_cairo_path_fixed_fill_is_rectilinear (path)) - return _cairo_clip_intersect_rectilinear_path (clip, path, - fill_rule, antialias); - - _cairo_path_fixed_approximate_clip_extents (path, &extents); - if (extents.width == 0 || extents.height == 0) - return _cairo_clip_set_all_clipped (clip); - - clip = _cairo_clip_intersect_rectangle (clip, &extents); - if (_cairo_clip_is_all_clipped (clip)) - return clip; - - clip_path = _cairo_clip_path_create (clip); - if (unlikely (clip_path == NULL)) - return _cairo_clip_set_all_clipped (clip); - - status = _cairo_path_fixed_init_copy (&clip_path->path, path); - if (unlikely (status)) - return _cairo_clip_set_all_clipped (clip); - - clip_path->fill_rule = fill_rule; - clip_path->tolerance = tolerance; - clip_path->antialias = antialias; - - if (clip->region) { - cairo_region_destroy (clip->region); - clip->region = NULL; - } - - clip->is_region = FALSE; - return clip; -} - -static cairo_clip_t * -_cairo_clip_intersect_clip_path (cairo_clip_t *clip, - const cairo_clip_path_t *clip_path) -{ - if (clip_path->prev) - clip = _cairo_clip_intersect_clip_path (clip, clip_path->prev); - - return _cairo_clip_intersect_path (clip, - &clip_path->path, - clip_path->fill_rule, - clip_path->tolerance, - clip_path->antialias); -} - -cairo_clip_t * -_cairo_clip_intersect_clip (cairo_clip_t *clip, - const cairo_clip_t *other) -{ - if (_cairo_clip_is_all_clipped (clip)) - return clip; - - if (other == NULL) - return clip; - - if (clip == NULL) - return _cairo_clip_copy (other); - - if (_cairo_clip_is_all_clipped (other)) - return _cairo_clip_set_all_clipped (clip); - - if (! _cairo_rectangle_intersect (&clip->extents, &other->extents)) - return _cairo_clip_set_all_clipped (clip); - - if (other->num_boxes) { - cairo_boxes_t boxes; - - _cairo_boxes_init_for_array (&boxes, other->boxes, other->num_boxes); - clip = _cairo_clip_intersect_boxes (clip, &boxes); - } - - if (! _cairo_clip_is_all_clipped (clip)) { - if (other->path) { - if (clip->path == NULL) - clip->path = _cairo_clip_path_reference (other->path); - else - clip = _cairo_clip_intersect_clip_path (clip, other->path); - } - } - - if (clip->region) { - cairo_region_destroy (clip->region); - clip->region = NULL; - } - clip->is_region = FALSE; - - return clip; -} - -cairo_bool_t -_cairo_clip_equal (const cairo_clip_t *clip_a, - const cairo_clip_t *clip_b) -{ - const cairo_clip_path_t *cp_a, *cp_b; - - /* are both all-clipped or no-clip? */ - if (clip_a == clip_b) - return TRUE; - - /* or just one of them? */ - if (clip_a == NULL || clip_b == NULL || - _cairo_clip_is_all_clipped (clip_a) || - _cairo_clip_is_all_clipped (clip_b)) - { - return FALSE; - } - - /* We have a pair of normal clips, check their contents */ - - if (clip_a->num_boxes != clip_b->num_boxes) - return FALSE; - - if (memcmp (clip_a->boxes, clip_b->boxes, - sizeof (cairo_box_t) * clip_a->num_boxes)) - return FALSE; - - cp_a = clip_a->path; - cp_b = clip_b->path; - while (cp_a && cp_b) { - if (cp_a == cp_b) - return TRUE; - - /* XXX compare reduced polygons? */ - - if (cp_a->antialias != cp_b->antialias) - return FALSE; - - if (cp_a->tolerance != cp_b->tolerance) - return FALSE; - - if (cp_a->fill_rule != cp_b->fill_rule) - return FALSE; - - if (! _cairo_path_fixed_equal (&cp_a->path, - &cp_b->path)) - return FALSE; - - cp_a = cp_a->prev; - cp_b = cp_b->prev; - } - - return cp_a == NULL && cp_b == NULL; -} - -static cairo_clip_t * -_cairo_clip_path_copy_with_translation (cairo_clip_t *clip, - cairo_clip_path_t *other_path, - int fx, int fy) -{ - cairo_status_t status; - cairo_clip_path_t *clip_path; - - if (other_path->prev != NULL) - clip = _cairo_clip_path_copy_with_translation (clip, other_path->prev, - fx, fy); - if (_cairo_clip_is_all_clipped (clip)) - return clip; - - clip_path = _cairo_clip_path_create (clip); - if (unlikely (clip_path == NULL)) - return _cairo_clip_set_all_clipped (clip); - - status = _cairo_path_fixed_init_copy (&clip_path->path, - &other_path->path); - if (unlikely (status)) - return _cairo_clip_set_all_clipped (clip); - - _cairo_path_fixed_translate (&clip_path->path, fx, fy); - - clip_path->fill_rule = other_path->fill_rule; - clip_path->tolerance = other_path->tolerance; - clip_path->antialias = other_path->antialias; - - return clip; -} - -cairo_clip_t * -_cairo_clip_translate (cairo_clip_t *clip, int tx, int ty) -{ - int fx, fy, i; - cairo_clip_path_t *clip_path; - - if (clip == NULL || _cairo_clip_is_all_clipped (clip)) - return clip; - - if (tx == 0 && ty == 0) - return clip; - - fx = _cairo_fixed_from_int (tx); - fy = _cairo_fixed_from_int (ty); - - for (i = 0; i < clip->num_boxes; i++) { - clip->boxes[i].p1.x += fx; - clip->boxes[i].p2.x += fx; - clip->boxes[i].p1.y += fy; - clip->boxes[i].p2.y += fy; - } - - clip->extents.x += tx; - clip->extents.y += ty; - - if (clip->path == NULL) - return clip; - - clip_path = clip->path; - clip->path = NULL; - clip = _cairo_clip_path_copy_with_translation (clip, clip_path, fx, fy); - _cairo_clip_path_destroy (clip_path); - - return clip; -} - -static cairo_status_t -_cairo_path_fixed_add_box (cairo_path_fixed_t *path, - const cairo_box_t *box) -{ - cairo_status_t status; - - status = _cairo_path_fixed_move_to (path, box->p1.x, box->p1.y); - if (unlikely (status)) - return status; - - status = _cairo_path_fixed_line_to (path, box->p2.x, box->p1.y); - if (unlikely (status)) - return status; - - status = _cairo_path_fixed_line_to (path, box->p2.x, box->p2.y); - if (unlikely (status)) - return status; - - status = _cairo_path_fixed_line_to (path, box->p1.x, box->p2.y); - if (unlikely (status)) - return status; - - return _cairo_path_fixed_close_path (path); -} - -static cairo_status_t -_cairo_path_fixed_init_from_boxes (cairo_path_fixed_t *path, - const cairo_boxes_t *boxes) -{ - cairo_status_t status; - const struct _cairo_boxes_chunk *chunk; - int i; - - _cairo_path_fixed_init (path); - if (boxes->num_boxes == 0) - return CAIRO_STATUS_SUCCESS; - - for (chunk = &boxes->chunks; chunk; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) { - status = _cairo_path_fixed_add_box (path, &chunk->base[i]); - if (unlikely (status)) { - _cairo_path_fixed_fini (path); - return status; - } - } - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_clip_t * -_cairo_clip_intersect_clip_path_transformed (cairo_clip_t *clip, - const cairo_clip_path_t *clip_path, - const cairo_matrix_t *m) -{ - cairo_path_fixed_t path; - - if (clip_path->prev) - clip = _cairo_clip_intersect_clip_path_transformed (clip, - clip_path->prev, - m); - - if (_cairo_path_fixed_init_copy (&path, &clip_path->path)) - return _cairo_clip_set_all_clipped (clip); - - _cairo_path_fixed_transform (&path, m); - - clip = _cairo_clip_intersect_path (clip, - &path, - clip_path->fill_rule, - clip_path->tolerance, - clip_path->antialias); - _cairo_path_fixed_fini (&path); - - return clip; -} - -cairo_clip_t * -_cairo_clip_transform (cairo_clip_t *clip, const cairo_matrix_t *m) -{ - cairo_clip_t *copy; - - if (clip == NULL || _cairo_clip_is_all_clipped (clip)) - return clip; - - if (_cairo_matrix_is_translation (m)) - return _cairo_clip_translate (clip, m->x0, m->y0); - - copy = _cairo_clip_create (); - - if (clip->num_boxes) { - cairo_path_fixed_t path; - cairo_boxes_t boxes; - - _cairo_boxes_init_for_array (&boxes, clip->boxes, clip->num_boxes); - _cairo_path_fixed_init_from_boxes (&path, &boxes); - _cairo_path_fixed_transform (&path, m); - - copy = _cairo_clip_intersect_path (copy, &path, - CAIRO_FILL_RULE_WINDING, - 0.1, - CAIRO_ANTIALIAS_DEFAULT); - - _cairo_path_fixed_fini (&path); - } - - if (clip->path) - copy = _cairo_clip_intersect_clip_path_transformed (copy, clip->path,m); - - _cairo_clip_destroy (clip); - return copy; -} - -cairo_clip_t * -_cairo_clip_copy_with_translation (const cairo_clip_t *clip, int tx, int ty) -{ - cairo_clip_t *copy; - int fx, fy, i; - - if (clip == NULL || _cairo_clip_is_all_clipped (clip)) - return (cairo_clip_t *)clip; - - if (tx == 0 && ty == 0) - return _cairo_clip_copy (clip); - - copy = _cairo_clip_create (); - if (copy == NULL) - return _cairo_clip_set_all_clipped (copy); - - fx = _cairo_fixed_from_int (tx); - fy = _cairo_fixed_from_int (ty); - - if (clip->num_boxes) { - if (clip->num_boxes == 1) { - copy->boxes = ©->embedded_box; - } else { - copy->boxes = _cairo_malloc_ab (clip->num_boxes, sizeof (cairo_box_t)); - if (unlikely (copy->boxes == NULL)) - return _cairo_clip_set_all_clipped (copy); - } - - for (i = 0; i < clip->num_boxes; i++) { - copy->boxes[i].p1.x = clip->boxes[i].p1.x + fx; - copy->boxes[i].p2.x = clip->boxes[i].p2.x + fx; - copy->boxes[i].p1.y = clip->boxes[i].p1.y + fy; - copy->boxes[i].p2.y = clip->boxes[i].p2.y + fy; - } - copy->num_boxes = clip->num_boxes; - } - - copy->extents = clip->extents; - copy->extents.x += tx; - copy->extents.y += ty; - - if (clip->path == NULL) - return copy; - - return _cairo_clip_path_copy_with_translation (copy, clip->path, fx, fy); -} - -cairo_bool_t -_cairo_clip_contains_extents (const cairo_clip_t *clip, - const cairo_composite_rectangles_t *extents) -{ - const cairo_rectangle_int_t *rect; - - rect = extents->is_bounded ? &extents->bounded : &extents->unbounded; - return _cairo_clip_contains_rectangle (clip, rect); -} - -void -_cairo_debug_print_clip (FILE *stream, const cairo_clip_t *clip) -{ - int i; - - if (clip == NULL) { - fprintf (stream, "no clip\n"); - return; - } - - if (_cairo_clip_is_all_clipped (clip)) { - fprintf (stream, "clip: all-clipped\n"); - return; - } - - fprintf (stream, "clip:\n"); - fprintf (stream, " extents: (%d, %d) x (%d, %d), is-region? %d", - clip->extents.x, clip->extents.y, - clip->extents.width, clip->extents.height, - clip->is_region); - - fprintf (stream, " num_boxes = %d\n", clip->num_boxes); - for (i = 0; i < clip->num_boxes; i++) { - fprintf (stream, " [%d] = (%f, %f), (%f, %f)\n", i, - _cairo_fixed_to_double (clip->boxes[i].p1.x), - _cairo_fixed_to_double (clip->boxes[i].p1.y), - _cairo_fixed_to_double (clip->boxes[i].p2.x), - _cairo_fixed_to_double (clip->boxes[i].p2.y)); - } - - if (clip->path) { - cairo_clip_path_t *clip_path = clip->path; - do { - fprintf (stream, "path: aa=%d, tolerance=%f, rule=%d: ", - clip_path->antialias, - clip_path->tolerance, - clip_path->fill_rule); - _cairo_debug_print_path (stream, &clip_path->path); - fprintf (stream, "\n"); - } while ((clip_path = clip_path->prev) != NULL); - } -} - -const cairo_rectangle_int_t * -_cairo_clip_get_extents (const cairo_clip_t *clip) -{ - if (clip == NULL) - return &_cairo_unbounded_rectangle; - - if (_cairo_clip_is_all_clipped (clip)) - return &_cairo_empty_rectangle; - - return &clip->extents; -} - -const cairo_rectangle_list_t _cairo_rectangles_nil = - { CAIRO_STATUS_NO_MEMORY, NULL, 0 }; -static const cairo_rectangle_list_t _cairo_rectangles_not_representable = - { CAIRO_STATUS_CLIP_NOT_REPRESENTABLE, NULL, 0 }; - -static cairo_bool_t -_cairo_clip_int_rect_to_user (cairo_gstate_t *gstate, - cairo_rectangle_int_t *clip_rect, - cairo_rectangle_t *user_rect) -{ - cairo_bool_t is_tight; - - double x1 = clip_rect->x; - double y1 = clip_rect->y; - double x2 = clip_rect->x + (int) clip_rect->width; - double y2 = clip_rect->y + (int) clip_rect->height; - - _cairo_gstate_backend_to_user_rectangle (gstate, - &x1, &y1, &x2, &y2, - &is_tight); - - user_rect->x = x1; - user_rect->y = y1; - user_rect->width = x2 - x1; - user_rect->height = y2 - y1; - - return is_tight; -} - -cairo_rectangle_list_t * -_cairo_rectangle_list_create_in_error (cairo_status_t status) -{ - cairo_rectangle_list_t *list; - - if (status == CAIRO_STATUS_NO_MEMORY) - return (cairo_rectangle_list_t*) &_cairo_rectangles_nil; - if (status == CAIRO_STATUS_CLIP_NOT_REPRESENTABLE) - return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable; - - list = malloc (sizeof (*list)); - if (unlikely (list == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - return (cairo_rectangle_list_t*) &_cairo_rectangles_nil; - } - - list->status = status; - list->rectangles = NULL; - list->num_rectangles = 0; - - return list; -} - -cairo_rectangle_list_t * -_cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate) -{ -#define ERROR_LIST(S) _cairo_rectangle_list_create_in_error (_cairo_error (S)) - - cairo_rectangle_list_t *list; - cairo_rectangle_t *rectangles = NULL; - cairo_region_t *region = NULL; - int n_rects = 0; - int i; - - if (clip == NULL) - return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE); - - if (_cairo_clip_is_all_clipped (clip)) - goto DONE; - - if (! _cairo_clip_is_region (clip)) - return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE); - - region = _cairo_clip_get_region (clip); - if (region == NULL) - return ERROR_LIST (CAIRO_STATUS_NO_MEMORY); - - n_rects = cairo_region_num_rectangles (region); - if (n_rects) { - rectangles = _cairo_malloc_ab (n_rects, sizeof (cairo_rectangle_t)); - if (unlikely (rectangles == NULL)) { - return ERROR_LIST (CAIRO_STATUS_NO_MEMORY); - } - - for (i = 0; i < n_rects; ++i) { - cairo_rectangle_int_t clip_rect; - - cairo_region_get_rectangle (region, i, &clip_rect); - - if (! _cairo_clip_int_rect_to_user (gstate, - &clip_rect, - &rectangles[i])) - { - free (rectangles); - return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE); - } - } - } - - DONE: - list = malloc (sizeof (cairo_rectangle_list_t)); - if (unlikely (list == NULL)) { - free (rectangles); - return ERROR_LIST (CAIRO_STATUS_NO_MEMORY); - } - - list->status = CAIRO_STATUS_SUCCESS; - list->rectangles = rectangles; - list->num_rectangles = n_rects; - return list; - -#undef ERROR_LIST -} - -/** - * cairo_rectangle_list_destroy: - * @rectangle_list: a rectangle list, as obtained from cairo_copy_clip_rectangle_list() - * - * Unconditionally frees @rectangle_list and all associated - * references. After this call, the @rectangle_list pointer must not - * be dereferenced. - * - * Since: 1.4 - **/ -void -cairo_rectangle_list_destroy (cairo_rectangle_list_t *rectangle_list) -{ - if (rectangle_list == NULL || rectangle_list == &_cairo_rectangles_nil || - rectangle_list == &_cairo_rectangles_not_representable) - return; - - free (rectangle_list->rectangles); - free (rectangle_list); -} - -void -_cairo_clip_reset_static_data (void) -{ - _freed_pool_reset (&clip_path_pool); - _freed_pool_reset (&clip_pool); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-cogl-context-private.h b/source/libs/cairo/cairo-src/src/cairo-cogl-context-private.h deleted file mode 100644 index 0a7185ef1f58a64274e3d331cde3e3af6f10d1b1..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-cogl-context-private.h +++ /dev/null @@ -1,52 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2011 Intel Corporation. - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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.og/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. - * - * Contributor(s): - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef CAIRO_COGL_CONTEXT_PRIVATE_H -#define CAIRO_COGL_CONTEXT_PRIVATE_H - -#include "cairo-default-context-private.h" -#include "cairo-cogl-private.h" - -typedef struct _cairo_cogl_context { - cairo_default_context_t base; - - cairo_cogl_device_t *dev; - int path_ctm_age; - cairo_path_fixed_t user_path; - - cairo_bool_t path_is_rectangle; - double x, y, width, height; -} cairo_cogl_context_t; - -cairo_t * -_cairo_cogl_context_create (void *target); - -#endif /* CAIRO_COGL_CONTEXT_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-cogl-context.c b/source/libs/cairo/cairo-src/src/cairo-cogl-context.c deleted file mode 100644 index 0116b0a5a93fafbbf7a791d1f328221453a0f57d..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-cogl-context.c +++ /dev/null @@ -1,822 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2011 Intel Corporation. - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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.og/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. - * - * Contributor(s): - * Robert Bragg <robert@linux.intel.com> - */ - -/* so long as we can verify that the ctm doesn't change multiple times - * during the construction of a path we can build a shadow - * #cairo_path_fixed_t in user coordinates that we can use to create a - * hash value for caching tessellations of that path. - * - * We need to hook into all the points where the ctm can be changed - * so we can bump a cr->path_ctm_age counter. - * - * We need to hook into all the points where the path can be modified - * so we can catch the start of a path and reset the cr->path_ctm_age - * counter at that point. - * - * When a draw operation is hit we can then check that the - * path_ctm_age == 0 and if so we create a hash of the path. - * - * We use this hash to lookup a #cairo_cogl_path_meta_t struct which - * may contain tessellated triangles for the path or may just contain - * a count of how many times the path has been re-seen (we only cache - * tessellated triangles if there is evidence that the path is being - * used multiple times because there is a cost involved in allocating - * a separate buffer for the triangles). - */ - -#include "cairoint.h" - -#include "cairo-cogl-context-private.h" -#include "cairo-freed-pool-private.h" -#include "cairo-arc-private.h" -#include "cairo-path-fixed-private.h" - -#include <glib.h> - -static freed_pool_t context_pool; - -void -_cairo_cogl_context_reset_static_data (void) -{ - _freed_pool_reset (&context_pool); -} - -static cairo_status_t -_cairo_cogl_context_rectangle_real (cairo_cogl_context_t *cr, - double x, double y, - double width, double height) -{ - cairo_status_t status; - status = cr->dev->backend_parent.rectangle (cr, x, y, width, height); - if (unlikely (status)) - return status; - - return _cairo_cogl_path_fixed_rectangle (&cr->user_path, - _cairo_fixed_from_double (x), - _cairo_fixed_from_double (y), - _cairo_fixed_from_double (width), - _cairo_fixed_from_double (height)); -} - -/* The idea here is that we have a simplified way of tracking rectangle paths - * because rectangles are perhaps the most common shape drawn with cairo. - * - * Basically we have a speculative store for a rectangle path that doesn't - * need to use the #cairo_path_fixed_t api to describe a rectangle in terms of - * (move_to,rel_line_to,rel_line_to,_rel_line_to,close) because if you profile - * heavy rectangle drawing with Cairo that process can be overly expensive. - * - * If the user asks to add more than just a rectangle to their current path - * then we "flush" any speculative rectangle stored into the current path - * before continuing to append their operations. - * - * In addition to the speculative store cairo-cogl also has a fast-path - * fill_rectangle drawing operation that further aims to minimize the cost - * of drawing rectangles. - */ -static cairo_status_t -_flush_cr_rectangle (cairo_cogl_context_t *cr) -{ - if (!cr->path_is_rectangle) - return CAIRO_STATUS_SUCCESS; - - cr->path_is_rectangle = FALSE; - return _cairo_cogl_context_rectangle_real (cr, cr->x, cr->y, cr->width, cr->height); -} - -static cairo_status_t -_cairo_cogl_context_restore (void *abstract_cr) -{ - cairo_cogl_context_t *cr = abstract_cr; - - if (cr->path_is_rectangle) { - cairo_status_t status = _flush_cr_rectangle (cr); - if (unlikely (status)) - return status; - } - - cr->path_ctm_age++; - return cr->dev->backend_parent.restore (abstract_cr); -} - -static cairo_status_t -_cairo_cogl_context_translate (void *abstract_cr, double tx, double ty) -{ - cairo_cogl_context_t *cr = abstract_cr; - - if (cr->path_is_rectangle) { - cairo_status_t status = _flush_cr_rectangle (cr); - if (unlikely (status)) - return status; - } - - cr->path_ctm_age++; - return cr->dev->backend_parent.translate (abstract_cr, tx, ty); -} - -static cairo_status_t -_cairo_cogl_context_scale (void *abstract_cr, double sx, double sy) -{ - cairo_cogl_context_t *cr = abstract_cr; - - if (cr->path_is_rectangle) { - cairo_status_t status = _flush_cr_rectangle (cr); - if (unlikely (status)) - return status; - } - - cr->path_ctm_age++; - return cr->dev->backend_parent.scale (abstract_cr, sx, sy); -} - -static cairo_status_t -_cairo_cogl_context_rotate (void *abstract_cr, double theta) -{ - cairo_cogl_context_t *cr = abstract_cr; - - if (cr->path_is_rectangle) { - cairo_status_t status = _flush_cr_rectangle (cr); - if (unlikely (status)) - return status; - } - - cr->path_ctm_age++; - return cr->dev->backend_parent.rotate (abstract_cr, theta); -} - -static cairo_status_t -_cairo_cogl_context_transform (void *abstract_cr, const cairo_matrix_t *matrix) -{ - cairo_cogl_context_t *cr = abstract_cr; - - if (cr->path_is_rectangle) { - cairo_status_t status = _flush_cr_rectangle (cr); - if (unlikely (status)) - return status; - } - - cr->path_ctm_age++; - return cr->dev->backend_parent.transform (abstract_cr, matrix); -} - -static cairo_status_t -_cairo_cogl_context_set_matrix (void *abstract_cr, const cairo_matrix_t *matrix) -{ - cairo_cogl_context_t *cr = abstract_cr; - - if (cr->path_is_rectangle) { - cairo_status_t status = _flush_cr_rectangle (cr); - if (unlikely (status)) - return status; - } - - cr->path_ctm_age++; - return cr->dev->backend_parent.set_matrix (abstract_cr, matrix); -} - -static cairo_status_t -_cairo_cogl_context_set_identity_matrix (void *abstract_cr) -{ - cairo_cogl_context_t *cr = abstract_cr; - - if (cr->path_is_rectangle) { - cairo_status_t status = _flush_cr_rectangle (cr); - if (unlikely (status)) - return status; - } - - cr->path_ctm_age++; - return cr->dev->backend_parent.set_identity_matrix (abstract_cr); -} - -static cairo_status_t -_cairo_cogl_context_new_path (void *abstract_cr) -{ - cairo_cogl_context_t *cr = abstract_cr; - cairo_status_t status; - - if (cr->path_is_rectangle) { - status = _flush_cr_rectangle (cr); - if (unlikely (status)) - return status; - } - - status = cr->dev->backend_parent.new_path (abstract_cr); - if (unlikely (status)) - return status; - - _cairo_path_fixed_fini (&cr->user_path); - _cairo_path_fixed_init (&cr->user_path); - cr->path_is_rectangle = FALSE; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_cogl_context_new_sub_path (void *abstract_cr) -{ - cairo_cogl_context_t *cr = abstract_cr; - cairo_status_t status; - - if (cr->path_is_rectangle) { - status = _flush_cr_rectangle (cr); - if (unlikely (status)) - return status; - } - - status = cr->dev->backend_parent.new_sub_path (abstract_cr); - if (unlikely (status)) - return status; - - _cairo_path_fixed_new_sub_path (&cr->user_path); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_cogl_context_move_to (void *abstract_cr, double x, double y) -{ - cairo_cogl_context_t *cr = abstract_cr; - cairo_status_t status; - cairo_fixed_t x_fixed, y_fixed; - - if (cr->path_is_rectangle) { - status = _flush_cr_rectangle (cr); - if (unlikely (status)) - return status; - } - - status = cr->dev->backend_parent.move_to (abstract_cr, x, y); - if (unlikely (status)) - return status; - - x_fixed = _cairo_fixed_from_double (x); - y_fixed = _cairo_fixed_from_double (y); - - return _cairo_path_fixed_move_to (&cr->user_path, x_fixed, y_fixed); -} - -static cairo_status_t -_cairo_cogl_context_line_to (void *abstract_cr, double x, double y) -{ - cairo_cogl_context_t *cr = abstract_cr; - cairo_status_t status; - cairo_fixed_t x_fixed, y_fixed; - - if (cr->path_is_rectangle) { - status = _flush_cr_rectangle (cr); - if (unlikely (status)) - return status; - } - - status = cr->dev->backend_parent.line_to (abstract_cr, x, y); - if (unlikely (status)) - return status; - - x_fixed = _cairo_fixed_from_double (x); - y_fixed = _cairo_fixed_from_double (y); - - if (cr->user_path.buf.base.num_ops == 0) - cr->path_ctm_age = 0; - - return _cairo_path_fixed_line_to (&cr->user_path, x_fixed, y_fixed); -} - -static cairo_status_t -_cairo_cogl_context_curve_to (void *abstract_cr, - double x1, double y1, - double x2, double y2, - double x3, double y3) -{ - cairo_cogl_context_t *cr = abstract_cr; - cairo_status_t status; - cairo_fixed_t x1_fixed, y1_fixed; - cairo_fixed_t x2_fixed, y2_fixed; - cairo_fixed_t x3_fixed, y3_fixed; - - if (cr->path_is_rectangle) { - status = _flush_cr_rectangle (cr); - if (unlikely (status)) - return status; - } - - status = cr->dev->backend_parent.curve_to (abstract_cr, x1, y1, x2, y2, x3, y3); - if (unlikely (status)) - return status; - - x1_fixed = _cairo_fixed_from_double (x1); - y1_fixed = _cairo_fixed_from_double (y1); - - x2_fixed = _cairo_fixed_from_double (x2); - y2_fixed = _cairo_fixed_from_double (y2); - - x3_fixed = _cairo_fixed_from_double (x3); - y3_fixed = _cairo_fixed_from_double (y3); - - if (cr->user_path.buf.base.num_ops == 0) - cr->path_ctm_age = 0; - - return _cairo_path_fixed_curve_to (&cr->user_path, - x1_fixed, y1_fixed, - x2_fixed, y2_fixed, - x3_fixed, y3_fixed); -} - -static cairo_status_t -_cairo_cogl_context_arc (void *abstract_cr, - double xc, double yc, double radius, - double angle1, double angle2, - cairo_bool_t forward) -{ - cairo_cogl_context_t *cr = abstract_cr; - cairo_status_t status; - - if (cr->path_is_rectangle) { - status = _flush_cr_rectangle (cr); - if (unlikely (status)) - return status; - } - - status = cr->dev->backend_parent.arc (abstract_cr, xc, yc, radius, angle1, angle2, forward); - if (unlikely (status)) - return status; - - if (cr->user_path.buf.base.num_ops == 0) - cr->path_ctm_age = 0; - - /* Do nothing, successfully, if radius is <= 0 */ - if (radius <= 0.0) { - cairo_fixed_t x_fixed, y_fixed; - - x_fixed = _cairo_fixed_from_double (xc); - y_fixed = _cairo_fixed_from_double (yc); - status = _cairo_path_fixed_line_to (&cr->user_path, x_fixed, y_fixed); - if (unlikely (status)) - return status; - - status = _cairo_path_fixed_line_to (&cr->user_path, x_fixed, y_fixed); - if (unlikely (status)) - return status; - - return CAIRO_STATUS_SUCCESS; - } - - status = _cairo_cogl_context_line_to (cr, - xc + radius * cos (angle1), - yc + radius * sin (angle1)); - - if (unlikely (status)) - return status; - - if (forward) - _cairo_arc_path (&cr->base.base, xc, yc, radius, angle1, angle2); - else - _cairo_arc_path_negative (&cr->base.base, xc, yc, radius, angle1, angle2); - - return CAIRO_STATUS_SUCCESS; /* any error will have already been set on cr */ -} - -static cairo_status_t -_cairo_cogl_context_rel_move_to (void *abstract_cr, double dx, double dy) -{ - cairo_cogl_context_t *cr = abstract_cr; - cairo_status_t status; - cairo_fixed_t dx_fixed, dy_fixed; - - if (cr->path_is_rectangle) { - status = _flush_cr_rectangle (cr); - if (unlikely (status)) - return status; - } - - status = cr->dev->backend_parent.rel_move_to (abstract_cr, dx, dy); - if (unlikely (status)) - return status; - - dx_fixed = _cairo_fixed_from_double (dx); - dy_fixed = _cairo_fixed_from_double (dy); - - return _cairo_path_fixed_rel_move_to (&cr->user_path, dx_fixed, dy_fixed); -} - -static cairo_status_t -_cairo_cogl_context_rel_line_to (void *abstract_cr, double dx, double dy) -{ - cairo_cogl_context_t *cr = abstract_cr; - cairo_status_t status; - cairo_fixed_t dx_fixed, dy_fixed; - - if (cr->path_is_rectangle) { - status = _flush_cr_rectangle (cr); - if (unlikely (status)) - return status; - } - - status = cr->dev->backend_parent.rel_line_to (abstract_cr, dx, dy); - if (unlikely (status)) - return status; - - dx_fixed = _cairo_fixed_from_double (dx); - dy_fixed = _cairo_fixed_from_double (dy); - - if (cr->user_path.buf.base.num_ops == 0) - cr->path_ctm_age = 0; - - return _cairo_path_fixed_rel_line_to (&cr->user_path, dx_fixed, dy_fixed); -} - - -static cairo_status_t -_cairo_cogl_context_rel_curve_to (void *abstract_cr, - double dx1, double dy1, - double dx2, double dy2, - double dx3, double dy3) -{ - cairo_cogl_context_t *cr = abstract_cr; - cairo_status_t status; - cairo_fixed_t dx1_fixed, dy1_fixed; - cairo_fixed_t dx2_fixed, dy2_fixed; - cairo_fixed_t dx3_fixed, dy3_fixed; - - if (cr->path_is_rectangle) { - status = _flush_cr_rectangle (cr); - if (unlikely (status)) - return status; - } - - status = cr->dev->backend_parent.rel_curve_to (abstract_cr, dx1, dy1, dx2, dy2, dx3, dy3); - if (unlikely (status)) - return status; - - dx1_fixed = _cairo_fixed_from_double (dx1); - dy1_fixed = _cairo_fixed_from_double (dy1); - - dx2_fixed = _cairo_fixed_from_double (dx2); - dy2_fixed = _cairo_fixed_from_double (dy2); - - dx3_fixed = _cairo_fixed_from_double (dx3); - dy3_fixed = _cairo_fixed_from_double (dy3); - - if (cr->user_path.buf.base.num_ops == 0) - cr->path_ctm_age = 0; - - return _cairo_path_fixed_rel_curve_to (&cr->user_path, - dx1_fixed, dy1_fixed, - dx2_fixed, dy2_fixed, - dx3_fixed, dy3_fixed); -} - -#if 0 -static cairo_status_t -_cairo_cogl_context_arc_to (void *abstract_cr, - double x1, double y1, - double x2, double y2, - double radius) -{ - cairo_cogl_context_t *cr = abstract_cr; - cairo_status_t status; - - if (cr->path_is_rectangle) { - status = _flush_cr_rectangle (cr); - if (unlikely (status)) - return status; - } - - status = cr->dev->backend_parent.arc_to (abstract_cr, x1, y1, x2, y2, radius); - if (unlikely (status)) - return status; -#warning "FIXME" -} - -static cairo_status_t -_cairo_cogl_rel_arc_to (void *cr, - double dx1, double dy1, - double dx2, double dy2, - double radius) -{ - cairo_cogl_context_t *cr = abstract_cr; - cairo_status_t status; - - if (cr->path_is_rectangle) { - status = _flush_cr_rectangle (cr); - if (unlikely (status)) - return status; - } - - status = cr->dev->backend_parent.rel_arc_to (abstract_cr, dx1, dy2, dx2, dy2, radius); - if (unlikely (status)) - return status; -#warning "FIXME" -} -#endif - -static cairo_status_t -_cairo_cogl_context_close_path (void *abstract_cr) -{ - cairo_cogl_context_t *cr = abstract_cr; - cairo_status_t status; - - if (cr->path_is_rectangle) { - status = _flush_cr_rectangle (cr); - if (unlikely (status)) - return status; - } - - status = cr->dev->backend_parent.close_path (abstract_cr); - if (unlikely (status)) - return status; - - if (cr->user_path.buf.base.num_ops == 0) - cr->path_ctm_age = 0; - - return _cairo_path_fixed_close_path (&cr->user_path); -} - -static cairo_status_t -_cairo_cogl_context_rectangle (void *abstract_cr, - double x, double y, - double width, double height) -{ - cairo_cogl_context_t *cr = abstract_cr; - - if (cr->user_path.buf.base.num_ops == 0) { - cr->path_ctm_age = 0; - -#if 1 - /* XXX: Since drawing rectangles is so common we have a - * fast-path for drawing a single rectangle. */ - cr->x = x; - cr->y = y; - cr->width = width; - cr->height = height; - cr->path_is_rectangle = TRUE; - return CAIRO_STATUS_SUCCESS; -#endif - } - - if (cr->path_is_rectangle) { - cairo_status_t status = _flush_cr_rectangle (cr); - if (unlikely (status)) - return status; - } - - return _cairo_cogl_context_rectangle_real (cr, x, y, width, height); -} - -/* Since the surface backend drawing operator functions don't get - * passed the current #cairo_t context we don't have a good way - * to get our user-coordinates path into our surface operator - * functions. - * - * For now we use this function to set side band data on the surface - * itself. - */ -static void -_cairo_cogl_surface_set_side_band_state (cairo_cogl_surface_t *surface, - cairo_cogl_context_t *cr) -{ - - if (cr->path_ctm_age <= 1) { - surface->user_path = &cr->user_path; - surface->ctm = &cr->base.gstate->ctm; - surface->ctm_inverse = &cr->base.gstate->ctm_inverse; - surface->path_is_rectangle = cr->path_is_rectangle; - if (surface->path_is_rectangle) { - surface->path_rectangle_x = cr->x; - surface->path_rectangle_y = cr->y; - surface->path_rectangle_width = cr->width; - surface->path_rectangle_height = cr->height; - } - } else { - surface->user_path = NULL; - surface->path_is_rectangle = FALSE; - } -} - -static cairo_status_t -_cairo_cogl_context_fill (void *abstract_cr) -{ - cairo_cogl_context_t *cr = abstract_cr; - cairo_status_t status; - cairo_cogl_surface_t *surface = (cairo_cogl_surface_t *)cr->base.gstate->target; - - if (cr->path_is_rectangle) { - status = _cairo_cogl_surface_fill_rectangle (cr->base.gstate->target, - cr->base.gstate->op, - cr->base.gstate->source, - cr->x, - cr->y, - cr->width, - cr->height, - &cr->base.gstate->ctm, - cr->base.gstate->clip); - if (status == CAIRO_STATUS_SUCCESS) - goto DONE; - _flush_cr_rectangle (cr); - } - - _cairo_cogl_surface_set_side_band_state (surface, cr); - - status = cr->dev->backend_parent.fill (abstract_cr); - if (unlikely (status)) - return status; - -DONE: - _cairo_path_fixed_fini (&cr->user_path); - _cairo_path_fixed_init (&cr->user_path); - cr->path_is_rectangle = FALSE; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_cogl_context_fill_preserve (void *abstract_cr) -{ - cairo_cogl_context_t *cr = abstract_cr; - cairo_status_t status; - cairo_cogl_surface_t *surface = (cairo_cogl_surface_t *)cr->base.gstate->target; - - _cairo_cogl_surface_set_side_band_state (surface, cr); - - status = cr->dev->backend_parent.fill_preserve (abstract_cr); - if (unlikely (status)) - return status; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_cogl_context_stroke (void *abstract_cr) -{ - cairo_cogl_context_t *cr = abstract_cr; - cairo_status_t status; - cairo_cogl_surface_t *surface = (cairo_cogl_surface_t *)cr->base.gstate->target; - - _cairo_cogl_surface_set_side_band_state (surface, cr); - - status = cr->dev->backend_parent.stroke (abstract_cr); - if (unlikely (status)) - return status; - - _cairo_path_fixed_fini (&cr->user_path); - _cairo_path_fixed_init (&cr->user_path); - cr->path_is_rectangle = FALSE; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_cogl_context_stroke_preserve (void *abstract_cr) -{ - cairo_cogl_context_t *cr = abstract_cr; - cairo_status_t status; - cairo_cogl_surface_t *surface = (cairo_cogl_surface_t *)cr->base.gstate->target; - - _cairo_cogl_surface_set_side_band_state (surface, cr); - - status = cr->dev->backend_parent.stroke_preserve (abstract_cr); - if (unlikely (status)) - return status; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_cogl_context_clip (void *abstract_cr) -{ - cairo_cogl_context_t *cr = abstract_cr; - cairo_status_t status; - - status = cr->dev->backend_parent.clip (abstract_cr); - if (unlikely (status)) - return status; - - _cairo_path_fixed_fini (&cr->user_path); - _cairo_path_fixed_init (&cr->user_path); - cr->path_is_rectangle = FALSE; - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_cogl_context_destroy (void *abstract_cr) -{ - cairo_cogl_context_t *cr = abstract_cr; - - _cairo_default_context_fini (&cr->base); - - _cairo_path_fixed_fini (&cr->user_path); - - /* mark the context as invalid to protect against misuse */ - cr->base.base.status = CAIRO_STATUS_NULL_POINTER; - _freed_pool_put (&context_pool, cr); -} - -/* We want to hook into the frontend of the path construction APIs so - * we can build up a path description in user coordinates instead of - * backend coordinates so that we can recognize user coordinate - * rectangles and so we can hash a user path independent of its - * transform. (With some care to catch unusual cases where the ctm - * changes mid-path) */ -cairo_t * -_cairo_cogl_context_create (void *target) -{ - cairo_cogl_surface_t *surface = target; - cairo_cogl_context_t *cr; - cairo_status_t status; - - cr = _freed_pool_get (&context_pool); - if (unlikely (cr == NULL)) { - cr = malloc (sizeof (cairo_cogl_context_t)); - if (unlikely (cr == NULL)) - return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - status = _cairo_default_context_init (&cr->base, target); - if (unlikely (status)) { - _freed_pool_put (&context_pool, cr); - return _cairo_create_in_error (status); - } - - cr->dev = (cairo_cogl_device_t *)surface->base.device; - - if (unlikely (cr->dev->backend_vtable_initialized == FALSE)) { - cairo_backend_t *backend = &cr->dev->backend; - memcpy (backend, cr->base.base.backend, sizeof (cairo_backend_t)); - memcpy (&cr->dev->backend_parent, cr->base.base.backend, sizeof (cairo_backend_t)); - - backend->destroy = _cairo_cogl_context_destroy; - - backend->restore = _cairo_cogl_context_restore; - backend->translate = _cairo_cogl_context_translate; - backend->scale = _cairo_cogl_context_scale; - backend->rotate = _cairo_cogl_context_rotate; - backend->transform = _cairo_cogl_context_transform; - backend->set_matrix = _cairo_cogl_context_set_matrix; - backend->set_identity_matrix = _cairo_cogl_context_set_identity_matrix; - - backend->new_path = _cairo_cogl_context_new_path; - backend->new_sub_path = _cairo_cogl_context_new_sub_path; - backend->move_to = _cairo_cogl_context_move_to; - backend->rel_move_to = _cairo_cogl_context_rel_move_to; - backend->line_to = _cairo_cogl_context_line_to; - backend->rel_line_to = _cairo_cogl_context_rel_line_to; - backend->curve_to = _cairo_cogl_context_curve_to; - backend->rel_curve_to = _cairo_cogl_context_rel_curve_to; -#if 0 - backend->arc_to = _cairo_cogl_context_arc_to; - backend->rel_arc_to = _cairo_cogl_context_rel_arc_to; -#endif - backend->close_path = _cairo_cogl_context_close_path; - //backend->arc = _cairo_cogl_context_arc; - backend->rectangle = _cairo_cogl_context_rectangle; - - /* Try to automatically catch if any new path APIs are added that mean - * we may need to overload more functions... */ - assert (((char *)&backend->path_extents - (char *)&backend->device_to_user_distance) - == (sizeof (void *) * 14)); - - backend->fill = _cairo_cogl_context_fill; - backend->fill_preserve = _cairo_cogl_context_fill_preserve; - backend->stroke = _cairo_cogl_context_stroke; - backend->stroke_preserve = _cairo_cogl_context_stroke_preserve; - backend->clip = _cairo_cogl_context_clip; - - cr->dev->backend_vtable_initialized = TRUE; - } - - cr->base.base.backend = &cr->dev->backend; - - _cairo_path_fixed_init (&cr->user_path); - cr->path_is_rectangle = FALSE; - - return &cr->base.base; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-cogl-gradient-private.h b/source/libs/cairo/cairo-src/src/cairo-cogl-gradient-private.h deleted file mode 100644 index fa684d2c6b0eb36289ad302d517be7eb75ccdfc4..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-cogl-gradient-private.h +++ /dev/null @@ -1,89 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2011 Intel Corporation. - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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.og/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. - * - * Contributor(s): - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef CAIRO_COGL_GRADIENT_PRIVATE_H -#define CAIRO_COGL_GRADIENT_PRIVATE_H - -#include "cairoint.h" -#include "cairo-pattern-private.h" - -#include <cogl/cogl2-experimental.h> - -#define CAIRO_COGL_LINEAR_GRADIENT_CACHE_SIZE (1024 * 1024) - -typedef enum _cairo_cogl_gradient_compatibility { - CAIRO_COGL_GRADIENT_CAN_EXTEND_PAD = 1<<0, - CAIRO_COGL_GRADIENT_CAN_EXTEND_REPEAT = 1<<1, - CAIRO_COGL_GRADIENT_CAN_EXTEND_REFLECT = 1<<2, - CAIRO_COGL_GRADIENT_CAN_EXTEND_NONE = 1<<3 -} cairo_cogl_gradient_compatibility_t; -#define CAIRO_COGL_GRADIENT_CAN_EXTEND_ALL (CAIRO_COGL_GRADIENT_CAN_EXTEND_PAD |\ - CAIRO_COGL_GRADIENT_CAN_EXTEND_REPEAT|\ - CAIRO_COGL_GRADIENT_CAN_EXTEND_REFLECT|\ - CAIRO_COGL_GRADIENT_CAN_EXTEND_NONE) - -typedef struct _cairo_cogl_linear_texture_entry { - cairo_cogl_gradient_compatibility_t compatibility; - CoglTexture *texture; - float translate_x; - float scale_x; -} cairo_cogl_linear_texture_entry_t; - -typedef struct _cairo_cogl_linear_gradient { - cairo_cache_entry_t cache_entry; - cairo_reference_count_t ref_count; - GList *textures; - int n_stops; - const cairo_gradient_stop_t *stops; - cairo_gradient_stop_t stops_embedded[1]; -} cairo_cogl_linear_gradient_t; - -cairo_int_status_t -_cairo_cogl_get_linear_gradient (cairo_cogl_device_t *context, - cairo_extend_t extend_mode, - int n_stops, - const cairo_gradient_stop_t *stops, - cairo_cogl_linear_gradient_t **gradient_out); - -cairo_cogl_linear_texture_entry_t * -_cairo_cogl_linear_gradient_texture_for_extend (cairo_cogl_linear_gradient_t *gradient, - cairo_extend_t extend_mode); - -cairo_cogl_linear_gradient_t * -_cairo_cogl_linear_gradient_reference (cairo_cogl_linear_gradient_t *gradient); - -void -_cairo_cogl_linear_gradient_destroy (cairo_cogl_linear_gradient_t *gradient); - -cairo_bool_t -_cairo_cogl_linear_gradient_equal (const void *key_a, const void *key_b); - -#endif /* CAIRO_COGL_GRADIENT_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-cogl-gradient.c b/source/libs/cairo/cairo-src/src/cairo-cogl-gradient.c deleted file mode 100644 index f8c800416295faa9d6b06c85bd79dda29efcddec..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-cogl-gradient.c +++ /dev/null @@ -1,642 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2011 Intel Corporation. - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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.og/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. - * - * Contributor(s): - * Robert Bragg <robert@linux.intel.com> - */ -//#include "cairoint.h" - -#include "cairo-cogl-private.h" -#include "cairo-cogl-gradient-private.h" -#include "cairo-image-surface-private.h" - -#include <cogl/cogl2-experimental.h> -#include <glib.h> - -#define DUMP_GRADIENTS_TO_PNG - -static unsigned long -_cairo_cogl_linear_gradient_hash (unsigned int n_stops, - const cairo_gradient_stop_t *stops) -{ - return _cairo_hash_bytes (n_stops, stops, - sizeof (cairo_gradient_stop_t) * n_stops); -} - -static cairo_cogl_linear_gradient_t * -_cairo_cogl_linear_gradient_lookup (cairo_cogl_device_t *ctx, - unsigned long hash, - unsigned int n_stops, - const cairo_gradient_stop_t *stops) -{ - cairo_cogl_linear_gradient_t lookup; - - lookup.cache_entry.hash = hash, - lookup.n_stops = n_stops; - lookup.stops = stops; - - return _cairo_cache_lookup (&ctx->linear_cache, &lookup.cache_entry); -} - -cairo_bool_t -_cairo_cogl_linear_gradient_equal (const void *key_a, const void *key_b) -{ - const cairo_cogl_linear_gradient_t *a = key_a; - const cairo_cogl_linear_gradient_t *b = key_b; - - if (a->n_stops != b->n_stops) - return FALSE; - - return memcmp (a->stops, b->stops, a->n_stops * sizeof (cairo_gradient_stop_t)) == 0; -} - -cairo_cogl_linear_gradient_t * -_cairo_cogl_linear_gradient_reference (cairo_cogl_linear_gradient_t *gradient) -{ - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&gradient->ref_count)); - - _cairo_reference_count_inc (&gradient->ref_count); - - return gradient; -} - -void -_cairo_cogl_linear_gradient_destroy (cairo_cogl_linear_gradient_t *gradient) -{ - GList *l; - - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&gradient->ref_count)); - - if (! _cairo_reference_count_dec_and_test (&gradient->ref_count)) - return; - - for (l = gradient->textures; l; l = l->next) { - cairo_cogl_linear_texture_entry_t *entry = l->data; - cogl_object_unref (entry->texture); - free (entry); - } - g_list_free (gradient->textures); - - free (gradient); -} - -static int -_cairo_cogl_util_next_p2 (int a) -{ - int rval = 1; - - while (rval < a) - rval <<= 1; - - return rval; -} - -static float -get_max_color_component_range (const cairo_color_stop_t *color0, const cairo_color_stop_t *color1) -{ - float range; - float max = 0; - - range = fabs (color0->red - color1->red); - max = MAX (range, max); - range = fabs (color0->green - color1->green); - max = MAX (range, max); - range = fabs (color0->blue - color1->blue); - max = MAX (range, max); - range = fabs (color0->alpha - color1->alpha); - max = MAX (range, max); - - return max; -} - -static int -_cairo_cogl_linear_gradient_width_for_stops (cairo_extend_t extend, - unsigned int n_stops, - const cairo_gradient_stop_t *stops) -{ - unsigned int n; - float max_texels_per_unit_offset = 0; - float total_offset_range; - - /* Find the stop pair demanding the most precision because we are - * interpolating the largest color-component range. - * - * From that we can define the relative sizes of all the other - * stop pairs within our texture and thus the overall size. - * - * To determine the maximum number of texels for a given gap we - * look at the range of colors we are expected to interpolate (so - * long as the stop offsets are not degenerate) and we simply - * assume we want one texel for each unique color value possible - * for a one byte-per-component representation. - * XXX: maybe this is overkill and just allowing 128 levels - * instead of 256 would be enough and then we'd rely on the - * bilinear filtering to give the full range. - * - * XXX: potentially we could try and map offsets to pixels to come - * up with a more precise mapping, but we are aiming to cache - * the gradients so we can't make assumptions about how it will be - * scaled in the future. - */ - for (n = 1; n < n_stops; n++) { - float color_range; - float offset_range; - float texels; - float texels_per_unit_offset; - - /* note: degenerate stops don't need to be represented in the - * texture but we want to be sure that solid gaps get at least - * one texel and all other gaps get at least 2 texels. - */ - - if (stops[n].offset == stops[n-1].offset) - continue; - - color_range = get_max_color_component_range (&stops[n].color, &stops[n-1].color); - if (color_range == 0) - texels = 1; - else - texels = MAX (2, 256.0f * color_range); - - /* So how many texels would we need to map over the full [0,1] - * gradient range so this gap would have enough texels? ... */ - offset_range = stops[n].offset - stops[n - 1].offset; - texels_per_unit_offset = texels / offset_range; - - if (texels_per_unit_offset > max_texels_per_unit_offset) - max_texels_per_unit_offset = texels_per_unit_offset; - } - - total_offset_range = fabs (stops[n_stops - 1].offset - stops[0].offset); - return max_texels_per_unit_offset * total_offset_range; -} - -/* Aim to create gradient textures without an alpha component so we can avoid - * needing to use blending... */ -static CoglPixelFormat -_cairo_cogl_linear_gradient_format_for_stops (cairo_extend_t extend, - unsigned int n_stops, - const cairo_gradient_stop_t *stops) -{ - unsigned int n; - - /* We have to add extra transparent texels to the end of the gradient to - * handle CAIRO_EXTEND_NONE... */ - if (extend == CAIRO_EXTEND_NONE) - return COGL_PIXEL_FORMAT_BGRA_8888_PRE; - - for (n = 1; n < n_stops; n++) { - if (stops[n].color.alpha != 1.0) - return COGL_PIXEL_FORMAT_BGRA_8888_PRE; - } - - return COGL_PIXEL_FORMAT_BGR_888; -} - -static cairo_cogl_gradient_compatibility_t -_cairo_cogl_compatibility_from_extend_mode (cairo_extend_t extend_mode) -{ - switch (extend_mode) - { - case CAIRO_EXTEND_NONE: - return CAIRO_COGL_GRADIENT_CAN_EXTEND_NONE; - case CAIRO_EXTEND_PAD: - return CAIRO_COGL_GRADIENT_CAN_EXTEND_PAD; - case CAIRO_EXTEND_REPEAT: - return CAIRO_COGL_GRADIENT_CAN_EXTEND_REPEAT; - case CAIRO_EXTEND_REFLECT: - return CAIRO_COGL_GRADIENT_CAN_EXTEND_REFLECT; - } - - assert (0); /* not reached */ - return CAIRO_EXTEND_NONE; -} - -cairo_cogl_linear_texture_entry_t * -_cairo_cogl_linear_gradient_texture_for_extend (cairo_cogl_linear_gradient_t *gradient, - cairo_extend_t extend_mode) -{ - GList *l; - cairo_cogl_gradient_compatibility_t compatibility = - _cairo_cogl_compatibility_from_extend_mode (extend_mode); - for (l = gradient->textures; l; l = l->next) { - cairo_cogl_linear_texture_entry_t *entry = l->data; - if (entry->compatibility & compatibility) - return entry; - } - return NULL; -} - -static void -color_stop_lerp (const cairo_color_stop_t *c0, - const cairo_color_stop_t *c1, - float factor, - cairo_color_stop_t *dest) -{ - /* NB: we always ignore the short members in this file so we don't need to - * worry about initializing them here. */ - dest->red = c0->red * (1.0f-factor) + c1->red * factor; - dest->green = c0->green * (1.0f-factor) + c1->green * factor; - dest->blue = c0->blue * (1.0f-factor) + c1->blue * factor; - dest->alpha = c0->alpha * (1.0f-factor) + c1->alpha * factor; -} - -static size_t -_cairo_cogl_linear_gradient_size (cairo_cogl_linear_gradient_t *gradient) -{ - GList *l; - size_t size = 0; - for (l = gradient->textures; l; l = l->next) { - cairo_cogl_linear_texture_entry_t *entry = l->data; - size += cogl_texture_get_width (entry->texture) * 4; - } - return size; -} - -static void -emit_stop (CoglVertexP2C4 **position, - float left, - float right, - const cairo_color_stop_t *left_color, - const cairo_color_stop_t *right_color) -{ - CoglVertexP2C4 *p = *position; - - guint8 lr = left_color->red * 255; - guint8 lg = left_color->green * 255; - guint8 lb = left_color->blue * 255; - guint8 la = left_color->alpha * 255; - - guint8 rr = right_color->red * 255; - guint8 rg = right_color->green * 255; - guint8 rb = right_color->blue * 255; - guint8 ra = right_color->alpha * 255; - - p[0].x = left; - p[0].y = 0; - p[0].r = lr; p[0].g = lg; p[0].b = lb; p[0].a = la; - p[1].x = left; - p[1].y = 1; - p[1].r = lr; p[1].g = lg; p[1].b = lb; p[1].a = la; - p[2].x = right; - p[2].y = 1; - p[2].r = rr; p[2].g = rg; p[2].b = rb; p[2].a = ra; - - p[3].x = left; - p[3].y = 0; - p[3].r = lr; p[3].g = lg; p[3].b = lb; p[3].a = la; - p[4].x = right; - p[4].y = 1; - p[4].r = rr; p[4].g = rg; p[4].b = rb; p[4].a = ra; - p[5].x = right; - p[5].y = 0; - p[5].r = rr; p[5].g = rg; p[5].b = rb; p[5].a = ra; - - *position = &p[6]; -} - -#ifdef DUMP_GRADIENTS_TO_PNG -static void -dump_gradient_to_png (CoglTexture *texture) -{ - cairo_image_surface_t *image = (cairo_image_surface_t *) - cairo_image_surface_create (CAIRO_FORMAT_ARGB32, - cogl_texture_get_width (texture), - cogl_texture_get_height (texture)); - CoglPixelFormat format; - static int gradient_id = 0; - char *gradient_name; - - if (image->base.status) - return; - -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - format = COGL_PIXEL_FORMAT_BGRA_8888_PRE; -#else - format = COGL_PIXEL_FORMAT_ARGB_8888_PRE; -#endif - cogl_texture_get_data (texture, - format, - 0, - image->data); - gradient_name = g_strdup_printf ("./gradient%d.png", gradient_id++); - g_print ("writing gradient: %s\n", gradient_name); - cairo_surface_write_to_png ((cairo_surface_t *)image, gradient_name); - g_free (gradient_name); -} -#endif - -cairo_int_status_t -_cairo_cogl_get_linear_gradient (cairo_cogl_device_t *device, - cairo_extend_t extend_mode, - int n_stops, - const cairo_gradient_stop_t *stops, - cairo_cogl_linear_gradient_t **gradient_out) -{ - unsigned long hash; - cairo_cogl_linear_gradient_t *gradient; - cairo_cogl_linear_texture_entry_t *entry; - cairo_gradient_stop_t *internal_stops; - int stop_offset; - int n_internal_stops; - int n; - cairo_cogl_gradient_compatibility_t compatibilities; - int width; - int left_padding = 0; - cairo_color_stop_t left_padding_color; - int right_padding = 0; - cairo_color_stop_t right_padding_color; - CoglPixelFormat format; - CoglTexture2D *tex; - GError *error = NULL; - int un_padded_width; - CoglHandle offscreen; - cairo_int_status_t status; - int n_quads; - int n_vertices; - float prev; - float right; - CoglVertexP2C4 *vertices; - CoglVertexP2C4 *p; - CoglPrimitive *prim; - - hash = _cairo_cogl_linear_gradient_hash (n_stops, stops); - - gradient = _cairo_cogl_linear_gradient_lookup (device, hash, n_stops, stops); - if (gradient) { - cairo_cogl_linear_texture_entry_t *entry = - _cairo_cogl_linear_gradient_texture_for_extend (gradient, extend_mode); - if (entry) { - *gradient_out = _cairo_cogl_linear_gradient_reference (gradient); - return CAIRO_INT_STATUS_SUCCESS; - } - } - - if (!gradient) { - gradient = malloc (sizeof (cairo_cogl_linear_gradient_t) + - sizeof (cairo_gradient_stop_t) * (n_stops - 1)); - if (!gradient) - return CAIRO_INT_STATUS_NO_MEMORY; - - CAIRO_REFERENCE_COUNT_INIT (&gradient->ref_count, 1); - /* NB: we update the cache_entry size at the end before - * [re]adding it to the cache. */ - gradient->cache_entry.hash = hash; - gradient->textures = NULL; - gradient->n_stops = n_stops; - gradient->stops = gradient->stops_embedded; - memcpy (gradient->stops_embedded, stops, sizeof (cairo_gradient_stop_t) * n_stops); - } else - _cairo_cogl_linear_gradient_reference (gradient); - - entry = malloc (sizeof (cairo_cogl_linear_texture_entry_t)); - if (!entry) { - status = CAIRO_INT_STATUS_NO_MEMORY; - goto BAIL; - } - - compatibilities = _cairo_cogl_compatibility_from_extend_mode (extend_mode); - - n_internal_stops = n_stops; - stop_offset = 0; - - /* We really need stops covering the full [0,1] range for repeat/reflect - * if we want to use sampler REPEAT/MIRROR wrap modes so we may need - * to add some extra stops... */ - if (extend_mode == CAIRO_EXTEND_REPEAT || extend_mode == CAIRO_EXTEND_REFLECT) - { - /* If we don't need any extra stops then actually the texture - * will be shareable for repeat and reflect... */ - compatibilities = (CAIRO_COGL_GRADIENT_CAN_EXTEND_REPEAT | - CAIRO_COGL_GRADIENT_CAN_EXTEND_REFLECT); - - if (stops[0].offset != 0) { - n_internal_stops++; - stop_offset++; - } - - if (stops[n_stops - 1].offset != 1) - n_internal_stops++; - } - - internal_stops = alloca (n_internal_stops * sizeof (cairo_gradient_stop_t)); - memcpy (&internal_stops[stop_offset], stops, sizeof (cairo_gradient_stop_t) * n_stops); - - /* cairo_color_stop_t values are all unpremultiplied but we need to - * interpolate premultiplied colors so we premultiply all the double - * components now. (skipping any extra stops added for repeat/reflect) - * - * Anothing thing to note is that by premultiplying the colors - * early we'll also reduce the range of colors to interpolate - * which can result in smaller gradient textures. - */ - for (n = stop_offset; n < n_stops; n++) { - cairo_color_stop_t *color = &internal_stops[n].color; - color->red *= color->alpha; - color->green *= color->alpha; - color->blue *= color->alpha; - } - - if (n_internal_stops != n_stops) - { - if (extend_mode == CAIRO_EXTEND_REPEAT) { - compatibilities &= ~CAIRO_COGL_GRADIENT_CAN_EXTEND_REFLECT; - if (stops[0].offset != 0) { - /* what's the wrap-around distance between the user's end-stops? */ - double dx = (1.0 - stops[n_stops - 1].offset) + stops[0].offset; - internal_stops[0].offset = 0; - color_stop_lerp (&stops[0].color, - &stops[n_stops - 1].color, - stops[0].offset / dx, - &internal_stops[0].color); - } - if (stops[n_stops - 1].offset != 1) { - internal_stops[n_internal_stops - 1].offset = 1; - internal_stops[n_internal_stops - 1].color = internal_stops[0].color; - } - } else if (extend_mode == CAIRO_EXTEND_REFLECT) { - compatibilities &= ~CAIRO_COGL_GRADIENT_CAN_EXTEND_REPEAT; - if (stops[0].offset != 0) { - internal_stops[0].offset = 0; - internal_stops[0].color = stops[n_stops - 1].color; - } - if (stops[n_stops - 1].offset != 1) { - internal_stops[n_internal_stops - 1].offset = 1; - internal_stops[n_internal_stops - 1].color = stops[0].color; - } - } - } - - stops = internal_stops; - n_stops = n_internal_stops; - - width = _cairo_cogl_linear_gradient_width_for_stops (extend_mode, n_stops, stops); - - if (extend_mode == CAIRO_EXTEND_PAD) { - - /* Here we need to guarantee that the edge texels of our - * texture correspond to the desired padding color so we - * can use CLAMP_TO_EDGE. - * - * For short stop-gaps and especially for degenerate stops - * it's possible that without special consideration the - * user's end stop colors would not be present in our final - * texture. - * - * To handle this we forcibly add two extra padding texels - * at the edges which extend beyond the [0,1] range of the - * gradient itself and we will later report a translate and - * scale transform to compensate for this. - */ - - /* XXX: If we consider generating a mipmap for our 1d texture - * at some point then we also need to consider how much - * padding to add to be sure lower mipmap levels still have - * the desired edge color (as opposed to a linear blend with - * other colors of the gradient). - */ - - left_padding = 1; - left_padding_color = stops[0].color; - right_padding = 1; - right_padding_color = stops[n_stops - 1].color; - } else if (extend_mode == CAIRO_EXTEND_NONE) { - /* We handle EXTEND_NONE by adding two extra, transparent, texels at - * the ends of the texture and use CLAMP_TO_EDGE. - * - * We add a scale and translate transform so to account for our texels - * extending beyond the [0,1] range. */ - - left_padding = 1; - left_padding_color.red = 0; - left_padding_color.green = 0; - left_padding_color.blue = 0; - left_padding_color.alpha = 0; - right_padding = 1; - right_padding_color = left_padding_color; - } - - /* If we still have stops that don't cover the full [0,1] range - * then we need to define a texture-coordinate scale + translate - * transform to account for that... */ - if (stops[n_stops - 1].offset - stops[0].offset < 1) { - float range = stops[n_stops - 1].offset - stops[0].offset; - entry->scale_x = 1.0 / range; - entry->translate_x = -(stops[0].offset * entry->scale_x); - } - - width += left_padding + right_padding; - - width = _cairo_cogl_util_next_p2 (width); - width = MIN (4096, width); /* lets not go too stupidly big! */ - format = _cairo_cogl_linear_gradient_format_for_stops (extend_mode, n_stops, stops); - - do { - tex = cogl_texture_2d_new_with_size (device->cogl_context, - width, - 1, - format, - &error); - if (!tex) - g_error_free (error); - } while (tex == NULL && width >> 1); - - if (!tex) { - status = CAIRO_INT_STATUS_NO_MEMORY; - goto BAIL; - } - - entry->texture = COGL_TEXTURE (tex); - entry->compatibility = compatibilities; - - un_padded_width = width - left_padding - right_padding; - - /* XXX: only when we know the final texture width can we calculate the - * scale and translate factors needed to account for padding... */ - if (un_padded_width != width) - entry->scale_x *= (float)un_padded_width / (float)width; - if (left_padding) - entry->translate_x += (entry->scale_x / (float)un_padded_width) * (float)left_padding; - - offscreen = cogl_offscreen_new_to_texture (tex); - cogl_push_framebuffer (COGL_FRAMEBUFFER (offscreen)); - cogl_ortho (0, width, 1, 0, -1, 100); - cogl_framebuffer_clear4f (COGL_FRAMEBUFFER (offscreen), - COGL_BUFFER_BIT_COLOR, - 0, 0, 0, 0); - - n_quads = n_stops - 1 + !!left_padding + !!right_padding; - n_vertices = 6 * n_quads; - vertices = alloca (sizeof (CoglVertexP2C4) * n_vertices); - p = vertices; - if (left_padding) - emit_stop (&p, 0, left_padding, &left_padding_color, &left_padding_color); - prev = (float)left_padding; - for (n = 1; n < n_stops; n++) { - right = (float)left_padding + (float)un_padded_width * stops[n].offset; - emit_stop (&p, prev, right, &stops[n-1].color, &stops[n].color); - prev = right; - } - if (right_padding) - emit_stop (&p, prev, width, &right_padding_color, &right_padding_color); - - prim = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLES, - n_vertices, - vertices); - /* Just use this as the simplest way to setup a default pipeline... */ - cogl_set_source_color4f (0, 0, 0, 0); - cogl_primitive_draw (prim); - cogl_object_unref (prim); - - cogl_pop_framebuffer (); - cogl_object_unref (offscreen); - - gradient->textures = g_list_prepend (gradient->textures, entry); - gradient->cache_entry.size = _cairo_cogl_linear_gradient_size (gradient); - -#ifdef DUMP_GRADIENTS_TO_PNG - dump_gradient_to_png (COGL_TEXTURE (tex)); -#endif - -#warning "FIXME:" - /* XXX: it seems the documentation of _cairo_cache_insert isn't true - it - * doesn't handle re-adding the same entry gracefully - the cache will - * just keep on growing and then it will start randomly evicting things - * pointlessly */ - /* we ignore errors here and just return an uncached gradient */ - if (likely (! _cairo_cache_insert (&device->linear_cache, &gradient->cache_entry))) - _cairo_cogl_linear_gradient_reference (gradient); - - *gradient_out = gradient; - return CAIRO_INT_STATUS_SUCCESS; - -BAIL: - free (entry); - if (gradient) - _cairo_cogl_linear_gradient_destroy (gradient); - return status; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-cogl-private.h b/source/libs/cairo/cairo-src/src/cairo-cogl-private.h deleted file mode 100644 index 13fe5a8dc7646a8ef9626097aeeb6b811e47badf..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-cogl-private.h +++ /dev/null @@ -1,164 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2011 Intel Corporation. - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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.og/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. - * - * Contributor(s): - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef CAIRO_COGL_PRIVATE_H -#define CAIRO_COGL_PRIVATE_H - -#include "cairo-device-private.h" -#include "cairo-cache-private.h" -#include "cairo-backend-private.h" -#include "cairo-default-context-private.h" -#include "cairo-surface-private.h" - -#include <cogl/cogl2-experimental.h> - -typedef enum _cairo_cogl_template_type { - CAIRO_COGL_TEMPLATE_TYPE_SOLID, - CAIRO_COGL_TEMPLATE_TYPE_TEXTURE, - CAIRO_COGL_TEMPLATE_TYPE_MASK_SOLID, - CAIRO_COGL_TEMPLATE_TYPE_MASK_TEXTURE, - CAIRO_COGL_TEMPLATE_TYPE_COUNT -} cairo_cogl_template_type; - -typedef struct _cairo_cogl_device { - cairo_device_t base; - - cairo_bool_t backend_vtable_initialized; - cairo_backend_t backend; - - /* We save a copy of all the original backend methods that we override so - * we can chain up... - */ - cairo_backend_t backend_parent; - - CoglContext *cogl_context; - - CoglTexture *dummy_texture; - - /* This is a sparsely filled set of templates because we don't support - * the full range of operators that cairo has. All entries corresponding - * to unsupported operators are NULL. - * - * The CAIRO_OPERATOR_ADD is the operator enum with the highest value that - * we support so we at least cap the size of the array by that. - * - * For each operator we have a template for when we have a solid source - * and another for each texture format that could be used as a source. - */ - CoglPipeline *template_pipelines[CAIRO_OPERATOR_ADD + 1][CAIRO_COGL_TEMPLATE_TYPE_COUNT]; - - CoglMatrix identity; - - /* Caches 1d linear gradient textures */ - cairo_cache_t linear_cache; - - cairo_cache_t path_fill_staging_cache; - cairo_cache_t path_fill_prim_cache; - cairo_cache_t path_stroke_staging_cache; - cairo_cache_t path_stroke_prim_cache; -} cairo_cogl_device_t; - -typedef struct _cairo_cogl_clip_primitives { - cairo_t *clip; - CoglPrimitive **primitives; -} cairo_cogl_clip_primitives_t; - -typedef struct _cairo_cogl_surface { - cairo_surface_t base; - - CoglPixelFormat cogl_format; - cairo_bool_t ignore_alpha; - - /* We currently have 3 basic kinds of Cogl surfaces: - * 1) A light surface simply wrapping a CoglTexture - * 2) A CoglOffscreen framebuffer that implicitly also wraps a CoglTexture - * 3) A CoglOnscreen framebuffer which could potentially be mapped to - * a CoglTexture (e.g. via tfp on X11) but we don't currently do - * that. - */ - - CoglTexture *texture; - CoglFramebuffer *framebuffer; - - int width; - int height; - - GQueue *journal; - - CoglAttributeBuffer *buffer_stack; - size_t buffer_stack_size; - size_t buffer_stack_offset; - guint8 *buffer_stack_pointer; - - cairo_clip_t *last_clip; - - /* A small fifo of recently used cairo_clip_ts paired with CoglPrimitives - * that can be used to mask the stencil buffer. */ - GList *clips_fifo; - - int n_clip_updates_per_frame; - - /* Since the surface backend drawing operator functions don't get - * passed the current cairo_t context we don't have a good way - * to get our user-coordinates path into our surface_fill function. - * - * For now we use our _cairo_cogl_context_fill() wrapper to set this - * side band data on the surface... - */ - cairo_path_fixed_t *user_path; - cairo_matrix_t *ctm; - cairo_matrix_t *ctm_inverse; - cairo_bool_t path_is_rectangle; - double path_rectangle_x; - double path_rectangle_y; - double path_rectangle_width; - double path_rectangle_height; -} cairo_cogl_surface_t; - -cairo_status_t -_cairo_cogl_path_fixed_rectangle (cairo_path_fixed_t *path, - cairo_fixed_t x, - cairo_fixed_t y, - cairo_fixed_t width, - cairo_fixed_t height); - -cairo_int_status_t -_cairo_cogl_surface_fill_rectangle (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - double x, - double y, - double width, - double height, - cairo_matrix_t *ctm, - const cairo_clip_t *clip); - -#endif /* CAIRO_COGL_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-cogl-surface.c b/source/libs/cairo/cairo-src/src/cairo-cogl-surface.c deleted file mode 100644 index c57fd7f433c5ac1f97275c9012e08e0788797ae5..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-cogl-surface.c +++ /dev/null @@ -1,2805 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2011 Intel Corporation. - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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.og/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. - * - * Contributor(s): - * Robert Bragg <robert@linux.intel.com> - */ -#include "cairoint.h" - -#include "cairo-cache-private.h" -#include "cairo-error-private.h" -#include "cairo-path-fixed-private.h" -#include "cairo-recording-surface-private.h" -#include "cairo-surface-clipper-private.h" -#include "cairo-fixed-private.h" -#include "cairo-device-private.h" -#include "cairo-composite-rectangles-private.h" -#include "cairo-image-surface-inline.h" -#include "cairo-cogl-private.h" -#include "cairo-cogl-gradient-private.h" -#include "cairo-arc-private.h" -#include "cairo-traps-private.h" -#include "cairo-cogl-context-private.h" -#include "cairo-cogl-utils-private.h" -#include "cairo-box-inline.h" -#include "cairo-surface-subsurface-inline.h" -#include "cairo-surface-fallback-private.h" -#include "cairo-surface-offset-private.h" - -#include "cairo-cogl.h" - -#include <cogl/cogl2-experimental.h> -#include <glib.h> - -#define CAIRO_COGL_DEBUG 0 -//#define FILL_WITH_COGL_PATH -//#define USE_CAIRO_PATH_FLATTENER -#define ENABLE_PATH_CACHE -//#define DISABLE_BATCHING -#define USE_COGL_RECTANGLE_API -#define ENABLE_RECTANGLES_FASTPATH - -#if defined (USE_COGL_RECTANGLE_API) || defined (ENABLE_PATH_CACHE) -#define NEED_COGL_CONTEXT -#endif - -#if CAIRO_COGL_DEBUG && __GNUC__ -#define UNSUPPORTED(reason) ({ \ - g_warning ("cairo-cogl: hit unsupported operation: %s", reason); \ - CAIRO_INT_STATUS_UNSUPPORTED; \ -}) -#else -#define UNSUPPORTED(reason) CAIRO_INT_STATUS_UNSUPPORTED -#endif - -#define CAIRO_COGL_PATH_META_CACHE_SIZE (1024 * 1024) - -typedef struct _cairo_cogl_texture_attributes { - /* nabbed from cairo_surface_attributes_t... */ - cairo_matrix_t matrix; - cairo_extend_t extend; - cairo_filter_t filter; - cairo_bool_t has_component_alpha; - - CoglPipelineWrapMode s_wrap; - CoglPipelineWrapMode t_wrap; -} cairo_cogl_texture_attributes_t; - -typedef enum _cairo_cogl_journal_entry_type { - CAIRO_COGL_JOURNAL_ENTRY_TYPE_RECTANGLE, - CAIRO_COGL_JOURNAL_ENTRY_TYPE_PRIMITIVE, - CAIRO_COGL_JOURNAL_ENTRY_TYPE_PATH, - CAIRO_COGL_JOURNAL_ENTRY_TYPE_CLIP -} cairo_cogl_journal_entry_type_t; - -typedef struct _cairo_cogl_journal_entry { - cairo_cogl_journal_entry_type_t type; -} cairo_cogl_journal_entry_t; - -typedef struct _cairo_cogl_journal_clip_entry { - cairo_cogl_journal_entry_t base; - cairo_clip_t *clip; -} cairo_cogl_journal_clip_entry_t; - -typedef struct _cairo_cogl_journal_rect_entry { - cairo_cogl_journal_entry_t base; - CoglPipeline *pipeline; - float x; - float y; - float width; - float height; - int n_layers; - cairo_matrix_t ctm; -} cairo_cogl_journal_rect_entry_t; - -typedef struct _cairo_cogl_journal_prim_entry { - cairo_cogl_journal_entry_t base; - CoglPipeline *pipeline; - CoglPrimitive *primitive; - gboolean has_transform; - cairo_matrix_t transform; -} cairo_cogl_journal_prim_entry_t; - -typedef struct _cairo_cogl_journal_path_entry { - cairo_cogl_journal_entry_t base; - CoglPipeline *pipeline; - CoglPath *path; -} cairo_cogl_journal_path_entry_t; - -typedef struct _cairo_cogl_path_fill_meta { - cairo_cache_entry_t cache_entry; - cairo_reference_count_t ref_count; - int counter; - cairo_path_fixed_t *user_path; - cairo_matrix_t ctm_inverse; - - /* TODO */ -#if 0 - /* A cached path tessellation should be re-usable with different rotations - * and translations but not for different scales. - * - * one idea is to track the diagonal lenghts of a unit rectangle - * transformed through the original ctm use to tessellate the geometry - * so we can check what the lengths are for any new ctm to know if - * this geometry is compatible. - */ -#endif - - CoglPrimitive *prim; -} cairo_cogl_path_fill_meta_t; - -typedef struct _cairo_cogl_path_stroke_meta { - cairo_cache_entry_t cache_entry; - cairo_reference_count_t ref_count; - int counter; - cairo_path_fixed_t *user_path; - cairo_matrix_t ctm_inverse; - cairo_stroke_style_t style; - double tolerance; - - /* TODO */ -#if 0 - /* A cached path tessellation should be re-usable with different rotations - * and translations but not for different scales. - * - * one idea is to track the diagonal lenghts of a unit rectangle - * transformed through the original ctm use to tessellate the geometry - * so we can check what the lengths are for any new ctm to know if - * this geometry is compatible. - */ -#endif - - CoglPrimitive *prim; -} cairo_cogl_path_stroke_meta_t; - -static cairo_surface_t * -_cairo_cogl_surface_create_full (cairo_cogl_device_t *dev, - cairo_bool_t ignore_alpha, - CoglFramebuffer *framebuffer, - CoglTexture *texture); - -static cairo_int_status_t -_cairo_cogl_surface_fill (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip); - -static void -_cairo_cogl_journal_flush (cairo_cogl_surface_t *surface); - -cairo_private extern const cairo_surface_backend_t _cairo_cogl_surface_backend; - -slim_hidden_proto (cairo_cogl_device_create); -slim_hidden_proto (cairo_cogl_surface_create); -slim_hidden_proto (cairo_cogl_surface_get_framebuffer); -slim_hidden_proto (cairo_cogl_surface_get_texture); -slim_hidden_proto (cairo_cogl_surface_end_frame); - -static cairo_cogl_device_t * -to_device (cairo_device_t *device) -{ - return (cairo_cogl_device_t *)device; -} - -/* moves trap points such that they become the actual corners of the trapezoid */ -static void -_sanitize_trap (cairo_trapezoid_t *t) -{ - cairo_trapezoid_t s = *t; - -#define FIX(lr, tb, p) \ - if (t->lr.p.y != t->tb) { \ - t->lr.p.x = s.lr.p2.x + _cairo_fixed_mul_div_floor (s.lr.p1.x - s.lr.p2.x, s.tb - s.lr.p2.y, s.lr.p1.y - s.lr.p2.y); \ - t->lr.p.y = s.tb; \ - } - FIX (left, top, p1); - FIX (left, bottom, p2); - FIX (right, top, p1); - FIX (right, bottom, p2); -} - -static cairo_status_t -_cairo_cogl_surface_ensure_framebuffer (cairo_cogl_surface_t *surface) -{ - GError *error = NULL; - - if (surface->framebuffer) - return CAIRO_STATUS_SUCCESS; - - surface->framebuffer = COGL_FRAMEBUFFER (cogl_offscreen_new_to_texture (surface->texture)); - if (!cogl_framebuffer_allocate (surface->framebuffer, &error)) { - g_error_free (error); - cogl_object_unref (surface->framebuffer); - surface->framebuffer = NULL; - return CAIRO_STATUS_NO_MEMORY; - } - - cogl_push_framebuffer (surface->framebuffer); - cogl_ortho (0, surface->width, - surface->height, 0, - -1, 100); - cogl_pop_framebuffer (); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_surface_t * -_cairo_cogl_surface_create_similar (void *abstract_surface, - cairo_content_t content, - int width, - int height) -{ - cairo_cogl_surface_t *reference_surface = abstract_surface; - cairo_cogl_surface_t *surface; - CoglTexture *texture; - cairo_status_t status; - - texture = cogl_texture_new_with_size (width, height, - COGL_TEXTURE_NO_SLICING, - (content & CAIRO_CONTENT_COLOR) ? - COGL_PIXEL_FORMAT_BGRA_8888_PRE : - COGL_PIXEL_FORMAT_A_8); - if (!texture) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - surface = (cairo_cogl_surface_t *) - _cairo_cogl_surface_create_full (to_device(reference_surface->base.device), - (content & CAIRO_CONTENT_ALPHA) == 0, - NULL, - texture); - if (unlikely (surface->base.status)) - return &surface->base; - - status = _cairo_cogl_surface_ensure_framebuffer (surface); - if (unlikely (status)) { - cairo_surface_destroy (&surface->base); - return _cairo_surface_create_in_error (status); - } - - return &surface->base; -} - -static cairo_bool_t -_cairo_cogl_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *extents) -{ - cairo_cogl_surface_t *surface = abstract_surface; - - extents->x = 0; - extents->y = 0; - extents->width = surface->width; - extents->height = surface->height; - - return TRUE; -} - -static void -_cairo_cogl_journal_free (cairo_cogl_surface_t *surface) -{ - GList *l; - - for (l = surface->journal->head; l; l = l->next) { - cairo_cogl_journal_entry_t *entry = l->data; - - if (entry->type == CAIRO_COGL_JOURNAL_ENTRY_TYPE_PRIMITIVE) { - cairo_cogl_journal_prim_entry_t *prim_entry = - (cairo_cogl_journal_prim_entry_t *)entry; - cogl_object_unref (prim_entry->primitive); - } else if (entry->type == CAIRO_COGL_JOURNAL_ENTRY_TYPE_PATH) { - cairo_cogl_journal_path_entry_t *path_entry = - (cairo_cogl_journal_path_entry_t *)entry; - cogl_object_unref (path_entry->path); - } - } - - g_queue_free (surface->journal); - surface->journal = NULL; -} - -#ifdef FILL_WITH_COGL_PATH -static void -_cairo_cogl_journal_log_path (cairo_cogl_surface_t *surface, - CoglPipeline *pipeline, - CoglPath *path) -{ - cairo_cogl_journal_path_entry_t *entry; - - if (unlikely (surface->journal == NULL)) - surface->journal = g_queue_new (); - - /* FIXME: Instead of a GList here we should stack allocate the journal - * entries so it would be cheaper to allocate and they can all be freed in - * one go after flushing! */ - entry = g_slice_new (cairo_cogl_journal_path_entry_t); - entry->base.type = CAIRO_COGL_JOURNAL_ENTRY_TYPE_PATH; - - entry->pipeline = cogl_object_ref (pipeline); - entry->path = cogl_object_ref (path); - - g_queue_push_tail (surface->journal, entry); - -#ifdef DISABLE_BATCHING - _cairo_cogl_journal_flush (surface); -#endif -} -#endif /* FILL_WITH_COGL_PATH */ - -static void -_cairo_cogl_journal_log_primitive (cairo_cogl_surface_t *surface, - CoglPipeline *pipeline, - CoglPrimitive *primitive, - cairo_matrix_t *transform) -{ - cairo_cogl_journal_prim_entry_t *entry; - - if (unlikely (surface->journal == NULL)) - surface->journal = g_queue_new (); - - /* FIXME: Instead of a GList here we should stack allocate the journal - * entries so it would be cheaper to allocate and they can all be freed in - * one go after flushing! */ - entry = g_slice_new (cairo_cogl_journal_prim_entry_t); - entry->base.type = CAIRO_COGL_JOURNAL_ENTRY_TYPE_PRIMITIVE; - - entry->pipeline = cogl_object_ref (pipeline); - - if (transform) { - entry->transform = *transform; - entry->has_transform = TRUE; - } else - entry->has_transform = FALSE; - - entry->primitive = cogl_object_ref (primitive); - - g_queue_push_tail (surface->journal, entry); - -#ifdef DISABLE_BATCHING - _cairo_cogl_journal_flush (surface); -#endif -} - -static void -_cairo_cogl_journal_log_rectangle (cairo_cogl_surface_t *surface, - CoglPipeline *pipeline, - float x, - float y, - float width, - float height, - int n_layers, - cairo_matrix_t *ctm) -{ - cairo_cogl_journal_rect_entry_t *entry; - - if (unlikely (surface->journal == NULL)) - surface->journal = g_queue_new (); - - /* FIXME: Instead of a GList here we should stack allocate the journal - * entries so it would be cheaper to allocate and they can all be freed in - * one go after flushing! */ - entry = g_slice_new (cairo_cogl_journal_rect_entry_t); - entry->base.type = CAIRO_COGL_JOURNAL_ENTRY_TYPE_RECTANGLE; - - entry->pipeline = cogl_object_ref (pipeline); - - entry->x = x; - entry->y = y; - entry->width = width; - entry->height = height; - entry->ctm = *ctm; - - entry->n_layers = n_layers; - - g_queue_push_tail (surface->journal, entry); - -#ifdef DISABLE_BATCHING - _cairo_cogl_journal_flush (surface); -#endif -} - -static void -_cairo_cogl_journal_log_clip (cairo_cogl_surface_t *surface, - const cairo_clip_t *clip) -{ - cairo_cogl_journal_clip_entry_t *entry; - - if (unlikely (surface->journal == NULL)) - surface->journal = g_queue_new (); - - /* FIXME: Instead of a GList here we should stack allocate the journal - * entries so it would be cheaper to allocate and they can all be freed in - * one go after flushing! */ - entry = g_slice_new (cairo_cogl_journal_clip_entry_t); - entry->base.type = CAIRO_COGL_JOURNAL_ENTRY_TYPE_CLIP; - entry->clip = _cairo_clip_copy (clip); - - g_queue_push_tail (surface->journal, entry); -} - -static void -_cairo_cogl_journal_discard (cairo_cogl_surface_t *surface) -{ - GList *l; - - if (!surface->journal) { - assert (surface->last_clip == NULL); - return; - } - - if (surface->buffer_stack && surface->buffer_stack_offset) { - cogl_buffer_unmap (COGL_BUFFER (surface->buffer_stack)); - cogl_object_unref (surface->buffer_stack); - surface->buffer_stack = NULL; - } - - for (l = surface->journal->head; l; l = l->next) { - cairo_cogl_journal_entry_t *entry = l->data; - gsize entry_size; - - switch (entry->type) - { - case CAIRO_COGL_JOURNAL_ENTRY_TYPE_CLIP: { - cairo_cogl_journal_clip_entry_t *clip_entry = - (cairo_cogl_journal_clip_entry_t *)entry; - _cairo_clip_destroy (clip_entry->clip); - entry_size = sizeof (cairo_cogl_journal_clip_entry_t); - break; - } - case CAIRO_COGL_JOURNAL_ENTRY_TYPE_RECTANGLE: { - cairo_cogl_journal_rect_entry_t *rect_entry = - (cairo_cogl_journal_rect_entry_t *)entry; - cogl_object_unref (rect_entry->pipeline); - entry_size = sizeof (cairo_cogl_journal_rect_entry_t); - break; - } - case CAIRO_COGL_JOURNAL_ENTRY_TYPE_PRIMITIVE: { - cairo_cogl_journal_prim_entry_t *prim_entry = - (cairo_cogl_journal_prim_entry_t *)entry; - cogl_object_unref (prim_entry->pipeline); - cogl_object_unref (prim_entry->primitive); - entry_size = sizeof (cairo_cogl_journal_prim_entry_t); - break; - } - case CAIRO_COGL_JOURNAL_ENTRY_TYPE_PATH: { - cairo_cogl_journal_path_entry_t *path_entry = - (cairo_cogl_journal_path_entry_t *)entry; - cogl_object_unref (path_entry->pipeline); - cogl_object_unref (path_entry->path); - entry_size = sizeof (cairo_cogl_journal_path_entry_t); - break; - } - default: - assert (0); /* not reached! */ - entry_size = 0; /* avoid compiler warning */ - } - g_slice_free1 (entry_size, entry); - } - - g_queue_clear (surface->journal); - - if (surface->last_clip) { - _cairo_clip_destroy (surface->last_clip); - surface->last_clip = NULL; - } -} - -static CoglAttributeBuffer * -_cairo_cogl_surface_allocate_buffer_space (cairo_cogl_surface_t *surface, - size_t size, - size_t *offset, - void **pointer) -{ - /* XXX: In the Cogl journal we found it more efficient to have a pool of - * buffers that we re-cycle but for now we simply thow away our stack - * buffer each time we flush. */ - if (unlikely (surface->buffer_stack && - (surface->buffer_stack_size - surface->buffer_stack_offset) < size)) { - cogl_buffer_unmap (COGL_BUFFER (surface->buffer_stack)); - cogl_object_unref (surface->buffer_stack); - surface->buffer_stack = NULL; - surface->buffer_stack_size *= 2; - } - - if (unlikely (surface->buffer_stack_size < size)) - surface->buffer_stack_size = size * 2; - - if (unlikely (surface->buffer_stack == NULL)) { - surface->buffer_stack = cogl_attribute_buffer_new (surface->buffer_stack_size, NULL); - surface->buffer_stack_pointer = - cogl_buffer_map (COGL_BUFFER (surface->buffer_stack), - COGL_BUFFER_ACCESS_WRITE, - COGL_BUFFER_MAP_HINT_DISCARD); - surface->buffer_stack_offset = 0; - } - - *pointer = surface->buffer_stack_pointer + surface->buffer_stack_offset; - *offset = surface->buffer_stack_offset; - - surface->buffer_stack_offset += size; - return cogl_object_ref (surface->buffer_stack); -} - - -static CoglAttributeBuffer * -_cairo_cogl_traps_to_triangles_buffer (cairo_cogl_surface_t *surface, - cairo_traps_t *traps, - size_t *offset, - gboolean one_shot) -{ - CoglAttributeBuffer *buffer; - int n_traps = traps->num_traps; - int i; - CoglVertexP2 *triangles; - - if (one_shot) { - buffer = _cairo_cogl_surface_allocate_buffer_space (surface, - n_traps * sizeof (CoglVertexP2) * 6, - offset, - (void **)&triangles); - if (!buffer) - return NULL; - } else { - buffer = cogl_attribute_buffer_new (n_traps * sizeof (CoglVertexP2) * 6, NULL); - if (!buffer) - return NULL; - triangles = cogl_buffer_map (COGL_BUFFER (buffer), - COGL_BUFFER_ACCESS_WRITE, - COGL_BUFFER_MAP_HINT_DISCARD); - if (!triangles) - return NULL; - *offset = 0; - } - - /* XXX: This is can be very expensive. I'm not sure a.t.m if it's - * predominantly the bandwidth required or the cost of the fixed_to_float - * conversions but either way we should try using an index buffer to - * reduce the amount we upload by 1/3 (offset by allocating and uploading - * indices though) sadly though my experience with the intel mesa drivers - * is that slow paths can easily be hit when starting to use indices. - */ - for (i = 0; i < n_traps; i++) - { - CoglVertexP2 *p = &triangles[i * 6]; - cairo_trapezoid_t *trap = &traps->traps[i]; - - p[0].x = _cairo_cogl_util_fixed_to_float (trap->left.p1.x); - p[0].y = _cairo_cogl_util_fixed_to_float (trap->left.p1.y); - - p[1].x = _cairo_cogl_util_fixed_to_float (trap->left.p2.x); - p[1].y = _cairo_cogl_util_fixed_to_float (trap->left.p2.y); - - p[2].x = _cairo_cogl_util_fixed_to_float (trap->right.p2.x); - p[2].y = _cairo_cogl_util_fixed_to_float (trap->right.p2.y); - - p[3].x = _cairo_cogl_util_fixed_to_float (trap->left.p1.x); - p[3].y = _cairo_cogl_util_fixed_to_float (trap->left.p1.y); - - p[4].x = _cairo_cogl_util_fixed_to_float (trap->right.p2.x); - p[4].y = _cairo_cogl_util_fixed_to_float (trap->right.p2.y); - - p[5].x = _cairo_cogl_util_fixed_to_float (trap->right.p1.x); - p[5].y = _cairo_cogl_util_fixed_to_float (trap->right.p1.y); - } - - if (!one_shot) - cogl_buffer_unmap (COGL_BUFFER (buffer)); - - return buffer; -} - -/* Used for solid fills, in this case we just need a mesh made of - * a single (2-component) position attribute. */ -static CoglPrimitive * -_cairo_cogl_traps_to_composite_prim_p2 (cairo_cogl_surface_t *surface, - cairo_traps_t *traps, - gboolean one_shot) -{ - size_t offset; - CoglAttributeBuffer *buffer = _cairo_cogl_traps_to_triangles_buffer (surface, traps, &offset, one_shot); - CoglAttribute *pos = cogl_attribute_new (buffer, - "cogl_position_in", - sizeof (CoglVertexP2), - offset, - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - CoglPrimitive *prim; - - /* The attribute will have taken a reference on the buffer */ - cogl_object_unref (buffer); - - prim = cogl_primitive_new (COGL_VERTICES_MODE_TRIANGLES, - traps->num_traps * 6, pos, NULL); - - /* The primitive will now keep the attribute alive... */ - cogl_object_unref (pos); - - return prim; -} - -/* Used for surface fills, in this case we need a mesh made of a single - * (2-component) position attribute + we also alias the same attribute as - * (2-component) texture coordinates */ -static CoglPrimitive * -_cairo_cogl_traps_to_composite_prim_p2t2 (cairo_cogl_surface_t *surface, - cairo_traps_t *traps, - gboolean one_shot) -{ - size_t offset; - CoglAttributeBuffer *buffer = _cairo_cogl_traps_to_triangles_buffer (surface, traps, &offset, one_shot); - CoglAttribute *pos = cogl_attribute_new (buffer, - "cogl_position_in", - sizeof (CoglVertexP2), - offset, - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - CoglAttribute *tex_coords = cogl_attribute_new (buffer, - "cogl_tex_coord0_in", - sizeof (CoglVertexP2), - 0, - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - CoglPrimitive *prim; - - /* The attributes will have taken references on the buffer */ - cogl_object_unref (buffer); - - prim = cogl_primitive_new (COGL_VERTICES_MODE_TRIANGLES, - traps->num_traps * 6, pos, tex_coords, NULL); - - /* The primitive will now keep the attributes alive... */ - cogl_object_unref (pos); - cogl_object_unref (tex_coords); - - return prim; -} - -static CoglPrimitive * -_cairo_cogl_traps_to_composite_prim (cairo_cogl_surface_t *surface, - cairo_traps_t *traps, - int n_layers, - gboolean one_shot) -{ - int n_traps = traps->num_traps; - int i; - - /* XXX: Ideally we would skip tessellating to traps entirely since - * given their representation, conversion to triangles is quite expensive. - * - * This simplifies the conversion to triangles by making the end points of - * the two side lines actually just correspond to the corners of the - * traps. - */ - for (i = 0; i < n_traps; i++) - _sanitize_trap (&traps->traps[i]); - - if (n_layers == 0) - return _cairo_cogl_traps_to_composite_prim_p2 (surface, traps, one_shot); - else { - assert (n_layers == 1); - return _cairo_cogl_traps_to_composite_prim_p2t2 (surface, traps, one_shot); - } -} - -static cairo_int_status_t -_cairo_cogl_fill_to_primitive (cairo_cogl_surface_t *surface, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - int n_layers, - cairo_bool_t one_shot, - CoglPrimitive **primitive, - size_t *size) -{ - cairo_traps_t traps; - cairo_int_status_t status; - - _cairo_traps_init (&traps); - status = _cairo_path_fixed_fill_to_traps (path, fill_rule, tolerance, &traps); - if (unlikely (status)) - goto BAIL; - - if (traps.num_traps == 0) { - status = CAIRO_INT_STATUS_NOTHING_TO_DO; - goto BAIL; - } - - *size = traps.num_traps * sizeof (CoglVertexP2) * 6; - - *primitive = _cairo_cogl_traps_to_composite_prim (surface, &traps, n_layers, one_shot); - if (!*primitive) { - status = CAIRO_INT_STATUS_NO_MEMORY; - goto BAIL; - } - -BAIL: - _cairo_traps_fini (&traps); - return status; -} - -static void -_cairo_cogl_clip_push_box (const cairo_box_t *box) -{ - if (_cairo_box_is_pixel_aligned (box)) { - cairo_rectangle_int_t rect; - _cairo_box_round_to_rectangle (box, &rect); - cogl_clip_push_window_rectangle (rect.x, rect.y, - rect.width, rect.height); - } else { - double x1, y1, x2, y2; - _cairo_box_to_doubles (box, &x1, &y1, &x2, &y2); - cogl_clip_push_rectangle (x1, y1, x2, y2); - } -} - -static void -_cairo_cogl_journal_flush (cairo_cogl_surface_t *surface) -{ - GList *l; - int clip_stack_depth = 0; - int i; - - if (!surface->journal) - return; - - if (surface->buffer_stack && surface->buffer_stack_offset) { - cogl_buffer_unmap (COGL_BUFFER (surface->buffer_stack)); - cogl_object_unref (surface->buffer_stack); - surface->buffer_stack = NULL; - } - - cogl_set_framebuffer (surface->framebuffer); - - cogl_push_matrix (); - - for (l = surface->journal->head; l; l = l->next) { - cairo_cogl_journal_entry_t *entry = l->data; - - switch (entry->type) - { - case CAIRO_COGL_JOURNAL_ENTRY_TYPE_CLIP: { - cairo_cogl_journal_clip_entry_t *clip_entry = - (cairo_cogl_journal_clip_entry_t *)entry; - cairo_clip_path_t *path; -#if 0 - cairo_bool_t checked_for_primitives = FALSE; - cairo_cogl_clip_primitives_t *clip_primitives; -#endif - - for (i = 0; i < clip_stack_depth; i++) - cogl_clip_pop (); - clip_stack_depth = 0; - - for (path = clip_entry->clip->path, i = 0; path; path = path->prev, i++) { - cairo_rectangle_int_t extents; - cairo_int_status_t status; - CoglPrimitive *prim; - size_t prim_size; - - _cairo_path_fixed_approximate_clip_extents (&path->path, &extents); - - /* TODO - maintain a fifo of the last 10 used clips with cached - * primitives to see if we can avoid tessellating the path and - * uploading the vertices... - */ -#if 0 - if (!checked_for_primitives) { - clip_primitives = find_clip_primitives (clip); - checked_for_primitives = TRUE; - } - if (clip_primitives) - prim = clip_primitives->primitives[i]; -#endif - status = _cairo_cogl_fill_to_primitive (surface, - &path->path, - path->fill_rule, - path->tolerance, - 0, - TRUE, - &prim, - &prim_size); - if (unlikely (status)) { - g_warning ("Failed to get primitive for clip path while flushing journal"); - continue; - } - clip_stack_depth++; - cogl_clip_push_primitive (prim, - extents.x, extents.y, - extents.x + extents.width, - extents.y + extents.height); - cogl_object_unref (prim); - } - - for (i = 0; i < clip_entry->clip->num_boxes; i++) { - clip_stack_depth++; - _cairo_cogl_clip_push_box (&clip_entry->clip->boxes[i]); - } - - surface->n_clip_updates_per_frame++; - break; - } - case CAIRO_COGL_JOURNAL_ENTRY_TYPE_RECTANGLE: { - cairo_cogl_journal_rect_entry_t *rect_entry = - (cairo_cogl_journal_rect_entry_t *)entry; - float tex_coords[8]; - float x1 = rect_entry->x; - float y1 = rect_entry->y; - float x2 = rect_entry->x + rect_entry->width; - float y2 = rect_entry->y + rect_entry->height; - cairo_matrix_t *ctm = &rect_entry->ctm; - float ctmfv[16] = { - ctm->xx, ctm->yx, 0, 0, - ctm->xy, ctm->yy, 0, 0, - 0, 0, 1, 0, - ctm->x0, ctm->y0, 0, 1 - }; - CoglMatrix transform; - - cogl_matrix_init_from_array (&transform, ctmfv); - - if (rect_entry->n_layers) { - g_assert (rect_entry->n_layers <= 2); - tex_coords[0] = x1; - tex_coords[1] = y1; - tex_coords[2] = x2; - tex_coords[3] = y2; - if (rect_entry->n_layers > 1) - memcpy (&tex_coords[4], tex_coords, sizeof (float) * 4); - } - - cogl_set_source (rect_entry->pipeline); - cogl_push_matrix (); - cogl_transform (&transform); - cogl_rectangle_with_multitexture_coords (x1, y1, x2, y2, - tex_coords, 4 * rect_entry->n_layers); - cogl_pop_matrix (); - break; - } - case CAIRO_COGL_JOURNAL_ENTRY_TYPE_PRIMITIVE: { - cairo_cogl_journal_prim_entry_t *prim_entry = - (cairo_cogl_journal_prim_entry_t *)entry; - CoglMatrix transform; - - cogl_push_matrix (); - if (prim_entry->has_transform) { - cairo_matrix_t *ctm = &prim_entry->transform; - float ctmfv[16] = { - ctm->xx, ctm->yx, 0, 0, - ctm->xy, ctm->yy, 0, 0, - 0, 0, 1, 0, - ctm->x0, ctm->y0, 0, 1 - }; - cogl_matrix_init_from_array (&transform, ctmfv); - cogl_transform (&transform); - } else { - cogl_matrix_init_identity (&transform); - cogl_set_modelview_matrix (&transform); - } - - cogl_set_source (prim_entry->pipeline); - cogl_primitive_draw (prim_entry->primitive); - cogl_pop_matrix (); - break; - } - case CAIRO_COGL_JOURNAL_ENTRY_TYPE_PATH: { - cairo_cogl_journal_path_entry_t *path_entry = - (cairo_cogl_journal_path_entry_t *)entry; - - cogl_set_source (path_entry->pipeline); - cogl_path_fill (path_entry->path); - break; - } - default: - assert (0); /* not reached! */ - } - } - - cogl_pop_matrix (); - - for (i = 0; i < clip_stack_depth; i++) - cogl_clip_pop (); - - _cairo_cogl_journal_discard (surface); -} - -static cairo_status_t -_cairo_cogl_surface_flush (void *abstract_surface, - unsigned flags) -{ - cairo_cogl_surface_t *surface = (cairo_cogl_surface_t *)abstract_surface; - - if (flags) - return CAIRO_STATUS_SUCCESS; - - _cairo_cogl_journal_flush (surface); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_cogl_surface_finish (void *abstract_surface) -{ - cairo_cogl_surface_t *surface = abstract_surface; - - if (surface->texture) - cogl_object_unref (surface->texture); - - if (surface->framebuffer) - cogl_object_unref (surface->framebuffer); - - if (surface->journal) - _cairo_cogl_journal_free (surface); - - /*XXX wtf */ - cairo_device_release (surface->base.device); - - return CAIRO_STATUS_SUCCESS; -} - -static CoglPixelFormat -get_cogl_format_from_cairo_format (cairo_format_t cairo_format); - -/* XXX: We often use RGBA format for onscreen framebuffers so make sure - * to handle CAIRO_FORMAT_INVALID sensibly */ -static cairo_format_t -get_cairo_format_from_cogl_format (CoglPixelFormat format) -{ - switch ((int)format) - { - case COGL_PIXEL_FORMAT_A_8: - return CAIRO_FORMAT_A8; - case COGL_PIXEL_FORMAT_RGB_565: - return CAIRO_FORMAT_RGB16_565; - - case COGL_PIXEL_FORMAT_BGRA_8888_PRE: - case COGL_PIXEL_FORMAT_ARGB_8888_PRE: - case COGL_PIXEL_FORMAT_RGBA_8888_PRE: - /* Note: this is ambiguous since CAIRO_FORMAT_RGB24 - * would also map to the same CoglPixelFormat */ - return CAIRO_FORMAT_ARGB32; - - default: - g_warning("bad format: %x a? %d, bgr? %d, pre %d, format: %d\n", - format, - format & COGL_A_BIT, - format & COGL_BGR_BIT, - format & COGL_PREMULT_BIT, - format & ~(COGL_A_BIT | COGL_BGR_BIT | COGL_PREMULT_BIT)); - return CAIRO_FORMAT_INVALID; - } -} - -static CoglPixelFormat -get_cogl_format_from_cairo_format (cairo_format_t cairo_format) -{ - switch (cairo_format) - { - case CAIRO_FORMAT_ARGB32: - case CAIRO_FORMAT_RGB24: -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - return COGL_PIXEL_FORMAT_BGRA_8888_PRE; -#else - return COGL_PIXEL_FORMAT_ARGB_8888_PRE; -#endif - case CAIRO_FORMAT_A8: - return COGL_PIXEL_FORMAT_A_8; - case CAIRO_FORMAT_RGB16_565: - return COGL_PIXEL_FORMAT_RGB_565; - case CAIRO_FORMAT_INVALID: - case CAIRO_FORMAT_A1: - case CAIRO_FORMAT_RGB30: - return 0; - } - - g_warn_if_reached (); - return 0; -} - -static cairo_status_t -_cairo_cogl_surface_read_rect_to_image_surface (cairo_cogl_surface_t *surface, - cairo_rectangle_int_t *interest, - cairo_image_surface_t **image_out) -{ - cairo_image_surface_t *image; - cairo_status_t status; - cairo_format_t cairo_format; - CoglPixelFormat cogl_format; - - /* TODO: Add cogl_texture_get_region() API so we don't have to ensure the - * surface is bound to an fbo to read back pixels */ - status = _cairo_cogl_surface_ensure_framebuffer (surface); - if (unlikely (status)) - return status; - - cairo_format = get_cairo_format_from_cogl_format (surface->cogl_format); - if (cairo_format == CAIRO_FORMAT_INVALID) { - cairo_format = CAIRO_FORMAT_ARGB32; - cogl_format = get_cogl_format_from_cairo_format (cairo_format); - } else { - cogl_format = cogl_framebuffer_get_color_format (surface->framebuffer); - } - - image = (cairo_image_surface_t *) - cairo_image_surface_create (cairo_format, surface->width, surface->height); - if (image->base.status) - return image->base.status; - - /* TODO: Add cogl_framebuffer_read_pixels() API */ - cogl_push_framebuffer (surface->framebuffer); - cogl_read_pixels (0, 0, surface->width, surface->height, - COGL_READ_PIXELS_COLOR_BUFFER, - cogl_format, - image->data); - cogl_pop_framebuffer (); - - *image_out = image; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_cogl_surface_acquire_source_image (void *abstract_surface, - cairo_image_surface_t **image_out, - void **image_extra) -{ - cairo_cogl_surface_t *surface = abstract_surface; - cairo_status_t status; - - if (surface->texture) { - cairo_format_t format = get_cairo_format_from_cogl_format (surface->cogl_format); - cairo_image_surface_t *image = (cairo_image_surface_t *) - cairo_image_surface_create (format, surface->width, surface->height); - if (image->base.status) - return image->base.status; - - cogl_texture_get_data (surface->texture, - cogl_texture_get_format (surface->texture), - 0, - image->data); - - image->base.is_clear = FALSE; - *image_out = image; - } else { - cairo_rectangle_int_t extents = { - 0, 0, surface->width, surface->height - }; - status = _cairo_cogl_surface_read_rect_to_image_surface (surface, &extents, - image_out); - if (unlikely (status)) - return status; - } - - *image_extra = NULL; - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_cogl_surface_release_source_image (void *abstract_surface, - cairo_image_surface_t *image, - void *image_extra) -{ - cairo_surface_destroy (&image->base); -} - -static cairo_status_t -_cairo_cogl_surface_clear (cairo_cogl_surface_t *surface, - const cairo_color_t *color) -{ - /* Anything batched in the journal up until now is redundant... */ - _cairo_cogl_journal_discard (surface); - - /* XXX: we currently implicitly clear the depth and stencil buffer here - * but since we use the framebuffer_discard extension when available I - * suppose this doesn't matter too much. - * - * The main concern is that we want to avoid re-loading an external z - * buffer at the start of each frame, but also many gpu architectures have - * optimizations for how they handle the depth/stencil buffers and can get - * upset if they aren't cleared together at the start of the frame. - * - * FIXME: we need a way to assert that the clip stack currently isn't - * using the stencil buffer before clearing it here! - */ - cogl_framebuffer_clear4f (surface->framebuffer, - COGL_BUFFER_BIT_COLOR | - COGL_BUFFER_BIT_DEPTH | - COGL_BUFFER_BIT_STENCIL, - color->red * color->alpha, - color->green * color->alpha, - color->blue * color->alpha, - color->alpha); - return CAIRO_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_cogl_path_fixed_rectangle (cairo_path_fixed_t *path, - cairo_fixed_t x, - cairo_fixed_t y, - cairo_fixed_t width, - cairo_fixed_t height) -{ - cairo_status_t status; - - status = _cairo_path_fixed_move_to (path, x, y); - if (unlikely (status)) - return status; - - status = _cairo_path_fixed_rel_line_to (path, width, 0); - if (unlikely (status)) - return status; - - status = _cairo_path_fixed_rel_line_to (path, 0, height); - if (unlikely (status)) - return status; - - status = _cairo_path_fixed_rel_line_to (path, -width, 0); - if (unlikely (status)) - return status; - - status = _cairo_path_fixed_close_path (path); - if (unlikely (status)) - return status; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_cogl_surface_paint (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - cairo_cogl_surface_t *surface; - cairo_path_fixed_t path; - cairo_status_t status; - cairo_matrix_t identity; - - if (clip == NULL) { - if (op == CAIRO_OPERATOR_CLEAR) - return _cairo_cogl_surface_clear (abstract_surface, CAIRO_COLOR_TRANSPARENT); - else if (source->type == CAIRO_PATTERN_TYPE_SOLID && - (op == CAIRO_OPERATOR_SOURCE || - (op == CAIRO_OPERATOR_OVER && (((cairo_surface_t *)abstract_surface)->is_clear || _cairo_pattern_is_opaque_solid (source))))) { - return _cairo_cogl_surface_clear (abstract_surface, - &((cairo_solid_pattern_t *) source)->color); - } - } - - /* fallback to handling the paint in terms of a fill... */ - - surface = abstract_surface; - - _cairo_path_fixed_init (&path); - - status = _cairo_cogl_path_fixed_rectangle (&path, 0, 0, surface->width, surface->height); - if (unlikely (status)) - goto BAIL; - -#ifdef NEED_COGL_CONTEXT - /* XXX: in cairo-cogl-context.c we set some sideband data on the - * surface before issuing a fill so we need to do that here too... */ - surface->user_path = &path; - cairo_matrix_init_identity (&identity); - surface->ctm = &identity; - surface->ctm_inverse = &identity; - surface->path_is_rectangle = TRUE; - surface->path_rectangle_x = 0; - surface->path_rectangle_y = 0; - surface->path_rectangle_width = surface->width; - surface->path_rectangle_height = surface->height; -#endif - - status = _cairo_cogl_surface_fill (abstract_surface, - op, - source, - &path, - CAIRO_FILL_RULE_WINDING, - 1, - CAIRO_ANTIALIAS_DEFAULT, - clip); -BAIL: - _cairo_path_fixed_fini (&path); - return status; -} - -static CoglPipelineWrapMode -get_cogl_wrap_mode_for_extend (cairo_extend_t extend_mode) -{ - switch (extend_mode) - { - case CAIRO_EXTEND_NONE: - return COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE; - case CAIRO_EXTEND_PAD: - return COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE; - case CAIRO_EXTEND_REPEAT: - return COGL_PIPELINE_WRAP_MODE_REPEAT; - case CAIRO_EXTEND_REFLECT: - /* TODO: return COGL_PIPELINE_WRAP_MODE_MIRROR; */ - return CAIRO_EXTEND_REPEAT; - } - assert (0); /* not reached */ - return COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE; -} - -#if 0 -/* Given an arbitrary texture, check if it's already a pot texture and simply - * return it back if so. If not create a new pot texture, scale the old to - * fill it, unref the old and return a pointer to the new pot texture. */ -static cairo_int_status_t -_cairo_cogl_get_pot_texture (CoglContext *context, - CoglTexture *texture, - CoglTexture **pot_texture) -{ - int width = cogl_texture_get_width (texture); - int height = cogl_texture_get_height (texture); - int pot_width; - int pot_height; - CoglHandle offscreen = NULL; - CoglTexture2D *pot = NULL; - GError *error; - - pot_width = _cairo_cogl_util_next_p2 (width); - pot_height = _cairo_cogl_util_next_p2 (height); - - if (pot_width == width && pot_height == height) - return CAIRO_INT_STATUS_SUCCESS; - - for (;;) { - error = NULL; - pot = cogl_texture_2d_new_with_size (context, - pot_width, - pot_height, - cogl_texture_get_format (texture), - &error); - if (pot) - break; - else - g_error_free (error); - - if (pot_width > pot_height) - pot_width >>= 1; - else - pot_height >>= 1; - - if (!pot_width || !pot_height) - break; - } - - *pot_texture = COGL_TEXTURE (pot); - - if (!pot) - return CAIRO_INT_STATUS_NO_MEMORY; - - /* Use the GPU to do a bilinear filtered scale from npot to pot... */ - offscreen = cogl_offscreen_new_to_texture (COGL_TEXTURE (pot)); - error = NULL; - if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (offscreen), &error)) { - /* NB: if we don't pass an error then Cogl is allowed to simply abort - * automatically. */ - g_error_free (error); - cogl_object_unref (pot); - *pot_texture = NULL; - return CAIRO_INT_STATUS_NO_MEMORY; - } - - cogl_push_framebuffer (COGL_FRAMEBUFFER (offscreen)); - cogl_set_source_texture (texture); - cogl_rectangle (-1, 1, 1, -1); - cogl_pop_framebuffer (); - - cogl_object_unref (offscreen); -} -#endif - -/* NB: a reference for the texture is transferred to the caller which should - * be unrefed */ -static CoglTexture * -_cairo_cogl_acquire_surface_texture (cairo_cogl_surface_t *reference_surface, - cairo_surface_t *abstract_surface) -{ - cairo_image_surface_t *image; - cairo_image_surface_t *acquired_image = NULL; - void *image_extra; - CoglPixelFormat format; - cairo_image_surface_t *image_clone = NULL; - CoglTexture2D *texture; - GError *error = NULL; - cairo_surface_t *clone; - - if (abstract_surface->device == reference_surface->base.device) { - cairo_cogl_surface_t *surface = (cairo_cogl_surface_t *)abstract_surface; - _cairo_cogl_surface_flush (surface, 0); - return surface->texture ? cogl_object_ref (surface->texture) : NULL; - } - - if (abstract_surface->type == CAIRO_SURFACE_TYPE_COGL) { - if (_cairo_surface_is_subsurface (abstract_surface)) { - cairo_cogl_surface_t *surface; - - surface = (cairo_cogl_surface_t *) - _cairo_surface_subsurface_get_target (abstract_surface); - if (surface->base.device == reference_surface->base.device) - return surface->texture ? cogl_object_ref (surface->texture) : NULL; - } - } - - clone = _cairo_surface_has_snapshot (abstract_surface, &_cairo_cogl_surface_backend); - if (clone) { - cairo_cogl_surface_t *surface = (cairo_cogl_surface_t *)clone; - return surface->texture ? cogl_object_ref (surface->texture) : NULL; - } - - g_warning ("Uploading image surface to texture"); - - if (_cairo_surface_is_image (abstract_surface)) { - image = (cairo_image_surface_t *)abstract_surface; - } else { - cairo_status_t status = _cairo_surface_acquire_source_image (abstract_surface, - &acquired_image, &image_extra); - if (unlikely (status)) { - g_warning ("acquire_source_image failed: %s [%d]\n", - cairo_status_to_string (status), status); - return NULL; - } - image = acquired_image; - } - - format = get_cogl_format_from_cairo_format (image->format); - if (!format) - { - image_clone = _cairo_image_surface_coerce (image); - if (unlikely (image_clone->base.status)) { - g_warning ("image_surface_coerce failed"); - texture = NULL; - goto BAIL; - } - - format = get_cogl_format_from_cairo_format (image_clone->format); - assert (format); - } - - texture = cogl_texture_2d_new_from_data (to_device(reference_surface->base.device)->cogl_context, - image->width, - image->height, - format, /* incoming */ - format, /* desired */ - image->stride, - image->data, - &error); - if (!texture) { - g_warning ("Failed to allocate texture: %s", error->message); - g_error_free (error); - goto BAIL; - } - - clone = _cairo_cogl_surface_create_full (to_device(reference_surface->base.device), - reference_surface->ignore_alpha, - NULL, COGL_TEXTURE (texture)); - - _cairo_surface_attach_snapshot (abstract_surface, clone, NULL); - - /* Attaching the snapshot will take a reference on the clone surface... */ - cairo_surface_destroy (clone); - -BAIL: - if (image_clone) - cairo_surface_destroy (&image_clone->base); - if (acquired_image) - _cairo_surface_release_source_image (abstract_surface, acquired_image, image_extra); - - return COGL_TEXTURE (texture); -} - -/* NB: a reference for the texture is transferred to the caller which should - * be unrefed */ -static CoglTexture * -_cairo_cogl_acquire_pattern_texture (const cairo_pattern_t *pattern, - cairo_cogl_surface_t *destination, - const cairo_rectangle_int_t *extents, - const cairo_rectangle_int_t *sample, - cairo_cogl_texture_attributes_t *attributes) -{ - CoglTexture *texture = NULL; - - switch ((int)pattern->type) - { - case CAIRO_PATTERN_TYPE_SURFACE: { - cairo_surface_t *surface = ((cairo_surface_pattern_t *)pattern)->surface; - texture = _cairo_cogl_acquire_surface_texture (destination, surface); - if (!texture) - return NULL; - - /* XXX: determine if it would have no effect to change the - * extend mode to EXTEND_PAD instead since we can simply map - * EXTEND_PAD to CLAMP_TO_EDGE without needing fragment shader - * tricks or extra border texels. */ -#if 0 - /* TODO: We still need to consider HW such as SGX which doesn't have - * full support for NPOT textures. */ - if (pattern->extend == CAIRO_EXTEND_REPEAT || pattern->extend == CAIRO_EXTEND_REFLECT) { - _cairo_cogl_get_pot_texture (); - } -#endif - - cairo_matrix_init_identity (&attributes->matrix); - - /* Convert from un-normalized source coordinates in backend - * coordinates to normalized texture coordinates */ - cairo_matrix_scale (&attributes->matrix, - 1.0f / cogl_texture_get_width (texture), - 1.0f / cogl_texture_get_height (texture)); - - /* XXX: need to multiply in the pattern->matrix */ - - attributes->extend = pattern->extend; - attributes->filter = CAIRO_FILTER_BILINEAR; - attributes->has_component_alpha = pattern->has_component_alpha; - - attributes->s_wrap = get_cogl_wrap_mode_for_extend (pattern->extend); - attributes->t_wrap = attributes->s_wrap; - - return texture; - } - case CAIRO_PATTERN_TYPE_RADIAL: - case CAIRO_PATTERN_TYPE_MESH: { - cairo_surface_t *surface; - cairo_matrix_t texture_matrix; - - surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, - extents->width, extents->height); - if (_cairo_surface_offset_paint (surface, - extents->x, extents->y, - CAIRO_OPERATOR_SOURCE, - pattern, NULL)) { - cairo_surface_destroy (surface); - return NULL; - } - - texture = _cairo_cogl_acquire_surface_texture (destination, surface); - if (!texture) - goto BAIL; - - cairo_matrix_init_identity (&texture_matrix); - - /* Convert from un-normalized source coordinates in backend - * coordinates to normalized texture coordinates */ - cairo_matrix_scale (&texture_matrix, - 1.0f / cogl_texture_get_width (texture), - 1.0f / cogl_texture_get_height (texture)); - - cairo_matrix_translate (&texture_matrix, -extents->x, -extents->y); - - attributes->matrix = texture_matrix; - attributes->extend = pattern->extend; - attributes->filter = CAIRO_FILTER_NEAREST; - attributes->has_component_alpha = pattern->has_component_alpha; - - /* any pattern extend modes have already been dealt with... */ - attributes->s_wrap = COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE; - attributes->t_wrap = attributes->s_wrap; - -BAIL: - cairo_surface_destroy (surface); - - return texture; - } - case CAIRO_PATTERN_TYPE_LINEAR: { - cairo_linear_pattern_t *linear_pattern = (cairo_linear_pattern_t *)pattern; - cairo_cogl_linear_gradient_t *gradient; - cairo_cogl_linear_texture_entry_t *linear_texture; - cairo_int_status_t status; - float a, b; - float dist; - float scale; - float angle; - - status = _cairo_cogl_get_linear_gradient (to_device(destination->base.device), - pattern->extend, - linear_pattern->base.n_stops, - linear_pattern->base.stops, - &gradient); - if (unlikely (status)) - return NULL; - - linear_texture = _cairo_cogl_linear_gradient_texture_for_extend (gradient, pattern->extend); - - attributes->extend = pattern->extend; - attributes->filter = CAIRO_FILTER_BILINEAR; - attributes->has_component_alpha = pattern->has_component_alpha; - attributes->s_wrap = get_cogl_wrap_mode_for_extend (pattern->extend); - attributes->t_wrap = COGL_PIPELINE_WRAP_MODE_REPEAT; - - cairo_matrix_init_identity (&attributes->matrix); - - a = linear_pattern->pd2.x - linear_pattern->pd1.x; - b = linear_pattern->pd2.y - linear_pattern->pd1.y; - dist = sqrtf (a*a + b*b); - scale = 1.0f / dist; - angle = - atan2f (b, a); - - cairo_matrix_rotate (&attributes->matrix, angle); - cairo_matrix_scale (&attributes->matrix, scale, scale); - - cairo_matrix_translate (&attributes->matrix, - -linear_pattern->pd1.x, - -linear_pattern->pd1.y); - - /* XXX: this caught me out: cairo doesn't follow the standard - * maths convention for multiplying two matrices A x B - cairo - * does B x A so the final matrix is as if A's transforms were - * applied first. - */ - cairo_matrix_multiply (&attributes->matrix, - &pattern->matrix, - &attributes->matrix); - - return cogl_object_ref (linear_texture->texture); - } - default: - g_warning ("Un-supported source type"); - return NULL; - } -} - -static void -set_layer_texture_with_attributes (CoglPipeline *pipeline, - int layer_index, - CoglTexture *texture, - cairo_cogl_texture_attributes_t *attributes) -{ - cogl_pipeline_set_layer_texture (pipeline, layer_index, texture); - - if (!_cairo_matrix_is_identity (&attributes->matrix)) { - cairo_matrix_t *m = &attributes->matrix; - float texture_matrixfv[16] = { - m->xx, m->yx, 0, 0, - m->xy, m->yy, 0, 0, - 0, 0, 1, 0, - m->x0, m->y0, 0, 1 - }; - CoglMatrix texture_matrix; - cogl_matrix_init_from_array (&texture_matrix, texture_matrixfv); - cogl_pipeline_set_layer_matrix (pipeline, layer_index, &texture_matrix); - } - - if (attributes->s_wrap != attributes->t_wrap) { - cogl_pipeline_set_layer_wrap_mode_s (pipeline, layer_index, attributes->s_wrap); - cogl_pipeline_set_layer_wrap_mode_t (pipeline, layer_index, attributes->t_wrap); - } else - cogl_pipeline_set_layer_wrap_mode (pipeline, layer_index, attributes->s_wrap); -} - -static CoglPipeline * -get_source_mask_operator_destination_pipeline (const cairo_pattern_t *mask, - const cairo_pattern_t *source, - cairo_operator_t op, - cairo_cogl_surface_t *destination, - cairo_composite_rectangles_t *extents) -{ - cairo_cogl_template_type template_type; - CoglPipeline *pipeline; - - switch ((int)source->type) - { - case CAIRO_PATTERN_TYPE_SOLID: - template_type = mask ? - CAIRO_COGL_TEMPLATE_TYPE_MASK_SOLID : CAIRO_COGL_TEMPLATE_TYPE_SOLID; - break; - case CAIRO_PATTERN_TYPE_SURFACE: - case CAIRO_PATTERN_TYPE_LINEAR: - case CAIRO_PATTERN_TYPE_RADIAL: - case CAIRO_PATTERN_TYPE_MESH: - template_type = mask ? - CAIRO_COGL_TEMPLATE_TYPE_MASK_TEXTURE : CAIRO_COGL_TEMPLATE_TYPE_TEXTURE; - break; - default: - g_warning ("Un-supported source type"); - return NULL; - } - - pipeline = cogl_pipeline_copy (to_device(destination->base.device)->template_pipelines[op][template_type]); - - if (source->type == CAIRO_PATTERN_TYPE_SOLID) { - cairo_solid_pattern_t *solid_pattern = (cairo_solid_pattern_t *)source; - cogl_pipeline_set_color4f (pipeline, - solid_pattern->color.red * solid_pattern->color.alpha, - solid_pattern->color.green * solid_pattern->color.alpha, - solid_pattern->color.blue * solid_pattern->color.alpha, - solid_pattern->color.alpha); - } else { - cairo_cogl_texture_attributes_t attributes; - CoglTexture *texture = - _cairo_cogl_acquire_pattern_texture (source, destination, - &extents->bounded, - &extents->source_sample_area, - &attributes); - if (!texture) - goto BAIL; - set_layer_texture_with_attributes (pipeline, 0, texture, &attributes); - cogl_object_unref (texture); - } - - if (mask) { - if (mask->type == CAIRO_PATTERN_TYPE_SOLID) { - cairo_solid_pattern_t *solid_pattern = (cairo_solid_pattern_t *)mask; - CoglColor color; - cogl_color_init_from_4f (&color, - solid_pattern->color.red * solid_pattern->color.alpha, - solid_pattern->color.green * solid_pattern->color.alpha, - solid_pattern->color.blue * solid_pattern->color.alpha, - solid_pattern->color.alpha); - cogl_pipeline_set_layer_combine_constant (pipeline, 1, &color); - } else { - cairo_cogl_texture_attributes_t attributes; - CoglTexture *texture = - _cairo_cogl_acquire_pattern_texture (mask, destination, - &extents->bounded, - &extents->mask_sample_area, - &attributes); - if (!texture) - goto BAIL; - set_layer_texture_with_attributes (pipeline, 1, texture, &attributes); - cogl_object_unref (texture); - } - } - - return pipeline; - -BAIL: - cogl_object_unref (pipeline); - return NULL; -} - -#if 0 -CoglPrimitive * -_cairo_cogl_rectangle_new_p2t2t2 (float x, - float y, - float width, - float height) -{ - CoglVertexP2 vertices[] = { - {x, y}, {x, y + height}, {x + width, y + height}, - {x, y}, {x + width, y + height}, {x + width, y} - }; - CoglAttributeBuffer *buffer = cogl_attribute_buffer_new (sizeof (vertices)); - CoglAttribute *pos = cogl_attribute_new (buffer, - "cogl_position_in", - sizeof (CoglVertexP2), - 0, - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - CoglAttribute *tex_coords0 = cogl_attribute_new (buffer, - "cogl_tex_coord0_in", - sizeof (CoglVertexP2), - 0, - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - CoglAttribute *tex_coords0 = cogl_attribute_new (buffer, - "cogl_tex_coord0_in", - sizeof (CoglVertexP2), - 0, - 2, - COGL_ATTRIBUTE_TYPE_FLOAT); - CoglPrimitive *prim; - - cogl_buffer_set_data (COGL_BUFFER (buffer), 0, vertices, sizeof (vertices)); - - /* The attributes will now keep the buffer alive... */ - cogl_object_unref (buffer); - - prim = cogl_primitive_new (COGL_VERTICES_MODE_TRIANGLES, - 6, pos, tex_coords, NULL); - - /* The primitive will now keep the attribute alive... */ - cogl_object_unref (pos); - - return prim; -} -#endif - -static void -_cairo_cogl_log_clip (cairo_cogl_surface_t *surface, - const cairo_clip_t *clip) -{ - if (!_cairo_clip_equal (clip, surface->last_clip)) { - _cairo_cogl_journal_log_clip (surface, clip); - _cairo_clip_destroy (surface->last_clip); - surface->last_clip = _cairo_clip_copy (clip); - } -} - -static void -_cairo_cogl_maybe_log_clip (cairo_cogl_surface_t *surface, - cairo_composite_rectangles_t *composite) -{ - cairo_clip_t *clip = composite->clip; - - if (_cairo_composite_rectangles_can_reduce_clip (composite, clip)) - clip = NULL; - - if (clip == NULL) { - if (_cairo_composite_rectangles_can_reduce_clip (composite, - surface->last_clip)) - return; - } - - _cairo_cogl_log_clip (surface, clip); -} - -static cairo_bool_t -is_operator_supported (cairo_operator_t op) -{ - switch ((int)op) { - case CAIRO_OPERATOR_SOURCE: - case CAIRO_OPERATOR_OVER: - case CAIRO_OPERATOR_IN: - case CAIRO_OPERATOR_DEST_OVER: - case CAIRO_OPERATOR_DEST_IN: - case CAIRO_OPERATOR_ADD: - return TRUE; - - default: - return FALSE; - } -} - -static cairo_int_status_t -_cairo_cogl_surface_mask (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - cairo_cogl_surface_t *surface = abstract_surface; - cairo_composite_rectangles_t extents; - cairo_status_t status; - CoglPipeline *pipeline; - cairo_matrix_t identity; - - /* XXX: Use this to smoke test the acquire_source/dest_image fallback - * paths... */ - //return CAIRO_INT_STATUS_UNSUPPORTED; - - if (!is_operator_supported (op)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_composite_rectangles_init_for_mask (&extents, - &surface->base, - op, source, mask, clip); - if (unlikely (status)) - return status; - - pipeline = get_source_mask_operator_destination_pipeline (mask, source, - op, surface, &extents); - if (!pipeline){ - status = CAIRO_INT_STATUS_UNSUPPORTED; - goto BAIL; - } - - _cairo_cogl_maybe_log_clip (surface, &extents); - - cairo_matrix_init_identity (&identity); - _cairo_cogl_journal_log_rectangle (surface, pipeline, - extents.bounded.x, - extents.bounded.y, - extents.bounded.width, - extents.bounded.height, - 2, - &identity); - - /* The journal will take a reference on the pipeline and clip_path... */ - cogl_object_unref (pipeline); - -BAIL: - return status; -} - -static int -_cairo_cogl_source_n_layers (const cairo_pattern_t *source) -{ - switch ((int)source->type) - { - case CAIRO_PATTERN_TYPE_SOLID: - return 0; - case CAIRO_PATTERN_TYPE_LINEAR: - case CAIRO_PATTERN_TYPE_RADIAL: - case CAIRO_PATTERN_TYPE_MESH: - case CAIRO_PATTERN_TYPE_SURFACE: - return 1; - default: - g_warning ("Unsupported source type"); - return 0; - } -} - -static cairo_bool_t -_cairo_cogl_path_fill_meta_equal (const void *key_a, const void *key_b) -{ - const cairo_cogl_path_fill_meta_t *meta0 = key_a; - const cairo_cogl_path_fill_meta_t *meta1 = key_b; - - return _cairo_path_fixed_equal (meta0->user_path, meta1->user_path); -} - -static cairo_bool_t -_cairo_cogl_stroke_style_equal (const cairo_stroke_style_t *a, - const cairo_stroke_style_t *b) -{ - if (a->line_width == b->line_width && - a->line_cap == b->line_cap && - a->line_join == b->line_join && - a->miter_limit == b->miter_limit && - a->num_dashes == b->num_dashes && - a->dash_offset == b->dash_offset) - { - unsigned int i; - for (i = 0; i < a->num_dashes; i++) { - if (a->dash[i] != b->dash[i]) - return FALSE; - } - } - return TRUE; -} - -static cairo_bool_t -_cairo_cogl_path_stroke_meta_equal (const void *key_a, const void *key_b) -{ - const cairo_cogl_path_stroke_meta_t *meta0 = key_a; - const cairo_cogl_path_stroke_meta_t *meta1 = key_b; - - return _cairo_cogl_stroke_style_equal (&meta0->style, &meta1->style) && - _cairo_path_fixed_equal (meta0->user_path, meta1->user_path); -} - -static cairo_cogl_path_stroke_meta_t * -_cairo_cogl_path_stroke_meta_reference (cairo_cogl_path_stroke_meta_t *meta) -{ - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&meta->ref_count)); - - _cairo_reference_count_inc (&meta->ref_count); - - return meta; -} - -static void -_cairo_cogl_path_stroke_meta_destroy (cairo_cogl_path_stroke_meta_t *meta) -{ - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&meta->ref_count)); - - if (! _cairo_reference_count_dec_and_test (&meta->ref_count)) - return; - - _cairo_path_fixed_fini (meta->user_path); - free (meta->user_path); - - _cairo_stroke_style_fini (&meta->style); - - if (meta->prim) - cogl_object_unref (meta->prim); - - free (meta); -} - -static cairo_cogl_path_stroke_meta_t * -_cairo_cogl_path_stroke_meta_lookup (cairo_cogl_device_t *ctx, - unsigned long hash, - cairo_path_fixed_t *user_path, - const cairo_stroke_style_t *style, - double tolerance) -{ - cairo_cogl_path_stroke_meta_t *ret; - cairo_cogl_path_stroke_meta_t lookup; - - lookup.cache_entry.hash = hash; - lookup.user_path = user_path; - lookup.style = *style; - lookup.tolerance = tolerance; - - ret = _cairo_cache_lookup (&ctx->path_stroke_staging_cache, &lookup.cache_entry); - if (!ret) - ret = _cairo_cache_lookup (&ctx->path_stroke_prim_cache, &lookup.cache_entry); - return ret; -} - -static void -_cairo_cogl_path_stroke_meta_set_prim_size (cairo_cogl_surface_t *surface, - cairo_cogl_path_stroke_meta_t *meta, - size_t size) -{ - /* now that we know the meta structure is associated with a primitive - * we promote it from the staging cache into the primitive cache. - */ - - /* XXX: _cairo_cache borks if you try and remove an entry that's already - * been evicted so we explicitly look it up first... */ - if (_cairo_cache_lookup (&to_device(surface->base.device)->path_stroke_staging_cache, &meta->cache_entry)) { - _cairo_cogl_path_stroke_meta_reference (meta); - _cairo_cache_remove (&to_device(surface->base.device)->path_stroke_staging_cache, &meta->cache_entry); - } - - meta->cache_entry.size = size; - if (_cairo_cache_insert (&to_device(surface->base.device)->path_stroke_prim_cache, &meta->cache_entry) != - CAIRO_STATUS_SUCCESS) - _cairo_cogl_path_stroke_meta_destroy (meta); -} - -static unsigned int -_cairo_cogl_stroke_style_hash (unsigned int hash, - const cairo_stroke_style_t *style) -{ - unsigned int i; - hash = _cairo_hash_bytes (hash, &style->line_width, sizeof (style->line_width)); - hash = _cairo_hash_bytes (hash, &style->line_cap, sizeof (style->line_cap)); - hash = _cairo_hash_bytes (hash, &style->line_join, sizeof (style->line_join)); - hash = _cairo_hash_bytes (hash, &style->miter_limit, sizeof (style->miter_limit)); - hash = _cairo_hash_bytes (hash, &style->num_dashes, sizeof (style->num_dashes)); - hash = _cairo_hash_bytes (hash, &style->dash_offset, sizeof (style->dash_offset)); - for (i = 0; i < style->num_dashes; i++) - hash = _cairo_hash_bytes (hash, &style->dash[i], sizeof (double)); - return hash; -} - -static cairo_cogl_path_stroke_meta_t * -_cairo_cogl_get_path_stroke_meta (cairo_cogl_surface_t *surface, - const cairo_stroke_style_t *style, - double tolerance) -{ - unsigned long hash; - cairo_cogl_path_stroke_meta_t *meta = NULL; - cairo_path_fixed_t *meta_path = NULL; - cairo_status_t status; - - if (!surface->user_path) - return NULL; - - hash = _cairo_path_fixed_hash (surface->user_path); - hash = _cairo_cogl_stroke_style_hash (hash, style); - hash = _cairo_hash_bytes (hash, &tolerance, sizeof (tolerance)); - - meta = _cairo_cogl_path_stroke_meta_lookup (to_device(surface->base.device), hash, - surface->user_path, style, tolerance); - if (meta) - return meta; - - meta = calloc (1, sizeof (cairo_cogl_path_stroke_meta_t)); - if (!meta) - goto BAIL; - CAIRO_REFERENCE_COUNT_INIT (&meta->ref_count, 1); - meta->cache_entry.hash = hash; - meta->counter = 0; - meta_path = malloc (sizeof (cairo_path_fixed_t)); - if (!meta_path) - goto BAIL; - /* FIXME: we should add a ref-counted wrapper for our user_paths - * so we don't have to keep copying them here! */ - status = _cairo_path_fixed_init_copy (meta_path, surface->user_path); - if (unlikely (status)) - goto BAIL; - meta->user_path = meta_path; - meta->ctm_inverse = *surface->ctm_inverse; - - status = _cairo_stroke_style_init_copy (&meta->style, style); - if (unlikely (status)) { - _cairo_path_fixed_fini (meta_path); - goto BAIL; - } - meta->tolerance = tolerance; - - return meta; - -BAIL: - free (meta_path); - free (meta); - return NULL; -} - -static cairo_int_status_t -_cairo_cogl_stroke_to_primitive (cairo_cogl_surface_t *surface, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - int n_layers, - cairo_bool_t one_shot, - CoglPrimitive **primitive, - size_t *size) -{ - cairo_traps_t traps; - cairo_int_status_t status; - - _cairo_traps_init (&traps); - - status = _cairo_path_fixed_stroke_polygon_to_traps (path, style, - ctm, ctm_inverse, - tolerance, - &traps); - if (unlikely (status)) - goto BAIL; - - if (traps.num_traps == 0) { - status = CAIRO_INT_STATUS_NOTHING_TO_DO; - goto BAIL; - } - - *size = traps.num_traps * sizeof (CoglVertexP2) * 6; - - //g_print ("new stroke prim\n"); - *primitive = _cairo_cogl_traps_to_composite_prim (surface, &traps, n_layers, one_shot); - if (!*primitive) { - status = CAIRO_INT_STATUS_NO_MEMORY; - goto BAIL; - } - -BAIL: - _cairo_traps_fini (&traps); - return status; -} - -static cairo_int_status_t -_cairo_cogl_surface_stroke (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_cogl_surface_t *surface = (cairo_cogl_surface_t *)abstract_surface; - cairo_composite_rectangles_t extents; - CoglPipeline *pipeline; - cairo_status_t status; -#ifdef ENABLE_PATH_CACHE - cairo_cogl_path_stroke_meta_t *meta = NULL; - cairo_matrix_t transform_matrix; -#endif - cairo_matrix_t *transform = NULL; - gboolean one_shot = TRUE; - CoglPrimitive *prim = NULL; - cairo_bool_t new_prim = FALSE; - - if (! is_operator_supported (op)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* FIXME - support unbounded operators */ - if (!_cairo_operator_bounded_by_mask (op)) { - /* Currently IN this is the only unbounded operator we aim to support - * in cairo-cogl. */ - assert (op == CAIRO_OPERATOR_IN); - g_warning ("FIXME: handle stroking with unbounded operators!"); - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - status = _cairo_composite_rectangles_init_for_stroke (&extents, - &surface->base, - op, source, path, - style, - ctm, - clip); - if (unlikely (status)) - return status; - -#ifdef ENABLE_PATH_CACHE - /* FIXME: we are currently leaking the meta state if we don't reach - * the cache_insert at the end. */ - meta = _cairo_cogl_get_path_stroke_meta (surface, style, tolerance); - if (meta) { - prim = meta->prim; - if (prim) { - cairo_matrix_multiply (&transform_matrix, &meta->ctm_inverse, surface->ctm); - transform = &transform_matrix; - } else if (meta->counter++ > 10) - one_shot = FALSE; - } -#endif - - if (!prim) { - int n_layers = _cairo_cogl_source_n_layers (source); - size_t prim_size = 0; - status = _cairo_cogl_stroke_to_primitive (surface, path, style, - ctm, ctm_inverse, tolerance, - n_layers, one_shot, - &prim, &prim_size); - if (unlikely (status)) - return status; - new_prim = TRUE; -#if defined (ENABLE_PATH_CACHE) - if (meta) { - meta->prim = cogl_object_ref (prim); - _cairo_cogl_path_stroke_meta_set_prim_size (surface, meta, prim_size); - } -#endif - } - - pipeline = get_source_mask_operator_destination_pipeline (NULL, source, - op, surface, &extents); - if (!pipeline) - return CAIRO_INT_STATUS_UNSUPPORTED; - - _cairo_cogl_maybe_log_clip (surface, &extents); - - _cairo_cogl_journal_log_primitive (surface, pipeline, prim, transform); - - /* The journal will take a reference on the pipeline and primitive... */ - cogl_object_unref (pipeline); - if (new_prim) - cogl_object_unref (prim); - - return CAIRO_INT_STATUS_SUCCESS; -} - -static cairo_cogl_path_fill_meta_t * -_cairo_cogl_path_fill_meta_reference (cairo_cogl_path_fill_meta_t *meta) -{ - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&meta->ref_count)); - - _cairo_reference_count_inc (&meta->ref_count); - - return meta; -} - -static void -_cairo_cogl_path_fill_meta_destroy (cairo_cogl_path_fill_meta_t *meta) -{ - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&meta->ref_count)); - - if (! _cairo_reference_count_dec_and_test (&meta->ref_count)) - return; - - _cairo_path_fixed_fini (meta->user_path); - free (meta->user_path); - - if (meta->prim) - cogl_object_unref (meta->prim); - - free (meta); -} - -static cairo_cogl_path_fill_meta_t * -_cairo_cogl_path_fill_meta_lookup (cairo_cogl_device_t *ctx, - unsigned long hash, - cairo_path_fixed_t *user_path) -{ - cairo_cogl_path_fill_meta_t *ret; - cairo_cogl_path_fill_meta_t lookup; - - lookup.cache_entry.hash = hash; - lookup.user_path = user_path; - - ret = _cairo_cache_lookup (&ctx->path_fill_staging_cache, &lookup.cache_entry); - if (!ret) - ret = _cairo_cache_lookup (&ctx->path_fill_prim_cache, &lookup.cache_entry); - return ret; -} - -static void -_cairo_cogl_path_fill_meta_set_prim_size (cairo_cogl_surface_t *surface, - cairo_cogl_path_fill_meta_t *meta, - size_t size) -{ - /* now that we know the meta structure is associated with a primitive - * we promote it from the staging cache into the primitive cache. - */ - - /* XXX: _cairo_cache borks if you try and remove an entry that's already - * been evicted so we explicitly look it up first... */ - if (_cairo_cache_lookup (&to_device(surface->base.device)->path_fill_staging_cache, &meta->cache_entry)) { - _cairo_cogl_path_fill_meta_reference (meta); - _cairo_cache_remove (&to_device(surface->base.device)->path_fill_staging_cache, &meta->cache_entry); - } - - meta->cache_entry.size = size; - if (_cairo_cache_insert (&to_device(surface->base.device)->path_fill_prim_cache, &meta->cache_entry) != - CAIRO_STATUS_SUCCESS) - _cairo_cogl_path_fill_meta_destroy (meta); -} - -static cairo_cogl_path_fill_meta_t * -_cairo_cogl_get_path_fill_meta (cairo_cogl_surface_t *surface) -{ - unsigned long hash; - cairo_cogl_path_fill_meta_t *meta = NULL; - cairo_path_fixed_t *meta_path = NULL; - cairo_status_t status; - - if (!surface->user_path) - return NULL; - - hash = _cairo_path_fixed_hash (surface->user_path); - - meta = _cairo_cogl_path_fill_meta_lookup (to_device(surface->base.device), - hash, surface->user_path); - if (meta) - return meta; - - meta = calloc (1, sizeof (cairo_cogl_path_fill_meta_t)); - if (!meta) - goto BAIL; - meta->cache_entry.hash = hash; - meta->counter = 0; - CAIRO_REFERENCE_COUNT_INIT (&meta->ref_count, 1); - meta_path = malloc (sizeof (cairo_path_fixed_t)); - if (!meta_path) - goto BAIL; - /* FIXME: we should add a ref-counted wrapper for our user_paths - * so we don't have to keep copying them here! */ - status = _cairo_path_fixed_init_copy (meta_path, surface->user_path); - if (unlikely (status)) - goto BAIL; - meta->user_path = meta_path; - meta->ctm_inverse = *surface->ctm_inverse; - - /* To start with - until we associate a CoglPrimitive with the meta - * structure - we keep the meta in a staging structure until we - * see whether it actually gets re-used. */ - meta->cache_entry.size = 1; - if (_cairo_cache_insert (&to_device(surface->base.device)->path_fill_staging_cache, &meta->cache_entry) != - CAIRO_STATUS_SUCCESS) - _cairo_cogl_path_fill_meta_destroy (meta); - - return meta; - -BAIL: - free (meta_path); - free (meta); - return NULL; -} - -static cairo_int_status_t -_cairo_cogl_surface_fill (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_cogl_surface_t *surface = abstract_surface; - cairo_composite_rectangles_t extents; - cairo_status_t status; -#ifdef ENABLE_PATH_CACHE - cairo_cogl_path_fill_meta_t *meta = NULL; - cairo_matrix_t transform_matrix; -#endif - cairo_matrix_t *transform = NULL; - cairo_bool_t one_shot = TRUE; - CoglPrimitive *prim = NULL; - cairo_bool_t new_prim = FALSE; - CoglPipeline *pipeline; - - if (! is_operator_supported (op)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* FIXME - support unbounded operators */ - if (!_cairo_operator_bounded_by_mask (op)) { - /* Currently IN this is the only unbounded operator we aim to support - * in cairo-cogl. */ - assert (op == CAIRO_OPERATOR_IN); - g_warning ("FIXME: handle filling with unbounded operators!"); - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - status = _cairo_composite_rectangles_init_for_fill (&extents, - &surface->base, - op, source, path, - clip); - if (unlikely (status)) - return status; - -#ifndef FILL_WITH_COGL_PATH -#ifdef ENABLE_PATH_CACHE - meta = _cairo_cogl_get_path_fill_meta (surface); - if (meta) { - prim = meta->prim; - if (prim) { - cairo_matrix_multiply (&transform_matrix, &meta->ctm_inverse, surface->ctm); - transform = &transform_matrix; - } else if (meta->counter++ > 10) - one_shot = FALSE; - } -#endif /* ENABLE_PATH_CACHE */ - - if (!prim) { - int n_layers = _cairo_cogl_source_n_layers (source); - size_t prim_size; - status = _cairo_cogl_fill_to_primitive (surface, path, fill_rule, tolerance, - one_shot, n_layers, &prim, &prim_size); - if (unlikely (status)) - return status; - new_prim = TRUE; -#ifdef ENABLE_PATH_CACHE - if (meta) { - meta->prim = cogl_object_ref (prim); - _cairo_cogl_path_fill_meta_set_prim_size (surface, meta, prim_size); - } -#endif /* ENABLE_PATH_CACHE */ - } - -#endif /* !FILL_WITH_COGL_PATH */ - - pipeline = get_source_mask_operator_destination_pipeline (NULL, source, - op, surface, &extents); - if (!pipeline) - return CAIRO_INT_STATUS_UNSUPPORTED; - - _cairo_cogl_maybe_log_clip (surface, &extents); - -#ifndef FILL_WITH_COGL_PATH - _cairo_cogl_journal_log_primitive (surface, pipeline, prim, transform); - /* The journal will take a reference on the prim */ - if (new_prim) - cogl_object_unref (prim); -#else - CoglPath * cogl_path = _cairo_cogl_util_path_from_cairo (path, fill_rule, tolerance); - _cairo_cogl_journal_log_path (surface, pipeline, cogl_path); - cogl_object_unref (cogl_path); -#endif - - /* The journal will take a reference on the pipeline... */ - cogl_object_unref (pipeline); - - return CAIRO_INT_STATUS_SUCCESS; -} - -cairo_int_status_t -_cairo_cogl_surface_fill_rectangle (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - double x, - double y, - double width, - double height, - cairo_matrix_t *ctm, - const cairo_clip_t *clip) -{ - cairo_cogl_surface_t *surface = abstract_surface; - CoglPipeline *pipeline; - - if (! is_operator_supported (op)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* FIXME - support unbounded operators */ - if (!_cairo_operator_bounded_by_mask (op)) { - /* Currently IN this is the only unbounded operator we aim to support - * in cairo-cogl. */ - assert (op == CAIRO_OPERATOR_IN); - g_warning ("FIXME: handle filling with unbounded operators!"); - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - /* FIXME */ -#if 0 - status = _cairo_composite_rectangles_init_for_fill_rectangle (&extents, - &surface->base, - op, source, path, - clip); - if (unlikely (status)) - return status; -#endif - - if (source->type == CAIRO_PATTERN_TYPE_SOLID) { - double x1 = x; - double y1 = y; - double x2 = x1 + width; - double y2 = y1 + height; - - pipeline = get_source_mask_operator_destination_pipeline (NULL, source, - op, surface, NULL); - if (!pipeline) - return CAIRO_INT_STATUS_UNSUPPORTED; - - _cairo_cogl_log_clip (surface, clip); - - _cairo_cogl_journal_log_rectangle (surface, - pipeline, - x1, y1, x2, y2, - 0, - ctm); - return CAIRO_INT_STATUS_SUCCESS; - } else - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* TODO: - * We need to acquire the textures here, look at the corresponding - * attributes and see if this can be trivially handled by logging - * a textured rectangle only needing simple scaling or translation - * of texture coordinates. - * - * At this point we should also aim to remap the default - * EXTEND_NONE mode to EXTEND_PAD which is more efficient if we - * know it makes no difference either way since we can map that to - * CLAMP_TO_EDGE. - */ -} - -static cairo_int_status_t -_cairo_cogl_surface_show_glyphs (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - return CAIRO_INT_STATUS_UNSUPPORTED; -} - -const cairo_surface_backend_t _cairo_cogl_surface_backend = { - CAIRO_SURFACE_TYPE_COGL, - _cairo_cogl_surface_finish, -#ifdef NEED_COGL_CONTEXT - _cairo_cogl_context_create, -#else - _cairo_default_context_create, -#endif - - _cairo_cogl_surface_create_similar, - NULL, /* create similar image */ - NULL, /* map to image */ - NULL, /* unmap image */ - - _cairo_surface_default_source, - _cairo_cogl_surface_acquire_source_image, - _cairo_cogl_surface_release_source_image, - NULL, /* snapshot */ - - NULL, /* copy_page */ - NULL, /* show_page */ - - _cairo_cogl_surface_get_extents, - NULL, /* get_font_options */ - - _cairo_cogl_surface_flush, /* flush */ - NULL, /* mark_dirty_rectangle */ - - _cairo_cogl_surface_paint, - _cairo_cogl_surface_mask, - _cairo_cogl_surface_stroke, - _cairo_cogl_surface_fill, - NULL, /* fill_stroke*/ - _cairo_surface_fallback_glyphs, -}; - -static cairo_surface_t * -_cairo_cogl_surface_create_full (cairo_cogl_device_t *dev, - cairo_bool_t ignore_alpha, - CoglFramebuffer *framebuffer, - CoglTexture *texture) -{ - cairo_cogl_surface_t *surface; - cairo_status_t status; - - status = cairo_device_acquire (&dev->base); - if (unlikely (status)) - return _cairo_surface_create_in_error (status); - - surface = malloc (sizeof (cairo_cogl_surface_t)); - if (unlikely (surface == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - surface->ignore_alpha = ignore_alpha; - - surface->framebuffer = framebuffer; - if (framebuffer) { - surface->width = cogl_framebuffer_get_width (framebuffer); - surface->height = cogl_framebuffer_get_height (framebuffer); - surface->cogl_format = cogl_framebuffer_get_color_format (framebuffer); - cogl_object_ref (framebuffer); - } - - /* FIXME: If texture == NULL and we are given an offscreen framebuffer - * then we want a way to poke inside the framebuffer to get a texture */ - surface->texture = texture; - if (texture) { - if (!framebuffer) { - surface->width = cogl_texture_get_width (texture); - surface->height = cogl_texture_get_height (texture); - surface->cogl_format = cogl_texture_get_format (texture); - } - cogl_object_ref (texture); - } - - assert(surface->width && surface->height); - - surface->journal = NULL; - - surface->buffer_stack = NULL; - surface->buffer_stack_size = 4096; - - surface->last_clip = NULL; - - surface->n_clip_updates_per_frame = 0; - - _cairo_surface_init (&surface->base, - &_cairo_cogl_surface_backend, - &dev->base, - CAIRO_CONTENT_COLOR_ALPHA); - - return &surface->base; -} - -cairo_surface_t * -cairo_cogl_surface_create (cairo_device_t *abstract_device, - CoglFramebuffer *framebuffer) -{ - cairo_cogl_device_t *dev = (cairo_cogl_device_t *)abstract_device; - - if (abstract_device == NULL) - return _cairo_surface_create_in_error (CAIRO_STATUS_DEVICE_ERROR); - - if (abstract_device->status) - return _cairo_surface_create_in_error (abstract_device->status); - - if (abstract_device->backend->type != CAIRO_DEVICE_TYPE_COGL) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH)); - - return _cairo_cogl_surface_create_full (dev, FALSE, framebuffer, NULL); -} -slim_hidden_def (cairo_cogl_surface_create); - -CoglFramebuffer * -cairo_cogl_surface_get_framebuffer (cairo_surface_t *abstract_surface) -{ - cairo_cogl_surface_t *surface; - - if (abstract_surface->backend != &_cairo_cogl_surface_backend) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return NULL; - } - - surface = (cairo_cogl_surface_t *) abstract_surface; - - return surface->framebuffer; -} -slim_hidden_def (cairo_cogl_surface_get_framebuffer); - -CoglTexture * -cairo_cogl_surface_get_texture (cairo_surface_t *abstract_surface) -{ - cairo_cogl_surface_t *surface; - - if (abstract_surface->backend != &_cairo_cogl_surface_backend) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return NULL; - } - - surface = (cairo_cogl_surface_t *) abstract_surface; - - return surface->texture; -} -slim_hidden_def (cairo_cogl_surface_get_texture); - -static cairo_status_t -_cairo_cogl_device_flush (void *device) -{ - cairo_status_t status; - - status = cairo_device_acquire (device); - if (unlikely (status)) - return status; - - /* XXX: we don't need to flush Cogl here, we just need to flush - * any batching we do of compositing primitives. */ - - cairo_device_release (device); - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_cogl_device_finish (void *device) -{ - cairo_status_t status; - - status = cairo_device_acquire (device); - if (unlikely (status)) - return; - - /* XXX: Drop references to external resources */ - - cairo_device_release (device); -} - -static void -_cairo_cogl_device_destroy (void *device) -{ - cairo_cogl_device_t *dev = device; - - /* FIXME: Free stuff! */ - - g_free (dev); -} - -static const cairo_device_backend_t _cairo_cogl_device_backend = { - CAIRO_DEVICE_TYPE_COGL, - - NULL, /* lock */ - NULL, /* unlock */ - - _cairo_cogl_device_flush, - _cairo_cogl_device_finish, - _cairo_cogl_device_destroy, -}; - -static cairo_bool_t -set_blend (CoglPipeline *pipeline, const char *blend_string) -{ - GError *error = NULL; - if (!cogl_pipeline_set_blend (pipeline, blend_string, &error)) { - g_warning ("Unsupported blend string with current gpu/driver: %s", blend_string); - g_error_free (error); - return FALSE; - } - return TRUE; -} - -static cairo_bool_t -_cairo_cogl_setup_op_state (CoglPipeline *pipeline, cairo_operator_t op) -{ - cairo_bool_t status = FALSE; - - switch ((int)op) - { - case CAIRO_OPERATOR_SOURCE: - status = set_blend (pipeline, "RGBA = ADD (SRC_COLOR, 0)"); - break; - case CAIRO_OPERATOR_OVER: - status = set_blend (pipeline, "RGBA = ADD (SRC_COLOR, DST_COLOR * (1 - SRC_COLOR[A]))"); - break; - case CAIRO_OPERATOR_IN: - status = set_blend (pipeline, "RGBA = ADD (SRC_COLOR * DST_COLOR[A], 0)"); - break; - case CAIRO_OPERATOR_DEST_OVER: - status = set_blend (pipeline, "RGBA = ADD (SRC_COLOR * (1 - DST_COLOR[A]), DST_COLOR)"); - break; - case CAIRO_OPERATOR_DEST_IN: - status = set_blend (pipeline, "RGBA = ADD (0, DST_COLOR * SRC_COLOR[A])"); - break; - case CAIRO_OPERATOR_ADD: - status = set_blend (pipeline, "RGBA = ADD (SRC_COLOR, DST_COLOR)"); - break; - } - - return status; -} - -static void -create_templates_for_op (cairo_cogl_device_t *dev, cairo_operator_t op) -{ - CoglPipeline *base = cogl_pipeline_new (); - CoglPipeline *pipeline; - CoglColor color; - - if (!_cairo_cogl_setup_op_state (base, op)) { - cogl_object_unref (base); - return; - } - - dev->template_pipelines[op][CAIRO_COGL_TEMPLATE_TYPE_SOLID] = base; - - pipeline = cogl_pipeline_copy (base); - cogl_pipeline_set_layer_texture (pipeline, 0, dev->dummy_texture); - dev->template_pipelines[op][CAIRO_COGL_TEMPLATE_TYPE_TEXTURE] = pipeline; - - pipeline = cogl_pipeline_copy (base); - cogl_pipeline_set_layer_combine (pipeline, 1, - "RGBA = MODULATE (PREVIOUS, CONSTANT[A])", - NULL); - cogl_pipeline_set_layer_combine_constant (pipeline, 1, &color); - cogl_pipeline_set_layer_texture (pipeline, 1, dev->dummy_texture); - dev->template_pipelines[op][CAIRO_COGL_TEMPLATE_TYPE_MASK_SOLID] = pipeline; - - pipeline = cogl_pipeline_copy (base); - cogl_pipeline_set_layer_combine (pipeline, 1, - "RGBA = MODULATE (PREVIOUS, TEXTURE[A])", - NULL); - cogl_pipeline_set_layer_texture (pipeline, 1, dev->dummy_texture); - dev->template_pipelines[op][CAIRO_COGL_TEMPLATE_TYPE_MASK_TEXTURE] = pipeline; -} - -cairo_device_t * -cairo_cogl_device_create (CoglContext *cogl_context) -{ - cairo_cogl_device_t *dev = g_new0 (cairo_cogl_device_t, 1); - cairo_status_t status; - - dev->backend_vtable_initialized = FALSE; - - dev->cogl_context = cogl_context; - - dev->dummy_texture = cogl_texture_new_with_size (1, 1, - COGL_TEXTURE_NO_SLICING, - COGL_PIXEL_FORMAT_ANY); - if (!dev->dummy_texture) - goto ERROR; - - memset (dev->template_pipelines, 0, sizeof (dev->template_pipelines)); - create_templates_for_op (dev, CAIRO_OPERATOR_SOURCE); - create_templates_for_op (dev, CAIRO_OPERATOR_OVER); - create_templates_for_op (dev, CAIRO_OPERATOR_IN); - create_templates_for_op (dev, CAIRO_OPERATOR_DEST_OVER); - create_templates_for_op (dev, CAIRO_OPERATOR_DEST_IN); - create_templates_for_op (dev, CAIRO_OPERATOR_ADD); - - status = _cairo_cache_init (&dev->linear_cache, - _cairo_cogl_linear_gradient_equal, - NULL, - (cairo_destroy_func_t) _cairo_cogl_linear_gradient_destroy, - CAIRO_COGL_LINEAR_GRADIENT_CACHE_SIZE); - if (unlikely (status)) - return _cairo_device_create_in_error(status); - - status = _cairo_cache_init (&dev->path_fill_staging_cache, - _cairo_cogl_path_fill_meta_equal, - NULL, - (cairo_destroy_func_t) _cairo_cogl_path_fill_meta_destroy, - 1000); - - status = _cairo_cache_init (&dev->path_stroke_staging_cache, - _cairo_cogl_path_stroke_meta_equal, - NULL, - (cairo_destroy_func_t) _cairo_cogl_path_stroke_meta_destroy, - 1000); - - status = _cairo_cache_init (&dev->path_fill_prim_cache, - _cairo_cogl_path_fill_meta_equal, - NULL, - (cairo_destroy_func_t) _cairo_cogl_path_fill_meta_destroy, - CAIRO_COGL_PATH_META_CACHE_SIZE); - - status = _cairo_cache_init (&dev->path_stroke_prim_cache, - _cairo_cogl_path_stroke_meta_equal, - NULL, - (cairo_destroy_func_t) _cairo_cogl_path_stroke_meta_destroy, - CAIRO_COGL_PATH_META_CACHE_SIZE); - - _cairo_device_init (&dev->base, &_cairo_cogl_device_backend); - return &dev->base; - -ERROR: - g_free (dev); - return _cairo_device_create_in_error (CAIRO_STATUS_DEVICE_ERROR); -} -slim_hidden_def (cairo_cogl_device_create); - -void -cairo_cogl_surface_end_frame (cairo_surface_t *abstract_surface) -{ - cairo_cogl_surface_t *surface = (cairo_cogl_surface_t *)abstract_surface; - cairo_surface_flush (abstract_surface); - - //g_print ("n_clip_update_per_frame = %d\n", surface->n_clip_updates_per_frame); - surface->n_clip_updates_per_frame = 0; -} -slim_hidden_def (cairo_cogl_surface_end_frame); diff --git a/source/libs/cairo/cairo-src/src/cairo-cogl-utils-private.h b/source/libs/cairo/cairo-src/src/cairo-cogl-utils-private.h deleted file mode 100644 index ee77f3034c3c390f76b5b8f3c45c1906f0f981c8..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-cogl-utils-private.h +++ /dev/null @@ -1,54 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2011 Intel Corporation. - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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.og/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. - * - * Contributor(s): - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef CAIRO_COGL_UTILS_PRIVATE_H -#define CAIRO_COGL_UTILS_PRIVATE_H - -#include "cairo-path-fixed-private.h" -#include <cogl/cogl2-experimental.h> - -CoglPath * -_cairo_cogl_util_path_from_cairo (const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - float tolerance); - -int -_cairo_cogl_util_next_p2 (int a); - -#define CAIRO_FIXED_ONE_FLOAT ((float)(1 << CAIRO_FIXED_FRAC_BITS)) - -static inline float -_cairo_cogl_util_fixed_to_float (cairo_fixed_t f) -{ - return ((float) f) / CAIRO_FIXED_ONE_FLOAT; -} - -#endif /* CAIRO_COGL_UTILS_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-cogl-utils.c b/source/libs/cairo/cairo-src/src/cairo-cogl-utils.c deleted file mode 100644 index 4f02aaa52dad1fded1aea9875a080087ea6c5e16..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-cogl-utils.c +++ /dev/null @@ -1,126 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2011 Intel Corporation. - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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.og/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. - * - * Contributor(s): - * Robert Bragg <robert@linux.intel.com> - */ - -#include "cairoint.h" -#include "cairo-cogl-utils-private.h" - -#include <cogl/cogl.h> -#include <glib.h> - -static cairo_status_t -_cogl_move_to (void *closure, - const cairo_point_t *point) -{ - cogl_path_move_to (closure, - _cairo_cogl_util_fixed_to_float (point->x), - _cairo_cogl_util_fixed_to_float (point->y)); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cogl_line_to (void *closure, - const cairo_point_t *point) -{ - cogl_path_line_to (closure, - _cairo_cogl_util_fixed_to_float (point->x), - _cairo_cogl_util_fixed_to_float (point->y)); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cogl_curve_to (void *closure, - const cairo_point_t *p0, - const cairo_point_t *p1, - const cairo_point_t *p2) -{ - cogl_path_curve_to (closure, - _cairo_cogl_util_fixed_to_float (p0->x), - _cairo_cogl_util_fixed_to_float (p0->y), - _cairo_cogl_util_fixed_to_float (p1->x), - _cairo_cogl_util_fixed_to_float (p1->y), - _cairo_cogl_util_fixed_to_float (p2->x), - _cairo_cogl_util_fixed_to_float (p2->y)); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cogl_close_path (void *closure) -{ - cogl_path_close (closure); - return CAIRO_STATUS_SUCCESS; -} - -CoglPath * -_cairo_cogl_util_path_from_cairo (const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - float tolerance) -{ - CoglPath *cogl_path = cogl_path_new (); - cairo_status_t status; - - if (fill_rule == CAIRO_FILL_RULE_EVEN_ODD) - cogl_path_set_fill_rule (cogl_path, COGL_PATH_FILL_RULE_EVEN_ODD); - else - cogl_path_set_fill_rule (cogl_path, COGL_PATH_FILL_RULE_NON_ZERO); - -#ifdef USE_CAIRO_PATH_FLATTENER - /* XXX: rely on cairo to do path flattening, since it seems Cogl's - * curve_to flattening is much slower */ - status = _cairo_path_fixed_interpret_flat (path, - _cogl_move_to, - _cogl_line_to, - _cogl_close_path, - cogl_path, - tolerance); -#else - status = _cairo_path_fixed_interpret (path, - _cogl_move_to, - _cogl_line_to, - _cogl_curve_to, - _cogl_close_path, - cogl_path); -#endif - - assert (status == CAIRO_STATUS_SUCCESS); - return cogl_path; -} - -int -_cairo_cogl_util_next_p2 (int a) -{ - int rval = 1; - - while (rval < a) - rval <<= 1; - - return rval; -} - diff --git a/source/libs/cairo/cairo-src/src/cairo-cogl.h b/source/libs/cairo/cairo-src/src/cairo-cogl.h deleted file mode 100644 index f270d74d307eb2b73cdcd215570bd0a28a90db85..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-cogl.h +++ /dev/null @@ -1,69 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2011 Intel Corporation. - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Mozilla Corporation. - * - * Contributor(s): - * Robert Bragg <robert@linux.intel.com> - */ - -#ifndef CAIRO_VG_H -#define CAIRO_VG_H - -#include "cairo.h" - -#if CAIRO_HAS_COGL_SURFACE - -#include <cogl/cogl2-experimental.h> - -CAIRO_BEGIN_DECLS - -cairo_public cairo_device_t * -cairo_cogl_device_create (CoglContext *context); - -cairo_public cairo_surface_t * -cairo_cogl_surface_create (cairo_device_t *device, - CoglFramebuffer *framebuffer); - -cairo_public CoglFramebuffer * -cairo_cogl_surface_get_framebuffer (cairo_surface_t *surface); - -cairo_public CoglTexture * -cairo_cogl_surface_get_texture (cairo_surface_t *surface); - -cairo_public void -cairo_cogl_surface_end_frame (cairo_surface_t *surface); - -CAIRO_END_DECLS - -#else /* CAIRO_HAS_COGL_SURFACE*/ -# error Cairo was not compiled with support for the Cogl backend -#endif /* CAIRO_HAS_COGL_SURFACE*/ - -#endif /* CAIRO_COGL_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-color.c b/source/libs/cairo/cairo-src/src/cairo-color.c deleted file mode 100644 index c2a11a177380dac02c01c3a28b2accff9c27dbc8..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-color.c +++ /dev/null @@ -1,193 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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" - -static cairo_color_t const cairo_color_white = { - 1.0, 1.0, 1.0, 1.0, - 0xffff, 0xffff, 0xffff, 0xffff -}; - -static cairo_color_t const cairo_color_black = { - 0.0, 0.0, 0.0, 1.0, - 0x0, 0x0, 0x0, 0xffff -}; - -static cairo_color_t const cairo_color_transparent = { - 0.0, 0.0, 0.0, 0.0, - 0x0, 0x0, 0x0, 0x0 -}; - -static cairo_color_t const cairo_color_magenta = { - 1.0, 0.0, 1.0, 1.0, - 0xffff, 0x0, 0xffff, 0xffff -}; - -const cairo_color_t * -_cairo_stock_color (cairo_stock_t stock) -{ - switch (stock) { - case CAIRO_STOCK_WHITE: - return &cairo_color_white; - case CAIRO_STOCK_BLACK: - return &cairo_color_black; - case CAIRO_STOCK_TRANSPARENT: - return &cairo_color_transparent; - - case CAIRO_STOCK_NUM_COLORS: - default: - ASSERT_NOT_REACHED; - /* If the user can get here somehow, give a color that indicates a - * problem. */ - return &cairo_color_magenta; - } -} - -/* Convert a double in [0.0, 1.0] to an integer in [0, 65535] - * The conversion is designed to choose the integer i such that - * i / 65535.0 is as close as possible to the input value. - */ -uint16_t -_cairo_color_double_to_short (double d) -{ - return d * 65535.0 + 0.5; -} - -static void -_cairo_color_compute_shorts (cairo_color_t *color) -{ - color->red_short = _cairo_color_double_to_short (color->red * color->alpha); - color->green_short = _cairo_color_double_to_short (color->green * color->alpha); - color->blue_short = _cairo_color_double_to_short (color->blue * color->alpha); - color->alpha_short = _cairo_color_double_to_short (color->alpha); -} - -void -_cairo_color_init_rgba (cairo_color_t *color, - double red, double green, double blue, - double alpha) -{ - color->red = red; - color->green = green; - color->blue = blue; - color->alpha = alpha; - - _cairo_color_compute_shorts (color); -} - -void -_cairo_color_multiply_alpha (cairo_color_t *color, - double alpha) -{ - color->alpha *= alpha; - - _cairo_color_compute_shorts (color); -} - -void -_cairo_color_get_rgba (cairo_color_t *color, - double *red, - double *green, - double *blue, - double *alpha) -{ - *red = color->red; - *green = color->green; - *blue = color->blue; - *alpha = color->alpha; -} - -void -_cairo_color_get_rgba_premultiplied (cairo_color_t *color, - double *red, - double *green, - double *blue, - double *alpha) -{ - *red = color->red * color->alpha; - *green = color->green * color->alpha; - *blue = color->blue * color->alpha; - *alpha = color->alpha; -} - -/* NB: This function works both for unmultiplied and premultiplied colors */ -cairo_bool_t -_cairo_color_equal (const cairo_color_t *color_a, - const cairo_color_t *color_b) -{ - if (color_a == color_b) - return TRUE; - - if (color_a->alpha_short != color_b->alpha_short) - return FALSE; - - if (color_a->alpha_short == 0) - return TRUE; - - return color_a->red_short == color_b->red_short && - color_a->green_short == color_b->green_short && - color_a->blue_short == color_b->blue_short; -} - -cairo_bool_t -_cairo_color_stop_equal (const cairo_color_stop_t *color_a, - const cairo_color_stop_t *color_b) -{ - if (color_a == color_b) - return TRUE; - - return color_a->alpha_short == color_b->alpha_short && - color_a->red_short == color_b->red_short && - color_a->green_short == color_b->green_short && - color_a->blue_short == color_b->blue_short; -} - -cairo_content_t -_cairo_color_get_content (const cairo_color_t *color) -{ - if (CAIRO_COLOR_IS_OPAQUE (color)) - return CAIRO_CONTENT_COLOR; - - if (color->red_short == 0 && - color->green_short == 0 && - color->blue_short == 0) - { - return CAIRO_CONTENT_ALPHA; - } - - return CAIRO_CONTENT_COLOR_ALPHA; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-combsort-inline.h b/source/libs/cairo/cairo-src/src/cairo-combsort-inline.h deleted file mode 100644 index d359faeb5b865c3e14bbe466c6a869d428bc0142..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-combsort-inline.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright © 2008 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Chris Wilson - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -/* This fragment implements a comb sort (specifically combsort11) */ -#ifndef _HAVE_CAIRO_COMBSORT_NEWGAP -#define _HAVE_CAIRO_COMBSORT_NEWGAP -static inline unsigned int -_cairo_combsort_newgap (unsigned int gap) -{ - gap = 10 * gap / 13; - if (gap == 9 || gap == 10) - gap = 11; - if (gap < 1) - gap = 1; - return gap; -} -#endif - -#define CAIRO_COMBSORT_DECLARE(NAME, TYPE, CMP) \ -static void \ -NAME (TYPE *base, unsigned int nmemb) \ -{ \ - unsigned int gap = nmemb; \ - unsigned int i, j; \ - int swapped; \ - do { \ - gap = _cairo_combsort_newgap (gap); \ - swapped = gap > 1; \ - for (i = 0; i < nmemb-gap ; i++) { \ - j = i + gap; \ - if (CMP (base[i], base[j]) > 0 ) { \ - TYPE tmp; \ - tmp = base[i]; \ - base[i] = base[j]; \ - base[j] = tmp; \ - swapped = 1; \ - } \ - } \ - } while (swapped); \ -} - -#define CAIRO_COMBSORT_DECLARE_WITH_DATA(NAME, TYPE, CMP) \ -static void \ -NAME (TYPE *base, unsigned int nmemb, void *data) \ -{ \ - unsigned int gap = nmemb; \ - unsigned int i, j; \ - int swapped; \ - do { \ - gap = _cairo_combsort_newgap (gap); \ - swapped = gap > 1; \ - for (i = 0; i < nmemb-gap ; i++) { \ - j = i + gap; \ - if (CMP (base[i], base[j], data) > 0 ) { \ - TYPE tmp; \ - tmp = base[i]; \ - base[i] = base[j]; \ - base[j] = tmp; \ - swapped = 1; \ - } \ - } \ - } while (swapped); \ -} diff --git a/source/libs/cairo/cairo-src/src/cairo-compiler-private.h b/source/libs/cairo/cairo-src/src/cairo-compiler-private.h deleted file mode 100644 index 216e71b4ec35fd514edfdc399c12d7a7f597f8d8..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-compiler-private.h +++ /dev/null @@ -1,244 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - */ - -#ifndef CAIRO_COMPILER_PRIVATE_H -#define CAIRO_COMPILER_PRIVATE_H - -#include "cairo.h" - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -/* Size in bytes of buffer to use off the stack per functions. - * Mostly used by text functions. For larger allocations, they'll - * malloc(). */ -#ifndef CAIRO_STACK_BUFFER_SIZE -#define CAIRO_STACK_BUFFER_SIZE (512 * sizeof (int)) -#endif - -#define CAIRO_STACK_ARRAY_LENGTH(T) (CAIRO_STACK_BUFFER_SIZE / sizeof(T)) - -/* - * The goal of this block is to define the following macros for - * providing faster linkage to functions in the public API for calls - * from within cairo. - * - * slim_hidden_proto(f) - * slim_hidden_proto_no_warn(f) - * - * Declares `f' as a library internal function and hides the - * function from the global symbol table. This macro must be - * expanded after `f' has been declared with a prototype but before - * any calls to the function are seen by the compiler. The no_warn - * variant inhibits warnings about the return value being unused at - * call sites. The macro works by renaming `f' to an internal name - * in the symbol table and hiding that. As far as cairo internal - * calls are concerned they're calling a library internal function - * and thus don't need to bounce via the PLT. - * - * slim_hidden_def(f) - * - * Exports `f' back to the global symbol table. This macro must be - * expanded right after the function definition and only for symbols - * hidden previously with slim_hidden_proto(). The macro works by - * adding a global entry to the symbol table which points at the - * internal name of `f' created by slim_hidden_proto(). - * - * Functions in the public API which aren't called by the library - * don't need to be hidden and re-exported using the slim hidden - * macros. - */ -#if __GNUC__ >= 3 && defined(__ELF__) && !defined(__sun) -# define slim_hidden_proto(name) slim_hidden_proto1(name, slim_hidden_int_name(name)) cairo_private -# define slim_hidden_proto_no_warn(name) slim_hidden_proto1(name, slim_hidden_int_name(name)) cairo_private_no_warn -# define slim_hidden_def(name) slim_hidden_def1(name, slim_hidden_int_name(name)) -# define slim_hidden_int_name(name) INT_##name -# define slim_hidden_proto1(name, internal) \ - extern __typeof (name) name \ - __asm__ (slim_hidden_asmname (internal)) -# define slim_hidden_def1(name, internal) \ - extern __typeof (name) EXT_##name __asm__(slim_hidden_asmname(name)) \ - __attribute__((__alias__(slim_hidden_asmname(internal)))) -# define slim_hidden_ulp slim_hidden_ulp1(__USER_LABEL_PREFIX__) -# define slim_hidden_ulp1(x) slim_hidden_ulp2(x) -# define slim_hidden_ulp2(x) #x -# define slim_hidden_asmname(name) slim_hidden_asmname1(name) -# define slim_hidden_asmname1(name) slim_hidden_ulp #name -#else -# define slim_hidden_proto(name) int _cairo_dummy_prototype(void) -# define slim_hidden_proto_no_warn(name) int _cairo_dummy_prototype(void) -# define slim_hidden_def(name) int _cairo_dummy_prototype(void) -#endif - -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) -#define CAIRO_PRINTF_FORMAT(fmt_index, va_index) \ - __attribute__((__format__(__printf__, fmt_index, va_index))) -#else -#define CAIRO_PRINTF_FORMAT(fmt_index, va_index) -#endif - -/* slim_internal.h */ -#define CAIRO_HAS_HIDDEN_SYMBOLS 1 -#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && \ - (defined(__ELF__) || defined(__APPLE__)) && \ - !defined(__sun) -#define cairo_private_no_warn __attribute__((__visibility__("hidden"))) -#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) -#define cairo_private_no_warn __hidden -#else /* not gcc >= 3.3 and not Sun Studio >= 8 */ -#define cairo_private_no_warn -#undef CAIRO_HAS_HIDDEN_SYMBOLS -#endif - -#ifndef WARN_UNUSED_RESULT -#define WARN_UNUSED_RESULT -#endif -/* Add attribute(warn_unused_result) if supported */ -#define cairo_warn WARN_UNUSED_RESULT -#define cairo_private cairo_private_no_warn cairo_warn - -/* This macro allow us to deprecate a function by providing an alias - for the old function name to the new function name. With this - macro, binary compatibility is preserved. The macro only works on - some platforms --- tough. - - Meanwhile, new definitions in the public header file break the - source code so that it will no longer link against the old - symbols. Instead it will give a descriptive error message - indicating that the old function has been deprecated by the new - function. -*/ -#if __GNUC__ >= 2 && defined(__ELF__) -# define CAIRO_FUNCTION_ALIAS(old, new) \ - extern __typeof (new) old \ - __asm__ ("" #old) \ - __attribute__((__alias__("" #new))) -#else -# define CAIRO_FUNCTION_ALIAS(old, new) -#endif - -/* - * Cairo uses the following function attributes in order to improve the - * generated code (effectively by manual inter-procedural analysis). - * - * 'cairo_pure': The function is only allowed to read from its arguments - * and global memory (i.e. following a pointer argument or - * accessing a shared variable). The return value should - * only depend on its arguments, and for an identical set of - * arguments should return the same value. - * - * 'cairo_const': The function is only allowed to read from its arguments. - * It is not allowed to access global memory. The return - * value should only depend its arguments, and for an - * identical set of arguments should return the same value. - * This is currently the most strict function attribute. - * - * Both these function attributes allow gcc to perform CSE and - * constant-folding, with 'cairo_const 'also guaranteeing that pointer contents - * do not change across the function call. - */ -#if __GNUC__ >= 3 -#define cairo_pure __attribute__((pure)) -#define cairo_const __attribute__((const)) -#define cairo_always_inline inline __attribute__((always_inline)) -#else -#define cairo_pure -#define cairo_const -#define cairo_always_inline inline -#endif - -#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) -#define likely(expr) (__builtin_expect (!!(expr), 1)) -#define unlikely(expr) (__builtin_expect (!!(expr), 0)) -#else -#define likely(expr) (expr) -#define unlikely(expr) (expr) -#endif - -#ifndef __GNUC__ -#undef __attribute__ -#define __attribute__(x) -#endif - -#if (defined(__WIN32__) && !defined(__WINE__)) || defined(_MSC_VER) -#define access _access -#define fdopen _fdopen -#define hypot _hypot -#define pclose _pclose -#define popen _popen -#define snprintf _snprintf -#define strdup _strdup -#define unlink _unlink -#define vsnprintf _vsnprintf -#endif - -#ifdef _MSC_VER -#ifndef __cplusplus -#undef inline -#define inline __inline -#endif -#endif - -#if defined(_MSC_VER) && defined(_M_IX86) -/* When compiling with /Gy and /OPT:ICF identical functions will be folded in together. - The CAIRO_ENSURE_UNIQUE macro ensures that a function is always unique and - will never be folded into another one. Something like this might eventually - be needed for GCC but it seems fine for now. */ -#define CAIRO_ENSURE_UNIQUE \ - do { \ - char file[] = __FILE__; \ - __asm { \ - __asm jmp __internal_skip_line_no \ - __asm _emit (__COUNTER__ & 0xff) \ - __asm _emit ((__COUNTER__>>8) & 0xff) \ - __asm _emit ((__COUNTER__>>16) & 0xff)\ - __asm _emit ((__COUNTER__>>24) & 0xff)\ - __asm lea eax, dword ptr file \ - __asm __internal_skip_line_no: \ - }; \ - } while (0) -#else -#define CAIRO_ENSURE_UNIQUE do { } while (0) -#endif - -#ifdef __STRICT_ANSI__ -#undef inline -#define inline __inline__ -#endif - -#endif diff --git a/source/libs/cairo/cairo-src/src/cairo-composite-rectangles-private.h b/source/libs/cairo/cairo-src/src/cairo-composite-rectangles-private.h deleted file mode 100644 index fd7728995de50baa0b00a53c4d693c4a2fea1f99..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-composite-rectangles-private.h +++ /dev/null @@ -1,159 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.u> - */ - -#ifndef CAIRO_COMPOSITE_RECTANGLES_PRIVATE_H -#define CAIRO_COMPOSITE_RECTANGLES_PRIVATE_H - -#include "cairo-types-private.h" -#include "cairo-error-private.h" -#include "cairo-pattern-private.h" - -CAIRO_BEGIN_DECLS - -/* Rectangles that take part in a composite operation. - * - * The source and mask track the extents of the respective patterns in device - * space. The unbounded rectangle is essentially the clip rectangle. And the - * intersection of all is the bounded rectangle, which is the minimum extents - * the operation may require. Whether or not the operation is actually bounded - * is tracked in the is_bounded boolean. - * - */ -struct _cairo_composite_rectangles { - cairo_surface_t *surface; - cairo_operator_t op; - - cairo_rectangle_int_t source; - cairo_rectangle_int_t mask; - cairo_rectangle_int_t destination; - - cairo_rectangle_int_t bounded; /* source? IN mask? IN unbounded */ - cairo_rectangle_int_t unbounded; /* destination IN clip */ - uint32_t is_bounded; - - cairo_rectangle_int_t source_sample_area; - cairo_rectangle_int_t mask_sample_area; - - cairo_pattern_union_t source_pattern; - cairo_pattern_union_t mask_pattern; - const cairo_pattern_t *original_source_pattern; - const cairo_pattern_t *original_mask_pattern; - - cairo_clip_t *clip; /* clip will be reduced to the minimal container */ -}; - -cairo_private cairo_int_status_t -_cairo_composite_rectangles_init_for_paint (cairo_composite_rectangles_t *extents, - cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip); - -cairo_private cairo_int_status_t -_cairo_composite_rectangles_init_for_mask (cairo_composite_rectangles_t *extents, - cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip); - -cairo_private cairo_int_status_t -_cairo_composite_rectangles_init_for_stroke (cairo_composite_rectangles_t *extents, - cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_clip_t *clip); - -cairo_private cairo_int_status_t -_cairo_composite_rectangles_init_for_fill (cairo_composite_rectangles_t *extents, - cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_clip_t *clip); - -cairo_private cairo_int_status_t -_cairo_composite_rectangles_init_for_boxes (cairo_composite_rectangles_t *extents, - cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_boxes_t *boxes, - const cairo_clip_t *clip); - -cairo_private cairo_int_status_t -_cairo_composite_rectangles_init_for_polygon (cairo_composite_rectangles_t *extents, - cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_polygon_t *polygon, - const cairo_clip_t *clip); - -cairo_private cairo_int_status_t -_cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *extents, - cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int num_glyphs, - const cairo_clip_t *clip, - cairo_bool_t *overlap); - -cairo_private cairo_int_status_t -_cairo_composite_rectangles_intersect_source_extents (cairo_composite_rectangles_t *extents, - const cairo_box_t *box); - -cairo_private cairo_int_status_t -_cairo_composite_rectangles_intersect_mask_extents (cairo_composite_rectangles_t *extents, - const cairo_box_t *box); - -cairo_private cairo_bool_t -_cairo_composite_rectangles_can_reduce_clip (cairo_composite_rectangles_t *composite, - cairo_clip_t *clip); - -cairo_private cairo_int_status_t -_cairo_composite_rectangles_add_to_damage (cairo_composite_rectangles_t *composite, - cairo_boxes_t *damage); - -cairo_private void -_cairo_composite_rectangles_fini (cairo_composite_rectangles_t *extents); - -CAIRO_END_DECLS - -#endif /* CAIRO_COMPOSITE_RECTANGLES_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-composite-rectangles.c b/source/libs/cairo/cairo-src/src/cairo-composite-rectangles.c deleted file mode 100644 index 6c3e97d4a9700dff3c46e6177b961be85aea7a1b..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-composite-rectangles.c +++ /dev/null @@ -1,500 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-clip-inline.h" -#include "cairo-error-private.h" -#include "cairo-composite-rectangles-private.h" -#include "cairo-pattern-private.h" - -/* A collection of routines to facilitate writing compositors. */ - -void _cairo_composite_rectangles_fini (cairo_composite_rectangles_t *extents) -{ - _cairo_clip_destroy (extents->clip); -} - -static void -_cairo_composite_reduce_pattern (const cairo_pattern_t *src, - cairo_pattern_union_t *dst) -{ - int tx, ty; - - _cairo_pattern_init_static_copy (&dst->base, src); - if (dst->base.type == CAIRO_PATTERN_TYPE_SOLID) - return; - - dst->base.filter = _cairo_pattern_analyze_filter (&dst->base); - - tx = ty = 0; - if (_cairo_matrix_is_pixman_translation (&dst->base.matrix, - dst->base.filter, - &tx, &ty)) - { - dst->base.matrix.x0 = tx; - dst->base.matrix.y0 = ty; - } -} - -static inline cairo_bool_t -_cairo_composite_rectangles_init (cairo_composite_rectangles_t *extents, - cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - if (_cairo_clip_is_all_clipped (clip)) - return FALSE; - - extents->surface = surface; - extents->op = op; - - _cairo_surface_get_extents (surface, &extents->destination); - extents->clip = NULL; - - extents->unbounded = extents->destination; - if (clip && ! _cairo_rectangle_intersect (&extents->unbounded, - _cairo_clip_get_extents (clip))) - return FALSE; - - extents->bounded = extents->unbounded; - extents->is_bounded = _cairo_operator_bounded_by_either (op); - - extents->original_source_pattern = source; - _cairo_composite_reduce_pattern (source, &extents->source_pattern); - - _cairo_pattern_get_extents (&extents->source_pattern.base, - &extents->source); - if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_SOURCE) { - if (! _cairo_rectangle_intersect (&extents->bounded, &extents->source)) - return FALSE; - } - - extents->original_mask_pattern = NULL; - extents->mask_pattern.base.type = CAIRO_PATTERN_TYPE_SOLID; - extents->mask_pattern.solid.color.alpha = 1.; /* XXX full initialisation? */ - extents->mask_pattern.solid.color.alpha_short = 0xffff; - - return TRUE; -} - -cairo_int_status_t -_cairo_composite_rectangles_init_for_paint (cairo_composite_rectangles_t *extents, - cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - if (! _cairo_composite_rectangles_init (extents, - surface, op, source, clip)) - { - return CAIRO_INT_STATUS_NOTHING_TO_DO; - } - - extents->mask = extents->destination; - - extents->clip = _cairo_clip_reduce_for_composite (clip, extents); - if (_cairo_clip_is_all_clipped (extents->clip)) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - if (! _cairo_rectangle_intersect (&extents->unbounded, - _cairo_clip_get_extents (extents->clip))) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) - _cairo_pattern_sampled_area (&extents->source_pattern.base, - &extents->bounded, - &extents->source_sample_area); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_composite_rectangles_intersect (cairo_composite_rectangles_t *extents, - const cairo_clip_t *clip) -{ - cairo_bool_t ret; - - ret = _cairo_rectangle_intersect (&extents->bounded, &extents->mask); - if (! ret && extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - if (extents->is_bounded == (CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE)) { - extents->unbounded = extents->bounded; - } else if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) { - if (!_cairo_rectangle_intersect (&extents->unbounded, &extents->mask)) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - } - - extents->clip = _cairo_clip_reduce_for_composite (clip, extents); - if (_cairo_clip_is_all_clipped (extents->clip)) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - if (! _cairo_rectangle_intersect (&extents->unbounded, - _cairo_clip_get_extents (extents->clip))) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - if (! _cairo_rectangle_intersect (&extents->bounded, - _cairo_clip_get_extents (extents->clip)) && - extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) - { - return CAIRO_INT_STATUS_NOTHING_TO_DO; - } - - if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) - _cairo_pattern_sampled_area (&extents->source_pattern.base, - &extents->bounded, - &extents->source_sample_area); - if (extents->mask_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) { - _cairo_pattern_sampled_area (&extents->mask_pattern.base, - &extents->bounded, - &extents->mask_sample_area); - if (extents->mask_sample_area.width == 0 || - extents->mask_sample_area.height == 0) { - _cairo_composite_rectangles_fini (extents); - return CAIRO_INT_STATUS_NOTHING_TO_DO; - } - } - - return CAIRO_STATUS_SUCCESS; -} - -cairo_int_status_t -_cairo_composite_rectangles_intersect_source_extents (cairo_composite_rectangles_t *extents, - const cairo_box_t *box) -{ - cairo_rectangle_int_t rect; - cairo_clip_t *clip; - - _cairo_box_round_to_rectangle (box, &rect); - if (rect.x == extents->source.x && - rect.y == extents->source.y && - rect.width == extents->source.width && - rect.height == extents->source.height) - { - return CAIRO_INT_STATUS_SUCCESS; - } - - _cairo_rectangle_intersect (&extents->source, &rect); - - rect = extents->bounded; - if (! _cairo_rectangle_intersect (&extents->bounded, &extents->source) && - extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_SOURCE) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - if (rect.width == extents->bounded.width && - rect.height == extents->bounded.height) - return CAIRO_INT_STATUS_SUCCESS; - - if (extents->is_bounded == (CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE)) { - extents->unbounded = extents->bounded; - } else if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) { - if (!_cairo_rectangle_intersect (&extents->unbounded, &extents->mask)) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - } - - clip = extents->clip; - extents->clip = _cairo_clip_reduce_for_composite (clip, extents); - if (clip != extents->clip) - _cairo_clip_destroy (clip); - - if (_cairo_clip_is_all_clipped (extents->clip)) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - if (! _cairo_rectangle_intersect (&extents->unbounded, - _cairo_clip_get_extents (extents->clip))) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) - _cairo_pattern_sampled_area (&extents->source_pattern.base, - &extents->bounded, - &extents->source_sample_area); - if (extents->mask_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) { - _cairo_pattern_sampled_area (&extents->mask_pattern.base, - &extents->bounded, - &extents->mask_sample_area); - if (extents->mask_sample_area.width == 0 || - extents->mask_sample_area.height == 0) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - } - - return CAIRO_INT_STATUS_SUCCESS; -} - -cairo_int_status_t -_cairo_composite_rectangles_intersect_mask_extents (cairo_composite_rectangles_t *extents, - const cairo_box_t *box) -{ - cairo_rectangle_int_t mask; - cairo_clip_t *clip; - - _cairo_box_round_to_rectangle (box, &mask); - if (mask.x == extents->mask.x && - mask.y == extents->mask.y && - mask.width == extents->mask.width && - mask.height == extents->mask.height) - { - return CAIRO_INT_STATUS_SUCCESS; - } - - _cairo_rectangle_intersect (&extents->mask, &mask); - - mask = extents->bounded; - if (! _cairo_rectangle_intersect (&extents->bounded, &extents->mask) && - extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - if (mask.width == extents->bounded.width && - mask.height == extents->bounded.height) - return CAIRO_INT_STATUS_SUCCESS; - - if (extents->is_bounded == (CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE)) { - extents->unbounded = extents->bounded; - } else if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) { - if (!_cairo_rectangle_intersect (&extents->unbounded, &extents->mask)) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - } - - clip = extents->clip; - extents->clip = _cairo_clip_reduce_for_composite (clip, extents); - if (clip != extents->clip) - _cairo_clip_destroy (clip); - - if (_cairo_clip_is_all_clipped (extents->clip)) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - if (! _cairo_rectangle_intersect (&extents->unbounded, - _cairo_clip_get_extents (extents->clip))) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) - _cairo_pattern_sampled_area (&extents->source_pattern.base, - &extents->bounded, - &extents->source_sample_area); - if (extents->mask_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) { - _cairo_pattern_sampled_area (&extents->mask_pattern.base, - &extents->bounded, - &extents->mask_sample_area); - if (extents->mask_sample_area.width == 0 || - extents->mask_sample_area.height == 0) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - } - - return CAIRO_INT_STATUS_SUCCESS; -} - -cairo_int_status_t -_cairo_composite_rectangles_init_for_mask (cairo_composite_rectangles_t *extents, - cairo_surface_t*surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - if (! _cairo_composite_rectangles_init (extents, - surface, op, source, clip)) - { - return CAIRO_INT_STATUS_NOTHING_TO_DO; - } - - extents->original_mask_pattern = mask; - _cairo_composite_reduce_pattern (mask, &extents->mask_pattern); - _cairo_pattern_get_extents (&extents->mask_pattern.base, &extents->mask); - - return _cairo_composite_rectangles_intersect (extents, clip); -} - -cairo_int_status_t -_cairo_composite_rectangles_init_for_stroke (cairo_composite_rectangles_t *extents, - cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_clip_t *clip) -{ - if (! _cairo_composite_rectangles_init (extents, - surface, op, source, clip)) - { - return CAIRO_INT_STATUS_NOTHING_TO_DO; - } - - _cairo_path_fixed_approximate_stroke_extents (path, style, ctm, &extents->mask); - - return _cairo_composite_rectangles_intersect (extents, clip); -} - -cairo_int_status_t -_cairo_composite_rectangles_init_for_fill (cairo_composite_rectangles_t *extents, - cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_clip_t *clip) -{ - if (! _cairo_composite_rectangles_init (extents, - surface, op, source, clip)) - { - return CAIRO_INT_STATUS_NOTHING_TO_DO; - } - - _cairo_path_fixed_approximate_fill_extents (path, &extents->mask); - - return _cairo_composite_rectangles_intersect (extents, clip); -} - -cairo_int_status_t -_cairo_composite_rectangles_init_for_polygon (cairo_composite_rectangles_t *extents, - cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_polygon_t *polygon, - const cairo_clip_t *clip) -{ - if (! _cairo_composite_rectangles_init (extents, - surface, op, source, clip)) - { - return CAIRO_INT_STATUS_NOTHING_TO_DO; - } - - _cairo_box_round_to_rectangle (&polygon->extents, &extents->mask); - return _cairo_composite_rectangles_intersect (extents, clip); -} - -cairo_int_status_t -_cairo_composite_rectangles_init_for_boxes (cairo_composite_rectangles_t *extents, - cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_boxes_t *boxes, - const cairo_clip_t *clip) -{ - cairo_box_t box; - - if (! _cairo_composite_rectangles_init (extents, - surface, op, source, clip)) - { - return CAIRO_INT_STATUS_NOTHING_TO_DO; - } - - _cairo_boxes_extents (boxes, &box); - _cairo_box_round_to_rectangle (&box, &extents->mask); - return _cairo_composite_rectangles_intersect (extents, clip); -} - -cairo_int_status_t -_cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *extents, - cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int num_glyphs, - const cairo_clip_t *clip, - cairo_bool_t *overlap) -{ - cairo_status_t status; - - if (! _cairo_composite_rectangles_init (extents, surface, op, source, clip)) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - /* Computing the exact bbox and the overlap is expensive. - * First perform a cheap test to see if the glyphs are all clipped out. - */ - if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK && - _cairo_scaled_font_glyph_approximate_extents (scaled_font, - glyphs, num_glyphs, - &extents->mask)) - { - if (! _cairo_rectangle_intersect (&extents->bounded, &extents->mask)) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - } - - status = _cairo_scaled_font_glyph_device_extents (scaled_font, - glyphs, num_glyphs, - &extents->mask, - overlap); - if (unlikely (status)) - return status; - - if (overlap && *overlap && - scaled_font->options.antialias == CAIRO_ANTIALIAS_NONE && - _cairo_pattern_is_opaque_solid (&extents->source_pattern.base)) - { - *overlap = FALSE; - } - - return _cairo_composite_rectangles_intersect (extents, clip); -} - -cairo_bool_t -_cairo_composite_rectangles_can_reduce_clip (cairo_composite_rectangles_t *composite, - cairo_clip_t *clip) -{ - cairo_rectangle_int_t extents; - cairo_box_t box; - - if (clip == NULL) - return TRUE; - - extents = composite->destination; - if (composite->is_bounded & CAIRO_OPERATOR_BOUND_BY_SOURCE) - _cairo_rectangle_intersect (&extents, &composite->source); - if (composite->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) - _cairo_rectangle_intersect (&extents, &composite->mask); - - _cairo_box_from_rectangle (&box, &extents); - return _cairo_clip_contains_box (clip, &box); -} - -cairo_int_status_t -_cairo_composite_rectangles_add_to_damage (cairo_composite_rectangles_t *composite, - cairo_boxes_t *damage) -{ - cairo_int_status_t status; - int n; - - for (n = 0; n < composite->clip->num_boxes; n++) { - status = _cairo_boxes_add (damage, - CAIRO_ANTIALIAS_NONE, - &composite->clip->boxes[n]); - if (unlikely (status)) - return status; - } - - return CAIRO_INT_STATUS_SUCCESS; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-compositor-private.h b/source/libs/cairo/cairo-src/src/cairo-compositor-private.h deleted file mode 100644 index 019972333f34e2a40d81cbfe4f23253a2dc7abbc..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-compositor-private.h +++ /dev/null @@ -1,365 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_COMPOSITOR_PRIVATE_H -#define CAIRO_COMPOSITOR_PRIVATE_H - -#include "cairo-composite-rectangles-private.h" - -CAIRO_BEGIN_DECLS - -typedef struct { - cairo_scaled_font_t *font; - cairo_glyph_t *glyphs; - int num_glyphs; - cairo_bool_t use_mask; - cairo_rectangle_int_t extents; -} cairo_composite_glyphs_info_t; - -struct cairo_compositor { - const cairo_compositor_t *delegate; - - cairo_warn cairo_int_status_t - (*paint) (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *extents); - - cairo_warn cairo_int_status_t - (*mask) (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *extents); - - cairo_warn cairo_int_status_t - (*stroke) (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias); - - cairo_warn cairo_int_status_t - (*fill) (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias); - - cairo_warn cairo_int_status_t - (*glyphs) (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_bool_t overlap); -}; - -struct cairo_mask_compositor { - cairo_compositor_t base; - - cairo_int_status_t (*acquire) (void *surface); - cairo_int_status_t (*release) (void *surface); - - cairo_int_status_t (*set_clip_region) (void *surface, - cairo_region_t *clip_region); - - cairo_surface_t * (*pattern_to_surface) (cairo_surface_t *dst, - const cairo_pattern_t *pattern, - cairo_bool_t is_mask, - const cairo_rectangle_int_t *extents, - const cairo_rectangle_int_t *sample, - int *src_x, int *src_y); - - cairo_int_status_t (*draw_image_boxes) (void *surface, - cairo_image_surface_t *image, - cairo_boxes_t *boxes, - int dx, int dy); - - cairo_int_status_t (*copy_boxes) (void *surface, - cairo_surface_t *src, - cairo_boxes_t *boxes, - const cairo_rectangle_int_t *extents, - int dx, int dy); - - cairo_int_status_t - (*fill_rectangles) (void *surface, - cairo_operator_t op, - const cairo_color_t *color, - cairo_rectangle_int_t *rectangles, - int num_rects); - - cairo_int_status_t - (*fill_boxes) (void *surface, - cairo_operator_t op, - const cairo_color_t *color, - cairo_boxes_t *boxes); - - cairo_int_status_t - (*check_composite) (const cairo_composite_rectangles_t *extents); - - cairo_int_status_t - (*composite) (void *dst, - cairo_operator_t op, - cairo_surface_t *src, - cairo_surface_t *mask, - 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_int_status_t - (*composite_boxes) (void *surface, - cairo_operator_t op, - cairo_surface_t *source, - cairo_surface_t *mask, - int src_x, - int src_y, - int mask_x, - int mask_y, - int dst_x, - int dst_y, - cairo_boxes_t *boxes, - const cairo_rectangle_int_t *extents); - - cairo_int_status_t - (*check_composite_glyphs) (const cairo_composite_rectangles_t *extents, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int *num_glyphs); - cairo_int_status_t - (*composite_glyphs) (void *surface, - cairo_operator_t op, - cairo_surface_t *src, - int src_x, - int src_y, - int dst_x, - int dst_y, - cairo_composite_glyphs_info_t *info); -}; - -struct cairo_traps_compositor { - cairo_compositor_t base; - - cairo_int_status_t - (*acquire) (void *surface); - - cairo_int_status_t - (*release) (void *surface); - - cairo_int_status_t - (*set_clip_region) (void *surface, - cairo_region_t *clip_region); - - cairo_surface_t * - (*pattern_to_surface) (cairo_surface_t *dst, - const cairo_pattern_t *pattern, - cairo_bool_t is_mask, - const cairo_rectangle_int_t *extents, - const cairo_rectangle_int_t *sample, - int *src_x, int *src_y); - - cairo_int_status_t (*draw_image_boxes) (void *surface, - cairo_image_surface_t *image, - cairo_boxes_t *boxes, - int dx, int dy); - - cairo_int_status_t (*copy_boxes) (void *surface, - cairo_surface_t *src, - cairo_boxes_t *boxes, - const cairo_rectangle_int_t *extents, - int dx, int dy); - - cairo_int_status_t - (*fill_boxes) (void *surface, - cairo_operator_t op, - const cairo_color_t *color, - cairo_boxes_t *boxes); - - cairo_int_status_t - (*check_composite) (const cairo_composite_rectangles_t *extents); - - cairo_int_status_t - (*composite) (void *dst, - cairo_operator_t op, - cairo_surface_t *src, - cairo_surface_t *mask, - 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_int_status_t - (*lerp) (void *_dst, - cairo_surface_t *abstract_src, - cairo_surface_t *abstract_mask, - 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_int_status_t - (*composite_boxes) (void *surface, - cairo_operator_t op, - cairo_surface_t *source, - cairo_surface_t *mask, - int src_x, - int src_y, - int mask_x, - int mask_y, - int dst_x, - int dst_y, - cairo_boxes_t *boxes, - const cairo_rectangle_int_t *extents); - - cairo_int_status_t - (*composite_traps) (void *dst, - cairo_operator_t op, - cairo_surface_t *source, - int src_x, - int src_y, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents, - cairo_antialias_t antialias, - cairo_traps_t *traps); - - cairo_int_status_t - (*composite_tristrip) (void *dst, - cairo_operator_t op, - cairo_surface_t *source, - int src_x, - int src_y, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents, - cairo_antialias_t antialias, - cairo_tristrip_t *tristrip); - - cairo_int_status_t - (*check_composite_glyphs) (const cairo_composite_rectangles_t *extents, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int *num_glyphs); - cairo_int_status_t - (*composite_glyphs) (void *surface, - cairo_operator_t op, - cairo_surface_t *src, - int src_x, - int src_y, - int dst_x, - int dst_y, - cairo_composite_glyphs_info_t *info); -}; - -cairo_private extern const cairo_compositor_t __cairo_no_compositor; -cairo_private extern const cairo_compositor_t _cairo_fallback_compositor; - -cairo_private void -_cairo_mask_compositor_init (cairo_mask_compositor_t *compositor, - const cairo_compositor_t *delegate); - -cairo_private void -_cairo_shape_mask_compositor_init (cairo_compositor_t *compositor, - const cairo_compositor_t *delegate); - -cairo_private void -_cairo_traps_compositor_init (cairo_traps_compositor_t *compositor, - const cairo_compositor_t *delegate); - -cairo_private cairo_int_status_t -_cairo_compositor_paint (const cairo_compositor_t *compositor, - cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip); - -cairo_private cairo_int_status_t -_cairo_compositor_mask (const cairo_compositor_t *compositor, - cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip); - -cairo_private cairo_int_status_t -_cairo_compositor_stroke (const cairo_compositor_t *compositor, - cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip); - -cairo_private cairo_int_status_t -_cairo_compositor_fill (const cairo_compositor_t *compositor, - cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip); - -cairo_private cairo_int_status_t -_cairo_compositor_glyphs (const cairo_compositor_t *compositor, - cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip); - -CAIRO_END_DECLS - -#endif /* CAIRO_COMPOSITOR_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-compositor.c b/source/libs/cairo/cairo-src/src/cairo-compositor.c deleted file mode 100644 index b31413b99646145f1692bef2bbc0674a6d811392..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-compositor.c +++ /dev/null @@ -1,268 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-compositor-private.h" -#include "cairo-damage-private.h" -#include "cairo-error-private.h" - -cairo_int_status_t -_cairo_compositor_paint (const cairo_compositor_t *compositor, - cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - cairo_composite_rectangles_t extents; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - status = _cairo_composite_rectangles_init_for_paint (&extents, surface, - op, source, - clip); - if (unlikely (status)) - return status; - - do { - while (compositor->paint == NULL) - compositor = compositor->delegate; - - status = compositor->paint (compositor, &extents); - - compositor = compositor->delegate; - } while (status == CAIRO_INT_STATUS_UNSUPPORTED); - - if (status == CAIRO_INT_STATUS_SUCCESS && surface->damage) { - TRACE ((stderr, "%s: applying damage (%d,%d)x(%d, %d)\n", - __FUNCTION__, - extents.unbounded.x, extents.unbounded.y, - extents.unbounded.width, extents.unbounded.height)); - surface->damage = _cairo_damage_add_rectangle (surface->damage, - &extents.unbounded); - } - - _cairo_composite_rectangles_fini (&extents); - - return status; -} - -cairo_int_status_t -_cairo_compositor_mask (const cairo_compositor_t *compositor, - cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - cairo_composite_rectangles_t extents; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - status = _cairo_composite_rectangles_init_for_mask (&extents, surface, - op, source, mask, - clip); - if (unlikely (status)) - return status; - - do { - while (compositor->mask == NULL) - compositor = compositor->delegate; - - status = compositor->mask (compositor, &extents); - - compositor = compositor->delegate; - } while (status == CAIRO_INT_STATUS_UNSUPPORTED); - - if (status == CAIRO_INT_STATUS_SUCCESS && surface->damage) { - TRACE ((stderr, "%s: applying damage (%d,%d)x(%d, %d)\n", - __FUNCTION__, - extents.unbounded.x, extents.unbounded.y, - extents.unbounded.width, extents.unbounded.height)); - surface->damage = _cairo_damage_add_rectangle (surface->damage, - &extents.unbounded); - } - - _cairo_composite_rectangles_fini (&extents); - - return status; -} - -cairo_int_status_t -_cairo_compositor_stroke (const cairo_compositor_t *compositor, - cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_composite_rectangles_t extents; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - if (_cairo_pen_vertices_needed (tolerance, style->line_width/2, ctm) <= 1) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - status = _cairo_composite_rectangles_init_for_stroke (&extents, surface, - op, source, - path, style, ctm, - clip); - if (unlikely (status)) - return status; - - do { - while (compositor->stroke == NULL) - compositor = compositor->delegate; - - status = compositor->stroke (compositor, &extents, - path, style, ctm, ctm_inverse, - tolerance, antialias); - - compositor = compositor->delegate; - } while (status == CAIRO_INT_STATUS_UNSUPPORTED); - - if (status == CAIRO_INT_STATUS_SUCCESS && surface->damage) { - TRACE ((stderr, "%s: applying damage (%d,%d)x(%d, %d)\n", - __FUNCTION__, - extents.unbounded.x, extents.unbounded.y, - extents.unbounded.width, extents.unbounded.height)); - surface->damage = _cairo_damage_add_rectangle (surface->damage, - &extents.unbounded); - } - - _cairo_composite_rectangles_fini (&extents); - - return status; -} - -cairo_int_status_t -_cairo_compositor_fill (const cairo_compositor_t *compositor, - cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_composite_rectangles_t extents; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - status = _cairo_composite_rectangles_init_for_fill (&extents, surface, - op, source, path, - clip); - if (unlikely (status)) - return status; - - do { - while (compositor->fill == NULL) - compositor = compositor->delegate; - - status = compositor->fill (compositor, &extents, - path, fill_rule, tolerance, antialias); - - compositor = compositor->delegate; - } while (status == CAIRO_INT_STATUS_UNSUPPORTED); - - if (status == CAIRO_INT_STATUS_SUCCESS && surface->damage) { - TRACE ((stderr, "%s: applying damage (%d,%d)x(%d, %d)\n", - __FUNCTION__, - extents.unbounded.x, extents.unbounded.y, - extents.unbounded.width, extents.unbounded.height)); - surface->damage = _cairo_damage_add_rectangle (surface->damage, - &extents.unbounded); - } - - _cairo_composite_rectangles_fini (&extents); - - return status; -} - -cairo_int_status_t -_cairo_compositor_glyphs (const cairo_compositor_t *compositor, - cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - cairo_composite_rectangles_t extents; - cairo_bool_t overlap; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - status = _cairo_composite_rectangles_init_for_glyphs (&extents, surface, - op, source, - scaled_font, - glyphs, num_glyphs, - clip, &overlap); - if (unlikely (status)) - return status; - - do { - while (compositor->glyphs == NULL) - compositor = compositor->delegate; - - status = compositor->glyphs (compositor, &extents, - scaled_font, glyphs, num_glyphs, overlap); - - compositor = compositor->delegate; - } while (status == CAIRO_INT_STATUS_UNSUPPORTED); - - if (status == CAIRO_INT_STATUS_SUCCESS && surface->damage) { - TRACE ((stderr, "%s: applying damage (%d,%d)x(%d, %d)\n", - __FUNCTION__, - extents.unbounded.x, extents.unbounded.y, - extents.unbounded.width, extents.unbounded.height)); - surface->damage = _cairo_damage_add_rectangle (surface->damage, - &extents.unbounded); - } - - _cairo_composite_rectangles_fini (&extents); - - return status; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-contour-inline.h b/source/libs/cairo/cairo-src/src/cairo-contour-inline.h deleted file mode 100644 index 7972c1ac5e082d89e4d4031524170349db9d211c..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-contour-inline.h +++ /dev/null @@ -1,80 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Intel Corporation - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_CONTOUR_INLINE_H -#define CAIRO_CONTOUR_INLINE_H - -#include "cairo-contour-private.h" - -CAIRO_BEGIN_DECLS - -static inline cairo_int_status_t -_cairo_contour_add_point (cairo_contour_t *contour, - const cairo_point_t *point) -{ - struct _cairo_contour_chain *tail = contour->tail; - - if (unlikely (tail->num_points == tail->size_points)) - return __cairo_contour_add_point (contour, point); - - tail->points[tail->num_points++] = *point; - return CAIRO_INT_STATUS_SUCCESS; -} - -static inline cairo_point_t * -_cairo_contour_first_point (cairo_contour_t *c) -{ - return &c->chain.points[0]; -} - -static inline cairo_point_t * -_cairo_contour_last_point (cairo_contour_t *c) -{ - return &c->tail->points[c->tail->num_points-1]; -} - -static inline void -_cairo_contour_remove_last_point (cairo_contour_t *contour) -{ - if (contour->chain.num_points == 0) - return; - - if (--contour->tail->num_points == 0) - __cairo_contour_remove_last_chain (contour); -} - -CAIRO_END_DECLS - -#endif /* CAIRO_CONTOUR_INLINE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-contour-private.h b/source/libs/cairo/cairo-src/src/cairo-contour-private.h deleted file mode 100644 index 1dfc46f3acd7a25abc106a289c20d041ad802e27..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-contour-private.h +++ /dev/null @@ -1,124 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Intel Corporation - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_CONTOUR_PRIVATE_H -#define CAIRO_CONTOUR_PRIVATE_H - -#include "cairo-types-private.h" -#include "cairo-compiler-private.h" -#include "cairo-error-private.h" -#include "cairo-list-private.h" - -#include <stdio.h> - -CAIRO_BEGIN_DECLS - -/* A contour is simply a closed chain of points that divide the infinite plane - * into inside and outside. Each contour is a simple polygon, that is it - * contains no holes or self-intersections, but maybe either concave or convex. - */ - -struct _cairo_contour_chain { - cairo_point_t *points; - int num_points, size_points; - struct _cairo_contour_chain *next; -}; - -struct _cairo_contour_iter { - cairo_point_t *point; - cairo_contour_chain_t *chain; -}; - -struct _cairo_contour { - cairo_list_t next; - int direction; - cairo_contour_chain_t chain, *tail; - - cairo_point_t embedded_points[64]; -}; - -/* Initial definition of a shape is a set of contours (some representing holes) */ -struct _cairo_shape { - cairo_list_t contours; -}; - -typedef struct _cairo_shape cairo_shape_t; - -#if 0 -cairo_private cairo_status_t -_cairo_shape_init_from_polygon (cairo_shape_t *shape, - const cairo_polygon_t *polygon); - -cairo_private cairo_status_t -_cairo_shape_reduce (cairo_shape_t *shape, double tolerance); -#endif - -cairo_private void -_cairo_contour_init (cairo_contour_t *contour, - int direction); - -cairo_private cairo_int_status_t -__cairo_contour_add_point (cairo_contour_t *contour, - const cairo_point_t *point); - -cairo_private void -_cairo_contour_simplify (cairo_contour_t *contour, double tolerance); - -cairo_private void -_cairo_contour_reverse (cairo_contour_t *contour); - -cairo_private cairo_int_status_t -_cairo_contour_add (cairo_contour_t *dst, - const cairo_contour_t *src); - -cairo_private cairo_int_status_t -_cairo_contour_add_reversed (cairo_contour_t *dst, - const cairo_contour_t *src); - -cairo_private void -__cairo_contour_remove_last_chain (cairo_contour_t *contour); - -cairo_private void -_cairo_contour_reset (cairo_contour_t *contour); - -cairo_private void -_cairo_contour_fini (cairo_contour_t *contour); - -cairo_private void -_cairo_debug_print_contour (FILE *file, cairo_contour_t *contour); - -CAIRO_END_DECLS - -#endif /* CAIRO_CONTOUR_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-contour.c b/source/libs/cairo/cairo-src/src/cairo-contour.c deleted file mode 100644 index 9ad75bdbf8df670e01ca338b8eac0830b4838282..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-contour.c +++ /dev/null @@ -1,453 +0,0 @@ -/* - * Copyright © 2004 Carl Worth - * Copyright © 2006 Red Hat, Inc. - * Copyright © 2008 Chris Wilson - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Carl Worth - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-error-private.h" -#include "cairo-freelist-private.h" -#include "cairo-combsort-inline.h" -#include "cairo-contour-inline.h" -#include "cairo-contour-private.h" - -void -_cairo_contour_init (cairo_contour_t *contour, - int direction) -{ - contour->direction = direction; - contour->chain.points = contour->embedded_points; - contour->chain.next = NULL; - contour->chain.num_points = 0; - contour->chain.size_points = ARRAY_LENGTH (contour->embedded_points); - contour->tail = &contour->chain; -} - -cairo_int_status_t -__cairo_contour_add_point (cairo_contour_t *contour, - const cairo_point_t *point) -{ - cairo_contour_chain_t *tail = contour->tail; - cairo_contour_chain_t *next; - - assert (tail->next == NULL); - - next = _cairo_malloc_ab_plus_c (tail->size_points*2, - sizeof (cairo_point_t), - sizeof (cairo_contour_chain_t)); - if (unlikely (next == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - next->size_points = tail->size_points*2; - next->num_points = 1; - next->points = (cairo_point_t *)(next+1); - next->next = NULL; - tail->next = next; - contour->tail = next; - - next->points[0] = *point; - return CAIRO_INT_STATUS_SUCCESS; -} - -static void -first_inc (cairo_contour_t *contour, - cairo_point_t **p, - cairo_contour_chain_t **chain) -{ - if (*p == (*chain)->points + (*chain)->num_points) { - assert ((*chain)->next); - *chain = (*chain)->next; - *p = &(*chain)->points[0]; - } else - ++*p; -} - -static void -last_dec (cairo_contour_t *contour, - cairo_point_t **p, - cairo_contour_chain_t **chain) -{ - if (*p == (*chain)->points) { - cairo_contour_chain_t *prev; - assert (*chain != &contour->chain); - for (prev = &contour->chain; prev->next != *chain; prev = prev->next) - ; - *chain = prev; - *p = &(*chain)->points[(*chain)->num_points-1]; - } else - --*p; -} - -void -_cairo_contour_reverse (cairo_contour_t *contour) -{ - cairo_contour_chain_t *first_chain, *last_chain; - cairo_point_t *first, *last; - - contour->direction = -contour->direction; - - if (contour->chain.num_points <= 1) - return; - - first_chain = &contour->chain; - last_chain = contour->tail; - - first = &first_chain->points[0]; - last = &last_chain->points[last_chain->num_points-1]; - - while (first != last) { - cairo_point_t p; - - p = *first; - *first = *last; - *last = p; - - first_inc (contour, &first, &first_chain); - last_dec (contour, &last, &last_chain); - } -} - -cairo_int_status_t -_cairo_contour_add (cairo_contour_t *dst, - const cairo_contour_t *src) -{ - const cairo_contour_chain_t *chain; - cairo_int_status_t status; - int i; - - for (chain = &src->chain; chain; chain = chain->next) { - for (i = 0; i < chain->num_points; i++) { - status = _cairo_contour_add_point (dst, &chain->points[i]); - if (unlikely (status)) - return status; - } - } - - return CAIRO_INT_STATUS_SUCCESS; -} - -static inline cairo_bool_t -iter_next (cairo_contour_iter_t *iter) -{ - if (iter->point == &iter->chain->points[iter->chain->size_points-1]) { - iter->chain = iter->chain->next; - if (iter->chain == NULL) - return FALSE; - - iter->point = &iter->chain->points[0]; - return TRUE; - } else { - iter->point++; - return TRUE; - } -} - -static cairo_bool_t -iter_equal (const cairo_contour_iter_t *i1, - const cairo_contour_iter_t *i2) -{ - return i1->chain == i2->chain && i1->point == i2->point; -} - -static void -iter_init (cairo_contour_iter_t *iter, cairo_contour_t *contour) -{ - iter->chain = &contour->chain; - iter->point = &contour->chain.points[0]; -} - -static void -iter_init_last (cairo_contour_iter_t *iter, cairo_contour_t *contour) -{ - iter->chain = contour->tail; - iter->point = &contour->tail->points[contour->tail->num_points-1]; -} - -static const cairo_contour_chain_t *prev_const_chain(const cairo_contour_t *contour, - const cairo_contour_chain_t *chain) -{ - const cairo_contour_chain_t *prev; - - if (chain == &contour->chain) - return NULL; - - for (prev = &contour->chain; prev->next != chain; prev = prev->next) - ; - - return prev; -} - -cairo_int_status_t -_cairo_contour_add_reversed (cairo_contour_t *dst, - const cairo_contour_t *src) -{ - const cairo_contour_chain_t *last; - cairo_int_status_t status; - int i; - - if (src->chain.num_points == 0) - return CAIRO_INT_STATUS_SUCCESS; - - for (last = src->tail; last; last = prev_const_chain (src, last)) { - for (i = last->num_points-1; i >= 0; i--) { - status = _cairo_contour_add_point (dst, &last->points[i]); - if (unlikely (status)) - return status; - } - } - - return CAIRO_INT_STATUS_SUCCESS; -} - -static cairo_uint64_t -point_distance_sq (const cairo_point_t *p1, - const cairo_point_t *p2) -{ - int32_t dx = p1->x - p2->x; - int32_t dy = p1->y - p2->y; - return _cairo_int32x32_64_mul (dx, dx) + _cairo_int32x32_64_mul (dy, dy); -} - -#define DELETED(p) ((p)->x == INT_MIN && (p)->y == INT_MAX) -#define MARK_DELETED(p) ((p)->x = INT_MIN, (p)->y = INT_MAX) - -static cairo_bool_t -_cairo_contour_simplify_chain (cairo_contour_t *contour, const double tolerance, - const cairo_contour_iter_t *first, - const cairo_contour_iter_t *last) -{ - cairo_contour_iter_t iter, furthest; - uint64_t max_error; - int x0, y0; - int nx, ny; - int count; - - iter = *first; - iter_next (&iter); - if (iter_equal (&iter, last)) - return FALSE; - - x0 = first->point->x; - y0 = first->point->y; - nx = last->point->y - y0; - ny = x0 - last->point->x; - - count = 0; - max_error = 0; - do { - cairo_point_t *p = iter.point; - if (! DELETED(p)) { - uint64_t d = (uint64_t)nx * (x0 - p->x) + (uint64_t)ny * (y0 - p->y); - if (d * d > max_error) { - max_error = d * d; - furthest = iter; - } - count++; - } - iter_next (&iter); - } while (! iter_equal (&iter, last)); - if (count == 0) - return FALSE; - - if (max_error > tolerance * ((uint64_t)nx * nx + (uint64_t)ny * ny)) { - cairo_bool_t simplified; - - simplified = FALSE; - simplified |= _cairo_contour_simplify_chain (contour, tolerance, - first, &furthest); - simplified |= _cairo_contour_simplify_chain (contour, tolerance, - &furthest, last); - return simplified; - } else { - iter = *first; - iter_next (&iter); - do { - MARK_DELETED (iter.point); - iter_next (&iter); - } while (! iter_equal (&iter, last)); - - return TRUE; - } -} - -void -_cairo_contour_simplify (cairo_contour_t *contour, double tolerance) -{ - cairo_contour_chain_t *chain; - cairo_point_t *last = NULL; - cairo_contour_iter_t iter, furthest; - cairo_bool_t simplified; - uint64_t max = 0; - int i; - - if (contour->chain.num_points <= 2) - return; - - tolerance = tolerance * CAIRO_FIXED_ONE; - tolerance *= tolerance; - - /* stage 1: vertex reduction */ - for (chain = &contour->chain; chain; chain = chain->next) { - for (i = 0; i < chain->num_points; i++) { - if (last == NULL || - point_distance_sq (last, &chain->points[i]) > tolerance) { - last = &chain->points[i]; - } else { - MARK_DELETED (&chain->points[i]); - } - } - } - - /* stage2: polygon simplification using Douglas-Peucker */ - do { - last = &contour->chain.points[0]; - iter_init (&furthest, contour); - max = 0; - for (chain = &contour->chain; chain; chain = chain->next) { - for (i = 0; i < chain->num_points; i++) { - uint64_t d; - - if (DELETED (&chain->points[i])) - continue; - - d = point_distance_sq (last, &chain->points[i]); - if (d > max) { - furthest.chain = chain; - furthest.point = &chain->points[i]; - max = d; - } - } - } - assert (max); - - simplified = FALSE; - iter_init (&iter, contour); - simplified |= _cairo_contour_simplify_chain (contour, tolerance, - &iter, &furthest); - - iter_init_last (&iter, contour); - if (! iter_equal (&furthest, &iter)) - simplified |= _cairo_contour_simplify_chain (contour, tolerance, - &furthest, &iter); - } while (simplified); - - iter_init (&iter, contour); - for (chain = &contour->chain; chain; chain = chain->next) { - int num_points = chain->num_points; - chain->num_points = 0; - for (i = 0; i < num_points; i++) { - if (! DELETED(&chain->points[i])) { - if (iter.point != &chain->points[i]) - *iter.point = chain->points[i]; - iter.chain->num_points++; - iter_next (&iter); - } - } - } - - if (iter.chain) { - cairo_contour_chain_t *next; - - for (chain = iter.chain->next; chain; chain = next) { - next = chain->next; - free (chain); - } - - iter.chain->next = NULL; - contour->tail = iter.chain; - } -} - -void -_cairo_contour_reset (cairo_contour_t *contour) -{ - _cairo_contour_fini (contour); - _cairo_contour_init (contour, contour->direction); -} - -void -_cairo_contour_fini (cairo_contour_t *contour) -{ - cairo_contour_chain_t *chain, *next; - - for (chain = contour->chain.next; chain; chain = next) { - next = chain->next; - free (chain); - } -} - -void -_cairo_debug_print_contour (FILE *file, cairo_contour_t *contour) -{ - cairo_contour_chain_t *chain; - int num_points, size_points; - int i; - - num_points = 0; - size_points = 0; - for (chain = &contour->chain; chain; chain = chain->next) { - num_points += chain->num_points; - size_points += chain->size_points; - } - - fprintf (file, "contour: direction=%d, num_points=%d / %d\n", - contour->direction, num_points, size_points); - - num_points = 0; - for (chain = &contour->chain; chain; chain = chain->next) { - for (i = 0; i < chain->num_points; i++) { - fprintf (file, " [%d] = (%f, %f)\n", - num_points++, - _cairo_fixed_to_double (chain->points[i].x), - _cairo_fixed_to_double (chain->points[i].y)); - } - } -} - -void -__cairo_contour_remove_last_chain (cairo_contour_t *contour) -{ - cairo_contour_chain_t *chain; - - if (contour->tail == &contour->chain) - return; - - for (chain = &contour->chain; chain->next != contour->tail; chain = chain->next) - ; - free (contour->tail); - contour->tail = chain; - chain->next = NULL; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-damage-private.h b/source/libs/cairo/cairo-src/src/cairo-damage-private.h deleted file mode 100644 index 97b177e86b45ebf16996398ca468da305d88e805..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-damage-private.h +++ /dev/null @@ -1,85 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2012 Intel Corporation - * - * 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 Chris Wilson - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_DAMAGE_PRIVATE_H -#define CAIRO_DAMAGE_PRIVATE_H - -#include "cairo-types-private.h" - -#include <pixman.h> - -CAIRO_BEGIN_DECLS - -struct _cairo_damage { - cairo_status_t status; - cairo_region_t *region; - - int dirty, remain; - struct _cairo_damage_chunk { - struct _cairo_damage_chunk *next; - cairo_box_t *base; - int count; - int size; - } chunks, *tail; - cairo_box_t boxes[32]; -}; - -cairo_private cairo_damage_t * -_cairo_damage_create (void); - -cairo_private cairo_damage_t * -_cairo_damage_create_in_error (cairo_status_t status); - -cairo_private cairo_damage_t * -_cairo_damage_add_box (cairo_damage_t *damage, - const cairo_box_t *box); - -cairo_private cairo_damage_t * -_cairo_damage_add_rectangle (cairo_damage_t *damage, - const cairo_rectangle_int_t *rect); - -cairo_private cairo_damage_t * -_cairo_damage_add_region (cairo_damage_t *damage, - const cairo_region_t *region); - -cairo_private cairo_damage_t * -_cairo_damage_reduce (cairo_damage_t *damage); - -cairo_private void -_cairo_damage_destroy (cairo_damage_t *damage); - -CAIRO_END_DECLS - -#endif /* CAIRO_DAMAGE_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-damage.c b/source/libs/cairo/cairo-src/src/cairo-damage.c deleted file mode 100644 index 63191fee95d410ade54443756846ab34a788ec06..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-damage.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright © 2012 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Chris Wilson - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-damage-private.h" -#include "cairo-region-private.h" - -static const cairo_damage_t __cairo_damage__nil = { CAIRO_STATUS_NO_MEMORY }; - -cairo_damage_t * -_cairo_damage_create_in_error (cairo_status_t status) -{ - _cairo_error_throw (status); - return (cairo_damage_t *) &__cairo_damage__nil; -} - -cairo_damage_t * -_cairo_damage_create (void) -{ - cairo_damage_t *damage; - - damage = malloc (sizeof (*damage)); - if (unlikely (damage == NULL)) { - _cairo_error_throw(CAIRO_STATUS_NO_MEMORY); - return (cairo_damage_t *) &__cairo_damage__nil; - } - - damage->status = CAIRO_STATUS_SUCCESS; - damage->region = NULL; - damage->dirty = 0; - damage->tail = &damage->chunks; - damage->chunks.base = damage->boxes; - damage->chunks.size = ARRAY_LENGTH(damage->boxes); - damage->chunks.count = 0; - damage->chunks.next = NULL; - - damage->remain = damage->chunks.size; - - return damage; -} - -void -_cairo_damage_destroy (cairo_damage_t *damage) -{ - struct _cairo_damage_chunk *chunk, *next; - - if (damage == (cairo_damage_t *) &__cairo_damage__nil) - return; - - for (chunk = damage->chunks.next; chunk != NULL; chunk = next) { - next = chunk->next; - free (chunk); - } - cairo_region_destroy (damage->region); - free (damage); -} - -static cairo_damage_t * -_cairo_damage_add_boxes(cairo_damage_t *damage, - const cairo_box_t *boxes, - int count) -{ - struct _cairo_damage_chunk *chunk; - int n, size; - - TRACE ((stderr, "%s x%d\n", __FUNCTION__, count)); - - if (damage == NULL) - damage = _cairo_damage_create (); - if (damage->status) - return damage; - - damage->dirty += count; - - n = count; - if (n > damage->remain) - n = damage->remain; - - memcpy (damage->tail->base + damage->tail->count, boxes, - n * sizeof (cairo_box_t)); - - count -= n; - damage->tail->count += n; - damage->remain -= n; - - if (count == 0) - return damage; - - size = 2 * damage->tail->size; - if (size < count) - size = (count + 64) & ~63; - - chunk = malloc (sizeof (*chunk) + sizeof (cairo_box_t) * size); - if (unlikely (chunk == NULL)) { - _cairo_damage_destroy (damage); - return (cairo_damage_t *) &__cairo_damage__nil; - } - - chunk->next = NULL; - chunk->base = (cairo_box_t *) (chunk + 1); - chunk->size = size; - chunk->count = count; - - damage->tail->next = chunk; - damage->tail = chunk; - - memcpy (damage->tail->base, boxes + n, - count * sizeof (cairo_box_t)); - damage->remain = size - count; - - return damage; -} - -cairo_damage_t * -_cairo_damage_add_box(cairo_damage_t *damage, - const cairo_box_t *box) -{ - TRACE ((stderr, "%s: (%d, %d),(%d, %d)\n", __FUNCTION__, - box->p1.x, box->p1.y, box->p2.x, box->p2.y)); - - return _cairo_damage_add_boxes(damage, box, 1); -} - -cairo_damage_t * -_cairo_damage_add_rectangle(cairo_damage_t *damage, - const cairo_rectangle_int_t *r) -{ - cairo_box_t box; - - TRACE ((stderr, "%s: (%d, %d)x(%d, %d)\n", __FUNCTION__, - r->x, r->y, r->width, r->height)); - - box.p1.x = r->x; - box.p1.y = r->y; - box.p2.x = r->x + r->width; - box.p2.y = r->y + r->height; - - return _cairo_damage_add_boxes(damage, &box, 1); -} - -cairo_damage_t * -_cairo_damage_add_region (cairo_damage_t *damage, - const cairo_region_t *region) -{ - cairo_box_t *boxes; - int nbox; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - boxes = _cairo_region_get_boxes (region, &nbox); - return _cairo_damage_add_boxes(damage, boxes, nbox); -} - -cairo_damage_t * -_cairo_damage_reduce (cairo_damage_t *damage) -{ - cairo_box_t *free_boxes = NULL; - cairo_box_t *boxes, *b; - struct _cairo_damage_chunk *chunk, *last; - - TRACE ((stderr, "%s: dirty=%d\n", __FUNCTION__, - damage ? damage->dirty : -1)); - if (damage == NULL || damage->status || !damage->dirty) - return damage; - - if (damage->region) { - cairo_region_t *region; - - region = damage->region; - damage->region = NULL; - - damage = _cairo_damage_add_region (damage, region); - cairo_region_destroy (region); - - if (unlikely (damage->status)) - return damage; - } - - boxes = damage->tail->base; - if (damage->dirty > damage->tail->size) { - boxes = free_boxes = malloc (damage->dirty * sizeof (cairo_box_t)); - if (unlikely (boxes == NULL)) { - _cairo_damage_destroy (damage); - return (cairo_damage_t *) &__cairo_damage__nil; - } - - b = boxes; - last = NULL; - } else { - b = boxes + damage->tail->count; - last = damage->tail; - } - - for (chunk = &damage->chunks; chunk != last; chunk = chunk->next) { - memcpy (b, chunk->base, chunk->count * sizeof (cairo_box_t)); - b += chunk->count; - } - - damage->region = _cairo_region_create_from_boxes (boxes, damage->dirty); - free (free_boxes); - - if (unlikely (damage->region->status)) { - _cairo_damage_destroy (damage); - return (cairo_damage_t *) &__cairo_damage__nil; - } - - damage->dirty = 0; - return damage; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-debug.c b/source/libs/cairo/cairo-src/src/cairo-debug.c deleted file mode 100644 index e7ffe48d28c3287113a726f635731eb6078e785c..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-debug.c +++ /dev/null @@ -1,304 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - */ - -#include "cairoint.h" -#include "cairo-image-surface-private.h" - -/** - * cairo_debug_reset_static_data: - * - * Resets all static data within cairo to its original state, - * (ie. identical to the state at the time of program invocation). For - * example, all caches within cairo will be flushed empty. - * - * This function is intended to be useful when using memory-checking - * tools such as valgrind. When valgrind's memcheck analyzes a - * cairo-using program without a call to cairo_debug_reset_static_data(), - * it will report all data reachable via cairo's static objects as - * "still reachable". Calling cairo_debug_reset_static_data() just prior - * to program termination will make it easier to get squeaky clean - * reports from valgrind. - * - * WARNING: It is only safe to call this function when there are no - * active cairo objects remaining, (ie. the appropriate destroy - * functions have been called as necessary). If there are active cairo - * objects, this call is likely to cause a crash, (eg. an assertion - * failure due to a hash table being destroyed when non-empty). - * - * Since: 1.0 - **/ -void -cairo_debug_reset_static_data (void) -{ - CAIRO_MUTEX_INITIALIZE (); - - _cairo_scaled_font_map_destroy (); - - _cairo_toy_font_face_reset_static_data (); - -#if CAIRO_HAS_FT_FONT - _cairo_ft_font_reset_static_data (); -#endif - -#if CAIRO_HAS_WIN32_FONT - _cairo_win32_font_reset_static_data (); -#endif - - _cairo_intern_string_reset_static_data (); - - _cairo_scaled_font_reset_static_data (); - - _cairo_pattern_reset_static_data (); - - _cairo_clip_reset_static_data (); - - _cairo_image_reset_static_data (); - -#if CAIRO_HAS_DRM_SURFACE - _cairo_drm_device_reset_static_data (); -#endif - - _cairo_default_context_reset_static_data (); - -#if CAIRO_HAS_COGL_SURFACE - _cairo_cogl_context_reset_static_data (); -#endif - - CAIRO_MUTEX_FINALIZE (); -} - -#if HAVE_VALGRIND -void -_cairo_debug_check_image_surface_is_defined (const cairo_surface_t *surface) -{ - const cairo_image_surface_t *image = (cairo_image_surface_t *) surface; - const uint8_t *bits; - int row, width; - - if (surface == NULL) - return; - - if (! RUNNING_ON_VALGRIND) - return; - - bits = image->data; - switch (image->format) { - case CAIRO_FORMAT_A1: - width = (image->width + 7)/8; - break; - case CAIRO_FORMAT_A8: - width = image->width; - break; - case CAIRO_FORMAT_RGB16_565: - width = image->width*2; - break; - case CAIRO_FORMAT_RGB24: - case CAIRO_FORMAT_RGB30: - case CAIRO_FORMAT_ARGB32: - width = image->width*4; - break; - case CAIRO_FORMAT_INVALID: - default: - /* XXX compute width from pixman bpp */ - return; - } - - for (row = 0; row < image->height; row++) { - VALGRIND_CHECK_MEM_IS_DEFINED (bits, width); - /* and then silence any future valgrind warnings */ - VALGRIND_MAKE_MEM_DEFINED (bits, width); - bits += image->stride; - } -} -#endif - - -#if 0 -void -_cairo_image_surface_write_to_ppm (cairo_image_surface_t *isurf, const char *fn) -{ - char *fmt; - if (isurf->format == CAIRO_FORMAT_ARGB32 || isurf->format == CAIRO_FORMAT_RGB24) - fmt = "P6"; - else if (isurf->format == CAIRO_FORMAT_A8) - fmt = "P5"; - else - return; - - FILE *fp = fopen(fn, "wb"); - if (!fp) - return; - - fprintf (fp, "%s %d %d 255\n", fmt,isurf->width, isurf->height); - for (int j = 0; j < isurf->height; j++) { - unsigned char *row = isurf->data + isurf->stride * j; - for (int i = 0; i < isurf->width; i++) { - if (isurf->format == CAIRO_FORMAT_ARGB32 || isurf->format == CAIRO_FORMAT_RGB24) { - unsigned char r = *row++; - unsigned char g = *row++; - unsigned char b = *row++; - *row++; - putc(r, fp); - putc(g, fp); - putc(b, fp); - } else { - unsigned char a = *row++; - putc(a, fp); - } - } - } - - fclose (fp); - - fprintf (stderr, "Wrote %s\n", fn); -} -#endif - -static cairo_status_t -_print_move_to (void *closure, - const cairo_point_t *point) -{ - fprintf (closure, - " %f %f m", - _cairo_fixed_to_double (point->x), - _cairo_fixed_to_double (point->y)); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_print_line_to (void *closure, - const cairo_point_t *point) -{ - fprintf (closure, - " %f %f l", - _cairo_fixed_to_double (point->x), - _cairo_fixed_to_double (point->y)); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_print_curve_to (void *closure, - const cairo_point_t *p1, - const cairo_point_t *p2, - const cairo_point_t *p3) -{ - fprintf (closure, - " %f %f %f %f %f %f c", - _cairo_fixed_to_double (p1->x), - _cairo_fixed_to_double (p1->y), - _cairo_fixed_to_double (p2->x), - _cairo_fixed_to_double (p2->y), - _cairo_fixed_to_double (p3->x), - _cairo_fixed_to_double (p3->y)); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_print_close (void *closure) -{ - fprintf (closure, " h"); - - return CAIRO_STATUS_SUCCESS; -} - -void -_cairo_debug_print_path (FILE *stream, cairo_path_fixed_t *path) -{ - cairo_status_t status; - cairo_box_t box; - - fprintf (stream, - "path: extents=(%f, %f), (%f, %f)\n", - _cairo_fixed_to_double (path->extents.p1.x), - _cairo_fixed_to_double (path->extents.p1.y), - _cairo_fixed_to_double (path->extents.p2.x), - _cairo_fixed_to_double (path->extents.p2.y)); - - status = _cairo_path_fixed_interpret (path, - _print_move_to, - _print_line_to, - _print_curve_to, - _print_close, - stream); - assert (status == CAIRO_STATUS_SUCCESS); - - if (_cairo_path_fixed_is_box (path, &box)) { - fprintf (stream, "[box (%d, %d), (%d, %d)]", - box.p1.x, box.p1.y, box.p2.x, box.p2.y); - } - - fprintf (stream, "\n"); -} - -void -_cairo_debug_print_polygon (FILE *stream, cairo_polygon_t *polygon) -{ - int n; - - fprintf (stream, - "polygon: extents=(%f, %f), (%f, %f)\n", - _cairo_fixed_to_double (polygon->extents.p1.x), - _cairo_fixed_to_double (polygon->extents.p1.y), - _cairo_fixed_to_double (polygon->extents.p2.x), - _cairo_fixed_to_double (polygon->extents.p2.y)); - if (polygon->num_limits) { - fprintf (stream, - " : limit=(%f, %f), (%f, %f) x %d\n", - _cairo_fixed_to_double (polygon->limit.p1.x), - _cairo_fixed_to_double (polygon->limit.p1.y), - _cairo_fixed_to_double (polygon->limit.p2.x), - _cairo_fixed_to_double (polygon->limit.p2.y), - polygon->num_limits); - } - - for (n = 0; n < polygon->num_edges; n++) { - cairo_edge_t *edge = &polygon->edges[n]; - - fprintf (stream, - " [%d] = [(%f, %f), (%f, %f)], top=%f, bottom=%f, dir=%d\n", - n, - _cairo_fixed_to_double (edge->line.p1.x), - _cairo_fixed_to_double (edge->line.p1.y), - _cairo_fixed_to_double (edge->line.p2.x), - _cairo_fixed_to_double (edge->line.p2.y), - _cairo_fixed_to_double (edge->top), - _cairo_fixed_to_double (edge->bottom), - edge->dir); - - } -} diff --git a/source/libs/cairo/cairo-src/src/cairo-default-context-private.h b/source/libs/cairo/cairo-src/src/cairo-default-context-private.h deleted file mode 100644 index fd159b496707e288a3e32683b064c986710c3df8..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-default-context-private.h +++ /dev/null @@ -1,68 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Carl D. Worth <cworth@redhat.com> - */ - -#ifndef CAIRO_DEFAULT_CONTEXT_PRIVATE_H -#define CAIRO_DEFAULT_CONTEXT_PRIVATE_H - -#include "cairo-private.h" -#include "cairo-gstate-private.h" -#include "cairo-path-fixed-private.h" - -CAIRO_BEGIN_DECLS - -typedef struct _cairo_default_context cairo_default_context_t; - -struct _cairo_default_context { - cairo_t base; - - cairo_gstate_t *gstate; - cairo_gstate_t gstate_tail[2]; - cairo_gstate_t *gstate_freelist; - - cairo_path_fixed_t path[1]; -}; - -cairo_private cairo_t * -_cairo_default_context_create (void *target); - -cairo_private cairo_status_t -_cairo_default_context_init (cairo_default_context_t *cr, void *target); - -cairo_private void -_cairo_default_context_fini (cairo_default_context_t *cr); - -CAIRO_END_DECLS - -#endif /* CAIRO_DEFAULT_CONTEXT_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-default-context.c b/source/libs/cairo/cairo-src/src/cairo-default-context.c deleted file mode 100644 index 1e5067bf1b8063dec39f13e49e05931ebc5721a2..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-default-context.c +++ /dev/null @@ -1,1475 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-private.h" -#include "cairo-arc-private.h" -#include "cairo-backend-private.h" -#include "cairo-clip-inline.h" -#include "cairo-default-context-private.h" -#include "cairo-error-private.h" -#include "cairo-freed-pool-private.h" -#include "cairo-path-private.h" -#include "cairo-pattern-private.h" - -#define CAIRO_TOLERANCE_MINIMUM _cairo_fixed_to_double(1) - -#if !defined(INFINITY) -#define INFINITY HUGE_VAL -#endif - -static freed_pool_t context_pool; - -void -_cairo_default_context_reset_static_data (void) -{ - _freed_pool_reset (&context_pool); -} - -void -_cairo_default_context_fini (cairo_default_context_t *cr) -{ - while (cr->gstate != &cr->gstate_tail[0]) { - if (_cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist)) - break; - } - - _cairo_gstate_fini (cr->gstate); - cr->gstate_freelist = cr->gstate_freelist->next; /* skip over tail[1] */ - while (cr->gstate_freelist != NULL) { - cairo_gstate_t *gstate = cr->gstate_freelist; - cr->gstate_freelist = gstate->next; - free (gstate); - } - - _cairo_path_fixed_fini (cr->path); - - _cairo_fini (&cr->base); -} - -static void -_cairo_default_context_destroy (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - _cairo_default_context_fini (cr); - - /* mark the context as invalid to protect against misuse */ - cr->base.status = CAIRO_STATUS_NULL_POINTER; - _freed_pool_put (&context_pool, cr); -} - -static cairo_surface_t * -_cairo_default_context_get_original_target (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_get_original_target (cr->gstate); -} - -static cairo_surface_t * -_cairo_default_context_get_current_target (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_get_target (cr->gstate); -} - -static cairo_status_t -_cairo_default_context_save (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_save (&cr->gstate, &cr->gstate_freelist); -} - -static cairo_status_t -_cairo_default_context_restore (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - if (unlikely (_cairo_gstate_is_group (cr->gstate))) - return _cairo_error (CAIRO_STATUS_INVALID_RESTORE); - - return _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist); -} - -static cairo_status_t -_cairo_default_context_push_group (void *abstract_cr, cairo_content_t content) -{ - cairo_default_context_t *cr = abstract_cr; - cairo_surface_t *group_surface; - cairo_clip_t *clip; - cairo_status_t status; - - clip = _cairo_gstate_get_clip (cr->gstate); - if (_cairo_clip_is_all_clipped (clip)) { - group_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0); - status = group_surface->status; - if (unlikely (status)) - goto bail; - } else { - cairo_surface_t *parent_surface; - cairo_rectangle_int_t extents; - cairo_bool_t bounded, is_empty; - - parent_surface = _cairo_gstate_get_target (cr->gstate); - - if (unlikely (parent_surface->status)) - return parent_surface->status; - if (unlikely (parent_surface->finished)) - return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED); - - /* Get the extents that we'll use in creating our new group surface */ - bounded = _cairo_surface_get_extents (parent_surface, &extents); - if (clip) - /* XXX: This assignment just fixes a compiler warning? */ - is_empty = _cairo_rectangle_intersect (&extents, - _cairo_clip_get_extents (clip)); - - if (!bounded) { - /* XXX: Generic solution? */ - group_surface = cairo_recording_surface_create (content, NULL); - extents.x = extents.y = 0; - } else { - group_surface = _cairo_surface_create_scratch (parent_surface, - content, - extents.width, - extents.height, - CAIRO_COLOR_TRANSPARENT); - } - status = group_surface->status; - if (unlikely (status)) - goto bail; - - /* Set device offsets on the new surface so that logically it appears at - * the same location on the parent surface -- when we pop_group this, - * the source pattern will get fixed up for the appropriate target surface - * device offsets, so we want to set our own surface offsets from /that/, - * and not from the device origin. */ - cairo_surface_set_device_offset (group_surface, - parent_surface->device_transform.x0 - extents.x, - parent_surface->device_transform.y0 - extents.y); - - cairo_surface_set_device_scale (group_surface, - parent_surface->device_transform.xx, - parent_surface->device_transform.yy); - - /* If we have a current path, we need to adjust it to compensate for - * the device offset just applied. */ - _cairo_path_fixed_translate (cr->path, - _cairo_fixed_from_int (-extents.x), - _cairo_fixed_from_int (-extents.y)); - } - - /* create a new gstate for the redirect */ - status = _cairo_gstate_save (&cr->gstate, &cr->gstate_freelist); - if (unlikely (status)) - goto bail; - - status = _cairo_gstate_redirect_target (cr->gstate, group_surface); - -bail: - cairo_surface_destroy (group_surface); - return status; -} - -static cairo_pattern_t * -_cairo_default_context_pop_group (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - cairo_surface_t *group_surface; - cairo_pattern_t *group_pattern; - cairo_surface_t *parent_surface; - cairo_matrix_t group_matrix; - cairo_status_t status; - - /* Verify that we are at the right nesting level */ - if (unlikely (! _cairo_gstate_is_group (cr->gstate))) - return _cairo_pattern_create_in_error (CAIRO_STATUS_INVALID_POP_GROUP); - - /* Get a reference to the active surface before restoring */ - group_surface = _cairo_gstate_get_target (cr->gstate); - group_surface = cairo_surface_reference (group_surface); - - status = _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist); - assert (status == CAIRO_STATUS_SUCCESS); - - parent_surface = _cairo_gstate_get_target (cr->gstate); - - group_pattern = cairo_pattern_create_for_surface (group_surface); - status = group_pattern->status; - if (unlikely (status)) - goto done; - - _cairo_gstate_get_matrix (cr->gstate, &group_matrix); - cairo_pattern_set_matrix (group_pattern, &group_matrix); - - /* If we have a current path, we need to adjust it to compensate for - * the device offset just removed. */ - _cairo_path_fixed_translate (cr->path, - _cairo_fixed_from_int (parent_surface->device_transform.x0 - group_surface->device_transform.x0), - _cairo_fixed_from_int (parent_surface->device_transform.y0 - group_surface->device_transform.y0)); - -done: - cairo_surface_destroy (group_surface); - - return group_pattern; -} - -static cairo_status_t -_cairo_default_context_set_source (void *abstract_cr, - cairo_pattern_t *source) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_set_source (cr->gstate, source); -} - -static cairo_bool_t -_current_source_matches_solid (const cairo_pattern_t *pattern, - double red, - double green, - double blue, - double alpha) -{ - cairo_color_t color; - - if (pattern->type != CAIRO_PATTERN_TYPE_SOLID) - return FALSE; - - red = _cairo_restrict_value (red, 0.0, 1.0); - green = _cairo_restrict_value (green, 0.0, 1.0); - blue = _cairo_restrict_value (blue, 0.0, 1.0); - alpha = _cairo_restrict_value (alpha, 0.0, 1.0); - - _cairo_color_init_rgba (&color, red, green, blue, alpha); - return _cairo_color_equal (&color, - &((cairo_solid_pattern_t *) pattern)->color); -} - -static cairo_status_t -_cairo_default_context_set_source_rgba (void *abstract_cr, double red, double green, double blue, double alpha) -{ - cairo_default_context_t *cr = abstract_cr; - cairo_pattern_t *pattern; - cairo_status_t status; - - if (_current_source_matches_solid (cr->gstate->source, - red, green, blue, alpha)) - return CAIRO_STATUS_SUCCESS; - - /* push the current pattern to the freed lists */ - _cairo_default_context_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_black); - - pattern = cairo_pattern_create_rgba (red, green, blue, alpha); - if (unlikely (pattern->status)) - return pattern->status; - - status = _cairo_default_context_set_source (cr, pattern); - cairo_pattern_destroy (pattern); - - return status; -} - -static cairo_status_t -_cairo_default_context_set_source_surface (void *abstract_cr, - cairo_surface_t *surface, - double x, - double y) -{ - cairo_default_context_t *cr = abstract_cr; - cairo_pattern_t *pattern; - cairo_matrix_t matrix; - cairo_status_t status; - - /* push the current pattern to the freed lists */ - _cairo_default_context_set_source (cr, (cairo_pattern_t *) &_cairo_pattern_black); - - pattern = cairo_pattern_create_for_surface (surface); - if (unlikely (pattern->status)) - return pattern->status; - - cairo_matrix_init_translate (&matrix, -x, -y); - cairo_pattern_set_matrix (pattern, &matrix); - - status = _cairo_default_context_set_source (cr, pattern); - cairo_pattern_destroy (pattern); - - return status; -} - -static cairo_pattern_t * -_cairo_default_context_get_source (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_get_source (cr->gstate); -} - -static cairo_status_t -_cairo_default_context_set_tolerance (void *abstract_cr, - double tolerance) -{ - cairo_default_context_t *cr = abstract_cr; - - if (tolerance < CAIRO_TOLERANCE_MINIMUM) - tolerance = CAIRO_TOLERANCE_MINIMUM; - - return _cairo_gstate_set_tolerance (cr->gstate, tolerance); -} - -static cairo_status_t -_cairo_default_context_set_operator (void *abstract_cr, cairo_operator_t op) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_set_operator (cr->gstate, op); -} - -static cairo_status_t -_cairo_default_context_set_opacity (void *abstract_cr, double opacity) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_set_opacity (cr->gstate, opacity); -} - -static cairo_status_t -_cairo_default_context_set_antialias (void *abstract_cr, - cairo_antialias_t antialias) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_set_antialias (cr->gstate, antialias); -} - -static cairo_status_t -_cairo_default_context_set_fill_rule (void *abstract_cr, - cairo_fill_rule_t fill_rule) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_set_fill_rule (cr->gstate, fill_rule); -} - -static cairo_status_t -_cairo_default_context_set_line_width (void *abstract_cr, - double line_width) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_set_line_width (cr->gstate, line_width); -} - -static cairo_status_t -_cairo_default_context_set_line_cap (void *abstract_cr, - cairo_line_cap_t line_cap) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_set_line_cap (cr->gstate, line_cap); -} - -static cairo_status_t -_cairo_default_context_set_line_join (void *abstract_cr, - cairo_line_join_t line_join) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_set_line_join (cr->gstate, line_join); -} - -static cairo_status_t -_cairo_default_context_set_dash (void *abstract_cr, - const double *dashes, - int num_dashes, - double offset) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_set_dash (cr->gstate, - dashes, num_dashes, offset); -} - -static cairo_status_t -_cairo_default_context_set_miter_limit (void *abstract_cr, - double limit) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_set_miter_limit (cr->gstate, limit); -} - -static cairo_antialias_t -_cairo_default_context_get_antialias (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_get_antialias (cr->gstate); -} - -static void -_cairo_default_context_get_dash (void *abstract_cr, - double *dashes, - int *num_dashes, - double *offset) -{ - cairo_default_context_t *cr = abstract_cr; - - _cairo_gstate_get_dash (cr->gstate, dashes, num_dashes, offset); -} - -static cairo_fill_rule_t -_cairo_default_context_get_fill_rule (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_get_fill_rule (cr->gstate); -} - -static double -_cairo_default_context_get_line_width (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_get_line_width (cr->gstate); -} - -static cairo_line_cap_t -_cairo_default_context_get_line_cap (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_get_line_cap (cr->gstate); -} - -static cairo_line_join_t -_cairo_default_context_get_line_join (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_get_line_join (cr->gstate); -} - -static double -_cairo_default_context_get_miter_limit (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_get_miter_limit (cr->gstate); -} - -static cairo_operator_t -_cairo_default_context_get_operator (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_get_operator (cr->gstate); -} - -static double -_cairo_default_context_get_opacity (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_get_opacity (cr->gstate); -} - -static double -_cairo_default_context_get_tolerance (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_get_tolerance (cr->gstate); -} - - -/* Current tranformation matrix */ - -static cairo_status_t -_cairo_default_context_translate (void *abstract_cr, - double tx, - double ty) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_translate (cr->gstate, tx, ty); -} - -static cairo_status_t -_cairo_default_context_scale (void *abstract_cr, - double sx, - double sy) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_scale (cr->gstate, sx, sy); -} - -static cairo_status_t -_cairo_default_context_rotate (void *abstract_cr, - double theta) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_rotate (cr->gstate, theta); -} - -static cairo_status_t -_cairo_default_context_transform (void *abstract_cr, - const cairo_matrix_t *matrix) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_transform (cr->gstate, matrix); -} - -static cairo_status_t -_cairo_default_context_set_matrix (void *abstract_cr, - const cairo_matrix_t *matrix) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_set_matrix (cr->gstate, matrix); -} - -static cairo_status_t -_cairo_default_context_set_identity_matrix (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - _cairo_gstate_identity_matrix (cr->gstate); - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_default_context_get_matrix (void *abstract_cr, - cairo_matrix_t *matrix) -{ - cairo_default_context_t *cr = abstract_cr; - - _cairo_gstate_get_matrix (cr->gstate, matrix); -} - -static void -_cairo_default_context_user_to_device (void *abstract_cr, - double *x, - double *y) -{ - cairo_default_context_t *cr = abstract_cr; - - _cairo_gstate_user_to_device (cr->gstate, x, y); -} - -static void -_cairo_default_context_user_to_device_distance (void *abstract_cr, double *dx, double *dy) -{ - cairo_default_context_t *cr = abstract_cr; - - _cairo_gstate_user_to_device_distance (cr->gstate, dx, dy); -} - -static void -_cairo_default_context_device_to_user (void *abstract_cr, - double *x, - double *y) -{ - cairo_default_context_t *cr = abstract_cr; - - _cairo_gstate_device_to_user (cr->gstate, x, y); -} - -static void -_cairo_default_context_device_to_user_distance (void *abstract_cr, - double *dx, - double *dy) -{ - cairo_default_context_t *cr = abstract_cr; - - _cairo_gstate_device_to_user_distance (cr->gstate, dx, dy); -} - -static void -_cairo_default_context_backend_to_user (void *abstract_cr, - double *x, - double *y) -{ - cairo_default_context_t *cr = abstract_cr; - - _cairo_gstate_backend_to_user (cr->gstate, x, y); -} - -static void -_cairo_default_context_backend_to_user_distance (void *abstract_cr, double *dx, double *dy) -{ - cairo_default_context_t *cr = abstract_cr; - - _cairo_gstate_backend_to_user_distance (cr->gstate, dx, dy); -} - -static void -_cairo_default_context_user_to_backend (void *abstract_cr, - double *x, - double *y) -{ - cairo_default_context_t *cr = abstract_cr; - - _cairo_gstate_user_to_backend (cr->gstate, x, y); -} - -static void -_cairo_default_context_user_to_backend_distance (void *abstract_cr, - double *dx, - double *dy) -{ - cairo_default_context_t *cr = abstract_cr; - - _cairo_gstate_user_to_backend_distance (cr->gstate, dx, dy); -} - -/* Path constructor */ - -static cairo_status_t -_cairo_default_context_new_path (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - _cairo_path_fixed_fini (cr->path); - _cairo_path_fixed_init (cr->path); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_default_context_new_sub_path (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - _cairo_path_fixed_new_sub_path (cr->path); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_default_context_move_to (void *abstract_cr, double x, double y) -{ - cairo_default_context_t *cr = abstract_cr; - cairo_fixed_t x_fixed, y_fixed; - - _cairo_gstate_user_to_backend (cr->gstate, &x, &y); - x_fixed = _cairo_fixed_from_double (x); - y_fixed = _cairo_fixed_from_double (y); - - return _cairo_path_fixed_move_to (cr->path, x_fixed, y_fixed); -} - -static cairo_status_t -_cairo_default_context_line_to (void *abstract_cr, double x, double y) -{ - cairo_default_context_t *cr = abstract_cr; - cairo_fixed_t x_fixed, y_fixed; - - _cairo_gstate_user_to_backend (cr->gstate, &x, &y); - x_fixed = _cairo_fixed_from_double (x); - y_fixed = _cairo_fixed_from_double (y); - - return _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed); -} - -static cairo_status_t -_cairo_default_context_curve_to (void *abstract_cr, - double x1, double y1, - double x2, double y2, - double x3, double y3) -{ - cairo_default_context_t *cr = abstract_cr; - cairo_fixed_t x1_fixed, y1_fixed; - cairo_fixed_t x2_fixed, y2_fixed; - cairo_fixed_t x3_fixed, y3_fixed; - - _cairo_gstate_user_to_backend (cr->gstate, &x1, &y1); - _cairo_gstate_user_to_backend (cr->gstate, &x2, &y2); - _cairo_gstate_user_to_backend (cr->gstate, &x3, &y3); - - x1_fixed = _cairo_fixed_from_double (x1); - y1_fixed = _cairo_fixed_from_double (y1); - - x2_fixed = _cairo_fixed_from_double (x2); - y2_fixed = _cairo_fixed_from_double (y2); - - x3_fixed = _cairo_fixed_from_double (x3); - y3_fixed = _cairo_fixed_from_double (y3); - - return _cairo_path_fixed_curve_to (cr->path, - x1_fixed, y1_fixed, - x2_fixed, y2_fixed, - x3_fixed, y3_fixed); -} - -static cairo_status_t -_cairo_default_context_arc (void *abstract_cr, - double xc, double yc, double radius, - double angle1, double angle2, - cairo_bool_t forward) -{ - cairo_default_context_t *cr = abstract_cr; - cairo_status_t status; - - /* Do nothing, successfully, if radius is <= 0 */ - if (radius <= 0.0) { - cairo_fixed_t x_fixed, y_fixed; - - _cairo_gstate_user_to_backend (cr->gstate, &xc, &yc); - x_fixed = _cairo_fixed_from_double (xc); - y_fixed = _cairo_fixed_from_double (yc); - status = _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed); - if (unlikely (status)) - return status; - - status = _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed); - if (unlikely (status)) - return status; - - return CAIRO_STATUS_SUCCESS; - } - - status = _cairo_default_context_line_to (cr, - xc + radius * cos (angle1), - yc + radius * sin (angle1)); - - if (unlikely (status)) - return status; - - if (forward) - _cairo_arc_path (&cr->base, xc, yc, radius, angle1, angle2); - else - _cairo_arc_path_negative (&cr->base, xc, yc, radius, angle1, angle2); - - return CAIRO_STATUS_SUCCESS; /* any error will have already been set on cr */ -} - -static cairo_status_t -_cairo_default_context_rel_move_to (void *abstract_cr, double dx, double dy) -{ - cairo_default_context_t *cr = abstract_cr; - cairo_fixed_t dx_fixed, dy_fixed; - - _cairo_gstate_user_to_backend_distance (cr->gstate, &dx, &dy); - - dx_fixed = _cairo_fixed_from_double (dx); - dy_fixed = _cairo_fixed_from_double (dy); - - return _cairo_path_fixed_rel_move_to (cr->path, dx_fixed, dy_fixed); -} - -static cairo_status_t -_cairo_default_context_rel_line_to (void *abstract_cr, double dx, double dy) -{ - cairo_default_context_t *cr = abstract_cr; - cairo_fixed_t dx_fixed, dy_fixed; - - _cairo_gstate_user_to_backend_distance (cr->gstate, &dx, &dy); - - dx_fixed = _cairo_fixed_from_double (dx); - dy_fixed = _cairo_fixed_from_double (dy); - - return _cairo_path_fixed_rel_line_to (cr->path, dx_fixed, dy_fixed); -} - - -static cairo_status_t -_cairo_default_context_rel_curve_to (void *abstract_cr, - double dx1, double dy1, - double dx2, double dy2, - double dx3, double dy3) -{ - cairo_default_context_t *cr = abstract_cr; - cairo_fixed_t dx1_fixed, dy1_fixed; - cairo_fixed_t dx2_fixed, dy2_fixed; - cairo_fixed_t dx3_fixed, dy3_fixed; - - _cairo_gstate_user_to_backend_distance (cr->gstate, &dx1, &dy1); - _cairo_gstate_user_to_backend_distance (cr->gstate, &dx2, &dy2); - _cairo_gstate_user_to_backend_distance (cr->gstate, &dx3, &dy3); - - dx1_fixed = _cairo_fixed_from_double (dx1); - dy1_fixed = _cairo_fixed_from_double (dy1); - - dx2_fixed = _cairo_fixed_from_double (dx2); - dy2_fixed = _cairo_fixed_from_double (dy2); - - dx3_fixed = _cairo_fixed_from_double (dx3); - dy3_fixed = _cairo_fixed_from_double (dy3); - - return _cairo_path_fixed_rel_curve_to (cr->path, - dx1_fixed, dy1_fixed, - dx2_fixed, dy2_fixed, - dx3_fixed, dy3_fixed); -} - -static cairo_status_t -_cairo_default_context_close_path (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_path_fixed_close_path (cr->path); -} - -static cairo_status_t -_cairo_default_context_rectangle (void *abstract_cr, - double x, double y, - double width, double height) -{ - cairo_default_context_t *cr = abstract_cr; - cairo_status_t status; - - status = _cairo_default_context_move_to (cr, x, y); - if (unlikely (status)) - return status; - - status = _cairo_default_context_rel_line_to (cr, width, 0); - if (unlikely (status)) - return status; - - status = _cairo_default_context_rel_line_to (cr, 0, height); - if (unlikely (status)) - return status; - - status = _cairo_default_context_rel_line_to (cr, -width, 0); - if (unlikely (status)) - return status; - - return _cairo_default_context_close_path (cr); -} - -static void -_cairo_default_context_path_extents (void *abstract_cr, - double *x1, - double *y1, - double *x2, - double *y2) -{ - cairo_default_context_t *cr = abstract_cr; - - _cairo_gstate_path_extents (cr->gstate, - cr->path, - x1, y1, x2, y2); -} - -static cairo_bool_t -_cairo_default_context_has_current_point (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - return cr->path->has_current_point; -} - -static cairo_bool_t -_cairo_default_context_get_current_point (void *abstract_cr, - double *x, - double *y) -{ - cairo_default_context_t *cr = abstract_cr; - cairo_fixed_t x_fixed, y_fixed; - - if (_cairo_path_fixed_get_current_point (cr->path, &x_fixed, &y_fixed)) - { - *x = _cairo_fixed_to_double (x_fixed); - *y = _cairo_fixed_to_double (y_fixed); - _cairo_gstate_backend_to_user (cr->gstate, x, y); - - return TRUE; - } - else - { - return FALSE; - } -} - -static cairo_path_t * -_cairo_default_context_copy_path (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_path_create (cr->path, &cr->base); -} - -static cairo_path_t * -_cairo_default_context_copy_path_flat (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_path_create_flat (cr->path, &cr->base); -} - -static cairo_status_t -_cairo_default_context_append_path (void *abstract_cr, - const cairo_path_t *path) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_path_append_to_context (path, &cr->base); -} - -static cairo_status_t -_cairo_default_context_paint (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_paint (cr->gstate); -} - -static cairo_status_t -_cairo_default_context_paint_with_alpha (void *abstract_cr, - double alpha) -{ - cairo_default_context_t *cr = abstract_cr; - cairo_solid_pattern_t pattern; - cairo_status_t status; - cairo_color_t color; - - if (CAIRO_ALPHA_IS_OPAQUE (alpha)) - return _cairo_gstate_paint (cr->gstate); - - if (CAIRO_ALPHA_IS_ZERO (alpha) && - _cairo_operator_bounded_by_mask (cr->gstate->op)) { - return CAIRO_STATUS_SUCCESS; - } - - _cairo_color_init_rgba (&color, 0., 0., 0., alpha); - _cairo_pattern_init_solid (&pattern, &color); - - status = _cairo_gstate_mask (cr->gstate, &pattern.base); - _cairo_pattern_fini (&pattern.base); - - return status; -} - -static cairo_status_t -_cairo_default_context_mask (void *abstract_cr, - cairo_pattern_t *mask) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_mask (cr->gstate, mask); -} - -static cairo_status_t -_cairo_default_context_stroke_preserve (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_stroke (cr->gstate, cr->path); -} - -static cairo_status_t -_cairo_default_context_stroke (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - cairo_status_t status; - - status = _cairo_gstate_stroke (cr->gstate, cr->path); - if (unlikely (status)) - return status; - - return _cairo_default_context_new_path (cr); -} - -static cairo_status_t -_cairo_default_context_in_stroke (void *abstract_cr, - double x, double y, - cairo_bool_t *inside) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_in_stroke (cr->gstate, - cr->path, - x, y, - inside); -} - -static cairo_status_t -_cairo_default_context_stroke_extents (void *abstract_cr, - double *x1, double *y1, double *x2, double *y2) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_stroke_extents (cr->gstate, - cr->path, - x1, y1, x2, y2); -} - -static cairo_status_t -_cairo_default_context_fill_preserve (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_fill (cr->gstate, cr->path); -} - -static cairo_status_t -_cairo_default_context_fill (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - cairo_status_t status; - - status = _cairo_gstate_fill (cr->gstate, cr->path); - if (unlikely (status)) - return status; - - return _cairo_default_context_new_path (cr); -} - -static cairo_status_t -_cairo_default_context_in_fill (void *abstract_cr, - double x, double y, - cairo_bool_t *inside) -{ - cairo_default_context_t *cr = abstract_cr; - - *inside = _cairo_gstate_in_fill (cr->gstate, - cr->path, - x, y); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_default_context_fill_extents (void *abstract_cr, - double *x1, double *y1, double *x2, double *y2) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_fill_extents (cr->gstate, - cr->path, - x1, y1, x2, y2); -} - -static cairo_status_t -_cairo_default_context_clip_preserve (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_clip (cr->gstate, cr->path); -} - -static cairo_status_t -_cairo_default_context_clip (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - cairo_status_t status; - - status = _cairo_gstate_clip (cr->gstate, cr->path); - if (unlikely (status)) - return status; - - return _cairo_default_context_new_path (cr); -} - -static cairo_status_t -_cairo_default_context_in_clip (void *abstract_cr, - double x, double y, - cairo_bool_t *inside) -{ - cairo_default_context_t *cr = abstract_cr; - - *inside = _cairo_gstate_in_clip (cr->gstate, x, y); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_default_context_reset_clip (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_reset_clip (cr->gstate); -} - -static cairo_status_t -_cairo_default_context_clip_extents (void *abstract_cr, - double *x1, double *y1, double *x2, double *y2) -{ - cairo_default_context_t *cr = abstract_cr; - - if (! _cairo_gstate_clip_extents (cr->gstate, x1, y1, x2, y2)) { - *x1 = -INFINITY; - *y1 = -INFINITY; - *x2 = +INFINITY; - *y2 = +INFINITY; - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_rectangle_list_t * -_cairo_default_context_copy_clip_rectangle_list (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_copy_clip_rectangle_list (cr->gstate); -} - -static cairo_status_t -_cairo_default_context_copy_page (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_copy_page (cr->gstate); -} - -static cairo_status_t -_cairo_default_context_show_page (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_show_page (cr->gstate); -} - -static cairo_status_t -_cairo_default_context_set_font_face (void *abstract_cr, - cairo_font_face_t *font_face) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_set_font_face (cr->gstate, font_face); -} - -static cairo_font_face_t * -_cairo_default_context_get_font_face (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - cairo_font_face_t *font_face; - cairo_status_t status; - - status = _cairo_gstate_get_font_face (cr->gstate, &font_face); - if (unlikely (status)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_font_face_t *) &_cairo_font_face_nil; - } - - return font_face; -} - -static cairo_status_t -_cairo_default_context_font_extents (void *abstract_cr, - cairo_font_extents_t *extents) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_get_font_extents (cr->gstate, extents); -} - -static cairo_status_t -_cairo_default_context_set_font_size (void *abstract_cr, - double size) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_set_font_size (cr->gstate, size); -} - -static cairo_status_t -_cairo_default_context_set_font_matrix (void *abstract_cr, - const cairo_matrix_t *matrix) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_set_font_matrix (cr->gstate, matrix); -} - -static void -_cairo_default_context_get_font_matrix (void *abstract_cr, - cairo_matrix_t *matrix) -{ - cairo_default_context_t *cr = abstract_cr; - - _cairo_gstate_get_font_matrix (cr->gstate, matrix); -} - -static cairo_status_t -_cairo_default_context_set_font_options (void *abstract_cr, - const cairo_font_options_t *options) -{ - cairo_default_context_t *cr = abstract_cr; - - _cairo_gstate_set_font_options (cr->gstate, options); - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_default_context_get_font_options (void *abstract_cr, - cairo_font_options_t *options) -{ - cairo_default_context_t *cr = abstract_cr; - - _cairo_gstate_get_font_options (cr->gstate, options); -} - -static cairo_status_t -_cairo_default_context_set_scaled_font (void *abstract_cr, - cairo_scaled_font_t *scaled_font) -{ - cairo_default_context_t *cr = abstract_cr; - cairo_bool_t was_previous; - cairo_status_t status; - - if (scaled_font == cr->gstate->scaled_font) - return CAIRO_STATUS_SUCCESS; - - was_previous = scaled_font == cr->gstate->previous_scaled_font; - - status = _cairo_gstate_set_font_face (cr->gstate, scaled_font->font_face); - if (unlikely (status)) - return status; - - status = _cairo_gstate_set_font_matrix (cr->gstate, &scaled_font->font_matrix); - if (unlikely (status)) - return status; - - _cairo_gstate_set_font_options (cr->gstate, &scaled_font->options); - - if (was_previous) - cr->gstate->scaled_font = cairo_scaled_font_reference (scaled_font); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_scaled_font_t * -_cairo_default_context_get_scaled_font (void *abstract_cr) -{ - cairo_default_context_t *cr = abstract_cr; - cairo_scaled_font_t *scaled_font; - cairo_status_t status; - - status = _cairo_gstate_get_scaled_font (cr->gstate, &scaled_font); - if (unlikely (status)) - return _cairo_scaled_font_create_in_error (status); - - return scaled_font; -} - -static cairo_status_t -_cairo_default_context_glyphs (void *abstract_cr, - const cairo_glyph_t *glyphs, - int num_glyphs, - cairo_glyph_text_info_t *info) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_show_text_glyphs (cr->gstate, glyphs, num_glyphs, info); -} - -static cairo_status_t -_cairo_default_context_glyph_path (void *abstract_cr, - const cairo_glyph_t *glyphs, - int num_glyphs) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_glyph_path (cr->gstate, - glyphs, num_glyphs, - cr->path); -} - -static cairo_status_t -_cairo_default_context_glyph_extents (void *abstract_cr, - const cairo_glyph_t *glyphs, - int num_glyphs, - cairo_text_extents_t *extents) -{ - cairo_default_context_t *cr = abstract_cr; - - return _cairo_gstate_glyph_extents (cr->gstate, glyphs, num_glyphs, extents); -} - -static const cairo_backend_t _cairo_default_context_backend = { - CAIRO_TYPE_DEFAULT, - _cairo_default_context_destroy, - - _cairo_default_context_get_original_target, - _cairo_default_context_get_current_target, - - _cairo_default_context_save, - _cairo_default_context_restore, - - _cairo_default_context_push_group, - _cairo_default_context_pop_group, - - _cairo_default_context_set_source_rgba, - _cairo_default_context_set_source_surface, - _cairo_default_context_set_source, - _cairo_default_context_get_source, - - _cairo_default_context_set_antialias, - _cairo_default_context_set_dash, - _cairo_default_context_set_fill_rule, - _cairo_default_context_set_line_cap, - _cairo_default_context_set_line_join, - _cairo_default_context_set_line_width, - _cairo_default_context_set_miter_limit, - _cairo_default_context_set_opacity, - _cairo_default_context_set_operator, - _cairo_default_context_set_tolerance, - _cairo_default_context_get_antialias, - _cairo_default_context_get_dash, - _cairo_default_context_get_fill_rule, - _cairo_default_context_get_line_cap, - _cairo_default_context_get_line_join, - _cairo_default_context_get_line_width, - _cairo_default_context_get_miter_limit, - _cairo_default_context_get_opacity, - _cairo_default_context_get_operator, - _cairo_default_context_get_tolerance, - - _cairo_default_context_translate, - _cairo_default_context_scale, - _cairo_default_context_rotate, - _cairo_default_context_transform, - _cairo_default_context_set_matrix, - _cairo_default_context_set_identity_matrix, - _cairo_default_context_get_matrix, - - _cairo_default_context_user_to_device, - _cairo_default_context_user_to_device_distance, - _cairo_default_context_device_to_user, - _cairo_default_context_device_to_user_distance, - - _cairo_default_context_user_to_backend, - _cairo_default_context_user_to_backend_distance, - _cairo_default_context_backend_to_user, - _cairo_default_context_backend_to_user_distance, - - _cairo_default_context_new_path, - _cairo_default_context_new_sub_path, - _cairo_default_context_move_to, - _cairo_default_context_rel_move_to, - _cairo_default_context_line_to, - _cairo_default_context_rel_line_to, - _cairo_default_context_curve_to, - _cairo_default_context_rel_curve_to, - NULL, /* arc-to */ - NULL, /* rel-arc-to */ - _cairo_default_context_close_path, - _cairo_default_context_arc, - _cairo_default_context_rectangle, - _cairo_default_context_path_extents, - _cairo_default_context_has_current_point, - _cairo_default_context_get_current_point, - _cairo_default_context_copy_path, - _cairo_default_context_copy_path_flat, - _cairo_default_context_append_path, - - NULL, /* stroke-to-path */ - - _cairo_default_context_clip, - _cairo_default_context_clip_preserve, - _cairo_default_context_in_clip, - _cairo_default_context_clip_extents, - _cairo_default_context_reset_clip, - _cairo_default_context_copy_clip_rectangle_list, - - _cairo_default_context_paint, - _cairo_default_context_paint_with_alpha, - _cairo_default_context_mask, - - _cairo_default_context_stroke, - _cairo_default_context_stroke_preserve, - _cairo_default_context_in_stroke, - _cairo_default_context_stroke_extents, - - _cairo_default_context_fill, - _cairo_default_context_fill_preserve, - _cairo_default_context_in_fill, - _cairo_default_context_fill_extents, - - _cairo_default_context_set_font_face, - _cairo_default_context_get_font_face, - _cairo_default_context_set_font_size, - _cairo_default_context_set_font_matrix, - _cairo_default_context_get_font_matrix, - _cairo_default_context_set_font_options, - _cairo_default_context_get_font_options, - _cairo_default_context_set_scaled_font, - _cairo_default_context_get_scaled_font, - _cairo_default_context_font_extents, - - _cairo_default_context_glyphs, - _cairo_default_context_glyph_path, - _cairo_default_context_glyph_extents, - - _cairo_default_context_copy_page, - _cairo_default_context_show_page, -}; - -cairo_status_t -_cairo_default_context_init (cairo_default_context_t *cr, void *target) -{ - _cairo_init (&cr->base, &_cairo_default_context_backend); - _cairo_path_fixed_init (cr->path); - - cr->gstate = &cr->gstate_tail[0]; - cr->gstate_freelist = &cr->gstate_tail[1]; - cr->gstate_tail[1].next = NULL; - - return _cairo_gstate_init (cr->gstate, target); -} - -cairo_t * -_cairo_default_context_create (void *target) -{ - cairo_default_context_t *cr; - cairo_status_t status; - - cr = _freed_pool_get (&context_pool); - if (unlikely (cr == NULL)) { - cr = malloc (sizeof (cairo_default_context_t)); - if (unlikely (cr == NULL)) - return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - status = _cairo_default_context_init (cr, target); - if (unlikely (status)) { - _freed_pool_put (&context_pool, cr); - return _cairo_create_in_error (status); - } - - return &cr->base; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-deflate-stream.c b/source/libs/cairo/cairo-src/src/cairo-deflate-stream.c deleted file mode 100644 index ae23bda9472a5b2440a19db9e9bba5a063d3ad1e..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-deflate-stream.c +++ /dev/null @@ -1,156 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2006 Adrian Johnson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Adrian Johnson. - * - * Author(s): - * Adrian Johnson <ajohnson@redneon.com> - */ - -#include "cairoint.h" - -#if CAIRO_HAS_DEFLATE_STREAM - -#include "cairo-error-private.h" -#include "cairo-output-stream-private.h" -#include <zlib.h> - -#define BUFFER_SIZE 16384 - -typedef struct _cairo_deflate_stream { - cairo_output_stream_t base; - cairo_output_stream_t *output; - z_stream zlib_stream; - unsigned char input_buf[BUFFER_SIZE]; - unsigned char output_buf[BUFFER_SIZE]; -} cairo_deflate_stream_t; - -static void -cairo_deflate_stream_deflate (cairo_deflate_stream_t *stream, cairo_bool_t flush) -{ - int ret; - cairo_bool_t finished; - - do { - ret = deflate (&stream->zlib_stream, flush ? Z_FINISH : Z_NO_FLUSH); - if (flush || stream->zlib_stream.avail_out == 0) - { - _cairo_output_stream_write (stream->output, - stream->output_buf, - BUFFER_SIZE - stream->zlib_stream.avail_out); - stream->zlib_stream.next_out = stream->output_buf; - stream->zlib_stream.avail_out = BUFFER_SIZE; - } - - finished = TRUE; - if (stream->zlib_stream.avail_in != 0) - finished = FALSE; - if (flush && ret != Z_STREAM_END) - finished = FALSE; - - } while (!finished); - - stream->zlib_stream.next_in = stream->input_buf; -} - -static cairo_status_t -_cairo_deflate_stream_write (cairo_output_stream_t *base, - const unsigned char *data, - unsigned int length) -{ - cairo_deflate_stream_t *stream = (cairo_deflate_stream_t *) base; - unsigned int count; - const unsigned char *p = data; - - while (length) { - count = length; - if (count > BUFFER_SIZE - stream->zlib_stream.avail_in) - count = BUFFER_SIZE - stream->zlib_stream.avail_in; - memcpy (stream->input_buf + stream->zlib_stream.avail_in, p, count); - p += count; - stream->zlib_stream.avail_in += count; - length -= count; - - if (stream->zlib_stream.avail_in == BUFFER_SIZE) - cairo_deflate_stream_deflate (stream, FALSE); - } - - return _cairo_output_stream_get_status (stream->output); -} - -static cairo_status_t -_cairo_deflate_stream_close (cairo_output_stream_t *base) -{ - cairo_deflate_stream_t *stream = (cairo_deflate_stream_t *) base; - - cairo_deflate_stream_deflate (stream, TRUE); - deflateEnd (&stream->zlib_stream); - - return _cairo_output_stream_get_status (stream->output); -} - -cairo_output_stream_t * -_cairo_deflate_stream_create (cairo_output_stream_t *output) -{ - cairo_deflate_stream_t *stream; - - if (output->status) - return _cairo_output_stream_create_in_error (output->status); - - stream = malloc (sizeof (cairo_deflate_stream_t)); - if (unlikely (stream == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_output_stream_t *) &_cairo_output_stream_nil; - } - - _cairo_output_stream_init (&stream->base, - _cairo_deflate_stream_write, - NULL, - _cairo_deflate_stream_close); - stream->output = output; - - stream->zlib_stream.zalloc = Z_NULL; - stream->zlib_stream.zfree = Z_NULL; - stream->zlib_stream.opaque = Z_NULL; - - if (deflateInit (&stream->zlib_stream, Z_DEFAULT_COMPRESSION) != Z_OK) { - free (stream); - return (cairo_output_stream_t *) &_cairo_output_stream_nil; - } - - stream->zlib_stream.next_in = stream->input_buf; - stream->zlib_stream.avail_in = 0; - stream->zlib_stream.next_out = stream->output_buf; - stream->zlib_stream.avail_out = BUFFER_SIZE; - - return &stream->base; -} - -#endif /* CAIRO_HAS_DEFLATE_STREAM */ diff --git a/source/libs/cairo/cairo-src/src/cairo-deprecated.h b/source/libs/cairo/cairo-src/src/cairo-deprecated.h deleted file mode 100644 index 7a56aadbfe18a7cf8216cd89db5367494727936b..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-deprecated.h +++ /dev/null @@ -1,123 +0,0 @@ -/* 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - */ - -#ifndef CAIRO_DEPRECATED_H -#define CAIRO_DEPRECATED_H - -#define CAIRO_FONT_TYPE_ATSUI CAIRO_FONT_TYPE_QUARTZ - -/* Obsolete functions. These definitions exist to coerce the compiler - * into providing a little bit of guidance with its error - * messages. The idea is to help users port their old code without - * having to dig through lots of documentation. - * - * The first set of REPLACED_BY functions is for functions whose names - * have just been changed. So fixing these up is mechanical, (and - * automated by means of the cairo/util/cairo-api-update script. - * - * The second set of DEPRECATED_BY functions is for functions where - * the replacement is used in a different way, (ie. different - * arguments, multiple functions instead of one, etc). Fixing these up - * will require a bit more work on the user's part, (and hopefully we - * can get cairo-api-update to find these and print some guiding - * information). - */ -#define cairo_current_font_extents cairo_current_font_extents_REPLACED_BY_cairo_font_extents -#define cairo_get_font_extents cairo_get_font_extents_REPLACED_BY_cairo_font_extents -#define cairo_current_operator cairo_current_operator_REPLACED_BY_cairo_get_operator -#define cairo_current_tolerance cairo_current_tolerance_REPLACED_BY_cairo_get_tolerance -#define cairo_current_point cairo_current_point_REPLACED_BY_cairo_get_current_point -#define cairo_current_fill_rule cairo_current_fill_rule_REPLACED_BY_cairo_get_fill_rule -#define cairo_current_line_width cairo_current_line_width_REPLACED_BY_cairo_get_line_width -#define cairo_current_line_cap cairo_current_line_cap_REPLACED_BY_cairo_get_line_cap -#define cairo_current_line_join cairo_current_line_join_REPLACED_BY_cairo_get_line_join -#define cairo_current_miter_limit cairo_current_miter_limit_REPLACED_BY_cairo_get_miter_limit -#define cairo_current_matrix cairo_current_matrix_REPLACED_BY_cairo_get_matrix -#define cairo_current_target_surface cairo_current_target_surface_REPLACED_BY_cairo_get_target -#define cairo_get_status cairo_get_status_REPLACED_BY_cairo_status -#define cairo_concat_matrix cairo_concat_matrix_REPLACED_BY_cairo_transform -#define cairo_scale_font cairo_scale_font_REPLACED_BY_cairo_set_font_size -#define cairo_select_font cairo_select_font_REPLACED_BY_cairo_select_font_face -#define cairo_transform_font cairo_transform_font_REPLACED_BY_cairo_set_font_matrix -#define cairo_transform_point cairo_transform_point_REPLACED_BY_cairo_user_to_device -#define cairo_transform_distance cairo_transform_distance_REPLACED_BY_cairo_user_to_device_distance -#define cairo_inverse_transform_point cairo_inverse_transform_point_REPLACED_BY_cairo_device_to_user -#define cairo_inverse_transform_distance cairo_inverse_transform_distance_REPLACED_BY_cairo_device_to_user_distance -#define cairo_init_clip cairo_init_clip_REPLACED_BY_cairo_reset_clip -#define cairo_surface_create_for_image cairo_surface_create_for_image_REPLACED_BY_cairo_image_surface_create_for_data -#define cairo_default_matrix cairo_default_matrix_REPLACED_BY_cairo_identity_matrix -#define cairo_matrix_set_affine cairo_matrix_set_affine_REPLACED_BY_cairo_matrix_init -#define cairo_matrix_set_identity cairo_matrix_set_identity_REPLACED_BY_cairo_matrix_init_identity -#define cairo_pattern_add_color_stop cairo_pattern_add_color_stop_REPLACED_BY_cairo_pattern_add_color_stop_rgba -#define cairo_set_rgb_color cairo_set_rgb_color_REPLACED_BY_cairo_set_source_rgb -#define cairo_set_pattern cairo_set_pattern_REPLACED_BY_cairo_set_source -#define cairo_xlib_surface_create_for_pixmap_with_visual cairo_xlib_surface_create_for_pixmap_with_visual_REPLACED_BY_cairo_xlib_surface_create -#define cairo_xlib_surface_create_for_window_with_visual cairo_xlib_surface_create_for_window_with_visual_REPLACED_BY_cairo_xlib_surface_create -#define cairo_xcb_surface_create_for_pixmap_with_visual cairo_xcb_surface_create_for_pixmap_with_visual_REPLACED_BY_cairo_xcb_surface_create -#define cairo_xcb_surface_create_for_window_with_visual cairo_xcb_surface_create_for_window_with_visual_REPLACED_BY_cairo_xcb_surface_create -#define cairo_ps_surface_set_dpi cairo_ps_surface_set_dpi_REPLACED_BY_cairo_surface_set_fallback_resolution -#define cairo_pdf_surface_set_dpi cairo_pdf_surface_set_dpi_REPLACED_BY_cairo_surface_set_fallback_resolution -#define cairo_svg_surface_set_dpi cairo_svg_surface_set_dpi_REPLACED_BY_cairo_surface_set_fallback_resolution -#define cairo_atsui_font_face_create_for_atsu_font_id cairo_atsui_font_face_create_for_atsu_font_id_REPLACED_BY_cairo_quartz_font_face_create_for_atsu_font_id - -#define cairo_current_path cairo_current_path_DEPRECATED_BY_cairo_copy_path -#define cairo_current_path_flat cairo_current_path_flat_DEPRECATED_BY_cairo_copy_path_flat -#define cairo_get_path cairo_get_path_DEPRECATED_BY_cairo_copy_path -#define cairo_get_path_flat cairo_get_path_flat_DEPRECATED_BY_cairo_get_path_flat -#define cairo_set_alpha cairo_set_alpha_DEPRECATED_BY_cairo_set_source_rgba_OR_cairo_paint_with_alpha -#define cairo_show_surface cairo_show_surface_DEPRECATED_BY_cairo_set_source_surface_AND_cairo_paint -#define cairo_copy cairo_copy_DEPRECATED_BY_cairo_create_AND_MANY_INDIVIDUAL_FUNCTIONS -#define cairo_surface_set_repeat cairo_surface_set_repeat_DEPRECATED_BY_cairo_pattern_set_extend -#define cairo_surface_set_matrix cairo_surface_set_matrix_DEPRECATED_BY_cairo_pattern_set_matrix -#define cairo_surface_get_matrix cairo_surface_get_matrix_DEPRECATED_BY_cairo_pattern_get_matrix -#define cairo_surface_set_filter cairo_surface_set_filter_DEPRECATED_BY_cairo_pattern_set_filter -#define cairo_surface_get_filter cairo_surface_get_filter_DEPRECATED_BY_cairo_pattern_get_filter -#define cairo_matrix_create cairo_matrix_create_DEPRECATED_BY_cairo_matrix_t -#define cairo_matrix_destroy cairo_matrix_destroy_DEPRECATED_BY_cairo_matrix_t -#define cairo_matrix_copy cairo_matrix_copy_DEPRECATED_BY_cairo_matrix_t -#define cairo_matrix_get_affine cairo_matrix_get_affine_DEPRECATED_BY_cairo_matrix_t -#define cairo_set_target_surface cairo_set_target_surface_DEPRECATED_BY_cairo_create -#define cairo_set_target_image cairo_set_target_image_DEPRECATED_BY_cairo_image_surface_create_for_data -#define cairo_set_target_pdf cairo_set_target_pdf_DEPRECATED_BY_cairo_pdf_surface_create -#define cairo_set_target_png cairo_set_target_png_DEPRECATED_BY_cairo_surface_write_to_png -#define cairo_set_target_ps cairo_set_target_ps_DEPRECATED_BY_cairo_ps_surface_create -#define cairo_set_target_quartz cairo_set_target_quartz_DEPRECATED_BY_cairo_quartz_surface_create -#define cairo_set_target_win32 cairo_set_target_win32_DEPRECATED_BY_cairo_win32_surface_create -#define cairo_set_target_xcb cairo_set_target_xcb_DEPRECATED_BY_cairo_xcb_surface_create -#define cairo_set_target_drawable cairo_set_target_drawable_DEPRECATED_BY_cairo_xlib_surface_create -#define cairo_get_status_string cairo_get_status_string_DEPRECATED_BY_cairo_status_AND_cairo_status_to_string -#define cairo_status_string cairo_status_string_DEPRECATED_BY_cairo_status_AND_cairo_status_to_string - -#endif /* CAIRO_DEPRECATED_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-device-private.h b/source/libs/cairo/cairo-src/src/cairo-device-private.h deleted file mode 100644 index 6eb44f3b634300185b967a585a644c10e86d1ceb..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-device-private.h +++ /dev/null @@ -1,86 +0,0 @@ -/* Cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Intel Corporation. - * - * Contributors(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef _CAIRO_DEVICE_PRIVATE_H_ -#define _CAIRO_DEVICE_PRIVATE_H_ - -#include "cairo-compiler-private.h" -#include "cairo-mutex-private.h" -#include "cairo-reference-count-private.h" -#include "cairo-types-private.h" - -struct _cairo_device { - cairo_reference_count_t ref_count; - cairo_status_t status; - cairo_user_data_array_t user_data; - - const cairo_device_backend_t *backend; - - cairo_recursive_mutex_t mutex; - unsigned mutex_depth; - - cairo_bool_t finished; -}; - -struct _cairo_device_backend { - cairo_device_type_t type; - - void (*lock) (void *device); - void (*unlock) (void *device); - - cairo_warn cairo_status_t (*flush) (void *device); - void (*finish) (void *device); - void (*destroy) (void *device); -}; - -cairo_private cairo_device_t * -_cairo_device_create_in_error (cairo_status_t status); - -cairo_private void -_cairo_device_init (cairo_device_t *device, - const cairo_device_backend_t *backend); - -cairo_private cairo_status_t -_cairo_device_set_error (cairo_device_t *device, - cairo_status_t error); - -slim_hidden_proto_no_warn (cairo_device_reference); -slim_hidden_proto (cairo_device_acquire); -slim_hidden_proto (cairo_device_release); -slim_hidden_proto (cairo_device_flush); -slim_hidden_proto (cairo_device_finish); -slim_hidden_proto (cairo_device_destroy); - -#endif /* _CAIRO_DEVICE_PRIVATE_H_ */ diff --git a/source/libs/cairo/cairo-src/src/cairo-device.c b/source/libs/cairo/cairo-src/src/cairo-device.c deleted file mode 100644 index 585a9c1c41f98f76caee56eebb8ccd072fe0b80a..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-device.c +++ /dev/null @@ -1,541 +0,0 @@ -/* Cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Intel Corporation. - * - * Contributors(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" -#include "cairo-device-private.h" -#include "cairo-error-private.h" - -/** - * SECTION:cairo-device - * @Title: cairo_device_t - * @Short_Description: interface to underlying rendering system - * @See_Also: #cairo_surface_t - * - * Devices are the abstraction Cairo employs for the rendering system - * used by a #cairo_surface_t. You can get the device of a surface using - * cairo_surface_get_device(). - * - * Devices are created using custom functions specific to the rendering - * system you want to use. See the documentation for the surface types - * for those functions. - * - * An important function that devices fulfill is sharing access to the - * rendering system between Cairo and your application. If you want to - * access a device directly that you used to draw to with Cairo, you must - * first call cairo_device_flush() to ensure that Cairo finishes all - * operations on the device and resets it to a clean state. - * - * Cairo also provides the functions cairo_device_acquire() and - * cairo_device_release() to synchronize access to the rendering system - * in a multithreaded environment. This is done internally, but can also - * be used by applications. - * - * Putting this all together, a function that works with devices should - * look something like this: - * <informalexample><programlisting> - * void - * my_device_modifying_function (cairo_device_t *device) - * { - * cairo_status_t status; - * - * // Ensure the device is properly reset - * cairo_device_flush (device); - * // Try to acquire the device - * status = cairo_device_acquire (device); - * if (status != CAIRO_STATUS_SUCCESS) { - * printf ("Failed to acquire the device: %s\n", cairo_status_to_string (status)); - * return; - * } - * - * // Do the custom operations on the device here. - * // But do not call any Cairo functions that might acquire devices. - * - * // Release the device when done. - * cairo_device_release (device); - * } - * </programlisting></informalexample> - * - * <note><para>Please refer to the documentation of each backend for - * additional usage requirements, guarantees provided, and - * interactions with existing surface API of the device functions for - * surfaces of that type. - * </para></note> - **/ - -static const cairo_device_t _nil_device = { - CAIRO_REFERENCE_COUNT_INVALID, - CAIRO_STATUS_NO_MEMORY, -}; - -static const cairo_device_t _mismatch_device = { - CAIRO_REFERENCE_COUNT_INVALID, - CAIRO_STATUS_DEVICE_TYPE_MISMATCH, -}; - -static const cairo_device_t _invalid_device = { - CAIRO_REFERENCE_COUNT_INVALID, - CAIRO_STATUS_DEVICE_ERROR, -}; - -cairo_device_t * -_cairo_device_create_in_error (cairo_status_t status) -{ - switch (status) { - case CAIRO_STATUS_NO_MEMORY: - return (cairo_device_t *) &_nil_device; - case CAIRO_STATUS_DEVICE_ERROR: - return (cairo_device_t *) &_invalid_device; - case CAIRO_STATUS_DEVICE_TYPE_MISMATCH: - return (cairo_device_t *) &_mismatch_device; - - case CAIRO_STATUS_SUCCESS: - case CAIRO_STATUS_LAST_STATUS: - ASSERT_NOT_REACHED; - /* fall-through */ - case CAIRO_STATUS_SURFACE_TYPE_MISMATCH: - case CAIRO_STATUS_INVALID_STATUS: - case CAIRO_STATUS_INVALID_FORMAT: - case CAIRO_STATUS_INVALID_VISUAL: - case CAIRO_STATUS_READ_ERROR: - case CAIRO_STATUS_WRITE_ERROR: - case CAIRO_STATUS_FILE_NOT_FOUND: - case CAIRO_STATUS_TEMP_FILE_ERROR: - case CAIRO_STATUS_INVALID_STRIDE: - case CAIRO_STATUS_INVALID_SIZE: - case CAIRO_STATUS_INVALID_RESTORE: - case CAIRO_STATUS_INVALID_POP_GROUP: - case CAIRO_STATUS_NO_CURRENT_POINT: - case CAIRO_STATUS_INVALID_MATRIX: - case CAIRO_STATUS_NULL_POINTER: - case CAIRO_STATUS_INVALID_STRING: - case CAIRO_STATUS_INVALID_PATH_DATA: - case CAIRO_STATUS_SURFACE_FINISHED: - case CAIRO_STATUS_PATTERN_TYPE_MISMATCH: - case CAIRO_STATUS_INVALID_DASH: - case CAIRO_STATUS_INVALID_DSC_COMMENT: - case CAIRO_STATUS_INVALID_INDEX: - case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE: - case CAIRO_STATUS_FONT_TYPE_MISMATCH: - case CAIRO_STATUS_USER_FONT_IMMUTABLE: - case CAIRO_STATUS_USER_FONT_ERROR: - case CAIRO_STATUS_NEGATIVE_COUNT: - case CAIRO_STATUS_INVALID_CLUSTERS: - case CAIRO_STATUS_INVALID_SLANT: - case CAIRO_STATUS_INVALID_WEIGHT: - case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: - case CAIRO_STATUS_INVALID_CONTENT: - case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION: - case CAIRO_STATUS_DEVICE_FINISHED: - case CAIRO_STATUS_JBIG2_GLOBAL_MISSING: - default: - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_device_t *) &_nil_device; - } -} - -void -_cairo_device_init (cairo_device_t *device, - const cairo_device_backend_t *backend) -{ - CAIRO_REFERENCE_COUNT_INIT (&device->ref_count, 1); - device->status = CAIRO_STATUS_SUCCESS; - - device->backend = backend; - - CAIRO_RECURSIVE_MUTEX_INIT (device->mutex); - device->mutex_depth = 0; - - device->finished = FALSE; - - _cairo_user_data_array_init (&device->user_data); -} - -/** - * cairo_device_reference: - * @device: a #cairo_device_t - * - * Increases the reference count on @device by one. This prevents - * @device from being destroyed until a matching call to - * cairo_device_destroy() is made. - * - * The number of references to a #cairo_device_t can be get using - * cairo_device_get_reference_count(). - * - * Return value: the referenced #cairo_device_t. - * - * Since: 1.10 - **/ -cairo_device_t * -cairo_device_reference (cairo_device_t *device) -{ - if (device == NULL || - CAIRO_REFERENCE_COUNT_IS_INVALID (&device->ref_count)) - { - return device; - } - - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&device->ref_count)); - _cairo_reference_count_inc (&device->ref_count); - - return device; -} -slim_hidden_def (cairo_device_reference); - -/** - * cairo_device_status: - * @device: a #cairo_device_t - * - * Checks whether an error has previously occurred for this - * device. - * - * Return value: %CAIRO_STATUS_SUCCESS on success or an error code if - * the device is in an error state. - * - * Since: 1.10 - **/ -cairo_status_t -cairo_device_status (cairo_device_t *device) -{ - if (device == NULL) - return CAIRO_STATUS_NULL_POINTER; - - return device->status; -} - -/** - * cairo_device_flush: - * @device: a #cairo_device_t - * - * Finish any pending operations for the device and also restore any - * temporary modifications cairo has made to the device's state. - * This function must be called before switching from using the - * device with Cairo to operating on it directly with native APIs. - * If the device doesn't support direct access, then this function - * does nothing. - * - * This function may acquire devices. - * - * Since: 1.10 - **/ -void -cairo_device_flush (cairo_device_t *device) -{ - cairo_status_t status; - - if (device == NULL || device->status) - return; - - if (device->finished) - return; - - if (device->backend->flush != NULL) { - status = device->backend->flush (device); - if (unlikely (status)) - status = _cairo_device_set_error (device, status); - } -} -slim_hidden_def (cairo_device_flush); - -/** - * cairo_device_finish: - * @device: the #cairo_device_t to finish - * - * This function finishes the device and drops all references to - * external resources. All surfaces, fonts and other objects created - * for this @device will be finished, too. - * Further operations on the @device will not affect the @device but - * will instead trigger a %CAIRO_STATUS_DEVICE_FINISHED error. - * - * When the last call to cairo_device_destroy() decreases the - * reference count to zero, cairo will call cairo_device_finish() if - * it hasn't been called already, before freeing the resources - * associated with the device. - * - * This function may acquire devices. - * - * Since: 1.10 - **/ -void -cairo_device_finish (cairo_device_t *device) -{ - if (device == NULL || - CAIRO_REFERENCE_COUNT_IS_INVALID (&device->ref_count)) - { - return; - } - - if (device->finished) - return; - - cairo_device_flush (device); - - if (device->backend->finish != NULL) - device->backend->finish (device); - - /* We only finish the device after the backend's callback returns because - * the device might still be needed during the callback - * (e.g. for cairo_device_acquire ()). - */ - device->finished = TRUE; -} -slim_hidden_def (cairo_device_finish); - -/** - * cairo_device_destroy: - * @device: a #cairo_device_t - * - * Decreases the reference count on @device by one. If the result is - * zero, then @device and all associated resources are freed. See - * cairo_device_reference(). - * - * This function may acquire devices if the last reference was dropped. - * - * Since: 1.10 - **/ -void -cairo_device_destroy (cairo_device_t *device) -{ - cairo_user_data_array_t user_data; - - if (device == NULL || - CAIRO_REFERENCE_COUNT_IS_INVALID (&device->ref_count)) - { - return; - } - - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&device->ref_count)); - if (! _cairo_reference_count_dec_and_test (&device->ref_count)) - return; - - cairo_device_finish (device); - - assert (device->mutex_depth == 0); - CAIRO_MUTEX_FINI (device->mutex); - - user_data = device->user_data; - - device->backend->destroy (device); - - _cairo_user_data_array_fini (&user_data); - -} -slim_hidden_def (cairo_device_destroy); - -/** - * cairo_device_get_type: - * @device: a #cairo_device_t - * - * This function returns the type of the device. See #cairo_device_type_t - * for available types. - * - * Return value: The type of @device. - * - * Since: 1.10 - **/ -cairo_device_type_t -cairo_device_get_type (cairo_device_t *device) -{ - if (device == NULL || - CAIRO_REFERENCE_COUNT_IS_INVALID (&device->ref_count)) - { - return CAIRO_DEVICE_TYPE_INVALID; - } - - return device->backend->type; -} - -/** - * cairo_device_acquire: - * @device: a #cairo_device_t - * - * Acquires the @device for the current thread. This function will block - * until no other thread has acquired the device. - * - * If the return value is %CAIRO_STATUS_SUCCESS, you successfully acquired the - * device. From now on your thread owns the device and no other thread will be - * able to acquire it until a matching call to cairo_device_release(). It is - * allowed to recursively acquire the device multiple times from the same - * thread. - * - * <note><para>You must never acquire two different devices at the same time - * unless this is explicitly allowed. Otherwise the possibility of deadlocks - * exist. - * - * As various Cairo functions can acquire devices when called, these functions - * may also cause deadlocks when you call them with an acquired device. So you - * must not have a device acquired when calling them. These functions are - * marked in the documentation. - * </para></note> - * - * Return value: %CAIRO_STATUS_SUCCESS on success or an error code if - * the device is in an error state and could not be - * acquired. After a successful call to cairo_device_acquire(), - * a matching call to cairo_device_release() is required. - * - * Since: 1.10 - **/ -cairo_status_t -cairo_device_acquire (cairo_device_t *device) -{ - if (device == NULL) - return CAIRO_STATUS_SUCCESS; - - if (unlikely (device->status)) - return device->status; - - if (unlikely (device->finished)) - return _cairo_device_set_error (device, CAIRO_STATUS_DEVICE_FINISHED); - - CAIRO_MUTEX_LOCK (device->mutex); - if (device->mutex_depth++ == 0) { - if (device->backend->lock != NULL) - device->backend->lock (device); - } - - return CAIRO_STATUS_SUCCESS; -} -slim_hidden_def (cairo_device_acquire); - -/** - * cairo_device_release: - * @device: a #cairo_device_t - * - * Releases a @device previously acquired using cairo_device_acquire(). See - * that function for details. - * - * Since: 1.10 - **/ -void -cairo_device_release (cairo_device_t *device) -{ - if (device == NULL) - return; - - assert (device->mutex_depth > 0); - - if (--device->mutex_depth == 0) { - if (device->backend->unlock != NULL) - device->backend->unlock (device); - } - - CAIRO_MUTEX_UNLOCK (device->mutex); -} -slim_hidden_def (cairo_device_release); - -cairo_status_t -_cairo_device_set_error (cairo_device_t *device, - cairo_status_t status) -{ - if (status == CAIRO_STATUS_SUCCESS) - return CAIRO_STATUS_SUCCESS; - - _cairo_status_set_error (&device->status, status); - - return _cairo_error (status); -} - -/** - * cairo_device_get_reference_count: - * @device: a #cairo_device_t - * - * Returns the current reference count of @device. - * - * Return value: the current reference count of @device. If the - * object is a nil object, 0 will be returned. - * - * Since: 1.10 - **/ -unsigned int -cairo_device_get_reference_count (cairo_device_t *device) -{ - if (device == NULL || - CAIRO_REFERENCE_COUNT_IS_INVALID (&device->ref_count)) - return 0; - - return CAIRO_REFERENCE_COUNT_GET_VALUE (&device->ref_count); -} - -/** - * cairo_device_get_user_data: - * @device: a #cairo_device_t - * @key: the address of the #cairo_user_data_key_t the user data was - * attached to - * - * Return user data previously attached to @device using the - * specified key. If no user data has been attached with the given - * key this function returns %NULL. - * - * Return value: the user data previously attached or %NULL. - * - * Since: 1.10 - **/ -void * -cairo_device_get_user_data (cairo_device_t *device, - const cairo_user_data_key_t *key) -{ - return _cairo_user_data_array_get_data (&device->user_data, - key); -} - -/** - * cairo_device_set_user_data: - * @device: a #cairo_device_t - * @key: the address of a #cairo_user_data_key_t to attach the user data to - * @user_data: the user data to attach to the #cairo_device_t - * @destroy: a #cairo_destroy_func_t which will be called when the - * #cairo_t is destroyed or when new user data is attached using the - * same key. - * - * Attach user data to @device. To remove user data from a surface, - * call this function with the key that was used to set it and %NULL - * for @data. - * - * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a - * slot could not be allocated for the user data. - * - * Since: 1.10 - **/ -cairo_status_t -cairo_device_set_user_data (cairo_device_t *device, - const cairo_user_data_key_t *key, - void *user_data, - cairo_destroy_func_t destroy) -{ - if (CAIRO_REFERENCE_COUNT_IS_INVALID (&device->ref_count)) - return device->status; - - return _cairo_user_data_array_set_data (&device->user_data, - key, user_data, destroy); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-directfb-surface.c b/source/libs/cairo/cairo-src/src/cairo-directfb-surface.c deleted file mode 100644 index 5ac64ba98eeddfa74ffeed3e440f0ca2b6544a3b..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-directfb-surface.c +++ /dev/null @@ -1,544 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2012 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Chris Wilson - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" -#include "cairo-directfb.h" - -#include "cairo-clip-private.h" -#include "cairo-compositor-private.h" -#include "cairo-default-context-private.h" -#include "cairo-error-private.h" -#include "cairo-image-surface-inline.h" -#include "cairo-pattern-private.h" -#include "cairo-surface-backend-private.h" -#include "cairo-surface-fallback-private.h" - -#include <pixman.h> - -#include <directfb.h> -#include <direct/types.h> -#include <direct/debug.h> -#include <direct/memcpy.h> -#include <direct/util.h> - -slim_hidden_proto(cairo_directfb_surface_create); - -typedef struct _cairo_dfb_surface { - cairo_image_surface_t image; - - IDirectFB *dfb; - IDirectFBSurface *dfb_surface; - - unsigned blit_premultiplied : 1; -} cairo_dfb_surface_t; - -static cairo_content_t -_directfb_format_to_content (DFBSurfacePixelFormat format) -{ - cairo_content_t content = 0; - - if (DFB_PIXELFORMAT_HAS_ALPHA (format)) - content |= CAIRO_CONTENT_ALPHA; - if (DFB_COLOR_BITS_PER_PIXEL (format)) - content |= CAIRO_CONTENT_COLOR_ALPHA; - - assert(content); - return content; -} - -static inline pixman_format_code_t -_directfb_to_pixman_format (DFBSurfacePixelFormat format) -{ - switch (format) { - case DSPF_UNKNOWN: return 0; - case DSPF_ARGB1555: return PIXMAN_a1r5g5b5; - case DSPF_RGB16: return PIXMAN_r5g6b5; - case DSPF_RGB24: return PIXMAN_r8g8b8; - case DSPF_RGB32: return PIXMAN_x8r8g8b8; - case DSPF_ARGB: return PIXMAN_a8r8g8b8; - case DSPF_A8: return PIXMAN_a8; - case DSPF_YUY2: return PIXMAN_yuy2; - case DSPF_RGB332: return PIXMAN_r3g3b2; - case DSPF_UYVY: return 0; - case DSPF_I420: return 0; - case DSPF_YV12: return PIXMAN_yv12; - case DSPF_LUT8: return 0; - case DSPF_ALUT44: return 0; - case DSPF_AiRGB: return 0; - case DSPF_A1: return 0; /* bit reversed, oops */ - case DSPF_NV12: return 0; - case DSPF_NV16: return 0; - case DSPF_ARGB2554: return 0; - case DSPF_ARGB4444: return PIXMAN_a4r4g4b4; - case DSPF_NV21: return 0; - case DSPF_AYUV: return 0; - case DSPF_A4: return PIXMAN_a4; - case DSPF_ARGB1666: return 0; - case DSPF_ARGB6666: return 0; - case DSPF_RGB18: return 0; - case DSPF_LUT2: return 0; - case DSPF_RGB444: return PIXMAN_x4r4g4b4; - case DSPF_RGB555: return PIXMAN_x1r5g5b5; -#if DFB_NUM_PIXELFORMATS >= 29 - case DSPF_BGR555: return PIXMAN_x1b5g5r5; -#endif - } - return 0; -} - -static cairo_surface_t * -_cairo_dfb_surface_create_similar (void *abstract_src, - cairo_content_t content, - int width, - int height) -{ - cairo_dfb_surface_t *other = abstract_src; - DFBSurfacePixelFormat format; - IDirectFBSurface *buffer; - DFBSurfaceDescription dsc; - cairo_surface_t *surface; - - if (width <= 0 || height <= 0) - return _cairo_image_surface_create_with_content (content, width, height); - - switch (content) { - default: - ASSERT_NOT_REACHED; - case CAIRO_CONTENT_COLOR_ALPHA: - format = DSPF_ARGB; - break; - case CAIRO_CONTENT_COLOR: - format = DSPF_RGB32; - break; - case CAIRO_CONTENT_ALPHA: - format = DSPF_A8; - break; - } - - dsc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT; - dsc.caps = DSCAPS_PREMULTIPLIED; - dsc.width = width; - dsc.height = height; - dsc.pixelformat = format; - - if (other->dfb->CreateSurface (other->dfb, &dsc, &buffer)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_DEVICE_ERROR)); - - surface = cairo_directfb_surface_create (other->dfb, buffer); - buffer->Release (buffer); - - return surface; -} - -static cairo_status_t -_cairo_dfb_surface_finish (void *abstract_surface) -{ - cairo_dfb_surface_t *surface = abstract_surface; - - surface->dfb_surface->Release (surface->dfb_surface); - return _cairo_image_surface_finish (abstract_surface); -} - -static cairo_image_surface_t * -_cairo_dfb_surface_map_to_image (void *abstract_surface, - const cairo_rectangle_int_t *extents) -{ - cairo_dfb_surface_t *surface = abstract_surface; - - if (surface->image.pixman_image == NULL) { - IDirectFBSurface *buffer = surface->dfb_surface; - pixman_image_t *image; - void *data; - int pitch; - - if (buffer->Lock (buffer, DSLF_READ | DSLF_WRITE, &data, &pitch)) - return _cairo_image_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - image = pixman_image_create_bits (surface->image.pixman_format, - surface->image.width, - surface->image.height, - data, pitch); - if (image == NULL) { - buffer->Unlock (buffer); - return _cairo_image_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - _cairo_image_surface_init (&surface->image, image, surface->image.pixman_format); - } - - return _cairo_image_surface_map_to_image (&surface->image.base, extents); -} - -static cairo_int_status_t -_cairo_dfb_surface_unmap_image (void *abstract_surface, - cairo_image_surface_t *image) -{ - cairo_dfb_surface_t *surface = abstract_surface; - return _cairo_image_surface_unmap_image (&surface->image.base, image); -} - -static cairo_status_t -_cairo_dfb_surface_flush (void *abstract_surface, - unsigned flags) -{ - cairo_dfb_surface_t *surface = abstract_surface; - - if (flags) - return CAIRO_STATUS_SUCCESS; - - if (surface->image.pixman_image) { - surface->dfb_surface->Unlock (surface->dfb_surface); - - pixman_image_unref (surface->image.pixman_image); - surface->image.pixman_image = NULL; - surface->image.data = NULL; - } - - return CAIRO_STATUS_SUCCESS; -} - -#if 0 -static inline DFBSurfacePixelFormat -_directfb_from_pixman_format (pixman_format_code_t format) -{ - switch ((int) format) { - case PIXMAN_a1r5g5b5: return DSPF_ARGB1555; - case PIXMAN_r5g6b5: return DSPF_RGB16; - case PIXMAN_r8g8b8: return DSPF_RGB24; - case PIXMAN_x8r8g8b8: return DSPF_RGB32; - case PIXMAN_a8r8g8b8: return DSPF_ARGB; - case PIXMAN_a8: return DSPF_A8; - case PIXMAN_yuy2: return DSPF_YUY2; - case PIXMAN_r3g3b2: return DSPF_RGB332; - case PIXMAN_yv12: return DSPF_YV12; - case PIXMAN_a1: return DSPF_A1; /* bit reversed, oops */ - case PIXMAN_a4r4g4b4: return DSPF_ARGB4444; - case PIXMAN_a4: return DSPF_A4; - case PIXMAN_x4r4g4b4: return DSPF_RGB444; - case PIXMAN_x1r5g5b5: return DSPF_RGB555; -#if DFB_NUM_PIXELFORMATS >= 29 - case PIXMAN_x1b5g5r5: return DSPF_BGR555; -#endif - default: return 0; - } -} - -static cairo_bool_t -_directfb_get_operator (cairo_operator_t operator, - DFBSurfaceBlendFunction *ret_srcblend, - DFBSurfaceBlendFunction *ret_dstblend) -{ - DFBSurfaceBlendFunction srcblend = DSBF_ONE; - DFBSurfaceBlendFunction dstblend = DSBF_ZERO; - - switch (operator) { - case CAIRO_OPERATOR_CLEAR: - srcblend = DSBF_ZERO; - dstblend = DSBF_ZERO; - break; - case CAIRO_OPERATOR_SOURCE: - srcblend = DSBF_ONE; - dstblend = DSBF_ZERO; - break; - case CAIRO_OPERATOR_OVER: - srcblend = DSBF_ONE; - dstblend = DSBF_INVSRCALPHA; - break; - case CAIRO_OPERATOR_IN: - srcblend = DSBF_DESTALPHA; - dstblend = DSBF_ZERO; - break; - case CAIRO_OPERATOR_OUT: - srcblend = DSBF_INVDESTALPHA; - dstblend = DSBF_ZERO; - break; - case CAIRO_OPERATOR_ATOP: - srcblend = DSBF_DESTALPHA; - dstblend = DSBF_INVSRCALPHA; - break; - case CAIRO_OPERATOR_DEST: - srcblend = DSBF_ZERO; - dstblend = DSBF_ONE; - break; - case CAIRO_OPERATOR_DEST_OVER: - srcblend = DSBF_INVDESTALPHA; - dstblend = DSBF_ONE; - break; - case CAIRO_OPERATOR_DEST_IN: - srcblend = DSBF_ZERO; - dstblend = DSBF_SRCALPHA; - break; - case CAIRO_OPERATOR_DEST_OUT: - srcblend = DSBF_ZERO; - dstblend = DSBF_INVSRCALPHA; - break; - case CAIRO_OPERATOR_DEST_ATOP: - srcblend = DSBF_INVDESTALPHA; - dstblend = DSBF_SRCALPHA; - break; - case CAIRO_OPERATOR_XOR: - srcblend = DSBF_INVDESTALPHA; - dstblend = DSBF_INVSRCALPHA; - break; - case CAIRO_OPERATOR_ADD: - srcblend = DSBF_ONE; - dstblend = DSBF_ONE; - break; - case CAIRO_OPERATOR_SATURATE: - /* XXX This does not work. */ -#if 0 - srcblend = DSBF_SRCALPHASAT; - dstblend = DSBF_ONE; - break; -#endif - case CAIRO_OPERATOR_MULTIPLY: - case CAIRO_OPERATOR_SCREEN: - case CAIRO_OPERATOR_OVERLAY: - case CAIRO_OPERATOR_DARKEN: - case CAIRO_OPERATOR_LIGHTEN: - case CAIRO_OPERATOR_COLOR_DODGE: - case CAIRO_OPERATOR_COLOR_BURN: - case CAIRO_OPERATOR_HARD_LIGHT: - case CAIRO_OPERATOR_SOFT_LIGHT: - case CAIRO_OPERATOR_DIFFERENCE: - case CAIRO_OPERATOR_EXCLUSION: - case CAIRO_OPERATOR_HSL_HUE: - case CAIRO_OPERATOR_HSL_SATURATION: - case CAIRO_OPERATOR_HSL_COLOR: - case CAIRO_OPERATOR_HSL_LUMINOSITY: - default: - return FALSE; - } - - *ret_srcblend = srcblend; - *ret_dstblend = dstblend; - - return TRUE; -} -#define RUN_CLIPPED(surface, clip_region, clip, func) {\ - if ((clip_region) != NULL) {\ - int n_clips = cairo_region_num_rectangles (clip_region), n; \ - for (n = 0; n < n_clips; n++) {\ - if (clip) {\ - DFBRegion reg, *cli = (clip); \ - cairo_rectangle_int_t rect; \ - cairo_region_get_rectangle (clip_region, n, &rect); \ - reg.x1 = rect.x; \ - reg.y1 = rect.y; \ - reg.x2 = rect.x + rect.width - 1; \ - reg.y2 = rect.y + rect.height - 1; \ - if (reg.x2 < cli->x1 || reg.y2 < cli->y1 ||\ - reg.x1 > cli->x2 || reg.y1 > cli->y2)\ - continue;\ - if (reg.x1 < cli->x1)\ - reg.x1 = cli->x1;\ - if (reg.y1 < cli->y1)\ - reg.y1 = cli->y1;\ - if (reg.x2 > cli->x2)\ - reg.x2 = cli->x2;\ - if (reg.y2 > cli->y2)\ - reg.y2 = cli->y2;\ - (surface)->dfbsurface->SetClip ((surface)->dfbsurface, ®);\ - } else {\ - DFBRegion reg; \ - cairo_rectangle_int_t rect; \ - cairo_region_get_rectangle (clip_region, n, &rect); \ - reg.x1 = rect.x; \ - reg.y1 = rect.y; \ - reg.x2 = rect.x + rect.width - 1; \ - reg.y2 = rect.y + rect.height - 1; \ - (surface)->dfbsurface->SetClip ((surface)->dfbsurface, ®); \ - }\ - func;\ - }\ - } else {\ - (surface)->dfbsurface->SetClip ((surface)->dfbsurface, clip);\ - func;\ - }\ -} - -static cairo_int_status_t -_cairo_dfb_surface_fill_rectangles (void *abstract_surface, - cairo_operator_t op, - const cairo_color_t *color, - cairo_rectangle_int_t *rects, - int n_rects) -{ - cairo_dfb_surface_t *dst = abstract_surface; - DFBSurfaceDrawingFlags flags; - DFBSurfaceBlendFunction sblend; - DFBSurfaceBlendFunction dblend; - DFBRectangle r[n_rects]; - int i; - - D_DEBUG_AT (CairoDFB_Render, - "%s( dst=%p, op=%d, color=%p, rects=%p, n_rects=%d ).\n", - __FUNCTION__, dst, op, color, rects, n_rects); - - if (! dst->supported_destination) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (! _directfb_get_operator (op, &sblend, &dblend)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (CAIRO_COLOR_IS_OPAQUE (color)) { - if (sblend == DSBF_SRCALPHA) - sblend = DSBF_ONE; - else if (sblend == DSBF_INVSRCALPHA) - sblend = DSBF_ZERO; - - if (dblend == DSBF_SRCALPHA) - dblend = DSBF_ONE; - else if (dblend == DSBF_INVSRCALPHA) - dblend = DSBF_ZERO; - } - if ((dst->base.content & CAIRO_CONTENT_ALPHA) == 0) { - if (sblend == DSBF_DESTALPHA) - sblend = DSBF_ONE; - else if (sblend == DSBF_INVDESTALPHA) - sblend = DSBF_ZERO; - - if (dblend == DSBF_DESTALPHA) - dblend = DSBF_ONE; - else if (dblend == DSBF_INVDESTALPHA) - dblend = DSBF_ZERO; - } - - flags = (sblend == DSBF_ONE && dblend == DSBF_ZERO) ? DSDRAW_NOFX : DSDRAW_BLEND; - dst->dfbsurface->SetDrawingFlags (dst->dfbsurface, flags); - if (flags & DSDRAW_BLEND) { - dst->dfbsurface->SetSrcBlendFunction (dst->dfbsurface, sblend); - dst->dfbsurface->SetDstBlendFunction (dst->dfbsurface, dblend); - } - - dst->dfbsurface->SetColor (dst->dfbsurface, - color->red_short >> 8, - color->green_short >> 8, - color->blue_short >> 8, - color->alpha_short >> 8); - - for (i = 0; i < n_rects; i++) { - r[i].x = rects[i].x; - r[i].y = rects[i].y; - r[i].w = rects[i].width; - r[i].h = rects[i].height; - } - - RUN_CLIPPED (dst, NULL, NULL, - dst->dfbsurface->FillRectangles (dst->dfbsurface, r, n_rects)); - - return CAIRO_STATUS_SUCCESS; -} -#endif - -static cairo_surface_backend_t -_cairo_dfb_surface_backend = { - CAIRO_SURFACE_TYPE_DIRECTFB, /*type*/ - _cairo_dfb_surface_finish, /*finish*/ - _cairo_default_context_create, - - _cairo_dfb_surface_create_similar,/*create_similar*/ - NULL, /* create similar image */ - _cairo_dfb_surface_map_to_image, - _cairo_dfb_surface_unmap_image, - - _cairo_surface_default_source, - _cairo_surface_default_acquire_source_image, - _cairo_surface_default_release_source_image, - NULL, - - NULL, /* copy_page */ - NULL, /* show_page */ - - _cairo_image_surface_get_extents, - _cairo_image_surface_get_font_options, - - _cairo_dfb_surface_flush, - NULL, /* mark_dirty_rectangle */ - - _cairo_surface_fallback_paint, - _cairo_surface_fallback_mask, - _cairo_surface_fallback_stroke, - _cairo_surface_fallback_fill, - NULL, /* fill-stroke */ - _cairo_surface_fallback_glyphs, -}; - -cairo_surface_t * -cairo_directfb_surface_create (IDirectFB *dfb, IDirectFBSurface *dfbsurface) -{ - cairo_dfb_surface_t *surface; - DFBSurfacePixelFormat format; - DFBSurfaceCapabilities caps; - pixman_format_code_t pixman_format; - int width, height; - - D_ASSERT (dfb != NULL); - D_ASSERT (dfbsurface != NULL); - - dfbsurface->GetPixelFormat (dfbsurface, &format); - dfbsurface->GetSize (dfbsurface, &width, &height); - - pixman_format = _directfb_to_pixman_format (format); - if (! pixman_format_supported_destination (pixman_format)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT)); - - surface = calloc (1, sizeof (cairo_dfb_surface_t)); - if (surface == NULL) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - /* XXX dfb -> device */ - _cairo_surface_init (&surface->image.base, - &_cairo_dfb_surface_backend, - NULL, /* device */ - _directfb_format_to_content (format)); - - surface->image.pixman_format = pixman_format; - surface->image.format = _cairo_format_from_pixman_format (pixman_format); - - surface->image.width = width; - surface->image.height = height; - surface->image.depth = PIXMAN_FORMAT_DEPTH(pixman_format); - - surface->dfb = dfb; - surface->dfb_surface = dfbsurface; - dfbsurface->AddRef (dfbsurface); - - dfbsurface->GetCapabilities (dfbsurface, &caps); - if (caps & DSCAPS_PREMULTIPLIED) - surface->blit_premultiplied = TRUE; - - return &surface->image.base; -} -slim_hidden_def(cairo_directfb_surface_create); diff --git a/source/libs/cairo/cairo-src/src/cairo-directfb.h b/source/libs/cairo/cairo-src/src/cairo-directfb.h deleted file mode 100644 index e3d818c6687c14769363082a406dfaea747c2f59..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-directfb.h +++ /dev/null @@ -1,67 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2003 University of Southern California - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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@isi.edu> - */ - -/* - * Environment variables affecting the backend: - * - * %CAIRO_DIRECTFB_NO_ACCEL (boolean) - * if found, disables acceleration at all - * - * %CAIRO_DIRECTFB_ARGB_FONT (boolean) - * if found, enables using ARGB fonts instead of A8 - */ - -#ifndef CAIRO_DIRECTFB_H -#define CAIRO_DIRECTFB_H - -#include "cairo.h" - -#if CAIRO_HAS_DIRECTFB_SURFACE - -#include <directfb.h> - -CAIRO_BEGIN_DECLS - -cairo_public cairo_surface_t * -cairo_directfb_surface_create (IDirectFB *dfb, IDirectFBSurface *surface); - -CAIRO_END_DECLS - -#else /*CAIRO_HAS_DIRECTFB_SURFACE*/ -# error Cairo was not compiled with support for the directfb backend -#endif /*CAIRO_HAS_DIRECTFB_SURFACE*/ - -#endif /*CAIRO_DIRECTFB_H*/ diff --git a/source/libs/cairo/cairo-src/src/cairo-drm.h b/source/libs/cairo/cairo-src/src/cairo-drm.h deleted file mode 100644 index 907610dcde87bdf912d0c3cddf881a7bfc29eb40..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-drm.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Chris Wilson. - */ - -#ifndef CAIRO_DRM_H -#define CAIRO_DRM_H - -#include "cairo.h" - -#if CAIRO_HAS_DRM_SURFACE - -CAIRO_BEGIN_DECLS - -struct udev_device; - -cairo_public cairo_device_t * -cairo_drm_device_get (struct udev_device *device); - -cairo_public cairo_device_t * -cairo_drm_device_get_for_fd (int fd); - -cairo_public cairo_device_t * -cairo_drm_device_default (void); - -cairo_public int -cairo_drm_device_get_fd (cairo_device_t *device); - -cairo_public void -cairo_drm_device_throttle (cairo_device_t *device); - -cairo_public cairo_surface_t * -cairo_drm_surface_create (cairo_device_t *device, - cairo_format_t format, - int width, int height); - -cairo_public cairo_surface_t * -cairo_drm_surface_create_for_name (cairo_device_t *device, - unsigned int name, - cairo_format_t format, - int width, int height, int stride); - -cairo_public cairo_surface_t * -cairo_drm_surface_create_from_cacheable_image (cairo_device_t *device, - cairo_surface_t *surface); - -cairo_public cairo_status_t -cairo_drm_surface_enable_scan_out (cairo_surface_t *surface); - -cairo_public unsigned int -cairo_drm_surface_get_handle (cairo_surface_t *surface); - -cairo_public unsigned int -cairo_drm_surface_get_name (cairo_surface_t *surface); - -cairo_public cairo_format_t -cairo_drm_surface_get_format (cairo_surface_t *surface); - -cairo_public int -cairo_drm_surface_get_width (cairo_surface_t *surface); - -cairo_public int -cairo_drm_surface_get_height (cairo_surface_t *surface); - -cairo_public int -cairo_drm_surface_get_stride (cairo_surface_t *surface); - -/* XXX map/unmap, general surface layer? */ - -/* Rough outline, culled from a conversation on IRC: - * map() returns an image-surface representation of the drm-surface, - * which you unmap() when you are finished, i.e. map() pulls the buffer back - * from the GPU, maps it into the CPU domain and gives you direct access to - * the pixels. With the unmap(), the buffer is ready to be used again by the - * GPU and *until* the unmap(), all operations will be done in software. - * - * (Technically calling cairo_surface_flush() on the underlying drm-surface - * will also disassociate the mapping.) -*/ -cairo_public cairo_surface_t * -cairo_drm_surface_map_to_image (cairo_surface_t *surface); - -cairo_public void -cairo_drm_surface_unmap (cairo_surface_t *drm_surface, - cairo_surface_t *image_surface); - -CAIRO_END_DECLS - -#else /* CAIRO_HAS_DRM_SURFACE */ -# error Cairo was not compiled with support for the DRM backend -#endif /* CAIRO_HAS_DRM_SURFACE */ - -#endif /* CAIRO_DRM_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-egl-context.c b/source/libs/cairo/cairo-src/src/cairo-egl-context.c deleted file mode 100644 index bf704c630fb60056a697137bb22e4433685bd2ea..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-egl-context.c +++ /dev/null @@ -1,317 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Eric Anholt - * Copyright © 2009 Chris Wilson - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Carl Worth <cworth@cworth.org> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-gl-private.h" - -#include "cairo-error-private.h" - -typedef struct _cairo_egl_context { - cairo_gl_context_t base; - - EGLDisplay display; - EGLContext context; - - EGLSurface dummy_surface; - - EGLContext previous_context; - EGLSurface previous_surface; -} cairo_egl_context_t; - -typedef struct _cairo_egl_surface { - cairo_gl_surface_t base; - - EGLSurface egl; -} cairo_egl_surface_t; - - -static cairo_bool_t -_context_acquisition_changed_egl_state (cairo_egl_context_t *ctx, - EGLSurface current_surface) -{ - return ctx->previous_context != ctx->context || - ctx->previous_surface != current_surface; -} - -static EGLSurface -_egl_get_current_surface (cairo_egl_context_t *ctx) -{ - if (ctx->base.current_target == NULL || - _cairo_gl_surface_is_texture (ctx->base.current_target)) { - return ctx->dummy_surface; - } - - return ((cairo_egl_surface_t *) ctx->base.current_target)->egl; -} - -static void -_egl_query_current_state (cairo_egl_context_t *ctx) -{ - ctx->previous_surface = eglGetCurrentSurface (EGL_DRAW); - ctx->previous_context = eglGetCurrentContext (); - - /* If any of the values were none, assume they are all none. Not all - drivers seem well behaved when it comes to using these values across - multiple threads. */ - if (ctx->previous_surface == EGL_NO_SURFACE || - ctx->previous_context == EGL_NO_CONTEXT) { - ctx->previous_surface = EGL_NO_SURFACE; - ctx->previous_context = EGL_NO_CONTEXT; - } -} - -static void -_egl_acquire (void *abstract_ctx) -{ - cairo_egl_context_t *ctx = abstract_ctx; - EGLSurface current_surface = _egl_get_current_surface (ctx); - - _egl_query_current_state (ctx); - if (!_context_acquisition_changed_egl_state (ctx, current_surface)) - return; - - eglMakeCurrent (ctx->display, - current_surface, current_surface, ctx->context); -} - -static void -_egl_release (void *abstract_ctx) -{ - cairo_egl_context_t *ctx = abstract_ctx; - if (!ctx->base.thread_aware || - !_context_acquisition_changed_egl_state (ctx, - _egl_get_current_surface (ctx))) { - return; - } - - eglMakeCurrent (ctx->display, - EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); -} - -static void -_egl_make_current (void *abstract_ctx, - cairo_gl_surface_t *abstract_surface) -{ - cairo_egl_context_t *ctx = abstract_ctx; - cairo_egl_surface_t *surface = (cairo_egl_surface_t *) abstract_surface; - - eglMakeCurrent(ctx->display, surface->egl, surface->egl, ctx->context); -} - -static void -_egl_swap_buffers (void *abstract_ctx, - cairo_gl_surface_t *abstract_surface) -{ - cairo_egl_context_t *ctx = abstract_ctx; - cairo_egl_surface_t *surface = (cairo_egl_surface_t *) abstract_surface; - - eglSwapBuffers (ctx->display, surface->egl); -} - -static void -_egl_destroy (void *abstract_ctx) -{ - cairo_egl_context_t *ctx = abstract_ctx; - - eglMakeCurrent (ctx->display, - EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - if (ctx->dummy_surface != EGL_NO_SURFACE) - eglDestroySurface (ctx->display, ctx->dummy_surface); -} - -static cairo_bool_t -_egl_make_current_surfaceless(cairo_egl_context_t *ctx) -{ - const char *extensions; - - extensions = eglQueryString(ctx->display, EGL_EXTENSIONS); - if (strstr(extensions, "EGL_KHR_surfaceless_context") == NULL && - strstr(extensions, "EGL_KHR_surfaceless_opengl") == NULL) - return FALSE; - - if (!eglMakeCurrent(ctx->display, - EGL_NO_SURFACE, EGL_NO_SURFACE, ctx->context)) - return FALSE; - - return TRUE; -} - -cairo_device_t * -cairo_egl_device_create (EGLDisplay dpy, EGLContext egl) -{ - cairo_egl_context_t *ctx; - cairo_status_t status; - int attribs[] = { - EGL_WIDTH, 1, - EGL_HEIGHT, 1, - EGL_NONE, - }; - EGLConfig config; - EGLint numConfigs; - - ctx = calloc (1, sizeof (cairo_egl_context_t)); - if (unlikely (ctx == NULL)) - return _cairo_gl_context_create_in_error (CAIRO_STATUS_NO_MEMORY); - - ctx->display = dpy; - ctx->context = egl; - - ctx->base.acquire = _egl_acquire; - ctx->base.release = _egl_release; - ctx->base.make_current = _egl_make_current; - ctx->base.swap_buffers = _egl_swap_buffers; - ctx->base.destroy = _egl_destroy; - - /* We are about the change the current state of EGL, so we should - * query the pre-existing surface now instead of later. */ - _egl_query_current_state (ctx); - - if (!_egl_make_current_surfaceless (ctx)) { - /* Fall back to dummy surface, meh. */ - EGLint config_attribs[] = { - EGL_CONFIG_ID, 0, - EGL_NONE - }; - - /* - * In order to be able to make an egl context current when using a - * pbuffer surface, that surface must have been created with a config - * that is compatible with the context config. For Mesa, this means - * that the configs must be the same. - */ - eglQueryContext (dpy, egl, EGL_CONFIG_ID, &config_attribs[1]); - eglChooseConfig (dpy, config_attribs, &config, 1, &numConfigs); - - ctx->dummy_surface = eglCreatePbufferSurface (dpy, config, attribs); - if (ctx->dummy_surface == NULL) { - free (ctx); - return _cairo_gl_context_create_in_error (CAIRO_STATUS_NO_MEMORY); - } - - if (!eglMakeCurrent (dpy, ctx->dummy_surface, ctx->dummy_surface, egl)) { - free (ctx); - return _cairo_gl_context_create_in_error (CAIRO_STATUS_NO_MEMORY); - } - } - - status = _cairo_gl_dispatch_init (&ctx->base.dispatch, eglGetProcAddress); - if (unlikely (status)) { - free (ctx); - return _cairo_gl_context_create_in_error (status); - } - - status = _cairo_gl_context_init (&ctx->base); - if (unlikely (status)) { - if (ctx->dummy_surface != EGL_NO_SURFACE) - eglDestroySurface (dpy, ctx->dummy_surface); - free (ctx); - return _cairo_gl_context_create_in_error (status); - } - - /* Tune the default VBO size to reduce overhead on embedded devices. - * This smaller size means that flushing needs to be done more often, - * but it is less demanding of scarce memory on embedded devices. - */ - ctx->base.vbo_size = 16*1024; - - eglMakeCurrent (dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - - return &ctx->base.base; -} - -cairo_surface_t * -cairo_gl_surface_create_for_egl (cairo_device_t *device, - EGLSurface egl, - int width, - int height) -{ - cairo_egl_surface_t *surface; - - if (unlikely (device->status)) - return _cairo_surface_create_in_error (device->status); - - if (device->backend->type != CAIRO_DEVICE_TYPE_GL) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH)); - - if (width <= 0 || height <= 0) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE)); - - surface = calloc (1, sizeof (cairo_egl_surface_t)); - if (unlikely (surface == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - _cairo_gl_surface_init (device, &surface->base, - CAIRO_CONTENT_COLOR_ALPHA, width, height); - surface->egl = egl; - - return &surface->base.base; -} - -static cairo_bool_t is_egl_device (cairo_device_t *device) -{ - return (device->backend != NULL && - device->backend->type == CAIRO_DEVICE_TYPE_GL); -} - -static cairo_egl_context_t *to_egl_context (cairo_device_t *device) -{ - return (cairo_egl_context_t *) device; -} - -EGLDisplay -cairo_egl_device_get_display (cairo_device_t *device) -{ - if (! is_egl_device (device)) { - _cairo_error_throw (CAIRO_STATUS_DEVICE_TYPE_MISMATCH); - return EGL_NO_DISPLAY; - } - - return to_egl_context (device)->display; -} - -cairo_public EGLContext -cairo_egl_device_get_context (cairo_device_t *device) -{ - if (! is_egl_device (device)) { - _cairo_error_throw (CAIRO_STATUS_DEVICE_TYPE_MISMATCH); - return EGL_NO_CONTEXT; - } - - return to_egl_context (device)->context; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-error-inline.h b/source/libs/cairo/cairo-src/src/cairo-error-inline.h deleted file mode 100644 index 9126c5e61eb9da37a92199cc1a638c28b9149b1a..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-error-inline.h +++ /dev/null @@ -1,52 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - */ - -#ifndef _CAIRO_ERROR_INLINE_H_ -#define _CAIRO_ERROR_INLINE_H_ - -#include "cairo-error-private.h" - -CAIRO_BEGIN_DECLS - -static inline cairo_status_t -_cairo_public_status (cairo_int_status_t status) -{ - assert (status <= CAIRO_INT_STATUS_LAST_STATUS); - return (cairo_status_t) status; -} - -#endif /* _CAIRO_ERROR_INLINE_H_ */ diff --git a/source/libs/cairo/cairo-src/src/cairo-error-private.h b/source/libs/cairo/cairo-src/src/cairo-error-private.h deleted file mode 100644 index 178078ad6146b7c65a8674e5d47458461dfa3360..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-error-private.h +++ /dev/null @@ -1,127 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - */ - -#ifndef _CAIRO_ERROR_PRIVATE_H_ -#define _CAIRO_ERROR_PRIVATE_H_ - -#include "cairo.h" -#include "cairo-compiler-private.h" -#include "cairo-types-private.h" - -#include <assert.h> - -CAIRO_BEGIN_DECLS - -/* _cairo_int_status: internal status - * - * Sure wish C had a real enum type so that this would be distinct - * from #cairo_status_t. Oh well, without that, I'll use this bogus 100 - * offset. We want to keep it fit in int8_t as the compiler may choose - * that for #cairo_status_t - */ -enum _cairo_int_status { - CAIRO_INT_STATUS_SUCCESS = 0, - - CAIRO_INT_STATUS_NO_MEMORY, - CAIRO_INT_STATUS_INVALID_RESTORE, - CAIRO_INT_STATUS_INVALID_POP_GROUP, - CAIRO_INT_STATUS_NO_CURRENT_POINT, - CAIRO_INT_STATUS_INVALID_MATRIX, - CAIRO_INT_STATUS_INVALID_STATUS, - CAIRO_INT_STATUS_NULL_POINTER, - CAIRO_INT_STATUS_INVALID_STRING, - CAIRO_INT_STATUS_INVALID_PATH_DATA, - CAIRO_INT_STATUS_READ_ERROR, - CAIRO_INT_STATUS_WRITE_ERROR, - CAIRO_INT_STATUS_SURFACE_FINISHED, - CAIRO_INT_STATUS_SURFACE_TYPE_MISMATCH, - CAIRO_INT_STATUS_PATTERN_TYPE_MISMATCH, - CAIRO_INT_STATUS_INVALID_CONTENT, - CAIRO_INT_STATUS_INVALID_FORMAT, - CAIRO_INT_STATUS_INVALID_VISUAL, - CAIRO_INT_STATUS_FILE_NOT_FOUND, - CAIRO_INT_STATUS_INVALID_DASH, - CAIRO_INT_STATUS_INVALID_DSC_COMMENT, - CAIRO_INT_STATUS_INVALID_INDEX, - CAIRO_INT_STATUS_CLIP_NOT_REPRESENTABLE, - CAIRO_INT_STATUS_TEMP_FILE_ERROR, - CAIRO_INT_STATUS_INVALID_STRIDE, - CAIRO_INT_STATUS_FONT_TYPE_MISMATCH, - CAIRO_INT_STATUS_USER_FONT_IMMUTABLE, - CAIRO_INT_STATUS_USER_FONT_ERROR, - CAIRO_INT_STATUS_NEGATIVE_COUNT, - CAIRO_INT_STATUS_INVALID_CLUSTERS, - CAIRO_INT_STATUS_INVALID_SLANT, - CAIRO_INT_STATUS_INVALID_WEIGHT, - CAIRO_INT_STATUS_INVALID_SIZE, - CAIRO_INT_STATUS_USER_FONT_NOT_IMPLEMENTED, - CAIRO_INT_STATUS_DEVICE_TYPE_MISMATCH, - CAIRO_INT_STATUS_DEVICE_ERROR, - CAIRO_INT_STATUS_INVALID_MESH_CONSTRUCTION, - CAIRO_INT_STATUS_DEVICE_FINISHED, - CAIRO_INT_STATUS_JBIG2_GLOBAL_MISSING, - - CAIRO_INT_STATUS_LAST_STATUS, - - CAIRO_INT_STATUS_UNSUPPORTED = 100, - CAIRO_INT_STATUS_DEGENERATE, - CAIRO_INT_STATUS_NOTHING_TO_DO, - CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY, - CAIRO_INT_STATUS_IMAGE_FALLBACK, - CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN, -}; - -typedef enum _cairo_int_status cairo_int_status_t; - -#define _cairo_status_is_error(status) \ - (status != CAIRO_STATUS_SUCCESS && status < CAIRO_STATUS_LAST_STATUS) - -#define _cairo_int_status_is_error(status) \ - (status != CAIRO_INT_STATUS_SUCCESS && status < CAIRO_INT_STATUS_LAST_STATUS) - -cairo_private cairo_status_t -_cairo_error (cairo_status_t status); - -/* hide compiler warnings when discarding the return value */ -#define _cairo_error_throw(status) do { \ - cairo_status_t status__ = _cairo_error (status); \ - (void) status__; \ -} while (0) - -CAIRO_END_DECLS - -#endif /* _CAIRO_ERROR_PRIVATE_H_ */ diff --git a/source/libs/cairo/cairo-src/src/cairo-error.c b/source/libs/cairo/cairo-src/src/cairo-error.c deleted file mode 100644 index 1b9bd76be13a3c9218dcda33fbf7cb28b6f7fd37..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-error.c +++ /dev/null @@ -1,73 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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" -#include "cairo-private.h" - -#include "cairo-compiler-private.h" -#include "cairo-error-private.h" - -#include <assert.h> - -/** - * _cairo_error: - * @status: a status value indicating an error, (eg. not - * %CAIRO_STATUS_SUCCESS) - * - * Checks that status is an error status, but does nothing else. - * - * All assignments of an error status to any user-visible object - * within the cairo application should result in a call to - * _cairo_error(). - * - * The purpose of this function is to allow the user to set a - * breakpoint in _cairo_error() to generate a stack trace for when the - * user causes cairo to detect an error. - * - * Return value: the error status. - **/ -cairo_status_t -_cairo_error (cairo_status_t status) -{ - CAIRO_ENSURE_UNIQUE; - assert (_cairo_status_is_error (status)); - - return status; -} - -COMPILE_TIME_ASSERT ((int)CAIRO_INT_STATUS_LAST_STATUS == (int)CAIRO_STATUS_LAST_STATUS); diff --git a/source/libs/cairo/cairo-src/src/cairo-fallback-compositor.c b/source/libs/cairo/cairo-src/src/cairo-fallback-compositor.c deleted file mode 100644 index 3f6199fe2bbdb4f26c335ec930f2dc4aece89b69..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-fallback-compositor.c +++ /dev/null @@ -1,185 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Joonas Pihlaja <jpihlaja@cc.helsinki.fi> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-compositor-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-surface-offset-private.h" - -/* high-level compositor interface */ - -static cairo_int_status_t -_cairo_fallback_compositor_paint (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents) -{ - cairo_image_surface_t *image; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - image = _cairo_surface_map_to_image (extents->surface, &extents->unbounded); - - status = _cairo_surface_offset_paint (&image->base, - extents->unbounded.x, - extents->unbounded.y, - extents->op, - &extents->source_pattern.base, - extents->clip); - - return _cairo_surface_unmap_image (extents->surface, image); -} - -static cairo_int_status_t -_cairo_fallback_compositor_mask (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents) -{ - cairo_image_surface_t *image; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - image = _cairo_surface_map_to_image (extents->surface, &extents->unbounded); - - status = _cairo_surface_offset_mask (&image->base, - extents->unbounded.x, - extents->unbounded.y, - extents->op, - &extents->source_pattern.base, - &extents->mask_pattern.base, - extents->clip); - - return _cairo_surface_unmap_image (extents->surface, image); -} - -static cairo_int_status_t -_cairo_fallback_compositor_stroke (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_image_surface_t *image; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - image = _cairo_surface_map_to_image (extents->surface, &extents->unbounded); - - status = _cairo_surface_offset_stroke (&image->base, - extents->unbounded.x, - extents->unbounded.y, - extents->op, - &extents->source_pattern.base, - path, style, - ctm, ctm_inverse, - tolerance, - antialias, - extents->clip); - - return _cairo_surface_unmap_image (extents->surface, image); -} - -static cairo_int_status_t -_cairo_fallback_compositor_fill (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_image_surface_t *image; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - image = _cairo_surface_map_to_image (extents->surface, &extents->unbounded); - - status = _cairo_surface_offset_fill (&image->base, - extents->unbounded.x, - extents->unbounded.y, - extents->op, - &extents->source_pattern.base, - path, - fill_rule, tolerance, antialias, - extents->clip); - - return _cairo_surface_unmap_image (extents->surface, image); -} - -static cairo_int_status_t -_cairo_fallback_compositor_glyphs (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_bool_t overlap) -{ - cairo_image_surface_t *image; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - image = _cairo_surface_map_to_image (extents->surface, &extents->unbounded); - - status = _cairo_surface_offset_glyphs (&image->base, - extents->unbounded.x, - extents->unbounded.y, - extents->op, - &extents->source_pattern.base, - scaled_font, glyphs, num_glyphs, - extents->clip); - - return _cairo_surface_unmap_image (extents->surface, image); -} - -const cairo_compositor_t _cairo_fallback_compositor = { - &__cairo_no_compositor, - - _cairo_fallback_compositor_paint, - _cairo_fallback_compositor_mask, - _cairo_fallback_compositor_stroke, - _cairo_fallback_compositor_fill, - _cairo_fallback_compositor_glyphs, -}; diff --git a/source/libs/cairo/cairo-src/src/cairo-features-uninstalled.pc.in b/source/libs/cairo/cairo-src/src/cairo-features-uninstalled.pc.in deleted file mode 100644 index b9cd9d3ad2b38faef5dd74aa3e6055cf868db55b..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-features-uninstalled.pc.in +++ /dev/null @@ -1,7 +0,0 @@ -Name: @FEATURE_PC@ -Description: @FEATURE_NAME@ for cairo graphics library -Version: @VERSION@ - -Requires: @FEATURE_BASE@ @FEATURE_REQUIRES@ -Libs: @FEATURE_NONPKGCONFIG_LIBS@ @FEATURE_NONPKGCONFIG_EXTRA_LIBS@ -Cflags: -I${pc_top_builddir}/${pcfiledir}/@srcdir@/src @FEATURE_NONPKGCONFIG_CFLAGS@ diff --git a/source/libs/cairo/cairo-src/src/cairo-features.pc.in b/source/libs/cairo/cairo-src/src/cairo-features.pc.in deleted file mode 100644 index 9a4b657c8da4c3948d0fe7f6c7a4069ddb31a787..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-features.pc.in +++ /dev/null @@ -1,12 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: @FEATURE_PC@ -Description: @FEATURE_NAME@ for cairo graphics library -Version: @VERSION@ - -Requires: @FEATURE_BASE@ @FEATURE_REQUIRES@ -Libs: @FEATURE_NONPKGCONFIG_LIBS@ @FEATURE_NONPKGCONFIG_EXTRA_LIBS@ -Cflags: -I${includedir}/cairo @FEATURE_NONPKGCONFIG_CFLAGS@ diff --git a/source/libs/cairo/cairo-src/src/cairo-fixed-private.h b/source/libs/cairo/cairo-src/src/cairo-fixed-private.h deleted file mode 100644 index 9ff8f750392c6d3f5386babd202615a6e1786e6c..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-fixed-private.h +++ /dev/null @@ -1,395 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* Cairo - a vector graphics library with display and print output - * - * Copyright © 2007 Mozilla Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Mozilla Foundation - * - * Contributor(s): - * Vladimir Vukicevic <vladimir@pobox.com> - */ - -#ifndef CAIRO_FIXED_PRIVATE_H -#define CAIRO_FIXED_PRIVATE_H - -#include "cairo-fixed-type-private.h" - -#include "cairo-wideint-private.h" -#include "cairoint.h" - -/* Implementation */ - -#if (CAIRO_FIXED_BITS != 32) -# error CAIRO_FIXED_BITS must be 32, and the type must be a 32-bit type. -# error To remove this limitation, you will have to fix the tessellator. -#endif - -#define CAIRO_FIXED_ONE ((cairo_fixed_t)(1 << CAIRO_FIXED_FRAC_BITS)) -#define CAIRO_FIXED_ONE_DOUBLE ((double)(1 << CAIRO_FIXED_FRAC_BITS)) -#define CAIRO_FIXED_EPSILON ((cairo_fixed_t)(1)) - -#define CAIRO_FIXED_ERROR_DOUBLE (1. / (2 * CAIRO_FIXED_ONE_DOUBLE)) - -#define CAIRO_FIXED_FRAC_MASK ((cairo_fixed_t)(((cairo_fixed_unsigned_t)(-1)) >> (CAIRO_FIXED_BITS - CAIRO_FIXED_FRAC_BITS))) -#define CAIRO_FIXED_WHOLE_MASK (~CAIRO_FIXED_FRAC_MASK) - -static inline cairo_fixed_t -_cairo_fixed_from_int (int i) -{ - return i << CAIRO_FIXED_FRAC_BITS; -} - -/* This is the "magic number" approach to converting a double into fixed - * point as described here: - * - * http://www.stereopsis.com/sree/fpu2006.html (an overview) - * http://www.d6.com/users/checker/pdfs/gdmfp.pdf (in detail) - * - * The basic idea is to add a large enough number to the double that the - * literal floating point is moved up to the extent that it forces the - * double's value to be shifted down to the bottom of the mantissa (to make - * room for the large number being added in). Since the mantissa is, at a - * given moment in time, a fixed point integer itself, one can convert a - * float to various fixed point representations by moving around the point - * of a floating point number through arithmetic operations. This behavior - * is reliable on most modern platforms as it is mandated by the IEEE-754 - * standard for floating point arithmetic. - * - * For our purposes, a "magic number" must be carefully selected that is - * both large enough to produce the desired point-shifting effect, and also - * has no lower bits in its representation that would interfere with our - * value at the bottom of the mantissa. The magic number is calculated as - * follows: - * - * (2 ^ (MANTISSA_SIZE - FRACTIONAL_SIZE)) * 1.5 - * - * where in our case: - * - MANTISSA_SIZE for 64-bit doubles is 52 - * - FRACTIONAL_SIZE for 16.16 fixed point is 16 - * - * Although this approach provides a very large speedup of this function - * on a wide-array of systems, it does come with two caveats: - * - * 1) It uses banker's rounding as opposed to arithmetic rounding. - * 2) It doesn't function properly if the FPU is in single-precision - * mode. - */ - -/* The 16.16 number must always be available */ -#define CAIRO_MAGIC_NUMBER_FIXED_16_16 (103079215104.0) - -#if CAIRO_FIXED_BITS <= 32 -#define CAIRO_MAGIC_NUMBER_FIXED ((1LL << (52 - CAIRO_FIXED_FRAC_BITS)) * 1.5) - -/* For 32-bit fixed point numbers */ -static inline cairo_fixed_t -_cairo_fixed_from_double (double d) -{ - union { - double d; - int32_t i[2]; - } u; - - u.d = d + CAIRO_MAGIC_NUMBER_FIXED; -#ifdef FLOAT_WORDS_BIGENDIAN - return u.i[1]; -#else - return u.i[0]; -#endif -} - -#else -# error Please define a magic number for your fixed point type! -# error See cairo-fixed-private.h for details. -#endif - -static inline cairo_fixed_t -_cairo_fixed_from_26_6 (uint32_t i) -{ -#if CAIRO_FIXED_FRAC_BITS > 6 - return i << (CAIRO_FIXED_FRAC_BITS - 6); -#else - return i >> (6 - CAIRO_FIXED_FRAC_BITS); -#endif -} - -static inline cairo_fixed_t -_cairo_fixed_from_16_16 (uint32_t i) -{ -#if CAIRO_FIXED_FRAC_BITS > 16 - return i << (CAIRO_FIXED_FRAC_BITS - 16); -#else - return i >> (16 - CAIRO_FIXED_FRAC_BITS); -#endif -} - -static inline double -_cairo_fixed_to_double (cairo_fixed_t f) -{ - return ((double) f) / CAIRO_FIXED_ONE_DOUBLE; -} - -static inline int -_cairo_fixed_is_integer (cairo_fixed_t f) -{ - return (f & CAIRO_FIXED_FRAC_MASK) == 0; -} - -static inline cairo_fixed_t -_cairo_fixed_floor (cairo_fixed_t f) -{ - return f & ~CAIRO_FIXED_FRAC_MASK; -} - -static inline cairo_fixed_t -_cairo_fixed_ceil (cairo_fixed_t f) -{ - return _cairo_fixed_floor (f + CAIRO_FIXED_FRAC_MASK); -} - -static inline cairo_fixed_t -_cairo_fixed_round (cairo_fixed_t f) -{ - return _cairo_fixed_floor (f + (CAIRO_FIXED_FRAC_MASK+1)/2); -} - -static inline cairo_fixed_t -_cairo_fixed_round_down (cairo_fixed_t f) -{ - return _cairo_fixed_floor (f + CAIRO_FIXED_FRAC_MASK/2); -} - -static inline int -_cairo_fixed_integer_part (cairo_fixed_t f) -{ - return f >> CAIRO_FIXED_FRAC_BITS; -} - -static inline int -_cairo_fixed_integer_round (cairo_fixed_t f) -{ - return _cairo_fixed_integer_part (f + (CAIRO_FIXED_FRAC_MASK+1)/2); -} - -static inline int -_cairo_fixed_integer_round_down (cairo_fixed_t f) -{ - return _cairo_fixed_integer_part (f + CAIRO_FIXED_FRAC_MASK/2); -} - -static inline int -_cairo_fixed_fractional_part (cairo_fixed_t f) -{ - return f & CAIRO_FIXED_FRAC_MASK; -} - -static inline int -_cairo_fixed_integer_floor (cairo_fixed_t f) -{ - if (f >= 0) - return f >> CAIRO_FIXED_FRAC_BITS; - else - return -((-f - 1) >> CAIRO_FIXED_FRAC_BITS) - 1; -} - -static inline int -_cairo_fixed_integer_ceil (cairo_fixed_t f) -{ - if (f > 0) - return ((f - 1)>>CAIRO_FIXED_FRAC_BITS) + 1; - else - return - (-f >> CAIRO_FIXED_FRAC_BITS); -} - -/* A bunch of explicit 16.16 operators; we need these - * to interface with pixman and other backends that require - * 16.16 fixed point types. - */ -static inline cairo_fixed_16_16_t -_cairo_fixed_to_16_16 (cairo_fixed_t f) -{ -#if (CAIRO_FIXED_FRAC_BITS == 16) && (CAIRO_FIXED_BITS == 32) - return f; -#elif CAIRO_FIXED_FRAC_BITS > 16 - /* We're just dropping the low bits, so we won't ever got over/underflow here */ - return f >> (CAIRO_FIXED_FRAC_BITS - 16); -#else - cairo_fixed_16_16_t x; - - /* Handle overflow/underflow by clamping to the lowest/highest - * value representable as 16.16 - */ - if ((f >> CAIRO_FIXED_FRAC_BITS) < INT16_MIN) { - x = INT32_MIN; - } else if ((f >> CAIRO_FIXED_FRAC_BITS) > INT16_MAX) { - x = INT32_MAX; - } else { - x = f << (16 - CAIRO_FIXED_FRAC_BITS); - } - - return x; -#endif -} - -static inline cairo_fixed_16_16_t -_cairo_fixed_16_16_from_double (double d) -{ - union { - double d; - int32_t i[2]; - } u; - - u.d = d + CAIRO_MAGIC_NUMBER_FIXED_16_16; -#ifdef FLOAT_WORDS_BIGENDIAN - return u.i[1]; -#else - return u.i[0]; -#endif -} - -static inline int -_cairo_fixed_16_16_floor (cairo_fixed_16_16_t f) -{ - if (f >= 0) - return f >> 16; - else - return -((-f - 1) >> 16) - 1; -} - -static inline double -_cairo_fixed_16_16_to_double (cairo_fixed_16_16_t f) -{ - return ((double) f) / (double) (1 << 16); -} - -#if CAIRO_FIXED_BITS == 32 - -static inline cairo_fixed_t -_cairo_fixed_mul (cairo_fixed_t a, cairo_fixed_t b) -{ - cairo_int64_t temp = _cairo_int32x32_64_mul (a, b); - return _cairo_int64_to_int32(_cairo_int64_rsl (temp, CAIRO_FIXED_FRAC_BITS)); -} - -/* computes round (a * b / c) */ -static inline cairo_fixed_t -_cairo_fixed_mul_div (cairo_fixed_t a, cairo_fixed_t b, cairo_fixed_t c) -{ - cairo_int64_t ab = _cairo_int32x32_64_mul (a, b); - cairo_int64_t c64 = _cairo_int32_to_int64 (c); - return _cairo_int64_to_int32 (_cairo_int64_divrem (ab, c64).quo); -} - -/* computes floor (a * b / c) */ -static inline cairo_fixed_t -_cairo_fixed_mul_div_floor (cairo_fixed_t a, cairo_fixed_t b, cairo_fixed_t c) -{ - return _cairo_int64_32_div (_cairo_int32x32_64_mul (a, b), c); -} - -/* compute y from x so that (x,y), p1, and p2 are collinear */ -static inline cairo_fixed_t -_cairo_edge_compute_intersection_y_for_x (const cairo_point_t *p1, - const cairo_point_t *p2, - cairo_fixed_t x) -{ - cairo_fixed_t y, dx; - - if (x == p1->x) - return p1->y; - if (x == p2->x) - return p2->y; - - y = p1->y; - dx = p2->x - p1->x; - if (dx != 0) - y += _cairo_fixed_mul_div_floor (x - p1->x, p2->y - p1->y, dx); - - return y; -} - -/* compute x from y so that (x,y), p1, and p2 are collinear */ -static inline cairo_fixed_t -_cairo_edge_compute_intersection_x_for_y (const cairo_point_t *p1, - const cairo_point_t *p2, - cairo_fixed_t y) -{ - cairo_fixed_t x, dy; - - if (y == p1->y) - return p1->x; - if (y == p2->y) - return p2->x; - - x = p1->x; - dy = p2->y - p1->y; - if (dy != 0) - x += _cairo_fixed_mul_div_floor (y - p1->y, p2->x - p1->x, dy); - - return x; -} - -/* Intersect two segments based on the algorithm described at - * http://paulbourke.net/geometry/pointlineplane/. This implementation - * uses floating point math. */ -static inline cairo_bool_t -_slow_segment_intersection (const cairo_point_t *seg1_p1, - const cairo_point_t *seg1_p2, - const cairo_point_t *seg2_p1, - const cairo_point_t *seg2_p2, - cairo_point_t *intersection) -{ - double denominator, u_a, u_b; - double seg1_dx, seg1_dy, seg2_dx, seg2_dy, seg_start_dx, seg_start_dy; - - seg1_dx = _cairo_fixed_to_double (seg1_p2->x - seg1_p1->x); - seg1_dy = _cairo_fixed_to_double (seg1_p2->y - seg1_p1->y); - seg2_dx = _cairo_fixed_to_double (seg2_p2->x - seg2_p1->x); - seg2_dy = _cairo_fixed_to_double (seg2_p2->y - seg2_p1->y); - denominator = (seg2_dy * seg1_dx) - (seg2_dx * seg1_dy); - if (denominator == 0) - return FALSE; - - seg_start_dx = _cairo_fixed_to_double (seg1_p1->x - seg2_p1->x); - seg_start_dy = _cairo_fixed_to_double (seg1_p1->y - seg2_p1->y); - u_a = ((seg2_dx * seg_start_dy) - (seg2_dy * seg_start_dx)) / denominator; - u_b = ((seg1_dx * seg_start_dy) - (seg1_dy * seg_start_dx)) / denominator; - - if (u_a <= 0 || u_a >= 1 || u_b <= 0 || u_b >= 1) - return FALSE; - - intersection->x = seg1_p1->x + _cairo_fixed_from_double ((u_a * seg1_dx)); - intersection->y = seg1_p1->y + _cairo_fixed_from_double ((u_a * seg1_dy)); - return TRUE; -} - -#else -# error Please define multiplication and other operands for your fixed-point type size -#endif - -#endif /* CAIRO_FIXED_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-fixed-type-private.h b/source/libs/cairo/cairo-src/src/cairo-fixed-type-private.h deleted file mode 100644 index e9f26f61539508db944558957605dcd9f502756b..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-fixed-type-private.h +++ /dev/null @@ -1,75 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* Cairo - a vector graphics library with display and print output - * - * Copyright © 2007 Mozilla Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Mozilla Foundation - * - * Contributor(s): - * Vladimir Vukicevic <vladimir@pobox.com> - */ - -#ifndef CAIRO_FIXED_TYPE_PRIVATE_H -#define CAIRO_FIXED_TYPE_PRIVATE_H - -#include "cairo-wideint-type-private.h" - -/* - * Fixed-point configuration - */ - -typedef int32_t cairo_fixed_16_16_t; -typedef cairo_int64_t cairo_fixed_32_32_t; -typedef cairo_int64_t cairo_fixed_48_16_t; -typedef cairo_int128_t cairo_fixed_64_64_t; -typedef cairo_int128_t cairo_fixed_96_32_t; - -/* Eventually, we should allow changing this, but I think - * there are some assumptions in the tessellator about the - * size of a fixed type. For now, it must be 32. - */ -#define CAIRO_FIXED_BITS 32 - -/* The number of fractional bits. Changing this involves - * making sure that you compute a double-to-fixed magic number. - * (see below). - */ -#define CAIRO_FIXED_FRAC_BITS 8 - -/* A signed type %CAIRO_FIXED_BITS in size; the main fixed point type */ -typedef int32_t cairo_fixed_t; - -/* An unsigned type of the same size as #cairo_fixed_t */ -typedef uint32_t cairo_fixed_unsigned_t; - -typedef struct _cairo_point { - cairo_fixed_t x; - cairo_fixed_t y; -} cairo_point_t; - -#endif /* CAIRO_FIXED_TYPE_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-fixed.c b/source/libs/cairo/cairo-src/src/cairo-fixed.c deleted file mode 100644 index 03e05592354d88607c831bc17b5b672bf9dc6f87..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-fixed.c +++ /dev/null @@ -1,39 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2003 University of Southern California - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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" - -#include "cairo-fixed-private.h" diff --git a/source/libs/cairo/cairo-src/src/cairo-font-face-twin-data.c b/source/libs/cairo/cairo-src/src/cairo-font-face-twin-data.c deleted file mode 100644 index ff09cb2be10a9a32a54defd1607f35423dbd96ff..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-font-face-twin-data.c +++ /dev/null @@ -1,1072 +0,0 @@ -/* See cairo-font-face-twin.c for copyright info */ - -#include "cairoint.h" - -const int8_t _cairo_twin_outlines[] = { -/* 0x0 '\0' offset 0 */ - 0, 24, 42, 0, 2, 2, - 0, 24, /* snap_x */ - -42, 0, /* snap_y */ - 'm', 0, 0, - 'l', 0, -42, - 'l', 24, -42, - 'l', 24, 0, - 'l', 0, 0, - 'e', - 'X', 'X', -/* 0x20 ' ' offset 28 */ - 0, 4, 0, 0, 0, 0, - /* snap_x */ - /* snap_y */ - 'e', - 'X', 'X', 'X', - 'X', 'X', -/* 0x21 '!' offset 40 */ - 0, 0, 42, 0, 1, 3, - 0, /* snap_x */ - -42, -14, 0, /* snap_y */ - 'm', 0, -42, - 'l', 0, -14, - 'm', 0, 0, - 'l', 0, 0, - 'e', - 'X', 'X', 'X', 'X', 'X', 'X', - 'X', 'X', 'X', 'X', 'X', 'X', - 'X', 'X', 'X', 'X', 'X', 'X', - 'X', 'X', 'X', 'X', 'X', 'X', - 'X', 'X', 'X', -/* 0x22 '"' offset 90 */ - 0, 16, 42, -28, 2, 2, - 0, 16, /* snap_x */ - -42, -28, /* snap_y */ - 'm', 0, -42, - 'l', 0, -28, - 'm', 16, -42, - 'l', 16, -28, - 'e', - 'X', -/* 0x23 '#' offset 114 */ - 0, 30, 50, 14, 2, 5, - 0, 30, /* snap_x */ - -24, -21, -15, -12, 0, /* snap_y */ - 'm', 16, -50, - 'l', 2, 14, - 'm', 28, -50, - 'l', 14, 14, - 'm', 2, -24, - 'l', 30, -24, - 'm', 0, -12, - 'l', 28, -12, - 'e', -/* 0x24 '$' offset 152 */ - 0, 28, 50, 8, 4, 4, - 0, 10, 18, 28, /* snap_x */ - -42, -21, -15, 0, /* snap_y */ - 'm', 10, -50, - 'l', 10, 8, - 'm', 18, -50, - 'l', 18, 8, - 'm', 28, -36, - 'c', 24, -42, 18, -42, 14, -42, - 'c', 10, -42, 0, -42, 0, -34, - 'c', 0, -25, 8, -24, 14, -22, - 'c', 20, -20, 28, -19, 28, -9, - 'c', 28, 0, 18, 0, 14, 0, - 'c', 10, 0, 4, 0, 0, -6, - 'e', -/* 0x25 '%' offset 224 */ - 0, 36, 42, 0, 4, 7, - 0, 14, 22, 36, /* snap_x */ - -42, -38, -28, -21, -15, -14, 0, /* snap_y */ - 'm', 10, -42, - 'c', 12, -41, 14, -40, 14, -36, - 'c', 14, -30, 11, -28, 6, -28, - 'c', 2, -28, 0, -30, 0, -34, - 'c', 0, -39, 3, -42, 8, -42, - 'l', 10, -42, - 'c', 18, -37, 28, -37, 36, -42, - 'l', 0, 0, - 'm', 28, -14, - 'c', 24, -14, 22, -11, 22, -6, - 'c', 22, -2, 24, 0, 28, 0, - 'c', 33, 0, 36, -2, 36, -8, - 'c', 36, -12, 34, -14, 30, -14, - 'l', 28, -14, - 'e', - 'X', 'X', 'X', -/* 0x26 '&' offset 323 */ - 0, 40, 42, 0, 4, 4, - 0, 10, 22, 40, /* snap_x */ - -28, -21, -15, 0, /* snap_y */ - 'm', 40, -24, - 'c', 40, -27, 39, -28, 37, -28, - 'c', 29, -28, 32, 0, 12, 0, - 'c', 0, 0, 0, -8, 0, -10, - 'c', 0, -24, 22, -20, 22, -34, - 'c', 22, -45, 10, -45, 10, -34, - 'c', 10, -27, 25, 0, 36, 0, - 'c', 39, 0, 40, -1, 40, -4, - 'e', -/* 0x27 ''' offset 390 */ - 0, 4, 42, -30, 2, 2, - 0, 4, /* snap_x */ - -42, -28, /* snap_y */ - 'm', 2, -38, - 'c', -1, -38, -1, -42, 2, -42, - 'c', 6, -42, 5, -33, 0, -30, - 'e', - 'X', -/* 0x28 '(' offset 419 */ - 0, 14, 50, 14, 2, 2, - 0, 14, /* snap_x */ - -50, 14, /* snap_y */ - 'm', 14, -50, - 'c', -5, -32, -5, -5, 14, 14, - 'e', - 'X', -/* 0x29 ')' offset 441 */ - 0, 14, 50, 14, 2, 2, - 0, 14, /* snap_x */ - -15, 14, /* snap_y */ - 'm', 0, -50, - 'c', 19, -34, 19, -2, 0, 14, - 'e', - 'X', -/* 0x2a '*' offset 463 */ - 0, 20, 30, -6, 3, 3, - 0, 10, 20, /* snap_x */ - -21, -15, 0, /* snap_y */ - 'm', 10, -30, - 'l', 10, -6, - 'm', 0, -24, - 'l', 20, -12, - 'm', 20, -24, - 'l', 0, -12, - 'e', -/* 0x2b '+' offset 494 */ - 0, 36, 36, 0, 3, 4, - 0, 18, 36, /* snap_x */ - -21, -18, -15, 0, /* snap_y */ - 'm', 18, -36, - 'l', 18, 0, - 'm', 0, -18, - 'l', 36, -18, - 'e', -/* 0x2c ',' offset 520 */ - 0, 4, 4, 8, 2, 3, - 0, 4, /* snap_x */ - -21, -15, 0, /* snap_y */ - 'm', 4, -2, - 'c', 4, 1, 0, 1, 0, -2, - 'c', 0, -5, 4, -5, 4, -2, - 'c', 4, 4, 2, 6, 0, 8, - 'e', -/* 0x2d '-' offset 556 */ - 0, 36, 18, -18, 2, 4, - 0, 36, /* snap_x */ - -21, -18, -15, 0, /* snap_y */ - 'm', 0, -18, - 'l', 36, -18, - 'e', -/* 0x2e '.' offset 575 */ - 0, 4, 4, 0, 2, 3, - 0, 4, /* snap_x */ - -21, -15, 0, /* snap_y */ - 'm', 2, -4, - 'c', -1, -4, -1, 0, 2, 0, - 'c', 5, 0, 5, -4, 2, -4, - 'e', -/* 0x2f '/' offset 604 */ - 0, 36, 50, 14, 2, 3, - 0, 36, /* snap_x */ - -21, -15, 0, /* snap_y */ - 'm', 36, -50, - 'l', 0, 14, - 'e', -/* 0x30 '0' offset 622 */ - 0, 28, 42, 0, 2, 4, - 0, 28, /* snap_x */ - -42, -21, -15, 0, /* snap_y */ - 'm', 14, -42, - 'c', 9, -42, 0, -42, 0, -21, - 'c', 0, 0, 9, 0, 14, 0, - 'c', 19, 0, 28, 0, 28, -21, - 'c', 28, -42, 19, -42, 14, -42, - 'E', -/* 0x31 '1' offset 666 */ - 0, 28, 42, 0, 2, 3, - 0, 17, 28 /* snap_x */ - -42, -34, 0, /* snap_y */ - 'm', 7, -34, - 'c', 11, -35, 15, -38, 17, -42, - 'l', 17, 0, - 'e', -/* 0x32 '2' offset 691 */ - 0, 28, 42, 0, 4, 4, - 0, 2, 26, 28, /* snap_x */ - -42, -21, -15, 0, /* snap_y */ - 'm', 2, -32, - 'c', 2, -34, 2, -42, 14, -42, - 'c', 26, -42, 26, -34, 26, -32, - 'c', 26, -30, 25, -25, 10, -10, - 'l', 0, 0, - 'l', 28, 0, - 'e', -/* 0x33 '3' offset 736 */ - 0, 28, 42, 0, 2, 5, - 0, 28, /* snap_x */ - -42, -26, -21, -15, 0, /* snap_y */ - 'm', 4, -42, - 'l', 26, -42, - 'l', 14, -26, - 'c', 21, -26, 28, -26, 28, -14, - 'c', 28, 0, 17, 0, 13, 0, - 'c', 8, 0, 3, -1, 0, -8, - 'e', -/* 0x34 '4' offset 780 */ - 0, 28, 42, 0, 3, 3, - 0, 20, 30, /* snap_x */ - -42, -14, 0, /* snap_y */ - 'm', 20, 0, - 'l', 20, -42, - 'l', 0, -14, - 'l', 30, -14, - 'e', - 'X', 'X', 'X', - 'X', -/* 0x35 '5' offset 809 */ - 0, 28, 42, 0, 2, 5, - 0, 28, /* snap_x */ - -42, -28, -21, -15, 0, /* snap_y */ - 'm', 24, -42, - 'l', 4, -42, - 'l', 2, -24, - 'c', 5, -27, 10, -28, 13, -28, - 'c', 16, -28, 28, -28, 28, -14, - 'c', 28, 0, 16, 0, 13, 0, - 'c', 10, 0, 3, 0, 0, -8, - 'e', -/* 0x36 '6' offset 860 */ - 0, 28, 42, 0, 2, 5, - 0, 26, /* snap_x */ - -42, -26, -21, -15, 0, /* snap_y */ - 'm', 24, -36, - 'c', 22, -41, 19, -42, 14, -42, - 'c', 9, -42, 0, -41, 0, -19, - 'c', 0, -1, 9, 0, 13, 0, - 'c', 18, 0, 26, -3, 26, -13, - 'c', 26, -18, 23, -26, 13, -26, - 'c', 10, -26, 1, -24, 0, -14, - 'e', -/* 0x37 '7' offset 919 */ - 0, 28, 42, 0, 2, 4, - 0, 28, /* snap_x */ - -42, -21, -15, 0, /* snap_y */ - 'm', 0, -42, - 'l', 28, -42, - 'l', 8, 0, - 'e', - 'X', 'X', 'X', -/* 0x38 '8' offset 944 */ - 0, 28, 42, 0, 4, 4, - 0, 2, 26, 28, /* snap_x */ - -42, -21, -15, 0, /* snap_y */ - 'm', 14, -42, - 'c', 5, -42, 2, -40, 2, -34, - 'c', 2, -18, 28, -32, 28, -11, - 'c', 28, 0, 18, 0, 14, 0, - 'c', 10, 0, 0, 0, 0, -11, - 'c', 0, -32, 26, -18, 26, -34, - 'c', 26, -40, 23, -42, 14, -42, - 'E', -/* 0x39 '9' offset 1004 */ - 0, 28, 42, 0, 2, 5, - 0, 26, /* snap_x */ - -42, -21, -16, -15, 0, /* snap_y */ - 'm', 26, -28, - 'c', 25, -16, 13, -16, 13, -16, - 'c', 8, -16, 0, -19, 0, -29, - 'c', 0, -34, 3, -42, 13, -42, - 'c', 24, -42, 26, -32, 26, -23, - 'c', 26, -14, 24, 0, 12, 0, - 'c', 7, 0, 4, -2, 2, -6, - 'e', -/* 0x3a ':' offset 1063 */ - 0, 4, 28, 0, 2, 3, - 0, 4, /* snap_x */ - -21, -15, 0, /* snap_y */ - 'm', 2, -28, - 'c', -1, -28, -1, -24, 2, -24, - 'c', 5, -24, 5, -28, 2, -28, - 'm', 2, -4, - 'c', -1, -4, -1, 0, 2, 0, - 'c', 5, 0, 5, -4, 2, -4, - 'e', -/* 0x3b ';' offset 1109 */ - 0, 4, 28, 8, 2, 3, - 0, 4, /* snap_x */ - -21, -15, 0, /* snap_y */ - 'm', 2, -28, - 'c', -1, -28, -1, -24, 2, -24, - 'c', 5, -24, 5, -28, 2, -28, - 'm', 4, -2, - 'c', 4, 1, 0, 1, 0, -2, - 'c', 0, -5, 4, -5, 4, -2, - 'c', 4, 3, 2, 6, 0, 8, - 'e', -/* 0x3c '<' offset 1162 */ - 0, 32, 36, 0, 2, 3, - 0, 32, /* snap_x */ - -36, -18, 0, /* snap_y */ - 'm', 32, -36, - 'l', 0, -18, - 'l', 32, 0, - 'e', -/* 0x3d '=' offset 1183 */ - 0, 36, 24, -12, 2, 2, - 0, 36, /* snap_x */ - -24, -15, /* snap_y */ - 'm', 0, -24, - 'l', 36, -24, - 'm', 0, -12, - 'l', 36, -12, - 'e', - 'X', 'X', 'X', -/* 0x3e '>' offset 1209 */ - 0, 32, 36, 0, 2, 3, - 0, 32, /* snap_x */ - -36, -18, 0, /* snap_y */ - 'm', 0, -36, - 'l', 32, -18, - 'l', 0, 0, - 'e', -/* 0x3f '?' offset 1230 */ - 0, 24, 42, 0, 3, 4, - 0, 12, 24, /* snap_x */ - -42, -21, -15, 0, /* snap_y */ - 'm', 0, -32, - 'c', 0, -34, 0, -42, 12, -42, - 'c', 24, -42, 24, -34, 24, -32, - 'c', 24, -29, 24, -24, 12, -20, - 'l', 12, -14, - 'm', 12, 0, - 'l', 12, 0, - 'e', - 'X', 'X', 'X', - 'X', 'X', 'X', - 'X', 'X', 'X', - 'X', 'X', -/* 0x40 '@' offset 1288 */ - 0, 42, 42, 0, 1, 6, - 30, /* snap_x */ - -42, -32, -21, -15, -10, 0, /* snap_y */ - 'm', 30, -26, - 'c', 28, -31, 24, -32, 21, -32, - 'c', 10, -32, 10, -23, 10, -19, - 'c', 10, -13, 11, -10, 19, -10, - 'c', 30, -10, 28, -21, 30, -32, - 'c', 27, -10, 30, -10, 34, -10, - 'c', 41, -10, 42, -19, 42, -22, - 'c', 42, -34, 34, -42, 21, -42, - 'c', 9, -42, 0, -34, 0, -21, - 'c', 0, -9, 8, 0, 21, 0, - 'c', 30, 0, 34, -3, 36, -6, - 'e', -/* 0x41 'A' offset 1375 */ - 0, 32, 42, 0, 2, 3, - 0, 32, /* snap_x */ - -42, -14, 0, /* snap_y */ - 'm', 0, 0, - 'l', 16, -42, - 'l', 32, 0, - 'm', 6, -14, - 'l', 26, -14, - 'e', - 'X', 'X', 'X', - 'X', -/* 0x42 'B' offset 1406 */ - 0, 28, 42, 0, 2, 3, - 0, 28, /* snap_x */ - -42, -22, 0, /* snap_y */ - 'm', 0, 0, - 'l', 0, -42, - 'l', 18, -42, - 'c', 32, -42, 32, -22, 18, -22, - 'l', 0, -22, - 'l', 18, -22, - 'c', 32, -22, 32, 0, 18, 0, - 'E', - 'X', 'X', 'X', - 'X', 'X', 'X', - 'X', 'X', -/* 0x43 'C' offset 1455 */ - 0, 30, 42, 0, 2, 4, - 0, 30, /* snap_x */ - -42, -21, -15, 0, /* snap_y */ - 'm', 30, -32, - 'c', 26, -42, 21, -42, 16, -42, - 'c', 2, -42, 0, -29, 0, -21, - 'c', 0, -13, 2, 0, 16, 0, - 'c', 21, 0, 26, 0, 30, -10, - 'e', -/* 0x44 'D' offset 1499 */ - 0, 28, 42, 0, 2, 2, - 0, 28, /* snap_x */ - -42, 0, /* snap_y */ - 'm', 0, 0, - 'l', 0, -42, - 'l', 14, -42, - 'c', 33, -42, 33, 0, 14, 0, - 'E', - 'X', 'X', 'X', - 'X', 'X', 'X', - 'X', 'X', -/* 0x45 'E' offset 1534 */ - 0, 26, 42, 0, 2, 3, - 0, 26, /* snap_x */ - -42, -22, 0, /* snap_y */ - 'm', 26, -42, - 'l', 0, -42, - 'l', 0, 0, - 'l', 26, 0, - 'm', 0, -22, - 'l', 16, -22, - 'e', - 'X', 'X', 'X', - 'X', 'X', 'X', - 'X', 'X', -/* 0x46 'F' offset 1572 */ - 0, 26, 42, 0, 2, 3, - 0, 26, /* snap_x */ - -42, -22, 0, /* snap_y */ - 'm', 0, 0, - 'l', 0, -42, - 'l', 26, -42, - 'm', 0, -22, - 'l', 16, -22, - 'e', - 'X', 'X', 'X', - 'X', 'X', -/* 0x47 'G' offset 1604 */ - 0, 30, 42, 0, 2, 5, - 0, 30, /* snap_x */ - -42, -21, -16, -15, 0, /* snap_y */ - 'm', 30, -32, - 'c', 26, -42, 21, -42, 16, -42, - 'c', 2, -42, 0, -29, 0, -21, - 'c', 0, -13, 2, 0, 16, 0, - 'c', 28, 0, 30, -7, 30, -16, - 'l', 20, -16, - 'e', - 'X', 'X', 'X', -/* 0x48 'H' offset 1655 */ - 0, 28, 42, 0, 2, 3, - 0, 28, /* snap_x */ - -42, -22, 0, /* snap_y */ - 'm', 0, -42, - 'l', 0, 0, - 'm', 28, -42, - 'l', 28, 0, - 'm', 0, -22, - 'l', 28, -22, - 'e', - 'X', -/* 0x49 'I' offset 1686 */ - 0, 0, 42, 0, 1, 2, - 0, /* snap_x */ - -42, 0, /* snap_y */ - 'm', 0, -42, - 'l', 0, 0, - 'e', - 'X', -/* 0x4a 'J' offset 1703 */ - 0, 20, 42, 0, 2, 3, - 0, 20, /* snap_x */ - -42, -15, 0, /* snap_y */ - 'm', 20, -42, - 'l', 20, -10, - 'c', 20, 3, 0, 3, 0, -10, - 'l', 0, -14, - 'e', -/* 0x4b 'K' offset 1731 */ - 0, 28, 42, 0, 2, 3, - 0, 28, /* snap_x */ - -42, -15, 0, /* snap_y */ - 'm', 0, -42, - 'l', 0, 0, - 'm', 28, -42, - 'l', 0, -14, - 'm', 10, -24, - 'l', 28, 0, - 'e', -/* 0x4c 'L' offset 1761 */ - 0, 24, 42, 0, 2, 2, - 0, 24, /* snap_x */ - -42, 0, /* snap_y */ - 'm', 0, -42, - 'l', 0, 0, - 'l', 24, 0, - 'e', - 'X', 'X', 'X', - 'X', -/* 0x4d 'M' offset 1785 */ - 0, 32, 42, 0, 2, 2, - 0, 32, /* snap_x */ - -42, 0, /* snap_y */ - 'm', 0, 0, - 'l', 0, -42, - 'l', 16, 0, - 'l', 32, -42, - 'l', 32, 0, - 'e', - 'X', 'X', 'X', - 'X', 'X', 'X', - 'X', 'X', 'X', - 'X', -/* 0x4e 'N' offset 1821 */ - 0, 28, 42, 0, 2, 2, - 0, 28, /* snap_x */ - -42, 0, /* snap_y */ - 'm', 0, 0, - 'l', 0, -42, - 'l', 28, 0, - 'l', 28, -42, - 'e', - 'X', 'X', 'X', - 'X', 'X', 'X', - 'X', -/* 0x4f 'O' offset 1851 */ - 0, 32, 42, 0, 2, 4, - 0, 32, /* snap_x */ - -42, -21, -15, 0, /* snap_y */ - 'm', 16, -42, - 'c', 2, -42, 0, -29, 0, -21, - 'c', 0, -13, 2, 0, 16, 0, - 'c', 30, 0, 32, -13, 32, -21, - 'c', 32, -29, 30, -42, 16, -42, - 'E', -/* 0x50 'P' offset 1895 */ - 0, 28, 42, 0, 2, 5, - 0, 28, /* snap_x */ - -42, -21, -20, -15, 0, /* snap_y */ - 'm', 0, 0, - 'l', 0, -42, - 'l', 18, -42, - 'c', 32, -42, 32, -20, 18, -20, - 'l', 0, -20, - 'e', - 'X', 'X', 'X', -/* 0x51 'Q' offset 1931 */ - 0, 32, 42, 4, 2, 4, - 0, 32, /* snap_x */ - -42, -21, -15, 0, /* snap_y */ - 'm', 16, -42, - 'c', 2, -42, 0, -29, 0, -21, - 'c', 0, -13, 2, 0, 16, 0, - 'c', 30, 0, 32, -13, 32, -21, - 'c', 32, -29, 30, -42, 16, -42, - 'M', 18, -8, - 'l', 30, 4, - 'e', -/* 0x52 'R' offset 1981 */ - 0, 28, 42, 0, 2, 5, - 0, 28, /* snap_x */ - -42, -22, -21, -15, 0, /* snap_y */ - 'm', 0, 0, - 'l', 0, -42, - 'l', 18, -42, - 'c', 32, -42, 31, -22, 18, -22, - 'l', 0, -22, - 'm', 14, -22, - 'l', 28, 0, - 'e', - 'X', 'X', 'X', -/* 0x53 'S' offset 2023 */ - 0, 28, 42, 0, 2, 4, - 0, 28, /* snap_x */ - -42, -21, -15, 0, /* snap_y */ - 'm', 28, -36, - 'c', 25, -41, 21, -42, 14, -42, - 'c', 10, -42, 0, -42, 0, -34, - 'c', 0, -17, 28, -28, 28, -9, - 'c', 28, 0, 19, 0, 14, 0, - 'c', 7, 0, 3, -1, 0, -6, - 'e', -/* 0x54 'T' offset 2074 */ - 0, 28, 42, 0, 3, 4, - 0, 14, 28, /* snap_x */ - -42, -21, -15, 0, /* snap_y */ - 'm', 14, -42, - 'l', 14, 0, - 'm', 0, -42, - 'l', 28, -42, - 'e', -/* 0x55 'U' offset 2100 */ - 0, 28, 42, 0, 2, 2, - 0, 28, /* snap_x */ - -42, 0, /* snap_y */ - 'm', 0, -42, - 'l', 0, -12, - 'c', 0, 4, 28, 4, 28, -12, - 'l', 28, -42, - 'e', - 'X', -/* 0x56 'V' offset 2128 */ - 0, 32, 42, 0, 2, 2, - 0, 32, /* snap_x */ - -42, 0, /* snap_y */ - 'm', 0, -42, - 'l', 16, 0, - 'l', 32, -42, - 'e', - 'X', 'X', 'X', - 'X', -/* 0x57 'W' offset 2152 */ - 0, 40, 42, 0, 2, 2, - 0, 40, /* snap_x */ - -42, 0, /* snap_y */ - 'm', 0, -42, - 'l', 10, 0, - 'l', 20, -42, - 'l', 30, 0, - 'l', 40, -42, - 'e', - 'X', 'X', 'X', - 'X', 'X', 'X', - 'X', 'X', 'X', - 'X', -/* 0x58 'X' offset 2188 */ - 0, 28, 42, 0, 2, 2, - 0, 28, /* snap_x */ - -42, 0, /* snap_y */ - 'm', 0, -42, - 'l', 28, 0, - 'm', 28, -42, - 'l', 0, 0, - 'e', - 'X', -/* 0x59 'Y' offset 2212 */ - 0, 32, 42, 0, 3, 3, - 0, 16, 32, /* snap_x */ - -42, -21, 0, /* snap_y */ - 'm', 0, -42, - 'l', 16, -22, - 'l', 16, 0, - 'm', 32, -42, - 'l', 16, -22, - 'e', -/* 0x5a 'Z' offset 2240 */ - 0, 28, 42, 0, 2, 4, - 0, 28, /* snap_x */ - -42, -21, -15, 0, /* snap_y */ - 'm', 28, 0, - 'l', 0, 0, - 'l', 28, -42, - 'l', 0, -42, - 'e', - 'X', 'X', 'X', - 'X', 'X', 'X', -/* 0x5b '[' offset 2271 */ - 0, 14, 44, 0, 2, 4, - 0, 14, /* snap_x */ - -44, -21, -15, 0, /* snap_y */ - 'm', 14, -44, - 'l', 0, -44, - 'l', 0, 0, - 'l', 14, 0, - 'e', -/* 0x5c '\' offset 2296 */ - 0, 36, 50, 14, 2, 3, - 0, 36, /* snap_x */ - -21, -15, 0, /* snap_y */ - 'm', 0, -50, - 'l', 36, 14, - 'e', -/* 0x5d ']' offset 2314 */ - 0, 14, 44, 0, 2, 4, - 0, 14, /* snap_x */ - -44, -21, -15, 0, /* snap_y */ - 'm', 0, -44, - 'l', 14, -44, - 'l', 14, 0, - 'l', 0, 0, - 'e', -/* 0x5e '^' offset 2339 */ - 0, 32, 46, -18, 2, 3, - 0, 32, /* snap_x */ - -21, -15, 0, /* snap_y */ - 'm', 0, -18, - 'l', 16, -46, - 'l', 32, -18, - 'e', - 'X', 'X', 'X', -/* 0x5f '_' offset 2363 */ - 0, 36, 0, 0, 2, 1, - 0, 36, /* snap_x */ - 0, /* snap_y */ - 'm', 0, 0, - 'l', 36, 0, - 'e', - 'X', 'X', -/* 0x60 '`' offset 2381 */ - 0, 4, 42, -30, 2, 2, - 0, 4, /* snap_x */ - -42, 0, /* snap_y */ - 'm', 4, -42, - 'c', 2, -40, 0, -39, 0, -32, - 'c', 0, -31, 1, -30, 2, -30, - 'c', 5, -30, 5, -34, 2, -34, - 'e', - 'X', -/* 0x61 'a' offset 2417 */ - 0, 24, 28, 0, 2, 4, - 0, 24, /* snap_x */ - -28, -21, -15, 0, /* snap_y */ - 'm', 24, -28, - 'l', 24, 0, - 'm', 24, -22, - 'c', 21, -27, 18, -28, 13, -28, - 'c', 2, -28, 0, -19, 0, -14, - 'c', 0, -9, 2, 0, 13, 0, - 'c', 18, 0, 21, -1, 24, -6, - 'e', -/* 0x62 'b' offset 2467 */ - 0, 24, 42, 0, 2, 4, - 0, 24, /* snap_x */ - -42, -28, -15, 0, /* snap_y */ - 'm', 0, -42, - 'l', 0, 0, - 'm', 0, -22, - 'c', 3, -26, 6, -28, 11, -28, - 'c', 22, -28, 24, -19, 24, -14, - 'c', 24, -9, 22, 0, 11, 0, - 'c', 6, 0, 3, -2, 0, -6, - 'e', -/* 0x63 'c' offset 2517 */ - 0, 24, 28, 0, 2, 4, - 0, 24, /* snap_x */ - -28, -21, -15, 0, /* snap_y */ - 'm', 24, -22, - 'c', 21, -26, 18, -28, 13, -28, - 'c', 2, -28, 0, -19, 0, -14, - 'c', 0, -9, 2, 0, 13, 0, - 'c', 18, 0, 21, -2, 24, -6, - 'e', -/* 0x64 'd' offset 2561 */ - 0, 24, 42, 0, 2, 4, - 0, 24, /* snap_x */ - -42, -28, -15, 0, /* snap_y */ - 'm', 24, -42, - 'l', 24, 0, - 'm', 24, -22, - 'c', 21, -26, 18, -28, 13, -28, - 'c', 2, -28, 0, -19, 0, -14, - 'c', 0, -9, 2, 0, 13, 0, - 'c', 18, 0, 21, -2, 24, -6, - 'e', -/* 0x65 'e' offset 2611 */ - 0, 24, 28, 0, 2, 5, - 0, 24, /* snap_x */ - -28, -21, -16, -15, 0, /* snap_y */ - 'm', 0, -16, - 'l', 24, -16, - 'c', 24, -20, 24, -28, 13, -28, - 'c', 2, -28, 0, -19, 0, -14, - 'c', 0, -9, 2, 0, 13, 0, - 'c', 18, 0, 21, -2, 24, -6, - 'e', -/* 0x66 'f' offset 2659 */ - 0, 16, 42, 0, 3, 5, - 0, 6, 16, /* snap_x */ - -42, -28, -21, -15, 0, /* snap_y */ - 'm', 16, -42, - 'c', 8, -42, 6, -40, 6, -34, - 'l', 6, 0, - 'm', 0, -28, - 'l', 14, -28, - 'e', -/* 0x67 'g' offset 2693 */ - 0, 24, 28, 14, 2, 5, - 0, 24, /* snap_x */ - -28, -21, -15, 0, 14, /* snap_y */ - 'm', 24, -28, - 'l', 24, 4, - 'c', 23, 14, 16, 14, 13, 14, - 'c', 10, 14, 8, 14, 6, 12, - 'm', 24, -22, - 'c', 21, -26, 18, -28, 13, -28, - 'c', 2, -28, 0, -19, 0, -14, - 'c', 0, -9, 2, 0, 13, 0, - 'c', 18, 0, 21, -2, 24, -6, - 'e', -/* 0x68 'h' offset 2758 */ - 0, 22, 42, 0, 2, 4, - 0, 22, /* snap_x */ - -42, -28, -15, 0, /* snap_y */ - 'm', 0, -42, - 'l', 0, 0, - 'm', 0, -20, - 'c', 8, -32, 22, -31, 22, -20, - 'l', 22, 0, - 'e', -/* 0x69 'i' offset 2790 */ - 0, 0, 44, 0, 1, 3, - 0, /* snap_x */ - -42, -28, 0, /* snap_y */ - 'm', 0, -42, - 'l', 0, -42, - 'm', 0, -28, - 'l', 0, 0, - 'e', - 'X', 'X', 'X', - 'X', 'X', 'X', - 'X', 'X', 'X', - 'X', 'X', - 'X', 'X', -/* 0x6a 'j' offset 2826 */ - -8, 4, 44, 14, 3, 5, - -8, 2, 4, /* snap_x */ - -42, -21, -15, 0, 14, /* snap_y */ - 'm', 2, -42, - 'l', 2, -42, - 'm', 2, -28, - 'l', 2, 6, - 'c', 2, 13, -1, 14, -8, 14, - 'e', - 'X', 'X', 'X', - 'X', 'X', 'X', - 'X', 'X', 'X', - 'X', -/* 0x6b 'k' offset 2870 */ - 0, 22, 42, 0, 2, 3, - 0, 22, /* snap_x */ - -42, -28, 0, /* snap_y */ - 'm', 0, -42, - 'l', 0, 0, - 'm', 20, -28, - 'l', 0, -8, - 'm', 8, -16, - 'l', 22, 0, - 'e', -/* 0x6c 'l' offset 2900 */ - 0, 0, 42, 0, 1, 2, - 0, /* snap_x */ - -42, 0, /* snap_y */ - 'm', 0, -42, - 'l', 0, 0, - 'e', - 'X', -/* 0x6d 'm' offset 2917 */ - 0, 44, 28, 0, 3, 3, - 0, 22, 44, /* snap_x */ - -28, -21, 0, /* snap_y */ - 'm', 0, -28, - 'l', 0, 0, - 'm', 0, -20, - 'c', 5, -29, 22, -33, 22, -20, - 'l', 22, 0, - 'm', 22, -20, - 'c', 27, -29, 44, -33, 44, -20, - 'l', 44, 0, - 'e', - 'X', -/* 0x6e 'n' offset 2963 */ - 0, 22, 28, 0, 2, 3, - 0, 22, /* snap_x */ - -28, -21, 0, /* snap_y */ - 'm', 0, -28, - 'l', 0, 0, - 'm', 0, -20, - 'c', 4, -28, 22, -34, 22, -20, - 'l', 22, 0, - 'e', - 'X', -/* 0x6f 'o' offset 2995 */ - 0, 26, 28, 0, 2, 4, - 0, 26, /* snap_x */ - -28, -21, -15, 0, /* snap_y */ - 'm', 13, -28, - 'c', 2, -28, 0, -19, 0, -14, - 'c', 0, -9, 2, 0, 13, 0, - 'c', 24, 0, 26, -9, 26, -14, - 'c', 26, -19, 24, -28, 13, -28, - 'E', -/* 0x70 'p' offset 3039 */ - 0, 24, 28, 14, 2, 4, - 0, 24, /* snap_x */ - -28, -21, 0, 14, /* snap_y */ - 'm', 0, -28, - 'l', 0, 14, - 'm', 0, -22, - 'c', 3, -26, 6, -28, 11, -28, - 'c', 22, -28, 24, -19, 24, -14, - 'c', 24, -9, 22, 0, 11, 0, - 'c', 6, 0, 3, -2, 0, -6, - 'e', -/* 0x71 'q' offset 3089 */ - 0, 24, 28, 14, 2, 4, - 0, 24, /* snap_x */ - -28, -21, 0, 14, /* snap_y */ - 'm', 24, -28, - 'l', 24, 14, - 'm', 24, -22, - 'c', 21, -26, 18, -28, 13, -28, - 'c', 2, -28, 0, -19, 0, -14, - 'c', 0, -9, 2, 0, 13, 0, - 'c', 18, 0, 21, -2, 24, -6, - 'e', -/* 0x72 'r' offset 3139 */ - 0, 16, 28, 0, 2, 4, - 0, 16, /* snap_x */ - -28, -21, -15, 0, /* snap_y */ - 'm', 0, -28, - 'l', 0, 0, - 'm', 0, -16, - 'c', 2, -27, 7, -28, 16, -28, - 'e', -/* 0x73 's' offset 3168 */ - 0, 22, 28, 0, 2, 4, - 0, 22, /* snap_x */ - -28, -21, -15, 0, /* snap_y */ - 'm', 22, -22, - 'c', 22, -27, 16, -28, 11, -28, - 'c', 4, -28, 0, -26, 0, -22, - 'c', 0, -11, 22, -20, 22, -7, - 'c', 22, 0, 17, 0, 11, 0, - 'c', 6, 0, 0, -1, 0, -6, - 'e', -/* 0x74 't' offset 3219 */ - 0, 16, 42, 0, 3, 4, - 0, 6, 16, /* snap_x */ - -42, -28, -21, 0, /* snap_y */ - 'm', 6, -42, - 'l', 6, -8, - 'c', 6, -2, 8, 0, 16, 0, - 'm', 0, -28, - 'l', 14, -28, - 'e', -/* 0x75 'u' offset 3252 */ - 0, 22, 28, 0, 2, 3, - 0, 22, /* snap_x */ - -28, -15, 0, /* snap_y */ - 'm', 0, -28, - 'l', 0, -8, - 'c', 0, 6, 18, 0, 22, -8, - 'm', 22, -28, - 'l', 22, 0, - 'e', -/* 0x76 'v' offset 3283 */ - 0, 24, 28, 0, 2, 3, - 0, 24, /* snap_x */ - -28, -15, 0, /* snap_y */ - 'm', 0, -28, - 'l', 12, 0, - 'l', 24, -28, - 'e', - 'X', 'X', 'X', -/* 0x77 'w' offset 3307 */ - 0, 32, 28, 0, 2, 3, - 0, 32, /* snap_x */ - -28, -15, 0, /* snap_y */ - 'm', 0, -28, - 'l', 8, 0, - 'l', 16, -28, - 'l', 24, 0, - 'l', 32, -28, - 'e', - 'X', 'X', 'X', - 'X', 'X', 'X', - 'X', 'X', 'X', -/* 0x78 'x' offset 3343 */ - 0, 22, 28, 0, 2, 2, - 0, 22, /* snap_x */ - -28, 0, /* snap_y */ - 'm', 0, -28, - 'l', 22, 0, - 'm', 22, -28, - 'l', 0, 0, - 'e', - 'X', -/* 0x79 'y' offset 3367 */ - -2, 24, 28, 14, 2, 4, - 0, 24, /* snap_x */ - -28, -15, 0, 14, /* snap_y */ - 'm', 0, -28, - 'l', 12, 0, - 'm', 24, -28, - 'l', 12, 0, - 'c', 6, 13, 0, 14, -2, 14, - 'e', -/* 0x7a 'z' offset 3399 */ - 0, 22, 28, 0, 2, 4, - 0, 22, /* snap_x */ - -28, -21, -15, 0, /* snap_y */ - 'm', 22, 0, - 'l', 0, 0, - 'l', 22, -28, - 'l', 0, -28, - 'e', - 'X', 'X', 'X', - 'X', 'X', 'X', -/* 0x7b '{' offset 3430 */ - 0, 16, 44, 0, 3, 5, - 0, 6, 16, /* snap_x */ - -44, -24, -21, -15, 0, /* snap_y */ - 'm', 16, -44, - 'c', 10, -44, 6, -42, 6, -36, - 'l', 6, -24, - 'l', 0, -24, - 'l', 6, -24, - 'l', 6, -8, - 'c', 6, -2, 10, 0, 16, 0, - 'e', -/* 0x7c '|' offset 3474 */ - 0, 0, 50, 14, 1, 2, - 0, /* snap_x */ - -50, 14, /* snap_y */ - 'm', 0, -50, - 'l', 0, 14, - 'e', - 'X', -/* 0x7d '}' offset 3491 */ - 0, 16, 44, 0, 3, 5, - 0, 10, 16, /* snap_x */ - -44, -24, -21, -15, 0, /* snap_y */ - 'm', 0, -44, - 'c', 6, -44, 10, -42, 10, -36, - 'l', 10, -24, - 'l', 16, -24, - 'l', 10, -24, - 'l', 10, -8, - 'c', 10, -2, 6, 0, 0, 0, - 'e', -/* 0x7e '~' offset 3535 */ - 0, 36, 24, -12, 2, 5, - 0, 36, /* snap_x */ - -24, -21, -15, -12, 0, /* snap_y */ - 'm', 0, -14, - 'c', 1, -21, 4, -24, 8, -24, - 'c', 18, -24, 18, -12, 28, -12, - 'c', 32, -12, 35, -15, 36, -22, - 'e', -}; - -const uint16_t _cairo_twin_charmap[128] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 28, 40, 90, 114, 152, 224, 323, 390, - 419, 441, 463, 494, 520, 556, 575, 604, - 622, 666, 691, 736, 780, 809, 860, 919, - 944, 1004, 1063, 1109, 1162, 1183, 1209, 1230, - 1288, 1375, 1406, 1455, 1499, 1534, 1572, 1604, - 1655, 1686, 1703, 1731, 1761, 1785, 1821, 1851, - 1895, 1931, 1981, 2023, 2074, 2100, 2128, 2152, - 2188, 2212, 2240, 2271, 2296, 2314, 2339, 2363, - 2381, 2417, 2467, 2517, 2561, 2611, 2659, 2693, - 2758, 2790, 2826, 2870, 2900, 2917, 2963, 2995, - 3039, 3089, 3139, 3168, 3219, 3252, 3283, 3307, - 3343, 3367, 3399, 3430, 3474, 3491, 3535, 0, -}; - diff --git a/source/libs/cairo/cairo-src/src/cairo-font-face-twin.c b/source/libs/cairo/cairo-src/src/cairo-font-face-twin.c deleted file mode 100644 index 2ad263028492836d1330caeafac935bcfa6d3aa6..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-font-face-twin.c +++ /dev/null @@ -1,752 +0,0 @@ -/* - * Copyright © 2004 Keith Packard - * Copyright © 2008 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Keith Packard - * - * Contributor(s): - * Keith Packard <keithp@keithp.com> - * Behdad Esfahbod <behdad@behdad.org> - */ - -#include "cairoint.h" -#include "cairo-error-private.h" - -#include <math.h> - -/* - * This file implements a user-font rendering the descendant of the Hershey - * font coded by Keith Packard for use in the Twin window system. - * The actual font data is in cairo-font-face-twin-data.c - * - * Ported to cairo user font and extended by Behdad Esfahbod. - */ - - - -static cairo_user_data_key_t twin_properties_key; - - -/* - * Face properties - */ - -/* We synthesize multiple faces from the twin data. Here is the parameters. */ - -/* The following tables and matching code are copied from Pango */ - -/* CSS weight */ -typedef enum { - TWIN_WEIGHT_THIN = 100, - TWIN_WEIGHT_ULTRALIGHT = 200, - TWIN_WEIGHT_LIGHT = 300, - TWIN_WEIGHT_BOOK = 380, - TWIN_WEIGHT_NORMAL = 400, - TWIN_WEIGHT_MEDIUM = 500, - TWIN_WEIGHT_SEMIBOLD = 600, - TWIN_WEIGHT_BOLD = 700, - TWIN_WEIGHT_ULTRABOLD = 800, - TWIN_WEIGHT_HEAVY = 900, - TWIN_WEIGHT_ULTRAHEAVY = 1000 -} twin_face_weight_t; - -/* CSS stretch */ -typedef enum { - TWIN_STRETCH_ULTRA_CONDENSED, - TWIN_STRETCH_EXTRA_CONDENSED, - TWIN_STRETCH_CONDENSED, - TWIN_STRETCH_SEMI_CONDENSED, - TWIN_STRETCH_NORMAL, - TWIN_STRETCH_SEMI_EXPANDED, - TWIN_STRETCH_EXPANDED, - TWIN_STRETCH_EXTRA_EXPANDED, - TWIN_STRETCH_ULTRA_EXPANDED -} twin_face_stretch_t; - -typedef struct -{ - int value; - const char str[16]; -} FieldMap; - -static const FieldMap slant_map[] = { - { CAIRO_FONT_SLANT_NORMAL, "" }, - { CAIRO_FONT_SLANT_NORMAL, "Roman" }, - { CAIRO_FONT_SLANT_OBLIQUE, "Oblique" }, - { CAIRO_FONT_SLANT_ITALIC, "Italic" } -}; - -static const FieldMap smallcaps_map[] = { - { FALSE, "" }, - { TRUE, "Small-Caps" } -}; - -static const FieldMap weight_map[] = { - { TWIN_WEIGHT_THIN, "Thin" }, - { TWIN_WEIGHT_ULTRALIGHT, "Ultra-Light" }, - { TWIN_WEIGHT_ULTRALIGHT, "Extra-Light" }, - { TWIN_WEIGHT_LIGHT, "Light" }, - { TWIN_WEIGHT_BOOK, "Book" }, - { TWIN_WEIGHT_NORMAL, "" }, - { TWIN_WEIGHT_NORMAL, "Regular" }, - { TWIN_WEIGHT_MEDIUM, "Medium" }, - { TWIN_WEIGHT_SEMIBOLD, "Semi-Bold" }, - { TWIN_WEIGHT_SEMIBOLD, "Demi-Bold" }, - { TWIN_WEIGHT_BOLD, "Bold" }, - { TWIN_WEIGHT_ULTRABOLD, "Ultra-Bold" }, - { TWIN_WEIGHT_ULTRABOLD, "Extra-Bold" }, - { TWIN_WEIGHT_HEAVY, "Heavy" }, - { TWIN_WEIGHT_HEAVY, "Black" }, - { TWIN_WEIGHT_ULTRAHEAVY, "Ultra-Heavy" }, - { TWIN_WEIGHT_ULTRAHEAVY, "Extra-Heavy" }, - { TWIN_WEIGHT_ULTRAHEAVY, "Ultra-Black" }, - { TWIN_WEIGHT_ULTRAHEAVY, "Extra-Black" } -}; - -static const FieldMap stretch_map[] = { - { TWIN_STRETCH_ULTRA_CONDENSED, "Ultra-Condensed" }, - { TWIN_STRETCH_EXTRA_CONDENSED, "Extra-Condensed" }, - { TWIN_STRETCH_CONDENSED, "Condensed" }, - { TWIN_STRETCH_SEMI_CONDENSED, "Semi-Condensed" }, - { TWIN_STRETCH_NORMAL, "" }, - { TWIN_STRETCH_SEMI_EXPANDED, "Semi-Expanded" }, - { TWIN_STRETCH_EXPANDED, "Expanded" }, - { TWIN_STRETCH_EXTRA_EXPANDED, "Extra-Expanded" }, - { TWIN_STRETCH_ULTRA_EXPANDED, "Ultra-Expanded" } -}; - -static const FieldMap monospace_map[] = { - { FALSE, "" }, - { TRUE, "Mono" }, - { TRUE, "Monospace" } -}; - - -typedef struct _twin_face_properties { - cairo_font_slant_t slant; - twin_face_weight_t weight; - twin_face_stretch_t stretch; - - /* lets have some fun */ - cairo_bool_t monospace; - cairo_bool_t smallcaps; -} twin_face_properties_t; - -static cairo_bool_t -field_matches (const char *s1, - const char *s2, - int len) -{ - int c1, c2; - - while (len && *s1 && *s2) - { -#define TOLOWER(c) \ - (((c) >= 'A' && (c) <= 'Z') ? (c) - 'A' + 'a' : (c)) - - c1 = TOLOWER (*s1); - c2 = TOLOWER (*s2); - if (c1 != c2) { - if (c1 == '-') { - s1++; - continue; - } - return FALSE; - } - s1++; s2++; - len--; - } - - return len == 0 && *s1 == '\0'; -} - -static cairo_bool_t -parse_int (const char *word, - size_t wordlen, - int *out) -{ - char *end; - long val = strtol (word, &end, 10); - int i = val; - - if (end != word && (end == word + wordlen) && val >= 0 && val == i) - { - if (out) - *out = i; - - return TRUE; - } - - return FALSE; -} - -static cairo_bool_t -find_field (const char *what, - const FieldMap *map, - int n_elements, - const char *str, - int len, - int *val) -{ - int i; - cairo_bool_t had_prefix = FALSE; - - if (what) - { - i = strlen (what); - if (len > i && 0 == strncmp (what, str, i) && str[i] == '=') - { - str += i + 1; - len -= i + 1; - had_prefix = TRUE; - } - } - - for (i=0; i<n_elements; i++) - { - if (map[i].str[0] && field_matches (map[i].str, str, len)) - { - if (val) - *val = map[i].value; - return TRUE; - } - } - - if (!what || had_prefix) - return parse_int (str, len, val); - - return FALSE; -} - -static void -parse_field (twin_face_properties_t *props, - const char *str, - int len) -{ - if (field_matches ("Normal", str, len)) - return; - -#define FIELD(NAME) \ - if (find_field (STRINGIFY (NAME), NAME##_map, ARRAY_LENGTH (NAME##_map), str, len, \ - (int *)(void *)&props->NAME)) \ - return; \ - - FIELD (weight); - FIELD (slant); - FIELD (stretch); - FIELD (smallcaps); - FIELD (monospace); - -#undef FIELD -} - -static void -face_props_parse (twin_face_properties_t *props, - const char *s) -{ - const char *start, *end; - - for (start = end = s; *end; end++) { - if (*end != ' ' && *end != ':') - continue; - - if (start < end) - parse_field (props, start, end - start); - start = end + 1; - } - if (start < end) - parse_field (props, start, end - start); -} - -static twin_face_properties_t * -twin_font_face_create_properties (cairo_font_face_t *twin_face) -{ - twin_face_properties_t *props; - - props = malloc (sizeof (twin_face_properties_t)); - if (unlikely (props == NULL)) - return NULL; - - props->stretch = TWIN_STRETCH_NORMAL; - props->slant = CAIRO_FONT_SLANT_NORMAL; - props->weight = TWIN_WEIGHT_NORMAL; - props->monospace = FALSE; - props->smallcaps = FALSE; - - if (unlikely (cairo_font_face_set_user_data (twin_face, - &twin_properties_key, - props, free))) { - free (props); - return NULL; - } - - return props; -} - -static cairo_status_t -twin_font_face_set_properties_from_toy (cairo_font_face_t *twin_face, - cairo_toy_font_face_t *toy_face) -{ - twin_face_properties_t *props; - - props = twin_font_face_create_properties (twin_face); - if (unlikely (props == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - props->slant = toy_face->slant; - props->weight = toy_face->weight == CAIRO_FONT_WEIGHT_NORMAL ? - TWIN_WEIGHT_NORMAL : TWIN_WEIGHT_BOLD; - face_props_parse (props, toy_face->family); - - return CAIRO_STATUS_SUCCESS; -} - - -/* - * Scaled properties - */ - -typedef struct _twin_scaled_properties { - twin_face_properties_t *face_props; - - cairo_bool_t snap; /* hint outlines */ - - double weight; /* unhinted pen width */ - double penx, peny; /* hinted pen width */ - double marginl, marginr; /* hinted side margins */ - - double stretch; /* stretch factor */ -} twin_scaled_properties_t; - -static void -compute_hinting_scale (cairo_t *cr, - double x, double y, - double *scale, double *inv) -{ - cairo_user_to_device_distance (cr, &x, &y); - *scale = x == 0 ? y : y == 0 ? x :sqrt (x*x + y*y); - *inv = 1 / *scale; -} - -static void -compute_hinting_scales (cairo_t *cr, - double *x_scale, double *x_scale_inv, - double *y_scale, double *y_scale_inv) -{ - double x, y; - - x = 1; y = 0; - compute_hinting_scale (cr, x, y, x_scale, x_scale_inv); - - x = 0; y = 1; - compute_hinting_scale (cr, x, y, y_scale, y_scale_inv); -} - -#define SNAPXI(p) (_cairo_round ((p) * x_scale) * x_scale_inv) -#define SNAPYI(p) (_cairo_round ((p) * y_scale) * y_scale_inv) - -/* This controls the global font size */ -#define F(g) ((g) / 72.) - -static void -twin_hint_pen_and_margins(cairo_t *cr, - double *penx, double *peny, - double *marginl, double *marginr) -{ - double x_scale, x_scale_inv; - double y_scale, y_scale_inv; - double margin; - - compute_hinting_scales (cr, - &x_scale, &x_scale_inv, - &y_scale, &y_scale_inv); - - *penx = SNAPXI (*penx); - if (*penx < x_scale_inv) - *penx = x_scale_inv; - - *peny = SNAPYI (*peny); - if (*peny < y_scale_inv) - *peny = y_scale_inv; - - margin = *marginl + *marginr; - *marginl = SNAPXI (*marginl); - if (*marginl < x_scale_inv) - *marginl = x_scale_inv; - - *marginr = margin - *marginl; - if (*marginr < 0) - *marginr = 0; - *marginr = SNAPXI (*marginr); -} - -static cairo_status_t -twin_scaled_font_compute_properties (cairo_scaled_font_t *scaled_font, - cairo_t *cr) -{ - cairo_status_t status; - twin_scaled_properties_t *props; - - props = malloc (sizeof (twin_scaled_properties_t)); - if (unlikely (props == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - - props->face_props = cairo_font_face_get_user_data (cairo_scaled_font_get_font_face (scaled_font), - &twin_properties_key); - - props->snap = scaled_font->options.hint_style > CAIRO_HINT_STYLE_NONE; - - /* weight */ - props->weight = props->face_props->weight * (F (4) / TWIN_WEIGHT_NORMAL); - - /* pen & margins */ - props->penx = props->peny = props->weight; - props->marginl = props->marginr = F (4); - if (scaled_font->options.hint_style > CAIRO_HINT_STYLE_SLIGHT) - twin_hint_pen_and_margins(cr, - &props->penx, &props->peny, - &props->marginl, &props->marginr); - - /* stretch */ - props->stretch = 1 + .1 * ((int) props->face_props->stretch - (int) TWIN_STRETCH_NORMAL); - - - /* Save it */ - status = cairo_scaled_font_set_user_data (scaled_font, - &twin_properties_key, - props, free); - if (unlikely (status)) - goto FREE_PROPS; - - return CAIRO_STATUS_SUCCESS; - -FREE_PROPS: - free (props); - return status; -} - - -/* - * User-font implementation - */ - -static cairo_status_t -twin_scaled_font_init (cairo_scaled_font_t *scaled_font, - cairo_t *cr, - cairo_font_extents_t *metrics) -{ - metrics->ascent = F (54); - metrics->descent = 1 - metrics->ascent; - - return twin_scaled_font_compute_properties (scaled_font, cr); -} - -#define TWIN_GLYPH_MAX_SNAP_X 4 -#define TWIN_GLYPH_MAX_SNAP_Y 7 - -typedef struct { - int n_snap_x; - int8_t snap_x[TWIN_GLYPH_MAX_SNAP_X]; - double snapped_x[TWIN_GLYPH_MAX_SNAP_X]; - int n_snap_y; - int8_t snap_y[TWIN_GLYPH_MAX_SNAP_Y]; - double snapped_y[TWIN_GLYPH_MAX_SNAP_Y]; -} twin_snap_info_t; - -#define twin_glyph_left(g) ((g)[0]) -#define twin_glyph_right(g) ((g)[1]) -#define twin_glyph_ascent(g) ((g)[2]) -#define twin_glyph_descent(g) ((g)[3]) - -#define twin_glyph_n_snap_x(g) ((g)[4]) -#define twin_glyph_n_snap_y(g) ((g)[5]) -#define twin_glyph_snap_x(g) (&g[6]) -#define twin_glyph_snap_y(g) (twin_glyph_snap_x(g) + twin_glyph_n_snap_x(g)) -#define twin_glyph_draw(g) (twin_glyph_snap_y(g) + twin_glyph_n_snap_y(g)) - -static void -twin_compute_snap (cairo_t *cr, - twin_snap_info_t *info, - const signed char *b) -{ - int s, n; - const signed char *snap; - double x_scale, x_scale_inv; - double y_scale, y_scale_inv; - - compute_hinting_scales (cr, - &x_scale, &x_scale_inv, - &y_scale, &y_scale_inv); - - snap = twin_glyph_snap_x (b); - n = twin_glyph_n_snap_x (b); - info->n_snap_x = n; - assert (n <= TWIN_GLYPH_MAX_SNAP_X); - for (s = 0; s < n; s++) { - info->snap_x[s] = snap[s]; - info->snapped_x[s] = SNAPXI (F (snap[s])); - } - - snap = twin_glyph_snap_y (b); - n = twin_glyph_n_snap_y (b); - info->n_snap_y = n; - assert (n <= TWIN_GLYPH_MAX_SNAP_Y); - for (s = 0; s < n; s++) { - info->snap_y[s] = snap[s]; - info->snapped_y[s] = SNAPYI (F (snap[s])); - } -} - -static double -twin_snap (int8_t v, int n, int8_t *snap, double *snapped) -{ - int s; - - if (!n) - return F(v); - - if (snap[0] == v) - return snapped[0]; - - for (s = 0; s < n - 1; s++) - { - if (snap[s+1] == v) - return snapped[s+1]; - - if (snap[s] <= v && v <= snap[s+1]) - { - int before = snap[s]; - int after = snap[s+1]; - int dist = after - before; - double snap_before = snapped[s]; - double snap_after = snapped[s+1]; - double dist_before = v - before; - return snap_before + (snap_after - snap_before) * dist_before / dist; - } - } - return F(v); -} - -#define SNAPX(p) twin_snap (p, info.n_snap_x, info.snap_x, info.snapped_x) -#define SNAPY(p) twin_snap (p, info.n_snap_y, info.snap_y, info.snapped_y) - -static cairo_status_t -twin_scaled_font_render_glyph (cairo_scaled_font_t *scaled_font, - unsigned long glyph, - cairo_t *cr, - cairo_text_extents_t *metrics) -{ - double x1, y1, x2, y2, x3, y3; - double marginl; - twin_scaled_properties_t *props; - twin_snap_info_t info; - const int8_t *b; - const int8_t *g; - int8_t w; - double gw; - - props = cairo_scaled_font_get_user_data (scaled_font, &twin_properties_key); - - /* Save glyph space, we need it when stroking */ - cairo_save (cr); - - /* center the pen */ - cairo_translate (cr, props->penx * .5, -props->peny * .5); - - /* small-caps */ - if (props->face_props->smallcaps && glyph >= 'a' && glyph <= 'z') { - glyph += 'A' - 'a'; - /* 28 and 42 are small and capital letter heights of the glyph data */ - cairo_scale (cr, 1, 28. / 42); - } - - /* slant */ - if (props->face_props->slant != CAIRO_FONT_SLANT_NORMAL) { - cairo_matrix_t shear = { 1, 0, -.2, 1, 0, 0}; - cairo_transform (cr, &shear); - } - - b = _cairo_twin_outlines + - _cairo_twin_charmap[unlikely (glyph >= ARRAY_LENGTH (_cairo_twin_charmap)) ? 0 : glyph]; - g = twin_glyph_draw(b); - w = twin_glyph_right(b); - gw = F(w); - - marginl = props->marginl; - - /* monospace */ - if (props->face_props->monospace) { - double monow = F(24); - double extra = props->penx + props->marginl + props->marginr; - cairo_scale (cr, (monow + extra) / (gw + extra), 1); - gw = monow; - - /* resnap margin for new transform */ - { - double x, y, x_scale, x_scale_inv; - x = 1; y = 0; - compute_hinting_scale (cr, x, y, &x_scale, &x_scale_inv); - marginl = SNAPXI (marginl); - } - } - - cairo_translate (cr, marginl, 0); - - /* stretch */ - cairo_scale (cr, props->stretch, 1); - - if (props->snap) - twin_compute_snap (cr, &info, b); - else - info.n_snap_x = info.n_snap_y = 0; - - /* advance width */ - metrics->x_advance = gw * props->stretch + props->penx + props->marginl + props->marginr; - - /* glyph shape */ - for (;;) { - switch (*g++) { - case 'M': - cairo_close_path (cr); - /* fall through */ - case 'm': - x1 = SNAPX(*g++); - y1 = SNAPY(*g++); - cairo_move_to (cr, x1, y1); - continue; - case 'L': - cairo_close_path (cr); - /* fall through */ - case 'l': - x1 = SNAPX(*g++); - y1 = SNAPY(*g++); - cairo_line_to (cr, x1, y1); - continue; - case 'C': - cairo_close_path (cr); - /* fall through */ - case 'c': - x1 = SNAPX(*g++); - y1 = SNAPY(*g++); - x2 = SNAPX(*g++); - y2 = SNAPY(*g++); - x3 = SNAPX(*g++); - y3 = SNAPY(*g++); - cairo_curve_to (cr, x1, y1, x2, y2, x3, y3); - continue; - case 'E': - cairo_close_path (cr); - /* fall through */ - case 'e': - cairo_restore (cr); /* restore glyph space */ - cairo_set_tolerance (cr, 0.01); - cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); - cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); - cairo_set_line_width (cr, 1); - cairo_scale (cr, props->penx, props->peny); - cairo_stroke (cr); - break; - case 'X': - /* filler */ - continue; - } - break; - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -twin_scaled_font_unicode_to_glyph (cairo_scaled_font_t *scaled_font, - unsigned long unicode, - unsigned long *glyph) -{ - /* We use an identity charmap. Which means we could live - * with no unicode_to_glyph method too. But we define this - * to map all unknown chars to a single unknown glyph to - * reduce pressure on cache. */ - - if (likely (unicode < ARRAY_LENGTH (_cairo_twin_charmap))) - *glyph = unicode; - else - *glyph = 0; - - return CAIRO_STATUS_SUCCESS; -} - - -/* - * Face constructor - */ - -static cairo_font_face_t * -_cairo_font_face_twin_create_internal (void) -{ - cairo_font_face_t *twin_font_face; - - twin_font_face = cairo_user_font_face_create (); - cairo_user_font_face_set_init_func (twin_font_face, twin_scaled_font_init); - cairo_user_font_face_set_render_glyph_func (twin_font_face, twin_scaled_font_render_glyph); - cairo_user_font_face_set_unicode_to_glyph_func (twin_font_face, twin_scaled_font_unicode_to_glyph); - - return twin_font_face; -} - -cairo_font_face_t * -_cairo_font_face_twin_create_fallback (void) -{ - cairo_font_face_t *twin_font_face; - - twin_font_face = _cairo_font_face_twin_create_internal (); - if (! twin_font_face_create_properties (twin_font_face)) { - cairo_font_face_destroy (twin_font_face); - return (cairo_font_face_t *) &_cairo_font_face_nil; - } - - return twin_font_face; -} - -cairo_status_t -_cairo_font_face_twin_create_for_toy (cairo_toy_font_face_t *toy_face, - cairo_font_face_t **font_face) -{ - cairo_status_t status; - cairo_font_face_t *twin_font_face; - - twin_font_face = _cairo_font_face_twin_create_internal (); - status = twin_font_face_set_properties_from_toy (twin_font_face, toy_face); - if (status) { - cairo_font_face_destroy (twin_font_face); - return status; - } - - *font_face = twin_font_face; - - return CAIRO_STATUS_SUCCESS; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-font-face.c b/source/libs/cairo/cairo-src/src/cairo-font-face.c deleted file mode 100644 index 795951b142073f046d7e722503e24e0261774f7a..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-font-face.c +++ /dev/null @@ -1,345 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat Inc. - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Graydon Hoare <graydon@redhat.com> - * Owen Taylor <otaylor@redhat.com> - */ - -#include "cairoint.h" -#include "cairo-error-private.h" - -/** - * SECTION:cairo-font-face - * @Title: cairo_font_face_t - * @Short_Description: Base class for font faces - * @See_Also: #cairo_scaled_font_t - * - * #cairo_font_face_t represents a particular font at a particular weight, - * slant, and other characteristic but no size, transformation, or size. - * - * Font faces are created using <firstterm>font-backend</firstterm>-specific - * constructors, typically of the form - * <function>cairo_<emphasis>backend</emphasis>_font_face_create(<!-- -->)</function>, - * or implicitly using the <firstterm>toy</firstterm> text API by way of - * cairo_select_font_face(). The resulting face can be accessed using - * cairo_get_font_face(). - **/ - -/* #cairo_font_face_t */ - -const cairo_font_face_t _cairo_font_face_nil = { - { 0 }, /* hash_entry */ - CAIRO_STATUS_NO_MEMORY, /* status */ - CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ - { 0, 0, 0, NULL }, /* user_data */ - NULL -}; -const cairo_font_face_t _cairo_font_face_nil_file_not_found = { - { 0 }, /* hash_entry */ - CAIRO_STATUS_FILE_NOT_FOUND, /* status */ - CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ - { 0, 0, 0, NULL }, /* user_data */ - NULL -}; - -cairo_status_t -_cairo_font_face_set_error (cairo_font_face_t *font_face, - cairo_status_t status) -{ - if (status == CAIRO_STATUS_SUCCESS) - return status; - - /* Don't overwrite an existing error. This preserves the first - * error, which is the most significant. */ - _cairo_status_set_error (&font_face->status, status); - - return _cairo_error (status); -} - -void -_cairo_font_face_init (cairo_font_face_t *font_face, - const cairo_font_face_backend_t *backend) -{ - CAIRO_MUTEX_INITIALIZE (); - - font_face->status = CAIRO_STATUS_SUCCESS; - CAIRO_REFERENCE_COUNT_INIT (&font_face->ref_count, 1); - font_face->backend = backend; - - _cairo_user_data_array_init (&font_face->user_data); -} - -/** - * cairo_font_face_reference: - * @font_face: a #cairo_font_face_t, (may be %NULL in which case this - * function does nothing). - * - * Increases the reference count on @font_face by one. This prevents - * @font_face from being destroyed until a matching call to - * cairo_font_face_destroy() is made. - * - * The number of references to a #cairo_font_face_t can be get using - * cairo_font_face_get_reference_count(). - * - * Return value: the referenced #cairo_font_face_t. - * - * Since: 1.0 - **/ -cairo_font_face_t * -cairo_font_face_reference (cairo_font_face_t *font_face) -{ - if (font_face == NULL || - CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count)) - return font_face; - - /* We would normally assert that we have a reference here but we - * can't get away with that due to the zombie case as documented - * in _cairo_ft_font_face_destroy. */ - - _cairo_reference_count_inc (&font_face->ref_count); - - return font_face; -} -slim_hidden_def (cairo_font_face_reference); - -static inline cairo_bool_t -__put(cairo_reference_count_t *v) -{ - int c, old; - - c = CAIRO_REFERENCE_COUNT_GET_VALUE(v); - while (c != 1 && (old = _cairo_atomic_int_cmpxchg_return_old(&v->ref_count, c, c - 1)) != c) - c = old; - - return c != 1; -} - -cairo_bool_t -_cairo_font_face_destroy (void *abstract_face) -{ -#if 0 /* Nothing needs to be done, we can just drop the last reference */ - cairo_font_face_t *font_face = abstract_face; - return _cairo_reference_count_dec_and_test (&font_face->ref_count); -#endif - return TRUE; -} - -/** - * cairo_font_face_destroy: - * @font_face: a #cairo_font_face_t - * - * Decreases the reference count on @font_face by one. If the result - * is zero, then @font_face and all associated resources are freed. - * See cairo_font_face_reference(). - * - * Since: 1.0 - **/ -void -cairo_font_face_destroy (cairo_font_face_t *font_face) -{ - if (font_face == NULL || - CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count)) - return; - - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&font_face->ref_count)); - - /* We allow resurrection to deal with some memory management for the - * FreeType backend where cairo_ft_font_face_t and cairo_ft_unscaled_font_t - * need to effectively mutually reference each other - */ - if (__put (&font_face->ref_count)) - return; - - if (! font_face->backend->destroy (font_face)) - return; - - _cairo_user_data_array_fini (&font_face->user_data); - - free (font_face); -} -slim_hidden_def (cairo_font_face_destroy); - -/** - * cairo_font_face_get_type: - * @font_face: a font face - * - * This function returns the type of the backend used to create - * a font face. See #cairo_font_type_t for available types. - * - * Return value: The type of @font_face. - * - * Since: 1.2 - **/ -cairo_font_type_t -cairo_font_face_get_type (cairo_font_face_t *font_face) -{ - if (CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count)) - return CAIRO_FONT_TYPE_TOY; - - return font_face->backend->type; -} - -/** - * cairo_font_face_get_reference_count: - * @font_face: a #cairo_font_face_t - * - * Returns the current reference count of @font_face. - * - * Return value: the current reference count of @font_face. If the - * object is a nil object, 0 will be returned. - * - * Since: 1.4 - **/ -unsigned int -cairo_font_face_get_reference_count (cairo_font_face_t *font_face) -{ - if (font_face == NULL || - CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count)) - return 0; - - return CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->ref_count); -} - -/** - * cairo_font_face_status: - * @font_face: a #cairo_font_face_t - * - * Checks whether an error has previously occurred for this - * font face - * - * Return value: %CAIRO_STATUS_SUCCESS or another error such as - * %CAIRO_STATUS_NO_MEMORY. - * - * Since: 1.0 - **/ -cairo_status_t -cairo_font_face_status (cairo_font_face_t *font_face) -{ - return font_face->status; -} - -/** - * cairo_font_face_get_user_data: - * @font_face: a #cairo_font_face_t - * @key: the address of the #cairo_user_data_key_t the user data was - * attached to - * - * Return user data previously attached to @font_face using the specified - * key. If no user data has been attached with the given key this - * function returns %NULL. - * - * Return value: the user data previously attached or %NULL. - * - * Since: 1.0 - **/ -void * -cairo_font_face_get_user_data (cairo_font_face_t *font_face, - const cairo_user_data_key_t *key) -{ - return _cairo_user_data_array_get_data (&font_face->user_data, - key); -} -slim_hidden_def (cairo_font_face_get_user_data); - -/** - * cairo_font_face_set_user_data: - * @font_face: a #cairo_font_face_t - * @key: the address of a #cairo_user_data_key_t to attach the user data to - * @user_data: the user data to attach to the font face - * @destroy: a #cairo_destroy_func_t which will be called when the - * font face is destroyed or when new user data is attached using the - * same key. - * - * Attach user data to @font_face. To remove user data from a font face, - * call this function with the key that was used to set it and %NULL - * for @data. - * - * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a - * slot could not be allocated for the user data. - * - * Since: 1.0 - **/ -cairo_status_t -cairo_font_face_set_user_data (cairo_font_face_t *font_face, - const cairo_user_data_key_t *key, - void *user_data, - cairo_destroy_func_t destroy) -{ - if (CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count)) - return font_face->status; - - return _cairo_user_data_array_set_data (&font_face->user_data, - key, user_data, destroy); -} -slim_hidden_def (cairo_font_face_set_user_data); - -void -_cairo_unscaled_font_init (cairo_unscaled_font_t *unscaled_font, - const cairo_unscaled_font_backend_t *backend) -{ - CAIRO_REFERENCE_COUNT_INIT (&unscaled_font->ref_count, 1); - unscaled_font->backend = backend; -} - -cairo_unscaled_font_t * -_cairo_unscaled_font_reference (cairo_unscaled_font_t *unscaled_font) -{ - if (unscaled_font == NULL) - return NULL; - - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&unscaled_font->ref_count)); - - _cairo_reference_count_inc (&unscaled_font->ref_count); - - return unscaled_font; -} - -void -_cairo_unscaled_font_destroy (cairo_unscaled_font_t *unscaled_font) -{ - if (unscaled_font == NULL) - return; - - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&unscaled_font->ref_count)); - - if (__put (&unscaled_font->ref_count)) - return; - - if (! unscaled_font->backend->destroy (unscaled_font)) - return; - - free (unscaled_font); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-font-options.c b/source/libs/cairo/cairo-src/src/cairo-font-options.c deleted file mode 100644 index ad28745e6b9236fba128ef321d79e21a61e8ec8d..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-font-options.c +++ /dev/null @@ -1,535 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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): - * Owen Taylor <otaylor@redhat.com> - */ - -#include "cairoint.h" -#include "cairo-error-private.h" - -/** - * SECTION:cairo-font-options - * @Title: cairo_font_options_t - * @Short_Description: How a font should be rendered - * @See_Also: #cairo_scaled_font_t - * - * The font options specify how fonts should be rendered. Most of the - * time the font options implied by a surface are just right and do not - * need any changes, but for pixel-based targets tweaking font options - * may result in superior output on a particular display. - **/ - -static const cairo_font_options_t _cairo_font_options_nil = { - CAIRO_ANTIALIAS_DEFAULT, - CAIRO_SUBPIXEL_ORDER_DEFAULT, - CAIRO_LCD_FILTER_DEFAULT, - CAIRO_HINT_STYLE_DEFAULT, - CAIRO_HINT_METRICS_DEFAULT, - CAIRO_ROUND_GLYPH_POS_DEFAULT -}; - -/** - * _cairo_font_options_init_default: - * @options: a #cairo_font_options_t - * - * Initializes all fields of the font options object to default values. - **/ -void -_cairo_font_options_init_default (cairo_font_options_t *options) -{ - options->antialias = CAIRO_ANTIALIAS_DEFAULT; - options->subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT; - options->lcd_filter = CAIRO_LCD_FILTER_DEFAULT; - options->hint_style = CAIRO_HINT_STYLE_DEFAULT; - options->hint_metrics = CAIRO_HINT_METRICS_DEFAULT; - options->round_glyph_positions = CAIRO_ROUND_GLYPH_POS_DEFAULT; -} - -void -_cairo_font_options_init_copy (cairo_font_options_t *options, - const cairo_font_options_t *other) -{ - options->antialias = other->antialias; - options->subpixel_order = other->subpixel_order; - options->lcd_filter = other->lcd_filter; - options->hint_style = other->hint_style; - options->hint_metrics = other->hint_metrics; - options->round_glyph_positions = other->round_glyph_positions; -} - -/** - * cairo_font_options_create: - * - * Allocates a new font options object with all options initialized - * to default values. - * - * Return value: a newly allocated #cairo_font_options_t. Free with - * cairo_font_options_destroy(). This function always returns a - * valid pointer; if memory cannot be allocated, then a special - * error object is returned where all operations on the object do nothing. - * You can check for this with cairo_font_options_status(). - * - * Since: 1.0 - **/ -cairo_font_options_t * -cairo_font_options_create (void) -{ - cairo_font_options_t *options; - - options = malloc (sizeof (cairo_font_options_t)); - if (!options) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_font_options_t *) &_cairo_font_options_nil; - } - - _cairo_font_options_init_default (options); - - return options; -} - -/** - * cairo_font_options_copy: - * @original: a #cairo_font_options_t - * - * Allocates a new font options object copying the option values from - * @original. - * - * Return value: a newly allocated #cairo_font_options_t. Free with - * cairo_font_options_destroy(). This function always returns a - * valid pointer; if memory cannot be allocated, then a special - * error object is returned where all operations on the object do nothing. - * You can check for this with cairo_font_options_status(). - * - * Since: 1.0 - **/ -cairo_font_options_t * -cairo_font_options_copy (const cairo_font_options_t *original) -{ - cairo_font_options_t *options; - - if (cairo_font_options_status ((cairo_font_options_t *) original)) - return (cairo_font_options_t *) &_cairo_font_options_nil; - - options = malloc (sizeof (cairo_font_options_t)); - if (!options) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_font_options_t *) &_cairo_font_options_nil; - } - - _cairo_font_options_init_copy (options, original); - - return options; -} - -/** - * cairo_font_options_destroy: - * @options: a #cairo_font_options_t - * - * Destroys a #cairo_font_options_t object created with - * cairo_font_options_create() or cairo_font_options_copy(). - * - * Since: 1.0 - **/ -void -cairo_font_options_destroy (cairo_font_options_t *options) -{ - if (cairo_font_options_status (options)) - return; - - free (options); -} - -/** - * cairo_font_options_status: - * @options: a #cairo_font_options_t - * - * Checks whether an error has previously occurred for this - * font options object - * - * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY - * - * Since: 1.0 - **/ -cairo_status_t -cairo_font_options_status (cairo_font_options_t *options) -{ - if (options == NULL) - return CAIRO_STATUS_NULL_POINTER; - else if (options == (cairo_font_options_t *) &_cairo_font_options_nil) - return CAIRO_STATUS_NO_MEMORY; - else - return CAIRO_STATUS_SUCCESS; -} -slim_hidden_def (cairo_font_options_status); - -/** - * cairo_font_options_merge: - * @options: a #cairo_font_options_t - * @other: another #cairo_font_options_t - * - * Merges non-default options from @other into @options, replacing - * existing values. This operation can be thought of as somewhat - * similar to compositing @other onto @options with the operation - * of %CAIRO_OPERATOR_OVER. - * - * Since: 1.0 - **/ -void -cairo_font_options_merge (cairo_font_options_t *options, - const cairo_font_options_t *other) -{ - if (cairo_font_options_status (options)) - return; - - if (cairo_font_options_status ((cairo_font_options_t *) other)) - return; - - if (other->antialias != CAIRO_ANTIALIAS_DEFAULT) - options->antialias = other->antialias; - if (other->subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT) - options->subpixel_order = other->subpixel_order; - if (other->lcd_filter != CAIRO_LCD_FILTER_DEFAULT) - options->lcd_filter = other->lcd_filter; - if (other->hint_style != CAIRO_HINT_STYLE_DEFAULT) - options->hint_style = other->hint_style; - if (other->hint_metrics != CAIRO_HINT_METRICS_DEFAULT) - options->hint_metrics = other->hint_metrics; - if (other->round_glyph_positions != CAIRO_ROUND_GLYPH_POS_DEFAULT) - options->round_glyph_positions = other->round_glyph_positions; -} -slim_hidden_def (cairo_font_options_merge); - -/** - * cairo_font_options_equal: - * @options: a #cairo_font_options_t - * @other: another #cairo_font_options_t - * - * Compares two font options objects for equality. - * - * Return value: %TRUE if all fields of the two font options objects match. - * Note that this function will return %FALSE if either object is in - * error. - * - * Since: 1.0 - **/ -cairo_bool_t -cairo_font_options_equal (const cairo_font_options_t *options, - const cairo_font_options_t *other) -{ - if (cairo_font_options_status ((cairo_font_options_t *) options)) - return FALSE; - if (cairo_font_options_status ((cairo_font_options_t *) other)) - return FALSE; - - if (options == other) - return TRUE; - - return (options->antialias == other->antialias && - options->subpixel_order == other->subpixel_order && - options->lcd_filter == other->lcd_filter && - options->hint_style == other->hint_style && - options->hint_metrics == other->hint_metrics && - options->round_glyph_positions == other->round_glyph_positions); -} -slim_hidden_def (cairo_font_options_equal); - -/** - * cairo_font_options_hash: - * @options: a #cairo_font_options_t - * - * Compute a hash for the font options object; this value will - * be useful when storing an object containing a #cairo_font_options_t - * in a hash table. - * - * Return value: the hash value for the font options object. - * The return value can be cast to a 32-bit type if a - * 32-bit hash value is needed. - * - * Since: 1.0 - **/ -unsigned long -cairo_font_options_hash (const cairo_font_options_t *options) -{ - if (cairo_font_options_status ((cairo_font_options_t *) options)) - options = &_cairo_font_options_nil; /* force default values */ - - return ((options->antialias) | - (options->subpixel_order << 4) | - (options->lcd_filter << 8) | - (options->hint_style << 12) | - (options->hint_metrics << 16)); -} -slim_hidden_def (cairo_font_options_hash); - -/** - * cairo_font_options_set_antialias: - * @options: a #cairo_font_options_t - * @antialias: the new antialiasing mode - * - * Sets the antialiasing mode for the font options object. This - * specifies the type of antialiasing to do when rendering text. - * - * Since: 1.0 - **/ -void -cairo_font_options_set_antialias (cairo_font_options_t *options, - cairo_antialias_t antialias) -{ - if (cairo_font_options_status (options)) - return; - - options->antialias = antialias; -} -slim_hidden_def (cairo_font_options_set_antialias); - -/** - * cairo_font_options_get_antialias: - * @options: a #cairo_font_options_t - * - * Gets the antialiasing mode for the font options object. - * - * Return value: the antialiasing mode - * - * Since: 1.0 - **/ -cairo_antialias_t -cairo_font_options_get_antialias (const cairo_font_options_t *options) -{ - if (cairo_font_options_status ((cairo_font_options_t *) options)) - return CAIRO_ANTIALIAS_DEFAULT; - - return options->antialias; -} - -/** - * cairo_font_options_set_subpixel_order: - * @options: a #cairo_font_options_t - * @subpixel_order: the new subpixel order - * - * Sets the subpixel order for the font options object. The subpixel - * order specifies the order of color elements within each pixel on - * the display device when rendering with an antialiasing mode of - * %CAIRO_ANTIALIAS_SUBPIXEL. See the documentation for - * #cairo_subpixel_order_t for full details. - * - * Since: 1.0 - **/ -void -cairo_font_options_set_subpixel_order (cairo_font_options_t *options, - cairo_subpixel_order_t subpixel_order) -{ - if (cairo_font_options_status (options)) - return; - - options->subpixel_order = subpixel_order; -} -slim_hidden_def (cairo_font_options_set_subpixel_order); - -/** - * cairo_font_options_get_subpixel_order: - * @options: a #cairo_font_options_t - * - * Gets the subpixel order for the font options object. - * See the documentation for #cairo_subpixel_order_t for full details. - * - * Return value: the subpixel order for the font options object - * - * Since: 1.0 - **/ -cairo_subpixel_order_t -cairo_font_options_get_subpixel_order (const cairo_font_options_t *options) -{ - if (cairo_font_options_status ((cairo_font_options_t *) options)) - return CAIRO_SUBPIXEL_ORDER_DEFAULT; - - return options->subpixel_order; -} - -/** - * _cairo_font_options_set_lcd_filter: - * @options: a #cairo_font_options_t - * @lcd_filter: the new LCD filter - * - * Sets the LCD filter for the font options object. The LCD filter - * specifies how pixels are filtered when rendered with an antialiasing - * mode of %CAIRO_ANTIALIAS_SUBPIXEL. See the documentation for - * #cairo_lcd_filter_t for full details. - **/ -void -_cairo_font_options_set_lcd_filter (cairo_font_options_t *options, - cairo_lcd_filter_t lcd_filter) -{ - if (cairo_font_options_status (options)) - return; - - options->lcd_filter = lcd_filter; -} - -/** - * _cairo_font_options_get_lcd_filter: - * @options: a #cairo_font_options_t - * - * Gets the LCD filter for the font options object. - * See the documentation for #cairo_lcd_filter_t for full details. - * - * Return value: the LCD filter for the font options object - **/ -cairo_lcd_filter_t -_cairo_font_options_get_lcd_filter (const cairo_font_options_t *options) -{ - if (cairo_font_options_status ((cairo_font_options_t *) options)) - return CAIRO_LCD_FILTER_DEFAULT; - - return options->lcd_filter; -} - -/** - * _cairo_font_options_set_round_glyph_positions: - * @options: a #cairo_font_options_t - * @round: the new rounding value - * - * Sets the rounding options for the font options object. If rounding is set, a - * glyph's position will be rounded to integer values. - **/ -void -_cairo_font_options_set_round_glyph_positions (cairo_font_options_t *options, - cairo_round_glyph_positions_t round) -{ - if (cairo_font_options_status (options)) - return; - - options->round_glyph_positions = round; -} - -/** - * _cairo_font_options_get_round_glyph_positions: - * @options: a #cairo_font_options_t - * - * Gets the glyph position rounding option for the font options object. - * - * Return value: The round glyph posistions flag for the font options object. - **/ -cairo_round_glyph_positions_t -_cairo_font_options_get_round_glyph_positions (const cairo_font_options_t *options) -{ - if (cairo_font_options_status ((cairo_font_options_t *) options)) - return CAIRO_ROUND_GLYPH_POS_DEFAULT; - - return options->round_glyph_positions; -} - -/** - * cairo_font_options_set_hint_style: - * @options: a #cairo_font_options_t - * @hint_style: the new hint style - * - * Sets the hint style for font outlines for the font options object. - * This controls whether to fit font outlines to the pixel grid, - * and if so, whether to optimize for fidelity or contrast. - * See the documentation for #cairo_hint_style_t for full details. - * - * Since: 1.0 - **/ -void -cairo_font_options_set_hint_style (cairo_font_options_t *options, - cairo_hint_style_t hint_style) -{ - if (cairo_font_options_status (options)) - return; - - options->hint_style = hint_style; -} -slim_hidden_def (cairo_font_options_set_hint_style); - -/** - * cairo_font_options_get_hint_style: - * @options: a #cairo_font_options_t - * - * Gets the hint style for font outlines for the font options object. - * See the documentation for #cairo_hint_style_t for full details. - * - * Return value: the hint style for the font options object - * - * Since: 1.0 - **/ -cairo_hint_style_t -cairo_font_options_get_hint_style (const cairo_font_options_t *options) -{ - if (cairo_font_options_status ((cairo_font_options_t *) options)) - return CAIRO_HINT_STYLE_DEFAULT; - - return options->hint_style; -} - -/** - * cairo_font_options_set_hint_metrics: - * @options: a #cairo_font_options_t - * @hint_metrics: the new metrics hinting mode - * - * Sets the metrics hinting mode for the font options object. This - * controls whether metrics are quantized to integer values in - * device units. - * See the documentation for #cairo_hint_metrics_t for full details. - * - * Since: 1.0 - **/ -void -cairo_font_options_set_hint_metrics (cairo_font_options_t *options, - cairo_hint_metrics_t hint_metrics) -{ - if (cairo_font_options_status (options)) - return; - - options->hint_metrics = hint_metrics; -} -slim_hidden_def (cairo_font_options_set_hint_metrics); - -/** - * cairo_font_options_get_hint_metrics: - * @options: a #cairo_font_options_t - * - * Gets the metrics hinting mode for the font options object. - * See the documentation for #cairo_hint_metrics_t for full details. - * - * Return value: the metrics hinting mode for the font options object - * - * Since: 1.0 - **/ -cairo_hint_metrics_t -cairo_font_options_get_hint_metrics (const cairo_font_options_t *options) -{ - if (cairo_font_options_status ((cairo_font_options_t *) options)) - return CAIRO_HINT_METRICS_DEFAULT; - - return options->hint_metrics; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-fontconfig-private.h b/source/libs/cairo/cairo-src/src/cairo-fontconfig-private.h deleted file mode 100644 index ea873abe7e4d5a5a1a79519fbd2f6230b8b74fb6..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-fontconfig-private.h +++ /dev/null @@ -1,78 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2000 Keith Packard - * Copyright © 2005 Red Hat, Inc - * Copyright © 2010 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Graydon Hoare <graydon@redhat.com> - * Owen Taylor <otaylor@redhat.com> - * Keith Packard <keithp@keithp.com> - * Carl Worth <cworth@cworth.org> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef _CAIRO_FONTCONFIG_PRIVATE_H -#define _CAIRO_FONTCONFIG_PRIVATE_H - -#include "cairo.h" - -#if CAIRO_HAS_FC_FONT -#include <fontconfig/fontconfig.h> -#include <fontconfig/fcfreetype.h> -#endif - -/* sub-pixel order */ -#ifndef FC_RGBA_UNKNOWN -#define FC_RGBA_UNKNOWN 0 -#define FC_RGBA_RGB 1 -#define FC_RGBA_BGR 2 -#define FC_RGBA_VRGB 3 -#define FC_RGBA_VBGR 4 -#define FC_RGBA_NONE 5 -#endif - -/* hinting style */ -#ifndef FC_HINT_NONE -#define FC_HINT_NONE 0 -#define FC_HINT_SLIGHT 1 -#define FC_HINT_MEDIUM 2 -#define FC_HINT_FULL 3 -#endif - -/* LCD filter */ -#ifndef FC_LCD_NONE -#define FC_LCD_NONE 0 -#define FC_LCD_DEFAULT 1 -#define FC_LCD_LIGHT 2 -#define FC_LCD_LEGACY 3 -#endif - -#endif /* _CAIRO_FONTCONFIG_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-freed-pool-private.h b/source/libs/cairo/cairo-src/src/cairo-freed-pool-private.h deleted file mode 100644 index 0ec6de3d1f1f4eb207ecfa5fdd26bc5b16adb5a6..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-freed-pool-private.h +++ /dev/null @@ -1,139 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_FREED_POOL_H -#define CAIRO_FREED_POOL_H - -#include "cairoint.h" -#include "cairo-atomic-private.h" - -CAIRO_BEGIN_DECLS - -#define DISABLE_FREED_POOLS 0 - -#if HAS_ATOMIC_OPS && ! DISABLE_FREED_POOLS -/* Keep a stash of recently freed clip_paths, since we need to - * reallocate them frequently. - */ -#define MAX_FREED_POOL_SIZE 16 -typedef struct { - void *pool[MAX_FREED_POOL_SIZE]; - int top; -} freed_pool_t; - -static cairo_always_inline void * -_atomic_fetch (void **slot) -{ - void *ptr; - - do { - ptr = _cairo_atomic_ptr_get (slot); - } while (! _cairo_atomic_ptr_cmpxchg (slot, ptr, NULL)); - - return ptr; -} - -static cairo_always_inline cairo_bool_t -_atomic_store (void **slot, void *ptr) -{ - return _cairo_atomic_ptr_cmpxchg (slot, NULL, ptr); -} - -cairo_private void * -_freed_pool_get_search (freed_pool_t *pool); - -static inline void * -_freed_pool_get (freed_pool_t *pool) -{ - void *ptr; - int i; - - i = pool->top - 1; - if (i < 0) - i = 0; - - ptr = _atomic_fetch (&pool->pool[i]); - if (likely (ptr != NULL)) { - pool->top = i; - return ptr; - } - - /* either empty or contended */ - return _freed_pool_get_search (pool); -} - -cairo_private void -_freed_pool_put_search (freed_pool_t *pool, void *ptr); - -static inline void -_freed_pool_put (freed_pool_t *pool, void *ptr) -{ - int i; - - i = pool->top; - if (likely (i < ARRAY_LENGTH (pool->pool) && - _atomic_store (&pool->pool[i], ptr))) - { - pool->top = i + 1; - return; - } - - /* either full or contended */ - _freed_pool_put_search (pool, ptr); -} - -cairo_private void -_freed_pool_reset (freed_pool_t *pool); - -#define HAS_FREED_POOL 1 - -#else - -/* A warning about an unused freed-pool in a build without atomics - * enabled usually indicates a missing _freed_pool_reset() in the - * static reset function */ - -typedef int freed_pool_t; - -#define _freed_pool_get(pool) NULL -#define _freed_pool_put(pool, ptr) free(ptr) -#define _freed_pool_reset(ptr) - -#endif - -CAIRO_END_DECLS - -#endif /* CAIRO_FREED_POOL_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-freed-pool.c b/source/libs/cairo/cairo-src/src/cairo-freed-pool.c deleted file mode 100644 index cfdc8e96b059db72e83ce551b640032d82b54be8..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-freed-pool.c +++ /dev/null @@ -1,93 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-freed-pool-private.h" - -#if HAS_FREED_POOL - -void * -_freed_pool_get_search (freed_pool_t *pool) -{ - void *ptr; - int i; - - for (i = ARRAY_LENGTH (pool->pool); i--;) { - ptr = _atomic_fetch (&pool->pool[i]); - if (ptr != NULL) { - pool->top = i; - return ptr; - } - } - - /* empty */ - pool->top = 0; - return NULL; -} - -void -_freed_pool_put_search (freed_pool_t *pool, void *ptr) -{ - int i; - - for (i = 0; i < ARRAY_LENGTH (pool->pool); i++) { - if (_atomic_store (&pool->pool[i], ptr)) { - pool->top = i + 1; - return; - } - } - - /* full */ - pool->top = i; - free (ptr); -} - -void -_freed_pool_reset (freed_pool_t *pool) -{ - int i; - - for (i = 0; i < ARRAY_LENGTH (pool->pool); i++) { - free (pool->pool[i]); - pool->pool[i] = NULL; - } - - pool->top = 0; -} - -#endif diff --git a/source/libs/cairo/cairo-src/src/cairo-freelist-private.h b/source/libs/cairo/cairo-src/src/cairo-freelist-private.h deleted file mode 100644 index 8fe6516f385d1d34ca581e842c75e93bf183ca55..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-freelist-private.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright © 2006 Joonas Pihlaja - * - * 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 the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS 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. - */ -#ifndef CAIRO_FREELIST_H -#define CAIRO_FREELIST_H - -#include "cairo-types-private.h" -#include "cairo-compiler-private.h" -#include "cairo-freelist-type-private.h" - -/* for stand-alone compilation*/ -#ifndef VG -#define VG(x) -#endif - -#ifndef NULL -#define NULL (void *) 0 -#endif - -/* Initialise a freelist that will be responsible for allocating - * nodes of size nodesize. */ -cairo_private void -_cairo_freelist_init (cairo_freelist_t *freelist, unsigned nodesize); - -/* Deallocate any nodes in the freelist. */ -cairo_private void -_cairo_freelist_fini (cairo_freelist_t *freelist); - -/* Allocate a new node from the freelist. If the freelist contains no - * nodes, a new one will be allocated using malloc(). The caller is - * responsible for calling _cairo_freelist_free() or free() on the - * returned node. Returns %NULL on memory allocation error. */ -cairo_private void * -_cairo_freelist_alloc (cairo_freelist_t *freelist); - -/* Allocate a new node from the freelist. If the freelist contains no - * nodes, a new one will be allocated using calloc(). The caller is - * responsible for calling _cairo_freelist_free() or free() on the - * returned node. Returns %NULL on memory allocation error. */ -cairo_private void * -_cairo_freelist_calloc (cairo_freelist_t *freelist); - -/* Return a node to the freelist. This does not deallocate the memory, - * but makes it available for later reuse by - * _cairo_freelist_alloc(). */ -cairo_private void -_cairo_freelist_free (cairo_freelist_t *freelist, void *node); - - -cairo_private void -_cairo_freepool_init (cairo_freepool_t *freepool, unsigned nodesize); - -cairo_private void -_cairo_freepool_fini (cairo_freepool_t *freepool); - -static inline void -_cairo_freepool_reset (cairo_freepool_t *freepool) -{ - while (freepool->pools != &freepool->embedded_pool) { - cairo_freelist_pool_t *pool = freepool->pools; - freepool->pools = pool->next; - pool->next = freepool->freepools; - freepool->freepools = pool; - } - - freepool->embedded_pool.rem = sizeof (freepool->embedded_data); - freepool->embedded_pool.data = freepool->embedded_data; -} - -cairo_private void * -_cairo_freepool_alloc_from_new_pool (cairo_freepool_t *freepool); - -static inline void * -_cairo_freepool_alloc_from_pool (cairo_freepool_t *freepool) -{ - cairo_freelist_pool_t *pool; - uint8_t *ptr; - - pool = freepool->pools; - if (unlikely (freepool->nodesize > pool->rem)) - return _cairo_freepool_alloc_from_new_pool (freepool); - - ptr = pool->data; - pool->data += freepool->nodesize; - pool->rem -= freepool->nodesize; - VG (VALGRIND_MAKE_MEM_UNDEFINED (ptr, freepool->nodesize)); - return ptr; -} - -static inline void * -_cairo_freepool_alloc (cairo_freepool_t *freepool) -{ - cairo_freelist_node_t *node; - - node = freepool->first_free_node; - if (node == NULL) - return _cairo_freepool_alloc_from_pool (freepool); - - VG (VALGRIND_MAKE_MEM_DEFINED (node, sizeof (node->next))); - freepool->first_free_node = node->next; - VG (VALGRIND_MAKE_MEM_UNDEFINED (node, freepool->nodesize)); - - return node; -} - -cairo_private cairo_status_t -_cairo_freepool_alloc_array (cairo_freepool_t *freepool, - int count, - void **array); - -static inline void -_cairo_freepool_free (cairo_freepool_t *freepool, void *ptr) -{ - cairo_freelist_node_t *node = ptr; - - node->next = freepool->first_free_node; - freepool->first_free_node = node; - VG (VALGRIND_MAKE_MEM_NOACCESS (node, freepool->nodesize)); -} - -#endif /* CAIRO_FREELIST_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-freelist-type-private.h b/source/libs/cairo/cairo-src/src/cairo-freelist-type-private.h deleted file mode 100644 index 4dd056461078cff59eb6a2bde2c88c278db1ce63..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-freelist-type-private.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright © 2010 Joonas Pihlaja - * - * 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 the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS 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. - */ -#ifndef CAIRO_FREELIST_TYPE_H -#define CAIRO_FREELIST_TYPE_H - -#include "cairo-types-private.h" -#include "cairo-compiler-private.h" - -typedef struct _cairo_freelist_node cairo_freelist_node_t; -struct _cairo_freelist_node { - cairo_freelist_node_t *next; -}; - -typedef struct _cairo_freelist { - cairo_freelist_node_t *first_free_node; - unsigned nodesize; -} cairo_freelist_t; - -typedef struct _cairo_freelist_pool cairo_freelist_pool_t; -struct _cairo_freelist_pool { - cairo_freelist_pool_t *next; - unsigned size, rem; - uint8_t *data; -}; - -typedef struct _cairo_freepool { - cairo_freelist_node_t *first_free_node; - cairo_freelist_pool_t *pools; - cairo_freelist_pool_t *freepools; - unsigned nodesize; - cairo_freelist_pool_t embedded_pool; - uint8_t embedded_data[1000]; -} cairo_freepool_t; - -#endif /* CAIRO_FREELIST_TYPE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-freelist.c b/source/libs/cairo/cairo-src/src/cairo-freelist.c deleted file mode 100644 index d596eab81dcb68e5997c9e9c68769158c588e26b..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-freelist.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright © 2006 Joonas Pihlaja - * - * 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 the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS 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. - */ - -#include "cairoint.h" - -#include "cairo-error-private.h" -#include "cairo-freelist-private.h" - -void -_cairo_freelist_init (cairo_freelist_t *freelist, unsigned nodesize) -{ - memset (freelist, 0, sizeof (cairo_freelist_t)); - freelist->nodesize = nodesize; -} - -void -_cairo_freelist_fini (cairo_freelist_t *freelist) -{ - cairo_freelist_node_t *node = freelist->first_free_node; - while (node) { - cairo_freelist_node_t *next; - - VG (VALGRIND_MAKE_MEM_DEFINED (node, sizeof (node->next))); - next = node->next; - - free (node); - node = next; - } -} - -void * -_cairo_freelist_alloc (cairo_freelist_t *freelist) -{ - if (freelist->first_free_node) { - cairo_freelist_node_t *node; - - node = freelist->first_free_node; - VG (VALGRIND_MAKE_MEM_DEFINED (node, sizeof (node->next))); - freelist->first_free_node = node->next; - VG (VALGRIND_MAKE_MEM_UNDEFINED (node, freelist->nodesize)); - - return node; - } - - return malloc (freelist->nodesize); -} - -void * -_cairo_freelist_calloc (cairo_freelist_t *freelist) -{ - void *node = _cairo_freelist_alloc (freelist); - if (node) - memset (node, 0, freelist->nodesize); - return node; -} - -void -_cairo_freelist_free (cairo_freelist_t *freelist, void *voidnode) -{ - cairo_freelist_node_t *node = voidnode; - if (node) { - node->next = freelist->first_free_node; - freelist->first_free_node = node; - VG (VALGRIND_MAKE_MEM_NOACCESS (node, freelist->nodesize)); - } -} - -void -_cairo_freepool_init (cairo_freepool_t *freepool, unsigned nodesize) -{ - freepool->first_free_node = NULL; - freepool->pools = &freepool->embedded_pool; - freepool->freepools = NULL; - freepool->nodesize = nodesize; - - freepool->embedded_pool.next = NULL; - freepool->embedded_pool.size = sizeof (freepool->embedded_data); - freepool->embedded_pool.rem = sizeof (freepool->embedded_data); - freepool->embedded_pool.data = freepool->embedded_data; - - VG (VALGRIND_MAKE_MEM_NOACCESS (freepool->embedded_data, sizeof (freepool->embedded_data))); -} - -void -_cairo_freepool_fini (cairo_freepool_t *freepool) -{ - cairo_freelist_pool_t *pool; - - pool = freepool->pools; - while (pool != &freepool->embedded_pool) { - cairo_freelist_pool_t *next = pool->next; - free (pool); - pool = next; - } - - pool = freepool->freepools; - while (pool != NULL) { - cairo_freelist_pool_t *next = pool->next; - free (pool); - pool = next; - } - - VG (VALGRIND_MAKE_MEM_NOACCESS (freepool, sizeof (freepool))); -} - -void * -_cairo_freepool_alloc_from_new_pool (cairo_freepool_t *freepool) -{ - cairo_freelist_pool_t *pool; - int poolsize; - - if (freepool->freepools != NULL) { - pool = freepool->freepools; - freepool->freepools = pool->next; - - poolsize = pool->size; - } else { - if (freepool->pools != &freepool->embedded_pool) - poolsize = 2 * freepool->pools->size; - else - poolsize = (128 * freepool->nodesize + 8191) & -8192; - - pool = malloc (sizeof (cairo_freelist_pool_t) + poolsize); - if (unlikely (pool == NULL)) - return pool; - - pool->size = poolsize; - } - - pool->next = freepool->pools; - freepool->pools = pool; - - pool->rem = poolsize - freepool->nodesize; - pool->data = (uint8_t *) (pool + 1) + freepool->nodesize; - - VG (VALGRIND_MAKE_MEM_NOACCESS (pool->data, pool->rem)); - - return pool + 1; -} - -cairo_status_t -_cairo_freepool_alloc_array (cairo_freepool_t *freepool, - int count, - void **array) -{ - int i; - - for (i = 0; i < count; i++) { - cairo_freelist_node_t *node; - - node = freepool->first_free_node; - if (likely (node != NULL)) { - VG (VALGRIND_MAKE_MEM_DEFINED (node, sizeof (node->next))); - freepool->first_free_node = node->next; - VG (VALGRIND_MAKE_MEM_UNDEFINED (node, freepool->nodesize)); - } else { - node = _cairo_freepool_alloc_from_pool (freepool); - if (unlikely (node == NULL)) - goto CLEANUP; - } - - array[i] = node; - } - - return CAIRO_STATUS_SUCCESS; - - CLEANUP: - while (i--) - _cairo_freepool_free (freepool, array[i]); - - return _cairo_error (CAIRO_STATUS_NO_MEMORY); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-ft-font.c b/source/libs/cairo/cairo-src/src/cairo-ft-font.c deleted file mode 100644 index 3e485c5b74cd61d6c2ae0c89c52166ce19f5af94..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-ft-font.c +++ /dev/null @@ -1,3596 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2000 Keith Packard - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Graydon Hoare <graydon@redhat.com> - * Owen Taylor <otaylor@redhat.com> - * Keith Packard <keithp@keithp.com> - * Carl Worth <cworth@cworth.org> - */ - -#define _BSD_SOURCE /* for strdup() */ -#include "cairoint.h" - -#include "cairo-error-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-ft-private.h" -#include "cairo-pattern-private.h" -#include "cairo-pixman-private.h" - -#include <float.h> - -#include "cairo-fontconfig-private.h" - -#include <ft2build.h> -#include FT_FREETYPE_H -#include FT_OUTLINE_H -#include FT_IMAGE_H -#include FT_BITMAP_H -#include FT_TRUETYPE_TABLES_H -#include FT_XFREE86_H -#if HAVE_FT_GLYPHSLOT_EMBOLDEN -#include FT_SYNTHESIS_H -#endif - -#if HAVE_FT_LIBRARY_SETLCDFILTER -#include FT_LCD_FILTER_H -#endif - -#if HAVE_UNISTD_H -#include <unistd.h> -#else -#define access(p, m) 0 -#endif - -/* Fontconfig version older than 2.6 didn't have these options */ -#ifndef FC_LCD_FILTER -#define FC_LCD_FILTER "lcdfilter" -#endif -/* Some Ubuntu versions defined FC_LCD_FILTER without defining the following */ -#ifndef FC_LCD_NONE -#define FC_LCD_NONE 0 -#define FC_LCD_DEFAULT 1 -#define FC_LCD_LIGHT 2 -#define FC_LCD_LEGACY 3 -#endif - -/* FreeType version older than 2.3.5(?) didn't have these options */ -#ifndef FT_LCD_FILTER_NONE -#define FT_LCD_FILTER_NONE 0 -#define FT_LCD_FILTER_DEFAULT 1 -#define FT_LCD_FILTER_LIGHT 2 -#define FT_LCD_FILTER_LEGACY 16 -#endif - -#define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0)) -#define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0) -#define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0)) -#define DOUBLE_FROM_16_16(t) ((double)(t) / 65536.0) - -/* This is the max number of FT_face objects we keep open at once - */ -#define MAX_OPEN_FACES 10 - -/** - * SECTION:cairo-ft - * @Title: FreeType Fonts - * @Short_Description: Font support for FreeType - * @See_Also: #cairo_font_face_t - * - * The FreeType font backend is primarily used to render text on GNU/Linux - * systems, but can be used on other platforms too. - **/ - -/** - * CAIRO_HAS_FT_FONT: - * - * Defined if the FreeType font backend is available. - * This macro can be used to conditionally compile backend-specific code. - * - * Since: 1.0 - **/ - -/** - * CAIRO_HAS_FC_FONT: - * - * Defined if the Fontconfig-specific functions of the FreeType font backend - * are available. - * This macro can be used to conditionally compile backend-specific code. - * - * Since: 1.10 - **/ - -/* - * The simple 2x2 matrix is converted into separate scale and shape - * factors so that hinting works right - */ - -typedef struct _cairo_ft_font_transform { - double x_scale, y_scale; - double shape[2][2]; -} cairo_ft_font_transform_t; - -/* - * We create an object that corresponds to a single font on the disk; - * (identified by a filename/id pair) these are shared between all - * fonts using that file. For cairo_ft_font_face_create_for_ft_face(), we - * just create a one-off version with a permanent face value. - */ - -typedef struct _cairo_ft_font_face cairo_ft_font_face_t; - -struct _cairo_ft_unscaled_font { - cairo_unscaled_font_t base; - - cairo_bool_t from_face; /* was the FT_Face provided by user? */ - FT_Face face; /* provided or cached face */ - - /* only set if from_face is false */ - char *filename; - int id; - - /* We temporarily scale the unscaled font as needed */ - cairo_bool_t have_scale; - cairo_matrix_t current_scale; - double x_scale; /* Extracted X scale factor */ - double y_scale; /* Extracted Y scale factor */ - cairo_bool_t have_shape; /* true if the current scale has a non-scale component*/ - cairo_matrix_t current_shape; - FT_Matrix Current_Shape; - - cairo_mutex_t mutex; - int lock_count; - - cairo_ft_font_face_t *faces; /* Linked list of faces for this font */ -}; - -static int -_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); - -typedef struct _cairo_ft_options { - cairo_font_options_t base; - unsigned int load_flags; /* flags for FT_Load_Glyph */ - unsigned int synth_flags; -} cairo_ft_options_t; - -struct _cairo_ft_font_face { - cairo_font_face_t base; - - cairo_ft_unscaled_font_t *unscaled; - cairo_ft_options_t ft_options; - cairo_ft_font_face_t *next; - -#if CAIRO_HAS_FC_FONT - FcPattern *pattern; /* if pattern is set, the above fields will be NULL */ - cairo_font_face_t *resolved_font_face; - FcConfig *resolved_config; -#endif -}; - -static const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend; - -#if CAIRO_HAS_FC_FONT -static cairo_status_t -_cairo_ft_font_options_substitute (const cairo_font_options_t *options, - FcPattern *pattern); - -static cairo_font_face_t * -_cairo_ft_resolve_pattern (FcPattern *pattern, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options); - -#endif - -static cairo_status_t -_ft_to_cairo_error (FT_Error error) -{ - /* Currently we don't get many (any?) useful statuses here. - * Populate as needed. */ - switch (error) - { - default: return CAIRO_STATUS_NO_MEMORY; - } -} - -/* - * We maintain a hash table to map file/id => #cairo_ft_unscaled_font_t. - * The hash table itself isn't limited in size. However, we limit the - * number of FT_Face objects we keep around; when we've exceeded that - * limit and need to create a new FT_Face, we dump the FT_Face from a - * random #cairo_ft_unscaled_font_t which has an unlocked FT_Face, (if - * there are any). - */ - -typedef struct _cairo_ft_unscaled_font_map { - cairo_hash_table_t *hash_table; - FT_Library ft_library; - int num_open_faces; -} cairo_ft_unscaled_font_map_t; - -static cairo_ft_unscaled_font_map_t *cairo_ft_unscaled_font_map = NULL; - - -static FT_Face -_cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t *unscaled); - -static void -_cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t *unscaled); - -static cairo_bool_t -_cairo_ft_scaled_font_is_vertical (cairo_scaled_font_t *scaled_font); - - -static void -_font_map_release_face_lock_held (cairo_ft_unscaled_font_map_t *font_map, - cairo_ft_unscaled_font_t *unscaled) -{ - if (unscaled->face) { - FT_Done_Face (unscaled->face); - unscaled->face = NULL; - unscaled->have_scale = FALSE; - - font_map->num_open_faces--; - } -} - -static cairo_status_t -_cairo_ft_unscaled_font_map_create (void) -{ - cairo_ft_unscaled_font_map_t *font_map; - - /* This function is only intended to be called from - * _cairo_ft_unscaled_font_map_lock. So we'll crash if we can - * detect some other call path. */ - assert (cairo_ft_unscaled_font_map == NULL); - - font_map = malloc (sizeof (cairo_ft_unscaled_font_map_t)); - if (unlikely (font_map == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - font_map->hash_table = - _cairo_hash_table_create (_cairo_ft_unscaled_font_keys_equal); - - if (unlikely (font_map->hash_table == NULL)) - goto FAIL; - - if (unlikely (FT_Init_FreeType (&font_map->ft_library))) - goto FAIL; - - font_map->num_open_faces = 0; - - cairo_ft_unscaled_font_map = font_map; - return CAIRO_STATUS_SUCCESS; - -FAIL: - if (font_map->hash_table) - _cairo_hash_table_destroy (font_map->hash_table); - free (font_map); - - return _cairo_error (CAIRO_STATUS_NO_MEMORY); -} - - -static void -_cairo_ft_unscaled_font_map_pluck_entry (void *entry, void *closure) -{ - cairo_ft_unscaled_font_t *unscaled = entry; - cairo_ft_unscaled_font_map_t *font_map = closure; - - _cairo_hash_table_remove (font_map->hash_table, - &unscaled->base.hash_entry); - - if (! unscaled->from_face) - _font_map_release_face_lock_held (font_map, unscaled); - - _cairo_ft_unscaled_font_fini (unscaled); - free (unscaled); -} - -static void -_cairo_ft_unscaled_font_map_destroy (void) -{ - cairo_ft_unscaled_font_map_t *font_map; - - CAIRO_MUTEX_LOCK (_cairo_ft_unscaled_font_map_mutex); - font_map = cairo_ft_unscaled_font_map; - cairo_ft_unscaled_font_map = NULL; - CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex); - - if (font_map != NULL) { - _cairo_hash_table_foreach (font_map->hash_table, - _cairo_ft_unscaled_font_map_pluck_entry, - font_map); - assert (font_map->num_open_faces == 0); - - FT_Done_FreeType (font_map->ft_library); - - _cairo_hash_table_destroy (font_map->hash_table); - - free (font_map); - } -} - -static cairo_ft_unscaled_font_map_t * -_cairo_ft_unscaled_font_map_lock (void) -{ - CAIRO_MUTEX_LOCK (_cairo_ft_unscaled_font_map_mutex); - - if (unlikely (cairo_ft_unscaled_font_map == NULL)) { - if (unlikely (_cairo_ft_unscaled_font_map_create ())) { - CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex); - return NULL; - } - } - - return cairo_ft_unscaled_font_map; -} - -static void -_cairo_ft_unscaled_font_map_unlock (void) -{ - CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex); -} - -static void -_cairo_ft_unscaled_font_init_key (cairo_ft_unscaled_font_t *key, - cairo_bool_t from_face, - char *filename, - int id, - FT_Face face) -{ - unsigned long hash; - - key->from_face = from_face; - key->filename = filename; - key->id = id; - key->face = face; - - hash = _cairo_hash_string (filename); - /* the constants are just arbitrary primes */ - hash += ((unsigned long) id) * 1607; - hash += ((unsigned long) face) * 2137; - - key->base.hash_entry.hash = hash; -} - -/** - * _cairo_ft_unscaled_font_init: - * - * Initialize a #cairo_ft_unscaled_font_t. - * - * There are two basic flavors of #cairo_ft_unscaled_font_t, one - * created from an FT_Face and the other created from a filename/id - * pair. These two flavors are identified as from_face and !from_face. - * - * To initialize a from_face font, pass filename==%NULL, id=0 and the - * desired face. - * - * To initialize a !from_face font, pass the filename/id as desired - * and face==%NULL. - * - * Note that the code handles these two flavors in very distinct - * ways. For example there is a hash_table mapping - * filename/id->#cairo_unscaled_font_t in the !from_face case, but no - * parallel in the from_face case, (where the calling code would have - * to do its own mapping to ensure similar sharing). - **/ -static cairo_status_t -_cairo_ft_unscaled_font_init (cairo_ft_unscaled_font_t *unscaled, - cairo_bool_t from_face, - const char *filename, - int id, - FT_Face face) -{ - _cairo_unscaled_font_init (&unscaled->base, - &cairo_ft_unscaled_font_backend); - - if (from_face) { - unscaled->from_face = TRUE; - _cairo_ft_unscaled_font_init_key (unscaled, TRUE, NULL, 0, face); - } else { - char *filename_copy; - - unscaled->from_face = FALSE; - unscaled->face = NULL; - - filename_copy = strdup (filename); - if (unlikely (filename_copy == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_ft_unscaled_font_init_key (unscaled, FALSE, filename_copy, id, NULL); - } - - unscaled->have_scale = FALSE; - CAIRO_MUTEX_INIT (unscaled->mutex); - unscaled->lock_count = 0; - - unscaled->faces = NULL; - - return CAIRO_STATUS_SUCCESS; -} - -/** - * _cairo_ft_unscaled_font_fini: - * - * Free all data associated with a #cairo_ft_unscaled_font_t. - * - * CAUTION: The unscaled->face field must be %NULL before calling this - * function. This is because the #cairo_ft_unscaled_font_t_map keeps a - * count of these faces (font_map->num_open_faces) so it maintains the - * unscaled->face field while it has its lock held. See - * _font_map_release_face_lock_held(). - **/ -static void -_cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t *unscaled) -{ - assert (unscaled->face == NULL); - - free (unscaled->filename); - unscaled->filename = NULL; - - CAIRO_MUTEX_FINI (unscaled->mutex); -} - -static int -_cairo_ft_unscaled_font_keys_equal (const void *key_a, - const void *key_b) -{ - const cairo_ft_unscaled_font_t *unscaled_a = key_a; - const cairo_ft_unscaled_font_t *unscaled_b = key_b; - - if (unscaled_a->id == unscaled_b->id && - unscaled_a->from_face == unscaled_b->from_face) - { - if (unscaled_a->from_face) - return unscaled_a->face == unscaled_b->face; - - if (unscaled_a->filename == NULL && unscaled_b->filename == NULL) - return TRUE; - else if (unscaled_a->filename == NULL || unscaled_b->filename == NULL) - return FALSE; - else - return (strcmp (unscaled_a->filename, unscaled_b->filename) == 0); - } - - return FALSE; -} - -/* Finds or creates a #cairo_ft_unscaled_font_t for the filename/id from - * pattern. Returns a new reference to the unscaled font. - */ -static cairo_status_t -_cairo_ft_unscaled_font_create_internal (cairo_bool_t from_face, - char *filename, - int id, - FT_Face font_face, - cairo_ft_unscaled_font_t **out) -{ - cairo_ft_unscaled_font_t key, *unscaled; - cairo_ft_unscaled_font_map_t *font_map; - cairo_status_t status; - - font_map = _cairo_ft_unscaled_font_map_lock (); - if (unlikely (font_map == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_ft_unscaled_font_init_key (&key, from_face, filename, id, font_face); - - /* Return existing unscaled font if it exists in the hash table. */ - unscaled = _cairo_hash_table_lookup (font_map->hash_table, - &key.base.hash_entry); - if (unscaled != NULL) { - _cairo_unscaled_font_reference (&unscaled->base); - goto DONE; - } - - /* Otherwise create it and insert into hash table. */ - unscaled = malloc (sizeof (cairo_ft_unscaled_font_t)); - if (unlikely (unscaled == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto UNWIND_FONT_MAP_LOCK; - } - - status = _cairo_ft_unscaled_font_init (unscaled, from_face, filename, id, font_face); - if (unlikely (status)) - goto UNWIND_UNSCALED_MALLOC; - - assert (unscaled->base.hash_entry.hash == key.base.hash_entry.hash); - status = _cairo_hash_table_insert (font_map->hash_table, - &unscaled->base.hash_entry); - if (unlikely (status)) - goto UNWIND_UNSCALED_FONT_INIT; - -DONE: - _cairo_ft_unscaled_font_map_unlock (); - *out = unscaled; - return CAIRO_STATUS_SUCCESS; - -UNWIND_UNSCALED_FONT_INIT: - _cairo_ft_unscaled_font_fini (unscaled); -UNWIND_UNSCALED_MALLOC: - free (unscaled); -UNWIND_FONT_MAP_LOCK: - _cairo_ft_unscaled_font_map_unlock (); - return status; -} - - -#if CAIRO_HAS_FC_FONT -static cairo_status_t -_cairo_ft_unscaled_font_create_for_pattern (FcPattern *pattern, - cairo_ft_unscaled_font_t **out) -{ - FT_Face font_face = NULL; - char *filename = NULL; - int id = 0; - FcResult ret; - - ret = FcPatternGetFTFace (pattern, FC_FT_FACE, 0, &font_face); - if (ret == FcResultMatch) - goto DONE; - if (ret == FcResultOutOfMemory) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - ret = FcPatternGetString (pattern, FC_FILE, 0, (FcChar8 **) &filename); - if (ret == FcResultOutOfMemory) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - if (ret == FcResultMatch) { - if (access (filename, R_OK) == 0) { - /* If FC_INDEX is not set, we just use 0 */ - ret = FcPatternGetInteger (pattern, FC_INDEX, 0, &id); - if (ret == FcResultOutOfMemory) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - goto DONE; - } else - return _cairo_error (CAIRO_STATUS_FILE_NOT_FOUND); - } - - /* The pattern contains neither a face nor a filename, resolve it later. */ - *out = NULL; - return CAIRO_STATUS_SUCCESS; - -DONE: - return _cairo_ft_unscaled_font_create_internal (font_face != NULL, - filename, id, font_face, - out); -} -#endif - -static cairo_status_t -_cairo_ft_unscaled_font_create_from_face (FT_Face face, - cairo_ft_unscaled_font_t **out) -{ - return _cairo_ft_unscaled_font_create_internal (TRUE, NULL, 0, face, out); -} - -static cairo_bool_t -_cairo_ft_unscaled_font_destroy (void *abstract_font) -{ - cairo_ft_unscaled_font_t *unscaled = abstract_font; - cairo_ft_unscaled_font_map_t *font_map; - - font_map = _cairo_ft_unscaled_font_map_lock (); - /* All created objects must have been mapped in the font map. */ - assert (font_map != NULL); - - if (! _cairo_reference_count_dec_and_test (&unscaled->base.ref_count)) { - /* somebody recreated the font whilst we waited for the lock */ - _cairo_ft_unscaled_font_map_unlock (); - return FALSE; - } - - _cairo_hash_table_remove (font_map->hash_table, - &unscaled->base.hash_entry); - - if (unscaled->from_face) { - /* See comments in _ft_font_face_destroy about the "zombie" state - * for a _ft_font_face. - */ - if (unscaled->faces && unscaled->faces->unscaled == NULL) { - assert (unscaled->faces->next == NULL); - cairo_font_face_destroy (&unscaled->faces->base); - } - } else { - _font_map_release_face_lock_held (font_map, unscaled); - } - unscaled->face = NULL; - - _cairo_ft_unscaled_font_map_unlock (); - - _cairo_ft_unscaled_font_fini (unscaled); - return TRUE; -} - -static cairo_bool_t -_has_unlocked_face (const void *entry) -{ - const cairo_ft_unscaled_font_t *unscaled = entry; - - return (!unscaled->from_face && unscaled->lock_count == 0 && unscaled->face); -} - -/* Ensures that an unscaled font has a face object. If we exceed - * MAX_OPEN_FACES, try to close some. - * - * This differs from _cairo_ft_scaled_font_lock_face in that it doesn't - * set the scale on the face, but just returns it at the last scale. - */ -static cairo_warn FT_Face -_cairo_ft_unscaled_font_lock_face (cairo_ft_unscaled_font_t *unscaled) -{ - cairo_ft_unscaled_font_map_t *font_map; - FT_Face face = NULL; - FT_Error error; - - CAIRO_MUTEX_LOCK (unscaled->mutex); - unscaled->lock_count++; - - if (unscaled->face) - return unscaled->face; - - /* If this unscaled font was created from an FT_Face then we just - * returned it above. */ - assert (!unscaled->from_face); - - font_map = _cairo_ft_unscaled_font_map_lock (); - { - assert (font_map != NULL); - - while (font_map->num_open_faces >= MAX_OPEN_FACES) - { - cairo_ft_unscaled_font_t *entry; - - entry = _cairo_hash_table_random_entry (font_map->hash_table, - _has_unlocked_face); - if (entry == NULL) - break; - - _font_map_release_face_lock_held (font_map, entry); - } - } - _cairo_ft_unscaled_font_map_unlock (); - - error = FT_New_Face (font_map->ft_library, - unscaled->filename, - unscaled->id, - &face); - if (error) - { - unscaled->lock_count--; - CAIRO_MUTEX_UNLOCK (unscaled->mutex); - _cairo_error_throw (_ft_to_cairo_error (error)); - return NULL; - } - - unscaled->face = face; - - font_map->num_open_faces++; - - return face; -} - - -/* Unlock unscaled font locked with _cairo_ft_unscaled_font_lock_face - */ -static void -_cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t *unscaled) -{ - assert (unscaled->lock_count > 0); - - unscaled->lock_count--; - - CAIRO_MUTEX_UNLOCK (unscaled->mutex); -} - - -static cairo_status_t -_compute_transform (cairo_ft_font_transform_t *sf, - cairo_matrix_t *scale, - cairo_ft_unscaled_font_t *unscaled) -{ - cairo_status_t status; - double x_scale, y_scale; - cairo_matrix_t normalized = *scale; - - /* The font matrix has x and y "scale" components which we extract and - * use as character scale values. These influence the way freetype - * chooses hints, as well as selecting different bitmaps in - * hand-rendered fonts. We also copy the normalized matrix to - * freetype's transformation. - */ - - status = _cairo_matrix_compute_basis_scale_factors (scale, - &x_scale, &y_scale, - 1); - if (unlikely (status)) - return status; - - /* FreeType docs say this about x_scale and y_scale: - * "A character width or height smaller than 1pt is set to 1pt;" - * So, we cap them from below at 1.0 and let the FT transform - * take care of sub-1.0 scaling. */ - if (x_scale < 1.0) - x_scale = 1.0; - if (y_scale < 1.0) - y_scale = 1.0; - - if (unscaled && (unscaled->face->face_flags & FT_FACE_FLAG_SCALABLE) == 0) { - double min_distance = DBL_MAX; - cairo_bool_t magnify = TRUE; - int i; - double best_x_size = 0; - double best_y_size = 0; - - for (i = 0; i < unscaled->face->num_fixed_sizes; i++) { - double x_size = unscaled->face->available_sizes[i].x_ppem / 64.; - double y_size = unscaled->face->available_sizes[i].y_ppem / 64.; - double distance = y_size - y_scale; - - /* - * distance is positive if current strike is larger than desired - * size, and negative if smaller. - * - * We like to prefer down-scaling to upscaling. - */ - - if ((magnify && distance >= 0) || fabs (distance) <= min_distance) { - magnify = distance < 0; - min_distance = fabs (distance); - best_x_size = x_size; - best_y_size = y_size; - } - } - - x_scale = best_x_size; - y_scale = best_y_size; - } - - sf->x_scale = x_scale; - sf->y_scale = y_scale; - - cairo_matrix_scale (&normalized, 1.0 / x_scale, 1.0 / y_scale); - - _cairo_matrix_get_affine (&normalized, - &sf->shape[0][0], &sf->shape[0][1], - &sf->shape[1][0], &sf->shape[1][1], - NULL, NULL); - - return CAIRO_STATUS_SUCCESS; -} - -/* Temporarily scales an unscaled font to the give scale. We catch - * scaling to the same size, since changing a FT_Face is expensive. - */ -static cairo_status_t -_cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled, - cairo_matrix_t *scale) -{ - cairo_status_t status; - cairo_ft_font_transform_t sf; - FT_Matrix mat; - FT_Error error; - - assert (unscaled->face != NULL); - - if (unscaled->have_scale && - scale->xx == unscaled->current_scale.xx && - scale->yx == unscaled->current_scale.yx && - scale->xy == unscaled->current_scale.xy && - scale->yy == unscaled->current_scale.yy) - return CAIRO_STATUS_SUCCESS; - - unscaled->have_scale = TRUE; - unscaled->current_scale = *scale; - - status = _compute_transform (&sf, scale, unscaled); - if (unlikely (status)) - return status; - - unscaled->x_scale = sf.x_scale; - unscaled->y_scale = sf.y_scale; - - mat.xx = DOUBLE_TO_16_16(sf.shape[0][0]); - mat.yx = - DOUBLE_TO_16_16(sf.shape[0][1]); - mat.xy = - DOUBLE_TO_16_16(sf.shape[1][0]); - mat.yy = DOUBLE_TO_16_16(sf.shape[1][1]); - - unscaled->have_shape = (mat.xx != 0x10000 || - mat.yx != 0x00000 || - mat.xy != 0x00000 || - mat.yy != 0x10000); - - unscaled->Current_Shape = mat; - cairo_matrix_init (&unscaled->current_shape, - sf.shape[0][0], sf.shape[0][1], - sf.shape[1][0], sf.shape[1][1], - 0.0, 0.0); - - FT_Set_Transform(unscaled->face, &mat, NULL); - - error = FT_Set_Char_Size (unscaled->face, - sf.x_scale * 64.0 + .5, - sf.y_scale * 64.0 + .5, - 0, 0); - if (error) - return _cairo_error (_ft_to_cairo_error (error)); - - return CAIRO_STATUS_SUCCESS; -} - -/* we sometimes need to convert the glyph bitmap in a FT_GlyphSlot - * into a different format. For example, we want to convert a - * FT_PIXEL_MODE_LCD or FT_PIXEL_MODE_LCD_V bitmap into a 32-bit - * ARGB or ABGR bitmap. - * - * this function prepares a target descriptor for this operation. - * - * input :: target bitmap descriptor. The function will set its - * 'width', 'rows' and 'pitch' fields, and only these - * - * slot :: the glyph slot containing the source bitmap. this - * function assumes that slot->format == FT_GLYPH_FORMAT_BITMAP - * - * mode :: the requested final rendering mode. supported values are - * MONO, NORMAL (i.e. gray), LCD and LCD_V - * - * the function returns the size in bytes of the corresponding buffer, - * it's up to the caller to allocate the corresponding memory block - * before calling _fill_xrender_bitmap - * - * it also returns -1 in case of error (e.g. incompatible arguments, - * like trying to convert a gray bitmap into a monochrome one) - */ -static int -_compute_xrender_bitmap_size(FT_Bitmap *target, - FT_GlyphSlot slot, - FT_Render_Mode mode) -{ - FT_Bitmap *ftbit; - int width, height, pitch; - - if (slot->format != FT_GLYPH_FORMAT_BITMAP) - return -1; - - /* compute the size of the final bitmap */ - ftbit = &slot->bitmap; - - width = ftbit->width; - height = ftbit->rows; - pitch = (width + 3) & ~3; - - switch (ftbit->pixel_mode) { - case FT_PIXEL_MODE_MONO: - if (mode == FT_RENDER_MODE_MONO) { - pitch = (((width + 31) & ~31) >> 3); - break; - } - /* fall-through */ - - case FT_PIXEL_MODE_GRAY: - if (mode == FT_RENDER_MODE_LCD || - mode == FT_RENDER_MODE_LCD_V) - { - /* each pixel is replicated into a 32-bit ARGB value */ - pitch = width * 4; - } - break; - - case FT_PIXEL_MODE_LCD: - if (mode != FT_RENDER_MODE_LCD) - return -1; - - /* horz pixel triplets are packed into 32-bit ARGB values */ - width /= 3; - pitch = width * 4; - break; - - case FT_PIXEL_MODE_LCD_V: - if (mode != FT_RENDER_MODE_LCD_V) - return -1; - - /* vert pixel triplets are packed into 32-bit ARGB values */ - height /= 3; - pitch = width * 4; - break; - - default: /* unsupported source format */ - return -1; - } - - target->width = width; - target->rows = height; - target->pitch = pitch; - target->buffer = NULL; - - return pitch * height; -} - -/* this functions converts the glyph bitmap found in a FT_GlyphSlot - * into a different format (see _compute_xrender_bitmap_size) - * - * you should call this function after _compute_xrender_bitmap_size - * - * target :: target bitmap descriptor. Note that its 'buffer' pointer - * must point to memory allocated by the caller - * - * slot :: the glyph slot containing the source bitmap - * - * mode :: the requested final rendering mode - * - * bgr :: boolean, set if BGR or VBGR pixel ordering is needed - */ -static void -_fill_xrender_bitmap(FT_Bitmap *target, - FT_GlyphSlot slot, - FT_Render_Mode mode, - int bgr) -{ - FT_Bitmap *ftbit = &slot->bitmap; - unsigned char *srcLine = ftbit->buffer; - unsigned char *dstLine = target->buffer; - int src_pitch = ftbit->pitch; - int width = target->width; - int height = target->rows; - int pitch = target->pitch; - int subpixel; - int h; - - subpixel = (mode == FT_RENDER_MODE_LCD || - mode == FT_RENDER_MODE_LCD_V); - - if (src_pitch < 0) - srcLine -= src_pitch * (ftbit->rows - 1); - - target->pixel_mode = ftbit->pixel_mode; - - switch (ftbit->pixel_mode) { - case FT_PIXEL_MODE_MONO: - if (subpixel) { - /* convert mono to ARGB32 values */ - - for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch) { - int x; - - for (x = 0; x < width; x++) { - if (srcLine[(x >> 3)] & (0x80 >> (x & 7))) - ((unsigned int *) dstLine)[x] = 0xffffffffU; - } - } - target->pixel_mode = FT_PIXEL_MODE_LCD; - - } else if (mode == FT_RENDER_MODE_NORMAL) { - /* convert mono to 8-bit gray */ - - for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch) { - int x; - - for (x = 0; x < width; x++) { - if (srcLine[(x >> 3)] & (0x80 >> (x & 7))) - dstLine[x] = 0xff; - } - } - target->pixel_mode = FT_PIXEL_MODE_GRAY; - - } else { - /* copy mono to mono */ - - int bytes = (width + 7) >> 3; - - for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch) - memcpy (dstLine, srcLine, bytes); - } - break; - - case FT_PIXEL_MODE_GRAY: - if (subpixel) { - /* convert gray to ARGB32 values */ - - for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch) { - int x; - unsigned int *dst = (unsigned int *) dstLine; - - for (x = 0; x < width; x++) { - unsigned int pix = srcLine[x]; - - pix |= (pix << 8); - pix |= (pix << 16); - - dst[x] = pix; - } - } - target->pixel_mode = FT_PIXEL_MODE_LCD; - } else { - /* copy gray into gray */ - - for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch) - memcpy (dstLine, srcLine, width); - } - break; - - case FT_PIXEL_MODE_LCD: - if (!bgr) { - /* convert horizontal RGB into ARGB32 */ - - for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch) { - int x; - unsigned char *src = srcLine; - unsigned int *dst = (unsigned int *) dstLine; - - for (x = 0; x < width; x++, src += 3) { - unsigned int pix; - - pix = ((unsigned int)src[0] << 16) | - ((unsigned int)src[1] << 8) | - ((unsigned int)src[2] ) | - ((unsigned int)src[1] << 24) ; - - dst[x] = pix; - } - } - } else { - /* convert horizontal BGR into ARGB32 */ - - for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch) { - - int x; - unsigned char *src = srcLine; - unsigned int *dst = (unsigned int *) dstLine; - - for (x = 0; x < width; x++, src += 3) { - unsigned int pix; - - pix = ((unsigned int)src[2] << 16) | - ((unsigned int)src[1] << 8) | - ((unsigned int)src[0] ) | - ((unsigned int)src[1] << 24) ; - - dst[x] = pix; - } - } - } - break; - - default: /* FT_PIXEL_MODE_LCD_V */ - /* convert vertical RGB into ARGB32 */ - if (!bgr) { - - for (h = height; h > 0; h--, srcLine += 3 * src_pitch, dstLine += pitch) { - int x; - unsigned char* src = srcLine; - unsigned int* dst = (unsigned int *) dstLine; - - for (x = 0; x < width; x++, src += 1) { - unsigned int pix; - pix = ((unsigned int)src[0] << 16) | - ((unsigned int)src[src_pitch] << 8) | - ((unsigned int)src[src_pitch*2] ) | - ((unsigned int)src[src_pitch] << 24) ; - dst[x] = pix; - } - } - } else { - - for (h = height; h > 0; h--, srcLine += 3*src_pitch, dstLine += pitch) { - int x; - unsigned char *src = srcLine; - unsigned int *dst = (unsigned int *) dstLine; - - for (x = 0; x < width; x++, src += 1) { - unsigned int pix; - - pix = ((unsigned int)src[src_pitch * 2] << 16) | - ((unsigned int)src[src_pitch] << 8) | - ((unsigned int)src[0] ) | - ((unsigned int)src[src_pitch] << 24) ; - - dst[x] = pix; - } - } - } - } -} - - -/* Fills in val->image with an image surface created from @bitmap - */ -static cairo_status_t -_get_bitmap_surface (FT_Bitmap *bitmap, - FT_Library library, - cairo_bool_t own_buffer, - cairo_font_options_t *font_options, - cairo_image_surface_t **surface) -{ - unsigned int width, height; - unsigned char *data; - int format = CAIRO_FORMAT_A8; - int stride; - cairo_image_surface_t *image; - cairo_bool_t component_alpha = FALSE; - - width = bitmap->width; - height = bitmap->rows; - - if (width == 0 || height == 0) { - *surface = (cairo_image_surface_t *) - cairo_image_surface_create_for_data (NULL, format, 0, 0, 0); - return (*surface)->base.status; - } - - switch (bitmap->pixel_mode) { - case FT_PIXEL_MODE_MONO: - stride = (((width + 31) & ~31) >> 3); - if (own_buffer) { - data = bitmap->buffer; - assert (stride == bitmap->pitch); - } else { - data = _cairo_malloc_ab (height, stride); - if (!data) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - if (stride == bitmap->pitch) { - memcpy (data, bitmap->buffer, stride * height); - } else { - int i; - unsigned char *source, *dest; - - source = bitmap->buffer; - dest = data; - for (i = height; i; i--) { - memcpy (dest, source, bitmap->pitch); - memset (dest + bitmap->pitch, '\0', stride - bitmap->pitch); - - source += bitmap->pitch; - dest += stride; - } - } - } - -#ifndef WORDS_BIGENDIAN - { - uint8_t *d = data; - int count = stride * height; - - while (count--) { - *d = CAIRO_BITSWAP8 (*d); - d++; - } - } -#endif - format = CAIRO_FORMAT_A1; - break; - - case FT_PIXEL_MODE_LCD: - case FT_PIXEL_MODE_LCD_V: - case FT_PIXEL_MODE_GRAY: - if (font_options->antialias != CAIRO_ANTIALIAS_SUBPIXEL || - bitmap->pixel_mode == FT_PIXEL_MODE_GRAY) - { - stride = bitmap->pitch; - - /* We don't support stride not multiple of 4. */ - if (stride & 3) - { - assert (!own_buffer); - goto convert; - } - - if (own_buffer) { - data = bitmap->buffer; - } else { - data = _cairo_malloc_ab (height, stride); - if (!data) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - memcpy (data, bitmap->buffer, stride * height); - } - - format = CAIRO_FORMAT_A8; - } else { - data = bitmap->buffer; - stride = bitmap->pitch; - format = CAIRO_FORMAT_ARGB32; - component_alpha = TRUE; - } - break; -#ifdef FT_LOAD_COLOR - case FT_PIXEL_MODE_BGRA: - stride = width * 4; - if (own_buffer) { - data = bitmap->buffer; - } else { - data = _cairo_malloc_ab (height, stride); - if (!data) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - memcpy (data, bitmap->buffer, stride * height); - } - format = CAIRO_FORMAT_ARGB32; - break; -#endif - case FT_PIXEL_MODE_GRAY2: - case FT_PIXEL_MODE_GRAY4: - convert: - if (!own_buffer && library) - { - /* This is pretty much the only case that we can get in here. */ - /* Convert to 8bit grayscale. */ - - FT_Bitmap tmp; - FT_Int align; - FT_Error error; - - format = CAIRO_FORMAT_A8; - - align = cairo_format_stride_for_width (format, bitmap->width); - - FT_Bitmap_New( &tmp ); - - error = FT_Bitmap_Convert( library, bitmap, &tmp, align ); - if (error) - return _cairo_error (_ft_to_cairo_error (error)); - - FT_Bitmap_Done( library, bitmap ); - *bitmap = tmp; - - stride = bitmap->pitch; - data = _cairo_malloc_ab (height, stride); - if (!data) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - if (bitmap->num_grays != 256) - { - unsigned int x, y; - unsigned int mul = 255 / (bitmap->num_grays - 1); - FT_Byte *p = bitmap->buffer; - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) - p[x] *= mul; - p += bitmap->pitch; - } - } - - memcpy (data, bitmap->buffer, stride * height); - break; - } - /* These could be triggered by very rare types of TrueType fonts */ - default: - if (own_buffer) - free (bitmap->buffer); - return _cairo_error (CAIRO_STATUS_INVALID_FORMAT); - } - - /* XXX */ - *surface = image = (cairo_image_surface_t *) - cairo_image_surface_create_for_data (data, - format, - width, height, stride); - if (image->base.status) { - free (data); - return (*surface)->base.status; - } - - if (component_alpha) - pixman_image_set_component_alpha (image->pixman_image, TRUE); - - _cairo_image_surface_assume_ownership_of_data (image); - - _cairo_debug_check_image_surface_is_defined (&image->base); - - return CAIRO_STATUS_SUCCESS; -} - -/* Converts an outline FT_GlyphSlot into an image - * - * This could go through _render_glyph_bitmap as well, letting - * FreeType convert the outline to a bitmap, but doing it ourselves - * has two minor advantages: first, we save a copy of the bitmap - * buffer: we can directly use the buffer that FreeType renders - * into. - * - * Second, it may help when we add support for subpixel - * rendering: the Xft code does it this way. (Keith thinks that - * it may also be possible to get the subpixel rendering with - * FT_Render_Glyph: something worth looking into in more detail - * when we add subpixel support. If so, we may want to eliminate - * this version of the code path entirely. - */ -static cairo_status_t -_render_glyph_outline (FT_Face face, - cairo_font_options_t *font_options, - cairo_image_surface_t **surface) -{ - int rgba = FC_RGBA_UNKNOWN; - int lcd_filter = FT_LCD_FILTER_LEGACY; - FT_GlyphSlot glyphslot = face->glyph; - FT_Outline *outline = &glyphslot->outline; - FT_Bitmap bitmap; - FT_BBox cbox; - unsigned int width, height; - cairo_status_t status; - FT_Error error; - FT_Library library = glyphslot->library; - FT_Render_Mode render_mode = FT_RENDER_MODE_NORMAL; - - switch (font_options->antialias) { - case CAIRO_ANTIALIAS_NONE: - render_mode = FT_RENDER_MODE_MONO; - break; - - case CAIRO_ANTIALIAS_SUBPIXEL: - case CAIRO_ANTIALIAS_BEST: - switch (font_options->subpixel_order) { - case CAIRO_SUBPIXEL_ORDER_DEFAULT: - case CAIRO_SUBPIXEL_ORDER_RGB: - case CAIRO_SUBPIXEL_ORDER_BGR: - render_mode = FT_RENDER_MODE_LCD; - break; - - case CAIRO_SUBPIXEL_ORDER_VRGB: - case CAIRO_SUBPIXEL_ORDER_VBGR: - render_mode = FT_RENDER_MODE_LCD_V; - break; - } - - switch (font_options->lcd_filter) { - case CAIRO_LCD_FILTER_NONE: - lcd_filter = FT_LCD_FILTER_NONE; - break; - case CAIRO_LCD_FILTER_DEFAULT: - case CAIRO_LCD_FILTER_INTRA_PIXEL: - lcd_filter = FT_LCD_FILTER_LEGACY; - break; - case CAIRO_LCD_FILTER_FIR3: - lcd_filter = FT_LCD_FILTER_LIGHT; - break; - case CAIRO_LCD_FILTER_FIR5: - lcd_filter = FT_LCD_FILTER_DEFAULT; - break; - } - - break; - - case CAIRO_ANTIALIAS_DEFAULT: - case CAIRO_ANTIALIAS_GRAY: - case CAIRO_ANTIALIAS_GOOD: - case CAIRO_ANTIALIAS_FAST: - render_mode = FT_RENDER_MODE_NORMAL; - } - - FT_Outline_Get_CBox (outline, &cbox); - - cbox.xMin &= -64; - cbox.yMin &= -64; - cbox.xMax = (cbox.xMax + 63) & -64; - cbox.yMax = (cbox.yMax + 63) & -64; - - width = (unsigned int) ((cbox.xMax - cbox.xMin) >> 6); - height = (unsigned int) ((cbox.yMax - cbox.yMin) >> 6); - - if (width * height == 0) { - cairo_format_t format; - /* Looks like fb handles zero-sized images just fine */ - switch (render_mode) { - case FT_RENDER_MODE_MONO: - format = CAIRO_FORMAT_A1; - break; - case FT_RENDER_MODE_LCD: - case FT_RENDER_MODE_LCD_V: - format= CAIRO_FORMAT_ARGB32; - break; - case FT_RENDER_MODE_LIGHT: - case FT_RENDER_MODE_NORMAL: - case FT_RENDER_MODE_MAX: - default: - format = CAIRO_FORMAT_A8; - break; - } - - (*surface) = (cairo_image_surface_t *) - cairo_image_surface_create_for_data (NULL, format, 0, 0, 0); - if ((*surface)->base.status) - return (*surface)->base.status; - } else { - - int bitmap_size; - - switch (render_mode) { - case FT_RENDER_MODE_LCD: - if (font_options->subpixel_order == CAIRO_SUBPIXEL_ORDER_BGR) - rgba = FC_RGBA_BGR; - else - rgba = FC_RGBA_RGB; - break; - - case FT_RENDER_MODE_LCD_V: - if (font_options->subpixel_order == CAIRO_SUBPIXEL_ORDER_VBGR) - rgba = FC_RGBA_VBGR; - else - rgba = FC_RGBA_VRGB; - break; - - case FT_RENDER_MODE_MONO: - case FT_RENDER_MODE_LIGHT: - case FT_RENDER_MODE_NORMAL: - case FT_RENDER_MODE_MAX: - default: - break; - } - -#if HAVE_FT_LIBRARY_SETLCDFILTER - FT_Library_SetLcdFilter (library, lcd_filter); -#endif - - error = FT_Render_Glyph (face->glyph, render_mode); - -#if HAVE_FT_LIBRARY_SETLCDFILTER - FT_Library_SetLcdFilter (library, FT_LCD_FILTER_NONE); -#endif - - if (error) - return _cairo_error (_ft_to_cairo_error (error)); - - bitmap_size = _compute_xrender_bitmap_size (&bitmap, - face->glyph, - render_mode); - if (bitmap_size < 0) - return _cairo_error (CAIRO_STATUS_INVALID_FORMAT); - - bitmap.buffer = calloc (1, bitmap_size); - if (bitmap.buffer == NULL) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _fill_xrender_bitmap (&bitmap, face->glyph, render_mode, - (rgba == FC_RGBA_BGR || rgba == FC_RGBA_VBGR)); - - /* Note: - * _get_bitmap_surface will free bitmap.buffer if there is an error - */ - status = _get_bitmap_surface (&bitmap, NULL, TRUE, font_options, surface); - if (unlikely (status)) - return status; - - /* Note: the font's coordinate system is upside down from ours, so the - * Y coordinate of the control box needs to be negated. Moreover, device - * offsets are position of glyph origin relative to top left while xMin - * and yMax are offsets of top left relative to origin. Another negation. - */ - cairo_surface_set_device_offset (&(*surface)->base, - (double)-glyphslot->bitmap_left, - (double)+glyphslot->bitmap_top); - } - - return CAIRO_STATUS_SUCCESS; -} - -/* Converts a bitmap (or other) FT_GlyphSlot into an image */ -static cairo_status_t -_render_glyph_bitmap (FT_Face face, - cairo_font_options_t *font_options, - cairo_image_surface_t **surface) -{ - FT_GlyphSlot glyphslot = face->glyph; - cairo_status_t status; - FT_Error error; - - /* According to the FreeType docs, glyphslot->format could be - * something other than FT_GLYPH_FORMAT_OUTLINE or - * FT_GLYPH_FORMAT_BITMAP. Calling FT_Render_Glyph gives FreeType - * the opportunity to convert such to - * bitmap. FT_GLYPH_FORMAT_COMPOSITE will not be encountered since - * we avoid the FT_LOAD_NO_RECURSE flag. - */ - error = FT_Render_Glyph (glyphslot, FT_RENDER_MODE_NORMAL); - /* XXX ignoring all other errors for now. They are not fatal, typically - * just a glyph-not-found. */ - if (error == FT_Err_Out_Of_Memory) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - status = _get_bitmap_surface (&glyphslot->bitmap, - glyphslot->library, - FALSE, font_options, - surface); - if (unlikely (status)) - return status; - - /* - * Note: the font's coordinate system is upside down from ours, so the - * Y coordinate of the control box needs to be negated. Moreover, device - * offsets are position of glyph origin relative to top left while - * bitmap_left and bitmap_top are offsets of top left relative to origin. - * Another negation. - */ - cairo_surface_set_device_offset (&(*surface)->base, - -glyphslot->bitmap_left, - +glyphslot->bitmap_top); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_transform_glyph_bitmap (cairo_matrix_t * shape, - cairo_image_surface_t ** surface) -{ - cairo_matrix_t original_to_transformed; - cairo_matrix_t transformed_to_original; - cairo_image_surface_t *old_image; - cairo_surface_t *image; - double x[4], y[4]; - double origin_x, origin_y; - int orig_width, orig_height; - int i; - int x_min, y_min, x_max, y_max; - int width, height; - cairo_status_t status; - cairo_surface_pattern_t pattern; - - /* We want to compute a transform that takes the origin - * (device_x_offset, device_y_offset) to 0,0, then applies - * the "shape" portion of the font transform - */ - original_to_transformed = *shape; - - cairo_surface_get_device_offset (&(*surface)->base, &origin_x, &origin_y); - orig_width = (*surface)->width; - orig_height = (*surface)->height; - - cairo_matrix_translate (&original_to_transformed, - -origin_x, -origin_y); - - /* Find the bounding box of the original bitmap under that - * transform - */ - x[0] = 0; y[0] = 0; - x[1] = orig_width; y[1] = 0; - x[2] = orig_width; y[2] = orig_height; - x[3] = 0; y[3] = orig_height; - - for (i = 0; i < 4; i++) - cairo_matrix_transform_point (&original_to_transformed, - &x[i], &y[i]); - - x_min = floor (x[0]); y_min = floor (y[0]); - x_max = ceil (x[0]); y_max = ceil (y[0]); - - for (i = 1; i < 4; i++) { - if (x[i] < x_min) - x_min = floor (x[i]); - else if (x[i] > x_max) - x_max = ceil (x[i]); - if (y[i] < y_min) - y_min = floor (y[i]); - else if (y[i] > y_max) - y_max = ceil (y[i]); - } - - /* Adjust the transform so that the bounding box starts at 0,0 ... - * this gives our final transform from original bitmap to transformed - * bitmap. - */ - original_to_transformed.x0 -= x_min; - original_to_transformed.y0 -= y_min; - - /* Create the transformed bitmap */ - width = x_max - x_min; - height = y_max - y_min; - - transformed_to_original = original_to_transformed; - status = cairo_matrix_invert (&transformed_to_original); - if (unlikely (status)) - return status; - - if ((*surface)->format == CAIRO_FORMAT_ARGB32 && - !pixman_image_get_component_alpha ((*surface)->pixman_image)) - image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); - else - image = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height); - if (unlikely (image->status)) - return image->status; - - /* Draw the original bitmap transformed into the new bitmap - */ - _cairo_pattern_init_for_surface (&pattern, &(*surface)->base); - cairo_pattern_set_matrix (&pattern.base, &transformed_to_original); - - status = _cairo_surface_paint (image, - CAIRO_OPERATOR_SOURCE, - &pattern.base, - NULL); - - _cairo_pattern_fini (&pattern.base); - - if (unlikely (status)) { - cairo_surface_destroy (image); - return status; - } - - /* Now update the cache entry for the new bitmap, recomputing - * the origin based on the final transform. - */ - cairo_matrix_transform_point (&original_to_transformed, - &origin_x, &origin_y); - - old_image = (*surface); - (*surface) = (cairo_image_surface_t *)image; - cairo_surface_destroy (&old_image->base); - - cairo_surface_set_device_offset (&(*surface)->base, - _cairo_lround (origin_x), - _cairo_lround (origin_y)); - return CAIRO_STATUS_SUCCESS; -} - -static const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend = { - _cairo_ft_unscaled_font_destroy, -#if 0 - _cairo_ft_unscaled_font_create_glyph -#endif -}; - -/* #cairo_ft_scaled_font_t */ - -typedef struct _cairo_ft_scaled_font { - cairo_scaled_font_t base; - cairo_ft_unscaled_font_t *unscaled; - cairo_ft_options_t ft_options; -} cairo_ft_scaled_font_t; - -static const cairo_scaled_font_backend_t _cairo_ft_scaled_font_backend; - -#if CAIRO_HAS_FC_FONT -/* The load flags passed to FT_Load_Glyph control aspects like hinting and - * antialiasing. Here we compute them from the fields of a FcPattern. - */ -static void -_get_pattern_ft_options (FcPattern *pattern, cairo_ft_options_t *ret) -{ - FcBool antialias, vertical_layout, hinting, autohint, bitmap, embolden; - cairo_ft_options_t ft_options; - int rgba; -#ifdef FC_HINT_STYLE - int hintstyle; -#endif - - _cairo_font_options_init_default (&ft_options.base); - ft_options.load_flags = FT_LOAD_DEFAULT; - ft_options.synth_flags = 0; - -#ifndef FC_EMBEDDED_BITMAP -#define FC_EMBEDDED_BITMAP "embeddedbitmap" -#endif - - /* Check whether to force use of embedded bitmaps */ - if (FcPatternGetBool (pattern, - FC_EMBEDDED_BITMAP, 0, &bitmap) != FcResultMatch) - bitmap = FcFalse; - - /* disable antialiasing if requested */ - if (FcPatternGetBool (pattern, - FC_ANTIALIAS, 0, &antialias) != FcResultMatch) - antialias = FcTrue; - - if (antialias) { - cairo_subpixel_order_t subpixel_order; - int lcd_filter; - - /* disable hinting if requested */ - if (FcPatternGetBool (pattern, - FC_HINTING, 0, &hinting) != FcResultMatch) - hinting = FcTrue; - - if (FcPatternGetInteger (pattern, - FC_RGBA, 0, &rgba) != FcResultMatch) - rgba = FC_RGBA_UNKNOWN; - - switch (rgba) { - case FC_RGBA_RGB: - subpixel_order = CAIRO_SUBPIXEL_ORDER_RGB; - break; - case FC_RGBA_BGR: - subpixel_order = CAIRO_SUBPIXEL_ORDER_BGR; - break; - case FC_RGBA_VRGB: - subpixel_order = CAIRO_SUBPIXEL_ORDER_VRGB; - break; - case FC_RGBA_VBGR: - subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR; - break; - case FC_RGBA_UNKNOWN: - case FC_RGBA_NONE: - default: - subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT; - break; - } - - if (subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT) { - ft_options.base.subpixel_order = subpixel_order; - ft_options.base.antialias = CAIRO_ANTIALIAS_SUBPIXEL; - } - - if (FcPatternGetInteger (pattern, - FC_LCD_FILTER, 0, &lcd_filter) == FcResultMatch) - { - switch (lcd_filter) { - case FC_LCD_NONE: - ft_options.base.lcd_filter = CAIRO_LCD_FILTER_NONE; - break; - case FC_LCD_DEFAULT: - ft_options.base.lcd_filter = CAIRO_LCD_FILTER_FIR5; - break; - case FC_LCD_LIGHT: - ft_options.base.lcd_filter = CAIRO_LCD_FILTER_FIR3; - break; - case FC_LCD_LEGACY: - ft_options.base.lcd_filter = CAIRO_LCD_FILTER_INTRA_PIXEL; - break; - } - } - -#ifdef FC_HINT_STYLE - if (FcPatternGetInteger (pattern, - FC_HINT_STYLE, 0, &hintstyle) != FcResultMatch) - hintstyle = FC_HINT_FULL; - - if (!hinting) - hintstyle = FC_HINT_NONE; - - switch (hintstyle) { - case FC_HINT_NONE: - ft_options.base.hint_style = CAIRO_HINT_STYLE_NONE; - break; - case FC_HINT_SLIGHT: - ft_options.base.hint_style = CAIRO_HINT_STYLE_SLIGHT; - break; - case FC_HINT_MEDIUM: - default: - ft_options.base.hint_style = CAIRO_HINT_STYLE_MEDIUM; - break; - case FC_HINT_FULL: - ft_options.base.hint_style = CAIRO_HINT_STYLE_FULL; - break; - } -#else /* !FC_HINT_STYLE */ - if (!hinting) { - ft_options.base.hint_style = CAIRO_HINT_STYLE_NONE; - } -#endif /* FC_HINT_STYLE */ - - /* Force embedded bitmaps off if no hinting requested */ - if (ft_options.base.hint_style == CAIRO_HINT_STYLE_NONE) - bitmap = FcFalse; - - if (!bitmap) - ft_options.load_flags |= FT_LOAD_NO_BITMAP; - - } else { - ft_options.base.antialias = CAIRO_ANTIALIAS_NONE; - } - - /* force autohinting if requested */ - if (FcPatternGetBool (pattern, - FC_AUTOHINT, 0, &autohint) != FcResultMatch) - autohint = FcFalse; - - if (autohint) - ft_options.load_flags |= FT_LOAD_FORCE_AUTOHINT; - - if (FcPatternGetBool (pattern, - FC_VERTICAL_LAYOUT, 0, &vertical_layout) != FcResultMatch) - vertical_layout = FcFalse; - - if (vertical_layout) - ft_options.load_flags |= FT_LOAD_VERTICAL_LAYOUT; - -#ifndef FC_EMBOLDEN -#define FC_EMBOLDEN "embolden" -#endif - if (FcPatternGetBool (pattern, - FC_EMBOLDEN, 0, &embolden) != FcResultMatch) - embolden = FcFalse; - - if (embolden) - ft_options.synth_flags |= CAIRO_FT_SYNTHESIZE_BOLD; - - *ret = ft_options; -} -#endif - -static void -_cairo_ft_options_merge (cairo_ft_options_t *options, - cairo_ft_options_t *other) -{ - int load_flags = other->load_flags; - int load_target = FT_LOAD_TARGET_NORMAL; - - /* clear load target mode */ - load_flags &= ~(FT_LOAD_TARGET_(FT_LOAD_TARGET_MODE(other->load_flags))); - - if (load_flags & FT_LOAD_NO_HINTING) - other->base.hint_style = CAIRO_HINT_STYLE_NONE; - - if (other->base.antialias == CAIRO_ANTIALIAS_NONE || - options->base.antialias == CAIRO_ANTIALIAS_NONE) { - options->base.antialias = CAIRO_ANTIALIAS_NONE; - options->base.subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT; - } - - if (other->base.antialias == CAIRO_ANTIALIAS_SUBPIXEL && - (options->base.antialias == CAIRO_ANTIALIAS_DEFAULT || - options->base.antialias == CAIRO_ANTIALIAS_GRAY)) { - options->base.antialias = CAIRO_ANTIALIAS_SUBPIXEL; - options->base.subpixel_order = other->base.subpixel_order; - } - - if (options->base.hint_style == CAIRO_HINT_STYLE_DEFAULT) - options->base.hint_style = other->base.hint_style; - - if (other->base.hint_style == CAIRO_HINT_STYLE_NONE) - options->base.hint_style = CAIRO_HINT_STYLE_NONE; - - if (options->base.lcd_filter == CAIRO_LCD_FILTER_DEFAULT) - options->base.lcd_filter = other->base.lcd_filter; - - if (other->base.lcd_filter == CAIRO_LCD_FILTER_NONE) - options->base.lcd_filter = CAIRO_LCD_FILTER_NONE; - - if (options->base.antialias == CAIRO_ANTIALIAS_NONE) { - if (options->base.hint_style == CAIRO_HINT_STYLE_NONE) - load_flags |= FT_LOAD_NO_HINTING; - else - load_target = FT_LOAD_TARGET_MONO; - load_flags |= FT_LOAD_MONOCHROME; - } else { - switch (options->base.hint_style) { - case CAIRO_HINT_STYLE_NONE: - load_flags |= FT_LOAD_NO_HINTING; - break; - case CAIRO_HINT_STYLE_SLIGHT: - load_target = FT_LOAD_TARGET_LIGHT; - break; - case CAIRO_HINT_STYLE_MEDIUM: - break; - case CAIRO_HINT_STYLE_FULL: - case CAIRO_HINT_STYLE_DEFAULT: - if (options->base.antialias == CAIRO_ANTIALIAS_SUBPIXEL) { - switch (options->base.subpixel_order) { - case CAIRO_SUBPIXEL_ORDER_DEFAULT: - case CAIRO_SUBPIXEL_ORDER_RGB: - case CAIRO_SUBPIXEL_ORDER_BGR: - load_target = FT_LOAD_TARGET_LCD; - break; - case CAIRO_SUBPIXEL_ORDER_VRGB: - case CAIRO_SUBPIXEL_ORDER_VBGR: - load_target = FT_LOAD_TARGET_LCD_V; - break; - } - } - break; - } - } - - options->load_flags = load_flags | load_target; - options->synth_flags = other->synth_flags; -} - -static cairo_status_t -_cairo_ft_font_face_scaled_font_create (void *abstract_font_face, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options, - cairo_scaled_font_t **font_out) -{ - cairo_ft_font_face_t *font_face = abstract_font_face; - cairo_ft_scaled_font_t *scaled_font; - FT_Face face; - FT_Size_Metrics *metrics; - cairo_font_extents_t fs_metrics; - cairo_status_t status; - cairo_ft_unscaled_font_t *unscaled; - - assert (font_face->unscaled); - - face = _cairo_ft_unscaled_font_lock_face (font_face->unscaled); - if (unlikely (face == NULL)) /* backend error */ - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - scaled_font = malloc (sizeof (cairo_ft_scaled_font_t)); - if (unlikely (scaled_font == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto FAIL; - } - - scaled_font->unscaled = unscaled = font_face->unscaled; - _cairo_unscaled_font_reference (&unscaled->base); - - _cairo_font_options_init_copy (&scaled_font->ft_options.base, options); - _cairo_ft_options_merge (&scaled_font->ft_options, &font_face->ft_options); - - status = _cairo_scaled_font_init (&scaled_font->base, - &font_face->base, - font_matrix, ctm, options, - &_cairo_ft_scaled_font_backend); - if (unlikely (status)) - goto CLEANUP_SCALED_FONT; - - status = _cairo_ft_unscaled_font_set_scale (unscaled, - &scaled_font->base.scale); - if (unlikely (status)) { - /* This can only fail if we encounter an error with the underlying - * font, so propagate the error back to the font-face. */ - _cairo_ft_unscaled_font_unlock_face (unscaled); - _cairo_unscaled_font_destroy (&unscaled->base); - free (scaled_font); - return status; - } - - - metrics = &face->size->metrics; - - /* - * Get to unscaled metrics so that the upper level can get back to - * user space - * - * Also use this path for bitmap-only fonts. The other branch uses - * face members that are only relevant for scalable fonts. This is - * detected by simply checking for units_per_EM==0. - */ - if (scaled_font->base.options.hint_metrics != CAIRO_HINT_METRICS_OFF || - face->units_per_EM == 0) { - double x_factor, y_factor; - - if (unscaled->x_scale == 0) - x_factor = 0; - else - x_factor = 1 / unscaled->x_scale; - - if (unscaled->y_scale == 0) - y_factor = 0; - else - y_factor = 1 / unscaled->y_scale; - - fs_metrics.ascent = DOUBLE_FROM_26_6(metrics->ascender) * y_factor; - fs_metrics.descent = DOUBLE_FROM_26_6(- metrics->descender) * y_factor; - fs_metrics.height = DOUBLE_FROM_26_6(metrics->height) * y_factor; - if (!_cairo_ft_scaled_font_is_vertical (&scaled_font->base)) { - fs_metrics.max_x_advance = DOUBLE_FROM_26_6(metrics->max_advance) * x_factor; - fs_metrics.max_y_advance = 0; - } else { - fs_metrics.max_x_advance = 0; - fs_metrics.max_y_advance = DOUBLE_FROM_26_6(metrics->max_advance) * y_factor; - } - } else { - double scale = face->units_per_EM; - - fs_metrics.ascent = face->ascender / scale; - fs_metrics.descent = - face->descender / scale; - fs_metrics.height = face->height / scale; - if (!_cairo_ft_scaled_font_is_vertical (&scaled_font->base)) { - fs_metrics.max_x_advance = face->max_advance_width / scale; - fs_metrics.max_y_advance = 0; - } else { - fs_metrics.max_x_advance = 0; - fs_metrics.max_y_advance = face->max_advance_height / scale; - } - } - - status = _cairo_scaled_font_set_metrics (&scaled_font->base, &fs_metrics); - if (unlikely (status)) - goto CLEANUP_SCALED_FONT; - - _cairo_ft_unscaled_font_unlock_face (unscaled); - - *font_out = &scaled_font->base; - return CAIRO_STATUS_SUCCESS; - - CLEANUP_SCALED_FONT: - _cairo_unscaled_font_destroy (&unscaled->base); - free (scaled_font); - FAIL: - _cairo_ft_unscaled_font_unlock_face (font_face->unscaled); - *font_out = _cairo_scaled_font_create_in_error (status); - return CAIRO_STATUS_SUCCESS; /* non-backend error */ -} - -cairo_bool_t -_cairo_scaled_font_is_ft (cairo_scaled_font_t *scaled_font) -{ - return scaled_font->backend == &_cairo_ft_scaled_font_backend; -} - -static void -_cairo_ft_scaled_font_fini (void *abstract_font) -{ - cairo_ft_scaled_font_t *scaled_font = abstract_font; - - if (scaled_font == NULL) - return; - - _cairo_unscaled_font_destroy (&scaled_font->unscaled->base); -} - -static int -_move_to (FT_Vector *to, void *closure) -{ - cairo_path_fixed_t *path = closure; - cairo_fixed_t x, y; - - x = _cairo_fixed_from_26_6 (to->x); - y = _cairo_fixed_from_26_6 (to->y); - - if (_cairo_path_fixed_close_path (path) != CAIRO_STATUS_SUCCESS) - return 1; - if (_cairo_path_fixed_move_to (path, x, y) != CAIRO_STATUS_SUCCESS) - return 1; - - return 0; -} - -static int -_line_to (FT_Vector *to, void *closure) -{ - cairo_path_fixed_t *path = closure; - cairo_fixed_t x, y; - - x = _cairo_fixed_from_26_6 (to->x); - y = _cairo_fixed_from_26_6 (to->y); - - if (_cairo_path_fixed_line_to (path, x, y) != CAIRO_STATUS_SUCCESS) - return 1; - - return 0; -} - -static int -_conic_to (FT_Vector *control, FT_Vector *to, void *closure) -{ - cairo_path_fixed_t *path = closure; - - cairo_fixed_t x0, y0; - cairo_fixed_t x1, y1; - cairo_fixed_t x2, y2; - cairo_fixed_t x3, y3; - cairo_point_t conic; - - if (! _cairo_path_fixed_get_current_point (path, &x0, &y0)) - return 1; - - conic.x = _cairo_fixed_from_26_6 (control->x); - conic.y = _cairo_fixed_from_26_6 (control->y); - - x3 = _cairo_fixed_from_26_6 (to->x); - y3 = _cairo_fixed_from_26_6 (to->y); - - x1 = x0 + 2.0/3.0 * (conic.x - x0); - y1 = y0 + 2.0/3.0 * (conic.y - y0); - - x2 = x3 + 2.0/3.0 * (conic.x - x3); - y2 = y3 + 2.0/3.0 * (conic.y - y3); - - if (_cairo_path_fixed_curve_to (path, - x1, y1, - x2, y2, - x3, y3) != CAIRO_STATUS_SUCCESS) - return 1; - - return 0; -} - -static int -_cubic_to (FT_Vector *control1, FT_Vector *control2, - FT_Vector *to, void *closure) -{ - cairo_path_fixed_t *path = closure; - cairo_fixed_t x0, y0; - cairo_fixed_t x1, y1; - cairo_fixed_t x2, y2; - - x0 = _cairo_fixed_from_26_6 (control1->x); - y0 = _cairo_fixed_from_26_6 (control1->y); - - x1 = _cairo_fixed_from_26_6 (control2->x); - y1 = _cairo_fixed_from_26_6 (control2->y); - - x2 = _cairo_fixed_from_26_6 (to->x); - y2 = _cairo_fixed_from_26_6 (to->y); - - if (_cairo_path_fixed_curve_to (path, - x0, y0, - x1, y1, - x2, y2) != CAIRO_STATUS_SUCCESS) - return 1; - - return 0; -} - -static cairo_status_t -_decompose_glyph_outline (FT_Face face, - cairo_font_options_t *options, - cairo_path_fixed_t **pathp) -{ - static const FT_Outline_Funcs outline_funcs = { - (FT_Outline_MoveToFunc)_move_to, - (FT_Outline_LineToFunc)_line_to, - (FT_Outline_ConicToFunc)_conic_to, - (FT_Outline_CubicToFunc)_cubic_to, - 0, /* shift */ - 0, /* delta */ - }; - static const FT_Matrix invert_y = { - DOUBLE_TO_16_16 (1.0), 0, - 0, DOUBLE_TO_16_16 (-1.0), - }; - - FT_GlyphSlot glyph; - cairo_path_fixed_t *path; - cairo_status_t status; - - path = _cairo_path_fixed_create (); - if (!path) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - glyph = face->glyph; - - /* Font glyphs have an inverted Y axis compared to cairo. */ - FT_Outline_Transform (&glyph->outline, &invert_y); - if (FT_Outline_Decompose (&glyph->outline, &outline_funcs, path)) { - _cairo_path_fixed_destroy (path); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - status = _cairo_path_fixed_close_path (path); - if (unlikely (status)) { - _cairo_path_fixed_destroy (path); - return status; - } - - *pathp = path; - - return CAIRO_STATUS_SUCCESS; -} - -/* - * Translate glyph to match its metrics. - */ -static void -_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (void *abstract_font, - FT_GlyphSlot glyph) -{ - cairo_ft_scaled_font_t *scaled_font = abstract_font; - FT_Vector vector; - - vector.x = glyph->metrics.vertBearingX - glyph->metrics.horiBearingX; - vector.y = -glyph->metrics.vertBearingY - glyph->metrics.horiBearingY; - - if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) { - FT_Vector_Transform (&vector, &scaled_font->unscaled->Current_Shape); - FT_Outline_Translate(&glyph->outline, vector.x, vector.y); - } else if (glyph->format == FT_GLYPH_FORMAT_BITMAP) { - glyph->bitmap_left += vector.x / 64; - glyph->bitmap_top += vector.y / 64; - } -} - -static cairo_int_status_t -_cairo_ft_scaled_glyph_init (void *abstract_font, - cairo_scaled_glyph_t *scaled_glyph, - cairo_scaled_glyph_info_t info) -{ - cairo_text_extents_t fs_metrics; - cairo_ft_scaled_font_t *scaled_font = abstract_font; - cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled; - FT_GlyphSlot glyph; - FT_Face face; - FT_Error error; - int load_flags = scaled_font->ft_options.load_flags; - FT_Glyph_Metrics *metrics; - double x_factor, y_factor; - cairo_bool_t vertical_layout = FALSE; - cairo_status_t status; - - face = _cairo_ft_unscaled_font_lock_face (unscaled); - if (!face) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled, - &scaled_font->base.scale); - if (unlikely (status)) - goto FAIL; - - /* Ignore global advance unconditionally */ - load_flags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH; - - if ((info & CAIRO_SCALED_GLYPH_INFO_PATH) != 0 && - (info & CAIRO_SCALED_GLYPH_INFO_SURFACE) == 0) - load_flags |= FT_LOAD_NO_BITMAP; - - /* - * Don't pass FT_LOAD_VERTICAL_LAYOUT to FT_Load_Glyph here as - * suggested by freetype people. - */ - if (load_flags & FT_LOAD_VERTICAL_LAYOUT) { - load_flags &= ~FT_LOAD_VERTICAL_LAYOUT; - vertical_layout = TRUE; - } - -#ifdef FT_LOAD_COLOR - /* Color-glyph support: - * - * This flags needs plumbing through fontconfig (does it?), and - * maybe we should cache color and grayscale bitmaps separately - * such that users of the font (ie. the surface) can choose which - * version to use based on target content type. - * - * Moreover, none of our backends and compositors currently support - * color glyphs. As such, this is currently disabled. - */ - /* load_flags |= FT_LOAD_COLOR; */ -#endif - - error = FT_Load_Glyph (face, - _cairo_scaled_glyph_index(scaled_glyph), - load_flags); - /* XXX ignoring all other errors for now. They are not fatal, typically - * just a glyph-not-found. */ - if (error == FT_Err_Out_Of_Memory) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto FAIL; - } - - glyph = face->glyph; - - /* - * synthesize glyphs if requested - */ -#if HAVE_FT_GLYPHSLOT_EMBOLDEN - if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_BOLD) - FT_GlyphSlot_Embolden (glyph); -#endif - -#if HAVE_FT_GLYPHSLOT_OBLIQUE - if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_OBLIQUE) - FT_GlyphSlot_Oblique (glyph); -#endif - - if (vertical_layout) - _cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font, glyph); - - if (info & CAIRO_SCALED_GLYPH_INFO_METRICS) { - - cairo_bool_t hint_metrics = scaled_font->base.options.hint_metrics != CAIRO_HINT_METRICS_OFF; - /* - * Compute font-space metrics - */ - metrics = &glyph->metrics; - - if (unscaled->x_scale == 0) - x_factor = 0; - else - x_factor = 1 / unscaled->x_scale; - - if (unscaled->y_scale == 0) - y_factor = 0; - else - y_factor = 1 / unscaled->y_scale; - - /* - * Note: Y coordinates of the horizontal bearing need to be negated. - * - * Scale metrics back to glyph space from the scaled glyph space returned - * by FreeType - * - * If we want hinted metrics but aren't asking for hinted glyphs from - * FreeType, then we need to do the metric hinting ourselves. - */ - - if (hint_metrics && (load_flags & FT_LOAD_NO_HINTING)) - { - FT_Pos x1, x2; - FT_Pos y1, y2; - FT_Pos advance; - - if (!vertical_layout) { - x1 = (metrics->horiBearingX) & -64; - x2 = (metrics->horiBearingX + metrics->width + 63) & -64; - y1 = (-metrics->horiBearingY) & -64; - y2 = (-metrics->horiBearingY + metrics->height + 63) & -64; - - advance = ((metrics->horiAdvance + 32) & -64); - - fs_metrics.x_bearing = DOUBLE_FROM_26_6 (x1) * x_factor; - fs_metrics.y_bearing = DOUBLE_FROM_26_6 (y1) * y_factor; - - fs_metrics.width = DOUBLE_FROM_26_6 (x2 - x1) * x_factor; - fs_metrics.height = DOUBLE_FROM_26_6 (y2 - y1) * y_factor; - - fs_metrics.x_advance = DOUBLE_FROM_26_6 (advance) * x_factor; - fs_metrics.y_advance = 0; - } else { - x1 = (metrics->vertBearingX) & -64; - x2 = (metrics->vertBearingX + metrics->width + 63) & -64; - y1 = (metrics->vertBearingY) & -64; - y2 = (metrics->vertBearingY + metrics->height + 63) & -64; - - advance = ((metrics->vertAdvance + 32) & -64); - - fs_metrics.x_bearing = DOUBLE_FROM_26_6 (x1) * x_factor; - fs_metrics.y_bearing = DOUBLE_FROM_26_6 (y1) * y_factor; - - fs_metrics.width = DOUBLE_FROM_26_6 (x2 - x1) * x_factor; - fs_metrics.height = DOUBLE_FROM_26_6 (y2 - y1) * y_factor; - - fs_metrics.x_advance = 0; - fs_metrics.y_advance = DOUBLE_FROM_26_6 (advance) * y_factor; - } - } else { - fs_metrics.width = DOUBLE_FROM_26_6 (metrics->width) * x_factor; - fs_metrics.height = DOUBLE_FROM_26_6 (metrics->height) * y_factor; - - if (!vertical_layout) { - fs_metrics.x_bearing = DOUBLE_FROM_26_6 (metrics->horiBearingX) * x_factor; - fs_metrics.y_bearing = DOUBLE_FROM_26_6 (-metrics->horiBearingY) * y_factor; - - if (hint_metrics || glyph->format != FT_GLYPH_FORMAT_OUTLINE) - fs_metrics.x_advance = DOUBLE_FROM_26_6 (metrics->horiAdvance) * x_factor; - else - fs_metrics.x_advance = DOUBLE_FROM_16_16 (glyph->linearHoriAdvance) * x_factor; - fs_metrics.y_advance = 0 * y_factor; - } else { - fs_metrics.x_bearing = DOUBLE_FROM_26_6 (metrics->vertBearingX) * x_factor; - fs_metrics.y_bearing = DOUBLE_FROM_26_6 (metrics->vertBearingY) * y_factor; - - fs_metrics.x_advance = 0 * x_factor; - if (hint_metrics || glyph->format != FT_GLYPH_FORMAT_OUTLINE) - fs_metrics.y_advance = DOUBLE_FROM_26_6 (metrics->vertAdvance) * y_factor; - else - fs_metrics.y_advance = DOUBLE_FROM_16_16 (glyph->linearVertAdvance) * y_factor; - } - } - - _cairo_scaled_glyph_set_metrics (scaled_glyph, - &scaled_font->base, - &fs_metrics); - } - - if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) { - cairo_image_surface_t *surface; - - if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) { - status = _render_glyph_outline (face, &scaled_font->ft_options.base, - &surface); - } else { - status = _render_glyph_bitmap (face, &scaled_font->ft_options.base, - &surface); - if (likely (status == CAIRO_STATUS_SUCCESS) && - unscaled->have_shape) - { - status = _transform_glyph_bitmap (&unscaled->current_shape, - &surface); - if (unlikely (status)) - cairo_surface_destroy (&surface->base); - } - } - if (unlikely (status)) - goto FAIL; - - _cairo_scaled_glyph_set_surface (scaled_glyph, - &scaled_font->base, - surface); - } - - if (info & CAIRO_SCALED_GLYPH_INFO_PATH) { - cairo_path_fixed_t *path = NULL; /* hide compiler warning */ - - /* - * A kludge -- the above code will trash the outline, - * so reload it. This will probably never occur though - */ - if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) { - error = FT_Load_Glyph (face, - _cairo_scaled_glyph_index(scaled_glyph), - load_flags | FT_LOAD_NO_BITMAP); - /* XXX ignoring all other errors for now. They are not fatal, typically - * just a glyph-not-found. */ - if (error == FT_Err_Out_Of_Memory) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto FAIL; - } -#if HAVE_FT_GLYPHSLOT_EMBOLDEN - if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_BOLD) - FT_GlyphSlot_Embolden (glyph); -#endif -#if HAVE_FT_GLYPHSLOT_OBLIQUE - if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_OBLIQUE) - FT_GlyphSlot_Oblique (glyph); -#endif - if (vertical_layout) - _cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font, glyph); - - } - if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) - status = _decompose_glyph_outline (face, &scaled_font->ft_options.base, - &path); - else - status = CAIRO_INT_STATUS_UNSUPPORTED; - - if (unlikely (status)) - goto FAIL; - - _cairo_scaled_glyph_set_path (scaled_glyph, - &scaled_font->base, - path); - } - FAIL: - _cairo_ft_unscaled_font_unlock_face (unscaled); - - return status; -} - -static unsigned long -_cairo_ft_ucs4_to_index (void *abstract_font, - uint32_t ucs4) -{ - cairo_ft_scaled_font_t *scaled_font = abstract_font; - cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled; - FT_Face face; - FT_UInt index; - - face = _cairo_ft_unscaled_font_lock_face (unscaled); - if (!face) - return 0; - -#if CAIRO_HAS_FC_FONT - index = FcFreeTypeCharIndex (face, ucs4); -#else - index = FT_Get_Char_Index (face, ucs4); -#endif - - _cairo_ft_unscaled_font_unlock_face (unscaled); - return index; -} - -static cairo_int_status_t -_cairo_ft_load_truetype_table (void *abstract_font, - unsigned long tag, - long offset, - unsigned char *buffer, - unsigned long *length) -{ - cairo_ft_scaled_font_t *scaled_font = abstract_font; - cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled; - FT_Face face; - cairo_status_t status = CAIRO_INT_STATUS_UNSUPPORTED; - - /* We don't support the FreeType feature of loading a table - * without specifying the size since this may overflow our - * buffer. */ - assert (length != NULL); - - if (_cairo_ft_scaled_font_is_vertical (&scaled_font->base)) - return CAIRO_INT_STATUS_UNSUPPORTED; - -#if HAVE_FT_LOAD_SFNT_TABLE - face = _cairo_ft_unscaled_font_lock_face (unscaled); - if (!face) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - if (FT_IS_SFNT (face)) { - if (buffer == NULL) - *length = 0; - - if (FT_Load_Sfnt_Table (face, tag, offset, buffer, length) == 0) - status = CAIRO_STATUS_SUCCESS; - } - - _cairo_ft_unscaled_font_unlock_face (unscaled); -#endif - - return status; -} - -static cairo_int_status_t -_cairo_ft_index_to_ucs4(void *abstract_font, - unsigned long index, - uint32_t *ucs4) -{ - cairo_ft_scaled_font_t *scaled_font = abstract_font; - cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled; - FT_Face face; - FT_ULong charcode; - FT_UInt gindex; - - face = _cairo_ft_unscaled_font_lock_face (unscaled); - if (!face) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - *ucs4 = (uint32_t) -1; - charcode = FT_Get_First_Char(face, &gindex); - while (gindex != 0) { - if (gindex == index) { - *ucs4 = charcode; - break; - } - charcode = FT_Get_Next_Char (face, charcode, &gindex); - } - - _cairo_ft_unscaled_font_unlock_face (unscaled); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_bool_t -_cairo_ft_is_synthetic (void *abstract_font) -{ - cairo_ft_scaled_font_t *scaled_font = abstract_font; - return scaled_font->ft_options.synth_flags != 0; -} - -static cairo_int_status_t -_cairo_index_to_glyph_name (void *abstract_font, - char **glyph_names, - int num_glyph_names, - unsigned long glyph_index, - unsigned long *glyph_array_index) -{ - cairo_ft_scaled_font_t *scaled_font = abstract_font; - cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled; - FT_Face face; - char buffer[256]; /* PLRM spcifies max name length of 127 */ - FT_Error error; - int i; - - face = _cairo_ft_unscaled_font_lock_face (unscaled); - if (!face) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - error = FT_Get_Glyph_Name (face, glyph_index, buffer, sizeof buffer); - - _cairo_ft_unscaled_font_unlock_face (unscaled); - - if (error != FT_Err_Ok) { - /* propagate fatal errors from FreeType */ - if (error == FT_Err_Out_Of_Memory) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - /* FT first numbers the glyphs in the order they are read from the - * Type 1 font. Then if .notdef is not the first glyph, the first - * glyph is swapped with .notdef to ensure that .notdef is at - * glyph index 0. - * - * As all but two glyphs in glyph_names already have the same - * index as the FT glyph index, we first check if - * glyph_names[glyph_index] is the name we are looking for. If not - * we fall back to searching the entire array. - */ - - if ((long)glyph_index < num_glyph_names && - strcmp (glyph_names[glyph_index], buffer) == 0) - { - *glyph_array_index = glyph_index; - - return CAIRO_STATUS_SUCCESS; - } - - for (i = 0; i < num_glyph_names; i++) { - if (strcmp (glyph_names[i], buffer) == 0) { - *glyph_array_index = i; - - return CAIRO_STATUS_SUCCESS; - } - } - - return CAIRO_INT_STATUS_UNSUPPORTED; -} - -static cairo_bool_t -_ft_is_type1 (FT_Face face) -{ -#if HAVE_FT_GET_X11_FONT_FORMAT - const char *font_format = FT_Get_X11_Font_Format (face); - if (font_format && - (strcmp (font_format, "Type 1") == 0 || - strcmp (font_format, "CFF") == 0)) - { - return TRUE; - } -#endif - - return FALSE; -} - -static cairo_int_status_t -_cairo_ft_load_type1_data (void *abstract_font, - long offset, - unsigned char *buffer, - unsigned long *length) -{ - cairo_ft_scaled_font_t *scaled_font = abstract_font; - cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled; - FT_Face face; - cairo_status_t status = CAIRO_STATUS_SUCCESS; - unsigned long available_length; - unsigned long ret; - - assert (length != NULL); - - if (_cairo_ft_scaled_font_is_vertical (&scaled_font->base)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - face = _cairo_ft_unscaled_font_lock_face (unscaled); - if (!face) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - -#if HAVE_FT_LOAD_SFNT_TABLE - if (FT_IS_SFNT (face)) { - status = CAIRO_INT_STATUS_UNSUPPORTED; - goto unlock; - } -#endif - - if (! _ft_is_type1 (face)) { - status = CAIRO_INT_STATUS_UNSUPPORTED; - goto unlock; - } - - available_length = MAX (face->stream->size - offset, 0); - if (!buffer) { - *length = available_length; - } else { - if (*length > available_length) { - status = CAIRO_INT_STATUS_UNSUPPORTED; - } else if (face->stream->read != NULL) { - /* Note that read() may be implemented as a macro, thanks POSIX!, so we - * need to wrap the following usage in parentheses in order to - * disambiguate it for the pre-processor - using the verbose function - * pointer dereference for clarity. - */ - ret = (* face->stream->read) (face->stream, - offset, - buffer, - *length); - if (ret != *length) - status = _cairo_error (CAIRO_STATUS_READ_ERROR); - } else { - memcpy (buffer, face->stream->base + offset, *length); - } - } - - unlock: - _cairo_ft_unscaled_font_unlock_face (unscaled); - - return status; -} - -static const cairo_scaled_font_backend_t _cairo_ft_scaled_font_backend = { - CAIRO_FONT_TYPE_FT, - _cairo_ft_scaled_font_fini, - _cairo_ft_scaled_glyph_init, - NULL, /* text_to_glyphs */ - _cairo_ft_ucs4_to_index, - _cairo_ft_load_truetype_table, - _cairo_ft_index_to_ucs4, - _cairo_ft_is_synthetic, - _cairo_index_to_glyph_name, - _cairo_ft_load_type1_data -}; - -/* #cairo_ft_font_face_t */ - -#if CAIRO_HAS_FC_FONT -static cairo_font_face_t * -_cairo_ft_font_face_create_for_pattern (FcPattern *pattern); - -static cairo_status_t -_cairo_ft_font_face_create_for_toy (cairo_toy_font_face_t *toy_face, - cairo_font_face_t **font_face_out) -{ - cairo_font_face_t *font_face = (cairo_font_face_t *) &_cairo_font_face_nil; - FcPattern *pattern; - int fcslant; - int fcweight; - - pattern = FcPatternCreate (); - if (!pattern) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return font_face->status; - } - - if (!FcPatternAddString (pattern, - FC_FAMILY, (unsigned char *) toy_face->family)) - { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - goto FREE_PATTERN; - } - - switch (toy_face->slant) - { - case CAIRO_FONT_SLANT_ITALIC: - fcslant = FC_SLANT_ITALIC; - break; - case CAIRO_FONT_SLANT_OBLIQUE: - fcslant = FC_SLANT_OBLIQUE; - break; - case CAIRO_FONT_SLANT_NORMAL: - default: - fcslant = FC_SLANT_ROMAN; - break; - } - - if (!FcPatternAddInteger (pattern, FC_SLANT, fcslant)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - goto FREE_PATTERN; - } - - switch (toy_face->weight) - { - case CAIRO_FONT_WEIGHT_BOLD: - fcweight = FC_WEIGHT_BOLD; - break; - case CAIRO_FONT_WEIGHT_NORMAL: - default: - fcweight = FC_WEIGHT_MEDIUM; - break; - } - - if (!FcPatternAddInteger (pattern, FC_WEIGHT, fcweight)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - goto FREE_PATTERN; - } - - font_face = _cairo_ft_font_face_create_for_pattern (pattern); - - FREE_PATTERN: - FcPatternDestroy (pattern); - - *font_face_out = font_face; - return font_face->status; -} -#endif - -static cairo_bool_t -_cairo_ft_font_face_destroy (void *abstract_face) -{ - cairo_ft_font_face_t *font_face = abstract_face; - - /* When destroying a face created by cairo_ft_font_face_create_for_ft_face, - * we have a special "zombie" state for the face when the unscaled font - * is still alive but there are no other references to a font face with - * the same FT_Face. - * - * We go from: - * - * font_face ------> unscaled - * <-....weak....../ - * - * To: - * - * font_face <------- unscaled - */ - - if (font_face->unscaled && - font_face->unscaled->from_face && - font_face->next == NULL && - font_face->unscaled->faces == font_face && - CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->unscaled->base.ref_count) > 1) - { - _cairo_unscaled_font_destroy (&font_face->unscaled->base); - font_face->unscaled = NULL; - - return FALSE; - } - - if (font_face->unscaled) { - cairo_ft_font_face_t *tmp_face = NULL; - cairo_ft_font_face_t *last_face = NULL; - - /* Remove face from linked list */ - for (tmp_face = font_face->unscaled->faces; - tmp_face; - tmp_face = tmp_face->next) - { - if (tmp_face == font_face) { - if (last_face) - last_face->next = tmp_face->next; - else - font_face->unscaled->faces = tmp_face->next; - } - - last_face = tmp_face; - } - - _cairo_unscaled_font_destroy (&font_face->unscaled->base); - font_face->unscaled = NULL; - } - -#if CAIRO_HAS_FC_FONT - if (font_face->pattern) { - FcPatternDestroy (font_face->pattern); - cairo_font_face_destroy (font_face->resolved_font_face); - } -#endif - - return TRUE; -} - -static cairo_font_face_t * -_cairo_ft_font_face_get_implementation (void *abstract_face, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options) -{ - cairo_ft_font_face_t *font_face = abstract_face; - - /* The handling of font options is different depending on how the - * font face was created. When the user creates a font face with - * cairo_ft_font_face_create_for_ft_face(), then the load flags - * passed in augment the load flags for the options. But for - * cairo_ft_font_face_create_for_pattern(), the load flags are - * derived from a pattern where the user has called - * cairo_ft_font_options_substitute(), so *just* use those load - * flags and ignore the options. - */ - -#if CAIRO_HAS_FC_FONT - /* If we have an unresolved pattern, resolve it and create - * unscaled font. Otherwise, use the ones stored in font_face. - */ - if (font_face->pattern) { - cairo_font_face_t *resolved; - - /* Cache the resolved font whilst the FcConfig remains consistent. */ - resolved = font_face->resolved_font_face; - if (resolved != NULL) { - if (! FcInitBringUptoDate ()) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_font_face_t *) &_cairo_font_face_nil; - } - - if (font_face->resolved_config == FcConfigGetCurrent ()) - return cairo_font_face_reference (resolved); - - cairo_font_face_destroy (resolved); - font_face->resolved_font_face = NULL; - } - - resolved = _cairo_ft_resolve_pattern (font_face->pattern, - font_matrix, - ctm, - options); - if (unlikely (resolved->status)) - return resolved; - - font_face->resolved_font_face = cairo_font_face_reference (resolved); - font_face->resolved_config = FcConfigGetCurrent (); - - return resolved; - } -#endif - - return abstract_face; -} - -const cairo_font_face_backend_t _cairo_ft_font_face_backend = { - CAIRO_FONT_TYPE_FT, -#if CAIRO_HAS_FC_FONT - _cairo_ft_font_face_create_for_toy, -#else - NULL, -#endif - _cairo_ft_font_face_destroy, - _cairo_ft_font_face_scaled_font_create, - _cairo_ft_font_face_get_implementation -}; - -#if CAIRO_HAS_FC_FONT -static cairo_font_face_t * -_cairo_ft_font_face_create_for_pattern (FcPattern *pattern) -{ - cairo_ft_font_face_t *font_face; - - font_face = malloc (sizeof (cairo_ft_font_face_t)); - if (unlikely (font_face == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_font_face_t *) &_cairo_font_face_nil; - } - - font_face->unscaled = NULL; - font_face->next = NULL; - - font_face->pattern = FcPatternDuplicate (pattern); - if (unlikely (font_face->pattern == NULL)) { - free (font_face); - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_font_face_t *) &_cairo_font_face_nil; - } - - font_face->resolved_font_face = NULL; - font_face->resolved_config = NULL; - - _cairo_font_face_init (&font_face->base, &_cairo_ft_font_face_backend); - - return &font_face->base; -} -#endif - -static cairo_font_face_t * -_cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled, - cairo_ft_options_t *ft_options) -{ - cairo_ft_font_face_t *font_face, **prev_font_face; - - /* Looked for an existing matching font face */ - for (font_face = unscaled->faces, prev_font_face = &unscaled->faces; - font_face; - prev_font_face = &font_face->next, font_face = font_face->next) - { - if (font_face->ft_options.load_flags == ft_options->load_flags && - font_face->ft_options.synth_flags == ft_options->synth_flags && - cairo_font_options_equal (&font_face->ft_options.base, &ft_options->base)) - { - if (font_face->base.status) { - /* The font_face has been left in an error state, abandon it. */ - *prev_font_face = font_face->next; - break; - } - - if (font_face->unscaled == NULL) { - /* Resurrect this "zombie" font_face (from - * _cairo_ft_font_face_destroy), switching its unscaled_font - * from owner to ownee. */ - font_face->unscaled = unscaled; - _cairo_unscaled_font_reference (&unscaled->base); - return &font_face->base; - } else - return cairo_font_face_reference (&font_face->base); - } - } - - /* No match found, create a new one */ - font_face = malloc (sizeof (cairo_ft_font_face_t)); - if (unlikely (!font_face)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_font_face_t *)&_cairo_font_face_nil; - } - - font_face->unscaled = unscaled; - _cairo_unscaled_font_reference (&unscaled->base); - - font_face->ft_options = *ft_options; - - if (unscaled->faces && unscaled->faces->unscaled == NULL) { - /* This "zombie" font_face (from _cairo_ft_font_face_destroy) - * is no longer needed. */ - assert (unscaled->from_face && unscaled->faces->next == NULL); - cairo_font_face_destroy (&unscaled->faces->base); - unscaled->faces = NULL; - } - - font_face->next = unscaled->faces; - unscaled->faces = font_face; - -#if CAIRO_HAS_FC_FONT - font_face->pattern = NULL; -#endif - - _cairo_font_face_init (&font_face->base, &_cairo_ft_font_face_backend); - - return &font_face->base; -} - -/* implement the platform-specific interface */ - -#if CAIRO_HAS_FC_FONT -static cairo_status_t -_cairo_ft_font_options_substitute (const cairo_font_options_t *options, - FcPattern *pattern) -{ - FcValue v; - - if (options->antialias != CAIRO_ANTIALIAS_DEFAULT) - { - if (FcPatternGet (pattern, FC_ANTIALIAS, 0, &v) == FcResultNoMatch) - { - if (! FcPatternAddBool (pattern, - FC_ANTIALIAS, - options->antialias != CAIRO_ANTIALIAS_NONE)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - if (options->antialias != CAIRO_ANTIALIAS_SUBPIXEL) { - FcPatternDel (pattern, FC_RGBA); - if (! FcPatternAddInteger (pattern, FC_RGBA, FC_RGBA_NONE)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - } - } - - if (options->antialias != CAIRO_ANTIALIAS_DEFAULT) - { - if (FcPatternGet (pattern, FC_RGBA, 0, &v) == FcResultNoMatch) - { - int rgba; - - if (options->antialias == CAIRO_ANTIALIAS_SUBPIXEL) { - switch (options->subpixel_order) { - case CAIRO_SUBPIXEL_ORDER_DEFAULT: - case CAIRO_SUBPIXEL_ORDER_RGB: - default: - rgba = FC_RGBA_RGB; - break; - case CAIRO_SUBPIXEL_ORDER_BGR: - rgba = FC_RGBA_BGR; - break; - case CAIRO_SUBPIXEL_ORDER_VRGB: - rgba = FC_RGBA_VRGB; - break; - case CAIRO_SUBPIXEL_ORDER_VBGR: - rgba = FC_RGBA_VBGR; - break; - } - } else { - rgba = FC_RGBA_NONE; - } - - if (! FcPatternAddInteger (pattern, FC_RGBA, rgba)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - } - - if (options->lcd_filter != CAIRO_LCD_FILTER_DEFAULT) - { - if (FcPatternGet (pattern, FC_LCD_FILTER, 0, &v) == FcResultNoMatch) - { - int lcd_filter; - - switch (options->lcd_filter) { - case CAIRO_LCD_FILTER_NONE: - lcd_filter = FT_LCD_FILTER_NONE; - break; - case CAIRO_LCD_FILTER_DEFAULT: - case CAIRO_LCD_FILTER_INTRA_PIXEL: - lcd_filter = FT_LCD_FILTER_LEGACY; - break; - case CAIRO_LCD_FILTER_FIR3: - lcd_filter = FT_LCD_FILTER_LIGHT; - break; - default: - case CAIRO_LCD_FILTER_FIR5: - lcd_filter = FT_LCD_FILTER_DEFAULT; - break; - } - - if (! FcPatternAddInteger (pattern, FC_LCD_FILTER, lcd_filter)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - } - - if (options->hint_style != CAIRO_HINT_STYLE_DEFAULT) - { - if (FcPatternGet (pattern, FC_HINTING, 0, &v) == FcResultNoMatch) - { - if (! FcPatternAddBool (pattern, - FC_HINTING, - options->hint_style != CAIRO_HINT_STYLE_NONE)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - -#ifdef FC_HINT_STYLE - if (FcPatternGet (pattern, FC_HINT_STYLE, 0, &v) == FcResultNoMatch) - { - int hint_style; - - switch (options->hint_style) { - case CAIRO_HINT_STYLE_NONE: - hint_style = FC_HINT_NONE; - break; - case CAIRO_HINT_STYLE_SLIGHT: - hint_style = FC_HINT_SLIGHT; - break; - case CAIRO_HINT_STYLE_MEDIUM: - hint_style = FC_HINT_MEDIUM; - break; - case CAIRO_HINT_STYLE_FULL: - case CAIRO_HINT_STYLE_DEFAULT: - default: - hint_style = FC_HINT_FULL; - break; - } - - if (! FcPatternAddInteger (pattern, FC_HINT_STYLE, hint_style)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } -#endif - } - - return CAIRO_STATUS_SUCCESS; -} - -/** - * cairo_ft_font_options_substitute: - * @options: a #cairo_font_options_t object - * @pattern: an existing #FcPattern - * - * Add options to a #FcPattern based on a #cairo_font_options_t font - * options object. Options that are already in the pattern, are not overridden, - * so you should call this function after calling FcConfigSubstitute() (the - * user's settings should override options based on the surface type), but - * before calling FcDefaultSubstitute(). - * - * Since: 1.0 - **/ -void -cairo_ft_font_options_substitute (const cairo_font_options_t *options, - FcPattern *pattern) -{ - if (cairo_font_options_status ((cairo_font_options_t *) options)) - return; - - _cairo_ft_font_options_substitute (options, pattern); -} - -static cairo_font_face_t * -_cairo_ft_resolve_pattern (FcPattern *pattern, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *font_options) -{ - cairo_status_t status; - - cairo_matrix_t scale; - FcPattern *resolved; - cairo_ft_font_transform_t sf; - FcResult result; - cairo_ft_unscaled_font_t *unscaled; - cairo_ft_options_t ft_options; - cairo_font_face_t *font_face; - - scale = *ctm; - scale.x0 = scale.y0 = 0; - cairo_matrix_multiply (&scale, - font_matrix, - &scale); - - status = _compute_transform (&sf, &scale, NULL); - if (unlikely (status)) - return (cairo_font_face_t *)&_cairo_font_face_nil; - - pattern = FcPatternDuplicate (pattern); - if (pattern == NULL) - return (cairo_font_face_t *)&_cairo_font_face_nil; - - if (! FcPatternAddDouble (pattern, FC_PIXEL_SIZE, sf.y_scale)) { - font_face = (cairo_font_face_t *)&_cairo_font_face_nil; - goto FREE_PATTERN; - } - - if (! FcConfigSubstitute (NULL, pattern, FcMatchPattern)) { - font_face = (cairo_font_face_t *)&_cairo_font_face_nil; - goto FREE_PATTERN; - } - - status = _cairo_ft_font_options_substitute (font_options, pattern); - if (status) { - font_face = (cairo_font_face_t *)&_cairo_font_face_nil; - goto FREE_PATTERN; - } - - FcDefaultSubstitute (pattern); - - status = _cairo_ft_unscaled_font_create_for_pattern (pattern, &unscaled); - if (unlikely (status)) { - font_face = (cairo_font_face_t *)&_cairo_font_face_nil; - goto FREE_PATTERN; - } - - if (unscaled == NULL) { - resolved = FcFontMatch (NULL, pattern, &result); - if (!resolved) { - /* We failed to find any font. Substitute twin so that the user can - * see something (and hopefully recognise that the font is missing) - * and not just receive a NO_MEMORY error during rendering. - */ - font_face = _cairo_font_face_twin_create_fallback (); - goto FREE_PATTERN; - } - - status = _cairo_ft_unscaled_font_create_for_pattern (resolved, &unscaled); - if (unlikely (status || unscaled == NULL)) { - font_face = (cairo_font_face_t *)&_cairo_font_face_nil; - goto FREE_RESOLVED; - } - } else - resolved = pattern; - - _get_pattern_ft_options (resolved, &ft_options); - font_face = _cairo_ft_font_face_create (unscaled, &ft_options); - _cairo_unscaled_font_destroy (&unscaled->base); - -FREE_RESOLVED: - if (resolved != pattern) - FcPatternDestroy (resolved); - -FREE_PATTERN: - FcPatternDestroy (pattern); - - return font_face; -} - -/** - * cairo_ft_font_face_create_for_pattern: - * @pattern: A fontconfig pattern. Cairo makes a copy of the pattern - * if it needs to. You are free to modify or free @pattern after this call. - * - * Creates a new font face for the FreeType font backend based on a - * fontconfig pattern. This font can then be used with - * cairo_set_font_face() or cairo_scaled_font_create(). The - * #cairo_scaled_font_t returned from cairo_scaled_font_create() is - * also for the FreeType backend and can be used with functions such - * as cairo_ft_scaled_font_lock_face(). - * - * Font rendering options are represented both here and when you - * call cairo_scaled_font_create(). Font options that have a representation - * in a #FcPattern must be passed in here; to modify #FcPattern - * appropriately to reflect the options in a #cairo_font_options_t, call - * cairo_ft_font_options_substitute(). - * - * The pattern's FC_FT_FACE element is inspected first and if that is set, - * that will be the FreeType font face associated with the returned cairo - * font face. Otherwise the FC_FILE element is checked. If it's set, - * that and the value of the FC_INDEX element (defaults to zero) of @pattern - * are used to load a font face from file. - * - * If both steps from the previous paragraph fails, @pattern will be passed - * to FcConfigSubstitute, FcDefaultSubstitute, and finally FcFontMatch, - * and the resulting font pattern is used. - * - * If the FC_FT_FACE element of @pattern is set, the user is responsible - * for making sure that the referenced FT_Face remains valid for the life - * time of the returned #cairo_font_face_t. See - * cairo_ft_font_face_create_for_ft_face() for an example of how to couple - * the life time of the FT_Face to that of the cairo font-face. - * - * Return value: a newly created #cairo_font_face_t. Free with - * cairo_font_face_destroy() when you are done using it. - * - * Since: 1.0 - **/ -cairo_font_face_t * -cairo_ft_font_face_create_for_pattern (FcPattern *pattern) -{ - cairo_ft_unscaled_font_t *unscaled; - cairo_font_face_t *font_face; - cairo_ft_options_t ft_options; - cairo_status_t status; - - status = _cairo_ft_unscaled_font_create_for_pattern (pattern, &unscaled); - if (unlikely (status)) { - if (status == CAIRO_STATUS_FILE_NOT_FOUND) - return (cairo_font_face_t *) &_cairo_font_face_nil_file_not_found; - else - return (cairo_font_face_t *) &_cairo_font_face_nil; - } - if (unlikely (unscaled == NULL)) { - /* Store the pattern. We will resolve it and create unscaled - * font when creating scaled fonts */ - return _cairo_ft_font_face_create_for_pattern (pattern); - } - - _get_pattern_ft_options (pattern, &ft_options); - font_face = _cairo_ft_font_face_create (unscaled, &ft_options); - _cairo_unscaled_font_destroy (&unscaled->base); - - return font_face; -} -#endif - -/** - * cairo_ft_font_face_create_for_ft_face: - * @face: A FreeType face object, already opened. This must - * be kept around until the face's ref_count drops to - * zero and it is freed. Since the face may be referenced - * internally to Cairo, the best way to determine when it - * is safe to free the face is to pass a - * #cairo_destroy_func_t to cairo_font_face_set_user_data() - * @load_flags: flags to pass to FT_Load_Glyph when loading - * glyphs from the font. These flags are OR'ed together with - * the flags derived from the #cairo_font_options_t passed - * to cairo_scaled_font_create(), so only a few values such - * as %FT_LOAD_VERTICAL_LAYOUT, and %FT_LOAD_FORCE_AUTOHINT - * are useful. You should not pass any of the flags affecting - * the load target, such as %FT_LOAD_TARGET_LIGHT. - * - * Creates a new font face for the FreeType font backend from a - * pre-opened FreeType face. This font can then be used with - * cairo_set_font_face() or cairo_scaled_font_create(). The - * #cairo_scaled_font_t returned from cairo_scaled_font_create() is - * also for the FreeType backend and can be used with functions such - * as cairo_ft_scaled_font_lock_face(). Note that Cairo may keep a reference - * to the FT_Face alive in a font-cache and the exact lifetime of the reference - * depends highly upon the exact usage pattern and is subject to external - * factors. You must not call FT_Done_Face() before the last reference to the - * #cairo_font_face_t has been dropped. - * - * As an example, below is how one might correctly couple the lifetime of - * the FreeType face object to the #cairo_font_face_t. - * - * <informalexample><programlisting> - * static const cairo_user_data_key_t key; - * - * font_face = cairo_ft_font_face_create_for_ft_face (ft_face, 0); - * status = cairo_font_face_set_user_data (font_face, &key, - * ft_face, (cairo_destroy_func_t) FT_Done_Face); - * if (status) { - * cairo_font_face_destroy (font_face); - * FT_Done_Face (ft_face); - * return ERROR; - * } - * </programlisting></informalexample> - * - * Return value: a newly created #cairo_font_face_t. Free with - * cairo_font_face_destroy() when you are done using it. - * - * Since: 1.0 - **/ -cairo_font_face_t * -cairo_ft_font_face_create_for_ft_face (FT_Face face, - int load_flags) -{ - cairo_ft_unscaled_font_t *unscaled; - cairo_font_face_t *font_face; - cairo_ft_options_t ft_options; - cairo_status_t status; - - status = _cairo_ft_unscaled_font_create_from_face (face, &unscaled); - if (unlikely (status)) - return (cairo_font_face_t *)&_cairo_font_face_nil; - - ft_options.load_flags = load_flags; - ft_options.synth_flags = 0; - _cairo_font_options_init_default (&ft_options.base); - - font_face = _cairo_ft_font_face_create (unscaled, &ft_options); - _cairo_unscaled_font_destroy (&unscaled->base); - - return font_face; -} - -/** - * cairo_ft_font_face_set_synthesize: - * @font_face: The #cairo_ft_font_face_t object to modify - * @synth_flags: the set of synthesis options to enable - * - * FreeType provides the ability to synthesize different glyphs from a base - * font, which is useful if you lack those glyphs from a true bold or oblique - * font. See also #cairo_ft_synthesize_t. - * - * Since: 1.12 - **/ -void -cairo_ft_font_face_set_synthesize (cairo_font_face_t *font_face, - unsigned int synth_flags) -{ - cairo_ft_font_face_t *ft; - - if (font_face->backend->type != CAIRO_FONT_TYPE_FT) - return; - - ft = (cairo_ft_font_face_t *) font_face; - ft->ft_options.synth_flags |= synth_flags; -} - -/** - * cairo_ft_font_face_unset_synthesize: - * @font_face: The #cairo_ft_font_face_t object to modify - * @synth_flags: the set of synthesis options to disable - * - * See cairo_ft_font_face_set_synthesize(). - * - * Since: 1.12 - **/ -void -cairo_ft_font_face_unset_synthesize (cairo_font_face_t *font_face, - unsigned int synth_flags) -{ - cairo_ft_font_face_t *ft; - - if (font_face->backend->type != CAIRO_FONT_TYPE_FT) - return; - - ft = (cairo_ft_font_face_t *) font_face; - ft->ft_options.synth_flags &= ~synth_flags; -} - -/** - * cairo_ft_font_face_get_synthesize: - * @font_face: The #cairo_ft_font_face_t object to query - * - * See #cairo_ft_synthesize_t. - * - * Returns: the current set of synthesis options. - * - * Since: 1.12 - **/ -unsigned int -cairo_ft_font_face_get_synthesize (cairo_font_face_t *font_face) -{ - cairo_ft_font_face_t *ft; - - if (font_face->backend->type != CAIRO_FONT_TYPE_FT) - return 0; - - ft = (cairo_ft_font_face_t *) font_face; - return ft->ft_options.synth_flags; -} - -/** - * cairo_ft_scaled_font_lock_face: - * @scaled_font: A #cairo_scaled_font_t from the FreeType font backend. Such an - * object can be created by calling cairo_scaled_font_create() on a - * FreeType backend font face (see cairo_ft_font_face_create_for_pattern(), - * cairo_ft_font_face_create_for_ft_face()). - * - * cairo_ft_scaled_font_lock_face() gets the #FT_Face object from a FreeType - * backend font and scales it appropriately for the font. You must - * release the face with cairo_ft_scaled_font_unlock_face() - * when you are done using it. Since the #FT_Face object can be - * shared between multiple #cairo_scaled_font_t objects, you must not - * lock any other font objects until you unlock this one. A count is - * kept of the number of times cairo_ft_scaled_font_lock_face() is - * called. cairo_ft_scaled_font_unlock_face() must be called the same number - * of times. - * - * You must be careful when using this function in a library or in a - * threaded application, because freetype's design makes it unsafe to - * call freetype functions simultaneously from multiple threads, (even - * if using distinct FT_Face objects). Because of this, application - * code that acquires an FT_Face object with this call must add its - * own locking to protect any use of that object, (and which also must - * protect any other calls into cairo as almost any cairo function - * might result in a call into the freetype library). - * - * Return value: The #FT_Face object for @font, scaled appropriately, - * or %NULL if @scaled_font is in an error state (see - * cairo_scaled_font_status()) or there is insufficient memory. - * - * Since: 1.0 - **/ -FT_Face -cairo_ft_scaled_font_lock_face (cairo_scaled_font_t *abstract_font) -{ - cairo_ft_scaled_font_t *scaled_font = (cairo_ft_scaled_font_t *) abstract_font; - FT_Face face; - cairo_status_t status; - - if (! _cairo_scaled_font_is_ft (abstract_font)) { - _cairo_error_throw (CAIRO_STATUS_FONT_TYPE_MISMATCH); - return NULL; - } - - if (scaled_font->base.status) - return NULL; - - face = _cairo_ft_unscaled_font_lock_face (scaled_font->unscaled); - if (unlikely (face == NULL)) { - status = _cairo_scaled_font_set_error (&scaled_font->base, CAIRO_STATUS_NO_MEMORY); - return NULL; - } - - status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled, - &scaled_font->base.scale); - if (unlikely (status)) { - _cairo_ft_unscaled_font_unlock_face (scaled_font->unscaled); - status = _cairo_scaled_font_set_error (&scaled_font->base, status); - return NULL; - } - - /* Note: We deliberately release the unscaled font's mutex here, - * so that we are not holding a lock across two separate calls to - * cairo function, (which would give the application some - * opportunity for creating deadlock. This is obviously unsafe, - * but as documented, the user must add manual locking when using - * this function. */ - CAIRO_MUTEX_UNLOCK (scaled_font->unscaled->mutex); - - return face; -} - -/** - * cairo_ft_scaled_font_unlock_face: - * @scaled_font: A #cairo_scaled_font_t from the FreeType font backend. Such an - * object can be created by calling cairo_scaled_font_create() on a - * FreeType backend font face (see cairo_ft_font_face_create_for_pattern(), - * cairo_ft_font_face_create_for_ft_face()). - * - * Releases a face obtained with cairo_ft_scaled_font_lock_face(). - * - * Since: 1.0 - **/ -void -cairo_ft_scaled_font_unlock_face (cairo_scaled_font_t *abstract_font) -{ - cairo_ft_scaled_font_t *scaled_font = (cairo_ft_scaled_font_t *) abstract_font; - - if (! _cairo_scaled_font_is_ft (abstract_font)) { - _cairo_error_throw (CAIRO_STATUS_FONT_TYPE_MISMATCH); - return; - } - - if (scaled_font->base.status) - return; - - /* Note: We released the unscaled font's mutex at the end of - * cairo_ft_scaled_font_lock_face, so we have to acquire it again - * as _cairo_ft_unscaled_font_unlock_face expects it to be held - * when we call into it. */ - CAIRO_MUTEX_LOCK (scaled_font->unscaled->mutex); - - _cairo_ft_unscaled_font_unlock_face (scaled_font->unscaled); -} - -static cairo_bool_t -_cairo_ft_scaled_font_is_vertical (cairo_scaled_font_t *scaled_font) -{ - cairo_ft_scaled_font_t *ft_scaled_font; - - if (!_cairo_scaled_font_is_ft (scaled_font)) - return FALSE; - - ft_scaled_font = (cairo_ft_scaled_font_t *) scaled_font; - if (ft_scaled_font->ft_options.load_flags & FT_LOAD_VERTICAL_LAYOUT) - return TRUE; - return FALSE; -} - -unsigned int -_cairo_ft_scaled_font_get_load_flags (cairo_scaled_font_t *scaled_font) -{ - cairo_ft_scaled_font_t *ft_scaled_font; - - if (! _cairo_scaled_font_is_ft (scaled_font)) - return 0; - - ft_scaled_font = (cairo_ft_scaled_font_t *) scaled_font; - return ft_scaled_font->ft_options.load_flags; -} - -void -_cairo_ft_font_reset_static_data (void) -{ - _cairo_ft_unscaled_font_map_destroy (); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-ft-private.h b/source/libs/cairo/cairo-src/src/cairo-ft-private.h deleted file mode 100644 index 0dc8114726f56dd5e2c01ad8e3b4d1f58d276553..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-ft-private.h +++ /dev/null @@ -1,61 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Graydon Hoare <graydon@redhat.com> - * Owen Taylor <otaylor@redhat.com> - */ - -#ifndef CAIRO_FT_PRIVATE_H -#define CAIRO_FT_PRIVATE_H - -#include "cairoint.h" -#include "cairo-ft.h" - -#if CAIRO_HAS_FT_FONT - -CAIRO_BEGIN_DECLS - -typedef struct _cairo_ft_unscaled_font cairo_ft_unscaled_font_t; - -cairo_private cairo_bool_t -_cairo_scaled_font_is_ft (cairo_scaled_font_t *scaled_font); - -/* These functions are needed by the PDF backend, which needs to keep track of the - * the different fonts-on-disk used by a document, so it can embed them - */ -cairo_private unsigned int -_cairo_ft_scaled_font_get_load_flags (cairo_scaled_font_t *scaled_font); - -CAIRO_END_DECLS - -#endif /* CAIRO_HAS_FT_FONT */ -#endif /* CAIRO_FT_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-ft.h b/source/libs/cairo/cairo-src/src/cairo-ft.h deleted file mode 100644 index 29c43c9655bc6eec50580b463468d7e3198f2005..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-ft.h +++ /dev/null @@ -1,118 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Graydon Hoare <graydon@redhat.com> - * Owen Taylor <otaylor@redhat.com> - */ - -#ifndef CAIRO_FT_H -#define CAIRO_FT_H - -#include "cairo.h" - -#if CAIRO_HAS_FT_FONT - -/* Fontconfig/Freetype platform-specific font interface */ - -#include <ft2build.h> -#include FT_FREETYPE_H - -#if CAIRO_HAS_FC_FONT -#include <fontconfig/fontconfig.h> -#endif - -CAIRO_BEGIN_DECLS - -cairo_public cairo_font_face_t * -cairo_ft_font_face_create_for_ft_face (FT_Face face, - int load_flags); - -/** - * cairo_ft_synthesize_t: - * @CAIRO_FT_SYNTHESIZE_BOLD: Embolden the glyphs (redraw with a pixel offset) - * @CAIRO_FT_SYNTHESIZE_OBLIQUE: Slant the glyph outline by 12 degrees to the - * right. - * - * A set of synthesis options to control how FreeType renders the glyphs - * for a particular font face. - * - * Individual synthesis features of a #cairo_ft_font_face_t can be set - * using cairo_ft_font_face_set_synthesize(), or disabled using - * cairo_ft_font_face_unset_synthesize(). The currently enabled set of - * synthesis options can be queried with cairo_ft_font_face_get_synthesize(). - * - * Note: that when synthesizing glyphs, the font metrics returned will only - * be estimates. - * - * Since: 1.12 - **/ -typedef enum { - CAIRO_FT_SYNTHESIZE_BOLD = 1 << 0, - CAIRO_FT_SYNTHESIZE_OBLIQUE = 1 << 1 -} cairo_ft_synthesize_t; - -cairo_public void -cairo_ft_font_face_set_synthesize (cairo_font_face_t *font_face, - unsigned int synth_flags); - -cairo_public void -cairo_ft_font_face_unset_synthesize (cairo_font_face_t *font_face, - unsigned int synth_flags); - -cairo_public unsigned int -cairo_ft_font_face_get_synthesize (cairo_font_face_t *font_face); - - -cairo_public FT_Face -cairo_ft_scaled_font_lock_face (cairo_scaled_font_t *scaled_font); - -cairo_public void -cairo_ft_scaled_font_unlock_face (cairo_scaled_font_t *scaled_font); - -#if CAIRO_HAS_FC_FONT - -cairo_public cairo_font_face_t * -cairo_ft_font_face_create_for_pattern (FcPattern *pattern); - -cairo_public void -cairo_ft_font_options_substitute (const cairo_font_options_t *options, - FcPattern *pattern); - -#endif - -CAIRO_END_DECLS - -#else /* CAIRO_HAS_FT_FONT */ -# error Cairo was not compiled with support for the freetype font backend -#endif /* CAIRO_HAS_FT_FONT */ - -#endif /* CAIRO_FT_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-gl-composite.c b/source/libs/cairo/cairo-src/src/cairo-gl-composite.c deleted file mode 100644 index 5b1411472d09405d0bb86d94ea5f6009e0a75e3c..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-gl-composite.c +++ /dev/null @@ -1,1265 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Eric Anholt - * Copyright © 2009 Chris Wilson - * Copyright © 2005,2010 Red Hat, Inc - * Copyright © 2011 Linaro Limited - * Copyright © 2011 Samsung Electronics - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Benjamin Otte <otte@gnome.org> - * Carl Worth <cworth@cworth.org> - * Chris Wilson <chris@chris-wilson.co.uk> - * Eric Anholt <eric@anholt.net> - * Alexandros Frantzis <alexandros.frantzis@linaro.org> - * Henry Song <hsong@sisa.samsung.com> - * Martin Robinson <mrobinson@igalia.com> - */ - -#include "cairoint.h" - -#include "cairo-gl-private.h" - -#include "cairo-composite-rectangles-private.h" -#include "cairo-clip-private.h" -#include "cairo-error-private.h" -#include "cairo-image-surface-private.h" - -cairo_int_status_t -_cairo_gl_composite_set_source (cairo_gl_composite_t *setup, - const cairo_pattern_t *pattern, - const cairo_rectangle_int_t *sample, - const cairo_rectangle_int_t *extents, - cairo_bool_t use_texgen) -{ - _cairo_gl_operand_destroy (&setup->src); - return _cairo_gl_operand_init (&setup->src, pattern, setup->dst, - sample, extents, use_texgen); -} - -void -_cairo_gl_composite_set_source_operand (cairo_gl_composite_t *setup, - const cairo_gl_operand_t *source) -{ - _cairo_gl_operand_destroy (&setup->src); - _cairo_gl_operand_copy (&setup->src, source); -} - -void -_cairo_gl_composite_set_solid_source (cairo_gl_composite_t *setup, - const cairo_color_t *color) -{ - _cairo_gl_operand_destroy (&setup->src); - _cairo_gl_solid_operand_init (&setup->src, color); -} - -cairo_int_status_t -_cairo_gl_composite_set_mask (cairo_gl_composite_t *setup, - const cairo_pattern_t *pattern, - const cairo_rectangle_int_t *sample, - const cairo_rectangle_int_t *extents, - cairo_bool_t use_texgen) -{ - _cairo_gl_operand_destroy (&setup->mask); - if (pattern == NULL) - return CAIRO_STATUS_SUCCESS; - - return _cairo_gl_operand_init (&setup->mask, pattern, setup->dst, - sample, extents, use_texgen); -} - -void -_cairo_gl_composite_set_mask_operand (cairo_gl_composite_t *setup, - const cairo_gl_operand_t *mask) -{ - _cairo_gl_operand_destroy (&setup->mask); - if (mask) - _cairo_gl_operand_copy (&setup->mask, mask); -} - -void -_cairo_gl_composite_set_spans (cairo_gl_composite_t *setup) -{ - setup->spans = TRUE; -} - -void -_cairo_gl_composite_set_multisample (cairo_gl_composite_t *setup) -{ - setup->multisample = TRUE; -} - -void -_cairo_gl_composite_set_clip_region (cairo_gl_composite_t *setup, - cairo_region_t *clip_region) -{ - setup->clip_region = clip_region; -} - -void -_cairo_gl_composite_set_clip (cairo_gl_composite_t *setup, - cairo_clip_t *clip) -{ - setup->clip = clip; -} - -static void -_cairo_gl_composite_bind_to_shader (cairo_gl_context_t *ctx, - cairo_gl_composite_t *setup) -{ - _cairo_gl_shader_bind_matrix4f(ctx, ctx->current_shader->mvp_location, - ctx->modelviewprojection_matrix); - _cairo_gl_operand_bind_to_shader (ctx, &setup->src, CAIRO_GL_TEX_SOURCE); - _cairo_gl_operand_bind_to_shader (ctx, &setup->mask, CAIRO_GL_TEX_MASK); -} - -static void -_cairo_gl_texture_set_filter (cairo_gl_context_t *ctx, - GLuint target, - cairo_filter_t filter) -{ - switch (filter) { - case CAIRO_FILTER_FAST: - case CAIRO_FILTER_NEAREST: - glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - break; - case CAIRO_FILTER_GOOD: - case CAIRO_FILTER_BEST: - case CAIRO_FILTER_BILINEAR: - glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - break; - default: - case CAIRO_FILTER_GAUSSIAN: - ASSERT_NOT_REACHED; - } -} - -static void -_cairo_gl_texture_set_extend (cairo_gl_context_t *ctx, - GLuint target, - cairo_extend_t extend) -{ - GLint wrap_mode; - assert (! _cairo_gl_device_requires_power_of_two_textures (&ctx->base) || - (extend != CAIRO_EXTEND_REPEAT && extend != CAIRO_EXTEND_REFLECT)); - - switch (extend) { - case CAIRO_EXTEND_NONE: - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES) - wrap_mode = GL_CLAMP_TO_EDGE; - else - wrap_mode = GL_CLAMP_TO_BORDER; - break; - case CAIRO_EXTEND_PAD: - wrap_mode = GL_CLAMP_TO_EDGE; - break; - case CAIRO_EXTEND_REPEAT: - if (ctx->has_npot_repeat) - wrap_mode = GL_REPEAT; - else - wrap_mode = GL_CLAMP_TO_EDGE; - break; - case CAIRO_EXTEND_REFLECT: - if (ctx->has_npot_repeat) - wrap_mode = GL_MIRRORED_REPEAT; - else - wrap_mode = GL_CLAMP_TO_EDGE; - break; - default: - wrap_mode = 0; - } - - if (likely (wrap_mode)) { - glTexParameteri (target, GL_TEXTURE_WRAP_S, wrap_mode); - glTexParameteri (target, GL_TEXTURE_WRAP_T, wrap_mode); - } -} - - -static void -_cairo_gl_context_setup_operand (cairo_gl_context_t *ctx, - cairo_gl_tex_t tex_unit, - cairo_gl_operand_t *operand, - unsigned int vertex_offset, - cairo_bool_t vertex_size_changed) -{ - cairo_gl_dispatch_t *dispatch = &ctx->dispatch; - cairo_bool_t needs_setup; - - /* XXX: we need to do setup when switching from shaders - * to no shaders (or back) */ - needs_setup = vertex_size_changed; - needs_setup |= _cairo_gl_operand_needs_setup (&ctx->operands[tex_unit], - operand, - vertex_offset); - - if (needs_setup) { - _cairo_gl_composite_flush (ctx); - _cairo_gl_context_destroy_operand (ctx, tex_unit); - } - - memcpy (&ctx->operands[tex_unit], operand, sizeof (cairo_gl_operand_t)); - ctx->operands[tex_unit].vertex_offset = vertex_offset; - - if (! needs_setup) - return; - - switch (operand->type) { - default: - case CAIRO_GL_OPERAND_COUNT: - ASSERT_NOT_REACHED; - case CAIRO_GL_OPERAND_NONE: - break; - /* fall through */ - case CAIRO_GL_OPERAND_CONSTANT: - break; - case CAIRO_GL_OPERAND_TEXTURE: - glActiveTexture (GL_TEXTURE0 + tex_unit); - glBindTexture (ctx->tex_target, operand->texture.tex); - _cairo_gl_texture_set_extend (ctx, ctx->tex_target, - operand->texture.attributes.extend); - _cairo_gl_texture_set_filter (ctx, ctx->tex_target, - operand->texture.attributes.filter); - - if (! operand->texture.texgen) { - dispatch->VertexAttribPointer (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit, 2, - GL_FLOAT, GL_FALSE, ctx->vertex_size, - ctx->vb + vertex_offset); - dispatch->EnableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit); - } - break; - case CAIRO_GL_OPERAND_LINEAR_GRADIENT: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT: - glActiveTexture (GL_TEXTURE0 + tex_unit); - glBindTexture (ctx->tex_target, operand->gradient.gradient->tex); - _cairo_gl_texture_set_extend (ctx, ctx->tex_target, operand->gradient.extend); - _cairo_gl_texture_set_filter (ctx, ctx->tex_target, CAIRO_FILTER_BILINEAR); - - if (! operand->gradient.texgen) { - dispatch->VertexAttribPointer (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit, 2, - GL_FLOAT, GL_FALSE, ctx->vertex_size, - ctx->vb + vertex_offset); - dispatch->EnableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit); - } - break; - } -} - -static void -_cairo_gl_context_setup_spans (cairo_gl_context_t *ctx, - cairo_bool_t spans_enabled, - unsigned int vertex_size, - unsigned int vertex_offset) -{ - cairo_gl_dispatch_t *dispatch = &ctx->dispatch; - - if (! spans_enabled) { - dispatch->DisableVertexAttribArray (CAIRO_GL_COLOR_ATTRIB_INDEX); - ctx->spans = FALSE; - return; - } - - dispatch->VertexAttribPointer (CAIRO_GL_COLOR_ATTRIB_INDEX, 4, - GL_UNSIGNED_BYTE, GL_TRUE, vertex_size, - ctx->vb + vertex_offset); - dispatch->EnableVertexAttribArray (CAIRO_GL_COLOR_ATTRIB_INDEX); - ctx->spans = TRUE; -} - -void -_cairo_gl_context_destroy_operand (cairo_gl_context_t *ctx, - cairo_gl_tex_t tex_unit) -{ - cairo_gl_dispatch_t *dispatch = &ctx->dispatch; - - if (!_cairo_gl_context_is_flushed (ctx)) - _cairo_gl_composite_flush (ctx); - - switch (ctx->operands[tex_unit].type) { - default: - case CAIRO_GL_OPERAND_COUNT: - ASSERT_NOT_REACHED; - case CAIRO_GL_OPERAND_NONE: - break; - /* fall through */ - case CAIRO_GL_OPERAND_CONSTANT: - break; - case CAIRO_GL_OPERAND_TEXTURE: - dispatch->DisableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit); - break; - case CAIRO_GL_OPERAND_LINEAR_GRADIENT: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT: - dispatch->DisableVertexAttribArray (CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + tex_unit); - break; - } - - memset (&ctx->operands[tex_unit], 0, sizeof (cairo_gl_operand_t)); -} - -static void -_cairo_gl_set_operator (cairo_gl_context_t *ctx, - cairo_operator_t op, - cairo_bool_t component_alpha) -{ - struct { - GLenum src; - GLenum dst; - } blend_factors[] = { - { GL_ZERO, GL_ZERO }, /* Clear */ - { GL_ONE, GL_ZERO }, /* Source */ - { GL_ONE, GL_ONE_MINUS_SRC_ALPHA }, /* Over */ - { GL_DST_ALPHA, GL_ZERO }, /* In */ - { GL_ONE_MINUS_DST_ALPHA, GL_ZERO }, /* Out */ - { GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA }, /* Atop */ - - { GL_ZERO, GL_ONE }, /* Dest */ - { GL_ONE_MINUS_DST_ALPHA, GL_ONE }, /* DestOver */ - { GL_ZERO, GL_SRC_ALPHA }, /* DestIn */ - { GL_ZERO, GL_ONE_MINUS_SRC_ALPHA }, /* DestOut */ - { GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA }, /* DestAtop */ - - { GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA }, /* Xor */ - { GL_ONE, GL_ONE }, /* Add */ - }; - GLenum src_factor, dst_factor; - - assert (op < ARRAY_LENGTH (blend_factors)); - /* different dst and component_alpha changes cause flushes elsewhere */ - if (ctx->current_operator != op) - _cairo_gl_composite_flush (ctx); - ctx->current_operator = op; - - src_factor = blend_factors[op].src; - dst_factor = blend_factors[op].dst; - - /* Even when the user requests CAIRO_CONTENT_COLOR, we use GL_RGBA - * due to texture filtering of GL_CLAMP_TO_BORDER. So fix those - * bits in that case. - */ - if (ctx->current_target->base.content == CAIRO_CONTENT_COLOR) { - if (src_factor == GL_ONE_MINUS_DST_ALPHA) - src_factor = GL_ZERO; - if (src_factor == GL_DST_ALPHA) - src_factor = GL_ONE; - } - - if (component_alpha) { - if (dst_factor == GL_ONE_MINUS_SRC_ALPHA) - dst_factor = GL_ONE_MINUS_SRC_COLOR; - if (dst_factor == GL_SRC_ALPHA) - dst_factor = GL_SRC_COLOR; - } - - if (ctx->current_target->base.content == CAIRO_CONTENT_ALPHA) { - glBlendFuncSeparate (GL_ZERO, GL_ZERO, src_factor, dst_factor); - } else if (ctx->current_target->base.content == CAIRO_CONTENT_COLOR) { - glBlendFuncSeparate (src_factor, dst_factor, GL_ONE, GL_ONE); - } else { - glBlendFunc (src_factor, dst_factor); - } -} - -static cairo_status_t -_cairo_gl_composite_begin_component_alpha (cairo_gl_context_t *ctx, - cairo_gl_composite_t *setup) -{ - cairo_gl_shader_t *pre_shader = NULL; - cairo_status_t status; - - /* For CLEAR, cairo's rendering equation (quoting Owen's description in: - * http://lists.cairographics.org/archives/cairo/2005-August/004992.html) - * is: - * mask IN clip ? src OP dest : dest - * or more simply: - * mask IN CLIP ? 0 : dest - * - * where the ternary operator A ? B : C is (A * B) + ((1 - A) * C). - * - * The model we use in _cairo_gl_set_operator() is Render's: - * src IN mask IN clip OP dest - * which would boil down to: - * 0 (bounded by the extents of the drawing). - * - * However, we can do a Render operation using an opaque source - * and DEST_OUT to produce: - * 1 IN mask IN clip DEST_OUT dest - * which is - * mask IN clip ? 0 : dest - */ - if (setup->op == CAIRO_OPERATOR_CLEAR) { - _cairo_gl_solid_operand_init (&setup->src, CAIRO_COLOR_WHITE); - setup->op = CAIRO_OPERATOR_DEST_OUT; - } - - /* - * implements component-alpha %CAIRO_OPERATOR_OVER using two passes of - * the simpler operations %CAIRO_OPERATOR_DEST_OUT and %CAIRO_OPERATOR_ADD. - * - * From http://anholt.livejournal.com/32058.html: - * - * The trouble is that component-alpha rendering requires two different sources - * for blending: one for the source value to the blender, which is the - * per-channel multiplication of source and mask, and one for the source alpha - * for multiplying with the destination channels, which is the multiplication - * of the source channels by the mask alpha. So the equation for Over is: - * - * dst.A = src.A * mask.A + (1 - (src.A * mask.A)) * dst.A - * dst.R = src.R * mask.R + (1 - (src.A * mask.R)) * dst.R - * dst.G = src.G * mask.G + (1 - (src.A * mask.G)) * dst.G - * dst.B = src.B * mask.B + (1 - (src.A * mask.B)) * dst.B - * - * But we can do some simpler operations, right? How about PictOpOutReverse, - * which has a source factor of 0 and dest factor of (1 - source alpha). We - * can get the source alpha value (srca.X = src.A * mask.X) out of the texture - * blenders pretty easily. So we can do a component-alpha OutReverse, which - * gets us: - * - * dst.A = 0 + (1 - (src.A * mask.A)) * dst.A - * dst.R = 0 + (1 - (src.A * mask.R)) * dst.R - * dst.G = 0 + (1 - (src.A * mask.G)) * dst.G - * dst.B = 0 + (1 - (src.A * mask.B)) * dst.B - * - * OK. And if an op doesn't use the source alpha value for the destination - * factor, then we can do the channel multiplication in the texture blenders - * to get the source value, and ignore the source alpha that we wouldn't use. - * We've supported this in the Radeon driver for a long time. An example would - * be PictOpAdd, which does: - * - * dst.A = src.A * mask.A + dst.A - * dst.R = src.R * mask.R + dst.R - * dst.G = src.G * mask.G + dst.G - * dst.B = src.B * mask.B + dst.B - * - * Hey, this looks good! If we do a PictOpOutReverse and then a PictOpAdd right - * after it, we get: - * - * dst.A = src.A * mask.A + ((1 - (src.A * mask.A)) * dst.A) - * dst.R = src.R * mask.R + ((1 - (src.A * mask.R)) * dst.R) - * dst.G = src.G * mask.G + ((1 - (src.A * mask.G)) * dst.G) - * dst.B = src.B * mask.B + ((1 - (src.A * mask.B)) * dst.B) - * - * This two-pass trickery could be avoided using a new GL extension that - * lets two values come out of the shader and into the blend unit. - */ - if (setup->op == CAIRO_OPERATOR_OVER) { - setup->op = CAIRO_OPERATOR_ADD; - status = _cairo_gl_get_shader_by_type (ctx, - &setup->src, - &setup->mask, - setup->spans, - CAIRO_GL_SHADER_IN_CA_SOURCE_ALPHA, - &pre_shader); - if (unlikely (status)) - return status; - } - - if (ctx->pre_shader != pre_shader) - _cairo_gl_composite_flush (ctx); - ctx->pre_shader = pre_shader; - - return CAIRO_STATUS_SUCCESS; -} - -static void -_scissor_to_doubles (cairo_gl_surface_t *surface, - double x1, double y1, - double x2, double y2) -{ - double height; - - height = y2 - y1; - if (_cairo_gl_surface_is_texture (surface) == FALSE) - y1 = surface->height - (y1 + height); - glScissor (x1, y1, x2 - x1, height); - glEnable (GL_SCISSOR_TEST); -} - -void -_cairo_gl_scissor_to_rectangle (cairo_gl_surface_t *surface, - const cairo_rectangle_int_t *r) -{ - _scissor_to_doubles (surface, r->x, r->y, r->x+r->width, r->y+r->height); -} - -static void -_scissor_to_box (cairo_gl_surface_t *surface, - const cairo_box_t *box) -{ - double x1, y1, x2, y2; - _cairo_box_to_doubles (box, &x1, &y1, &x2, &y2); - _scissor_to_doubles (surface, x1, y1, x2, y2); -} - -static cairo_bool_t -_cairo_gl_composite_setup_vbo (cairo_gl_context_t *ctx, - unsigned int size_per_vertex) -{ - cairo_bool_t vertex_size_changed = ctx->vertex_size != size_per_vertex; - if (vertex_size_changed) { - ctx->vertex_size = size_per_vertex; - _cairo_gl_composite_flush (ctx); - } - - if (_cairo_gl_context_is_flushed (ctx)) { - ctx->dispatch.VertexAttribPointer (CAIRO_GL_VERTEX_ATTRIB_INDEX, 2, - GL_FLOAT, GL_FALSE, size_per_vertex, - ctx->vb); - ctx->dispatch.EnableVertexAttribArray (CAIRO_GL_VERTEX_ATTRIB_INDEX); - } - - return vertex_size_changed; -} - -static void -_disable_stencil_buffer (void) -{ - glDisable (GL_STENCIL_TEST); - glDepthMask (GL_FALSE); -} - -static cairo_int_status_t -_cairo_gl_composite_setup_painted_clipping (cairo_gl_composite_t *setup, - cairo_gl_context_t *ctx, - int vertex_size) -{ - cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS; - - cairo_gl_surface_t *dst = setup->dst; - cairo_clip_t *clip = setup->clip; - - if (clip->num_boxes == 1 && clip->path == NULL) { - _scissor_to_box (dst, &clip->boxes[0]); - goto disable_stencil_buffer_and_return; - } - - if (! _cairo_gl_ensure_stencil (ctx, setup->dst)) { - status = CAIRO_INT_STATUS_UNSUPPORTED; - goto disable_stencil_buffer_and_return; - } - - /* We only want to clear the part of the stencil buffer - * that we are about to use. It also does not hurt to - * scissor around the painted clip. */ - _cairo_gl_scissor_to_rectangle (dst, _cairo_clip_get_extents (clip)); - - /* The clip is not rectangular, so use the stencil buffer. */ - glDepthMask (GL_TRUE); - glEnable (GL_STENCIL_TEST); - - /* Texture surfaces have private depth/stencil buffers, so we can - * rely on any previous clip being cached there. */ - if (_cairo_gl_surface_is_texture (setup->dst)) { - cairo_clip_t *old_clip = setup->dst->clip_on_stencil_buffer; - if (_cairo_clip_equal (old_clip, setup->clip)) - goto activate_stencil_buffer_and_return; - - if (old_clip) { - _cairo_clip_destroy (setup->dst->clip_on_stencil_buffer); - } - - setup->dst->clip_on_stencil_buffer = _cairo_clip_copy (setup->clip); - } - - glClearStencil (0); - glClear (GL_STENCIL_BUFFER_BIT); - - glStencilOp (GL_REPLACE, GL_REPLACE, GL_REPLACE); - glStencilFunc (GL_EQUAL, 1, 0xffffffff); - glColorMask (0, 0, 0, 0); - - status = _cairo_gl_msaa_compositor_draw_clip (ctx, setup, clip); - - if (unlikely (status)) { - glColorMask (1, 1, 1, 1); - goto disable_stencil_buffer_and_return; - } - - /* We want to only render to the stencil buffer, so draw everything now. - Flushing also unbinds the VBO, which we want to rebind for regular - drawing. */ - _cairo_gl_composite_flush (ctx); - _cairo_gl_composite_setup_vbo (ctx, vertex_size); - -activate_stencil_buffer_and_return: - glColorMask (1, 1, 1, 1); - glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP); - glStencilFunc (GL_EQUAL, 1, 0xffffffff); - return CAIRO_INT_STATUS_SUCCESS; - -disable_stencil_buffer_and_return: - _disable_stencil_buffer (); - return status; -} - -static cairo_int_status_t -_cairo_gl_composite_setup_clipping (cairo_gl_composite_t *setup, - cairo_gl_context_t *ctx, - int vertex_size) -{ - cairo_bool_t clip_changing = TRUE; - cairo_bool_t clip_region_changing = TRUE; - - if (! ctx->clip && ! setup->clip && ! setup->clip_region && ! ctx->clip_region) - goto disable_all_clipping; - - clip_changing = ! _cairo_clip_equal (ctx->clip, setup->clip); - clip_region_changing = ! cairo_region_equal (ctx->clip_region, setup->clip_region); - if (! _cairo_gl_context_is_flushed (ctx) && - (clip_region_changing || clip_changing)) - _cairo_gl_composite_flush (ctx); - - assert (!setup->clip_region || !setup->clip); - - /* setup->clip is only used by the msaa compositor and setup->clip_region - * only by the other compositors, so it's safe to wait to clean up obsolete - * clips. */ - if (clip_region_changing) { - cairo_region_destroy (ctx->clip_region); - ctx->clip_region = cairo_region_reference (setup->clip_region); - } - if (clip_changing) { - _cairo_clip_destroy (ctx->clip); - ctx->clip = _cairo_clip_copy (setup->clip); - } - - /* For clip regions, we scissor right before drawing. */ - if (setup->clip_region) - goto disable_all_clipping; - - if (setup->clip) - return _cairo_gl_composite_setup_painted_clipping (setup, ctx, - vertex_size); -disable_all_clipping: - _disable_stencil_buffer (); - glDisable (GL_SCISSOR_TEST); - return CAIRO_INT_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_gl_set_operands_and_operator (cairo_gl_composite_t *setup, - cairo_gl_context_t *ctx) -{ - unsigned int dst_size, src_size, mask_size, vertex_size; - cairo_status_t status; - cairo_gl_shader_t *shader; - cairo_bool_t component_alpha; - cairo_bool_t vertex_size_changed; - - component_alpha = - setup->mask.type == CAIRO_GL_OPERAND_TEXTURE && - setup->mask.texture.attributes.has_component_alpha; - - /* Do various magic for component alpha */ - if (component_alpha) { - status = _cairo_gl_composite_begin_component_alpha (ctx, setup); - if (unlikely (status)) - return status; - } else { - if (ctx->pre_shader) { - _cairo_gl_composite_flush (ctx); - ctx->pre_shader = NULL; - } - } - - status = _cairo_gl_get_shader_by_type (ctx, - &setup->src, - &setup->mask, - setup->spans, - component_alpha ? - CAIRO_GL_SHADER_IN_CA_SOURCE : - CAIRO_GL_SHADER_IN_NORMAL, - &shader); - if (unlikely (status)) { - ctx->pre_shader = NULL; - return status; - } - if (ctx->current_shader != shader) - _cairo_gl_composite_flush (ctx); - - status = CAIRO_STATUS_SUCCESS; - - dst_size = 2 * sizeof (GLfloat); - src_size = _cairo_gl_operand_get_vertex_size (&setup->src); - mask_size = _cairo_gl_operand_get_vertex_size (&setup->mask); - vertex_size = dst_size + src_size + mask_size; - - if (setup->spans) - vertex_size += sizeof (GLfloat); - - vertex_size_changed = _cairo_gl_composite_setup_vbo (ctx, vertex_size); - - _cairo_gl_context_setup_operand (ctx, CAIRO_GL_TEX_SOURCE, &setup->src, dst_size, vertex_size_changed); - _cairo_gl_context_setup_operand (ctx, CAIRO_GL_TEX_MASK, &setup->mask, dst_size + src_size, vertex_size_changed); - - _cairo_gl_context_setup_spans (ctx, setup->spans, vertex_size, - dst_size + src_size + mask_size); - - _cairo_gl_set_operator (ctx, setup->op, component_alpha); - - if (_cairo_gl_context_is_flushed (ctx)) { - if (ctx->pre_shader) { - _cairo_gl_set_shader (ctx, ctx->pre_shader); - _cairo_gl_composite_bind_to_shader (ctx, setup); - } - _cairo_gl_set_shader (ctx, shader); - _cairo_gl_composite_bind_to_shader (ctx, setup); - } - - return status; -} - -cairo_status_t -_cairo_gl_composite_begin (cairo_gl_composite_t *setup, - cairo_gl_context_t **ctx_out) -{ - cairo_gl_context_t *ctx; - cairo_status_t status; - - assert (setup->dst); - - status = _cairo_gl_context_acquire (setup->dst->base.device, &ctx); - if (unlikely (status)) - return status; - - _cairo_gl_context_set_destination (ctx, setup->dst, setup->multisample); - glEnable (GL_BLEND); - - status = _cairo_gl_set_operands_and_operator (setup, ctx); - if (unlikely (status)) - goto FAIL; - - status = _cairo_gl_composite_setup_clipping (setup, ctx, ctx->vertex_size); - if (unlikely (status)) - goto FAIL; - - *ctx_out = ctx; - -FAIL: - if (unlikely (status)) - status = _cairo_gl_context_release (ctx, status); - - return status; -} - -static inline void -_cairo_gl_composite_draw_tristrip (cairo_gl_context_t *ctx) -{ - cairo_array_t* indices = &ctx->tristrip_indices; - const unsigned short *indices_array = _cairo_array_index_const (indices, 0); - - if (ctx->pre_shader) { - cairo_gl_shader_t *prev_shader = ctx->current_shader; - - _cairo_gl_set_shader (ctx, ctx->pre_shader); - _cairo_gl_set_operator (ctx, CAIRO_OPERATOR_DEST_OUT, TRUE); - glDrawElements (GL_TRIANGLE_STRIP, _cairo_array_num_elements (indices), GL_UNSIGNED_SHORT, indices_array); - - _cairo_gl_set_shader (ctx, prev_shader); - _cairo_gl_set_operator (ctx, CAIRO_OPERATOR_ADD, TRUE); - } - - glDrawElements (GL_TRIANGLE_STRIP, _cairo_array_num_elements (indices), GL_UNSIGNED_SHORT, indices_array); - _cairo_array_truncate (indices, 0); -} - -static inline void -_cairo_gl_composite_draw_triangles (cairo_gl_context_t *ctx, - unsigned int count) -{ - if (! ctx->pre_shader) { - glDrawArrays (GL_TRIANGLES, 0, count); - } else { - cairo_gl_shader_t *prev_shader = ctx->current_shader; - - _cairo_gl_set_shader (ctx, ctx->pre_shader); - _cairo_gl_set_operator (ctx, CAIRO_OPERATOR_DEST_OUT, TRUE); - glDrawArrays (GL_TRIANGLES, 0, count); - - _cairo_gl_set_shader (ctx, prev_shader); - _cairo_gl_set_operator (ctx, CAIRO_OPERATOR_ADD, TRUE); - glDrawArrays (GL_TRIANGLES, 0, count); - } -} - -static void -_cairo_gl_composite_draw_triangles_with_clip_region (cairo_gl_context_t *ctx, - unsigned int count) -{ - int i, num_rectangles; - - if (!ctx->clip_region) { - _cairo_gl_composite_draw_triangles (ctx, count); - return; - } - - num_rectangles = cairo_region_num_rectangles (ctx->clip_region); - for (i = 0; i < num_rectangles; i++) { - cairo_rectangle_int_t rect; - - cairo_region_get_rectangle (ctx->clip_region, i, &rect); - - _cairo_gl_scissor_to_rectangle (ctx->current_target, &rect); - _cairo_gl_composite_draw_triangles (ctx, count); - } -} - -static void -_cairo_gl_composite_unmap_vertex_buffer (cairo_gl_context_t *ctx) -{ - ctx->vb_offset = 0; -} - -void -_cairo_gl_composite_flush (cairo_gl_context_t *ctx) -{ - unsigned int count; - int i; - - if (_cairo_gl_context_is_flushed (ctx)) - return; - - count = ctx->vb_offset / ctx->vertex_size; - _cairo_gl_composite_unmap_vertex_buffer (ctx); - - if (ctx->primitive_type == CAIRO_GL_PRIMITIVE_TYPE_TRISTRIPS) { - _cairo_gl_composite_draw_tristrip (ctx); - } else { - assert (ctx->primitive_type == CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES); - _cairo_gl_composite_draw_triangles_with_clip_region (ctx, count); - } - - for (i = 0; i < ARRAY_LENGTH (ctx->glyph_cache); i++) - _cairo_gl_glyph_cache_unlock (&ctx->glyph_cache[i]); -} - -static void -_cairo_gl_composite_prepare_buffer (cairo_gl_context_t *ctx, - unsigned int n_vertices, - cairo_gl_primitive_type_t primitive_type) -{ - if (ctx->primitive_type != primitive_type) { - _cairo_gl_composite_flush (ctx); - ctx->primitive_type = primitive_type; - } - - assert(ctx->vbo_size > 0); - if (ctx->vb_offset + n_vertices * ctx->vertex_size > ctx->vbo_size) - _cairo_gl_composite_flush (ctx); -} - -static inline void -_cairo_gl_composite_emit_vertex (cairo_gl_context_t *ctx, - GLfloat x, GLfloat y) -{ - GLfloat *vb = (GLfloat *) (void *) &ctx->vb[ctx->vb_offset]; - - *vb++ = x; - *vb++ = y; - - _cairo_gl_operand_emit (&ctx->operands[CAIRO_GL_TEX_SOURCE], &vb, x, y); - _cairo_gl_operand_emit (&ctx->operands[CAIRO_GL_TEX_MASK ], &vb, x, y); - - ctx->vb_offset += ctx->vertex_size; -} - -static inline void -_cairo_gl_composite_emit_alpha_vertex (cairo_gl_context_t *ctx, - GLfloat x, GLfloat y, uint8_t alpha) -{ - GLfloat *vb = (GLfloat *) (void *) &ctx->vb[ctx->vb_offset]; - union fi { - float f; - GLbyte bytes[4]; - } fi; - - *vb++ = x; - *vb++ = y; - - _cairo_gl_operand_emit (&ctx->operands[CAIRO_GL_TEX_SOURCE], &vb, x, y); - _cairo_gl_operand_emit (&ctx->operands[CAIRO_GL_TEX_MASK ], &vb, x, y); - - fi.bytes[0] = 0; - fi.bytes[1] = 0; - fi.bytes[2] = 0; - fi.bytes[3] = alpha; - *vb++ = fi.f; - - ctx->vb_offset += ctx->vertex_size; -} - -static void -_cairo_gl_composite_emit_point (cairo_gl_context_t *ctx, - const cairo_point_t *point) -{ - _cairo_gl_composite_emit_vertex (ctx, - _cairo_fixed_to_double (point->x), - _cairo_fixed_to_double (point->y)); -} - -static void -_cairo_gl_composite_emit_rect (cairo_gl_context_t *ctx, - GLfloat x1, GLfloat y1, - GLfloat x2, GLfloat y2) -{ - _cairo_gl_composite_prepare_buffer (ctx, 6, - CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES); - - _cairo_gl_composite_emit_vertex (ctx, x1, y1); - _cairo_gl_composite_emit_vertex (ctx, x2, y1); - _cairo_gl_composite_emit_vertex (ctx, x1, y2); - - _cairo_gl_composite_emit_vertex (ctx, x2, y1); - _cairo_gl_composite_emit_vertex (ctx, x2, y2); - _cairo_gl_composite_emit_vertex (ctx, x1, y2); -} - -cairo_gl_emit_rect_t -_cairo_gl_context_choose_emit_rect (cairo_gl_context_t *ctx) -{ - return _cairo_gl_composite_emit_rect; -} - -void -_cairo_gl_context_emit_rect (cairo_gl_context_t *ctx, - GLfloat x1, GLfloat y1, - GLfloat x2, GLfloat y2) -{ - _cairo_gl_composite_emit_rect (ctx, x1, y1, x2, y2); -} - -static void -_cairo_gl_composite_emit_span (cairo_gl_context_t *ctx, - GLfloat x1, GLfloat y1, - GLfloat x2, GLfloat y2, - uint8_t alpha) -{ - _cairo_gl_composite_prepare_buffer (ctx, 6, - CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES); - - _cairo_gl_composite_emit_alpha_vertex (ctx, x1, y1, alpha); - _cairo_gl_composite_emit_alpha_vertex (ctx, x2, y1, alpha); - _cairo_gl_composite_emit_alpha_vertex (ctx, x1, y2, alpha); - - _cairo_gl_composite_emit_alpha_vertex (ctx, x2, y1, alpha); - _cairo_gl_composite_emit_alpha_vertex (ctx, x2, y2, alpha); - _cairo_gl_composite_emit_alpha_vertex (ctx, x1, y2, alpha); -} - -static void -_cairo_gl_composite_emit_solid_span (cairo_gl_context_t *ctx, - GLfloat x1, GLfloat y1, - GLfloat x2, GLfloat y2, - uint8_t alpha) -{ - GLfloat *v; - union fi { - float f; - GLbyte bytes[4]; - } fi; - - _cairo_gl_composite_prepare_buffer (ctx, 6, - CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES); - v = (GLfloat *) (void *) &ctx->vb[ctx->vb_offset]; - - v[15] = v[ 6] = v[0] = x1; - v[10] = v[ 4] = v[1] = y1; - v[12] = v[ 9] = v[3] = x2; - v[16] = v[13] = v[7] = y2; - - fi.bytes[0] = 0; - fi.bytes[1] = 0; - fi.bytes[2] = 0; - fi.bytes[3] = alpha; - v[17] =v[14] = v[11] = v[8] = v[5] = v[2] = fi.f; - - ctx->vb_offset += 6*3 * sizeof(GLfloat); -} - -cairo_gl_emit_span_t -_cairo_gl_context_choose_emit_span (cairo_gl_context_t *ctx) -{ - if (ctx->operands[CAIRO_GL_TEX_MASK].type != CAIRO_GL_OPERAND_NONE) { - switch (ctx->operands[CAIRO_GL_TEX_MASK].type) { - default: - case CAIRO_GL_OPERAND_COUNT: - ASSERT_NOT_REACHED; - case CAIRO_GL_OPERAND_NONE: - case CAIRO_GL_OPERAND_CONSTANT: - break; - - case CAIRO_GL_OPERAND_LINEAR_GRADIENT: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT: - if (!ctx->operands[CAIRO_GL_TEX_MASK].gradient.texgen) - return _cairo_gl_composite_emit_span; - break; - - case CAIRO_GL_OPERAND_TEXTURE: - if (!ctx->operands[CAIRO_GL_TEX_MASK].texture.texgen) - return _cairo_gl_composite_emit_span; - break; - } - } - - switch (ctx->operands[CAIRO_GL_TEX_SOURCE].type) { - default: - case CAIRO_GL_OPERAND_COUNT: - ASSERT_NOT_REACHED; - case CAIRO_GL_OPERAND_NONE: - case CAIRO_GL_OPERAND_CONSTANT: - break; - - case CAIRO_GL_OPERAND_LINEAR_GRADIENT: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT: - if (!ctx->operands[CAIRO_GL_TEX_SOURCE].gradient.texgen) - return _cairo_gl_composite_emit_span; - break; - - case CAIRO_GL_OPERAND_TEXTURE: - if (!ctx->operands[CAIRO_GL_TEX_SOURCE].texture.texgen) - return _cairo_gl_composite_emit_span; - } - - return _cairo_gl_composite_emit_solid_span; -} - -static inline void -_cairo_gl_composite_emit_glyph_vertex (cairo_gl_context_t *ctx, - GLfloat x, GLfloat y, - GLfloat glyph_x, GLfloat glyph_y) -{ - GLfloat *vb = (GLfloat *) (void *) &ctx->vb[ctx->vb_offset]; - - *vb++ = x; - *vb++ = y; - - _cairo_gl_operand_emit (&ctx->operands[CAIRO_GL_TEX_SOURCE], &vb, x, y); - - *vb++ = glyph_x; - *vb++ = glyph_y; - - ctx->vb_offset += ctx->vertex_size; -} - -static void -_cairo_gl_composite_emit_glyph (cairo_gl_context_t *ctx, - GLfloat x1, GLfloat y1, - GLfloat x2, GLfloat y2, - GLfloat glyph_x1, GLfloat glyph_y1, - GLfloat glyph_x2, GLfloat glyph_y2) -{ - _cairo_gl_composite_prepare_buffer (ctx, 6, - CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES); - - _cairo_gl_composite_emit_glyph_vertex (ctx, x1, y1, glyph_x1, glyph_y1); - _cairo_gl_composite_emit_glyph_vertex (ctx, x2, y1, glyph_x2, glyph_y1); - _cairo_gl_composite_emit_glyph_vertex (ctx, x1, y2, glyph_x1, glyph_y2); - - _cairo_gl_composite_emit_glyph_vertex (ctx, x2, y1, glyph_x2, glyph_y1); - _cairo_gl_composite_emit_glyph_vertex (ctx, x2, y2, glyph_x2, glyph_y2); - _cairo_gl_composite_emit_glyph_vertex (ctx, x1, y2, glyph_x1, glyph_y2); -} - -static void -_cairo_gl_composite_emit_solid_glyph (cairo_gl_context_t *ctx, - GLfloat x1, GLfloat y1, - GLfloat x2, GLfloat y2, - GLfloat glyph_x1, GLfloat glyph_y1, - GLfloat glyph_x2, GLfloat glyph_y2) -{ - GLfloat *v; - - _cairo_gl_composite_prepare_buffer (ctx, 6, - CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES); - - v = (GLfloat *) (void *) &ctx->vb[ctx->vb_offset]; - - v[20] = v[ 8] = v[0] = x1; - v[13] = v[ 5] = v[1] = y1; - v[22] = v[10] = v[2] = glyph_x1; - v[15] = v[ 7] = v[3] = glyph_y1; - - v[16] = v[12] = v[4] = x2; - v[18] = v[14] = v[6] = glyph_x2; - - v[21] = v[17] = v[ 9] = y2; - v[23] = v[19] = v[11] = glyph_y2; - - ctx->vb_offset += 4 * 6 * sizeof (GLfloat); -} - -cairo_gl_emit_glyph_t -_cairo_gl_context_choose_emit_glyph (cairo_gl_context_t *ctx) -{ - switch (ctx->operands[CAIRO_GL_TEX_SOURCE].type) { - default: - case CAIRO_GL_OPERAND_COUNT: - ASSERT_NOT_REACHED; - case CAIRO_GL_OPERAND_NONE: - case CAIRO_GL_OPERAND_CONSTANT: - return _cairo_gl_composite_emit_solid_glyph; - - case CAIRO_GL_OPERAND_LINEAR_GRADIENT: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT: - case CAIRO_GL_OPERAND_TEXTURE: - return _cairo_gl_composite_emit_glyph; - } -} - -void -_cairo_gl_composite_fini (cairo_gl_composite_t *setup) -{ - _cairo_gl_operand_destroy (&setup->src); - _cairo_gl_operand_destroy (&setup->mask); -} - -cairo_status_t -_cairo_gl_composite_set_operator (cairo_gl_composite_t *setup, - cairo_operator_t op, - cairo_bool_t assume_component_alpha) -{ - if (assume_component_alpha) { - if (op != CAIRO_OPERATOR_CLEAR && - op != CAIRO_OPERATOR_OVER && - op != CAIRO_OPERATOR_ADD) - return UNSUPPORTED ("unsupported component alpha operator"); - } else { - if (! _cairo_gl_operator_is_supported (op)) - return UNSUPPORTED ("unsupported operator"); - } - - setup->op = op; - return CAIRO_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_gl_composite_init (cairo_gl_composite_t *setup, - cairo_operator_t op, - cairo_gl_surface_t *dst, - cairo_bool_t assume_component_alpha) -{ - cairo_status_t status; - - memset (setup, 0, sizeof (cairo_gl_composite_t)); - - status = _cairo_gl_composite_set_operator (setup, op, - assume_component_alpha); - if (status) - return status; - - setup->dst = dst; - setup->clip_region = dst->clip_region; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_gl_composite_append_vertex_indices (cairo_gl_context_t *ctx, - int number_of_new_indices) -{ - cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS; - cairo_array_t *indices = &ctx->tristrip_indices; - int number_of_indices = _cairo_array_num_elements (indices); - unsigned short current_vertex_index = 0; - int i; - - assert (number_of_new_indices > 0); - - /* If any preexisting triangle triangle strip indices exist on this - context, we insert a set of degenerate triangles from the last - preexisting vertex to our first one. */ - if (number_of_indices > 0) { - const unsigned short *indices_array = _cairo_array_index_const (indices, 0); - current_vertex_index = indices_array[number_of_indices - 1]; - - status = _cairo_array_append (indices, ¤t_vertex_index); - if (unlikely (status)) - return status; - - current_vertex_index++; - status =_cairo_array_append (indices, ¤t_vertex_index); - if (unlikely (status)) - return status; - } - - for (i = 0; i < number_of_new_indices; i++) { - status = _cairo_array_append (indices, ¤t_vertex_index); - current_vertex_index++; - if (unlikely (status)) - return status; - } - - return CAIRO_STATUS_SUCCESS; -} - -cairo_int_status_t -_cairo_gl_composite_emit_quad_as_tristrip (cairo_gl_context_t *ctx, - cairo_gl_composite_t *setup, - const cairo_point_t quad[4]) -{ - _cairo_gl_composite_prepare_buffer (ctx, 4, - CAIRO_GL_PRIMITIVE_TYPE_TRISTRIPS); - - _cairo_gl_composite_emit_point (ctx, &quad[0]); - _cairo_gl_composite_emit_point (ctx, &quad[1]); - - /* Cairo stores quad vertices in counter-clockwise order, but we need to - emit them from top to bottom in the triangle strip, so we need to reverse - the order of the last two vertices. */ - _cairo_gl_composite_emit_point (ctx, &quad[3]); - _cairo_gl_composite_emit_point (ctx, &quad[2]); - - return _cairo_gl_composite_append_vertex_indices (ctx, 4); -} - -cairo_int_status_t -_cairo_gl_composite_emit_triangle_as_tristrip (cairo_gl_context_t *ctx, - cairo_gl_composite_t *setup, - const cairo_point_t triangle[3]) -{ - _cairo_gl_composite_prepare_buffer (ctx, 3, - CAIRO_GL_PRIMITIVE_TYPE_TRISTRIPS); - - _cairo_gl_composite_emit_point (ctx, &triangle[0]); - _cairo_gl_composite_emit_point (ctx, &triangle[1]); - _cairo_gl_composite_emit_point (ctx, &triangle[2]); - return _cairo_gl_composite_append_vertex_indices (ctx, 3); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-gl-device.c b/source/libs/cairo/cairo-src/src/cairo-gl-device.c deleted file mode 100644 index 7235d9ae123e555f8d4dbf11b7ec2e505ff1d6a9..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-gl-device.c +++ /dev/null @@ -1,804 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Eric Anholt - * Copyright © 2009 Chris Wilson - * Copyright © 2005,2010 Red Hat, Inc - * Copyright © 2010 Linaro Limited - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Benjamin Otte <otte@gnome.org> - * Carl Worth <cworth@cworth.org> - * Chris Wilson <chris@chris-wilson.co.uk> - * Eric Anholt <eric@anholt.net> - * Alexandros Frantzis <alexandros.frantzis@linaro.org> - */ - -#include "cairoint.h" - -#include "cairo-error-private.h" -#include "cairo-gl-private.h" - -#define MAX_MSAA_SAMPLES 4 - -static void -_gl_lock (void *device) -{ - cairo_gl_context_t *ctx = (cairo_gl_context_t *) device; - - ctx->acquire (ctx); -} - -static void -_gl_unlock (void *device) -{ - cairo_gl_context_t *ctx = (cairo_gl_context_t *) device; - - ctx->release (ctx); -} - -static cairo_status_t -_gl_flush (void *device) -{ - cairo_gl_context_t *ctx; - cairo_status_t status; - - status = _cairo_gl_context_acquire (device, &ctx); - if (unlikely (status)) - return status; - - _cairo_gl_composite_flush (ctx); - - _cairo_gl_context_destroy_operand (ctx, CAIRO_GL_TEX_SOURCE); - _cairo_gl_context_destroy_operand (ctx, CAIRO_GL_TEX_MASK); - - if (ctx->clip_region) { - cairo_region_destroy (ctx->clip_region); - ctx->clip_region = NULL; - } - - ctx->current_target = NULL; - ctx->current_operator = -1; - ctx->vertex_size = 0; - ctx->pre_shader = NULL; - _cairo_gl_set_shader (ctx, NULL); - - ctx->dispatch.BindBuffer (GL_ARRAY_BUFFER, 0); - - glDisable (GL_SCISSOR_TEST); - glDisable (GL_BLEND); - - return _cairo_gl_context_release (ctx, status); -} - -static void -_gl_finish (void *device) -{ - cairo_gl_context_t *ctx = device; - int n; - - _gl_lock (device); - - _cairo_cache_fini (&ctx->gradients); - - _cairo_gl_context_fini_shaders (ctx); - - for (n = 0; n < ARRAY_LENGTH (ctx->glyph_cache); n++) - _cairo_gl_glyph_cache_fini (ctx, &ctx->glyph_cache[n]); - - _gl_unlock (device); -} - -static void -_gl_destroy (void *device) -{ - cairo_gl_context_t *ctx = device; - - ctx->acquire (ctx); - - while (! cairo_list_is_empty (&ctx->fonts)) { - cairo_gl_font_t *font; - - font = cairo_list_first_entry (&ctx->fonts, - cairo_gl_font_t, - link); - - cairo_list_del (&font->base.link); - cairo_list_del (&font->link); - free (font); - } - - _cairo_array_fini (&ctx->tristrip_indices); - - cairo_region_destroy (ctx->clip_region); - _cairo_clip_destroy (ctx->clip); - - free (ctx->vb); - - ctx->destroy (ctx); - - free (ctx); -} - -static const cairo_device_backend_t _cairo_gl_device_backend = { - CAIRO_DEVICE_TYPE_GL, - - _gl_lock, - _gl_unlock, - - _gl_flush, /* flush */ - _gl_finish, - _gl_destroy, -}; - -static cairo_bool_t -_cairo_gl_msaa_compositor_enabled (void) -{ - const char *env = getenv ("CAIRO_GL_COMPOSITOR"); - return env && strcmp(env, "msaa") == 0; -} - -static cairo_bool_t -test_can_read_bgra (cairo_gl_flavor_t gl_flavor) -{ - /* Desktop GL always supports BGRA formats. */ - if (gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) - return TRUE; - - assert (gl_flavor == CAIRO_GL_FLAVOR_ES); - - /* For OpenGL ES we have to look for the specific extension and BGRA only - * matches cairo's integer packed bytes on little-endian machines. */ - if (!_cairo_is_little_endian()) - return FALSE; - return _cairo_gl_has_extension ("EXT_read_format_bgra"); -} - -cairo_status_t -_cairo_gl_context_init (cairo_gl_context_t *ctx) -{ - cairo_status_t status; - cairo_gl_dispatch_t *dispatch = &ctx->dispatch; - int gl_version = _cairo_gl_get_version (); - cairo_gl_flavor_t gl_flavor = _cairo_gl_get_flavor (); - int n; - - cairo_bool_t is_desktop = gl_flavor == CAIRO_GL_FLAVOR_DESKTOP; - cairo_bool_t is_gles = gl_flavor == CAIRO_GL_FLAVOR_ES; - - _cairo_device_init (&ctx->base, &_cairo_gl_device_backend); - - /* XXX The choice of compositor should be made automatically at runtime. - * However, it is useful to force one particular compositor whilst - * testing. - */ - if (_cairo_gl_msaa_compositor_enabled ()) - ctx->compositor = _cairo_gl_msaa_compositor_get (); - else - ctx->compositor = _cairo_gl_span_compositor_get (); - - - ctx->thread_aware = TRUE; - - memset (ctx->glyph_cache, 0, sizeof (ctx->glyph_cache)); - cairo_list_init (&ctx->fonts); - - /* Support only GL version >= 1.3 */ - if (gl_version < CAIRO_GL_VERSION_ENCODE (1, 3)) - return _cairo_error (CAIRO_STATUS_DEVICE_ERROR); - - /* Check for required extensions */ - if (is_desktop) { - if (_cairo_gl_has_extension ("GL_ARB_texture_non_power_of_two")) { - ctx->tex_target = GL_TEXTURE_2D; - ctx->has_npot_repeat = TRUE; - } else if (_cairo_gl_has_extension ("GL_ARB_texture_rectangle")) { - ctx->tex_target = GL_TEXTURE_RECTANGLE; - ctx->has_npot_repeat = FALSE; - } else - return _cairo_error (CAIRO_STATUS_DEVICE_ERROR); - } else { - ctx->tex_target = GL_TEXTURE_2D; - if (_cairo_gl_has_extension ("GL_OES_texture_npot") || - _cairo_gl_has_extension ("GL_IMG_texture_npot")) - ctx->has_npot_repeat = TRUE; - else - ctx->has_npot_repeat = FALSE; - } - - if (is_desktop && gl_version < CAIRO_GL_VERSION_ENCODE (2, 1) && - ! _cairo_gl_has_extension ("GL_ARB_pixel_buffer_object")) - return _cairo_error (CAIRO_STATUS_DEVICE_ERROR); - - if (is_gles && ! _cairo_gl_has_extension ("GL_EXT_texture_format_BGRA8888")) - return _cairo_error (CAIRO_STATUS_DEVICE_ERROR); - - ctx->has_map_buffer = - is_desktop || (is_gles && _cairo_gl_has_extension ("GL_OES_mapbuffer")); - - ctx->can_read_bgra = test_can_read_bgra (gl_flavor); - - ctx->has_mesa_pack_invert = - _cairo_gl_has_extension ("GL_MESA_pack_invert"); - - ctx->has_packed_depth_stencil = - (is_desktop && _cairo_gl_has_extension ("GL_EXT_packed_depth_stencil")) || - (is_gles && _cairo_gl_has_extension ("GL_OES_packed_depth_stencil")); - - ctx->num_samples = 1; - -#if CAIRO_HAS_GL_SURFACE - if (is_desktop && ctx->has_packed_depth_stencil && - (gl_version >= CAIRO_GL_VERSION_ENCODE (3, 0) || - _cairo_gl_has_extension ("GL_ARB_framebuffer_object") || - (_cairo_gl_has_extension ("GL_EXT_framebuffer_blit") && - _cairo_gl_has_extension ("GL_EXT_framebuffer_multisample")))) { - glGetIntegerv(GL_MAX_SAMPLES_EXT, &ctx->num_samples); - } -#endif - -#if CAIRO_HAS_GLESV2_SURFACE && defined(GL_MAX_SAMPLES_EXT) - if (is_gles && ctx->has_packed_depth_stencil && - _cairo_gl_has_extension ("GL_EXT_multisampled_render_to_texture")) { - glGetIntegerv(GL_MAX_SAMPLES_EXT, &ctx->num_samples); - } -#endif - -#if CAIRO_HAS_GLESV2_SURFACE && defined(GL_MAX_SAMPLES_IMG) - if (is_gles && ctx->has_packed_depth_stencil && - _cairo_gl_has_extension ("GL_IMG_multisampled_render_to_texture")) { - glGetIntegerv(GL_MAX_SAMPLES_IMG, &ctx->num_samples); - } -#endif - - ctx->supports_msaa = ctx->num_samples > 1; - if (ctx->num_samples > MAX_MSAA_SAMPLES) - ctx->num_samples = MAX_MSAA_SAMPLES; - - - ctx->current_operator = -1; - ctx->gl_flavor = gl_flavor; - - status = _cairo_gl_context_init_shaders (ctx); - if (unlikely (status)) - return status; - - status = _cairo_cache_init (&ctx->gradients, - _cairo_gl_gradient_equal, - NULL, - (cairo_destroy_func_t) _cairo_gl_gradient_destroy, - CAIRO_GL_GRADIENT_CACHE_SIZE); - if (unlikely (status)) - return status; - - ctx->vbo_size = _cairo_gl_get_vbo_size(); - - ctx->vb = malloc (ctx->vbo_size); - if (unlikely (ctx->vb == NULL)) { - _cairo_cache_fini (&ctx->gradients); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - ctx->primitive_type = CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES; - _cairo_array_init (&ctx->tristrip_indices, sizeof (unsigned short)); - - /* PBO for any sort of texture upload */ - dispatch->GenBuffers (1, &ctx->texture_load_pbo); - - ctx->max_framebuffer_size = 0; - glGetIntegerv (GL_MAX_RENDERBUFFER_SIZE, &ctx->max_framebuffer_size); - ctx->max_texture_size = 0; - glGetIntegerv (GL_MAX_TEXTURE_SIZE, &ctx->max_texture_size); - ctx->max_textures = 0; - glGetIntegerv (GL_MAX_TEXTURE_IMAGE_UNITS, &ctx->max_textures); - - for (n = 0; n < ARRAY_LENGTH (ctx->glyph_cache); n++) - _cairo_gl_glyph_cache_init (&ctx->glyph_cache[n]); - - return CAIRO_STATUS_SUCCESS; -} - -void -_cairo_gl_context_activate (cairo_gl_context_t *ctx, - cairo_gl_tex_t tex_unit) -{ - if (ctx->max_textures <= (GLint) tex_unit) { - if (tex_unit < 2) { - _cairo_gl_composite_flush (ctx); - _cairo_gl_context_destroy_operand (ctx, ctx->max_textures - 1); - } - glActiveTexture (ctx->max_textures - 1); - } else { - glActiveTexture (GL_TEXTURE0 + tex_unit); - } -} - -static GLenum -_get_depth_stencil_format (cairo_gl_context_t *ctx) -{ - /* This is necessary to properly handle the situation where both - OpenGL and OpenGLES are active and returning a sane default. */ -#if CAIRO_HAS_GL_SURFACE - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) - return GL_DEPTH_STENCIL; -#endif - -#if CAIRO_HAS_GLESV2_SURFACE - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) - return GL_DEPTH24_STENCIL8_OES; -#endif - -#if CAIRO_HAS_GL_SURFACE - return GL_DEPTH_STENCIL; -#elif CAIRO_HAS_GLESV2_SURFACE - return GL_DEPTH24_STENCIL8_OES; -#endif -} - -#if CAIRO_HAS_GLESV2_SURFACE -static void -_cairo_gl_ensure_msaa_gles_framebuffer (cairo_gl_context_t *ctx, - cairo_gl_surface_t *surface) -{ - if (surface->msaa_active) - return; - - ctx->dispatch.FramebufferTexture2DMultisample(GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, - ctx->tex_target, - surface->tex, - 0, - ctx->num_samples); - - /* From now on MSAA will always be active on this surface. */ - surface->msaa_active = TRUE; -} -#endif - -static void -_cairo_gl_ensure_framebuffer (cairo_gl_context_t *ctx, - cairo_gl_surface_t *surface) -{ - GLenum status; - cairo_gl_dispatch_t *dispatch = &ctx->dispatch; - - if (likely (surface->fb)) - return; - - /* Create a framebuffer object wrapping the texture so that we can render - * to it. - */ - dispatch->GenFramebuffers (1, &surface->fb); - dispatch->BindFramebuffer (GL_FRAMEBUFFER, surface->fb); - - /* Unlike for desktop GL we only maintain one multisampling framebuffer - for OpenGLES since the EXT_multisampled_render_to_texture extension - does not require an explicit multisample resolution. */ -#if CAIRO_HAS_GLESV2_SURFACE - if (surface->supports_msaa && _cairo_gl_msaa_compositor_enabled () && - ctx->gl_flavor == CAIRO_GL_FLAVOR_ES) { - _cairo_gl_ensure_msaa_gles_framebuffer (ctx, surface); - } else -#endif - dispatch->FramebufferTexture2D (GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, - ctx->tex_target, - surface->tex, - 0); - -#if CAIRO_HAS_GL_SURFACE - glDrawBuffer (GL_COLOR_ATTACHMENT0); - glReadBuffer (GL_COLOR_ATTACHMENT0); -#endif - - status = dispatch->CheckFramebufferStatus (GL_FRAMEBUFFER); - if (status != GL_FRAMEBUFFER_COMPLETE) { - const char *str; - switch (status) { - //case GL_FRAMEBUFFER_UNDEFINED: str= "undefined"; break; - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: str= "incomplete attachment"; break; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: str= "incomplete/missing attachment"; break; - case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: str= "incomplete draw buffer"; break; - case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: str= "incomplete read buffer"; break; - case GL_FRAMEBUFFER_UNSUPPORTED: str= "unsupported"; break; - case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: str= "incomplete multiple"; break; - default: str = "unknown error"; break; - } - - fprintf (stderr, - "destination is framebuffer incomplete: %s [%#x]\n", - str, status); - } -} -#if CAIRO_HAS_GL_SURFACE -static void -_cairo_gl_ensure_multisampling (cairo_gl_context_t *ctx, - cairo_gl_surface_t *surface) -{ - assert (surface->supports_msaa); - assert (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP); - - if (surface->msaa_fb) - return; - - /* We maintain a separate framebuffer for multisampling operations. - This allows us to do a fast paint to the non-multisampling framebuffer - when mulitsampling is disabled. */ - ctx->dispatch.GenFramebuffers (1, &surface->msaa_fb); - ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->msaa_fb); - ctx->dispatch.GenRenderbuffers (1, &surface->msaa_rb); - ctx->dispatch.BindRenderbuffer (GL_RENDERBUFFER, surface->msaa_rb); - - /* FIXME: For now we assume that textures passed from the outside have GL_RGBA - format, but eventually we need to expose a way for the API consumer to pass - this information. */ - ctx->dispatch.RenderbufferStorageMultisample (GL_RENDERBUFFER, - ctx->num_samples, - GL_RGBA, - surface->width, - surface->height); - ctx->dispatch.FramebufferRenderbuffer (GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, - GL_RENDERBUFFER, - surface->msaa_rb); - - /* Cairo surfaces start out initialized to transparent (black) */ - glDisable (GL_SCISSOR_TEST); - glClearColor (0, 0, 0, 0); - glClear (GL_COLOR_BUFFER_BIT); -} -#endif - -static cairo_bool_t -_cairo_gl_ensure_msaa_depth_stencil_buffer (cairo_gl_context_t *ctx, - cairo_gl_surface_t *surface) -{ - cairo_gl_dispatch_t *dispatch = &ctx->dispatch; - if (surface->msaa_depth_stencil) - return TRUE; - - _cairo_gl_ensure_framebuffer (ctx, surface); -#if CAIRO_HAS_GL_SURFACE - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) - _cairo_gl_ensure_multisampling (ctx, surface); -#endif - - dispatch->GenRenderbuffers (1, &surface->msaa_depth_stencil); - dispatch->BindRenderbuffer (GL_RENDERBUFFER, - surface->msaa_depth_stencil); - - dispatch->RenderbufferStorageMultisample (GL_RENDERBUFFER, - ctx->num_samples, - _get_depth_stencil_format (ctx), - surface->width, - surface->height); - -#if CAIRO_HAS_GL_SURFACE - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) { - dispatch->FramebufferRenderbuffer (GL_FRAMEBUFFER, - GL_DEPTH_STENCIL_ATTACHMENT, - GL_RENDERBUFFER, - surface->msaa_depth_stencil); - } -#endif - -#if CAIRO_HAS_GLESV2_SURFACE - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES) { - dispatch->FramebufferRenderbuffer (GL_FRAMEBUFFER, - GL_DEPTH_ATTACHMENT, - GL_RENDERBUFFER, - surface->msaa_depth_stencil); - dispatch->FramebufferRenderbuffer (GL_FRAMEBUFFER, - GL_STENCIL_ATTACHMENT, - GL_RENDERBUFFER, - surface->msaa_depth_stencil); - } -#endif - - if (dispatch->CheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - dispatch->DeleteRenderbuffers (1, &surface->msaa_depth_stencil); - surface->msaa_depth_stencil = 0; - return FALSE; - } - - return TRUE; -} - -static cairo_bool_t -_cairo_gl_ensure_depth_stencil_buffer (cairo_gl_context_t *ctx, - cairo_gl_surface_t *surface) -{ - cairo_gl_dispatch_t *dispatch = &ctx->dispatch; - - if (surface->depth_stencil) - return TRUE; - - _cairo_gl_ensure_framebuffer (ctx, surface); - - dispatch->GenRenderbuffers (1, &surface->depth_stencil); - dispatch->BindRenderbuffer (GL_RENDERBUFFER, surface->depth_stencil); - dispatch->RenderbufferStorage (GL_RENDERBUFFER, - _get_depth_stencil_format (ctx), - surface->width, surface->height); - - dispatch->FramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, - GL_RENDERBUFFER, surface->depth_stencil); - dispatch->FramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, - GL_RENDERBUFFER, surface->depth_stencil); - if (dispatch->CheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - dispatch->DeleteRenderbuffers (1, &surface->depth_stencil); - surface->depth_stencil = 0; - return FALSE; - } - - return TRUE; -} - -cairo_bool_t -_cairo_gl_ensure_stencil (cairo_gl_context_t *ctx, - cairo_gl_surface_t *surface) -{ - if (! _cairo_gl_surface_is_texture (surface)) - return TRUE; /* best guess for now, will check later */ - if (! ctx->has_packed_depth_stencil) - return FALSE; - - if (surface->msaa_active) - return _cairo_gl_ensure_msaa_depth_stencil_buffer (ctx, surface); - else - return _cairo_gl_ensure_depth_stencil_buffer (ctx, surface); -} - -/* - * Stores a parallel projection transformation in matrix 'm', - * using column-major order. - * - * This is equivalent to: - * - * glLoadIdentity() - * gluOrtho2D() - * - * The calculation for the ortho tranformation was taken from the - * mesa source code. - */ -static void -_gl_identity_ortho (GLfloat *m, - GLfloat left, GLfloat right, - GLfloat bottom, GLfloat top) -{ -#define M(row,col) m[col*4+row] - M(0,0) = 2.f / (right - left); - M(0,1) = 0.f; - M(0,2) = 0.f; - M(0,3) = -(right + left) / (right - left); - - M(1,0) = 0.f; - M(1,1) = 2.f / (top - bottom); - M(1,2) = 0.f; - M(1,3) = -(top + bottom) / (top - bottom); - - M(2,0) = 0.f; - M(2,1) = 0.f; - M(2,2) = -1.f; - M(2,3) = 0.f; - - M(3,0) = 0.f; - M(3,1) = 0.f; - M(3,2) = 0.f; - M(3,3) = 1.f; -#undef M -} - -#if CAIRO_HAS_GL_SURFACE -static void -bind_multisample_framebuffer (cairo_gl_context_t *ctx, - cairo_gl_surface_t *surface) -{ - cairo_bool_t stencil_test_enabled; - cairo_bool_t scissor_test_enabled; - - assert (surface->supports_msaa); - assert (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP); - - _cairo_gl_ensure_framebuffer (ctx, surface); - _cairo_gl_ensure_multisampling (ctx, surface); - - if (surface->msaa_active) { - glEnable (GL_MULTISAMPLE); - ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->msaa_fb); - return; - } - - _cairo_gl_composite_flush (ctx); - - stencil_test_enabled = glIsEnabled (GL_STENCIL_TEST); - scissor_test_enabled = glIsEnabled (GL_SCISSOR_TEST); - glDisable (GL_STENCIL_TEST); - glDisable (GL_SCISSOR_TEST); - - glEnable (GL_MULTISAMPLE); - - /* The last time we drew to the surface, we were not using multisampling, - so we need to blit from the non-multisampling framebuffer into the - multisampling framebuffer. */ - ctx->dispatch.BindFramebuffer (GL_DRAW_FRAMEBUFFER, surface->msaa_fb); - ctx->dispatch.BindFramebuffer (GL_READ_FRAMEBUFFER, surface->fb); - ctx->dispatch.BlitFramebuffer (0, 0, surface->width, surface->height, - 0, 0, surface->width, surface->height, - GL_COLOR_BUFFER_BIT, GL_NEAREST); - ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->msaa_fb); - - if (stencil_test_enabled) - glEnable (GL_STENCIL_TEST); - if (scissor_test_enabled) - glEnable (GL_SCISSOR_TEST); -} -#endif - -#if CAIRO_HAS_GL_SURFACE -static void -bind_singlesample_framebuffer (cairo_gl_context_t *ctx, - cairo_gl_surface_t *surface) -{ - cairo_bool_t stencil_test_enabled; - cairo_bool_t scissor_test_enabled; - - assert (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP); - _cairo_gl_ensure_framebuffer (ctx, surface); - - if (! surface->msaa_active) { - glDisable (GL_MULTISAMPLE); - ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->fb); - return; - } - - _cairo_gl_composite_flush (ctx); - - stencil_test_enabled = glIsEnabled (GL_STENCIL_TEST); - scissor_test_enabled = glIsEnabled (GL_SCISSOR_TEST); - glDisable (GL_STENCIL_TEST); - glDisable (GL_SCISSOR_TEST); - - glDisable (GL_MULTISAMPLE); - - /* The last time we drew to the surface, we were using multisampling, - so we need to blit from the multisampling framebuffer into the - non-multisampling framebuffer. */ - ctx->dispatch.BindFramebuffer (GL_DRAW_FRAMEBUFFER, surface->fb); - ctx->dispatch.BindFramebuffer (GL_READ_FRAMEBUFFER, surface->msaa_fb); - ctx->dispatch.BlitFramebuffer (0, 0, surface->width, surface->height, - 0, 0, surface->width, surface->height, - GL_COLOR_BUFFER_BIT, GL_NEAREST); - ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->fb); - - if (stencil_test_enabled) - glEnable (GL_STENCIL_TEST); - if (scissor_test_enabled) - glEnable (GL_SCISSOR_TEST); -} -#endif - -void -_cairo_gl_context_bind_framebuffer (cairo_gl_context_t *ctx, - cairo_gl_surface_t *surface, - cairo_bool_t multisampling) -{ - if (_cairo_gl_surface_is_texture (surface)) { - /* OpenGL ES surfaces only have either a multisample framebuffer or a - * singlesample framebuffer, so we cannot switch back and forth. */ - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES) { - _cairo_gl_ensure_framebuffer (ctx, surface); - ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, surface->fb); - return; - } - -#if CAIRO_HAS_GL_SURFACE - if (multisampling) - bind_multisample_framebuffer (ctx, surface); - else - bind_singlesample_framebuffer (ctx, surface); -#endif - } else { - ctx->dispatch.BindFramebuffer (GL_FRAMEBUFFER, 0); - -#if CAIRO_HAS_GL_SURFACE - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) { - if (multisampling) - glEnable (GL_MULTISAMPLE); - else - glDisable (GL_MULTISAMPLE); - } -#endif - } - - surface->msaa_active = multisampling; -} - -void -_cairo_gl_context_set_destination (cairo_gl_context_t *ctx, - cairo_gl_surface_t *surface, - cairo_bool_t multisampling) -{ - cairo_bool_t changing_surface, changing_sampling; - - /* The decision whether or not to use multisampling happens when - * we create an OpenGL ES surface, so we can never switch modes. */ - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES) - multisampling = surface->msaa_active; - - changing_surface = ctx->current_target != surface || surface->needs_update; - changing_sampling = surface->msaa_active != multisampling; - if (! changing_surface && ! changing_sampling) - return; - - if (! changing_surface) { - _cairo_gl_composite_flush (ctx); - _cairo_gl_context_bind_framebuffer (ctx, surface, multisampling); - return; - } - - _cairo_gl_composite_flush (ctx); - - ctx->current_target = surface; - surface->needs_update = FALSE; - - if (! _cairo_gl_surface_is_texture (surface)) { - ctx->make_current (ctx, surface); - } - - _cairo_gl_context_bind_framebuffer (ctx, surface, multisampling); - - if (! _cairo_gl_surface_is_texture (surface)) { -#if CAIRO_HAS_GL_SURFACE - glDrawBuffer (GL_BACK_LEFT); - glReadBuffer (GL_BACK_LEFT); -#endif - } - - glDisable (GL_DITHER); - glViewport (0, 0, surface->width, surface->height); - - if (_cairo_gl_surface_is_texture (surface)) - _gl_identity_ortho (ctx->modelviewprojection_matrix, - 0, surface->width, 0, surface->height); - else - _gl_identity_ortho (ctx->modelviewprojection_matrix, - 0, surface->width, surface->height, 0); -} - -void -cairo_gl_device_set_thread_aware (cairo_device_t *device, - cairo_bool_t thread_aware) -{ - if (device->backend->type != CAIRO_DEVICE_TYPE_GL) { - _cairo_error_throw (CAIRO_STATUS_DEVICE_TYPE_MISMATCH); - return; - } - ((cairo_gl_context_t *) device)->thread_aware = thread_aware; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-gl-dispatch-private.h b/source/libs/cairo/cairo-src/src/cairo-gl-dispatch-private.h deleted file mode 100644 index cabf76f0d6b57b9c4bc600cc3b044fd1e2454159..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-gl-dispatch-private.h +++ /dev/null @@ -1,129 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2010 Linaro Limited - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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. - * - * Contributor(s): - * Alexandros Frantzis <alexandros.frantzis@linaro.org> - */ - -#ifndef CAIRO_GL_DISPATCH_PRIVATE_H -#define CAIRO_GL_DISPATCH_PRIVATE_H - -#include "cairo-gl-private.h" -#include <stddef.h> - -typedef enum _cairo_gl_dispatch_name { - CAIRO_GL_DISPATCH_NAME_CORE, - CAIRO_GL_DISPATCH_NAME_EXT, - CAIRO_GL_DISPATCH_NAME_ES, - CAIRO_GL_DISPATCH_NAME_COUNT -} cairo_gl_dispatch_name_t; - -typedef struct _cairo_gl_dispatch_entry { - const char *name[CAIRO_GL_DISPATCH_NAME_COUNT]; - size_t offset; -} cairo_gl_dispatch_entry_t; - -#define DISPATCH_ENTRY_ARB(name) { { "gl"#name, "gl"#name"ARB", "gl"#name }, \ - offsetof(cairo_gl_dispatch_t, name) } -#define DISPATCH_ENTRY_EXT(name) { { "gl"#name, "gl"#name"EXT", "gl"#name }, \ - offsetof(cairo_gl_dispatch_t, name) } -#define DISPATCH_ENTRY_ARB_OES(name) { { "gl"#name, "gl"#name"ARB", "gl"#name"OES" }, \ - offsetof(cairo_gl_dispatch_t, name) } -#define DISPATCH_ENTRY_EXT_IMG(name) { { "gl"#name, "gl"#name"EXT", "gl"#name"IMG" }, \ - offsetof(cairo_gl_dispatch_t, name) } -#define DISPATCH_ENTRY_CUSTOM(name, name2) { { "gl"#name, "gl"#name2, "gl"#name }, \ - offsetof(cairo_gl_dispatch_t, name)} -#define DISPATCH_ENTRY_LAST { { NULL, NULL, NULL }, 0 } - -cairo_private cairo_gl_dispatch_entry_t dispatch_buffers_entries[] = { - DISPATCH_ENTRY_ARB (GenBuffers), - DISPATCH_ENTRY_ARB (BindBuffer), - DISPATCH_ENTRY_ARB (BufferData), - DISPATCH_ENTRY_ARB_OES (MapBuffer), - DISPATCH_ENTRY_ARB_OES (UnmapBuffer), - DISPATCH_ENTRY_LAST -}; - -cairo_private cairo_gl_dispatch_entry_t dispatch_shaders_entries[] = { - /* Shaders */ - DISPATCH_ENTRY_CUSTOM (CreateShader, CreateShaderObjectARB), - DISPATCH_ENTRY_ARB (ShaderSource), - DISPATCH_ENTRY_ARB (CompileShader), - DISPATCH_ENTRY_CUSTOM (GetShaderiv, GetObjectParameterivARB), - DISPATCH_ENTRY_CUSTOM (GetShaderInfoLog, GetInfoLogARB), - DISPATCH_ENTRY_CUSTOM (DeleteShader, DeleteObjectARB), - - /* Programs */ - DISPATCH_ENTRY_CUSTOM (CreateProgram, CreateProgramObjectARB), - DISPATCH_ENTRY_CUSTOM (AttachShader, AttachObjectARB), - DISPATCH_ENTRY_CUSTOM (DeleteProgram, DeleteObjectARB), - DISPATCH_ENTRY_ARB (LinkProgram), - DISPATCH_ENTRY_CUSTOM (UseProgram, UseProgramObjectARB), - DISPATCH_ENTRY_CUSTOM (GetProgramiv, GetObjectParameterivARB), - DISPATCH_ENTRY_CUSTOM (GetProgramInfoLog, GetInfoLogARB), - - /* Uniforms */ - DISPATCH_ENTRY_ARB (GetUniformLocation), - DISPATCH_ENTRY_ARB (Uniform1f), - DISPATCH_ENTRY_ARB (Uniform2f), - DISPATCH_ENTRY_ARB (Uniform3f), - DISPATCH_ENTRY_ARB (Uniform4f), - DISPATCH_ENTRY_ARB (UniformMatrix3fv), - DISPATCH_ENTRY_ARB (UniformMatrix4fv), - DISPATCH_ENTRY_ARB (Uniform1i), - - /* Attributes */ - DISPATCH_ENTRY_ARB (BindAttribLocation), - DISPATCH_ENTRY_ARB (VertexAttribPointer), - DISPATCH_ENTRY_ARB (EnableVertexAttribArray), - DISPATCH_ENTRY_ARB (DisableVertexAttribArray), - - DISPATCH_ENTRY_LAST -}; - -cairo_private cairo_gl_dispatch_entry_t dispatch_fbo_entries[] = { - DISPATCH_ENTRY_EXT (GenFramebuffers), - DISPATCH_ENTRY_EXT (BindFramebuffer), - DISPATCH_ENTRY_EXT (FramebufferTexture2D), - DISPATCH_ENTRY_EXT (CheckFramebufferStatus), - DISPATCH_ENTRY_EXT (DeleteFramebuffers), - DISPATCH_ENTRY_EXT (GenRenderbuffers), - DISPATCH_ENTRY_EXT (BindRenderbuffer), - DISPATCH_ENTRY_EXT (RenderbufferStorage), - DISPATCH_ENTRY_EXT (FramebufferRenderbuffer), - DISPATCH_ENTRY_EXT (DeleteRenderbuffers), - DISPATCH_ENTRY_EXT (BlitFramebuffer), - DISPATCH_ENTRY_LAST -}; - -cairo_private cairo_gl_dispatch_entry_t dispatch_multisampling_entries[] = { - DISPATCH_ENTRY_EXT_IMG (RenderbufferStorageMultisample), - DISPATCH_ENTRY_EXT_IMG (FramebufferTexture2DMultisample), - DISPATCH_ENTRY_LAST -}; - -#endif /* CAIRO_GL_DISPATCH_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-gl-dispatch.c b/source/libs/cairo/cairo-src/src/cairo-gl-dispatch.c deleted file mode 100644 index 76c3115ba377f44c98d8c689d14d26d1d79e4b82..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-gl-dispatch.c +++ /dev/null @@ -1,261 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2010 Linaro Limited - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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. - * - * Contributor(s): - * Alexandros Frantzis <alexandros.frantzis@linaro.org> - */ - -#include "cairoint.h" -#include "cairo-gl-private.h" -#include "cairo-gl-dispatch-private.h" -#if CAIRO_HAS_DLSYM -#include <dlfcn.h> -#endif - -#if CAIRO_HAS_DLSYM -static void * -_cairo_gl_dispatch_open_lib (void) -{ - return dlopen (NULL, RTLD_LAZY); -} - -static void -_cairo_gl_dispatch_close_lib (void *handle) -{ - dlclose (handle); -} - -static cairo_gl_generic_func_t -_cairo_gl_dispatch_get_proc_addr (void *handle, const char *name) -{ - return (cairo_gl_generic_func_t) dlsym (handle, name); -} -#else -static void * -_cairo_gl_dispatch_open_lib (void) -{ - return NULL; -} - -static void -_cairo_gl_dispatch_close_lib (void *handle) -{ - return; -} - -static cairo_gl_generic_func_t -_cairo_gl_dispatch_get_proc_addr (void *handle, const char *name) -{ - return NULL; -} -#endif /* CAIRO_HAS_DLSYM */ - - -static void -_cairo_gl_dispatch_init_entries (cairo_gl_dispatch_t *dispatch, - cairo_gl_get_proc_addr_func_t get_proc_addr, - cairo_gl_dispatch_entry_t *entries, - cairo_gl_dispatch_name_t dispatch_name) -{ - cairo_gl_dispatch_entry_t *entry = entries; - void *handle = _cairo_gl_dispatch_open_lib (); - - while (entry->name[CAIRO_GL_DISPATCH_NAME_CORE] != NULL) { - void *dispatch_ptr = &((char *) dispatch)[entry->offset]; - const char *name = entry->name[dispatch_name]; - - /* - * In strictly conforming EGL implementations, eglGetProcAddress() can - * be used only to get extension functions, but some of the functions - * we want belong to core GL(ES). If the *GetProcAddress function - * provided by the context fails, try to get the address of the wanted - * GL function using standard system facilities (eg dlsym() in *nix - * systems). - */ - cairo_gl_generic_func_t func = get_proc_addr (name); - if (func == NULL) - func = _cairo_gl_dispatch_get_proc_addr (handle, name); - - *((cairo_gl_generic_func_t *) dispatch_ptr) = func; - - ++entry; - } - - _cairo_gl_dispatch_close_lib (handle); -} - -static cairo_status_t -_cairo_gl_dispatch_init_buffers (cairo_gl_dispatch_t *dispatch, - cairo_gl_get_proc_addr_func_t get_proc_addr, - int gl_version, cairo_gl_flavor_t gl_flavor) -{ - cairo_gl_dispatch_name_t dispatch_name; - - if (gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) - { - if (gl_version >= CAIRO_GL_VERSION_ENCODE (1, 5)) - dispatch_name = CAIRO_GL_DISPATCH_NAME_CORE; - else if (_cairo_gl_has_extension ("GL_ARB_vertex_buffer_object")) - dispatch_name = CAIRO_GL_DISPATCH_NAME_EXT; - else - return CAIRO_STATUS_DEVICE_ERROR; - } - else if (gl_flavor == CAIRO_GL_FLAVOR_ES && - gl_version >= CAIRO_GL_VERSION_ENCODE (2, 0)) - { - dispatch_name = CAIRO_GL_DISPATCH_NAME_ES; - } - else - { - return CAIRO_STATUS_DEVICE_ERROR; - } - - _cairo_gl_dispatch_init_entries (dispatch, get_proc_addr, - dispatch_buffers_entries, dispatch_name); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_gl_dispatch_init_shaders (cairo_gl_dispatch_t *dispatch, - cairo_gl_get_proc_addr_func_t get_proc_addr, - int gl_version, cairo_gl_flavor_t gl_flavor) -{ - cairo_gl_dispatch_name_t dispatch_name; - - if (gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) - { - if (gl_version >= CAIRO_GL_VERSION_ENCODE (2, 0)) - dispatch_name = CAIRO_GL_DISPATCH_NAME_CORE; - else if (_cairo_gl_has_extension ("GL_ARB_shader_objects")) - dispatch_name = CAIRO_GL_DISPATCH_NAME_EXT; - else - return CAIRO_STATUS_DEVICE_ERROR; - } - else if (gl_flavor == CAIRO_GL_FLAVOR_ES && - gl_version >= CAIRO_GL_VERSION_ENCODE (2, 0)) - { - dispatch_name = CAIRO_GL_DISPATCH_NAME_ES; - } - else - { - return CAIRO_STATUS_DEVICE_ERROR; - } - - _cairo_gl_dispatch_init_entries (dispatch, get_proc_addr, - dispatch_shaders_entries, dispatch_name); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_gl_dispatch_init_fbo (cairo_gl_dispatch_t *dispatch, - cairo_gl_get_proc_addr_func_t get_proc_addr, - int gl_version, cairo_gl_flavor_t gl_flavor) -{ - cairo_gl_dispatch_name_t dispatch_name; - - if (gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) - { - if (gl_version >= CAIRO_GL_VERSION_ENCODE (3, 0) || - _cairo_gl_has_extension ("GL_ARB_framebuffer_object")) - dispatch_name = CAIRO_GL_DISPATCH_NAME_CORE; - else if (_cairo_gl_has_extension ("GL_EXT_framebuffer_object")) - dispatch_name = CAIRO_GL_DISPATCH_NAME_EXT; - else - return CAIRO_STATUS_DEVICE_ERROR; - } - else if (gl_flavor == CAIRO_GL_FLAVOR_ES && - gl_version >= CAIRO_GL_VERSION_ENCODE (2, 0)) - { - dispatch_name = CAIRO_GL_DISPATCH_NAME_ES; - } - else - { - return CAIRO_STATUS_DEVICE_ERROR; - } - - _cairo_gl_dispatch_init_entries (dispatch, get_proc_addr, - dispatch_fbo_entries, dispatch_name); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_gl_dispatch_init_multisampling (cairo_gl_dispatch_t *dispatch, - cairo_gl_get_proc_addr_func_t get_proc_addr, - int gl_version, - cairo_gl_flavor_t gl_flavor) -{ - /* For the multisampling table, there are two GLES versions of the - * extension, so we put one in the EXT slot and one in the real ES slot.*/ - cairo_gl_dispatch_name_t dispatch_name = CAIRO_GL_DISPATCH_NAME_CORE; - if (gl_flavor == CAIRO_GL_FLAVOR_ES) { - if (_cairo_gl_has_extension ("GL_EXT_multisampled_render_to_texture")) - dispatch_name = CAIRO_GL_DISPATCH_NAME_EXT; - else if (_cairo_gl_has_extension ("GL_IMG_multisampled_render_to_texture")) - dispatch_name = CAIRO_GL_DISPATCH_NAME_ES; - } - _cairo_gl_dispatch_init_entries (dispatch, get_proc_addr, - dispatch_multisampling_entries, - dispatch_name); - return CAIRO_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_gl_dispatch_init (cairo_gl_dispatch_t *dispatch, - cairo_gl_get_proc_addr_func_t get_proc_addr) -{ - cairo_status_t status; - int gl_version; - cairo_gl_flavor_t gl_flavor; - - gl_version = _cairo_gl_get_version (); - gl_flavor = _cairo_gl_get_flavor (); - - status = _cairo_gl_dispatch_init_buffers (dispatch, get_proc_addr, - gl_version, gl_flavor); - if (status != CAIRO_STATUS_SUCCESS) - return status; - - status = _cairo_gl_dispatch_init_shaders (dispatch, get_proc_addr, - gl_version, gl_flavor); - if (status != CAIRO_STATUS_SUCCESS) - return status; - - status = _cairo_gl_dispatch_init_fbo (dispatch, get_proc_addr, - gl_version, gl_flavor); - if (status != CAIRO_STATUS_SUCCESS) - return status; - - status = _cairo_gl_dispatch_init_multisampling (dispatch, get_proc_addr, - gl_version, gl_flavor); - if (status != CAIRO_STATUS_SUCCESS) - return status; - - return CAIRO_STATUS_SUCCESS; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-gl-ext-def-private.h b/source/libs/cairo/cairo-src/src/cairo-gl-ext-def-private.h deleted file mode 100644 index a261947bef070acb0cde80d122abe5139a31e813..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-gl-ext-def-private.h +++ /dev/null @@ -1,143 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2010 Linaro Limited - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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. - * - * Contributor(s): - * Alexandros Frantzis <alexandros.frantzis@linaro.org> - */ - -#ifndef CAIRO_GL_EXT_DEF_PRIVATE_H -#define CAIRO_GL_EXT_DEF_PRIVATE_H - -#ifndef GL_TEXTURE_RECTANGLE -#define GL_TEXTURE_RECTANGLE 0x84F5 -#endif - -#ifndef GL_ARRAY_BUFFER -#define GL_ARRAY_BUFFER 0x8892 -#endif - -#ifndef GL_STREAM_DRAW -#define GL_STREAM_DRAW 0x88E0 -#endif - -#ifndef GL_WRITE_ONLY -#define GL_WRITE_ONLY 0x88B9 -#endif - -#ifndef GL_PIXEL_UNPACK_BUFFER -#define GL_PIXEL_UNPACK_BUFFER 0x88EC -#endif - -#ifndef GL_FRAMEBUFFER -#define GL_FRAMEBUFFER 0x8D40 -#endif - -#ifndef GL_COLOR_ATTACHMENT0 -#define GL_COLOR_ATTACHMENT0 0x8CE0 -#endif - -#ifndef GL_FRAMEBUFFER_COMPLETE -#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 -#endif - -#ifndef GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 -#endif - -#ifndef GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 -#endif - -#ifndef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS -#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 -#endif - -#ifndef GL_FRAMEBUFFER_INCOMPLETE_FORMATS -#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS 0x8CDA -#endif - -#ifndef GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER -#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB -#endif - -#ifndef GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER -#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC -#endif - -#ifndef GL_FRAMEBUFFER_UNSUPPORTED -#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD -#endif - -#ifndef GL_PACK_INVERT_MESA -#define GL_PACK_INVERT_MESA 0x8758 -#endif - -#ifndef GL_CLAMP_TO_BORDER -#define GL_CLAMP_TO_BORDER 0x812D -#endif - -#ifndef GL_BGR -#define GL_BGR 0x80E0 -#endif - -#ifndef GL_BGRA -#define GL_BGRA 0x80E1 -#endif - -#ifndef GL_RGBA8 -#define GL_RGBA8 0x8058 -#endif - -#ifndef GL_UNSIGNED_INT_8_8_8_8 -#define GL_UNSIGNED_INT_8_8_8_8 0x8035 -#endif - -#ifndef GL_UNSIGNED_SHORT_5_6_5_REV -#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 -#endif - -#ifndef GL_UNSIGNED_SHORT_1_5_5_5_REV -#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 -#endif - -#ifndef GL_UNSIGNED_INT_8_8_8_8_REV -#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 -#endif - -#ifndef GL_PACK_ROW_LENGTH -#define GL_PACK_ROW_LENGTH 0x0D02 -#endif - -#ifndef GL_UNPACK_ROW_LENGTH -#define GL_UNPACK_ROW_LENGTH 0x0CF2 -#endif - -#ifndef GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 -#endif - -#endif /* CAIRO_GL_EXT_DEF_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-gl-glyphs.c b/source/libs/cairo/cairo-src/src/cairo-gl-glyphs.c deleted file mode 100644 index 8a1a548d939718c83f9fa493d251301b841f6e3a..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-gl-glyphs.c +++ /dev/null @@ -1,503 +0,0 @@ -/* Cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Chris Wilson - * Copyright © 2010 Intel Corporation - * Copyright © 2010 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Chris Wilson. - * - * Contributors: - * Benjamin Otte <otte@gnome.org> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-gl-private.h" - -#include "cairo-compositor-private.h" -#include "cairo-composite-rectangles-private.h" -#include "cairo-error-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-rtree-private.h" - -#define GLYPH_CACHE_WIDTH 1024 -#define GLYPH_CACHE_HEIGHT 1024 -#define GLYPH_CACHE_MIN_SIZE 4 -#define GLYPH_CACHE_MAX_SIZE 128 - -typedef struct _cairo_gl_glyph { - cairo_rtree_node_t node; - cairo_scaled_glyph_private_t base; - cairo_scaled_glyph_t *glyph; - cairo_gl_glyph_cache_t *cache; - struct { float x, y; } p1, p2; -} cairo_gl_glyph_t; - -static void -_cairo_gl_node_destroy (cairo_rtree_node_t *node) -{ - cairo_gl_glyph_t *priv = cairo_container_of (node, cairo_gl_glyph_t, node); - cairo_scaled_glyph_t *glyph; - - glyph = priv->glyph; - if (glyph == NULL) - return; - - if (glyph->dev_private_key == priv->cache) { - glyph->dev_private = NULL; - glyph->dev_private_key = NULL; - } - cairo_list_del (&priv->base.link); - priv->glyph = NULL; -} - -static void -_cairo_gl_glyph_fini (cairo_scaled_glyph_private_t *glyph_private, - cairo_scaled_glyph_t *scaled_glyph, - cairo_scaled_font_t *scaled_font) -{ - cairo_gl_glyph_t *priv = cairo_container_of (glyph_private, - cairo_gl_glyph_t, - base); - - assert (priv->glyph); - - _cairo_gl_node_destroy (&priv->node); - - /* XXX thread-safety? Probably ok due to the frozen scaled-font. */ - if (! priv->node.pinned) - _cairo_rtree_node_remove (&priv->cache->rtree, &priv->node); - - assert (priv->glyph == NULL); -} - -static cairo_int_status_t -_cairo_gl_glyph_cache_add_glyph (cairo_gl_context_t *ctx, - cairo_gl_glyph_cache_t *cache, - cairo_scaled_glyph_t *scaled_glyph) -{ - cairo_image_surface_t *glyph_surface = scaled_glyph->surface; - cairo_gl_glyph_t *glyph_private; - cairo_rtree_node_t *node = NULL; - cairo_int_status_t status; - int width, height; - - width = glyph_surface->width; - if (width < GLYPH_CACHE_MIN_SIZE) - width = GLYPH_CACHE_MIN_SIZE; - height = glyph_surface->height; - if (height < GLYPH_CACHE_MIN_SIZE) - height = GLYPH_CACHE_MIN_SIZE; - - /* search for an available slot */ - status = _cairo_rtree_insert (&cache->rtree, width, height, &node); - /* search for an unlocked slot */ - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - status = _cairo_rtree_evict_random (&cache->rtree, - width, height, &node); - if (status == CAIRO_INT_STATUS_SUCCESS) { - status = _cairo_rtree_node_insert (&cache->rtree, - node, width, height, &node); - } - } - if (status) - return status; - - /* XXX: Make sure we use the mask texture. This should work automagically somehow */ - glActiveTexture (GL_TEXTURE1); - status = _cairo_gl_surface_draw_image (cache->surface, glyph_surface, - 0, 0, - glyph_surface->width, glyph_surface->height, - node->x, node->y, FALSE); - if (unlikely (status)) - return status; - - glyph_private = (cairo_gl_glyph_t *) node; - glyph_private->cache = cache; - glyph_private->glyph = scaled_glyph; - _cairo_scaled_glyph_attach_private (scaled_glyph, - &glyph_private->base, - cache, - _cairo_gl_glyph_fini); - - scaled_glyph->dev_private = glyph_private; - scaled_glyph->dev_private_key = cache; - - /* compute tex coords */ - glyph_private->p1.x = node->x; - glyph_private->p1.y = node->y; - glyph_private->p2.x = node->x + glyph_surface->width; - glyph_private->p2.y = node->y + glyph_surface->height; - if (! _cairo_gl_device_requires_power_of_two_textures (&ctx->base)) { - glyph_private->p1.x /= GLYPH_CACHE_WIDTH; - glyph_private->p2.x /= GLYPH_CACHE_WIDTH; - glyph_private->p1.y /= GLYPH_CACHE_HEIGHT; - glyph_private->p2.y /= GLYPH_CACHE_HEIGHT; - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_gl_glyph_t * -_cairo_gl_glyph_cache_lock (cairo_gl_glyph_cache_t *cache, - cairo_scaled_glyph_t *scaled_glyph) -{ - return _cairo_rtree_pin (&cache->rtree, scaled_glyph->dev_private); -} - -static cairo_status_t -cairo_gl_context_get_glyph_cache (cairo_gl_context_t *ctx, - cairo_format_t format, - cairo_gl_glyph_cache_t **cache_out) -{ - cairo_gl_glyph_cache_t *cache; - cairo_content_t content; - - switch (format) { - case CAIRO_FORMAT_RGB30: - case CAIRO_FORMAT_RGB16_565: - case CAIRO_FORMAT_ARGB32: - case CAIRO_FORMAT_RGB24: - cache = &ctx->glyph_cache[0]; - content = CAIRO_CONTENT_COLOR_ALPHA; - break; - case CAIRO_FORMAT_A8: - case CAIRO_FORMAT_A1: - cache = &ctx->glyph_cache[1]; - content = CAIRO_CONTENT_ALPHA; - break; - default: - case CAIRO_FORMAT_INVALID: - ASSERT_NOT_REACHED; - return _cairo_error (CAIRO_STATUS_INVALID_FORMAT); - } - - if (unlikely (cache->surface == NULL)) { - cairo_surface_t *surface; - - surface = _cairo_gl_surface_create_scratch_for_caching (ctx, - content, - GLYPH_CACHE_WIDTH, - GLYPH_CACHE_HEIGHT); - if (unlikely (surface->status)) - return surface->status; - - _cairo_surface_release_device_reference (surface); - - cache->surface = (cairo_gl_surface_t *)surface; - cache->surface->operand.texture.attributes.has_component_alpha = - content == CAIRO_CONTENT_COLOR_ALPHA; - } - - *cache_out = cache; - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -render_glyphs (cairo_gl_surface_t *dst, - int dst_x, int dst_y, - cairo_operator_t op, - cairo_surface_t *source, - cairo_composite_glyphs_info_t *info, - cairo_bool_t *has_component_alpha, - cairo_clip_t *clip) -{ - cairo_format_t last_format = CAIRO_FORMAT_INVALID; - cairo_gl_glyph_cache_t *cache = NULL; - cairo_gl_context_t *ctx; - cairo_gl_emit_glyph_t emit = NULL; - cairo_gl_composite_t setup; - cairo_int_status_t status; - int i = 0; - - TRACE ((stderr, "%s (%d, %d)x(%d, %d)\n", __FUNCTION__, - info->extents.x, info->extents.y, - info->extents.width, info->extents.height)); - - *has_component_alpha = FALSE; - - status = _cairo_gl_context_acquire (dst->base.device, &ctx); - if (unlikely (status)) - return status; - - status = _cairo_gl_composite_init (&setup, op, dst, TRUE); - if (unlikely (status)) - goto FINISH; - - if (source == NULL) { - _cairo_gl_composite_set_solid_source (&setup, CAIRO_COLOR_WHITE); - } else { - _cairo_gl_composite_set_source_operand (&setup, - source_to_operand (source)); - - } - - _cairo_gl_composite_set_clip (&setup, clip); - - for (i = 0; i < info->num_glyphs; i++) { - cairo_scaled_glyph_t *scaled_glyph; - cairo_gl_glyph_t *glyph; - double x_offset, y_offset; - double x1, x2, y1, y2; - - status = _cairo_scaled_glyph_lookup (info->font, - info->glyphs[i].index, - CAIRO_SCALED_GLYPH_INFO_SURFACE, - &scaled_glyph); - if (unlikely (status)) - goto FINISH; - - if (scaled_glyph->surface->width == 0 || - scaled_glyph->surface->height == 0) - { - continue; - } - if (scaled_glyph->surface->format != last_format) { - status = cairo_gl_context_get_glyph_cache (ctx, - scaled_glyph->surface->format, - &cache); - if (unlikely (status)) - goto FINISH; - - last_format = scaled_glyph->surface->format; - - _cairo_gl_composite_set_mask_operand (&setup, &cache->surface->operand); - *has_component_alpha |= cache->surface->operand.texture.attributes.has_component_alpha; - - /* XXX Shoot me. */ - status = _cairo_gl_composite_begin (&setup, &ctx); - status = _cairo_gl_context_release (ctx, status); - if (unlikely (status)) - goto FINISH; - - emit = _cairo_gl_context_choose_emit_glyph (ctx); - } - - if (scaled_glyph->dev_private_key != cache) { - cairo_scaled_glyph_private_t *priv; - - priv = _cairo_scaled_glyph_find_private (scaled_glyph, cache); - if (priv) { - scaled_glyph->dev_private_key = cache; - scaled_glyph->dev_private = cairo_container_of (priv, - cairo_gl_glyph_t, - base); - } else { - status = _cairo_gl_glyph_cache_add_glyph (ctx, cache, scaled_glyph); - - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - /* Cache is full, so flush existing prims and try again. */ - _cairo_gl_composite_flush (ctx); - _cairo_gl_glyph_cache_unlock (cache); - status = _cairo_gl_glyph_cache_add_glyph (ctx, cache, scaled_glyph); - } - - if (unlikely (_cairo_int_status_is_error (status))) - goto FINISH; - } - } - - x_offset = scaled_glyph->surface->base.device_transform.x0; - y_offset = scaled_glyph->surface->base.device_transform.y0; - - x1 = _cairo_lround (info->glyphs[i].x - x_offset - dst_x); - y1 = _cairo_lround (info->glyphs[i].y - y_offset - dst_y); - x2 = x1 + scaled_glyph->surface->width; - y2 = y1 + scaled_glyph->surface->height; - - glyph = _cairo_gl_glyph_cache_lock (cache, scaled_glyph); - assert (emit); - emit (ctx, - x1, y1, x2, y2, - glyph->p1.x, glyph->p1.y, - glyph->p2.x, glyph->p2.y); - } - - status = CAIRO_STATUS_SUCCESS; - FINISH: - status = _cairo_gl_context_release (ctx, status); - - _cairo_gl_composite_fini (&setup); - return status; -} - -static cairo_int_status_t -render_glyphs_via_mask (cairo_gl_surface_t *dst, - int dst_x, int dst_y, - cairo_operator_t op, - cairo_surface_t *source, - cairo_composite_glyphs_info_t *info, - cairo_clip_t *clip) -{ - cairo_surface_t *mask; - cairo_status_t status; - cairo_bool_t has_component_alpha; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - /* XXX: For non-CA, this should be CAIRO_CONTENT_ALPHA to save memory */ - mask = cairo_gl_surface_create (dst->base.device, - CAIRO_CONTENT_COLOR_ALPHA, - info->extents.width, - info->extents.height); - if (unlikely (mask->status)) - return mask->status; - - status = render_glyphs ((cairo_gl_surface_t *) mask, - info->extents.x, info->extents.y, - CAIRO_OPERATOR_ADD, NULL, - info, &has_component_alpha, NULL); - if (likely (status == CAIRO_STATUS_SUCCESS)) { - cairo_surface_pattern_t mask_pattern; - cairo_surface_pattern_t source_pattern; - cairo_rectangle_int_t clip_extents; - - mask->is_clear = FALSE; - _cairo_pattern_init_for_surface (&mask_pattern, mask); - mask_pattern.base.has_component_alpha = has_component_alpha; - mask_pattern.base.filter = CAIRO_FILTER_NEAREST; - mask_pattern.base.extend = CAIRO_EXTEND_NONE; - - cairo_matrix_init_translate (&mask_pattern.base.matrix, - dst_x-info->extents.x, dst_y-info->extents.y); - - _cairo_pattern_init_for_surface (&source_pattern, source); - cairo_matrix_init_translate (&source_pattern.base.matrix, - dst_x-info->extents.x, dst_y-info->extents.y); - - clip = _cairo_clip_copy (clip); - clip_extents.x = info->extents.x - dst_x; - clip_extents.y = info->extents.y - dst_y; - clip_extents.width = info->extents.width; - clip_extents.height = info->extents.height; - clip = _cairo_clip_intersect_rectangle (clip, &clip_extents); - - status = _cairo_surface_mask (&dst->base, op, - &source_pattern.base, - &mask_pattern.base, - clip); - - _cairo_clip_destroy (clip); - - _cairo_pattern_fini (&mask_pattern.base); - _cairo_pattern_fini (&source_pattern.base); - } - - cairo_surface_destroy (mask); - - return status; -} - -cairo_int_status_t -_cairo_gl_check_composite_glyphs (const cairo_composite_rectangles_t *extents, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int *num_glyphs) -{ - if (! _cairo_gl_operator_is_supported (extents->op)) - return UNSUPPORTED ("unsupported operator"); - - /* XXX use individual masks for large glyphs? */ - if (ceil (scaled_font->max_scale) >= GLYPH_CACHE_MAX_SIZE) - return UNSUPPORTED ("glyphs too large"); - - return CAIRO_STATUS_SUCCESS; -} - -cairo_int_status_t -_cairo_gl_composite_glyphs_with_clip (void *_dst, - cairo_operator_t op, - cairo_surface_t *_src, - int src_x, - int src_y, - int dst_x, - int dst_y, - cairo_composite_glyphs_info_t *info, - cairo_clip_t *clip) -{ - cairo_gl_surface_t *dst = _dst; - cairo_bool_t has_component_alpha; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - /* If any of the glyphs require component alpha, we have to go through - * a mask, since only _cairo_gl_surface_composite() currently supports - * component alpha. - */ - if (!dst->base.is_clear && ! info->use_mask && op != CAIRO_OPERATOR_OVER && - (info->font->options.antialias == CAIRO_ANTIALIAS_SUBPIXEL || - info->font->options.antialias == CAIRO_ANTIALIAS_BEST)) - { - info->use_mask = TRUE; - } - - if (info->use_mask) { - return render_glyphs_via_mask (dst, dst_x, dst_y, - op, _src, info, clip); - } else { - return render_glyphs (dst, dst_x, dst_y, - op, _src, info, - &has_component_alpha, - clip); - } - -} - -cairo_int_status_t -_cairo_gl_composite_glyphs (void *_dst, - cairo_operator_t op, - cairo_surface_t *_src, - int src_x, - int src_y, - int dst_x, - int dst_y, - cairo_composite_glyphs_info_t *info) -{ - return _cairo_gl_composite_glyphs_with_clip (_dst, op, _src, src_x, src_y, - dst_x, dst_y, info, NULL); -} - -void -_cairo_gl_glyph_cache_init (cairo_gl_glyph_cache_t *cache) -{ - _cairo_rtree_init (&cache->rtree, - GLYPH_CACHE_WIDTH, - GLYPH_CACHE_HEIGHT, - GLYPH_CACHE_MIN_SIZE, - sizeof (cairo_gl_glyph_t), - _cairo_gl_node_destroy); -} - -void -_cairo_gl_glyph_cache_fini (cairo_gl_context_t *ctx, - cairo_gl_glyph_cache_t *cache) -{ - _cairo_rtree_fini (&cache->rtree); - cairo_surface_destroy (&cache->surface->base); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-gl-gradient-private.h b/source/libs/cairo/cairo-src/src/cairo-gl-gradient-private.h deleted file mode 100644 index 77f9bbdc5f5423224e9e833a57f6d711468dc2be..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-gl-gradient-private.h +++ /dev/null @@ -1,93 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Eric Anholt - * Copyright © 2009 Chris Wilson - * Copyright © 2005,2010 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Benjamin Otte <otte@gnome.org> - * Carl Worth <cworth@cworth.org> - * Chris Wilson <chris@chris-wilson.co.uk> - * Eric Anholt <eric@anholt.net> - */ - -#ifndef CAIRO_GL_GRADIENT_PRIVATE_H -#define CAIRO_GL_GRADIENT_PRIVATE_H - -#define GL_GLEXT_PROTOTYPES - -#include "cairo-cache-private.h" -#include "cairo-device-private.h" -#include "cairo-reference-count-private.h" -#include "cairo-pattern-private.h" -#include "cairo-types-private.h" - -#include "cairo-gl.h" - -#if CAIRO_HAS_GL_SURFACE -#include <GL/gl.h> -#include <GL/glext.h> -#elif CAIRO_HAS_GLESV2_SURFACE -#include <GLES2/gl2.h> -#include <GLES2/gl2ext.h> -#endif - -#define CAIRO_GL_GRADIENT_CACHE_SIZE 4096 - -/* XXX: Declare in a better place */ -typedef struct _cairo_gl_context cairo_gl_context_t; - -typedef struct _cairo_gl_gradient { - cairo_cache_entry_t cache_entry; - cairo_reference_count_t ref_count; - cairo_device_t *device; /* NB: we don't hold a reference */ - GLuint tex; - unsigned int n_stops; - const cairo_gradient_stop_t *stops; - cairo_gradient_stop_t stops_embedded[1]; -} cairo_gl_gradient_t; - -cairo_private cairo_int_status_t -_cairo_gl_gradient_create (cairo_gl_context_t *ctx, - unsigned int n_stops, - const cairo_gradient_stop_t *stops, - cairo_gl_gradient_t **gradient_out); - -cairo_private_no_warn cairo_gl_gradient_t * -_cairo_gl_gradient_reference (cairo_gl_gradient_t *gradient); - -cairo_private void -_cairo_gl_gradient_destroy (cairo_gl_gradient_t *gradient); - -cairo_private cairo_bool_t -_cairo_gl_gradient_equal (const void *key_a, const void *key_b); - - -#endif /* CAIRO_GL_GRADIENT_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-gl-gradient.c b/source/libs/cairo/cairo-src/src/cairo-gl-gradient.c deleted file mode 100644 index ac3292101eca19588523a4dfee971656c4a5ab59..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-gl-gradient.c +++ /dev/null @@ -1,338 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Eric Anholt - * Copyright © 2009 Chris Wilson - * Copyright © 2005,2010 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Benjamin Otte <otte@gnome.org> - * Carl Worth <cworth@cworth.org> - * Chris Wilson <chris@chris-wilson.co.uk> - * Eric Anholt <eric@anholt.net> - */ - -#include "cairoint.h" - -#include "cairo-error-private.h" -#include "cairo-gl-gradient-private.h" -#include "cairo-gl-private.h" - - -static int -_cairo_gl_gradient_sample_width (unsigned int n_stops, - const cairo_gradient_stop_t *stops) -{ - unsigned int n; - int width; - - width = 8; - for (n = 1; n < n_stops; n++) { - double dx = stops[n].offset - stops[n-1].offset; - double delta, max; - int ramp; - - if (dx == 0) - return 1024; /* we need to emulate an infinitely sharp step */ - - max = fabs (stops[n].color.red - stops[n-1].color.red); - - delta = fabs (stops[n].color.green - stops[n-1].color.green); - if (delta > max) - max = delta; - - delta = fabs (stops[n].color.blue - stops[n-1].color.blue); - if (delta > max) - max = delta; - - delta = fabs (stops[n].color.alpha - stops[n-1].color.alpha); - if (delta > max) - max = delta; - - ramp = 128 * max / dx; - if (ramp > width) - width = ramp; - } - - return (width + 7) & -8; -} - -static uint8_t premultiply(double c, double a) -{ - int v = c * a * 256; - return v - (v >> 8); -} - -static uint32_t color_stop_to_pixel(const cairo_gradient_stop_t *stop) -{ - uint8_t a, r, g, b; - - a = stop->color.alpha_short >> 8; - r = premultiply(stop->color.red, stop->color.alpha); - g = premultiply(stop->color.green, stop->color.alpha); - b = premultiply(stop->color.blue, stop->color.alpha); - - if (_cairo_is_little_endian ()) - return a << 24 | r << 16 | g << 8 | b << 0; - else - return a << 0 | r << 8 | g << 16 | b << 24; -} - -static cairo_status_t -_cairo_gl_gradient_render (const cairo_gl_context_t *ctx, - unsigned int n_stops, - const cairo_gradient_stop_t *stops, - void *bytes, - int width) -{ - pixman_image_t *gradient, *image; - pixman_gradient_stop_t pixman_stops_stack[32]; - pixman_gradient_stop_t *pixman_stops; - pixman_point_fixed_t p1, p2; - unsigned int i; - pixman_format_code_t gradient_pixman_format; - - /* - * Ensure that the order of the gradient's components in memory is BGRA. - * This is done so that the gradient's pixel data is always suitable for - * texture upload using format=GL_BGRA and type=GL_UNSIGNED_BYTE. - */ - if (_cairo_is_little_endian ()) - gradient_pixman_format = PIXMAN_a8r8g8b8; - else - gradient_pixman_format = PIXMAN_b8g8r8a8; - - pixman_stops = pixman_stops_stack; - if (unlikely (n_stops > ARRAY_LENGTH (pixman_stops_stack))) { - pixman_stops = _cairo_malloc_ab (n_stops, - sizeof (pixman_gradient_stop_t)); - if (unlikely (pixman_stops == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - for (i = 0; i < n_stops; i++) { - pixman_stops[i].x = _cairo_fixed_16_16_from_double (stops[i].offset); - pixman_stops[i].color.red = stops[i].color.red_short; - pixman_stops[i].color.green = stops[i].color.green_short; - pixman_stops[i].color.blue = stops[i].color.blue_short; - pixman_stops[i].color.alpha = stops[i].color.alpha_short; - } - - p1.x = _cairo_fixed_16_16_from_double (0.5); - p1.y = 0; - p2.x = _cairo_fixed_16_16_from_double (width - 0.5); - p2.y = 0; - - gradient = pixman_image_create_linear_gradient (&p1, &p2, - pixman_stops, - n_stops); - if (pixman_stops != pixman_stops_stack) - free (pixman_stops); - - if (unlikely (gradient == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - pixman_image_set_filter (gradient, PIXMAN_FILTER_BILINEAR, NULL, 0); - pixman_image_set_repeat (gradient, PIXMAN_REPEAT_PAD); - - image = pixman_image_create_bits (gradient_pixman_format, width, 1, - bytes, sizeof(uint32_t)*width); - if (unlikely (image == NULL)) { - pixman_image_unref (gradient); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - pixman_image_composite32 (PIXMAN_OP_SRC, - gradient, NULL, image, - 0, 0, - 0, 0, - 0, 0, - width, 1); - - pixman_image_unref (gradient); - pixman_image_unref (image); - - /* We need to fudge pixel 0 to hold the left-most color stop and not - * the neareset stop to the zeroth pixel centre in order to correctly - * populate the border color. For completeness, do both edges. - */ - ((uint32_t*)bytes)[0] = color_stop_to_pixel(&stops[0]); - ((uint32_t*)bytes)[width-1] = color_stop_to_pixel(&stops[n_stops-1]); - - return CAIRO_STATUS_SUCCESS; -} - -static unsigned long -_cairo_gl_gradient_hash (unsigned int n_stops, - const cairo_gradient_stop_t *stops) -{ - return _cairo_hash_bytes (n_stops, - stops, - sizeof (cairo_gradient_stop_t) * n_stops); -} - -static cairo_gl_gradient_t * -_cairo_gl_gradient_lookup (cairo_gl_context_t *ctx, - unsigned long hash, - unsigned int n_stops, - const cairo_gradient_stop_t *stops) -{ - cairo_gl_gradient_t lookup; - - lookup.cache_entry.hash = hash, - lookup.n_stops = n_stops; - lookup.stops = stops; - - return _cairo_cache_lookup (&ctx->gradients, &lookup.cache_entry); -} - -cairo_bool_t -_cairo_gl_gradient_equal (const void *key_a, const void *key_b) -{ - const cairo_gl_gradient_t *a = key_a; - const cairo_gl_gradient_t *b = key_b; - - if (a->n_stops != b->n_stops) - return FALSE; - - return memcmp (a->stops, b->stops, a->n_stops * sizeof (cairo_gradient_stop_t)) == 0; -} - -cairo_int_status_t -_cairo_gl_gradient_create (cairo_gl_context_t *ctx, - unsigned int n_stops, - const cairo_gradient_stop_t *stops, - cairo_gl_gradient_t **gradient_out) -{ - unsigned long hash; - cairo_gl_gradient_t *gradient; - cairo_status_t status; - int tex_width; - GLint internal_format; - void *data; - - if ((unsigned int) ctx->max_texture_size / 2 <= n_stops) - return CAIRO_INT_STATUS_UNSUPPORTED; - - hash = _cairo_gl_gradient_hash (n_stops, stops); - - gradient = _cairo_gl_gradient_lookup (ctx, hash, n_stops, stops); - if (gradient) { - *gradient_out = _cairo_gl_gradient_reference (gradient); - return CAIRO_STATUS_SUCCESS; - } - - gradient = malloc (sizeof (cairo_gl_gradient_t) + sizeof (cairo_gradient_stop_t) * (n_stops - 1)); - if (gradient == NULL) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - tex_width = _cairo_gl_gradient_sample_width (n_stops, stops); - if (tex_width > ctx->max_texture_size) - tex_width = ctx->max_texture_size; - - CAIRO_REFERENCE_COUNT_INIT (&gradient->ref_count, 2); - gradient->cache_entry.hash = hash; - gradient->cache_entry.size = tex_width; - gradient->device = &ctx->base; - gradient->n_stops = n_stops; - gradient->stops = gradient->stops_embedded; - memcpy (gradient->stops_embedded, stops, n_stops * sizeof (cairo_gradient_stop_t)); - - glGenTextures (1, &gradient->tex); - _cairo_gl_context_activate (ctx, CAIRO_GL_TEX_TEMP); - glBindTexture (ctx->tex_target, gradient->tex); - - data = _cairo_malloc_ab (tex_width, sizeof (uint32_t)); - if (unlikely (data == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto cleanup_gradient; - } - - status = _cairo_gl_gradient_render (ctx, n_stops, stops, data, tex_width); - if (unlikely (status)) - goto cleanup_data; - - /* - * In OpenGL ES 2.0 no format conversion is allowed i.e. 'internalFormat' - * must match 'format' in glTexImage2D. - */ - if (_cairo_gl_get_flavor () == CAIRO_GL_FLAVOR_ES) - internal_format = GL_BGRA; - else - internal_format = GL_RGBA; - - glTexImage2D (ctx->tex_target, 0, internal_format, tex_width, 1, 0, - GL_BGRA, GL_UNSIGNED_BYTE, data); - - free (data); - - /* we ignore errors here and just return an uncached gradient */ - if (unlikely (_cairo_cache_insert (&ctx->gradients, &gradient->cache_entry))) - CAIRO_REFERENCE_COUNT_INIT (&gradient->ref_count, 1); - - *gradient_out = gradient; - return CAIRO_STATUS_SUCCESS; - -cleanup_data: - free (data); -cleanup_gradient: - free (gradient); - return status; -} - -cairo_gl_gradient_t * -_cairo_gl_gradient_reference (cairo_gl_gradient_t *gradient) -{ - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&gradient->ref_count)); - - _cairo_reference_count_inc (&gradient->ref_count); - - return gradient; -} - -void -_cairo_gl_gradient_destroy (cairo_gl_gradient_t *gradient) -{ - cairo_gl_context_t *ctx; - cairo_status_t ignore; - - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&gradient->ref_count)); - - if (! _cairo_reference_count_dec_and_test (&gradient->ref_count)) - return; - - if (_cairo_gl_context_acquire (gradient->device, &ctx) == CAIRO_STATUS_SUCCESS) { - /* The gradient my still be active in the last operation, so flush */ - _cairo_gl_composite_flush (ctx); - glDeleteTextures (1, &gradient->tex); - ignore = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS); - } - - free (gradient); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-gl-info.c b/source/libs/cairo/cairo-src/src/cairo-gl-info.c deleted file mode 100644 index acefbb91059e3ea11afc52a238508e121a178831..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-gl-info.c +++ /dev/null @@ -1,111 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2010 Linaro Limited - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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. - * - * Contributor(s): - * Alexandros Frantzis <alexandros.frantzis@linaro.org> - */ - -#include "cairoint.h" -#include "cairo-gl-private.h" - -#include <errno.h> - -int -_cairo_gl_get_version (void) -{ - int major, minor; - const char *version = (const char *) glGetString (GL_VERSION); - const char *dot = version == NULL ? NULL : strchr (version, '.'); - const char *major_start = dot; - - /* Sanity check */ - if (dot == NULL || dot == version || *(dot + 1) == '\0') { - major = 0; - minor = 0; - } else { - /* Find the start of the major version in the string */ - while (major_start > version && *major_start != ' ') - --major_start; - major = strtol (major_start, NULL, 10); - minor = strtol (dot + 1, NULL, 10); - } - - return CAIRO_GL_VERSION_ENCODE (major, minor); -} - -cairo_gl_flavor_t -_cairo_gl_get_flavor (void) -{ - const char *version = (const char *) glGetString (GL_VERSION); - cairo_gl_flavor_t flavor; - - if (version == NULL) - flavor = CAIRO_GL_FLAVOR_NONE; - else if (strstr (version, "OpenGL ES") != NULL) - flavor = CAIRO_GL_FLAVOR_ES; - else - flavor = CAIRO_GL_FLAVOR_DESKTOP; - - return flavor; -} - -unsigned long -_cairo_gl_get_vbo_size (void) -{ - unsigned long vbo_size; - - const char *env = getenv ("CAIRO_GL_VBO_SIZE"); - if (env == NULL) { - vbo_size = CAIRO_GL_VBO_SIZE_DEFAULT; - } else { - errno = 0; - vbo_size = strtol (env, NULL, 10); - assert (errno == 0); - assert (vbo_size > 0); - } - - return vbo_size; -} - -cairo_bool_t -_cairo_gl_has_extension (const char *ext) -{ - const char *extensions = (const char *) glGetString (GL_EXTENSIONS); - size_t len = strlen (ext); - const char *ext_ptr = extensions; - - if (unlikely (ext_ptr == NULL)) - return 0; - - while ((ext_ptr = strstr (ext_ptr, ext)) != NULL) { - if (ext_ptr[len] == ' ' || ext_ptr[len] == '\0') - break; - ext_ptr += len; - } - - return (ext_ptr != NULL); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-gl-msaa-compositor.c b/source/libs/cairo/cairo-src/src/cairo-gl-msaa-compositor.c deleted file mode 100644 index 83e8eb2d16067f1ea8328be1e51d8a09a58aff7c..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-gl-msaa-compositor.c +++ /dev/null @@ -1,944 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * Copyright © 2011 Intel Corporation - * Copyright © 2011 Samsung Electronics - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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): - * Henry Song <hsong@sisa.samsung.com> - * Martin Robinson <mrobinson@igalia.com> - */ - -#include "cairoint.h" - -#include "cairo-clip-inline.h" -#include "cairo-composite-rectangles-private.h" -#include "cairo-compositor-private.h" -#include "cairo-gl-private.h" -#include "cairo-path-private.h" -#include "cairo-traps-private.h" - -static cairo_bool_t -can_use_msaa_compositor (cairo_gl_surface_t *surface, - cairo_antialias_t antialias); - -static void -query_surface_capabilities (cairo_gl_surface_t *surface); - -struct _tristrip_composite_info { - cairo_gl_composite_t setup; - cairo_gl_context_t *ctx; -}; - -static cairo_int_status_t -_draw_trap (cairo_gl_context_t *ctx, - cairo_gl_composite_t *setup, - cairo_trapezoid_t *trap) -{ - cairo_point_t quad[4]; - - quad[0].x = _cairo_edge_compute_intersection_x_for_y (&trap->left.p1, - &trap->left.p2, - trap->top); - quad[0].y = trap->top; - - quad[1].x = _cairo_edge_compute_intersection_x_for_y (&trap->left.p1, - &trap->left.p2, - trap->bottom); - quad[1].y = trap->bottom; - - quad[2].x = _cairo_edge_compute_intersection_x_for_y (&trap->right.p1, - &trap->right.p2, - trap->bottom); - quad[2].y = trap->bottom; - - quad[3].x = _cairo_edge_compute_intersection_x_for_y (&trap->right.p1, - &trap->right.p2, - trap->top); - quad[3].y = trap->top; - return _cairo_gl_composite_emit_quad_as_tristrip (ctx, setup, quad); -} - -static cairo_int_status_t -_draw_traps (cairo_gl_context_t *ctx, - cairo_gl_composite_t *setup, - cairo_traps_t *traps) -{ - cairo_int_status_t status = CAIRO_STATUS_SUCCESS; - int i; - - for (i = 0; i < traps->num_traps; i++) { - cairo_trapezoid_t *trap = traps->traps + i; - if (unlikely ((status = _draw_trap (ctx, setup, trap)))) - return status; - } - - return status; -} - -static cairo_int_status_t -_draw_int_rect (cairo_gl_context_t *ctx, - cairo_gl_composite_t *setup, - cairo_rectangle_int_t *rect) -{ - cairo_box_t box; - cairo_point_t quad[4]; - - _cairo_box_from_rectangle (&box, rect); - quad[0].x = box.p1.x; - quad[0].y = box.p1.y; - quad[1].x = box.p1.x; - quad[1].y = box.p2.y; - quad[2].x = box.p2.x; - quad[2].y = box.p2.y; - quad[3].x = box.p2.x; - quad[3].y = box.p1.y; - - return _cairo_gl_composite_emit_quad_as_tristrip (ctx, setup, quad); -} - -static cairo_int_status_t -_draw_triangle_fan (cairo_gl_context_t *ctx, - cairo_gl_composite_t *setup, - const cairo_point_t *midpt, - const cairo_point_t *points, - int npoints) -{ - int i; - - /* Our strategy here is to not even try to build a triangle fan, but to - draw each triangle as if it was an unconnected member of a triangle strip. */ - for (i = 1; i < npoints; i++) { - cairo_int_status_t status; - cairo_point_t triangle[3]; - - triangle[0] = *midpt; - triangle[1] = points[i - 1]; - triangle[2] = points[i]; - - status = _cairo_gl_composite_emit_triangle_as_tristrip (ctx, setup, triangle); - if (unlikely (status)) - return status; - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_clip_to_traps (cairo_clip_t *clip, - cairo_traps_t *traps) -{ - cairo_int_status_t status; - cairo_polygon_t polygon; - cairo_antialias_t antialias; - cairo_fill_rule_t fill_rule; - - _cairo_traps_init (traps); - - if (clip->num_boxes == 1 && clip->path == NULL) { - cairo_boxes_t boxes; - _cairo_boxes_init_for_array (&boxes, clip->boxes, clip->num_boxes); - return _cairo_traps_init_boxes (traps, &boxes); - } - - status = _cairo_clip_get_polygon (clip, &polygon, &fill_rule, &antialias); - if (unlikely (status)) - return status; - - /* We ignore the antialias mode of the clip here, since the user requested - * unantialiased rendering of their path and we expect that this stencil - * based rendering of the clip to be a reasonable approximation to - * the intersection between that clip and the path. - * - * In other words, what the user expects when they try to perform - * a geometric intersection between an unantialiased polygon and an - * antialiased polygon is open to interpretation. And we choose the fast - * option. - */ - - _cairo_traps_init (traps); - status = _cairo_bentley_ottmann_tessellate_polygon (traps, - &polygon, - fill_rule); - _cairo_polygon_fini (&polygon); - - return status; -} - -cairo_int_status_t -_cairo_gl_msaa_compositor_draw_clip (cairo_gl_context_t *ctx, - cairo_gl_composite_t *setup, - cairo_clip_t *clip) -{ - cairo_int_status_t status; - cairo_traps_t traps; - - status = _clip_to_traps (clip, &traps); - if (unlikely (status)) - return status; - status = _draw_traps (ctx, setup, &traps); - - _cairo_traps_fini (&traps); - return status; -} - -static cairo_bool_t -_should_use_unbounded_surface (cairo_composite_rectangles_t *composite) -{ - cairo_gl_surface_t *dst = (cairo_gl_surface_t *) composite->surface; - cairo_rectangle_int_t *source = &composite->source; - - if (composite->is_bounded) - return FALSE; - - /* This isn't just an optimization. It also detects when painting is used - to paint back the unbounded surface, preventing infinite recursion. */ - return ! (source->x <= 0 && source->y <= 0 && - source->height + source->y >= dst->height && - source->width + source->x >= dst->width); -} - -static cairo_surface_t* -_prepare_unbounded_surface (cairo_gl_surface_t *dst) -{ - - cairo_surface_t* surface = cairo_gl_surface_create (dst->base.device, - dst->base.content, - dst->width, - dst->height); - if (surface == NULL) - return NULL; - if (unlikely (surface->status)) { - cairo_surface_destroy (surface); - return NULL; - } - return surface; -} - -static cairo_int_status_t -_paint_back_unbounded_surface (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *composite, - cairo_surface_t *surface) -{ - cairo_gl_surface_t *dst = (cairo_gl_surface_t *) composite->surface; - cairo_int_status_t status; - - cairo_pattern_t *pattern = cairo_pattern_create_for_surface (surface); - if (unlikely (pattern->status)) { - status = pattern->status; - goto finish; - } - - status = _cairo_compositor_paint (compositor, &dst->base, - composite->op, pattern, - composite->clip); - -finish: - cairo_pattern_destroy (pattern); - cairo_surface_destroy (surface); - return status; -} - -static cairo_bool_t -can_use_msaa_compositor (cairo_gl_surface_t *surface, - cairo_antialias_t antialias) -{ - query_surface_capabilities (surface); - if (! surface->supports_stencil) - return FALSE; - - /* Multisampling OpenGL ES surfaces only maintain one multisampling - framebuffer and thus must use the spans compositor to do non-antialiased - rendering. */ - if (((cairo_gl_context_t *) surface->base.device)->gl_flavor == CAIRO_GL_FLAVOR_ES - && surface->supports_msaa - && antialias == CAIRO_ANTIALIAS_NONE) - return FALSE; - - /* The MSAA compositor has a single-sample mode, so we can - support non-antialiased rendering. */ - if (antialias == CAIRO_ANTIALIAS_NONE) - return TRUE; - - if (antialias == CAIRO_ANTIALIAS_FAST || antialias == CAIRO_ANTIALIAS_DEFAULT) - return surface->supports_msaa; - return FALSE; -} - -static void -_cairo_gl_msaa_compositor_set_clip (cairo_composite_rectangles_t *composite, - cairo_gl_composite_t *setup) -{ - if (_cairo_composite_rectangles_can_reduce_clip (composite, composite->clip)) - return; - _cairo_gl_composite_set_clip (setup, composite->clip); -} - -/* Masking with the SOURCE operator requires two passes. In the first - * pass we use the mask as the source to get: - * result = (1 - ma) * dst - * In the second pass we use the add operator to achieve: - * result = (src * ma) + dst - * Combined this produces: - * result = (src * ma) + (1 - ma) * dst - */ -static cairo_int_status_t -_cairo_gl_msaa_compositor_mask_source_operator (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *composite) -{ - cairo_gl_composite_t setup; - cairo_gl_surface_t *dst = (cairo_gl_surface_t *) composite->surface; - cairo_gl_context_t *ctx = NULL; - cairo_int_status_t status; - - cairo_clip_t *clip = composite->clip; - cairo_traps_t traps; - - /* If we have a non-rectangular clip, we can avoid using the stencil buffer - * for clipping and just draw the clip polygon. */ - if (clip) { - status = _clip_to_traps (clip, &traps); - if (unlikely (status)) { - _cairo_traps_fini (&traps); - return status; - } - } - - status = _cairo_gl_composite_init (&setup, - CAIRO_OPERATOR_DEST_OUT, - dst, - FALSE /* assume_component_alpha */); - if (unlikely (status)) - return status; - status = _cairo_gl_composite_set_source (&setup, - &composite->mask_pattern.base, - &composite->mask_sample_area, - &composite->bounded, - FALSE); - if (unlikely (status)) - goto finish; - _cairo_gl_composite_set_multisample (&setup); - status = _cairo_gl_composite_begin (&setup, &ctx); - if (unlikely (status)) - goto finish; - - if (! clip) - status = _draw_int_rect (ctx, &setup, &composite->bounded); - else - status = _draw_traps (ctx, &setup, &traps); - if (unlikely (status)) - goto finish; - - /* Now draw the second pass. */ - status = _cairo_gl_composite_set_operator (&setup, CAIRO_OPERATOR_ADD, - FALSE /* assume_component_alpha */); - if (unlikely (status)) - goto finish; - status = _cairo_gl_composite_set_source (&setup, - &composite->source_pattern.base, - &composite->source_sample_area, - &composite->bounded, - FALSE); - if (unlikely (status)) - goto finish; - status = _cairo_gl_composite_set_mask (&setup, - &composite->mask_pattern.base, - &composite->source_sample_area, - &composite->bounded, - FALSE); - if (unlikely (status)) - goto finish; - status = _cairo_gl_set_operands_and_operator (&setup, ctx); - if (unlikely (status)) - goto finish; - - if (! clip) - status = _draw_int_rect (ctx, &setup, &composite->bounded); - else - status = _draw_traps (ctx, &setup, &traps); - -finish: - _cairo_gl_composite_fini (&setup); - if (ctx) - status = _cairo_gl_context_release (ctx, status); - if (clip) - _cairo_traps_fini (&traps); - - return status; -} - -static cairo_int_status_t -_cairo_gl_msaa_compositor_mask (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *composite) -{ - cairo_gl_composite_t setup; - cairo_gl_surface_t *dst = (cairo_gl_surface_t *) composite->surface; - cairo_gl_context_t *ctx = NULL; - cairo_int_status_t status; - cairo_operator_t op = composite->op; - cairo_clip_t *clip = composite->clip; - - if (! can_use_msaa_compositor (dst, CAIRO_ANTIALIAS_DEFAULT)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (composite->op == CAIRO_OPERATOR_CLEAR && - composite->original_mask_pattern != NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* GL compositing operators cannot properly represent a mask operation - using the SOURCE compositing operator in one pass. This only matters if - there actually is a mask (there isn't in a paint operation) and if the - mask isn't totally opaque. */ - if (op == CAIRO_OPERATOR_SOURCE && - composite->original_mask_pattern != NULL && - ! _cairo_pattern_is_opaque (&composite->mask_pattern.base, - &composite->mask_sample_area)) { - - if (! _cairo_pattern_is_opaque (&composite->source_pattern.base, - &composite->source_sample_area)) { - return _cairo_gl_msaa_compositor_mask_source_operator (compositor, composite); - } - - /* If the source is opaque the operation reduces to OVER. */ - op = CAIRO_OPERATOR_OVER; - } - - if (_should_use_unbounded_surface (composite)) { - cairo_surface_t* surface = _prepare_unbounded_surface (dst); - - if (unlikely (surface == NULL)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* This may be a paint operation. */ - if (composite->original_mask_pattern == NULL) { - status = _cairo_compositor_paint (compositor, surface, - CAIRO_OPERATOR_SOURCE, - &composite->source_pattern.base, - NULL); - } else { - status = _cairo_compositor_mask (compositor, surface, - CAIRO_OPERATOR_SOURCE, - &composite->source_pattern.base, - &composite->mask_pattern.base, - NULL); - } - - if (unlikely (status)) { - cairo_surface_destroy (surface); - return status; - } - - return _paint_back_unbounded_surface (compositor, composite, surface); - } - - status = _cairo_gl_composite_init (&setup, - op, - dst, - FALSE /* assume_component_alpha */); - if (unlikely (status)) - return status; - - status = _cairo_gl_composite_set_source (&setup, - &composite->source_pattern.base, - &composite->source_sample_area, - &composite->bounded, - FALSE); - if (unlikely (status)) - goto finish; - - if (composite->original_mask_pattern != NULL) { - status = _cairo_gl_composite_set_mask (&setup, - &composite->mask_pattern.base, - &composite->mask_sample_area, - &composite->bounded, - FALSE); - } - if (unlikely (status)) - goto finish; - - /* We always use multisampling here, because we do not yet have the smarts - to calculate when the clip or the source requires it. */ - _cairo_gl_composite_set_multisample (&setup); - - status = _cairo_gl_composite_begin (&setup, &ctx); - if (unlikely (status)) - goto finish; - - if (! clip) - status = _draw_int_rect (ctx, &setup, &composite->bounded); - else - status = _cairo_gl_msaa_compositor_draw_clip (ctx, &setup, clip); - -finish: - _cairo_gl_composite_fini (&setup); - - if (ctx) - status = _cairo_gl_context_release (ctx, status); - - return status; -} - -static cairo_int_status_t -_cairo_gl_msaa_compositor_paint (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *composite) -{ - return _cairo_gl_msaa_compositor_mask (compositor, composite); -} - -static cairo_status_t -_stroke_shaper_add_triangle (void *closure, - const cairo_point_t triangle[3]) -{ - struct _tristrip_composite_info *info = closure; - return _cairo_gl_composite_emit_triangle_as_tristrip (info->ctx, - &info->setup, - triangle); -} - -static cairo_status_t -_stroke_shaper_add_triangle_fan (void *closure, - const cairo_point_t *midpoint, - const cairo_point_t *points, - int npoints) -{ - struct _tristrip_composite_info *info = closure; - return _draw_triangle_fan (info->ctx, &info->setup, - midpoint, points, npoints); -} - -static cairo_status_t -_stroke_shaper_add_quad (void *closure, - const cairo_point_t quad[4]) -{ - struct _tristrip_composite_info *info = closure; - return _cairo_gl_composite_emit_quad_as_tristrip (info->ctx, &info->setup, - quad); -} - -static cairo_int_status_t -_prevent_overlapping_strokes (cairo_gl_context_t *ctx, - cairo_gl_composite_t *setup, - cairo_composite_rectangles_t *composite, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm) -{ - cairo_rectangle_int_t stroke_extents; - - if (! _cairo_gl_ensure_stencil (ctx, setup->dst)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (_cairo_pattern_is_opaque (&composite->source_pattern.base, - &composite->source_sample_area)) - return CAIRO_INT_STATUS_SUCCESS; - - if (glIsEnabled (GL_STENCIL_TEST) == FALSE) { - cairo_bool_t scissor_was_enabled; - - /* In case we have pending operations we have to flush before - adding the stencil buffer. */ - _cairo_gl_composite_flush (ctx); - - /* Enable the stencil buffer, even if we are not using it for clipping, - so we can use it below to prevent overlapping shapes. We initialize - it all to one here which represents infinite clip. */ - glDepthMask (GL_TRUE); - glEnable (GL_STENCIL_TEST); - - /* We scissor here so that we don't have to clear the entire stencil - * buffer. If the scissor test is already enabled, it was enabled - * for clipping. In that case, instead of calculating an intersection, - * we just reuse it, and risk clearing too much. */ - scissor_was_enabled = glIsEnabled (GL_SCISSOR_TEST); - if (! scissor_was_enabled) { - _cairo_path_fixed_approximate_stroke_extents (path, style, ctm, - &stroke_extents); - _cairo_gl_scissor_to_rectangle (setup->dst, &stroke_extents); - } - glClearStencil (1); - glClear (GL_STENCIL_BUFFER_BIT); - if (! scissor_was_enabled) - glDisable (GL_SCISSOR_TEST); - - glStencilFunc (GL_EQUAL, 1, 1); - } - - /* This means that once we draw to a particular pixel nothing else can - be drawn there until the stencil buffer is reset or the stencil test - is disabled. */ - glStencilOp (GL_ZERO, GL_ZERO, GL_ZERO); - - _cairo_clip_destroy (setup->dst->clip_on_stencil_buffer); - setup->dst->clip_on_stencil_buffer = NULL; - - return CAIRO_INT_STATUS_SUCCESS; -} - -static void -query_surface_capabilities (cairo_gl_surface_t *surface) -{ - GLint samples, stencil_bits; - cairo_gl_context_t *ctx; - cairo_int_status_t status; - - /* Texture surfaces are create in such a way that they always - have stencil and multisample bits if possible, so we don't - need to query their capabilities lazily. */ - if (_cairo_gl_surface_is_texture (surface)) - return; - if (surface->stencil_and_msaa_caps_initialized) - return; - - surface->stencil_and_msaa_caps_initialized = TRUE; - surface->supports_stencil = FALSE; - surface->supports_msaa = FALSE; - - status = _cairo_gl_context_acquire (surface->base.device, &ctx); - if (unlikely (status)) - return; - - _cairo_gl_context_set_destination (ctx, surface, FALSE); - - glGetIntegerv(GL_SAMPLES, &samples); - glGetIntegerv(GL_STENCIL_BITS, &stencil_bits); - surface->supports_stencil = stencil_bits > 0; - surface->supports_msaa = samples > 1; - - status = _cairo_gl_context_release (ctx, status); -} - -static cairo_int_status_t -_cairo_gl_msaa_compositor_stroke (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *composite, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_int_status_t status; - cairo_gl_surface_t *dst = (cairo_gl_surface_t *) composite->surface; - struct _tristrip_composite_info info; - - if (! can_use_msaa_compositor (dst, antialias)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (composite->is_bounded == FALSE) { - cairo_surface_t* surface = _prepare_unbounded_surface (dst); - - if (unlikely (surface == NULL)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_compositor_stroke (compositor, surface, - CAIRO_OPERATOR_SOURCE, - &composite->source_pattern.base, - path, style, ctm, ctm_inverse, - tolerance, antialias, NULL); - if (unlikely (status)) { - cairo_surface_destroy (surface); - return status; - } - - return _paint_back_unbounded_surface (compositor, composite, surface); - } - - status = _cairo_gl_composite_init (&info.setup, - composite->op, - dst, - FALSE /* assume_component_alpha */); - if (unlikely (status)) - return status; - - info.ctx = NULL; - - status = _cairo_gl_composite_set_source (&info.setup, - &composite->source_pattern.base, - &composite->source_sample_area, - &composite->bounded, - FALSE); - if (unlikely (status)) - goto finish; - - _cairo_gl_msaa_compositor_set_clip (composite, &info.setup); - if (antialias != CAIRO_ANTIALIAS_NONE) - _cairo_gl_composite_set_multisample (&info.setup); - - status = _cairo_gl_composite_begin (&info.setup, &info.ctx); - if (unlikely (status)) - goto finish; - - status = _prevent_overlapping_strokes (info.ctx, &info.setup, - composite, path, style, ctm); - if (unlikely (status)) - goto finish; - - status = _cairo_path_fixed_stroke_to_shaper ((cairo_path_fixed_t *) path, - style, - ctm, - ctm_inverse, - tolerance, - _stroke_shaper_add_triangle, - _stroke_shaper_add_triangle_fan, - _stroke_shaper_add_quad, - &info); - if (unlikely (status)) - goto finish; - -finish: - _cairo_gl_composite_fini (&info.setup); - - if (info.ctx) - status = _cairo_gl_context_release (info.ctx, status); - - return status; -} - -static cairo_int_status_t -_draw_simple_quad_path (cairo_gl_context_t *ctx, - cairo_gl_composite_t *setup, - const cairo_path_fixed_t *path) -{ - cairo_point_t triangle[3]; - cairo_int_status_t status; - const cairo_point_t *points; - - points = cairo_path_head (path)->points; - triangle[0] = points[0]; - triangle[1] = points[1]; - triangle[2] = points[2]; - status = _cairo_gl_composite_emit_triangle_as_tristrip (ctx, setup, triangle); - if (status) - return status; - - triangle[0] = points[2]; - triangle[1] = points[3]; - triangle[2] = points[0]; - return _cairo_gl_composite_emit_triangle_as_tristrip (ctx, setup, triangle); -} - -static cairo_int_status_t -_cairo_gl_msaa_compositor_fill (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *composite, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_gl_composite_t setup; - cairo_gl_surface_t *dst = (cairo_gl_surface_t *) composite->surface; - cairo_gl_context_t *ctx = NULL; - cairo_int_status_t status; - cairo_traps_t traps; - cairo_bool_t draw_path_with_traps; - - if (! can_use_msaa_compositor (dst, antialias)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (composite->is_bounded == FALSE) { - cairo_surface_t* surface = _prepare_unbounded_surface (dst); - - if (unlikely (surface == NULL)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - - status = _cairo_compositor_fill (compositor, surface, - CAIRO_OPERATOR_SOURCE, - &composite->source_pattern.base, - path, fill_rule, tolerance, - antialias, NULL); - - if (unlikely (status)) { - cairo_surface_destroy (surface); - return status; - } - - return _paint_back_unbounded_surface (compositor, composite, surface); - } - - draw_path_with_traps = ! _cairo_path_fixed_is_simple_quad (path); - - if (draw_path_with_traps) { - _cairo_traps_init (&traps); - status = _cairo_path_fixed_fill_to_traps (path, fill_rule, tolerance, &traps); - if (unlikely (status)) - goto cleanup_traps; - } - - status = _cairo_gl_composite_init (&setup, - composite->op, - dst, - FALSE /* assume_component_alpha */); - if (unlikely (status)) - goto cleanup_traps; - - status = _cairo_gl_composite_set_source (&setup, - &composite->source_pattern.base, - &composite->source_sample_area, - &composite->bounded, - FALSE); - if (unlikely (status)) - goto cleanup_setup; - - _cairo_gl_msaa_compositor_set_clip (composite, &setup); - if (antialias != CAIRO_ANTIALIAS_NONE) - _cairo_gl_composite_set_multisample (&setup); - - status = _cairo_gl_composite_begin (&setup, &ctx); - if (unlikely (status)) - goto cleanup_setup; - - if (! draw_path_with_traps) - status = _draw_simple_quad_path (ctx, &setup, path); - else - status = _draw_traps (ctx, &setup, &traps); - if (unlikely (status)) - goto cleanup_setup; - -cleanup_setup: - _cairo_gl_composite_fini (&setup); - - if (ctx) - status = _cairo_gl_context_release (ctx, status); - -cleanup_traps: - if (draw_path_with_traps) - _cairo_traps_fini (&traps); - - return status; -} - -static cairo_int_status_t -_cairo_gl_msaa_compositor_glyphs (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *composite, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_bool_t overlap) -{ - cairo_int_status_t status; - cairo_surface_t *src = NULL; - int src_x, src_y; - cairo_composite_glyphs_info_t info; - - cairo_gl_surface_t *dst = (cairo_gl_surface_t *) composite->surface; - - query_surface_capabilities (dst); - if (! dst->supports_stencil) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (composite->op == CAIRO_OPERATOR_CLEAR) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (composite->is_bounded == FALSE) { - cairo_surface_t* surface = _prepare_unbounded_surface (dst); - - if (unlikely (surface == NULL)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_compositor_glyphs (compositor, surface, - CAIRO_OPERATOR_SOURCE, - &composite->source_pattern.base, - glyphs, num_glyphs, - scaled_font, composite->clip); - - if (unlikely (status)) { - cairo_surface_destroy (surface); - return status; - } - - return _paint_back_unbounded_surface (compositor, composite, surface); - } - - src = _cairo_gl_pattern_to_source (&dst->base, - &composite->source_pattern.base, - FALSE, - &composite->bounded, - &composite->source_sample_area, - &src_x, &src_y); - if (unlikely (src->status)) { - status = src->status; - goto finish; - } - - status = _cairo_gl_check_composite_glyphs (composite, - scaled_font, glyphs, - &num_glyphs); - if (unlikely (status != CAIRO_INT_STATUS_SUCCESS)) - goto finish; - - info.font = scaled_font; - info.glyphs = glyphs; - info.num_glyphs = num_glyphs; - info.use_mask = overlap || ! composite->is_bounded || - composite->op == CAIRO_OPERATOR_SOURCE; - info.extents = composite->bounded; - - _cairo_scaled_font_freeze_cache (scaled_font); - status = _cairo_gl_composite_glyphs_with_clip (dst, composite->op, - src, src_x, src_y, - 0, 0, &info, - composite->clip); - - _cairo_scaled_font_thaw_cache (scaled_font); - -finish: - if (src) - cairo_surface_destroy (src); - - return status; -} - -static void -_cairo_gl_msaa_compositor_init (cairo_compositor_t *compositor, - const cairo_compositor_t *delegate) -{ - compositor->delegate = delegate; - - compositor->paint = _cairo_gl_msaa_compositor_paint; - compositor->mask = _cairo_gl_msaa_compositor_mask; - compositor->fill = _cairo_gl_msaa_compositor_fill; - compositor->stroke = _cairo_gl_msaa_compositor_stroke; - compositor->glyphs = _cairo_gl_msaa_compositor_glyphs; -} - -const cairo_compositor_t * -_cairo_gl_msaa_compositor_get (void) -{ - static cairo_compositor_t compositor; - if (compositor.delegate == NULL) - _cairo_gl_msaa_compositor_init (&compositor, - _cairo_gl_span_compositor_get ()); - - return &compositor; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-gl-operand.c b/source/libs/cairo/cairo-src/src/cairo-gl-operand.c deleted file mode 100644 index 1d1465a0be90e4a797a521a31a20a391c79ed1d5..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-gl-operand.c +++ /dev/null @@ -1,792 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Eric Anholt - * Copyright © 2009 Chris Wilson - * Copyright © 2005,2010 Red Hat, Inc - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Benjamin Otte <otte@gnome.org> - * Carl Worth <cworth@cworth.org> - * Chris Wilson <chris@chris-wilson.co.uk> - * Eric Anholt <eric@anholt.net> - */ - -#include "cairoint.h" - -#include "cairo-gl-private.h" - -#include "cairo-composite-rectangles-private.h" -#include "cairo-compositor-private.h" -#include "cairo-default-context-private.h" -#include "cairo-error-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-surface-backend-private.h" -#include "cairo-surface-offset-private.h" -#include "cairo-surface-subsurface-inline.h" - -static cairo_int_status_t -_cairo_gl_create_gradient_texture (cairo_gl_surface_t *dst, - const cairo_gradient_pattern_t *pattern, - cairo_gl_gradient_t **gradient) -{ - cairo_gl_context_t *ctx; - cairo_status_t status; - - status = _cairo_gl_context_acquire (dst->base.device, &ctx); - if (unlikely (status)) - return status; - - status = _cairo_gl_gradient_create (ctx, pattern->n_stops, pattern->stops, gradient); - - return _cairo_gl_context_release (ctx, status); -} - -static cairo_status_t -_cairo_gl_subsurface_clone_operand_init (cairo_gl_operand_t *operand, - const cairo_pattern_t *_src, - cairo_gl_surface_t *dst, - const cairo_rectangle_int_t *sample, - const cairo_rectangle_int_t *extents, - cairo_bool_t use_texgen) -{ - const cairo_surface_pattern_t *src = (cairo_surface_pattern_t *)_src; - cairo_surface_pattern_t local_pattern; - cairo_surface_subsurface_t *sub; - cairo_gl_surface_t *surface; - cairo_gl_context_t *ctx; - cairo_surface_attributes_t *attributes; - cairo_status_t status; - - sub = (cairo_surface_subsurface_t *) src->surface; - - if (sub->snapshot && - sub->snapshot->type == CAIRO_SURFACE_TYPE_GL && - sub->snapshot->device == dst->base.device) - { - surface = (cairo_gl_surface_t *) - cairo_surface_reference (sub->snapshot); - } - else - { - status = _cairo_gl_context_acquire (dst->base.device, &ctx); - if (unlikely (status)) - return status; - - /* XXX Trim surface to the sample area within the subsurface? */ - surface = (cairo_gl_surface_t *) - _cairo_gl_surface_create_scratch (ctx, - sub->target->content, - sub->extents.width, - sub->extents.height); - if (surface->base.status) - return _cairo_gl_context_release (ctx, surface->base.status); - - _cairo_pattern_init_for_surface (&local_pattern, sub->target); - cairo_matrix_init_translate (&local_pattern.base.matrix, - sub->extents.x, sub->extents.y); - local_pattern.base.filter = CAIRO_FILTER_NEAREST; - status = _cairo_surface_paint (&surface->base, - CAIRO_OPERATOR_SOURCE, - &local_pattern.base, - NULL); - _cairo_pattern_fini (&local_pattern.base); - - status = _cairo_gl_context_release (ctx, status); - if (unlikely (status)) { - cairo_surface_destroy (&surface->base); - return status; - } - - _cairo_surface_subsurface_set_snapshot (&sub->base, &surface->base); - } - - status = _cairo_gl_surface_resolve_multisampling (surface); - if (unlikely (status)) - return status; - - attributes = &operand->texture.attributes; - - operand->type = CAIRO_GL_OPERAND_TEXTURE; - operand->texture.surface = surface; - operand->texture.owns_surface = surface; - operand->texture.tex = surface->tex; - - if (_cairo_gl_device_requires_power_of_two_textures (dst->base.device)) { - attributes->matrix = src->base.matrix; - } else { - cairo_matrix_t m; - - cairo_matrix_init_scale (&m, - 1.0 / surface->width, - 1.0 / surface->height); - cairo_matrix_multiply (&attributes->matrix, &src->base.matrix, &m); - } - - attributes->extend = src->base.extend; - attributes->filter = src->base.filter; - attributes->has_component_alpha = src->base.has_component_alpha; - - operand->texture.texgen = use_texgen; - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_gl_subsurface_operand_init (cairo_gl_operand_t *operand, - const cairo_pattern_t *_src, - cairo_gl_surface_t *dst, - const cairo_rectangle_int_t *sample, - const cairo_rectangle_int_t *extents, - cairo_bool_t use_texgen) -{ - const cairo_surface_pattern_t *src = (cairo_surface_pattern_t *)_src; - cairo_surface_subsurface_t *sub; - cairo_gl_surface_t *surface; - cairo_surface_attributes_t *attributes; - cairo_int_status_t status; - - sub = (cairo_surface_subsurface_t *) src->surface; - - if (sample->x < 0 || sample->y < 0 || - sample->x + sample->width > sub->extents.width || - sample->y + sample->height > sub->extents.height) - { - return _cairo_gl_subsurface_clone_operand_init (operand, _src, - dst, sample, extents, - use_texgen); - } - - surface = (cairo_gl_surface_t *) sub->target; - if (surface->base.device && surface->base.device != dst->base.device) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (! _cairo_gl_surface_is_texture (surface)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_gl_surface_resolve_multisampling (surface); - if (unlikely (status)) - return status; - - /* Translate the matrix from - * (unnormalized src -> unnormalized src) to - * (unnormalized dst -> unnormalized src) - */ - _cairo_gl_operand_copy(operand, &surface->operand); - - attributes = &operand->texture.attributes; - attributes->matrix = src->base.matrix; - attributes->matrix.x0 += sub->extents.x; - attributes->matrix.y0 += sub->extents.y; - cairo_matrix_multiply (&attributes->matrix, - &attributes->matrix, - &surface->operand.texture.attributes.matrix); - - attributes->extend = src->base.extend; - attributes->filter = src->base.filter; - attributes->has_component_alpha = src->base.has_component_alpha; - - operand->texture.texgen = use_texgen; - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_gl_surface_operand_init (cairo_gl_operand_t *operand, - const cairo_pattern_t *_src, - cairo_gl_surface_t *dst, - const cairo_rectangle_int_t *sample, - const cairo_rectangle_int_t *extents, - cairo_bool_t use_texgen) -{ - const cairo_surface_pattern_t *src = (cairo_surface_pattern_t *)_src; - cairo_gl_surface_t *surface; - cairo_surface_attributes_t *attributes; - cairo_int_status_t status; - - surface = (cairo_gl_surface_t *) src->surface; - if (surface->base.type != CAIRO_SURFACE_TYPE_GL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (surface->base.backend->type != CAIRO_SURFACE_TYPE_GL) { - if (_cairo_surface_is_subsurface (&surface->base)) - return _cairo_gl_subsurface_operand_init (operand, _src, dst, - sample, extents, - use_texgen); - - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - if (surface->base.device && surface->base.device != dst->base.device) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (surface->base.device && ! _cairo_gl_surface_is_texture (surface)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_gl_surface_resolve_multisampling (surface); - if (unlikely (status)) - return status; - - _cairo_gl_operand_copy(operand, &surface->operand); - - attributes = &operand->texture.attributes; - cairo_matrix_multiply (&attributes->matrix, - &src->base.matrix, - &attributes->matrix); - - attributes->extend = src->base.extend; - attributes->filter = src->base.filter; - attributes->has_component_alpha = src->base.has_component_alpha; - - operand->texture.texgen = use_texgen; - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_gl_pattern_texture_setup (cairo_gl_operand_t *operand, - const cairo_pattern_t *_src, - cairo_gl_surface_t *dst, - const cairo_rectangle_int_t *extents) -{ - cairo_status_t status; - cairo_gl_surface_t *surface; - cairo_gl_context_t *ctx; - cairo_image_surface_t *image; - cairo_bool_t src_is_gl_surface = FALSE; - cairo_rectangle_int_t map_extents; - - if (_src->type == CAIRO_PATTERN_TYPE_SURFACE) { - cairo_surface_t* src_surface = ((cairo_surface_pattern_t *) _src)->surface; - src_is_gl_surface = src_surface->type == CAIRO_SURFACE_TYPE_GL; - } - - status = _cairo_gl_context_acquire (dst->base.device, &ctx); - if (unlikely (status)) - return status; - - surface = (cairo_gl_surface_t *) - _cairo_gl_surface_create_scratch (ctx, - CAIRO_CONTENT_COLOR_ALPHA, - extents->width, extents->height); - map_extents = *extents; - map_extents.x = map_extents.y = 0; - image = _cairo_surface_map_to_image (&surface->base, &map_extents); - - /* If the pattern is a GL surface, it belongs to some other GL context, - so we need to release this device while we paint it to the image. */ - if (src_is_gl_surface) { - status = _cairo_gl_context_release (ctx, status); - if (unlikely (status)) { - _cairo_surface_unmap_image (&surface->base, image); - goto fail; - } - } - - status = _cairo_surface_offset_paint (&image->base, extents->x, extents->y, - CAIRO_OPERATOR_SOURCE, _src, NULL); - - if (src_is_gl_surface) { - status = _cairo_gl_context_acquire (dst->base.device, &ctx); - if (unlikely (status)) { - _cairo_surface_unmap_image (&surface->base, image); - goto fail; - } - } - - status = _cairo_surface_unmap_image (&surface->base, image); - status = _cairo_gl_context_release (ctx, status); - if (unlikely (status)) - goto fail; - - *operand = surface->operand; - operand->texture.owns_surface = surface; - operand->texture.attributes.matrix.x0 -= extents->x * operand->texture.attributes.matrix.xx; - operand->texture.attributes.matrix.y0 -= extents->y * operand->texture.attributes.matrix.yy; - return CAIRO_STATUS_SUCCESS; - -fail: - cairo_surface_destroy (&surface->base); - return status; -} - -void -_cairo_gl_solid_operand_init (cairo_gl_operand_t *operand, - const cairo_color_t *color) -{ - operand->type = CAIRO_GL_OPERAND_CONSTANT; - operand->constant.color[0] = color->red * color->alpha; - operand->constant.color[1] = color->green * color->alpha; - operand->constant.color[2] = color->blue * color->alpha; - operand->constant.color[3] = color->alpha; -} - -void -_cairo_gl_operand_translate (cairo_gl_operand_t *operand, - double tx, double ty) -{ - switch (operand->type) { - case CAIRO_GL_OPERAND_TEXTURE: - operand->texture.attributes.matrix.x0 -= tx * operand->texture.attributes.matrix.xx; - operand->texture.attributes.matrix.y0 -= ty * operand->texture.attributes.matrix.yy; - break; - - case CAIRO_GL_OPERAND_LINEAR_GRADIENT: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT: - operand->gradient.m.x0 -= tx * operand->gradient.m.xx; - operand->gradient.m.y0 -= ty * operand->gradient.m.yy; - break; - - case CAIRO_GL_OPERAND_NONE: - case CAIRO_GL_OPERAND_CONSTANT: - case CAIRO_GL_OPERAND_COUNT: - default: - break; - } -} - -static cairo_status_t -_cairo_gl_gradient_operand_init (cairo_gl_operand_t *operand, - const cairo_pattern_t *pattern, - cairo_gl_surface_t *dst, - cairo_bool_t use_texgen) -{ - const cairo_gradient_pattern_t *gradient = (const cairo_gradient_pattern_t *)pattern; - cairo_status_t status; - - assert (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR || - gradient->base.type == CAIRO_PATTERN_TYPE_RADIAL); - - if (! _cairo_gl_device_has_glsl (dst->base.device)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_gl_create_gradient_texture (dst, - gradient, - &operand->gradient.gradient); - if (unlikely (status)) - return status; - - if (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR) { - cairo_linear_pattern_t *linear = (cairo_linear_pattern_t *) gradient; - double x0, y0, dx, dy, sf, offset; - - dx = linear->pd2.x - linear->pd1.x; - dy = linear->pd2.y - linear->pd1.y; - sf = 1.0 / (dx * dx + dy * dy); - dx *= sf; - dy *= sf; - - x0 = linear->pd1.x; - y0 = linear->pd1.y; - offset = dx * x0 + dy * y0; - - operand->type = CAIRO_GL_OPERAND_LINEAR_GRADIENT; - - cairo_matrix_init (&operand->gradient.m, dx, 0, dy, 1, -offset, 0); - if (! _cairo_matrix_is_identity (&pattern->matrix)) { - cairo_matrix_multiply (&operand->gradient.m, - &pattern->matrix, - &operand->gradient.m); - } - } else { - cairo_matrix_t m; - cairo_circle_double_t circles[2]; - double x0, y0, r0, dx, dy, dr; - - /* - * Some fragment shader implementations use half-floats to - * represent numbers, so the maximum number they can represent - * is about 2^14. Some intermediate computations used in the - * radial gradient shaders can produce results of up to 2*k^4. - * Setting k=8 makes the maximum result about 8192 (assuming - * that the extreme circles are not much smaller than the - * destination image). - */ - _cairo_gradient_pattern_fit_to_range (gradient, 8., - &operand->gradient.m, circles); - - x0 = circles[0].center.x; - y0 = circles[0].center.y; - r0 = circles[0].radius; - dx = circles[1].center.x - x0; - dy = circles[1].center.y - y0; - dr = circles[1].radius - r0; - - operand->gradient.a = dx * dx + dy * dy - dr * dr; - operand->gradient.radius_0 = r0; - operand->gradient.circle_d.center.x = dx; - operand->gradient.circle_d.center.y = dy; - operand->gradient.circle_d.radius = dr; - - if (operand->gradient.a == 0) - operand->type = CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0; - else if (pattern->extend == CAIRO_EXTEND_NONE) - operand->type = CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE; - else - operand->type = CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT; - - cairo_matrix_init_translate (&m, -x0, -y0); - cairo_matrix_multiply (&operand->gradient.m, - &operand->gradient.m, - &m); - } - - operand->gradient.extend = pattern->extend; - operand->gradient.texgen = use_texgen; - - return CAIRO_STATUS_SUCCESS; -} - -void -_cairo_gl_operand_copy (cairo_gl_operand_t *dst, - const cairo_gl_operand_t *src) -{ - *dst = *src; - switch (dst->type) { - case CAIRO_GL_OPERAND_CONSTANT: - break; - case CAIRO_GL_OPERAND_LINEAR_GRADIENT: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT: - _cairo_gl_gradient_reference (dst->gradient.gradient); - break; - case CAIRO_GL_OPERAND_TEXTURE: - cairo_surface_reference (&dst->texture.owns_surface->base); - break; - default: - case CAIRO_GL_OPERAND_COUNT: - ASSERT_NOT_REACHED; - case CAIRO_GL_OPERAND_NONE: - break; - } -} - -void -_cairo_gl_operand_destroy (cairo_gl_operand_t *operand) -{ - switch (operand->type) { - case CAIRO_GL_OPERAND_CONSTANT: - break; - case CAIRO_GL_OPERAND_LINEAR_GRADIENT: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT: - _cairo_gl_gradient_destroy (operand->gradient.gradient); - break; - case CAIRO_GL_OPERAND_TEXTURE: - cairo_surface_destroy (&operand->texture.owns_surface->base); - break; - default: - case CAIRO_GL_OPERAND_COUNT: - ASSERT_NOT_REACHED; - case CAIRO_GL_OPERAND_NONE: - break; - } - - operand->type = CAIRO_GL_OPERAND_NONE; -} - -cairo_int_status_t -_cairo_gl_operand_init (cairo_gl_operand_t *operand, - const cairo_pattern_t *pattern, - cairo_gl_surface_t *dst, - const cairo_rectangle_int_t *sample, - const cairo_rectangle_int_t *extents, - cairo_bool_t use_texgen) -{ - cairo_int_status_t status; - - TRACE ((stderr, "%s: type=%d\n", __FUNCTION__, pattern->type)); - switch (pattern->type) { - case CAIRO_PATTERN_TYPE_SOLID: - _cairo_gl_solid_operand_init (operand, - &((cairo_solid_pattern_t *) pattern)->color); - return CAIRO_STATUS_SUCCESS; - case CAIRO_PATTERN_TYPE_SURFACE: - status = _cairo_gl_surface_operand_init (operand, pattern, dst, - sample, extents, use_texgen); - if (status == CAIRO_INT_STATUS_UNSUPPORTED) - break; - - return status; - - case CAIRO_PATTERN_TYPE_LINEAR: - case CAIRO_PATTERN_TYPE_RADIAL: - status = _cairo_gl_gradient_operand_init (operand, pattern, dst, - use_texgen); - if (status == CAIRO_INT_STATUS_UNSUPPORTED) - break; - - return status; - - default: - case CAIRO_PATTERN_TYPE_MESH: - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - break; - } - - return _cairo_gl_pattern_texture_setup (operand, pattern, dst, extents); -} - -cairo_filter_t -_cairo_gl_operand_get_filter (cairo_gl_operand_t *operand) -{ - cairo_filter_t filter; - - switch ((int) operand->type) { - case CAIRO_GL_OPERAND_TEXTURE: - filter = operand->texture.attributes.filter; - break; - case CAIRO_GL_OPERAND_LINEAR_GRADIENT: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT: - filter = CAIRO_FILTER_BILINEAR; - break; - default: - filter = CAIRO_FILTER_DEFAULT; - break; - } - - return filter; -} - -GLint -_cairo_gl_operand_get_gl_filter (cairo_gl_operand_t *operand) -{ - cairo_filter_t filter = _cairo_gl_operand_get_filter (operand); - - return filter != CAIRO_FILTER_FAST && filter != CAIRO_FILTER_NEAREST ? - GL_LINEAR : - GL_NEAREST; -} - -cairo_extend_t -_cairo_gl_operand_get_extend (cairo_gl_operand_t *operand) -{ - cairo_extend_t extend; - - switch ((int) operand->type) { - case CAIRO_GL_OPERAND_TEXTURE: - extend = operand->texture.attributes.extend; - break; - case CAIRO_GL_OPERAND_LINEAR_GRADIENT: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT: - extend = operand->gradient.extend; - break; - default: - extend = CAIRO_EXTEND_NONE; - break; - } - - return extend; -} - - -void -_cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx, - cairo_gl_operand_t *operand, - cairo_gl_tex_t tex_unit) -{ - const cairo_matrix_t *texgen = NULL; - - switch (operand->type) { - default: - case CAIRO_GL_OPERAND_COUNT: - ASSERT_NOT_REACHED; - case CAIRO_GL_OPERAND_NONE: - return; - - case CAIRO_GL_OPERAND_CONSTANT: - _cairo_gl_shader_bind_vec4 (ctx, - ctx->current_shader->constant_location[tex_unit], - operand->constant.color[0], - operand->constant.color[1], - operand->constant.color[2], - operand->constant.color[3]); - return; - - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT: - _cairo_gl_shader_bind_float (ctx, - ctx->current_shader->a_location[tex_unit], - operand->gradient.a); - /* fall through */ - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0: - _cairo_gl_shader_bind_vec3 (ctx, - ctx->current_shader->circle_d_location[tex_unit], - operand->gradient.circle_d.center.x, - operand->gradient.circle_d.center.y, - operand->gradient.circle_d.radius); - _cairo_gl_shader_bind_float (ctx, - ctx->current_shader->radius_0_location[tex_unit], - operand->gradient.radius_0); - /* fall through */ - case CAIRO_GL_OPERAND_LINEAR_GRADIENT: - case CAIRO_GL_OPERAND_TEXTURE: - /* - * For GLES2 we use shaders to implement GL_CLAMP_TO_BORDER (used - * with CAIRO_EXTEND_NONE). When bilinear filtering is enabled, - * these shaders need the texture dimensions for their calculations. - */ - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES && - _cairo_gl_operand_get_extend (operand) == CAIRO_EXTEND_NONE && - _cairo_gl_operand_get_gl_filter (operand) == GL_LINEAR) - { - float width, height; - if (operand->type == CAIRO_GL_OPERAND_TEXTURE) { - width = operand->texture.surface->width; - height = operand->texture.surface->height; - } - else { - width = operand->gradient.gradient->cache_entry.size, - height = 1; - } - _cairo_gl_shader_bind_vec2 (ctx, - ctx->current_shader->texdims_location[tex_unit], - width, height); - } - break; - } - - if (operand->type == CAIRO_GL_OPERAND_TEXTURE) { - if (operand->texture.texgen) - texgen = &operand->texture.attributes.matrix; - } else { - if (operand->gradient.texgen) - texgen = &operand->gradient.m; - } - if (texgen) { - _cairo_gl_shader_bind_matrix(ctx, - ctx->current_shader->texgen_location[tex_unit], - texgen); - } -} - - -cairo_bool_t -_cairo_gl_operand_needs_setup (cairo_gl_operand_t *dest, - cairo_gl_operand_t *source, - unsigned int vertex_offset) -{ - if (dest->type != source->type) - return TRUE; - if (dest->vertex_offset != vertex_offset) - return TRUE; - - switch (source->type) { - case CAIRO_GL_OPERAND_NONE: - return FALSE; - case CAIRO_GL_OPERAND_CONSTANT: - return dest->constant.color[0] != source->constant.color[0] || - dest->constant.color[1] != source->constant.color[1] || - dest->constant.color[2] != source->constant.color[2] || - dest->constant.color[3] != source->constant.color[3]; - case CAIRO_GL_OPERAND_TEXTURE: - return dest->texture.surface != source->texture.surface || - dest->texture.attributes.extend != source->texture.attributes.extend || - dest->texture.attributes.filter != source->texture.attributes.filter || - dest->texture.attributes.has_component_alpha != source->texture.attributes.has_component_alpha; - case CAIRO_GL_OPERAND_LINEAR_GRADIENT: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT: - /* XXX: improve this */ - return TRUE; - default: - case CAIRO_GL_OPERAND_COUNT: - ASSERT_NOT_REACHED; - break; - } - return TRUE; -} - -unsigned int -_cairo_gl_operand_get_vertex_size (const cairo_gl_operand_t *operand) -{ - switch (operand->type) { - default: - case CAIRO_GL_OPERAND_COUNT: - ASSERT_NOT_REACHED; - case CAIRO_GL_OPERAND_NONE: - case CAIRO_GL_OPERAND_CONSTANT: - return 0; - case CAIRO_GL_OPERAND_TEXTURE: - return operand->texture.texgen ? 0 : 2 * sizeof (GLfloat); - case CAIRO_GL_OPERAND_LINEAR_GRADIENT: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT: - return operand->gradient.texgen ? 0 : 2 * sizeof (GLfloat); - } -} - -void -_cairo_gl_operand_emit (cairo_gl_operand_t *operand, - GLfloat ** vb, - GLfloat x, - GLfloat y) -{ - switch (operand->type) { - default: - case CAIRO_GL_OPERAND_COUNT: - ASSERT_NOT_REACHED; - case CAIRO_GL_OPERAND_NONE: - case CAIRO_GL_OPERAND_CONSTANT: - break; - case CAIRO_GL_OPERAND_LINEAR_GRADIENT: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT: - if (! operand->gradient.texgen) { - double s = x; - double t = y; - - cairo_matrix_transform_point (&operand->gradient.m, &s, &t); - - *(*vb)++ = s; - *(*vb)++ = t; - } - break; - case CAIRO_GL_OPERAND_TEXTURE: - if (! operand->texture.texgen) { - cairo_surface_attributes_t *src_attributes = &operand->texture.attributes; - double s = x; - double t = y; - - cairo_matrix_transform_point (&src_attributes->matrix, &s, &t); - *(*vb)++ = s; - *(*vb)++ = t; - } - break; - } -} diff --git a/source/libs/cairo/cairo-src/src/cairo-gl-private.h b/source/libs/cairo/cairo-src/src/cairo-gl-private.h deleted file mode 100644 index cb915c8cf25b4165668d556bbe1f0d24f78e6b56..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-gl-private.h +++ /dev/null @@ -1,853 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Eric Anholt - * Copyright © 2009 Chris Wilson - * Copyright © 2005,2010 Red Hat, Inc - * Copyright © 2011 Linaro Limited - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Benjamin Otte <otte@gnome.org> - * Carl Worth <cworth@cworth.org> - * Chris Wilson <chris@chris-wilson.co.uk> - * Eric Anholt <eric@anholt.net> - * T. Zachary Laine <whatwasthataddress@gmail.com> - * Alexandros Frantzis <alexandros.frantzis@linaro.org> - */ - -#ifndef CAIRO_GL_PRIVATE_H -#define CAIRO_GL_PRIVATE_H - -#define GL_GLEXT_PROTOTYPES - -#include "cairoint.h" - -#include "cairo-gl.h" -#include "cairo-gl-gradient-private.h" - -#include "cairo-device-private.h" -#include "cairo-error-private.h" -#include "cairo-rtree-private.h" -#include "cairo-scaled-font-private.h" -#include "cairo-spans-compositor-private.h" -#include "cairo-array-private.h" - -#include <assert.h> - -#if CAIRO_HAS_GL_SURFACE -#include <GL/gl.h> -#include <GL/glext.h> -#elif CAIRO_HAS_GLESV2_SURFACE -#include <GLES2/gl2.h> -#include <GLES2/gl2ext.h> -#endif - -#include "cairo-gl-ext-def-private.h" - -#define DEBUG_GL 0 - -#if DEBUG_GL && __GNUC__ -#define UNSUPPORTED(reason) ({ \ - fprintf (stderr, \ - "cairo-gl: hit unsupported operation in %s(), line %d: %s\n", \ - __FUNCTION__, __LINE__, reason); \ - CAIRO_INT_STATUS_UNSUPPORTED; \ -}) -#else -#define UNSUPPORTED(reason) CAIRO_INT_STATUS_UNSUPPORTED -#endif - -#define CAIRO_GL_VERSION_ENCODE(major, minor) ( \ - ((major) * 256) \ - + ((minor) * 1)) - -/* maximal number of shaders we keep in the cache. - * Random number that is hopefully big enough to not cause many cache evictions. */ -#define CAIRO_GL_MAX_SHADERS_PER_CONTEXT 64 - -/* VBO size that we allocate, smaller size means we gotta flush more often, - * but larger means hogging more memory and can cause trouble for drivers - * (especially on embedded devices). Use the CAIRO_GL_VBO_SIZE environment - * variable to set this to a different size. */ -#define CAIRO_GL_VBO_SIZE_DEFAULT (1024*1024) - -typedef struct _cairo_gl_surface cairo_gl_surface_t; - -/* GL flavor */ -typedef enum cairo_gl_flavor { - CAIRO_GL_FLAVOR_NONE = 0, - CAIRO_GL_FLAVOR_DESKTOP = 1, - CAIRO_GL_FLAVOR_ES = 2 -} cairo_gl_flavor_t; - -/* Indices for vertex attributes used by BindAttribLocation etc */ -enum { - CAIRO_GL_VERTEX_ATTRIB_INDEX = 0, - CAIRO_GL_COLOR_ATTRIB_INDEX = 1, - CAIRO_GL_TEXCOORD0_ATTRIB_INDEX = 2, - CAIRO_GL_TEXCOORD1_ATTRIB_INDEX = CAIRO_GL_TEXCOORD0_ATTRIB_INDEX + 1 -}; - -typedef enum cairo_gl_operand_type { - CAIRO_GL_OPERAND_NONE, - CAIRO_GL_OPERAND_CONSTANT, - CAIRO_GL_OPERAND_TEXTURE, - CAIRO_GL_OPERAND_LINEAR_GRADIENT, - CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0, - CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE, - CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT, - - CAIRO_GL_OPERAND_COUNT -} cairo_gl_operand_type_t; - -/* This union structure describes a potential source or mask operand to the - * compositing equation. - */ -typedef struct cairo_gl_operand { - cairo_gl_operand_type_t type; - union { - struct { - GLuint tex; - cairo_gl_surface_t *surface; - cairo_gl_surface_t *owns_surface; - cairo_surface_attributes_t attributes; - int texgen; - } texture; - struct { - GLfloat color[4]; - } constant; - struct { - cairo_gl_gradient_t *gradient; - cairo_matrix_t m; - cairo_circle_double_t circle_d; - double radius_0, a; - cairo_extend_t extend; - int texgen; - } gradient; - }; - unsigned int vertex_offset; -} cairo_gl_operand_t; - -typedef struct cairo_gl_source { - cairo_surface_t base; - cairo_gl_operand_t operand; -} cairo_gl_source_t; - -struct _cairo_gl_surface { - cairo_surface_t base; - cairo_gl_operand_t operand; - - int width, height; - - GLuint tex; /* GL texture object containing our data. */ - GLuint fb; /* GL framebuffer object wrapping our data. */ - GLuint depth_stencil; /* GL renderbuffer object for holding stencil buffer clip. */ - -#if CAIRO_HAS_GL_SURFACE - GLuint msaa_rb; /* The ARB MSAA path uses a renderbuffer. */ - GLuint msaa_fb; -#endif - GLuint msaa_depth_stencil; - - cairo_bool_t stencil_and_msaa_caps_initialized; - cairo_bool_t supports_stencil; /* Stencil support for for non-texture surfaces. */ - cairo_bool_t supports_msaa; - cairo_bool_t msaa_active; /* Whether the multisampling - framebuffer is active or not. */ - cairo_clip_t *clip_on_stencil_buffer; - - int owns_tex; - cairo_bool_t needs_update; - - cairo_region_t *clip_region; -}; - -typedef struct cairo_gl_glyph_cache { - cairo_rtree_t rtree; - cairo_gl_surface_t *surface; -} cairo_gl_glyph_cache_t; - -typedef enum cairo_gl_tex { - CAIRO_GL_TEX_SOURCE = 0, - CAIRO_GL_TEX_MASK = 1, - CAIRO_GL_TEX_TEMP = 2 -} cairo_gl_tex_t; - -typedef struct cairo_gl_shader { - GLuint fragment_shader; - GLuint program; - GLint mvp_location; - GLint constant_location[2]; - GLint a_location[2]; - GLint circle_d_location[2]; - GLint radius_0_location[2]; - GLint texdims_location[2]; - GLint texgen_location[2]; -} cairo_gl_shader_t; - -typedef enum cairo_gl_shader_in { - CAIRO_GL_SHADER_IN_NORMAL, - CAIRO_GL_SHADER_IN_CA_SOURCE, - CAIRO_GL_SHADER_IN_CA_SOURCE_ALPHA, - - CAIRO_GL_SHADER_IN_COUNT -} cairo_gl_shader_in_t; - -typedef enum cairo_gl_var_type { - CAIRO_GL_VAR_NONE, - CAIRO_GL_VAR_TEXCOORDS, - CAIRO_GL_VAR_TEXGEN, -} cairo_gl_var_type_t; - -typedef enum cairo_gl_primitive_type { - CAIRO_GL_PRIMITIVE_TYPE_TRIANGLES, - CAIRO_GL_PRIMITIVE_TYPE_TRISTRIPS -} cairo_gl_primitive_type_t; - -typedef void (*cairo_gl_emit_rect_t) (cairo_gl_context_t *ctx, - GLfloat x1, GLfloat y1, - GLfloat x2, GLfloat y2); - -typedef void (*cairo_gl_emit_span_t) (cairo_gl_context_t *ctx, - GLfloat x1, GLfloat y1, - GLfloat x2, GLfloat y2, - uint8_t alpha); - -typedef void (*cairo_gl_emit_glyph_t) (cairo_gl_context_t *ctx, - GLfloat x1, GLfloat y1, - GLfloat x2, GLfloat y2, - GLfloat glyph_x1, GLfloat glyph_y1, - GLfloat glyph_x2, GLfloat glyph_y2); - -#define cairo_gl_var_type_hash(src,mask,spans,dest) ((spans) << 5) | ((mask) << 3 | (src << 1) | (dest)) -#define CAIRO_GL_VAR_TYPE_MAX (1 << 6) - -typedef void (*cairo_gl_generic_func_t)(void); -typedef cairo_gl_generic_func_t (*cairo_gl_get_proc_addr_func_t)(const char *procname); - -typedef struct _cairo_gl_dispatch { - /* Buffers */ - void (*GenBuffers) (GLsizei n, GLuint *buffers); - void (*BindBuffer) (GLenum target, GLuint buffer); - void (*BufferData) (GLenum target, GLsizeiptr size, - const GLvoid* data, GLenum usage); - GLvoid *(*MapBuffer) (GLenum target, GLenum access); - GLboolean (*UnmapBuffer) (GLenum target); - - /* Shaders */ - GLuint (*CreateShader) (GLenum type); - void (*ShaderSource) (GLuint shader, GLsizei count, - const GLchar** string, const GLint* length); - void (*CompileShader) (GLuint shader); - void (*GetShaderiv) (GLuint shader, GLenum pname, GLint *params); - void (*GetShaderInfoLog) (GLuint shader, GLsizei bufSize, - GLsizei *length, GLchar *infoLog); - void (*DeleteShader) (GLuint shader); - - /* Programs */ - GLuint (*CreateProgram) (void); - void (*AttachShader) (GLuint program, GLuint shader); - void (*DeleteProgram) (GLuint program); - void (*LinkProgram) (GLuint program); - void (*UseProgram) (GLuint program); - void (*GetProgramiv) (GLuint program, GLenum pname, GLint *params); - void (*GetProgramInfoLog) (GLuint program, GLsizei bufSize, - GLsizei *length, GLchar *infoLog); - - /* Uniforms */ - GLint (*GetUniformLocation) (GLuint program, const GLchar* name); - void (*Uniform1f) (GLint location, GLfloat x); - void (*Uniform2f) (GLint location, GLfloat x, GLfloat y); - void (*Uniform3f) (GLint location, GLfloat x, GLfloat y, GLfloat z); - void (*Uniform4f) (GLint location, GLfloat x, GLfloat y, GLfloat z, - GLfloat w); - void (*UniformMatrix3fv) (GLint location, GLsizei count, - GLboolean transpose, const GLfloat *value); - void (*UniformMatrix4fv) (GLint location, GLsizei count, - GLboolean transpose, const GLfloat *value); - void (*Uniform1i) (GLint location, GLint x); - - /* Attributes */ - void (*BindAttribLocation) (GLuint program, GLuint index, - const GLchar *name); - void (*VertexAttribPointer) (GLuint index, GLint size, GLenum type, - GLboolean normalized, GLsizei stride, - const GLvoid *pointer); - void (*EnableVertexAttribArray) (GLuint index); - void (*DisableVertexAttribArray) (GLuint index); - - /* Framebuffer objects */ - void (*GenFramebuffers) (GLsizei n, GLuint* framebuffers); - void (*BindFramebuffer) (GLenum target, GLuint framebuffer); - void (*FramebufferTexture2D) (GLenum target, GLenum attachment, - GLenum textarget, GLuint texture, - GLint level); - GLenum (*CheckFramebufferStatus) (GLenum target); - void (*DeleteFramebuffers) (GLsizei n, const GLuint* framebuffers); - void (*GenRenderbuffers) (GLsizei n, GLuint *renderbuffers); - void (*BindRenderbuffer) (GLenum target, GLuint renderbuffer); - void (*RenderbufferStorage) (GLenum target, GLenum internal_format, - GLsizei width, GLsizei height); - void (*FramebufferRenderbuffer) (GLenum target, GLenum attachment, - GLenum renderbuffer_ttarget, GLuint renderbuffer); - void (*DeleteRenderbuffers) (GLsizei n, GLuint *renderbuffers); - void (*BlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter); - void (*RenderbufferStorageMultisample) (GLenum target, GLsizei samples, - GLenum internalformat, - GLsizei width, GLsizei height); - void (*FramebufferTexture2DMultisample) (GLenum target, GLenum attachment, - GLenum textarget, GLuint texture, - GLint level, GLsizei samples); -} cairo_gl_dispatch_t; - -struct _cairo_gl_context { - cairo_device_t base; - - const cairo_compositor_t *compositor; - - GLuint texture_load_pbo; - GLint max_framebuffer_size; - GLint max_texture_size; - GLint max_textures; - GLenum tex_target; - - GLint num_samples; - cairo_bool_t supports_msaa; - char *vb; - - cairo_bool_t has_shader_support; - - GLuint vertex_shaders[CAIRO_GL_VAR_TYPE_MAX]; - cairo_gl_shader_t fill_rectangles_shader; - cairo_cache_t shaders; - - cairo_cache_t gradients; - - cairo_gl_glyph_cache_t glyph_cache[2]; - cairo_list_t fonts; - - cairo_gl_surface_t *current_target; - cairo_operator_t current_operator; - cairo_gl_shader_t *pre_shader; /* for component alpha */ - cairo_gl_shader_t *current_shader; - - cairo_gl_operand_t operands[2]; - cairo_bool_t spans; - - unsigned int vbo_size; - unsigned int vb_offset; - unsigned int vertex_size; - cairo_region_t *clip_region; - cairo_clip_t *clip; - - cairo_gl_primitive_type_t primitive_type; - cairo_array_t tristrip_indices; - - cairo_bool_t has_mesa_pack_invert; - cairo_gl_dispatch_t dispatch; - GLfloat modelviewprojection_matrix[16]; - cairo_gl_flavor_t gl_flavor; - cairo_bool_t has_map_buffer; - cairo_bool_t has_packed_depth_stencil; - cairo_bool_t has_npot_repeat; - cairo_bool_t can_read_bgra; - - cairo_bool_t thread_aware; - - void (*acquire) (void *ctx); - void (*release) (void *ctx); - - void (*make_current) (void *ctx, cairo_gl_surface_t *surface); - void (*swap_buffers)(void *ctx, cairo_gl_surface_t *surface); - void (*destroy) (void *ctx); -}; - -typedef struct _cairo_gl_composite { - cairo_gl_surface_t *dst; - cairo_operator_t op; - cairo_region_t *clip_region; - - cairo_gl_operand_t src; - cairo_gl_operand_t mask; - cairo_bool_t spans; - - cairo_clip_t *clip; - cairo_bool_t multisample; -} cairo_gl_composite_t; - -typedef struct _cairo_gl_font { - cairo_scaled_font_private_t base; - cairo_device_t *device; - cairo_list_t link; -} cairo_gl_font_t; - -static cairo_always_inline GLenum -_cairo_gl_get_error (void) -{ - GLenum err = glGetError(); - - if (unlikely (err)) - while (glGetError ()); - - return err; -} - -static inline cairo_device_t * -_cairo_gl_context_create_in_error (cairo_status_t status) -{ - return (cairo_device_t *) _cairo_device_create_in_error (status); -} - -cairo_private cairo_status_t -_cairo_gl_context_init (cairo_gl_context_t *ctx); - -cairo_private void -_cairo_gl_surface_init (cairo_device_t *device, - cairo_gl_surface_t *surface, - cairo_content_t content, - int width, int height); - -static cairo_always_inline cairo_bool_t cairo_warn -_cairo_gl_surface_is_texture (cairo_gl_surface_t *surface) -{ - return surface->tex != 0; -} - -cairo_private cairo_status_t -_cairo_gl_surface_draw_image (cairo_gl_surface_t *dst, - cairo_image_surface_t *src, - int src_x, int src_y, - int width, int height, - int dst_x, int dst_y, - cairo_bool_t force_flush); - -cairo_private cairo_int_status_t -_cairo_gl_surface_resolve_multisampling (cairo_gl_surface_t *surface); - -static cairo_always_inline cairo_bool_t -_cairo_gl_device_has_glsl (cairo_device_t *device) -{ - return ((cairo_gl_context_t *) device)->has_shader_support; -} - -static cairo_always_inline cairo_bool_t -_cairo_gl_device_requires_power_of_two_textures (cairo_device_t *device) -{ - return ((cairo_gl_context_t *) device)->tex_target == GL_TEXTURE_RECTANGLE; -} - -static cairo_always_inline cairo_status_t cairo_warn -_cairo_gl_context_acquire (cairo_device_t *device, - cairo_gl_context_t **ctx) -{ - cairo_status_t status; - - status = cairo_device_acquire (device); - if (unlikely (status)) - return status; - - /* clear potential previous GL errors */ - _cairo_gl_get_error (); - - *ctx = (cairo_gl_context_t *) device; - return CAIRO_STATUS_SUCCESS; -} - -static cairo_always_inline cairo_warn cairo_status_t -_cairo_gl_context_release (cairo_gl_context_t *ctx, cairo_status_t status) -{ - GLenum err; - - err = _cairo_gl_get_error (); - - if (unlikely (err)) { - cairo_status_t new_status; - new_status = _cairo_error (CAIRO_STATUS_DEVICE_ERROR); - if (status == CAIRO_STATUS_SUCCESS) - status = new_status; - } - - cairo_device_release (&(ctx)->base); - - return status; -} - -cairo_private void -_cairo_gl_context_set_destination (cairo_gl_context_t *ctx, - cairo_gl_surface_t *surface, - cairo_bool_t multisampling); - -cairo_private void -_cairo_gl_context_bind_framebuffer (cairo_gl_context_t *ctx, - cairo_gl_surface_t *surface, - cairo_bool_t multisampling); - -cairo_private cairo_gl_emit_rect_t -_cairo_gl_context_choose_emit_rect (cairo_gl_context_t *ctx); - -cairo_private void -_cairo_gl_context_emit_rect (cairo_gl_context_t *ctx, - GLfloat x1, GLfloat y1, - GLfloat x2, GLfloat y2); - -cairo_private cairo_gl_emit_span_t -_cairo_gl_context_choose_emit_span (cairo_gl_context_t *ctx); - -cairo_private cairo_gl_emit_glyph_t -_cairo_gl_context_choose_emit_glyph (cairo_gl_context_t *ctx); - -cairo_private void -_cairo_gl_context_activate (cairo_gl_context_t *ctx, - cairo_gl_tex_t tex_unit); - -cairo_private cairo_bool_t -_cairo_gl_operator_is_supported (cairo_operator_t op); - -cairo_private cairo_bool_t -_cairo_gl_ensure_stencil (cairo_gl_context_t *ctx, - cairo_gl_surface_t *surface); - -cairo_private cairo_status_t -_cairo_gl_composite_init (cairo_gl_composite_t *setup, - cairo_operator_t op, - cairo_gl_surface_t *dst, - cairo_bool_t has_component_alpha); - -cairo_private void -_cairo_gl_composite_fini (cairo_gl_composite_t *setup); - -cairo_private cairo_status_t -_cairo_gl_composite_set_operator (cairo_gl_composite_t *setup, - cairo_operator_t op, - cairo_bool_t assume_component_alpha); - -cairo_private void -_cairo_gl_composite_set_clip_region (cairo_gl_composite_t *setup, - cairo_region_t *clip_region); - -cairo_private void -_cairo_gl_composite_set_clip(cairo_gl_composite_t *setup, - cairo_clip_t *clip); - -cairo_private cairo_int_status_t -_cairo_gl_composite_set_source (cairo_gl_composite_t *setup, - const cairo_pattern_t *pattern, - const cairo_rectangle_int_t *sample, - const cairo_rectangle_int_t *extents, - cairo_bool_t use_texgen); - -cairo_private void -_cairo_gl_composite_set_solid_source (cairo_gl_composite_t *setup, - const cairo_color_t *color); - -cairo_private void -_cairo_gl_composite_set_source_operand (cairo_gl_composite_t *setup, - const cairo_gl_operand_t *source); - -cairo_private cairo_int_status_t -_cairo_gl_composite_set_mask (cairo_gl_composite_t *setup, - const cairo_pattern_t *pattern, - const cairo_rectangle_int_t *sample, - const cairo_rectangle_int_t *extents, - cairo_bool_t use_texgen); - -cairo_private void -_cairo_gl_composite_set_mask_operand (cairo_gl_composite_t *setup, - const cairo_gl_operand_t *mask); - -cairo_private void -_cairo_gl_composite_set_spans (cairo_gl_composite_t *setup); - -cairo_private void -_cairo_gl_composite_set_multisample (cairo_gl_composite_t *setup); - -cairo_private cairo_status_t -_cairo_gl_composite_begin (cairo_gl_composite_t *setup, - cairo_gl_context_t **ctx); - -cairo_private cairo_status_t -_cairo_gl_set_operands_and_operator (cairo_gl_composite_t *setup, - cairo_gl_context_t *ctx); - -cairo_private void -_cairo_gl_composite_flush (cairo_gl_context_t *ctx); - -cairo_private cairo_int_status_t -_cairo_gl_composite_emit_quad_as_tristrip (cairo_gl_context_t *ctx, - cairo_gl_composite_t *setup, - const cairo_point_t quad[4]); - -cairo_private cairo_int_status_t -_cairo_gl_composite_emit_triangle_as_tristrip (cairo_gl_context_t *ctx, - cairo_gl_composite_t *setup, - const cairo_point_t triangle[3]); - -cairo_private void -_cairo_gl_context_destroy_operand (cairo_gl_context_t *ctx, - cairo_gl_tex_t tex_unit); - -cairo_private cairo_bool_t -_cairo_gl_get_image_format_and_type (cairo_gl_flavor_t flavor, - pixman_format_code_t pixman_format, - GLenum *internal_format, GLenum *format, - GLenum *type, cairo_bool_t *has_alpha, - cairo_bool_t *needs_swap); - -cairo_private void -_cairo_gl_glyph_cache_init (cairo_gl_glyph_cache_t *cache); - -cairo_private void -_cairo_gl_glyph_cache_fini (cairo_gl_context_t *ctx, - cairo_gl_glyph_cache_t *cache); - -cairo_private cairo_int_status_t -_cairo_gl_surface_show_glyphs (void *abstract_dst, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip, - int *remaining_glyphs); - -cairo_private cairo_status_t -_cairo_gl_context_init_shaders (cairo_gl_context_t *ctx); - -cairo_private void -_cairo_gl_context_fini_shaders (cairo_gl_context_t *ctx); - -static cairo_always_inline cairo_bool_t -_cairo_gl_context_is_flushed (cairo_gl_context_t *ctx) -{ - return ctx->vb_offset == 0; -} - -cairo_private cairo_status_t -_cairo_gl_get_shader_by_type (cairo_gl_context_t *ctx, - cairo_gl_operand_t *source, - cairo_gl_operand_t *mask, - cairo_bool_t use_coverage, - cairo_gl_shader_in_t in, - cairo_gl_shader_t **shader); - -cairo_private void -_cairo_gl_shader_bind_float (cairo_gl_context_t *ctx, - GLint location, - float value); - -cairo_private void -_cairo_gl_shader_bind_vec2 (cairo_gl_context_t *ctx, - GLint location, - float value0, float value1); - -cairo_private void -_cairo_gl_shader_bind_vec3 (cairo_gl_context_t *ctx, - GLint location, - float value0, - float value1, - float value2); - -cairo_private void -_cairo_gl_shader_bind_vec4 (cairo_gl_context_t *ctx, - GLint location, - float value0, float value1, - float value2, float value3); - -cairo_private void -_cairo_gl_shader_bind_matrix (cairo_gl_context_t *ctx, - GLint location, - const cairo_matrix_t* m); - -cairo_private void -_cairo_gl_shader_bind_matrix4f (cairo_gl_context_t *ctx, - GLint location, - GLfloat* gl_m); - -cairo_private void -_cairo_gl_set_shader (cairo_gl_context_t *ctx, - cairo_gl_shader_t *shader); - -cairo_private void -_cairo_gl_shader_fini (cairo_gl_context_t *ctx, cairo_gl_shader_t *shader); - -cairo_private int -_cairo_gl_get_version (void); - -cairo_private cairo_gl_flavor_t -_cairo_gl_get_flavor (void); - -cairo_private unsigned long -_cairo_gl_get_vbo_size (void); - -cairo_private cairo_bool_t -_cairo_gl_has_extension (const char *ext); - -cairo_private cairo_status_t -_cairo_gl_dispatch_init(cairo_gl_dispatch_t *dispatch, - cairo_gl_get_proc_addr_func_t get_proc_addr); - -cairo_private cairo_int_status_t -_cairo_gl_operand_init (cairo_gl_operand_t *operand, - const cairo_pattern_t *pattern, - cairo_gl_surface_t *dst, - const cairo_rectangle_int_t *sample, - const cairo_rectangle_int_t *extents, - cairo_bool_t use_texgen); - -cairo_private void -_cairo_gl_solid_operand_init (cairo_gl_operand_t *operand, - const cairo_color_t *color); - -cairo_private cairo_filter_t -_cairo_gl_operand_get_filter (cairo_gl_operand_t *operand); - -cairo_private GLint -_cairo_gl_operand_get_gl_filter (cairo_gl_operand_t *operand); - -cairo_private cairo_extend_t -_cairo_gl_operand_get_extend (cairo_gl_operand_t *operand); - -cairo_private unsigned int -_cairo_gl_operand_get_vertex_size (const cairo_gl_operand_t *operand); - -cairo_private cairo_bool_t -_cairo_gl_operand_needs_setup (cairo_gl_operand_t *dest, - cairo_gl_operand_t *source, - unsigned int vertex_offset); - -cairo_private void -_cairo_gl_operand_bind_to_shader (cairo_gl_context_t *ctx, - cairo_gl_operand_t *operand, - cairo_gl_tex_t tex_unit); - -cairo_private void -_cairo_gl_operand_emit (cairo_gl_operand_t *operand, - GLfloat ** vb, - GLfloat x, - GLfloat y); - -cairo_private void -_cairo_gl_operand_copy (cairo_gl_operand_t *dst, - const cairo_gl_operand_t *src); - -cairo_private void -_cairo_gl_operand_translate (cairo_gl_operand_t *operand, - double tx, double ty); - -cairo_private void -_cairo_gl_operand_destroy (cairo_gl_operand_t *operand); - -cairo_private const cairo_compositor_t * -_cairo_gl_msaa_compositor_get (void); - -cairo_private const cairo_compositor_t * -_cairo_gl_span_compositor_get (void); - -cairo_private const cairo_compositor_t * -_cairo_gl_traps_compositor_get (void); - -cairo_private cairo_int_status_t -_cairo_gl_check_composite_glyphs (const cairo_composite_rectangles_t *extents, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int *num_glyphs); - -cairo_private cairo_int_status_t -_cairo_gl_composite_glyphs (void *_dst, - cairo_operator_t op, - cairo_surface_t *_src, - int src_x, - int src_y, - int dst_x, - int dst_y, - cairo_composite_glyphs_info_t *info); - -cairo_private cairo_int_status_t -_cairo_gl_composite_glyphs_with_clip (void *_dst, - cairo_operator_t op, - cairo_surface_t *_src, - int src_x, - int src_y, - int dst_x, - int dst_y, - cairo_composite_glyphs_info_t *info, - cairo_clip_t *clip); - -cairo_private cairo_surface_t * -_cairo_gl_surface_create_scratch (cairo_gl_context_t *ctx, - cairo_content_t content, - int width, - int height); - -cairo_private cairo_surface_t * -_cairo_gl_surface_create_scratch_for_caching (cairo_gl_context_t *ctx, - cairo_content_t content, - int width, - int height); - -cairo_private cairo_surface_t * -_cairo_gl_pattern_to_source (cairo_surface_t *dst, - const cairo_pattern_t *pattern, - cairo_bool_t is_mask, - const cairo_rectangle_int_t *extents, - const cairo_rectangle_int_t *sample, - int *src_x, int *src_y); - -cairo_private cairo_int_status_t -_cairo_gl_msaa_compositor_draw_clip (cairo_gl_context_t *ctx, - cairo_gl_composite_t *setup, - cairo_clip_t *clip); - -cairo_private cairo_surface_t * -_cairo_gl_white_source (void); - -cairo_private void -_cairo_gl_scissor_to_rectangle (cairo_gl_surface_t *surface, - const cairo_rectangle_int_t *r); - -static inline cairo_gl_operand_t * -source_to_operand (cairo_surface_t *surface) -{ - cairo_gl_source_t *source = (cairo_gl_source_t *)surface; - return source ? &source->operand : NULL; -} - -static inline void -_cairo_gl_glyph_cache_unlock (cairo_gl_glyph_cache_t *cache) -{ - _cairo_rtree_unpin (&cache->rtree); -} - - -slim_hidden_proto (cairo_gl_surface_create); -slim_hidden_proto (cairo_gl_surface_create_for_texture); - -#endif /* CAIRO_GL_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-gl-shaders.c b/source/libs/cairo/cairo-src/src/cairo-gl-shaders.c deleted file mode 100644 index fe975d2d7c9fb5a07d10dc848f76b9ca4a34e015..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-gl-shaders.c +++ /dev/null @@ -1,1093 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 T. Zachary Laine - * Copyright © 2010 Eric Anholt - * Copyright © 2010 Red Hat, Inc - * Copyright © 2010 Linaro Limited - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 T. Zachary Laine. - * - * Contributor(s): - * Benjamin Otte <otte@gnome.org> - * Eric Anholt <eric@anholt.net> - * T. Zachary Laine <whatwasthataddress@gmail.com> - * Alexandros Frantzis <alexandros.frantzis@linaro.org> - */ - -#include "cairoint.h" -#include "cairo-gl-private.h" -#include "cairo-error-private.h" -#include "cairo-output-stream-private.h" - -static cairo_status_t -_cairo_gl_shader_compile_and_link (cairo_gl_context_t *ctx, - cairo_gl_shader_t *shader, - cairo_gl_var_type_t src, - cairo_gl_var_type_t mask, - cairo_bool_t use_coverage, - const char *fragment_text); - -typedef struct _cairo_shader_cache_entry { - cairo_cache_entry_t base; - - unsigned vertex; - - cairo_gl_operand_type_t src; - cairo_gl_operand_type_t mask; - cairo_gl_operand_type_t dest; - cairo_bool_t use_coverage; - - cairo_gl_shader_in_t in; - GLint src_gl_filter; - cairo_bool_t src_border_fade; - cairo_extend_t src_extend; - GLint mask_gl_filter; - cairo_bool_t mask_border_fade; - cairo_extend_t mask_extend; - - cairo_gl_context_t *ctx; /* XXX: needed to destroy the program */ - cairo_gl_shader_t shader; -} cairo_shader_cache_entry_t; - -static cairo_bool_t -_cairo_gl_shader_cache_equal_desktop (const void *key_a, const void *key_b) -{ - const cairo_shader_cache_entry_t *a = key_a; - const cairo_shader_cache_entry_t *b = key_b; - cairo_bool_t both_have_npot_repeat = - a->ctx->has_npot_repeat && b->ctx->has_npot_repeat; - - return (a->vertex == b->vertex && - a->src == b->src && - a->mask == b->mask && - a->dest == b->dest && - a->use_coverage == b->use_coverage && - a->in == b->in && - (both_have_npot_repeat || a->src_extend == b->src_extend) && - (both_have_npot_repeat || a->mask_extend == b->mask_extend)); -} - -/* - * For GLES2 we use more complicated shaders to implement missing GL - * features. In this case we need more parameters to uniquely identify - * a shader (vs _cairo_gl_shader_cache_equal_desktop()). - */ -static cairo_bool_t -_cairo_gl_shader_cache_equal_gles2 (const void *key_a, const void *key_b) -{ - const cairo_shader_cache_entry_t *a = key_a; - const cairo_shader_cache_entry_t *b = key_b; - cairo_bool_t both_have_npot_repeat = - a->ctx->has_npot_repeat && b->ctx->has_npot_repeat; - - return (a->vertex == b->vertex && - a->src == b->src && - a->mask == b->mask && - a->dest == b->dest && - a->use_coverage == b->use_coverage && - a->in == b->in && - a->src_gl_filter == b->src_gl_filter && - a->src_border_fade == b->src_border_fade && - (both_have_npot_repeat || a->src_extend == b->src_extend) && - a->mask_gl_filter == b->mask_gl_filter && - a->mask_border_fade == b->mask_border_fade && - (both_have_npot_repeat || a->mask_extend == b->mask_extend)); -} - -static unsigned long -_cairo_gl_shader_cache_hash (const cairo_shader_cache_entry_t *entry) -{ - return ((entry->src << 24) | (entry->mask << 16) | (entry->dest << 8) | (entry->in << 1) | entry->use_coverage) ^ entry->vertex; -} - -static void -_cairo_gl_shader_cache_destroy (void *data) -{ - cairo_shader_cache_entry_t *entry = data; - - _cairo_gl_shader_fini (entry->ctx, &entry->shader); - if (entry->ctx->current_shader == &entry->shader) - entry->ctx->current_shader = NULL; - free (entry); -} - -static void -_cairo_gl_shader_init (cairo_gl_shader_t *shader) -{ - shader->fragment_shader = 0; - shader->program = 0; -} - -cairo_status_t -_cairo_gl_context_init_shaders (cairo_gl_context_t *ctx) -{ - static const char *fill_fs_source = - "#ifdef GL_ES\n" - "precision mediump float;\n" - "#endif\n" - "uniform vec4 color;\n" - "void main()\n" - "{\n" - " gl_FragColor = color;\n" - "}\n"; - cairo_status_t status; - - if (_cairo_gl_get_version () >= CAIRO_GL_VERSION_ENCODE (2, 0) || - (_cairo_gl_has_extension ("GL_ARB_shader_objects") && - _cairo_gl_has_extension ("GL_ARB_fragment_shader") && - _cairo_gl_has_extension ("GL_ARB_vertex_shader"))) { - ctx->has_shader_support = TRUE; - } else { - ctx->has_shader_support = FALSE; - fprintf (stderr, "Error: The cairo gl backend requires shader support!\n"); - return CAIRO_STATUS_DEVICE_ERROR; - } - - memset (ctx->vertex_shaders, 0, sizeof (ctx->vertex_shaders)); - - status = _cairo_cache_init (&ctx->shaders, - ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP ? - _cairo_gl_shader_cache_equal_desktop : - _cairo_gl_shader_cache_equal_gles2, - NULL, - _cairo_gl_shader_cache_destroy, - CAIRO_GL_MAX_SHADERS_PER_CONTEXT); - if (unlikely (status)) - return status; - - _cairo_gl_shader_init (&ctx->fill_rectangles_shader); - status = _cairo_gl_shader_compile_and_link (ctx, - &ctx->fill_rectangles_shader, - CAIRO_GL_VAR_NONE, - CAIRO_GL_VAR_NONE, - FALSE, - fill_fs_source); - if (unlikely (status)) - return status; - - return CAIRO_STATUS_SUCCESS; -} - -void -_cairo_gl_context_fini_shaders (cairo_gl_context_t *ctx) -{ - int i; - - for (i = 0; i < CAIRO_GL_VAR_TYPE_MAX; i++) { - if (ctx->vertex_shaders[i]) - ctx->dispatch.DeleteShader (ctx->vertex_shaders[i]); - } - - _cairo_cache_fini (&ctx->shaders); -} - -void -_cairo_gl_shader_fini (cairo_gl_context_t *ctx, - cairo_gl_shader_t *shader) -{ - if (shader->fragment_shader) - ctx->dispatch.DeleteShader (shader->fragment_shader); - - if (shader->program) - ctx->dispatch.DeleteProgram (shader->program); -} - -static const char *operand_names[] = { "source", "mask", "dest" }; - -static cairo_gl_var_type_t -cairo_gl_operand_get_var_type (cairo_gl_operand_t *operand) -{ - switch (operand->type) { - default: - case CAIRO_GL_OPERAND_COUNT: - ASSERT_NOT_REACHED; - case CAIRO_GL_OPERAND_NONE: - case CAIRO_GL_OPERAND_CONSTANT: - return CAIRO_GL_VAR_NONE; - case CAIRO_GL_OPERAND_LINEAR_GRADIENT: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE: - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT: - return operand->gradient.texgen ? CAIRO_GL_VAR_TEXGEN : CAIRO_GL_VAR_TEXCOORDS; - case CAIRO_GL_OPERAND_TEXTURE: - return operand->texture.texgen ? CAIRO_GL_VAR_TEXGEN : CAIRO_GL_VAR_TEXCOORDS; - } -} - -static void -cairo_gl_shader_emit_variable (cairo_output_stream_t *stream, - cairo_gl_var_type_t type, - cairo_gl_tex_t name) -{ - switch (type) { - default: - ASSERT_NOT_REACHED; - case CAIRO_GL_VAR_NONE: - break; - case CAIRO_GL_VAR_TEXCOORDS: - _cairo_output_stream_printf (stream, - "attribute vec4 MultiTexCoord%d;\n" - "varying vec2 %s_texcoords;\n", - name, - operand_names[name]); - break; - case CAIRO_GL_VAR_TEXGEN: - _cairo_output_stream_printf (stream, - "uniform mat3 %s_texgen;\n" - "varying vec2 %s_texcoords;\n", - operand_names[name], - operand_names[name]); - break; - } -} - -static void -cairo_gl_shader_emit_vertex (cairo_output_stream_t *stream, - cairo_gl_var_type_t type, - cairo_gl_tex_t name) -{ - switch (type) { - default: - ASSERT_NOT_REACHED; - case CAIRO_GL_VAR_NONE: - break; - case CAIRO_GL_VAR_TEXCOORDS: - _cairo_output_stream_printf (stream, - " %s_texcoords = MultiTexCoord%d.xy;\n", - operand_names[name], name); - break; - - case CAIRO_GL_VAR_TEXGEN: - _cairo_output_stream_printf (stream, - " %s_texcoords = (%s_texgen * Vertex.xyw).xy;\n", - operand_names[name], operand_names[name]); - break; - } -} - -static void -cairo_gl_shader_dcl_coverage (cairo_output_stream_t *stream) -{ - _cairo_output_stream_printf (stream, "varying float coverage;\n"); -} - -static void -cairo_gl_shader_def_coverage (cairo_output_stream_t *stream) -{ - _cairo_output_stream_printf (stream, " coverage = Color.a;\n"); -} - -static cairo_status_t -cairo_gl_shader_get_vertex_source (cairo_gl_var_type_t src, - cairo_gl_var_type_t mask, - cairo_bool_t use_coverage, - cairo_gl_var_type_t dest, - char **out) -{ - cairo_output_stream_t *stream = _cairo_memory_stream_create (); - unsigned char *source; - unsigned long length; - cairo_status_t status; - - cairo_gl_shader_emit_variable (stream, src, CAIRO_GL_TEX_SOURCE); - cairo_gl_shader_emit_variable (stream, mask, CAIRO_GL_TEX_MASK); - if (use_coverage) - cairo_gl_shader_dcl_coverage (stream); - - _cairo_output_stream_printf (stream, - "attribute vec4 Vertex;\n" - "attribute vec4 Color;\n" - "uniform mat4 ModelViewProjectionMatrix;\n" - "void main()\n" - "{\n" - " gl_Position = ModelViewProjectionMatrix * Vertex;\n"); - - cairo_gl_shader_emit_vertex (stream, src, CAIRO_GL_TEX_SOURCE); - cairo_gl_shader_emit_vertex (stream, mask, CAIRO_GL_TEX_MASK); - if (use_coverage) - cairo_gl_shader_def_coverage (stream); - - _cairo_output_stream_write (stream, - "}\n\0", 3); - - status = _cairo_memory_stream_destroy (stream, &source, &length); - if (unlikely (status)) - return status; - - *out = (char *) source; - return CAIRO_STATUS_SUCCESS; -} - -/* - * Returns whether an operand needs a special border fade fragment shader - * to simulate the GL_CLAMP_TO_BORDER wrapping method that is missing in GLES2. - */ -static cairo_bool_t -_cairo_gl_shader_needs_border_fade (cairo_gl_operand_t *operand) -{ - cairo_extend_t extend =_cairo_gl_operand_get_extend (operand); - - return extend == CAIRO_EXTEND_NONE && - (operand->type == CAIRO_GL_OPERAND_TEXTURE || - operand->type == CAIRO_GL_OPERAND_LINEAR_GRADIENT || - operand->type == CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE || - operand->type == CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0); -} - -static void -cairo_gl_shader_emit_color (cairo_output_stream_t *stream, - cairo_gl_context_t *ctx, - cairo_gl_operand_t *op, - cairo_gl_tex_t name) -{ - const char *namestr = operand_names[name]; - const char *rectstr = (ctx->tex_target == GL_TEXTURE_RECTANGLE ? "Rect" : ""); - - switch (op->type) { - case CAIRO_GL_OPERAND_COUNT: - default: - ASSERT_NOT_REACHED; - break; - case CAIRO_GL_OPERAND_NONE: - _cairo_output_stream_printf (stream, - "vec4 get_%s()\n" - "{\n" - " return vec4 (0, 0, 0, 1);\n" - "}\n", - namestr); - break; - case CAIRO_GL_OPERAND_CONSTANT: - _cairo_output_stream_printf (stream, - "uniform vec4 %s_constant;\n" - "vec4 get_%s()\n" - "{\n" - " return %s_constant;\n" - "}\n", - namestr, namestr, namestr); - break; - case CAIRO_GL_OPERAND_TEXTURE: - _cairo_output_stream_printf (stream, - "uniform sampler2D%s %s_sampler;\n" - "uniform vec2 %s_texdims;\n" - "varying vec2 %s_texcoords;\n" - "vec4 get_%s()\n" - "{\n", - rectstr, namestr, namestr, namestr, namestr); - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES && - _cairo_gl_shader_needs_border_fade (op)) - { - _cairo_output_stream_printf (stream, - " vec2 border_fade = %s_border_fade (%s_texcoords, %s_texdims);\n" - " vec4 texel = texture2D%s (%s_sampler, %s_texcoords);\n" - " return texel * border_fade.x * border_fade.y;\n" - "}\n", - namestr, namestr, namestr, rectstr, namestr, namestr); - } - else - { - _cairo_output_stream_printf (stream, - " return texture2D%s (%s_sampler, %s_wrap (%s_texcoords));\n" - "}\n", - rectstr, namestr, namestr, namestr); - } - break; - case CAIRO_GL_OPERAND_LINEAR_GRADIENT: - _cairo_output_stream_printf (stream, - "varying vec2 %s_texcoords;\n" - "uniform vec2 %s_texdims;\n" - "uniform sampler2D%s %s_sampler;\n" - "\n" - "vec4 get_%s()\n" - "{\n", - namestr, namestr, rectstr, namestr, namestr); - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES && - _cairo_gl_shader_needs_border_fade (op)) - { - _cairo_output_stream_printf (stream, - " float border_fade = %s_border_fade (%s_texcoords.x, %s_texdims.x);\n" - " vec4 texel = texture2D%s (%s_sampler, vec2 (%s_texcoords.x, 0.5));\n" - " return texel * border_fade;\n" - "}\n", - namestr, namestr, namestr, rectstr, namestr, namestr); - } - else - { - _cairo_output_stream_printf (stream, - " return texture2D%s (%s_sampler, %s_wrap (vec2 (%s_texcoords.x, 0.5)));\n" - "}\n", - rectstr, namestr, namestr, namestr); - } - break; - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0: - _cairo_output_stream_printf (stream, - "varying vec2 %s_texcoords;\n" - "uniform vec2 %s_texdims;\n" - "uniform sampler2D%s %s_sampler;\n" - "uniform vec3 %s_circle_d;\n" - "uniform float %s_radius_0;\n" - "\n" - "vec4 get_%s()\n" - "{\n" - " vec3 pos = vec3 (%s_texcoords, %s_radius_0);\n" - " \n" - " float B = dot (pos, %s_circle_d);\n" - " float C = dot (pos, vec3 (pos.xy, -pos.z));\n" - " \n" - " float t = 0.5 * C / B;\n" - " float is_valid = step (-%s_radius_0, t * %s_circle_d.z);\n", - namestr, namestr, rectstr, namestr, namestr, namestr, namestr, - namestr, namestr, namestr, namestr, namestr); - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES && - _cairo_gl_shader_needs_border_fade (op)) - { - _cairo_output_stream_printf (stream, - " float border_fade = %s_border_fade (t, %s_texdims.x);\n" - " vec4 texel = texture2D%s (%s_sampler, vec2 (t, 0.5));\n" - " return mix (vec4 (0.0), texel * border_fade, is_valid);\n" - "}\n", - namestr, namestr, rectstr, namestr); - } - else - { - _cairo_output_stream_printf (stream, - " vec4 texel = texture2D%s (%s_sampler, %s_wrap (vec2 (t, 0.5)));\n" - " return mix (vec4 (0.0), texel, is_valid);\n" - "}\n", - rectstr, namestr, namestr); - } - break; - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_NONE: - _cairo_output_stream_printf (stream, - "varying vec2 %s_texcoords;\n" - "uniform vec2 %s_texdims;\n" - "uniform sampler2D%s %s_sampler;\n" - "uniform vec3 %s_circle_d;\n" - "uniform float %s_a;\n" - "uniform float %s_radius_0;\n" - "\n" - "vec4 get_%s()\n" - "{\n" - " vec3 pos = vec3 (%s_texcoords, %s_radius_0);\n" - " \n" - " float B = dot (pos, %s_circle_d);\n" - " float C = dot (pos, vec3 (pos.xy, -pos.z));\n" - " \n" - " float det = dot (vec2 (B, %s_a), vec2 (B, -C));\n" - " float sqrtdet = sqrt (abs (det));\n" - " vec2 t = (B + vec2 (sqrtdet, -sqrtdet)) / %s_a;\n" - " \n" - " vec2 is_valid = step (vec2 (0.0), t) * step (t, vec2(1.0));\n" - " float has_color = step (0., det) * max (is_valid.x, is_valid.y);\n" - " \n" - " float upper_t = mix (t.y, t.x, is_valid.x);\n", - namestr, namestr, rectstr, namestr, namestr, namestr, namestr, - namestr, namestr, namestr, namestr, namestr, namestr); - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES && - _cairo_gl_shader_needs_border_fade (op)) - { - _cairo_output_stream_printf (stream, - " float border_fade = %s_border_fade (upper_t, %s_texdims.x);\n" - " vec4 texel = texture2D%s (%s_sampler, vec2 (upper_t, 0.5));\n" - " return mix (vec4 (0.0), texel * border_fade, has_color);\n" - "}\n", - namestr, namestr, rectstr, namestr); - } - else - { - _cairo_output_stream_printf (stream, - " vec4 texel = texture2D%s (%s_sampler, %s_wrap (vec2(upper_t, 0.5)));\n" - " return mix (vec4 (0.0), texel, has_color);\n" - "}\n", - rectstr, namestr, namestr); - } - break; - case CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT: - _cairo_output_stream_printf (stream, - "varying vec2 %s_texcoords;\n" - "uniform sampler2D%s %s_sampler;\n" - "uniform vec3 %s_circle_d;\n" - "uniform float %s_a;\n" - "uniform float %s_radius_0;\n" - "\n" - "vec4 get_%s()\n" - "{\n" - " vec3 pos = vec3 (%s_texcoords, %s_radius_0);\n" - " \n" - " float B = dot (pos, %s_circle_d);\n" - " float C = dot (pos, vec3 (pos.xy, -pos.z));\n" - " \n" - " float det = dot (vec2 (B, %s_a), vec2 (B, -C));\n" - " float sqrtdet = sqrt (abs (det));\n" - " vec2 t = (B + vec2 (sqrtdet, -sqrtdet)) / %s_a;\n" - " \n" - " vec2 is_valid = step (vec2 (-%s_radius_0), t * %s_circle_d.z);\n" - " float has_color = step (0., det) * max (is_valid.x, is_valid.y);\n" - " \n" - " float upper_t = mix (t.y, t.x, is_valid.x);\n" - " vec4 texel = texture2D%s (%s_sampler, %s_wrap (vec2(upper_t, 0.5)));\n" - " return mix (vec4 (0.0), texel, has_color);\n" - "}\n", - namestr, rectstr, namestr, namestr, namestr, namestr, - namestr, namestr, namestr, namestr, namestr, - namestr, namestr, namestr, rectstr, namestr, namestr); - break; - } -} - -/* - * Emits the border fade functions used by an operand. - * - * If bilinear filtering is used, the emitted function performs a linear - * fade to transparency effect in the intervals [-1/2n, 1/2n] and - * [1 - 1/2n, 1 + 1/2n] (n: texture size). - * - * If nearest filtering is used, the emitted function just returns - * 0.0 for all values outside [0, 1). - */ -static void -_cairo_gl_shader_emit_border_fade (cairo_output_stream_t *stream, - cairo_gl_operand_t *operand, - cairo_gl_tex_t name) -{ - const char *namestr = operand_names[name]; - GLint gl_filter = _cairo_gl_operand_get_gl_filter (operand); - - /* 2D version */ - _cairo_output_stream_printf (stream, - "vec2 %s_border_fade (vec2 coords, vec2 dims)\n" - "{\n", - namestr); - - if (gl_filter == GL_LINEAR) - _cairo_output_stream_printf (stream, - " return clamp(-abs(dims * (coords - 0.5)) + (dims + vec2(1.0)) * 0.5, 0.0, 1.0);\n"); - else - _cairo_output_stream_printf (stream, - " bvec2 in_tex1 = greaterThanEqual (coords, vec2 (0.0));\n" - " bvec2 in_tex2 = lessThan (coords, vec2 (1.0));\n" - " return vec2 (float (all (in_tex1) && all (in_tex2)));\n"); - - _cairo_output_stream_printf (stream, "}\n"); - - /* 1D version */ - _cairo_output_stream_printf (stream, - "float %s_border_fade (float x, float dim)\n" - "{\n", - namestr); - if (gl_filter == GL_LINEAR) - _cairo_output_stream_printf (stream, - " return clamp(-abs(dim * (x - 0.5)) + (dim + 1.0) * 0.5, 0.0, 1.0);\n"); - else - _cairo_output_stream_printf (stream, - " bool in_tex = x >= 0.0 && x < 1.0;\n" - " return float (in_tex);\n"); - - _cairo_output_stream_printf (stream, "}\n"); -} - -/* - * Emits the wrap function used by an operand. - * - * In OpenGL ES 2.0, repeat wrap modes (GL_REPEAT and GL_MIRRORED REPEAT) are - * only available for NPOT textures if the GL_OES_texture_npot is supported. - * If GL_OES_texture_npot is not supported, we need to implement the wrapping - * functionality in the shader. - */ -static void -_cairo_gl_shader_emit_wrap (cairo_gl_context_t *ctx, - cairo_output_stream_t *stream, - cairo_gl_operand_t *operand, - cairo_gl_tex_t name) -{ - const char *namestr = operand_names[name]; - cairo_extend_t extend = _cairo_gl_operand_get_extend (operand); - - _cairo_output_stream_printf (stream, - "vec2 %s_wrap(vec2 coords)\n" - "{\n", - namestr); - - if (! ctx->has_npot_repeat && - (extend == CAIRO_EXTEND_REPEAT || extend == CAIRO_EXTEND_REFLECT)) - { - if (extend == CAIRO_EXTEND_REPEAT) { - _cairo_output_stream_printf (stream, - " return fract(coords);\n"); - } else { /* CAIRO_EXTEND_REFLECT */ - _cairo_output_stream_printf (stream, - " return mix(fract(coords), 1.0 - fract(coords), floor(mod(coords, 2.0)));\n"); - } - } - else - { - _cairo_output_stream_printf (stream, " return coords;\n"); - } - - _cairo_output_stream_printf (stream, "}\n"); -} - -static cairo_status_t -cairo_gl_shader_get_fragment_source (cairo_gl_context_t *ctx, - cairo_gl_shader_in_t in, - cairo_gl_operand_t *src, - cairo_gl_operand_t *mask, - cairo_bool_t use_coverage, - cairo_gl_operand_type_t dest_type, - char **out) -{ - cairo_output_stream_t *stream = _cairo_memory_stream_create (); - unsigned char *source; - unsigned long length; - cairo_status_t status; - const char *coverage_str; - - _cairo_output_stream_printf (stream, - "#ifdef GL_ES\n" - "precision mediump float;\n" - "#endif\n"); - - _cairo_gl_shader_emit_wrap (ctx, stream, src, CAIRO_GL_TEX_SOURCE); - _cairo_gl_shader_emit_wrap (ctx, stream, mask, CAIRO_GL_TEX_MASK); - - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES) { - if (_cairo_gl_shader_needs_border_fade (src)) - _cairo_gl_shader_emit_border_fade (stream, src, CAIRO_GL_TEX_SOURCE); - if (_cairo_gl_shader_needs_border_fade (mask)) - _cairo_gl_shader_emit_border_fade (stream, mask, CAIRO_GL_TEX_MASK); - } - - cairo_gl_shader_emit_color (stream, ctx, src, CAIRO_GL_TEX_SOURCE); - cairo_gl_shader_emit_color (stream, ctx, mask, CAIRO_GL_TEX_MASK); - - coverage_str = ""; - if (use_coverage) { - _cairo_output_stream_printf (stream, "varying float coverage;\n"); - coverage_str = " * coverage"; - } - - _cairo_output_stream_printf (stream, - "void main()\n" - "{\n"); - switch (in) { - case CAIRO_GL_SHADER_IN_COUNT: - default: - ASSERT_NOT_REACHED; - case CAIRO_GL_SHADER_IN_NORMAL: - _cairo_output_stream_printf (stream, - " gl_FragColor = get_source() * get_mask().a%s;\n", - coverage_str); - break; - case CAIRO_GL_SHADER_IN_CA_SOURCE: - _cairo_output_stream_printf (stream, - " gl_FragColor = get_source() * get_mask()%s;\n", - coverage_str); - break; - case CAIRO_GL_SHADER_IN_CA_SOURCE_ALPHA: - _cairo_output_stream_printf (stream, - " gl_FragColor = get_source().a * get_mask()%s;\n", - coverage_str); - break; - } - - _cairo_output_stream_write (stream, - "}\n\0", 3); - - status = _cairo_memory_stream_destroy (stream, &source, &length); - if (unlikely (status)) - return status; - - *out = (char *) source; - return CAIRO_STATUS_SUCCESS; -} - -static void -compile_shader (cairo_gl_context_t *ctx, - GLuint *shader, - GLenum type, - const char *source) -{ - cairo_gl_dispatch_t *dispatch = &ctx->dispatch; - GLint success, log_size, num_chars; - char *log; - - *shader = dispatch->CreateShader (type); - dispatch->ShaderSource (*shader, 1, &source, 0); - dispatch->CompileShader (*shader); - dispatch->GetShaderiv (*shader, GL_COMPILE_STATUS, &success); - - if (success) - return; - - dispatch->GetShaderiv (*shader, GL_INFO_LOG_LENGTH, &log_size); - if (log_size < 0) { - printf ("OpenGL shader compilation failed.\n"); - ASSERT_NOT_REACHED; - return; - } - - log = _cairo_malloc (log_size + 1); - dispatch->GetShaderInfoLog (*shader, log_size, &num_chars, log); - log[num_chars] = '\0'; - - printf ("OpenGL shader compilation failed. Shader:\n%s\n", source); - printf ("OpenGL compilation log:\n%s\n", log); - - free (log); - ASSERT_NOT_REACHED; -} - -static void -link_shader_program (cairo_gl_context_t *ctx, - GLuint *program, - GLuint vert, - GLuint frag) -{ - cairo_gl_dispatch_t *dispatch = &ctx->dispatch; - GLint success, log_size, num_chars; - char *log; - - *program = dispatch->CreateProgram (); - dispatch->AttachShader (*program, vert); - dispatch->AttachShader (*program, frag); - - dispatch->BindAttribLocation (*program, CAIRO_GL_VERTEX_ATTRIB_INDEX, - "Vertex"); - dispatch->BindAttribLocation (*program, CAIRO_GL_COLOR_ATTRIB_INDEX, - "Color"); - dispatch->BindAttribLocation (*program, CAIRO_GL_TEXCOORD0_ATTRIB_INDEX, - "MultiTexCoord0"); - dispatch->BindAttribLocation (*program, CAIRO_GL_TEXCOORD1_ATTRIB_INDEX, - "MultiTexCoord1"); - - dispatch->LinkProgram (*program); - dispatch->GetProgramiv (*program, GL_LINK_STATUS, &success); - if (success) - return; - - dispatch->GetProgramiv (*program, GL_INFO_LOG_LENGTH, &log_size); - if (log_size < 0) { - printf ("OpenGL shader link failed.\n"); - ASSERT_NOT_REACHED; - return; - } - - log = _cairo_malloc (log_size + 1); - dispatch->GetProgramInfoLog (*program, log_size, &num_chars, log); - log[num_chars] = '\0'; - - printf ("OpenGL shader link failed:\n%s\n", log); - free (log); - ASSERT_NOT_REACHED; -} - -static GLint -_cairo_gl_get_op_uniform_location(cairo_gl_context_t *ctx, - cairo_gl_shader_t *shader, - cairo_gl_tex_t tex_unit, - const char *suffix) -{ - cairo_gl_dispatch_t *dispatch = &ctx->dispatch; - char uniform_name[100]; - const char *unit_name[2] = { "source", "mask" }; - - snprintf (uniform_name, sizeof (uniform_name), "%s_%s", - unit_name[tex_unit], suffix); - - return dispatch->GetUniformLocation (shader->program, uniform_name); -} - -static cairo_status_t -_cairo_gl_shader_compile_and_link (cairo_gl_context_t *ctx, - cairo_gl_shader_t *shader, - cairo_gl_var_type_t src, - cairo_gl_var_type_t mask, - cairo_bool_t use_coverage, - const char *fragment_text) -{ - cairo_gl_dispatch_t *dispatch = &ctx->dispatch; - unsigned int vertex_shader; - cairo_status_t status; - int i; - - assert (shader->program == 0); - - vertex_shader = cairo_gl_var_type_hash (src, mask, use_coverage, - CAIRO_GL_VAR_NONE); - if (ctx->vertex_shaders[vertex_shader] == 0) { - char *source; - - status = cairo_gl_shader_get_vertex_source (src, - mask, - use_coverage, - CAIRO_GL_VAR_NONE, - &source); - if (unlikely (status)) - goto FAILURE; - - compile_shader (ctx, &ctx->vertex_shaders[vertex_shader], - GL_VERTEX_SHADER, source); - free (source); - } - - compile_shader (ctx, &shader->fragment_shader, - GL_FRAGMENT_SHADER, fragment_text); - - link_shader_program (ctx, &shader->program, - ctx->vertex_shaders[vertex_shader], - shader->fragment_shader); - - shader->mvp_location = - dispatch->GetUniformLocation (shader->program, - "ModelViewProjectionMatrix"); - - for (i = 0; i < 2; i++) { - shader->constant_location[i] = - _cairo_gl_get_op_uniform_location (ctx, shader, i, "constant"); - shader->a_location[i] = - _cairo_gl_get_op_uniform_location (ctx, shader, i, "a"); - shader->circle_d_location[i] = - _cairo_gl_get_op_uniform_location (ctx, shader, i, "circle_d"); - shader->radius_0_location[i] = - _cairo_gl_get_op_uniform_location (ctx, shader, i, "radius_0"); - shader->texdims_location[i] = - _cairo_gl_get_op_uniform_location (ctx, shader, i, "texdims"); - shader->texgen_location[i] = - _cairo_gl_get_op_uniform_location (ctx, shader, i, "texgen"); - } - - return CAIRO_STATUS_SUCCESS; - - FAILURE: - _cairo_gl_shader_fini (ctx, shader); - shader->fragment_shader = 0; - shader->program = 0; - - return status; -} - -/* We always bind the source to texture unit 0 if present, and mask to - * texture unit 1 if present, so we can just initialize these once at - * compile time. - */ -static void -_cairo_gl_shader_set_samplers (cairo_gl_context_t *ctx, - cairo_gl_shader_t *shader) -{ - cairo_gl_dispatch_t *dispatch = &ctx->dispatch; - GLint location; - GLint saved_program; - - /* We have to save/restore the current program because we might be - * asked for a different program while a shader is bound. This shouldn't - * be a performance issue, since this is only called once per compile. - */ - glGetIntegerv (GL_CURRENT_PROGRAM, &saved_program); - dispatch->UseProgram (shader->program); - - location = dispatch->GetUniformLocation (shader->program, "source_sampler"); - if (location != -1) { - dispatch->Uniform1i (location, CAIRO_GL_TEX_SOURCE); - } - - location = dispatch->GetUniformLocation (shader->program, "mask_sampler"); - if (location != -1) { - dispatch->Uniform1i (location, CAIRO_GL_TEX_MASK); - } - - dispatch->UseProgram (saved_program); -} - -void -_cairo_gl_shader_bind_float (cairo_gl_context_t *ctx, - GLint location, - float value) -{ - cairo_gl_dispatch_t *dispatch = &ctx->dispatch; - assert (location != -1); - dispatch->Uniform1f (location, value); -} - -void -_cairo_gl_shader_bind_vec2 (cairo_gl_context_t *ctx, - GLint location, - float value0, - float value1) -{ - cairo_gl_dispatch_t *dispatch = &ctx->dispatch; - assert (location != -1); - dispatch->Uniform2f (location, value0, value1); -} - -void -_cairo_gl_shader_bind_vec3 (cairo_gl_context_t *ctx, - GLint location, - float value0, - float value1, - float value2) -{ - cairo_gl_dispatch_t *dispatch = &ctx->dispatch; - assert (location != -1); - dispatch->Uniform3f (location, value0, value1, value2); -} - -void -_cairo_gl_shader_bind_vec4 (cairo_gl_context_t *ctx, - GLint location, - float value0, float value1, - float value2, float value3) -{ - cairo_gl_dispatch_t *dispatch = &ctx->dispatch; - assert (location != -1); - dispatch->Uniform4f (location, value0, value1, value2, value3); -} - -void -_cairo_gl_shader_bind_matrix (cairo_gl_context_t *ctx, - GLint location, - const cairo_matrix_t* m) -{ - cairo_gl_dispatch_t *dispatch = &ctx->dispatch; - float gl_m[9] = { - m->xx, m->yx, 0, - m->xy, m->yy, 0, - m->x0, m->y0, 1 - }; - assert (location != -1); - dispatch->UniformMatrix3fv (location, 1, GL_FALSE, gl_m); -} - -void -_cairo_gl_shader_bind_matrix4f (cairo_gl_context_t *ctx, - GLint location, GLfloat* gl_m) -{ - cairo_gl_dispatch_t *dispatch = &ctx->dispatch; - assert (location != -1); - dispatch->UniformMatrix4fv (location, 1, GL_FALSE, gl_m); -} - -void -_cairo_gl_set_shader (cairo_gl_context_t *ctx, - cairo_gl_shader_t *shader) -{ - if (ctx->current_shader == shader) - return; - - if (shader) - ctx->dispatch.UseProgram (shader->program); - else - ctx->dispatch.UseProgram (0); - - ctx->current_shader = shader; -} - -cairo_status_t -_cairo_gl_get_shader_by_type (cairo_gl_context_t *ctx, - cairo_gl_operand_t *source, - cairo_gl_operand_t *mask, - cairo_bool_t use_coverage, - cairo_gl_shader_in_t in, - cairo_gl_shader_t **shader) -{ - cairo_shader_cache_entry_t lookup, *entry; - char *fs_source; - cairo_status_t status; - - lookup.ctx = ctx; - - lookup.vertex = cairo_gl_var_type_hash (cairo_gl_operand_get_var_type (source), - cairo_gl_operand_get_var_type (mask), - use_coverage, - CAIRO_GL_VAR_NONE); - - lookup.src = source->type; - lookup.mask = mask->type; - lookup.dest = CAIRO_GL_OPERAND_NONE; - lookup.use_coverage = use_coverage; - lookup.in = in; - lookup.src_gl_filter = _cairo_gl_operand_get_gl_filter (source); - lookup.src_border_fade = _cairo_gl_shader_needs_border_fade (source); - lookup.src_extend = _cairo_gl_operand_get_extend (source); - lookup.mask_gl_filter = _cairo_gl_operand_get_gl_filter (mask); - lookup.mask_border_fade = _cairo_gl_shader_needs_border_fade (mask); - lookup.mask_extend = _cairo_gl_operand_get_extend (mask); - lookup.base.hash = _cairo_gl_shader_cache_hash (&lookup); - lookup.base.size = 1; - - entry = _cairo_cache_lookup (&ctx->shaders, &lookup.base); - if (entry) { - assert (entry->shader.program); - *shader = &entry->shader; - return CAIRO_STATUS_SUCCESS; - } - - status = cairo_gl_shader_get_fragment_source (ctx, - in, - source, - mask, - use_coverage, - CAIRO_GL_OPERAND_NONE, - &fs_source); - if (unlikely (status)) - return status; - - entry = malloc (sizeof (cairo_shader_cache_entry_t)); - if (unlikely (entry == NULL)) { - free (fs_source); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - memcpy (entry, &lookup, sizeof (cairo_shader_cache_entry_t)); - - entry->ctx = ctx; - _cairo_gl_shader_init (&entry->shader); - status = _cairo_gl_shader_compile_and_link (ctx, - &entry->shader, - cairo_gl_operand_get_var_type (source), - cairo_gl_operand_get_var_type (mask), - use_coverage, - fs_source); - free (fs_source); - - if (unlikely (status)) { - free (entry); - return status; - } - - _cairo_gl_shader_set_samplers (ctx, &entry->shader); - - status = _cairo_cache_insert (&ctx->shaders, &entry->base); - if (unlikely (status)) { - _cairo_gl_shader_fini (ctx, &entry->shader); - free (entry); - return status; - } - - *shader = &entry->shader; - - return CAIRO_STATUS_SUCCESS; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-gl-source.c b/source/libs/cairo/cairo-src/src/cairo-gl-source.c deleted file mode 100644 index 12235295f407252e97a88ca1bf52e3429d3bbf6e..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-gl-source.c +++ /dev/null @@ -1,111 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-gl-private.h" - -#include "cairo-surface-backend-private.h" - -static cairo_status_t -_cairo_gl_source_finish (void *abstract_surface) -{ - cairo_gl_source_t *source = abstract_surface; - - _cairo_gl_operand_destroy (&source->operand); - return CAIRO_STATUS_SUCCESS; -} - -static const cairo_surface_backend_t cairo_gl_source_backend = { - CAIRO_SURFACE_TYPE_GL, - _cairo_gl_source_finish, - NULL, /* read-only wrapper */ -}; - -cairo_surface_t * -_cairo_gl_pattern_to_source (cairo_surface_t *dst, - const cairo_pattern_t *pattern, - cairo_bool_t is_mask, - const cairo_rectangle_int_t *extents, - const cairo_rectangle_int_t *sample, - int *src_x, int *src_y) -{ - cairo_gl_source_t *source; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - if (pattern == NULL) - return _cairo_gl_white_source (); - - source = malloc (sizeof (*source)); - if (unlikely (source == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - _cairo_surface_init (&source->base, - &cairo_gl_source_backend, - NULL, /* device */ - CAIRO_CONTENT_COLOR_ALPHA); - - *src_x = *src_y = 0; - status = _cairo_gl_operand_init (&source->operand, pattern, - (cairo_gl_surface_t *)dst, - sample, extents, - FALSE); - if (unlikely (status)) { - cairo_surface_destroy (&source->base); - return _cairo_surface_create_in_error (status); - } - - return &source->base; -} - -cairo_surface_t * -_cairo_gl_white_source (void) -{ - cairo_gl_source_t *source; - - source = malloc (sizeof (*source)); - if (unlikely (source == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - _cairo_surface_init (&source->base, - &cairo_gl_source_backend, - NULL, /* device */ - CAIRO_CONTENT_COLOR_ALPHA); - - _cairo_gl_solid_operand_init (&source->operand, CAIRO_COLOR_WHITE); - - return &source->base; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-gl-spans-compositor.c b/source/libs/cairo/cairo-src/src/cairo-gl-spans-compositor.c deleted file mode 100644 index 4317ccd074a1ec57d8950bc03e0c745321f9dc62..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-gl-spans-compositor.c +++ /dev/null @@ -1,553 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Eric Anholt - * Copyright © 2009 Chris Wilson - * Copyright © 2005,2010 Red Hat, Inc - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Benjamin Otte <otte@gnome.org> - * Carl Worth <cworth@cworth.org> - * Chris Wilson <chris@chris-wilson.co.uk> - * Eric Anholt <eric@anholt.net> - */ - -#include "cairoint.h" - -#include "cairo-gl-private.h" - -#include "cairo-composite-rectangles-private.h" -#include "cairo-compositor-private.h" -#include "cairo-default-context-private.h" -#include "cairo-error-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-spans-compositor-private.h" -#include "cairo-surface-backend-private.h" - -typedef struct _cairo_gl_span_renderer { - cairo_span_renderer_t base; - - cairo_gl_composite_t setup; - double opacity; - - cairo_gl_emit_span_t emit; - - int xmin, xmax; - int ymin, ymax; - - cairo_gl_context_t *ctx; -} cairo_gl_span_renderer_t; - -static cairo_status_t -_cairo_gl_bounded_opaque_spans (void *abstract_renderer, - int y, int height, - const cairo_half_open_span_t *spans, - unsigned num_spans) -{ - cairo_gl_span_renderer_t *r = abstract_renderer; - cairo_gl_emit_span_t emit = r->emit; - - if (num_spans == 0) - return CAIRO_STATUS_SUCCESS; - - do { - if (spans[0].coverage) { - emit (r->ctx, - spans[0].x, y, - spans[1].x, y + height, - spans[0].coverage); - } - - spans++; - } while (--num_spans > 1); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_gl_bounded_spans (void *abstract_renderer, - int y, int height, - const cairo_half_open_span_t *spans, - unsigned num_spans) -{ - cairo_gl_span_renderer_t *r = abstract_renderer; - cairo_gl_emit_span_t emit = r->emit; - - if (num_spans == 0) - return CAIRO_STATUS_SUCCESS; - - do { - if (spans[0].coverage) { - emit (r->ctx, - spans[0].x, y, - spans[1].x, y + height, - r->opacity * spans[0].coverage); - } - - spans++; - } while (--num_spans > 1); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_gl_unbounded_spans (void *abstract_renderer, - int y, int height, - const cairo_half_open_span_t *spans, - unsigned num_spans) -{ - cairo_gl_span_renderer_t *r = abstract_renderer; - cairo_gl_emit_span_t emit = r->emit; - - if (y > r->ymin) { - emit (r->ctx, - r->xmin, r->ymin, - r->xmax, y, - 0); - } - - if (num_spans == 0) { - emit (r->ctx, - r->xmin, y, - r->xmax, y + height, - 0); - } else { - if (spans[0].x != r->xmin) { - emit (r->ctx, - r->xmin, y, - spans[0].x, y + height, - 0); - } - - do { - emit (r->ctx, - spans[0].x, y, - spans[1].x, y + height, - r->opacity * spans[0].coverage); - spans++; - } while (--num_spans > 1); - - if (spans[0].x != r->xmax) { - emit (r->ctx, - spans[0].x, y, - r->xmax, y + height, - 0); - } - } - - r->ymin = y + height; - return CAIRO_STATUS_SUCCESS; -} - -/* XXX */ -static cairo_status_t -_cairo_gl_clipped_spans (void *abstract_renderer, - int y, int height, - const cairo_half_open_span_t *spans, - unsigned num_spans) -{ - cairo_gl_span_renderer_t *r = abstract_renderer; - cairo_gl_emit_span_t emit = r->emit; - - if (y > r->ymin) { - emit (r->ctx, - r->xmin, r->ymin, - r->xmax, y, - 0); - } - - if (num_spans == 0) { - emit (r->ctx, - r->xmin, y, - r->xmax, y + height, - 0); - } else { - if (spans[0].x != r->xmin) { - emit (r->ctx, - r->xmin, y, - spans[0].x, y + height, - 0); - } - - do { - emit (r->ctx, - spans[0].x, y, - spans[1].x, y + height, - r->opacity * spans[0].coverage); - spans++; - } while (--num_spans > 1); - - if (spans[0].x != r->xmax) { - emit (r->ctx, - spans[0].x, y, - r->xmax, y + height, - 0); - } - } - - r->ymin = y + height; - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_gl_finish_unbounded_spans (void *abstract_renderer) -{ - cairo_gl_span_renderer_t *r = abstract_renderer; - cairo_gl_emit_span_t emit = r->emit; - - if (r->ymax > r->ymin) { - emit (r->ctx, - r->xmin, r->ymin, - r->xmax, r->ymax, - 0); - } - - return _cairo_gl_context_release (r->ctx, CAIRO_STATUS_SUCCESS); -} - -static cairo_status_t -_cairo_gl_finish_bounded_spans (void *abstract_renderer) -{ - cairo_gl_span_renderer_t *r = abstract_renderer; - - return _cairo_gl_context_release (r->ctx, CAIRO_STATUS_SUCCESS); -} - -static void -emit_aligned_boxes (cairo_gl_context_t *ctx, - const cairo_boxes_t *boxes) -{ - const struct _cairo_boxes_chunk *chunk; - cairo_gl_emit_rect_t emit = _cairo_gl_context_choose_emit_rect (ctx); - int i; - - TRACE ((stderr, "%s: num_boxes=%d\n", __FUNCTION__, boxes->num_boxes)); - for (chunk = &boxes->chunks; chunk; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) { - int x1 = _cairo_fixed_integer_part (chunk->base[i].p1.x); - int y1 = _cairo_fixed_integer_part (chunk->base[i].p1.y); - int x2 = _cairo_fixed_integer_part (chunk->base[i].p2.x); - int y2 = _cairo_fixed_integer_part (chunk->base[i].p2.y); - emit (ctx, x1, y1, x2, y2); - } - } -} - -static cairo_int_status_t -fill_boxes (void *_dst, - cairo_operator_t op, - const cairo_color_t *color, - cairo_boxes_t *boxes) -{ - cairo_gl_composite_t setup; - cairo_gl_context_t *ctx; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - status = _cairo_gl_composite_init (&setup, op, _dst, FALSE); - if (unlikely (status)) - goto FAIL; - - _cairo_gl_composite_set_solid_source (&setup, color); - - status = _cairo_gl_composite_begin (&setup, &ctx); - if (unlikely (status)) - goto FAIL; - - emit_aligned_boxes (ctx, boxes); - status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS); - -FAIL: - _cairo_gl_composite_fini (&setup); - return status; -} - -static cairo_int_status_t -draw_image_boxes (void *_dst, - cairo_image_surface_t *image, - cairo_boxes_t *boxes, - int dx, int dy) -{ - cairo_gl_surface_t *dst = _dst; - struct _cairo_boxes_chunk *chunk; - int i; - - for (chunk = &boxes->chunks; chunk; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) { - cairo_box_t *b = &chunk->base[i]; - int x = _cairo_fixed_integer_part (b->p1.x); - int y = _cairo_fixed_integer_part (b->p1.y); - int w = _cairo_fixed_integer_part (b->p2.x) - x; - int h = _cairo_fixed_integer_part (b->p2.y) - y; - cairo_status_t status; - - status = _cairo_gl_surface_draw_image (dst, image, - x + dx, y + dy, - w, h, - x, y, TRUE); - if (unlikely (status)) - return status; - } - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t copy_boxes (void *_dst, - cairo_surface_t *_src, - cairo_boxes_t *boxes, - const cairo_rectangle_int_t *extents, - int dx, int dy) -{ - cairo_gl_surface_t *dst = _dst; - cairo_gl_surface_t *src = (cairo_gl_surface_t *)_src; - cairo_gl_composite_t setup; - cairo_gl_context_t *ctx; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - if (! _cairo_gl_surface_is_texture (src)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (src->base.device != dst->base.device) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_gl_composite_init (&setup, CAIRO_OPERATOR_SOURCE, _dst, FALSE); - if (unlikely (status)) - goto FAIL; - - _cairo_gl_composite_set_source_operand (&setup, &src->operand); - _cairo_gl_operand_translate (&setup.src, -dx, -dy); - - status = _cairo_gl_composite_begin (&setup, &ctx); - if (unlikely (status)) - goto FAIL; - - emit_aligned_boxes (ctx, boxes); - status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS); - -FAIL: - _cairo_gl_composite_fini (&setup); - return status; -} - -static cairo_int_status_t -composite_boxes (void *_dst, - cairo_operator_t op, - cairo_surface_t *abstract_src, - cairo_surface_t *abstract_mask, - int src_x, - int src_y, - int mask_x, - int mask_y, - int dst_x, - int dst_y, - cairo_boxes_t *boxes, - const cairo_rectangle_int_t *extents) -{ - cairo_gl_composite_t setup; - cairo_gl_context_t *ctx; - cairo_int_status_t status; - cairo_gl_operand_t tmp_operand; - cairo_gl_operand_t *src_operand; - - TRACE ((stderr, "%s mask=(%d,%d), dst=(%d, %d)\n", __FUNCTION__, - mask_x, mask_y, dst_x, dst_y)); - - if (abstract_mask) { - if (op == CAIRO_OPERATOR_CLEAR) { - _cairo_gl_solid_operand_init (&tmp_operand, CAIRO_COLOR_WHITE); - src_operand = &tmp_operand; - op = CAIRO_OPERATOR_DEST_OUT; - } else if (op == CAIRO_OPERATOR_SOURCE) { - /* requires a LERP in the shader between dest and source */ - return CAIRO_INT_STATUS_UNSUPPORTED; - } else - src_operand = source_to_operand (abstract_src); - } else - src_operand = source_to_operand (abstract_src); - - status = _cairo_gl_composite_init (&setup, op, _dst, FALSE); - if (unlikely (status)) - goto FAIL; - - _cairo_gl_composite_set_source_operand (&setup, - src_operand); - _cairo_gl_operand_translate (&setup.src, -src_x, -src_y); - - _cairo_gl_composite_set_mask_operand (&setup, - source_to_operand (abstract_mask)); - _cairo_gl_operand_translate (&setup.mask, -mask_x, -mask_y); - - status = _cairo_gl_composite_begin (&setup, &ctx); - if (unlikely (status)) - goto FAIL; - - emit_aligned_boxes (ctx, boxes); - status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS); - -FAIL: - _cairo_gl_composite_fini (&setup); - if (src_operand == &tmp_operand) - _cairo_gl_operand_destroy (&tmp_operand); - return status; -} - -static cairo_int_status_t -_cairo_gl_span_renderer_init (cairo_abstract_span_renderer_t *_r, - const cairo_composite_rectangles_t *composite, - cairo_antialias_t antialias, - cairo_bool_t needs_clip) -{ - cairo_gl_span_renderer_t *r = (cairo_gl_span_renderer_t *)_r; - const cairo_pattern_t *source = &composite->source_pattern.base; - cairo_operator_t op = composite->op; - cairo_int_status_t status; - - if (op == CAIRO_OPERATOR_SOURCE) { - if (! _cairo_pattern_is_opaque (&composite->source_pattern.base, - &composite->source_sample_area)) - return CAIRO_INT_STATUS_UNSUPPORTED; - op = CAIRO_OPERATOR_OVER; - } - - /* XXX earlier! */ - if (op == CAIRO_OPERATOR_CLEAR) { - source = &_cairo_pattern_white.base; - op = CAIRO_OPERATOR_DEST_OUT; - } else if (composite->surface->is_clear && - (op == CAIRO_OPERATOR_SOURCE || - op == CAIRO_OPERATOR_OVER || - op == CAIRO_OPERATOR_ADD)) { - op = CAIRO_OPERATOR_SOURCE; - } else if (op == CAIRO_OPERATOR_SOURCE) { - /* no lerp equivalent without some major PITA */ - return CAIRO_INT_STATUS_UNSUPPORTED; - } else if (! _cairo_gl_operator_is_supported (op)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_gl_composite_init (&r->setup, - op, (cairo_gl_surface_t *)composite->surface, - FALSE); - if (unlikely (status)) - goto FAIL; - - status = _cairo_gl_composite_set_source (&r->setup, source, - &composite->source_sample_area, - &composite->unbounded, - TRUE); - if (unlikely (status)) - goto FAIL; - - r->opacity = 1.0; - if (composite->mask_pattern.base.type == CAIRO_PATTERN_TYPE_SOLID) { - r->opacity = composite->mask_pattern.solid.color.alpha; - } else { - status = _cairo_gl_composite_set_mask (&r->setup, - &composite->mask_pattern.base, - &composite->mask_sample_area, - &composite->unbounded, - TRUE); - if (unlikely (status)) - goto FAIL; - } - - _cairo_gl_composite_set_spans (&r->setup); - - status = _cairo_gl_composite_begin (&r->setup, &r->ctx); - if (unlikely (status)) - goto FAIL; - - r->emit = _cairo_gl_context_choose_emit_span (r->ctx); - if (composite->is_bounded) { - if (r->opacity == 1.) - r->base.render_rows = _cairo_gl_bounded_opaque_spans; - else - r->base.render_rows = _cairo_gl_bounded_spans; - r->base.finish = _cairo_gl_finish_bounded_spans; - } else { - if (needs_clip) - r->base.render_rows = _cairo_gl_clipped_spans; - else - r->base.render_rows = _cairo_gl_unbounded_spans; - r->base.finish = _cairo_gl_finish_unbounded_spans; - r->xmin = composite->unbounded.x; - r->xmax = composite->unbounded.x + composite->unbounded.width; - r->ymin = composite->unbounded.y; - r->ymax = composite->unbounded.y + composite->unbounded.height; - } - - return CAIRO_STATUS_SUCCESS; - -FAIL: - return status; -} - -static void -_cairo_gl_span_renderer_fini (cairo_abstract_span_renderer_t *_r, - cairo_int_status_t status) -{ - cairo_gl_span_renderer_t *r = (cairo_gl_span_renderer_t *) _r; - - if (status == CAIRO_INT_STATUS_UNSUPPORTED) - return; - - if (status == CAIRO_INT_STATUS_SUCCESS) - r->base.finish (r); - - _cairo_gl_composite_fini (&r->setup); -} - -const cairo_compositor_t * -_cairo_gl_span_compositor_get (void) -{ - static cairo_spans_compositor_t spans; - static cairo_compositor_t shape; - - if (spans.base.delegate == NULL) { - /* The fallback to traps here is essentially just for glyphs... */ - _cairo_shape_mask_compositor_init (&shape, - _cairo_gl_traps_compositor_get()); - shape.glyphs = NULL; - - _cairo_spans_compositor_init (&spans, &shape); - spans.fill_boxes = fill_boxes; - spans.draw_image_boxes = draw_image_boxes; - spans.copy_boxes = copy_boxes; - //spans.check_composite_boxes = check_composite_boxes; - spans.pattern_to_surface = _cairo_gl_pattern_to_source; - spans.composite_boxes = composite_boxes; - //spans.check_span_renderer = check_span_renderer; - spans.renderer_init = _cairo_gl_span_renderer_init; - spans.renderer_fini = _cairo_gl_span_renderer_fini; - } - - return &spans.base; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-gl-surface.c b/source/libs/cairo/cairo-src/src/cairo-gl-surface.c deleted file mode 100644 index cfccf4dfda53a08e2414ca7dd8038bceff558273..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-gl-surface.c +++ /dev/null @@ -1,1459 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Eric Anholt - * Copyright © 2009 Chris Wilson - * Copyright © 2005,2010 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Benjamin Otte <otte@gnome.org> - * Carl Worth <cworth@cworth.org> - * Chris Wilson <chris@chris-wilson.co.uk> - * Eric Anholt <eric@anholt.net> - */ - -#include "cairoint.h" - -#include "cairo-gl-private.h" - -#include "cairo-composite-rectangles-private.h" -#include "cairo-compositor-private.h" -#include "cairo-default-context-private.h" -#include "cairo-error-private.h" -#include "cairo-image-surface-inline.h" -#include "cairo-surface-backend-private.h" - -static const cairo_surface_backend_t _cairo_gl_surface_backend; - -static cairo_status_t -_cairo_gl_surface_flush (void *abstract_surface, unsigned flags); - -static cairo_bool_t _cairo_surface_is_gl (cairo_surface_t *surface) -{ - return surface->backend == &_cairo_gl_surface_backend; -} - -static cairo_bool_t -_cairo_gl_get_image_format_and_type_gles2 (pixman_format_code_t pixman_format, - GLenum *internal_format, GLenum *format, - GLenum *type, cairo_bool_t *has_alpha, - cairo_bool_t *needs_swap) -{ - cairo_bool_t is_little_endian = _cairo_is_little_endian (); - - *has_alpha = TRUE; - - switch ((int) pixman_format) { - case PIXMAN_a8r8g8b8: - *internal_format = GL_BGRA; - *format = GL_BGRA; - *type = GL_UNSIGNED_BYTE; - *needs_swap = !is_little_endian; - return TRUE; - - case PIXMAN_x8r8g8b8: - *internal_format = GL_BGRA; - *format = GL_BGRA; - *type = GL_UNSIGNED_BYTE; - *has_alpha = FALSE; - *needs_swap = !is_little_endian; - return TRUE; - - case PIXMAN_a8b8g8r8: - *internal_format = GL_RGBA; - *format = GL_RGBA; - *type = GL_UNSIGNED_BYTE; - *needs_swap = !is_little_endian; - return TRUE; - - case PIXMAN_x8b8g8r8: - *internal_format = GL_RGBA; - *format = GL_RGBA; - *type = GL_UNSIGNED_BYTE; - *has_alpha = FALSE; - *needs_swap = !is_little_endian; - return TRUE; - - case PIXMAN_b8g8r8a8: - *internal_format = GL_BGRA; - *format = GL_BGRA; - *type = GL_UNSIGNED_BYTE; - *needs_swap = is_little_endian; - return TRUE; - - case PIXMAN_b8g8r8x8: - *internal_format = GL_BGRA; - *format = GL_BGRA; - *type = GL_UNSIGNED_BYTE; - *has_alpha = FALSE; - *needs_swap = is_little_endian; - return TRUE; - - case PIXMAN_r8g8b8: - *internal_format = GL_RGB; - *format = GL_RGB; - *type = GL_UNSIGNED_BYTE; - *needs_swap = is_little_endian; - return TRUE; - - case PIXMAN_b8g8r8: - *internal_format = GL_RGB; - *format = GL_RGB; - *type = GL_UNSIGNED_BYTE; - *needs_swap = !is_little_endian; - return TRUE; - - case PIXMAN_r5g6b5: - *internal_format = GL_RGB; - *format = GL_RGB; - *type = GL_UNSIGNED_SHORT_5_6_5; - *needs_swap = FALSE; - return TRUE; - - case PIXMAN_b5g6r5: - *internal_format = GL_RGB; - *format = GL_RGB; - *type = GL_UNSIGNED_SHORT_5_6_5; - *needs_swap = TRUE; - return TRUE; - - case PIXMAN_a1b5g5r5: - *internal_format = GL_RGBA; - *format = GL_RGBA; - *type = GL_UNSIGNED_SHORT_5_5_5_1; - *needs_swap = TRUE; - return TRUE; - - case PIXMAN_x1b5g5r5: - *internal_format = GL_RGBA; - *format = GL_RGBA; - *type = GL_UNSIGNED_SHORT_5_5_5_1; - *has_alpha = FALSE; - *needs_swap = TRUE; - return TRUE; - - case PIXMAN_a8: - *internal_format = GL_ALPHA; - *format = GL_ALPHA; - *type = GL_UNSIGNED_BYTE; - *needs_swap = FALSE; - return TRUE; - - default: - return FALSE; - } -} - -static cairo_bool_t -_cairo_gl_get_image_format_and_type_gl (pixman_format_code_t pixman_format, - GLenum *internal_format, GLenum *format, - GLenum *type, cairo_bool_t *has_alpha, - cairo_bool_t *needs_swap) -{ - *has_alpha = TRUE; - *needs_swap = FALSE; - - switch (pixman_format) { - case PIXMAN_a8r8g8b8: - *internal_format = GL_RGBA; - *format = GL_BGRA; - *type = GL_UNSIGNED_INT_8_8_8_8_REV; - return TRUE; - case PIXMAN_x8r8g8b8: - *internal_format = GL_RGB; - *format = GL_BGRA; - *type = GL_UNSIGNED_INT_8_8_8_8_REV; - *has_alpha = FALSE; - return TRUE; - case PIXMAN_a8b8g8r8: - *internal_format = GL_RGBA; - *format = GL_RGBA; - *type = GL_UNSIGNED_INT_8_8_8_8_REV; - return TRUE; - case PIXMAN_x8b8g8r8: - *internal_format = GL_RGB; - *format = GL_RGBA; - *type = GL_UNSIGNED_INT_8_8_8_8_REV; - *has_alpha = FALSE; - return TRUE; - case PIXMAN_b8g8r8a8: - *internal_format = GL_RGBA; - *format = GL_BGRA; - *type = GL_UNSIGNED_INT_8_8_8_8; - return TRUE; - case PIXMAN_b8g8r8x8: - *internal_format = GL_RGB; - *format = GL_BGRA; - *type = GL_UNSIGNED_INT_8_8_8_8; - *has_alpha = FALSE; - return TRUE; - case PIXMAN_r8g8b8: - *internal_format = GL_RGB; - *format = GL_RGB; - *type = GL_UNSIGNED_BYTE; - return TRUE; - case PIXMAN_b8g8r8: - *internal_format = GL_RGB; - *format = GL_BGR; - *type = GL_UNSIGNED_BYTE; - return TRUE; - case PIXMAN_r5g6b5: - *internal_format = GL_RGB; - *format = GL_RGB; - *type = GL_UNSIGNED_SHORT_5_6_5; - return TRUE; - case PIXMAN_b5g6r5: - *internal_format = GL_RGB; - *format = GL_RGB; - *type = GL_UNSIGNED_SHORT_5_6_5_REV; - return TRUE; - case PIXMAN_a1r5g5b5: - *internal_format = GL_RGBA; - *format = GL_BGRA; - *type = GL_UNSIGNED_SHORT_1_5_5_5_REV; - return TRUE; - case PIXMAN_x1r5g5b5: - *internal_format = GL_RGB; - *format = GL_BGRA; - *type = GL_UNSIGNED_SHORT_1_5_5_5_REV; - *has_alpha = FALSE; - return TRUE; - case PIXMAN_a1b5g5r5: - *internal_format = GL_RGBA; - *format = GL_RGBA; - *type = GL_UNSIGNED_SHORT_1_5_5_5_REV; - return TRUE; - case PIXMAN_x1b5g5r5: - *internal_format = GL_RGB; - *format = GL_RGBA; - *type = GL_UNSIGNED_SHORT_1_5_5_5_REV; - *has_alpha = FALSE; - return TRUE; - case PIXMAN_a8: - *internal_format = GL_ALPHA; - *format = GL_ALPHA; - *type = GL_UNSIGNED_BYTE; - return TRUE; - -#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,27,2) - case PIXMAN_a8r8g8b8_sRGB: -#endif - case PIXMAN_a2b10g10r10: - case PIXMAN_x2b10g10r10: - case PIXMAN_a4r4g4b4: - case PIXMAN_x4r4g4b4: - case PIXMAN_a4b4g4r4: - case PIXMAN_x4b4g4r4: - case PIXMAN_r3g3b2: - case PIXMAN_b2g3r3: - case PIXMAN_a2r2g2b2: - case PIXMAN_a2b2g2r2: - case PIXMAN_c8: - case PIXMAN_x4a4: - /* case PIXMAN_x4c4: */ - case PIXMAN_x4g4: - case PIXMAN_a4: - case PIXMAN_r1g2b1: - case PIXMAN_b1g2r1: - case PIXMAN_a1r1g1b1: - case PIXMAN_a1b1g1r1: - case PIXMAN_c4: - case PIXMAN_g4: - case PIXMAN_a1: - case PIXMAN_g1: - case PIXMAN_yuy2: - case PIXMAN_yv12: - case PIXMAN_x2r10g10b10: - case PIXMAN_a2r10g10b10: - case PIXMAN_r8g8b8x8: - case PIXMAN_r8g8b8a8: - case PIXMAN_x14r6g6b6: - default: - return FALSE; - } -} - -/* - * Extracts pixel data from an image surface. - */ -static cairo_status_t -_cairo_gl_surface_extract_image_data (cairo_image_surface_t *image, - int x, int y, - int width, int height, - void **output) -{ - int cpp = PIXMAN_FORMAT_BPP (image->pixman_format) / 8; - char *data = _cairo_malloc_ab (width * height, cpp); - char *dst = data; - unsigned char *src = image->data + y * image->stride + x * cpp; - int i; - - if (unlikely (data == NULL)) - return CAIRO_STATUS_NO_MEMORY; - - for (i = 0; i < height; i++) { - memcpy (dst, src, width * cpp); - src += image->stride; - dst += width * cpp; - } - - *output = data; - - return CAIRO_STATUS_SUCCESS; -} - -cairo_bool_t -_cairo_gl_get_image_format_and_type (cairo_gl_flavor_t flavor, - pixman_format_code_t pixman_format, - GLenum *internal_format, GLenum *format, - GLenum *type, cairo_bool_t *has_alpha, - cairo_bool_t *needs_swap) -{ - if (flavor == CAIRO_GL_FLAVOR_DESKTOP) - return _cairo_gl_get_image_format_and_type_gl (pixman_format, - internal_format, format, - type, has_alpha, - needs_swap); - else - return _cairo_gl_get_image_format_and_type_gles2 (pixman_format, - internal_format, format, - type, has_alpha, - needs_swap); - -} - -cairo_bool_t -_cairo_gl_operator_is_supported (cairo_operator_t op) -{ - return op < CAIRO_OPERATOR_SATURATE; -} - -static void -_cairo_gl_surface_embedded_operand_init (cairo_gl_surface_t *surface) -{ - cairo_gl_operand_t *operand = &surface->operand; - cairo_surface_attributes_t *attributes = &operand->texture.attributes; - - memset (operand, 0, sizeof (cairo_gl_operand_t)); - - operand->type = CAIRO_GL_OPERAND_TEXTURE; - operand->texture.surface = surface; - operand->texture.tex = surface->tex; - - if (_cairo_gl_device_requires_power_of_two_textures (surface->base.device)) { - cairo_matrix_init_identity (&attributes->matrix); - } else { - cairo_matrix_init_scale (&attributes->matrix, - 1.0 / surface->width, - 1.0 / surface->height); - } - - attributes->extend = CAIRO_EXTEND_NONE; - attributes->filter = CAIRO_FILTER_NEAREST; -} - -void -_cairo_gl_surface_init (cairo_device_t *device, - cairo_gl_surface_t *surface, - cairo_content_t content, - int width, int height) -{ - assert (width > 0 && height > 0); - - _cairo_surface_init (&surface->base, - &_cairo_gl_surface_backend, - device, - content); - - surface->width = width; - surface->height = height; - surface->needs_update = FALSE; - - _cairo_gl_surface_embedded_operand_init (surface); -} - -static cairo_bool_t -_cairo_gl_surface_size_valid_for_context (cairo_gl_context_t *ctx, - int width, int height) -{ - return width > 0 && height > 0 && - width <= ctx->max_framebuffer_size && - height <= ctx->max_framebuffer_size; -} - -static cairo_bool_t -_cairo_gl_surface_size_valid (cairo_gl_surface_t *surface, - int width, int height) -{ - cairo_gl_context_t *ctx = (cairo_gl_context_t *)surface->base.device; - return _cairo_gl_surface_size_valid_for_context (ctx, width, height); -} - -static cairo_surface_t * -_cairo_gl_surface_create_scratch_for_texture (cairo_gl_context_t *ctx, - cairo_content_t content, - GLuint tex, - int width, - int height) -{ - cairo_gl_surface_t *surface; - - surface = calloc (1, sizeof (cairo_gl_surface_t)); - if (unlikely (surface == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - surface->tex = tex; - _cairo_gl_surface_init (&ctx->base, surface, content, width, height); - - surface->supports_msaa = ctx->supports_msaa; - surface->supports_stencil = TRUE; - - /* Create the texture used to store the surface's data. */ - _cairo_gl_context_activate (ctx, CAIRO_GL_TEX_TEMP); - glBindTexture (ctx->tex_target, surface->tex); - glTexParameteri (ctx->tex_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri (ctx->tex_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - return &surface->base; -} - -static cairo_surface_t * -_create_scratch_internal (cairo_gl_context_t *ctx, - cairo_content_t content, - int width, - int height, - cairo_bool_t for_caching) -{ - cairo_gl_surface_t *surface; - GLenum format; - GLuint tex; - - glGenTextures (1, &tex); - surface = (cairo_gl_surface_t *) - _cairo_gl_surface_create_scratch_for_texture (ctx, content, - tex, width, height); - if (unlikely (surface->base.status)) - return &surface->base; - - surface->owns_tex = TRUE; - - /* adjust the texture size after setting our real extents */ - if (width < 1) - width = 1; - if (height < 1) - height = 1; - - switch (content) { - default: - ASSERT_NOT_REACHED; - case CAIRO_CONTENT_COLOR_ALPHA: - format = GL_RGBA; - break; - case CAIRO_CONTENT_ALPHA: - /* When using GL_ALPHA, compositing doesn't work properly, but for - * caching surfaces, we are just uploading pixel data, so it isn't - * an issue. */ - if (for_caching) - format = GL_ALPHA; - else - format = GL_RGBA; - break; - case CAIRO_CONTENT_COLOR: - /* GL_RGB is almost what we want here -- sampling 1 alpha when - * texturing, using 1 as destination alpha factor in blending, - * etc. However, when filtering with GL_CLAMP_TO_BORDER, the - * alpha channel of the border color will also be clamped to - * 1, when we actually want the border color we explicitly - * specified. So, we have to store RGBA, and fill the alpha - * channel with 1 when blending. - */ - format = GL_RGBA; - break; - } - - glTexImage2D (ctx->tex_target, 0, format, width, height, 0, - format, GL_UNSIGNED_BYTE, NULL); - - return &surface->base; -} - -cairo_surface_t * -_cairo_gl_surface_create_scratch (cairo_gl_context_t *ctx, - cairo_content_t content, - int width, - int height) -{ - return _create_scratch_internal (ctx, content, width, height, FALSE); -} - -cairo_surface_t * -_cairo_gl_surface_create_scratch_for_caching (cairo_gl_context_t *ctx, - cairo_content_t content, - int width, - int height) -{ - return _create_scratch_internal (ctx, content, width, height, TRUE); -} - -static cairo_status_t -_cairo_gl_surface_clear (cairo_gl_surface_t *surface, - const cairo_color_t *color) -{ - cairo_gl_context_t *ctx; - cairo_status_t status; - double r, g, b, a; - - status = _cairo_gl_context_acquire (surface->base.device, &ctx); - if (unlikely (status)) - return status; - - _cairo_gl_context_set_destination (ctx, surface, surface->msaa_active); - if (surface->base.content & CAIRO_CONTENT_COLOR) { - r = color->red * color->alpha; - g = color->green * color->alpha; - b = color->blue * color->alpha; - } else { - r = g = b = 0; - } - if (surface->base.content & CAIRO_CONTENT_ALPHA) { - a = color->alpha; - } else { - a = 1.0; - } - - glDisable (GL_SCISSOR_TEST); - glClearColor (r, g, b, a); - glClear (GL_COLOR_BUFFER_BIT); - - if (a == 0) - surface->base.is_clear = TRUE; - - return _cairo_gl_context_release (ctx, status); -} - -static cairo_surface_t * -_cairo_gl_surface_create_and_clear_scratch (cairo_gl_context_t *ctx, - cairo_content_t content, - int width, - int height) -{ - cairo_gl_surface_t *surface; - cairo_int_status_t status; - - surface = (cairo_gl_surface_t *) - _cairo_gl_surface_create_scratch (ctx, content, width, height); - if (unlikely (surface->base.status)) - return &surface->base; - - /* Cairo surfaces start out initialized to transparent (black) */ - status = _cairo_gl_surface_clear (surface, CAIRO_COLOR_TRANSPARENT); - if (unlikely (status)) { - cairo_surface_destroy (&surface->base); - return _cairo_surface_create_in_error (status); - } - - return &surface->base; -} - -cairo_surface_t * -cairo_gl_surface_create (cairo_device_t *abstract_device, - cairo_content_t content, - int width, - int height) -{ - cairo_gl_context_t *ctx; - cairo_gl_surface_t *surface; - cairo_status_t status; - - if (! CAIRO_CONTENT_VALID (content)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT)); - - if (abstract_device == NULL) - return _cairo_image_surface_create_with_content (content, width, height); - - if (abstract_device->status) - return _cairo_surface_create_in_error (abstract_device->status); - - if (abstract_device->backend->type != CAIRO_DEVICE_TYPE_GL) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH)); - - status = _cairo_gl_context_acquire (abstract_device, &ctx); - if (unlikely (status)) - return _cairo_surface_create_in_error (status); - - if (! _cairo_gl_surface_size_valid_for_context (ctx, width, height)) { - status = _cairo_gl_context_release (ctx, status); - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE)); - } - - surface = (cairo_gl_surface_t *) - _cairo_gl_surface_create_and_clear_scratch (ctx, content, width, height); - if (unlikely (surface->base.status)) { - status = _cairo_gl_context_release (ctx, surface->base.status); - cairo_surface_destroy (&surface->base); - return _cairo_surface_create_in_error (status); - } - - status = _cairo_gl_context_release (ctx, status); - if (unlikely (status)) { - cairo_surface_destroy (&surface->base); - return _cairo_surface_create_in_error (status); - } - - return &surface->base; -} -slim_hidden_def (cairo_gl_surface_create); - -/** - * cairo_gl_surface_create_for_texture: - * @content: type of content in the surface - * @tex: name of texture to use for storage of surface pixels - * @width: width of the surface, in pixels - * @height: height of the surface, in pixels - * - * Creates a GL surface for the specified texture with the specified - * content and dimensions. The texture must be kept around until the - * #cairo_surface_t is destroyed or cairo_surface_finish() is called - * on the surface. The initial contents of @tex will be used as the - * initial image contents; you must explicitly clear the buffer, - * using, for example, cairo_rectangle() and cairo_fill() if you want - * it cleared. The format of @tex should be compatible with @content, - * in the sense that it must have the color components required by - * @content. - * - * Return value: a pointer to the newly created surface. The caller - * owns the surface and should call cairo_surface_destroy() when done - * with it. - * - * This function always returns a valid pointer, but it will return a - * pointer to a "nil" surface if an error such as out of memory - * occurs. You can use cairo_surface_status() to check for this. - * - * Since: TBD - **/ -cairo_surface_t * -cairo_gl_surface_create_for_texture (cairo_device_t *abstract_device, - cairo_content_t content, - unsigned int tex, - int width, - int height) -{ - cairo_gl_context_t *ctx; - cairo_gl_surface_t *surface; - cairo_status_t status; - - if (! CAIRO_CONTENT_VALID (content)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT)); - - if (abstract_device == NULL) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NULL_POINTER)); - - if (abstract_device->status) - return _cairo_surface_create_in_error (abstract_device->status); - - if (abstract_device->backend->type != CAIRO_DEVICE_TYPE_GL) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_DEVICE_TYPE_MISMATCH)); - - status = _cairo_gl_context_acquire (abstract_device, &ctx); - if (unlikely (status)) - return _cairo_surface_create_in_error (status); - - if (! _cairo_gl_surface_size_valid_for_context (ctx, width, height)) { - status = _cairo_gl_context_release (ctx, status); - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE)); - } - - surface = (cairo_gl_surface_t *) - _cairo_gl_surface_create_scratch_for_texture (ctx, content, - tex, width, height); - status = _cairo_gl_context_release (ctx, status); - - return &surface->base; -} -slim_hidden_def (cairo_gl_surface_create_for_texture); - - -void -cairo_gl_surface_set_size (cairo_surface_t *abstract_surface, - int width, - int height) -{ - cairo_gl_surface_t *surface = (cairo_gl_surface_t *) abstract_surface; - - if (unlikely (abstract_surface->status)) - return; - if (unlikely (abstract_surface->finished)) { - _cairo_surface_set_error (abstract_surface, - _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - return; - } - - if (! _cairo_surface_is_gl (abstract_surface) || - _cairo_gl_surface_is_texture (surface)) { - _cairo_surface_set_error (abstract_surface, - _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH)); - return; - } - - if (surface->width != width || surface->height != height) { - surface->needs_update = TRUE; - surface->width = width; - surface->height = height; - } -} - -int -cairo_gl_surface_get_width (cairo_surface_t *abstract_surface) -{ - cairo_gl_surface_t *surface = (cairo_gl_surface_t *) abstract_surface; - - if (! _cairo_surface_is_gl (abstract_surface)) - return 0; - - return surface->width; -} - -int -cairo_gl_surface_get_height (cairo_surface_t *abstract_surface) -{ - cairo_gl_surface_t *surface = (cairo_gl_surface_t *) abstract_surface; - - if (! _cairo_surface_is_gl (abstract_surface)) - return 0; - - return surface->height; -} - -void -cairo_gl_surface_swapbuffers (cairo_surface_t *abstract_surface) -{ - cairo_gl_surface_t *surface = (cairo_gl_surface_t *) abstract_surface; - - if (unlikely (abstract_surface->status)) - return; - if (unlikely (abstract_surface->finished)) { - _cairo_surface_set_error (abstract_surface, - _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - return; - } - - if (! _cairo_surface_is_gl (abstract_surface)) { - _cairo_surface_set_error (abstract_surface, - CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return; - } - - if (! _cairo_gl_surface_is_texture (surface)) { - cairo_gl_context_t *ctx; - cairo_status_t status; - - status = _cairo_gl_context_acquire (surface->base.device, &ctx); - if (unlikely (status)) - return; - - /* For swapping on EGL, at least, we need a valid context/target. */ - _cairo_gl_context_set_destination (ctx, surface, FALSE); - /* And in any case we should flush any pending operations. */ - _cairo_gl_composite_flush (ctx); - - ctx->swap_buffers (ctx, surface); - - status = _cairo_gl_context_release (ctx, status); - if (status) - status = _cairo_surface_set_error (abstract_surface, status); - } -} - -static cairo_surface_t * -_cairo_gl_surface_create_similar (void *abstract_surface, - cairo_content_t content, - int width, - int height) -{ - cairo_surface_t *surface = abstract_surface; - cairo_gl_context_t *ctx; - cairo_status_t status; - - if (! _cairo_gl_surface_size_valid (abstract_surface, width, height)) - return _cairo_image_surface_create_with_content (content, width, height); - - status = _cairo_gl_context_acquire (surface->device, &ctx); - if (unlikely (status)) - return _cairo_surface_create_in_error (status); - - surface = _cairo_gl_surface_create_and_clear_scratch (ctx, content, width, height); - - status = _cairo_gl_context_release (ctx, status); - if (unlikely (status)) { - cairo_surface_destroy (surface); - return _cairo_surface_create_in_error (status); - } - - return surface; -} - -static cairo_int_status_t -_cairo_gl_surface_fill_alpha_channel (cairo_gl_surface_t *dst, - cairo_gl_context_t *ctx, - int x, int y, - int width, int height) -{ - cairo_gl_composite_t setup; - cairo_status_t status; - - _cairo_gl_composite_flush (ctx); - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); - - status = _cairo_gl_composite_init (&setup, CAIRO_OPERATOR_SOURCE, - dst, FALSE); - if (unlikely (status)) - goto CLEANUP; - - _cairo_gl_composite_set_solid_source (&setup, CAIRO_COLOR_BLACK); - - status = _cairo_gl_composite_begin (&setup, &ctx); - if (unlikely (status)) - goto CLEANUP; - - _cairo_gl_context_emit_rect (ctx, x, y, x + width, y + height); - - status = _cairo_gl_context_release (ctx, status); - - CLEANUP: - _cairo_gl_composite_fini (&setup); - - _cairo_gl_composite_flush (ctx); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - - return status; -} - -cairo_status_t -_cairo_gl_surface_draw_image (cairo_gl_surface_t *dst, - cairo_image_surface_t *src, - int src_x, int src_y, - int width, int height, - int dst_x, int dst_y, - cairo_bool_t force_flush) -{ - GLenum internal_format, format, type; - cairo_bool_t has_alpha, needs_swap; - cairo_image_surface_t *clone = NULL; - cairo_gl_context_t *ctx; - int cpp; - cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS; - - status = _cairo_gl_context_acquire (dst->base.device, &ctx); - if (unlikely (status)) - return status; - - if (! _cairo_gl_get_image_format_and_type (ctx->gl_flavor, - src->pixman_format, - &internal_format, - &format, - &type, - &has_alpha, - &needs_swap)) - { - cairo_bool_t is_supported; - - clone = _cairo_image_surface_coerce (src); - if (unlikely (status = clone->base.status)) - goto FAIL; - - is_supported = - _cairo_gl_get_image_format_and_type (ctx->gl_flavor, - clone->pixman_format, - &internal_format, - &format, - &type, - &has_alpha, - &needs_swap); - assert (is_supported); - assert (!needs_swap); - src = clone; - } - - cpp = PIXMAN_FORMAT_BPP (src->pixman_format) / 8; - - if (force_flush) { - status = _cairo_gl_surface_flush (&dst->base, 0); - if (unlikely (status)) - goto FAIL; - } - - if (_cairo_gl_surface_is_texture (dst)) { - void *data_start = src->data + src_y * src->stride + src_x * cpp; - void *data_start_gles2 = NULL; - - /* - * Due to GL_UNPACK_ROW_LENGTH missing in GLES2 we have to extract the - * image data ourselves in some cases. In particular, we must extract - * the pixels if: - * a. we don't want full-length lines or - * b. the row stride cannot be handled by GL itself using a 4 byte - * alignment constraint - */ - if (src->stride < 0 || - (ctx->gl_flavor == CAIRO_GL_FLAVOR_ES && - (src->width * cpp < src->stride - 3 || - width != src->width))) - { - glPixelStorei (GL_UNPACK_ALIGNMENT, 1); - status = _cairo_gl_surface_extract_image_data (src, src_x, src_y, - width, height, - &data_start_gles2); - if (unlikely (status)) - goto FAIL; - - data_start = data_start_gles2; - } - else - { - glPixelStorei (GL_UNPACK_ALIGNMENT, 4); - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) - glPixelStorei (GL_UNPACK_ROW_LENGTH, src->stride / cpp); - } - - _cairo_gl_context_activate (ctx, CAIRO_GL_TEX_TEMP); - glBindTexture (ctx->tex_target, dst->tex); - glTexParameteri (ctx->tex_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri (ctx->tex_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexSubImage2D (ctx->tex_target, 0, - dst_x, dst_y, width, height, - format, type, data_start); - - free (data_start_gles2); - - /* If we just treated some rgb-only data as rgba, then we have to - * go back and fix up the alpha channel where we filled in this - * texture data. - */ - if (!has_alpha) { - _cairo_gl_surface_fill_alpha_channel (dst, ctx, - dst_x, dst_y, - width, height); - } - } else { - cairo_surface_t *tmp; - - tmp = _cairo_gl_surface_create_scratch (ctx, - dst->base.content, - width, height); - if (unlikely (tmp->status)) - goto FAIL; - - status = _cairo_gl_surface_draw_image ((cairo_gl_surface_t *) tmp, - src, - src_x, src_y, - width, height, - 0, 0, force_flush); - if (status == CAIRO_INT_STATUS_SUCCESS) { - cairo_surface_pattern_t tmp_pattern; - cairo_rectangle_int_t r; - cairo_clip_t *clip; - - _cairo_pattern_init_for_surface (&tmp_pattern, tmp); - cairo_matrix_init_translate (&tmp_pattern.base.matrix, - -dst_x, -dst_y); - tmp_pattern.base.filter = CAIRO_FILTER_NEAREST; - tmp_pattern.base.extend = CAIRO_EXTEND_NONE; - - r.x = dst_x; - r.y = dst_y; - r.width = width; - r.height = height; - clip = _cairo_clip_intersect_rectangle (NULL, &r); - status = _cairo_surface_paint (&dst->base, - CAIRO_OPERATOR_SOURCE, - &tmp_pattern.base, - clip); - _cairo_clip_destroy (clip); - _cairo_pattern_fini (&tmp_pattern.base); - } - - cairo_surface_destroy (tmp); - } - -FAIL: - status = _cairo_gl_context_release (ctx, status); - - if (clone) - cairo_surface_destroy (&clone->base); - - return status; -} - -static int _cairo_gl_surface_flavor (cairo_gl_surface_t *surface) -{ - cairo_gl_context_t *ctx = (cairo_gl_context_t *)surface->base.device; - return ctx->gl_flavor; -} - -static cairo_status_t -_cairo_gl_surface_finish (void *abstract_surface) -{ - cairo_gl_surface_t *surface = abstract_surface; - cairo_status_t status; - cairo_gl_context_t *ctx; - - status = _cairo_gl_context_acquire (surface->base.device, &ctx); - if (unlikely (status)) - return status; - - if (ctx->operands[CAIRO_GL_TEX_SOURCE].type == CAIRO_GL_OPERAND_TEXTURE && - ctx->operands[CAIRO_GL_TEX_SOURCE].texture.surface == surface) - _cairo_gl_context_destroy_operand (ctx, CAIRO_GL_TEX_SOURCE); - if (ctx->operands[CAIRO_GL_TEX_MASK].type == CAIRO_GL_OPERAND_TEXTURE && - ctx->operands[CAIRO_GL_TEX_MASK].texture.surface == surface) - _cairo_gl_context_destroy_operand (ctx, CAIRO_GL_TEX_MASK); - if (ctx->current_target == surface) - ctx->current_target = NULL; - - if (surface->fb) - ctx->dispatch.DeleteFramebuffers (1, &surface->fb); - if (surface->depth_stencil) - ctx->dispatch.DeleteRenderbuffers (1, &surface->depth_stencil); - if (surface->owns_tex) - glDeleteTextures (1, &surface->tex); - - if (surface->msaa_depth_stencil) - ctx->dispatch.DeleteRenderbuffers (1, &surface->msaa_depth_stencil); - -#if CAIRO_HAS_GL_SURFACE - if (surface->msaa_fb) - ctx->dispatch.DeleteFramebuffers (1, &surface->msaa_fb); - if (surface->msaa_rb) - ctx->dispatch.DeleteRenderbuffers (1, &surface->msaa_rb); -#endif - - _cairo_clip_destroy (surface->clip_on_stencil_buffer); - - return _cairo_gl_context_release (ctx, status); -} - -static cairo_image_surface_t * -_cairo_gl_surface_map_to_image (void *abstract_surface, - const cairo_rectangle_int_t *extents) -{ - cairo_gl_surface_t *surface = abstract_surface; - cairo_image_surface_t *image; - cairo_gl_context_t *ctx; - GLenum format, type; - pixman_format_code_t pixman_format; - unsigned int cpp; - cairo_bool_t flipped, mesa_invert; - cairo_status_t status; - int y; - - status = _cairo_gl_context_acquire (surface->base.device, &ctx); - if (unlikely (status)) { - return _cairo_image_surface_create_in_error (status); - } - - /* Want to use a switch statement here but the compiler gets whiny. */ - if (surface->base.content == CAIRO_CONTENT_COLOR_ALPHA) { - format = GL_BGRA; - pixman_format = PIXMAN_a8r8g8b8; - type = GL_UNSIGNED_INT_8_8_8_8_REV; - cpp = 4; - } else if (surface->base.content == CAIRO_CONTENT_COLOR) { - format = GL_BGRA; - pixman_format = PIXMAN_x8r8g8b8; - type = GL_UNSIGNED_INT_8_8_8_8_REV; - cpp = 4; - } else if (surface->base.content == CAIRO_CONTENT_ALPHA) { - format = GL_ALPHA; - pixman_format = PIXMAN_a8; - type = GL_UNSIGNED_BYTE; - cpp = 1; - } else { - ASSERT_NOT_REACHED; - return NULL; - } - - if (_cairo_gl_surface_flavor (surface) == CAIRO_GL_FLAVOR_ES) { - /* If only RGBA is supported, we must download data in a compatible - * format. This means that pixman will convert the data on the CPU when - * interacting with other image surfaces. For ALPHA, GLES2 does not - * support GL_PACK_ROW_LENGTH anyway, and this makes sure that the - * pixman image that is created has row_stride = row_width * bpp. */ - if (surface->base.content == CAIRO_CONTENT_ALPHA || !ctx->can_read_bgra) { - cairo_bool_t little_endian = _cairo_is_little_endian (); - format = GL_RGBA; - - if (surface->base.content == CAIRO_CONTENT_COLOR) { - pixman_format = little_endian ? - PIXMAN_x8b8g8r8 : PIXMAN_r8g8b8x8; - } else { - pixman_format = little_endian ? - PIXMAN_a8b8g8r8 : PIXMAN_r8g8b8a8; - } - } - - /* GLES2 only supports GL_UNSIGNED_BYTE. */ - type = GL_UNSIGNED_BYTE; - cpp = 4; - } - - image = (cairo_image_surface_t*) - _cairo_image_surface_create_with_pixman_format (NULL, - pixman_format, - extents->width, - extents->height, - -1); - if (unlikely (image->base.status)) { - status = _cairo_gl_context_release (ctx, status); - return image; - } - - cairo_surface_set_device_offset (&image->base, -extents->x, -extents->y); - - /* If the original surface has not been modified or - * is clear, we can avoid downloading data. */ - if (surface->base.is_clear || surface->base.serial == 0) { - status = _cairo_gl_context_release (ctx, status); - return image; - } - - /* This is inefficient, as we'd rather just read the thing without making - * it the destination. But then, this is the fallback path, so let's not - * fall back instead. - */ - _cairo_gl_composite_flush (ctx); - _cairo_gl_context_set_destination (ctx, surface, FALSE); - - flipped = ! _cairo_gl_surface_is_texture (surface); - mesa_invert = flipped && ctx->has_mesa_pack_invert; - - glPixelStorei (GL_PACK_ALIGNMENT, 4); - if (ctx->gl_flavor == CAIRO_GL_FLAVOR_DESKTOP) - glPixelStorei (GL_PACK_ROW_LENGTH, image->stride / cpp); - if (mesa_invert) - glPixelStorei (GL_PACK_INVERT_MESA, 1); - - y = extents->y; - if (flipped) - y = surface->height - extents->y - extents->height; - - glReadPixels (extents->x, y, - extents->width, extents->height, - format, type, image->data); - if (mesa_invert) - glPixelStorei (GL_PACK_INVERT_MESA, 0); - - status = _cairo_gl_context_release (ctx, status); - if (unlikely (status)) { - cairo_surface_destroy (&image->base); - return _cairo_image_surface_create_in_error (status); - } - - /* We must invert the image manualy if we lack GL_MESA_pack_invert */ - if (flipped && ! mesa_invert) { - uint8_t stack[1024], *row = stack; - uint8_t *top = image->data; - uint8_t *bot = image->data + (image->height-1)*image->stride; - - if (image->stride > (int)sizeof(stack)) { - row = malloc (image->stride); - if (unlikely (row == NULL)) { - cairo_surface_destroy (&image->base); - return _cairo_image_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - } - - while (top < bot) { - memcpy (row, top, image->stride); - memcpy (top, bot, image->stride); - memcpy (bot, row, image->stride); - top += image->stride; - bot -= image->stride; - } - - if (row != stack) - free(row); - } - - image->base.is_clear = FALSE; - return image; -} - -static cairo_surface_t * -_cairo_gl_surface_source (void *abstract_surface, - cairo_rectangle_int_t *extents) -{ - cairo_gl_surface_t *surface = abstract_surface; - - if (extents) { - extents->x = extents->y = 0; - extents->width = surface->width; - extents->height = surface->height; - } - - return &surface->base; -} - -static cairo_status_t -_cairo_gl_surface_acquire_source_image (void *abstract_surface, - cairo_image_surface_t **image_out, - void **image_extra) -{ - cairo_gl_surface_t *surface = abstract_surface; - cairo_rectangle_int_t extents; - - *image_extra = NULL; - - extents.x = extents.y = 0; - extents.width = surface->width; - extents.height = surface->height; - - *image_out = (cairo_image_surface_t *) - _cairo_gl_surface_map_to_image (surface, &extents); - return (*image_out)->base.status; -} - -static void -_cairo_gl_surface_release_source_image (void *abstract_surface, - cairo_image_surface_t *image, - void *image_extra) -{ - cairo_surface_destroy (&image->base); -} - -static cairo_int_status_t -_cairo_gl_surface_unmap_image (void *abstract_surface, - cairo_image_surface_t *image) -{ - cairo_int_status_t status; - - status = _cairo_gl_surface_draw_image (abstract_surface, image, - 0, 0, - image->width, image->height, - image->base.device_transform_inverse.x0, - image->base.device_transform_inverse.y0, - TRUE); - - cairo_surface_finish (&image->base); - cairo_surface_destroy (&image->base); - - return status; -} - -static cairo_bool_t -_cairo_gl_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *rectangle) -{ - cairo_gl_surface_t *surface = abstract_surface; - - rectangle->x = 0; - rectangle->y = 0; - rectangle->width = surface->width; - rectangle->height = surface->height; - - return TRUE; -} - -static cairo_status_t -_cairo_gl_surface_flush (void *abstract_surface, unsigned flags) -{ - cairo_gl_surface_t *surface = abstract_surface; - cairo_status_t status; - cairo_gl_context_t *ctx; - - if (flags) - return CAIRO_STATUS_SUCCESS; - - status = _cairo_gl_context_acquire (surface->base.device, &ctx); - if (unlikely (status)) - return status; - - if ((ctx->operands[CAIRO_GL_TEX_SOURCE].type == CAIRO_GL_OPERAND_TEXTURE && - ctx->operands[CAIRO_GL_TEX_SOURCE].texture.surface == surface) || - (ctx->operands[CAIRO_GL_TEX_MASK].type == CAIRO_GL_OPERAND_TEXTURE && - ctx->operands[CAIRO_GL_TEX_MASK].texture.surface == surface) || - (ctx->current_target == surface)) - _cairo_gl_composite_flush (ctx); - - status = _cairo_gl_surface_resolve_multisampling (surface); - - return _cairo_gl_context_release (ctx, status); -} - -cairo_int_status_t -_cairo_gl_surface_resolve_multisampling (cairo_gl_surface_t *surface) -{ - cairo_gl_context_t *ctx; - cairo_int_status_t status; - - if (! surface->msaa_active) - return CAIRO_INT_STATUS_SUCCESS; - - if (surface->base.device == NULL) - return CAIRO_INT_STATUS_SUCCESS; - - /* GLES surfaces do not need explicit resolution. */ - if (((cairo_gl_context_t *) surface->base.device)->gl_flavor == CAIRO_GL_FLAVOR_ES) - return CAIRO_INT_STATUS_SUCCESS; - - if (! _cairo_gl_surface_is_texture (surface)) - return CAIRO_INT_STATUS_SUCCESS; - - status = _cairo_gl_context_acquire (surface->base.device, &ctx); - if (unlikely (status)) - return status; - - ctx->current_target = surface; - -#if CAIRO_HAS_GL_SURFACE - _cairo_gl_context_bind_framebuffer (ctx, surface, FALSE); -#endif - - status = _cairo_gl_context_release (ctx, status); - return status; -} - -static const cairo_compositor_t * -get_compositor (cairo_gl_surface_t *surface) -{ - cairo_gl_context_t *ctx = (cairo_gl_context_t *)surface->base.device; - return ctx->compositor; -} - -static cairo_int_status_t -_cairo_gl_surface_paint (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - /* simplify the common case of clearing the surface */ - if (clip == NULL) { - if (op == CAIRO_OPERATOR_CLEAR) - return _cairo_gl_surface_clear (surface, CAIRO_COLOR_TRANSPARENT); - else if (source->type == CAIRO_PATTERN_TYPE_SOLID && - (op == CAIRO_OPERATOR_SOURCE || - (op == CAIRO_OPERATOR_OVER && _cairo_pattern_is_opaque_solid (source)))) { - return _cairo_gl_surface_clear (surface, - &((cairo_solid_pattern_t *) source)->color); - } - } - - return _cairo_compositor_paint (get_compositor (surface), surface, - op, source, clip); -} - -static cairo_int_status_t -_cairo_gl_surface_mask (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - return _cairo_compositor_mask (get_compositor (surface), surface, - op, source, mask, clip); -} - -static cairo_int_status_t -_cairo_gl_surface_stroke (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - return _cairo_compositor_stroke (get_compositor (surface), surface, - op, source, path, style, - ctm, ctm_inverse, tolerance, antialias, - clip); -} - -static cairo_int_status_t -_cairo_gl_surface_fill (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t*path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - return _cairo_compositor_fill (get_compositor (surface), surface, - op, source, path, - fill_rule, tolerance, antialias, - clip); -} - -static cairo_int_status_t -_cairo_gl_surface_glyphs (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *font, - const cairo_clip_t *clip) -{ - return _cairo_compositor_glyphs (get_compositor (surface), surface, - op, source, glyphs, num_glyphs, font, - clip); -} - -static const cairo_surface_backend_t _cairo_gl_surface_backend = { - CAIRO_SURFACE_TYPE_GL, - _cairo_gl_surface_finish, - _cairo_default_context_create, - - _cairo_gl_surface_create_similar, - NULL, /* similar image */ - _cairo_gl_surface_map_to_image, - _cairo_gl_surface_unmap_image, - - _cairo_gl_surface_source, - _cairo_gl_surface_acquire_source_image, - _cairo_gl_surface_release_source_image, - NULL, /* snapshot */ - - NULL, /* copy_page */ - NULL, /* show_page */ - - _cairo_gl_surface_get_extents, - _cairo_image_surface_get_font_options, - - _cairo_gl_surface_flush, - NULL, /* mark_dirty_rectangle */ - - _cairo_gl_surface_paint, - _cairo_gl_surface_mask, - _cairo_gl_surface_stroke, - _cairo_gl_surface_fill, - NULL, /* fill/stroke */ - _cairo_gl_surface_glyphs, -}; diff --git a/source/libs/cairo/cairo-src/src/cairo-gl-traps-compositor.c b/source/libs/cairo/cairo-src/src/cairo-gl-traps-compositor.c deleted file mode 100644 index 125ed4eabcbe4f2c33ab327179bd8cdf8ea3b322..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-gl-traps-compositor.c +++ /dev/null @@ -1,558 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Eric Anholt - * Copyright © 2009 Chris Wilson - * Copyright © 2005,2010 Red Hat, Inc - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Benjamin Otte <otte@gnome.org> - * Carl Worth <cworth@cworth.org> - * Chris Wilson <chris@chris-wilson.co.uk> - * Eric Anholt <eric@anholt.net> - */ - -#include "cairoint.h" - -#include "cairo-gl-private.h" - -#include "cairo-composite-rectangles-private.h" -#include "cairo-compositor-private.h" -#include "cairo-default-context-private.h" -#include "cairo-error-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-spans-compositor-private.h" -#include "cairo-surface-backend-private.h" -#include "cairo-surface-offset-private.h" - -static cairo_int_status_t -acquire (void *abstract_dst) -{ - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -release (void *abstract_dst) -{ - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -set_clip_region (void *_surface, - cairo_region_t *region) -{ - cairo_gl_surface_t *surface = _surface; - - surface->clip_region = region; - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -draw_image_boxes (void *_dst, - cairo_image_surface_t *image, - cairo_boxes_t *boxes, - int dx, int dy) -{ - cairo_gl_surface_t *dst = _dst; - struct _cairo_boxes_chunk *chunk; - int i; - - for (chunk = &boxes->chunks; chunk; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) { - cairo_box_t *b = &chunk->base[i]; - int x = _cairo_fixed_integer_part (b->p1.x); - int y = _cairo_fixed_integer_part (b->p1.y); - int w = _cairo_fixed_integer_part (b->p2.x) - x; - int h = _cairo_fixed_integer_part (b->p2.y) - y; - cairo_status_t status; - - status = _cairo_gl_surface_draw_image (dst, image, - x + dx, y + dy, - w, h, - x, y, - TRUE); - if (unlikely (status)) - return status; - } - } - - return CAIRO_STATUS_SUCCESS; -} - -static void -emit_aligned_boxes (cairo_gl_context_t *ctx, - const cairo_boxes_t *boxes) -{ - const struct _cairo_boxes_chunk *chunk; - cairo_gl_emit_rect_t emit = _cairo_gl_context_choose_emit_rect (ctx); - int i; - - for (chunk = &boxes->chunks; chunk; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) { - int x1 = _cairo_fixed_integer_part (chunk->base[i].p1.x); - int y1 = _cairo_fixed_integer_part (chunk->base[i].p1.y); - int x2 = _cairo_fixed_integer_part (chunk->base[i].p2.x); - int y2 = _cairo_fixed_integer_part (chunk->base[i].p2.y); - emit (ctx, x1, y1, x2, y2); - } - } -} - -static cairo_int_status_t -fill_boxes (void *_dst, - cairo_operator_t op, - const cairo_color_t *color, - cairo_boxes_t *boxes) -{ - cairo_gl_composite_t setup; - cairo_gl_context_t *ctx; - cairo_int_status_t status; - - status = _cairo_gl_composite_init (&setup, op, _dst, FALSE); - if (unlikely (status)) - goto FAIL; - - _cairo_gl_composite_set_solid_source (&setup, color); - - status = _cairo_gl_composite_begin (&setup, &ctx); - if (unlikely (status)) - goto FAIL; - - emit_aligned_boxes (ctx, boxes); - status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS); - -FAIL: - _cairo_gl_composite_fini (&setup); - return status; -} - -static cairo_int_status_t -composite_boxes (void *_dst, - cairo_operator_t op, - cairo_surface_t *abstract_src, - cairo_surface_t *abstract_mask, - int src_x, - int src_y, - int mask_x, - int mask_y, - int dst_x, - int dst_y, - cairo_boxes_t *boxes, - const cairo_rectangle_int_t *extents) -{ - cairo_gl_composite_t setup; - cairo_gl_context_t *ctx; - cairo_int_status_t status; - - status = _cairo_gl_composite_init (&setup, op, _dst, FALSE); - if (unlikely (status)) - goto FAIL; - - _cairo_gl_composite_set_source_operand (&setup, - source_to_operand (abstract_src)); - _cairo_gl_operand_translate (&setup.src, dst_x-src_x, dst_y-src_y); - - _cairo_gl_composite_set_mask_operand (&setup, - source_to_operand (abstract_mask)); - _cairo_gl_operand_translate (&setup.mask, dst_x-mask_x, dst_y-mask_y); - - status = _cairo_gl_composite_begin (&setup, &ctx); - if (unlikely (status)) - goto FAIL; - - emit_aligned_boxes (ctx, boxes); - status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS); - -FAIL: - _cairo_gl_composite_fini (&setup); - return status; -} - -static cairo_int_status_t -composite (void *_dst, - cairo_operator_t op, - cairo_surface_t *abstract_src, - cairo_surface_t *abstract_mask, - 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_gl_composite_t setup; - cairo_gl_context_t *ctx; - cairo_int_status_t status; - - status = _cairo_gl_composite_init (&setup, op, _dst, FALSE); - if (unlikely (status)) - goto FAIL; - - _cairo_gl_composite_set_source_operand (&setup, - source_to_operand (abstract_src)); - _cairo_gl_operand_translate (&setup.src, dst_x-src_x, dst_y-src_y); - - _cairo_gl_composite_set_mask_operand (&setup, - source_to_operand (abstract_mask)); - _cairo_gl_operand_translate (&setup.mask, dst_x-mask_x, dst_y-mask_y); - - status = _cairo_gl_composite_begin (&setup, &ctx); - if (unlikely (status)) - goto FAIL; - - /* XXX clip */ - _cairo_gl_context_emit_rect (ctx, dst_x, dst_y, dst_x+width, dst_y+height); - status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS); - -FAIL: - _cairo_gl_composite_fini (&setup); - return status; -} - -static cairo_int_status_t -lerp (void *dst, - cairo_surface_t *src, - cairo_surface_t *mask, - 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_int_status_t status; - - /* we could avoid some repetition... */ - status = composite (dst, CAIRO_OPERATOR_DEST_OUT, mask, NULL, - mask_x, mask_y, - 0, 0, - dst_x, dst_y, - width, height); - if (unlikely (status)) - return status; - - status = composite (dst, CAIRO_OPERATOR_ADD, src, mask, - src_x, src_y, - mask_x, mask_y, - dst_x, dst_y, - width, height); - if (unlikely (status)) - return status; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -traps_to_operand (void *_dst, - const cairo_rectangle_int_t *extents, - cairo_antialias_t antialias, - cairo_traps_t *traps, - cairo_gl_operand_t *operand, - int dst_x, int dst_y) -{ - pixman_format_code_t pixman_format; - pixman_image_t *pixman_image; - cairo_surface_t *image, *mask; - cairo_surface_pattern_t pattern; - cairo_status_t status; - - pixman_format = antialias != CAIRO_ANTIALIAS_NONE ? PIXMAN_a8 : PIXMAN_a1; - pixman_image = pixman_image_create_bits (pixman_format, - extents->width, - extents->height, - NULL, 0); - if (unlikely (pixman_image == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _pixman_image_add_traps (pixman_image, extents->x, extents->y, traps); - image = _cairo_image_surface_create_for_pixman_image (pixman_image, - pixman_format); - if (unlikely (image->status)) { - pixman_image_unref (pixman_image); - return image->status; - } - - /* GLES2 only supports RGB/RGBA when uploading */ - if (_cairo_gl_get_flavor () == CAIRO_GL_FLAVOR_ES) { - cairo_surface_pattern_t pattern; - cairo_surface_t *rgba_image; - - /* XXX perform this fixup inside _cairo_gl_draw_image() */ - - rgba_image = - _cairo_image_surface_create_with_pixman_format (NULL, - _cairo_is_little_endian () ? PIXMAN_a8b8g8r8 : PIXMAN_r8g8b8a8, - extents->width, - extents->height, - 0); - if (unlikely (rgba_image->status)) - return rgba_image->status; - - _cairo_pattern_init_for_surface (&pattern, image); - status = _cairo_surface_paint (rgba_image, CAIRO_OPERATOR_SOURCE, - &pattern.base, NULL); - _cairo_pattern_fini (&pattern.base); - - cairo_surface_destroy (image); - image = rgba_image; - - if (unlikely (status)) { - cairo_surface_destroy (image); - return status; - } - } - - mask = _cairo_surface_create_scratch (_dst, - CAIRO_CONTENT_COLOR_ALPHA, - extents->width, - extents->height, - NULL); - if (unlikely (mask->status)) { - cairo_surface_destroy (image); - return mask->status; - } - - status = _cairo_gl_surface_draw_image ((cairo_gl_surface_t *)mask, - (cairo_image_surface_t *)image, - 0, 0, - extents->width, extents->height, - 0, 0, - TRUE); - cairo_surface_destroy (image); - - if (unlikely (status)) - goto error; - - _cairo_pattern_init_for_surface (&pattern, mask); - cairo_matrix_init_translate (&pattern.base.matrix, - -extents->x+dst_x, -extents->y+dst_y); - pattern.base.filter = CAIRO_FILTER_NEAREST; - pattern.base.extend = CAIRO_EXTEND_NONE; - status = _cairo_gl_operand_init (operand, &pattern.base, _dst, - &_cairo_unbounded_rectangle, - &_cairo_unbounded_rectangle, - FALSE); - _cairo_pattern_fini (&pattern.base); - - if (unlikely (status)) - goto error; - - operand->texture.owns_surface = (cairo_gl_surface_t *)mask; - return CAIRO_STATUS_SUCCESS; - -error: - cairo_surface_destroy (mask); - return status; -} - -static cairo_int_status_t -composite_traps (void *_dst, - cairo_operator_t op, - cairo_surface_t *abstract_src, - int src_x, - int src_y, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents, - cairo_antialias_t antialias, - cairo_traps_t *traps) -{ - cairo_gl_composite_t setup; - cairo_gl_context_t *ctx; - cairo_int_status_t status; - - status = _cairo_gl_composite_init (&setup, op, _dst, FALSE); - if (unlikely (status)) - goto FAIL; - - _cairo_gl_composite_set_source_operand (&setup, - source_to_operand (abstract_src)); - _cairo_gl_operand_translate (&setup.src, -src_x-dst_x, -src_y-dst_y); - status = traps_to_operand (_dst, extents, antialias, traps, &setup.mask, dst_x, dst_y); - if (unlikely (status)) - goto FAIL; - - status = _cairo_gl_composite_begin (&setup, &ctx); - if (unlikely (status)) - goto FAIL; - - /* XXX clip */ - _cairo_gl_context_emit_rect (ctx, - extents->x-dst_x, extents->y-dst_y, - extents->x-dst_x+extents->width, - extents->y-dst_y+extents->height); - status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS); - -FAIL: - _cairo_gl_composite_fini (&setup); - return status; -} - -static cairo_gl_surface_t * -tristrip_to_surface (void *_dst, - const cairo_rectangle_int_t *extents, - cairo_antialias_t antialias, - cairo_tristrip_t *strip) -{ - pixman_format_code_t pixman_format; - pixman_image_t *pixman_image; - cairo_surface_t *image, *mask; - cairo_status_t status; - - pixman_format = antialias != CAIRO_ANTIALIAS_NONE ? PIXMAN_a8 : PIXMAN_a1, - pixman_image = pixman_image_create_bits (pixman_format, - extents->width, - extents->height, - NULL, 0); - if (unlikely (pixman_image == NULL)) - return (cairo_gl_surface_t *)_cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - _pixman_image_add_tristrip (pixman_image, extents->x, extents->y, strip); - image = _cairo_image_surface_create_for_pixman_image (pixman_image, - pixman_format); - if (unlikely (image->status)) { - pixman_image_unref (pixman_image); - return (cairo_gl_surface_t *)image; - } - - mask = _cairo_surface_create_scratch (_dst, - CAIRO_CONTENT_COLOR_ALPHA, - extents->width, - extents->height, - NULL); - if (unlikely (mask->status)) { - cairo_surface_destroy (image); - return (cairo_gl_surface_t *)mask; - } - - status = _cairo_gl_surface_draw_image ((cairo_gl_surface_t *)mask, - (cairo_image_surface_t *)image, - 0, 0, - extents->width, extents->height, - 0, 0, - TRUE); - cairo_surface_destroy (image); - if (unlikely (status)) { - cairo_surface_destroy (mask); - return (cairo_gl_surface_t*)_cairo_surface_create_in_error (status); - } - - return (cairo_gl_surface_t*)mask; -} - -static cairo_int_status_t -composite_tristrip (void *_dst, - cairo_operator_t op, - cairo_surface_t *abstract_src, - int src_x, - int src_y, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents, - cairo_antialias_t antialias, - cairo_tristrip_t *strip) -{ - cairo_gl_composite_t setup; - cairo_gl_context_t *ctx; - cairo_gl_surface_t *mask; - cairo_int_status_t status; - - mask = tristrip_to_surface (_dst, extents, antialias, strip); - if (unlikely (mask->base.status)) - return mask->base.status; - - status = _cairo_gl_composite_init (&setup, op, _dst, FALSE); - if (unlikely (status)) - goto FAIL; - - _cairo_gl_composite_set_source_operand (&setup, - source_to_operand (abstract_src)); - - //_cairo_gl_composite_set_mask_surface (&setup, mask, 0, 0); - - status = _cairo_gl_composite_begin (&setup, &ctx); - if (unlikely (status)) - goto FAIL; - - /* XXX clip */ - _cairo_gl_context_emit_rect (ctx, - dst_x, dst_y, - dst_x+extents->width, - dst_y+extents->height); - status = _cairo_gl_context_release (ctx, CAIRO_STATUS_SUCCESS); - -FAIL: - _cairo_gl_composite_fini (&setup); - cairo_surface_destroy (&mask->base); - return status; -} - -static cairo_int_status_t -check_composite (const cairo_composite_rectangles_t *extents) -{ - if (! _cairo_gl_operator_is_supported (extents->op)) - return UNSUPPORTED ("unsupported operator"); - - return CAIRO_STATUS_SUCCESS; -} - -const cairo_compositor_t * -_cairo_gl_traps_compositor_get (void) -{ - static cairo_traps_compositor_t compositor; - - if (compositor.base.delegate == NULL) { - _cairo_traps_compositor_init (&compositor, &_cairo_fallback_compositor); - compositor.acquire = acquire; - compositor.release = release; - compositor.set_clip_region = set_clip_region; - compositor.pattern_to_surface = _cairo_gl_pattern_to_source; - compositor.draw_image_boxes = draw_image_boxes; - //compositor.copy_boxes = copy_boxes; - compositor.fill_boxes = fill_boxes; - compositor.check_composite = check_composite; - compositor.composite = composite; - compositor.lerp = lerp; - //compositor.check_composite_boxes = check_composite_boxes; - compositor.composite_boxes = composite_boxes; - //compositor.check_composite_traps = check_composite_traps; - compositor.composite_traps = composite_traps; - //compositor.check_composite_tristrip = check_composite_traps; - compositor.composite_tristrip = composite_tristrip; - compositor.check_composite_glyphs = _cairo_gl_check_composite_glyphs; - compositor.composite_glyphs = _cairo_gl_composite_glyphs; - } - - return &compositor.base; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-gl.h b/source/libs/cairo/cairo-src/src/cairo-gl.h deleted file mode 100644 index 9fd7608f5cfec20228696ac46ec82c9e18e3287b..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-gl.h +++ /dev/null @@ -1,155 +0,0 @@ -/* Cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Eric Anholt - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Eric Anholt. - */ - -/* - * cairo-gl.h: - * - * The cairo-gl backend provides an implementation of possibly - * hardware-accelerated cairo rendering by targeting the OpenGL API. - * The goal of the cairo-gl backend is to provide better performance - * with equal functionality to cairo-image where possible. It does - * not directly provide for applying additional OpenGL effects to - * cairo surfaces. - * - * Cairo-gl allows interoperability with other GL rendering through GL - * context sharing. Cairo-gl surfaces are created in reference to a - * #cairo_device_t, which represents a GL context created by the user. - * When that GL context is created with its sharePtr set to another - * context (or vice versa), its objects (textures backing cairo-gl - * surfaces) can be accessed in the other OpenGL context. This allows - * cairo-gl to maintain its drawing state in one context while the - * user's 3D rendering occurs in the user's other context. - * - * However, as only one context can be current to a thread at a time, - * cairo-gl may make its context current to the thread on any cairo - * call which interacts with a cairo-gl surface or the cairo-gl - * device. As a result, the user must make their own context current - * between any cairo calls and their own OpenGL rendering. - **/ - -#ifndef CAIRO_GL_H -#define CAIRO_GL_H - -#include "cairo.h" - -#if CAIRO_HAS_GL_SURFACE || CAIRO_HAS_GLESV2_SURFACE - -CAIRO_BEGIN_DECLS - -cairo_public cairo_surface_t * -cairo_gl_surface_create (cairo_device_t *device, - cairo_content_t content, - int width, int height); - -cairo_public cairo_surface_t * -cairo_gl_surface_create_for_texture (cairo_device_t *abstract_device, - cairo_content_t content, - unsigned int tex, - int width, int height); -cairo_public void -cairo_gl_surface_set_size (cairo_surface_t *surface, int width, int height); - -cairo_public int -cairo_gl_surface_get_width (cairo_surface_t *abstract_surface); - -cairo_public int -cairo_gl_surface_get_height (cairo_surface_t *abstract_surface); - -cairo_public void -cairo_gl_surface_swapbuffers (cairo_surface_t *surface); - -cairo_public void -cairo_gl_device_set_thread_aware (cairo_device_t *device, - cairo_bool_t thread_aware); - -#if CAIRO_HAS_GLX_FUNCTIONS -#include <GL/glx.h> - -cairo_public cairo_device_t * -cairo_glx_device_create (Display *dpy, GLXContext gl_ctx); - -cairo_public Display * -cairo_glx_device_get_display (cairo_device_t *device); - -cairo_public GLXContext -cairo_glx_device_get_context (cairo_device_t *device); - -cairo_public cairo_surface_t * -cairo_gl_surface_create_for_window (cairo_device_t *device, - Window win, - int width, int height); -#endif - -#if CAIRO_HAS_WGL_FUNCTIONS -#include <windows.h> - -cairo_public cairo_device_t * -cairo_wgl_device_create (HGLRC rc); - -cairo_public HGLRC -cairo_wgl_device_get_context (cairo_device_t *device); - -cairo_public cairo_surface_t * -cairo_gl_surface_create_for_dc (cairo_device_t *device, - HDC dc, - int width, - int height); -#endif - -#if CAIRO_HAS_EGL_FUNCTIONS -#include <EGL/egl.h> - -cairo_public cairo_device_t * -cairo_egl_device_create (EGLDisplay dpy, EGLContext egl); - -cairo_public cairo_surface_t * -cairo_gl_surface_create_for_egl (cairo_device_t *device, - EGLSurface egl, - int width, - int height); - -cairo_public EGLDisplay -cairo_egl_device_get_display (cairo_device_t *device); - -cairo_public EGLSurface -cairo_egl_device_get_context (cairo_device_t *device); - -#endif - -CAIRO_END_DECLS - -#else /* CAIRO_HAS_GL_SURFACE */ -# error Cairo was not compiled with support for the GL backend -#endif /* CAIRO_HAS_GL_SURFACE */ - -#endif /* CAIRO_GL_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-glx-context.c b/source/libs/cairo/cairo-src/src/cairo-glx-context.c deleted file mode 100644 index 3761b9079a4d3b5b8cae253ec6a95f5e4cd7d234..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-glx-context.c +++ /dev/null @@ -1,324 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Eric Anholt - * Copyright © 2009 Chris Wilson - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Carl Worth <cworth@cworth.org> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-gl-private.h" - -#include "cairo-error-private.h" - -#include <X11/Xutil.h> - -/* XXX needs hooking into XCloseDisplay() */ - -typedef struct _cairo_glx_context { - cairo_gl_context_t base; - - Display *display; - Window dummy_window; - GLXContext context; - - GLXDrawable previous_drawable; - GLXContext previous_context; - - cairo_bool_t has_multithread_makecurrent; -} cairo_glx_context_t; - -typedef struct _cairo_glx_surface { - cairo_gl_surface_t base; - - Window win; -} cairo_glx_surface_t; - -static cairo_bool_t -_context_acquisition_changed_glx_state (cairo_glx_context_t *ctx, - GLXDrawable current_drawable) -{ - return ctx->previous_drawable != current_drawable || - ctx->previous_context != ctx->context; -} - -static GLXDrawable -_glx_get_current_drawable (cairo_glx_context_t *ctx) -{ - if (ctx->base.current_target == NULL || - _cairo_gl_surface_is_texture (ctx->base.current_target)) { - return ctx->dummy_window; - } - - return ((cairo_glx_surface_t *) ctx->base.current_target)->win; -} - -static void -_glx_query_current_state (cairo_glx_context_t * ctx) -{ - ctx->previous_drawable = glXGetCurrentDrawable (); - ctx->previous_context = glXGetCurrentContext (); - - /* If any of the values were none, assume they are all none. Not all - drivers seem well behaved when it comes to using these values across - multiple threads. */ - if (ctx->previous_drawable == None || - ctx->previous_context == None) { - ctx->previous_drawable = None; - ctx->previous_context = None; - } -} - -static void -_glx_acquire (void *abstract_ctx) -{ - cairo_glx_context_t *ctx = abstract_ctx; - GLXDrawable current_drawable = _glx_get_current_drawable (ctx); - - _glx_query_current_state (ctx); - if (!_context_acquisition_changed_glx_state (ctx, current_drawable)) - return; - - glXMakeCurrent (ctx->display, current_drawable, ctx->context); -} - -static void -_glx_make_current (void *abstract_ctx, cairo_gl_surface_t *abstract_surface) -{ - cairo_glx_context_t *ctx = abstract_ctx; - cairo_glx_surface_t *surface = (cairo_glx_surface_t *) abstract_surface; - - /* Set the window as the target of our context. */ - glXMakeCurrent (ctx->display, surface->win, ctx->context); -} - -static void -_glx_release (void *abstract_ctx) -{ - cairo_glx_context_t *ctx = abstract_ctx; - - if (ctx->has_multithread_makecurrent || !ctx->base.thread_aware || - !_context_acquisition_changed_glx_state (ctx, - _glx_get_current_drawable (ctx))) { - return; - } - - glXMakeCurrent (ctx->display, None, None); -} - -static void -_glx_swap_buffers (void *abstract_ctx, - cairo_gl_surface_t *abstract_surface) -{ - cairo_glx_context_t *ctx = abstract_ctx; - cairo_glx_surface_t *surface = (cairo_glx_surface_t *) abstract_surface; - - glXSwapBuffers (ctx->display, surface->win); -} - -static void -_glx_destroy (void *abstract_ctx) -{ - cairo_glx_context_t *ctx = abstract_ctx; - - if (ctx->dummy_window != None) - XDestroyWindow (ctx->display, ctx->dummy_window); - - glXMakeCurrent (ctx->display, None, None); -} - -static cairo_status_t -_glx_dummy_window (Display *dpy, GLXContext gl_ctx, Window *dummy) -{ - int attr[3] = { GLX_FBCONFIG_ID, 0, None }; - GLXFBConfig *config; - XVisualInfo *vi; - Colormap cmap; - XSetWindowAttributes swa; - Window win = None; - int cnt; - - /* Create a dummy window created for the target GLX context that we can - * use to query the available GL/GLX extensions. - */ - glXQueryContext (dpy, gl_ctx, GLX_FBCONFIG_ID, &attr[1]); - - cnt = 0; - config = glXChooseFBConfig (dpy, DefaultScreen (dpy), attr, &cnt); - if (unlikely (cnt == 0)) - return _cairo_error (CAIRO_STATUS_INVALID_FORMAT); - - vi = glXGetVisualFromFBConfig (dpy, config[0]); - XFree (config); - - if (unlikely (vi == NULL)) - return _cairo_error (CAIRO_STATUS_INVALID_FORMAT); - - cmap = XCreateColormap (dpy, - RootWindow (dpy, vi->screen), - vi->visual, - AllocNone); - swa.colormap = cmap; - swa.border_pixel = 0; - win = XCreateWindow (dpy, RootWindow (dpy, vi->screen), - -1, -1, 1, 1, 0, - vi->depth, - InputOutput, - vi->visual, - CWBorderPixel | CWColormap, &swa); - XFreeColormap (dpy, cmap); - XFree (vi); - - XFlush (dpy); - if (unlikely (! glXMakeCurrent (dpy, win, gl_ctx))) { - XDestroyWindow (dpy, win); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - *dummy = win; - return CAIRO_STATUS_SUCCESS; -} - -cairo_device_t * -cairo_glx_device_create (Display *dpy, GLXContext gl_ctx) -{ - cairo_glx_context_t *ctx; - cairo_status_t status; - Window dummy = None; - const char *glx_extensions; - - ctx = calloc (1, sizeof (cairo_glx_context_t)); - if (unlikely (ctx == NULL)) - return _cairo_gl_context_create_in_error (CAIRO_STATUS_NO_MEMORY); - - /* glx_dummy_window will call glXMakeCurrent, so we need to - * query the current state of the context now. */ - _glx_query_current_state (ctx); - - status = _glx_dummy_window (dpy, gl_ctx, &dummy); - if (unlikely (status)) { - free (ctx); - return _cairo_gl_context_create_in_error (status); - } - - ctx->display = dpy; - ctx->dummy_window = dummy; - ctx->context = gl_ctx; - - ctx->base.acquire = _glx_acquire; - ctx->base.release = _glx_release; - ctx->base.make_current = _glx_make_current; - ctx->base.swap_buffers = _glx_swap_buffers; - ctx->base.destroy = _glx_destroy; - - status = _cairo_gl_dispatch_init (&ctx->base.dispatch, - (cairo_gl_get_proc_addr_func_t) glXGetProcAddress); - if (unlikely (status)) { - free (ctx); - return _cairo_gl_context_create_in_error (status); - } - - status = _cairo_gl_context_init (&ctx->base); - if (unlikely (status)) { - free (ctx); - return _cairo_gl_context_create_in_error (status); - } - - glx_extensions = glXQueryExtensionsString (dpy, DefaultScreen (dpy)); - if (strstr(glx_extensions, "GLX_MESA_multithread_makecurrent")) { - ctx->has_multithread_makecurrent = TRUE; - } - - ctx->base.release (ctx); - - return &ctx->base.base; -} - -Display * -cairo_glx_device_get_display (cairo_device_t *device) -{ - cairo_glx_context_t *ctx; - - if (device->backend->type != CAIRO_DEVICE_TYPE_GL) { - _cairo_error_throw (CAIRO_STATUS_DEVICE_TYPE_MISMATCH); - return NULL; - } - - ctx = (cairo_glx_context_t *) device; - - return ctx->display; -} - -GLXContext -cairo_glx_device_get_context (cairo_device_t *device) -{ - cairo_glx_context_t *ctx; - - if (device->backend->type != CAIRO_DEVICE_TYPE_GL) { - _cairo_error_throw (CAIRO_STATUS_DEVICE_TYPE_MISMATCH); - return NULL; - } - - ctx = (cairo_glx_context_t *) device; - - return ctx->context; -} - -cairo_surface_t * -cairo_gl_surface_create_for_window (cairo_device_t *device, - Window win, - int width, - int height) -{ - cairo_glx_surface_t *surface; - - if (unlikely (device->status)) - return _cairo_surface_create_in_error (device->status); - - if (device->backend->type != CAIRO_DEVICE_TYPE_GL) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH)); - - if (width <= 0 || height <= 0) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE)); - - surface = calloc (1, sizeof (cairo_glx_surface_t)); - if (unlikely (surface == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - _cairo_gl_surface_init (device, &surface->base, - CAIRO_CONTENT_COLOR_ALPHA, width, height); - surface->win = win; - - return &surface->base.base; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-gstate-private.h b/source/libs/cairo/cairo-src/src/cairo-gstate-private.h deleted file mode 100644 index b2ccc76d1451ba8c1848118cedbaa5a7bc6a2cb5..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-gstate-private.h +++ /dev/null @@ -1,387 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Carl D. Worth <cworth@redhat.com> - */ - -#ifndef CAIRO_GSTATE_PRIVATE_H -#define CAIRO_GSTATE_PRIVATE_H - -#include "cairo-clip-private.h" - -struct _cairo_gstate { - cairo_operator_t op; - - double opacity; - double tolerance; - cairo_antialias_t antialias; - - cairo_stroke_style_t stroke_style; - - cairo_fill_rule_t fill_rule; - - cairo_font_face_t *font_face; - cairo_scaled_font_t *scaled_font; /* Specific to the current CTM */ - cairo_scaled_font_t *previous_scaled_font; /* holdover */ - cairo_matrix_t font_matrix; - cairo_font_options_t font_options; - - cairo_clip_t *clip; - - cairo_surface_t *target; /* The target to which all rendering is directed */ - cairo_surface_t *parent_target; /* The previous target which was receiving rendering */ - cairo_surface_t *original_target; /* The original target the initial gstate was created with */ - - /* the user is allowed to update the device after we have cached the matrices... */ - cairo_observer_t device_transform_observer; - - cairo_matrix_t ctm; - cairo_matrix_t ctm_inverse; - cairo_matrix_t source_ctm_inverse; /* At the time ->source was set */ - cairo_bool_t is_identity; - - cairo_pattern_t *source; - - struct _cairo_gstate *next; -}; - -/* cairo-gstate.c */ -cairo_private cairo_status_t -_cairo_gstate_init (cairo_gstate_t *gstate, - cairo_surface_t *target); - -cairo_private void -_cairo_gstate_fini (cairo_gstate_t *gstate); - -cairo_private cairo_status_t -_cairo_gstate_save (cairo_gstate_t **gstate, cairo_gstate_t **freelist); - -cairo_private cairo_status_t -_cairo_gstate_restore (cairo_gstate_t **gstate, cairo_gstate_t **freelist); - -cairo_private cairo_bool_t -_cairo_gstate_is_group (cairo_gstate_t *gstate); - -cairo_private cairo_status_t -_cairo_gstate_redirect_target (cairo_gstate_t *gstate, cairo_surface_t *child); - -cairo_private cairo_surface_t * -_cairo_gstate_get_target (cairo_gstate_t *gstate); - -cairo_private cairo_surface_t * -_cairo_gstate_get_original_target (cairo_gstate_t *gstate); - -cairo_private cairo_clip_t * -_cairo_gstate_get_clip (cairo_gstate_t *gstate); - -cairo_private cairo_status_t -_cairo_gstate_set_source (cairo_gstate_t *gstate, cairo_pattern_t *source); - -cairo_private cairo_pattern_t * -_cairo_gstate_get_source (cairo_gstate_t *gstate); - -cairo_private cairo_status_t -_cairo_gstate_set_operator (cairo_gstate_t *gstate, cairo_operator_t op); - -cairo_private cairo_operator_t -_cairo_gstate_get_operator (cairo_gstate_t *gstate); - -cairo_private cairo_status_t -_cairo_gstate_set_opacity (cairo_gstate_t *gstate, double opacity); - -cairo_private double -_cairo_gstate_get_opacity (cairo_gstate_t *gstate); - -cairo_private cairo_status_t -_cairo_gstate_set_tolerance (cairo_gstate_t *gstate, double tolerance); - -cairo_private double -_cairo_gstate_get_tolerance (cairo_gstate_t *gstate); - -cairo_private cairo_status_t -_cairo_gstate_set_fill_rule (cairo_gstate_t *gstate, cairo_fill_rule_t fill_rule); - -cairo_private cairo_fill_rule_t -_cairo_gstate_get_fill_rule (cairo_gstate_t *gstate); - -cairo_private cairo_status_t -_cairo_gstate_set_line_width (cairo_gstate_t *gstate, double width); - -cairo_private double -_cairo_gstate_get_line_width (cairo_gstate_t *gstate); - -cairo_private cairo_status_t -_cairo_gstate_set_line_cap (cairo_gstate_t *gstate, cairo_line_cap_t line_cap); - -cairo_private cairo_line_cap_t -_cairo_gstate_get_line_cap (cairo_gstate_t *gstate); - -cairo_private cairo_status_t -_cairo_gstate_set_line_join (cairo_gstate_t *gstate, cairo_line_join_t line_join); - -cairo_private cairo_line_join_t -_cairo_gstate_get_line_join (cairo_gstate_t *gstate); - -cairo_private cairo_status_t -_cairo_gstate_set_dash (cairo_gstate_t *gstate, const double *dash, int num_dashes, double offset); - -cairo_private void -_cairo_gstate_get_dash (cairo_gstate_t *gstate, double *dash, int *num_dashes, double *offset); - -cairo_private cairo_status_t -_cairo_gstate_set_miter_limit (cairo_gstate_t *gstate, double limit); - -cairo_private double -_cairo_gstate_get_miter_limit (cairo_gstate_t *gstate); - -cairo_private void -_cairo_gstate_get_matrix (cairo_gstate_t *gstate, cairo_matrix_t *matrix); - -cairo_private cairo_status_t -_cairo_gstate_translate (cairo_gstate_t *gstate, double tx, double ty); - -cairo_private cairo_status_t -_cairo_gstate_scale (cairo_gstate_t *gstate, double sx, double sy); - -cairo_private cairo_status_t -_cairo_gstate_rotate (cairo_gstate_t *gstate, double angle); - -cairo_private cairo_status_t -_cairo_gstate_transform (cairo_gstate_t *gstate, - const cairo_matrix_t *matrix); - -cairo_private cairo_status_t -_cairo_gstate_set_matrix (cairo_gstate_t *gstate, - const cairo_matrix_t *matrix); - -cairo_private void -_cairo_gstate_identity_matrix (cairo_gstate_t *gstate); - -cairo_private void -_cairo_gstate_user_to_device (cairo_gstate_t *gstate, double *x, double *y); - -cairo_private void -_cairo_gstate_user_to_device_distance (cairo_gstate_t *gstate, double *dx, double *dy); - -cairo_private void -_cairo_gstate_device_to_user (cairo_gstate_t *gstate, double *x, double *y); - -cairo_private void -_cairo_gstate_device_to_user_distance (cairo_gstate_t *gstate, double *dx, double *dy); - -cairo_private void -_do_cairo_gstate_user_to_backend (cairo_gstate_t *gstate, double *x, double *y); - -static inline void -_cairo_gstate_user_to_backend (cairo_gstate_t *gstate, double *x, double *y) -{ - if (! gstate->is_identity) - _do_cairo_gstate_user_to_backend (gstate, x, y); -} - -cairo_private void -_do_cairo_gstate_user_to_backend_distance (cairo_gstate_t *gstate, double *x, double *y); - -static inline void -_cairo_gstate_user_to_backend_distance (cairo_gstate_t *gstate, double *x, double *y) -{ - if (! gstate->is_identity) - _do_cairo_gstate_user_to_backend_distance (gstate, x, y); -} - -cairo_private void -_do_cairo_gstate_backend_to_user (cairo_gstate_t *gstate, double *x, double *y); - -static inline void -_cairo_gstate_backend_to_user (cairo_gstate_t *gstate, double *x, double *y) -{ - if (! gstate->is_identity) - _do_cairo_gstate_backend_to_user (gstate, x, y); -} - -cairo_private void -_do_cairo_gstate_backend_to_user_distance (cairo_gstate_t *gstate, double *x, double *y); - -static inline void -_cairo_gstate_backend_to_user_distance (cairo_gstate_t *gstate, double *x, double *y) -{ - if (! gstate->is_identity) - _do_cairo_gstate_backend_to_user_distance (gstate, x, y); -} - -cairo_private void -_cairo_gstate_backend_to_user_rectangle (cairo_gstate_t *gstate, - double *x1, double *y1, - double *x2, double *y2, - cairo_bool_t *is_tight); - -cairo_private void -_cairo_gstate_path_extents (cairo_gstate_t *gstate, - cairo_path_fixed_t *path, - double *x1, double *y1, - double *x2, double *y2); - -cairo_private cairo_status_t -_cairo_gstate_paint (cairo_gstate_t *gstate); - -cairo_private cairo_status_t -_cairo_gstate_mask (cairo_gstate_t *gstate, - cairo_pattern_t *mask); - -cairo_private cairo_status_t -_cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path); - -cairo_private cairo_status_t -_cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path); - -cairo_private cairo_status_t -_cairo_gstate_copy_page (cairo_gstate_t *gstate); - -cairo_private cairo_status_t -_cairo_gstate_show_page (cairo_gstate_t *gstate); - -cairo_private cairo_status_t -_cairo_gstate_stroke_extents (cairo_gstate_t *gstate, - cairo_path_fixed_t *path, - double *x1, double *y1, - double *x2, double *y2); - -cairo_private cairo_status_t -_cairo_gstate_fill_extents (cairo_gstate_t *gstate, - cairo_path_fixed_t *path, - double *x1, double *y1, - double *x2, double *y2); - -cairo_private cairo_status_t -_cairo_gstate_in_stroke (cairo_gstate_t *gstate, - cairo_path_fixed_t *path, - double x, - double y, - cairo_bool_t *inside_ret); - -cairo_private cairo_bool_t -_cairo_gstate_in_fill (cairo_gstate_t *gstate, - cairo_path_fixed_t *path, - double x, - double y); - -cairo_private cairo_bool_t -_cairo_gstate_in_clip (cairo_gstate_t *gstate, - double x, - double y); - -cairo_private cairo_status_t -_cairo_gstate_clip (cairo_gstate_t *gstate, cairo_path_fixed_t *path); - -cairo_private cairo_status_t -_cairo_gstate_reset_clip (cairo_gstate_t *gstate); - -cairo_private cairo_bool_t -_cairo_gstate_clip_extents (cairo_gstate_t *gstate, - double *x1, - double *y1, - double *x2, - double *y2); - -cairo_private cairo_rectangle_list_t* -_cairo_gstate_copy_clip_rectangle_list (cairo_gstate_t *gstate); - -cairo_private cairo_status_t -_cairo_gstate_show_surface (cairo_gstate_t *gstate, - cairo_surface_t *surface, - double x, - double y, - double width, - double height); - -cairo_private cairo_status_t -_cairo_gstate_set_font_size (cairo_gstate_t *gstate, - double size); - -cairo_private void -_cairo_gstate_get_font_matrix (cairo_gstate_t *gstate, - cairo_matrix_t *matrix); - -cairo_private cairo_status_t -_cairo_gstate_set_font_matrix (cairo_gstate_t *gstate, - const cairo_matrix_t *matrix); - -cairo_private void -_cairo_gstate_get_font_options (cairo_gstate_t *gstate, - cairo_font_options_t *options); - -cairo_private void -_cairo_gstate_set_font_options (cairo_gstate_t *gstate, - const cairo_font_options_t *options); - -cairo_private cairo_status_t -_cairo_gstate_get_font_face (cairo_gstate_t *gstate, - cairo_font_face_t **font_face); - -cairo_private cairo_status_t -_cairo_gstate_get_scaled_font (cairo_gstate_t *gstate, - cairo_scaled_font_t **scaled_font); - -cairo_private cairo_status_t -_cairo_gstate_get_font_extents (cairo_gstate_t *gstate, - cairo_font_extents_t *extents); - -cairo_private cairo_status_t -_cairo_gstate_set_font_face (cairo_gstate_t *gstate, - cairo_font_face_t *font_face); - -cairo_private cairo_status_t -_cairo_gstate_glyph_extents (cairo_gstate_t *gstate, - const cairo_glyph_t *glyphs, - int num_glyphs, - cairo_text_extents_t *extents); - -cairo_private cairo_status_t -_cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate, - const cairo_glyph_t *glyphs, - int num_glyphs, - cairo_glyph_text_info_t *info); - -cairo_private cairo_status_t -_cairo_gstate_glyph_path (cairo_gstate_t *gstate, - const cairo_glyph_t *glyphs, - int num_glyphs, - cairo_path_fixed_t *path); - -cairo_private cairo_status_t -_cairo_gstate_set_antialias (cairo_gstate_t *gstate, - cairo_antialias_t antialias); - -cairo_private cairo_antialias_t -_cairo_gstate_get_antialias (cairo_gstate_t *gstate); - -#endif /* CAIRO_GSTATE_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-gstate.c b/source/libs/cairo/cairo-src/src/cairo-gstate.c deleted file mode 100644 index b4e988e96d809632af3c1a0f26bb458c8b3c107b..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-gstate.c +++ /dev/null @@ -1,2346 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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" - -#include "cairo-clip-inline.h" -#include "cairo-clip-private.h" -#include "cairo-error-private.h" -#include "cairo-list-inline.h" -#include "cairo-gstate-private.h" -#include "cairo-pattern-private.h" -#include "cairo-traps-private.h" - -#if _XOPEN_SOURCE >= 600 || defined (_ISOC99_SOURCE) -#define ISFINITE(x) isfinite (x) -#else -#define ISFINITE(x) ((x) * (x) >= 0.) /* check for NaNs */ -#endif - -static cairo_status_t -_cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other); - -static cairo_status_t -_cairo_gstate_ensure_font_face (cairo_gstate_t *gstate); - -static cairo_status_t -_cairo_gstate_ensure_scaled_font (cairo_gstate_t *gstate); - -static void -_cairo_gstate_unset_scaled_font (cairo_gstate_t *gstate); - -static void -_cairo_gstate_transform_glyphs_to_backend (cairo_gstate_t *gstate, - const cairo_glyph_t *glyphs, - int num_glyphs, - const cairo_text_cluster_t *clusters, - int num_clusters, - cairo_text_cluster_flags_t cluster_flags, - cairo_glyph_t *transformed_glyphs, - int *num_transformed_glyphs, - cairo_text_cluster_t *transformed_clusters); - -static void -_cairo_gstate_update_device_transform (cairo_observer_t *observer, - void *arg) -{ - cairo_gstate_t *gstate = cairo_container_of (observer, - cairo_gstate_t, - device_transform_observer); - - gstate->is_identity = (_cairo_matrix_is_identity (&gstate->ctm) && - _cairo_matrix_is_identity (&gstate->target->device_transform)); -} - -cairo_status_t -_cairo_gstate_init (cairo_gstate_t *gstate, - cairo_surface_t *target) -{ - VG (VALGRIND_MAKE_MEM_UNDEFINED (gstate, sizeof (cairo_gstate_t))); - - gstate->next = NULL; - - gstate->op = CAIRO_GSTATE_OPERATOR_DEFAULT; - gstate->opacity = 1.; - - gstate->tolerance = CAIRO_GSTATE_TOLERANCE_DEFAULT; - gstate->antialias = CAIRO_ANTIALIAS_DEFAULT; - - _cairo_stroke_style_init (&gstate->stroke_style); - - gstate->fill_rule = CAIRO_GSTATE_FILL_RULE_DEFAULT; - - gstate->font_face = NULL; - gstate->scaled_font = NULL; - gstate->previous_scaled_font = NULL; - - cairo_matrix_init_scale (&gstate->font_matrix, - CAIRO_GSTATE_DEFAULT_FONT_SIZE, - CAIRO_GSTATE_DEFAULT_FONT_SIZE); - - _cairo_font_options_init_default (&gstate->font_options); - - gstate->clip = NULL; - - gstate->target = cairo_surface_reference (target); - gstate->parent_target = NULL; - gstate->original_target = cairo_surface_reference (target); - - gstate->device_transform_observer.callback = _cairo_gstate_update_device_transform; - cairo_list_add (&gstate->device_transform_observer.link, - &gstate->target->device_transform_observers); - - gstate->is_identity = _cairo_matrix_is_identity (&gstate->target->device_transform); - cairo_matrix_init_identity (&gstate->ctm); - gstate->ctm_inverse = gstate->ctm; - gstate->source_ctm_inverse = gstate->ctm; - - gstate->source = (cairo_pattern_t *) &_cairo_pattern_black.base; - - /* Now that the gstate is fully initialized and ready for the eventual - * _cairo_gstate_fini(), we can check for errors (and not worry about - * the resource deallocation). */ - return target->status; -} - -/** - * _cairo_gstate_init_copy: - * - * Initialize @gstate by performing a deep copy of state fields from - * @other. Note that gstate->next is not copied but is set to %NULL by - * this function. - **/ -static cairo_status_t -_cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other) -{ - cairo_status_t status; - - VG (VALGRIND_MAKE_MEM_UNDEFINED (gstate, sizeof (cairo_gstate_t))); - - gstate->op = other->op; - gstate->opacity = other->opacity; - - gstate->tolerance = other->tolerance; - gstate->antialias = other->antialias; - - status = _cairo_stroke_style_init_copy (&gstate->stroke_style, - &other->stroke_style); - if (unlikely (status)) - return status; - - gstate->fill_rule = other->fill_rule; - - gstate->font_face = cairo_font_face_reference (other->font_face); - gstate->scaled_font = cairo_scaled_font_reference (other->scaled_font); - gstate->previous_scaled_font = cairo_scaled_font_reference (other->previous_scaled_font); - - gstate->font_matrix = other->font_matrix; - - _cairo_font_options_init_copy (&gstate->font_options , &other->font_options); - - gstate->clip = _cairo_clip_copy (other->clip); - - gstate->target = cairo_surface_reference (other->target); - /* parent_target is always set to NULL; it's only ever set by redirect_target */ - gstate->parent_target = NULL; - gstate->original_target = cairo_surface_reference (other->original_target); - - gstate->device_transform_observer.callback = _cairo_gstate_update_device_transform; - cairo_list_add (&gstate->device_transform_observer.link, - &gstate->target->device_transform_observers); - - gstate->is_identity = other->is_identity; - gstate->ctm = other->ctm; - gstate->ctm_inverse = other->ctm_inverse; - gstate->source_ctm_inverse = other->source_ctm_inverse; - - gstate->source = cairo_pattern_reference (other->source); - - gstate->next = NULL; - - return CAIRO_STATUS_SUCCESS; -} - -void -_cairo_gstate_fini (cairo_gstate_t *gstate) -{ - _cairo_stroke_style_fini (&gstate->stroke_style); - - cairo_font_face_destroy (gstate->font_face); - gstate->font_face = NULL; - - cairo_scaled_font_destroy (gstate->previous_scaled_font); - gstate->previous_scaled_font = NULL; - - cairo_scaled_font_destroy (gstate->scaled_font); - gstate->scaled_font = NULL; - - _cairo_clip_destroy (gstate->clip); - - cairo_list_del (&gstate->device_transform_observer.link); - - cairo_surface_destroy (gstate->target); - gstate->target = NULL; - - cairo_surface_destroy (gstate->parent_target); - gstate->parent_target = NULL; - - cairo_surface_destroy (gstate->original_target); - gstate->original_target = NULL; - - cairo_pattern_destroy (gstate->source); - gstate->source = NULL; - - VG (VALGRIND_MAKE_MEM_NOACCESS (gstate, sizeof (cairo_gstate_t))); -} - -/** - * _cairo_gstate_save: - * @gstate: input/output gstate pointer - * - * Makes a copy of the current state of @gstate and saves it - * to @gstate->next, then put the address of the newly allcated - * copy into @gstate. _cairo_gstate_restore() reverses this. - **/ -cairo_status_t -_cairo_gstate_save (cairo_gstate_t **gstate, cairo_gstate_t **freelist) -{ - cairo_gstate_t *top; - cairo_status_t status; - - if (CAIRO_INJECT_FAULT ()) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - top = *freelist; - if (top == NULL) { - top = malloc (sizeof (cairo_gstate_t)); - if (unlikely (top == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } else - *freelist = top->next; - - status = _cairo_gstate_init_copy (top, *gstate); - if (unlikely (status)) { - top->next = *freelist; - *freelist = top; - return status; - } - - top->next = *gstate; - *gstate = top; - - return CAIRO_STATUS_SUCCESS; -} - -/** - * _cairo_gstate_restore: - * @gstate: input/output gstate pointer - * - * Reverses the effects of one _cairo_gstate_save() call. - **/ -cairo_status_t -_cairo_gstate_restore (cairo_gstate_t **gstate, cairo_gstate_t **freelist) -{ - cairo_gstate_t *top; - - top = *gstate; - if (top->next == NULL) - return _cairo_error (CAIRO_STATUS_INVALID_RESTORE); - - *gstate = top->next; - - _cairo_gstate_fini (top); - VG (VALGRIND_MAKE_MEM_UNDEFINED (&top->next, sizeof (cairo_gstate_t *))); - top->next = *freelist; - *freelist = top; - - return CAIRO_STATUS_SUCCESS; -} - -/** - * _cairo_gstate_redirect_target: - * @gstate: a #cairo_gstate_t - * @child: the new child target - * - * Redirect @gstate rendering to a "child" target. The original - * "parent" target with which the gstate was created will not be - * affected. See _cairo_gstate_get_target(). - **/ -cairo_status_t -_cairo_gstate_redirect_target (cairo_gstate_t *gstate, cairo_surface_t *child) -{ - /* If this gstate is already redirected, this is an error; we need a - * new gstate to be able to redirect */ - assert (gstate->parent_target == NULL); - - /* Set up our new parent_target based on our current target; - * gstate->parent_target will take the ref that is held by gstate->target - */ - gstate->parent_target = gstate->target; - - /* Now set up our new target; we overwrite gstate->target directly, - * since its ref is now owned by gstate->parent_target */ - gstate->target = cairo_surface_reference (child); - gstate->is_identity &= _cairo_matrix_is_identity (&child->device_transform); - cairo_list_move (&gstate->device_transform_observer.link, - &gstate->target->device_transform_observers); - - /* The clip is in surface backend coordinates for the previous target; - * translate it into the child's backend coordinates. */ - _cairo_clip_destroy (gstate->clip); - gstate->clip = _cairo_clip_copy_with_translation (gstate->next->clip, - child->device_transform.x0 - gstate->parent_target->device_transform.x0, - child->device_transform.y0 - gstate->parent_target->device_transform.y0); - - return CAIRO_STATUS_SUCCESS; -} - -/** - * _cairo_gstate_is_group: - * @gstate: a #cairo_gstate_t - * - * Check if _cairo_gstate_redirect_target has been called on the head - * of the stack. - * - * Return value: %TRUE if @gstate is redirected to a target different - * than the previous state in the stack, %FALSE otherwise. - **/ -cairo_bool_t -_cairo_gstate_is_group (cairo_gstate_t *gstate) -{ - return gstate->parent_target != NULL; -} - -/** - * _cairo_gstate_get_target: - * @gstate: a #cairo_gstate_t - * - * Return the current drawing target; if drawing is not redirected, - * this will be the same as _cairo_gstate_get_original_target(). - * - * Return value: the current target surface - **/ -cairo_surface_t * -_cairo_gstate_get_target (cairo_gstate_t *gstate) -{ - return gstate->target; -} - -/** - * _cairo_gstate_get_original_target: - * @gstate: a #cairo_gstate_t - * - * Return the original target with which @gstate was created. This - * function always returns the original target independent of any - * child target that may have been set with - * _cairo_gstate_redirect_target. - * - * Return value: the original target surface - **/ -cairo_surface_t * -_cairo_gstate_get_original_target (cairo_gstate_t *gstate) -{ - return gstate->original_target; -} - -/** - * _cairo_gstate_get_clip: - * @gstate: a #cairo_gstate_t - * - * This space left intentionally blank. - * - * Return value: a pointer to the gstate's #cairo_clip_t structure. - **/ -cairo_clip_t * -_cairo_gstate_get_clip (cairo_gstate_t *gstate) -{ - return gstate->clip; -} - -cairo_status_t -_cairo_gstate_set_source (cairo_gstate_t *gstate, - cairo_pattern_t *source) -{ - if (source->status) - return source->status; - - source = cairo_pattern_reference (source); - cairo_pattern_destroy (gstate->source); - gstate->source = source; - gstate->source_ctm_inverse = gstate->ctm_inverse; - - return CAIRO_STATUS_SUCCESS; -} - -cairo_pattern_t * -_cairo_gstate_get_source (cairo_gstate_t *gstate) -{ - if (gstate->source == &_cairo_pattern_black.base) { - /* do not expose the static object to the user */ - gstate->source = _cairo_pattern_create_solid (CAIRO_COLOR_BLACK); - } - - return gstate->source; -} - -cairo_status_t -_cairo_gstate_set_operator (cairo_gstate_t *gstate, cairo_operator_t op) -{ - gstate->op = op; - - return CAIRO_STATUS_SUCCESS; -} - -cairo_operator_t -_cairo_gstate_get_operator (cairo_gstate_t *gstate) -{ - return gstate->op; -} - -cairo_status_t -_cairo_gstate_set_opacity (cairo_gstate_t *gstate, double op) -{ - gstate->opacity = op; - - return CAIRO_STATUS_SUCCESS; -} - -double -_cairo_gstate_get_opacity (cairo_gstate_t *gstate) -{ - return gstate->opacity; -} - -cairo_status_t -_cairo_gstate_set_tolerance (cairo_gstate_t *gstate, double tolerance) -{ - gstate->tolerance = tolerance; - - return CAIRO_STATUS_SUCCESS; -} - -double -_cairo_gstate_get_tolerance (cairo_gstate_t *gstate) -{ - return gstate->tolerance; -} - -cairo_status_t -_cairo_gstate_set_fill_rule (cairo_gstate_t *gstate, cairo_fill_rule_t fill_rule) -{ - gstate->fill_rule = fill_rule; - - return CAIRO_STATUS_SUCCESS; -} - -cairo_fill_rule_t -_cairo_gstate_get_fill_rule (cairo_gstate_t *gstate) -{ - return gstate->fill_rule; -} - -cairo_status_t -_cairo_gstate_set_line_width (cairo_gstate_t *gstate, double width) -{ - gstate->stroke_style.line_width = width; - - return CAIRO_STATUS_SUCCESS; -} - -double -_cairo_gstate_get_line_width (cairo_gstate_t *gstate) -{ - return gstate->stroke_style.line_width; -} - -cairo_status_t -_cairo_gstate_set_line_cap (cairo_gstate_t *gstate, cairo_line_cap_t line_cap) -{ - gstate->stroke_style.line_cap = line_cap; - - return CAIRO_STATUS_SUCCESS; -} - -cairo_line_cap_t -_cairo_gstate_get_line_cap (cairo_gstate_t *gstate) -{ - return gstate->stroke_style.line_cap; -} - -cairo_status_t -_cairo_gstate_set_line_join (cairo_gstate_t *gstate, cairo_line_join_t line_join) -{ - gstate->stroke_style.line_join = line_join; - - return CAIRO_STATUS_SUCCESS; -} - -cairo_line_join_t -_cairo_gstate_get_line_join (cairo_gstate_t *gstate) -{ - return gstate->stroke_style.line_join; -} - -cairo_status_t -_cairo_gstate_set_dash (cairo_gstate_t *gstate, const double *dash, int num_dashes, double offset) -{ - double dash_total, on_total, off_total; - int i, j; - - free (gstate->stroke_style.dash); - - gstate->stroke_style.num_dashes = num_dashes; - - if (gstate->stroke_style.num_dashes == 0) { - gstate->stroke_style.dash = NULL; - gstate->stroke_style.dash_offset = 0.0; - return CAIRO_STATUS_SUCCESS; - } - - gstate->stroke_style.dash = _cairo_malloc_ab (gstate->stroke_style.num_dashes, sizeof (double)); - if (unlikely (gstate->stroke_style.dash == NULL)) { - gstate->stroke_style.num_dashes = 0; - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - on_total = off_total = dash_total = 0.0; - for (i = j = 0; i < num_dashes; i++) { - if (dash[i] < 0) - return _cairo_error (CAIRO_STATUS_INVALID_DASH); - - if (dash[i] == 0 && i > 0 && i < num_dashes - 1) { - if (dash[++i] < 0) - return _cairo_error (CAIRO_STATUS_INVALID_DASH); - - gstate->stroke_style.dash[j-1] += dash[i]; - gstate->stroke_style.num_dashes -= 2; - } else - gstate->stroke_style.dash[j++] = dash[i]; - - if (dash[i]) { - dash_total += dash[i]; - if ((i & 1) == 0) - on_total += dash[i]; - else - off_total += dash[i]; - } - } - - if (dash_total == 0.0) - return _cairo_error (CAIRO_STATUS_INVALID_DASH); - - /* An odd dash value indicate symmetric repeating, so the total - * is twice as long. */ - if (gstate->stroke_style.num_dashes & 1) { - dash_total *= 2; - on_total += off_total; - } - - if (dash_total - on_total < CAIRO_FIXED_ERROR_DOUBLE) { - /* Degenerate dash -> solid line */ - free (gstate->stroke_style.dash); - gstate->stroke_style.dash = NULL; - gstate->stroke_style.num_dashes = 0; - gstate->stroke_style.dash_offset = 0.0; - return CAIRO_STATUS_SUCCESS; - } - - /* The dashing code doesn't like a negative offset or a big positive - * offset, so we compute an equivalent offset which is guaranteed to be - * positive and less than twice the pattern length. */ - offset = fmod (offset, dash_total); - if (offset < 0.0) - offset += dash_total; - if (offset <= 0.0) /* Take care of -0 */ - offset = 0.0; - gstate->stroke_style.dash_offset = offset; - - return CAIRO_STATUS_SUCCESS; -} - -void -_cairo_gstate_get_dash (cairo_gstate_t *gstate, - double *dashes, - int *num_dashes, - double *offset) -{ - if (dashes) { - memcpy (dashes, - gstate->stroke_style.dash, - sizeof (double) * gstate->stroke_style.num_dashes); - } - - if (num_dashes) - *num_dashes = gstate->stroke_style.num_dashes; - - if (offset) - *offset = gstate->stroke_style.dash_offset; -} - -cairo_status_t -_cairo_gstate_set_miter_limit (cairo_gstate_t *gstate, double limit) -{ - gstate->stroke_style.miter_limit = limit; - - return CAIRO_STATUS_SUCCESS; -} - -double -_cairo_gstate_get_miter_limit (cairo_gstate_t *gstate) -{ - return gstate->stroke_style.miter_limit; -} - -void -_cairo_gstate_get_matrix (cairo_gstate_t *gstate, cairo_matrix_t *matrix) -{ - *matrix = gstate->ctm; -} - -cairo_status_t -_cairo_gstate_translate (cairo_gstate_t *gstate, double tx, double ty) -{ - cairo_matrix_t tmp; - - if (! ISFINITE (tx) || ! ISFINITE (ty)) - return _cairo_error (CAIRO_STATUS_INVALID_MATRIX); - - _cairo_gstate_unset_scaled_font (gstate); - - cairo_matrix_init_translate (&tmp, tx, ty); - cairo_matrix_multiply (&gstate->ctm, &tmp, &gstate->ctm); - gstate->is_identity = FALSE; - - /* paranoid check against gradual numerical instability */ - if (! _cairo_matrix_is_invertible (&gstate->ctm)) - return _cairo_error (CAIRO_STATUS_INVALID_MATRIX); - - cairo_matrix_init_translate (&tmp, -tx, -ty); - cairo_matrix_multiply (&gstate->ctm_inverse, &gstate->ctm_inverse, &tmp); - - return CAIRO_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_gstate_scale (cairo_gstate_t *gstate, double sx, double sy) -{ - cairo_matrix_t tmp; - - if (sx * sy == 0.) /* either sx or sy is 0, or det == 0 due to underflow */ - return _cairo_error (CAIRO_STATUS_INVALID_MATRIX); - if (! ISFINITE (sx) || ! ISFINITE (sy)) - return _cairo_error (CAIRO_STATUS_INVALID_MATRIX); - - _cairo_gstate_unset_scaled_font (gstate); - - cairo_matrix_init_scale (&tmp, sx, sy); - cairo_matrix_multiply (&gstate->ctm, &tmp, &gstate->ctm); - gstate->is_identity = FALSE; - - /* paranoid check against gradual numerical instability */ - if (! _cairo_matrix_is_invertible (&gstate->ctm)) - return _cairo_error (CAIRO_STATUS_INVALID_MATRIX); - - cairo_matrix_init_scale (&tmp, 1/sx, 1/sy); - cairo_matrix_multiply (&gstate->ctm_inverse, &gstate->ctm_inverse, &tmp); - - return CAIRO_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_gstate_rotate (cairo_gstate_t *gstate, double angle) -{ - cairo_matrix_t tmp; - - if (angle == 0.) - return CAIRO_STATUS_SUCCESS; - - if (! ISFINITE (angle)) - return _cairo_error (CAIRO_STATUS_INVALID_MATRIX); - - _cairo_gstate_unset_scaled_font (gstate); - - cairo_matrix_init_rotate (&tmp, angle); - cairo_matrix_multiply (&gstate->ctm, &tmp, &gstate->ctm); - gstate->is_identity = FALSE; - - /* paranoid check against gradual numerical instability */ - if (! _cairo_matrix_is_invertible (&gstate->ctm)) - return _cairo_error (CAIRO_STATUS_INVALID_MATRIX); - - cairo_matrix_init_rotate (&tmp, -angle); - cairo_matrix_multiply (&gstate->ctm_inverse, &gstate->ctm_inverse, &tmp); - - return CAIRO_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_gstate_transform (cairo_gstate_t *gstate, - const cairo_matrix_t *matrix) -{ - cairo_matrix_t tmp; - cairo_status_t status; - - if (! _cairo_matrix_is_invertible (matrix)) - return _cairo_error (CAIRO_STATUS_INVALID_MATRIX); - - if (_cairo_matrix_is_identity (matrix)) - return CAIRO_STATUS_SUCCESS; - - tmp = *matrix; - status = cairo_matrix_invert (&tmp); - if (unlikely (status)) - return status; - - _cairo_gstate_unset_scaled_font (gstate); - - cairo_matrix_multiply (&gstate->ctm, matrix, &gstate->ctm); - cairo_matrix_multiply (&gstate->ctm_inverse, &gstate->ctm_inverse, &tmp); - gstate->is_identity = FALSE; - - /* paranoid check against gradual numerical instability */ - if (! _cairo_matrix_is_invertible (&gstate->ctm)) - return _cairo_error (CAIRO_STATUS_INVALID_MATRIX); - - return CAIRO_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_gstate_set_matrix (cairo_gstate_t *gstate, - const cairo_matrix_t *matrix) -{ - cairo_status_t status; - - if (memcmp (matrix, &gstate->ctm, sizeof (cairo_matrix_t)) == 0) - return CAIRO_STATUS_SUCCESS; - - if (! _cairo_matrix_is_invertible (matrix)) - return _cairo_error (CAIRO_STATUS_INVALID_MATRIX); - - if (_cairo_matrix_is_identity (matrix)) { - _cairo_gstate_identity_matrix (gstate); - return CAIRO_STATUS_SUCCESS; - } - - _cairo_gstate_unset_scaled_font (gstate); - - gstate->ctm = *matrix; - gstate->ctm_inverse = *matrix; - status = cairo_matrix_invert (&gstate->ctm_inverse); - assert (status == CAIRO_STATUS_SUCCESS); - gstate->is_identity = FALSE; - - return CAIRO_STATUS_SUCCESS; -} - -void -_cairo_gstate_identity_matrix (cairo_gstate_t *gstate) -{ - if (_cairo_matrix_is_identity (&gstate->ctm)) - return; - - _cairo_gstate_unset_scaled_font (gstate); - - cairo_matrix_init_identity (&gstate->ctm); - cairo_matrix_init_identity (&gstate->ctm_inverse); - gstate->is_identity = _cairo_matrix_is_identity (&gstate->target->device_transform); -} - -void -_cairo_gstate_user_to_device (cairo_gstate_t *gstate, double *x, double *y) -{ - cairo_matrix_transform_point (&gstate->ctm, x, y); -} - -void -_cairo_gstate_user_to_device_distance (cairo_gstate_t *gstate, - double *dx, double *dy) -{ - cairo_matrix_transform_distance (&gstate->ctm, dx, dy); -} - -void -_cairo_gstate_device_to_user (cairo_gstate_t *gstate, double *x, double *y) -{ - cairo_matrix_transform_point (&gstate->ctm_inverse, x, y); -} - -void -_cairo_gstate_device_to_user_distance (cairo_gstate_t *gstate, - double *dx, double *dy) -{ - cairo_matrix_transform_distance (&gstate->ctm_inverse, dx, dy); -} - -void -_do_cairo_gstate_user_to_backend (cairo_gstate_t *gstate, double *x, double *y) -{ - cairo_matrix_transform_point (&gstate->ctm, x, y); - cairo_matrix_transform_point (&gstate->target->device_transform, x, y); -} - -void -_do_cairo_gstate_user_to_backend_distance (cairo_gstate_t *gstate, double *x, double *y) -{ - cairo_matrix_transform_distance (&gstate->ctm, x, y); - cairo_matrix_transform_distance (&gstate->target->device_transform, x, y); -} - -void -_do_cairo_gstate_backend_to_user (cairo_gstate_t *gstate, double *x, double *y) -{ - cairo_matrix_transform_point (&gstate->target->device_transform_inverse, x, y); - cairo_matrix_transform_point (&gstate->ctm_inverse, x, y); -} - -void -_do_cairo_gstate_backend_to_user_distance (cairo_gstate_t *gstate, double *x, double *y) -{ - cairo_matrix_transform_distance (&gstate->target->device_transform_inverse, x, y); - cairo_matrix_transform_distance (&gstate->ctm_inverse, x, y); -} - -void -_cairo_gstate_backend_to_user_rectangle (cairo_gstate_t *gstate, - double *x1, double *y1, - double *x2, double *y2, - cairo_bool_t *is_tight) -{ - cairo_matrix_t matrix_inverse; - - if (! _cairo_matrix_is_identity (&gstate->target->device_transform_inverse) || - ! _cairo_matrix_is_identity (&gstate->ctm_inverse)) - { - cairo_matrix_multiply (&matrix_inverse, - &gstate->target->device_transform_inverse, - &gstate->ctm_inverse); - _cairo_matrix_transform_bounding_box (&matrix_inverse, - x1, y1, x2, y2, is_tight); - } - - else - { - if (is_tight) - *is_tight = TRUE; - } -} - -/* XXX: NYI -cairo_status_t -_cairo_gstate_stroke_to_path (cairo_gstate_t *gstate) -{ - cairo_status_t status; - - _cairo_pen_init (&gstate); - return CAIRO_STATUS_SUCCESS; -} -*/ - -void -_cairo_gstate_path_extents (cairo_gstate_t *gstate, - cairo_path_fixed_t *path, - double *x1, double *y1, - double *x2, double *y2) -{ - cairo_box_t box; - double px1, py1, px2, py2; - - if (_cairo_path_fixed_extents (path, &box)) { - px1 = _cairo_fixed_to_double (box.p1.x); - py1 = _cairo_fixed_to_double (box.p1.y); - px2 = _cairo_fixed_to_double (box.p2.x); - py2 = _cairo_fixed_to_double (box.p2.y); - - _cairo_gstate_backend_to_user_rectangle (gstate, - &px1, &py1, &px2, &py2, - NULL); - } else { - px1 = 0.0; - py1 = 0.0; - px2 = 0.0; - py2 = 0.0; - } - - if (x1) - *x1 = px1; - if (y1) - *y1 = py1; - if (x2) - *x2 = px2; - if (y2) - *y2 = py2; -} - -static void -_cairo_gstate_copy_pattern (cairo_pattern_t *pattern, - const cairo_pattern_t *original) -{ - /* First check if the we can replace the original with a much simpler - * pattern. For example, gradients that are uniform or just have a single - * stop can sometimes be replaced with a solid. - */ - - if (_cairo_pattern_is_clear (original)) { - _cairo_pattern_init_solid ((cairo_solid_pattern_t *) pattern, - CAIRO_COLOR_TRANSPARENT); - return; - } - - if (original->type == CAIRO_PATTERN_TYPE_LINEAR || - original->type == CAIRO_PATTERN_TYPE_RADIAL) - { - cairo_color_t color; - if (_cairo_gradient_pattern_is_solid ((cairo_gradient_pattern_t *) original, - NULL, - &color)) - { - _cairo_pattern_init_solid ((cairo_solid_pattern_t *) pattern, - &color); - return; - } - } - - _cairo_pattern_init_static_copy (pattern, original); -} - -static void -_cairo_gstate_copy_transformed_pattern (cairo_gstate_t *gstate, - cairo_pattern_t *pattern, - const cairo_pattern_t *original, - const cairo_matrix_t *ctm_inverse) -{ - _cairo_gstate_copy_pattern (pattern, original); - - /* apply device_transform first so that it is transformed by ctm_inverse */ - if (original->type == CAIRO_PATTERN_TYPE_SURFACE) { - cairo_surface_pattern_t *surface_pattern; - cairo_surface_t *surface; - - surface_pattern = (cairo_surface_pattern_t *) original; - surface = surface_pattern->surface; - - if (_cairo_surface_has_device_transform (surface)) - _cairo_pattern_pretransform (pattern, &surface->device_transform); - } - - if (! _cairo_matrix_is_identity (ctm_inverse)) - _cairo_pattern_transform (pattern, ctm_inverse); - - if (_cairo_surface_has_device_transform (gstate->target)) { - _cairo_pattern_transform (pattern, - &gstate->target->device_transform_inverse); - } -} - -static void -_cairo_gstate_copy_transformed_source (cairo_gstate_t *gstate, - cairo_pattern_t *pattern) -{ - _cairo_gstate_copy_transformed_pattern (gstate, pattern, - gstate->source, - &gstate->source_ctm_inverse); -} - -static void -_cairo_gstate_copy_transformed_mask (cairo_gstate_t *gstate, - cairo_pattern_t *pattern, - cairo_pattern_t *mask) -{ - _cairo_gstate_copy_transformed_pattern (gstate, pattern, - mask, - &gstate->ctm_inverse); -} - -static cairo_operator_t -_reduce_op (cairo_gstate_t *gstate) -{ - cairo_operator_t op; - const cairo_pattern_t *pattern; - - op = gstate->op; - if (op != CAIRO_OPERATOR_SOURCE) - return op; - - pattern = gstate->source; - if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) { - const cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) pattern; - if (solid->color.alpha_short <= 0x00ff) { - op = CAIRO_OPERATOR_CLEAR; - } else if ((gstate->target->content & CAIRO_CONTENT_ALPHA) == 0) { - if ((solid->color.red_short | - solid->color.green_short | - solid->color.blue_short) <= 0x00ff) - { - op = CAIRO_OPERATOR_CLEAR; - } - } - } else if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) { - const cairo_surface_pattern_t *surface = (cairo_surface_pattern_t *) pattern; - if (surface->surface->is_clear && - surface->surface->content & CAIRO_CONTENT_ALPHA) - { - op = CAIRO_OPERATOR_CLEAR; - } - } else { - const cairo_gradient_pattern_t *gradient = (cairo_gradient_pattern_t *) pattern; - if (gradient->n_stops == 0) - op = CAIRO_OPERATOR_CLEAR; - } - - return op; -} - -static cairo_status_t -_cairo_gstate_get_pattern_status (const cairo_pattern_t *pattern) -{ - if (unlikely (pattern->type == CAIRO_PATTERN_TYPE_MESH && - ((const cairo_mesh_pattern_t *) pattern)->current_patch)) - { - /* If current patch != NULL, the pattern is under construction - * and cannot be used as a source */ - return CAIRO_STATUS_INVALID_MESH_CONSTRUCTION; - } - - return pattern->status; -} - -cairo_status_t -_cairo_gstate_paint (cairo_gstate_t *gstate) -{ - cairo_pattern_union_t source_pattern; - const cairo_pattern_t *pattern; - cairo_status_t status; - cairo_operator_t op; - - status = _cairo_gstate_get_pattern_status (gstate->source); - if (unlikely (status)) - return status; - - if (gstate->op == CAIRO_OPERATOR_DEST) - return CAIRO_STATUS_SUCCESS; - - if (_cairo_clip_is_all_clipped (gstate->clip)) - return CAIRO_STATUS_SUCCESS; - - op = _reduce_op (gstate); - if (op == CAIRO_OPERATOR_CLEAR) { - pattern = &_cairo_pattern_clear.base; - } else { - _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base); - pattern = &source_pattern.base; - } - - return _cairo_surface_paint (gstate->target, - op, pattern, - gstate->clip); -} - -cairo_status_t -_cairo_gstate_mask (cairo_gstate_t *gstate, - cairo_pattern_t *mask) -{ - cairo_pattern_union_t source_pattern, mask_pattern; - const cairo_pattern_t *source; - cairo_operator_t op; - cairo_status_t status; - - status = _cairo_gstate_get_pattern_status (mask); - if (unlikely (status)) - return status; - - status = _cairo_gstate_get_pattern_status (gstate->source); - if (unlikely (status)) - return status; - - if (gstate->op == CAIRO_OPERATOR_DEST) - return CAIRO_STATUS_SUCCESS; - - if (_cairo_clip_is_all_clipped (gstate->clip)) - return CAIRO_STATUS_SUCCESS; - - assert (gstate->opacity == 1.0); - - if (_cairo_pattern_is_opaque (mask, NULL)) - return _cairo_gstate_paint (gstate); - - if (_cairo_pattern_is_clear (mask) && - _cairo_operator_bounded_by_mask (gstate->op)) - { - return CAIRO_STATUS_SUCCESS; - } - - op = _reduce_op (gstate); - if (op == CAIRO_OPERATOR_CLEAR) { - source = &_cairo_pattern_clear.base; - } else { - _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base); - source = &source_pattern.base; - } - _cairo_gstate_copy_transformed_mask (gstate, &mask_pattern.base, mask); - - if (source->type == CAIRO_PATTERN_TYPE_SOLID && - mask_pattern.base.type == CAIRO_PATTERN_TYPE_SOLID && - _cairo_operator_bounded_by_source (op)) - { - const cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) source; - cairo_color_t combined; - - if (mask_pattern.base.has_component_alpha) { -#define M(R, A, B, c) R.c = A.c * B.c - M(combined, solid->color, mask_pattern.solid.color, red); - M(combined, solid->color, mask_pattern.solid.color, green); - M(combined, solid->color, mask_pattern.solid.color, blue); - M(combined, solid->color, mask_pattern.solid.color, alpha); -#undef M - } else { - combined = solid->color; - _cairo_color_multiply_alpha (&combined, mask_pattern.solid.color.alpha); - } - - _cairo_pattern_init_solid (&source_pattern.solid, &combined); - - status = _cairo_surface_paint (gstate->target, op, - &source_pattern.base, - gstate->clip); - } - else - { - status = _cairo_surface_mask (gstate->target, op, - source, - &mask_pattern.base, - gstate->clip); - } - - return status; -} - -cairo_status_t -_cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path) -{ - cairo_pattern_union_t source_pattern; - cairo_stroke_style_t style; - double dash[2]; - cairo_status_t status; - cairo_matrix_t aggregate_transform; - cairo_matrix_t aggregate_transform_inverse; - - status = _cairo_gstate_get_pattern_status (gstate->source); - if (unlikely (status)) - return status; - - if (gstate->op == CAIRO_OPERATOR_DEST) - return CAIRO_STATUS_SUCCESS; - - if (gstate->stroke_style.line_width <= 0.0) - return CAIRO_STATUS_SUCCESS; - - if (_cairo_clip_is_all_clipped (gstate->clip)) - return CAIRO_STATUS_SUCCESS; - - assert (gstate->opacity == 1.0); - - cairo_matrix_multiply (&aggregate_transform, - &gstate->ctm, - &gstate->target->device_transform); - cairo_matrix_multiply (&aggregate_transform_inverse, - &gstate->target->device_transform_inverse, - &gstate->ctm_inverse); - - memcpy (&style, &gstate->stroke_style, sizeof (gstate->stroke_style)); - if (_cairo_stroke_style_dash_can_approximate (&gstate->stroke_style, &aggregate_transform, gstate->tolerance)) { - style.dash = dash; - _cairo_stroke_style_dash_approximate (&gstate->stroke_style, &gstate->ctm, gstate->tolerance, - &style.dash_offset, - style.dash, - &style.num_dashes); - } - - _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base); - - return _cairo_surface_stroke (gstate->target, - gstate->op, - &source_pattern.base, - path, - &style, - &aggregate_transform, - &aggregate_transform_inverse, - gstate->tolerance, - gstate->antialias, - gstate->clip); -} - -cairo_status_t -_cairo_gstate_in_stroke (cairo_gstate_t *gstate, - cairo_path_fixed_t *path, - double x, - double y, - cairo_bool_t *inside_ret) -{ - cairo_status_t status; - cairo_rectangle_int_t extents; - cairo_box_t limit; - cairo_traps_t traps; - - if (gstate->stroke_style.line_width <= 0.0) { - *inside_ret = FALSE; - return CAIRO_STATUS_SUCCESS; - } - - _cairo_gstate_user_to_backend (gstate, &x, &y); - - /* Before we perform the expensive stroke analysis, - * check whether the point is within the extents of the path. - */ - _cairo_path_fixed_approximate_stroke_extents (path, - &gstate->stroke_style, - &gstate->ctm, - &extents); - if (x < extents.x || x > extents.x + extents.width || - y < extents.y || y > extents.y + extents.height) - { - *inside_ret = FALSE; - return CAIRO_STATUS_SUCCESS; - } - - limit.p1.x = _cairo_fixed_from_double (x) - 1; - limit.p1.y = _cairo_fixed_from_double (y) - 1; - limit.p2.x = limit.p1.x + 2; - limit.p2.y = limit.p1.y + 2; - - _cairo_traps_init (&traps); - _cairo_traps_limit (&traps, &limit, 1); - - status = _cairo_path_fixed_stroke_polygon_to_traps (path, - &gstate->stroke_style, - &gstate->ctm, - &gstate->ctm_inverse, - gstate->tolerance, - &traps); - if (unlikely (status)) - goto BAIL; - - *inside_ret = _cairo_traps_contain (&traps, x, y); - -BAIL: - _cairo_traps_fini (&traps); - - return status; -} - -cairo_status_t -_cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path) -{ - cairo_status_t status; - - status = _cairo_gstate_get_pattern_status (gstate->source); - if (unlikely (status)) - return status; - - if (gstate->op == CAIRO_OPERATOR_DEST) - return CAIRO_STATUS_SUCCESS; - - if (_cairo_clip_is_all_clipped (gstate->clip)) - return CAIRO_STATUS_SUCCESS; - - assert (gstate->opacity == 1.0); - - if (_cairo_path_fixed_fill_is_empty (path)) { - if (_cairo_operator_bounded_by_mask (gstate->op)) - return CAIRO_STATUS_SUCCESS; - - status = _cairo_surface_paint (gstate->target, - CAIRO_OPERATOR_CLEAR, - &_cairo_pattern_clear.base, - gstate->clip); - } else { - cairo_pattern_union_t source_pattern; - const cairo_pattern_t *pattern; - cairo_operator_t op; - cairo_rectangle_int_t extents; - cairo_box_t box; - - op = _reduce_op (gstate); - if (op == CAIRO_OPERATOR_CLEAR) { - pattern = &_cairo_pattern_clear.base; - } else { - _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base); - pattern = &source_pattern.base; - } - - /* Toolkits often paint the entire background with a fill */ - if (_cairo_surface_get_extents (gstate->target, &extents) && - _cairo_path_fixed_is_box (path, &box) && - box.p1.x <= _cairo_fixed_from_int (extents.x) && - box.p1.y <= _cairo_fixed_from_int (extents.y) && - box.p2.x >= _cairo_fixed_from_int (extents.x + extents.width) && - box.p2.y >= _cairo_fixed_from_int (extents.y + extents.height)) - { - status = _cairo_surface_paint (gstate->target, op, pattern, - gstate->clip); - } - else - { - status = _cairo_surface_fill (gstate->target, op, pattern, - path, - gstate->fill_rule, - gstate->tolerance, - gstate->antialias, - gstate->clip); - } - } - - return status; -} - -cairo_bool_t -_cairo_gstate_in_fill (cairo_gstate_t *gstate, - cairo_path_fixed_t *path, - double x, - double y) -{ - _cairo_gstate_user_to_backend (gstate, &x, &y); - - return _cairo_path_fixed_in_fill (path, - gstate->fill_rule, - gstate->tolerance, - x, y); -} - -cairo_bool_t -_cairo_gstate_in_clip (cairo_gstate_t *gstate, - double x, - double y) -{ - cairo_clip_t *clip = gstate->clip; - int i; - - if (_cairo_clip_is_all_clipped (clip)) - return FALSE; - - if (clip == NULL) - return TRUE; - - _cairo_gstate_user_to_backend (gstate, &x, &y); - - if (x < clip->extents.x || - x >= clip->extents.x + clip->extents.width || - y < clip->extents.y || - y >= clip->extents.y + clip->extents.height) - { - return FALSE; - } - - if (clip->num_boxes) { - int fx, fy; - - fx = _cairo_fixed_from_double (x); - fy = _cairo_fixed_from_double (y); - for (i = 0; i < clip->num_boxes; i++) { - if (fx >= clip->boxes[i].p1.x && fx <= clip->boxes[i].p2.x && - fy >= clip->boxes[i].p1.y && fy <= clip->boxes[i].p2.y) - break; - } - if (i == clip->num_boxes) - return FALSE; - } - - if (clip->path) { - cairo_clip_path_t *clip_path = clip->path; - do { - if (! _cairo_path_fixed_in_fill (&clip_path->path, - clip_path->fill_rule, - clip_path->tolerance, - x, y)) - return FALSE; - } while ((clip_path = clip_path->prev) != NULL); - } - - return TRUE; -} - -cairo_status_t -_cairo_gstate_copy_page (cairo_gstate_t *gstate) -{ - cairo_surface_copy_page (gstate->target); - return cairo_surface_status (gstate->target); -} - -cairo_status_t -_cairo_gstate_show_page (cairo_gstate_t *gstate) -{ - cairo_surface_show_page (gstate->target); - return cairo_surface_status (gstate->target); -} - -static void -_cairo_gstate_extents_to_user_rectangle (cairo_gstate_t *gstate, - const cairo_box_t *extents, - double *x1, double *y1, - double *x2, double *y2) -{ - double px1, py1, px2, py2; - - px1 = _cairo_fixed_to_double (extents->p1.x); - py1 = _cairo_fixed_to_double (extents->p1.y); - px2 = _cairo_fixed_to_double (extents->p2.x); - py2 = _cairo_fixed_to_double (extents->p2.y); - - _cairo_gstate_backend_to_user_rectangle (gstate, - &px1, &py1, &px2, &py2, - NULL); - if (x1) - *x1 = px1; - if (y1) - *y1 = py1; - if (x2) - *x2 = px2; - if (y2) - *y2 = py2; -} - -cairo_status_t -_cairo_gstate_stroke_extents (cairo_gstate_t *gstate, - cairo_path_fixed_t *path, - double *x1, double *y1, - double *x2, double *y2) -{ - cairo_int_status_t status; - cairo_box_t extents; - cairo_bool_t empty; - - if (x1) - *x1 = 0.0; - if (y1) - *y1 = 0.0; - if (x2) - *x2 = 0.0; - if (y2) - *y2 = 0.0; - - if (gstate->stroke_style.line_width <= 0.0) - return CAIRO_STATUS_SUCCESS; - - status = CAIRO_INT_STATUS_UNSUPPORTED; - if (_cairo_path_fixed_stroke_is_rectilinear (path)) { - cairo_boxes_t boxes; - - _cairo_boxes_init (&boxes); - status = _cairo_path_fixed_stroke_rectilinear_to_boxes (path, - &gstate->stroke_style, - &gstate->ctm, - gstate->antialias, - &boxes); - empty = boxes.num_boxes == 0; - if (! empty) - _cairo_boxes_extents (&boxes, &extents); - _cairo_boxes_fini (&boxes); - } - - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - cairo_polygon_t polygon; - - _cairo_polygon_init (&polygon, NULL, 0); - status = _cairo_path_fixed_stroke_to_polygon (path, - &gstate->stroke_style, - &gstate->ctm, - &gstate->ctm_inverse, - gstate->tolerance, - &polygon); - empty = polygon.num_edges == 0; - if (! empty) - extents = polygon.extents; - _cairo_polygon_fini (&polygon); - } - if (! empty) { - _cairo_gstate_extents_to_user_rectangle (gstate, &extents, - x1, y1, x2, y2); - } - - return status; -} - -cairo_status_t -_cairo_gstate_fill_extents (cairo_gstate_t *gstate, - cairo_path_fixed_t *path, - double *x1, double *y1, - double *x2, double *y2) -{ - cairo_status_t status; - cairo_box_t extents; - cairo_bool_t empty; - - if (x1) - *x1 = 0.0; - if (y1) - *y1 = 0.0; - if (x2) - *x2 = 0.0; - if (y2) - *y2 = 0.0; - - if (_cairo_path_fixed_fill_is_empty (path)) - return CAIRO_STATUS_SUCCESS; - - if (_cairo_path_fixed_fill_is_rectilinear (path)) { - cairo_boxes_t boxes; - - _cairo_boxes_init (&boxes); - status = _cairo_path_fixed_fill_rectilinear_to_boxes (path, - gstate->fill_rule, - gstate->antialias, - &boxes); - empty = boxes.num_boxes == 0; - if (! empty) - _cairo_boxes_extents (&boxes, &extents); - - _cairo_boxes_fini (&boxes); - } else { - cairo_traps_t traps; - - _cairo_traps_init (&traps); - - status = _cairo_path_fixed_fill_to_traps (path, - gstate->fill_rule, - gstate->tolerance, - &traps); - empty = traps.num_traps == 0; - if (! empty) - _cairo_traps_extents (&traps, &extents); - - _cairo_traps_fini (&traps); - } - - if (! empty) { - _cairo_gstate_extents_to_user_rectangle (gstate, &extents, - x1, y1, x2, y2); - } - - return status; -} - -cairo_status_t -_cairo_gstate_reset_clip (cairo_gstate_t *gstate) -{ - _cairo_clip_destroy (gstate->clip); - gstate->clip = NULL; - - return CAIRO_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_gstate_clip (cairo_gstate_t *gstate, cairo_path_fixed_t *path) -{ - gstate->clip = - _cairo_clip_intersect_path (gstate->clip, - path, - gstate->fill_rule, - gstate->tolerance, - gstate->antialias); - /* XXX */ - return CAIRO_STATUS_SUCCESS; -} - -static cairo_bool_t -_cairo_gstate_int_clip_extents (cairo_gstate_t *gstate, - cairo_rectangle_int_t *extents) -{ - cairo_bool_t is_bounded; - - is_bounded = _cairo_surface_get_extents (gstate->target, extents); - - if (gstate->clip) { - _cairo_rectangle_intersect (extents, - _cairo_clip_get_extents (gstate->clip)); - is_bounded = TRUE; - } - - return is_bounded; -} - -cairo_bool_t -_cairo_gstate_clip_extents (cairo_gstate_t *gstate, - double *x1, - double *y1, - double *x2, - double *y2) -{ - cairo_rectangle_int_t extents; - double px1, py1, px2, py2; - - if (! _cairo_gstate_int_clip_extents (gstate, &extents)) - return FALSE; - - px1 = extents.x; - py1 = extents.y; - px2 = extents.x + (int) extents.width; - py2 = extents.y + (int) extents.height; - - _cairo_gstate_backend_to_user_rectangle (gstate, - &px1, &py1, &px2, &py2, - NULL); - - if (x1) - *x1 = px1; - if (y1) - *y1 = py1; - if (x2) - *x2 = px2; - if (y2) - *y2 = py2; - - return TRUE; -} - -cairo_rectangle_list_t* -_cairo_gstate_copy_clip_rectangle_list (cairo_gstate_t *gstate) -{ - cairo_rectangle_int_t extents; - cairo_rectangle_list_t *list; - cairo_clip_t *clip; - - if (_cairo_surface_get_extents (gstate->target, &extents)) - clip = _cairo_clip_copy_intersect_rectangle (gstate->clip, &extents); - else - clip = gstate->clip; - - list = _cairo_clip_copy_rectangle_list (clip, gstate); - - if (clip != gstate->clip) - _cairo_clip_destroy (clip); - - return list; -} - -static void -_cairo_gstate_unset_scaled_font (cairo_gstate_t *gstate) -{ - if (gstate->scaled_font == NULL) - return; - - if (gstate->previous_scaled_font != NULL) - cairo_scaled_font_destroy (gstate->previous_scaled_font); - - gstate->previous_scaled_font = gstate->scaled_font; - gstate->scaled_font = NULL; -} - -cairo_status_t -_cairo_gstate_set_font_size (cairo_gstate_t *gstate, - double size) -{ - _cairo_gstate_unset_scaled_font (gstate); - - cairo_matrix_init_scale (&gstate->font_matrix, size, size); - - return CAIRO_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_gstate_set_font_matrix (cairo_gstate_t *gstate, - const cairo_matrix_t *matrix) -{ - if (memcmp (matrix, &gstate->font_matrix, sizeof (cairo_matrix_t)) == 0) - return CAIRO_STATUS_SUCCESS; - - _cairo_gstate_unset_scaled_font (gstate); - - gstate->font_matrix = *matrix; - - return CAIRO_STATUS_SUCCESS; -} - -void -_cairo_gstate_get_font_matrix (cairo_gstate_t *gstate, - cairo_matrix_t *matrix) -{ - *matrix = gstate->font_matrix; -} - -void -_cairo_gstate_set_font_options (cairo_gstate_t *gstate, - const cairo_font_options_t *options) -{ - if (memcmp (options, &gstate->font_options, sizeof (cairo_font_options_t)) == 0) - return; - - _cairo_gstate_unset_scaled_font (gstate); - - _cairo_font_options_init_copy (&gstate->font_options, options); -} - -void -_cairo_gstate_get_font_options (cairo_gstate_t *gstate, - cairo_font_options_t *options) -{ - *options = gstate->font_options; -} - -cairo_status_t -_cairo_gstate_get_font_face (cairo_gstate_t *gstate, - cairo_font_face_t **font_face) -{ - cairo_status_t status; - - status = _cairo_gstate_ensure_font_face (gstate); - if (unlikely (status)) - return status; - - *font_face = gstate->font_face; - - return CAIRO_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_gstate_get_scaled_font (cairo_gstate_t *gstate, - cairo_scaled_font_t **scaled_font) -{ - cairo_status_t status; - - status = _cairo_gstate_ensure_scaled_font (gstate); - if (unlikely (status)) - return status; - - *scaled_font = gstate->scaled_font; - - return CAIRO_STATUS_SUCCESS; -} - -/* - * Like everything else in this file, fonts involve Too Many Coordinate Spaces; - * it is easy to get confused about what's going on. - * - * The user's view - * --------------- - * - * Users ask for things in user space. When cairo starts, a user space unit - * is about 1/96 inch, which is similar to (but importantly different from) - * the normal "point" units most users think in terms of. When a user - * selects a font, its scale is set to "one user unit". The user can then - * independently scale the user coordinate system *or* the font matrix, in - * order to adjust the rendered size of the font. - * - * Metrics are returned in user space, whether they are obtained from - * the currently selected font in a #cairo_t or from a #cairo_scaled_font_t - * which is a font specialized to a particular scale matrix, CTM, and target - * surface. - * - * The font's view - * --------------- - * - * Fonts are designed and stored (in say .ttf files) in "font space", which - * describes an "EM Square" (a design tile) and has some abstract number - * such as 1000, 1024, or 2048 units per "EM". This is basically an - * uninteresting space for us, but we need to remember that it exists. - * - * Font resources (from libraries or operating systems) render themselves - * to a particular device. Since they do not want to make most programmers - * worry about the font design space, the scaling API is simplified to - * involve just telling the font the required pixel size of the EM square - * (that is, in device space). - * - * - * Cairo's gstate view - * ------------------- - * - * In addition to the CTM and CTM inverse, we keep a matrix in the gstate - * called the "font matrix" which describes the user's most recent - * font-scaling or font-transforming request. This is kept in terms of an - * abstract scale factor, composed with the CTM and used to set the font's - * pixel size. So if the user asks to "scale the font by 12", the matrix - * is: - * - * [ 12.0, 0.0, 0.0, 12.0, 0.0, 0.0 ] - * - * It is an affine matrix, like all cairo matrices, where its tx and ty - * components are used to "nudging" fonts around and are handled in gstate - * and then ignored by the "scaled-font" layer. - * - * In order to perform any action on a font, we must build an object - * called a #cairo_font_scale_t; this contains the central 2x2 matrix - * resulting from "font matrix * CTM" (sans the font matrix translation - * components as stated in the previous paragraph). - * - * We pass this to the font when making requests of it, which causes it to - * reply for a particular [user request, device] combination, under the CTM - * (to accommodate the "zoom in" == "bigger fonts" issue above). - * - * The other terms in our communication with the font are therefore in - * device space. When we ask it to perform text->glyph conversion, it will - * produce a glyph string in device space. Glyph vectors we pass to it for - * measuring or rendering should be in device space. The metrics which we - * get back from the font will be in device space. The contents of the - * global glyph image cache will be in device space. - * - * - * Cairo's public view - * ------------------- - * - * Since the values entering and leaving via public API calls are in user - * space, the gstate functions typically need to multiply arguments by the - * CTM (for user-input glyph vectors), and return values by the CTM inverse - * (for font responses such as metrics or glyph vectors). - * - */ - -static cairo_status_t -_cairo_gstate_ensure_font_face (cairo_gstate_t *gstate) -{ - cairo_font_face_t *font_face; - - if (gstate->font_face != NULL) - return gstate->font_face->status; - - - font_face = cairo_toy_font_face_create (CAIRO_FONT_FAMILY_DEFAULT, - CAIRO_FONT_SLANT_DEFAULT, - CAIRO_FONT_WEIGHT_DEFAULT); - if (font_face->status) - return font_face->status; - - gstate->font_face = font_face; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_gstate_ensure_scaled_font (cairo_gstate_t *gstate) -{ - cairo_status_t status; - cairo_font_options_t options; - cairo_scaled_font_t *scaled_font; - cairo_matrix_t font_ctm; - - if (gstate->scaled_font != NULL) - return gstate->scaled_font->status; - - status = _cairo_gstate_ensure_font_face (gstate); - if (unlikely (status)) - return status; - - cairo_surface_get_font_options (gstate->target, &options); - cairo_font_options_merge (&options, &gstate->font_options); - - cairo_matrix_multiply (&font_ctm, - &gstate->ctm, - &gstate->target->device_transform); - - scaled_font = cairo_scaled_font_create (gstate->font_face, - &gstate->font_matrix, - &font_ctm, - &options); - - status = cairo_scaled_font_status (scaled_font); - if (unlikely (status)) - return status; - - gstate->scaled_font = scaled_font; - - return CAIRO_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_gstate_get_font_extents (cairo_gstate_t *gstate, - cairo_font_extents_t *extents) -{ - cairo_status_t status = _cairo_gstate_ensure_scaled_font (gstate); - if (unlikely (status)) - return status; - - cairo_scaled_font_extents (gstate->scaled_font, extents); - - return cairo_scaled_font_status (gstate->scaled_font); -} - -cairo_status_t -_cairo_gstate_set_font_face (cairo_gstate_t *gstate, - cairo_font_face_t *font_face) -{ - if (font_face && font_face->status) - return _cairo_error (font_face->status); - - if (font_face == gstate->font_face) - return CAIRO_STATUS_SUCCESS; - - cairo_font_face_destroy (gstate->font_face); - gstate->font_face = cairo_font_face_reference (font_face); - - _cairo_gstate_unset_scaled_font (gstate); - - return CAIRO_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_gstate_glyph_extents (cairo_gstate_t *gstate, - const cairo_glyph_t *glyphs, - int num_glyphs, - cairo_text_extents_t *extents) -{ - cairo_status_t status; - - status = _cairo_gstate_ensure_scaled_font (gstate); - if (unlikely (status)) - return status; - - cairo_scaled_font_glyph_extents (gstate->scaled_font, - glyphs, num_glyphs, - extents); - - return cairo_scaled_font_status (gstate->scaled_font); -} - -cairo_status_t -_cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate, - const cairo_glyph_t *glyphs, - int num_glyphs, - cairo_glyph_text_info_t *info) -{ - cairo_glyph_t stack_transformed_glyphs[CAIRO_STACK_ARRAY_LENGTH (cairo_glyph_t)]; - cairo_text_cluster_t stack_transformed_clusters[CAIRO_STACK_ARRAY_LENGTH (cairo_text_cluster_t)]; - cairo_pattern_union_t source_pattern; - cairo_glyph_t *transformed_glyphs; - const cairo_pattern_t *pattern; - cairo_text_cluster_t *transformed_clusters; - cairo_operator_t op; - cairo_status_t status; - - status = _cairo_gstate_get_pattern_status (gstate->source); - if (unlikely (status)) - return status; - - if (gstate->op == CAIRO_OPERATOR_DEST) - return CAIRO_STATUS_SUCCESS; - - if (_cairo_clip_is_all_clipped (gstate->clip)) - return CAIRO_STATUS_SUCCESS; - - status = _cairo_gstate_ensure_scaled_font (gstate); - if (unlikely (status)) - return status; - - transformed_glyphs = stack_transformed_glyphs; - transformed_clusters = stack_transformed_clusters; - - if (num_glyphs > ARRAY_LENGTH (stack_transformed_glyphs)) { - transformed_glyphs = cairo_glyph_allocate (num_glyphs); - if (unlikely (transformed_glyphs == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - if (info != NULL) { - if (info->num_clusters > ARRAY_LENGTH (stack_transformed_clusters)) { - transformed_clusters = cairo_text_cluster_allocate (info->num_clusters); - if (unlikely (transformed_clusters == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto CLEANUP_GLYPHS; - } - } - - _cairo_gstate_transform_glyphs_to_backend (gstate, - glyphs, num_glyphs, - info->clusters, - info->num_clusters, - info->cluster_flags, - transformed_glyphs, - &num_glyphs, - transformed_clusters); - } else { - _cairo_gstate_transform_glyphs_to_backend (gstate, - glyphs, num_glyphs, - NULL, 0, 0, - transformed_glyphs, - &num_glyphs, - NULL); - } - - if (num_glyphs == 0) - goto CLEANUP_GLYPHS; - - op = _reduce_op (gstate); - if (op == CAIRO_OPERATOR_CLEAR) { - pattern = &_cairo_pattern_clear.base; - } else { - _cairo_gstate_copy_transformed_source (gstate, &source_pattern.base); - pattern = &source_pattern.base; - } - - /* For really huge font sizes, we can just do path;fill instead of - * show_glyphs, as show_glyphs would put excess pressure on the cache, - * and moreover, not all components below us correctly handle huge font - * sizes. I wanted to set the limit at 256. But alas, seems like cairo's - * rasterizer is something like ten times slower than freetype's for huge - * sizes. So, no win just yet. For now, do it for insanely-huge sizes, - * just to make sure we don't make anyone unhappy. When we get a really - * fast rasterizer in cairo, we may want to readjust this. - * - * Needless to say, do this only if show_text_glyphs is not available. */ - if (cairo_surface_has_show_text_glyphs (gstate->target) || - _cairo_scaled_font_get_max_scale (gstate->scaled_font) <= 10240) - { - - if (info != NULL) { - status = _cairo_surface_show_text_glyphs (gstate->target, op, pattern, - info->utf8, info->utf8_len, - transformed_glyphs, num_glyphs, - transformed_clusters, info->num_clusters, - info->cluster_flags, - gstate->scaled_font, - gstate->clip); - } else { - status = _cairo_surface_show_text_glyphs (gstate->target, op, pattern, - NULL, 0, - transformed_glyphs, num_glyphs, - NULL, 0, 0, - gstate->scaled_font, - gstate->clip); - } - } - else - { - cairo_path_fixed_t path; - - _cairo_path_fixed_init (&path); - - status = _cairo_scaled_font_glyph_path (gstate->scaled_font, - transformed_glyphs, num_glyphs, - &path); - - if (status == CAIRO_STATUS_SUCCESS) { - status = _cairo_surface_fill (gstate->target, op, pattern, - &path, - CAIRO_FILL_RULE_WINDING, - gstate->tolerance, - gstate->scaled_font->options.antialias, - gstate->clip); - } - - _cairo_path_fixed_fini (&path); - } - -CLEANUP_GLYPHS: - if (transformed_glyphs != stack_transformed_glyphs) - cairo_glyph_free (transformed_glyphs); - if (transformed_clusters != stack_transformed_clusters) - cairo_text_cluster_free (transformed_clusters); - - return status; -} - -cairo_status_t -_cairo_gstate_glyph_path (cairo_gstate_t *gstate, - const cairo_glyph_t *glyphs, - int num_glyphs, - cairo_path_fixed_t *path) -{ - cairo_glyph_t stack_transformed_glyphs[CAIRO_STACK_ARRAY_LENGTH (cairo_glyph_t)]; - cairo_glyph_t *transformed_glyphs; - cairo_status_t status; - - status = _cairo_gstate_ensure_scaled_font (gstate); - if (unlikely (status)) - return status; - - if (num_glyphs < ARRAY_LENGTH (stack_transformed_glyphs)) { - transformed_glyphs = stack_transformed_glyphs; - } else { - transformed_glyphs = cairo_glyph_allocate (num_glyphs); - if (unlikely (transformed_glyphs == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - _cairo_gstate_transform_glyphs_to_backend (gstate, - glyphs, num_glyphs, - NULL, 0, 0, - transformed_glyphs, - &num_glyphs, NULL); - - status = _cairo_scaled_font_glyph_path (gstate->scaled_font, - transformed_glyphs, num_glyphs, - path); - - if (transformed_glyphs != stack_transformed_glyphs) - cairo_glyph_free (transformed_glyphs); - - return status; -} - -cairo_status_t -_cairo_gstate_set_antialias (cairo_gstate_t *gstate, - cairo_antialias_t antialias) -{ - gstate->antialias = antialias; - - return CAIRO_STATUS_SUCCESS; -} - -cairo_antialias_t -_cairo_gstate_get_antialias (cairo_gstate_t *gstate) -{ - return gstate->antialias; -} - -/** - * _cairo_gstate_transform_glyphs_to_backend: - * @gstate: a #cairo_gstate_t - * @glyphs: the array of #cairo_glyph_t objects to be transformed - * @num_glyphs: the number of elements in @glyphs - * @transformed_glyphs: a pre-allocated array of at least @num_glyphs - * #cairo_glyph_t objects - * @num_transformed_glyphs: the number of elements in @transformed_glyphs - * after dropping out of bounds glyphs, or %NULL if glyphs shouldn't be - * dropped - * - * Transform an array of glyphs to backend space by first adding the offset - * of the font matrix, then transforming from user space to backend space. - * The result of the transformation is placed in @transformed_glyphs. - * - * This also uses information from the scaled font and the surface to - * cull/drop glyphs that will not be visible. - **/ -static void -_cairo_gstate_transform_glyphs_to_backend (cairo_gstate_t *gstate, - const cairo_glyph_t *glyphs, - int num_glyphs, - const cairo_text_cluster_t *clusters, - int num_clusters, - cairo_text_cluster_flags_t cluster_flags, - cairo_glyph_t *transformed_glyphs, - int *num_transformed_glyphs, - cairo_text_cluster_t *transformed_clusters) -{ - cairo_rectangle_int_t surface_extents; - cairo_matrix_t *ctm = &gstate->ctm; - cairo_matrix_t *font_matrix = &gstate->font_matrix; - cairo_matrix_t *device_transform = &gstate->target->device_transform; - cairo_bool_t drop = FALSE; - double x1 = 0, x2 = 0, y1 = 0, y2 = 0; - int i, j, k; - - drop = TRUE; - if (! _cairo_gstate_int_clip_extents (gstate, &surface_extents)) { - drop = FALSE; /* unbounded surface */ - } else { - double scale10 = 10 * _cairo_scaled_font_get_max_scale (gstate->scaled_font); - if (surface_extents.width == 0 || surface_extents.height == 0) { - /* No visible area. Don't draw anything */ - *num_transformed_glyphs = 0; - return; - } - /* XXX We currently drop any glyphs that has its position outside - * of the surface boundaries by a safety margin depending on the - * font scale. This however can fail in extreme cases where the - * font has really long swashes for example... We can correctly - * handle that by looking the glyph up and using its device bbox - * to device if it's going to be visible, but I'm not inclined to - * do that now. - */ - x1 = surface_extents.x - scale10; - y1 = surface_extents.y - scale10; - x2 = surface_extents.x + (int) surface_extents.width + scale10; - y2 = surface_extents.y + (int) surface_extents.height + scale10; - } - - if (!drop) - *num_transformed_glyphs = num_glyphs; - -#define KEEP_GLYPH(glyph) (x1 <= glyph.x && glyph.x <= x2 && y1 <= glyph.y && glyph.y <= y2) - - j = 0; - if (_cairo_matrix_is_identity (ctm) && - _cairo_matrix_is_identity (device_transform) && - font_matrix->x0 == 0 && font_matrix->y0 == 0) - { - if (! drop) { - memcpy (transformed_glyphs, glyphs, - num_glyphs * sizeof (cairo_glyph_t)); - memcpy (transformed_clusters, clusters, - num_clusters * sizeof (cairo_text_cluster_t)); - j = num_glyphs; - } else if (num_clusters == 0) { - for (i = 0; i < num_glyphs; i++) { - transformed_glyphs[j].index = glyphs[i].index; - transformed_glyphs[j].x = glyphs[i].x; - transformed_glyphs[j].y = glyphs[i].y; - if (KEEP_GLYPH (transformed_glyphs[j])) - j++; - } - } else { - const cairo_glyph_t *cur_glyph; - - if (cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD) - cur_glyph = glyphs + num_glyphs - 1; - else - cur_glyph = glyphs; - - for (i = 0; i < num_clusters; i++) { - cairo_bool_t cluster_visible = FALSE; - - for (k = 0; k < clusters[i].num_glyphs; k++) { - transformed_glyphs[j+k].index = cur_glyph->index; - transformed_glyphs[j+k].x = cur_glyph->x; - transformed_glyphs[j+k].y = cur_glyph->y; - if (KEEP_GLYPH (transformed_glyphs[j+k])) - cluster_visible = TRUE; - - if (cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD) - cur_glyph--; - else - cur_glyph++; - } - - transformed_clusters[i] = clusters[i]; - if (cluster_visible) - j += k; - else - transformed_clusters[i].num_glyphs = 0; - } - } - } - else if (_cairo_matrix_is_translation (ctm) && - _cairo_matrix_is_translation (device_transform)) - { - double tx = font_matrix->x0 + ctm->x0 + device_transform->x0; - double ty = font_matrix->y0 + ctm->y0 + device_transform->y0; - - if (! drop || num_clusters == 0) { - for (i = 0; i < num_glyphs; i++) { - transformed_glyphs[j].index = glyphs[i].index; - transformed_glyphs[j].x = glyphs[i].x + tx; - transformed_glyphs[j].y = glyphs[i].y + ty; - if (!drop || KEEP_GLYPH (transformed_glyphs[j])) - j++; - } - memcpy (transformed_clusters, clusters, - num_clusters * sizeof (cairo_text_cluster_t)); - } else { - const cairo_glyph_t *cur_glyph; - - if (cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD) - cur_glyph = glyphs + num_glyphs - 1; - else - cur_glyph = glyphs; - - for (i = 0; i < num_clusters; i++) { - cairo_bool_t cluster_visible = FALSE; - - for (k = 0; k < clusters[i].num_glyphs; k++) { - transformed_glyphs[j+k].index = cur_glyph->index; - transformed_glyphs[j+k].x = cur_glyph->x + tx; - transformed_glyphs[j+k].y = cur_glyph->y + ty; - if (KEEP_GLYPH (transformed_glyphs[j+k])) - cluster_visible = TRUE; - - if (cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD) - cur_glyph--; - else - cur_glyph++; - } - - transformed_clusters[i] = clusters[i]; - if (cluster_visible) - j += k; - else - transformed_clusters[i].num_glyphs = 0; - } - } - } - else - { - cairo_matrix_t aggregate_transform; - - cairo_matrix_init_translate (&aggregate_transform, - gstate->font_matrix.x0, - gstate->font_matrix.y0); - cairo_matrix_multiply (&aggregate_transform, - &aggregate_transform, ctm); - cairo_matrix_multiply (&aggregate_transform, - &aggregate_transform, device_transform); - - if (! drop || num_clusters == 0) { - for (i = 0; i < num_glyphs; i++) { - transformed_glyphs[j] = glyphs[i]; - cairo_matrix_transform_point (&aggregate_transform, - &transformed_glyphs[j].x, - &transformed_glyphs[j].y); - if (! drop || KEEP_GLYPH (transformed_glyphs[j])) - j++; - } - memcpy (transformed_clusters, clusters, - num_clusters * sizeof (cairo_text_cluster_t)); - } else { - const cairo_glyph_t *cur_glyph; - - if (cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD) - cur_glyph = glyphs + num_glyphs - 1; - else - cur_glyph = glyphs; - - for (i = 0; i < num_clusters; i++) { - cairo_bool_t cluster_visible = FALSE; - for (k = 0; k < clusters[i].num_glyphs; k++) { - transformed_glyphs[j+k] = *cur_glyph; - cairo_matrix_transform_point (&aggregate_transform, - &transformed_glyphs[j+k].x, - &transformed_glyphs[j+k].y); - if (KEEP_GLYPH (transformed_glyphs[j+k])) - cluster_visible = TRUE; - - if (cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD) - cur_glyph--; - else - cur_glyph++; - } - - transformed_clusters[i] = clusters[i]; - if (cluster_visible) - j += k; - else - transformed_clusters[i].num_glyphs = 0; - } - } - } - *num_transformed_glyphs = j; - - if (num_clusters != 0 && cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD) { - for (i = 0; i < --j; i++) { - cairo_glyph_t tmp; - - tmp = transformed_glyphs[i]; - transformed_glyphs[i] = transformed_glyphs[j]; - transformed_glyphs[j] = tmp; - } - } -} diff --git a/source/libs/cairo/cairo-src/src/cairo-hash-private.h b/source/libs/cairo/cairo-src/src/cairo-hash-private.h deleted file mode 100644 index 30e51ffe669135dc475bfd40e20345fa26792cdd..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-hash-private.h +++ /dev/null @@ -1,87 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2004 Red Hat, Inc. - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Keith Packard <keithp@keithp.com> - * Graydon Hoare <graydon@redhat.com> - * Carl Worth <cworth@cworth.org> - */ - -#ifndef CAIRO_HASH_PRIVATE_H -#define CAIRO_HASH_PRIVATE_H - -#include "cairo-compiler-private.h" -#include "cairo-types-private.h" - -/* XXX: I'd like this file to be self-contained in terms of - * includeability, but that's not really possible with the current - * monolithic cairoint.h. So, for now, just include cairoint.h instead - * if you want to include this file. */ - -typedef cairo_bool_t -(*cairo_hash_keys_equal_func_t) (const void *key_a, const void *key_b); - -typedef cairo_bool_t -(*cairo_hash_predicate_func_t) (const void *entry); - -typedef void -(*cairo_hash_callback_func_t) (void *entry, - void *closure); - -cairo_private cairo_hash_table_t * -_cairo_hash_table_create (cairo_hash_keys_equal_func_t keys_equal); - -cairo_private void -_cairo_hash_table_destroy (cairo_hash_table_t *hash_table); - -cairo_private void * -_cairo_hash_table_lookup (cairo_hash_table_t *hash_table, - cairo_hash_entry_t *key); - -cairo_private void * -_cairo_hash_table_random_entry (cairo_hash_table_t *hash_table, - cairo_hash_predicate_func_t predicate); - -cairo_private cairo_status_t -_cairo_hash_table_insert (cairo_hash_table_t *hash_table, - cairo_hash_entry_t *entry); - -cairo_private void -_cairo_hash_table_remove (cairo_hash_table_t *hash_table, - cairo_hash_entry_t *key); - -cairo_private void -_cairo_hash_table_foreach (cairo_hash_table_t *hash_table, - cairo_hash_callback_func_t hash_callback, - void *closure); - -#endif diff --git a/source/libs/cairo/cairo-src/src/cairo-hash.c b/source/libs/cairo/cairo-src/src/cairo-hash.c deleted file mode 100644 index 928c74b8bd6e04a9c2be9ba869ec5dfe4f265b21..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-hash.c +++ /dev/null @@ -1,578 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2004 Red Hat, Inc. - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Keith Packard <keithp@keithp.com> - * Graydon Hoare <graydon@redhat.com> - * Carl Worth <cworth@cworth.org> - */ - -#include "cairoint.h" -#include "cairo-error-private.h" - -/* - * An entry can be in one of three states: - * - * FREE: Entry has never been used, terminates all searches. - * Appears in the table as a %NULL pointer. - * - * DEAD: Entry had been live in the past. A dead entry can be reused - * but does not terminate a search for an exact entry. - * Appears in the table as a pointer to DEAD_ENTRY. - * - * LIVE: Entry is currently being used. - * Appears in the table as any non-%NULL, non-DEAD_ENTRY pointer. - */ - -#define DEAD_ENTRY ((cairo_hash_entry_t *) 0x1) - -#define ENTRY_IS_FREE(entry) ((entry) == NULL) -#define ENTRY_IS_DEAD(entry) ((entry) == DEAD_ENTRY) -#define ENTRY_IS_LIVE(entry) ((entry) > DEAD_ENTRY) - -/* - * This table is open-addressed with double hashing. Each table size - * is a prime and it makes for the "first" hash modulus; a second - * prime (2 less than the first prime) serves as the "second" hash - * modulus, which is smaller and thus guarantees a complete - * permutation of table indices. - * - * Hash tables are rehashed in order to keep between 12.5% and 50% - * entries in the hash table alive and at least 25% free. When table - * size is changed, the new table has about 25% live elements. - * - * The free entries guarantee an expected constant-time lookup. - * Doubling/halving the table in the described fashion guarantees - * amortized O(1) insertion/removal. - * - * This structure, and accompanying table, is borrowed/modified from the - * file xserver/render/glyph.c in the freedesktop.org x server, with - * permission (and suggested modification of doubling sizes) by Keith - * Packard. - */ - -static const unsigned long hash_table_sizes[] = { - 43, - 73, - 151, - 283, - 571, - 1153, - 2269, - 4519, - 9013, - 18043, - 36109, - 72091, - 144409, - 288361, - 576883, - 1153459, - 2307163, - 4613893, - 9227641, - 18455029, - 36911011, - 73819861, - 147639589, - 295279081, - 590559793 -}; - -struct _cairo_hash_table { - cairo_hash_keys_equal_func_t keys_equal; - - cairo_hash_entry_t *cache[32]; - - const unsigned long *table_size; - cairo_hash_entry_t **entries; - - unsigned long live_entries; - unsigned long free_entries; - unsigned long iterating; /* Iterating, no insert, no resize */ -}; - -/** - * _cairo_hash_table_uid_keys_equal: - * @key_a: the first key to be compared - * @key_b: the second key to be compared - * - * Provides a #cairo_hash_keys_equal_func_t which always returns - * %TRUE. This is useful to create hash tables using keys whose hash - * completely describes the key, because in this special case - * comparing the hashes is sufficient to guarantee that the keys are - * equal. - * - * Return value: %TRUE. - **/ -static cairo_bool_t -_cairo_hash_table_uid_keys_equal (const void *key_a, const void *key_b) -{ - return TRUE; -} - -/** - * _cairo_hash_table_create: - * @keys_equal: a function to return %TRUE if two keys are equal - * - * Creates a new hash table which will use the keys_equal() function - * to compare hash keys. Data is provided to the hash table in the - * form of user-derived versions of #cairo_hash_entry_t. A hash entry - * must be able to hold both a key (including a hash code) and a - * value. Sometimes only the key will be necessary, (as in - * _cairo_hash_table_remove), and other times both a key and a value - * will be necessary, (as in _cairo_hash_table_insert). - * - * If @keys_equal is %NULL, two keys will be considered equal if and - * only if their hashes are equal. - * - * See #cairo_hash_entry_t for more details. - * - * Return value: the new hash table or %NULL if out of memory. - **/ -cairo_hash_table_t * -_cairo_hash_table_create (cairo_hash_keys_equal_func_t keys_equal) -{ - cairo_hash_table_t *hash_table; - - hash_table = malloc (sizeof (cairo_hash_table_t)); - if (unlikely (hash_table == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return NULL; - } - - if (keys_equal == NULL) - hash_table->keys_equal = _cairo_hash_table_uid_keys_equal; - else - hash_table->keys_equal = keys_equal; - - memset (&hash_table->cache, 0, sizeof (hash_table->cache)); - hash_table->table_size = &hash_table_sizes[0]; - - hash_table->entries = calloc (*hash_table->table_size, - sizeof (cairo_hash_entry_t *)); - if (unlikely (hash_table->entries == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - free (hash_table); - return NULL; - } - - hash_table->live_entries = 0; - hash_table->free_entries = *hash_table->table_size; - hash_table->iterating = 0; - - return hash_table; -} - -/** - * _cairo_hash_table_destroy: - * @hash_table: an empty hash table to destroy - * - * Immediately destroys the given hash table, freeing all resources - * associated with it. - * - * WARNING: The hash_table must have no live entries in it before - * _cairo_hash_table_destroy is called. It is a fatal error otherwise, - * and this function will halt. The rationale for this behavior is to - * avoid memory leaks and to avoid needless complication of the API - * with destroy notifiy callbacks. - * - * WARNING: The hash_table must have no running iterators in it when - * _cairo_hash_table_destroy is called. It is a fatal error otherwise, - * and this function will halt. - **/ -void -_cairo_hash_table_destroy (cairo_hash_table_t *hash_table) -{ - /* The hash table must be empty. Otherwise, halt. */ - assert (hash_table->live_entries == 0); - /* No iterators can be running. Otherwise, halt. */ - assert (hash_table->iterating == 0); - - free (hash_table->entries); - free (hash_table); -} - -static cairo_hash_entry_t ** -_cairo_hash_table_lookup_unique_key (cairo_hash_table_t *hash_table, - cairo_hash_entry_t *key) -{ - unsigned long table_size, i, idx, step; - cairo_hash_entry_t **entry; - - table_size = *hash_table->table_size; - idx = key->hash % table_size; - - entry = &hash_table->entries[idx]; - if (! ENTRY_IS_LIVE (*entry)) - return entry; - - i = 1; - step = 1 + key->hash % (table_size - 2); - do { - idx += step; - if (idx >= table_size) - idx -= table_size; - - entry = &hash_table->entries[idx]; - if (! ENTRY_IS_LIVE (*entry)) - return entry; - } while (++i < table_size); - - ASSERT_NOT_REACHED; - return NULL; -} - -/** - * _cairo_hash_table_manage: - * @hash_table: a hash table - * - * Resize the hash table if the number of entries has gotten much - * bigger or smaller than the ideal number of entries for the current - * size and guarantee some free entries to be used as lookup - * termination points. - * - * Return value: %CAIRO_STATUS_SUCCESS if successful or - * %CAIRO_STATUS_NO_MEMORY if out of memory. - **/ -static cairo_status_t -_cairo_hash_table_manage (cairo_hash_table_t *hash_table) -{ - cairo_hash_table_t tmp; - unsigned long new_size, i; - - /* Keep between 12.5% and 50% entries in the hash table alive and - * at least 25% free. */ - unsigned long live_high = *hash_table->table_size >> 1; - unsigned long live_low = live_high >> 2; - unsigned long free_low = live_high >> 1; - - tmp = *hash_table; - - if (hash_table->live_entries > live_high) - { - tmp.table_size = hash_table->table_size + 1; - /* This code is being abused if we can't make a table big enough. */ - assert (tmp.table_size - hash_table_sizes < - ARRAY_LENGTH (hash_table_sizes)); - } - else if (hash_table->live_entries < live_low) - { - /* Can't shrink if we're at the smallest size */ - if (hash_table->table_size == &hash_table_sizes[0]) - tmp.table_size = hash_table->table_size; - else - tmp.table_size = hash_table->table_size - 1; - } - - if (tmp.table_size == hash_table->table_size && - hash_table->free_entries > free_low) - { - /* The number of live entries is within the desired bounds - * (we're not going to resize the table) and we have enough - * free entries. Do nothing. */ - return CAIRO_STATUS_SUCCESS; - } - - new_size = *tmp.table_size; - tmp.entries = calloc (new_size, sizeof (cairo_hash_entry_t*)); - if (unlikely (tmp.entries == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - for (i = 0; i < *hash_table->table_size; ++i) { - if (ENTRY_IS_LIVE (hash_table->entries[i])) { - *_cairo_hash_table_lookup_unique_key (&tmp, hash_table->entries[i]) - = hash_table->entries[i]; - } - } - - free (hash_table->entries); - hash_table->entries = tmp.entries; - hash_table->table_size = tmp.table_size; - hash_table->free_entries = new_size - hash_table->live_entries; - - return CAIRO_STATUS_SUCCESS; -} - -/** - * _cairo_hash_table_lookup: - * @hash_table: a hash table - * @key: the key of interest - * - * Performs a lookup in @hash_table looking for an entry which has a - * key that matches @key, (as determined by the keys_equal() function - * passed to _cairo_hash_table_create). - * - * Return value: the matching entry, of %NULL if no match was found. - **/ -void * -_cairo_hash_table_lookup (cairo_hash_table_t *hash_table, - cairo_hash_entry_t *key) -{ - cairo_hash_entry_t *entry; - unsigned long table_size, i, idx, step; - unsigned long hash = key->hash; - - entry = hash_table->cache[hash & 31]; - if (entry && entry->hash == hash && hash_table->keys_equal (key, entry)) - return entry; - - table_size = *hash_table->table_size; - idx = hash % table_size; - - entry = hash_table->entries[idx]; - if (ENTRY_IS_LIVE (entry)) { - if (entry->hash == hash && hash_table->keys_equal (key, entry)) - goto insert_cache; - } else if (ENTRY_IS_FREE (entry)) - return NULL; - - i = 1; - step = 1 + hash % (table_size - 2); - do { - idx += step; - if (idx >= table_size) - idx -= table_size; - - entry = hash_table->entries[idx]; - if (ENTRY_IS_LIVE (entry)) { - if (entry->hash == hash && hash_table->keys_equal (key, entry)) - goto insert_cache; - } else if (ENTRY_IS_FREE (entry)) - return NULL; - } while (++i < table_size); - - ASSERT_NOT_REACHED; - return NULL; - -insert_cache: - hash_table->cache[hash & 31] = entry; - return entry; -} - -/** - * _cairo_hash_table_random_entry: - * @hash_table: a hash table - * @predicate: a predicate function. - * - * Find a random entry in the hash table satisfying the given - * @predicate. - * - * We use the same algorithm as the lookup algorithm to walk over the - * entries in the hash table in a pseudo-random order. Walking - * linearly would favor entries following gaps in the hash table. We - * could also call rand() repeatedly, which works well for almost-full - * tables, but degrades when the table is almost empty, or predicate - * returns %TRUE for most entries. - * - * Return value: a random live entry or %NULL if there are no entries - * that match the given predicate. In particular, if predicate is - * %NULL, a %NULL return value indicates that the table is empty. - **/ -void * -_cairo_hash_table_random_entry (cairo_hash_table_t *hash_table, - cairo_hash_predicate_func_t predicate) -{ - cairo_hash_entry_t *entry; - unsigned long hash; - unsigned long table_size, i, idx, step; - - assert (predicate != NULL); - - table_size = *hash_table->table_size; - hash = rand (); - idx = hash % table_size; - - entry = hash_table->entries[idx]; - if (ENTRY_IS_LIVE (entry) && predicate (entry)) - return entry; - - i = 1; - step = 1 + hash % (table_size - 2); - do { - idx += step; - if (idx >= table_size) - idx -= table_size; - - entry = hash_table->entries[idx]; - if (ENTRY_IS_LIVE (entry) && predicate (entry)) - return entry; - } while (++i < table_size); - - return NULL; -} - -/** - * _cairo_hash_table_insert: - * @hash_table: a hash table - * @key_and_value: an entry to be inserted - * - * Insert the entry #key_and_value into the hash table. - * - * WARNING: There must not be an existing entry in the hash table - * with a matching key. - * - * WARNING: It is a fatal error to insert an element while - * an iterator is running - * - * Instead of using insert to replace an entry, consider just editing - * the entry obtained with _cairo_hash_table_lookup. Or if absolutely - * necessary, use _cairo_hash_table_remove first. - * - * Return value: %CAIRO_STATUS_SUCCESS if successful or - * %CAIRO_STATUS_NO_MEMORY if insufficient memory is available. - **/ -cairo_status_t -_cairo_hash_table_insert (cairo_hash_table_t *hash_table, - cairo_hash_entry_t *key_and_value) -{ - cairo_hash_entry_t **entry; - cairo_status_t status; - - /* Insert is illegal while an iterator is running. */ - assert (hash_table->iterating == 0); - - status = _cairo_hash_table_manage (hash_table); - if (unlikely (status)) - return status; - - entry = _cairo_hash_table_lookup_unique_key (hash_table, key_and_value); - - if (ENTRY_IS_FREE (*entry)) - hash_table->free_entries--; - - *entry = key_and_value; - hash_table->cache[key_and_value->hash & 31] = key_and_value; - hash_table->live_entries++; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_hash_entry_t ** -_cairo_hash_table_lookup_exact_key (cairo_hash_table_t *hash_table, - cairo_hash_entry_t *key) -{ - unsigned long table_size, i, idx, step; - cairo_hash_entry_t **entry; - - table_size = *hash_table->table_size; - idx = key->hash % table_size; - - entry = &hash_table->entries[idx]; - if (*entry == key) - return entry; - - i = 1; - step = 1 + key->hash % (table_size - 2); - do { - idx += step; - if (idx >= table_size) - idx -= table_size; - - entry = &hash_table->entries[idx]; - if (*entry == key) - return entry; - } while (++i < table_size); - - ASSERT_NOT_REACHED; - return NULL; -} -/** - * _cairo_hash_table_remove: - * @hash_table: a hash table - * @key: key of entry to be removed - * - * Remove an entry from the hash table which points to @key. - * - * Return value: %CAIRO_STATUS_SUCCESS if successful or - * %CAIRO_STATUS_NO_MEMORY if out of memory. - **/ -void -_cairo_hash_table_remove (cairo_hash_table_t *hash_table, - cairo_hash_entry_t *key) -{ - *_cairo_hash_table_lookup_exact_key (hash_table, key) = DEAD_ENTRY; - hash_table->live_entries--; - hash_table->cache[key->hash & 31] = NULL; - - /* Check for table resize. Don't do this when iterating as this will - * reorder elements of the table and cause the iteration to potentially - * skip some elements. */ - if (hash_table->iterating == 0) { - /* This call _can_ fail, but only in failing to allocate new - * memory to shrink the hash table. It does leave the table in a - * consistent state, and we've already succeeded in removing the - * entry, so we don't examine the failure status of this call. */ - _cairo_hash_table_manage (hash_table); - } -} - -/** - * _cairo_hash_table_foreach: - * @hash_table: a hash table - * @hash_callback: function to be called for each live entry - * @closure: additional argument to be passed to @hash_callback - * - * Call @hash_callback for each live entry in the hash table, in a - * non-specified order. - * - * Entries in @hash_table may be removed by code executed from @hash_callback. - * - * Entries may not be inserted to @hash_table, nor may @hash_table - * be destroyed by code executed from @hash_callback. The relevant - * functions will halt in these cases. - **/ -void -_cairo_hash_table_foreach (cairo_hash_table_t *hash_table, - cairo_hash_callback_func_t hash_callback, - void *closure) -{ - unsigned long i; - cairo_hash_entry_t *entry; - - /* Mark the table for iteration */ - ++hash_table->iterating; - for (i = 0; i < *hash_table->table_size; i++) { - entry = hash_table->entries[i]; - if (ENTRY_IS_LIVE(entry)) - hash_callback (entry, closure); - } - /* If some elements were deleted during the iteration, - * the table may need resizing. Just do this every time - * as the check is inexpensive. - */ - if (--hash_table->iterating == 0) { - /* Should we fail to shrink the hash table, it is left unaltered, - * and we don't need to propagate the error status. */ - _cairo_hash_table_manage (hash_table); - } -} diff --git a/source/libs/cairo/cairo-src/src/cairo-hull.c b/source/libs/cairo/cairo-src/src/cairo-hull.c deleted file mode 100644 index c65593327f6714e7c5103a9663a22d7a72bf28c9..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-hull.c +++ /dev/null @@ -1,235 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2003 University of Southern California - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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" - -#include "cairo-error-private.h" -#include "cairo-slope-private.h" - -typedef struct cairo_hull { - cairo_point_t point; - cairo_slope_t slope; - int discard; - int id; -} cairo_hull_t; - -static void -_cairo_hull_init (cairo_hull_t *hull, - cairo_pen_vertex_t *vertices, - int num_vertices) -{ - cairo_point_t *p, *extremum, tmp; - int i; - - extremum = &vertices[0].point; - for (i = 1; i < num_vertices; i++) { - p = &vertices[i].point; - if (p->y < extremum->y || (p->y == extremum->y && p->x < extremum->x)) - extremum = p; - } - /* Put the extremal point at the beginning of the array */ - tmp = *extremum; - *extremum = vertices[0].point; - vertices[0].point = tmp; - - for (i = 0; i < num_vertices; i++) { - hull[i].point = vertices[i].point; - _cairo_slope_init (&hull[i].slope, &hull[0].point, &hull[i].point); - - /* give each point a unique id for later comparison */ - hull[i].id = i; - - /* Don't discard by default */ - hull[i].discard = 0; - - /* Discard all points coincident with the extremal point */ - if (i != 0 && hull[i].slope.dx == 0 && hull[i].slope.dy == 0) - hull[i].discard = 1; - } -} - -static inline cairo_int64_t -_slope_length (cairo_slope_t *slope) -{ - return _cairo_int64_add (_cairo_int32x32_64_mul (slope->dx, slope->dx), - _cairo_int32x32_64_mul (slope->dy, slope->dy)); -} - -static int -_cairo_hull_vertex_compare (const void *av, const void *bv) -{ - cairo_hull_t *a = (cairo_hull_t *) av; - cairo_hull_t *b = (cairo_hull_t *) bv; - int ret; - - /* Some libraries are reported to actually compare identical - * pointers and require the result to be 0. This is the crazy world we - * have to live in. - */ - if (a == b) - return 0; - - ret = _cairo_slope_compare (&a->slope, &b->slope); - - /* - * In the case of two vertices with identical slope from the - * extremal point discard the nearer point. - */ - if (ret == 0) { - int cmp; - - cmp = _cairo_int64_cmp (_slope_length (&a->slope), - _slope_length (&b->slope)); - - /* - * Use the points' ids to ensure a well-defined ordering, - * and avoid setting discard on both points. - */ - if (cmp < 0 || (cmp == 0 && a->id < b->id)) { - a->discard = 1; - ret = -1; - } else { - b->discard = 1; - ret = 1; - } - } - - return ret; -} - -static int -_cairo_hull_prev_valid (cairo_hull_t *hull, int num_hull, int index) -{ - /* hull[0] is always valid, and we never need to wraparound, (if - * we are passed an index of 0 here, then the calling loop is just - * about to terminate). */ - if (index == 0) - return 0; - - do { - index--; - } while (hull[index].discard); - - return index; -} - -static int -_cairo_hull_next_valid (cairo_hull_t *hull, int num_hull, int index) -{ - do { - index = (index + 1) % num_hull; - } while (hull[index].discard); - - return index; -} - -static void -_cairo_hull_eliminate_concave (cairo_hull_t *hull, int num_hull) -{ - int i, j, k; - cairo_slope_t slope_ij, slope_jk; - - i = 0; - j = _cairo_hull_next_valid (hull, num_hull, i); - k = _cairo_hull_next_valid (hull, num_hull, j); - - do { - _cairo_slope_init (&slope_ij, &hull[i].point, &hull[j].point); - _cairo_slope_init (&slope_jk, &hull[j].point, &hull[k].point); - - /* Is the angle formed by ij and jk concave? */ - if (_cairo_slope_compare (&slope_ij, &slope_jk) >= 0) { - if (i == k) - return; - hull[j].discard = 1; - j = i; - i = _cairo_hull_prev_valid (hull, num_hull, j); - } else { - i = j; - j = k; - k = _cairo_hull_next_valid (hull, num_hull, j); - } - } while (j != 0); -} - -static void -_cairo_hull_to_pen (cairo_hull_t *hull, cairo_pen_vertex_t *vertices, int *num_vertices) -{ - int i, j = 0; - - for (i = 0; i < *num_vertices; i++) { - if (hull[i].discard) - continue; - vertices[j++].point = hull[i].point; - } - - *num_vertices = j; -} - -/* Given a set of vertices, compute the convex hull using the Graham - scan algorithm. */ -cairo_status_t -_cairo_hull_compute (cairo_pen_vertex_t *vertices, int *num_vertices) -{ - cairo_hull_t hull_stack[CAIRO_STACK_ARRAY_LENGTH (cairo_hull_t)]; - cairo_hull_t *hull; - int num_hull = *num_vertices; - - if (CAIRO_INJECT_FAULT ()) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - if (num_hull > ARRAY_LENGTH (hull_stack)) { - hull = _cairo_malloc_ab (num_hull, sizeof (cairo_hull_t)); - if (unlikely (hull == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } else { - hull = hull_stack; - } - - _cairo_hull_init (hull, vertices, num_hull); - - qsort (hull + 1, num_hull - 1, - sizeof (cairo_hull_t), _cairo_hull_vertex_compare); - - _cairo_hull_eliminate_concave (hull, num_hull); - - _cairo_hull_to_pen (hull, vertices, num_vertices); - - if (hull != hull_stack) - free (hull); - - return CAIRO_STATUS_SUCCESS; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-image-compositor.c b/source/libs/cairo/cairo-src/src/cairo-image-compositor.c deleted file mode 100644 index 48072f81bd0cb96033d54cb8e0e40002f877b446..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-image-compositor.c +++ /dev/null @@ -1,3137 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2003 University of Southern California - * Copyright © 2009,2010,2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -/* The primarily reason for keeping a traps-compositor around is - * for validating cairo-xlib (which currently also uses traps). - */ - -#include "cairoint.h" - -#include "cairo-image-surface-private.h" - -#include "cairo-compositor-private.h" -#include "cairo-spans-compositor-private.h" - -#include "cairo-region-private.h" -#include "cairo-traps-private.h" -#include "cairo-tristrip-private.h" - -#include "cairo-pixman-private.h" - -static pixman_image_t * -to_pixman_image (cairo_surface_t *s) -{ - return ((cairo_image_surface_t *)s)->pixman_image; -} - -static cairo_int_status_t -acquire (void *abstract_dst) -{ - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -release (void *abstract_dst) -{ - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -set_clip_region (void *_surface, - cairo_region_t *region) -{ - cairo_image_surface_t *surface = _surface; - pixman_region32_t *rgn = region ? ®ion->rgn : NULL; - - if (! pixman_image_set_clip_region32 (surface->pixman_image, rgn)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -draw_image_boxes (void *_dst, - cairo_image_surface_t *image, - cairo_boxes_t *boxes, - int dx, int dy) -{ - cairo_image_surface_t *dst = _dst; - struct _cairo_boxes_chunk *chunk; - int i; - - TRACE ((stderr, "%s x %d\n", __FUNCTION__, boxes->num_boxes)); - - for (chunk = &boxes->chunks; chunk; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) { - cairo_box_t *b = &chunk->base[i]; - int x = _cairo_fixed_integer_part (b->p1.x); - int y = _cairo_fixed_integer_part (b->p1.y); - int w = _cairo_fixed_integer_part (b->p2.x) - x; - int h = _cairo_fixed_integer_part (b->p2.y) - y; - if (dst->pixman_format != image->pixman_format || - ! pixman_blt ((uint32_t *)image->data, (uint32_t *)dst->data, - image->stride / sizeof (uint32_t), - dst->stride / sizeof (uint32_t), - PIXMAN_FORMAT_BPP (image->pixman_format), - PIXMAN_FORMAT_BPP (dst->pixman_format), - x + dx, y + dy, - x, y, - w, h)) - { - pixman_image_composite32 (PIXMAN_OP_SRC, - image->pixman_image, NULL, dst->pixman_image, - x + dx, y + dy, - 0, 0, - x, y, - w, h); - } - } - } - return CAIRO_STATUS_SUCCESS; -} - -static inline uint32_t -color_to_uint32 (const cairo_color_t *color) -{ - return - (color->alpha_short >> 8 << 24) | - (color->red_short >> 8 << 16) | - (color->green_short & 0xff00) | - (color->blue_short >> 8); -} - -static inline cairo_bool_t -color_to_pixel (const cairo_color_t *color, - pixman_format_code_t format, - uint32_t *pixel) -{ - uint32_t c; - - if (!(format == PIXMAN_a8r8g8b8 || - format == PIXMAN_x8r8g8b8 || - format == PIXMAN_a8b8g8r8 || - format == PIXMAN_x8b8g8r8 || - format == PIXMAN_b8g8r8a8 || - format == PIXMAN_b8g8r8x8 || - format == PIXMAN_r5g6b5 || - format == PIXMAN_b5g6r5 || - format == PIXMAN_a8)) - { - return FALSE; - } - - c = color_to_uint32 (color); - - if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR) { - c = ((c & 0xff000000) >> 0) | - ((c & 0x00ff0000) >> 16) | - ((c & 0x0000ff00) >> 0) | - ((c & 0x000000ff) << 16); - } - - if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA) { - c = ((c & 0xff000000) >> 24) | - ((c & 0x00ff0000) >> 8) | - ((c & 0x0000ff00) << 8) | - ((c & 0x000000ff) << 24); - } - - if (format == PIXMAN_a8) { - c = c >> 24; - } else if (format == PIXMAN_r5g6b5 || format == PIXMAN_b5g6r5) { - c = ((((c) >> 3) & 0x001f) | - (((c) >> 5) & 0x07e0) | - (((c) >> 8) & 0xf800)); - } - - *pixel = c; - return TRUE; -} - -static pixman_op_t -_pixman_operator (cairo_operator_t op) -{ - switch ((int) op) { - case CAIRO_OPERATOR_CLEAR: - return PIXMAN_OP_CLEAR; - - case CAIRO_OPERATOR_SOURCE: - return PIXMAN_OP_SRC; - case CAIRO_OPERATOR_OVER: - return PIXMAN_OP_OVER; - case CAIRO_OPERATOR_IN: - return PIXMAN_OP_IN; - case CAIRO_OPERATOR_OUT: - return PIXMAN_OP_OUT; - case CAIRO_OPERATOR_ATOP: - return PIXMAN_OP_ATOP; - - case CAIRO_OPERATOR_DEST: - return PIXMAN_OP_DST; - case CAIRO_OPERATOR_DEST_OVER: - return PIXMAN_OP_OVER_REVERSE; - case CAIRO_OPERATOR_DEST_IN: - return PIXMAN_OP_IN_REVERSE; - case CAIRO_OPERATOR_DEST_OUT: - return PIXMAN_OP_OUT_REVERSE; - case CAIRO_OPERATOR_DEST_ATOP: - return PIXMAN_OP_ATOP_REVERSE; - - case CAIRO_OPERATOR_XOR: - return PIXMAN_OP_XOR; - case CAIRO_OPERATOR_ADD: - return PIXMAN_OP_ADD; - case CAIRO_OPERATOR_SATURATE: - return PIXMAN_OP_SATURATE; - - case CAIRO_OPERATOR_MULTIPLY: - return PIXMAN_OP_MULTIPLY; - case CAIRO_OPERATOR_SCREEN: - return PIXMAN_OP_SCREEN; - case CAIRO_OPERATOR_OVERLAY: - return PIXMAN_OP_OVERLAY; - case CAIRO_OPERATOR_DARKEN: - return PIXMAN_OP_DARKEN; - case CAIRO_OPERATOR_LIGHTEN: - return PIXMAN_OP_LIGHTEN; - case CAIRO_OPERATOR_COLOR_DODGE: - return PIXMAN_OP_COLOR_DODGE; - case CAIRO_OPERATOR_COLOR_BURN: - return PIXMAN_OP_COLOR_BURN; - case CAIRO_OPERATOR_HARD_LIGHT: - return PIXMAN_OP_HARD_LIGHT; - case CAIRO_OPERATOR_SOFT_LIGHT: - return PIXMAN_OP_SOFT_LIGHT; - case CAIRO_OPERATOR_DIFFERENCE: - return PIXMAN_OP_DIFFERENCE; - case CAIRO_OPERATOR_EXCLUSION: - return PIXMAN_OP_EXCLUSION; - case CAIRO_OPERATOR_HSL_HUE: - return PIXMAN_OP_HSL_HUE; - case CAIRO_OPERATOR_HSL_SATURATION: - return PIXMAN_OP_HSL_SATURATION; - case CAIRO_OPERATOR_HSL_COLOR: - return PIXMAN_OP_HSL_COLOR; - case CAIRO_OPERATOR_HSL_LUMINOSITY: - return PIXMAN_OP_HSL_LUMINOSITY; - - default: - ASSERT_NOT_REACHED; - return PIXMAN_OP_OVER; - } -} - -static cairo_bool_t -__fill_reduces_to_source (cairo_operator_t op, - const cairo_color_t *color, - const cairo_image_surface_t *dst) -{ - if (op == CAIRO_OPERATOR_SOURCE || op == CAIRO_OPERATOR_CLEAR) - return TRUE; - if (op == CAIRO_OPERATOR_OVER && CAIRO_COLOR_IS_OPAQUE (color)) - return TRUE; - if (dst->base.is_clear) - return op == CAIRO_OPERATOR_OVER || op == CAIRO_OPERATOR_ADD; - - return FALSE; -} - -static cairo_bool_t -fill_reduces_to_source (cairo_operator_t op, - const cairo_color_t *color, - const cairo_image_surface_t *dst, - uint32_t *pixel) -{ - if (__fill_reduces_to_source (op, color, dst)) { - return color_to_pixel (color, dst->pixman_format, pixel); - } - - return FALSE; -} - -static cairo_int_status_t -fill_rectangles (void *_dst, - cairo_operator_t op, - const cairo_color_t *color, - cairo_rectangle_int_t *rects, - int num_rects) -{ - cairo_image_surface_t *dst = _dst; - uint32_t pixel; - int i; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - if (fill_reduces_to_source (op, color, dst, &pixel)) { - for (i = 0; i < num_rects; i++) { - pixman_fill ((uint32_t *) dst->data, dst->stride / sizeof (uint32_t), - PIXMAN_FORMAT_BPP (dst->pixman_format), - rects[i].x, rects[i].y, - rects[i].width, rects[i].height, - pixel); - } - } else { - pixman_image_t *src = _pixman_image_for_color (color); - if (unlikely (src == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - op = _pixman_operator (op); - for (i = 0; i < num_rects; i++) { - pixman_image_composite32 (op, - src, NULL, dst->pixman_image, - 0, 0, - 0, 0, - rects[i].x, rects[i].y, - rects[i].width, rects[i].height); - } - - pixman_image_unref (src); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -fill_boxes (void *_dst, - cairo_operator_t op, - const cairo_color_t *color, - cairo_boxes_t *boxes) -{ - cairo_image_surface_t *dst = _dst; - struct _cairo_boxes_chunk *chunk; - uint32_t pixel; - int i; - - TRACE ((stderr, "%s x %d\n", __FUNCTION__, boxes->num_boxes)); - - if (fill_reduces_to_source (op, color, dst, &pixel)) { - for (chunk = &boxes->chunks; chunk; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) { - int x = _cairo_fixed_integer_part (chunk->base[i].p1.x); - int y = _cairo_fixed_integer_part (chunk->base[i].p1.y); - int w = _cairo_fixed_integer_part (chunk->base[i].p2.x) - x; - int h = _cairo_fixed_integer_part (chunk->base[i].p2.y) - y; - pixman_fill ((uint32_t *) dst->data, - dst->stride / sizeof (uint32_t), - PIXMAN_FORMAT_BPP (dst->pixman_format), - x, y, w, h, pixel); - } - } - } - else - { - pixman_image_t *src = _pixman_image_for_color (color); - if (unlikely (src == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - op = _pixman_operator (op); - for (chunk = &boxes->chunks; chunk; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) { - int x1 = _cairo_fixed_integer_part (chunk->base[i].p1.x); - int y1 = _cairo_fixed_integer_part (chunk->base[i].p1.y); - int x2 = _cairo_fixed_integer_part (chunk->base[i].p2.x); - int y2 = _cairo_fixed_integer_part (chunk->base[i].p2.y); - pixman_image_composite32 (op, - src, NULL, dst->pixman_image, - 0, 0, - 0, 0, - x1, y1, - x2-x1, y2-y1); - } - } - - pixman_image_unref (src); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -composite (void *_dst, - cairo_operator_t op, - cairo_surface_t *abstract_src, - cairo_surface_t *abstract_mask, - 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_image_source_t *src = (cairo_image_source_t *)abstract_src; - cairo_image_source_t *mask = (cairo_image_source_t *)abstract_mask; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - if (mask) { - pixman_image_composite32 (_pixman_operator (op), - src->pixman_image, mask->pixman_image, to_pixman_image (_dst), - src_x, src_y, - mask_x, mask_y, - dst_x, dst_y, - width, height); - } else { - pixman_image_composite32 (_pixman_operator (op), - src->pixman_image, NULL, to_pixman_image (_dst), - src_x, src_y, - 0, 0, - dst_x, dst_y, - width, height); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -lerp (void *_dst, - cairo_surface_t *abstract_src, - cairo_surface_t *abstract_mask, - 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_image_surface_t *dst = _dst; - cairo_image_source_t *src = (cairo_image_source_t *)abstract_src; - cairo_image_source_t *mask = (cairo_image_source_t *)abstract_mask; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - -#if PIXMAN_HAS_OP_LERP - pixman_image_composite32 (PIXMAN_OP_LERP_SRC, - src->pixman_image, mask->pixman_image, dst->pixman_image, - src_x, src_y, - mask_x, mask_y, - dst_x, dst_y, - width, height); -#else - /* Punch the clip out of the destination */ - TRACE ((stderr, "%s - OUT_REVERSE (mask=%d/%p, dst=%d/%p)\n", - __FUNCTION__, - mask->base.unique_id, mask->pixman_image, - dst->base.unique_id, dst->pixman_image)); - pixman_image_composite32 (PIXMAN_OP_OUT_REVERSE, - mask->pixman_image, NULL, dst->pixman_image, - mask_x, mask_y, - 0, 0, - dst_x, dst_y, - width, height); - - /* Now add the two results together */ - TRACE ((stderr, "%s - ADD (src=%d/%p, mask=%d/%p, dst=%d/%p)\n", - __FUNCTION__, - src->base.unique_id, src->pixman_image, - mask->base.unique_id, mask->pixman_image, - dst->base.unique_id, dst->pixman_image)); - pixman_image_composite32 (PIXMAN_OP_ADD, - src->pixman_image, mask->pixman_image, dst->pixman_image, - src_x, src_y, - mask_x, mask_y, - dst_x, dst_y, - width, height); -#endif - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -composite_boxes (void *_dst, - cairo_operator_t op, - cairo_surface_t *abstract_src, - cairo_surface_t *abstract_mask, - int src_x, - int src_y, - int mask_x, - int mask_y, - int dst_x, - int dst_y, - cairo_boxes_t *boxes, - const cairo_rectangle_int_t *extents) -{ - pixman_image_t *dst = to_pixman_image (_dst); - pixman_image_t *src = ((cairo_image_source_t *)abstract_src)->pixman_image; - pixman_image_t *mask = abstract_mask ? ((cairo_image_source_t *)abstract_mask)->pixman_image : NULL; - pixman_image_t *free_src = NULL; - struct _cairo_boxes_chunk *chunk; - int i; - - /* XXX consider using a region? saves multiple prepare-composite */ - TRACE ((stderr, "%s x %d\n", __FUNCTION__, boxes->num_boxes)); - - if (((cairo_surface_t *)_dst)->is_clear && - (op == CAIRO_OPERATOR_SOURCE || - op == CAIRO_OPERATOR_OVER || - op == CAIRO_OPERATOR_ADD)) { - op = PIXMAN_OP_SRC; - } else if (mask) { - if (op == CAIRO_OPERATOR_CLEAR) { -#if PIXMAN_HAS_OP_LERP - op = PIXMAN_OP_LERP_CLEAR; -#else - free_src = src = _pixman_image_for_color (CAIRO_COLOR_WHITE); - if (unlikely (src == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - op = PIXMAN_OP_OUT_REVERSE; -#endif - } else if (op == CAIRO_OPERATOR_SOURCE) { -#if PIXMAN_HAS_OP_LERP - op = PIXMAN_OP_LERP_SRC; -#else - return CAIRO_INT_STATUS_UNSUPPORTED; -#endif - } else { - op = _pixman_operator (op); - } - } else { - op = _pixman_operator (op); - } - - for (chunk = &boxes->chunks; chunk; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) { - int x1 = _cairo_fixed_integer_part (chunk->base[i].p1.x); - int y1 = _cairo_fixed_integer_part (chunk->base[i].p1.y); - int x2 = _cairo_fixed_integer_part (chunk->base[i].p2.x); - int y2 = _cairo_fixed_integer_part (chunk->base[i].p2.y); - - pixman_image_composite32 (op, src, mask, dst, - x1 + src_x, y1 + src_y, - x1 + mask_x, y1 + mask_y, - x1 + dst_x, y1 + dst_y, - x2 - x1, y2 - y1); - } - } - - if (free_src) - pixman_image_unref (free_src); - - return CAIRO_STATUS_SUCCESS; -} - -#define CAIRO_FIXED_16_16_MIN _cairo_fixed_from_int (-32768) -#define CAIRO_FIXED_16_16_MAX _cairo_fixed_from_int (32767) - -static cairo_bool_t -line_exceeds_16_16 (const cairo_line_t *line) -{ - return - line->p1.x <= CAIRO_FIXED_16_16_MIN || - line->p1.x >= CAIRO_FIXED_16_16_MAX || - - line->p2.x <= CAIRO_FIXED_16_16_MIN || - line->p2.x >= CAIRO_FIXED_16_16_MAX || - - line->p1.y <= CAIRO_FIXED_16_16_MIN || - line->p1.y >= CAIRO_FIXED_16_16_MAX || - - line->p2.y <= CAIRO_FIXED_16_16_MIN || - line->p2.y >= CAIRO_FIXED_16_16_MAX; -} - -static void -project_line_x_onto_16_16 (const cairo_line_t *line, - cairo_fixed_t top, - cairo_fixed_t bottom, - pixman_line_fixed_t *out) -{ - /* XXX use fixed-point arithmetic? */ - cairo_point_double_t p1, p2; - double m; - - p1.x = _cairo_fixed_to_double (line->p1.x); - p1.y = _cairo_fixed_to_double (line->p1.y); - - p2.x = _cairo_fixed_to_double (line->p2.x); - p2.y = _cairo_fixed_to_double (line->p2.y); - - m = (p2.x - p1.x) / (p2.y - p1.y); - out->p1.x = _cairo_fixed_16_16_from_double (p1.x + m * _cairo_fixed_to_double (top - line->p1.y)); - out->p2.x = _cairo_fixed_16_16_from_double (p1.x + m * _cairo_fixed_to_double (bottom - line->p1.y)); -} - -void -_pixman_image_add_traps (pixman_image_t *image, - int dst_x, int dst_y, - cairo_traps_t *traps) -{ - cairo_trapezoid_t *t = traps->traps; - int num_traps = traps->num_traps; - while (num_traps--) { - pixman_trapezoid_t trap; - - /* top/bottom will be clamped to surface bounds */ - trap.top = _cairo_fixed_to_16_16 (t->top); - trap.bottom = _cairo_fixed_to_16_16 (t->bottom); - - /* However, all the other coordinates will have been left untouched so - * as not to introduce numerical error. Recompute them if they - * exceed the 16.16 limits. - */ - if (unlikely (line_exceeds_16_16 (&t->left))) { - project_line_x_onto_16_16 (&t->left, t->top, t->bottom, &trap.left); - trap.left.p1.y = trap.top; - trap.left.p2.y = trap.bottom; - } else { - trap.left.p1.x = _cairo_fixed_to_16_16 (t->left.p1.x); - trap.left.p1.y = _cairo_fixed_to_16_16 (t->left.p1.y); - trap.left.p2.x = _cairo_fixed_to_16_16 (t->left.p2.x); - trap.left.p2.y = _cairo_fixed_to_16_16 (t->left.p2.y); - } - - if (unlikely (line_exceeds_16_16 (&t->right))) { - project_line_x_onto_16_16 (&t->right, t->top, t->bottom, &trap.right); - trap.right.p1.y = trap.top; - trap.right.p2.y = trap.bottom; - } else { - trap.right.p1.x = _cairo_fixed_to_16_16 (t->right.p1.x); - trap.right.p1.y = _cairo_fixed_to_16_16 (t->right.p1.y); - trap.right.p2.x = _cairo_fixed_to_16_16 (t->right.p2.x); - trap.right.p2.y = _cairo_fixed_to_16_16 (t->right.p2.y); - } - - pixman_rasterize_trapezoid (image, &trap, -dst_x, -dst_y); - t++; - } -} - -static cairo_int_status_t -composite_traps (void *_dst, - cairo_operator_t op, - cairo_surface_t *abstract_src, - int src_x, - int src_y, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents, - cairo_antialias_t antialias, - cairo_traps_t *traps) -{ - cairo_image_surface_t *dst = (cairo_image_surface_t *) _dst; - cairo_image_source_t *src = (cairo_image_source_t *) abstract_src; - cairo_int_status_t status; - pixman_image_t *mask; - pixman_format_code_t format; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - /* pixman doesn't eliminate self-intersecting trapezoids/edges */ - status = _cairo_bentley_ottmann_tessellate_traps (traps, - CAIRO_FILL_RULE_WINDING); - if (status != CAIRO_INT_STATUS_SUCCESS) - return status; - - /* Special case adding trapezoids onto a mask surface; we want to avoid - * creating an intermediate temporary mask unnecessarily. - * - * We make the assumption here that the portion of the trapezoids - * contained within the surface is bounded by [dst_x,dst_y,width,height]; - * the Cairo core code passes bounds based on the trapezoid extents. - */ - format = antialias == CAIRO_ANTIALIAS_NONE ? PIXMAN_a1 : PIXMAN_a8; - if (dst->pixman_format == format && - (abstract_src == NULL || - (op == CAIRO_OPERATOR_ADD && src->is_opaque_solid))) - { - _pixman_image_add_traps (dst->pixman_image, dst_x, dst_y, traps); - return CAIRO_STATUS_SUCCESS; - } - - mask = pixman_image_create_bits (format, - extents->width, extents->height, - NULL, 0); - if (unlikely (mask == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _pixman_image_add_traps (mask, extents->x, extents->y, traps); - pixman_image_composite32 (_pixman_operator (op), - src->pixman_image, mask, dst->pixman_image, - extents->x + src_x, extents->y + src_y, - 0, 0, - extents->x - dst_x, extents->y - dst_y, - extents->width, extents->height); - - pixman_image_unref (mask); - - return CAIRO_STATUS_SUCCESS; -} - -#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,22,0) -static void -set_point (pixman_point_fixed_t *p, cairo_point_t *c) -{ - p->x = _cairo_fixed_to_16_16 (c->x); - p->y = _cairo_fixed_to_16_16 (c->y); -} - -void -_pixman_image_add_tristrip (pixman_image_t *image, - int dst_x, int dst_y, - cairo_tristrip_t *strip) -{ - pixman_triangle_t tri; - pixman_point_fixed_t *p[3] = {&tri.p1, &tri.p2, &tri.p3 }; - int n; - - set_point (p[0], &strip->points[0]); - set_point (p[1], &strip->points[1]); - set_point (p[2], &strip->points[2]); - pixman_add_triangles (image, -dst_x, -dst_y, 1, &tri); - for (n = 3; n < strip->num_points; n++) { - set_point (p[n%3], &strip->points[n]); - pixman_add_triangles (image, -dst_x, -dst_y, 1, &tri); - } -} - -static cairo_int_status_t -composite_tristrip (void *_dst, - cairo_operator_t op, - cairo_surface_t *abstract_src, - int src_x, - int src_y, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents, - cairo_antialias_t antialias, - cairo_tristrip_t *strip) -{ - cairo_image_surface_t *dst = (cairo_image_surface_t *) _dst; - cairo_image_source_t *src = (cairo_image_source_t *) abstract_src; - pixman_image_t *mask; - pixman_format_code_t format; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - if (strip->num_points < 3) - return CAIRO_STATUS_SUCCESS; - - if (1) { /* pixman doesn't eliminate self-intersecting triangles/edges */ - cairo_int_status_t status; - cairo_traps_t traps; - int n; - - _cairo_traps_init (&traps); - for (n = 0; n < strip->num_points; n++) { - cairo_point_t p[4]; - - p[0] = strip->points[0]; - p[1] = strip->points[1]; - p[2] = strip->points[2]; - p[3] = strip->points[0]; - - _cairo_traps_tessellate_convex_quad (&traps, p); - } - status = composite_traps (_dst, op, abstract_src, - src_x, src_y, - dst_x, dst_y, - extents, antialias, &traps); - _cairo_traps_fini (&traps); - - return status; - } - - format = antialias == CAIRO_ANTIALIAS_NONE ? PIXMAN_a1 : PIXMAN_a8; - if (dst->pixman_format == format && - (abstract_src == NULL || - (op == CAIRO_OPERATOR_ADD && src->is_opaque_solid))) - { - _pixman_image_add_tristrip (dst->pixman_image, dst_x, dst_y, strip); - return CAIRO_STATUS_SUCCESS; - } - - mask = pixman_image_create_bits (format, - extents->width, extents->height, - NULL, 0); - if (unlikely (mask == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _pixman_image_add_tristrip (mask, extents->x, extents->y, strip); - pixman_image_composite32 (_pixman_operator (op), - src->pixman_image, mask, dst->pixman_image, - extents->x + src_x, extents->y + src_y, - 0, 0, - extents->x - dst_x, extents->y - dst_y, - extents->width, extents->height); - - pixman_image_unref (mask); - - return CAIRO_STATUS_SUCCESS; -} -#endif - -static cairo_int_status_t -check_composite_glyphs (const cairo_composite_rectangles_t *extents, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int *num_glyphs) -{ - return CAIRO_STATUS_SUCCESS; -} - -#if HAS_PIXMAN_GLYPHS -static pixman_glyph_cache_t *global_glyph_cache; - -static inline pixman_glyph_cache_t * -get_glyph_cache (void) -{ - if (!global_glyph_cache) - global_glyph_cache = pixman_glyph_cache_create (); - - return global_glyph_cache; -} - -void -_cairo_image_scaled_glyph_fini (cairo_scaled_font_t *scaled_font, - cairo_scaled_glyph_t *scaled_glyph) -{ - CAIRO_MUTEX_LOCK (_cairo_glyph_cache_mutex); - - if (global_glyph_cache) { - pixman_glyph_cache_remove ( - global_glyph_cache, scaled_font, - (void *)_cairo_scaled_glyph_index (scaled_glyph)); - } - - CAIRO_MUTEX_UNLOCK (_cairo_glyph_cache_mutex); -} - -static cairo_int_status_t -composite_glyphs (void *_dst, - cairo_operator_t op, - cairo_surface_t *_src, - int src_x, - int src_y, - int dst_x, - int dst_y, - cairo_composite_glyphs_info_t *info) -{ - cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS; - pixman_glyph_cache_t *glyph_cache; - pixman_glyph_t pglyphs_stack[CAIRO_STACK_ARRAY_LENGTH (pixman_glyph_t)]; - pixman_glyph_t *pglyphs = pglyphs_stack; - pixman_glyph_t *pg; - int i; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - CAIRO_MUTEX_LOCK (_cairo_glyph_cache_mutex); - - glyph_cache = get_glyph_cache(); - if (unlikely (glyph_cache == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto out_unlock; - } - - pixman_glyph_cache_freeze (glyph_cache); - - if (info->num_glyphs > ARRAY_LENGTH (pglyphs_stack)) { - pglyphs = _cairo_malloc_ab (info->num_glyphs, sizeof (pixman_glyph_t)); - if (unlikely (pglyphs == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto out_thaw; - } - } - - pg = pglyphs; - for (i = 0; i < info->num_glyphs; i++) { - unsigned long index = info->glyphs[i].index; - const void *glyph; - - glyph = pixman_glyph_cache_lookup (glyph_cache, info->font, (void *)index); - if (!glyph) { - cairo_scaled_glyph_t *scaled_glyph; - cairo_image_surface_t *glyph_surface; - - /* This call can actually end up recursing, so we have to - * drop the mutex around it. - */ - CAIRO_MUTEX_UNLOCK (_cairo_glyph_cache_mutex); - status = _cairo_scaled_glyph_lookup (info->font, index, - CAIRO_SCALED_GLYPH_INFO_SURFACE, - &scaled_glyph); - CAIRO_MUTEX_LOCK (_cairo_glyph_cache_mutex); - - if (unlikely (status)) - goto out_thaw; - - glyph_surface = scaled_glyph->surface; - glyph = pixman_glyph_cache_insert (glyph_cache, info->font, (void *)index, - glyph_surface->base.device_transform.x0, - glyph_surface->base.device_transform.y0, - glyph_surface->pixman_image); - if (unlikely (!glyph)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto out_thaw; - } - } - - pg->x = _cairo_lround (info->glyphs[i].x); - pg->y = _cairo_lround (info->glyphs[i].y); - pg->glyph = glyph; - pg++; - } - - if (info->use_mask) { - pixman_format_code_t mask_format; - - mask_format = pixman_glyph_get_mask_format (glyph_cache, pg - pglyphs, pglyphs); - - pixman_composite_glyphs (_pixman_operator (op), - ((cairo_image_source_t *)_src)->pixman_image, - to_pixman_image (_dst), - mask_format, - info->extents.x + src_x, info->extents.y + src_y, - info->extents.x, info->extents.y, - info->extents.x - dst_x, info->extents.y - dst_y, - info->extents.width, info->extents.height, - glyph_cache, pg - pglyphs, pglyphs); - } else { - pixman_composite_glyphs_no_mask (_pixman_operator (op), - ((cairo_image_source_t *)_src)->pixman_image, - to_pixman_image (_dst), - src_x, src_y, - - dst_x, - dst_y, - glyph_cache, pg - pglyphs, pglyphs); - } - -out_thaw: - pixman_glyph_cache_thaw (glyph_cache); - - if (pglyphs != pglyphs_stack) - free(pglyphs); - -out_unlock: - CAIRO_MUTEX_UNLOCK (_cairo_glyph_cache_mutex); - return status; -} -#else -void -_cairo_image_scaled_glyph_fini (cairo_scaled_font_t *scaled_font, - cairo_scaled_glyph_t *scaled_glyph) -{ -} - -static cairo_int_status_t -composite_one_glyph (void *_dst, - cairo_operator_t op, - cairo_surface_t *_src, - int src_x, - int src_y, - int dst_x, - int dst_y, - cairo_composite_glyphs_info_t *info) -{ - cairo_image_surface_t *glyph_surface; - cairo_scaled_glyph_t *scaled_glyph; - cairo_status_t status; - int x, y; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - status = _cairo_scaled_glyph_lookup (info->font, - info->glyphs[0].index, - CAIRO_SCALED_GLYPH_INFO_SURFACE, - &scaled_glyph); - - if (unlikely (status)) - return status; - - glyph_surface = scaled_glyph->surface; - if (glyph_surface->width == 0 || glyph_surface->height == 0) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - /* round glyph locations to the nearest pixel */ - /* XXX: FRAGILE: We're ignoring device_transform scaling here. A bug? */ - x = _cairo_lround (info->glyphs[0].x - - glyph_surface->base.device_transform.x0); - y = _cairo_lround (info->glyphs[0].y - - glyph_surface->base.device_transform.y0); - - pixman_image_composite32 (_pixman_operator (op), - ((cairo_image_source_t *)_src)->pixman_image, - glyph_surface->pixman_image, - to_pixman_image (_dst), - x + src_x, y + src_y, - 0, 0, - x - dst_x, y - dst_y, - glyph_surface->width, - glyph_surface->height); - - return CAIRO_INT_STATUS_SUCCESS; -} - -static cairo_int_status_t -composite_glyphs_via_mask (void *_dst, - cairo_operator_t op, - cairo_surface_t *_src, - int src_x, - int src_y, - int dst_x, - int dst_y, - cairo_composite_glyphs_info_t *info) -{ - cairo_scaled_glyph_t *glyph_cache[64]; - pixman_image_t *white = _pixman_image_for_color (CAIRO_COLOR_WHITE); - cairo_scaled_glyph_t *scaled_glyph; - uint8_t buf[2048]; - pixman_image_t *mask; - pixman_format_code_t format; - cairo_status_t status; - int i; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - if (unlikely (white == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - /* XXX convert the glyphs to common formats a8/a8r8g8b8 to hit - * optimised paths through pixman. Should we increase the bit - * depth of the target surface, we should reconsider the appropriate - * mask formats. - */ - - status = _cairo_scaled_glyph_lookup (info->font, - info->glyphs[0].index, - CAIRO_SCALED_GLYPH_INFO_SURFACE, - &scaled_glyph); - if (unlikely (status)) { - pixman_image_unref (white); - return status; - } - - memset (glyph_cache, 0, sizeof (glyph_cache)); - glyph_cache[info->glyphs[0].index % ARRAY_LENGTH (glyph_cache)] = scaled_glyph; - - format = PIXMAN_a8; - i = (info->extents.width + 3) & ~3; - if (scaled_glyph->surface->base.content & CAIRO_CONTENT_COLOR) { - format = PIXMAN_a8r8g8b8; - i = info->extents.width * 4; - } - - if (i * info->extents.height > (int) sizeof (buf)) { - mask = pixman_image_create_bits (format, - info->extents.width, - info->extents.height, - NULL, 0); - } else { - memset (buf, 0, i * info->extents.height); - mask = pixman_image_create_bits (format, - info->extents.width, - info->extents.height, - (uint32_t *)buf, i); - } - if (unlikely (mask == NULL)) { - pixman_image_unref (white); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - status = CAIRO_STATUS_SUCCESS; - for (i = 0; i < info->num_glyphs; i++) { - unsigned long glyph_index = info->glyphs[i].index; - int cache_index = glyph_index % ARRAY_LENGTH (glyph_cache); - cairo_image_surface_t *glyph_surface; - int x, y; - - scaled_glyph = glyph_cache[cache_index]; - if (scaled_glyph == NULL || - _cairo_scaled_glyph_index (scaled_glyph) != glyph_index) - { - status = _cairo_scaled_glyph_lookup (info->font, glyph_index, - CAIRO_SCALED_GLYPH_INFO_SURFACE, - &scaled_glyph); - - if (unlikely (status)) { - pixman_image_unref (mask); - pixman_image_unref (white); - return status; - } - - glyph_cache[cache_index] = scaled_glyph; - } - - glyph_surface = scaled_glyph->surface; - if (glyph_surface->width && glyph_surface->height) { - if (glyph_surface->base.content & CAIRO_CONTENT_COLOR && - format == PIXMAN_a8) { - pixman_image_t *ca_mask; - - format = PIXMAN_a8r8g8b8; - ca_mask = pixman_image_create_bits (format, - info->extents.width, - info->extents.height, - NULL, 0); - if (unlikely (ca_mask == NULL)) { - pixman_image_unref (mask); - pixman_image_unref (white); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - pixman_image_composite32 (PIXMAN_OP_SRC, - white, mask, ca_mask, - 0, 0, - 0, 0, - 0, 0, - info->extents.width, - info->extents.height); - pixman_image_unref (mask); - mask = ca_mask; - } - - /* round glyph locations to the nearest pixel */ - /* XXX: FRAGILE: We're ignoring device_transform scaling here. A bug? */ - x = _cairo_lround (info->glyphs[i].x - - glyph_surface->base.device_transform.x0); - y = _cairo_lround (info->glyphs[i].y - - glyph_surface->base.device_transform.y0); - - if (glyph_surface->pixman_format == format) { - pixman_image_composite32 (PIXMAN_OP_ADD, - glyph_surface->pixman_image, NULL, mask, - 0, 0, - 0, 0, - x - info->extents.x, y - info->extents.y, - glyph_surface->width, - glyph_surface->height); - } else { - pixman_image_composite32 (PIXMAN_OP_ADD, - white, glyph_surface->pixman_image, mask, - 0, 0, - 0, 0, - x - info->extents.x, y - info->extents.y, - glyph_surface->width, - glyph_surface->height); - } - } - } - - if (format == PIXMAN_a8r8g8b8) - pixman_image_set_component_alpha (mask, TRUE); - - pixman_image_composite32 (_pixman_operator (op), - ((cairo_image_source_t *)_src)->pixman_image, - mask, - to_pixman_image (_dst), - info->extents.x + src_x, info->extents.y + src_y, - 0, 0, - info->extents.x - dst_x, info->extents.y - dst_y, - info->extents.width, info->extents.height); - pixman_image_unref (mask); - pixman_image_unref (white); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -composite_glyphs (void *_dst, - cairo_operator_t op, - cairo_surface_t *_src, - int src_x, - int src_y, - int dst_x, - int dst_y, - cairo_composite_glyphs_info_t *info) -{ - cairo_scaled_glyph_t *glyph_cache[64]; - pixman_image_t *dst, *src; - cairo_status_t status; - int i; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - if (info->num_glyphs == 1) - return composite_one_glyph(_dst, op, _src, src_x, src_y, dst_x, dst_y, info); - - if (info->use_mask) - return composite_glyphs_via_mask(_dst, op, _src, src_x, src_y, dst_x, dst_y, info); - - op = _pixman_operator (op); - dst = to_pixman_image (_dst); - src = ((cairo_image_source_t *)_src)->pixman_image; - - memset (glyph_cache, 0, sizeof (glyph_cache)); - status = CAIRO_STATUS_SUCCESS; - - for (i = 0; i < info->num_glyphs; i++) { - int x, y; - cairo_image_surface_t *glyph_surface; - cairo_scaled_glyph_t *scaled_glyph; - unsigned long glyph_index = info->glyphs[i].index; - int cache_index = glyph_index % ARRAY_LENGTH (glyph_cache); - - scaled_glyph = glyph_cache[cache_index]; - if (scaled_glyph == NULL || - _cairo_scaled_glyph_index (scaled_glyph) != glyph_index) - { - status = _cairo_scaled_glyph_lookup (info->font, glyph_index, - CAIRO_SCALED_GLYPH_INFO_SURFACE, - &scaled_glyph); - - if (unlikely (status)) - break; - - glyph_cache[cache_index] = scaled_glyph; - } - - glyph_surface = scaled_glyph->surface; - if (glyph_surface->width && glyph_surface->height) { - /* round glyph locations to the nearest pixel */ - /* XXX: FRAGILE: We're ignoring device_transform scaling here. A bug? */ - x = _cairo_lround (info->glyphs[i].x - - glyph_surface->base.device_transform.x0); - y = _cairo_lround (info->glyphs[i].y - - glyph_surface->base.device_transform.y0); - - pixman_image_composite32 (op, src, glyph_surface->pixman_image, dst, - x + src_x, y + src_y, - 0, 0, - x - dst_x, y - dst_y, - glyph_surface->width, - glyph_surface->height); - } - } - - return status; -} -#endif - -static cairo_int_status_t -check_composite (const cairo_composite_rectangles_t *extents) -{ - return CAIRO_STATUS_SUCCESS; -} - -const cairo_compositor_t * -_cairo_image_traps_compositor_get (void) -{ - static cairo_traps_compositor_t compositor; - - if (compositor.base.delegate == NULL) { - _cairo_traps_compositor_init (&compositor, - &__cairo_no_compositor); - compositor.acquire = acquire; - compositor.release = release; - compositor.set_clip_region = set_clip_region; - compositor.pattern_to_surface = _cairo_image_source_create_for_pattern; - compositor.draw_image_boxes = draw_image_boxes; - //compositor.copy_boxes = copy_boxes; - compositor.fill_boxes = fill_boxes; - compositor.check_composite = check_composite; - compositor.composite = composite; - compositor.lerp = lerp; - //compositor.check_composite_boxes = check_composite_boxes; - compositor.composite_boxes = composite_boxes; - //compositor.check_composite_traps = check_composite_traps; - compositor.composite_traps = composite_traps; - //compositor.check_composite_tristrip = check_composite_traps; -#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,22,0) - compositor.composite_tristrip = composite_tristrip; -#endif - compositor.check_composite_glyphs = check_composite_glyphs; - compositor.composite_glyphs = composite_glyphs; - } - - return &compositor.base; -} - -const cairo_compositor_t * -_cairo_image_mask_compositor_get (void) -{ - static cairo_mask_compositor_t compositor; - - if (compositor.base.delegate == NULL) { - _cairo_mask_compositor_init (&compositor, - _cairo_image_traps_compositor_get ()); - compositor.acquire = acquire; - compositor.release = release; - compositor.set_clip_region = set_clip_region; - compositor.pattern_to_surface = _cairo_image_source_create_for_pattern; - compositor.draw_image_boxes = draw_image_boxes; - compositor.fill_rectangles = fill_rectangles; - compositor.fill_boxes = fill_boxes; - compositor.check_composite = check_composite; - compositor.composite = composite; - //compositor.lerp = lerp; - //compositor.check_composite_boxes = check_composite_boxes; - compositor.composite_boxes = composite_boxes; - compositor.check_composite_glyphs = check_composite_glyphs; - compositor.composite_glyphs = composite_glyphs; - } - - return &compositor.base; -} - -#if PIXMAN_HAS_COMPOSITOR -typedef struct _cairo_image_span_renderer { - cairo_span_renderer_t base; - - pixman_image_compositor_t *compositor; - pixman_image_t *src, *mask; - float opacity; - cairo_rectangle_int_t extents; -} cairo_image_span_renderer_t; -COMPILE_TIME_ASSERT (sizeof (cairo_image_span_renderer_t) <= sizeof (cairo_abstract_span_renderer_t)); - -static cairo_status_t -_cairo_image_bounded_opaque_spans (void *abstract_renderer, - int y, int height, - const cairo_half_open_span_t *spans, - unsigned num_spans) -{ - cairo_image_span_renderer_t *r = abstract_renderer; - - if (num_spans == 0) - return CAIRO_STATUS_SUCCESS; - - do { - if (spans[0].coverage) - pixman_image_compositor_blt (r->compositor, - spans[0].x, y, - spans[1].x - spans[0].x, height, - spans[0].coverage); - spans++; - } while (--num_spans > 1); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_image_bounded_spans (void *abstract_renderer, - int y, int height, - const cairo_half_open_span_t *spans, - unsigned num_spans) -{ - cairo_image_span_renderer_t *r = abstract_renderer; - - if (num_spans == 0) - return CAIRO_STATUS_SUCCESS; - - do { - if (spans[0].coverage) { - pixman_image_compositor_blt (r->compositor, - spans[0].x, y, - spans[1].x - spans[0].x, height, - r->opacity * spans[0].coverage); - } - spans++; - } while (--num_spans > 1); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_image_unbounded_spans (void *abstract_renderer, - int y, int height, - const cairo_half_open_span_t *spans, - unsigned num_spans) -{ - cairo_image_span_renderer_t *r = abstract_renderer; - - assert (y + height <= r->extents.height); - if (y > r->extents.y) { - pixman_image_compositor_blt (r->compositor, - r->extents.x, r->extents.y, - r->extents.width, y - r->extents.y, - 0); - } - - if (num_spans == 0) { - pixman_image_compositor_blt (r->compositor, - r->extents.x, y, - r->extents.width, height, - 0); - } else { - if (spans[0].x != r->extents.x) { - pixman_image_compositor_blt (r->compositor, - r->extents.x, y, - spans[0].x - r->extents.x, - height, - 0); - } - - do { - assert (spans[0].x < r->extents.x + r->extents.width); - pixman_image_compositor_blt (r->compositor, - spans[0].x, y, - spans[1].x - spans[0].x, height, - r->opacity * spans[0].coverage); - spans++; - } while (--num_spans > 1); - - if (spans[0].x != r->extents.x + r->extents.width) { - assert (spans[0].x < r->extents.x + r->extents.width); - pixman_image_compositor_blt (r->compositor, - spans[0].x, y, - r->extents.x + r->extents.width - spans[0].x, height, - 0); - } - } - - r->extents.y = y + height; - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_image_clipped_spans (void *abstract_renderer, - int y, int height, - const cairo_half_open_span_t *spans, - unsigned num_spans) -{ - cairo_image_span_renderer_t *r = abstract_renderer; - - assert (num_spans); - - do { - if (! spans[0].inverse) - pixman_image_compositor_blt (r->compositor, - spans[0].x, y, - spans[1].x - spans[0].x, height, - r->opacity * spans[0].coverage); - spans++; - } while (--num_spans > 1); - - r->extents.y = y + height; - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_image_finish_unbounded_spans (void *abstract_renderer) -{ - cairo_image_span_renderer_t *r = abstract_renderer; - - if (r->extents.y < r->extents.height) { - pixman_image_compositor_blt (r->compositor, - r->extents.x, r->extents.y, - r->extents.width, - r->extents.height - r->extents.y, - 0); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -span_renderer_init (cairo_abstract_span_renderer_t *_r, - const cairo_composite_rectangles_t *composite, - cairo_bool_t needs_clip) -{ - cairo_image_span_renderer_t *r = (cairo_image_span_renderer_t *)_r; - cairo_image_surface_t *dst = (cairo_image_surface_t *)composite->surface; - const cairo_pattern_t *source = &composite->source_pattern.base; - cairo_operator_t op = composite->op; - int src_x, src_y; - int mask_x, mask_y; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - if (op == CAIRO_OPERATOR_CLEAR) { - op = PIXMAN_OP_LERP_CLEAR; - } else if (dst->base.is_clear && - (op == CAIRO_OPERATOR_SOURCE || - op == CAIRO_OPERATOR_OVER || - op == CAIRO_OPERATOR_ADD)) { - op = PIXMAN_OP_SRC; - } else if (op == CAIRO_OPERATOR_SOURCE) { - op = PIXMAN_OP_LERP_SRC; - } else { - op = _pixman_operator (op); - } - - r->compositor = NULL; - r->mask = NULL; - r->src = _pixman_image_for_pattern (dst, source, FALSE, - &composite->unbounded, - &composite->source_sample_area, - &src_x, &src_y); - if (unlikely (r->src == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - r->opacity = 1.0; - if (composite->mask_pattern.base.type == CAIRO_PATTERN_TYPE_SOLID) { - r->opacity = composite->mask_pattern.solid.color.alpha; - } else { - r->mask = _pixman_image_for_pattern (dst, - &composite->mask_pattern.base, - TRUE, - &composite->unbounded, - &composite->mask_sample_area, - &mask_x, &mask_y); - if (unlikely (r->mask == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - /* XXX Component-alpha? */ - if ((dst->base.content & CAIRO_CONTENT_COLOR) == 0 && - _cairo_pattern_is_opaque (source, &composite->source_sample_area)) - { - pixman_image_unref (r->src); - r->src = r->mask; - src_x = mask_x; - src_y = mask_y; - r->mask = NULL; - } - } - - if (composite->is_bounded) { - if (r->opacity == 1.) - r->base.render_rows = _cairo_image_bounded_opaque_spans; - else - r->base.render_rows = _cairo_image_bounded_spans; - r->base.finish = NULL; - } else { - if (needs_clip) - r->base.render_rows = _cairo_image_clipped_spans; - else - r->base.render_rows = _cairo_image_unbounded_spans; - r->base.finish = _cairo_image_finish_unbounded_spans; - r->extents = composite->unbounded; - r->extents.height += r->extents.y; - } - - r->compositor = - pixman_image_create_compositor (op, r->src, r->mask, dst->pixman_image, - composite->unbounded.x + src_x, - composite->unbounded.y + src_y, - composite->unbounded.x + mask_x, - composite->unbounded.y + mask_y, - composite->unbounded.x, - composite->unbounded.y, - composite->unbounded.width, - composite->unbounded.height); - if (unlikely (r->compositor == NULL)) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - return CAIRO_STATUS_SUCCESS; -} - -static void -span_renderer_fini (cairo_abstract_span_renderer_t *_r, - cairo_int_status_t status) -{ - cairo_image_span_renderer_t *r = (cairo_image_span_renderer_t *) _r; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - if (status == CAIRO_INT_STATUS_SUCCESS && r->base.finish) - r->base.finish (r); - - if (r->compositor) - pixman_image_compositor_destroy (r->compositor); - - if (r->src) - pixman_image_unref (r->src); - if (r->mask) - pixman_image_unref (r->mask); -} -#else -typedef struct _cairo_image_span_renderer { - cairo_span_renderer_t base; - - const cairo_composite_rectangles_t *composite; - - float opacity; - uint8_t op; - int bpp; - - pixman_image_t *src, *mask; - union { - struct fill { - int stride; - uint8_t *data; - uint32_t pixel; - } fill; - struct blit { - int stride; - uint8_t *data; - int src_stride; - uint8_t *src_data; - } blit; - struct composite { - pixman_image_t *dst; - int src_x, src_y; - int mask_x, mask_y; - int run_length; - } composite; - struct finish { - cairo_rectangle_int_t extents; - int src_x, src_y; - int stride; - uint8_t *data; - } mask; - } u; - uint8_t _buf[0]; -#define SZ_BUF (int)(sizeof (cairo_abstract_span_renderer_t) - sizeof (cairo_image_span_renderer_t)) -} cairo_image_span_renderer_t; -COMPILE_TIME_ASSERT (sizeof (cairo_image_span_renderer_t) <= sizeof (cairo_abstract_span_renderer_t)); - -static cairo_status_t -_cairo_image_spans (void *abstract_renderer, - int y, int height, - const cairo_half_open_span_t *spans, - unsigned num_spans) -{ - cairo_image_span_renderer_t *r = abstract_renderer; - uint8_t *mask, *row; - int len; - - if (num_spans == 0) - return CAIRO_STATUS_SUCCESS; - - mask = r->u.mask.data + (y - r->u.mask.extents.y) * r->u.mask.stride; - mask += spans[0].x - r->u.mask.extents.x; - row = mask; - - do { - len = spans[1].x - spans[0].x; - if (spans[0].coverage) { - *row++ = r->opacity * spans[0].coverage; - if (--len) - memset (row, row[-1], len); - } - row += len; - spans++; - } while (--num_spans > 1); - - len = row - mask; - row = mask; - while (--height) { - mask += r->u.mask.stride; - memcpy (mask, row, len); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_image_spans_and_zero (void *abstract_renderer, - int y, int height, - const cairo_half_open_span_t *spans, - unsigned num_spans) -{ - cairo_image_span_renderer_t *r = abstract_renderer; - uint8_t *mask; - int len; - - mask = r->u.mask.data; - if (y > r->u.mask.extents.y) { - len = (y - r->u.mask.extents.y) * r->u.mask.stride; - memset (mask, 0, len); - mask += len; - } - - r->u.mask.extents.y = y + height; - r->u.mask.data = mask + height * r->u.mask.stride; - if (num_spans == 0) { - memset (mask, 0, height * r->u.mask.stride); - } else { - uint8_t *row = mask; - - if (spans[0].x != r->u.mask.extents.x) { - len = spans[0].x - r->u.mask.extents.x; - memset (row, 0, len); - row += len; - } - - do { - len = spans[1].x - spans[0].x; - *row++ = r->opacity * spans[0].coverage; - if (len > 1) { - memset (row, row[-1], --len); - row += len; - } - spans++; - } while (--num_spans > 1); - - if (spans[0].x != r->u.mask.extents.x + r->u.mask.extents.width) { - len = r->u.mask.extents.x + r->u.mask.extents.width - spans[0].x; - memset (row, 0, len); - } - - row = mask; - while (--height) { - mask += r->u.mask.stride; - memcpy (mask, row, r->u.mask.extents.width); - } - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_image_finish_spans_and_zero (void *abstract_renderer) -{ - cairo_image_span_renderer_t *r = abstract_renderer; - - if (r->u.mask.extents.y < r->u.mask.extents.height) - memset (r->u.mask.data, 0, (r->u.mask.extents.height - r->u.mask.extents.y) * r->u.mask.stride); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_fill8_spans (void *abstract_renderer, int y, int h, - const cairo_half_open_span_t *spans, unsigned num_spans) -{ - cairo_image_span_renderer_t *r = abstract_renderer; - - if (num_spans == 0) - return CAIRO_STATUS_SUCCESS; - - if (likely(h == 1)) { - do { - if (spans[0].coverage) { - int len = spans[1].x - spans[0].x; - uint8_t *d = r->u.fill.data + r->u.fill.stride*y + spans[0].x; - if (len == 1) - *d = r->u.fill.pixel; - else - memset(d, r->u.fill.pixel, len); - } - spans++; - } while (--num_spans > 1); - } else { - do { - if (spans[0].coverage) { - int yy = y, hh = h; - do { - int len = spans[1].x - spans[0].x; - uint8_t *d = r->u.fill.data + r->u.fill.stride*yy + spans[0].x; - if (len == 1) - *d = r->u.fill.pixel; - else - memset(d, r->u.fill.pixel, len); - yy++; - } while (--hh); - } - spans++; - } while (--num_spans > 1); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_fill16_spans (void *abstract_renderer, int y, int h, - const cairo_half_open_span_t *spans, unsigned num_spans) -{ - cairo_image_span_renderer_t *r = abstract_renderer; - - if (num_spans == 0) - return CAIRO_STATUS_SUCCESS; - - if (likely(h == 1)) { - do { - if (spans[0].coverage) { - int len = spans[1].x - spans[0].x; - uint16_t *d = (uint16_t*)(r->u.fill.data + r->u.fill.stride*y + spans[0].x*2); - while (len--) - *d++ = r->u.fill.pixel; - } - spans++; - } while (--num_spans > 1); - } else { - do { - if (spans[0].coverage) { - int yy = y, hh = h; - do { - int len = spans[1].x - spans[0].x; - uint16_t *d = (uint16_t*)(r->u.fill.data + r->u.fill.stride*yy + spans[0].x*2); - while (len--) - *d++ = r->u.fill.pixel; - yy++; - } while (--hh); - } - spans++; - } while (--num_spans > 1); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_fill32_spans (void *abstract_renderer, int y, int h, - const cairo_half_open_span_t *spans, unsigned num_spans) -{ - cairo_image_span_renderer_t *r = abstract_renderer; - - if (num_spans == 0) - return CAIRO_STATUS_SUCCESS; - - if (likely(h == 1)) { - do { - if (spans[0].coverage) { - int len = spans[1].x - spans[0].x; - if (len > 32) { - pixman_fill ((uint32_t *)r->u.fill.data, r->u.fill.stride / sizeof(uint32_t), r->bpp, - spans[0].x, y, len, 1, r->u.fill.pixel); - } else { - uint32_t *d = (uint32_t*)(r->u.fill.data + r->u.fill.stride*y + spans[0].x*4); - while (len--) - *d++ = r->u.fill.pixel; - } - } - spans++; - } while (--num_spans > 1); - } else { - do { - if (spans[0].coverage) { - if (spans[1].x - spans[0].x > 16) { - pixman_fill ((uint32_t *)r->u.fill.data, r->u.fill.stride / sizeof(uint32_t), r->bpp, - spans[0].x, y, spans[1].x - spans[0].x, h, - r->u.fill.pixel); - } else { - int yy = y, hh = h; - do { - int len = spans[1].x - spans[0].x; - uint32_t *d = (uint32_t*)(r->u.fill.data + r->u.fill.stride*yy + spans[0].x*4); - while (len--) - *d++ = r->u.fill.pixel; - yy++; - } while (--hh); - } - } - spans++; - } while (--num_spans > 1); - } - - return CAIRO_STATUS_SUCCESS; -} - -#if 0 -static cairo_status_t -_fill_spans (void *abstract_renderer, int y, int h, - const cairo_half_open_span_t *spans, unsigned num_spans) -{ - cairo_image_span_renderer_t *r = abstract_renderer; - - if (num_spans == 0) - return CAIRO_STATUS_SUCCESS; - - do { - if (spans[0].coverage) { - pixman_fill ((uint32_t *) r->data, r->stride, r->bpp, - spans[0].x, y, - spans[1].x - spans[0].x, h, - r->pixel); - } - spans++; - } while (--num_spans > 1); - - return CAIRO_STATUS_SUCCESS; -} -#endif - -static cairo_status_t -_blit_spans (void *abstract_renderer, int y, int h, - const cairo_half_open_span_t *spans, unsigned num_spans) -{ - cairo_image_span_renderer_t *r = abstract_renderer; - int cpp; - - if (num_spans == 0) - return CAIRO_STATUS_SUCCESS; - - cpp = r->bpp/8; - if (likely (h == 1)) { - uint8_t *src = r->u.blit.src_data + y*r->u.blit.src_stride; - uint8_t *dst = r->u.blit.data + y*r->u.blit.stride; - do { - if (spans[0].coverage) { - void *s = src + spans[0].x*cpp; - void *d = dst + spans[0].x*cpp; - int len = (spans[1].x - spans[0].x) * cpp; - switch (len) { - case 1: - *(uint8_t *)d = *(uint8_t *)s; - break; - case 2: - *(uint16_t *)d = *(uint16_t *)s; - break; - case 4: - *(uint32_t *)d = *(uint32_t *)s; - break; -#if HAVE_UINT64_T - case 8: - *(uint64_t *)d = *(uint64_t *)s; - break; -#endif - default: - memcpy(d, s, len); - break; - } - } - spans++; - } while (--num_spans > 1); - } else { - do { - if (spans[0].coverage) { - int yy = y, hh = h; - do { - void *src = r->u.blit.src_data + yy*r->u.blit.src_stride + spans[0].x*cpp; - void *dst = r->u.blit.data + yy*r->u.blit.stride + spans[0].x*cpp; - int len = (spans[1].x - spans[0].x) * cpp; - switch (len) { - case 1: - *(uint8_t *)dst = *(uint8_t *)src; - break; - case 2: - *(uint16_t *)dst = *(uint16_t *)src; - break; - case 4: - *(uint32_t *)dst = *(uint32_t *)src; - break; -#if HAVE_UINT64_T - case 8: - *(uint64_t *)dst = *(uint64_t *)src; - break; -#endif - default: - memcpy(dst, src, len); - break; - } - yy++; - } while (--hh); - } - spans++; - } while (--num_spans > 1); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_mono_spans (void *abstract_renderer, int y, int h, - const cairo_half_open_span_t *spans, unsigned num_spans) -{ - cairo_image_span_renderer_t *r = abstract_renderer; - - if (num_spans == 0) - return CAIRO_STATUS_SUCCESS; - - do { - if (spans[0].coverage) { - pixman_image_composite32 (r->op, - r->src, NULL, r->u.composite.dst, - spans[0].x + r->u.composite.src_x, y + r->u.composite.src_y, - 0, 0, - spans[0].x, y, - spans[1].x - spans[0].x, h); - } - spans++; - } while (--num_spans > 1); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_mono_unbounded_spans (void *abstract_renderer, int y, int h, - const cairo_half_open_span_t *spans, unsigned num_spans) -{ - cairo_image_span_renderer_t *r = abstract_renderer; - - if (num_spans == 0) { - pixman_image_composite32 (PIXMAN_OP_CLEAR, - r->src, NULL, r->u.composite.dst, - spans[0].x + r->u.composite.src_x, y + r->u.composite.src_y, - 0, 0, - r->composite->unbounded.x, y, - r->composite->unbounded.width, h); - r->u.composite.mask_y = y + h; - return CAIRO_STATUS_SUCCESS; - } - - if (y != r->u.composite.mask_y) { - pixman_image_composite32 (PIXMAN_OP_CLEAR, - r->src, NULL, r->u.composite.dst, - spans[0].x + r->u.composite.src_x, y + r->u.composite.src_y, - 0, 0, - r->composite->unbounded.x, r->u.composite.mask_y, - r->composite->unbounded.width, y - r->u.composite.mask_y); - } - - if (spans[0].x != r->composite->unbounded.x) { - pixman_image_composite32 (PIXMAN_OP_CLEAR, - r->src, NULL, r->u.composite.dst, - spans[0].x + r->u.composite.src_x, y + r->u.composite.src_y, - 0, 0, - r->composite->unbounded.x, y, - spans[0].x - r->composite->unbounded.x, h); - } - - do { - int op = spans[0].coverage ? r->op : PIXMAN_OP_CLEAR; - pixman_image_composite32 (op, - r->src, NULL, r->u.composite.dst, - spans[0].x + r->u.composite.src_x, y + r->u.composite.src_y, - 0, 0, - spans[0].x, y, - spans[1].x - spans[0].x, h); - spans++; - } while (--num_spans > 1); - - if (spans[0].x != r->composite->unbounded.x + r->composite->unbounded.width) { - pixman_image_composite32 (PIXMAN_OP_CLEAR, - r->src, NULL, r->u.composite.dst, - spans[0].x + r->u.composite.src_x, y + r->u.composite.src_y, - 0, 0, - spans[0].x, y, - r->composite->unbounded.x + r->composite->unbounded.width - spans[0].x, h); - } - - r->u.composite.mask_y = y + h; - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_mono_finish_unbounded_spans (void *abstract_renderer) -{ - cairo_image_span_renderer_t *r = abstract_renderer; - - if (r->u.composite.mask_y < r->composite->unbounded.y + r->composite->unbounded.height) { - pixman_image_composite32 (PIXMAN_OP_CLEAR, - r->src, NULL, r->u.composite.dst, - r->composite->unbounded.x + r->u.composite.src_x, r->u.composite.mask_y + r->u.composite.src_y, - 0, 0, - r->composite->unbounded.x, r->u.composite.mask_y, - r->composite->unbounded.width, - r->composite->unbounded.y + r->composite->unbounded.height - r->u.composite.mask_y); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -mono_renderer_init (cairo_image_span_renderer_t *r, - const cairo_composite_rectangles_t *composite, - cairo_antialias_t antialias, - cairo_bool_t needs_clip) -{ - cairo_image_surface_t *dst = (cairo_image_surface_t *)composite->surface; - - if (antialias != CAIRO_ANTIALIAS_NONE) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (!_cairo_pattern_is_opaque_solid (&composite->mask_pattern.base)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - r->base.render_rows = NULL; - if (composite->source_pattern.base.type == CAIRO_PATTERN_TYPE_SOLID) { - const cairo_color_t *color; - - color = &composite->source_pattern.solid.color; - if (composite->op == CAIRO_OPERATOR_CLEAR) - color = CAIRO_COLOR_TRANSPARENT; - - if (fill_reduces_to_source (composite->op, color, dst, &r->u.fill.pixel)) { - /* Use plain C for the fill operations as the span length is - * typically small, too small to payback the startup overheads of - * using SSE2 etc. - */ - switch (PIXMAN_FORMAT_BPP(dst->pixman_format)) { - case 8: r->base.render_rows = _fill8_spans; break; - case 16: r->base.render_rows = _fill16_spans; break; - case 32: r->base.render_rows = _fill32_spans; break; - default: break; - } - r->u.fill.data = dst->data; - r->u.fill.stride = dst->stride; - } - } else if ((composite->op == CAIRO_OPERATOR_SOURCE || - (composite->op == CAIRO_OPERATOR_OVER && - (dst->base.is_clear || (dst->base.content & CAIRO_CONTENT_ALPHA) == 0))) && - composite->source_pattern.base.type == CAIRO_PATTERN_TYPE_SURFACE && - composite->source_pattern.surface.surface->backend->type == CAIRO_SURFACE_TYPE_IMAGE && - to_image_surface(composite->source_pattern.surface.surface)->format == dst->format) - { - cairo_image_surface_t *src = - to_image_surface(composite->source_pattern.surface.surface); - int tx, ty; - - if (_cairo_matrix_is_integer_translation(&composite->source_pattern.base.matrix, - &tx, &ty) && - composite->bounded.x + tx >= 0 && - composite->bounded.y + ty >= 0 && - composite->bounded.x + composite->bounded.width + tx <= src->width && - composite->bounded.y + composite->bounded.height + ty <= src->height) { - - r->u.blit.stride = dst->stride; - r->u.blit.data = dst->data; - r->u.blit.src_stride = src->stride; - r->u.blit.src_data = src->data + src->stride * ty + tx * 4; - r->base.render_rows = _blit_spans; - } - } - - if (r->base.render_rows == NULL) { - r->src = _pixman_image_for_pattern (dst, &composite->source_pattern.base, FALSE, - &composite->unbounded, - &composite->source_sample_area, - &r->u.composite.src_x, &r->u.composite.src_y); - if (unlikely (r->src == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - r->u.composite.dst = to_pixman_image (composite->surface); - r->op = _pixman_operator (composite->op); - if (composite->is_bounded == 0) { - r->base.render_rows = _mono_unbounded_spans; - r->base.finish = _mono_finish_unbounded_spans; - r->u.composite.mask_y = composite->unbounded.y; - } else - r->base.render_rows = _mono_spans; - } - r->bpp = PIXMAN_FORMAT_BPP(dst->pixman_format); - - return CAIRO_INT_STATUS_SUCCESS; -} - -#define ONE_HALF 0x7f -#define RB_MASK 0x00ff00ff -#define RB_ONE_HALF 0x007f007f -#define RB_MASK_PLUS_ONE 0x01000100 -#define G_SHIFT 8 -static inline uint32_t -mul8x2_8 (uint32_t a, uint8_t b) -{ - uint32_t t = (a & RB_MASK) * b + RB_ONE_HALF; - return ((t + ((t >> G_SHIFT) & RB_MASK)) >> G_SHIFT) & RB_MASK; -} - -static inline uint32_t -add8x2_8x2 (uint32_t a, uint32_t b) -{ - uint32_t t = a + b; - t |= RB_MASK_PLUS_ONE - ((t >> G_SHIFT) & RB_MASK); - return t & RB_MASK; -} - -static inline uint8_t -mul8_8 (uint8_t a, uint8_t b) -{ - uint16_t t = a * (uint16_t)b + ONE_HALF; - return ((t >> G_SHIFT) + t) >> G_SHIFT; -} - -static inline uint32_t -lerp8x4 (uint32_t src, uint8_t a, uint32_t dst) -{ - return (add8x2_8x2 (mul8x2_8 (src, a), - mul8x2_8 (dst, ~a)) | - add8x2_8x2 (mul8x2_8 (src >> G_SHIFT, a), - mul8x2_8 (dst >> G_SHIFT, ~a)) << G_SHIFT); -} - -static cairo_status_t -_fill_a8_lerp_opaque_spans (void *abstract_renderer, int y, int h, - const cairo_half_open_span_t *spans, unsigned num_spans) -{ - cairo_image_span_renderer_t *r = abstract_renderer; - - if (num_spans == 0) - return CAIRO_STATUS_SUCCESS; - - if (likely(h == 1)) { - uint8_t *d = r->u.fill.data + r->u.fill.stride*y; - do { - uint8_t a = spans[0].coverage; - if (a) { - int len = spans[1].x - spans[0].x; - if (a == 0xff) { - memset(d + spans[0].x, r->u.fill.pixel, len); - } else { - uint8_t s = mul8_8(a, r->u.fill.pixel); - uint8_t *dst = d + spans[0].x; - a = ~a; - while (len--) { - uint8_t t = mul8_8(*dst, a); - *dst++ = t + s; - } - } - } - spans++; - } while (--num_spans > 1); - } else { - do { - uint8_t a = spans[0].coverage; - if (a) { - int yy = y, hh = h; - if (a == 0xff) { - do { - int len = spans[1].x - spans[0].x; - uint8_t *d = r->u.fill.data + r->u.fill.stride*yy + spans[0].x; - memset(d, r->u.fill.pixel, len); - yy++; - } while (--hh); - } else { - uint8_t s = mul8_8(a, r->u.fill.pixel); - a = ~a; - do { - int len = spans[1].x - spans[0].x; - uint8_t *d = r->u.fill.data + r->u.fill.stride*yy + spans[0].x; - while (len--) { - uint8_t t = mul8_8(*d, a); - *d++ = t + s; - } - yy++; - } while (--hh); - } - } - spans++; - } while (--num_spans > 1); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_fill_xrgb32_lerp_opaque_spans (void *abstract_renderer, int y, int h, - const cairo_half_open_span_t *spans, unsigned num_spans) -{ - cairo_image_span_renderer_t *r = abstract_renderer; - - if (num_spans == 0) - return CAIRO_STATUS_SUCCESS; - - if (likely(h == 1)) { - do { - uint8_t a = spans[0].coverage; - if (a) { - int len = spans[1].x - spans[0].x; - uint32_t *d = (uint32_t*)(r->u.fill.data + r->u.fill.stride*y + spans[0].x*4); - if (a == 0xff) { - if (len > 31) { - pixman_fill ((uint32_t *)r->u.fill.data, r->u.fill.stride / sizeof(uint32_t), 32, - spans[0].x, y, len, 1, r->u.fill.pixel); - } else { - uint32_t *d = (uint32_t*)(r->u.fill.data + r->u.fill.stride*y + spans[0].x*4); - while (len-- > 0) - *d++ = r->u.fill.pixel; - } - } else while (len-- > 0) { - *d = lerp8x4 (r->u.fill.pixel, a, *d); - d++; - } - } - spans++; - } while (--num_spans > 1); - } else { - do { - uint8_t a = spans[0].coverage; - if (a) { - if (a == 0xff) { - if (spans[1].x - spans[0].x > 16) { - pixman_fill ((uint32_t *)r->u.fill.data, r->u.fill.stride / sizeof(uint32_t), 32, - spans[0].x, y, spans[1].x - spans[0].x, h, - r->u.fill.pixel); - } else { - int yy = y, hh = h; - do { - int len = spans[1].x - spans[0].x; - uint32_t *d = (uint32_t*)(r->u.fill.data + r->u.fill.stride*yy + spans[0].x*4); - while (len--) - *d++ = r->u.fill.pixel; - yy++; - } while (--hh); - } - } else { - int yy = y, hh = h; - do { - int len = spans[1].x - spans[0].x; - uint32_t *d = (uint32_t *)(r->u.fill.data + r->u.fill.stride*yy + spans[0].x*4); - while (len--) { - *d = lerp8x4 (r->u.fill.pixel, a, *d); - d++; - } - yy++; - } while (--hh); - } - } - spans++; - } while (--num_spans > 1); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_fill_a8_lerp_spans (void *abstract_renderer, int y, int h, - const cairo_half_open_span_t *spans, unsigned num_spans) -{ - cairo_image_span_renderer_t *r = abstract_renderer; - - if (num_spans == 0) - return CAIRO_STATUS_SUCCESS; - - if (likely(h == 1)) { - do { - uint8_t a = mul8_8 (spans[0].coverage, r->bpp); - if (a) { - int len = spans[1].x - spans[0].x; - uint8_t *d = r->u.fill.data + r->u.fill.stride*y + spans[0].x; - uint16_t p = (uint16_t)a * r->u.fill.pixel + 0x7f; - uint16_t ia = ~a; - while (len--) { - uint16_t t = *d*ia + p; - *d++ = (t + (t>>8)) >> 8; - } - } - spans++; - } while (--num_spans > 1); - } else { - do { - uint8_t a = mul8_8 (spans[0].coverage, r->bpp); - if (a) { - int yy = y, hh = h; - uint16_t p = (uint16_t)a * r->u.fill.pixel + 0x7f; - uint16_t ia = ~a; - do { - int len = spans[1].x - spans[0].x; - uint8_t *d = r->u.fill.data + r->u.fill.stride*yy + spans[0].x; - while (len--) { - uint16_t t = *d*ia + p; - *d++ = (t + (t>>8)) >> 8; - } - yy++; - } while (--hh); - } - spans++; - } while (--num_spans > 1); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_fill_xrgb32_lerp_spans (void *abstract_renderer, int y, int h, - const cairo_half_open_span_t *spans, unsigned num_spans) -{ - cairo_image_span_renderer_t *r = abstract_renderer; - - if (num_spans == 0) - return CAIRO_STATUS_SUCCESS; - - if (likely(h == 1)) { - do { - uint8_t a = mul8_8 (spans[0].coverage, r->bpp); - if (a) { - int len = spans[1].x - spans[0].x; - uint32_t *d = (uint32_t*)(r->u.fill.data + r->u.fill.stride*y + spans[0].x*4); - while (len--) { - *d = lerp8x4 (r->u.fill.pixel, a, *d); - d++; - } - } - spans++; - } while (--num_spans > 1); - } else { - do { - uint8_t a = mul8_8 (spans[0].coverage, r->bpp); - if (a) { - int yy = y, hh = h; - do { - int len = spans[1].x - spans[0].x; - uint32_t *d = (uint32_t *)(r->u.fill.data + r->u.fill.stride*yy + spans[0].x*4); - while (len--) { - *d = lerp8x4 (r->u.fill.pixel, a, *d); - d++; - } - yy++; - } while (--hh); - } - spans++; - } while (--num_spans > 1); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_blit_xrgb32_lerp_spans (void *abstract_renderer, int y, int h, - const cairo_half_open_span_t *spans, unsigned num_spans) -{ - cairo_image_span_renderer_t *r = abstract_renderer; - - if (num_spans == 0) - return CAIRO_STATUS_SUCCESS; - - if (likely(h == 1)) { - uint8_t *src = r->u.blit.src_data + y*r->u.blit.src_stride; - uint8_t *dst = r->u.blit.data + y*r->u.blit.stride; - do { - uint8_t a = mul8_8 (spans[0].coverage, r->bpp); - if (a) { - uint32_t *s = (uint32_t*)src + spans[0].x; - uint32_t *d = (uint32_t*)dst + spans[0].x; - int len = spans[1].x - spans[0].x; - if (a == 0xff) { - if (len == 1) - *d = *s; - else - memcpy(d, s, len*4); - } else { - while (len--) { - *d = lerp8x4 (*s, a, *d); - s++, d++; - } - } - } - spans++; - } while (--num_spans > 1); - } else { - do { - uint8_t a = mul8_8 (spans[0].coverage, r->bpp); - if (a) { - int yy = y, hh = h; - do { - uint32_t *s = (uint32_t *)(r->u.blit.src_data + yy*r->u.blit.src_stride + spans[0].x * 4); - uint32_t *d = (uint32_t *)(r->u.blit.data + yy*r->u.blit.stride + spans[0].x * 4); - int len = spans[1].x - spans[0].x; - if (a == 0xff) { - if (len == 1) - *d = *s; - else - memcpy(d, s, len * 4); - } else { - while (len--) { - *d = lerp8x4 (*s, a, *d); - s++, d++; - } - } - yy++; - } while (--hh); - } - spans++; - } while (--num_spans > 1); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_inplace_spans (void *abstract_renderer, - int y, int h, - const cairo_half_open_span_t *spans, - unsigned num_spans) -{ - cairo_image_span_renderer_t *r = abstract_renderer; - uint8_t *mask; - int x0, x1; - - if (num_spans == 0) - return CAIRO_STATUS_SUCCESS; - - if (num_spans == 2 && spans[0].coverage == 0xff) { - pixman_image_composite32 (r->op, r->src, NULL, r->u.composite.dst, - spans[0].x + r->u.composite.src_x, - y + r->u.composite.src_y, - 0, 0, - spans[0].x, y, - spans[1].x - spans[0].x, h); - return CAIRO_STATUS_SUCCESS; - } - - mask = (uint8_t *)pixman_image_get_data (r->mask); - x1 = x0 = spans[0].x; - do { - int len = spans[1].x - spans[0].x; - *mask++ = spans[0].coverage; - if (len > 1) { - if (len >= r->u.composite.run_length && spans[0].coverage == 0xff) { - if (x1 != x0) { - pixman_image_composite32 (r->op, r->src, r->mask, r->u.composite.dst, - x0 + r->u.composite.src_x, - y + r->u.composite.src_y, - 0, 0, - x0, y, - x1 - x0, h); - } - pixman_image_composite32 (r->op, r->src, NULL, r->u.composite.dst, - spans[0].x + r->u.composite.src_x, - y + r->u.composite.src_y, - 0, 0, - spans[0].x, y, - len, h); - mask = (uint8_t *)pixman_image_get_data (r->mask); - x0 = spans[1].x; - } else if (spans[0].coverage == 0x0 && - x1 - x0 > r->u.composite.run_length) { - pixman_image_composite32 (r->op, r->src, r->mask, r->u.composite.dst, - x0 + r->u.composite.src_x, - y + r->u.composite.src_y, - 0, 0, - x0, y, - x1 - x0, h); - mask = (uint8_t *)pixman_image_get_data (r->mask); - x0 = spans[1].x; - }else { - memset (mask, spans[0].coverage, --len); - mask += len; - } - } - x1 = spans[1].x; - spans++; - } while (--num_spans > 1); - - if (x1 != x0) { - pixman_image_composite32 (r->op, r->src, r->mask, r->u.composite.dst, - x0 + r->u.composite.src_x, - y + r->u.composite.src_y, - 0, 0, - x0, y, - x1 - x0, h); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_inplace_opacity_spans (void *abstract_renderer, int y, int h, - const cairo_half_open_span_t *spans, - unsigned num_spans) -{ - cairo_image_span_renderer_t *r = abstract_renderer; - uint8_t *mask; - int x0, x1; - - if (num_spans == 0) - return CAIRO_STATUS_SUCCESS; - - mask = (uint8_t *)pixman_image_get_data (r->mask); - x1 = x0 = spans[0].x; - do { - int len = spans[1].x - spans[0].x; - uint8_t m = mul8_8(spans[0].coverage, r->bpp); - *mask++ = m; - if (len > 1) { - if (m == 0 && - x1 - x0 > r->u.composite.run_length) { - pixman_image_composite32 (r->op, r->src, r->mask, r->u.composite.dst, - x0 + r->u.composite.src_x, - y + r->u.composite.src_y, - 0, 0, - x0, y, - x1 - x0, h); - mask = (uint8_t *)pixman_image_get_data (r->mask); - x0 = spans[1].x; - }else { - memset (mask, m, --len); - mask += len; - } - } - x1 = spans[1].x; - spans++; - } while (--num_spans > 1); - - if (x1 != x0) { - pixman_image_composite32 (r->op, r->src, r->mask, r->u.composite.dst, - x0 + r->u.composite.src_x, - y + r->u.composite.src_y, - 0, 0, - x0, y, - x1 - x0, h); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_inplace_src_spans (void *abstract_renderer, int y, int h, - const cairo_half_open_span_t *spans, - unsigned num_spans) -{ - cairo_image_span_renderer_t *r = abstract_renderer; - uint8_t *m; - int x0; - - if (num_spans == 0) - return CAIRO_STATUS_SUCCESS; - - x0 = spans[0].x; - m = r->_buf; - do { - int len = spans[1].x - spans[0].x; - if (len >= r->u.composite.run_length && spans[0].coverage == 0xff) { - if (spans[0].x != x0) { -#if PIXMAN_HAS_OP_LERP - pixman_image_composite32 (PIXMAN_OP_LERP_SRC, - r->src, r->mask, r->u.composite.dst, - x0 + r->u.composite.src_x, - y + r->u.composite.src_y, - 0, 0, - x0, y, - spans[0].x - x0, h); -#else - pixman_image_composite32 (PIXMAN_OP_OUT_REVERSE, - r->mask, NULL, r->u.composite.dst, - 0, 0, - 0, 0, - x0, y, - spans[0].x - x0, h); - pixman_image_composite32 (PIXMAN_OP_ADD, - r->src, r->mask, r->u.composite.dst, - x0 + r->u.composite.src_x, - y + r->u.composite.src_y, - 0, 0, - x0, y, - spans[0].x - x0, h); -#endif - } - - pixman_image_composite32 (PIXMAN_OP_SRC, - r->src, NULL, r->u.composite.dst, - spans[0].x + r->u.composite.src_x, - y + r->u.composite.src_y, - 0, 0, - spans[0].x, y, - spans[1].x - spans[0].x, h); - - m = r->_buf; - x0 = spans[1].x; - } else if (spans[0].coverage == 0x0) { - if (spans[0].x != x0) { -#if PIXMAN_HAS_OP_LERP - pixman_image_composite32 (PIXMAN_OP_LERP_SRC, - r->src, r->mask, r->u.composite.dst, - x0 + r->u.composite.src_x, - y + r->u.composite.src_y, - 0, 0, - x0, y, - spans[0].x - x0, h); -#else - pixman_image_composite32 (PIXMAN_OP_OUT_REVERSE, - r->mask, NULL, r->u.composite.dst, - 0, 0, - 0, 0, - x0, y, - spans[0].x - x0, h); - pixman_image_composite32 (PIXMAN_OP_ADD, - r->src, r->mask, r->u.composite.dst, - x0 + r->u.composite.src_x, - y + r->u.composite.src_y, - 0, 0, - x0, y, - spans[0].x - x0, h); -#endif - } - - m = r->_buf; - x0 = spans[1].x; - } else { - *m++ = spans[0].coverage; - if (len > 1) { - memset (m, spans[0].coverage, --len); - m += len; - } - } - spans++; - } while (--num_spans > 1); - - if (spans[0].x != x0) { -#if PIXMAN_HAS_OP_LERP - pixman_image_composite32 (PIXMAN_OP_LERP_SRC, - r->src, r->mask, r->u.composite.dst, - x0 + r->u.composite.src_x, - y + r->u.composite.src_y, - 0, 0, - x0, y, - spans[0].x - x0, h); -#else - pixman_image_composite32 (PIXMAN_OP_OUT_REVERSE, - r->mask, NULL, r->u.composite.dst, - 0, 0, - 0, 0, - x0, y, - spans[0].x - x0, h); - pixman_image_composite32 (PIXMAN_OP_ADD, - r->src, r->mask, r->u.composite.dst, - x0 + r->u.composite.src_x, - y + r->u.composite.src_y, - 0, 0, - x0, y, - spans[0].x - x0, h); -#endif - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_inplace_src_opacity_spans (void *abstract_renderer, int y, int h, - const cairo_half_open_span_t *spans, - unsigned num_spans) -{ - cairo_image_span_renderer_t *r = abstract_renderer; - uint8_t *mask; - int x0; - - if (num_spans == 0) - return CAIRO_STATUS_SUCCESS; - - x0 = spans[0].x; - mask = (uint8_t *)pixman_image_get_data (r->mask); - do { - int len = spans[1].x - spans[0].x; - uint8_t m = mul8_8(spans[0].coverage, r->bpp); - if (m == 0) { - if (spans[0].x != x0) { -#if PIXMAN_HAS_OP_LERP - pixman_image_composite32 (PIXMAN_OP_LERP_SRC, - r->src, r->mask, r->u.composite.dst, - x0 + r->u.composite.src_x, - y + r->u.composite.src_y, - 0, 0, - x0, y, - spans[0].x - x0, h); -#else - pixman_image_composite32 (PIXMAN_OP_OUT_REVERSE, - r->mask, NULL, r->u.composite.dst, - 0, 0, - 0, 0, - x0, y, - spans[0].x - x0, h); - pixman_image_composite32 (PIXMAN_OP_ADD, - r->src, r->mask, r->u.composite.dst, - x0 + r->u.composite.src_x, - y + r->u.composite.src_y, - 0, 0, - x0, y, - spans[0].x - x0, h); -#endif - } - - mask = (uint8_t *)pixman_image_get_data (r->mask); - x0 = spans[1].x; - } else { - *mask++ = m; - if (len > 1) { - memset (mask, m, --len); - mask += len; - } - } - spans++; - } while (--num_spans > 1); - - if (spans[0].x != x0) { -#if PIXMAN_HAS_OP_LERP - pixman_image_composite32 (PIXMAN_OP_LERP_SRC, - r->src, r->mask, r->u.composite.dst, - x0 + r->u.composite.src_x, - y + r->u.composite.src_y, - 0, 0, - x0, y, - spans[0].x - x0, h); -#else - pixman_image_composite32 (PIXMAN_OP_OUT_REVERSE, - r->mask, NULL, r->u.composite.dst, - 0, 0, - 0, 0, - x0, y, - spans[0].x - x0, h); - pixman_image_composite32 (PIXMAN_OP_ADD, - r->src, r->mask, r->u.composite.dst, - x0 + r->u.composite.src_x, - y + r->u.composite.src_y, - 0, 0, - x0, y, - spans[0].x - x0, h); -#endif - } - - return CAIRO_STATUS_SUCCESS; -} - -static void free_pixels (pixman_image_t *image, void *data) -{ - free (data); -} - -static cairo_int_status_t -inplace_renderer_init (cairo_image_span_renderer_t *r, - const cairo_composite_rectangles_t *composite, - cairo_antialias_t antialias, - cairo_bool_t needs_clip) -{ - cairo_image_surface_t *dst = (cairo_image_surface_t *)composite->surface; - uint8_t *buf; - - if (composite->mask_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) - return CAIRO_INT_STATUS_UNSUPPORTED; - - r->base.render_rows = NULL; - r->bpp = composite->mask_pattern.solid.color.alpha_short >> 8; - - if (composite->source_pattern.base.type == CAIRO_PATTERN_TYPE_SOLID) { - const cairo_color_t *color; - - color = &composite->source_pattern.solid.color; - if (composite->op == CAIRO_OPERATOR_CLEAR) - color = CAIRO_COLOR_TRANSPARENT; - - if (fill_reduces_to_source (composite->op, color, dst, &r->u.fill.pixel)) { - /* Use plain C for the fill operations as the span length is - * typically small, too small to payback the startup overheads of - * using SSE2 etc. - */ - if (r->bpp == 0xff) { - switch (dst->format) { - case CAIRO_FORMAT_A8: - r->base.render_rows = _fill_a8_lerp_opaque_spans; - break; - case CAIRO_FORMAT_RGB24: - case CAIRO_FORMAT_ARGB32: - r->base.render_rows = _fill_xrgb32_lerp_opaque_spans; - break; - case CAIRO_FORMAT_A1: - case CAIRO_FORMAT_RGB16_565: - case CAIRO_FORMAT_RGB30: - case CAIRO_FORMAT_INVALID: - default: break; - } - } else { - switch (dst->format) { - case CAIRO_FORMAT_A8: - r->base.render_rows = _fill_a8_lerp_spans; - break; - case CAIRO_FORMAT_RGB24: - case CAIRO_FORMAT_ARGB32: - r->base.render_rows = _fill_xrgb32_lerp_spans; - break; - case CAIRO_FORMAT_A1: - case CAIRO_FORMAT_RGB16_565: - case CAIRO_FORMAT_RGB30: - case CAIRO_FORMAT_INVALID: - default: break; - } - } - r->u.fill.data = dst->data; - r->u.fill.stride = dst->stride; - } - } else if ((dst->format == CAIRO_FORMAT_ARGB32 || dst->format == CAIRO_FORMAT_RGB24) && - (composite->op == CAIRO_OPERATOR_SOURCE || - (composite->op == CAIRO_OPERATOR_OVER && - (dst->base.is_clear || (dst->base.content & CAIRO_CONTENT_ALPHA) == 0))) && - composite->source_pattern.base.type == CAIRO_PATTERN_TYPE_SURFACE && - composite->source_pattern.surface.surface->backend->type == CAIRO_SURFACE_TYPE_IMAGE && - to_image_surface(composite->source_pattern.surface.surface)->format == dst->format) - { - cairo_image_surface_t *src = - to_image_surface(composite->source_pattern.surface.surface); - int tx, ty; - - if (_cairo_matrix_is_integer_translation(&composite->source_pattern.base.matrix, - &tx, &ty) && - composite->bounded.x + tx >= 0 && - composite->bounded.y + ty >= 0 && - composite->bounded.x + composite->bounded.width + tx <= src->width && - composite->bounded.y + composite->bounded.height + ty <= src->height) { - - assert(PIXMAN_FORMAT_BPP(dst->pixman_format) == 32); - r->u.blit.stride = dst->stride; - r->u.blit.data = dst->data; - r->u.blit.src_stride = src->stride; - r->u.blit.src_data = src->data + src->stride * ty + tx * 4; - r->base.render_rows = _blit_xrgb32_lerp_spans; - } - } - if (r->base.render_rows == NULL) { - const cairo_pattern_t *src = &composite->source_pattern.base; - unsigned int width; - - if (composite->is_bounded == 0) - return CAIRO_INT_STATUS_UNSUPPORTED; - - r->base.render_rows = r->bpp == 0xff ? _inplace_spans : _inplace_opacity_spans; - width = (composite->bounded.width + 3) & ~3; - - r->u.composite.run_length = 8; - if (src->type == CAIRO_PATTERN_TYPE_LINEAR || - src->type == CAIRO_PATTERN_TYPE_RADIAL) - r->u.composite.run_length = 256; - if (dst->base.is_clear && - (composite->op == CAIRO_OPERATOR_SOURCE || - composite->op == CAIRO_OPERATOR_OVER || - composite->op == CAIRO_OPERATOR_ADD)) { - r->op = PIXMAN_OP_SRC; - } else if (composite->op == CAIRO_OPERATOR_SOURCE) { - r->base.render_rows = r->bpp == 0xff ? _inplace_src_spans : _inplace_src_opacity_spans; - r->u.composite.mask_y = r->composite->unbounded.y; - width = (composite->unbounded.width + 3) & ~3; - } else if (composite->op == CAIRO_OPERATOR_CLEAR) { - r->op = PIXMAN_OP_OUT_REVERSE; - src = NULL; - } else { - r->op = _pixman_operator (composite->op); - } - - r->src = _pixman_image_for_pattern (dst, src, FALSE, - &composite->bounded, - &composite->source_sample_area, - &r->u.composite.src_x, &r->u.composite.src_y); - if (unlikely (r->src == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - /* Create an effectively unbounded mask by repeating the single line */ - buf = r->_buf; - if (width > SZ_BUF) { - buf = malloc (width); - if (unlikely (buf == NULL)) { - pixman_image_unref (r->src); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - } - r->mask = pixman_image_create_bits (PIXMAN_a8, - width, composite->unbounded.height, - (uint32_t *)buf, 0); - if (unlikely (r->mask == NULL)) { - pixman_image_unref (r->src); - if (buf != r->_buf) - free (buf); - return _cairo_error(CAIRO_STATUS_NO_MEMORY); - } - - if (buf != r->_buf) - pixman_image_set_destroy_function (r->mask, free_pixels, buf); - - r->u.composite.dst = dst->pixman_image; - } - - return CAIRO_INT_STATUS_SUCCESS; -} - -static cairo_int_status_t -span_renderer_init (cairo_abstract_span_renderer_t *_r, - const cairo_composite_rectangles_t *composite, - cairo_antialias_t antialias, - cairo_bool_t needs_clip) -{ - cairo_image_span_renderer_t *r = (cairo_image_span_renderer_t *)_r; - cairo_image_surface_t *dst = (cairo_image_surface_t *)composite->surface; - const cairo_pattern_t *source = &composite->source_pattern.base; - cairo_operator_t op = composite->op; - cairo_int_status_t status; - - TRACE ((stderr, "%s: antialias=%d, needs_clip=%d\n", __FUNCTION__, - antialias, needs_clip)); - - if (needs_clip) - return CAIRO_INT_STATUS_UNSUPPORTED; - - r->composite = composite; - r->mask = NULL; - r->src = NULL; - r->base.finish = NULL; - - status = mono_renderer_init (r, composite, antialias, needs_clip); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - - status = inplace_renderer_init (r, composite, antialias, needs_clip); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - - r->bpp = 0; - - if (op == CAIRO_OPERATOR_CLEAR) { -#if PIXMAN_HAS_OP_LERP - op = PIXMAN_OP_LERP_CLEAR; -#else - source = &_cairo_pattern_white.base; - op = PIXMAN_OP_OUT_REVERSE; -#endif - } else if (dst->base.is_clear && - (op == CAIRO_OPERATOR_SOURCE || - op == CAIRO_OPERATOR_OVER || - op == CAIRO_OPERATOR_ADD)) { - op = PIXMAN_OP_SRC; - } else if (op == CAIRO_OPERATOR_SOURCE) { - if (_cairo_pattern_is_opaque (&composite->source_pattern.base, - &composite->source_sample_area)) - { - op = PIXMAN_OP_OVER; - } - else - { -#if PIXMAN_HAS_OP_LERP - op = PIXMAN_OP_LERP_SRC; -#else - return CAIRO_INT_STATUS_UNSUPPORTED; -#endif - } - } else { - op = _pixman_operator (op); - } - r->op = op; - - r->src = _pixman_image_for_pattern (dst, source, FALSE, - &composite->unbounded, - &composite->source_sample_area, - &r->u.mask.src_x, &r->u.mask.src_y); - if (unlikely (r->src == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - r->opacity = 1.0; - if (composite->mask_pattern.base.type == CAIRO_PATTERN_TYPE_SOLID) { - r->opacity = composite->mask_pattern.solid.color.alpha; - } else { - pixman_image_t *mask; - int mask_x, mask_y; - - mask = _pixman_image_for_pattern (dst, - &composite->mask_pattern.base, - TRUE, - &composite->unbounded, - &composite->mask_sample_area, - &mask_x, &mask_y); - if (unlikely (mask == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - /* XXX Component-alpha? */ - if ((dst->base.content & CAIRO_CONTENT_COLOR) == 0 && - _cairo_pattern_is_opaque (source, &composite->source_sample_area)) - { - pixman_image_unref (r->src); - r->src = mask; - r->u.mask.src_x = mask_x; - r->u.mask.src_y = mask_y; - mask = NULL; - } - - if (mask) { - pixman_image_unref (mask); - return CAIRO_INT_STATUS_UNSUPPORTED; - } - } - - r->u.mask.extents = composite->unbounded; - r->u.mask.stride = (r->u.mask.extents.width + 3) & ~3; - if (r->u.mask.extents.height * r->u.mask.stride > SZ_BUF) { - r->mask = pixman_image_create_bits (PIXMAN_a8, - r->u.mask.extents.width, - r->u.mask.extents.height, - NULL, 0); - - r->base.render_rows = _cairo_image_spans; - r->base.finish = NULL; - } else { - r->mask = pixman_image_create_bits (PIXMAN_a8, - r->u.mask.extents.width, - r->u.mask.extents.height, - (uint32_t *)r->_buf, r->u.mask.stride); - - r->base.render_rows = _cairo_image_spans_and_zero; - r->base.finish = _cairo_image_finish_spans_and_zero; - } - if (unlikely (r->mask == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - r->u.mask.data = (uint8_t *) pixman_image_get_data (r->mask); - r->u.mask.stride = pixman_image_get_stride (r->mask); - - r->u.mask.extents.height += r->u.mask.extents.y; - return CAIRO_STATUS_SUCCESS; -} - -static void -span_renderer_fini (cairo_abstract_span_renderer_t *_r, - cairo_int_status_t status) -{ - cairo_image_span_renderer_t *r = (cairo_image_span_renderer_t *) _r; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) { - if (r->base.finish) - r->base.finish (r); - } - if (likely (status == CAIRO_INT_STATUS_SUCCESS && r->bpp == 0)) { - const cairo_composite_rectangles_t *composite = r->composite; - - pixman_image_composite32 (r->op, r->src, r->mask, - to_pixman_image (composite->surface), - composite->unbounded.x + r->u.mask.src_x, - composite->unbounded.y + r->u.mask.src_y, - 0, 0, - composite->unbounded.x, - composite->unbounded.y, - composite->unbounded.width, - composite->unbounded.height); - } - - if (r->src) - pixman_image_unref (r->src); - if (r->mask) - pixman_image_unref (r->mask); -} -#endif - -const cairo_compositor_t * -_cairo_image_spans_compositor_get (void) -{ - static cairo_spans_compositor_t spans; - static cairo_compositor_t shape; - - if (spans.base.delegate == NULL) { - _cairo_shape_mask_compositor_init (&shape, - _cairo_image_traps_compositor_get()); - shape.glyphs = NULL; - - _cairo_spans_compositor_init (&spans, &shape); - - spans.flags = 0; -#if PIXMAN_HAS_OP_LERP - spans.flags |= CAIRO_SPANS_COMPOSITOR_HAS_LERP; -#endif - - //spans.acquire = acquire; - //spans.release = release; - spans.fill_boxes = fill_boxes; - spans.draw_image_boxes = draw_image_boxes; - //spans.copy_boxes = copy_boxes; - spans.pattern_to_surface = _cairo_image_source_create_for_pattern; - //spans.check_composite_boxes = check_composite_boxes; - spans.composite_boxes = composite_boxes; - //spans.check_span_renderer = check_span_renderer; - spans.renderer_init = span_renderer_init; - spans.renderer_fini = span_renderer_fini; - } - - return &spans.base; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-image-info-private.h b/source/libs/cairo/cairo-src/src/cairo-image-info-private.h deleted file mode 100644 index e64928e40ec6d6b6ceac2a2ee345c25d82e67cb9..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-image-info-private.h +++ /dev/null @@ -1,68 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2008 Adrian Johnson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Adrian Johnson. - * - * Contributor(s): - * Adrian Johnson <ajohnson@redneon.com> - */ - -#ifndef CAIRO_IMAGE_INFO_PRIVATE_H -#define CAIRO_IMAGE_INFO_PRIVATE_H - -#include "cairoint.h" - -typedef struct _cairo_image_info { - int width; - int height; - int num_components; - int bits_per_component; -} cairo_image_info_t; - -cairo_private cairo_int_status_t -_cairo_image_info_get_jpeg_info (cairo_image_info_t *info, - const unsigned char *data, - long length); - -cairo_private cairo_int_status_t -_cairo_image_info_get_jpx_info (cairo_image_info_t *info, - const unsigned char *data, - unsigned long length); - -cairo_private cairo_int_status_t -_cairo_image_info_get_png_info (cairo_image_info_t *info, - const unsigned char *data, - unsigned long length); - -cairo_private cairo_int_status_t -_cairo_image_info_get_jbig2_info (cairo_image_info_t *info, - const unsigned char *data, - unsigned long length); - -#endif /* CAIRO_IMAGE_INFO_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-image-info.c b/source/libs/cairo/cairo-src/src/cairo-image-info.c deleted file mode 100644 index 26e7ae5afd110889e2898e27710031c699ca1264..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-image-info.c +++ /dev/null @@ -1,421 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2008 Adrian Johnson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Adrian Johnson. - * - * Contributor(s): - * Adrian Johnson <ajohnson@redneon.com> - */ - -#include "cairoint.h" - -#include "cairo-error-private.h" -#include "cairo-image-info-private.h" - -/* JPEG (image/jpeg) - * - * http://www.w3.org/Graphics/JPEG/itu-t81.pdf - */ - -/* Markers with no parameters. All other markers are followed by a two - * byte length of the parameters. */ -#define TEM 0x01 -#define RST_begin 0xd0 -#define RST_end 0xd7 -#define SOI 0xd8 -#define EOI 0xd9 - -/* Start of frame markers. */ -#define SOF0 0xc0 -#define SOF1 0xc1 -#define SOF2 0xc2 -#define SOF3 0xc3 -#define SOF5 0xc5 -#define SOF6 0xc6 -#define SOF7 0xc7 -#define SOF9 0xc9 -#define SOF10 0xca -#define SOF11 0xcb -#define SOF13 0xcd -#define SOF14 0xce -#define SOF15 0xcf - -static const unsigned char * -_jpeg_skip_segment (const unsigned char *p) -{ - int len; - - p++; - len = (p[0] << 8) | p[1]; - - return p + len; -} - -static void -_jpeg_extract_info (cairo_image_info_t *info, const unsigned char *p) -{ - info->width = (p[6] << 8) + p[7]; - info->height = (p[4] << 8) + p[5]; - info->num_components = p[8]; - info->bits_per_component = p[3]; -} - -cairo_int_status_t -_cairo_image_info_get_jpeg_info (cairo_image_info_t *info, - const unsigned char *data, - long length) -{ - const unsigned char *p = data; - - while (p + 1 < data + length) { - if (*p != 0xff) - return CAIRO_INT_STATUS_UNSUPPORTED; - p++; - - switch (*p) { - /* skip fill bytes */ - case 0xff: - p++; - break; - - case TEM: - case SOI: - case EOI: - p++; - break; - - case SOF0: - case SOF1: - case SOF2: - case SOF3: - case SOF5: - case SOF6: - case SOF7: - case SOF9: - case SOF10: - case SOF11: - case SOF13: - case SOF14: - case SOF15: - /* Start of frame found. Extract the image parameters. */ - if (p + 8 > data + length) - return CAIRO_INT_STATUS_UNSUPPORTED; - - _jpeg_extract_info (info, p); - return CAIRO_STATUS_SUCCESS; - - default: - if (*p >= RST_begin && *p <= RST_end) { - p++; - break; - } - - if (p + 2 > data + length) - return CAIRO_INT_STATUS_UNSUPPORTED; - - p = _jpeg_skip_segment (p); - break; - } - } - - return CAIRO_STATUS_SUCCESS; -} - -/* JPEG 2000 (image/jp2) - * - * http://www.jpeg.org/public/15444-1annexi.pdf - */ - -#define JPX_FILETYPE 0x66747970 -#define JPX_JP2_HEADER 0x6A703268 -#define JPX_IMAGE_HEADER 0x69686472 - -static const unsigned char _jpx_signature[] = { - 0x00, 0x00, 0x00, 0x0c, 0x6a, 0x50, 0x20, 0x20, 0x0d, 0x0a, 0x87, 0x0a -}; - -static const unsigned char * -_jpx_next_box (const unsigned char *p) -{ - return p + get_unaligned_be32 (p); -} - -static const unsigned char * -_jpx_get_box_contents (const unsigned char *p) -{ - return p + 8; -} - -static cairo_bool_t -_jpx_match_box (const unsigned char *p, const unsigned char *end, uint32_t type) -{ - uint32_t length; - - if (p + 8 < end) { - length = get_unaligned_be32 (p); - if (get_unaligned_be32 (p + 4) == type && p + length < end) - return TRUE; - } - - return FALSE; -} - -static const unsigned char * -_jpx_find_box (const unsigned char *p, const unsigned char *end, uint32_t type) -{ - while (p < end) { - if (_jpx_match_box (p, end, type)) - return p; - p = _jpx_next_box (p); - } - - return NULL; -} - -static void -_jpx_extract_info (const unsigned char *p, cairo_image_info_t *info) -{ - info->height = get_unaligned_be32 (p); - info->width = get_unaligned_be32 (p + 4); - info->num_components = (p[8] << 8) + p[9]; - info->bits_per_component = p[10]; -} - -cairo_int_status_t -_cairo_image_info_get_jpx_info (cairo_image_info_t *info, - const unsigned char *data, - unsigned long length) -{ - const unsigned char *p = data; - const unsigned char *end = data + length; - - /* First 12 bytes must be the JPEG 2000 signature box. */ - if (length < ARRAY_LENGTH(_jpx_signature) || - memcmp(p, _jpx_signature, ARRAY_LENGTH(_jpx_signature)) != 0) - return CAIRO_INT_STATUS_UNSUPPORTED; - - p += ARRAY_LENGTH(_jpx_signature); - - /* Next box must be a File Type Box */ - if (! _jpx_match_box (p, end, JPX_FILETYPE)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - p = _jpx_next_box (p); - - /* Locate the JP2 header box. */ - p = _jpx_find_box (p, end, JPX_JP2_HEADER); - if (!p) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* Step into the JP2 header box. First box must be the Image - * Header */ - p = _jpx_get_box_contents (p); - if (! _jpx_match_box (p, end, JPX_IMAGE_HEADER)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* Get the image info */ - p = _jpx_get_box_contents (p); - _jpx_extract_info (p, info); - - return CAIRO_STATUS_SUCCESS; -} - -/* PNG (image/png) - * - * http://www.w3.org/TR/2003/REC-PNG-20031110/ - */ - -#define PNG_IHDR 0x49484452 - -static const unsigned char _png_magic[8] = { 137, 80, 78, 71, 13, 10, 26, 10 }; - -cairo_int_status_t -_cairo_image_info_get_png_info (cairo_image_info_t *info, - const unsigned char *data, - unsigned long length) -{ - const unsigned char *p = data; - const unsigned char *end = data + length; - - if (length < 8 || memcmp (data, _png_magic, 8) != 0) - return CAIRO_INT_STATUS_UNSUPPORTED; - - p += 8; - - /* The first chunk must be IDHR. IDHR has 13 bytes of data plus - * the 12 bytes of overhead for the chunk. */ - if (p + 13 + 12 > end) - return CAIRO_INT_STATUS_UNSUPPORTED; - - p += 4; - if (get_unaligned_be32 (p) != PNG_IHDR) - return CAIRO_INT_STATUS_UNSUPPORTED; - - p += 4; - info->width = get_unaligned_be32 (p); - p += 4; - info->height = get_unaligned_be32 (p); - - return CAIRO_STATUS_SUCCESS; -} - -static const unsigned char * -_jbig2_find_data_end (const unsigned char *p, - const unsigned char *end, - int type) -{ - unsigned char end_seq[2]; - int mmr; - - /* Segments of type "Immediate generic region" may have an - * unspecified data length. The JBIG2 specification specifies the - * method to find the end of the data for these segments. */ - if (type == 36 || type == 38 || type == 39) { - if (p + 18 < end) { - mmr = p[17] & 0x01; - if (mmr) { - /* MMR encoding ends with 0x00, 0x00 */ - end_seq[0] = 0x00; - end_seq[1] = 0x00; - } else { - /* Template encoding ends with 0xff, 0xac */ - end_seq[0] = 0xff; - end_seq[1] = 0xac; - } - p += 18; - while (p < end) { - if (p[0] == end_seq[0] && p[1] == end_seq[1]) { - /* Skip the 2 terminating bytes and the 4 byte row count that follows. */ - p += 6; - if (p < end) - return p; - } - p++; - } - } - } - - return NULL; -} - -static const unsigned char * -_jbig2_get_next_segment (const unsigned char *p, - const unsigned char *end, - int *type, - const unsigned char **data, - unsigned long *data_len) -{ - unsigned long seg_num; - cairo_bool_t big_page_size; - int num_segs; - int ref_seg_bytes; - int referred_size; - - if (p + 6 >= end) - return NULL; - - seg_num = get_unaligned_be32 (p); - *type = p[4] & 0x3f; - big_page_size = (p[4] & 0x40) != 0; - p += 5; - - num_segs = p[0] >> 5; - if (num_segs == 7) { - num_segs = get_unaligned_be32 (p) & 0x1fffffff; - ref_seg_bytes = 4 + ((num_segs + 1)/8); - } else { - ref_seg_bytes = 1; - } - p += ref_seg_bytes; - - if (seg_num <= 256) - referred_size = 1; - else if (seg_num <= 65536) - referred_size = 2; - else - referred_size = 4; - - p += num_segs * referred_size; - p += big_page_size ? 4 : 1; - if (p + 4 >= end) - return NULL; - - *data_len = get_unaligned_be32 (p); - p += 4; - *data = p; - - if (*data_len == 0xffffffff) { - /* if data length is -1 we have to scan through the data to find the end */ - p = _jbig2_find_data_end (*data, end, *type); - if (!p || p >= end) - return NULL; - - *data_len = p - *data; - } else { - p += *data_len; - } - - if (p < end) - return p; - else - return NULL; -} - -static void -_jbig2_extract_info (cairo_image_info_t *info, const unsigned char *p) -{ - info->width = get_unaligned_be32 (p); - info->height = get_unaligned_be32 (p + 4); - info->num_components = 1; - info->bits_per_component = 1; -} - -cairo_int_status_t -_cairo_image_info_get_jbig2_info (cairo_image_info_t *info, - const unsigned char *data, - unsigned long length) -{ - const unsigned char *p = data; - const unsigned char *end = data + length; - int seg_type; - const unsigned char *seg_data; - unsigned long seg_data_len; - - while (p && p < end) { - p = _jbig2_get_next_segment (p, end, &seg_type, &seg_data, &seg_data_len); - if (p && seg_type == 48 && seg_data_len > 8) { - /* page information segment */ - _jbig2_extract_info (info, seg_data); - return CAIRO_STATUS_SUCCESS; - } - } - - return CAIRO_INT_STATUS_UNSUPPORTED; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-image-source.c b/source/libs/cairo/cairo-src/src/cairo-image-source.c deleted file mode 100644 index 950053db2c1ebf594c911804380ba0c6c78fadb3..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-image-source.c +++ /dev/null @@ -1,1601 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2003 University of Southern California - * Copyright © 2009,2010,2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -/* The purpose of this file/surface is to simply translate a pattern - * to a pixman_image_t and thence to feed it back to the general - * compositor interface. - */ - -#include "cairoint.h" - -#include "cairo-image-surface-private.h" - -#include "cairo-compositor-private.h" -#include "cairo-error-private.h" -#include "cairo-pattern-inline.h" -#include "cairo-paginated-private.h" -#include "cairo-recording-surface-private.h" -#include "cairo-surface-observer-private.h" -#include "cairo-surface-snapshot-inline.h" -#include "cairo-surface-subsurface-private.h" - -#define PIXMAN_MAX_INT ((pixman_fixed_1 >> 1) - pixman_fixed_e) /* need to ensure deltas also fit */ - -#if CAIRO_NO_MUTEX -#define PIXMAN_HAS_ATOMIC_OPS 1 -#endif - -#if PIXMAN_HAS_ATOMIC_OPS -static pixman_image_t *__pixman_transparent_image; -static pixman_image_t *__pixman_black_image; -static pixman_image_t *__pixman_white_image; - -static pixman_image_t * -_pixman_transparent_image (void) -{ - pixman_image_t *image; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - image = __pixman_transparent_image; - if (unlikely (image == NULL)) { - pixman_color_t color; - - color.red = 0x00; - color.green = 0x00; - color.blue = 0x00; - color.alpha = 0x00; - - image = pixman_image_create_solid_fill (&color); - if (unlikely (image == NULL)) - return NULL; - - if (_cairo_atomic_ptr_cmpxchg (&__pixman_transparent_image, - NULL, image)) - { - pixman_image_ref (image); - } - } else { - pixman_image_ref (image); - } - - return image; -} - -static pixman_image_t * -_pixman_black_image (void) -{ - pixman_image_t *image; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - image = __pixman_black_image; - if (unlikely (image == NULL)) { - pixman_color_t color; - - color.red = 0x00; - color.green = 0x00; - color.blue = 0x00; - color.alpha = 0xffff; - - image = pixman_image_create_solid_fill (&color); - if (unlikely (image == NULL)) - return NULL; - - if (_cairo_atomic_ptr_cmpxchg (&__pixman_black_image, - NULL, image)) - { - pixman_image_ref (image); - } - } else { - pixman_image_ref (image); - } - - return image; -} - -static pixman_image_t * -_pixman_white_image (void) -{ - pixman_image_t *image; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - image = __pixman_white_image; - if (unlikely (image == NULL)) { - pixman_color_t color; - - color.red = 0xffff; - color.green = 0xffff; - color.blue = 0xffff; - color.alpha = 0xffff; - - image = pixman_image_create_solid_fill (&color); - if (unlikely (image == NULL)) - return NULL; - - if (_cairo_atomic_ptr_cmpxchg (&__pixman_white_image, - NULL, image)) - { - pixman_image_ref (image); - } - } else { - pixman_image_ref (image); - } - - return image; -} - -static uint32_t -hars_petruska_f54_1_random (void) -{ -#define rol(x,k) ((x << k) | (x >> (32-k))) - static uint32_t x; - return x = (x ^ rol (x, 5) ^ rol (x, 24)) + 0x37798849; -#undef rol -} - -static struct { - cairo_color_t color; - pixman_image_t *image; -} cache[16]; -static int n_cached; - -#else /* !PIXMAN_HAS_ATOMIC_OPS */ -static pixman_image_t * -_pixman_transparent_image (void) -{ - TRACE ((stderr, "%s\n", __FUNCTION__)); - return _pixman_image_for_color (CAIRO_COLOR_TRANSPARENT); -} - -static pixman_image_t * -_pixman_black_image (void) -{ - TRACE ((stderr, "%s\n", __FUNCTION__)); - return _pixman_image_for_color (CAIRO_COLOR_BLACK); -} - -static pixman_image_t * -_pixman_white_image (void) -{ - TRACE ((stderr, "%s\n", __FUNCTION__)); - return _pixman_image_for_color (CAIRO_COLOR_WHITE); -} -#endif /* !PIXMAN_HAS_ATOMIC_OPS */ - - -pixman_image_t * -_pixman_image_for_color (const cairo_color_t *cairo_color) -{ - pixman_color_t color; - pixman_image_t *image; - -#if PIXMAN_HAS_ATOMIC_OPS - int i; - - if (CAIRO_COLOR_IS_CLEAR (cairo_color)) - return _pixman_transparent_image (); - - if (CAIRO_COLOR_IS_OPAQUE (cairo_color)) { - if (cairo_color->red_short <= 0x00ff && - cairo_color->green_short <= 0x00ff && - cairo_color->blue_short <= 0x00ff) - { - return _pixman_black_image (); - } - - if (cairo_color->red_short >= 0xff00 && - cairo_color->green_short >= 0xff00 && - cairo_color->blue_short >= 0xff00) - { - return _pixman_white_image (); - } - } - - CAIRO_MUTEX_LOCK (_cairo_image_solid_cache_mutex); - for (i = 0; i < n_cached; i++) { - if (_cairo_color_equal (&cache[i].color, cairo_color)) { - image = pixman_image_ref (cache[i].image); - goto UNLOCK; - } - } -#endif - - color.red = cairo_color->red_short; - color.green = cairo_color->green_short; - color.blue = cairo_color->blue_short; - color.alpha = cairo_color->alpha_short; - - image = pixman_image_create_solid_fill (&color); -#if PIXMAN_HAS_ATOMIC_OPS - if (image == NULL) - goto UNLOCK; - - if (n_cached < ARRAY_LENGTH (cache)) { - i = n_cached++; - } else { - i = hars_petruska_f54_1_random () % ARRAY_LENGTH (cache); - pixman_image_unref (cache[i].image); - } - cache[i].image = pixman_image_ref (image); - cache[i].color = *cairo_color; - -UNLOCK: - CAIRO_MUTEX_UNLOCK (_cairo_image_solid_cache_mutex); -#endif - return image; -} - - -void -_cairo_image_reset_static_data (void) -{ -#if PIXMAN_HAS_ATOMIC_OPS - while (n_cached) - pixman_image_unref (cache[--n_cached].image); - - if (__pixman_transparent_image) { - pixman_image_unref (__pixman_transparent_image); - __pixman_transparent_image = NULL; - } - - if (__pixman_black_image) { - pixman_image_unref (__pixman_black_image); - __pixman_black_image = NULL; - } - - if (__pixman_white_image) { - pixman_image_unref (__pixman_white_image); - __pixman_white_image = NULL; - } -#endif -} - -static pixman_image_t * -_pixman_image_for_gradient (const cairo_gradient_pattern_t *pattern, - const cairo_rectangle_int_t *extents, - int *ix, int *iy) -{ - pixman_image_t *pixman_image; - pixman_gradient_stop_t pixman_stops_static[2]; - pixman_gradient_stop_t *pixman_stops = pixman_stops_static; - pixman_transform_t pixman_transform; - cairo_matrix_t matrix; - cairo_circle_double_t extremes[2]; - pixman_point_fixed_t p1, p2; - unsigned int i; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - if (pattern->n_stops > ARRAY_LENGTH(pixman_stops_static)) { - pixman_stops = _cairo_malloc_ab (pattern->n_stops, - sizeof(pixman_gradient_stop_t)); - if (unlikely (pixman_stops == NULL)) - return NULL; - } - - for (i = 0; i < pattern->n_stops; i++) { - pixman_stops[i].x = _cairo_fixed_16_16_from_double (pattern->stops[i].offset); - pixman_stops[i].color.red = pattern->stops[i].color.red_short; - pixman_stops[i].color.green = pattern->stops[i].color.green_short; - pixman_stops[i].color.blue = pattern->stops[i].color.blue_short; - pixman_stops[i].color.alpha = pattern->stops[i].color.alpha_short; - } - - _cairo_gradient_pattern_fit_to_range (pattern, PIXMAN_MAX_INT >> 1, &matrix, extremes); - - p1.x = _cairo_fixed_16_16_from_double (extremes[0].center.x); - p1.y = _cairo_fixed_16_16_from_double (extremes[0].center.y); - p2.x = _cairo_fixed_16_16_from_double (extremes[1].center.x); - p2.y = _cairo_fixed_16_16_from_double (extremes[1].center.y); - - if (pattern->base.type == CAIRO_PATTERN_TYPE_LINEAR) { - pixman_image = pixman_image_create_linear_gradient (&p1, &p2, - pixman_stops, - pattern->n_stops); - } else { - pixman_fixed_t r1, r2; - - r1 = _cairo_fixed_16_16_from_double (extremes[0].radius); - r2 = _cairo_fixed_16_16_from_double (extremes[1].radius); - - pixman_image = pixman_image_create_radial_gradient (&p1, &p2, r1, r2, - pixman_stops, - pattern->n_stops); - } - - if (pixman_stops != pixman_stops_static) - free (pixman_stops); - - if (unlikely (pixman_image == NULL)) - return NULL; - - *ix = *iy = 0; - status = _cairo_matrix_to_pixman_matrix_offset (&matrix, pattern->base.filter, - extents->x + extents->width/2., - extents->y + extents->height/2., - &pixman_transform, ix, iy); - if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) { - if (unlikely (status != CAIRO_INT_STATUS_SUCCESS) || - ! pixman_image_set_transform (pixman_image, &pixman_transform)) - { - pixman_image_unref (pixman_image); - return NULL; - } - } - - { - pixman_repeat_t pixman_repeat; - - switch (pattern->base.extend) { - default: - case CAIRO_EXTEND_NONE: - pixman_repeat = PIXMAN_REPEAT_NONE; - break; - case CAIRO_EXTEND_REPEAT: - pixman_repeat = PIXMAN_REPEAT_NORMAL; - break; - case CAIRO_EXTEND_REFLECT: - pixman_repeat = PIXMAN_REPEAT_REFLECT; - break; - case CAIRO_EXTEND_PAD: - pixman_repeat = PIXMAN_REPEAT_PAD; - break; - } - - pixman_image_set_repeat (pixman_image, pixman_repeat); - } - - return pixman_image; -} - -static pixman_image_t * -_pixman_image_for_mesh (const cairo_mesh_pattern_t *pattern, - const cairo_rectangle_int_t *extents, - int *tx, int *ty) -{ - pixman_image_t *image; - int width, height; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - *tx = -extents->x; - *ty = -extents->y; - width = extents->width; - height = extents->height; - - image = pixman_image_create_bits (PIXMAN_a8r8g8b8, width, height, NULL, 0); - if (unlikely (image == NULL)) - return NULL; - - _cairo_mesh_pattern_rasterize (pattern, - pixman_image_get_data (image), - width, height, - pixman_image_get_stride (image), - *tx, *ty); - return image; -} - -struct acquire_source_cleanup { - cairo_surface_t *surface; - cairo_image_surface_t *image; - void *image_extra; -}; - -static void -_acquire_source_cleanup (pixman_image_t *pixman_image, - void *closure) -{ - struct acquire_source_cleanup *data = closure; - - _cairo_surface_release_source_image (data->surface, - data->image, - data->image_extra); - free (data); -} - -static void -_defer_free_cleanup (pixman_image_t *pixman_image, - void *closure) -{ - cairo_surface_destroy (closure); -} - -static uint16_t -expand_channel (uint16_t v, uint32_t bits) -{ - int offset = 16 - bits; - while (offset > 0) { - v |= v >> bits; - offset -= bits; - bits += bits; - } - return v; -} - -static pixman_image_t * -_pixel_to_solid (cairo_image_surface_t *image, int x, int y) -{ - uint32_t pixel; - pixman_color_t color; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - switch (image->format) { - default: - case CAIRO_FORMAT_INVALID: - ASSERT_NOT_REACHED; - return NULL; - - case CAIRO_FORMAT_A1: - pixel = *(uint8_t *) (image->data + y * image->stride + x/8); - return pixel & (1 << (x&7)) ? _pixman_black_image () : _pixman_transparent_image (); - - case CAIRO_FORMAT_A8: - color.alpha = *(uint8_t *) (image->data + y * image->stride + x); - color.alpha |= color.alpha << 8; - if (color.alpha == 0) - return _pixman_transparent_image (); - if (color.alpha == 0xffff) - return _pixman_black_image (); - - color.red = color.green = color.blue = 0; - return pixman_image_create_solid_fill (&color); - - case CAIRO_FORMAT_RGB16_565: - pixel = *(uint16_t *) (image->data + y * image->stride + 2 * x); - if (pixel == 0) - return _pixman_black_image (); - if (pixel == 0xffff) - return _pixman_white_image (); - - color.alpha = 0xffff; - color.red = expand_channel ((pixel >> 11 & 0x1f) << 11, 5); - color.green = expand_channel ((pixel >> 5 & 0x3f) << 10, 6); - color.blue = expand_channel ((pixel & 0x1f) << 11, 5); - return pixman_image_create_solid_fill (&color); - - case CAIRO_FORMAT_RGB30: - pixel = *(uint32_t *) (image->data + y * image->stride + 4 * x); - pixel &= 0x3fffffff; /* ignore alpha bits */ - if (pixel == 0) - return _pixman_black_image (); - if (pixel == 0x3fffffff) - return _pixman_white_image (); - - /* convert 10bpc to 16bpc */ - color.alpha = 0xffff; - color.red = expand_channel((pixel >> 20) & 0x3fff, 10); - color.green = expand_channel((pixel >> 10) & 0x3fff, 10); - color.blue = expand_channel(pixel & 0x3fff, 10); - return pixman_image_create_solid_fill (&color); - - case CAIRO_FORMAT_ARGB32: - case CAIRO_FORMAT_RGB24: - pixel = *(uint32_t *) (image->data + y * image->stride + 4 * x); - color.alpha = image->format == CAIRO_FORMAT_ARGB32 ? (pixel >> 24) | (pixel >> 16 & 0xff00) : 0xffff; - if (color.alpha == 0) - return _pixman_transparent_image (); - if (pixel == 0xffffffff) - return _pixman_white_image (); - if (color.alpha == 0xffff && (pixel & 0xffffff) == 0) - return _pixman_black_image (); - - color.red = (pixel >> 16 & 0xff) | (pixel >> 8 & 0xff00); - color.green = (pixel >> 8 & 0xff) | (pixel & 0xff00); - color.blue = (pixel & 0xff) | (pixel << 8 & 0xff00); - return pixman_image_create_solid_fill (&color); - } -} - -/* ========================================================================== */ - -/* Index into filter table */ -typedef enum -{ - KERNEL_IMPULSE, - KERNEL_BOX, - KERNEL_LINEAR, - KERNEL_MITCHELL, - KERNEL_NOTCH, - KERNEL_CATMULL_ROM, - KERNEL_LANCZOS3, - KERNEL_LANCZOS3_STRETCHED, - KERNEL_TENT -} kernel_t; - -/* Produce contribution of a filter of size r for pixel centered on x. - For a typical low-pass function this evaluates the function at x/r. - If the frequency is higher than 1/2, such as when r is less than 1, - this may need to integrate several samples, see cubic for examples. -*/ -typedef double (* kernel_func_t) (double x, double r); - -/* Return maximum number of pixels that will be non-zero. Except for - impluse this is the maximum of 2 and the width of the non-zero part - of the filter rounded up to the next integer. -*/ -typedef int (* kernel_width_func_t) (double r); - -/* Table of filters */ -typedef struct -{ - kernel_t kernel; - kernel_func_t func; - kernel_width_func_t width; -} filter_info_t; - -/* PIXMAN_KERNEL_IMPULSE: Returns pixel nearest the center. This - matches PIXMAN_FILTER_NEAREST. This is useful if you wish to - combine the result of nearest in one direction with another filter - in the other. -*/ - -static double -impulse_kernel (double x, double r) -{ - return 1; -} - -static int -impulse_width (double r) -{ - return 1; -} - -/* PIXMAN_KERNEL_BOX: Intersection of a box of width r with square - pixels. This is the smallest possible filter such that the output - image contains an equal contribution from all the input - pixels. Lots of software uses this. The function is a trapazoid of - width r+1, not a box. - - When r == 1.0, PIXMAN_KERNEL_BOX, PIXMAN_KERNEL_LINEAR, and - PIXMAN_KERNEL_TENT all produce the same filter, allowing - them to be exchanged at this point. -*/ - -static double -box_kernel (double x, double r) -{ - return MAX (0.0, MIN (MIN (r, 1.0), - MIN ((r + 1) / 2 - x, (r + 1) / 2 + x))); -} - -static int -box_width (double r) -{ - return r < 1.0 ? 2 : ceil(r + 1); -} - -/* PIXMAN_KERNEL_LINEAR: Weighted sum of the two pixels nearest the - center, or a triangle of width 2. This matches - PIXMAN_FILTER_BILINEAR. This is useful if you wish to combine the - result of bilinear in one direction with another filter in the - other. This is not a good filter if r > 1. You may actually want - PIXMAN_FILTER_TENT. - - When r == 1.0, PIXMAN_KERNEL_BOX, PIXMAN_KERNEL_LINEAR, and - PIXMAN_KERNEL_TENT all produce the same filter, allowing - them to be exchanged at this point. -*/ - -static double -linear_kernel (double x, double r) -{ - return MAX (1.0 - fabs(x), 0.0); -} - -static int -linear_width (double r) -{ - return 2; -} - -/* Cubic functions described in the Mitchell-Netravali paper. - http://mentallandscape.com/Papers_siggraph88.pdf. This describes - all possible cubic functions that can be used for sampling. -*/ - -static double -general_cubic (double x, double r, double B, double C) -{ - double ax; - if (r < 1.0) - return - general_cubic(x * 2 - .5, r * 2, B, C) + - general_cubic(x * 2 + .5, r * 2, B, C); - - ax = fabs (x / r); - - if (ax < 1) - { - return (((12 - 9 * B - 6 * C) * ax + - (-18 + 12 * B + 6 * C)) * ax * ax + - (6 - 2 * B)) / 6; - } - else if (ax < 2) - { - return ((((-B - 6 * C) * ax + - (6 * B + 30 * C)) * ax + - (-12 * B - 48 * C)) * ax + - (8 * B + 24 * C)) / 6; - } - else - { - return 0.0; - } -} - -static int -cubic_width (double r) -{ - return MAX (2, ceil (r * 4)); -} - -/* PIXMAN_KERNEL_CATMULL_ROM: Catmull-Rom interpolation. Often called - "cubic interpolation", "b-spline", or just "cubic" by other - software. This filter has negative values so it can produce ringing - and output pixels outside the range of input pixels. This is very - close to lanczos2 so there is no reason to supply that as well. -*/ - -static double -cubic_kernel (double x, double r) -{ - return general_cubic (x, r, 0.0, 0.5); -} - -/* PIXMAN_KERNEL_MITCHELL: Cubic recommended by the Mitchell-Netravali - paper. This has negative values and because the values at +/-1 are - not zero it does not interpolate the pixels, meaning it will change - an image even if there is no translation. -*/ - -static double -mitchell_kernel (double x, double r) -{ - return general_cubic (x, r, 1/3.0, 1/3.0); -} - -/* PIXMAN_KERNEL_NOTCH: Cubic recommended by the Mitchell-Netravali - paper to remove postaliasing artifacts. This does not remove - aliasing already present in the source image, though it may appear - to due to it's excessive blurriness. In any case this is more - useful than gaussian for image reconstruction. -*/ - -static double -notch_kernel (double x, double r) -{ - return general_cubic (x, r, 1.5, -0.25); -} - -/* PIXMAN_KERNEL_LANCZOS3: lanczos windowed sinc function from -3 to - +3. Very popular with high-end software though I think any - advantage over cubics is hidden by quantization and programming - mistakes. You will see LANCZOS5 or even 7 sometimes. -*/ - -static double -sinc (double x) -{ - return x ? sin (M_PI * x) / (M_PI * x) : 1.0; -} - -static double -lanczos (double x, double n) -{ - return fabs (x) < n ? sinc (x) * sinc (x * (1.0 / n)) : 0.0; -} - -static double -lanczos3_kernel (double x, double r) -{ - if (r < 1.0) - return - lanczos3_kernel (x * 2 - .5, r * 2) + - lanczos3_kernel (x * 2 + .5, r * 2); - else - return lanczos (x / r, 3.0); -} - -static int -lanczos3_width (double r) -{ - return MAX (2, ceil (r * 6)); -} - -/* PIXMAN_KERNEL_LANCZOS3_STRETCHED - The LANCZOS3 kernel widened by - 4/3. Recommended by Jim Blinn - http://graphics.cs.cmu.edu/nsp/course/15-462/Fall07/462/papers/jaggy.pdf -*/ - -static double -nice_kernel (double x, double r) -{ - return lanczos3_kernel (x, r * (4.0/3)); -} - -static int -nice_width (double r) -{ - return MAX (2.0, ceil (r * 8)); -} - -/* PIXMAN_KERNEL_TENT: Triangle of width 2r. Lots of software uses - this as a "better" filter, twice the size of a box but smaller than - a cubic. - - When r == 1.0, PIXMAN_KERNEL_BOX, PIXMAN_KERNEL_LINEAR, and - PIXMAN_KERNEL_TENT all produce the same filter, allowing - them to be exchanged at this point. -*/ - -static double -tent_kernel (double x, double r) -{ - if (r < 1.0) - return box_kernel(x, r); - else - return MAX (1.0 - fabs(x / r), 0.0); -} - -static int -tent_width (double r) -{ - return r < 1.0 ? 2 : ceil(2 * r); -} - - -static const filter_info_t filters[] = -{ - { KERNEL_IMPULSE, impulse_kernel, impulse_width }, - { KERNEL_BOX, box_kernel, box_width }, - { KERNEL_LINEAR, linear_kernel, linear_width }, - { KERNEL_MITCHELL, mitchell_kernel, cubic_width }, - { KERNEL_NOTCH, notch_kernel, cubic_width }, - { KERNEL_CATMULL_ROM, cubic_kernel, cubic_width }, - { KERNEL_LANCZOS3, lanczos3_kernel, lanczos3_width }, - { KERNEL_LANCZOS3_STRETCHED,nice_kernel, nice_width }, - { KERNEL_TENT, tent_kernel, tent_width } -}; - -/* Fills in one dimension of the filter array */ -static void get_filter(kernel_t filter, double r, - int width, int subsample, - pixman_fixed_t* out) -{ - int i; - pixman_fixed_t *p = out; - int n_phases = 1 << subsample; - double step = 1.0 / n_phases; - kernel_func_t func = filters[filter].func; - - /* special-case the impulse filter: */ - if (width <= 1) - { - for (i = 0; i < n_phases; ++i) - *p++ = pixman_fixed_1; - return; - } - - for (i = 0; i < n_phases; ++i) - { - double frac = (i + .5) * step; - /* Center of left-most pixel: */ - double x1 = ceil (frac - width / 2.0 - 0.5) - frac + 0.5; - double total = 0; - pixman_fixed_t new_total = 0; - int j; - - for (j = 0; j < width; ++j) - { - double v = func(x1 + j, r); - total += v; - p[j] = pixman_double_to_fixed (v); - } - - /* Normalize */ - total = 1 / total; - for (j = 0; j < width; ++j) - new_total += (p[j] *= total); - - /* Put any error on center pixel */ - p[width / 2] += (pixman_fixed_1 - new_total); - - p += width; - } -} - - -/* Create the parameter list for a SEPARABLE_CONVOLUTION filter - * with the given kernels and scale parameters. - */ -static pixman_fixed_t * -create_separable_convolution (int *n_values, - kernel_t xfilter, - double sx, - kernel_t yfilter, - double sy) -{ - int xwidth, xsubsample, ywidth, ysubsample, size_x, size_y; - pixman_fixed_t *params; - - xwidth = filters[xfilter].width(sx); - xsubsample = 0; - if (xwidth > 1) - while (sx * (1 << xsubsample) <= 128.0) xsubsample++; - size_x = (1 << xsubsample) * xwidth; - - ywidth = filters[yfilter].width(sy); - ysubsample = 0; - if (ywidth > 1) - while (sy * (1 << ysubsample) <= 128.0) ysubsample++; - size_y = (1 << ysubsample) * ywidth; - - *n_values = 4 + size_x + size_y; - params = malloc (*n_values * sizeof (pixman_fixed_t)); - if (!params) return 0; - - params[0] = pixman_int_to_fixed (xwidth); - params[1] = pixman_int_to_fixed (ywidth); - params[2] = pixman_int_to_fixed (xsubsample); - params[3] = pixman_int_to_fixed (ysubsample); - - get_filter(xfilter, sx, xwidth, xsubsample, params + 4); - get_filter(yfilter, sy, ywidth, ysubsample, params + 4 + size_x); - - return params; -} - -/* ========================================================================== */ - -static cairo_bool_t -_pixman_image_set_properties (pixman_image_t *pixman_image, - const cairo_pattern_t *pattern, - const cairo_rectangle_int_t *extents, - int *ix,int *iy) -{ - pixman_transform_t pixman_transform; - cairo_int_status_t status; - - status = _cairo_matrix_to_pixman_matrix_offset (&pattern->matrix, - pattern->filter, - extents->x + extents->width/2., - extents->y + extents->height/2., - &pixman_transform, ix, iy); - if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) - { - /* If the transform is an identity, we don't need to set it - * and we can use any filtering, so choose the fastest one. */ - pixman_image_set_filter (pixman_image, PIXMAN_FILTER_NEAREST, NULL, 0); - } - else if (unlikely (status != CAIRO_INT_STATUS_SUCCESS || - ! pixman_image_set_transform (pixman_image, - &pixman_transform))) - { - return FALSE; - } - else - { - pixman_filter_t pixman_filter; - kernel_t kernel; - double dx, dy; - - /* Compute scale factors from the pattern matrix. These scale - * factors are from user to pattern space, and as such they - * are greater than 1.0 for downscaling and less than 1.0 for - * upscaling. The factors are the size of an axis-aligned - * rectangle with the same area as the parallelgram a 1x1 - * square transforms to. - */ - dx = hypot (pattern->matrix.xx, pattern->matrix.xy); - dy = hypot (pattern->matrix.yx, pattern->matrix.yy); - - /* Clip at maximum pixman_fixed number. Besides making it - * passable to pixman, this avoids errors from inf and nan. - */ - if (! (dx < 0x7FFF)) dx = 0x7FFF; - if (! (dy < 0x7FFF)) dy = 0x7FFF; - - switch (pattern->filter) { - case CAIRO_FILTER_FAST: - pixman_filter = PIXMAN_FILTER_FAST; - break; - case CAIRO_FILTER_GOOD: - pixman_filter = PIXMAN_FILTER_SEPARABLE_CONVOLUTION; - kernel = KERNEL_BOX; - /* Clip the filter size to prevent extreme slowness. This - value could be raised if 2-pass filtering is done */ - if (dx > 16.0) dx = 16.0; - if (dy > 16.0) dy = 16.0; - /* Match the bilinear filter for scales > .75: */ - if (dx < 1.0/0.75) dx = 1.0; - if (dy < 1.0/0.75) dy = 1.0; - break; - case CAIRO_FILTER_BEST: - pixman_filter = PIXMAN_FILTER_SEPARABLE_CONVOLUTION; - kernel = KERNEL_CATMULL_ROM; /* LANCZOS3 is better but not much */ - /* Clip the filter size to prevent extreme slowness. This - value could be raised if 2-pass filtering is done */ - if (dx > 16.0) { dx = 16.0; kernel = KERNEL_BOX; } - /* blur up to 2x scale, then blend to square pixels for larger: */ - else if (dx < 1.0) { - if (dx < 1.0/128) dx = 1.0/127; - else if (dx < 0.5) dx = 1.0 / (1.0 / dx - 1.0); - else dx = 1.0; - } - if (dy > 16.0) { dy = 16.0; kernel = KERNEL_BOX; } - else if (dy < 1.0) { - if (dy < 1.0/128) dy = 1.0/127; - else if (dy < 0.5) dy = 1.0 / (1.0 / dy - 1.0); - else dy = 1.0; - } - break; - case CAIRO_FILTER_NEAREST: - pixman_filter = PIXMAN_FILTER_NEAREST; - break; - case CAIRO_FILTER_BILINEAR: - pixman_filter = PIXMAN_FILTER_BILINEAR; - break; - case CAIRO_FILTER_GAUSSIAN: - /* XXX: The GAUSSIAN value has no implementation in cairo - * whatsoever, so it was really a mistake to have it in the - * API. We could fix this by officially deprecating it, or - * else inventing semantics and providing an actual - * implementation for it. */ - default: - pixman_filter = PIXMAN_FILTER_BEST; - } - - if (pixman_filter == PIXMAN_FILTER_SEPARABLE_CONVOLUTION) { - int n_params; - pixman_fixed_t *params; - params = create_separable_convolution - (&n_params, kernel, dx, kernel, dy); - pixman_image_set_filter (pixman_image, pixman_filter, - params, n_params); - free (params); - } else { - pixman_image_set_filter (pixman_image, pixman_filter, NULL, 0); - } - } - - { - pixman_repeat_t pixman_repeat; - - switch (pattern->extend) { - default: - case CAIRO_EXTEND_NONE: - pixman_repeat = PIXMAN_REPEAT_NONE; - break; - case CAIRO_EXTEND_REPEAT: - pixman_repeat = PIXMAN_REPEAT_NORMAL; - break; - case CAIRO_EXTEND_REFLECT: - pixman_repeat = PIXMAN_REPEAT_REFLECT; - break; - case CAIRO_EXTEND_PAD: - pixman_repeat = PIXMAN_REPEAT_PAD; - break; - } - - pixman_image_set_repeat (pixman_image, pixman_repeat); - } - - if (pattern->has_component_alpha) - pixman_image_set_component_alpha (pixman_image, TRUE); - - return TRUE; -} - -struct proxy { - cairo_surface_t base; - cairo_surface_t *image; -}; - -static cairo_status_t -proxy_acquire_source_image (void *abstract_surface, - cairo_image_surface_t **image_out, - void **image_extra) -{ - struct proxy *proxy = abstract_surface; - return _cairo_surface_acquire_source_image (proxy->image, image_out, image_extra); -} - -static void -proxy_release_source_image (void *abstract_surface, - cairo_image_surface_t *image, - void *image_extra) -{ - struct proxy *proxy = abstract_surface; - _cairo_surface_release_source_image (proxy->image, image, image_extra); -} - -static cairo_status_t -proxy_finish (void *abstract_surface) -{ - return CAIRO_STATUS_SUCCESS; -} - -static const cairo_surface_backend_t proxy_backend = { - CAIRO_INTERNAL_SURFACE_TYPE_NULL, - proxy_finish, - NULL, - - NULL, /* create similar */ - NULL, /* create similar image */ - NULL, /* map to image */ - NULL, /* unmap image */ - - _cairo_surface_default_source, - proxy_acquire_source_image, - proxy_release_source_image, -}; - -static cairo_surface_t * -attach_proxy (cairo_surface_t *source, - cairo_surface_t *image) -{ - struct proxy *proxy; - - proxy = malloc (sizeof (*proxy)); - if (unlikely (proxy == NULL)) - return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_surface_init (&proxy->base, &proxy_backend, NULL, image->content); - - proxy->image = image; - _cairo_surface_attach_snapshot (source, &proxy->base, NULL); - - return &proxy->base; -} - -static void -detach_proxy (cairo_surface_t *source, - cairo_surface_t *proxy) -{ - cairo_surface_finish (proxy); - cairo_surface_destroy (proxy); -} - -static cairo_surface_t * -get_proxy (cairo_surface_t *proxy) -{ - return ((struct proxy *)proxy)->image; -} - -static pixman_image_t * -_pixman_image_for_recording (cairo_image_surface_t *dst, - const cairo_surface_pattern_t *pattern, - cairo_bool_t is_mask, - const cairo_rectangle_int_t *extents, - const cairo_rectangle_int_t *sample, - int *ix, int *iy) -{ - cairo_surface_t *source, *clone, *proxy; - cairo_rectangle_int_t limit; - pixman_image_t *pixman_image; - cairo_status_t status; - cairo_extend_t extend; - cairo_matrix_t *m, matrix; - int tx = 0, ty = 0; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - *ix = *iy = 0; - - source = _cairo_pattern_get_source (pattern, &limit); - - extend = pattern->base.extend; - if (_cairo_rectangle_contains_rectangle (&limit, sample)) - extend = CAIRO_EXTEND_NONE; - if (extend == CAIRO_EXTEND_NONE) { - if (! _cairo_rectangle_intersect (&limit, sample)) - return _pixman_transparent_image (); - - if (! _cairo_matrix_is_identity (&pattern->base.matrix)) { - double x1, y1, x2, y2; - - matrix = pattern->base.matrix; - status = cairo_matrix_invert (&matrix); - assert (status == CAIRO_STATUS_SUCCESS); - - x1 = limit.x; - y1 = limit.y; - x2 = limit.x + limit.width; - y2 = limit.y + limit.height; - - _cairo_matrix_transform_bounding_box (&matrix, - &x1, &y1, &x2, &y2, NULL); - - limit.x = floor (x1); - limit.y = floor (y1); - limit.width = ceil (x2) - limit.x; - limit.height = ceil (y2) - limit.y; - } - } - tx = limit.x; - ty = limit.y; - - /* XXX transformations! */ - proxy = _cairo_surface_has_snapshot (source, &proxy_backend); - if (proxy != NULL) { - clone = cairo_surface_reference (get_proxy (proxy)); - goto done; - } - - if (is_mask) { - clone = cairo_image_surface_create (CAIRO_FORMAT_A8, - limit.width, limit.height); - } else { - if (dst->base.content == source->content) - clone = cairo_image_surface_create (dst->format, - limit.width, limit.height); - else - clone = _cairo_image_surface_create_with_content (source->content, - limit.width, - limit.height); - } - - m = NULL; - if (extend == CAIRO_EXTEND_NONE) { - matrix = pattern->base.matrix; - if (tx | ty) - cairo_matrix_translate (&matrix, tx, ty); - m = &matrix; - } else { - /* XXX extract scale factor for repeating patterns */ - } - - /* Handle recursion by returning future reads from the current image */ - proxy = attach_proxy (source, clone); - status = _cairo_recording_surface_replay_with_clip (source, m, clone, NULL); - detach_proxy (source, proxy); - if (unlikely (status)) { - cairo_surface_destroy (clone); - return NULL; - } - -done: - pixman_image = pixman_image_ref (((cairo_image_surface_t *)clone)->pixman_image); - cairo_surface_destroy (clone); - - *ix = -limit.x; - *iy = -limit.y; - if (extend != CAIRO_EXTEND_NONE) { - if (! _pixman_image_set_properties (pixman_image, - &pattern->base, extents, - ix, iy)) { - pixman_image_unref (pixman_image); - pixman_image= NULL; - } - } - - return pixman_image; -} - -static pixman_image_t * -_pixman_image_for_surface (cairo_image_surface_t *dst, - const cairo_surface_pattern_t *pattern, - cairo_bool_t is_mask, - const cairo_rectangle_int_t *extents, - const cairo_rectangle_int_t *sample, - int *ix, int *iy) -{ - cairo_extend_t extend = pattern->base.extend; - pixman_image_t *pixman_image; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - *ix = *iy = 0; - pixman_image = NULL; - if (pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING) - return _pixman_image_for_recording(dst, pattern, - is_mask, extents, sample, - ix, iy); - - if (pattern->surface->type == CAIRO_SURFACE_TYPE_IMAGE && - (! is_mask || ! pattern->base.has_component_alpha || - (pattern->surface->content & CAIRO_CONTENT_COLOR) == 0)) - { - cairo_surface_t *defer_free = NULL; - cairo_image_surface_t *source = (cairo_image_surface_t *) pattern->surface; - cairo_surface_type_t type; - - if (_cairo_surface_is_snapshot (&source->base)) { - defer_free = _cairo_surface_snapshot_get_target (&source->base); - source = (cairo_image_surface_t *) defer_free; - } - - type = source->base.backend->type; - if (type == CAIRO_SURFACE_TYPE_IMAGE) { - if (extend != CAIRO_EXTEND_NONE && - sample->x >= 0 && - sample->y >= 0 && - sample->x + sample->width <= source->width && - sample->y + sample->height <= source->height) - { - extend = CAIRO_EXTEND_NONE; - } - - if (sample->width == 1 && sample->height == 1) { - if (sample->x < 0 || - sample->y < 0 || - sample->x >= source->width || - sample->y >= source->height) - { - if (extend == CAIRO_EXTEND_NONE) { - cairo_surface_destroy (defer_free); - return _pixman_transparent_image (); - } - } - else - { - pixman_image = _pixel_to_solid (source, - sample->x, sample->y); - if (pixman_image) { - cairo_surface_destroy (defer_free); - return pixman_image; - } - } - } - -#if PIXMAN_HAS_ATOMIC_OPS - /* avoid allocating a 'pattern' image if we can reuse the original */ - if (extend == CAIRO_EXTEND_NONE && - _cairo_matrix_is_pixman_translation (&pattern->base.matrix, - pattern->base.filter, - ix, iy)) - { - cairo_surface_destroy (defer_free); - return pixman_image_ref (source->pixman_image); - } -#endif - - pixman_image = pixman_image_create_bits (source->pixman_format, - source->width, - source->height, - (uint32_t *) source->data, - source->stride); - if (unlikely (pixman_image == NULL)) { - cairo_surface_destroy (defer_free); - return NULL; - } - - if (defer_free) { - pixman_image_set_destroy_function (pixman_image, - _defer_free_cleanup, - defer_free); - } - } else if (type == CAIRO_SURFACE_TYPE_SUBSURFACE) { - cairo_surface_subsurface_t *sub; - cairo_bool_t is_contained = FALSE; - - sub = (cairo_surface_subsurface_t *) source; - source = (cairo_image_surface_t *) sub->target; - - if (sample->x >= 0 && - sample->y >= 0 && - sample->x + sample->width <= sub->extents.width && - sample->y + sample->height <= sub->extents.height) - { - is_contained = TRUE; - } - - if (sample->width == 1 && sample->height == 1) { - if (is_contained) { - pixman_image = _pixel_to_solid (source, - sub->extents.x + sample->x, - sub->extents.y + sample->y); - if (pixman_image) - return pixman_image; - } else { - if (extend == CAIRO_EXTEND_NONE) - return _pixman_transparent_image (); - } - } - -#if PIXMAN_HAS_ATOMIC_OPS - *ix = sub->extents.x; - *iy = sub->extents.y; - if (is_contained && - _cairo_matrix_is_pixman_translation (&pattern->base.matrix, - pattern->base.filter, - ix, iy)) - { - return pixman_image_ref (source->pixman_image); - } -#endif - - /* Avoid sub-byte offsets, force a copy in that case. */ - if (PIXMAN_FORMAT_BPP (source->pixman_format) >= 8) { - if (is_contained) { - void *data = source->data - + sub->extents.x * PIXMAN_FORMAT_BPP(source->pixman_format)/8 - + sub->extents.y * source->stride; - pixman_image = pixman_image_create_bits (source->pixman_format, - sub->extents.width, - sub->extents.height, - data, - source->stride); - if (unlikely (pixman_image == NULL)) - return NULL; - } else { - /* XXX for a simple translation and EXTEND_NONE we can - * fix up the pattern matrix instead. - */ - } - } - } - } - - if (pixman_image == NULL) { - struct acquire_source_cleanup *cleanup; - cairo_image_surface_t *image; - void *extra; - cairo_status_t status; - - status = _cairo_surface_acquire_source_image (pattern->surface, &image, &extra); - if (unlikely (status)) - return NULL; - - pixman_image = pixman_image_create_bits (image->pixman_format, - image->width, - image->height, - (uint32_t *) image->data, - image->stride); - if (unlikely (pixman_image == NULL)) { - _cairo_surface_release_source_image (pattern->surface, image, extra); - return NULL; - } - - cleanup = malloc (sizeof (*cleanup)); - if (unlikely (cleanup == NULL)) { - _cairo_surface_release_source_image (pattern->surface, image, extra); - pixman_image_unref (pixman_image); - return NULL; - } - - cleanup->surface = pattern->surface; - cleanup->image = image; - cleanup->image_extra = extra; - pixman_image_set_destroy_function (pixman_image, - _acquire_source_cleanup, cleanup); - } - - if (! _pixman_image_set_properties (pixman_image, - &pattern->base, extents, - ix, iy)) { - pixman_image_unref (pixman_image); - pixman_image= NULL; - } - - return pixman_image; -} - -struct raster_source_cleanup { - const cairo_pattern_t *pattern; - cairo_surface_t *surface; - cairo_image_surface_t *image; - void *image_extra; -}; - -static void -_raster_source_cleanup (pixman_image_t *pixman_image, - void *closure) -{ - struct raster_source_cleanup *data = closure; - - _cairo_surface_release_source_image (data->surface, - data->image, - data->image_extra); - - _cairo_raster_source_pattern_release (data->pattern, - data->surface); - - free (data); -} - -static pixman_image_t * -_pixman_image_for_raster (cairo_image_surface_t *dst, - const cairo_raster_source_pattern_t *pattern, - cairo_bool_t is_mask, - const cairo_rectangle_int_t *extents, - const cairo_rectangle_int_t *sample, - int *ix, int *iy) -{ - pixman_image_t *pixman_image; - struct raster_source_cleanup *cleanup; - cairo_image_surface_t *image; - void *extra; - cairo_status_t status; - cairo_surface_t *surface; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - *ix = *iy = 0; - - surface = _cairo_raster_source_pattern_acquire (&pattern->base, - &dst->base, NULL); - if (unlikely (surface == NULL || surface->status)) - return NULL; - - status = _cairo_surface_acquire_source_image (surface, &image, &extra); - if (unlikely (status)) { - _cairo_raster_source_pattern_release (&pattern->base, surface); - return NULL; - } - - assert (image->width == pattern->extents.width); - assert (image->height == pattern->extents.height); - - pixman_image = pixman_image_create_bits (image->pixman_format, - image->width, - image->height, - (uint32_t *) image->data, - image->stride); - if (unlikely (pixman_image == NULL)) { - _cairo_surface_release_source_image (surface, image, extra); - _cairo_raster_source_pattern_release (&pattern->base, surface); - return NULL; - } - - cleanup = malloc (sizeof (*cleanup)); - if (unlikely (cleanup == NULL)) { - pixman_image_unref (pixman_image); - _cairo_surface_release_source_image (surface, image, extra); - _cairo_raster_source_pattern_release (&pattern->base, surface); - return NULL; - } - - cleanup->pattern = &pattern->base; - cleanup->surface = surface; - cleanup->image = image; - cleanup->image_extra = extra; - pixman_image_set_destroy_function (pixman_image, - _raster_source_cleanup, cleanup); - - if (! _pixman_image_set_properties (pixman_image, - &pattern->base, extents, - ix, iy)) { - pixman_image_unref (pixman_image); - pixman_image= NULL; - } - - return pixman_image; -} - -pixman_image_t * -_pixman_image_for_pattern (cairo_image_surface_t *dst, - const cairo_pattern_t *pattern, - cairo_bool_t is_mask, - const cairo_rectangle_int_t *extents, - const cairo_rectangle_int_t *sample, - int *tx, int *ty) -{ - *tx = *ty = 0; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - if (pattern == NULL) - return _pixman_white_image (); - - switch (pattern->type) { - default: - ASSERT_NOT_REACHED; - case CAIRO_PATTERN_TYPE_SOLID: - return _pixman_image_for_color (&((const cairo_solid_pattern_t *) pattern)->color); - - case CAIRO_PATTERN_TYPE_RADIAL: - case CAIRO_PATTERN_TYPE_LINEAR: - return _pixman_image_for_gradient ((const cairo_gradient_pattern_t *) pattern, - extents, tx, ty); - - case CAIRO_PATTERN_TYPE_MESH: - return _pixman_image_for_mesh ((const cairo_mesh_pattern_t *) pattern, - extents, tx, ty); - - case CAIRO_PATTERN_TYPE_SURFACE: - return _pixman_image_for_surface (dst, - (const cairo_surface_pattern_t *) pattern, - is_mask, extents, sample, - tx, ty); - - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - return _pixman_image_for_raster (dst, - (const cairo_raster_source_pattern_t *) pattern, - is_mask, extents, sample, - tx, ty); - } -} - -static cairo_status_t -_cairo_image_source_finish (void *abstract_surface) -{ - cairo_image_source_t *source = abstract_surface; - - pixman_image_unref (source->pixman_image); - return CAIRO_STATUS_SUCCESS; -} - -const cairo_surface_backend_t _cairo_image_source_backend = { - CAIRO_SURFACE_TYPE_IMAGE, - _cairo_image_source_finish, - NULL, /* read-only wrapper */ -}; - -cairo_surface_t * -_cairo_image_source_create_for_pattern (cairo_surface_t *dst, - const cairo_pattern_t *pattern, - cairo_bool_t is_mask, - const cairo_rectangle_int_t *extents, - const cairo_rectangle_int_t *sample, - int *src_x, int *src_y) -{ - cairo_image_source_t *source; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - source = malloc (sizeof (cairo_image_source_t)); - if (unlikely (source == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - source->pixman_image = - _pixman_image_for_pattern ((cairo_image_surface_t *)dst, - pattern, is_mask, - extents, sample, - src_x, src_y); - if (unlikely (source->pixman_image == NULL)) { - free (source); - return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY); - } - - _cairo_surface_init (&source->base, - &_cairo_image_source_backend, - NULL, /* device */ - CAIRO_CONTENT_COLOR_ALPHA); - - source->is_opaque_solid = - pattern == NULL || _cairo_pattern_is_opaque_solid (pattern); - - return &source->base; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-image-surface-inline.h b/source/libs/cairo/cairo-src/src/cairo-image-surface-inline.h deleted file mode 100644 index 743d5fd3e75f96bc81c36e42bb541fe0d0065710..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-image-surface-inline.h +++ /dev/null @@ -1,96 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - */ - -#ifndef CAIRO_IMAGE_SURFACE_INLINE_H -#define CAIRO_IMAGE_SURFACE_INLINE_H - -#include "cairo-surface-private.h" -#include "cairo-image-surface-private.h" - -CAIRO_BEGIN_DECLS - -static inline cairo_image_surface_t * -_cairo_image_surface_create_in_error (cairo_status_t status) -{ - return (cairo_image_surface_t *) _cairo_surface_create_in_error (status); -} - -static inline void -_cairo_image_surface_set_parent (cairo_image_surface_t *image, - cairo_surface_t *parent) -{ - image->parent = parent; -} - -static inline cairo_bool_t -_cairo_image_surface_is_clone (cairo_image_surface_t *image) -{ - return image->parent != NULL; -} - -/** - * _cairo_surface_is_image: - * @surface: a #cairo_surface_t - * - * Checks if a surface is an #cairo_image_surface_t - * - * Return value: %TRUE if the surface is an image surface - **/ -static inline cairo_bool_t -_cairo_surface_is_image (const cairo_surface_t *surface) -{ - /* _cairo_surface_nil sets a NULL backend so be safe */ - return surface->backend && surface->backend->type == CAIRO_SURFACE_TYPE_IMAGE; -} - -/** - * _cairo_surface_is_image_source: - * @surface: a #cairo_surface_t - * - * Checks if a surface is an #cairo_image_source_t - * - * Return value: %TRUE if the surface is an image source - **/ -static inline cairo_bool_t -_cairo_surface_is_image_source (const cairo_surface_t *surface) -{ - return surface->backend == &_cairo_image_source_backend; -} - -CAIRO_END_DECLS - -#endif /* CAIRO_IMAGE_SURFACE_INLINE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-image-surface-private.h b/source/libs/cairo/cairo-src/src/cairo-image-surface-private.h deleted file mode 100644 index 8ca694c5e3eef1956bf5ed3f46edec4e6a18582b..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-image-surface-private.h +++ /dev/null @@ -1,238 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - */ - -#ifndef CAIRO_IMAGE_SURFACE_PRIVATE_H -#define CAIRO_IMAGE_SURFACE_PRIVATE_H - -#include "cairo-surface-private.h" - -#include <pixman.h> - -CAIRO_BEGIN_DECLS - -/* The canonical image backend */ -struct _cairo_image_surface { - cairo_surface_t base; - - pixman_image_t *pixman_image; - const cairo_compositor_t *compositor; - - /* Parenting is tricky wrt lifetime tracking... - * - * One use for tracking the parent of an image surface is for - * create_similar_image() where we wish to create a device specific - * surface but return an image surface to the user. In such a case, - * the image may be owned by the device specific surface, its parent, - * but the user lifetime tracking is then performed on the image. So - * when the image is then finalized we call cairo_surface_destroy() - * on the parent. However, for normal usage where the lifetime tracking - * is done on the parent surface, we need to be careful to unhook - * the image->parent pointer before finalizing the image. - */ - cairo_surface_t *parent; - - pixman_format_code_t pixman_format; - cairo_format_t format; - unsigned char *data; - - int width; - int height; - int stride; - int depth; - - unsigned owns_data : 1; - unsigned transparency : 2; - unsigned color : 2; -}; -#define to_image_surface(S) ((cairo_image_surface_t *)(S)) - -/* A wrapper for holding pixman images returned by create_for_pattern */ -typedef struct _cairo_image_source { - cairo_surface_t base; - - pixman_image_t *pixman_image; - unsigned is_opaque_solid : 1; -} cairo_image_source_t; - -cairo_private extern const cairo_surface_backend_t _cairo_image_surface_backend; -cairo_private extern const cairo_surface_backend_t _cairo_image_source_backend; - -cairo_private const cairo_compositor_t * -_cairo_image_mask_compositor_get (void); - -cairo_private const cairo_compositor_t * -_cairo_image_traps_compositor_get (void); - -cairo_private const cairo_compositor_t * -_cairo_image_spans_compositor_get (void); - -#define _cairo_image_default_compositor_get _cairo_image_spans_compositor_get - -cairo_private cairo_int_status_t -_cairo_image_surface_paint (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip); - -cairo_private cairo_int_status_t -_cairo_image_surface_mask (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip); - -cairo_private cairo_int_status_t -_cairo_image_surface_stroke (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip); - -cairo_private cairo_int_status_t -_cairo_image_surface_fill (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip); - -cairo_private cairo_int_status_t -_cairo_image_surface_glyphs (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip); - -cairo_private void -_cairo_image_surface_init (cairo_image_surface_t *surface, - pixman_image_t *pixman_image, - pixman_format_code_t pixman_format); - -cairo_private cairo_surface_t * -_cairo_image_surface_create_similar (void *abstract_other, - cairo_content_t content, - int width, - int height); - -cairo_private cairo_image_surface_t * -_cairo_image_surface_map_to_image (void *abstract_other, - const cairo_rectangle_int_t *extents); - -cairo_private cairo_int_status_t -_cairo_image_surface_unmap_image (void *abstract_surface, - cairo_image_surface_t *image); - -cairo_private cairo_surface_t * -_cairo_image_surface_source (void *abstract_surface, - cairo_rectangle_int_t *extents); - -cairo_private cairo_status_t -_cairo_image_surface_acquire_source_image (void *abstract_surface, - cairo_image_surface_t **image_out, - void **image_extra); - -cairo_private void -_cairo_image_surface_release_source_image (void *abstract_surface, - cairo_image_surface_t *image, - void *image_extra); - -cairo_private cairo_surface_t * -_cairo_image_surface_snapshot (void *abstract_surface); - -cairo_private_no_warn cairo_bool_t -_cairo_image_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *rectangle); - -cairo_private void -_cairo_image_surface_get_font_options (void *abstract_surface, - cairo_font_options_t *options); - -cairo_private cairo_surface_t * -_cairo_image_source_create_for_pattern (cairo_surface_t *dst, - const cairo_pattern_t *pattern, - cairo_bool_t is_mask, - const cairo_rectangle_int_t *extents, - const cairo_rectangle_int_t *sample, - int *src_x, int *src_y); - -cairo_private cairo_status_t -_cairo_image_surface_finish (void *abstract_surface); - -cairo_private pixman_image_t * -_pixman_image_for_color (const cairo_color_t *cairo_color); - -cairo_private pixman_image_t * -_pixman_image_for_pattern (cairo_image_surface_t *dst, - const cairo_pattern_t *pattern, - cairo_bool_t is_mask, - const cairo_rectangle_int_t *extents, - const cairo_rectangle_int_t *sample, - int *tx, int *ty); - -cairo_private void -_pixman_image_add_traps (pixman_image_t *image, - int dst_x, int dst_y, - cairo_traps_t *traps); - -cairo_private void -_pixman_image_add_tristrip (pixman_image_t *image, - int dst_x, int dst_y, - cairo_tristrip_t *strip); - -cairo_private cairo_image_surface_t * -_cairo_image_surface_clone_subimage (cairo_surface_t *surface, - const cairo_rectangle_int_t *extents); - -/* Similar to clone; but allow format conversion */ -cairo_private cairo_image_surface_t * -_cairo_image_surface_create_from_image (cairo_image_surface_t *other, - pixman_format_code_t format, - int x, int y, int width, int height, - int stride); - -CAIRO_END_DECLS - -#endif /* CAIRO_IMAGE_SURFACE_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-image-surface.c b/source/libs/cairo/cairo-src/src/cairo-image-surface.c deleted file mode 100644 index 1fd563d1c3499c029463af852ba5e39c9c04f1cc..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-image-surface.c +++ /dev/null @@ -1,1321 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2003 University of Southern California - * Copyright © 2009,2010,2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-boxes-private.h" -#include "cairo-clip-private.h" -#include "cairo-composite-rectangles-private.h" -#include "cairo-compositor-private.h" -#include "cairo-default-context-private.h" -#include "cairo-error-private.h" -#include "cairo-image-surface-inline.h" -#include "cairo-paginated-private.h" -#include "cairo-pattern-private.h" -#include "cairo-pixman-private.h" -#include "cairo-recording-surface-private.h" -#include "cairo-region-private.h" -#include "cairo-scaled-font-private.h" -#include "cairo-surface-snapshot-private.h" -#include "cairo-surface-subsurface-private.h" - -/* Limit on the width / height of an image surface in pixels. This is - * mainly determined by coordinates of things sent to pixman at the - * moment being in 16.16 format. */ -#define MAX_IMAGE_SIZE 32767 - -/** - * SECTION:cairo-image - * @Title: Image Surfaces - * @Short_Description: Rendering to memory buffers - * @See_Also: #cairo_surface_t - * - * Image surfaces provide the ability to render to memory buffers - * either allocated by cairo or by the calling code. The supported - * image formats are those defined in #cairo_format_t. - **/ - -/** - * CAIRO_HAS_IMAGE_SURFACE: - * - * Defined if the image surface backend is available. - * The image surface backend is always built in. - * This macro was added for completeness in cairo 1.8. - * - * Since: 1.8 - **/ - -static cairo_bool_t -_cairo_image_surface_is_size_valid (int width, int height) -{ - return 0 <= width && width <= MAX_IMAGE_SIZE && - 0 <= height && height <= MAX_IMAGE_SIZE; -} - -cairo_format_t -_cairo_format_from_pixman_format (pixman_format_code_t pixman_format) -{ - switch (pixman_format) { - case PIXMAN_a8r8g8b8: - return CAIRO_FORMAT_ARGB32; - case PIXMAN_x2r10g10b10: - return CAIRO_FORMAT_RGB30; - case PIXMAN_x8r8g8b8: - return CAIRO_FORMAT_RGB24; - case PIXMAN_a8: - return CAIRO_FORMAT_A8; - case PIXMAN_a1: - return CAIRO_FORMAT_A1; - case PIXMAN_r5g6b5: - return CAIRO_FORMAT_RGB16_565; -#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,22,0) - case PIXMAN_r8g8b8a8: case PIXMAN_r8g8b8x8: -#endif -#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,27,2) - case PIXMAN_a8r8g8b8_sRGB: -#endif - case PIXMAN_a8b8g8r8: case PIXMAN_x8b8g8r8: case PIXMAN_r8g8b8: - case PIXMAN_b8g8r8: case PIXMAN_b5g6r5: - case PIXMAN_a1r5g5b5: case PIXMAN_x1r5g5b5: case PIXMAN_a1b5g5r5: - case PIXMAN_x1b5g5r5: case PIXMAN_a4r4g4b4: case PIXMAN_x4r4g4b4: - case PIXMAN_a4b4g4r4: case PIXMAN_x4b4g4r4: case PIXMAN_r3g3b2: - case PIXMAN_b2g3r3: case PIXMAN_a2r2g2b2: case PIXMAN_a2b2g2r2: - case PIXMAN_c8: case PIXMAN_g8: case PIXMAN_x4a4: - case PIXMAN_a4: case PIXMAN_r1g2b1: case PIXMAN_b1g2r1: - case PIXMAN_a1r1g1b1: case PIXMAN_a1b1g1r1: case PIXMAN_c4: - case PIXMAN_g4: case PIXMAN_g1: - case PIXMAN_yuy2: case PIXMAN_yv12: - case PIXMAN_b8g8r8x8: - case PIXMAN_b8g8r8a8: - case PIXMAN_a2b10g10r10: - case PIXMAN_x2b10g10r10: - case PIXMAN_a2r10g10b10: -#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,22,0) - case PIXMAN_x14r6g6b6: -#endif - default: - return CAIRO_FORMAT_INVALID; - } - - return CAIRO_FORMAT_INVALID; -} - -cairo_content_t -_cairo_content_from_pixman_format (pixman_format_code_t pixman_format) -{ - cairo_content_t content; - - content = 0; - if (PIXMAN_FORMAT_RGB (pixman_format)) - content |= CAIRO_CONTENT_COLOR; - if (PIXMAN_FORMAT_A (pixman_format)) - content |= CAIRO_CONTENT_ALPHA; - - return content; -} - -void -_cairo_image_surface_init (cairo_image_surface_t *surface, - pixman_image_t *pixman_image, - pixman_format_code_t pixman_format) -{ - surface->parent = NULL; - surface->pixman_image = pixman_image; - - surface->pixman_format = pixman_format; - surface->format = _cairo_format_from_pixman_format (pixman_format); - surface->data = (uint8_t *) pixman_image_get_data (pixman_image); - surface->owns_data = FALSE; - surface->transparency = CAIRO_IMAGE_UNKNOWN; - surface->color = CAIRO_IMAGE_UNKNOWN_COLOR; - - surface->width = pixman_image_get_width (pixman_image); - surface->height = pixman_image_get_height (pixman_image); - surface->stride = pixman_image_get_stride (pixman_image); - surface->depth = pixman_image_get_depth (pixman_image); - - surface->base.is_clear = surface->width == 0 || surface->height == 0; - - surface->compositor = _cairo_image_spans_compositor_get (); -} - -cairo_surface_t * -_cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image, - pixman_format_code_t pixman_format) -{ - cairo_image_surface_t *surface; - - surface = malloc (sizeof (cairo_image_surface_t)); - if (unlikely (surface == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - _cairo_surface_init (&surface->base, - &_cairo_image_surface_backend, - NULL, /* device */ - _cairo_content_from_pixman_format (pixman_format)); - - _cairo_image_surface_init (surface, pixman_image, pixman_format); - - return &surface->base; -} - -cairo_bool_t -_pixman_format_from_masks (cairo_format_masks_t *masks, - pixman_format_code_t *format_ret) -{ - pixman_format_code_t format; - int format_type; - int a, r, g, b; - cairo_format_masks_t format_masks; - - a = _cairo_popcount (masks->alpha_mask); - r = _cairo_popcount (masks->red_mask); - g = _cairo_popcount (masks->green_mask); - b = _cairo_popcount (masks->blue_mask); - - if (masks->red_mask) { - if (masks->red_mask > masks->blue_mask) - format_type = PIXMAN_TYPE_ARGB; - else - format_type = PIXMAN_TYPE_ABGR; - } else if (masks->alpha_mask) { - format_type = PIXMAN_TYPE_A; - } else { - return FALSE; - } - - format = PIXMAN_FORMAT (masks->bpp, format_type, a, r, g, b); - - if (! pixman_format_supported_destination (format)) - return FALSE; - - /* Sanity check that we got out of PIXMAN_FORMAT exactly what we - * expected. This avoid any problems from something bizarre like - * alpha in the least-significant bits, or insane channel order, - * or whatever. */ - if (!_pixman_format_to_masks (format, &format_masks) || - masks->bpp != format_masks.bpp || - masks->red_mask != format_masks.red_mask || - masks->green_mask != format_masks.green_mask || - masks->blue_mask != format_masks.blue_mask) - { - return FALSE; - } - - *format_ret = format; - return TRUE; -} - -/* A mask consisting of N bits set to 1. */ -#define MASK(N) ((1UL << (N))-1) - -cairo_bool_t -_pixman_format_to_masks (pixman_format_code_t format, - cairo_format_masks_t *masks) -{ - int a, r, g, b; - - masks->bpp = PIXMAN_FORMAT_BPP (format); - - /* Number of bits in each channel */ - a = PIXMAN_FORMAT_A (format); - r = PIXMAN_FORMAT_R (format); - g = PIXMAN_FORMAT_G (format); - b = PIXMAN_FORMAT_B (format); - - switch (PIXMAN_FORMAT_TYPE (format)) { - case PIXMAN_TYPE_ARGB: - masks->alpha_mask = MASK (a) << (r + g + b); - masks->red_mask = MASK (r) << (g + b); - masks->green_mask = MASK (g) << (b); - masks->blue_mask = MASK (b); - return TRUE; - case PIXMAN_TYPE_ABGR: - masks->alpha_mask = MASK (a) << (b + g + r); - masks->blue_mask = MASK (b) << (g + r); - masks->green_mask = MASK (g) << (r); - masks->red_mask = MASK (r); - return TRUE; -#ifdef PIXMAN_TYPE_BGRA - case PIXMAN_TYPE_BGRA: - masks->blue_mask = MASK (b) << (masks->bpp - b); - masks->green_mask = MASK (g) << (masks->bpp - b - g); - masks->red_mask = MASK (r) << (masks->bpp - b - g - r); - masks->alpha_mask = MASK (a); - return TRUE; -#endif - case PIXMAN_TYPE_A: - masks->alpha_mask = MASK (a); - masks->red_mask = 0; - masks->green_mask = 0; - masks->blue_mask = 0; - return TRUE; - case PIXMAN_TYPE_OTHER: - case PIXMAN_TYPE_COLOR: - case PIXMAN_TYPE_GRAY: - case PIXMAN_TYPE_YUY2: - case PIXMAN_TYPE_YV12: - default: - masks->alpha_mask = 0; - masks->red_mask = 0; - masks->green_mask = 0; - masks->blue_mask = 0; - return FALSE; - } -} - -pixman_format_code_t -_cairo_format_to_pixman_format_code (cairo_format_t format) -{ - pixman_format_code_t ret; - switch (format) { - case CAIRO_FORMAT_A1: - ret = PIXMAN_a1; - break; - case CAIRO_FORMAT_A8: - ret = PIXMAN_a8; - break; - case CAIRO_FORMAT_RGB24: - ret = PIXMAN_x8r8g8b8; - break; - case CAIRO_FORMAT_RGB30: - ret = PIXMAN_x2r10g10b10; - break; - case CAIRO_FORMAT_RGB16_565: - ret = PIXMAN_r5g6b5; - break; - case CAIRO_FORMAT_ARGB32: - case CAIRO_FORMAT_INVALID: - default: - ret = PIXMAN_a8r8g8b8; - break; - } - return ret; -} - -cairo_surface_t * -_cairo_image_surface_create_with_pixman_format (unsigned char *data, - pixman_format_code_t pixman_format, - int width, - int height, - int stride) -{ - cairo_surface_t *surface; - pixman_image_t *pixman_image; - - if (! _cairo_image_surface_is_size_valid (width, height)) - { - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE)); - } - - pixman_image = pixman_image_create_bits (pixman_format, width, height, - (uint32_t *) data, stride); - - if (unlikely (pixman_image == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - surface = _cairo_image_surface_create_for_pixman_image (pixman_image, - pixman_format); - if (unlikely (surface->status)) { - pixman_image_unref (pixman_image); - return surface; - } - - /* we can not make any assumptions about the initial state of user data */ - surface->is_clear = data == NULL; - return surface; -} - -/** - * cairo_image_surface_create: - * @format: format of pixels in the surface to create - * @width: width of the surface, in pixels - * @height: height of the surface, in pixels - * - * Creates an image surface of the specified format and - * dimensions. Initially the surface contents are all - * 0. (Specifically, within each pixel, each color or alpha channel - * belonging to format will be 0. The contents of bits within a pixel, - * but not belonging to the given format are undefined). - * - * Return value: a pointer to the newly created surface. The caller - * owns the surface and should call cairo_surface_destroy() when done - * with it. - * - * This function always returns a valid pointer, but it will return a - * pointer to a "nil" surface if an error such as out of memory - * occurs. You can use cairo_surface_status() to check for this. - * - * Since: 1.0 - **/ -cairo_surface_t * -cairo_image_surface_create (cairo_format_t format, - int width, - int height) -{ - pixman_format_code_t pixman_format; - - if (! CAIRO_FORMAT_VALID (format)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT)); - - pixman_format = _cairo_format_to_pixman_format_code (format); - - return _cairo_image_surface_create_with_pixman_format (NULL, pixman_format, - width, height, -1); -} -slim_hidden_def (cairo_image_surface_create); - - cairo_surface_t * -_cairo_image_surface_create_with_content (cairo_content_t content, - int width, - int height) -{ - return cairo_image_surface_create (_cairo_format_from_content (content), - width, height); -} - -/** - * cairo_format_stride_for_width: - * @format: A #cairo_format_t value - * @width: The desired width of an image surface to be created. - * - * This function provides a stride value that will respect all - * alignment requirements of the accelerated image-rendering code - * within cairo. Typical usage will be of the form: - * - * <informalexample><programlisting> - * int stride; - * unsigned char *data; - * cairo_surface_t *surface; - * - * stride = cairo_format_stride_for_width (format, width); - * data = malloc (stride * height); - * surface = cairo_image_surface_create_for_data (data, format, - * width, height, - * stride); - * </programlisting></informalexample> - * - * Return value: the appropriate stride to use given the desired - * format and width, or -1 if either the format is invalid or the width - * too large. - * - * Since: 1.6 - **/ - int -cairo_format_stride_for_width (cairo_format_t format, - int width) -{ - int bpp; - - if (! CAIRO_FORMAT_VALID (format)) { - _cairo_error_throw (CAIRO_STATUS_INVALID_FORMAT); - return -1; - } - - bpp = _cairo_format_bits_per_pixel (format); - if ((unsigned) (width) >= (INT32_MAX - 7) / (unsigned) (bpp)) - return -1; - - return CAIRO_STRIDE_FOR_WIDTH_BPP (width, bpp); -} -slim_hidden_def (cairo_format_stride_for_width); - -/** - * cairo_image_surface_create_for_data: - * @data: a pointer to a buffer supplied by the application in which - * to write contents. This pointer must be suitably aligned for any - * kind of variable, (for example, a pointer returned by malloc). - * @format: the format of pixels in the buffer - * @width: the width of the image to be stored in the buffer - * @height: the height of the image to be stored in the buffer - * @stride: the number of bytes between the start of rows in the - * buffer as allocated. This value should always be computed by - * cairo_format_stride_for_width() before allocating the data - * buffer. - * - * Creates an image surface for the provided pixel data. The output - * buffer must be kept around until the #cairo_surface_t is destroyed - * or cairo_surface_finish() is called on the surface. The initial - * contents of @data will be used as the initial image contents; you - * must explicitly clear the buffer, using, for example, - * cairo_rectangle() and cairo_fill() if you want it cleared. - * - * Note that the stride may be larger than - * width*bytes_per_pixel to provide proper alignment for each pixel - * and row. This alignment is required to allow high-performance rendering - * within cairo. The correct way to obtain a legal stride value is to - * call cairo_format_stride_for_width() with the desired format and - * maximum image width value, and then use the resulting stride value - * to allocate the data and to create the image surface. See - * cairo_format_stride_for_width() for example code. - * - * Return value: a pointer to the newly created surface. The caller - * owns the surface and should call cairo_surface_destroy() when done - * with it. - * - * This function always returns a valid pointer, but it will return a - * pointer to a "nil" surface in the case of an error such as out of - * memory or an invalid stride value. In case of invalid stride value - * the error status of the returned surface will be - * %CAIRO_STATUS_INVALID_STRIDE. You can use - * cairo_surface_status() to check for this. - * - * See cairo_surface_set_user_data() for a means of attaching a - * destroy-notification fallback to the surface if necessary. - * - * Since: 1.0 - **/ - cairo_surface_t * -cairo_image_surface_create_for_data (unsigned char *data, - cairo_format_t format, - int width, - int height, - int stride) -{ - pixman_format_code_t pixman_format; - int minstride; - - if (! CAIRO_FORMAT_VALID (format)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT)); - - if ((stride & (CAIRO_STRIDE_ALIGNMENT-1)) != 0) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE)); - - if (! _cairo_image_surface_is_size_valid (width, height)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE)); - - minstride = cairo_format_stride_for_width (format, width); - if (stride < 0) { - if (stride > -minstride) { - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE)); - } - } else { - if (stride < minstride) { - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE)); - } - } - - pixman_format = _cairo_format_to_pixman_format_code (format); - return _cairo_image_surface_create_with_pixman_format (data, - pixman_format, - width, height, - stride); -} -slim_hidden_def (cairo_image_surface_create_for_data); - -/** - * cairo_image_surface_get_data: - * @surface: a #cairo_image_surface_t - * - * Get a pointer to the data of the image surface, for direct - * inspection or modification. - * - * A call to cairo_surface_flush() is required before accessing the - * pixel data to ensure that all pending drawing operations are - * finished. A call to cairo_surface_mark_dirty() is required after - * the data is modified. - * - * Return value: a pointer to the image data of this surface or %NULL - * if @surface is not an image surface, or if cairo_surface_finish() - * has been called. - * - * Since: 1.2 - **/ -unsigned char * -cairo_image_surface_get_data (cairo_surface_t *surface) -{ - cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface; - - if (! _cairo_surface_is_image (surface)) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return NULL; - } - - return image_surface->data; -} -slim_hidden_def (cairo_image_surface_get_data); - -/** - * cairo_image_surface_get_format: - * @surface: a #cairo_image_surface_t - * - * Get the format of the surface. - * - * Return value: the format of the surface - * - * Since: 1.2 - **/ -cairo_format_t -cairo_image_surface_get_format (cairo_surface_t *surface) -{ - cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface; - - if (! _cairo_surface_is_image (surface)) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return CAIRO_FORMAT_INVALID; - } - - return image_surface->format; -} -slim_hidden_def (cairo_image_surface_get_format); - -/** - * cairo_image_surface_get_width: - * @surface: a #cairo_image_surface_t - * - * Get the width of the image surface in pixels. - * - * Return value: the width of the surface in pixels. - * - * Since: 1.0 - **/ -int -cairo_image_surface_get_width (cairo_surface_t *surface) -{ - cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface; - - if (! _cairo_surface_is_image (surface)) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return 0; - } - - return image_surface->width; -} -slim_hidden_def (cairo_image_surface_get_width); - -/** - * cairo_image_surface_get_height: - * @surface: a #cairo_image_surface_t - * - * Get the height of the image surface in pixels. - * - * Return value: the height of the surface in pixels. - * - * Since: 1.0 - **/ -int -cairo_image_surface_get_height (cairo_surface_t *surface) -{ - cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface; - - if (! _cairo_surface_is_image (surface)) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return 0; - } - - return image_surface->height; -} -slim_hidden_def (cairo_image_surface_get_height); - -/** - * cairo_image_surface_get_stride: - * @surface: a #cairo_image_surface_t - * - * Get the stride of the image surface in bytes - * - * Return value: the stride of the image surface in bytes (or 0 if - * @surface is not an image surface). The stride is the distance in - * bytes from the beginning of one row of the image data to the - * beginning of the next row. - * - * Since: 1.2 - **/ -int -cairo_image_surface_get_stride (cairo_surface_t *surface) -{ - - cairo_image_surface_t *image_surface = (cairo_image_surface_t *) surface; - - if (! _cairo_surface_is_image (surface)) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return 0; - } - - return image_surface->stride; -} -slim_hidden_def (cairo_image_surface_get_stride); - - cairo_format_t -_cairo_format_from_content (cairo_content_t content) -{ - switch (content) { - case CAIRO_CONTENT_COLOR: - return CAIRO_FORMAT_RGB24; - case CAIRO_CONTENT_ALPHA: - return CAIRO_FORMAT_A8; - case CAIRO_CONTENT_COLOR_ALPHA: - return CAIRO_FORMAT_ARGB32; - } - - ASSERT_NOT_REACHED; - return CAIRO_FORMAT_INVALID; -} - - cairo_content_t -_cairo_content_from_format (cairo_format_t format) -{ - switch (format) { - case CAIRO_FORMAT_ARGB32: - return CAIRO_CONTENT_COLOR_ALPHA; - case CAIRO_FORMAT_RGB30: - return CAIRO_CONTENT_COLOR; - case CAIRO_FORMAT_RGB24: - return CAIRO_CONTENT_COLOR; - case CAIRO_FORMAT_RGB16_565: - return CAIRO_CONTENT_COLOR; - case CAIRO_FORMAT_A8: - case CAIRO_FORMAT_A1: - return CAIRO_CONTENT_ALPHA; - case CAIRO_FORMAT_INVALID: - break; - } - - ASSERT_NOT_REACHED; - return CAIRO_CONTENT_COLOR_ALPHA; -} - - int -_cairo_format_bits_per_pixel (cairo_format_t format) -{ - switch (format) { - case CAIRO_FORMAT_ARGB32: - case CAIRO_FORMAT_RGB30: - case CAIRO_FORMAT_RGB24: - return 32; - case CAIRO_FORMAT_RGB16_565: - return 16; - case CAIRO_FORMAT_A8: - return 8; - case CAIRO_FORMAT_A1: - return 1; - case CAIRO_FORMAT_INVALID: - default: - ASSERT_NOT_REACHED; - return 0; - } -} - -cairo_surface_t * -_cairo_image_surface_create_similar (void *abstract_other, - cairo_content_t content, - int width, - int height) -{ - cairo_image_surface_t *other = abstract_other; - - TRACE ((stderr, "%s (other=%u)\n", __FUNCTION__, other->base.unique_id)); - - if (! _cairo_image_surface_is_size_valid (width, height)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE)); - - if (content == other->base.content) { - return _cairo_image_surface_create_with_pixman_format (NULL, - other->pixman_format, - width, height, - 0); - } - - return _cairo_image_surface_create_with_content (content, - width, height); -} - -cairo_surface_t * -_cairo_image_surface_snapshot (void *abstract_surface) -{ - cairo_image_surface_t *image = abstract_surface; - cairo_image_surface_t *clone; - - /* If we own the image, we can simply steal the memory for the snapshot */ - if (image->owns_data && image->base._finishing) { - clone = (cairo_image_surface_t *) - _cairo_image_surface_create_for_pixman_image (image->pixman_image, - image->pixman_format); - if (unlikely (clone->base.status)) - return &clone->base; - - image->pixman_image = NULL; - image->owns_data = FALSE; - - clone->transparency = image->transparency; - clone->color = image->color; - - clone->owns_data = TRUE; - return &clone->base; - } - - clone = (cairo_image_surface_t *) - _cairo_image_surface_create_with_pixman_format (NULL, - image->pixman_format, - image->width, - image->height, - 0); - if (unlikely (clone->base.status)) - return &clone->base; - - if (clone->stride == image->stride) { - memcpy (clone->data, image->data, clone->stride * clone->height); - } else { - pixman_image_composite32 (PIXMAN_OP_SRC, - image->pixman_image, NULL, clone->pixman_image, - 0, 0, - 0, 0, - 0, 0, - image->width, image->height); - } - clone->base.is_clear = FALSE; - return &clone->base; -} - -cairo_image_surface_t * -_cairo_image_surface_map_to_image (void *abstract_other, - const cairo_rectangle_int_t *extents) -{ - cairo_image_surface_t *other = abstract_other; - cairo_surface_t *surface; - uint8_t *data; - - data = other->data; - data += extents->y * other->stride; - data += extents->x * PIXMAN_FORMAT_BPP (other->pixman_format)/ 8; - - surface = - _cairo_image_surface_create_with_pixman_format (data, - other->pixman_format, - extents->width, - extents->height, - other->stride); - - cairo_surface_set_device_offset (surface, -extents->x, -extents->y); - return (cairo_image_surface_t *) surface; -} - -cairo_int_status_t -_cairo_image_surface_unmap_image (void *abstract_surface, - cairo_image_surface_t *image) -{ - cairo_surface_finish (&image->base); - cairo_surface_destroy (&image->base); - - return CAIRO_INT_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_image_surface_finish (void *abstract_surface) -{ - cairo_image_surface_t *surface = abstract_surface; - - if (surface->pixman_image) { - pixman_image_unref (surface->pixman_image); - surface->pixman_image = NULL; - } - - if (surface->owns_data) { - free (surface->data); - surface->data = NULL; - } - - if (surface->parent) { - cairo_surface_t *parent = surface->parent; - surface->parent = NULL; - cairo_surface_destroy (parent); - } - - return CAIRO_STATUS_SUCCESS; -} - -void -_cairo_image_surface_assume_ownership_of_data (cairo_image_surface_t *surface) -{ - surface->owns_data = TRUE; -} - -cairo_surface_t * -_cairo_image_surface_source (void *abstract_surface, - cairo_rectangle_int_t *extents) -{ - cairo_image_surface_t *surface = abstract_surface; - - if (extents) { - extents->x = extents->y = 0; - extents->width = surface->width; - extents->height = surface->height; - } - - return &surface->base; -} - -cairo_status_t -_cairo_image_surface_acquire_source_image (void *abstract_surface, - cairo_image_surface_t **image_out, - void **image_extra) -{ - *image_out = abstract_surface; - *image_extra = NULL; - - return CAIRO_STATUS_SUCCESS; -} - -void -_cairo_image_surface_release_source_image (void *abstract_surface, - cairo_image_surface_t *image, - void *image_extra) -{ -} - -/* high level image interface */ -cairo_bool_t -_cairo_image_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *rectangle) -{ - cairo_image_surface_t *surface = abstract_surface; - - rectangle->x = 0; - rectangle->y = 0; - rectangle->width = surface->width; - rectangle->height = surface->height; - - return TRUE; -} - -cairo_int_status_t -_cairo_image_surface_paint (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - cairo_image_surface_t *surface = abstract_surface; - - TRACE ((stderr, "%s (surface=%d)\n", - __FUNCTION__, surface->base.unique_id)); - - return _cairo_compositor_paint (surface->compositor, - &surface->base, op, source, clip); -} - -cairo_int_status_t -_cairo_image_surface_mask (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - cairo_image_surface_t *surface = abstract_surface; - - TRACE ((stderr, "%s (surface=%d)\n", - __FUNCTION__, surface->base.unique_id)); - - return _cairo_compositor_mask (surface->compositor, - &surface->base, op, source, mask, clip); -} - -cairo_int_status_t -_cairo_image_surface_stroke (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_image_surface_t *surface = abstract_surface; - - TRACE ((stderr, "%s (surface=%d)\n", - __FUNCTION__, surface->base.unique_id)); - - return _cairo_compositor_stroke (surface->compositor, &surface->base, - op, source, path, - style, ctm, ctm_inverse, - tolerance, antialias, clip); -} - -cairo_int_status_t -_cairo_image_surface_fill (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_image_surface_t *surface = abstract_surface; - - TRACE ((stderr, "%s (surface=%d)\n", - __FUNCTION__, surface->base.unique_id)); - - return _cairo_compositor_fill (surface->compositor, &surface->base, - op, source, path, - fill_rule, tolerance, antialias, - clip); -} - -cairo_int_status_t -_cairo_image_surface_glyphs (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - cairo_image_surface_t *surface = abstract_surface; - - TRACE ((stderr, "%s (surface=%d)\n", - __FUNCTION__, surface->base.unique_id)); - - return _cairo_compositor_glyphs (surface->compositor, &surface->base, - op, source, - glyphs, num_glyphs, scaled_font, - clip); -} - -void -_cairo_image_surface_get_font_options (void *abstract_surface, - cairo_font_options_t *options) -{ - _cairo_font_options_init_default (options); - - cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_ON); - _cairo_font_options_set_round_glyph_positions (options, CAIRO_ROUND_GLYPH_POS_ON); -} - -const cairo_surface_backend_t _cairo_image_surface_backend = { - CAIRO_SURFACE_TYPE_IMAGE, - _cairo_image_surface_finish, - - _cairo_default_context_create, - - _cairo_image_surface_create_similar, - NULL, /* create similar image */ - _cairo_image_surface_map_to_image, - _cairo_image_surface_unmap_image, - - _cairo_image_surface_source, - _cairo_image_surface_acquire_source_image, - _cairo_image_surface_release_source_image, - _cairo_image_surface_snapshot, - - NULL, /* copy_page */ - NULL, /* show_page */ - - _cairo_image_surface_get_extents, - _cairo_image_surface_get_font_options, - - NULL, /* flush */ - NULL, - - _cairo_image_surface_paint, - _cairo_image_surface_mask, - _cairo_image_surface_stroke, - _cairo_image_surface_fill, - NULL, /* fill-stroke */ - _cairo_image_surface_glyphs, -}; - -/* A convenience function for when one needs to coerce an image - * surface to an alternate format. */ -cairo_image_surface_t * -_cairo_image_surface_coerce (cairo_image_surface_t *surface) -{ - return _cairo_image_surface_coerce_to_format (surface, - _cairo_format_from_content (surface->base.content)); -} - -/* A convenience function for when one needs to coerce an image - * surface to an alternate format. */ -cairo_image_surface_t * -_cairo_image_surface_coerce_to_format (cairo_image_surface_t *surface, - cairo_format_t format) -{ - cairo_image_surface_t *clone; - cairo_status_t status; - - status = surface->base.status; - if (unlikely (status)) - return (cairo_image_surface_t *)_cairo_surface_create_in_error (status); - - if (surface->format == format) - return (cairo_image_surface_t *)cairo_surface_reference(&surface->base); - - clone = (cairo_image_surface_t *) - cairo_image_surface_create (format, surface->width, surface->height); - if (unlikely (clone->base.status)) - return clone; - - pixman_image_composite32 (PIXMAN_OP_SRC, - surface->pixman_image, NULL, clone->pixman_image, - 0, 0, - 0, 0, - 0, 0, - surface->width, surface->height); - clone->base.is_clear = FALSE; - - clone->base.device_transform = - surface->base.device_transform; - clone->base.device_transform_inverse = - surface->base.device_transform_inverse; - - return clone; -} - -cairo_image_surface_t * -_cairo_image_surface_create_from_image (cairo_image_surface_t *other, - pixman_format_code_t format, - int x, int y, - int width, int height, int stride) -{ - cairo_image_surface_t *surface; - cairo_status_t status; - pixman_image_t *image; - void *mem = NULL; - - status = other->base.status; - if (unlikely (status)) - goto cleanup; - - if (stride) { - mem = _cairo_malloc_ab (height, stride); - if (unlikely (mem == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto cleanup; - } - } - - image = pixman_image_create_bits (format, width, height, mem, stride); - if (unlikely (image == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto cleanup_mem; - } - - surface = (cairo_image_surface_t *) - _cairo_image_surface_create_for_pixman_image (image, format); - if (unlikely (surface->base.status)) { - status = surface->base.status; - goto cleanup_image; - } - - pixman_image_composite32 (PIXMAN_OP_SRC, - other->pixman_image, NULL, image, - x, y, - 0, 0, - 0, 0, - width, height); - surface->base.is_clear = FALSE; - surface->owns_data = mem != NULL; - - return surface; - -cleanup_image: - pixman_image_unref (image); -cleanup_mem: - free (mem); -cleanup: - return (cairo_image_surface_t *) _cairo_surface_create_in_error (status); -} - -cairo_image_transparency_t -_cairo_image_analyze_transparency (cairo_image_surface_t *image) -{ - int x, y; - - if (image->transparency != CAIRO_IMAGE_UNKNOWN) - return image->transparency; - - if ((image->base.content & CAIRO_CONTENT_ALPHA) == 0) - return image->transparency = CAIRO_IMAGE_IS_OPAQUE; - - if (image->base.is_clear) - return image->transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA; - - if ((image->base.content & CAIRO_CONTENT_COLOR) == 0) { - if (image->format == CAIRO_FORMAT_A1) { - return image->transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA; - } else if (image->format == CAIRO_FORMAT_A8) { - for (y = 0; y < image->height; y++) { - uint8_t *alpha = (uint8_t *) (image->data + y * image->stride); - - for (x = 0; x < image->width; x++, alpha++) { - if (*alpha > 0 && *alpha < 255) - return image->transparency = CAIRO_IMAGE_HAS_ALPHA; - } - } - return image->transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA; - } else { - return image->transparency = CAIRO_IMAGE_HAS_ALPHA; - } - } - - if (image->format == CAIRO_FORMAT_RGB16_565) { - image->transparency = CAIRO_IMAGE_IS_OPAQUE; - return CAIRO_IMAGE_IS_OPAQUE; - } - - if (image->format != CAIRO_FORMAT_ARGB32) - return image->transparency = CAIRO_IMAGE_HAS_ALPHA; - - image->transparency = CAIRO_IMAGE_IS_OPAQUE; - for (y = 0; y < image->height; y++) { - uint32_t *pixel = (uint32_t *) (image->data + y * image->stride); - - for (x = 0; x < image->width; x++, pixel++) { - int a = (*pixel & 0xff000000) >> 24; - if (a > 0 && a < 255) { - return image->transparency = CAIRO_IMAGE_HAS_ALPHA; - } else if (a == 0) { - image->transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA; - } - } - } - - return image->transparency; -} - -cairo_image_color_t -_cairo_image_analyze_color (cairo_image_surface_t *image) -{ - int x, y; - - if (image->color != CAIRO_IMAGE_UNKNOWN_COLOR) - return image->color; - - if (image->format == CAIRO_FORMAT_A1) - return image->color = CAIRO_IMAGE_IS_MONOCHROME; - - if (image->format == CAIRO_FORMAT_A8) - return image->color = CAIRO_IMAGE_IS_GRAYSCALE; - - if (image->format == CAIRO_FORMAT_ARGB32) { - image->color = CAIRO_IMAGE_IS_MONOCHROME; - for (y = 0; y < image->height; y++) { - uint32_t *pixel = (uint32_t *) (image->data + y * image->stride); - - for (x = 0; x < image->width; x++, pixel++) { - int a = (*pixel & 0xff000000) >> 24; - int r = (*pixel & 0x00ff0000) >> 16; - int g = (*pixel & 0x0000ff00) >> 8; - int b = (*pixel & 0x000000ff); - if (a == 0) { - r = g = b = 0; - } else { - r = (r * 255 + a / 2) / a; - g = (g * 255 + a / 2) / a; - b = (b * 255 + a / 2) / a; - } - if (!(r == g && g == b)) - return image->color = CAIRO_IMAGE_IS_COLOR; - else if (r > 0 && r < 255) - image->color = CAIRO_IMAGE_IS_GRAYSCALE; - } - } - return image->color; - } - - if (image->format == CAIRO_FORMAT_RGB24) { - image->color = CAIRO_IMAGE_IS_MONOCHROME; - for (y = 0; y < image->height; y++) { - uint32_t *pixel = (uint32_t *) (image->data + y * image->stride); - - for (x = 0; x < image->width; x++, pixel++) { - int r = (*pixel & 0x00ff0000) >> 16; - int g = (*pixel & 0x0000ff00) >> 8; - int b = (*pixel & 0x000000ff); - if (!(r == g && g == b)) - return image->color = CAIRO_IMAGE_IS_COLOR; - else if (r > 0 && r < 255) - image->color = CAIRO_IMAGE_IS_GRAYSCALE; - } - } - return image->color; - } - - return image->color = CAIRO_IMAGE_IS_COLOR; -} - -cairo_image_surface_t * -_cairo_image_surface_clone_subimage (cairo_surface_t *surface, - const cairo_rectangle_int_t *extents) -{ - cairo_surface_t *image; - cairo_surface_pattern_t pattern; - cairo_status_t status; - - image = cairo_surface_create_similar_image (surface, - _cairo_format_from_content (surface->content), - extents->width, - extents->height); - if (image->status) - return to_image_surface (image); - - /* TODO: check me with non-identity device_transform. Should we - * clone the scaling, too? */ - cairo_surface_set_device_offset (image, - -extents->x, - -extents->y); - - _cairo_pattern_init_for_surface (&pattern, surface); - pattern.base.filter = CAIRO_FILTER_NEAREST; - - status = _cairo_surface_paint (image, - CAIRO_OPERATOR_SOURCE, - &pattern.base, - NULL); - - _cairo_pattern_fini (&pattern.base); - - if (unlikely (status)) - goto error; - - /* We use the parent as a flag during map-to-image/umap-image that the - * resultant image came from a fallback rather than as direct call - * to the backend's map_to_image(). Whilst we use it as a simple flag, - * we need to make sure the parent surface obeys the reference counting - * semantics and is consistent for all callers. - */ - _cairo_image_surface_set_parent (to_image_surface (image), - cairo_surface_reference (surface)); - - return to_image_surface (image); - -error: - cairo_surface_destroy (image); - return to_image_surface (_cairo_surface_create_in_error (status)); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-line-inline.h b/source/libs/cairo/cairo-src/src/cairo-line-inline.h deleted file mode 100644 index 71cc5e7ebf42a73e8513b2b679a20c9f23137e04..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-line-inline.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2014 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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. - * - */ - -#ifndef CAIRO_LINE_INLINE_H -#define CAIRO_LINE_INLINE_H - -#include "cairo-types-private.h" -#include "cairo-compiler-private.h" -#include "cairo-fixed-private.h" -#include "cairo-line-private.h" - -static inline int -cairo_lines_equal (const cairo_line_t *a, const cairo_line_t *b) -{ - return (a->p1.x == b->p1.x && a->p1.y == b->p1.y && - a->p2.x == b->p2.x && a->p2.y == b->p2.y); -} - -#endif /* CAIRO_LINE_INLINE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-line-private.h b/source/libs/cairo/cairo-src/src/cairo-line-private.h deleted file mode 100644 index 08bf4b3587c074d734b19fcb58f8fb7fe4cebab4..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-line-private.h +++ /dev/null @@ -1,51 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2014 Intel Corporation, 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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. - * - */ - -#ifndef CAIRO_LINE_PRIVATE_H -#define CAIRO_LINE_PRIVATE_H - -#include "cairo-types-private.h" -#include "cairo-error-private.h" -#include "cairo-compiler-private.h" - -CAIRO_BEGIN_DECLS - -cairo_private int -cairo_lines_compare_at_y(const cairo_line_t *a, - const cairo_line_t *b, - int y); - -CAIRO_END_DECLS - -#endif /* CAIRO_LINE_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-line.c b/source/libs/cairo/cairo-src/src/cairo-line.c deleted file mode 100644 index cb13927bdceac76ba3db355ae09464be18c9a96e..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-line.c +++ /dev/null @@ -1,306 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* - * Copyright © 2004 Carl Worth - * Copyright © 2006 Red Hat, Inc. - * Copyright © 2008 Chris Wilson - * Copyright © 2014 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Keith Packard - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -#include "cairoint.h" - -#include "cairo-line-inline.h" -#include "cairo-slope-private.h" - -static int -line_compare_for_y_against_x (const cairo_line_t *a, - int32_t y, - int32_t x) -{ - int32_t adx, ady; - int32_t dx, dy; - cairo_int64_t L, R; - - if (x < a->p1.x && x < a->p2.x) - return 1; - if (x > a->p1.x && x > a->p2.x) - return -1; - - adx = a->p2.x - a->p1.x; - dx = x - a->p1.x; - - if (adx == 0) - return -dx; - if (dx == 0 || (adx ^ dx) < 0) - return adx; - - dy = y - a->p1.y; - ady = a->p2.y - a->p1.y; - - L = _cairo_int32x32_64_mul (dy, adx); - R = _cairo_int32x32_64_mul (dx, ady); - - return _cairo_int64_cmp (L, R); -} - -/* - * We need to compare the x-coordinates of a pair of lines for a particular y, - * without loss of precision. - * - * The x-coordinate along an edge for a given y is: - * X = A_x + (Y - A_y) * A_dx / A_dy - * - * So the inequality we wish to test is: - * A_x + (Y - A_y) * A_dx / A_dy ∘ B_x + (Y - B_y) * B_dx / B_dy, - * where ∘ is our inequality operator. - * - * By construction, we know that A_dy and B_dy (and (Y - A_y), (Y - B_y)) are - * all positive, so we can rearrange it thus without causing a sign change: - * A_dy * B_dy * (A_x - B_x) ∘ (Y - B_y) * B_dx * A_dy - * - (Y - A_y) * A_dx * B_dy - * - * Given the assumption that all the deltas fit within 32 bits, we can compute - * this comparison directly using 128 bit arithmetic. For certain, but common, - * input we can reduce this down to a single 32 bit compare by inspecting the - * deltas. - * - * (And put the burden of the work on developing fast 128 bit ops, which are - * required throughout the tessellator.) - * - * See the similar discussion for _slope_compare(). - */ -static int -lines_compare_x_for_y_general (const cairo_line_t *a, - const cairo_line_t *b, - int32_t y) -{ - /* XXX: We're assuming here that dx and dy will still fit in 32 - * bits. That's not true in general as there could be overflow. We - * should prevent that before the tessellation algorithm - * begins. - */ - int32_t dx; - int32_t adx, ady; - int32_t bdx, bdy; - enum { - HAVE_NONE = 0x0, - HAVE_DX = 0x1, - HAVE_ADX = 0x2, - HAVE_DX_ADX = HAVE_DX | HAVE_ADX, - HAVE_BDX = 0x4, - HAVE_DX_BDX = HAVE_DX | HAVE_BDX, - HAVE_ADX_BDX = HAVE_ADX | HAVE_BDX, - HAVE_ALL = HAVE_DX | HAVE_ADX | HAVE_BDX - } have_dx_adx_bdx = HAVE_ALL; - - ady = a->p2.y - a->p1.y; - adx = a->p2.x - a->p1.x; - if (adx == 0) - have_dx_adx_bdx &= ~HAVE_ADX; - - bdy = b->p2.y - b->p1.y; - bdx = b->p2.x - b->p1.x; - if (bdx == 0) - have_dx_adx_bdx &= ~HAVE_BDX; - - dx = a->p1.x - b->p1.x; - if (dx == 0) - have_dx_adx_bdx &= ~HAVE_DX; - -#define L _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (ady, bdy), dx) -#define A _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (adx, bdy), y - a->p1.y) -#define B _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (bdx, ady), y - b->p1.y) - switch (have_dx_adx_bdx) { - default: - case HAVE_NONE: - return 0; - case HAVE_DX: - /* A_dy * B_dy * (A_x - B_x) ∘ 0 */ - return dx; /* ady * bdy is positive definite */ - case HAVE_ADX: - /* 0 ∘ - (Y - A_y) * A_dx * B_dy */ - return adx; /* bdy * (y - a->top.y) is positive definite */ - case HAVE_BDX: - /* 0 ∘ (Y - B_y) * B_dx * A_dy */ - return -bdx; /* ady * (y - b->top.y) is positive definite */ - case HAVE_ADX_BDX: - /* 0 ∘ (Y - B_y) * B_dx * A_dy - (Y - A_y) * A_dx * B_dy */ - if ((adx ^ bdx) < 0) { - return adx; - } else if (a->p1.y == b->p1.y) { /* common origin */ - cairo_int64_t adx_bdy, bdx_ady; - - /* ∴ A_dx * B_dy ∘ B_dx * A_dy */ - - adx_bdy = _cairo_int32x32_64_mul (adx, bdy); - bdx_ady = _cairo_int32x32_64_mul (bdx, ady); - - return _cairo_int64_cmp (adx_bdy, bdx_ady); - } else - return _cairo_int128_cmp (A, B); - case HAVE_DX_ADX: - /* A_dy * (A_x - B_x) ∘ - (Y - A_y) * A_dx */ - if ((-adx ^ dx) < 0) { - return dx; - } else { - cairo_int64_t ady_dx, dy_adx; - - ady_dx = _cairo_int32x32_64_mul (ady, dx); - dy_adx = _cairo_int32x32_64_mul (a->p1.y - y, adx); - - return _cairo_int64_cmp (ady_dx, dy_adx); - } - case HAVE_DX_BDX: - /* B_dy * (A_x - B_x) ∘ (Y - B_y) * B_dx */ - if ((bdx ^ dx) < 0) { - return dx; - } else { - cairo_int64_t bdy_dx, dy_bdx; - - bdy_dx = _cairo_int32x32_64_mul (bdy, dx); - dy_bdx = _cairo_int32x32_64_mul (y - b->p1.y, bdx); - - return _cairo_int64_cmp (bdy_dx, dy_bdx); - } - case HAVE_ALL: - /* XXX try comparing (a->p2.x - b->p2.x) et al */ - return _cairo_int128_cmp (L, _cairo_int128_sub (B, A)); - } -#undef B -#undef A -#undef L -} - -static int -lines_compare_x_for_y (const cairo_line_t *a, - const cairo_line_t *b, - int32_t y) -{ - /* If the sweep-line is currently on an end-point of a line, - * then we know its precise x value (and considering that we often need to - * compare events at end-points, this happens frequently enough to warrant - * special casing). - */ - enum { - HAVE_NEITHER = 0x0, - HAVE_AX = 0x1, - HAVE_BX = 0x2, - HAVE_BOTH = HAVE_AX | HAVE_BX - } have_ax_bx = HAVE_BOTH; - int32_t ax, bx; - - if (y == a->p1.y) - ax = a->p1.x; - else if (y == a->p2.y) - ax = a->p2.x; - else - have_ax_bx &= ~HAVE_AX; - - if (y == b->p1.y) - bx = b->p1.x; - else if (y == b->p2.y) - bx = b->p2.x; - else - have_ax_bx &= ~HAVE_BX; - - switch (have_ax_bx) { - default: - case HAVE_NEITHER: - return lines_compare_x_for_y_general (a, b, y); - case HAVE_AX: - return -line_compare_for_y_against_x (b, y, ax); - case HAVE_BX: - return line_compare_for_y_against_x (a, y, bx); - case HAVE_BOTH: - return ax - bx; - } -} - -static int bbox_compare (const cairo_line_t *a, - const cairo_line_t *b) -{ - int32_t amin, amax; - int32_t bmin, bmax; - - if (a->p1.x < a->p2.x) { - amin = a->p1.x; - amax = a->p2.x; - } else { - amin = a->p2.x; - amax = a->p1.x; - } - - if (b->p1.x < b->p2.x) { - bmin = b->p1.x; - bmax = b->p2.x; - } else { - bmin = b->p2.x; - bmax = b->p1.x; - } - - if (amax < bmin) - return -1; - - if (amin > bmax) - return +1; - - return 0; -} - -int cairo_lines_compare_at_y (const cairo_line_t *a, - const cairo_line_t *b, - int y) -{ - cairo_slope_t sa, sb; - int ret; - - if (cairo_lines_equal (a, b)) - return 0; - - /* Don't bother solving for abscissa if the edges' bounding boxes - * can be used to order them. - */ - ret = bbox_compare (a, b); - if (ret) - return ret; - - ret = lines_compare_x_for_y (a, b, y); - if (ret) - return ret; - - _cairo_slope_init (&sa, &a->p1, &a->p2); - _cairo_slope_init (&sb, &b->p1, &b->p2); - - return _cairo_slope_compare (&sb, &sa); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-list-inline.h b/source/libs/cairo/cairo-src/src/cairo-list-inline.h deleted file mode 100644 index 0955178d24fd00538bfb08fd7ab8325977b19374..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-list-inline.h +++ /dev/null @@ -1,215 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Chris Wilson. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -#ifndef CAIRO_LIST_INLINE_H -#define CAIRO_LIST_INLINE_H - -#include "cairo-list-private.h" - -#define cairo_list_entry(ptr, type, member) \ - cairo_container_of(ptr, type, member) - -#define cairo_list_first_entry(ptr, type, member) \ - cairo_list_entry((ptr)->next, type, member) - -#define cairo_list_last_entry(ptr, type, member) \ - cairo_list_entry((ptr)->prev, type, member) - -#define cairo_list_foreach(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) - -#define cairo_list_foreach_entry(pos, type, head, member) \ - for (pos = cairo_list_entry((head)->next, type, member);\ - &pos->member != (head); \ - pos = cairo_list_entry(pos->member.next, type, member)) - -#define cairo_list_foreach_entry_safe(pos, n, type, head, member) \ - for (pos = cairo_list_entry ((head)->next, type, member),\ - n = cairo_list_entry (pos->member.next, type, member);\ - &pos->member != (head); \ - pos = n, n = cairo_list_entry (n->member.next, type, member)) - -#define cairo_list_foreach_entry_reverse(pos, type, head, member) \ - for (pos = cairo_list_entry((head)->prev, type, member);\ - &pos->member != (head); \ - pos = cairo_list_entry(pos->member.prev, type, member)) - -#define cairo_list_foreach_entry_reverse_safe(pos, n, type, head, member) \ - for (pos = cairo_list_entry((head)->prev, type, member),\ - n = cairo_list_entry (pos->member.prev, type, member);\ - &pos->member != (head); \ - pos = n, n = cairo_list_entry (n->member.prev, type, member)) - -#ifdef CAIRO_LIST_DEBUG -static inline void -_cairo_list_validate (const cairo_list_t *link) -{ - assert (link->next->prev == link); - assert (link->prev->next == link); -} -static inline void -cairo_list_validate (const cairo_list_t *head) -{ - cairo_list_t *link; - - cairo_list_foreach (link, head) - _cairo_list_validate (link); -} -static inline cairo_bool_t -cairo_list_is_empty (const cairo_list_t *head); -static inline void -cairo_list_validate_is_empty (const cairo_list_t *head) -{ - assert (head->next == NULL || (cairo_list_is_empty (head) && head->next == head->prev)); -} -#else -#define _cairo_list_validate(link) -#define cairo_list_validate(head) -#define cairo_list_validate_is_empty(head) -#endif - -static inline void -cairo_list_init (cairo_list_t *entry) -{ - entry->next = entry; - entry->prev = entry; -} - -static inline void -__cairo_list_add (cairo_list_t *entry, - cairo_list_t *prev, - cairo_list_t *next) -{ - next->prev = entry; - entry->next = next; - entry->prev = prev; - prev->next = entry; -} - -static inline void -cairo_list_add (cairo_list_t *entry, cairo_list_t *head) -{ - cairo_list_validate (head); - cairo_list_validate_is_empty (entry); - __cairo_list_add (entry, head, head->next); - cairo_list_validate (head); -} - -static inline void -cairo_list_add_tail (cairo_list_t *entry, cairo_list_t *head) -{ - cairo_list_validate (head); - cairo_list_validate_is_empty (entry); - __cairo_list_add (entry, head->prev, head); - cairo_list_validate (head); -} - -static inline void -__cairo_list_del (cairo_list_t *prev, cairo_list_t *next) -{ - next->prev = prev; - prev->next = next; -} - -static inline void -_cairo_list_del (cairo_list_t *entry) -{ - __cairo_list_del (entry->prev, entry->next); -} - -static inline void -cairo_list_del (cairo_list_t *entry) -{ - _cairo_list_del (entry); - cairo_list_init (entry); -} - -static inline void -cairo_list_move (cairo_list_t *entry, cairo_list_t *head) -{ - cairo_list_validate (head); - __cairo_list_del (entry->prev, entry->next); - __cairo_list_add (entry, head, head->next); - cairo_list_validate (head); -} - -static inline void -cairo_list_move_tail (cairo_list_t *entry, cairo_list_t *head) -{ - cairo_list_validate (head); - __cairo_list_del (entry->prev, entry->next); - __cairo_list_add (entry, head->prev, head); - cairo_list_validate (head); -} - -static inline void -cairo_list_swap (cairo_list_t *entry, cairo_list_t *other) -{ - __cairo_list_add (entry, other->prev, other->next); - cairo_list_init (other); -} - -static inline cairo_bool_t -cairo_list_is_first (const cairo_list_t *entry, - const cairo_list_t *head) -{ - cairo_list_validate (head); - return entry->prev == head; -} - -static inline cairo_bool_t -cairo_list_is_last (const cairo_list_t *entry, - const cairo_list_t *head) -{ - cairo_list_validate (head); - return entry->next == head; -} - -static inline cairo_bool_t -cairo_list_is_empty (const cairo_list_t *head) -{ - cairo_list_validate (head); - return head->next == head; -} - -static inline cairo_bool_t -cairo_list_is_singular (const cairo_list_t *head) -{ - cairo_list_validate (head); - return head->next == head || head->next == head->prev; -} - -#endif /* CAIRO_LIST_INLINE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-list-private.h b/source/libs/cairo/cairo-src/src/cairo-list-private.h deleted file mode 100644 index 9f39b668f82d39e2d4caa0d47bb5d35f9f12e385..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-list-private.h +++ /dev/null @@ -1,48 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Chris Wilson. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -#ifndef CAIRO_LIST_PRIVATE_H -#define CAIRO_LIST_PRIVATE_H - -#include "cairo-compiler-private.h" - -/* Basic circular, doubly linked list implementation */ - -typedef struct _cairo_list { - struct _cairo_list *next, *prev; -} cairo_list_t; - -#endif /* CAIRO_LIST_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-lzw.c b/source/libs/cairo/cairo-src/src/cairo-lzw.c deleted file mode 100644 index de7f999837635673933c7731938d5b4b56654320..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-lzw.c +++ /dev/null @@ -1,404 +0,0 @@ -/* 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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" -#include "cairo-error-private.h" - -typedef struct _lzw_buf { - cairo_status_t status; - - unsigned char *data; - int data_size; - int num_data; - uint32_t pending; - unsigned 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_size = size; - buf->num_data = 0; - buf->pending = 0; - buf->pending_bits = 0; - - buf->data = malloc (size); - if (unlikely (buf->data == NULL)) { - buf->data_size = 0; - buf->status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - return; - } -} - -/* 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 = NULL; - /* check for integer overflow */ - if (new_size / 2 == buf->data_size) - new_data = realloc (buf->data, new_size); - - if (unlikely (new_data == NULL)) { - free (buf->data); - buf->data_size = 0; - buf->status = _cairo_error (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 (unlikely (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 (unlikely (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 successful, 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). - */ -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 = NULL; /* just to squelch a warning */ - int code_next = LZW_CODE_FIRST; - int code_bits = LZW_BITS_MIN; - int prev, next = 0; /* just to squelch a warning */ - - 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; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-malloc-private.h b/source/libs/cairo/cairo-src/src/cairo-malloc-private.h deleted file mode 100644 index 1e2c67f8d9aae19c249adf3c86d51d353302ebb6..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-malloc-private.h +++ /dev/null @@ -1,149 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* Cairo - a vector graphics library with display and print output - * - * Copyright © 2007 Mozilla Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Mozilla Foundation - * - * Contributor(s): - * Vladimir Vukicevic <vladimir@pobox.com> - */ - -#ifndef CAIRO_MALLOC_PRIVATE_H -#define CAIRO_MALLOC_PRIVATE_H - -#include "cairo-wideint-private.h" -#include <stdlib.h> - -#if HAVE_MEMFAULT -#include <memfault.h> -#define CAIRO_INJECT_FAULT() MEMFAULT_INJECT_FAULT() -#else -#define CAIRO_INJECT_FAULT() 0 -#endif - -/** - * _cairo_malloc: - * @size: size in bytes - * - * Allocate @size memory using malloc(). - * The memory should be freed using free(). - * malloc is skipped, if 0 bytes are requested, and %NULL will be returned. - * - * Return value: A pointer to the newly allocated memory, or %NULL in - * case of malloc() failure or size is 0. - **/ - -#define _cairo_malloc(size) \ - ((size) ? malloc((unsigned) (size)) : NULL) - -/** - * _cairo_malloc_ab: - * @a: number of elements to allocate - * @size: size of each element - * - * Allocates @a*@size memory using _cairo_malloc(), taking care to not - * overflow when doing the multiplication. Behaves much like - * calloc(), except that the returned memory is not set to zero. - * The memory should be freed using free(). - * - * @size should be a constant so that the compiler can optimize - * out a constant division. - * - * Return value: A pointer to the newly allocated memory, or %NULL in - * case of malloc() failure or overflow. - **/ - -#define _cairo_malloc_ab(a, size) \ - ((size) && (unsigned) (a) >= INT32_MAX / (unsigned) (size) ? NULL : \ - _cairo_malloc((unsigned) (a) * (unsigned) (size))) - -/** - * _cairo_realloc_ab: - * @ptr: original pointer to block of memory to be resized - * @a: number of elements to allocate - * @size: size of each element - * - * Reallocates @ptr a block of @a*@size memory using realloc(), taking - * care to not overflow when doing the multiplication. The memory - * should be freed using free(). - * - * @size should be a constant so that the compiler can optimize - * out a constant division. - * - * Return value: A pointer to the newly allocated memory, or %NULL in - * case of realloc() failure or overflow (whereupon the original block - * of memory * is left untouched). - **/ - -#define _cairo_realloc_ab(ptr, a, size) \ - ((size) && (unsigned) (a) >= INT32_MAX / (unsigned) (size) ? NULL : \ - realloc(ptr, (unsigned) (a) * (unsigned) (size))) - -/** - * _cairo_malloc_abc: - * @a: first factor of number of elements to allocate - * @b: second factor of number of elements to allocate - * @size: size of each element - * - * Allocates @a*@b*@size memory using _cairo_malloc(), taking care to not - * overflow when doing the multiplication. Behaves like - * _cairo_malloc_ab(). The memory should be freed using free(). - * - * @size should be a constant so that the compiler can optimize - * out a constant division. - * - * Return value: A pointer to the newly allocated memory, or %NULL in - * case of malloc() failure or overflow. - **/ - -#define _cairo_malloc_abc(a, b, size) \ - ((b) && (unsigned) (a) >= INT32_MAX / (unsigned) (b) ? NULL : \ - (size) && (unsigned) ((a)*(b)) >= INT32_MAX / (unsigned) (size) ? NULL : \ - _cairo_malloc((unsigned) (a) * (unsigned) (b) * (unsigned) (size))) - -/** - * _cairo_malloc_ab_plus_c: - * @a: number of elements to allocate - * @size: size of each element - * @c: additional size to allocate - * - * Allocates @a*@size+@c memory using _cairo_malloc(), taking care to not - * overflow when doing the arithmetic. Behaves similar to - * _cairo_malloc_ab(). The memory should be freed using free(). - * - * Return value: A pointer to the newly allocated memory, or %NULL in - * case of malloc() failure or overflow. - **/ - -#define _cairo_malloc_ab_plus_c(a, size, c) \ - ((size) && (unsigned) (a) >= INT32_MAX / (unsigned) (size) ? NULL : \ - (unsigned) (c) >= INT32_MAX - (unsigned) (a) * (unsigned) (size) ? NULL : \ - _cairo_malloc((unsigned) (a) * (unsigned) (size) + (unsigned) (c))) - -#endif /* CAIRO_MALLOC_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-mask-compositor.c b/source/libs/cairo/cairo-src/src/cairo-mask-compositor.c deleted file mode 100644 index 4d6b118dda5846321eab415ba4485e252d4c9460..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-mask-compositor.c +++ /dev/null @@ -1,1481 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Joonas Pihlaja <jpihlaja@cc.helsinki.fi> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -/* This compositor renders the shape to a mask using an image surface - * then calls composite. - */ - -#include "cairoint.h" - -#include "cairo-clip-inline.h" -#include "cairo-compositor-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-pattern-inline.h" -#include "cairo-region-private.h" -#include "cairo-surface-observer-private.h" -#include "cairo-surface-offset-private.h" -#include "cairo-surface-snapshot-private.h" -#include "cairo-surface-subsurface-private.h" - -typedef cairo_int_status_t -(*draw_func_t) (const cairo_mask_compositor_t *compositor, - cairo_surface_t *dst, - void *closure, - cairo_operator_t op, - const cairo_pattern_t *src, - const cairo_rectangle_int_t *src_sample, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents, - cairo_clip_t *clip); - -static void do_unaligned_row(void (*blt)(void *closure, - int16_t x, int16_t y, - int16_t w, int16_t h, - uint16_t coverage), - void *closure, - const cairo_box_t *b, - int tx, int y, int h, - uint16_t coverage) -{ - int x1 = _cairo_fixed_integer_part (b->p1.x) - tx; - int x2 = _cairo_fixed_integer_part (b->p2.x) - tx; - if (x2 > x1) { - if (! _cairo_fixed_is_integer (b->p1.x)) { - blt(closure, x1, y, 1, h, - coverage * (256 - _cairo_fixed_fractional_part (b->p1.x))); - x1++; - } - - if (x2 > x1) - blt(closure, x1, y, x2-x1, h, (coverage << 8) - (coverage >> 8)); - - if (! _cairo_fixed_is_integer (b->p2.x)) - blt(closure, x2, y, 1, h, - coverage * _cairo_fixed_fractional_part (b->p2.x)); - } else - blt(closure, x1, y, 1, h, - coverage * (b->p2.x - b->p1.x)); -} - -static void do_unaligned_box(void (*blt)(void *closure, - int16_t x, int16_t y, - int16_t w, int16_t h, - uint16_t coverage), - void *closure, - const cairo_box_t *b, int tx, int ty) -{ - int y1 = _cairo_fixed_integer_part (b->p1.y) - ty; - int y2 = _cairo_fixed_integer_part (b->p2.y) - ty; - if (y2 > y1) { - if (! _cairo_fixed_is_integer (b->p1.y)) { - do_unaligned_row(blt, closure, b, tx, y1, 1, - 256 - _cairo_fixed_fractional_part (b->p1.y)); - y1++; - } - - if (y2 > y1) - do_unaligned_row(blt, closure, b, tx, y1, y2-y1, 256); - - if (! _cairo_fixed_is_integer (b->p2.y)) - do_unaligned_row(blt, closure, b, tx, y2, 1, - _cairo_fixed_fractional_part (b->p2.y)); - } else - do_unaligned_row(blt, closure, b, tx, y1, 1, - b->p2.y - b->p1.y); -} - -struct blt_in { - const cairo_mask_compositor_t *compositor; - cairo_surface_t *dst; -}; - -static void blt_in(void *closure, - int16_t x, int16_t y, - int16_t w, int16_t h, - uint16_t coverage) -{ - struct blt_in *info = closure; - cairo_color_t color; - cairo_rectangle_int_t rect; - - if (coverage == 0xffff) - return; - - rect.x = x; - rect.y = y; - rect.width = w; - rect.height = h; - - _cairo_color_init_rgba (&color, 0, 0, 0, coverage / (double) 0xffff); - info->compositor->fill_rectangles (info->dst, CAIRO_OPERATOR_IN, - &color, &rect, 1); -} - -static cairo_surface_t * -create_composite_mask (const cairo_mask_compositor_t *compositor, - cairo_surface_t *dst, - void *draw_closure, - draw_func_t draw_func, - draw_func_t mask_func, - const cairo_composite_rectangles_t *extents) -{ - cairo_surface_t *surface; - cairo_int_status_t status; - struct blt_in info; - int i; - - surface = _cairo_surface_create_scratch (dst, CAIRO_CONTENT_ALPHA, - extents->bounded.width, - extents->bounded.height, - NULL); - if (unlikely (surface->status)) - return surface; - - status = compositor->acquire (surface); - if (unlikely (status)) { - cairo_surface_destroy (surface); - return _cairo_int_surface_create_in_error (status); - } - - if (!surface->is_clear) { - cairo_rectangle_int_t rect; - - rect.x = rect.y = 0; - rect.width = extents->bounded.width; - rect.height = extents->bounded.height; - - status = compositor->fill_rectangles (surface, CAIRO_OPERATOR_CLEAR, - CAIRO_COLOR_TRANSPARENT, - &rect, 1); - if (unlikely (status)) - goto error; - } - - if (mask_func) { - status = mask_func (compositor, surface, draw_closure, - CAIRO_OPERATOR_SOURCE, NULL, NULL, - extents->bounded.x, extents->bounded.y, - &extents->bounded, extents->clip); - if (likely (status != CAIRO_INT_STATUS_UNSUPPORTED)) - goto out; - } - - /* Is it worth setting the clip region here? */ - status = draw_func (compositor, surface, draw_closure, - CAIRO_OPERATOR_ADD, NULL, NULL, - extents->bounded.x, extents->bounded.y, - &extents->bounded, NULL); - if (unlikely (status)) - goto error; - - info.compositor = compositor; - info.dst = surface; - for (i = 0; i < extents->clip->num_boxes; i++) { - cairo_box_t *b = &extents->clip->boxes[i]; - - if (! _cairo_fixed_is_integer (b->p1.x) || - ! _cairo_fixed_is_integer (b->p1.y) || - ! _cairo_fixed_is_integer (b->p2.x) || - ! _cairo_fixed_is_integer (b->p2.y)) - { - do_unaligned_box(blt_in, &info, b, - extents->bounded.x, - extents->bounded.y); - } - } - - if (extents->clip->path != NULL) { - status = _cairo_clip_combine_with_surface (extents->clip, surface, - extents->bounded.x, - extents->bounded.y); - if (unlikely (status)) - goto error; - } - -out: - compositor->release (surface); - surface->is_clear = FALSE; - return surface; - -error: - compositor->release (surface); - if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) { - cairo_surface_destroy (surface); - surface = _cairo_int_surface_create_in_error (status); - } - return surface; -} - -/* Handles compositing with a clip surface when the operator allows - * us to combine the clip with the mask - */ -static cairo_status_t -clip_and_composite_with_mask (const cairo_mask_compositor_t *compositor, - void *draw_closure, - draw_func_t draw_func, - draw_func_t mask_func, - cairo_operator_t op, - cairo_pattern_t *pattern, - const cairo_composite_rectangles_t*extents) -{ - cairo_surface_t *dst = extents->surface; - cairo_surface_t *mask, *src; - int src_x, src_y; - - mask = create_composite_mask (compositor, dst, draw_closure, - draw_func, mask_func, - extents); - if (unlikely (mask->status)) - return mask->status; - - if (pattern != NULL || dst->content != CAIRO_CONTENT_ALPHA) { - src = compositor->pattern_to_surface (dst, - &extents->source_pattern.base, - FALSE, - &extents->bounded, - &extents->source_sample_area, - &src_x, &src_y); - if (unlikely (src->status)) { - cairo_surface_destroy (mask); - return src->status; - } - - compositor->composite (dst, op, src, mask, - extents->bounded.x + src_x, - extents->bounded.y + src_y, - 0, 0, - extents->bounded.x, extents->bounded.y, - extents->bounded.width, extents->bounded.height); - - cairo_surface_destroy (src); - } else { - compositor->composite (dst, op, mask, NULL, - 0, 0, - 0, 0, - extents->bounded.x, extents->bounded.y, - extents->bounded.width, extents->bounded.height); - } - cairo_surface_destroy (mask); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_surface_t * -get_clip_source (const cairo_mask_compositor_t *compositor, - cairo_clip_t *clip, - cairo_surface_t *dst, - const cairo_rectangle_int_t *bounds, - int *out_x, int *out_y) -{ - cairo_surface_pattern_t pattern; - cairo_rectangle_int_t r; - cairo_surface_t *surface; - - surface = _cairo_clip_get_image (clip, dst, bounds); - if (unlikely (surface->status)) - return surface; - - _cairo_pattern_init_for_surface (&pattern, surface); - pattern.base.filter = CAIRO_FILTER_NEAREST; - cairo_surface_destroy (surface); - - r.x = r.y = 0; - r.width = bounds->width; - r.height = bounds->height; - - surface = compositor->pattern_to_surface (dst, &pattern.base, TRUE, - &r, &r, out_x, out_y); - _cairo_pattern_fini (&pattern.base); - - *out_x += -bounds->x; - *out_y += -bounds->y; - return surface; -} - -/* Handles compositing with a clip surface when we have to do the operation - * in two pieces and combine them together. - */ -static cairo_status_t -clip_and_composite_combine (const cairo_mask_compositor_t *compositor, - void *draw_closure, - draw_func_t draw_func, - cairo_operator_t op, - const cairo_pattern_t *pattern, - const cairo_composite_rectangles_t*extents) -{ - cairo_surface_t *dst = extents->surface; - cairo_surface_t *tmp, *clip; - cairo_status_t status; - int clip_x, clip_y; - - tmp = _cairo_surface_create_scratch (dst, dst->content, - extents->bounded.width, - extents->bounded.height, - NULL); - if (unlikely (tmp->status)) - return tmp->status; - - compositor->composite (tmp, CAIRO_OPERATOR_SOURCE, dst, NULL, - extents->bounded.x, extents->bounded.y, - 0, 0, - 0, 0, - extents->bounded.width, extents->bounded.height); - - status = draw_func (compositor, tmp, draw_closure, op, - pattern, &extents->source_sample_area, - extents->bounded.x, extents->bounded.y, - &extents->bounded, NULL); - if (unlikely (status)) - goto cleanup; - - clip = get_clip_source (compositor, - extents->clip, dst, &extents->bounded, - &clip_x, &clip_y); - if (unlikely ((status = clip->status))) - goto cleanup; - - if (dst->is_clear) { - compositor->composite (dst, CAIRO_OPERATOR_SOURCE, tmp, clip, - 0, 0, - clip_x, clip_y, - extents->bounded.x, extents->bounded.y, - extents->bounded.width, extents->bounded.height); - } else { - /* Punch the clip out of the destination */ - compositor->composite (dst, CAIRO_OPERATOR_DEST_OUT, clip, NULL, - clip_x, clip_y, - 0, 0, - extents->bounded.x, extents->bounded.y, - extents->bounded.width, extents->bounded.height); - - /* Now add the two results together */ - compositor->composite (dst, CAIRO_OPERATOR_ADD, tmp, clip, - 0, 0, - clip_x, clip_y, - extents->bounded.x, extents->bounded.y, - extents->bounded.width, extents->bounded.height); - } - cairo_surface_destroy (clip); - -cleanup: - cairo_surface_destroy (tmp); - return status; -} - -/* Handles compositing for %CAIRO_OPERATOR_SOURCE, which is special; it's - * defined as (src IN mask IN clip) ADD (dst OUT (mask IN clip)) - */ -static cairo_status_t -clip_and_composite_source (const cairo_mask_compositor_t *compositor, - void *draw_closure, - draw_func_t draw_func, - draw_func_t mask_func, - cairo_pattern_t *pattern, - const cairo_composite_rectangles_t *extents) -{ - cairo_surface_t *dst = extents->surface; - cairo_surface_t *mask, *src; - int src_x, src_y; - - /* Create a surface that is mask IN clip */ - mask = create_composite_mask (compositor, dst, draw_closure, - draw_func, mask_func, - extents); - if (unlikely (mask->status)) - return mask->status; - - src = compositor->pattern_to_surface (dst, - pattern, - FALSE, - &extents->bounded, - &extents->source_sample_area, - &src_x, &src_y); - if (unlikely (src->status)) { - cairo_surface_destroy (mask); - return src->status; - } - - if (dst->is_clear) { - compositor->composite (dst, CAIRO_OPERATOR_SOURCE, src, mask, - extents->bounded.x + src_x, extents->bounded.y + src_y, - 0, 0, - extents->bounded.x, extents->bounded.y, - extents->bounded.width, extents->bounded.height); - } else { - /* Compute dest' = dest OUT (mask IN clip) */ - compositor->composite (dst, CAIRO_OPERATOR_DEST_OUT, mask, NULL, - 0, 0, 0, 0, - extents->bounded.x, extents->bounded.y, - extents->bounded.width, extents->bounded.height); - - /* Now compute (src IN (mask IN clip)) ADD dest' */ - compositor->composite (dst, CAIRO_OPERATOR_ADD, src, mask, - extents->bounded.x + src_x, extents->bounded.y + src_y, - 0, 0, - extents->bounded.x, extents->bounded.y, - extents->bounded.width, extents->bounded.height); - } - - cairo_surface_destroy (src); - cairo_surface_destroy (mask); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_bool_t -can_reduce_alpha_op (cairo_operator_t op) -{ - int iop = op; - switch (iop) { - case CAIRO_OPERATOR_OVER: - case CAIRO_OPERATOR_SOURCE: - case CAIRO_OPERATOR_ADD: - return TRUE; - default: - return FALSE; - } -} - -static cairo_bool_t -reduce_alpha_op (cairo_surface_t *dst, - cairo_operator_t op, - const cairo_pattern_t *pattern) -{ - return dst->is_clear && - dst->content == CAIRO_CONTENT_ALPHA && - _cairo_pattern_is_opaque_solid (pattern) && - can_reduce_alpha_op (op); -} - -static cairo_status_t -fixup_unbounded (const cairo_mask_compositor_t *compositor, - cairo_surface_t *dst, - const cairo_composite_rectangles_t *extents) -{ - cairo_rectangle_int_t rects[4]; - int n; - - if (extents->bounded.width == extents->unbounded.width && - extents->bounded.height == extents->unbounded.height) - { - return CAIRO_STATUS_SUCCESS; - } - - n = 0; - if (extents->bounded.width == 0 || extents->bounded.height == 0) { - rects[n].x = extents->unbounded.x; - rects[n].width = extents->unbounded.width; - rects[n].y = extents->unbounded.y; - rects[n].height = extents->unbounded.height; - n++; - } else { - /* top */ - if (extents->bounded.y != extents->unbounded.y) { - rects[n].x = extents->unbounded.x; - rects[n].width = extents->unbounded.width; - rects[n].y = extents->unbounded.y; - rects[n].height = extents->bounded.y - extents->unbounded.y; - n++; - } - /* left */ - if (extents->bounded.x != extents->unbounded.x) { - rects[n].x = extents->unbounded.x; - rects[n].width = extents->bounded.x - extents->unbounded.x; - rects[n].y = extents->bounded.y; - rects[n].height = extents->bounded.height; - n++; - } - /* right */ - if (extents->bounded.x + extents->bounded.width != extents->unbounded.x + extents->unbounded.width) { - rects[n].x = extents->bounded.x + extents->bounded.width; - rects[n].width = extents->unbounded.x + extents->unbounded.width - rects[n].x; - rects[n].y = extents->bounded.y; - rects[n].height = extents->bounded.height; - n++; - } - /* bottom */ - if (extents->bounded.y + extents->bounded.height != extents->unbounded.y + extents->unbounded.height) { - rects[n].x = extents->unbounded.x; - rects[n].width = extents->unbounded.width; - rects[n].y = extents->bounded.y + extents->bounded.height; - rects[n].height = extents->unbounded.y + extents->unbounded.height - rects[n].y; - n++; - } - } - - return compositor->fill_rectangles (dst, CAIRO_OPERATOR_CLEAR, - CAIRO_COLOR_TRANSPARENT, - rects, n); -} - -static cairo_status_t -fixup_unbounded_with_mask (const cairo_mask_compositor_t *compositor, - cairo_surface_t *dst, - const cairo_composite_rectangles_t *extents) -{ - cairo_surface_t *mask; - int mask_x, mask_y; - - mask = get_clip_source (compositor, - extents->clip, dst, &extents->unbounded, - &mask_x, &mask_y); - if (unlikely (mask->status)) - return mask->status; - - /* top */ - if (extents->bounded.y != extents->unbounded.y) { - int x = extents->unbounded.x; - int y = extents->unbounded.y; - int width = extents->unbounded.width; - int height = extents->bounded.y - y; - - compositor->composite (dst, CAIRO_OPERATOR_DEST_OUT, mask, NULL, - x + mask_x, y + mask_y, - 0, 0, - x, y, - width, height); - } - - /* left */ - if (extents->bounded.x != extents->unbounded.x) { - int x = extents->unbounded.x; - int y = extents->bounded.y; - int width = extents->bounded.x - x; - int height = extents->bounded.height; - - compositor->composite (dst, CAIRO_OPERATOR_DEST_OUT, mask, NULL, - x + mask_x, y + mask_y, - 0, 0, - x, y, - width, height); - } - - /* right */ - if (extents->bounded.x + extents->bounded.width != extents->unbounded.x + extents->unbounded.width) { - int x = extents->bounded.x + extents->bounded.width; - int y = extents->bounded.y; - int width = extents->unbounded.x + extents->unbounded.width - x; - int height = extents->bounded.height; - - compositor->composite (dst, CAIRO_OPERATOR_DEST_OUT, mask, NULL, - x + mask_x, y + mask_y, - 0, 0, - x, y, - width, height); - } - - /* bottom */ - if (extents->bounded.y + extents->bounded.height != extents->unbounded.y + extents->unbounded.height) { - int x = extents->unbounded.x; - int y = extents->bounded.y + extents->bounded.height; - int width = extents->unbounded.width; - int height = extents->unbounded.y + extents->unbounded.height - y; - - compositor->composite (dst, CAIRO_OPERATOR_DEST_OUT, mask, NULL, - x + mask_x, y + mask_y, - 0, 0, - x, y, - width, height); - } - - cairo_surface_destroy (mask); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -fixup_unbounded_boxes (const cairo_mask_compositor_t *compositor, - const cairo_composite_rectangles_t *extents, - cairo_boxes_t *boxes) -{ - cairo_surface_t *dst = extents->surface; - cairo_boxes_t clear; - cairo_region_t *clip_region; - cairo_box_t box; - cairo_status_t status; - struct _cairo_boxes_chunk *chunk; - int i; - - assert (boxes->is_pixel_aligned); - - clip_region = NULL; - if (_cairo_clip_is_region (extents->clip) && - (clip_region = _cairo_clip_get_region (extents->clip)) && - cairo_region_contains_rectangle (clip_region, - &extents->bounded) == CAIRO_REGION_OVERLAP_IN) - clip_region = NULL; - - - if (boxes->num_boxes <= 1 && clip_region == NULL) - return fixup_unbounded (compositor, dst, extents); - - _cairo_boxes_init (&clear); - - box.p1.x = _cairo_fixed_from_int (extents->unbounded.x + extents->unbounded.width); - box.p1.y = _cairo_fixed_from_int (extents->unbounded.y); - box.p2.x = _cairo_fixed_from_int (extents->unbounded.x); - box.p2.y = _cairo_fixed_from_int (extents->unbounded.y + extents->unbounded.height); - - if (clip_region == NULL) { - cairo_boxes_t tmp; - - _cairo_boxes_init (&tmp); - - status = _cairo_boxes_add (&tmp, CAIRO_ANTIALIAS_DEFAULT, &box); - assert (status == CAIRO_STATUS_SUCCESS); - - tmp.chunks.next = &boxes->chunks; - tmp.num_boxes += boxes->num_boxes; - - status = _cairo_bentley_ottmann_tessellate_boxes (&tmp, - CAIRO_FILL_RULE_WINDING, - &clear); - - tmp.chunks.next = NULL; - } else { - pixman_box32_t *pbox; - - pbox = pixman_region32_rectangles (&clip_region->rgn, &i); - _cairo_boxes_limit (&clear, (cairo_box_t *) pbox, i); - - status = _cairo_boxes_add (&clear, CAIRO_ANTIALIAS_DEFAULT, &box); - assert (status == CAIRO_STATUS_SUCCESS); - - for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) { - status = _cairo_boxes_add (&clear, - CAIRO_ANTIALIAS_DEFAULT, - &chunk->base[i]); - if (unlikely (status)) { - _cairo_boxes_fini (&clear); - return status; - } - } - } - - status = _cairo_bentley_ottmann_tessellate_boxes (&clear, - CAIRO_FILL_RULE_WINDING, - &clear); - } - - if (likely (status == CAIRO_STATUS_SUCCESS)) { - status = compositor->fill_boxes (dst, - CAIRO_OPERATOR_CLEAR, - CAIRO_COLOR_TRANSPARENT, - &clear); - } - - _cairo_boxes_fini (&clear); - - return status; -} - -enum { - NEED_CLIP_REGION = 0x1, - NEED_CLIP_SURFACE = 0x2, - FORCE_CLIP_REGION = 0x4, -}; - -static cairo_bool_t -need_bounded_clip (cairo_composite_rectangles_t *extents) -{ - unsigned int flags = NEED_CLIP_REGION; - if (! _cairo_clip_is_region (extents->clip)) - flags |= NEED_CLIP_SURFACE; - return flags; -} - -static cairo_bool_t -need_unbounded_clip (cairo_composite_rectangles_t *extents) -{ - unsigned int flags = 0; - if (! extents->is_bounded) { - flags |= NEED_CLIP_REGION; - if (! _cairo_clip_is_region (extents->clip)) - flags |= NEED_CLIP_SURFACE; - } - if (extents->clip->path != NULL) - flags |= NEED_CLIP_SURFACE; - return flags; -} - -static cairo_status_t -clip_and_composite (const cairo_mask_compositor_t *compositor, - draw_func_t draw_func, - draw_func_t mask_func, - void *draw_closure, - cairo_composite_rectangles_t*extents, - unsigned int need_clip) -{ - cairo_surface_t *dst = extents->surface; - cairo_operator_t op = extents->op; - cairo_pattern_t *src = &extents->source_pattern.base; - cairo_region_t *clip_region = NULL; - cairo_status_t status; - - compositor->acquire (dst); - - if (need_clip & NEED_CLIP_REGION) { - clip_region = _cairo_clip_get_region (extents->clip); - if ((need_clip & FORCE_CLIP_REGION) == 0 && - _cairo_composite_rectangles_can_reduce_clip (extents, - extents->clip)) - clip_region = NULL; - if (clip_region != NULL) { - status = compositor->set_clip_region (dst, clip_region); - if (unlikely (status)) { - compositor->release (dst); - return status; - } - } - } - - if (reduce_alpha_op (dst, op, &extents->source_pattern.base)) { - op = CAIRO_OPERATOR_ADD; - src = NULL; - } - - if (op == CAIRO_OPERATOR_SOURCE) { - status = clip_and_composite_source (compositor, - draw_closure, draw_func, mask_func, - src, extents); - } else { - if (op == CAIRO_OPERATOR_CLEAR) { - op = CAIRO_OPERATOR_DEST_OUT; - src = NULL; - } - - if (need_clip & NEED_CLIP_SURFACE) { - if (extents->is_bounded) { - status = clip_and_composite_with_mask (compositor, - draw_closure, - draw_func, - mask_func, - op, src, extents); - } else { - status = clip_and_composite_combine (compositor, - draw_closure, - draw_func, - op, src, extents); - } - } else { - status = draw_func (compositor, - dst, draw_closure, - op, src, &extents->source_sample_area, - 0, 0, - &extents->bounded, - extents->clip); - } - } - - if (status == CAIRO_STATUS_SUCCESS && ! extents->is_bounded) { - if (need_clip & NEED_CLIP_SURFACE) - status = fixup_unbounded_with_mask (compositor, dst, extents); - else - status = fixup_unbounded (compositor, dst, extents); - } - - if (clip_region) - compositor->set_clip_region (dst, NULL); - - compositor->release (dst); - - return status; -} - -static cairo_int_status_t -trim_extents_to_boxes (cairo_composite_rectangles_t *extents, - cairo_boxes_t *boxes) -{ - cairo_box_t box; - - _cairo_boxes_extents (boxes, &box); - return _cairo_composite_rectangles_intersect_mask_extents (extents, &box); -} - -static cairo_status_t -upload_boxes (const cairo_mask_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - cairo_boxes_t *boxes) -{ - cairo_surface_t *dst = extents->surface; - const cairo_pattern_t *source = &extents->source_pattern.base; - cairo_surface_t *src; - cairo_rectangle_int_t limit; - cairo_int_status_t status; - int tx, ty; - - src = _cairo_pattern_get_source ((cairo_surface_pattern_t *)source, &limit); - if (!(src->type == CAIRO_SURFACE_TYPE_IMAGE || src->type == dst->type)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (! _cairo_matrix_is_integer_translation (&source->matrix, &tx, &ty)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* Check that the data is entirely within the image */ - if (extents->bounded.x + tx < limit.x || extents->bounded.y + ty < limit.y) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (extents->bounded.x + extents->bounded.width + tx > limit.x + limit.width || - extents->bounded.y + extents->bounded.height + ty > limit.y + limit.height) - return CAIRO_INT_STATUS_UNSUPPORTED; - - tx += limit.x; - ty += limit.y; - - if (src->type == CAIRO_SURFACE_TYPE_IMAGE) - status = compositor->draw_image_boxes (dst, - (cairo_image_surface_t *)src, - boxes, tx, ty); - else - status = compositor->copy_boxes (dst, src, boxes, &extents->bounded, - tx, ty); - - return status; -} - -static cairo_status_t -composite_boxes (const cairo_mask_compositor_t *compositor, - const cairo_composite_rectangles_t *extents, - cairo_boxes_t *boxes) -{ - cairo_surface_t *dst = extents->surface; - cairo_operator_t op = extents->op; - const cairo_pattern_t *source = &extents->source_pattern.base; - cairo_bool_t need_clip_mask = extents->clip->path != NULL; - cairo_status_t status; - - if (need_clip_mask && - (! extents->is_bounded || op == CAIRO_OPERATOR_SOURCE)) - { - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - status = compositor->acquire (dst); - if (unlikely (status)) - return status; - - if (! need_clip_mask && source->type == CAIRO_PATTERN_TYPE_SOLID) { - const cairo_color_t *color; - - color = &((cairo_solid_pattern_t *) source)->color; - status = compositor->fill_boxes (dst, op, color, boxes); - } else { - cairo_surface_t *src, *mask = NULL; - int src_x, src_y; - int mask_x = 0, mask_y = 0; - - if (need_clip_mask) { - mask = get_clip_source (compositor, - extents->clip, dst, &extents->bounded, - &mask_x, &mask_y); - if (unlikely (mask->status)) - return mask->status; - - if (op == CAIRO_OPERATOR_CLEAR) { - source = NULL; - op = CAIRO_OPERATOR_DEST_OUT; - } - } - - if (source || mask == NULL) { - src = compositor->pattern_to_surface (dst, source, FALSE, - &extents->bounded, - &extents->source_sample_area, - &src_x, &src_y); - } else { - src = mask; - src_x = mask_x; - src_y = mask_y; - mask = NULL; - } - - status = compositor->composite_boxes (dst, op, src, mask, - src_x, src_y, - mask_x, mask_y, - 0, 0, - boxes, &extents->bounded); - - cairo_surface_destroy (src); - cairo_surface_destroy (mask); - } - - if (status == CAIRO_STATUS_SUCCESS && ! extents->is_bounded) - status = fixup_unbounded_boxes (compositor, extents, boxes); - - compositor->release (dst); - - return status; -} - -static cairo_status_t -clip_and_composite_boxes (const cairo_mask_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - cairo_boxes_t *boxes) -{ - cairo_surface_t *dst = extents->surface; - cairo_int_status_t status; - - if (boxes->num_boxes == 0) { - if (extents->is_bounded) - return CAIRO_STATUS_SUCCESS; - - return fixup_unbounded_boxes (compositor, extents, boxes); - } - - if (! boxes->is_pixel_aligned) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = trim_extents_to_boxes (extents, boxes); - if (unlikely (status)) - return status; - - if (extents->source_pattern.base.type == CAIRO_PATTERN_TYPE_SURFACE && - extents->clip->path == NULL && - (extents->op == CAIRO_OPERATOR_SOURCE || - (dst->is_clear && (extents->op == CAIRO_OPERATOR_OVER || - extents->op == CAIRO_OPERATOR_ADD)))) - { - status = upload_boxes (compositor, extents, boxes); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - } - - return composite_boxes (compositor, extents, boxes); -} - -/* high-level compositor interface */ - -static cairo_int_status_t -_cairo_mask_compositor_paint (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents) -{ - cairo_mask_compositor_t *compositor = (cairo_mask_compositor_t*)_compositor; - cairo_boxes_t boxes; - cairo_int_status_t status; - - status = compositor->check_composite (extents); - if (unlikely (status)) - return status; - - _cairo_clip_steal_boxes (extents->clip, &boxes); - status = clip_and_composite_boxes (compositor, extents, &boxes); - _cairo_clip_unsteal_boxes (extents->clip, &boxes); - - return status; -} - -struct composite_opacity_info { - const cairo_mask_compositor_t *compositor; - uint8_t op; - cairo_surface_t *dst; - cairo_surface_t *src; - int src_x, src_y; - double opacity; -}; - -static void composite_opacity(void *closure, - int16_t x, int16_t y, - int16_t w, int16_t h, - uint16_t coverage) -{ - struct composite_opacity_info *info = closure; - const cairo_mask_compositor_t *compositor = info->compositor; - cairo_surface_t *mask; - int mask_x, mask_y; - cairo_color_t color; - cairo_solid_pattern_t solid; - - _cairo_color_init_rgba (&color, 0, 0, 0, info->opacity * coverage); - _cairo_pattern_init_solid (&solid, &color); - mask = compositor->pattern_to_surface (info->dst, &solid.base, TRUE, - &_cairo_unbounded_rectangle, - &_cairo_unbounded_rectangle, - &mask_x, &mask_y); - if (likely (mask->status == CAIRO_STATUS_SUCCESS)) { - if (info->src) { - compositor->composite (info->dst, info->op, info->src, mask, - x + info->src_x, y + info->src_y, - mask_x, mask_y, - x, y, - w, h); - } else { - compositor->composite (info->dst, info->op, mask, NULL, - mask_x, mask_y, - 0, 0, - x, y, - w, h); - } - } - - cairo_surface_destroy (mask); -} - -static cairo_int_status_t -composite_opacity_boxes (const cairo_mask_compositor_t *compositor, - cairo_surface_t *dst, - void *closure, - cairo_operator_t op, - const cairo_pattern_t *src_pattern, - const cairo_rectangle_int_t *src_sample, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents, - cairo_clip_t *clip) -{ - const cairo_solid_pattern_t *mask_pattern = closure; - struct composite_opacity_info info; - int i; - - assert (clip); - - info.compositor = compositor; - info.op = op; - info.dst = dst; - - if (src_pattern != NULL) { - info.src = compositor->pattern_to_surface (dst, src_pattern, FALSE, - extents, src_sample, - &info.src_x, &info.src_y); - if (unlikely (info.src->status)) - return info.src->status; - } else - info.src = NULL; - - info.opacity = mask_pattern->color.alpha / (double) 0xffff; - - /* XXX for lots of boxes create a clip region for the fully opaque areas */ - for (i = 0; i < clip->num_boxes; i++) - do_unaligned_box(composite_opacity, &info, - &clip->boxes[i], dst_x, dst_y); - cairo_surface_destroy (info.src); - - return CAIRO_STATUS_SUCCESS; -} - -struct composite_box_info { - const cairo_mask_compositor_t *compositor; - cairo_surface_t *dst; - cairo_surface_t *src; - int src_x, src_y; - uint8_t op; -}; - -static void composite_box(void *closure, - int16_t x, int16_t y, - int16_t w, int16_t h, - uint16_t coverage) -{ - struct composite_box_info *info = closure; - const cairo_mask_compositor_t *compositor = info->compositor; - - if (! CAIRO_ALPHA_SHORT_IS_OPAQUE (coverage)) { - cairo_surface_t *mask; - cairo_color_t color; - cairo_solid_pattern_t solid; - int mask_x, mask_y; - - _cairo_color_init_rgba (&color, 0, 0, 0, coverage / (double)0xffff); - _cairo_pattern_init_solid (&solid, &color); - - mask = compositor->pattern_to_surface (info->dst, &solid.base, FALSE, - &_cairo_unbounded_rectangle, - &_cairo_unbounded_rectangle, - &mask_x, &mask_y); - - if (likely (mask->status == CAIRO_STATUS_SUCCESS)) { - compositor->composite (info->dst, info->op, info->src, mask, - x + info->src_x, y + info->src_y, - mask_x, mask_y, - x, y, - w, h); - } - - cairo_surface_destroy (mask); - } else { - compositor->composite (info->dst, info->op, info->src, NULL, - x + info->src_x, y + info->src_y, - 0, 0, - x, y, - w, h); - } -} - -static cairo_int_status_t -composite_mask_clip_boxes (const cairo_mask_compositor_t *compositor, - cairo_surface_t *dst, - void *closure, - cairo_operator_t op, - const cairo_pattern_t *src_pattern, - const cairo_rectangle_int_t *src_sample, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents, - cairo_clip_t *clip) -{ - cairo_composite_rectangles_t *composite = closure; - struct composite_box_info info; - int i; - - assert (src_pattern == NULL); - assert (op == CAIRO_OPERATOR_SOURCE); - - info.compositor = compositor; - info.op = CAIRO_OPERATOR_SOURCE; - info.dst = dst; - info.src = compositor->pattern_to_surface (dst, - &composite->mask_pattern.base, - FALSE, extents, - &composite->mask_sample_area, - &info.src_x, &info.src_y); - if (unlikely (info.src->status)) - return info.src->status; - - info.src_x += dst_x; - info.src_y += dst_y; - - for (i = 0; i < clip->num_boxes; i++) - do_unaligned_box(composite_box, &info, &clip->boxes[i], dst_x, dst_y); - - cairo_surface_destroy (info.src); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -composite_mask (const cairo_mask_compositor_t *compositor, - cairo_surface_t *dst, - void *closure, - cairo_operator_t op, - const cairo_pattern_t *src_pattern, - const cairo_rectangle_int_t *src_sample, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents, - cairo_clip_t *clip) -{ - cairo_composite_rectangles_t *composite = closure; - cairo_surface_t *src, *mask; - int src_x, src_y; - int mask_x, mask_y; - - if (src_pattern != NULL) { - src = compositor->pattern_to_surface (dst, src_pattern, FALSE, - extents, src_sample, - &src_x, &src_y); - if (unlikely (src->status)) - return src->status; - - mask = compositor->pattern_to_surface (dst, &composite->mask_pattern.base, TRUE, - extents, &composite->mask_sample_area, - &mask_x, &mask_y); - if (unlikely (mask->status)) { - cairo_surface_destroy (src); - return mask->status; - } - - compositor->composite (dst, op, src, mask, - extents->x + src_x, extents->y + src_y, - extents->x + mask_x, extents->y + mask_y, - extents->x - dst_x, extents->y - dst_y, - extents->width, extents->height); - - cairo_surface_destroy (mask); - cairo_surface_destroy (src); - } else { - src = compositor->pattern_to_surface (dst, &composite->mask_pattern.base, FALSE, - extents, &composite->mask_sample_area, - &src_x, &src_y); - if (unlikely (src->status)) - return src->status; - - compositor->composite (dst, op, src, NULL, - extents->x + src_x, extents->y + src_y, - 0, 0, - extents->x - dst_x, extents->y - dst_y, - extents->width, extents->height); - - cairo_surface_destroy (src); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_mask_compositor_mask (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents) -{ - const cairo_mask_compositor_t *compositor = (cairo_mask_compositor_t*)_compositor; - cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED; - - status = compositor->check_composite (extents); - if (unlikely (status)) - return status; - - if (extents->mask_pattern.base.type == CAIRO_PATTERN_TYPE_SOLID && - extents->clip->path == NULL && - _cairo_clip_is_region (extents->clip)) { - status = clip_and_composite (compositor, - composite_opacity_boxes, - composite_opacity_boxes, - &extents->mask_pattern.solid, - extents, need_unbounded_clip (extents)); - } else { - status = clip_and_composite (compositor, - composite_mask, - extents->clip->path == NULL ? composite_mask_clip_boxes : NULL, - extents, - extents, need_bounded_clip (extents)); - } - - return status; -} - -static cairo_int_status_t -_cairo_mask_compositor_stroke (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias) -{ - const cairo_mask_compositor_t *compositor = (cairo_mask_compositor_t*)_compositor; - cairo_surface_t *mask; - cairo_surface_pattern_t pattern; - cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED; - - status = compositor->check_composite (extents); - if (unlikely (status)) - return status; - - if (_cairo_path_fixed_stroke_is_rectilinear (path)) { - cairo_boxes_t boxes; - - _cairo_boxes_init_with_clip (&boxes, extents->clip); - status = _cairo_path_fixed_stroke_rectilinear_to_boxes (path, - style, - ctm, - antialias, - &boxes); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) - status = clip_and_composite_boxes (compositor, extents, &boxes); - _cairo_boxes_fini (&boxes); - } - - - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - mask = cairo_surface_create_similar_image (extents->surface, - CAIRO_FORMAT_A8, - extents->bounded.width, - extents->bounded.height); - if (unlikely (mask->status)) - return mask->status; - - status = _cairo_surface_offset_stroke (mask, - extents->bounded.x, - extents->bounded.y, - CAIRO_OPERATOR_ADD, - &_cairo_pattern_white.base, - path, style, ctm, ctm_inverse, - tolerance, antialias, - extents->clip); - if (unlikely (status)) { - cairo_surface_destroy (mask); - return status; - } - - _cairo_pattern_init_for_surface (&pattern, mask); - cairo_surface_destroy (mask); - - cairo_matrix_init_translate (&pattern.base.matrix, - -extents->bounded.x, - -extents->bounded.y); - pattern.base.filter = CAIRO_FILTER_NEAREST; - pattern.base.extend = CAIRO_EXTEND_NONE; - status = _cairo_surface_mask (extents->surface, - extents->op, - &extents->source_pattern.base, - &pattern.base, - extents->clip); - _cairo_pattern_fini (&pattern.base); - } - - return status; -} - -static cairo_int_status_t -_cairo_mask_compositor_fill (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - const cairo_mask_compositor_t *compositor = (cairo_mask_compositor_t*)_compositor; - cairo_surface_t *mask; - cairo_surface_pattern_t pattern; - cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED; - - status = compositor->check_composite (extents); - if (unlikely (status)) - return status; - - if (_cairo_path_fixed_fill_is_rectilinear (path)) { - cairo_boxes_t boxes; - - _cairo_boxes_init_with_clip (&boxes, extents->clip); - status = _cairo_path_fixed_fill_rectilinear_to_boxes (path, - fill_rule, - antialias, - &boxes); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) - status = clip_and_composite_boxes (compositor, extents, &boxes); - _cairo_boxes_fini (&boxes); - } - - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - mask = cairo_surface_create_similar_image (extents->surface, - CAIRO_FORMAT_A8, - extents->bounded.width, - extents->bounded.height); - if (unlikely (mask->status)) - return mask->status; - - status = _cairo_surface_offset_fill (mask, - extents->bounded.x, - extents->bounded.y, - CAIRO_OPERATOR_ADD, - &_cairo_pattern_white.base, - path, fill_rule, tolerance, antialias, - extents->clip); - if (unlikely (status)) { - cairo_surface_destroy (mask); - return status; - } - - _cairo_pattern_init_for_surface (&pattern, mask); - cairo_surface_destroy (mask); - - cairo_matrix_init_translate (&pattern.base.matrix, - -extents->bounded.x, - -extents->bounded.y); - pattern.base.filter = CAIRO_FILTER_NEAREST; - pattern.base.extend = CAIRO_EXTEND_NONE; - status = _cairo_surface_mask (extents->surface, - extents->op, - &extents->source_pattern.base, - &pattern.base, - extents->clip); - _cairo_pattern_fini (&pattern.base); - } - - return status; -} - -static cairo_int_status_t -_cairo_mask_compositor_glyphs (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_bool_t overlap) -{ - const cairo_mask_compositor_t *compositor = (cairo_mask_compositor_t*)_compositor; - cairo_surface_t *mask; - cairo_surface_pattern_t pattern; - cairo_int_status_t status; - - status = compositor->check_composite (extents); - if (unlikely (status)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - mask = cairo_surface_create_similar_image (extents->surface, - CAIRO_FORMAT_A8, - extents->bounded.width, - extents->bounded.height); - if (unlikely (mask->status)) - return mask->status; - - status = _cairo_surface_offset_glyphs (mask, - extents->bounded.x, - extents->bounded.y, - CAIRO_OPERATOR_ADD, - &_cairo_pattern_white.base, - scaled_font, glyphs, num_glyphs, - extents->clip); - if (unlikely (status)) { - cairo_surface_destroy (mask); - return status; - } - - _cairo_pattern_init_for_surface (&pattern, mask); - cairo_surface_destroy (mask); - - cairo_matrix_init_translate (&pattern.base.matrix, - -extents->bounded.x, - -extents->bounded.y); - pattern.base.filter = CAIRO_FILTER_NEAREST; - pattern.base.extend = CAIRO_EXTEND_NONE; - status = _cairo_surface_mask (extents->surface, - extents->op, - &extents->source_pattern.base, - &pattern.base, - extents->clip); - _cairo_pattern_fini (&pattern.base); - - return status; -} - -void -_cairo_mask_compositor_init (cairo_mask_compositor_t *compositor, - const cairo_compositor_t *delegate) -{ - compositor->base.delegate = delegate; - - compositor->base.paint = _cairo_mask_compositor_paint; - compositor->base.mask = _cairo_mask_compositor_mask; - compositor->base.fill = _cairo_mask_compositor_fill; - compositor->base.stroke = _cairo_mask_compositor_stroke; - compositor->base.glyphs = _cairo_mask_compositor_glyphs; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-matrix.c b/source/libs/cairo/cairo-src/src/cairo-matrix.c deleted file mode 100644 index ae498f5151a2378814779095bf400d183bbe42f9..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-matrix.c +++ /dev/null @@ -1,1212 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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" -#include "cairo-error-private.h" -#include <float.h> - -#define PIXMAN_MAX_INT ((pixman_fixed_1 >> 1) - pixman_fixed_e) /* need to ensure deltas also fit */ - -#if _XOPEN_SOURCE >= 600 || defined (_ISOC99_SOURCE) -#define ISFINITE(x) isfinite (x) -#else -#define ISFINITE(x) ((x) * (x) >= 0.) /* check for NaNs */ -#endif - -/** - * SECTION:cairo-matrix - * @Title: cairo_matrix_t - * @Short_Description: Generic matrix operations - * @See_Also: #cairo_t - * - * #cairo_matrix_t is used throughout cairo to convert between different - * coordinate spaces. A #cairo_matrix_t holds an affine transformation, - * such as a scale, rotation, shear, or a combination of these. - * The transformation of a point (<literal>x</literal>,<literal>y</literal>) - * is given by: - * - * <programlisting> - * x_new = xx * x + xy * y + x0; - * y_new = yx * x + yy * y + y0; - * </programlisting> - * - * The current transformation matrix of a #cairo_t, represented as a - * #cairo_matrix_t, defines the transformation from user-space - * coordinates to device-space coordinates. See cairo_get_matrix() and - * cairo_set_matrix(). - **/ - -static void -_cairo_matrix_scalar_multiply (cairo_matrix_t *matrix, double scalar); - -static void -_cairo_matrix_compute_adjoint (cairo_matrix_t *matrix); - -/** - * cairo_matrix_init_identity: - * @matrix: a #cairo_matrix_t - * - * Modifies @matrix to be an identity transformation. - * - * Since: 1.0 - **/ -void -cairo_matrix_init_identity (cairo_matrix_t *matrix) -{ - cairo_matrix_init (matrix, - 1, 0, - 0, 1, - 0, 0); -} -slim_hidden_def(cairo_matrix_init_identity); - -/** - * cairo_matrix_init: - * @matrix: a #cairo_matrix_t - * @xx: xx component of the affine transformation - * @yx: yx component of the affine transformation - * @xy: xy component of the affine transformation - * @yy: yy component of the affine transformation - * @x0: X translation component of the affine transformation - * @y0: Y translation component of the affine transformation - * - * Sets @matrix to be the affine transformation given by - * @xx, @yx, @xy, @yy, @x0, @y0. The transformation is given - * by: - * <programlisting> - * x_new = xx * x + xy * y + x0; - * y_new = yx * x + yy * y + y0; - * </programlisting> - * - * Since: 1.0 - **/ -void -cairo_matrix_init (cairo_matrix_t *matrix, - double xx, double yx, - - double xy, double yy, - double x0, double y0) -{ - matrix->xx = xx; matrix->yx = yx; - matrix->xy = xy; matrix->yy = yy; - matrix->x0 = x0; matrix->y0 = y0; -} -slim_hidden_def(cairo_matrix_init); - -/** - * _cairo_matrix_get_affine: - * @matrix: a #cairo_matrix_t - * @xx: location to store xx component of matrix - * @yx: location to store yx component of matrix - * @xy: location to store xy component of matrix - * @yy: location to store yy component of matrix - * @x0: location to store x0 (X-translation component) of matrix, or %NULL - * @y0: location to store y0 (Y-translation component) of matrix, or %NULL - * - * Gets the matrix values for the affine transformation that @matrix represents. - * See cairo_matrix_init(). - * - * - * This function is a leftover from the old public API, but is still - * mildly useful as an internal means for getting at the matrix - * members in a positional way. For example, when reassigning to some - * external matrix type, or when renaming members to more meaningful - * names (such as a,b,c,d,e,f) for particular manipulations. - **/ -void -_cairo_matrix_get_affine (const cairo_matrix_t *matrix, - double *xx, double *yx, - double *xy, double *yy, - double *x0, double *y0) -{ - *xx = matrix->xx; - *yx = matrix->yx; - - *xy = matrix->xy; - *yy = matrix->yy; - - if (x0) - *x0 = matrix->x0; - if (y0) - *y0 = matrix->y0; -} - -/** - * cairo_matrix_init_translate: - * @matrix: a #cairo_matrix_t - * @tx: amount to translate in the X direction - * @ty: amount to translate in the Y direction - * - * Initializes @matrix to a transformation that translates by @tx and - * @ty in the X and Y dimensions, respectively. - * - * Since: 1.0 - **/ -void -cairo_matrix_init_translate (cairo_matrix_t *matrix, - double tx, double ty) -{ - cairo_matrix_init (matrix, - 1, 0, - 0, 1, - tx, ty); -} -slim_hidden_def(cairo_matrix_init_translate); - -/** - * cairo_matrix_translate: - * @matrix: a #cairo_matrix_t - * @tx: amount to translate in the X direction - * @ty: amount to translate in the Y direction - * - * Applies a translation by @tx, @ty to the transformation in - * @matrix. The effect of the new transformation is to first translate - * the coordinates by @tx and @ty, then apply the original transformation - * to the coordinates. - * - * Since: 1.0 - **/ -void -cairo_matrix_translate (cairo_matrix_t *matrix, double tx, double ty) -{ - cairo_matrix_t tmp; - - cairo_matrix_init_translate (&tmp, tx, ty); - - cairo_matrix_multiply (matrix, &tmp, matrix); -} -slim_hidden_def (cairo_matrix_translate); - -/** - * cairo_matrix_init_scale: - * @matrix: a #cairo_matrix_t - * @sx: scale factor in the X direction - * @sy: scale factor in the Y direction - * - * Initializes @matrix to a transformation that scales by @sx and @sy - * in the X and Y dimensions, respectively. - * - * Since: 1.0 - **/ -void -cairo_matrix_init_scale (cairo_matrix_t *matrix, - double sx, double sy) -{ - cairo_matrix_init (matrix, - sx, 0, - 0, sy, - 0, 0); -} -slim_hidden_def(cairo_matrix_init_scale); - -/** - * cairo_matrix_scale: - * @matrix: a #cairo_matrix_t - * @sx: scale factor in the X direction - * @sy: scale factor in the Y direction - * - * Applies scaling by @sx, @sy to the transformation in @matrix. The - * effect of the new transformation is to first scale the coordinates - * by @sx and @sy, then apply the original transformation to the coordinates. - * - * Since: 1.0 - **/ -void -cairo_matrix_scale (cairo_matrix_t *matrix, double sx, double sy) -{ - cairo_matrix_t tmp; - - cairo_matrix_init_scale (&tmp, sx, sy); - - cairo_matrix_multiply (matrix, &tmp, matrix); -} -slim_hidden_def(cairo_matrix_scale); - -/** - * cairo_matrix_init_rotate: - * @matrix: a #cairo_matrix_t - * @radians: angle of rotation, in radians. The direction of rotation - * is defined such that positive angles rotate in the direction from - * the positive X axis toward the positive Y axis. With the default - * axis orientation of cairo, positive angles rotate in a clockwise - * direction. - * - * Initialized @matrix to a transformation that rotates by @radians. - * - * Since: 1.0 - **/ -void -cairo_matrix_init_rotate (cairo_matrix_t *matrix, - double radians) -{ - double s; - double c; - - s = sin (radians); - c = cos (radians); - - cairo_matrix_init (matrix, - c, s, - -s, c, - 0, 0); -} -slim_hidden_def(cairo_matrix_init_rotate); - -/** - * cairo_matrix_rotate: - * @matrix: a #cairo_matrix_t - * @radians: angle of rotation, in radians. The direction of rotation - * is defined such that positive angles rotate in the direction from - * the positive X axis toward the positive Y axis. With the default - * axis orientation of cairo, positive angles rotate in a clockwise - * direction. - * - * Applies rotation by @radians to the transformation in - * @matrix. The effect of the new transformation is to first rotate the - * coordinates by @radians, then apply the original transformation - * to the coordinates. - * - * Since: 1.0 - **/ -void -cairo_matrix_rotate (cairo_matrix_t *matrix, double radians) -{ - cairo_matrix_t tmp; - - cairo_matrix_init_rotate (&tmp, radians); - - cairo_matrix_multiply (matrix, &tmp, matrix); -} - -/** - * cairo_matrix_multiply: - * @result: a #cairo_matrix_t in which to store the result - * @a: a #cairo_matrix_t - * @b: a #cairo_matrix_t - * - * Multiplies the affine transformations in @a and @b together - * and stores the result in @result. The effect of the resulting - * transformation is to first apply the transformation in @a to the - * coordinates and then apply the transformation in @b to the - * coordinates. - * - * It is allowable for @result to be identical to either @a or @b. - * - * Since: 1.0 - **/ -/* - * XXX: The ordering of the arguments to this function corresponds - * to [row_vector]*A*B. If we want to use column vectors instead, - * then we need to switch the two arguments and fix up all - * uses. - */ -void -cairo_matrix_multiply (cairo_matrix_t *result, const cairo_matrix_t *a, const cairo_matrix_t *b) -{ - cairo_matrix_t r; - - r.xx = a->xx * b->xx + a->yx * b->xy; - r.yx = a->xx * b->yx + a->yx * b->yy; - - r.xy = a->xy * b->xx + a->yy * b->xy; - r.yy = a->xy * b->yx + a->yy * b->yy; - - r.x0 = a->x0 * b->xx + a->y0 * b->xy + b->x0; - r.y0 = a->x0 * b->yx + a->y0 * b->yy + b->y0; - - *result = r; -} -slim_hidden_def(cairo_matrix_multiply); - -void -_cairo_matrix_multiply (cairo_matrix_t *r, - const cairo_matrix_t *a, - const cairo_matrix_t *b) -{ - r->xx = a->xx * b->xx + a->yx * b->xy; - r->yx = a->xx * b->yx + a->yx * b->yy; - - r->xy = a->xy * b->xx + a->yy * b->xy; - r->yy = a->xy * b->yx + a->yy * b->yy; - - r->x0 = a->x0 * b->xx + a->y0 * b->xy + b->x0; - r->y0 = a->x0 * b->yx + a->y0 * b->yy + b->y0; -} - -/** - * cairo_matrix_transform_distance: - * @matrix: a #cairo_matrix_t - * @dx: X component of a distance vector. An in/out parameter - * @dy: Y component of a distance vector. An in/out parameter - * - * Transforms the distance vector (@dx,@dy) by @matrix. This is - * similar to cairo_matrix_transform_point() except that the translation - * components of the transformation are ignored. The calculation of - * the returned vector is as follows: - * - * <programlisting> - * dx2 = dx1 * a + dy1 * c; - * dy2 = dx1 * b + dy1 * d; - * </programlisting> - * - * Affine transformations are position invariant, so the same vector - * always transforms to the same vector. If (@x1,@y1) transforms - * to (@x2,@y2) then (@x1+@dx1,@y1+@dy1) will transform to - * (@x1+@dx2,@y1+@dy2) for all values of @x1 and @x2. - * - * Since: 1.0 - **/ -void -cairo_matrix_transform_distance (const cairo_matrix_t *matrix, double *dx, double *dy) -{ - double new_x, new_y; - - new_x = (matrix->xx * *dx + matrix->xy * *dy); - new_y = (matrix->yx * *dx + matrix->yy * *dy); - - *dx = new_x; - *dy = new_y; -} -slim_hidden_def(cairo_matrix_transform_distance); - -/** - * cairo_matrix_transform_point: - * @matrix: a #cairo_matrix_t - * @x: X position. An in/out parameter - * @y: Y position. An in/out parameter - * - * Transforms the point (@x, @y) by @matrix. - * - * Since: 1.0 - **/ -void -cairo_matrix_transform_point (const cairo_matrix_t *matrix, double *x, double *y) -{ - cairo_matrix_transform_distance (matrix, x, y); - - *x += matrix->x0; - *y += matrix->y0; -} -slim_hidden_def(cairo_matrix_transform_point); - -void -_cairo_matrix_transform_bounding_box (const cairo_matrix_t *matrix, - double *x1, double *y1, - double *x2, double *y2, - cairo_bool_t *is_tight) -{ - int i; - double quad_x[4], quad_y[4]; - double min_x, max_x; - double min_y, max_y; - - if (matrix->xy == 0. && matrix->yx == 0.) { - /* non-rotation/skew matrix, just map the two extreme points */ - - if (matrix->xx != 1.) { - quad_x[0] = *x1 * matrix->xx; - quad_x[1] = *x2 * matrix->xx; - if (quad_x[0] < quad_x[1]) { - *x1 = quad_x[0]; - *x2 = quad_x[1]; - } else { - *x1 = quad_x[1]; - *x2 = quad_x[0]; - } - } - if (matrix->x0 != 0.) { - *x1 += matrix->x0; - *x2 += matrix->x0; - } - - if (matrix->yy != 1.) { - quad_y[0] = *y1 * matrix->yy; - quad_y[1] = *y2 * matrix->yy; - if (quad_y[0] < quad_y[1]) { - *y1 = quad_y[0]; - *y2 = quad_y[1]; - } else { - *y1 = quad_y[1]; - *y2 = quad_y[0]; - } - } - if (matrix->y0 != 0.) { - *y1 += matrix->y0; - *y2 += matrix->y0; - } - - if (is_tight) - *is_tight = TRUE; - - return; - } - - /* general matrix */ - quad_x[0] = *x1; - quad_y[0] = *y1; - cairo_matrix_transform_point (matrix, &quad_x[0], &quad_y[0]); - - quad_x[1] = *x2; - quad_y[1] = *y1; - cairo_matrix_transform_point (matrix, &quad_x[1], &quad_y[1]); - - quad_x[2] = *x1; - quad_y[2] = *y2; - cairo_matrix_transform_point (matrix, &quad_x[2], &quad_y[2]); - - quad_x[3] = *x2; - quad_y[3] = *y2; - cairo_matrix_transform_point (matrix, &quad_x[3], &quad_y[3]); - - min_x = max_x = quad_x[0]; - min_y = max_y = quad_y[0]; - - for (i=1; i < 4; i++) { - if (quad_x[i] < min_x) - min_x = quad_x[i]; - if (quad_x[i] > max_x) - max_x = quad_x[i]; - - if (quad_y[i] < min_y) - min_y = quad_y[i]; - if (quad_y[i] > max_y) - max_y = quad_y[i]; - } - - *x1 = min_x; - *y1 = min_y; - *x2 = max_x; - *y2 = max_y; - - if (is_tight) { - /* it's tight if and only if the four corner points form an axis-aligned - rectangle. - And that's true if and only if we can derive corners 0 and 3 from - corners 1 and 2 in one of two straightforward ways... - We could use a tolerance here but for now we'll fall back to FALSE in the case - of floating point error. - */ - *is_tight = - (quad_x[1] == quad_x[0] && quad_y[1] == quad_y[3] && - quad_x[2] == quad_x[3] && quad_y[2] == quad_y[0]) || - (quad_x[1] == quad_x[3] && quad_y[1] == quad_y[0] && - quad_x[2] == quad_x[0] && quad_y[2] == quad_y[3]); - } -} - -cairo_private void -_cairo_matrix_transform_bounding_box_fixed (const cairo_matrix_t *matrix, - cairo_box_t *bbox, - cairo_bool_t *is_tight) -{ - double x1, y1, x2, y2; - - _cairo_box_to_doubles (bbox, &x1, &y1, &x2, &y2); - _cairo_matrix_transform_bounding_box (matrix, &x1, &y1, &x2, &y2, is_tight); - _cairo_box_from_doubles (bbox, &x1, &y1, &x2, &y2); -} - -static void -_cairo_matrix_scalar_multiply (cairo_matrix_t *matrix, double scalar) -{ - matrix->xx *= scalar; - matrix->yx *= scalar; - - matrix->xy *= scalar; - matrix->yy *= scalar; - - matrix->x0 *= scalar; - matrix->y0 *= scalar; -} - -/* This function isn't a correct adjoint in that the implicit 1 in the - homogeneous result should actually be ad-bc instead. But, since this - adjoint is only used in the computation of the inverse, which - divides by det (A)=ad-bc anyway, everything works out in the end. */ -static void -_cairo_matrix_compute_adjoint (cairo_matrix_t *matrix) -{ - /* adj (A) = transpose (C:cofactor (A,i,j)) */ - double a, b, c, d, tx, ty; - - _cairo_matrix_get_affine (matrix, - &a, &b, - &c, &d, - &tx, &ty); - - cairo_matrix_init (matrix, - d, -b, - -c, a, - c*ty - d*tx, b*tx - a*ty); -} - -/** - * cairo_matrix_invert: - * @matrix: a #cairo_matrix_t - * - * Changes @matrix to be the inverse of its original value. Not - * all transformation matrices have inverses; if the matrix - * collapses points together (it is <firstterm>degenerate</firstterm>), - * then it has no inverse and this function will fail. - * - * Returns: If @matrix has an inverse, modifies @matrix to - * be the inverse matrix and returns %CAIRO_STATUS_SUCCESS. Otherwise, - * returns %CAIRO_STATUS_INVALID_MATRIX. - * - * Since: 1.0 - **/ -cairo_status_t -cairo_matrix_invert (cairo_matrix_t *matrix) -{ - double det; - - /* Simple scaling|translation matrices are quite common... */ - if (matrix->xy == 0. && matrix->yx == 0.) { - matrix->x0 = -matrix->x0; - matrix->y0 = -matrix->y0; - - if (matrix->xx != 1.) { - if (matrix->xx == 0.) - return _cairo_error (CAIRO_STATUS_INVALID_MATRIX); - - matrix->xx = 1. / matrix->xx; - matrix->x0 *= matrix->xx; - } - - if (matrix->yy != 1.) { - if (matrix->yy == 0.) - return _cairo_error (CAIRO_STATUS_INVALID_MATRIX); - - matrix->yy = 1. / matrix->yy; - matrix->y0 *= matrix->yy; - } - - return CAIRO_STATUS_SUCCESS; - } - - /* inv (A) = 1/det (A) * adj (A) */ - det = _cairo_matrix_compute_determinant (matrix); - - if (! ISFINITE (det)) - return _cairo_error (CAIRO_STATUS_INVALID_MATRIX); - - if (det == 0) - return _cairo_error (CAIRO_STATUS_INVALID_MATRIX); - - _cairo_matrix_compute_adjoint (matrix); - _cairo_matrix_scalar_multiply (matrix, 1 / det); - - return CAIRO_STATUS_SUCCESS; -} -slim_hidden_def(cairo_matrix_invert); - -cairo_bool_t -_cairo_matrix_is_invertible (const cairo_matrix_t *matrix) -{ - double det; - - det = _cairo_matrix_compute_determinant (matrix); - - return ISFINITE (det) && det != 0.; -} - -cairo_bool_t -_cairo_matrix_is_scale_0 (const cairo_matrix_t *matrix) -{ - return matrix->xx == 0. && - matrix->xy == 0. && - matrix->yx == 0. && - matrix->yy == 0.; -} - -double -_cairo_matrix_compute_determinant (const cairo_matrix_t *matrix) -{ - double a, b, c, d; - - a = matrix->xx; b = matrix->yx; - c = matrix->xy; d = matrix->yy; - - return a*d - b*c; -} - -/** - * _cairo_matrix_compute_basis_scale_factors: - * @matrix: a matrix - * @basis_scale: the scale factor in the direction of basis - * @normal_scale: the scale factor in the direction normal to the basis - * @x_basis: basis to use. X basis if true, Y basis otherwise. - * - * Computes |Mv| and det(M)/|Mv| for v=[1,0] if x_basis is true, and v=[0,1] - * otherwise, and M is @matrix. - * - * Return value: the scale factor of @matrix on the height of the font, - * or 1.0 if @matrix is %NULL. - **/ -cairo_status_t -_cairo_matrix_compute_basis_scale_factors (const cairo_matrix_t *matrix, - double *basis_scale, double *normal_scale, - cairo_bool_t x_basis) -{ - double det; - - det = _cairo_matrix_compute_determinant (matrix); - - if (! ISFINITE (det)) - return _cairo_error (CAIRO_STATUS_INVALID_MATRIX); - - if (det == 0) - { - *basis_scale = *normal_scale = 0; - } - else - { - double x = x_basis != 0; - double y = x == 0; - double major, minor; - - cairo_matrix_transform_distance (matrix, &x, &y); - major = hypot (x, y); - /* - * ignore mirroring - */ - if (det < 0) - det = -det; - if (major) - minor = det / major; - else - minor = 0.0; - if (x_basis) - { - *basis_scale = major; - *normal_scale = minor; - } - else - { - *basis_scale = minor; - *normal_scale = major; - } - } - - return CAIRO_STATUS_SUCCESS; -} - -cairo_bool_t -_cairo_matrix_is_integer_translation (const cairo_matrix_t *matrix, - int *itx, int *ity) -{ - if (_cairo_matrix_is_translation (matrix)) - { - cairo_fixed_t x0_fixed = _cairo_fixed_from_double (matrix->x0); - cairo_fixed_t y0_fixed = _cairo_fixed_from_double (matrix->y0); - - if (_cairo_fixed_is_integer (x0_fixed) && - _cairo_fixed_is_integer (y0_fixed)) - { - if (itx) - *itx = _cairo_fixed_integer_part (x0_fixed); - if (ity) - *ity = _cairo_fixed_integer_part (y0_fixed); - - return TRUE; - } - } - - return FALSE; -} - -#define SCALING_EPSILON _cairo_fixed_to_double(1) - -/* This only returns true if the matrix is 90 degree rotations or - * flips. It appears calling code is relying on this. It will return - * false for other rotations even if the scale is one. Approximations - * are allowed to handle matricies filled in using trig functions - * such as sin(M_PI_2). - */ -cairo_bool_t -_cairo_matrix_has_unity_scale (const cairo_matrix_t *matrix) -{ - /* check that the determinant is near +/-1 */ - double det = _cairo_matrix_compute_determinant (matrix); - if (fabs (det * det - 1.0) < SCALING_EPSILON) { - /* check that one axis is close to zero */ - if (fabs (matrix->xy) < SCALING_EPSILON && - fabs (matrix->yx) < SCALING_EPSILON) - return TRUE; - if (fabs (matrix->xx) < SCALING_EPSILON && - fabs (matrix->yy) < SCALING_EPSILON) - return TRUE; - /* If rotations are allowed then it must instead test for - * orthogonality. This is xx*xy+yx*yy ~= 0. - */ - } - return FALSE; -} - -/* By pixel exact here, we mean a matrix that is composed only of - * 90 degree rotations, flips, and integer translations and produces a 1:1 - * mapping between source and destination pixels. If we transform an image - * with a pixel-exact matrix, filtering is not useful. - */ -cairo_bool_t -_cairo_matrix_is_pixel_exact (const cairo_matrix_t *matrix) -{ - cairo_fixed_t x0_fixed, y0_fixed; - - if (! _cairo_matrix_has_unity_scale (matrix)) - return FALSE; - - x0_fixed = _cairo_fixed_from_double (matrix->x0); - y0_fixed = _cairo_fixed_from_double (matrix->y0); - - return _cairo_fixed_is_integer (x0_fixed) && _cairo_fixed_is_integer (y0_fixed); -} - -/* - A circle in user space is transformed into an ellipse in device space. - - The following is a derivation of a formula to calculate the length of the - major axis for this ellipse; this is useful for error bounds calculations. - - Thanks to Walter Brisken <wbrisken@aoc.nrao.edu> for this derivation: - - 1. First some notation: - - All capital letters represent vectors in two dimensions. A prime ' - represents a transformed coordinate. Matrices are written in underlined - form, ie _R_. Lowercase letters represent scalar real values. - - 2. The question has been posed: What is the maximum expansion factor - achieved by the linear transformation - - X' = X _R_ - - where _R_ is a real-valued 2x2 matrix with entries: - - _R_ = [a b] - [c d] . - - In other words, what is the maximum radius, MAX[ |X'| ], reached for any - X on the unit circle ( |X| = 1 ) ? - - 3. Some useful formulae - - (A) through (C) below are standard double-angle formulae. (D) is a lesser - known result and is derived below: - - (A) sin²(θ) = (1 - cos(2*θ))/2 - (B) cos²(θ) = (1 + cos(2*θ))/2 - (C) sin(θ)*cos(θ) = sin(2*θ)/2 - (D) MAX[a*cos(θ) + b*sin(θ)] = sqrt(a² + b²) - - Proof of (D): - - find the maximum of the function by setting the derivative to zero: - - -a*sin(θ)+b*cos(θ) = 0 - - From this it follows that - - tan(θ) = b/a - - and hence - - sin(θ) = b/sqrt(a² + b²) - - and - - cos(θ) = a/sqrt(a² + b²) - - Thus the maximum value is - - MAX[a*cos(θ) + b*sin(θ)] = (a² + b²)/sqrt(a² + b²) - = sqrt(a² + b²) - - 4. Derivation of maximum expansion - - To find MAX[ |X'| ] we search brute force method using calculus. The unit - circle on which X is constrained is to be parameterized by t: - - X(θ) = (cos(θ), sin(θ)) - - Thus - - X'(θ) = X(θ) * _R_ = (cos(θ), sin(θ)) * [a b] - [c d] - = (a*cos(θ) + c*sin(θ), b*cos(θ) + d*sin(θ)). - - Define - - r(θ) = |X'(θ)| - - Thus - - r²(θ) = (a*cos(θ) + c*sin(θ))² + (b*cos(θ) + d*sin(θ))² - = (a² + b²)*cos²(θ) + (c² + d²)*sin²(θ) - + 2*(a*c + b*d)*cos(θ)*sin(θ) - - Now apply the double angle formulae (A) to (C) from above: - - r²(θ) = (a² + b² + c² + d²)/2 - + (a² + b² - c² - d²)*cos(2*θ)/2 - + (a*c + b*d)*sin(2*θ) - = f + g*cos(φ) + h*sin(φ) - - Where - - f = (a² + b² + c² + d²)/2 - g = (a² + b² - c² - d²)/2 - h = (a*c + d*d) - φ = 2*θ - - It is clear that MAX[ |X'| ] = sqrt(MAX[ r² ]). Here we determine MAX[ r² ] - using (D) from above: - - MAX[ r² ] = f + sqrt(g² + h²) - - And finally - - MAX[ |X'| ] = sqrt( f + sqrt(g² + h²) ) - - Which is the solution to this problem. - - Walter Brisken - 2004/10/08 - - (Note that the minor axis length is at the minimum of the above solution, - which is just sqrt ( f - sqrt(g² + h²) ) given the symmetry of (D)). - - - For another derivation of the same result, using Singular Value Decomposition, - see doc/tutorial/src/singular.c. -*/ - -/* determine the length of the major axis of a circle of the given radius - after applying the transformation matrix. */ -double -_cairo_matrix_transformed_circle_major_axis (const cairo_matrix_t *matrix, - double radius) -{ - double a, b, c, d, f, g, h, i, j; - - if (_cairo_matrix_has_unity_scale (matrix)) - return radius; - - _cairo_matrix_get_affine (matrix, - &a, &b, - &c, &d, - NULL, NULL); - - i = a*a + b*b; - j = c*c + d*d; - - f = 0.5 * (i + j); - g = 0.5 * (i - j); - h = a*c + b*d; - - return radius * sqrt (f + hypot (g, h)); - - /* - * we don't need the minor axis length, which is - * double min = radius * sqrt (f - sqrt (g*g+h*h)); - */ -} - -static const pixman_transform_t pixman_identity_transform = {{ - {1 << 16, 0, 0}, - { 0, 1 << 16, 0}, - { 0, 0, 1 << 16} - }}; - -static cairo_status_t -_cairo_matrix_to_pixman_matrix (const cairo_matrix_t *matrix, - pixman_transform_t *pixman_transform, - double xc, - double yc) -{ - cairo_matrix_t inv; - unsigned max_iterations; - - pixman_transform->matrix[0][0] = _cairo_fixed_16_16_from_double (matrix->xx); - pixman_transform->matrix[0][1] = _cairo_fixed_16_16_from_double (matrix->xy); - pixman_transform->matrix[0][2] = _cairo_fixed_16_16_from_double (matrix->x0); - - pixman_transform->matrix[1][0] = _cairo_fixed_16_16_from_double (matrix->yx); - pixman_transform->matrix[1][1] = _cairo_fixed_16_16_from_double (matrix->yy); - pixman_transform->matrix[1][2] = _cairo_fixed_16_16_from_double (matrix->y0); - - pixman_transform->matrix[2][0] = 0; - pixman_transform->matrix[2][1] = 0; - pixman_transform->matrix[2][2] = 1 << 16; - - /* The conversion above breaks cairo's translation invariance: - * a translation of (a, b) in device space translates to - * a translation of (xx * a + xy * b, yx * a + yy * b) - * for cairo, while pixman uses rounded versions of xx ... yy. - * This error increases as a and b get larger. - * - * To compensate for this, we fix the point (xc, yc) in pattern - * space and adjust pixman's transform to agree with cairo's at - * that point. - */ - - if (_cairo_matrix_has_unity_scale (matrix)) - return CAIRO_STATUS_SUCCESS; - - if (unlikely (fabs (matrix->xx) > PIXMAN_MAX_INT || - fabs (matrix->xy) > PIXMAN_MAX_INT || - fabs (matrix->x0) > PIXMAN_MAX_INT || - fabs (matrix->yx) > PIXMAN_MAX_INT || - fabs (matrix->yy) > PIXMAN_MAX_INT || - fabs (matrix->y0) > PIXMAN_MAX_INT)) - { - return _cairo_error (CAIRO_STATUS_INVALID_MATRIX); - } - - /* Note: If we can't invert the transformation, skip the adjustment. */ - inv = *matrix; - if (cairo_matrix_invert (&inv) != CAIRO_STATUS_SUCCESS) - return CAIRO_STATUS_SUCCESS; - - /* find the pattern space coordinate that maps to (xc, yc) */ - max_iterations = 5; - do { - double x,y; - pixman_vector_t vector; - cairo_fixed_16_16_t dx, dy; - - vector.vector[0] = _cairo_fixed_16_16_from_double (xc); - vector.vector[1] = _cairo_fixed_16_16_from_double (yc); - vector.vector[2] = 1 << 16; - - /* If we can't transform the reference point, skip the adjustment. */ - if (! pixman_transform_point_3d (pixman_transform, &vector)) - return CAIRO_STATUS_SUCCESS; - - x = pixman_fixed_to_double (vector.vector[0]); - y = pixman_fixed_to_double (vector.vector[1]); - cairo_matrix_transform_point (&inv, &x, &y); - - /* Ideally, the vector should now be (xc, yc). - * We can now compensate for the resulting error. - */ - x -= xc; - y -= yc; - cairo_matrix_transform_distance (matrix, &x, &y); - dx = _cairo_fixed_16_16_from_double (x); - dy = _cairo_fixed_16_16_from_double (y); - pixman_transform->matrix[0][2] -= dx; - pixman_transform->matrix[1][2] -= dy; - - if (dx == 0 && dy == 0) - return CAIRO_STATUS_SUCCESS; - } while (--max_iterations); - - /* We didn't find an exact match between cairo and pixman, but - * the matrix should be mostly correct */ - return CAIRO_STATUS_SUCCESS; -} - -static inline double -_pixman_nearest_sample (double d) -{ - return ceil (d - .5); -} - -/** - * _cairo_matrix_is_pixman_translation: - * @matrix: a matrix - * @filter: the filter to be used on the pattern transformed by @matrix - * @x_offset: the translation in the X direction - * @y_offset: the translation in the Y direction - * - * Checks if @matrix translated by (x_offset, y_offset) can be - * represented using just an offset (within the range pixman can - * accept) and an identity matrix. - * - * Passing a non-zero value in x_offset/y_offset has the same effect - * as applying cairo_matrix_translate(matrix, x_offset, y_offset) and - * setting x_offset and y_offset to 0. - * - * Upon return x_offset and y_offset contain the translation vector if - * the return value is %TRUE. If the return value is %FALSE, they will - * not be modified. - * - * Return value: %TRUE if @matrix can be represented as a pixman - * translation, %FALSE otherwise. - **/ -cairo_bool_t -_cairo_matrix_is_pixman_translation (const cairo_matrix_t *matrix, - cairo_filter_t filter, - int *x_offset, - int *y_offset) -{ - double tx, ty; - - if (!_cairo_matrix_is_translation (matrix)) - return FALSE; - - if (matrix->x0 == 0. && matrix->y0 == 0.) - return TRUE; - - tx = matrix->x0 + *x_offset; - ty = matrix->y0 + *y_offset; - - if (filter == CAIRO_FILTER_FAST || filter == CAIRO_FILTER_NEAREST) { - tx = _pixman_nearest_sample (tx); - ty = _pixman_nearest_sample (ty); - } else if (tx != floor (tx) || ty != floor (ty)) { - return FALSE; - } - - if (fabs (tx) > PIXMAN_MAX_INT || fabs (ty) > PIXMAN_MAX_INT) - return FALSE; - - *x_offset = _cairo_lround (tx); - *y_offset = _cairo_lround (ty); - return TRUE; -} - -/** - * _cairo_matrix_to_pixman_matrix_offset: - * @matrix: a matrix - * @filter: the filter to be used on the pattern transformed by @matrix - * @xc: the X coordinate of the point to fix in pattern space - * @yc: the Y coordinate of the point to fix in pattern space - * @out_transform: the transformation which best approximates @matrix - * @x_offset: the translation in the X direction - * @y_offset: the translation in the Y direction - * - * This function tries to represent @matrix translated by (x_offset, - * y_offset) as a %pixman_transform_t and an translation. - * - * Passing a non-zero value in x_offset/y_offset has the same effect - * as applying cairo_matrix_translate(matrix, x_offset, y_offset) and - * setting x_offset and y_offset to 0. - * - * If it is possible to represent the matrix with an identity - * %pixman_transform_t and a translation within the valid range for - * pixman, this function will set @out_transform to be the identity, - * @x_offset and @y_offset to be the translation vector and will - * return %CAIRO_INT_STATUS_NOTHING_TO_DO. Otherwise it will try to - * evenly divide the translational component of @matrix between - * @out_transform and (@x_offset, @y_offset). - * - * Upon return x_offset and y_offset contain the translation vector. - * - * Return value: %CAIRO_INT_STATUS_NOTHING_TO_DO if the out_transform - * is the identity, %CAIRO_STATUS_INVALID_MATRIX if it was not - * possible to represent @matrix as a pixman_transform_t without - * overflows, %CAIRO_STATUS_SUCCESS otherwise. - **/ -cairo_status_t -_cairo_matrix_to_pixman_matrix_offset (const cairo_matrix_t *matrix, - cairo_filter_t filter, - double xc, - double yc, - pixman_transform_t *out_transform, - int *x_offset, - int *y_offset) -{ - cairo_bool_t is_pixman_translation; - - is_pixman_translation = _cairo_matrix_is_pixman_translation (matrix, - filter, - x_offset, - y_offset); - - if (is_pixman_translation) { - *out_transform = pixman_identity_transform; - return CAIRO_INT_STATUS_NOTHING_TO_DO; - } else { - cairo_matrix_t m; - - m = *matrix; - cairo_matrix_translate (&m, *x_offset, *y_offset); - if (m.x0 != 0.0 || m.y0 != 0.0) { - double tx, ty, norm; - int i, j; - - /* pixman also limits the [xy]_offset to 16 bits so evenly - * spread the bits between the two. - * - * To do this, find the solutions of: - * |x| = |x*m.xx + y*m.xy + m.x0| - * |y| = |x*m.yx + y*m.yy + m.y0| - * - * and select the one whose maximum norm is smallest. - */ - tx = m.x0; - ty = m.y0; - norm = MAX (fabs (tx), fabs (ty)); - - for (i = -1; i < 2; i+=2) { - for (j = -1; j < 2; j+=2) { - double x, y, den, new_norm; - - den = (m.xx + i) * (m.yy + j) - m.xy * m.yx; - if (fabs (den) < DBL_EPSILON) - continue; - - x = m.y0 * m.xy - m.x0 * (m.yy + j); - y = m.x0 * m.yx - m.y0 * (m.xx + i); - - den = 1 / den; - x *= den; - y *= den; - - new_norm = MAX (fabs (x), fabs (y)); - if (norm > new_norm) { - norm = new_norm; - tx = x; - ty = y; - } - } - } - - tx = floor (tx); - ty = floor (ty); - *x_offset = -tx; - *y_offset = -ty; - cairo_matrix_translate (&m, tx, ty); - } else { - *x_offset = 0; - *y_offset = 0; - } - - return _cairo_matrix_to_pixman_matrix (&m, out_transform, xc, yc); - } -} diff --git a/source/libs/cairo/cairo-src/src/cairo-mempool-private.h b/source/libs/cairo/cairo-src/src/cairo-mempool-private.h deleted file mode 100644 index a09f6ce51f6a6b5e9fbaf512356cbe4af391411c..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-mempool-private.h +++ /dev/null @@ -1,85 +0,0 @@ -/* Cairo - a vector graphics library with display and print output - * - * Copyright © 2007 Chris Wilson - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributors(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_MEMPOOL_PRIVATE_H -#define CAIRO_MEMPOOL_PRIVATE_H - -#include "cairo-compiler-private.h" -#include "cairo-error-private.h" - -#include <stddef.h> /* for size_t */ - -CAIRO_BEGIN_DECLS - -typedef struct _cairo_mempool cairo_mempool_t; - -struct _cairo_mempool { - char *base; - struct _cairo_memblock { - int bits; - cairo_list_t link; - } *blocks; - cairo_list_t free[32]; - unsigned char *map; - - unsigned int num_blocks; - int min_bits; /* Minimum block size is 1 << min_bits */ - int num_sizes; - int max_free_bits; - - size_t free_bytes; - size_t max_bytes; -}; - -cairo_private cairo_status_t -_cairo_mempool_init (cairo_mempool_t *pool, - void *base, - size_t bytes, - int min_bits, - int num_sizes); - -cairo_private void * -_cairo_mempool_alloc (cairo_mempool_t *pi, size_t bytes); - -cairo_private void -_cairo_mempool_free (cairo_mempool_t *pi, void *storage); - -cairo_private void -_cairo_mempool_fini (cairo_mempool_t *pool); - -CAIRO_END_DECLS - -#endif /* CAIRO_MEMPOOL_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-mempool.c b/source/libs/cairo/cairo-src/src/cairo-mempool.c deleted file mode 100644 index 751ede320f32010550cb5f47f1c951e0d35a7332..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-mempool.c +++ /dev/null @@ -1,369 +0,0 @@ -/* Cairo - a vector graphics library with display and print output - * - * Copyright © 2007 Chris Wilson - * Copyright © 2009 Intel Corporation - * - * 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 recipoolent 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributors(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-mempool-private.h" -#include "cairo-list-inline.h" - -/* a simple buddy allocator for memory pools - * XXX fragmentation? use Doug Lea's malloc? - */ - -#define BITTEST(p, n) ((p)->map[(n) >> 3] & (128 >> ((n) & 7))) -#define BITSET(p, n) ((p)->map[(n) >> 3] |= (128 >> ((n) & 7))) -#define BITCLEAR(p, n) ((p)->map[(n) >> 3] &= ~(128 >> ((n) & 7))) - -static void -clear_bits (cairo_mempool_t *pool, size_t first, size_t last) -{ - size_t i, n = last; - size_t first_full = (first + 7) & ~7; - size_t past_full = last & ~7; - size_t bytes; - - if (n > first_full) - n = first_full; - for (i = first; i < n; i++) - BITCLEAR (pool, i); - - if (past_full > first_full) { - bytes = past_full - first_full; - bytes = bytes >> 3; - memset (pool->map + (first_full >> 3), 0, bytes); - } - - if (past_full < n) - past_full = n; - for (i = past_full; i < last; i++) - BITCLEAR (pool, i); -} - -static void -free_bits (cairo_mempool_t *pool, size_t start, int bits, cairo_bool_t clear) -{ - struct _cairo_memblock *block; - - if (clear) - clear_bits (pool, start, start + (1 << bits)); - - block = pool->blocks + start; - block->bits = bits; - - cairo_list_add (&block->link, &pool->free[bits]); - - pool->free_bytes += 1 << (bits + pool->min_bits); - if (bits > pool->max_free_bits) - pool->max_free_bits = bits; -} - -/* Add a chunk to the free list */ -static void -free_blocks (cairo_mempool_t *pool, - size_t first, - size_t last, - cairo_bool_t clear) -{ - size_t i, len; - int bits = 0; - - for (i = first, len = 1; i < last; i += len) { - /* To avoid cost quadratic in the number of different - * blocks produced from this chunk of store, we have to - * use the size of the previous block produced from this - * chunk as the starting point to work out the size of the - * next block we can produce. If you look at the binary - * representation of the starting points of the blocks - * produced, you can see that you first of all increase the - * size of the blocks produced up to some maximum as the - * address dealt with gets offsets added on which zap out - * low order bits, then decrease as the low order bits of the - * final block produced get added in. E.g. as you go from - * 001 to 0111 you generate blocks - * of size 001 at 001 taking you to 010 - * of size 010 at 010 taking you to 100 - * of size 010 at 100 taking you to 110 - * of size 001 at 110 taking you to 111 - * So the maximum total cost of the loops below this comment - * is one trip from the lowest blocksize to the highest and - * back again. - */ - while (bits < pool->num_sizes - 1) { - size_t next_bits = bits + 1; - size_t next_len = len << 1; - - if (i + next_bits > last) { - /* off end of chunk to be freed */ - break; - } - - if (i & (next_len - 1)) /* block would not be on boundary */ - break; - - bits = next_bits; - len = next_len; - } - - do { - if (i + len <= last && /* off end of chunk to be freed */ - (i & (len - 1)) == 0) /* block would not be on boundary */ - break; - - bits--; len >>=1; - } while (len); - - if (len == 0) - break; - - free_bits (pool, i, bits, clear); - } -} - -static struct _cairo_memblock * -get_buddy (cairo_mempool_t *pool, size_t offset, int bits) -{ - struct _cairo_memblock *block; - - if (offset + (1 << bits) >= pool->num_blocks) - return NULL; /* invalid */ - - if (BITTEST (pool, offset + (1 << bits) - 1)) - return NULL; /* buddy is allocated */ - - block = pool->blocks + offset; - if (block->bits != bits) - return NULL; /* buddy is partially allocated */ - - return block; -} - -static void -merge_buddies (cairo_mempool_t *pool, - struct _cairo_memblock *block, - int max_bits) -{ - size_t block_offset = block - pool->blocks; - int bits = block->bits; - - while (bits < max_bits - 1) { - /* while you can, merge two blocks and get a legal block size */ - size_t buddy_offset = block_offset ^ (1 << bits); - - block = get_buddy (pool, buddy_offset, bits); - if (block == NULL) - break; - - cairo_list_del (&block->link); - - /* Merged block starts at buddy */ - if (buddy_offset < block_offset) - block_offset = buddy_offset; - - bits++; - } - - block = pool->blocks + block_offset; - block->bits = bits; - cairo_list_add (&block->link, &pool->free[bits]); - - if (bits > pool->max_free_bits) - pool->max_free_bits = bits; -} - -/* attempt to merge all available buddies up to a particular size */ -static int -merge_bits (cairo_mempool_t *pool, int max_bits) -{ - struct _cairo_memblock *block, *buddy, *next; - int bits; - - for (bits = 0; bits < max_bits - 1; bits++) { - cairo_list_foreach_entry_safe (block, next, - struct _cairo_memblock, - &pool->free[bits], - link) - { - size_t buddy_offset = (block - pool->blocks) ^ (1 << bits); - - buddy = get_buddy (pool, buddy_offset, bits); - if (buddy == NULL) - continue; - - if (buddy == next) { - next = cairo_container_of (buddy->link.next, - struct _cairo_memblock, - link); - } - - cairo_list_del (&block->link); - merge_buddies (pool, block, max_bits); - } - } - - return pool->max_free_bits; -} - -/* find store for 1 << bits blocks */ -static void * -buddy_malloc (cairo_mempool_t *pool, int bits) -{ - size_t past, offset; - struct _cairo_memblock *block; - int b; - - if (bits > pool->max_free_bits && bits > merge_bits (pool, bits)) - return NULL; - - /* Find a list with blocks big enough on it */ - block = NULL; - for (b = bits; b <= pool->max_free_bits; b++) { - if (! cairo_list_is_empty (&pool->free[b])) { - block = cairo_list_first_entry (&pool->free[b], - struct _cairo_memblock, - link); - break; - } - } - assert (block != NULL); - - cairo_list_del (&block->link); - - while (cairo_list_is_empty (&pool->free[pool->max_free_bits])) { - if (--pool->max_free_bits == -1) - break; - } - - /* Mark end of allocated area */ - offset = block - pool->blocks; - past = offset + (1 << bits); - BITSET (pool, past - 1); - block->bits = bits; - - /* If we used a larger free block than we needed, free the rest */ - pool->free_bytes -= 1 << (b + pool->min_bits); - free_blocks (pool, past, offset + (1 << b), 0); - - return pool->base + ((block - pool->blocks) << pool->min_bits); -} - -cairo_status_t -_cairo_mempool_init (cairo_mempool_t *pool, - void *base, size_t bytes, - int min_bits, int num_sizes) -{ - unsigned long tmp; - int num_blocks; - int i; - - /* Align the start to an integral chunk */ - tmp = ((unsigned long) base) & ((1 << min_bits) - 1); - if (tmp) { - tmp = (1 << min_bits) - tmp; - base = (char *)base + tmp; - bytes -= tmp; - } - - assert ((((unsigned long) base) & ((1 << min_bits) - 1)) == 0); - assert (num_sizes < ARRAY_LENGTH (pool->free)); - - pool->base = base; - pool->free_bytes = 0; - pool->max_bytes = bytes; - pool->max_free_bits = -1; - - num_blocks = bytes >> min_bits; - pool->blocks = calloc (num_blocks, sizeof (struct _cairo_memblock)); - if (pool->blocks == NULL) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - pool->num_blocks = num_blocks; - pool->min_bits = min_bits; - pool->num_sizes = num_sizes; - - for (i = 0; i < ARRAY_LENGTH (pool->free); i++) - cairo_list_init (&pool->free[i]); - - pool->map = malloc ((num_blocks + 7) >> 3); - if (pool->map == NULL) { - free (pool->blocks); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - memset (pool->map, -1, (num_blocks + 7) >> 3); - clear_bits (pool, 0, num_blocks); - - /* Now add all blocks to the free list */ - free_blocks (pool, 0, num_blocks, 1); - - return CAIRO_STATUS_SUCCESS; -} - -void * -_cairo_mempool_alloc (cairo_mempool_t *pool, size_t bytes) -{ - size_t size; - int bits; - - size = 1 << pool->min_bits; - for (bits = 0; size < bytes; bits++) - size <<= 1; - if (bits >= pool->num_sizes) - return NULL; - - return buddy_malloc (pool, bits); -} - -void -_cairo_mempool_free (cairo_mempool_t *pool, void *storage) -{ - size_t block_offset; - struct _cairo_memblock *block; - - block_offset = ((char *)storage - pool->base) >> pool->min_bits; - block = pool->blocks + block_offset; - - BITCLEAR (pool, block_offset + ((1 << block->bits) - 1)); - pool->free_bytes += 1 << (block->bits + pool->min_bits); - - merge_buddies (pool, block, pool->num_sizes); -} - -void -_cairo_mempool_fini (cairo_mempool_t *pool) -{ - free (pool->map); - free (pool->blocks); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-mesh-pattern-rasterizer.c b/source/libs/cairo/cairo-src/src/cairo-mesh-pattern-rasterizer.c deleted file mode 100644 index 1b63ca8a6609afc23aa5e0cb3ebdd5c79c5c5e1f..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-mesh-pattern-rasterizer.c +++ /dev/null @@ -1,941 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright 2009 Andrea Canciani - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Andrea Canciani. - * - * Contributor(s): - * Andrea Canciani <ranma42@gmail.com> - */ - -#include "cairoint.h" - -#include "cairo-array-private.h" -#include "cairo-pattern-private.h" - -/* - * Rasterizer for mesh patterns. - * - * This implementation is based on techniques derived from several - * papers (available from ACM): - * - * - Lien, Shantz and Pratt "Adaptive Forward Differencing for - * Rendering Curves and Surfaces" (discussion of the AFD technique, - * bound of 1/sqrt(2) on step length without proof) - * - * - Popescu and Rosen, "Forward rasterization" (description of - * forward rasterization, proof of the previous bound) - * - * - Klassen, "Integer Forward Differencing of Cubic Polynomials: - * Analysis and Algorithms" - * - * - Klassen, "Exact Integer Hybrid Subdivision and Forward - * Differencing of Cubics" (improving the bound on the minimum - * number of steps) - * - * - Chang, Shantz and Rocchetti, "Rendering Cubic Curves and Surfaces - * with Integer Adaptive Forward Differencing" (analysis of forward - * differencing applied to Bezier patches) - * - * Notes: - * - Poor performance expected in degenerate cases - * - * - Patches mostly outside the drawing area are drawn completely (and - * clipped), wasting time - * - * - Both previous problems are greatly reduced by splitting until a - * reasonably small size and clipping the new tiles: execution time - * is quadratic in the convex-hull diameter instead than linear to - * the painted area. Splitting the tiles doesn't change the painted - * area but (usually) reduces the bounding box area (bbox area can - * remain the same after splitting, but cannot grow) - * - * - The initial implementation used adaptive forward differencing, - * but simple forward differencing scored better in benchmarks - * - * Idea: - * - * We do a sampling over the cubic patch with step du and dv (in the - * two parameters) that guarantees that any point of our sampling will - * be at most at 1/sqrt(2) from its adjacent points. In formulae - * (assuming B is the patch): - * - * |B(u,v) - B(u+du,v)| < 1/sqrt(2) - * |B(u,v) - B(u,v+dv)| < 1/sqrt(2) - * - * This means that every pixel covered by the patch will contain at - * least one of the samples, thus forward rasterization can be - * performed. Sketch of proof (from Popescu and Rosen): - * - * Let's take the P pixel we're interested into. If we assume it to be - * square, its boundaries define 9 regions on the plane: - * - * 1|2|3 - * -+-+- - * 8|P|4 - * -+-+- - * 7|6|5 - * - * Let's check that the pixel P will contain at least one point - * assuming that it is covered by the patch. - * - * Since the pixel is covered by the patch, its center will belong to - * (at least) one of the quads: - * - * {(B(u,v), B(u+du,v), B(u,v+dv), B(u+du,v+dv)) for u,v in [0,1]} - * - * If P doesn't contain any of the corners of the quad: - * - * - if one of the corners is in 1,3,5 or 7, other two of them have to - * be in 2,4,6 or 8, thus if the last corner is not in P, the length - * of one of the edges will be > 1/sqrt(2) - * - * - if none of the corners is in 1,3,5 or 7, all of them are in 2,4,6 - * and/or 8. If they are all in different regions, they can't - * satisfy the distance constraint. If two of them are in the same - * region (let's say 2), no point is in 6 and again it is impossible - * to have the center of P in the quad respecting the distance - * constraint (both these assertions can be checked by continuity - * considering the length of the edges of a quad with the vertices - * on the edges of P) - * - * Each of the cases led to a contradiction, so P contains at least - * one of the corners of the quad. - */ - -/* - * Make sure that errors are less than 1 in fixed point math if you - * change these values. - * - * The error is amplified by about steps^3/4 times. - * The rasterizer always uses a number of steps that is a power of 2. - * - * 256 is the maximum allowed number of steps (to have error < 1) - * using 8.24 for the differences. - */ -#define STEPS_MAX_V 256.0 -#define STEPS_MAX_U 256.0 - -/* - * If the patch/curve is only partially visible, split it to a finer - * resolution to get higher chances to clip (part of) it. - * - * These values have not been computed, but simply obtained - * empirically (by benchmarking some patches). They should never be - * greater than STEPS_MAX_V (or STEPS_MAX_U), but they can be as small - * as 1 (depending on how much you want to spend time in splitting the - * patch/curve when trying to save some rasterization time). - */ -#define STEPS_CLIP_V 64.0 -#define STEPS_CLIP_U 64.0 - - -/* Utils */ -static inline double -sqlen (cairo_point_double_t p0, cairo_point_double_t p1) -{ - cairo_point_double_t delta; - - delta.x = p0.x - p1.x; - delta.y = p0.y - p1.y; - - return delta.x * delta.x + delta.y * delta.y; -} - -static inline int16_t -_color_delta_to_shifted_short (int32_t from, int32_t to, int shift) -{ - int32_t delta = to - from; - - /* We need to round toward zero, because otherwise adding the - * delta 2^shift times can overflow */ - if (delta >= 0) - return delta >> shift; - else - return -((-delta) >> shift); -} - -/* - * Convert a number of steps to the equivalent shift. - * - * Input: the square of the minimum number of steps - * - * Output: the smallest integer x such that 2^x > steps - */ -static inline int -sqsteps2shift (double steps_sq) -{ - int r; - frexp (MAX (1.0, steps_sq), &r); - return (r + 1) >> 1; -} - -/* - * FD functions - * - * A Bezier curve is defined (with respect to a parameter t in - * [0,1]) from its nodes (x,y,z,w) like this: - * - * B(t) = x(1-t)^3 + 3yt(1-t)^2 + 3zt^2(1-t) + wt^3 - * - * To efficiently evaluate a Bezier curve, the rasterizer uses forward - * differences. Given x, y, z, w (the 4 nodes of the Bezier curve), it - * is possible to convert them to forward differences form and walk - * over the curve using fd_init (), fd_down () and fd_fwd (). - * - * f[0] is always the value of the Bezier curve for "current" t. - */ - -/* - * Initialize the coefficient for forward differences. - * - * Input: x,y,z,w are the 4 nodes of the Bezier curve - * - * Output: f[i] is the i-th difference of the curve - * - * f[0] is the value of the curve for t==0, i.e. f[0]==x. - * - * The initial step is 1; this means that each step increases t by 1 - * (so fd_init () immediately followed by fd_fwd (f) n times makes - * f[0] be the value of the curve for t==n). - */ -static inline void -fd_init (double x, double y, double z, double w, double f[4]) -{ - f[0] = x; - f[1] = w - x; - f[2] = 6. * (w - 2. * z + y); - f[3] = 6. * (w - 3. * z + 3. * y - x); -} - -/* - * Halve the step of the coefficients for forward differences. - * - * Input: f[i] is the i-th difference of the curve - * - * Output: f[i] is the i-th difference of the curve with half the - * original step - * - * f[0] is not affected, so the current t is not changed. - * - * The other coefficients are changed so that the step is half the - * original step. This means that doing fd_fwd (f) n times with the - * input f results in the same f[0] as doing fd_fwd (f) 2n times with - * the output f. - */ -static inline void -fd_down (double f[4]) -{ - f[3] *= 0.125; - f[2] = f[2] * 0.25 - f[3]; - f[1] = (f[1] - f[2]) * 0.5; -} - -/* - * Perform one step of forward differences along the curve. - * - * Input: f[i] is the i-th difference of the curve - * - * Output: f[i] is the i-th difference of the curve after one step - */ -static inline void -fd_fwd (double f[4]) -{ - f[0] += f[1]; - f[1] += f[2]; - f[2] += f[3]; -} - -/* - * Transform to integer forward differences. - * - * Input: d[n] is the n-th difference (in double precision) - * - * Output: i[n] is the n-th difference (in fixed point precision) - * - * i[0] is 9.23 fixed point, other differences are 4.28 fixed point. - */ -static inline void -fd_fixed (double d[4], int32_t i[4]) -{ - i[0] = _cairo_fixed_16_16_from_double (256 * 2 * d[0]); - i[1] = _cairo_fixed_16_16_from_double (256 * 16 * d[1]); - i[2] = _cairo_fixed_16_16_from_double (256 * 16 * d[2]); - i[3] = _cairo_fixed_16_16_from_double (256 * 16 * d[3]); -} - -/* - * Perform one step of integer forward differences along the curve. - * - * Input: f[n] is the n-th difference - * - * Output: f[n] is the n-th difference - * - * f[0] is 9.23 fixed point, other differences are 4.28 fixed point. - */ -static inline void -fd_fixed_fwd (int32_t f[4]) -{ - f[0] += (f[1] >> 5) + ((f[1] >> 4) & 1); - f[1] += f[2]; - f[2] += f[3]; -} - -/* - * Compute the minimum number of steps that guarantee that walking - * over a curve will leave no holes. - * - * Input: p[0..3] the nodes of the Bezier curve - * - * Returns: the square of the number of steps - * - * Idea: - * - * We want to make sure that at every step we move by less than - * 1/sqrt(2). - * - * The derivative of the cubic Bezier with nodes (p0, p1, p2, p3) is - * the quadratic Bezier with nodes (p1-p0, p2-p1, p3-p2) scaled by 3, - * so (since a Bezier curve is always bounded by its convex hull), we - * can say that: - * - * max(|B'(t)|) <= 3 max (|p1-p0|, |p2-p1|, |p3-p2|) - * - * We can improve this by noticing that a quadratic Bezier (a,b,c) is - * bounded by the quad (a,lerp(a,b,t),lerp(b,c,t),c) for any t, so - * (substituting the previous values, using t=0.5 and simplifying): - * - * max(|B'(t)|) <= 3 max (|p1-p0|, |p2-p0|/2, |p3-p1|/2, |p3-p2|) - * - * So, to guarantee a maximum step length of 1/sqrt(2) we must do: - * - * 3 max (|p1-p0|, |p2-p0|/2, |p3-p1|/2, |p3-p2|) sqrt(2) steps - */ -static inline double -bezier_steps_sq (cairo_point_double_t p[4]) -{ - double tmp = sqlen (p[0], p[1]); - tmp = MAX (tmp, sqlen (p[2], p[3])); - tmp = MAX (tmp, sqlen (p[0], p[2]) * .25); - tmp = MAX (tmp, sqlen (p[1], p[3]) * .25); - return 18.0 * tmp; -} - -/* - * Split a 1D Bezier cubic using de Casteljau's algorithm. - * - * Input: x,y,z,w the nodes of the Bezier curve - * - * Output: x0,y0,z0,w0 and x1,y1,z1,w1 are respectively the nodes of - * the first half and of the second half of the curve - * - * The output control nodes have to be distinct. - */ -static inline void -split_bezier_1D (double x, double y, double z, double w, - double *x0, double *y0, double *z0, double *w0, - double *x1, double *y1, double *z1, double *w1) -{ - double tmp; - - *x0 = x; - *w1 = w; - - tmp = 0.5 * (y + z); - *y0 = 0.5 * (x + y); - *z1 = 0.5 * (z + w); - - *z0 = 0.5 * (*y0 + tmp); - *y1 = 0.5 * (tmp + *z1); - - *w0 = *x1 = 0.5 * (*z0 + *y1); -} - -/* - * Split a Bezier curve using de Casteljau's algorithm. - * - * Input: p[0..3] the nodes of the Bezier curve - * - * Output: fst_half[0..3] and snd_half[0..3] are respectively the - * nodes of the first and of the second half of the curve - * - * fst_half and snd_half must be different, but they can be the same as - * nodes. - */ -static void -split_bezier (cairo_point_double_t p[4], - cairo_point_double_t fst_half[4], - cairo_point_double_t snd_half[4]) -{ - split_bezier_1D (p[0].x, p[1].x, p[2].x, p[3].x, - &fst_half[0].x, &fst_half[1].x, &fst_half[2].x, &fst_half[3].x, - &snd_half[0].x, &snd_half[1].x, &snd_half[2].x, &snd_half[3].x); - - split_bezier_1D (p[0].y, p[1].y, p[2].y, p[3].y, - &fst_half[0].y, &fst_half[1].y, &fst_half[2].y, &fst_half[3].y, - &snd_half[0].y, &snd_half[1].y, &snd_half[2].y, &snd_half[3].y); -} - - -typedef enum _intersection { - INSIDE = -1, /* the interval is entirely contained in the reference interval */ - OUTSIDE = 0, /* the interval has no intersection with the reference interval */ - PARTIAL = 1 /* the interval intersects the reference interval (but is not fully inside it) */ -} intersection_t; - -/* - * Check if an interval if inside another. - * - * Input: a,b are the extrema of the first interval - * c,d are the extrema of the second interval - * - * Returns: INSIDE iff [a,b) intersection [c,d) = [a,b) - * OUTSIDE iff [a,b) intersection [c,d) = {} - * PARTIAL otherwise - * - * The function assumes a < b and c < d - * - * Note: Bitwise-anding the results along each component gives the - * expected result for [a,b) x [A,B) intersection [c,d) x [C,D). - */ -static inline int -intersect_interval (double a, double b, double c, double d) -{ - if (c <= a && b <= d) - return INSIDE; - else if (a >= d || b <= c) - return OUTSIDE; - else - return PARTIAL; -} - -/* - * Set the color of a pixel. - * - * Input: data is the base pointer of the image - * width, height are the dimensions of the image - * stride is the stride in bytes between adjacent rows - * x, y are the coordinates of the pixel to be colored - * r,g,b,a are the color components of the color to be set - * - * Output: the (x,y) pixel in data has the (r,g,b,a) color - * - * The input color components are not premultiplied, but the data - * stored in the image is assumed to be in CAIRO_FORMAT_ARGB32 (8 bpc, - * premultiplied). - * - * If the pixel to be set is outside the image, this function does - * nothing. - */ -static inline void -draw_pixel (unsigned char *data, int width, int height, int stride, - int x, int y, uint16_t r, uint16_t g, uint16_t b, uint16_t a) -{ - if (likely (0 <= x && 0 <= y && x < width && y < height)) { - uint32_t tr, tg, tb, ta; - - /* Premultiply and round */ - ta = a; - tr = r * ta + 0x8000; - tg = g * ta + 0x8000; - tb = b * ta + 0x8000; - - tr += tr >> 16; - tg += tg >> 16; - tb += tb >> 16; - - *((uint32_t*) (data + y*stride + 4*x)) = ((ta << 16) & 0xff000000) | - ((tr >> 8) & 0xff0000) | ((tg >> 16) & 0xff00) | (tb >> 24); - } -} - -/* - * Forward-rasterize a cubic curve using forward differences. - * - * Input: data is the base pointer of the image - * width, height are the dimensions of the image - * stride is the stride in bytes between adjacent rows - * ushift is log2(n) if n is the number of desired steps - * dxu[i], dyu[i] are the x,y forward differences of the curve - * r0,g0,b0,a0 are the color components of the start point - * r3,g3,b3,a3 are the color components of the end point - * - * Output: data will be changed to have the requested curve drawn in - * the specified colors - * - * The input color components are not premultiplied, but the data - * stored in the image is assumed to be in CAIRO_FORMAT_ARGB32 (8 bpc, - * premultiplied). - * - * The function draws n+1 pixels, that is from the point at step 0 to - * the point at step n, both included. This is the discrete equivalent - * to drawing the curve for values of the interpolation parameter in - * [0,1] (including both extremes). - */ -static inline void -rasterize_bezier_curve (unsigned char *data, int width, int height, int stride, - int ushift, double dxu[4], double dyu[4], - uint16_t r0, uint16_t g0, uint16_t b0, uint16_t a0, - uint16_t r3, uint16_t g3, uint16_t b3, uint16_t a3) -{ - int32_t xu[4], yu[4]; - int x0, y0, u, usteps = 1 << ushift; - - uint16_t r = r0, g = g0, b = b0, a = a0; - int16_t dr = _color_delta_to_shifted_short (r0, r3, ushift); - int16_t dg = _color_delta_to_shifted_short (g0, g3, ushift); - int16_t db = _color_delta_to_shifted_short (b0, b3, ushift); - int16_t da = _color_delta_to_shifted_short (a0, a3, ushift); - - fd_fixed (dxu, xu); - fd_fixed (dyu, yu); - - /* - * Use (dxu[0],dyu[0]) as origin for the forward differences. - * - * This makes it possible to handle much larger coordinates (the - * ones that can be represented as cairo_fixed_t) - */ - x0 = _cairo_fixed_from_double (dxu[0]); - y0 = _cairo_fixed_from_double (dyu[0]); - xu[0] = 0; - yu[0] = 0; - - for (u = 0; u <= usteps; ++u) { - /* - * This rasterizer assumes that pixels are integer aligned - * squares, so a generic (x,y) point belongs to the pixel with - * top-left coordinates (floor(x), floor(y)) - */ - - int x = _cairo_fixed_integer_floor (x0 + (xu[0] >> 15) + ((xu[0] >> 14) & 1)); - int y = _cairo_fixed_integer_floor (y0 + (yu[0] >> 15) + ((yu[0] >> 14) & 1)); - - draw_pixel (data, width, height, stride, x, y, r, g, b, a); - - fd_fixed_fwd (xu); - fd_fixed_fwd (yu); - r += dr; - g += dg; - b += db; - a += da; - } -} - -/* - * Clip, split and rasterize a Bezier curve. - * - * Input: data is the base pointer of the image - * width, height are the dimensions of the image - * stride is the stride in bytes between adjacent rows - * p[i] is the i-th node of the Bezier curve - * c0[i] is the i-th color component at the start point - * c3[i] is the i-th color component at the end point - * - * Output: data will be changed to have the requested curve drawn in - * the specified colors - * - * The input color components are not premultiplied, but the data - * stored in the image is assumed to be in CAIRO_FORMAT_ARGB32 (8 bpc, - * premultiplied). - * - * The color components are red, green, blue and alpha, in this order. - * - * The function guarantees that it will draw the curve with a step - * small enough to never have a distance above 1/sqrt(2) between two - * consecutive points (which is needed to ensure that no hole can - * appear when using this function to rasterize a patch). - */ -static void -draw_bezier_curve (unsigned char *data, int width, int height, int stride, - cairo_point_double_t p[4], double c0[4], double c3[4]) -{ - double top, bottom, left, right, steps_sq; - int i, v; - - top = bottom = p[0].y; - for (i = 1; i < 4; ++i) { - top = MIN (top, p[i].y); - bottom = MAX (bottom, p[i].y); - } - - /* Check visibility */ - v = intersect_interval (top, bottom, 0, height); - if (v == OUTSIDE) - return; - - left = right = p[0].x; - for (i = 1; i < 4; ++i) { - left = MIN (left, p[i].x); - right = MAX (right, p[i].x); - } - - v &= intersect_interval (left, right, 0, width); - if (v == OUTSIDE) - return; - - steps_sq = bezier_steps_sq (p); - if (steps_sq >= (v == INSIDE ? STEPS_MAX_U * STEPS_MAX_U : STEPS_CLIP_U * STEPS_CLIP_U)) { - /* - * The number of steps is greater than the threshold. This - * means that either the error would become too big if we - * directly rasterized it or that we can probably save some - * time by splitting the curve and clipping part of it - */ - cairo_point_double_t first[4], second[4]; - double midc[4]; - split_bezier (p, first, second); - midc[0] = (c0[0] + c3[0]) * 0.5; - midc[1] = (c0[1] + c3[1]) * 0.5; - midc[2] = (c0[2] + c3[2]) * 0.5; - midc[3] = (c0[3] + c3[3]) * 0.5; - draw_bezier_curve (data, width, height, stride, first, c0, midc); - draw_bezier_curve (data, width, height, stride, second, midc, c3); - } else { - double xu[4], yu[4]; - int ushift = sqsteps2shift (steps_sq), k; - - fd_init (p[0].x, p[1].x, p[2].x, p[3].x, xu); - fd_init (p[0].y, p[1].y, p[2].y, p[3].y, yu); - - for (k = 0; k < ushift; ++k) { - fd_down (xu); - fd_down (yu); - } - - rasterize_bezier_curve (data, width, height, stride, ushift, - xu, yu, - _cairo_color_double_to_short (c0[0]), - _cairo_color_double_to_short (c0[1]), - _cairo_color_double_to_short (c0[2]), - _cairo_color_double_to_short (c0[3]), - _cairo_color_double_to_short (c3[0]), - _cairo_color_double_to_short (c3[1]), - _cairo_color_double_to_short (c3[2]), - _cairo_color_double_to_short (c3[3])); - - /* Draw the end point, to make sure that we didn't leave it - * out because of rounding */ - draw_pixel (data, width, height, stride, - _cairo_fixed_integer_floor (_cairo_fixed_from_double (p[3].x)), - _cairo_fixed_integer_floor (_cairo_fixed_from_double (p[3].y)), - _cairo_color_double_to_short (c3[0]), - _cairo_color_double_to_short (c3[1]), - _cairo_color_double_to_short (c3[2]), - _cairo_color_double_to_short (c3[3])); - } -} - -/* - * Forward-rasterize a cubic Bezier patch using forward differences. - * - * Input: data is the base pointer of the image - * width, height are the dimensions of the image - * stride is the stride in bytes between adjacent rows - * vshift is log2(n) if n is the number of desired steps - * p[i][j], p[i][j] are the the nodes of the Bezier patch - * col[i][j] is the j-th color component of the i-th corner - * - * Output: data will be changed to have the requested patch drawn in - * the specified colors - * - * The nodes of the patch are as follows: - * - * u\v 0 - > 1 - * 0 p00 p01 p02 p03 - * | p10 p11 p12 p13 - * v p20 p21 p22 p23 - * 1 p30 p31 p32 p33 - * - * i.e. u varies along the first component (rows), v varies along the - * second one (columns). - * - * The color components are red, green, blue and alpha, in this order. - * c[0..3] are the colors in p00, p30, p03, p33 respectively - * - * The input color components are not premultiplied, but the data - * stored in the image is assumed to be in CAIRO_FORMAT_ARGB32 (8 bpc, - * premultiplied). - * - * If the patch folds over itself, the part with the highest v - * parameter is considered above. If both have the same v, the one - * with the highest u parameter is above. - * - * The function draws n+1 curves, that is from the curve at step 0 to - * the curve at step n, both included. This is the discrete equivalent - * to drawing the patch for values of the interpolation parameter in - * [0,1] (including both extremes). - */ -static inline void -rasterize_bezier_patch (unsigned char *data, int width, int height, int stride, int vshift, - cairo_point_double_t p[4][4], double col[4][4]) -{ - double pv[4][2][4], cstart[4], cend[4], dcstart[4], dcend[4]; - int v, i, k; - - v = 1 << vshift; - - /* - * pv[i][0] is the function (represented using forward - * differences) mapping v to the x coordinate of the i-th node of - * the Bezier curve with parameter u. - * (Likewise p[i][0] gives the y coordinate). - * - * This means that (pv[0][0][0],pv[0][1][0]), - * (pv[1][0][0],pv[1][1][0]), (pv[2][0][0],pv[2][1][0]) and - * (pv[3][0][0],pv[3][1][0]) are the nodes of the Bezier curve for - * the "current" v value (see the FD comments for more details). - */ - for (i = 0; i < 4; ++i) { - fd_init (p[i][0].x, p[i][1].x, p[i][2].x, p[i][3].x, pv[i][0]); - fd_init (p[i][0].y, p[i][1].y, p[i][2].y, p[i][3].y, pv[i][1]); - for (k = 0; k < vshift; ++k) { - fd_down (pv[i][0]); - fd_down (pv[i][1]); - } - } - - for (i = 0; i < 4; ++i) { - cstart[i] = col[0][i]; - cend[i] = col[1][i]; - dcstart[i] = (col[2][i] - col[0][i]) / v; - dcend[i] = (col[3][i] - col[1][i]) / v; - } - - v++; - while (v--) { - cairo_point_double_t nodes[4]; - for (i = 0; i < 4; ++i) { - nodes[i].x = pv[i][0][0]; - nodes[i].y = pv[i][1][0]; - } - - draw_bezier_curve (data, width, height, stride, nodes, cstart, cend); - - for (i = 0; i < 4; ++i) { - fd_fwd (pv[i][0]); - fd_fwd (pv[i][1]); - cstart[i] += dcstart[i]; - cend[i] += dcend[i]; - } - } -} - -/* - * Clip, split and rasterize a Bezier cubic patch. - * - * Input: data is the base pointer of the image - * width, height are the dimensions of the image - * stride is the stride in bytes between adjacent rows - * p[i][j], p[i][j] are the nodes of the patch - * col[i][j] is the j-th color component of the i-th corner - * - * Output: data will be changed to have the requested patch drawn in - * the specified colors - * - * The nodes of the patch are as follows: - * - * u\v 0 - > 1 - * 0 p00 p01 p02 p03 - * | p10 p11 p12 p13 - * v p20 p21 p22 p23 - * 1 p30 p31 p32 p33 - * - * i.e. u varies along the first component (rows), v varies along the - * second one (columns). - * - * The color components are red, green, blue and alpha, in this order. - * c[0..3] are the colors in p00, p30, p03, p33 respectively - * - * The input color components are not premultiplied, but the data - * stored in the image is assumed to be in CAIRO_FORMAT_ARGB32 (8 bpc, - * premultiplied). - * - * If the patch folds over itself, the part with the highest v - * parameter is considered above. If both have the same v, the one - * with the highest u parameter is above. - * - * The function guarantees that it will draw the patch with a step - * small enough to never have a distance above 1/sqrt(2) between two - * adjacent points (which guarantees that no hole can appear). - * - * This function can be used to rasterize a tile of PDF type 7 - * shadings (see http://www.adobe.com/devnet/pdf/pdf_reference.html). - */ -static void -draw_bezier_patch (unsigned char *data, int width, int height, int stride, - cairo_point_double_t p[4][4], double c[4][4]) -{ - double top, bottom, left, right, steps_sq; - int i, j, v; - - top = bottom = p[0][0].y; - for (i = 0; i < 4; ++i) { - for (j= 0; j < 4; ++j) { - top = MIN (top, p[i][j].y); - bottom = MAX (bottom, p[i][j].y); - } - } - - v = intersect_interval (top, bottom, 0, height); - if (v == OUTSIDE) - return; - - left = right = p[0][0].x; - for (i = 0; i < 4; ++i) { - for (j= 0; j < 4; ++j) { - left = MIN (left, p[i][j].x); - right = MAX (right, p[i][j].x); - } - } - - v &= intersect_interval (left, right, 0, width); - if (v == OUTSIDE) - return; - - steps_sq = 0; - for (i = 0; i < 4; ++i) - steps_sq = MAX (steps_sq, bezier_steps_sq (p[i])); - - if (steps_sq >= (v == INSIDE ? STEPS_MAX_V * STEPS_MAX_V : STEPS_CLIP_V * STEPS_CLIP_V)) { - /* The number of steps is greater than the threshold. This - * means that either the error would become too big if we - * directly rasterized it or that we can probably save some - * time by splitting the curve and clipping part of it. The - * patch is only split in the v direction to guarantee that - * rasterizing each part will overwrite parts with low v with - * overlapping parts with higher v. */ - - cairo_point_double_t first[4][4], second[4][4]; - double subc[4][4]; - - for (i = 0; i < 4; ++i) - split_bezier (p[i], first[i], second[i]); - - for (i = 0; i < 4; ++i) { - subc[0][i] = c[0][i]; - subc[1][i] = c[1][i]; - subc[2][i] = 0.5 * (c[0][i] + c[2][i]); - subc[3][i] = 0.5 * (c[1][i] + c[3][i]); - } - - draw_bezier_patch (data, width, height, stride, first, subc); - - for (i = 0; i < 4; ++i) { - subc[0][i] = subc[2][i]; - subc[1][i] = subc[3][i]; - subc[2][i] = c[2][i]; - subc[3][i] = c[3][i]; - } - draw_bezier_patch (data, width, height, stride, second, subc); - } else { - rasterize_bezier_patch (data, width, height, stride, sqsteps2shift (steps_sq), p, c); - } -} - -/* - * Draw a tensor product shading pattern. - * - * Input: mesh is the mesh pattern - * data is the base pointer of the image - * width, height are the dimensions of the image - * stride is the stride in bytes between adjacent rows - * - * Output: data will be changed to have the pattern drawn on it - * - * data is assumed to be clear and its content is assumed to be in - * CAIRO_FORMAT_ARGB32 (8 bpc, premultiplied). - * - * This function can be used to rasterize a PDF type 7 shading (see - * http://www.adobe.com/devnet/pdf/pdf_reference.html). - */ -void -_cairo_mesh_pattern_rasterize (const cairo_mesh_pattern_t *mesh, - void *data, - int width, - int height, - int stride, - double x_offset, - double y_offset) -{ - cairo_point_double_t nodes[4][4]; - double colors[4][4]; - cairo_matrix_t p2u; - unsigned int i, j, k, n; - cairo_status_t status; - const cairo_mesh_patch_t *patch; - const cairo_color_t *c; - - assert (mesh->base.status == CAIRO_STATUS_SUCCESS); - assert (mesh->current_patch == NULL); - - p2u = mesh->base.matrix; - status = cairo_matrix_invert (&p2u); - assert (status == CAIRO_STATUS_SUCCESS); - - n = _cairo_array_num_elements (&mesh->patches); - patch = _cairo_array_index_const (&mesh->patches, 0); - for (i = 0; i < n; i++) { - for (j = 0; j < 4; j++) { - for (k = 0; k < 4; k++) { - nodes[j][k] = patch->points[j][k]; - cairo_matrix_transform_point (&p2u, &nodes[j][k].x, &nodes[j][k].y); - nodes[j][k].x += x_offset; - nodes[j][k].y += y_offset; - } - } - - c = &patch->colors[0]; - colors[0][0] = c->red; - colors[0][1] = c->green; - colors[0][2] = c->blue; - colors[0][3] = c->alpha; - - c = &patch->colors[3]; - colors[1][0] = c->red; - colors[1][1] = c->green; - colors[1][2] = c->blue; - colors[1][3] = c->alpha; - - c = &patch->colors[1]; - colors[2][0] = c->red; - colors[2][1] = c->green; - colors[2][2] = c->blue; - colors[2][3] = c->alpha; - - c = &patch->colors[2]; - colors[3][0] = c->red; - colors[3][1] = c->green; - colors[3][2] = c->blue; - colors[3][3] = c->alpha; - - draw_bezier_patch (data, width, height, stride, nodes, colors); - patch++; - } -} diff --git a/source/libs/cairo/cairo-src/src/cairo-misc.c b/source/libs/cairo/cairo-src/src/cairo-misc.c deleted file mode 100644 index 3c7c959862db6c9ffefb512bfdfd4dba3cb13a9b..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-misc.c +++ /dev/null @@ -1,955 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * Copyright © 2007 Adrian Johnson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Adrian Johnson <ajohnson@redneon.com> - */ - -#include "cairoint.h" -#include "cairo-error-private.h" - -COMPILE_TIME_ASSERT ((int)CAIRO_STATUS_LAST_STATUS < (int)CAIRO_INT_STATUS_UNSUPPORTED); -COMPILE_TIME_ASSERT (CAIRO_INT_STATUS_LAST_STATUS <= 127); - -/** - * SECTION:cairo-status - * @Title: Error handling - * @Short_Description: Decoding cairo's status - * @See_Also: cairo_status(), cairo_surface_status(), cairo_pattern_status(), - * cairo_font_face_status(), cairo_scaled_font_status(), - * cairo_region_status() - * - * Cairo uses a single status type to represent all kinds of errors. A status - * value of %CAIRO_STATUS_SUCCESS represents no error and has an integer value - * of zero. All other status values represent an error. - * - * Cairo's error handling is designed to be easy to use and safe. All major - * cairo objects <firstterm>retain</firstterm> an error status internally which - * can be queried anytime by the users using cairo*_status() calls. In - * the mean time, it is safe to call all cairo functions normally even if the - * underlying object is in an error status. This means that no error handling - * code is required before or after each individual cairo function call. - **/ - -/* Public stuff */ - -/** - * cairo_status_to_string: - * @status: a cairo status - * - * Provides a human-readable description of a #cairo_status_t. - * - * Returns: a string representation of the status - * - * Since: 1.0 - **/ -const char * -cairo_status_to_string (cairo_status_t status) -{ - switch (status) { - case CAIRO_STATUS_SUCCESS: - return "no error has occurred"; - case CAIRO_STATUS_NO_MEMORY: - return "out of memory"; - case CAIRO_STATUS_INVALID_RESTORE: - return "cairo_restore() without matching cairo_save()"; - case CAIRO_STATUS_INVALID_POP_GROUP: - return "no saved group to pop, i.e. cairo_pop_group() without matching cairo_push_group()"; - case CAIRO_STATUS_NO_CURRENT_POINT: - return "no current point defined"; - case CAIRO_STATUS_INVALID_MATRIX: - return "invalid matrix (not invertible)"; - case CAIRO_STATUS_INVALID_STATUS: - return "invalid value for an input cairo_status_t"; - case CAIRO_STATUS_NULL_POINTER: - return "NULL pointer"; - case CAIRO_STATUS_INVALID_STRING: - return "input string not valid UTF-8"; - case CAIRO_STATUS_INVALID_PATH_DATA: - return "input path data not valid"; - case CAIRO_STATUS_READ_ERROR: - return "error while reading from input stream"; - case CAIRO_STATUS_WRITE_ERROR: - return "error while writing to output stream"; - case CAIRO_STATUS_SURFACE_FINISHED: - return "the target surface has been finished"; - case CAIRO_STATUS_SURFACE_TYPE_MISMATCH: - return "the surface type is not appropriate for the operation"; - case CAIRO_STATUS_PATTERN_TYPE_MISMATCH: - return "the pattern type is not appropriate for the operation"; - case CAIRO_STATUS_INVALID_CONTENT: - return "invalid value for an input cairo_content_t"; - case CAIRO_STATUS_INVALID_FORMAT: - return "invalid value for an input cairo_format_t"; - case CAIRO_STATUS_INVALID_VISUAL: - return "invalid value for an input Visual*"; - case CAIRO_STATUS_FILE_NOT_FOUND: - return "file not found"; - case CAIRO_STATUS_INVALID_DASH: - return "invalid value for a dash setting"; - case CAIRO_STATUS_INVALID_DSC_COMMENT: - return "invalid value for a DSC comment"; - case CAIRO_STATUS_INVALID_INDEX: - return "invalid index passed to getter"; - case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE: - return "clip region not representable in desired format"; - case CAIRO_STATUS_TEMP_FILE_ERROR: - return "error creating or writing to a temporary file"; - case CAIRO_STATUS_INVALID_STRIDE: - return "invalid value for stride"; - case CAIRO_STATUS_FONT_TYPE_MISMATCH: - return "the font type is not appropriate for the operation"; - case CAIRO_STATUS_USER_FONT_IMMUTABLE: - return "the user-font is immutable"; - case CAIRO_STATUS_USER_FONT_ERROR: - return "error occurred in a user-font callback function"; - case CAIRO_STATUS_NEGATIVE_COUNT: - return "negative number used where it is not allowed"; - case CAIRO_STATUS_INVALID_CLUSTERS: - return "input clusters do not represent the accompanying text and glyph arrays"; - case CAIRO_STATUS_INVALID_SLANT: - return "invalid value for an input cairo_font_slant_t"; - case CAIRO_STATUS_INVALID_WEIGHT: - return "invalid value for an input cairo_font_weight_t"; - case CAIRO_STATUS_INVALID_SIZE: - return "invalid value (typically too big) for the size of the input (surface, pattern, etc.)"; - case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: - return "user-font method not implemented"; - case CAIRO_STATUS_DEVICE_TYPE_MISMATCH: - return "the device type is not appropriate for the operation"; - case CAIRO_STATUS_DEVICE_ERROR: - return "an operation to the device caused an unspecified error"; - case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION: - return "invalid operation during mesh pattern construction"; - case CAIRO_STATUS_DEVICE_FINISHED: - return "the target device has been finished"; - case CAIRO_STATUS_JBIG2_GLOBAL_MISSING: - return "CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID used but no CAIRO_MIME_TYPE_JBIG2_GLOBAL data provided"; - default: - case CAIRO_STATUS_LAST_STATUS: - return "<unknown error status>"; - } -} - - -/** - * cairo_glyph_allocate: - * @num_glyphs: number of glyphs to allocate - * - * Allocates an array of #cairo_glyph_t's. - * This function is only useful in implementations of - * #cairo_user_scaled_font_text_to_glyphs_func_t where the user - * needs to allocate an array of glyphs that cairo will free. - * For all other uses, user can use their own allocation method - * for glyphs. - * - * This function returns %NULL if @num_glyphs is not positive, - * or if out of memory. That means, the %NULL return value - * signals out-of-memory only if @num_glyphs was positive. - * - * Returns: the newly allocated array of glyphs that should be - * freed using cairo_glyph_free() - * - * Since: 1.8 - **/ -cairo_glyph_t * -cairo_glyph_allocate (int num_glyphs) -{ - if (num_glyphs <= 0) - return NULL; - - return _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); -} -slim_hidden_def (cairo_glyph_allocate); - -/** - * cairo_glyph_free: - * @glyphs: array of glyphs to free, or %NULL - * - * Frees an array of #cairo_glyph_t's allocated using cairo_glyph_allocate(). - * This function is only useful to free glyph array returned - * by cairo_scaled_font_text_to_glyphs() where cairo returns - * an array of glyphs that the user will free. - * For all other uses, user can use their own allocation method - * for glyphs. - * - * Since: 1.8 - **/ -void -cairo_glyph_free (cairo_glyph_t *glyphs) -{ - free (glyphs); -} -slim_hidden_def (cairo_glyph_free); - -/** - * cairo_text_cluster_allocate: - * @num_clusters: number of text_clusters to allocate - * - * Allocates an array of #cairo_text_cluster_t's. - * This function is only useful in implementations of - * #cairo_user_scaled_font_text_to_glyphs_func_t where the user - * needs to allocate an array of text clusters that cairo will free. - * For all other uses, user can use their own allocation method - * for text clusters. - * - * This function returns %NULL if @num_clusters is not positive, - * or if out of memory. That means, the %NULL return value - * signals out-of-memory only if @num_clusters was positive. - * - * Returns: the newly allocated array of text clusters that should be - * freed using cairo_text_cluster_free() - * - * Since: 1.8 - **/ -cairo_text_cluster_t * -cairo_text_cluster_allocate (int num_clusters) -{ - if (num_clusters <= 0) - return NULL; - - return _cairo_malloc_ab (num_clusters, sizeof (cairo_text_cluster_t)); -} -slim_hidden_def (cairo_text_cluster_allocate); - -/** - * cairo_text_cluster_free: - * @clusters: array of text clusters to free, or %NULL - * - * Frees an array of #cairo_text_cluster's allocated using cairo_text_cluster_allocate(). - * This function is only useful to free text cluster array returned - * by cairo_scaled_font_text_to_glyphs() where cairo returns - * an array of text clusters that the user will free. - * For all other uses, user can use their own allocation method - * for text clusters. - * - * Since: 1.8 - **/ -void -cairo_text_cluster_free (cairo_text_cluster_t *clusters) -{ - free (clusters); -} -slim_hidden_def (cairo_text_cluster_free); - - -/* Private stuff */ - -/** - * _cairo_validate_text_clusters: - * @utf8: UTF-8 text - * @utf8_len: length of @utf8 in bytes - * @glyphs: array of glyphs - * @num_glyphs: number of glyphs - * @clusters: array of cluster mapping information - * @num_clusters: number of clusters in the mapping - * @cluster_flags: cluster flags - * - * Check that clusters cover the entire glyphs and utf8 arrays, - * and that cluster boundaries are UTF-8 boundaries. - * - * Return value: %CAIRO_STATUS_SUCCESS upon success, or - * %CAIRO_STATUS_INVALID_CLUSTERS on error. - * The error is either invalid UTF-8 input, - * or bad cluster mapping. - **/ -cairo_status_t -_cairo_validate_text_clusters (const char *utf8, - int utf8_len, - const cairo_glyph_t *glyphs, - int num_glyphs, - const cairo_text_cluster_t *clusters, - int num_clusters, - cairo_text_cluster_flags_t cluster_flags) -{ - cairo_status_t status; - unsigned int n_bytes = 0; - unsigned int n_glyphs = 0; - int i; - - for (i = 0; i < num_clusters; i++) { - int cluster_bytes = clusters[i].num_bytes; - int cluster_glyphs = clusters[i].num_glyphs; - - if (cluster_bytes < 0 || cluster_glyphs < 0) - goto BAD; - - /* A cluster should cover at least one character or glyph. - * I can't see any use for a 0,0 cluster. - * I can't see an immediate use for a zero-text cluster - * right now either, but they don't harm. - * Zero-glyph clusters on the other hand are useful for - * things like U+200C ZERO WIDTH NON-JOINER */ - if (cluster_bytes == 0 && cluster_glyphs == 0) - goto BAD; - - /* Since n_bytes and n_glyphs are unsigned, but the rest of - * values involved are signed, we can detect overflow easily */ - if (n_bytes+cluster_bytes > (unsigned int)utf8_len || n_glyphs+cluster_glyphs > (unsigned int)num_glyphs) - goto BAD; - - /* Make sure we've got valid UTF-8 for the cluster */ - status = _cairo_utf8_to_ucs4 (utf8+n_bytes, cluster_bytes, NULL, NULL); - if (unlikely (status)) - return _cairo_error (CAIRO_STATUS_INVALID_CLUSTERS); - - n_bytes += cluster_bytes ; - n_glyphs += cluster_glyphs; - } - - if (n_bytes != (unsigned int) utf8_len || n_glyphs != (unsigned int) num_glyphs) { - BAD: - return _cairo_error (CAIRO_STATUS_INVALID_CLUSTERS); - } - - return CAIRO_STATUS_SUCCESS; -} - -/** - * _cairo_operator_bounded_by_mask: - * @op: a #cairo_operator_t - * - * A bounded operator is one where mask pixel - * of zero results in no effect on the destination image. - * - * Unbounded operators often require special handling; if you, for - * example, draw trapezoids with an unbounded operator, the effect - * extends past the bounding box of the trapezoids. - * - * Return value: %TRUE if the operator is bounded by the mask operand - **/ -cairo_bool_t -_cairo_operator_bounded_by_mask (cairo_operator_t op) -{ - switch (op) { - case CAIRO_OPERATOR_CLEAR: - case CAIRO_OPERATOR_SOURCE: - case CAIRO_OPERATOR_OVER: - case CAIRO_OPERATOR_ATOP: - case CAIRO_OPERATOR_DEST: - case CAIRO_OPERATOR_DEST_OVER: - case CAIRO_OPERATOR_DEST_OUT: - case CAIRO_OPERATOR_XOR: - case CAIRO_OPERATOR_ADD: - case CAIRO_OPERATOR_SATURATE: - case CAIRO_OPERATOR_MULTIPLY: - case CAIRO_OPERATOR_SCREEN: - case CAIRO_OPERATOR_OVERLAY: - case CAIRO_OPERATOR_DARKEN: - case CAIRO_OPERATOR_LIGHTEN: - case CAIRO_OPERATOR_COLOR_DODGE: - case CAIRO_OPERATOR_COLOR_BURN: - case CAIRO_OPERATOR_HARD_LIGHT: - case CAIRO_OPERATOR_SOFT_LIGHT: - case CAIRO_OPERATOR_DIFFERENCE: - case CAIRO_OPERATOR_EXCLUSION: - case CAIRO_OPERATOR_HSL_HUE: - case CAIRO_OPERATOR_HSL_SATURATION: - case CAIRO_OPERATOR_HSL_COLOR: - case CAIRO_OPERATOR_HSL_LUMINOSITY: - return TRUE; - case CAIRO_OPERATOR_OUT: - case CAIRO_OPERATOR_IN: - case CAIRO_OPERATOR_DEST_IN: - case CAIRO_OPERATOR_DEST_ATOP: - return FALSE; - } - - ASSERT_NOT_REACHED; - return FALSE; -} - -/** - * _cairo_operator_bounded_by_source: - * @op: a #cairo_operator_t - * - * A bounded operator is one where source pixels of zero - * (in all four components, r, g, b and a) effect no change - * in the resulting destination image. - * - * Unbounded operators often require special handling; if you, for - * example, copy a surface with the SOURCE operator, the effect - * extends past the bounding box of the source surface. - * - * Return value: %TRUE if the operator is bounded by the source operand - **/ -cairo_bool_t -_cairo_operator_bounded_by_source (cairo_operator_t op) -{ - switch (op) { - case CAIRO_OPERATOR_OVER: - case CAIRO_OPERATOR_ATOP: - case CAIRO_OPERATOR_DEST: - case CAIRO_OPERATOR_DEST_OVER: - case CAIRO_OPERATOR_DEST_OUT: - case CAIRO_OPERATOR_XOR: - case CAIRO_OPERATOR_ADD: - case CAIRO_OPERATOR_SATURATE: - case CAIRO_OPERATOR_MULTIPLY: - case CAIRO_OPERATOR_SCREEN: - case CAIRO_OPERATOR_OVERLAY: - case CAIRO_OPERATOR_DARKEN: - case CAIRO_OPERATOR_LIGHTEN: - case CAIRO_OPERATOR_COLOR_DODGE: - case CAIRO_OPERATOR_COLOR_BURN: - case CAIRO_OPERATOR_HARD_LIGHT: - case CAIRO_OPERATOR_SOFT_LIGHT: - case CAIRO_OPERATOR_DIFFERENCE: - case CAIRO_OPERATOR_EXCLUSION: - case CAIRO_OPERATOR_HSL_HUE: - case CAIRO_OPERATOR_HSL_SATURATION: - case CAIRO_OPERATOR_HSL_COLOR: - case CAIRO_OPERATOR_HSL_LUMINOSITY: - return TRUE; - case CAIRO_OPERATOR_CLEAR: - case CAIRO_OPERATOR_SOURCE: - case CAIRO_OPERATOR_OUT: - case CAIRO_OPERATOR_IN: - case CAIRO_OPERATOR_DEST_IN: - case CAIRO_OPERATOR_DEST_ATOP: - return FALSE; - } - - ASSERT_NOT_REACHED; - return FALSE; -} - -uint32_t -_cairo_operator_bounded_by_either (cairo_operator_t op) -{ - switch (op) { - default: - ASSERT_NOT_REACHED; - case CAIRO_OPERATOR_OVER: - case CAIRO_OPERATOR_ATOP: - case CAIRO_OPERATOR_DEST: - case CAIRO_OPERATOR_DEST_OVER: - case CAIRO_OPERATOR_DEST_OUT: - case CAIRO_OPERATOR_XOR: - case CAIRO_OPERATOR_ADD: - case CAIRO_OPERATOR_SATURATE: - case CAIRO_OPERATOR_MULTIPLY: - case CAIRO_OPERATOR_SCREEN: - case CAIRO_OPERATOR_OVERLAY: - case CAIRO_OPERATOR_DARKEN: - case CAIRO_OPERATOR_LIGHTEN: - case CAIRO_OPERATOR_COLOR_DODGE: - case CAIRO_OPERATOR_COLOR_BURN: - case CAIRO_OPERATOR_HARD_LIGHT: - case CAIRO_OPERATOR_SOFT_LIGHT: - case CAIRO_OPERATOR_DIFFERENCE: - case CAIRO_OPERATOR_EXCLUSION: - case CAIRO_OPERATOR_HSL_HUE: - case CAIRO_OPERATOR_HSL_SATURATION: - case CAIRO_OPERATOR_HSL_COLOR: - case CAIRO_OPERATOR_HSL_LUMINOSITY: - return CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE; - case CAIRO_OPERATOR_CLEAR: - case CAIRO_OPERATOR_SOURCE: - return CAIRO_OPERATOR_BOUND_BY_MASK; - case CAIRO_OPERATOR_OUT: - case CAIRO_OPERATOR_IN: - case CAIRO_OPERATOR_DEST_IN: - case CAIRO_OPERATOR_DEST_ATOP: - return 0; - } - -} - -#if DISABLE_SOME_FLOATING_POINT -/* This function is identical to the C99 function lround(), except that it - * performs arithmetic rounding (floor(d + .5) instead of away-from-zero rounding) and - * has a valid input range of (INT_MIN, INT_MAX] instead of - * [INT_MIN, INT_MAX]. It is much faster on both x86 and FPU-less systems - * than other commonly used methods for rounding (lround, round, rint, lrint - * or float (d + 0.5)). - * - * The reason why this function is much faster on x86 than other - * methods is due to the fact that it avoids the fldcw instruction. - * This instruction incurs a large performance penalty on modern Intel - * processors due to how it prevents efficient instruction pipelining. - * - * The reason why this function is much faster on FPU-less systems is for - * an entirely different reason. All common rounding methods involve multiple - * floating-point operations. Each one of these operations has to be - * emulated in software, which adds up to be a large performance penalty. - * This function doesn't perform any floating-point calculations, and thus - * avoids this penalty. - */ -int -_cairo_lround (double d) -{ - uint32_t top, shift_amount, output; - union { - double d; - uint64_t ui64; - uint32_t ui32[2]; - } u; - - u.d = d; - - /* If the integer word order doesn't match the float word order, we swap - * the words of the input double. This is needed because we will be - * treating the whole double as a 64-bit unsigned integer. Notice that we - * use WORDS_BIGENDIAN to detect the integer word order, which isn't - * exactly correct because WORDS_BIGENDIAN refers to byte order, not word - * order. Thus, we are making the assumption that the byte order is the - * same as the integer word order which, on the modern machines that we - * care about, is OK. - */ -#if ( defined(FLOAT_WORDS_BIGENDIAN) && !defined(WORDS_BIGENDIAN)) || \ - (!defined(FLOAT_WORDS_BIGENDIAN) && defined(WORDS_BIGENDIAN)) - { - uint32_t temp = u.ui32[0]; - u.ui32[0] = u.ui32[1]; - u.ui32[1] = temp; - } -#endif - -#ifdef WORDS_BIGENDIAN - #define MSW (0) /* Most Significant Word */ - #define LSW (1) /* Least Significant Word */ -#else - #define MSW (1) - #define LSW (0) -#endif - - /* By shifting the most significant word of the input double to the - * right 20 places, we get the very "top" of the double where the exponent - * and sign bit lie. - */ - top = u.ui32[MSW] >> 20; - - /* Here, we calculate how much we have to shift the mantissa to normalize - * it to an integer value. We extract the exponent "top" by masking out the - * sign bit, then we calculate the shift amount by subtracting the exponent - * from the bias. Notice that the correct bias for 64-bit doubles is - * actually 1075, but we use 1053 instead for two reasons: - * - * 1) To perform rounding later on, we will first need the target - * value in a 31.1 fixed-point format. Thus, the bias needs to be one - * less: (1075 - 1: 1074). - * - * 2) To avoid shifting the mantissa as a full 64-bit integer (which is - * costly on certain architectures), we break the shift into two parts. - * First, the upper and lower parts of the mantissa are shifted - * individually by a constant amount that all valid inputs will require - * at the very least. This amount is chosen to be 21, because this will - * allow the two parts of the mantissa to later be combined into a - * single 32-bit representation, on which the remainder of the shift - * will be performed. Thus, we decrease the bias by an additional 21: - * (1074 - 21: 1053). - */ - shift_amount = 1053 - (top & 0x7FF); - - /* We are done with the exponent portion in "top", so here we shift it off - * the end. - */ - top >>= 11; - - /* Before we perform any operations on the mantissa, we need to OR in - * the implicit 1 at the top (see the IEEE-754 spec). We needn't mask - * off the sign bit nor the exponent bits because these higher bits won't - * make a bit of difference in the rest of our calculations. - */ - u.ui32[MSW] |= 0x100000; - - /* If the input double is negative, we have to decrease the mantissa - * by a hair. This is an important part of performing arithmetic rounding, - * as negative numbers must round towards positive infinity in the - * halfwase case of -x.5. Since "top" contains only the sign bit at this - * point, we can just decrease the mantissa by the value of "top". - */ - u.ui64 -= top; - - /* By decrementing "top", we create a bitmask with a value of either - * 0x0 (if the input was negative) or 0xFFFFFFFF (if the input was positive - * and thus the unsigned subtraction underflowed) that we'll use later. - */ - top--; - - /* Here, we shift the mantissa by the constant value as described above. - * We can emulate a 64-bit shift right by 21 through shifting the top 32 - * bits left 11 places and ORing in the bottom 32 bits shifted 21 places - * to the right. Both parts of the mantissa are now packed into a single - * 32-bit integer. Although we severely truncate the lower part in the - * process, we still have enough significant bits to perform the conversion - * without error (for all valid inputs). - */ - output = (u.ui32[MSW] << 11) | (u.ui32[LSW] >> 21); - - /* Next, we perform the shift that converts the X.Y fixed-point number - * currently found in "output" to the desired 31.1 fixed-point format - * needed for the following rounding step. It is important to consider - * all possible values for "shift_amount" at this point: - * - * - {shift_amount < 0} Since shift_amount is an unsigned integer, it - * really can't have a value less than zero. But, if the shift_amount - * calculation above caused underflow (which would happen with - * input > INT_MAX or input <= INT_MIN) then shift_amount will now be - * a very large number, and so this shift will result in complete - * garbage. But that's OK, as the input was out of our range, so our - * output is undefined. - * - * - {shift_amount > 31} If the magnitude of the input was very small - * (i.e. |input| << 1.0), shift_amount will have a value greater than - * 31. Thus, this shift will also result in garbage. After performing - * the shift, we will zero-out "output" if this is the case. - * - * - {0 <= shift_amount < 32} In this case, the shift will properly convert - * the mantissa into a 31.1 fixed-point number. - */ - output >>= shift_amount; - - /* This is where we perform rounding with the 31.1 fixed-point number. - * Since what we're after is arithmetic rounding, we simply add the single - * fractional bit into the integer part of "output", and just keep the - * integer part. - */ - output = (output >> 1) + (output & 1); - - /* Here, we zero-out the result if the magnitude if the input was very small - * (as explained in the section above). Notice that all input out of the - * valid range is also caught by this condition, which means we produce 0 - * for all invalid input, which is a nice side effect. - * - * The most straightforward way to do this would be: - * - * if (shift_amount > 31) - * output = 0; - * - * But we can use a little trick to avoid the potential branch. The - * expression (shift_amount > 31) will be either 1 or 0, which when - * decremented will be either 0x0 or 0xFFFFFFFF (unsigned underflow), - * which can be used to conditionally mask away all the bits in "output" - * (in the 0x0 case), effectively zeroing it out. Certain, compilers would - * have done this for us automatically. - */ - output &= ((shift_amount > 31) - 1); - - /* If the input double was a negative number, then we have to negate our - * output. The most straightforward way to do this would be: - * - * if (!top) - * output = -output; - * - * as "top" at this point is either 0x0 (if the input was negative) or - * 0xFFFFFFFF (if the input was positive). But, we can use a trick to - * avoid the branch. Observe that the following snippet of code has the - * same effect as the reference snippet above: - * - * if (!top) - * output = 0 - output; - * else - * output = output - 0; - * - * Armed with the bitmask found in "top", we can condense the two statements - * into the following: - * - * output = (output & top) - (output & ~top); - * - * where, in the case that the input double was negative, "top" will be 0, - * and the statement will be equivalent to: - * - * output = (0) - (output); - * - * and if the input double was positive, "top" will be 0xFFFFFFFF, and the - * statement will be equivalent to: - * - * output = (output) - (0); - * - * Which, as pointed out earlier, is equivalent to the original reference - * snippet. - */ - output = (output & top) - (output & ~top); - - return output; -#undef MSW -#undef LSW -} -#endif - -/* Convert a 32-bit IEEE single precision floating point number to a - * 'half' representation (s10.5) - */ -uint16_t -_cairo_half_from_float (float f) -{ - union { - uint32_t ui; - float f; - } u; - int s, e, m; - - u.f = f; - s = (u.ui >> 16) & 0x00008000; - e = ((u.ui >> 23) & 0x000000ff) - (127 - 15); - m = u.ui & 0x007fffff; - if (e <= 0) { - if (e < -10) { - /* underflow */ - return 0; - } - - m = (m | 0x00800000) >> (1 - e); - - /* round to nearest, round 0.5 up. */ - if (m & 0x00001000) - m += 0x00002000; - return s | (m >> 13); - } else if (e == 0xff - (127 - 15)) { - if (m == 0) { - /* infinity */ - return s | 0x7c00; - } else { - /* nan */ - m >>= 13; - return s | 0x7c00 | m | (m == 0); - } - } else { - /* round to nearest, round 0.5 up. */ - if (m & 0x00001000) { - m += 0x00002000; - - if (m & 0x00800000) { - m = 0; - e += 1; - } - } - - if (e > 30) { - /* overflow -> infinity */ - return s | 0x7c00; - } - - return s | (e << 10) | (m >> 13); - } -} - -#ifndef __BIONIC__ -# include <locale.h> - -const char * -cairo_get_locale_decimal_point (void) -{ - struct lconv *locale_data = localeconv (); - return locale_data->decimal_point; -} - -#else -/* Android's Bionic libc doesn't provide decimal_point */ -const char * -cairo_get_locale_decimal_point (void) -{ - return "."; -} -#endif - -#ifdef _WIN32 - -#define WIN32_LEAN_AND_MEAN -/* We require Windows 2000 features such as ETO_PDY */ -#if !defined(WINVER) || (WINVER < 0x0500) -# define WINVER 0x0500 -#endif -#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500) -# define _WIN32_WINNT 0x0500 -#endif - -#include <windows.h> -#include <io.h> - -#if !_WIN32_WCE -/* tmpfile() replacement for Windows. - * - * On Windows tmpfile() creates the file in the root directory. This - * may fail due to unsufficient privileges. However, this isn't a - * problem on Windows CE so we don't use it there. - */ -FILE * -_cairo_win32_tmpfile (void) -{ - DWORD path_len; - WCHAR path_name[MAX_PATH + 1]; - WCHAR file_name[MAX_PATH + 1]; - HANDLE handle; - int fd; - FILE *fp; - - path_len = GetTempPathW (MAX_PATH, path_name); - if (path_len <= 0 || path_len >= MAX_PATH) - return NULL; - - if (GetTempFileNameW (path_name, L"ps_", 0, file_name) == 0) - return NULL; - - handle = CreateFileW (file_name, - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, - NULL); - if (handle == INVALID_HANDLE_VALUE) { - DeleteFileW (file_name); - return NULL; - } - - fd = _open_osfhandle((intptr_t) handle, 0); - if (fd < 0) { - CloseHandle (handle); - return NULL; - } - - fp = fdopen(fd, "w+b"); - if (fp == NULL) { - _close(fd); - return NULL; - } - - return fp; -} -#endif /* !_WIN32_WCE */ - -#endif /* _WIN32 */ - -typedef struct _cairo_intern_string { - cairo_hash_entry_t hash_entry; - int len; - char *string; -} cairo_intern_string_t; - -static cairo_hash_table_t *_cairo_intern_string_ht; - -static unsigned long -_intern_string_hash (const char *str, int len) -{ - const signed char *p = (const signed char *) str; - unsigned int h = *p; - - for (p += 1; --len; p++) - h = (h << 5) - h + *p; - - return h; -} - -static cairo_bool_t -_intern_string_equal (const void *_a, const void *_b) -{ - const cairo_intern_string_t *a = _a; - const cairo_intern_string_t *b = _b; - - if (a->len != b->len) - return FALSE; - - return memcmp (a->string, b->string, a->len) == 0; -} - -cairo_status_t -_cairo_intern_string (const char **str_inout, int len) -{ - char *str = (char *) *str_inout; - cairo_intern_string_t tmpl, *istring; - cairo_status_t status = CAIRO_STATUS_SUCCESS; - - if (CAIRO_INJECT_FAULT ()) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - if (len < 0) - len = strlen (str); - tmpl.hash_entry.hash = _intern_string_hash (str, len); - tmpl.len = len; - tmpl.string = (char *) str; - - CAIRO_MUTEX_LOCK (_cairo_intern_string_mutex); - if (_cairo_intern_string_ht == NULL) { - _cairo_intern_string_ht = _cairo_hash_table_create (_intern_string_equal); - if (unlikely (_cairo_intern_string_ht == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto BAIL; - } - } - - istring = _cairo_hash_table_lookup (_cairo_intern_string_ht, - &tmpl.hash_entry); - if (istring == NULL) { - istring = malloc (sizeof (cairo_intern_string_t) + len + 1); - if (likely (istring != NULL)) { - istring->hash_entry.hash = tmpl.hash_entry.hash; - istring->len = tmpl.len; - istring->string = (char *) (istring + 1); - memcpy (istring->string, str, len); - istring->string[len] = '\0'; - - status = _cairo_hash_table_insert (_cairo_intern_string_ht, - &istring->hash_entry); - if (unlikely (status)) { - free (istring); - goto BAIL; - } - } else { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto BAIL; - } - } - - *str_inout = istring->string; - - BAIL: - CAIRO_MUTEX_UNLOCK (_cairo_intern_string_mutex); - return status; -} - -static void -_intern_string_pluck (void *entry, void *closure) -{ - _cairo_hash_table_remove (closure, entry); - free (entry); -} - -void -_cairo_intern_string_reset_static_data (void) -{ - CAIRO_MUTEX_LOCK (_cairo_intern_string_mutex); - if (_cairo_intern_string_ht != NULL) { - _cairo_hash_table_foreach (_cairo_intern_string_ht, - _intern_string_pluck, - _cairo_intern_string_ht); - _cairo_hash_table_destroy(_cairo_intern_string_ht); - _cairo_intern_string_ht = NULL; - } - CAIRO_MUTEX_UNLOCK (_cairo_intern_string_mutex); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-mono-scan-converter.c b/source/libs/cairo/cairo-src/src/cairo-mono-scan-converter.c deleted file mode 100644 index 2a9546cf82aa45dbb5aeee5d0b0baa48ae78c52b..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-mono-scan-converter.c +++ /dev/null @@ -1,612 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* - * Copyright (c) 2011 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -#include "cairoint.h" -#include "cairo-spans-private.h" -#include "cairo-error-private.h" - -#include <stdlib.h> -#include <string.h> -#include <limits.h> - -struct quorem { - int32_t quo; - int32_t rem; -}; - -struct edge { - struct edge *next, *prev; - - int32_t height_left; - int32_t dir; - int32_t vertical; - - int32_t dy; - struct quorem x; - struct quorem dxdy; -}; - -/* A collection of sorted and vertically clipped edges of the polygon. - * Edges are moved from the polygon to an active list while scan - * converting. */ -struct polygon { - /* The vertical clip extents. */ - int32_t ymin, ymax; - - int num_edges; - struct edge *edges; - - /* Array of edges all starting in the same bucket. An edge is put - * into bucket EDGE_BUCKET_INDEX(edge->ytop, polygon->ymin) when - * it is added to the polygon. */ - struct edge **y_buckets; - - struct edge *y_buckets_embedded[64]; - struct edge edges_embedded[32]; -}; - -struct mono_scan_converter { - struct polygon polygon[1]; - - /* Leftmost edge on the current scan line. */ - struct edge head, tail; - int is_vertical; - - cairo_half_open_span_t *spans; - cairo_half_open_span_t spans_embedded[64]; - int num_spans; - - /* Clip box. */ - int32_t xmin, xmax; - int32_t ymin, ymax; -}; - -#define I(x) _cairo_fixed_integer_round_down(x) - -/* Compute the floored division a/b. Assumes / and % perform symmetric - * division. */ -inline static struct quorem -floored_divrem(int a, int b) -{ - struct quorem qr; - qr.quo = a/b; - qr.rem = a%b; - if ((a^b)<0 && qr.rem) { - qr.quo -= 1; - qr.rem += b; - } - return qr; -} - -/* Compute the floored division (x*a)/b. Assumes / and % perform symmetric - * division. */ -static struct quorem -floored_muldivrem(int x, int a, int b) -{ - struct quorem qr; - long long xa = (long long)x*a; - qr.quo = xa/b; - qr.rem = xa%b; - if ((xa>=0) != (b>=0) && qr.rem) { - qr.quo -= 1; - qr.rem += b; - } - return qr; -} - -static cairo_status_t -polygon_init (struct polygon *polygon, int ymin, int ymax) -{ - unsigned h = ymax - ymin + 1; - - polygon->y_buckets = polygon->y_buckets_embedded; - if (h > ARRAY_LENGTH (polygon->y_buckets_embedded)) { - polygon->y_buckets = _cairo_malloc_ab (h, sizeof (struct edge *)); - if (unlikely (NULL == polygon->y_buckets)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - memset (polygon->y_buckets, 0, h * sizeof (struct edge *)); - polygon->y_buckets[h-1] = (void *)-1; - - polygon->ymin = ymin; - polygon->ymax = ymax; - return CAIRO_STATUS_SUCCESS; -} - -static void -polygon_fini (struct polygon *polygon) -{ - if (polygon->y_buckets != polygon->y_buckets_embedded) - free (polygon->y_buckets); - - if (polygon->edges != polygon->edges_embedded) - free (polygon->edges); -} - -static void -_polygon_insert_edge_into_its_y_bucket(struct polygon *polygon, - struct edge *e, - int y) -{ - struct edge **ptail = &polygon->y_buckets[y - polygon->ymin]; - if (*ptail) - (*ptail)->prev = e; - e->next = *ptail; - e->prev = NULL; - *ptail = e; -} - -inline static void -polygon_add_edge (struct polygon *polygon, - const cairo_edge_t *edge) -{ - struct edge *e; - cairo_fixed_t dx; - cairo_fixed_t dy; - int y, ytop, ybot; - int ymin = polygon->ymin; - int ymax = polygon->ymax; - - y = I(edge->top); - ytop = MAX(y, ymin); - - y = I(edge->bottom); - ybot = MIN(y, ymax); - - if (ybot <= ytop) - return; - - e = polygon->edges + polygon->num_edges++; - e->height_left = ybot - ytop; - e->dir = edge->dir; - - dx = edge->line.p2.x - edge->line.p1.x; - dy = edge->line.p2.y - edge->line.p1.y; - - if (dx == 0) { - e->vertical = TRUE; - e->x.quo = edge->line.p1.x; - e->x.rem = 0; - e->dxdy.quo = 0; - e->dxdy.rem = 0; - e->dy = 0; - } else { - e->vertical = FALSE; - e->dxdy = floored_muldivrem (dx, CAIRO_FIXED_ONE, dy); - e->dy = dy; - - e->x = floored_muldivrem (ytop * CAIRO_FIXED_ONE + CAIRO_FIXED_FRAC_MASK/2 - edge->line.p1.y, - dx, dy); - e->x.quo += edge->line.p1.x; - } - e->x.rem -= dy; - - _polygon_insert_edge_into_its_y_bucket (polygon, e, ytop); -} - -static struct edge * -merge_sorted_edges (struct edge *head_a, struct edge *head_b) -{ - struct edge *head, **next, *prev; - int32_t x; - - prev = head_a->prev; - next = &head; - if (head_a->x.quo <= head_b->x.quo) { - head = head_a; - } else { - head = head_b; - head_b->prev = prev; - goto start_with_b; - } - - do { - x = head_b->x.quo; - while (head_a != NULL && head_a->x.quo <= x) { - prev = head_a; - next = &head_a->next; - head_a = head_a->next; - } - - head_b->prev = prev; - *next = head_b; - if (head_a == NULL) - return head; - -start_with_b: - x = head_a->x.quo; - while (head_b != NULL && head_b->x.quo <= x) { - prev = head_b; - next = &head_b->next; - head_b = head_b->next; - } - - head_a->prev = prev; - *next = head_a; - if (head_b == NULL) - return head; - } while (1); -} - -static struct edge * -sort_edges (struct edge *list, - unsigned int level, - struct edge **head_out) -{ - struct edge *head_other, *remaining; - unsigned int i; - - head_other = list->next; - - if (head_other == NULL) { - *head_out = list; - return NULL; - } - - remaining = head_other->next; - if (list->x.quo <= head_other->x.quo) { - *head_out = list; - head_other->next = NULL; - } else { - *head_out = head_other; - head_other->prev = list->prev; - head_other->next = list; - list->prev = head_other; - list->next = NULL; - } - - for (i = 0; i < level && remaining; i++) { - remaining = sort_edges (remaining, i, &head_other); - *head_out = merge_sorted_edges (*head_out, head_other); - } - - return remaining; -} - -static struct edge * -merge_unsorted_edges (struct edge *head, struct edge *unsorted) -{ - sort_edges (unsorted, UINT_MAX, &unsorted); - return merge_sorted_edges (head, unsorted); -} - -inline static void -active_list_merge_edges (struct mono_scan_converter *c, struct edge *edges) -{ - struct edge *e; - - for (e = edges; c->is_vertical && e; e = e->next) - c->is_vertical = e->vertical; - - c->head.next = merge_unsorted_edges (c->head.next, edges); -} - -inline static void -add_span (struct mono_scan_converter *c, int x1, int x2) -{ - int n; - - if (x1 < c->xmin) - x1 = c->xmin; - if (x2 > c->xmax) - x2 = c->xmax; - if (x2 <= x1) - return; - - n = c->num_spans++; - c->spans[n].x = x1; - c->spans[n].coverage = 255; - - n = c->num_spans++; - c->spans[n].x = x2; - c->spans[n].coverage = 0; -} - -inline static void -row (struct mono_scan_converter *c, unsigned int mask) -{ - struct edge *edge = c->head.next; - int xstart = INT_MIN, prev_x = INT_MIN; - int winding = 0; - - c->num_spans = 0; - while (&c->tail != edge) { - struct edge *next = edge->next; - int xend = I(edge->x.quo); - - if (--edge->height_left) { - if (!edge->vertical) { - edge->x.quo += edge->dxdy.quo; - edge->x.rem += edge->dxdy.rem; - if (edge->x.rem >= 0) { - ++edge->x.quo; - edge->x.rem -= edge->dy; - } - } - - if (edge->x.quo < prev_x) { - struct edge *pos = edge->prev; - pos->next = next; - next->prev = pos; - do { - pos = pos->prev; - } while (edge->x.quo < pos->x.quo); - pos->next->prev = edge; - edge->next = pos->next; - edge->prev = pos; - pos->next = edge; - } else - prev_x = edge->x.quo; - } else { - edge->prev->next = next; - next->prev = edge->prev; - } - - winding += edge->dir; - if ((winding & mask) == 0) { - if (I(next->x.quo) > xend + 1) { - add_span (c, xstart, xend); - xstart = INT_MIN; - } - } else if (xstart == INT_MIN) - xstart = xend; - - edge = next; - } -} - -inline static void dec (struct edge *e, int h) -{ - e->height_left -= h; - if (e->height_left == 0) { - e->prev->next = e->next; - e->next->prev = e->prev; - } -} - -static cairo_status_t -_mono_scan_converter_init(struct mono_scan_converter *c, - int xmin, int ymin, - int xmax, int ymax) -{ - cairo_status_t status; - int max_num_spans; - - status = polygon_init (c->polygon, ymin, ymax); - if (unlikely (status)) - return status; - - max_num_spans = xmax - xmin + 1; - if (max_num_spans > ARRAY_LENGTH(c->spans_embedded)) { - c->spans = _cairo_malloc_ab (max_num_spans, - sizeof (cairo_half_open_span_t)); - if (unlikely (c->spans == NULL)) { - polygon_fini (c->polygon); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - } else - c->spans = c->spans_embedded; - - c->xmin = xmin; - c->xmax = xmax; - c->ymin = ymin; - c->ymax = ymax; - - c->head.vertical = 1; - c->head.height_left = INT_MAX; - c->head.x.quo = _cairo_fixed_from_int (_cairo_fixed_integer_part (INT_MIN)); - c->head.prev = NULL; - c->head.next = &c->tail; - c->tail.prev = &c->head; - c->tail.next = NULL; - c->tail.x.quo = _cairo_fixed_from_int (_cairo_fixed_integer_part (INT_MAX)); - c->tail.height_left = INT_MAX; - c->tail.vertical = 1; - - c->is_vertical = 1; - return CAIRO_STATUS_SUCCESS; -} - -static void -_mono_scan_converter_fini(struct mono_scan_converter *self) -{ - if (self->spans != self->spans_embedded) - free (self->spans); - - polygon_fini(self->polygon); -} - -static cairo_status_t -mono_scan_converter_allocate_edges(struct mono_scan_converter *c, - int num_edges) - -{ - c->polygon->num_edges = 0; - c->polygon->edges = c->polygon->edges_embedded; - if (num_edges > ARRAY_LENGTH (c->polygon->edges_embedded)) { - c->polygon->edges = _cairo_malloc_ab (num_edges, sizeof (struct edge)); - if (unlikely (c->polygon->edges == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - return CAIRO_STATUS_SUCCESS; -} - -static void -mono_scan_converter_add_edge (struct mono_scan_converter *c, - const cairo_edge_t *edge) -{ - polygon_add_edge (c->polygon, edge); -} - -static void -step_edges (struct mono_scan_converter *c, int count) -{ - struct edge *edge; - - for (edge = c->head.next; edge != &c->tail; edge = edge->next) { - edge->height_left -= count; - if (! edge->height_left) { - edge->prev->next = edge->next; - edge->next->prev = edge->prev; - } - } -} - -static cairo_status_t -mono_scan_converter_render(struct mono_scan_converter *c, - unsigned int winding_mask, - cairo_span_renderer_t *renderer) -{ - struct polygon *polygon = c->polygon; - int i, j, h = c->ymax - c->ymin; - cairo_status_t status; - - for (i = 0; i < h; i = j) { - j = i + 1; - - if (polygon->y_buckets[i]) - active_list_merge_edges (c, polygon->y_buckets[i]); - - if (c->is_vertical) { - int min_height; - struct edge *e; - - e = c->head.next; - min_height = e->height_left; - while (e != &c->tail) { - if (e->height_left < min_height) - min_height = e->height_left; - e = e->next; - } - - while (--min_height >= 1 && polygon->y_buckets[j] == NULL) - j++; - if (j != i + 1) - step_edges (c, j - (i + 1)); - } - - row (c, winding_mask); - if (c->num_spans) { - status = renderer->render_rows (renderer, c->ymin+i, j-i, - c->spans, c->num_spans); - if (unlikely (status)) - return status; - } - - /* XXX recompute after dropping edges? */ - if (c->head.next == &c->tail) - c->is_vertical = 1; - } - - return CAIRO_STATUS_SUCCESS; -} - -struct _cairo_mono_scan_converter { - cairo_scan_converter_t base; - - struct mono_scan_converter converter[1]; - cairo_fill_rule_t fill_rule; -}; - -typedef struct _cairo_mono_scan_converter cairo_mono_scan_converter_t; - -static void -_cairo_mono_scan_converter_destroy (void *converter) -{ - cairo_mono_scan_converter_t *self = converter; - _mono_scan_converter_fini (self->converter); - free(self); -} - -cairo_status_t -_cairo_mono_scan_converter_add_polygon (void *converter, - const cairo_polygon_t *polygon) -{ - cairo_mono_scan_converter_t *self = converter; - cairo_status_t status; - int i; - -#if 0 - FILE *file = fopen ("polygon.txt", "w"); - _cairo_debug_print_polygon (file, polygon); - fclose (file); -#endif - - status = mono_scan_converter_allocate_edges (self->converter, - polygon->num_edges); - if (unlikely (status)) - return status; - - for (i = 0; i < polygon->num_edges; i++) - mono_scan_converter_add_edge (self->converter, &polygon->edges[i]); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_mono_scan_converter_generate (void *converter, - cairo_span_renderer_t *renderer) -{ - cairo_mono_scan_converter_t *self = converter; - - return mono_scan_converter_render (self->converter, - self->fill_rule == CAIRO_FILL_RULE_WINDING ? ~0 : 1, - renderer); -} - -cairo_scan_converter_t * -_cairo_mono_scan_converter_create (int xmin, - int ymin, - int xmax, - int ymax, - cairo_fill_rule_t fill_rule) -{ - cairo_mono_scan_converter_t *self; - cairo_status_t status; - - self = malloc (sizeof(struct _cairo_mono_scan_converter)); - if (unlikely (self == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto bail_nomem; - } - - self->base.destroy = _cairo_mono_scan_converter_destroy; - self->base.generate = _cairo_mono_scan_converter_generate; - - status = _mono_scan_converter_init (self->converter, - xmin, ymin, xmax, ymax); - if (unlikely (status)) - goto bail; - - self->fill_rule = fill_rule; - - return &self->base; - - bail: - self->base.destroy(&self->base); - bail_nomem: - return _cairo_scan_converter_create_in_error (status); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-mutex-impl-private.h b/source/libs/cairo/cairo-src/src/cairo-mutex-impl-private.h deleted file mode 100644 index 25223f3eac0b11e39a9dc8a12dc134a3f9b8d007..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-mutex-impl-private.h +++ /dev/null @@ -1,278 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005,2007 Red Hat, Inc. - * Copyright © 2007 Mathias Hasselmann - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Mathias Hasselmann <mathias.hasselmann@gmx.de> - * Behdad Esfahbod <behdad@behdad.org> - */ - -#ifndef CAIRO_MUTEX_IMPL_PRIVATE_H -#define CAIRO_MUTEX_IMPL_PRIVATE_H - -#include "cairo.h" - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#if HAVE_LOCKDEP -#include <lockdep.h> -#endif - -/* A fully qualified no-operation statement */ -#define CAIRO_MUTEX_IMPL_NOOP do {/*no-op*/} while (0) -/* And one that evaluates its argument once */ -#define CAIRO_MUTEX_IMPL_NOOP1(expr) do { (void)(expr); } while (0) -/* Note: 'if (expr) {}' is an alternative to '(void)(expr);' that will 'use' the - * result of __attribute__((warn_used_result)) functions. */ - -/* Cairo mutex implementation: - * - * Any new mutex implementation needs to do the following: - * - * - Condition on the right header or feature. Headers are - * preferred as eg. you still can use win32 mutex implementation - * on a win32 system even if you do not compile the win32 - * surface/backend. - * - * - typedef #cairo_mutex_impl_t to the proper mutex type on your target - * system. Note that you may or may not need to use a pointer, - * depending on what kinds of initialization your mutex - * implementation supports. No trailing semicolon needed. - * You should be able to compile the following snippet (don't try - * running it): - * - * <programlisting> - * cairo_mutex_impl_t _cairo_some_mutex; - * </programlisting> - * - * - #define %CAIRO_MUTEX_IMPL_<NAME> 1 with suitable name for your platform. You - * can later use this symbol in cairo-system.c. - * - * - #define CAIRO_MUTEX_IMPL_LOCK(mutex) and CAIRO_MUTEX_IMPL_UNLOCK(mutex) to - * proper statement to lock/unlock the mutex object passed in. - * You can (and should) assume that the mutex is already - * initialized, and is-not-already-locked/is-locked, - * respectively. Use the "do { ... } while (0)" idiom if necessary. - * No trailing semicolons are needed (in any macro you define here). - * You should be able to compile the following snippet: - * - * <programlisting> - * cairo_mutex_impl_t _cairo_some_mutex; - * - * if (1) - * CAIRO_MUTEX_IMPL_LOCK (_cairo_some_mutex); - * else - * CAIRO_MUTEX_IMPL_UNLOCK (_cairo_some_mutex); - * </programlisting> - * - * - #define %CAIRO_MUTEX_IMPL_NIL_INITIALIZER to something that can - * initialize the #cairo_mutex_impl_t type you defined. Most of the - * time one of 0, %NULL, or {} works. At this point - * you should be able to compile the following snippet: - * - * <programlisting> - * cairo_mutex_impl_t _cairo_some_mutex = CAIRO_MUTEX_IMPL_NIL_INITIALIZER; - * - * if (1) - * CAIRO_MUTEX_IMPL_LOCK (_cairo_some_mutex); - * else - * CAIRO_MUTEX_IMPL_UNLOCK (_cairo_some_mutex); - * </programlisting> - * - * - If the above code is not enough to initialize a mutex on - * your platform, #define CAIRO_MUTEX_IMPL_INIT(mutex) to statement - * to initialize the mutex (allocate resources, etc). Such that - * you should be able to compile AND RUN the following snippet: - * - * <programlisting> - * cairo_mutex_impl_t _cairo_some_mutex = CAIRO_MUTEX_IMPL_NIL_INITIALIZER; - * - * CAIRO_MUTEX_IMPL_INIT (_cairo_some_mutex); - * - * if (1) - * CAIRO_MUTEX_IMPL_LOCK (_cairo_some_mutex); - * else - * CAIRO_MUTEX_IMPL_UNLOCK (_cairo_some_mutex); - * </programlisting> - * - * - If you define CAIRO_MUTEX_IMPL_INIT(mutex), cairo will use it to - * initialize all static mutex'es. If for any reason that should - * not happen (eg. %CAIRO_MUTEX_IMPL_INIT is just a faster way than - * what cairo does using %CAIRO_MUTEX_IMPL_NIL_INITIALIZER), then - * <programlisting> - * #define CAIRO_MUTEX_IMPL_INITIALIZE() CAIRO_MUTEX_IMPL_NOOP - * </programlisting> - * - * - If your system supports freeing a mutex object (deallocating - * resources, etc), then #define CAIRO_MUTEX_IMPL_FINI(mutex) to do - * that. - * - * - If you define CAIRO_MUTEX_IMPL_FINI(mutex), cairo will use it to - * define a finalizer function to finalize all static mutex'es. - * However, it's up to you to call CAIRO_MUTEX_IMPL_FINALIZE() at - * proper places, eg. when the system is unloading the cairo library. - * So, if for any reason finalizing static mutex'es is not needed - * (eg. you never call CAIRO_MUTEX_IMPL_FINALIZE()), then - * <programlisting> - * #define CAIRO_MUTEX_IMPL_FINALIZE() CAIRO_MUTEX_IMPL_NOOP - * </programlisting> - * - * - That is all. If for any reason you think the above API is - * not enough to implement #cairo_mutex_impl_t on your system, please - * stop and write to the cairo mailing list about it. DO NOT - * poke around cairo-mutex-private.h for possible solutions. - */ - -#if CAIRO_NO_MUTEX - -/* No mutexes */ - - typedef int cairo_mutex_impl_t; - -# define CAIRO_MUTEX_IMPL_NO 1 -# define CAIRO_MUTEX_IMPL_INITIALIZE() CAIRO_MUTEX_IMPL_NOOP -# define CAIRO_MUTEX_IMPL_LOCK(mutex) CAIRO_MUTEX_IMPL_NOOP1(mutex) -# define CAIRO_MUTEX_IMPL_UNLOCK(mutex) CAIRO_MUTEX_IMPL_NOOP1(mutex) -# define CAIRO_MUTEX_IMPL_NIL_INITIALIZER 0 - -# define CAIRO_MUTEX_HAS_RECURSIVE_IMPL 1 - - typedef int cairo_recursive_mutex_impl_t; - -# define CAIRO_RECURSIVE_MUTEX_IMPL_INIT(mutex) -# define CAIRO_RECURSIVE_MUTEX_IMPL_NIL_INITIALIZER 0 - -#elif defined(_WIN32) /******************************************************/ - -#define WIN32_LEAN_AND_MEAN -/* We require Windows 2000 features such as ETO_PDY */ -#if !defined(WINVER) || (WINVER < 0x0500) -# define WINVER 0x0500 -#endif -#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0500) -# define _WIN32_WINNT 0x0500 -#endif - -# include <windows.h> - - typedef CRITICAL_SECTION cairo_mutex_impl_t; - -# define CAIRO_MUTEX_IMPL_WIN32 1 -# define CAIRO_MUTEX_IMPL_LOCK(mutex) EnterCriticalSection (&(mutex)) -# define CAIRO_MUTEX_IMPL_UNLOCK(mutex) LeaveCriticalSection (&(mutex)) -# define CAIRO_MUTEX_IMPL_INIT(mutex) InitializeCriticalSection (&(mutex)) -# define CAIRO_MUTEX_IMPL_FINI(mutex) DeleteCriticalSection (&(mutex)) -# define CAIRO_MUTEX_IMPL_NIL_INITIALIZER { NULL, 0, 0, NULL, NULL, 0 } - -#elif defined __OS2__ /******************************************************/ - -# define INCL_BASE -# define INCL_PM -# include <os2.h> - - typedef HMTX cairo_mutex_impl_t; - -# define CAIRO_MUTEX_IMPL_OS2 1 -# define CAIRO_MUTEX_IMPL_LOCK(mutex) DosRequestMutexSem(mutex, SEM_INDEFINITE_WAIT) -# define CAIRO_MUTEX_IMPL_UNLOCK(mutex) DosReleaseMutexSem(mutex) -# define CAIRO_MUTEX_IMPL_INIT(mutex) DosCreateMutexSem (NULL, &(mutex), 0L, FALSE) -# define CAIRO_MUTEX_IMPL_FINI(mutex) DosCloseMutexSem (mutex) -# define CAIRO_MUTEX_IMPL_NIL_INITIALIZER 0 - -#elif CAIRO_HAS_BEOS_SURFACE /***********************************************/ - - typedef BLocker* cairo_mutex_impl_t; - -# define CAIRO_MUTEX_IMPL_BEOS 1 -# define CAIRO_MUTEX_IMPL_LOCK(mutex) (mutex)->Lock() -# define CAIRO_MUTEX_IMPL_UNLOCK(mutex) (mutex)->Unlock() -# define CAIRO_MUTEX_IMPL_INIT(mutex) (mutex) = new BLocker() -# define CAIRO_MUTEX_IMPL_FINI(mutex) delete (mutex) -# define CAIRO_MUTEX_IMPL_NIL_INITIALIZER NULL - -#elif CAIRO_HAS_PTHREAD /* and finally if there are no native mutexes ********/ - -# include <pthread.h> - - typedef pthread_mutex_t cairo_mutex_impl_t; - typedef pthread_mutex_t cairo_recursive_mutex_impl_t; - -# define CAIRO_MUTEX_IMPL_PTHREAD 1 -#if HAVE_LOCKDEP -/* expose all mutexes to the validator */ -# define CAIRO_MUTEX_IMPL_INIT(mutex) pthread_mutex_init (&(mutex), NULL) -#endif -# define CAIRO_MUTEX_IMPL_LOCK(mutex) pthread_mutex_lock (&(mutex)) -# define CAIRO_MUTEX_IMPL_UNLOCK(mutex) pthread_mutex_unlock (&(mutex)) -#if HAVE_LOCKDEP -# define CAIRO_MUTEX_IS_LOCKED(mutex) LOCKDEP_IS_LOCKED (&(mutex)) -# define CAIRO_MUTEX_IS_UNLOCKED(mutex) LOCKDEP_IS_UNLOCKED (&(mutex)) -#endif -# define CAIRO_MUTEX_IMPL_FINI(mutex) pthread_mutex_destroy (&(mutex)) -#if ! HAVE_LOCKDEP -# define CAIRO_MUTEX_IMPL_FINALIZE() CAIRO_MUTEX_IMPL_NOOP -#endif -# define CAIRO_MUTEX_IMPL_NIL_INITIALIZER PTHREAD_MUTEX_INITIALIZER - -# define CAIRO_MUTEX_HAS_RECURSIVE_IMPL 1 -# define CAIRO_RECURSIVE_MUTEX_IMPL_INIT(mutex) do { \ - pthread_mutexattr_t attr; \ - pthread_mutexattr_init (&attr); \ - pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); \ - pthread_mutex_init (&(mutex), &attr); \ - pthread_mutexattr_destroy (&attr); \ -} while (0) -# define CAIRO_RECURSIVE_MUTEX_IMPL_NIL_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP - -#else /**********************************************************************/ - -# error "XXX: No mutex implementation found. Cairo will not work with multiple threads. Define CAIRO_NO_MUTEX to 1 to acknowledge and accept this limitation and compile cairo without thread-safety support." - -#endif - -/* By default mutex implementations are assumed to be recursive */ -#if ! CAIRO_MUTEX_HAS_RECURSIVE_IMPL - -# define CAIRO_MUTEX_HAS_RECURSIVE_IMPL 1 - - typedef cairo_mutex_impl_t cairo_recursive_mutex_impl_t; - -# define CAIRO_RECURSIVE_MUTEX_IMPL_INIT(mutex) CAIRO_MUTEX_IMPL_INIT(mutex) -# define CAIRO_RECURSIVE_MUTEX_IMPL_NIL_INITIALIZER CAIRO_MUTEX_IMPL_NIL_INITIALIZER - -#endif - -#endif diff --git a/source/libs/cairo/cairo-src/src/cairo-mutex-list-private.h b/source/libs/cairo/cairo-src/src/cairo-mutex-list-private.h deleted file mode 100644 index f46afadb04b2ac807041d4398a01775d311caf8c..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-mutex-list-private.h +++ /dev/null @@ -1,78 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2007 Mathias Hasselmann - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * Contributor(s): - * Mathias Hasselmann <mathias.hasselmann@gmx.de> - */ - -#ifndef CAIRO_FEATURES_H -/* This block is to just make this header file standalone */ -#define CAIRO_MUTEX_DECLARE(mutex) -#endif - -CAIRO_MUTEX_DECLARE (_cairo_pattern_solid_surface_cache_lock) - -CAIRO_MUTEX_DECLARE (_cairo_image_solid_cache_mutex) - -CAIRO_MUTEX_DECLARE (_cairo_toy_font_face_mutex) -CAIRO_MUTEX_DECLARE (_cairo_intern_string_mutex) -CAIRO_MUTEX_DECLARE (_cairo_scaled_font_map_mutex) -CAIRO_MUTEX_DECLARE (_cairo_scaled_glyph_page_cache_mutex) -CAIRO_MUTEX_DECLARE (_cairo_scaled_font_error_mutex) -CAIRO_MUTEX_DECLARE (_cairo_glyph_cache_mutex) - -#if CAIRO_HAS_FT_FONT -CAIRO_MUTEX_DECLARE (_cairo_ft_unscaled_font_map_mutex) -#endif - -#if CAIRO_HAS_WIN32_FONT -CAIRO_MUTEX_DECLARE (_cairo_win32_font_face_mutex) -#endif - -#if CAIRO_HAS_XLIB_SURFACE -CAIRO_MUTEX_DECLARE (_cairo_xlib_display_mutex) -#endif - -#if CAIRO_HAS_XCB_SURFACE -CAIRO_MUTEX_DECLARE (_cairo_xcb_connections_mutex) -#endif - -#if CAIRO_HAS_GL_SURFACE -CAIRO_MUTEX_DECLARE (_cairo_gl_context_mutex) -#endif - -#if !defined (HAS_ATOMIC_OPS) || defined (ATOMIC_OP_NEEDS_MEMORY_BARRIER) -CAIRO_MUTEX_DECLARE (_cairo_atomic_mutex) -#endif - -#if CAIRO_HAS_DRM_SURFACE -CAIRO_MUTEX_DECLARE (_cairo_drm_device_mutex) -#endif -/* Undefine, to err on unintended inclusion */ -#undef CAIRO_MUTEX_DECLARE diff --git a/source/libs/cairo/cairo-src/src/cairo-mutex-private.h b/source/libs/cairo/cairo-src/src/cairo-mutex-private.h deleted file mode 100644 index 61a7160a066ce2445bc26ea6ffdab55fbb9e1d15..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-mutex-private.h +++ /dev/null @@ -1,67 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005,2007 Red Hat, Inc. - * Copyright © 2007 Mathias Hasselmann - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Mathias Hasselmann <mathias.hasselmann@gmx.de> - * Behdad Esfahbod <behdad@behdad.org> - */ - -#ifndef CAIRO_MUTEX_PRIVATE_H -#define CAIRO_MUTEX_PRIVATE_H - -#include "cairo-mutex-type-private.h" - -CAIRO_BEGIN_DECLS - -#if _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER -cairo_private void _cairo_mutex_initialize (void); -#endif -#if _CAIRO_MUTEX_IMPL_USE_STATIC_FINALIZER -cairo_private void _cairo_mutex_finalize (void); -#endif -/* only if using static initializer and/or finalizer define the boolean */ -#if _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER || _CAIRO_MUTEX_IMPL_USE_STATIC_FINALIZER - cairo_private extern cairo_bool_t _cairo_mutex_initialized; -#endif - -/* Finally, extern the static mutexes and undef */ - -#define CAIRO_MUTEX_DECLARE(mutex) cairo_private extern cairo_mutex_t mutex; -#include "cairo-mutex-list-private.h" -#undef CAIRO_MUTEX_DECLARE - -CAIRO_END_DECLS - -#endif diff --git a/source/libs/cairo/cairo-src/src/cairo-mutex-type-private.h b/source/libs/cairo/cairo-src/src/cairo-mutex-type-private.h deleted file mode 100644 index e8c493985c9c7023b6d50486e0dd678a85584fa7..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-mutex-type-private.h +++ /dev/null @@ -1,194 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005,2007 Red Hat, Inc. - * Copyright © 2007 Mathias Hasselmann - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Mathias Hasselmann <mathias.hasselmann@gmx.de> - * Behdad Esfahbod <behdad@behdad.org> - */ - -#ifndef CAIRO_MUTEX_TYPE_PRIVATE_H -#define CAIRO_MUTEX_TYPE_PRIVATE_H - -#include "cairo-compiler-private.h" -#include "cairo-mutex-impl-private.h" - -/* Only the following four are mandatory at this point */ -#ifndef CAIRO_MUTEX_IMPL_LOCK -# error "CAIRO_MUTEX_IMPL_LOCK not defined. Check cairo-mutex-impl-private.h." -#endif -#ifndef CAIRO_MUTEX_IMPL_UNLOCK -# error "CAIRO_MUTEX_IMPL_UNLOCK not defined. Check cairo-mutex-impl-private.h." -#endif -#ifndef CAIRO_MUTEX_IMPL_NIL_INITIALIZER -# error "CAIRO_MUTEX_IMPL_NIL_INITIALIZER not defined. Check cairo-mutex-impl-private.h." -#endif -#ifndef CAIRO_RECURSIVE_MUTEX_IMPL_INIT -# error "CAIRO_RECURSIVE_MUTEX_IMPL_INIT not defined. Check cairo-mutex-impl-private.h." -#endif - - -/* make sure implementations don't fool us: we decide these ourself */ -#undef _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER -#undef _CAIRO_MUTEX_IMPL_USE_STATIC_FINALIZER - - -#ifdef CAIRO_MUTEX_IMPL_INIT - -/* If %CAIRO_MUTEX_IMPL_INIT is defined, we may need to initialize all - * static mutex'es. */ -# ifndef CAIRO_MUTEX_IMPL_INITIALIZE -# define CAIRO_MUTEX_IMPL_INITIALIZE() do { \ - if (!_cairo_mutex_initialized) \ - _cairo_mutex_initialize (); \ - } while(0) - -/* and make sure we implement the above */ -# define _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER 1 -# endif /* CAIRO_MUTEX_IMPL_INITIALIZE */ - -#else /* no CAIRO_MUTEX_IMPL_INIT */ - -/* Otherwise we probably don't need to initialize static mutex'es, */ -# ifndef CAIRO_MUTEX_IMPL_INITIALIZE -# define CAIRO_MUTEX_IMPL_INITIALIZE() CAIRO_MUTEX_IMPL_NOOP -# endif /* CAIRO_MUTEX_IMPL_INITIALIZE */ - -/* and dynamic ones can be initialized using the static initializer. */ -# define CAIRO_MUTEX_IMPL_INIT(mutex) do { \ - cairo_mutex_t _tmp_mutex = CAIRO_MUTEX_IMPL_NIL_INITIALIZER; \ - memcpy (&(mutex), &_tmp_mutex, sizeof (_tmp_mutex)); \ - } while (0) - -#endif /* CAIRO_MUTEX_IMPL_INIT */ - -#ifdef CAIRO_MUTEX_IMPL_FINI - -/* If %CAIRO_MUTEX_IMPL_FINI is defined, we may need to finalize all - * static mutex'es. */ -# ifndef CAIRO_MUTEX_IMPL_FINALIZE -# define CAIRO_MUTEX_IMPL_FINALIZE() do { \ - if (_cairo_mutex_initialized) \ - _cairo_mutex_finalize (); \ - } while(0) - -/* and make sure we implement the above */ -# define _CAIRO_MUTEX_IMPL_USE_STATIC_FINALIZER 1 -# endif /* CAIRO_MUTEX_IMPL_FINALIZE */ - -#else /* no CAIRO_MUTEX_IMPL_FINI */ - -/* Otherwise we probably don't need to finalize static mutex'es, */ -# ifndef CAIRO_MUTEX_IMPL_FINALIZE -# define CAIRO_MUTEX_IMPL_FINALIZE() CAIRO_MUTEX_IMPL_NOOP -# endif /* CAIRO_MUTEX_IMPL_FINALIZE */ - -/* neither do the dynamic ones. */ -# define CAIRO_MUTEX_IMPL_FINI(mutex) CAIRO_MUTEX_IMPL_NOOP1(mutex) - -#endif /* CAIRO_MUTEX_IMPL_FINI */ - - -#ifndef _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER -#define _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER 0 -#endif -#ifndef _CAIRO_MUTEX_IMPL_USE_STATIC_FINALIZER -#define _CAIRO_MUTEX_IMPL_USE_STATIC_FINALIZER 0 -#endif - - -/* Make sure everything we want is defined */ -#ifndef CAIRO_MUTEX_IMPL_INITIALIZE -# error "CAIRO_MUTEX_IMPL_INITIALIZE not defined" -#endif -#ifndef CAIRO_MUTEX_IMPL_FINALIZE -# error "CAIRO_MUTEX_IMPL_FINALIZE not defined" -#endif -#ifndef CAIRO_MUTEX_IMPL_LOCK -# error "CAIRO_MUTEX_IMPL_LOCK not defined" -#endif -#ifndef CAIRO_MUTEX_IMPL_UNLOCK -# error "CAIRO_MUTEX_IMPL_UNLOCK not defined" -#endif -#ifndef CAIRO_MUTEX_IMPL_INIT -# error "CAIRO_MUTEX_IMPL_INIT not defined" -#endif -#ifndef CAIRO_MUTEX_IMPL_FINI -# error "CAIRO_MUTEX_IMPL_FINI not defined" -#endif -#ifndef CAIRO_MUTEX_IMPL_NIL_INITIALIZER -# error "CAIRO_MUTEX_IMPL_NIL_INITIALIZER not defined" -#endif - - -/* Public interface. */ - -/* By default it simply uses the implementation provided. - * But we can provide for debugging features by overriding them */ - -#ifndef CAIRO_MUTEX_DEBUG -typedef cairo_mutex_impl_t cairo_mutex_t; -typedef cairo_recursive_mutex_impl_t cairo_recursive_mutex_t; -#else -# define cairo_mutex_t cairo_mutex_impl_t -#endif - -#define CAIRO_MUTEX_INITIALIZE CAIRO_MUTEX_IMPL_INITIALIZE -#define CAIRO_MUTEX_FINALIZE CAIRO_MUTEX_IMPL_FINALIZE -#define CAIRO_MUTEX_LOCK CAIRO_MUTEX_IMPL_LOCK -#define CAIRO_MUTEX_UNLOCK CAIRO_MUTEX_IMPL_UNLOCK -#define CAIRO_MUTEX_INIT CAIRO_MUTEX_IMPL_INIT -#define CAIRO_MUTEX_FINI CAIRO_MUTEX_IMPL_FINI -#define CAIRO_MUTEX_NIL_INITIALIZER CAIRO_MUTEX_IMPL_NIL_INITIALIZER - -#define CAIRO_RECURSIVE_MUTEX_INIT CAIRO_RECURSIVE_MUTEX_IMPL_INIT -#define CAIRO_RECURSIVE_MUTEX_NIL_INITIALIZER CAIRO_RECURSIVE_MUTEX_IMPL_NIL_INITIALIZER - -#ifndef CAIRO_MUTEX_IS_LOCKED -# define CAIRO_MUTEX_IS_LOCKED(name) 1 -#endif -#ifndef CAIRO_MUTEX_IS_UNLOCKED -# define CAIRO_MUTEX_IS_UNLOCKED(name) 1 -#endif - - -/* Debugging support */ - -#ifdef CAIRO_MUTEX_DEBUG - -/* TODO add mutex debugging facilities here (eg deadlock detection) */ - -#endif /* CAIRO_MUTEX_DEBUG */ - -#endif diff --git a/source/libs/cairo/cairo-src/src/cairo-mutex.c b/source/libs/cairo/cairo-src/src/cairo-mutex.c deleted file mode 100644 index 0a31dced3e1b9861e1ecdbc5f91312f2c319d8c2..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-mutex.c +++ /dev/null @@ -1,82 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2007 Mathias Hasselmann - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * Contributor(s): - * Mathias Hasselmann <mathias.hasselmann@gmx.de> - */ - -#include "cairoint.h" - -#include "cairo-mutex-private.h" - -#define CAIRO_MUTEX_DECLARE(mutex) cairo_mutex_t mutex = CAIRO_MUTEX_NIL_INITIALIZER; -#include "cairo-mutex-list-private.h" -#undef CAIRO_MUTEX_DECLARE - -#if _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER || _CAIRO_MUTEX_IMPL_USE_STATIC_FINALIZER - -# if _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER -# define _CAIRO_MUTEX_IMPL_INITIALIZED_DEFAULT_VALUE FALSE -# else -# define _CAIRO_MUTEX_IMPL_INITIALIZED_DEFAULT_VALUE TRUE -# endif - -cairo_bool_t _cairo_mutex_initialized = _CAIRO_MUTEX_IMPL_INITIALIZED_DEFAULT_VALUE; - -# undef _CAIRO_MUTEX_IMPL_INITIALIZED_DEFAULT_VALUE - -#endif - -#if _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER -void _cairo_mutex_initialize (void) -{ - if (_cairo_mutex_initialized) - return; - - _cairo_mutex_initialized = TRUE; - -#define CAIRO_MUTEX_DECLARE(mutex) CAIRO_MUTEX_INIT (mutex); -#include "cairo-mutex-list-private.h" -#undef CAIRO_MUTEX_DECLARE -} -#endif - -#if _CAIRO_MUTEX_IMPL_USE_STATIC_FINALIZER -void _cairo_mutex_finalize (void) -{ - if (!_cairo_mutex_initialized) - return; - - _cairo_mutex_initialized = FALSE; - -#define CAIRO_MUTEX_DECLARE(mutex) CAIRO_MUTEX_FINI (mutex); -#include "cairo-mutex-list-private.h" -#undef CAIRO_MUTEX_DECLARE -} -#endif diff --git a/source/libs/cairo/cairo-src/src/cairo-no-compositor.c b/source/libs/cairo/cairo-src/src/cairo-no-compositor.c deleted file mode 100644 index 1602a12f63a17f3d0f1471fcb0bec039b09ee59c..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-no-compositor.c +++ /dev/null @@ -1,107 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Joonas Pihlaja <jpihlaja@cc.helsinki.fi> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-compositor-private.h" - -static cairo_int_status_t -_cairo_no_compositor_paint (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents) -{ - ASSERT_NOT_REACHED; - return CAIRO_INT_STATUS_NOTHING_TO_DO; -} - -static cairo_int_status_t -_cairo_no_compositor_mask (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *extents) -{ - ASSERT_NOT_REACHED; - return CAIRO_INT_STATUS_NOTHING_TO_DO; -} - -static cairo_int_status_t -_cairo_no_compositor_stroke (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias) -{ - ASSERT_NOT_REACHED; - return CAIRO_INT_STATUS_NOTHING_TO_DO; -} - -static cairo_int_status_t -_cairo_no_compositor_fill (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - ASSERT_NOT_REACHED; - return CAIRO_INT_STATUS_NOTHING_TO_DO; -} - -static cairo_int_status_t -_cairo_no_compositor_glyphs (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_bool_t overlap) -{ - ASSERT_NOT_REACHED; - return CAIRO_INT_STATUS_NOTHING_TO_DO; -} - -const cairo_compositor_t __cairo_no_compositor = { - NULL, - _cairo_no_compositor_paint, - _cairo_no_compositor_mask, - _cairo_no_compositor_stroke, - _cairo_no_compositor_fill, - _cairo_no_compositor_glyphs, -}; diff --git a/source/libs/cairo/cairo-src/src/cairo-observer.c b/source/libs/cairo/cairo-src/src/cairo-observer.c deleted file mode 100644 index 36d6b93bd6343d7d56968a1a32a60a28e3b63dc6..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-observer.c +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2010 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Intel Corporation - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-list-inline.h" - -void -_cairo_observers_notify (cairo_list_t *observers, void *arg) -{ - cairo_observer_t *obs, *next; - - cairo_list_foreach_entry_safe (obs, next, - cairo_observer_t, - observers, link) - { - obs->callback (obs, arg); - } -} diff --git a/source/libs/cairo/cairo-src/src/cairo-os2-private.h b/source/libs/cairo/cairo-src/src/cairo-os2-private.h deleted file mode 100644 index 829dd3c8d41fece0f75e7cebcddfeec0164b4dfd..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-os2-private.h +++ /dev/null @@ -1,67 +0,0 @@ -/* vim: set sw=4 sts=4 et cin: */ -/* cairo - a vector graphics library with display and print output - * - * Copyright (c) 2005-2006 netlabs.org - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 - * Doodle <doodle@scenergy.dfmk.hu> - * - * Contributor(s): - * Peter Weilbacher <mozilla@Weilbacher.org> - */ - -#ifndef CAIRO_OS2_PRIVATE_H -#define CAIRO_OS2_PRIVATE_H - -#include "cairo-os2.h" -#include "cairoint.h" - -typedef struct _cairo_os2_surface -{ - cairo_surface_t base; - - /* Mutex semaphore to protect private fields from concurrent access */ - HMTX hmtx_use_private_fields; - /* Private fields: */ - HPS hps_client_window; - HWND hwnd_client_window; - BITMAPINFO2 bitmap_info; - unsigned char *pixels; - cairo_image_surface_t *image_surface; - int pixel_array_lend_count; - HEV hev_pixel_array_came_back; - - RECTL rcl_dirty_area; - cairo_bool_t dirty_area_present; - - /* General flags: */ - cairo_bool_t blit_as_changes; - cairo_bool_t use_24bpp; -} cairo_os2_surface_t; - -#endif /* CAIRO_OS2_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-os2-surface.c b/source/libs/cairo/cairo-src/src/cairo-os2-surface.c deleted file mode 100644 index 1ab50f9779873e1022229c2c421af8cd1dfd5816..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-os2-surface.c +++ /dev/null @@ -1,1415 +0,0 @@ -/* vim: set sw=4 sts=4 et cin: */ -/* cairo - a vector graphics library with display and print output - * - * Copyright (c) 2005-2006 netlabs.org - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 - * Doodle <doodle@scenergy.dfmk.hu> - * - * Contributor(s): - * Peter Weilbacher <mozilla@Weilbacher.org> - * Rich Walsh <dragtext@e-vertise.com> - */ - -#include "cairoint.h" - -#include "cairo-os2-private.h" -#include "cairo-default-context-private.h" -#include "cairo-error-private.h" -#include "cairo-surface-fallback-private.h" -#include "cairo-image-surface-private.h" - -#if CAIRO_HAS_FC_FONT -#include <fontconfig/fontconfig.h> -#endif - -#include <float.h> -#ifdef BUILD_CAIRO_DLL -# include "cairo-os2.h" -# ifndef __WATCOMC__ -# include <emx/startup.h> -# endif -#endif - -/* - * Here comes the extra API for the OS/2 platform. Currently it consists - * of two extra functions, the cairo_os2_init() and the - * cairo_os2_fini(). Both of them are called automatically if - * Cairo is compiled to be a DLL file, but you have to call them before - * using the Cairo API if you link to Cairo statically! - * - * You'll also find the code in here which deals with DLL initialization - * and termination, if the code is built to be a DLL. - * (if BUILD_CAIRO_DLL is defined) - */ - -/* Initialization counter: */ -static int cairo_os2_initialization_count = 0; - -static inline void -DisableFPUException (void) -{ - unsigned short usCW; - - /* Some OS/2 PM API calls modify the FPU Control Word, - * but forget to restore it. - * - * This can result in XCPT_FLOAT_INVALID_OPCODE exceptions, - * so to be sure, we disable Invalid Opcode FPU exception - * before using FPU stuffs. - */ - usCW = _control87 (0, 0); - usCW = usCW | EM_INVALID | 0x80; - _control87 (usCW, MCW_EM | 0x80); -} - -/** - * cairo_os2_init: - * - * Initializes the Cairo library. This function is automatically called if - * Cairo was compiled to be a DLL (however it's not a problem if it's called - * multiple times). But if you link to Cairo statically, you have to call it - * once to set up Cairo's internal structures and mutexes. - * - * Since: 1.4 - **/ -cairo_public void -cairo_os2_init (void) -{ - /* This may initialize some stuffs, like create mutex semaphores etc.. */ - - cairo_os2_initialization_count++; - if (cairo_os2_initialization_count > 1) return; - - DisableFPUException (); - -#if CAIRO_HAS_FC_FONT - /* Initialize FontConfig */ - FcInit (); -#endif - - CAIRO_MUTEX_INITIALIZE (); -} - -/** - * cairo_os2_fini: - * - * Uninitializes the Cairo library. This function is automatically called if - * Cairo was compiled to be a DLL (however it's not a problem if it's called - * multiple times). But if you link to Cairo statically, you have to call it - * once to shut down Cairo, to let it free all the resources it has allocated. - * - * Since: 1.4 - **/ -cairo_public void -cairo_os2_fini (void) -{ - /* This has to uninitialize some stuffs, like destroy mutex semaphores etc.. */ - - if (cairo_os2_initialization_count <= 0) return; - cairo_os2_initialization_count--; - if (cairo_os2_initialization_count > 0) return; - - DisableFPUException (); - - cairo_debug_reset_static_data (); - -#if CAIRO_HAS_FC_FONT -# if HAVE_FCFINI - /* Uninitialize FontConfig */ - FcFini (); -# endif -#endif - -#ifdef __WATCOMC__ - /* It can happen that the libraries we use have memory leaks, - * so there are still memory chunks allocated at this point. - * In these cases, Watcom might still have a bigger memory chunk, - * called "the heap" allocated from the OS. - * As we want to minimize the memory we lose from the point of - * view of the OS, we call this function to shrink that heap - * as much as possible. - */ - _heapshrink (); -#else - /* GCC has a heapmin function that approximately corresponds to - * what the Watcom function does - */ - _heapmin (); -#endif -} - -/* - * This function calls the allocation function depending on which - * method was compiled into the library: it can be native allocation - * (DosAllocMem/DosFreeMem) or C-Library based allocation (malloc/free). - * Actually, for pixel buffers that we use this function for, cairo - * uses _cairo_malloc_abc, so we use that here, too. And use the - * change to check the size argument - */ -void *_buffer_alloc (size_t a, size_t b, const unsigned int size) -{ - size_t nbytes; - void *buffer = NULL; - - if (!a || !b || !size || - a >= INT32_MAX / b || a*b >= INT32_MAX / size) { - return NULL; - } - nbytes = a * b * size; - -#ifdef OS2_USE_PLATFORM_ALLOC - /* Using OBJ_ANY on a machine that isn't configured for hi-mem - * will cause ERROR_INVALID_PARAMETER. If this occurs, or this - * build doesn't have hi-mem enabled, fall back to using lo-mem. - */ -#ifdef OS2_HIGH_MEMORY - if (!DosAllocMem (&buffer, nbytes, - OBJ_ANY | PAG_READ | PAG_WRITE | PAG_COMMIT)) - return buffer; -#endif - if (DosAllocMem (&buffer, nbytes, - PAG_READ | PAG_WRITE | PAG_COMMIT)) - return NULL; -#else - /* Clear the malloc'd buffer the way DosAllocMem() does. */ - buffer = malloc (nbytes); - if (buffer) { - memset (buffer, 0, nbytes); - } -#endif - return buffer; -} - -/* - * This function selects the free function depending on which - * allocation method was compiled into the library - */ -void _buffer_free (void *buffer) -{ -#ifdef OS2_USE_PLATFORM_ALLOC - DosFreeMem (buffer); -#else - free (buffer); -#endif -} - -/* XXX - * The cairo_os2_ini() and cairo_os2_fini() functions should be removed and - * the LibMain code moved to cairo-system.c. It should also call - * cairo_debug_reset_static_data() instead of duplicating its logic... - */ - -#ifdef BUILD_CAIRO_DLL -/* The main DLL entry for DLL initialization and uninitialization */ -/* Only include this code if we're about to build a DLL. */ - -#ifdef __WATCOMC__ -unsigned _System -LibMain (unsigned hmod, - unsigned termination) -#else -unsigned long _System -_DLL_InitTerm (unsigned long hModule, - unsigned long termination) -#endif -{ - if (termination) { - /* Unloading the DLL */ - cairo_os2_fini (); - -#ifndef __WATCOMC__ - /* Uninitialize RTL of GCC */ - __ctordtorTerm (); - _CRT_term (); -#endif - return 1; - } else { - /* Loading the DLL */ -#ifndef __WATCOMC__ - /* Initialize RTL of GCC */ - if (_CRT_init () != 0) - return 0; - __ctordtorInit (); -#endif - - cairo_os2_init (); - return 1; - } -} - -#endif /* BUILD_CAIRO_DLL */ - -/* - * The following part of the source file contains the code which might - * be called the "core" of the OS/2 backend support. This contains the - * OS/2 surface support functions and structures. - */ - -/* Forward declaration */ -static const cairo_surface_backend_t cairo_os2_surface_backend; - -/* Unpublished API: - * GpiEnableYInversion = PMGPI.723 - * GpiQueryYInversion = PMGPI.726 - * BOOL APIENTRY GpiEnableYInversion (HPS hps, LONG lHeight); - * LONG APIENTRY GpiQueryYInversion (HPS hps); - */ -BOOL APIENTRY GpiEnableYInversion (HPS hps, LONG lHeight); -LONG APIENTRY GpiQueryYInversion (HPS hps); - -#ifdef __WATCOMC__ -/* Function declaration for GpiDrawBits () (missing from OpenWatcom headers) */ -LONG APIENTRY GpiDrawBits (HPS hps, - PVOID pBits, - PBITMAPINFO2 pbmiInfoTable, - LONG lCount, - PPOINTL aptlPoints, - LONG lRop, - ULONG flOptions); -#endif - -static void -_cairo_os2_surface_blit_pixels (cairo_os2_surface_t *surface, - HPS hps_begin_paint, - PRECTL prcl_begin_paint_rect) -{ - POINTL aptlPoints[4]; - LONG lOldYInversion; - LONG rc = GPI_OK; - - /* Check the limits (may not be necessary) */ - if (prcl_begin_paint_rect->xLeft < 0) - prcl_begin_paint_rect->xLeft = 0; - if (prcl_begin_paint_rect->yBottom < 0) - prcl_begin_paint_rect->yBottom = 0; - if (prcl_begin_paint_rect->xRight > (LONG) surface->bitmap_info.cx) - prcl_begin_paint_rect->xRight = (LONG) surface->bitmap_info.cx; - if (prcl_begin_paint_rect->yTop > (LONG) surface->bitmap_info.cy) - prcl_begin_paint_rect->yTop = (LONG) surface->bitmap_info.cy; - - /* Exit if the rectangle is empty */ - if (prcl_begin_paint_rect->xLeft >= prcl_begin_paint_rect->xRight || - prcl_begin_paint_rect->yBottom >= prcl_begin_paint_rect->yTop) - return; - - /* Set the Target & Source coordinates */ - *((PRECTL)&aptlPoints[0]) = *prcl_begin_paint_rect; - *((PRECTL)&aptlPoints[2]) = *prcl_begin_paint_rect; - - /* Make the Target coordinates non-inclusive */ - aptlPoints[1].x -= 1; - aptlPoints[1].y -= 1; - - /* Enable Y Inversion for the HPS, so GpiDrawBits will - * work with upside-top image, not with upside-down image! - */ - lOldYInversion = GpiQueryYInversion (hps_begin_paint); - GpiEnableYInversion (hps_begin_paint, surface->bitmap_info.cy-1); - - /* Debug code to draw rectangle limits */ -#if 0 - { - int x, y; - unsigned char *pixels; - - pixels = surface->pixels; - for (x = 0; x < surface->bitmap_info.cx; x++) { - for (y = 0; y < surface->bitmap_info.cy; y++) { - if ((x == 0) || - (y == 0) || - (x == y) || - (x >= surface->bitmap_info.cx-1) || - (y >= surface->bitmap_info.cy-1)) - { - pixels[y*surface->bitmap_info.cx*4+x*4] = 255; - } - } - } - } -#endif - if (!surface->use_24bpp) { - rc = GpiDrawBits (hps_begin_paint, - surface->pixels, - &(surface->bitmap_info), - 4, - aptlPoints, - ROP_SRCCOPY, - BBO_IGNORE); - if (rc != GPI_OK) - surface->use_24bpp = TRUE; - } - - if (surface->use_24bpp) { - /* If GpiDrawBits () failed then this is most likely because the - * display driver could not handle a 32bit bitmap. So we need to - * - create a buffer that only contains 3 bytes per pixel - * - change the bitmap info header to contain 24bit - * - pass the new buffer to GpiDrawBits () again - * - clean up the new buffer - */ - BITMAPINFO2 bmpinfo; - unsigned char *pchPixBuf; - unsigned char *pchTarget; - ULONG *pulSource; - ULONG ulX; - ULONG ulY; - ULONG ulPad; - - /* Set up the bitmap header, but this time for 24bit depth. */ - bmpinfo = surface->bitmap_info; - bmpinfo.cBitCount = 24; - - /* The start of each row has to be DWORD aligned. Calculate the - * of number aligned bytes per row, the total size of the bitmap, - * and the number of padding bytes at the end of each row. - */ - ulX = (((bmpinfo.cx * bmpinfo.cBitCount) + 31) / 32) * 4; - bmpinfo.cbImage = ulX * bmpinfo.cy; - ulPad = ulX - bmpinfo.cx * 3; - - /* Allocate temporary pixel buffer. If the rows don't need - * padding, it has to be 1 byte larger than the size of the - * bitmap or else the high-order byte from the last source - * row will end up in unallocated memory. - */ - pchPixBuf = (unsigned char *)_buffer_alloc (1, 1, - bmpinfo.cbImage + (ulPad ? 0 : 1)); - - if (pchPixBuf) { - /* Copy 4 bytes from the source but advance the target ptr only - * 3 bytes, so the high-order alpha byte will be overwritten by - * the next copy. At the end of each row, skip over the padding. - */ - pchTarget = pchPixBuf; - pulSource = (ULONG*)surface->pixels; - for (ulY = bmpinfo.cy; ulY; ulY--) { - for (ulX = bmpinfo.cx; ulX; ulX--) { - *((ULONG*)pchTarget) = *pulSource++; - pchTarget += 3; - } - pchTarget += ulPad; - } - - rc = GpiDrawBits (hps_begin_paint, - pchPixBuf, - &bmpinfo, - 4, - aptlPoints, - ROP_SRCCOPY, - BBO_IGNORE); - if (rc != GPI_OK) - surface->use_24bpp = FALSE; - - _buffer_free (pchPixBuf); - } - } - - /* Restore Y inversion */ - GpiEnableYInversion (hps_begin_paint, lOldYInversion); -} - -static void -_cairo_os2_surface_get_pixels_from_screen (cairo_os2_surface_t *surface, - HPS hps_begin_paint, - PRECTL prcl_begin_paint_rect) -{ - HPS hps; - HDC hdc; - SIZEL sizlTemp; - HBITMAP hbmpTemp; - BITMAPINFO2 bmi2Temp; - POINTL aptlPoints[4]; - int y; - unsigned char *pchTemp; - - /* To copy pixels from screen to our buffer, we do the following steps: - * - * - Blit pixels from screen to a HBITMAP: - * -- Create Memory Device Context - * -- Create a PS into it - * -- Create a HBITMAP - * -- Select HBITMAP into memory PS - * -- Blit dirty pixels from screen to HBITMAP - * - Copy HBITMAP lines (pixels) into our buffer - * - Free resources - */ - - /* Create a memory device context */ - hdc = DevOpenDC (0, OD_MEMORY,"*",0L, NULL, NULLHANDLE); - if (!hdc) { - return; - } - - /* Create a memory PS */ - sizlTemp.cx = prcl_begin_paint_rect->xRight - prcl_begin_paint_rect->xLeft; - sizlTemp.cy = prcl_begin_paint_rect->yTop - prcl_begin_paint_rect->yBottom; - hps = GpiCreatePS (0, - hdc, - &sizlTemp, - PU_PELS | GPIT_NORMAL | GPIA_ASSOC); - if (!hps) { - DevCloseDC (hdc); - return; - } - - /* Create an uninitialized bitmap. */ - /* Prepare BITMAPINFO2 structure for our buffer */ - memset (&bmi2Temp, 0, sizeof (bmi2Temp)); - bmi2Temp.cbFix = sizeof (BITMAPINFOHEADER2); - bmi2Temp.cx = sizlTemp.cx; - bmi2Temp.cy = sizlTemp.cy; - bmi2Temp.cPlanes = 1; - bmi2Temp.cBitCount = 32; - - hbmpTemp = GpiCreateBitmap (hps, - (PBITMAPINFOHEADER2) &bmi2Temp, - 0, - NULL, - NULL); - - if (!hbmpTemp) { - GpiDestroyPS (hps); - DevCloseDC (hdc); - return; - } - - /* Select the bitmap into the memory device context. */ - GpiSetBitmap (hps, hbmpTemp); - - /* Target coordinates (Noninclusive) */ - aptlPoints[0].x = 0; - aptlPoints[0].y = 0; - - aptlPoints[1].x = sizlTemp.cx; - aptlPoints[1].y = sizlTemp.cy; - - /* Source coordinates (Inclusive) */ - aptlPoints[2].x = prcl_begin_paint_rect->xLeft; - aptlPoints[2].y = surface->bitmap_info.cy - prcl_begin_paint_rect->yBottom; - - aptlPoints[3].x = prcl_begin_paint_rect->xRight; - aptlPoints[3].y = surface->bitmap_info.cy - prcl_begin_paint_rect->yTop; - - /* Blit pixels from screen to bitmap */ - GpiBitBlt (hps, - hps_begin_paint, - 4, - aptlPoints, - ROP_SRCCOPY, - BBO_IGNORE); - - /* Now we have to extract the pixels from the bitmap. */ - pchTemp = - surface->pixels + - (prcl_begin_paint_rect->yBottom)*surface->bitmap_info.cx*4 + - prcl_begin_paint_rect->xLeft*4; - for (y = 0; y < sizlTemp.cy; y++) { - /* Get one line of pixels */ - GpiQueryBitmapBits (hps, - sizlTemp.cy - y - 1, /* lScanStart */ - 1, /* lScans */ - (PBYTE)pchTemp, - &bmi2Temp); - - /* Go for next line */ - pchTemp += surface->bitmap_info.cx*4; - } - - /* Clean up resources */ - GpiSetBitmap (hps, (HBITMAP) NULL); - GpiDeleteBitmap (hbmpTemp); - GpiDestroyPS (hps); - DevCloseDC (hdc); -} - -static cairo_status_t -_cairo_os2_surface_acquire_source_image (void *abstract_surface, - cairo_image_surface_t **image_out, - void **image_extra) -{ - cairo_os2_surface_t *surface = (cairo_os2_surface_t *) abstract_surface; - - DosRequestMutexSem (surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT); - - /* Increase lend counter */ - surface->pixel_array_lend_count++; - - *image_out = surface->image_surface; - *image_extra = NULL; - - DosReleaseMutexSem (surface->hmtx_use_private_fields); - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_os2_surface_release_source_image (void *abstract_surface, - cairo_image_surface_t *image, - void *image_extra) -{ - cairo_os2_surface_t *surface = (cairo_os2_surface_t *) abstract_surface; - - /* Decrease Lend counter! */ - DosRequestMutexSem (surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT); - - if (surface->pixel_array_lend_count > 0) - surface->pixel_array_lend_count--; - DosPostEventSem (surface->hev_pixel_array_came_back); - - DosReleaseMutexSem (surface->hmtx_use_private_fields); -} - -static cairo_image_surface_t * -_cairo_os2_surface_map_to_image (void *abstract_surface, - const cairo_rectangle_int_t *extents) -{ - cairo_os2_surface_t *surface = (cairo_os2_surface_t *) abstract_surface; - - DosRequestMutexSem (surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT); - /* Increase lend counter */ - surface->pixel_array_lend_count++; - DosReleaseMutexSem (local_os2_surface->hmtx_use_private_fields); - - /* XXX: BROKEN! */ - *image_out = _cairo_surface_create_for_rectangle_int (surface->image_surface, - extents); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_os2_surface_unmap_image (void *abstract_surface, - cairo_image_surface_t *image) -{ - cairo_os2_surface_t *surface = (cairo_os2_surface_t *) abstract_surface; - - /* So, we got back the image, and if all goes well, then - * something has been changed inside the interest_rect. - * So, we blit it to the screen! - */ - if (surface->blit_as_changes) { - RECTL rclToBlit; - - /* Get mutex, we'll work with the pixel array! */ - if (DosRequestMutexSem (surface->hmtx_use_private_fields, - SEM_INDEFINITE_WAIT) != NO_ERROR) - { - /* Could not get mutex! */ - return; - } - - rclToBlit.xLeft = image->base.device_transform_inverse.x0; - rclToBlit.xRight = rclToBlit.xLeft + image->width; /* Noninclusive */ - rclToBlit.yTop = image->base.device_transform_inverse.y0; - rclToBlit.yBottom = rclToBlit.yTop + image->height; /* Noninclusive */ - - if (surface->hwnd_client_window) { - /* We know the HWND, so let's invalidate the window region, - * so the application will redraw itself, using the - * cairo_os2_surface_refresh_window () API from its own PM thread. - * - * This is the safe method, which should be preferred every time. - */ - rclToBlit.yTop = surface->bitmap_info.cy - rclToBlit.yTop; - rclToBlit.yBottom = surface->bitmap_info.cy - rclToBlit.yTop; - WinInvalidateRect (surface->hwnd_client_window, - &rclToBlit, - FALSE); - } else { - /* We don't know the HWND, so try to blit the pixels from here! - * Please note that it can be problematic if this is not the PM thread! - * - * It can cause internal PM stuffs to be screwed up, for some reason. - * Please always tell the HWND to the surface using the - * cairo_os2_surface_set_hwnd () API, and call cairo_os2_surface_refresh_window () - * from your WM_PAINT, if it's possible! - */ - _cairo_os2_surface_blit_pixels (surface, - surface->hps_client_window, - &rclToBlit); - } - - DosReleaseMutexSem (surface->hmtx_use_private_fields); - } - /* Also decrease Lend counter! */ - DosRequestMutexSem (surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT); - - if (surface->pixel_array_lend_count > 0) - surface->pixel_array_lend_count--; - DosPostEventSem (surface->hev_pixel_array_came_back); - - DosReleaseMutexSem (surface->hmtx_use_private_fields); -} - -static cairo_bool_t -_cairo_os2_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *rectangle) -{ - cairo_os2_surface_t *surface = (cairo_os2_surface_t *) abstract_surface; - - rectangle->x = 0; - rectangle->y = 0; - rectangle->width = surface->bitmap_info.cx; - rectangle->height = surface->bitmap_info.cy; - - return TRUE; -} - -/** - * cairo_os2_surface_create: - * @hps_client_window: the presentation handle to bind the surface to - * @width: the width of the surface - * @height: the height of the surface - * - * Create a Cairo surface which is bound to a given presentation space (HPS). - * The caller retains ownership of the HPS and must dispose of it after the - * the surface has been destroyed. The surface will be created to have the - * given size. By default every change to the surface will be made visible - * immediately by blitting it into the window. This can be changed with - * cairo_os2_surface_set_manual_window_refresh(). - * Note that the surface will contain garbage when created, so the pixels - * have to be initialized by hand first. You can use the Cairo functions to - * fill it with black, or use cairo_surface_mark_dirty() to fill the surface - * with pixels from the window/HPS. - * - * Return value: the newly created surface - * - * Since: 1.4 - **/ -cairo_surface_t * -cairo_os2_surface_create (HPS hps_client_window, - int width, - int height) -{ - cairo_os2_surface_t *local_os2_surface = 0; - cairo_status_t status; - int rc; - - /* Check the size of the window */ - if ((width <= 0) || (height <= 0)) { - status = _cairo_error (CAIRO_STATUS_INVALID_SIZE); - goto error_exit; - } - - /* Allocate an OS/2 surface structure. */ - local_os2_surface = (cairo_os2_surface_t *) malloc (sizeof (cairo_os2_surface_t)); - if (!local_os2_surface) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto error_exit; - } - - memset(local_os2_surface, 0, sizeof(cairo_os2_surface_t)); - - /* Allocate resources: mutex & event semaphores and the pixel buffer */ - if (DosCreateMutexSem (NULL, - &(local_os2_surface->hmtx_use_private_fields), - 0, - FALSE)) - { - status = _cairo_error (CAIRO_STATUS_DEVICE_ERROR); - goto error_exit; - } - - if (DosCreateEventSem (NULL, - &(local_os2_surface->hev_pixel_array_came_back), - 0, - FALSE)) - { - status = _cairo_error (CAIRO_STATUS_DEVICE_ERROR); - goto error_exit; - } - - local_os2_surface->pixels = (unsigned char *) _buffer_alloc (height, width, 4); - if (!local_os2_surface->pixels) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto error_exit; - } - - /* Create image surface from pixel array */ - local_os2_surface->image_surface = (cairo_image_surface_t *) - cairo_image_surface_create_for_data (local_os2_surface->pixels, - CAIRO_FORMAT_ARGB32, - width, /* Width */ - height, /* Height */ - width * 4); /* Rowstride */ - status = local_os2_surface->image_surface->base.status; - if (status) - goto error_exit; - - /* Set values for OS/2-specific data that aren't zero/NULL/FALSE. - * Note: hps_client_window may be null if this was called by - * cairo_os2_surface_create_for_window(). - */ - local_os2_surface->hps_client_window = hps_client_window; - local_os2_surface->blit_as_changes = TRUE; - - /* Prepare BITMAPINFO2 structure for our buffer */ - local_os2_surface->bitmap_info.cbFix = sizeof (BITMAPINFOHEADER2); - local_os2_surface->bitmap_info.cx = width; - local_os2_surface->bitmap_info.cy = height; - local_os2_surface->bitmap_info.cPlanes = 1; - local_os2_surface->bitmap_info.cBitCount = 32; - - /* Initialize base surface */ - _cairo_surface_init (&local_os2_surface->base, - &cairo_os2_surface_backend, - NULL, /* device */ - _cairo_content_from_format (CAIRO_FORMAT_ARGB32)); - - /* Successful exit */ - return (cairo_surface_t *)local_os2_surface; - - error_exit: - - /* This point will only be reached if an error occurred */ - - if (local_os2_surface) { - if (local_os2_surface->pixels) - _buffer_free (local_os2_surface->pixels); - if (local_os2_surface->hev_pixel_array_came_back) - DosCloseEventSem (local_os2_surface->hev_pixel_array_came_back); - if (local_os2_surface->hmtx_use_private_fields) - DosCloseMutexSem (local_os2_surface->hmtx_use_private_fields); - free (local_os2_surface); - } - - return _cairo_surface_create_in_error (status); -} - -/** - * cairo_os2_surface_create_for_window: - * @hwnd_client_window: the window handle to bind the surface to - * @width: the width of the surface - * @height: the height of the surface - * - * Create a Cairo surface which is bound to a given window; the caller retains - * ownership of the window. This is a convenience function for use with - * windows that will only be updated when cairo_os2_surface_refresh_window() - * is called (usually in response to a WM_PAINT message). It avoids the need - * to create a persistent HPS for every window and assumes that one will be - * supplied by the caller when a cairo function needs one. If it isn't, an - * HPS will be created on-the-fly and released before the function which needs - * it returns. - * - * Return value: the newly created surface - * - * Since: 1.10 - **/ -cairo_surface_t * -cairo_os2_surface_create_for_window (HWND hwnd_client_window, - int width, - int height) -{ - cairo_os2_surface_t *local_os2_surface; - - /* A window handle must be provided. */ - if (!hwnd_client_window) { - return _cairo_surface_create_in_error ( - _cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - /* Create the surface. */ - local_os2_surface = (cairo_os2_surface_t *) - cairo_os2_surface_create (0, width, height); - - /* If successful, save the hwnd & turn off automatic repainting. */ - if (!local_os2_surface->image_surface->base.status) { - local_os2_surface->hwnd_client_window = hwnd_client_window; - local_os2_surface->blit_as_changes = FALSE; - } - - return (cairo_surface_t *)local_os2_surface; -} - -/** - * cairo_os2_surface_set_size: - * @surface: the cairo surface to resize - * @new_width: the new width of the surface - * @new_height: the new height of the surface - * @timeout: timeout value in milliseconds - * - * When the client window is resized, call this API to set the new size in the - * underlying surface accordingly. This function will reallocate everything, - * so you'll have to redraw everything in the surface after this call. - * The surface will contain garbage after the resizing. So the notes of - * cairo_os2_surface_create() apply here, too. - * - * The timeout value specifies how long the function should wait on other parts - * of the program to release the buffers. It is necessary, because it can happen - * that Cairo is just drawing something into the surface while we want to - * destroy and recreate it. - * - * Return value: %CAIRO_STATUS_SUCCESS if the surface could be resized, - * %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface is not an OS/2 surface, - * %CAIRO_STATUS_INVALID_SIZE for invalid sizes - * %CAIRO_STATUS_NO_MEMORY if the new size could not be allocated, or if the - * timeout happened before all the buffers were released - * - * Since: 1.4 - **/ -int -cairo_os2_surface_set_size (cairo_surface_t *surface, - int new_width, - int new_height, - int timeout) -{ - cairo_os2_surface_t *local_os2_surface; - unsigned char *pchNewPixels; - int rc; - cairo_image_surface_t *pNewImageSurface; - - local_os2_surface = (cairo_os2_surface_t *) surface; - if ((!local_os2_surface) || - (local_os2_surface->base.backend != &cairo_os2_surface_backend)) - { - /* Invalid parameter (wrong surface)! */ - return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - } - - if ((new_width <= 0) || - (new_height <= 0)) - { - /* Invalid size! */ - return _cairo_error (CAIRO_STATUS_INVALID_SIZE); - } - - /* Allocate memory for new stuffs */ - pchNewPixels = (unsigned char *) _buffer_alloc (new_height, new_width, 4); - if (!pchNewPixels) { - /* Not enough memory for the pixels! - * Everything remains the same! - */ - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - /* Create image surface from new pixel array */ - pNewImageSurface = (cairo_image_surface_t *) - cairo_image_surface_create_for_data (pchNewPixels, - CAIRO_FORMAT_ARGB32, - new_width, /* Width */ - new_height, /* Height */ - new_width * 4); /* Rowstride */ - - if (pNewImageSurface->base.status) { - /* Could not create image surface! - * Everything remains the same! - */ - _buffer_free (pchNewPixels); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - /* Okay, new memory allocated, so it's time to swap old buffers - * to new ones! - */ - if (DosRequestMutexSem (local_os2_surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT)!=NO_ERROR) { - /* Could not get mutex! - * Everything remains the same! - */ - cairo_surface_destroy ((cairo_surface_t *) pNewImageSurface); - _buffer_free (pchNewPixels); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - /* We have to make sure that we won't destroy a surface which - * is lent to some other code (Cairo is drawing into it)! - */ - while (local_os2_surface->pixel_array_lend_count > 0) { - ULONG ulPostCount; - DosResetEventSem (local_os2_surface->hev_pixel_array_came_back, &ulPostCount); - DosReleaseMutexSem (local_os2_surface->hmtx_use_private_fields); - /* Wait for somebody to return the pixels! */ - rc = DosWaitEventSem (local_os2_surface->hev_pixel_array_came_back, timeout); - if (rc != NO_ERROR) { - /* Either timeout or something wrong... Exit. */ - cairo_surface_destroy ((cairo_surface_t *) pNewImageSurface); - _buffer_free (pchNewPixels); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - /* Okay, grab mutex and check counter again! */ - if (DosRequestMutexSem (local_os2_surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT) - != NO_ERROR) - { - /* Could not get mutex! - * Everything remains the same! - */ - cairo_surface_destroy ((cairo_surface_t *) pNewImageSurface); - _buffer_free (pchNewPixels); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - } - - /* Destroy old image surface */ - cairo_surface_destroy ((cairo_surface_t *) (local_os2_surface->image_surface)); - /* Destroy old pixel buffer */ - _buffer_free (local_os2_surface->pixels); - /* Set new image surface */ - local_os2_surface->image_surface = pNewImageSurface; - /* Set new pixel buffer */ - local_os2_surface->pixels = pchNewPixels; - /* Change bitmap2 structure */ - local_os2_surface->bitmap_info.cx = new_width; - local_os2_surface->bitmap_info.cy = new_height; - - DosReleaseMutexSem (local_os2_surface->hmtx_use_private_fields); - return CAIRO_STATUS_SUCCESS; -} - -/** - * cairo_os2_surface_refresh_window: - * @surface: the cairo surface to refresh - * @hps_begin_paint: the presentation handle of the window to refresh - * @prcl_begin_paint_rect: the rectangle to redraw - * - * This function can be used to force a repaint of a given area of the client - * window. It should usually be called from the WM_PAINT processing of the - * window procedure. However, it can be called any time a given part of the - * window has to be updated. - * - * The HPS and RECTL to be passed can be taken from the usual WinBeginPaint call - * of the window procedure, but you can also get the HPS using WinGetPS, and you - * can assemble your own update rectangle by hand. - * If hps_begin_paint is %NULL, the function will use the HPS passed into - * cairo_os2_surface_create(). If @prcl_begin_paint_rect is %NULL, the function - * will query the current window size and repaint the whole window. - * - * Cairo assumes that if you set the HWND to the surface using - * cairo_os2_surface_set_hwnd(), this function will be called by the application - * every time it gets a WM_PAINT for that HWND. If the HWND is set in the - * surface, Cairo uses this function to handle dirty areas too. - * - * Since: 1.4 - **/ -void -cairo_os2_surface_refresh_window (cairo_surface_t *surface, - HPS hps_begin_paint, - PRECTL prcl_begin_paint_rect) -{ - cairo_os2_surface_t *local_os2_surface; - RECTL rclTemp; - HPS hpsTemp = 0; - - local_os2_surface = (cairo_os2_surface_t *) surface; - if ((!local_os2_surface) || - (local_os2_surface->base.backend != &cairo_os2_surface_backend)) - { - /* Invalid parameter (wrong surface)! */ - return; - } - - /* If an HPS wasn't provided, see if we can get one. */ - if (!hps_begin_paint) { - hps_begin_paint = local_os2_surface->hps_client_window; - if (!hps_begin_paint) { - if (local_os2_surface->hwnd_client_window) { - hpsTemp = WinGetPS(local_os2_surface->hwnd_client_window); - hps_begin_paint = hpsTemp; - } - /* No HPS & no way to get one, so exit */ - if (!hps_begin_paint) - return; - } - } - - if (prcl_begin_paint_rect == NULL) { - /* Update the whole window! */ - rclTemp.xLeft = 0; - rclTemp.xRight = local_os2_surface->bitmap_info.cx; - rclTemp.yTop = local_os2_surface->bitmap_info.cy; - rclTemp.yBottom = 0; - } else { - /* Use the rectangle we got passed as parameter! */ - rclTemp.xLeft = prcl_begin_paint_rect->xLeft; - rclTemp.xRight = prcl_begin_paint_rect->xRight; - rclTemp.yTop = local_os2_surface->bitmap_info.cy - prcl_begin_paint_rect->yBottom; - rclTemp.yBottom = local_os2_surface->bitmap_info.cy - prcl_begin_paint_rect->yTop ; - } - - /* Get mutex, we'll work with the pixel array! */ - if (DosRequestMutexSem (local_os2_surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT) - != NO_ERROR) - { - /* Could not get mutex! */ - if (hpsTemp) - WinReleasePS(hpsTemp); - return; - } - - if ((local_os2_surface->dirty_area_present) && - (local_os2_surface->rcl_dirty_area.xLeft == rclTemp.xLeft) && - (local_os2_surface->rcl_dirty_area.xRight == rclTemp.xRight) && - (local_os2_surface->rcl_dirty_area.yTop == rclTemp.yTop) && - (local_os2_surface->rcl_dirty_area.yBottom == rclTemp.yBottom)) - { - /* Aha, this call was because of a dirty area, so in this case we - * have to blit the pixels from the screen to the surface! - */ - local_os2_surface->dirty_area_present = FALSE; - _cairo_os2_surface_get_pixels_from_screen (local_os2_surface, - hps_begin_paint, - &rclTemp); - } else { - /* Okay, we have the surface, have the HPS - * (might be from WinBeginPaint () or from WinGetPS () ) - * Now blit there the stuffs! - */ - _cairo_os2_surface_blit_pixels (local_os2_surface, - hps_begin_paint, - &rclTemp); - } - - DosReleaseMutexSem (local_os2_surface->hmtx_use_private_fields); - - if (hpsTemp) - WinReleasePS(hpsTemp); -} - -static cairo_status_t -_cairo_os2_surface_finish (void *abstract_surface) -{ - cairo_os2_surface_t *local_os2_surface; - - local_os2_surface = (cairo_os2_surface_t *) abstract_surface; - if ((!local_os2_surface) || - (local_os2_surface->base.backend != &cairo_os2_surface_backend)) - { - /* Invalid parameter (wrong surface)! */ - return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - } - - DosRequestMutexSem (local_os2_surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT); - - /* Destroy old image surface */ - cairo_surface_destroy ((cairo_surface_t *) (local_os2_surface->image_surface)); - /* Destroy old pixel buffer */ - _buffer_free (local_os2_surface->pixels); - DosCloseMutexSem (local_os2_surface->hmtx_use_private_fields); - DosCloseEventSem (local_os2_surface->hev_pixel_array_came_back); - - /* The memory itself will be free'd by the cairo_surface_destroy () - * who called us. - */ - - return CAIRO_STATUS_SUCCESS; -} - -/** - * cairo_os2_surface_set_hwnd: - * @surface: the cairo surface to associate with the window handle - * @hwnd_client_window: the window handle of the client window - * - * Sets window handle for surface; the caller retains ownership of the window. - * If Cairo wants to blit into the window because it is set to blit as the - * surface changes (see cairo_os2_surface_set_manual_window_refresh()), then - * there are two ways it can choose: - * If it knows the HWND of the surface, then it invalidates that area, so the - * application will get a WM_PAINT message and it can call - * cairo_os2_surface_refresh_window() to redraw that area. Otherwise cairo itself - * will use the HPS it got at surface creation time, and blit the pixels itself. - * It's also a solution, but experience shows that if this happens from a non-PM - * thread, then it can screw up PM internals. - * - * So, best solution is to set the HWND for the surface after the surface - * creation, so every blit will be done from application's message processing - * loop, which is the safest way to do. - * - * Since: 1.4 - **/ -void -cairo_os2_surface_set_hwnd (cairo_surface_t *surface, - HWND hwnd_client_window) -{ - cairo_os2_surface_t *local_os2_surface; - - local_os2_surface = (cairo_os2_surface_t *) surface; - if ((!local_os2_surface) || - (local_os2_surface->base.backend != &cairo_os2_surface_backend)) - { - /* Invalid parameter (wrong surface)! */ - return; - } - - if (DosRequestMutexSem (local_os2_surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT) - != NO_ERROR) - { - /* Could not get mutex! */ - return; - } - - local_os2_surface->hwnd_client_window = hwnd_client_window; - - DosReleaseMutexSem (local_os2_surface->hmtx_use_private_fields); -} - -/** - * cairo_os2_surface_set_manual_window_refresh: - * @surface: the cairo surface to set the refresh mode for - * @manual_refresh: the switch for manual surface refresh - * - * This API can tell Cairo if it should show every change to this surface - * immediately in the window or if it should be cached and will only be visible - * once the user calls cairo_os2_surface_refresh_window() explicitly. If the - * HWND was not set in the cairo surface, then the HPS will be used to blit the - * graphics. Otherwise it will invalidate the given window region so the user - * will get the WM_PAINT message to redraw that area of the window. - * - * So, if you're only interested in displaying the final result after several - * drawing operations, you might get better performance if you put the surface - * into manual refresh mode by passing a true value to this function. Then call - * cairo_os2_surface_refresh() whenever desired. - * - * Since: 1.4 - **/ -void -cairo_os2_surface_set_manual_window_refresh (cairo_surface_t *surface, - cairo_bool_t manual_refresh) -{ - cairo_os2_surface_t *local_os2_surface; - - local_os2_surface = (cairo_os2_surface_t *) surface; - if ((!local_os2_surface) || - (local_os2_surface->base.backend != &cairo_os2_surface_backend)) - { - /* Invalid parameter (wrong surface)! */ - return; - } - - local_os2_surface->blit_as_changes = !manual_refresh; -} - -/** - * cairo_os2_surface_get_manual_window_refresh: - * @surface: the cairo surface to query the refresh mode from - * - * This space left intentionally blank. - * - * Return value: current refresh mode of the surface (true by default) - * - * Since: 1.4 - **/ -cairo_bool_t -cairo_os2_surface_get_manual_window_refresh (cairo_surface_t *surface) -{ - cairo_os2_surface_t *local_os2_surface; - - local_os2_surface = (cairo_os2_surface_t *) surface; - if ((!local_os2_surface) || - (local_os2_surface->base.backend != &cairo_os2_surface_backend)) - { - /* Invalid parameter (wrong surface)! */ - return FALSE; - } - - return !(local_os2_surface->blit_as_changes); -} - -/** - * cairo_os2_surface_get_hps: - * @surface: the cairo surface to be querued - * @hps: HPS currently associated with the surface (if any) - * - * This API retrieves the HPS associated with the surface. - * - * Return value: %CAIRO_STATUS_SUCCESS if the hps could be retrieved, - * %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface is not an OS/2 surface, - * %CAIRO_STATUS_NULL_POINTER if the hps argument is null - * - * Since: 1.10 - **/ -cairo_status_t -cairo_os2_surface_get_hps (cairo_surface_t *surface, - HPS *hps) -{ - cairo_os2_surface_t *local_os2_surface; - - local_os2_surface = (cairo_os2_surface_t *) surface; - if ((!local_os2_surface) || - (local_os2_surface->base.backend != &cairo_os2_surface_backend)) - { - /* Invalid parameter (wrong surface)! */ - return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - } - if (!hps) - { - return _cairo_error (CAIRO_STATUS_NULL_POINTER); - } - *hps = local_os2_surface->hps_client_window; - - return CAIRO_STATUS_SUCCESS; -} - -/** - * cairo_os2_surface_set_hps: - * @surface: the cairo surface to associate with the HPS - * @hps: new HPS to be associated with the surface (the HPS may be null) - * - * This API replaces the HPS associated with the surface with a new one. - * The caller retains ownership of the HPS and must dispose of it after - * the surface has been destroyed or it has been replaced by another - * call to this function. - * - * Return value: %CAIRO_STATUS_SUCCESS if the hps could be replaced, - * %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface is not an OS/2 surface, - * - * Since: 1.10 - **/ -cairo_status_t -cairo_os2_surface_set_hps (cairo_surface_t *surface, - HPS hps) -{ - cairo_os2_surface_t *local_os2_surface; - - local_os2_surface = (cairo_os2_surface_t *) surface; - if ((!local_os2_surface) || - (local_os2_surface->base.backend != &cairo_os2_surface_backend)) - { - /* Invalid parameter (wrong surface)! */ - return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - } - local_os2_surface->hps_client_window = hps; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_os2_surface_mark_dirty_rectangle (void *surface, - int x, - int y, - int width, - int height) -{ - cairo_os2_surface_t *local_os2_surface; - RECTL rclToBlit; - - local_os2_surface = (cairo_os2_surface_t *) surface; - if ((!local_os2_surface) || - (local_os2_surface->base.backend != &cairo_os2_surface_backend)) - { - /* Invalid parameter (wrong surface)! */ - return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - } - - /* Get mutex, we'll work with the pixel array! */ - if (DosRequestMutexSem (local_os2_surface->hmtx_use_private_fields, SEM_INDEFINITE_WAIT) - != NO_ERROR) - { - /* Could not get mutex! */ - return CAIRO_STATUS_NO_MEMORY; - } - - /* Check for defaults */ - if (width < 0) - width = local_os2_surface->bitmap_info.cx; - if (height < 0) - height = local_os2_surface->bitmap_info.cy; - - if (local_os2_surface->hwnd_client_window) { - /* We know the HWND, so let's invalidate the window region, - * so the application will redraw itself, using the - * cairo_os2_surface_refresh_window () API from its own PM thread. - * From that function we'll note that it's not a redraw but a - * dirty-rectangle deal stuff, so we'll handle the things from - * there. - * - * This is the safe method, which should be preferred every time. - */ - rclToBlit.xLeft = x; - rclToBlit.xRight = x + width; /* Noninclusive */ - rclToBlit.yTop = local_os2_surface->bitmap_info.cy - (y); - rclToBlit.yBottom = local_os2_surface->bitmap_info.cy - (y + height); /* Noninclusive */ - -#if 0 - if (local_os2_surface->dirty_area_present) { - /* Yikes, there is already a dirty area which should be - * cleaned up, but we'll overwrite it. Sorry. - * TODO: Something clever should be done here. - */ - } -#endif - - /* Set up dirty area reminder stuff */ - memcpy (&(local_os2_surface->rcl_dirty_area), &rclToBlit, sizeof (RECTL)); - local_os2_surface->dirty_area_present = TRUE; - - /* Invalidate window area */ - WinInvalidateRect (local_os2_surface->hwnd_client_window, - &rclToBlit, - FALSE); - } else { - /* We don't know the HWND, so try to blit the pixels from here! - * Please note that it can be problematic if this is not the PM thread! - * - * It can cause internal PM stuffs to be scewed up, for some reason. - * Please always tell the HWND to the surface using the - * cairo_os2_surface_set_hwnd () API, and call cairo_os2_surface_refresh_window () - * from your WM_PAINT, if it's possible! - */ - - rclToBlit.xLeft = x; - rclToBlit.xRight = x + width; /* Noninclusive */ - rclToBlit.yBottom = y; - rclToBlit.yTop = y + height; /* Noninclusive */ - /* Now get the pixels from the screen! */ - _cairo_os2_surface_get_pixels_from_screen (local_os2_surface, - local_os2_surface->hps_client_window, - &rclToBlit); - } - - DosReleaseMutexSem (local_os2_surface->hmtx_use_private_fields); - - return CAIRO_STATUS_SUCCESS; -} - -static const cairo_surface_backend_t cairo_os2_surface_backend = { - CAIRO_SURFACE_TYPE_OS2, - _cairo_os2_surface_finish, - _cairo_default_context_create, - - NULL, /* create_similar */ - NULL, /* create_similar_image */ - _cairo_os2_surface_map_to_image, - _cairo_os2_surface_unmap_image, - - _cairo_surface_default_source, - _cairo_os2_surface_acquire_source_image, - _cairo_os2_surface_release_source_image, - NULL, /* snapshot */ - - _cairo_os2_surface_get_extents, - NULL, /* get_font_options */ - - NULL, /* flush */ - _cairo_os2_surface_mark_dirty_rectangle, - - _cairo_surface_fallback_paint, - _cairo_surface_fallback_mask, - _cairo_surface_fallback_fill, - _cairo_surface_fallback_stroke, - NULL, /* fill/stroke */ - _cairo_surface_fallback_glyphs, -}; diff --git a/source/libs/cairo/cairo-src/src/cairo-os2.h b/source/libs/cairo/cairo-src/src/cairo-os2.h deleted file mode 100644 index d23f2dec42adb4f131313485e2d576adea7ca78b..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-os2.h +++ /dev/null @@ -1,110 +0,0 @@ -/* vim: set sw=4 sts=4 et cin: */ -/* cairo - a vector graphics library with display and print output - * - * Copyright (c) 2005-2006 netlabs.org - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 - * Doodle <doodle@scenergy.dfmk.hu> - * - * Contributor(s): - * Peter Weilbacher <mozilla@Weilbacher.org> - * Rich Walsh <dragtext@e-vertise.com> - */ - -#ifndef _CAIRO_OS2_H_ -#define _CAIRO_OS2_H_ - -#define INCL_DOS -#define INCL_DOSSEMAPHORES -#define INCL_DOSERRORS -#define INCL_WIN -#define INCL_GPI - -#include "cairo.h" - -#include <os2.h> - -CAIRO_BEGIN_DECLS - -/* The OS/2 Specific Cairo API */ - -cairo_public void -cairo_os2_init (void); - -cairo_public void -cairo_os2_fini (void); - -#if CAIRO_HAS_OS2_SURFACE - -cairo_public cairo_surface_t * -cairo_os2_surface_create (HPS hps_client_window, - int width, - int height); - -cairo_public cairo_surface_t * -cairo_os2_surface_create_for_window (HWND hwnd_client_window, - int width, - int height); - -cairo_public void -cairo_os2_surface_set_hwnd (cairo_surface_t *surface, - HWND hwnd_client_window); - -cairo_public int -cairo_os2_surface_set_size (cairo_surface_t *surface, - int new_width, - int new_height, - int timeout); - -cairo_public void -cairo_os2_surface_refresh_window (cairo_surface_t *surface, - HPS hps_begin_paint, - PRECTL prcl_begin_paint_rect); - -cairo_public void -cairo_os2_surface_set_manual_window_refresh (cairo_surface_t *surface, - cairo_bool_t manual_refresh); - -cairo_public cairo_bool_t -cairo_os2_surface_get_manual_window_refresh (cairo_surface_t *surface); - -cairo_public cairo_status_t -cairo_os2_surface_get_hps (cairo_surface_t *surface, - HPS *hps); - -cairo_public cairo_status_t -cairo_os2_surface_set_hps (cairo_surface_t *surface, - HPS hps); - -#else /* CAIRO_HAS_OS2_SURFACE */ -# error Cairo was not compiled with support for the OS/2 backend -#endif /* CAIRO_HAS_OS2_SURFACE */ - -CAIRO_END_DECLS - -#endif /* _CAIRO_OS2_H_ */ diff --git a/source/libs/cairo/cairo-src/src/cairo-output-stream-private.h b/source/libs/cairo/cairo-src/src/cairo-output-stream-private.h deleted file mode 100644 index 2542646b86085df8260f1e38793d2dcc3daba71e..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-output-stream-private.h +++ /dev/null @@ -1,201 +0,0 @@ -/* 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Author(s): - * Kristian Høgsberg <krh@redhat.com> - */ - -#ifndef CAIRO_OUTPUT_STREAM_PRIVATE_H -#define CAIRO_OUTPUT_STREAM_PRIVATE_H - -#include "cairo-compiler-private.h" -#include "cairo-types-private.h" - -#include <stdlib.h> -#include <stdio.h> -#include <stdarg.h> - -typedef cairo_status_t -(*cairo_output_stream_write_func_t) (cairo_output_stream_t *output_stream, - const unsigned char *data, - unsigned int length); - -typedef cairo_status_t -(*cairo_output_stream_flush_func_t) (cairo_output_stream_t *output_stream); - -typedef cairo_status_t -(*cairo_output_stream_close_func_t) (cairo_output_stream_t *output_stream); - -struct _cairo_output_stream { - cairo_output_stream_write_func_t write_func; - cairo_output_stream_flush_func_t flush_func; - cairo_output_stream_close_func_t close_func; - unsigned long position; - cairo_status_t status; - cairo_bool_t closed; -}; - -extern const cairo_private cairo_output_stream_t _cairo_output_stream_nil; - -cairo_private void -_cairo_output_stream_init (cairo_output_stream_t *stream, - cairo_output_stream_write_func_t write_func, - cairo_output_stream_flush_func_t flush_func, - cairo_output_stream_close_func_t close_func); - -cairo_private cairo_status_t -_cairo_output_stream_fini (cairo_output_stream_t *stream); - - -/* 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 cairo_output_stream_t * -_cairo_output_stream_create_in_error (cairo_status_t status); - -/* Tries to flush any buffer maintained by the stream or its delegates. */ -cairo_private cairo_status_t -_cairo_output_stream_flush (cairo_output_stream_t *stream); - -/* Returns the final status value associated with this object, just - * before its last gasp. This final status value will capture any - * status failure returned by the stream's close_func as well. */ -cairo_private cairo_status_t -_cairo_output_stream_close (cairo_output_stream_t *stream); - -/* Returns the final status value associated with this object, just - * before its last gasp. This final status value will capture any - * status failure returned by the stream's close_func as well. */ -cairo_private cairo_status_t -_cairo_output_stream_destroy (cairo_output_stream_t *stream); - -cairo_private void -_cairo_output_stream_write (cairo_output_stream_t *stream, - const void *data, size_t length); - -cairo_private void -_cairo_output_stream_write_hex_string (cairo_output_stream_t *stream, - const unsigned char *data, - size_t length); - -cairo_private void -_cairo_output_stream_vprintf (cairo_output_stream_t *stream, - const char *fmt, - va_list ap) CAIRO_PRINTF_FORMAT ( 2, 0); - -cairo_private void -_cairo_output_stream_printf (cairo_output_stream_t *stream, - const char *fmt, - ...) CAIRO_PRINTF_FORMAT (2, 3); - -/* Print matrix element values with rounding of insignificant digits. */ -cairo_private void -_cairo_output_stream_print_matrix (cairo_output_stream_t *stream, - const cairo_matrix_t *matrix); - -cairo_private long -_cairo_output_stream_get_position (cairo_output_stream_t *stream); - -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_filename (const char *filename); - -/* 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. - * - * The caller still "owns" file and is responsible for calling fclose - * on it when finished. The stream will not do this itself. - */ -cairo_private cairo_output_stream_t * -_cairo_output_stream_create_for_file (FILE *file); - -cairo_private cairo_output_stream_t * -_cairo_memory_stream_create (void); - -cairo_private void -_cairo_memory_stream_copy (cairo_output_stream_t *base, - cairo_output_stream_t *dest); - -cairo_private int -_cairo_memory_stream_length (cairo_output_stream_t *stream); - -cairo_private cairo_status_t -_cairo_memory_stream_destroy (cairo_output_stream_t *abstract_stream, - unsigned char **data_out, - unsigned long *length_out); - -cairo_private cairo_output_stream_t * -_cairo_null_stream_create (void); - -/* cairo-base85-stream.c */ -cairo_private cairo_output_stream_t * -_cairo_base85_stream_create (cairo_output_stream_t *output); - -/* cairo-base64-stream.c */ -cairo_private cairo_output_stream_t * -_cairo_base64_stream_create (cairo_output_stream_t *output); - -/* cairo-deflate-stream.c */ -cairo_private cairo_output_stream_t * -_cairo_deflate_stream_create (cairo_output_stream_t *output); - - -#endif /* CAIRO_OUTPUT_STREAM_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-output-stream.c b/source/libs/cairo/cairo-src/src/cairo-output-stream.c deleted file mode 100644 index 369a59bfba889037193004dad76f6c8e0be47ffb..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-output-stream.c +++ /dev/null @@ -1,802 +0,0 @@ -/* 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Author(s): - * Kristian Høgsberg <krh@redhat.com> - */ - -#define _BSD_SOURCE /* for snprintf() */ -#include "cairoint.h" - -#include "cairo-output-stream-private.h" - -#include "cairo-array-private.h" -#include "cairo-error-private.h" -#include "cairo-compiler-private.h" - -#include <stdio.h> -#include <errno.h> - -/* Numbers printed with %f are printed with this number of significant - * digits after the decimal. - */ -#define SIGNIFICANT_DIGITS_AFTER_DECIMAL 6 - -/* Numbers printed with %g are assumed to only have %CAIRO_FIXED_FRAC_BITS - * bits of precision available after the decimal point. - * - * FIXED_POINT_DECIMAL_DIGITS specifies the minimum number of decimal - * digits after the decimal point required to preserve the available - * precision. - * - * The conversion is: - * - * <programlisting> - * FIXED_POINT_DECIMAL_DIGITS = ceil( CAIRO_FIXED_FRAC_BITS * ln(2)/ln(10) ) - * </programlisting> - * - * We can replace ceil(x) with (int)(x+1) since x will never be an - * integer for any likely value of %CAIRO_FIXED_FRAC_BITS. - */ -#define FIXED_POINT_DECIMAL_DIGITS ((int)(CAIRO_FIXED_FRAC_BITS*0.301029996 + 1)) - -void -_cairo_output_stream_init (cairo_output_stream_t *stream, - cairo_output_stream_write_func_t write_func, - cairo_output_stream_flush_func_t flush_func, - cairo_output_stream_close_func_t close_func) -{ - stream->write_func = write_func; - stream->flush_func = flush_func; - stream->close_func = close_func; - stream->position = 0; - stream->status = CAIRO_STATUS_SUCCESS; - stream->closed = FALSE; -} - -cairo_status_t -_cairo_output_stream_fini (cairo_output_stream_t *stream) -{ - return _cairo_output_stream_close (stream); -} - -const cairo_output_stream_t _cairo_output_stream_nil = { - NULL, /* write_func */ - NULL, /* flush_func */ - NULL, /* close_func */ - 0, /* position */ - CAIRO_STATUS_NO_MEMORY, - FALSE /* closed */ -}; - -static const cairo_output_stream_t _cairo_output_stream_nil_write_error = { - NULL, /* write_func */ - NULL, /* flush_func */ - NULL, /* close_func */ - 0, /* position */ - CAIRO_STATUS_WRITE_ERROR, - FALSE /* closed */ -}; - -typedef struct _cairo_output_stream_with_closure { - cairo_output_stream_t base; - cairo_write_func_t write_func; - cairo_close_func_t close_func; - void *closure; -} cairo_output_stream_with_closure_t; - - -static cairo_status_t -closure_write (cairo_output_stream_t *stream, - const unsigned char *data, unsigned int length) -{ - cairo_output_stream_with_closure_t *stream_with_closure = - (cairo_output_stream_with_closure_t *) stream; - - if (stream_with_closure->write_func == NULL) - return CAIRO_STATUS_SUCCESS; - - return stream_with_closure->write_func (stream_with_closure->closure, - data, length); -} - -static cairo_status_t -closure_close (cairo_output_stream_t *stream) -{ - cairo_output_stream_with_closure_t *stream_with_closure = - (cairo_output_stream_with_closure_t *) stream; - - if (stream_with_closure->close_func != NULL) - return stream_with_closure->close_func (stream_with_closure->closure); - else - return CAIRO_STATUS_SUCCESS; -} - -cairo_output_stream_t * -_cairo_output_stream_create (cairo_write_func_t write_func, - cairo_close_func_t close_func, - void *closure) -{ - cairo_output_stream_with_closure_t *stream; - - stream = malloc (sizeof (cairo_output_stream_with_closure_t)); - if (unlikely (stream == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_output_stream_t *) &_cairo_output_stream_nil; - } - - _cairo_output_stream_init (&stream->base, - closure_write, NULL, closure_close); - stream->write_func = write_func; - stream->close_func = close_func; - stream->closure = closure; - - return &stream->base; -} - -cairo_output_stream_t * -_cairo_output_stream_create_in_error (cairo_status_t status) -{ - cairo_output_stream_t *stream; - - /* check for the common ones */ - if (status == CAIRO_STATUS_NO_MEMORY) - return (cairo_output_stream_t *) &_cairo_output_stream_nil; - if (status == CAIRO_STATUS_WRITE_ERROR) - return (cairo_output_stream_t *) &_cairo_output_stream_nil_write_error; - - stream = malloc (sizeof (cairo_output_stream_t)); - if (unlikely (stream == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_output_stream_t *) &_cairo_output_stream_nil; - } - - _cairo_output_stream_init (stream, NULL, NULL, NULL); - stream->status = status; - - return stream; -} - -cairo_status_t -_cairo_output_stream_flush (cairo_output_stream_t *stream) -{ - cairo_status_t status; - - if (stream->closed) - return stream->status; - - if (stream == &_cairo_output_stream_nil || - stream == &_cairo_output_stream_nil_write_error) - { - return stream->status; - } - - if (stream->flush_func) { - status = stream->flush_func (stream); - /* Don't overwrite a pre-existing status failure. */ - if (stream->status == CAIRO_STATUS_SUCCESS) - stream->status = status; - } - - return stream->status; -} - -cairo_status_t -_cairo_output_stream_close (cairo_output_stream_t *stream) -{ - cairo_status_t status; - - if (stream->closed) - return stream->status; - - if (stream == &_cairo_output_stream_nil || - stream == &_cairo_output_stream_nil_write_error) - { - return stream->status; - } - - if (stream->close_func) { - status = stream->close_func (stream); - /* Don't overwrite a pre-existing status failure. */ - if (stream->status == CAIRO_STATUS_SUCCESS) - stream->status = status; - } - - stream->closed = TRUE; - - return stream->status; -} - -cairo_status_t -_cairo_output_stream_destroy (cairo_output_stream_t *stream) -{ - cairo_status_t status; - - assert (stream != NULL); - - if (stream == &_cairo_output_stream_nil || - stream == &_cairo_output_stream_nil_write_error) - { - return stream->status; - } - - status = _cairo_output_stream_fini (stream); - free (stream); - - return status; -} - -void -_cairo_output_stream_write (cairo_output_stream_t *stream, - const void *data, size_t length) -{ - if (length == 0) - return; - - if (stream->status) - return; - - stream->status = stream->write_func (stream, data, length); - stream->position += length; -} - -void -_cairo_output_stream_write_hex_string (cairo_output_stream_t *stream, - const unsigned char *data, - size_t length) -{ - const char hex_chars[] = "0123456789abcdef"; - char buffer[2]; - unsigned 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); - column = 0; - } - buffer[0] = hex_chars[(data[i] >> 4) & 0x0f]; - buffer[1] = hex_chars[data[i] & 0x0f]; - _cairo_output_stream_write (stream, buffer, 2); - } -} - -/* Format a double in a locale independent way and trim trailing - * zeros. Based on code from Alex Larson <alexl@redhat.com>. - * http://mail.gnome.org/archives/gtk-devel-list/2001-October/msg00087.html - * - * The code in the patch is copyright Red Hat, Inc under the LGPL, but - * has been relicensed under the LGPL/MPL dual license for inclusion - * into cairo (see COPYING). -- Kristian Høgsberg <krh@redhat.com> - */ -static void -_cairo_dtostr (char *buffer, size_t size, double d, cairo_bool_t limited_precision) -{ - const char *decimal_point; - int decimal_point_len; - char *p; - int decimal_len; - int num_zeros, decimal_digits; - - /* Omit the minus sign from negative zero. */ - if (d == 0.0) - d = 0.0; - - decimal_point = cairo_get_locale_decimal_point (); - decimal_point_len = strlen (decimal_point); - - assert (decimal_point_len != 0); - - if (limited_precision) { - snprintf (buffer, size, "%.*f", FIXED_POINT_DECIMAL_DIGITS, d); - } else { - /* Using "%f" to print numbers less than 0.1 will result in - * reduced precision due to the default 6 digits after the - * decimal point. - * - * For numbers is < 0.1, we print with maximum precision and count - * the number of zeros between the decimal point and the first - * significant digit. We then print the number again with the - * number of decimal places that gives us the required number of - * significant digits. This ensures the number is correctly - * rounded. - */ - if (fabs (d) >= 0.1) { - snprintf (buffer, size, "%f", d); - } else { - snprintf (buffer, size, "%.18f", d); - p = buffer; - - if (*p == '+' || *p == '-') - p++; - - while (_cairo_isdigit (*p)) - p++; - - if (strncmp (p, decimal_point, decimal_point_len) == 0) - p += decimal_point_len; - - num_zeros = 0; - while (*p++ == '0') - num_zeros++; - - decimal_digits = num_zeros + SIGNIFICANT_DIGITS_AFTER_DECIMAL; - - if (decimal_digits < 18) - snprintf (buffer, size, "%.*f", decimal_digits, d); - } - } - p = buffer; - - if (*p == '+' || *p == '-') - p++; - - while (_cairo_isdigit (*p)) - p++; - - if (strncmp (p, decimal_point, decimal_point_len) == 0) { - *p = '.'; - decimal_len = strlen (p + decimal_point_len); - memmove (p + 1, p + decimal_point_len, decimal_len); - p[1 + decimal_len] = 0; - - /* Remove trailing zeros and decimal point if possible. */ - for (p = p + decimal_len; *p == '0'; p--) - *p = 0; - - if (*p == '.') { - *p = 0; - p--; - } - } -} - -enum { - LENGTH_MODIFIER_LONG = 0x100 -}; - -/* Here's a limited reimplementation of printf. The reason for doing - * this is primarily to special case handling of doubles. We want - * locale independent formatting of doubles and we want to trim - * trailing zeros. This is handled by dtostr() above, and the code - * below handles everything else by calling snprintf() to do the - * formatting. This functionality is only for internal use and we - * only implement the formats we actually use. - */ -void -_cairo_output_stream_vprintf (cairo_output_stream_t *stream, - const char *fmt, va_list ap) -{ -#define SINGLE_FMT_BUFFER_SIZE 32 - char buffer[512], single_fmt[SINGLE_FMT_BUFFER_SIZE]; - int single_fmt_length; - char *p; - const char *f, *start; - int length_modifier, width; - cairo_bool_t var_width; - - if (stream->status) - return; - - f = fmt; - p = buffer; - while (*f != '\0') { - if (p == buffer + sizeof (buffer)) { - _cairo_output_stream_write (stream, buffer, sizeof (buffer)); - p = buffer; - } - - if (*f != '%') { - *p++ = *f++; - continue; - } - - start = f; - f++; - - if (*f == '0') - f++; - - var_width = FALSE; - if (*f == '*') { - var_width = TRUE; - f++; - } - - while (_cairo_isdigit (*f)) - f++; - - length_modifier = 0; - if (*f == 'l') { - length_modifier = LENGTH_MODIFIER_LONG; - f++; - } - - /* The only format strings exist in the cairo implementation - * itself. So there's an internal consistency problem if any - * of them is larger than our format buffer size. */ - single_fmt_length = f - start + 1; - assert (single_fmt_length + 1 <= SINGLE_FMT_BUFFER_SIZE); - - /* Reuse the format string for this conversion. */ - memcpy (single_fmt, start, single_fmt_length); - single_fmt[single_fmt_length] = '\0'; - - /* Flush contents of buffer before snprintf()'ing into it. */ - _cairo_output_stream_write (stream, buffer, p - buffer); - - /* We group signed and unsigned together in this switch, the - * only thing that matters here is the size of the arguments, - * since we're just passing the data through to sprintf(). */ - switch (*f | length_modifier) { - case '%': - buffer[0] = *f; - buffer[1] = 0; - break; - case 'd': - case 'u': - case 'o': - case 'x': - case 'X': - if (var_width) { - width = va_arg (ap, int); - snprintf (buffer, sizeof buffer, - single_fmt, width, va_arg (ap, int)); - } else { - snprintf (buffer, sizeof buffer, single_fmt, va_arg (ap, int)); - } - break; - case 'd' | LENGTH_MODIFIER_LONG: - case 'u' | LENGTH_MODIFIER_LONG: - case 'o' | LENGTH_MODIFIER_LONG: - case 'x' | LENGTH_MODIFIER_LONG: - case 'X' | LENGTH_MODIFIER_LONG: - if (var_width) { - width = va_arg (ap, int); - snprintf (buffer, sizeof buffer, - single_fmt, width, va_arg (ap, long int)); - } else { - snprintf (buffer, sizeof buffer, - single_fmt, va_arg (ap, long int)); - } - break; - case 's': - snprintf (buffer, sizeof buffer, - single_fmt, va_arg (ap, const char *)); - break; - case 'f': - _cairo_dtostr (buffer, sizeof buffer, va_arg (ap, double), FALSE); - break; - case 'g': - _cairo_dtostr (buffer, sizeof buffer, va_arg (ap, double), TRUE); - break; - case 'c': - buffer[0] = va_arg (ap, int); - buffer[1] = 0; - break; - default: - ASSERT_NOT_REACHED; - } - p = buffer + strlen (buffer); - f++; - } - - _cairo_output_stream_write (stream, buffer, p - buffer); -} - -void -_cairo_output_stream_printf (cairo_output_stream_t *stream, - const char *fmt, ...) -{ - va_list ap; - - va_start (ap, fmt); - - _cairo_output_stream_vprintf (stream, fmt, ap); - - va_end (ap); -} - -/* Matrix elements that are smaller than the value of the largest element * MATRIX_ROUNDING_TOLERANCE - * are rounded down to zero. */ -#define MATRIX_ROUNDING_TOLERANCE 1e-12 - -void -_cairo_output_stream_print_matrix (cairo_output_stream_t *stream, - const cairo_matrix_t *matrix) -{ - cairo_matrix_t m; - double s, e; - - m = *matrix; - s = fabs (m.xx); - if (fabs (m.xy) > s) - s = fabs (m.xy); - if (fabs (m.yx) > s) - s = fabs (m.yx); - if (fabs (m.yy) > s) - s = fabs (m.yy); - - e = s * MATRIX_ROUNDING_TOLERANCE; - if (fabs(m.xx) < e) - m.xx = 0; - if (fabs(m.xy) < e) - m.xy = 0; - if (fabs(m.yx) < e) - m.yx = 0; - if (fabs(m.yy) < e) - m.yy = 0; - if (fabs(m.x0) < e) - m.x0 = 0; - if (fabs(m.y0) < e) - m.y0 = 0; - - _cairo_output_stream_printf (stream, - "%f %f %f %f %f %f", - m.xx, m.yx, m.xy, m.yy, m.x0, m.y0); -} - -long -_cairo_output_stream_get_position (cairo_output_stream_t *stream) -{ - return stream->position; -} - -cairo_status_t -_cairo_output_stream_get_status (cairo_output_stream_t *stream) -{ - return stream->status; -} - -/* Maybe this should be a configure time option, so embedded targets - * don't have to pull in stdio. */ - - -typedef struct _stdio_stream { - cairo_output_stream_t base; - FILE *file; -} stdio_stream_t; - -static cairo_status_t -stdio_write (cairo_output_stream_t *base, - const unsigned char *data, unsigned int length) -{ - stdio_stream_t *stream = (stdio_stream_t *) base; - - if (fwrite (data, 1, length, stream->file) != length) - return _cairo_error (CAIRO_STATUS_WRITE_ERROR); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -stdio_flush (cairo_output_stream_t *base) -{ - stdio_stream_t *stream = (stdio_stream_t *) base; - - fflush (stream->file); - - if (ferror (stream->file)) - return _cairo_error (CAIRO_STATUS_WRITE_ERROR); - else - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -stdio_close (cairo_output_stream_t *base) -{ - cairo_status_t status; - stdio_stream_t *stream = (stdio_stream_t *) base; - - status = stdio_flush (base); - - fclose (stream->file); - - return status; -} - -cairo_output_stream_t * -_cairo_output_stream_create_for_file (FILE *file) -{ - stdio_stream_t *stream; - - if (file == NULL) { - _cairo_error_throw (CAIRO_STATUS_WRITE_ERROR); - return (cairo_output_stream_t *) &_cairo_output_stream_nil_write_error; - } - - stream = malloc (sizeof *stream); - if (unlikely (stream == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_output_stream_t *) &_cairo_output_stream_nil; - } - - _cairo_output_stream_init (&stream->base, - stdio_write, stdio_flush, stdio_flush); - stream->file = file; - - return &stream->base; -} - -cairo_output_stream_t * -_cairo_output_stream_create_for_filename (const char *filename) -{ - stdio_stream_t *stream; - FILE *file; - - if (filename == NULL) - return _cairo_null_stream_create (); - - file = fopen (filename, "wb"); - if (file == NULL) { - switch (errno) { - case ENOMEM: - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_output_stream_t *) &_cairo_output_stream_nil; - default: - _cairo_error_throw (CAIRO_STATUS_WRITE_ERROR); - return (cairo_output_stream_t *) &_cairo_output_stream_nil_write_error; - } - } - - stream = malloc (sizeof *stream); - if (unlikely (stream == NULL)) { - fclose (file); - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_output_stream_t *) &_cairo_output_stream_nil; - } - - _cairo_output_stream_init (&stream->base, - stdio_write, stdio_flush, stdio_close); - stream->file = file; - - return &stream->base; -} - - -typedef struct _memory_stream { - cairo_output_stream_t base; - cairo_array_t array; -} memory_stream_t; - -static cairo_status_t -memory_write (cairo_output_stream_t *base, - const unsigned char *data, unsigned int length) -{ - memory_stream_t *stream = (memory_stream_t *) base; - - return _cairo_array_append_multiple (&stream->array, data, length); -} - -static cairo_status_t -memory_close (cairo_output_stream_t *base) -{ - memory_stream_t *stream = (memory_stream_t *) base; - - _cairo_array_fini (&stream->array); - - return CAIRO_STATUS_SUCCESS; -} - -cairo_output_stream_t * -_cairo_memory_stream_create (void) -{ - memory_stream_t *stream; - - stream = malloc (sizeof *stream); - if (unlikely (stream == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_output_stream_t *) &_cairo_output_stream_nil; - } - - _cairo_output_stream_init (&stream->base, memory_write, NULL, memory_close); - _cairo_array_init (&stream->array, 1); - - return &stream->base; -} - -cairo_status_t -_cairo_memory_stream_destroy (cairo_output_stream_t *abstract_stream, - unsigned char **data_out, - unsigned long *length_out) -{ - memory_stream_t *stream; - cairo_status_t status; - - status = abstract_stream->status; - if (unlikely (status)) - return _cairo_output_stream_destroy (abstract_stream); - - stream = (memory_stream_t *) abstract_stream; - - *length_out = _cairo_array_num_elements (&stream->array); - *data_out = malloc (*length_out); - if (unlikely (*data_out == NULL)) { - status = _cairo_output_stream_destroy (abstract_stream); - assert (status == CAIRO_STATUS_SUCCESS); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - memcpy (*data_out, _cairo_array_index (&stream->array, 0), *length_out); - - return _cairo_output_stream_destroy (abstract_stream); -} - -void -_cairo_memory_stream_copy (cairo_output_stream_t *base, - cairo_output_stream_t *dest) -{ - memory_stream_t *stream = (memory_stream_t *) base; - - if (dest->status) - return; - - if (base->status) { - dest->status = base->status; - return; - } - - _cairo_output_stream_write (dest, - _cairo_array_index (&stream->array, 0), - _cairo_array_num_elements (&stream->array)); -} - -int -_cairo_memory_stream_length (cairo_output_stream_t *base) -{ - memory_stream_t *stream = (memory_stream_t *) base; - - return _cairo_array_num_elements (&stream->array); -} - -static cairo_status_t -null_write (cairo_output_stream_t *base, - const unsigned char *data, unsigned int length) -{ - return CAIRO_STATUS_SUCCESS; -} - -cairo_output_stream_t * -_cairo_null_stream_create (void) -{ - cairo_output_stream_t *stream; - - stream = malloc (sizeof *stream); - if (unlikely (stream == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_output_stream_t *) &_cairo_output_stream_nil; - } - - _cairo_output_stream_init (stream, null_write, NULL, NULL); - - return stream; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-paginated-private.h b/source/libs/cairo/cairo-src/src/cairo-paginated-private.h deleted file mode 100644 index b827faba0ef01e0ad06759ed81b5349a7c336eda..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-paginated-private.h +++ /dev/null @@ -1,168 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Carl Worth <cworth@cworth.org> - */ - -#ifndef CAIRO_PAGINATED_H -#define CAIRO_PAGINATED_H - -#include "cairoint.h" - -struct _cairo_paginated_surface_backend { - /* Optional. Will be called once for each page. - * - * Note: With respect to the order of drawing operations as seen - * by the target, this call will occur before any drawing - * operations for the relevant page. However, with respect to the - * function calls as made by the user, this call will be *after* - * any drawing operations for the page, (that is, it will occur - * during the user's call to cairo_show_page or cairo_copy_page). - */ - cairo_warn cairo_int_status_t - (*start_page) (void *surface); - - /* Required. Will be called twice for each page, once with an - * argument of CAIRO_PAGINATED_MODE_ANALYZE and once with - * CAIRO_PAGINATED_MODE_RENDER. See more details in the - * documentation for _cairo_paginated_surface_create below. - */ - void - (*set_paginated_mode) (void *surface, - cairo_paginated_mode_t mode); - - /* Optional. Specifies the smallest box that encloses all objects - * on the page. Will be called at the end of the ANALYZE phase but - * before the mode is changed to RENDER. - */ - cairo_warn cairo_int_status_t - (*set_bounding_box) (void *surface, - cairo_box_t *bbox); - - /* Optional. Indicates whether the page requires fallback images. - * Will be called at the end of the ANALYZE phase but before the - * mode is changed to RENDER. - */ - cairo_warn cairo_int_status_t - (*set_fallback_images_required) (void *surface, - cairo_bool_t fallbacks_required); - - cairo_bool_t - (*supports_fine_grained_fallbacks) (void *surface); -}; - -/* A #cairo_paginated_surface_t provides a very convenient wrapper that - * is well-suited for doing the analysis common to most surfaces that - * have paginated output, (that is, things directed at printers, or - * for saving content in files such as PostScript or PDF files). - * - * To use the paginated surface, you'll first need to create your - * 'real' surface using _cairo_surface_init() and the standard - * #cairo_surface_backend_t. Then you also call - * _cairo_paginated_surface_create which takes its own, much simpler, - * #cairo_paginated_surface_backend_t. You are free to return the result - * of _cairo_paginated_surface_create() from your public - * cairo_<foo>_surface_create(). The paginated backend will be careful - * to not let the user see that they really got a "wrapped" - * surface. See test-paginated-surface.c for a fairly minimal example - * of a paginated-using surface. That should be a reasonable example - * to follow. - * - * What the paginated surface does is first save all drawing - * operations for a page into a recording-surface. Then when the user calls - * cairo_show_page(), the paginated surface performs the following - * sequence of operations (using the backend functions passed to - * cairo_paginated_surface_create()): - * - * 1. Calls start_page() (if not %NULL). At this point, it is appropriate - * for the target to emit any page-specific header information into - * its output. - * - * 2. Calls set_paginated_mode() with an argument of %CAIRO_PAGINATED_MODE_ANALYZE - * - * 3. Replays the recording-surface to the target surface, (with an - * analysis surface inserted between which watches the return value - * from each operation). This analysis stage is used to decide which - * operations will require fallbacks. - * - * 4. Calls set_bounding_box() to provide the target surface with the - * tight bounding box of the page. - * - * 5. Calls set_paginated_mode() with an argument of %CAIRO_PAGINATED_MODE_RENDER - * - * 6. Replays a subset of the recording-surface operations to the target surface - * - * 7. Calls set_paginated_mode() with an argument of %CAIRO_PAGINATED_MODE_FALLBACK - * - * 8. Replays the remaining operations to an image surface, sets an - * appropriate clip on the target, then paints the resulting image - * surface to the target. - * - * So, the target will see drawing operations during three separate - * stages, (ANALYZE, RENDER and FALLBACK). During the ANALYZE phase - * the target should not actually perform any rendering, (for example, - * if performing output to a file, no output should be generated - * during this stage). Instead the drawing functions simply need to - * return %CAIRO_STATUS_SUCCESS or %CAIRO_INT_STATUS_UNSUPPORTED to - * indicate whether rendering would be supported. And it should do - * this as quickly as possible. The FALLBACK phase allows the surface - * to distinguish fallback images from native rendering in case they - * need to be handled as a special case. - * - * Note: The paginated surface layer assumes that the target surface - * is "blank" by default at the beginning of each page, without any - * need for an explicit erase operation, (as opposed to an image - * surface, for example, which might have uninitialized content - * originally). As such, it optimizes away CLEAR operations that - * happen at the beginning of each page---the target surface will not - * even see these operations. - */ -cairo_private cairo_surface_t * -_cairo_paginated_surface_create (cairo_surface_t *target, - cairo_content_t content, - const cairo_paginated_surface_backend_t *backend); - -cairo_private cairo_surface_t * -_cairo_paginated_surface_get_target (cairo_surface_t *surface); - -cairo_private cairo_surface_t * -_cairo_paginated_surface_get_recording (cairo_surface_t *surface); - -cairo_private cairo_bool_t -_cairo_surface_is_paginated (cairo_surface_t *surface); - -cairo_private cairo_status_t -_cairo_paginated_surface_set_size (cairo_surface_t *surface, - int width, - int height); - -#endif /* CAIRO_PAGINATED_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-paginated-surface-private.h b/source/libs/cairo/cairo-src/src/cairo-paginated-surface-private.h deleted file mode 100644 index ebf4b3424920c68db91234587df0819cb74f54a0..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-paginated-surface-private.h +++ /dev/null @@ -1,62 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Carl Worth <cworth@cworth.org> - */ - -#ifndef CAIRO_PAGINATED_SURFACE_H -#define CAIRO_PAGINATED_SURFACE_H - -#include "cairo.h" - -#include "cairo-surface-private.h" - -typedef struct _cairo_paginated_surface { - cairo_surface_t base; - - /* The target surface to hold the final result. */ - cairo_surface_t *target; - - cairo_content_t content; - - /* Paginated-surface specific functions for the target */ - const cairo_paginated_surface_backend_t *backend; - - /* A cairo_recording_surface to record all operations. To be replayed - * against target, and also against image surface as necessary for - * fallbacks. */ - cairo_surface_t *recording_surface; - - int page_num; -} cairo_paginated_surface_t; - -#endif /* CAIRO_PAGINATED_SURFACE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-paginated-surface.c b/source/libs/cairo/cairo-src/src/cairo-paginated-surface.c deleted file mode 100644 index 68e4e0e34fd9593b24d6f6f9279450a394ebe798..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-paginated-surface.c +++ /dev/null @@ -1,716 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2005 Red Hat, Inc - * Copyright © 2007 Adrian Johnson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Carl Worth <cworth@cworth.org> - * Keith Packard <keithp@keithp.com> - * Adrian Johnson <ajohnson@redneon.com> - */ - -/* The paginated surface layer exists to provide as much code sharing - * as possible for the various paginated surface backends in cairo - * (PostScript, PDF, etc.). See cairo-paginated-private.h for - * more details on how it works and how to use it. - */ - -#include "cairoint.h" - -#include "cairo-paginated-private.h" -#include "cairo-paginated-surface-private.h" -#include "cairo-recording-surface-private.h" -#include "cairo-analysis-surface-private.h" -#include "cairo-error-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-surface-subsurface-inline.h" - -static const cairo_surface_backend_t cairo_paginated_surface_backend; - -static cairo_int_status_t -_cairo_paginated_surface_show_page (void *abstract_surface); - -static cairo_surface_t * -_cairo_paginated_surface_create_similar (void *abstract_surface, - cairo_content_t content, - int width, - int height) -{ - cairo_rectangle_t rect; - rect.x = rect.y = 0.; - rect.width = width; - rect.height = height; - return cairo_recording_surface_create (content, &rect); -} - -static cairo_surface_t * -_create_recording_surface_for_target (cairo_surface_t *target, - cairo_content_t content) -{ - cairo_rectangle_int_t rect; - - if (_cairo_surface_get_extents (target, &rect)) { - cairo_rectangle_t recording_extents; - - recording_extents.x = rect.x; - recording_extents.y = rect.y; - recording_extents.width = rect.width; - recording_extents.height = rect.height; - - return cairo_recording_surface_create (content, &recording_extents); - } else { - return cairo_recording_surface_create (content, NULL); - } -} - -cairo_surface_t * -_cairo_paginated_surface_create (cairo_surface_t *target, - cairo_content_t content, - const cairo_paginated_surface_backend_t *backend) -{ - cairo_paginated_surface_t *surface; - cairo_status_t status; - - surface = malloc (sizeof (cairo_paginated_surface_t)); - if (unlikely (surface == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto FAIL; - } - - _cairo_surface_init (&surface->base, - &cairo_paginated_surface_backend, - NULL, /* device */ - content); - - /* 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 = target->type; - - surface->target = cairo_surface_reference (target); - - surface->content = content; - surface->backend = backend; - - surface->recording_surface = _create_recording_surface_for_target (target, content); - status = surface->recording_surface->status; - if (unlikely (status)) - goto FAIL_CLEANUP_SURFACE; - - surface->page_num = 1; - surface->base.is_clear = TRUE; - - return &surface->base; - - FAIL_CLEANUP_SURFACE: - cairo_surface_destroy (target); - free (surface); - FAIL: - return _cairo_surface_create_in_error (status); -} - -cairo_bool_t -_cairo_surface_is_paginated (cairo_surface_t *surface) -{ - return surface->backend == &cairo_paginated_surface_backend; -} - -cairo_surface_t * -_cairo_paginated_surface_get_target (cairo_surface_t *surface) -{ - cairo_paginated_surface_t *paginated_surface; - - assert (_cairo_surface_is_paginated (surface)); - - paginated_surface = (cairo_paginated_surface_t *) surface; - return paginated_surface->target; -} - -cairo_surface_t * -_cairo_paginated_surface_get_recording (cairo_surface_t *surface) -{ - cairo_paginated_surface_t *paginated_surface; - - assert (_cairo_surface_is_paginated (surface)); - - paginated_surface = (cairo_paginated_surface_t *) surface; - return paginated_surface->recording_surface; -} - -cairo_status_t -_cairo_paginated_surface_set_size (cairo_surface_t *surface, - int width, - int height) -{ - cairo_paginated_surface_t *paginated_surface; - cairo_status_t status; - cairo_rectangle_t recording_extents; - - assert (_cairo_surface_is_paginated (surface)); - - paginated_surface = (cairo_paginated_surface_t *) surface; - - recording_extents.x = 0; - recording_extents.y = 0; - recording_extents.width = width; - recording_extents.height = height; - - cairo_surface_destroy (paginated_surface->recording_surface); - paginated_surface->recording_surface = cairo_recording_surface_create (paginated_surface->content, - &recording_extents); - status = paginated_surface->recording_surface->status; - if (unlikely (status)) - return _cairo_surface_set_error (surface, status); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_paginated_surface_finish (void *abstract_surface) -{ - cairo_paginated_surface_t *surface = abstract_surface; - cairo_status_t status = CAIRO_STATUS_SUCCESS; - - if (! surface->base.is_clear || surface->page_num == 1) { - /* Bypass some of the sanity checking in cairo-surface.c, as we - * know that the surface is finished... - */ - status = _cairo_paginated_surface_show_page (surface); - } - - /* XXX We want to propagate any errors from destroy(), but those are not - * returned via the api. So we need to explicitly finish the target, - * and check the status afterwards. However, we can only call finish() - * on the target, if we own it. - */ - if (CAIRO_REFERENCE_COUNT_GET_VALUE (&surface->target->ref_count) == 1) - cairo_surface_finish (surface->target); - if (status == CAIRO_STATUS_SUCCESS) - status = cairo_surface_status (surface->target); - cairo_surface_destroy (surface->target); - - cairo_surface_finish (surface->recording_surface); - if (status == CAIRO_STATUS_SUCCESS) - status = cairo_surface_status (surface->recording_surface); - cairo_surface_destroy (surface->recording_surface); - - return status; -} - -static cairo_surface_t * -_cairo_paginated_surface_create_image_surface (void *abstract_surface, - int width, - int height) -{ - cairo_paginated_surface_t *surface = abstract_surface; - cairo_surface_t *image; - cairo_font_options_t options; - - image = _cairo_image_surface_create_with_content (surface->content, - width, - height); - - cairo_surface_get_font_options (&surface->base, &options); - _cairo_surface_set_font_options (image, &options); - - return image; -} - -static cairo_surface_t * -_cairo_paginated_surface_source (void *abstract_surface, - cairo_rectangle_int_t *extents) -{ - cairo_paginated_surface_t *surface = abstract_surface; - return _cairo_surface_get_source (surface->target, extents); -} - -static cairo_status_t -_cairo_paginated_surface_acquire_source_image (void *abstract_surface, - cairo_image_surface_t **image_out, - void **image_extra) -{ - cairo_paginated_surface_t *surface = abstract_surface; - cairo_bool_t is_bounded; - cairo_surface_t *image; - cairo_status_t status; - cairo_rectangle_int_t extents; - - is_bounded = _cairo_surface_get_extents (surface->target, &extents); - if (! is_bounded) - return CAIRO_INT_STATUS_UNSUPPORTED; - - image = _cairo_paginated_surface_create_image_surface (surface, - extents.width, - extents.height); - - status = _cairo_recording_surface_replay (surface->recording_surface, image); - if (unlikely (status)) { - cairo_surface_destroy (image); - return status; - } - - *image_out = (cairo_image_surface_t*) image; - *image_extra = NULL; - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_paginated_surface_release_source_image (void *abstract_surface, - cairo_image_surface_t *image, - void *image_extra) -{ - cairo_surface_destroy (&image->base); -} - -static cairo_int_status_t -_paint_fallback_image (cairo_paginated_surface_t *surface, - cairo_rectangle_int_t *rect) -{ - double x_scale = surface->base.x_fallback_resolution / surface->target->x_resolution; - double y_scale = surface->base.y_fallback_resolution / surface->target->y_resolution; - int x, y, width, height; - cairo_status_t status; - cairo_surface_t *image; - cairo_surface_pattern_t pattern; - cairo_clip_t *clip; - - x = rect->x; - y = rect->y; - width = rect->width; - height = rect->height; - image = _cairo_paginated_surface_create_image_surface (surface, - ceil (width * x_scale), - ceil (height * y_scale)); - cairo_surface_set_device_scale (image, x_scale, y_scale); - /* set_device_offset just sets the x0/y0 components of the matrix; - * so we have to do the scaling manually. */ - cairo_surface_set_device_offset (image, -x*x_scale, -y*y_scale); - - status = _cairo_recording_surface_replay (surface->recording_surface, image); - if (unlikely (status)) - goto CLEANUP_IMAGE; - - _cairo_pattern_init_for_surface (&pattern, image); - cairo_matrix_init (&pattern.base.matrix, - x_scale, 0, 0, y_scale, -x*x_scale, -y*y_scale); - /* the fallback should be rendered at native resolution, so disable - * filtering (if possible) to avoid introducing potential artifacts. */ - pattern.base.filter = CAIRO_FILTER_NEAREST; - - clip = _cairo_clip_intersect_rectangle (NULL, rect); - status = _cairo_surface_paint (surface->target, - CAIRO_OPERATOR_SOURCE, - &pattern.base, clip); - _cairo_clip_destroy (clip); - _cairo_pattern_fini (&pattern.base); - -CLEANUP_IMAGE: - cairo_surface_destroy (image); - - return status; -} - -static cairo_int_status_t -_paint_page (cairo_paginated_surface_t *surface) -{ - cairo_surface_t *analysis; - cairo_int_status_t status; - cairo_bool_t has_supported, has_page_fallback, has_finegrained_fallback; - - if (unlikely (surface->target->status)) - return surface->target->status; - - analysis = _cairo_analysis_surface_create (surface->target); - if (unlikely (analysis->status)) - return _cairo_surface_set_error (surface->target, analysis->status); - - surface->backend->set_paginated_mode (surface->target, - CAIRO_PAGINATED_MODE_ANALYZE); - status = _cairo_recording_surface_replay_and_create_regions (surface->recording_surface, - analysis); - if (status) - goto FAIL; - - assert (analysis->status == CAIRO_STATUS_SUCCESS); - - if (surface->backend->set_bounding_box) { - cairo_box_t bbox; - - _cairo_analysis_surface_get_bounding_box (analysis, &bbox); - status = surface->backend->set_bounding_box (surface->target, &bbox); - if (unlikely (status)) - goto FAIL; - } - - if (surface->backend->set_fallback_images_required) { - cairo_bool_t has_fallbacks = _cairo_analysis_surface_has_unsupported (analysis); - - status = surface->backend->set_fallback_images_required (surface->target, - has_fallbacks); - if (unlikely (status)) - goto FAIL; - } - - /* Finer grained fallbacks are currently only supported for some - * surface types */ - if (surface->backend->supports_fine_grained_fallbacks != NULL && - surface->backend->supports_fine_grained_fallbacks (surface->target)) - { - has_supported = _cairo_analysis_surface_has_supported (analysis); - has_page_fallback = FALSE; - has_finegrained_fallback = _cairo_analysis_surface_has_unsupported (analysis); - } - else - { - if (_cairo_analysis_surface_has_unsupported (analysis)) { - has_supported = FALSE; - has_page_fallback = TRUE; - } else { - has_supported = TRUE; - has_page_fallback = FALSE; - } - has_finegrained_fallback = FALSE; - } - - if (has_supported) { - surface->backend->set_paginated_mode (surface->target, - CAIRO_PAGINATED_MODE_RENDER); - - status = _cairo_recording_surface_replay_region (surface->recording_surface, - NULL, - surface->target, - CAIRO_RECORDING_REGION_NATIVE); - assert (status != CAIRO_INT_STATUS_UNSUPPORTED); - if (unlikely (status)) - goto FAIL; - } - - if (has_page_fallback) { - cairo_rectangle_int_t extents; - cairo_bool_t is_bounded; - - surface->backend->set_paginated_mode (surface->target, - CAIRO_PAGINATED_MODE_FALLBACK); - - is_bounded = _cairo_surface_get_extents (surface->target, &extents); - if (! is_bounded) { - status = CAIRO_INT_STATUS_UNSUPPORTED; - goto FAIL; - } - - status = _paint_fallback_image (surface, &extents); - if (unlikely (status)) - goto FAIL; - } - - if (has_finegrained_fallback) { - cairo_region_t *region; - int num_rects, i; - - surface->backend->set_paginated_mode (surface->target, - CAIRO_PAGINATED_MODE_FALLBACK); - - region = _cairo_analysis_surface_get_unsupported (analysis); - - num_rects = cairo_region_num_rectangles (region); - for (i = 0; i < num_rects; i++) { - cairo_rectangle_int_t rect; - - cairo_region_get_rectangle (region, i, &rect); - status = _paint_fallback_image (surface, &rect); - if (unlikely (status)) - goto FAIL; - } - } - - FAIL: - cairo_surface_destroy (analysis); - - return _cairo_surface_set_error (surface->target, status); -} - -static cairo_status_t -_start_page (cairo_paginated_surface_t *surface) -{ - if (surface->target->status) - return surface->target->status; - - if (! surface->backend->start_page) - return CAIRO_STATUS_SUCCESS; - - return _cairo_surface_set_error (surface->target, - surface->backend->start_page (surface->target)); -} - -static cairo_int_status_t -_cairo_paginated_surface_copy_page (void *abstract_surface) -{ - cairo_status_t status; - cairo_paginated_surface_t *surface = abstract_surface; - - status = _start_page (surface); - if (unlikely (status)) - return status; - - status = _paint_page (surface); - if (unlikely (status)) - return status; - - surface->page_num++; - - /* XXX: It might make sense to add some support here for calling - * cairo_surface_copy_page on the target surface. It would be an - * optimization for the output, but the interaction with image - * fallbacks gets tricky. For now, we just let the target see a - * show_page and we implement the copying by simply not destroying - * the recording-surface. */ - - cairo_surface_show_page (surface->target); - return cairo_surface_status (surface->target); -} - -static cairo_int_status_t -_cairo_paginated_surface_show_page (void *abstract_surface) -{ - cairo_status_t status; - cairo_paginated_surface_t *surface = abstract_surface; - - status = _start_page (surface); - if (unlikely (status)) - return status; - - status = _paint_page (surface); - if (unlikely (status)) - return status; - - cairo_surface_show_page (surface->target); - status = surface->target->status; - if (unlikely (status)) - return status; - - status = surface->recording_surface->status; - if (unlikely (status)) - return status; - - if (! surface->base.finished) { - cairo_surface_destroy (surface->recording_surface); - - surface->recording_surface = _create_recording_surface_for_target (surface->target, - surface->content); - status = surface->recording_surface->status; - if (unlikely (status)) - return status; - - surface->page_num++; - surface->base.is_clear = TRUE; - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_bool_t -_cairo_paginated_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *rectangle) -{ - cairo_paginated_surface_t *surface = abstract_surface; - - return _cairo_surface_get_extents (surface->target, rectangle); -} - -static void -_cairo_paginated_surface_get_font_options (void *abstract_surface, - cairo_font_options_t *options) -{ - cairo_paginated_surface_t *surface = abstract_surface; - - cairo_surface_get_font_options (surface->target, options); -} - -static cairo_int_status_t -_cairo_paginated_surface_paint (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - cairo_paginated_surface_t *surface = abstract_surface; - - return _cairo_surface_paint (surface->recording_surface, op, source, clip); -} - -static cairo_int_status_t -_cairo_paginated_surface_mask (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - cairo_paginated_surface_t *surface = abstract_surface; - - return _cairo_surface_mask (surface->recording_surface, op, source, mask, clip); -} - -static cairo_int_status_t -_cairo_paginated_surface_stroke (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_paginated_surface_t *surface = abstract_surface; - - return _cairo_surface_stroke (surface->recording_surface, op, source, - path, style, - ctm, ctm_inverse, - tolerance, antialias, - clip); -} - -static cairo_int_status_t -_cairo_paginated_surface_fill (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_paginated_surface_t *surface = abstract_surface; - - return _cairo_surface_fill (surface->recording_surface, op, source, - path, fill_rule, - tolerance, antialias, - clip); -} - -static cairo_bool_t -_cairo_paginated_surface_has_show_text_glyphs (void *abstract_surface) -{ - cairo_paginated_surface_t *surface = abstract_surface; - - return cairo_surface_has_show_text_glyphs (surface->target); -} - -static cairo_int_status_t -_cairo_paginated_surface_show_text_glyphs (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const char *utf8, - int utf8_len, - cairo_glyph_t *glyphs, - int num_glyphs, - const cairo_text_cluster_t *clusters, - int num_clusters, - cairo_text_cluster_flags_t cluster_flags, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - cairo_paginated_surface_t *surface = abstract_surface; - - return _cairo_surface_show_text_glyphs (surface->recording_surface, op, source, - utf8, utf8_len, - glyphs, num_glyphs, - clusters, num_clusters, - cluster_flags, - scaled_font, - clip); -} - -static const char ** -_cairo_paginated_surface_get_supported_mime_types (void *abstract_surface) -{ - cairo_paginated_surface_t *surface = abstract_surface; - - if (surface->target->backend->get_supported_mime_types) - return surface->target->backend->get_supported_mime_types (surface->target); - - return NULL; -} - -static cairo_surface_t * -_cairo_paginated_surface_snapshot (void *abstract_other) -{ - cairo_paginated_surface_t *other = abstract_other; - - return other->recording_surface->backend->snapshot (other->recording_surface); -} - -static cairo_t * -_cairo_paginated_context_create (void *target) -{ - cairo_paginated_surface_t *surface = target; - - if (_cairo_surface_is_subsurface (&surface->base)) - surface = (cairo_paginated_surface_t *) - _cairo_surface_subsurface_get_target (&surface->base); - - return surface->recording_surface->backend->create_context (target); -} - -static const cairo_surface_backend_t cairo_paginated_surface_backend = { - CAIRO_INTERNAL_SURFACE_TYPE_PAGINATED, - _cairo_paginated_surface_finish, - - _cairo_paginated_context_create, - - _cairo_paginated_surface_create_similar, - NULL, /* create simlar image */ - NULL, /* map to image */ - NULL, /* unmap image */ - - _cairo_paginated_surface_source, - _cairo_paginated_surface_acquire_source_image, - _cairo_paginated_surface_release_source_image, - _cairo_paginated_surface_snapshot, - - _cairo_paginated_surface_copy_page, - _cairo_paginated_surface_show_page, - - _cairo_paginated_surface_get_extents, - _cairo_paginated_surface_get_font_options, - - NULL, /* flush */ - NULL, /* mark_dirty_rectangle */ - - _cairo_paginated_surface_paint, - _cairo_paginated_surface_mask, - _cairo_paginated_surface_stroke, - _cairo_paginated_surface_fill, - NULL, /* fill_stroke */ - NULL, /* show_glyphs */ - _cairo_paginated_surface_has_show_text_glyphs, - _cairo_paginated_surface_show_text_glyphs, - _cairo_paginated_surface_get_supported_mime_types, -}; diff --git a/source/libs/cairo/cairo-src/src/cairo-path-bounds.c b/source/libs/cairo/cairo-src/src/cairo-path-bounds.c deleted file mode 100644 index 9c7222426d3753a7a3cc55642faff09bc64d651b..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-path-bounds.c +++ /dev/null @@ -1,207 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2003 University of Southern California - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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" -#include "cairo-box-inline.h" -#include "cairo-error-private.h" -#include "cairo-path-fixed-private.h" - -typedef struct _cairo_path_bounder { - cairo_point_t current_point; - cairo_bool_t has_extents; - cairo_box_t extents; -} cairo_path_bounder_t; - -static cairo_status_t -_cairo_path_bounder_move_to (void *closure, - const cairo_point_t *point) -{ - cairo_path_bounder_t *bounder = closure; - - bounder->current_point = *point; - - if (likely (bounder->has_extents)) { - _cairo_box_add_point (&bounder->extents, point); - } else { - bounder->has_extents = TRUE; - _cairo_box_set (&bounder->extents, point, point); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_path_bounder_line_to (void *closure, - const cairo_point_t *point) -{ - cairo_path_bounder_t *bounder = closure; - - bounder->current_point = *point; - _cairo_box_add_point (&bounder->extents, point); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_path_bounder_curve_to (void *closure, - const cairo_point_t *b, - const cairo_point_t *c, - const cairo_point_t *d) -{ - cairo_path_bounder_t *bounder = closure; - - _cairo_box_add_curve_to (&bounder->extents, - &bounder->current_point, - b, c, d); - bounder->current_point = *d; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_path_bounder_close_path (void *closure) -{ - return CAIRO_STATUS_SUCCESS; -} - -cairo_bool_t -_cairo_path_bounder_extents (const cairo_path_fixed_t *path, - cairo_box_t *extents) -{ - cairo_path_bounder_t bounder; - cairo_status_t status; - - bounder.has_extents = FALSE; - status = _cairo_path_fixed_interpret (path, - _cairo_path_bounder_move_to, - _cairo_path_bounder_line_to, - _cairo_path_bounder_curve_to, - _cairo_path_bounder_close_path, - &bounder); - assert (!status); - - if (bounder.has_extents) - *extents = bounder.extents; - - return bounder.has_extents; -} - -void -_cairo_path_fixed_approximate_clip_extents (const cairo_path_fixed_t *path, - cairo_rectangle_int_t *extents) -{ - _cairo_path_fixed_approximate_fill_extents (path, extents); -} - -void -_cairo_path_fixed_approximate_fill_extents (const cairo_path_fixed_t *path, - cairo_rectangle_int_t *extents) -{ - _cairo_path_fixed_fill_extents (path, CAIRO_FILL_RULE_WINDING, 0, extents); -} - -void -_cairo_path_fixed_fill_extents (const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_rectangle_int_t *extents) -{ - if (path->extents.p1.x < path->extents.p2.x && - path->extents.p1.y < path->extents.p2.y) { - _cairo_box_round_to_rectangle (&path->extents, extents); - } else { - extents->x = extents->y = 0; - extents->width = extents->height = 0; - } -} - -/* Adjusts the fill extents (above) by the device-space pen. */ -void -_cairo_path_fixed_approximate_stroke_extents (const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - cairo_rectangle_int_t *extents) -{ - if (path->has_extents) { - cairo_box_t box_extents; - double dx, dy; - - _cairo_stroke_style_max_distance_from_path (style, path, ctm, &dx, &dy); - - box_extents = path->extents; - box_extents.p1.x -= _cairo_fixed_from_double (dx); - box_extents.p1.y -= _cairo_fixed_from_double (dy); - box_extents.p2.x += _cairo_fixed_from_double (dx); - box_extents.p2.y += _cairo_fixed_from_double (dy); - - _cairo_box_round_to_rectangle (&box_extents, extents); - } else { - extents->x = extents->y = 0; - extents->width = extents->height = 0; - } -} - -cairo_status_t -_cairo_path_fixed_stroke_extents (const cairo_path_fixed_t *path, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_rectangle_int_t *extents) -{ - cairo_polygon_t polygon; - cairo_status_t status; - - _cairo_polygon_init (&polygon, NULL, 0); - status = _cairo_path_fixed_stroke_to_polygon (path, - stroke_style, - ctm, ctm_inverse, - tolerance, - &polygon); - _cairo_box_round_to_rectangle (&polygon.extents, extents); - _cairo_polygon_fini (&polygon); - - return status; -} - -cairo_bool_t -_cairo_path_fixed_extents (const cairo_path_fixed_t *path, - cairo_box_t *box) -{ - *box = path->extents; - return path->has_extents; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-path-fill.c b/source/libs/cairo/cairo-src/src/cairo-path-fill.c deleted file mode 100644 index 4000c9c586ee24ae705402ba8cdf1e79bf3a8f3b..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-path-fill.c +++ /dev/null @@ -1,341 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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" -#include "cairo-boxes-private.h" -#include "cairo-error-private.h" -#include "cairo-path-fixed-private.h" -#include "cairo-region-private.h" -#include "cairo-traps-private.h" - -typedef struct cairo_filler { - cairo_polygon_t *polygon; - double tolerance; - - cairo_box_t limit; - cairo_bool_t has_limits; - - cairo_point_t current_point; - cairo_point_t last_move_to; -} cairo_filler_t; - -static cairo_status_t -_cairo_filler_line_to (void *closure, - const cairo_point_t *point) -{ - cairo_filler_t *filler = closure; - cairo_status_t status; - - status = _cairo_polygon_add_external_edge (filler->polygon, - &filler->current_point, - point); - - filler->current_point = *point; - - return status; -} - -static cairo_status_t -_cairo_filler_close (void *closure) -{ - cairo_filler_t *filler = closure; - - /* close the subpath */ - return _cairo_filler_line_to (closure, &filler->last_move_to); -} - -static cairo_status_t -_cairo_filler_move_to (void *closure, - const cairo_point_t *point) -{ - cairo_filler_t *filler = closure; - cairo_status_t status; - - /* close current subpath */ - status = _cairo_filler_close (closure); - if (unlikely (status)) - return status; - - /* make sure that the closure represents a degenerate path */ - filler->current_point = *point; - filler->last_move_to = *point; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_filler_curve_to (void *closure, - const cairo_point_t *p1, - const cairo_point_t *p2, - const cairo_point_t *p3) -{ - cairo_filler_t *filler = closure; - cairo_spline_t spline; - - if (filler->has_limits) { - if (! _cairo_spline_intersects (&filler->current_point, p1, p2, p3, - &filler->limit)) - return _cairo_filler_line_to (filler, p3); - } - - if (! _cairo_spline_init (&spline, - (cairo_spline_add_point_func_t)_cairo_filler_line_to, filler, - &filler->current_point, p1, p2, p3)) - { - return _cairo_filler_line_to (closure, p3); - } - - return _cairo_spline_decompose (&spline, filler->tolerance); -} - -cairo_status_t -_cairo_path_fixed_fill_to_polygon (const cairo_path_fixed_t *path, - double tolerance, - cairo_polygon_t *polygon) -{ - cairo_filler_t filler; - cairo_status_t status; - - filler.polygon = polygon; - filler.tolerance = tolerance; - - filler.has_limits = FALSE; - if (polygon->num_limits) { - filler.has_limits = TRUE; - filler.limit = polygon->limit; - } - - /* make sure that the closure represents a degenerate path */ - filler.current_point.x = 0; - filler.current_point.y = 0; - filler.last_move_to = filler.current_point; - - status = _cairo_path_fixed_interpret (path, - _cairo_filler_move_to, - _cairo_filler_line_to, - _cairo_filler_curve_to, - _cairo_filler_close, - &filler); - if (unlikely (status)) - return status; - - return _cairo_filler_close (&filler); -} - -typedef struct cairo_filler_rectilinear_aligned { - cairo_polygon_t *polygon; - - cairo_point_t current_point; - cairo_point_t last_move_to; -} cairo_filler_ra_t; - -static cairo_status_t -_cairo_filler_ra_line_to (void *closure, - const cairo_point_t *point) -{ - cairo_filler_ra_t *filler = closure; - cairo_status_t status; - cairo_point_t p; - - p.x = _cairo_fixed_round_down (point->x); - p.y = _cairo_fixed_round_down (point->y); - - status = _cairo_polygon_add_external_edge (filler->polygon, - &filler->current_point, - &p); - - filler->current_point = p; - - return status; -} - -static cairo_status_t -_cairo_filler_ra_close (void *closure) -{ - cairo_filler_ra_t *filler = closure; - return _cairo_filler_ra_line_to (closure, &filler->last_move_to); -} - -static cairo_status_t -_cairo_filler_ra_move_to (void *closure, - const cairo_point_t *point) -{ - cairo_filler_ra_t *filler = closure; - cairo_status_t status; - cairo_point_t p; - - /* close current subpath */ - status = _cairo_filler_ra_close (closure); - if (unlikely (status)) - return status; - - p.x = _cairo_fixed_round_down (point->x); - p.y = _cairo_fixed_round_down (point->y); - - /* make sure that the closure represents a degenerate path */ - filler->current_point = p; - filler->last_move_to = p; - - return CAIRO_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_path_fixed_fill_rectilinear_to_polygon (const cairo_path_fixed_t *path, - cairo_antialias_t antialias, - cairo_polygon_t *polygon) -{ - cairo_filler_ra_t filler; - cairo_status_t status; - - if (antialias != CAIRO_ANTIALIAS_NONE) - return _cairo_path_fixed_fill_to_polygon (path, 0., polygon); - - filler.polygon = polygon; - - /* make sure that the closure represents a degenerate path */ - filler.current_point.x = 0; - filler.current_point.y = 0; - filler.last_move_to = filler.current_point; - - status = _cairo_path_fixed_interpret_flat (path, - _cairo_filler_ra_move_to, - _cairo_filler_ra_line_to, - _cairo_filler_ra_close, - &filler, - 0.); - if (unlikely (status)) - return status; - - return _cairo_filler_ra_close (&filler); -} - -cairo_status_t -_cairo_path_fixed_fill_to_traps (const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_traps_t *traps) -{ - cairo_polygon_t polygon; - cairo_status_t status; - - if (_cairo_path_fixed_fill_is_empty (path)) - return CAIRO_STATUS_SUCCESS; - - _cairo_polygon_init (&polygon, traps->limits, traps->num_limits); - status = _cairo_path_fixed_fill_to_polygon (path, tolerance, &polygon); - if (unlikely (status || polygon.num_edges == 0)) - goto CLEANUP; - - status = _cairo_bentley_ottmann_tessellate_polygon (traps, - &polygon, fill_rule); - - CLEANUP: - _cairo_polygon_fini (&polygon); - return status; -} - -static cairo_status_t -_cairo_path_fixed_fill_rectilinear_tessellate_to_boxes (const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - cairo_antialias_t antialias, - cairo_boxes_t *boxes) -{ - cairo_polygon_t polygon; - cairo_status_t status; - - _cairo_polygon_init (&polygon, boxes->limits, boxes->num_limits); - boxes->num_limits = 0; - - /* tolerance will be ignored as the path is rectilinear */ - status = _cairo_path_fixed_fill_rectilinear_to_polygon (path, antialias, &polygon); - if (likely (status == CAIRO_STATUS_SUCCESS)) { - status = - _cairo_bentley_ottmann_tessellate_rectilinear_polygon_to_boxes (&polygon, - fill_rule, - boxes); - } - - _cairo_polygon_fini (&polygon); - - return status; -} - -cairo_status_t -_cairo_path_fixed_fill_rectilinear_to_boxes (const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - cairo_antialias_t antialias, - cairo_boxes_t *boxes) -{ - cairo_path_fixed_iter_t iter; - cairo_status_t status; - cairo_box_t box; - - if (_cairo_path_fixed_is_box (path, &box)) - return _cairo_boxes_add (boxes, antialias, &box); - - _cairo_path_fixed_iter_init (&iter, path); - while (_cairo_path_fixed_iter_is_fill_box (&iter, &box)) { - if (box.p1.y == box.p2.y || box.p1.x == box.p2.x) - continue; - - if (box.p1.y > box.p2.y) { - cairo_fixed_t t; - - t = box.p1.y; - box.p1.y = box.p2.y; - box.p2.y = t; - - t = box.p1.x; - box.p1.x = box.p2.x; - box.p2.x = t; - } - - status = _cairo_boxes_add (boxes, antialias, &box); - if (unlikely (status)) - return status; - } - - if (_cairo_path_fixed_iter_at_end (&iter)) - return _cairo_bentley_ottmann_tessellate_boxes (boxes, fill_rule, boxes); - - /* path is not rectangular, try extracting clipped rectilinear edges */ - _cairo_boxes_clear (boxes); - return _cairo_path_fixed_fill_rectilinear_tessellate_to_boxes (path, - fill_rule, - antialias, - boxes); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-path-fixed-private.h b/source/libs/cairo/cairo-src/src/cairo-path-fixed-private.h deleted file mode 100644 index cf7cd0836fb106b2b60f577333798636b9f607ff..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-path-fixed-private.h +++ /dev/null @@ -1,206 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Carl D. Worth <cworth@redhat.com> - */ - -#ifndef CAIRO_PATH_FIXED_PRIVATE_H -#define CAIRO_PATH_FIXED_PRIVATE_H - -#include "cairo-types-private.h" -#include "cairo-compiler-private.h" -#include "cairo-list-private.h" - -#define WATCH_PATH 0 -#if WATCH_PATH -#include <stdio.h> -#endif - -enum cairo_path_op { - CAIRO_PATH_OP_MOVE_TO = 0, - CAIRO_PATH_OP_LINE_TO = 1, - CAIRO_PATH_OP_CURVE_TO = 2, - CAIRO_PATH_OP_CLOSE_PATH = 3 -}; - -/* we want to make sure a single byte is used for the enum */ -typedef char cairo_path_op_t; - -/* make _cairo_path_fixed fit into ~512 bytes -- about 50 items */ -#define CAIRO_PATH_BUF_SIZE ((512 - sizeof (cairo_path_buf_t)) \ - / (2 * sizeof (cairo_point_t) + sizeof (cairo_path_op_t))) - -#define cairo_path_head(path__) (&(path__)->buf.base) -#define cairo_path_tail(path__) cairo_path_buf_prev (cairo_path_head (path__)) - -#define cairo_path_buf_next(pos__) \ - cairo_list_entry ((pos__)->link.next, cairo_path_buf_t, link) -#define cairo_path_buf_prev(pos__) \ - cairo_list_entry ((pos__)->link.prev, cairo_path_buf_t, link) - -#define cairo_path_foreach_buf_start(pos__, path__) \ - pos__ = cairo_path_head (path__); do -#define cairo_path_foreach_buf_end(pos__, path__) \ - while ((pos__ = cairo_path_buf_next (pos__)) != cairo_path_head (path__)) - - -typedef struct _cairo_path_buf { - cairo_list_t link; - unsigned int num_ops; - unsigned int size_ops; - unsigned int num_points; - unsigned int size_points; - - cairo_path_op_t *op; - cairo_point_t *points; -} cairo_path_buf_t; - -typedef struct _cairo_path_buf_fixed { - cairo_path_buf_t base; - - cairo_path_op_t op[CAIRO_PATH_BUF_SIZE]; - cairo_point_t points[2 * CAIRO_PATH_BUF_SIZE]; -} cairo_path_buf_fixed_t; - -/* - NOTES: - has_curve_to => !stroke_is_rectilinear - fill_is_rectilinear => stroke_is_rectilinear - fill_is_empty => fill_is_rectilinear - fill_maybe_region => fill_is_rectilinear -*/ -struct _cairo_path_fixed { - cairo_point_t last_move_point; - cairo_point_t current_point; - unsigned int has_current_point : 1; - unsigned int needs_move_to : 1; - unsigned int has_extents : 1; - unsigned int has_curve_to : 1; - unsigned int stroke_is_rectilinear : 1; - unsigned int fill_is_rectilinear : 1; - unsigned int fill_maybe_region : 1; - unsigned int fill_is_empty : 1; - - cairo_box_t extents; - - cairo_path_buf_fixed_t buf; -}; - -cairo_private void -_cairo_path_fixed_translate (cairo_path_fixed_t *path, - cairo_fixed_t offx, - cairo_fixed_t offy); - -cairo_private cairo_status_t -_cairo_path_fixed_append (cairo_path_fixed_t *path, - const cairo_path_fixed_t *other, - cairo_fixed_t tx, - cairo_fixed_t ty); - -cairo_private unsigned long -_cairo_path_fixed_hash (const cairo_path_fixed_t *path); - -cairo_private unsigned long -_cairo_path_fixed_size (const cairo_path_fixed_t *path); - -cairo_private cairo_bool_t -_cairo_path_fixed_equal (const cairo_path_fixed_t *a, - const cairo_path_fixed_t *b); - -typedef struct _cairo_path_fixed_iter { - const cairo_path_buf_t *first; - const cairo_path_buf_t *buf; - unsigned int n_op; - unsigned int n_point; -} cairo_path_fixed_iter_t; - -cairo_private void -_cairo_path_fixed_iter_init (cairo_path_fixed_iter_t *iter, - const cairo_path_fixed_t *path); - -cairo_private cairo_bool_t -_cairo_path_fixed_iter_is_fill_box (cairo_path_fixed_iter_t *_iter, - cairo_box_t *box); - -cairo_private cairo_bool_t -_cairo_path_fixed_iter_at_end (const cairo_path_fixed_iter_t *iter); - -static inline cairo_bool_t -_cairo_path_fixed_fill_is_empty (const cairo_path_fixed_t *path) -{ - return path->fill_is_empty; -} - -static inline cairo_bool_t -_cairo_path_fixed_fill_is_rectilinear (const cairo_path_fixed_t *path) -{ - if (! path->fill_is_rectilinear) - return 0; - - if (! path->has_current_point || path->needs_move_to) - return 1; - - /* check whether the implicit close preserves the rectilinear property */ - return path->current_point.x == path->last_move_point.x || - path->current_point.y == path->last_move_point.y; -} - -static inline cairo_bool_t -_cairo_path_fixed_stroke_is_rectilinear (const cairo_path_fixed_t *path) -{ - return path->stroke_is_rectilinear; -} - -static inline cairo_bool_t -_cairo_path_fixed_fill_maybe_region (const cairo_path_fixed_t *path) -{ - if (! path->fill_maybe_region) - return 0; - - if (! path->has_current_point || path->needs_move_to) - return 1; - - /* check whether the implicit close preserves the rectilinear property - * (the integer point property is automatically preserved) - */ - return path->current_point.x == path->last_move_point.x || - path->current_point.y == path->last_move_point.y; -} - -cairo_private cairo_bool_t -_cairo_path_fixed_is_stroke_box (const cairo_path_fixed_t *path, - cairo_box_t *box); - -cairo_private cairo_bool_t -_cairo_path_fixed_is_simple_quad (const cairo_path_fixed_t *path); - -#endif /* CAIRO_PATH_FIXED_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-path-fixed.c b/source/libs/cairo/cairo-src/src/cairo-path-fixed.c deleted file mode 100644 index 4bbf496f075696a49d114e29f39ce37928bb754f..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-path-fixed.c +++ /dev/null @@ -1,1589 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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" - -#include "cairo-box-inline.h" -#include "cairo-error-private.h" -#include "cairo-list-inline.h" -#include "cairo-path-fixed-private.h" -#include "cairo-slope-private.h" - -static cairo_status_t -_cairo_path_fixed_add (cairo_path_fixed_t *path, - cairo_path_op_t op, - const cairo_point_t *points, - int num_points); - -static void -_cairo_path_fixed_add_buf (cairo_path_fixed_t *path, - cairo_path_buf_t *buf); - -static cairo_path_buf_t * -_cairo_path_buf_create (int size_ops, int size_points); - -static void -_cairo_path_buf_destroy (cairo_path_buf_t *buf); - -static void -_cairo_path_buf_add_op (cairo_path_buf_t *buf, - cairo_path_op_t op); - -static void -_cairo_path_buf_add_points (cairo_path_buf_t *buf, - const cairo_point_t *points, - int num_points); - -void -_cairo_path_fixed_init (cairo_path_fixed_t *path) -{ - VG (VALGRIND_MAKE_MEM_UNDEFINED (path, sizeof (cairo_path_fixed_t))); - - cairo_list_init (&path->buf.base.link); - - path->buf.base.num_ops = 0; - path->buf.base.num_points = 0; - path->buf.base.size_ops = ARRAY_LENGTH (path->buf.op); - path->buf.base.size_points = ARRAY_LENGTH (path->buf.points); - path->buf.base.op = path->buf.op; - path->buf.base.points = path->buf.points; - - path->current_point.x = 0; - path->current_point.y = 0; - path->last_move_point = path->current_point; - - path->has_current_point = FALSE; - path->needs_move_to = TRUE; - path->has_extents = FALSE; - path->has_curve_to = FALSE; - path->stroke_is_rectilinear = TRUE; - path->fill_is_rectilinear = TRUE; - path->fill_maybe_region = TRUE; - path->fill_is_empty = TRUE; - - path->extents.p1.x = path->extents.p1.y = 0; - path->extents.p2.x = path->extents.p2.y = 0; -} - -cairo_status_t -_cairo_path_fixed_init_copy (cairo_path_fixed_t *path, - const cairo_path_fixed_t *other) -{ - cairo_path_buf_t *buf, *other_buf; - unsigned int num_points, num_ops; - - VG (VALGRIND_MAKE_MEM_UNDEFINED (path, sizeof (cairo_path_fixed_t))); - - cairo_list_init (&path->buf.base.link); - - path->buf.base.op = path->buf.op; - path->buf.base.points = path->buf.points; - path->buf.base.size_ops = ARRAY_LENGTH (path->buf.op); - path->buf.base.size_points = ARRAY_LENGTH (path->buf.points); - - path->current_point = other->current_point; - path->last_move_point = other->last_move_point; - - path->has_current_point = other->has_current_point; - path->needs_move_to = other->needs_move_to; - path->has_extents = other->has_extents; - path->has_curve_to = other->has_curve_to; - path->stroke_is_rectilinear = other->stroke_is_rectilinear; - path->fill_is_rectilinear = other->fill_is_rectilinear; - path->fill_maybe_region = other->fill_maybe_region; - path->fill_is_empty = other->fill_is_empty; - - path->extents = other->extents; - - path->buf.base.num_ops = other->buf.base.num_ops; - path->buf.base.num_points = other->buf.base.num_points; - memcpy (path->buf.op, other->buf.base.op, - other->buf.base.num_ops * sizeof (other->buf.op[0])); - memcpy (path->buf.points, other->buf.points, - other->buf.base.num_points * sizeof (other->buf.points[0])); - - num_points = num_ops = 0; - for (other_buf = cairo_path_buf_next (cairo_path_head (other)); - other_buf != cairo_path_head (other); - other_buf = cairo_path_buf_next (other_buf)) - { - num_ops += other_buf->num_ops; - num_points += other_buf->num_points; - } - - if (num_ops) { - buf = _cairo_path_buf_create (num_ops, num_points); - if (unlikely (buf == NULL)) { - _cairo_path_fixed_fini (path); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - for (other_buf = cairo_path_buf_next (cairo_path_head (other)); - other_buf != cairo_path_head (other); - other_buf = cairo_path_buf_next (other_buf)) - { - memcpy (buf->op + buf->num_ops, other_buf->op, - other_buf->num_ops * sizeof (buf->op[0])); - buf->num_ops += other_buf->num_ops; - - memcpy (buf->points + buf->num_points, other_buf->points, - other_buf->num_points * sizeof (buf->points[0])); - buf->num_points += other_buf->num_points; - } - - _cairo_path_fixed_add_buf (path, buf); - } - - return CAIRO_STATUS_SUCCESS; -} - -unsigned long -_cairo_path_fixed_hash (const cairo_path_fixed_t *path) -{ - unsigned long hash = _CAIRO_HASH_INIT_VALUE; - const cairo_path_buf_t *buf; - unsigned int count; - - count = 0; - cairo_path_foreach_buf_start (buf, path) { - hash = _cairo_hash_bytes (hash, buf->op, - buf->num_ops * sizeof (buf->op[0])); - count += buf->num_ops; - } cairo_path_foreach_buf_end (buf, path); - hash = _cairo_hash_bytes (hash, &count, sizeof (count)); - - count = 0; - cairo_path_foreach_buf_start (buf, path) { - hash = _cairo_hash_bytes (hash, buf->points, - buf->num_points * sizeof (buf->points[0])); - count += buf->num_points; - } cairo_path_foreach_buf_end (buf, path); - hash = _cairo_hash_bytes (hash, &count, sizeof (count)); - - return hash; -} - -unsigned long -_cairo_path_fixed_size (const cairo_path_fixed_t *path) -{ - const cairo_path_buf_t *buf; - int num_points, num_ops; - - num_ops = num_points = 0; - cairo_path_foreach_buf_start (buf, path) { - num_ops += buf->num_ops; - num_points += buf->num_points; - } cairo_path_foreach_buf_end (buf, path); - - return num_ops * sizeof (buf->op[0]) + - num_points * sizeof (buf->points[0]); -} - -cairo_bool_t -_cairo_path_fixed_equal (const cairo_path_fixed_t *a, - const cairo_path_fixed_t *b) -{ - const cairo_path_buf_t *buf_a, *buf_b; - const cairo_path_op_t *ops_a, *ops_b; - const cairo_point_t *points_a, *points_b; - int num_points_a, num_ops_a; - int num_points_b, num_ops_b; - - if (a == b) - return TRUE; - - /* use the flags to quickly differentiate based on contents */ - if (a->has_curve_to != b->has_curve_to) - { - return FALSE; - } - - if (a->extents.p1.x != b->extents.p1.x || - a->extents.p1.y != b->extents.p1.y || - a->extents.p2.x != b->extents.p2.x || - a->extents.p2.y != b->extents.p2.y) - { - return FALSE; - } - - num_ops_a = num_points_a = 0; - cairo_path_foreach_buf_start (buf_a, a) { - num_ops_a += buf_a->num_ops; - num_points_a += buf_a->num_points; - } cairo_path_foreach_buf_end (buf_a, a); - - num_ops_b = num_points_b = 0; - cairo_path_foreach_buf_start (buf_b, b) { - num_ops_b += buf_b->num_ops; - num_points_b += buf_b->num_points; - } cairo_path_foreach_buf_end (buf_b, b); - - if (num_ops_a == 0 && num_ops_b == 0) - return TRUE; - - if (num_ops_a != num_ops_b || num_points_a != num_points_b) - return FALSE; - - buf_a = cairo_path_head (a); - num_points_a = buf_a->num_points; - num_ops_a = buf_a->num_ops; - ops_a = buf_a->op; - points_a = buf_a->points; - - buf_b = cairo_path_head (b); - num_points_b = buf_b->num_points; - num_ops_b = buf_b->num_ops; - ops_b = buf_b->op; - points_b = buf_b->points; - - while (TRUE) { - int num_ops = MIN (num_ops_a, num_ops_b); - int num_points = MIN (num_points_a, num_points_b); - - if (memcmp (ops_a, ops_b, num_ops * sizeof (cairo_path_op_t))) - return FALSE; - if (memcmp (points_a, points_b, num_points * sizeof (cairo_point_t))) - return FALSE; - - num_ops_a -= num_ops; - ops_a += num_ops; - num_points_a -= num_points; - points_a += num_points; - if (num_ops_a == 0 || num_points_a == 0) { - if (num_ops_a || num_points_a) - return FALSE; - - buf_a = cairo_path_buf_next (buf_a); - if (buf_a == cairo_path_head (a)) - break; - - num_points_a = buf_a->num_points; - num_ops_a = buf_a->num_ops; - ops_a = buf_a->op; - points_a = buf_a->points; - } - - num_ops_b -= num_ops; - ops_b += num_ops; - num_points_b -= num_points; - points_b += num_points; - if (num_ops_b == 0 || num_points_b == 0) { - if (num_ops_b || num_points_b) - return FALSE; - - buf_b = cairo_path_buf_next (buf_b); - if (buf_b == cairo_path_head (b)) - break; - - num_points_b = buf_b->num_points; - num_ops_b = buf_b->num_ops; - ops_b = buf_b->op; - points_b = buf_b->points; - } - } - - return TRUE; -} - -cairo_path_fixed_t * -_cairo_path_fixed_create (void) -{ - cairo_path_fixed_t *path; - - path = malloc (sizeof (cairo_path_fixed_t)); - if (!path) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return NULL; - } - - _cairo_path_fixed_init (path); - return path; -} - -void -_cairo_path_fixed_fini (cairo_path_fixed_t *path) -{ - cairo_path_buf_t *buf; - - buf = cairo_path_buf_next (cairo_path_head (path)); - while (buf != cairo_path_head (path)) { - cairo_path_buf_t *this = buf; - buf = cairo_path_buf_next (buf); - _cairo_path_buf_destroy (this); - } - - VG (VALGRIND_MAKE_MEM_NOACCESS (path, sizeof (cairo_path_fixed_t))); -} - -void -_cairo_path_fixed_destroy (cairo_path_fixed_t *path) -{ - _cairo_path_fixed_fini (path); - free (path); -} - -static cairo_path_op_t -_cairo_path_fixed_last_op (cairo_path_fixed_t *path) -{ - cairo_path_buf_t *buf; - - buf = cairo_path_tail (path); - assert (buf->num_ops != 0); - - return buf->op[buf->num_ops - 1]; -} - -static inline const cairo_point_t * -_cairo_path_fixed_penultimate_point (cairo_path_fixed_t *path) -{ - cairo_path_buf_t *buf; - - buf = cairo_path_tail (path); - if (likely (buf->num_points >= 2)) { - return &buf->points[buf->num_points - 2]; - } else { - cairo_path_buf_t *prev_buf = cairo_path_buf_prev (buf); - - assert (prev_buf->num_points >= 2 - buf->num_points); - return &prev_buf->points[prev_buf->num_points - (2 - buf->num_points)]; - } -} - -static void -_cairo_path_fixed_drop_line_to (cairo_path_fixed_t *path) -{ - cairo_path_buf_t *buf; - - assert (_cairo_path_fixed_last_op (path) == CAIRO_PATH_OP_LINE_TO); - - buf = cairo_path_tail (path); - buf->num_points--; - buf->num_ops--; -} - -cairo_status_t -_cairo_path_fixed_move_to (cairo_path_fixed_t *path, - cairo_fixed_t x, - cairo_fixed_t y) -{ - _cairo_path_fixed_new_sub_path (path); - - path->has_current_point = TRUE; - path->current_point.x = x; - path->current_point.y = y; - path->last_move_point = path->current_point; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_path_fixed_move_to_apply (cairo_path_fixed_t *path) -{ - if (likely (! path->needs_move_to)) - return CAIRO_STATUS_SUCCESS; - - path->needs_move_to = FALSE; - - if (path->has_extents) { - _cairo_box_add_point (&path->extents, &path->current_point); - } else { - _cairo_box_set (&path->extents, &path->current_point, &path->current_point); - path->has_extents = TRUE; - } - - if (path->fill_maybe_region) { - path->fill_maybe_region = _cairo_fixed_is_integer (path->current_point.x) && - _cairo_fixed_is_integer (path->current_point.y); - } - - path->last_move_point = path->current_point; - - return _cairo_path_fixed_add (path, CAIRO_PATH_OP_MOVE_TO, &path->current_point, 1); -} - -void -_cairo_path_fixed_new_sub_path (cairo_path_fixed_t *path) -{ - if (! path->needs_move_to) { - /* If the current subpath doesn't need_move_to, it contains at least one command */ - if (path->fill_is_rectilinear) { - /* Implicitly close for fill */ - path->fill_is_rectilinear = path->current_point.x == path->last_move_point.x || - path->current_point.y == path->last_move_point.y; - path->fill_maybe_region &= path->fill_is_rectilinear; - } - path->needs_move_to = TRUE; - } - - path->has_current_point = FALSE; -} - -cairo_status_t -_cairo_path_fixed_rel_move_to (cairo_path_fixed_t *path, - cairo_fixed_t dx, - cairo_fixed_t dy) -{ - if (unlikely (! path->has_current_point)) - return _cairo_error (CAIRO_STATUS_NO_CURRENT_POINT); - - return _cairo_path_fixed_move_to (path, - path->current_point.x + dx, - path->current_point.y + dy); - -} - -cairo_status_t -_cairo_path_fixed_line_to (cairo_path_fixed_t *path, - cairo_fixed_t x, - cairo_fixed_t y) -{ - cairo_status_t status; - cairo_point_t point; - - point.x = x; - point.y = y; - - /* When there is not yet a current point, the line_to operation - * becomes a move_to instead. Note: We have to do this by - * explicitly calling into _cairo_path_fixed_move_to to ensure - * that the last_move_point state is updated properly. - */ - if (! path->has_current_point) - return _cairo_path_fixed_move_to (path, point.x, point.y); - - status = _cairo_path_fixed_move_to_apply (path); - if (unlikely (status)) - return status; - - /* If the previous op was but the initial MOVE_TO and this segment - * is degenerate, then we can simply skip this point. Note that - * a move-to followed by a degenerate line-to is a valid path for - * stroking, but at all other times is simply a degenerate segment. - */ - if (_cairo_path_fixed_last_op (path) != CAIRO_PATH_OP_MOVE_TO) { - if (x == path->current_point.x && y == path->current_point.y) - return CAIRO_STATUS_SUCCESS; - } - - /* If the previous op was also a LINE_TO with the same gradient, - * then just change its end-point rather than adding a new op. - */ - if (_cairo_path_fixed_last_op (path) == CAIRO_PATH_OP_LINE_TO) { - const cairo_point_t *p; - - p = _cairo_path_fixed_penultimate_point (path); - if (p->x == path->current_point.x && p->y == path->current_point.y) { - /* previous line element was degenerate, replace */ - _cairo_path_fixed_drop_line_to (path); - } else { - cairo_slope_t prev, self; - - _cairo_slope_init (&prev, p, &path->current_point); - _cairo_slope_init (&self, &path->current_point, &point); - if (_cairo_slope_equal (&prev, &self) && - /* cannot trim anti-parallel segments whilst stroking */ - ! _cairo_slope_backwards (&prev, &self)) - { - _cairo_path_fixed_drop_line_to (path); - /* In this case the flags might be more restrictive than - * what we actually need. - * When changing the flags definition we should check if - * changing the line_to point can affect them. - */ - } - } - } - - if (path->stroke_is_rectilinear) { - path->stroke_is_rectilinear = path->current_point.x == x || - path->current_point.y == y; - path->fill_is_rectilinear &= path->stroke_is_rectilinear; - path->fill_maybe_region &= path->fill_is_rectilinear; - if (path->fill_maybe_region) { - path->fill_maybe_region = _cairo_fixed_is_integer (x) && - _cairo_fixed_is_integer (y); - } - if (path->fill_is_empty) { - path->fill_is_empty = path->current_point.x == x && - path->current_point.y == y; - } - } - - path->current_point = point; - - _cairo_box_add_point (&path->extents, &point); - - return _cairo_path_fixed_add (path, CAIRO_PATH_OP_LINE_TO, &point, 1); -} - -cairo_status_t -_cairo_path_fixed_rel_line_to (cairo_path_fixed_t *path, - cairo_fixed_t dx, - cairo_fixed_t dy) -{ - if (unlikely (! path->has_current_point)) - return _cairo_error (CAIRO_STATUS_NO_CURRENT_POINT); - - return _cairo_path_fixed_line_to (path, - path->current_point.x + dx, - path->current_point.y + dy); -} - -cairo_status_t -_cairo_path_fixed_curve_to (cairo_path_fixed_t *path, - cairo_fixed_t x0, cairo_fixed_t y0, - cairo_fixed_t x1, cairo_fixed_t y1, - cairo_fixed_t x2, cairo_fixed_t y2) -{ - cairo_status_t status; - cairo_point_t point[3]; - - /* If this curves does not move, replace it with a line-to. - * This frequently happens with rounded-rectangles and r==0. - */ - if (path->current_point.x == x2 && path->current_point.y == y2) { - if (x1 == x2 && x0 == x2 && y1 == y2 && y0 == y2) - return _cairo_path_fixed_line_to (path, x2, y2); - - /* We may want to check for the absence of a cusp, in which case - * we can also replace the curve-to with a line-to. - */ - } - - /* make sure subpaths are started properly */ - if (! path->has_current_point) { - status = _cairo_path_fixed_move_to (path, x0, y0); - assert (status == CAIRO_STATUS_SUCCESS); - } - - status = _cairo_path_fixed_move_to_apply (path); - if (unlikely (status)) - return status; - - /* If the previous op was a degenerate LINE_TO, drop it. */ - if (_cairo_path_fixed_last_op (path) == CAIRO_PATH_OP_LINE_TO) { - const cairo_point_t *p; - - p = _cairo_path_fixed_penultimate_point (path); - if (p->x == path->current_point.x && p->y == path->current_point.y) { - /* previous line element was degenerate, replace */ - _cairo_path_fixed_drop_line_to (path); - } - } - - point[0].x = x0; point[0].y = y0; - point[1].x = x1; point[1].y = y1; - point[2].x = x2; point[2].y = y2; - - _cairo_box_add_curve_to (&path->extents, &path->current_point, - &point[0], &point[1], &point[2]); - - path->current_point = point[2]; - path->has_curve_to = TRUE; - path->stroke_is_rectilinear = FALSE; - path->fill_is_rectilinear = FALSE; - path->fill_maybe_region = FALSE; - path->fill_is_empty = FALSE; - - return _cairo_path_fixed_add (path, CAIRO_PATH_OP_CURVE_TO, point, 3); -} - -cairo_status_t -_cairo_path_fixed_rel_curve_to (cairo_path_fixed_t *path, - cairo_fixed_t dx0, cairo_fixed_t dy0, - cairo_fixed_t dx1, cairo_fixed_t dy1, - cairo_fixed_t dx2, cairo_fixed_t dy2) -{ - if (unlikely (! path->has_current_point)) - return _cairo_error (CAIRO_STATUS_NO_CURRENT_POINT); - - return _cairo_path_fixed_curve_to (path, - path->current_point.x + dx0, - path->current_point.y + dy0, - - path->current_point.x + dx1, - path->current_point.y + dy1, - - path->current_point.x + dx2, - path->current_point.y + dy2); -} - -cairo_status_t -_cairo_path_fixed_close_path (cairo_path_fixed_t *path) -{ - cairo_status_t status; - - if (! path->has_current_point) - return CAIRO_STATUS_SUCCESS; - - /* - * Add a line_to, to compute flags and solve any degeneracy. - * It will be removed later (if it was actually added). - */ - status = _cairo_path_fixed_line_to (path, - path->last_move_point.x, - path->last_move_point.y); - if (unlikely (status)) - return status; - - /* - * If the command used to close the path is a line_to, drop it. - * We must check that last command is actually a line_to, - * because the path could have been closed with a curve_to (and - * the previous line_to not added as it would be degenerate). - */ - if (_cairo_path_fixed_last_op (path) == CAIRO_PATH_OP_LINE_TO) - _cairo_path_fixed_drop_line_to (path); - - path->needs_move_to = TRUE; /* After close_path, add an implicit move_to */ - - return _cairo_path_fixed_add (path, CAIRO_PATH_OP_CLOSE_PATH, NULL, 0); -} - -cairo_bool_t -_cairo_path_fixed_get_current_point (cairo_path_fixed_t *path, - cairo_fixed_t *x, - cairo_fixed_t *y) -{ - if (! path->has_current_point) - return FALSE; - - *x = path->current_point.x; - *y = path->current_point.y; - - return TRUE; -} - -static cairo_status_t -_cairo_path_fixed_add (cairo_path_fixed_t *path, - cairo_path_op_t op, - const cairo_point_t *points, - int num_points) -{ - cairo_path_buf_t *buf = cairo_path_tail (path); - - if (buf->num_ops + 1 > buf->size_ops || - buf->num_points + num_points > buf->size_points) - { - buf = _cairo_path_buf_create (buf->num_ops * 2, buf->num_points * 2); - if (unlikely (buf == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_path_fixed_add_buf (path, buf); - } - - if (WATCH_PATH) { - const char *op_str[] = { - "move-to", - "line-to", - "curve-to", - "close-path", - }; - char buf[1024]; - int len = 0; - int i; - - len += snprintf (buf + len, sizeof (buf), "["); - for (i = 0; i < num_points; i++) { - if (i != 0) - len += snprintf (buf + len, sizeof (buf), " "); - len += snprintf (buf + len, sizeof (buf), "(%f, %f)", - _cairo_fixed_to_double (points[i].x), - _cairo_fixed_to_double (points[i].y)); - } - len += snprintf (buf + len, sizeof (buf), "]"); - -#define STRINGIFYFLAG(x) (path->x ? #x " " : "") - fprintf (stderr, - "_cairo_path_fixed_add (%s, %s) [%s%s%s%s%s%s%s%s]\n", - op_str[(int) op], buf, - STRINGIFYFLAG(has_current_point), - STRINGIFYFLAG(needs_move_to), - STRINGIFYFLAG(has_extents), - STRINGIFYFLAG(has_curve_to), - STRINGIFYFLAG(stroke_is_rectilinear), - STRINGIFYFLAG(fill_is_rectilinear), - STRINGIFYFLAG(fill_is_empty), - STRINGIFYFLAG(fill_maybe_region) - ); -#undef STRINGIFYFLAG - } - - _cairo_path_buf_add_op (buf, op); - _cairo_path_buf_add_points (buf, points, num_points); - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_path_fixed_add_buf (cairo_path_fixed_t *path, - cairo_path_buf_t *buf) -{ - cairo_list_add_tail (&buf->link, &cairo_path_head (path)->link); -} - -COMPILE_TIME_ASSERT (sizeof (cairo_path_op_t) == 1); -static cairo_path_buf_t * -_cairo_path_buf_create (int size_ops, int size_points) -{ - cairo_path_buf_t *buf; - - /* adjust size_ops to ensure that buf->points is naturally aligned */ - size_ops += sizeof (double) - ((sizeof (cairo_path_buf_t) + size_ops) % sizeof (double)); - buf = _cairo_malloc_ab_plus_c (size_points, sizeof (cairo_point_t), size_ops + sizeof (cairo_path_buf_t)); - if (buf) { - buf->num_ops = 0; - buf->num_points = 0; - buf->size_ops = size_ops; - buf->size_points = size_points; - - buf->op = (cairo_path_op_t *) (buf + 1); - buf->points = (cairo_point_t *) (buf->op + size_ops); - } - - return buf; -} - -static void -_cairo_path_buf_destroy (cairo_path_buf_t *buf) -{ - free (buf); -} - -static void -_cairo_path_buf_add_op (cairo_path_buf_t *buf, - cairo_path_op_t op) -{ - buf->op[buf->num_ops++] = op; -} - -static void -_cairo_path_buf_add_points (cairo_path_buf_t *buf, - const cairo_point_t *points, - int num_points) -{ - if (num_points == 0) - return; - - memcpy (buf->points + buf->num_points, - points, - sizeof (points[0]) * num_points); - buf->num_points += num_points; -} - -cairo_status_t -_cairo_path_fixed_interpret (const cairo_path_fixed_t *path, - cairo_path_fixed_move_to_func_t *move_to, - cairo_path_fixed_line_to_func_t *line_to, - cairo_path_fixed_curve_to_func_t *curve_to, - cairo_path_fixed_close_path_func_t *close_path, - void *closure) -{ - const cairo_path_buf_t *buf; - cairo_status_t status; - - cairo_path_foreach_buf_start (buf, path) { - const cairo_point_t *points = buf->points; - unsigned int i; - - for (i = 0; i < buf->num_ops; i++) { - switch (buf->op[i]) { - case CAIRO_PATH_OP_MOVE_TO: - status = (*move_to) (closure, &points[0]); - points += 1; - break; - case CAIRO_PATH_OP_LINE_TO: - status = (*line_to) (closure, &points[0]); - points += 1; - break; - case CAIRO_PATH_OP_CURVE_TO: - status = (*curve_to) (closure, &points[0], &points[1], &points[2]); - points += 3; - break; - default: - ASSERT_NOT_REACHED; - case CAIRO_PATH_OP_CLOSE_PATH: - status = (*close_path) (closure); - break; - } - - if (unlikely (status)) - return status; - } - } cairo_path_foreach_buf_end (buf, path); - - if (path->needs_move_to && path->has_current_point) - return (*move_to) (closure, &path->current_point); - - return CAIRO_STATUS_SUCCESS; -} - -typedef struct _cairo_path_fixed_append_closure { - cairo_point_t offset; - cairo_path_fixed_t *path; -} cairo_path_fixed_append_closure_t; - -static cairo_status_t -_append_move_to (void *abstract_closure, - const cairo_point_t *point) -{ - cairo_path_fixed_append_closure_t *closure = abstract_closure; - - return _cairo_path_fixed_move_to (closure->path, - point->x + closure->offset.x, - point->y + closure->offset.y); -} - -static cairo_status_t -_append_line_to (void *abstract_closure, - const cairo_point_t *point) -{ - cairo_path_fixed_append_closure_t *closure = abstract_closure; - - return _cairo_path_fixed_line_to (closure->path, - point->x + closure->offset.x, - point->y + closure->offset.y); -} - -static cairo_status_t -_append_curve_to (void *abstract_closure, - const cairo_point_t *p0, - const cairo_point_t *p1, - const cairo_point_t *p2) -{ - cairo_path_fixed_append_closure_t *closure = abstract_closure; - - return _cairo_path_fixed_curve_to (closure->path, - p0->x + closure->offset.x, - p0->y + closure->offset.y, - p1->x + closure->offset.x, - p1->y + closure->offset.y, - p2->x + closure->offset.x, - p2->y + closure->offset.y); -} - -static cairo_status_t -_append_close_path (void *abstract_closure) -{ - cairo_path_fixed_append_closure_t *closure = abstract_closure; - - return _cairo_path_fixed_close_path (closure->path); -} - -cairo_status_t -_cairo_path_fixed_append (cairo_path_fixed_t *path, - const cairo_path_fixed_t *other, - cairo_fixed_t tx, - cairo_fixed_t ty) -{ - cairo_path_fixed_append_closure_t closure; - - closure.path = path; - closure.offset.x = tx; - closure.offset.y = ty; - - return _cairo_path_fixed_interpret (other, - _append_move_to, - _append_line_to, - _append_curve_to, - _append_close_path, - &closure); -} - -static void -_cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path, - cairo_fixed_t offx, - cairo_fixed_t offy, - cairo_fixed_t scalex, - cairo_fixed_t scaley) -{ - cairo_path_buf_t *buf; - unsigned int i; - - if (scalex == CAIRO_FIXED_ONE && scaley == CAIRO_FIXED_ONE) { - _cairo_path_fixed_translate (path, offx, offy); - return; - } - - path->last_move_point.x = _cairo_fixed_mul (scalex, path->last_move_point.x) + offx; - path->last_move_point.y = _cairo_fixed_mul (scaley, path->last_move_point.y) + offy; - path->current_point.x = _cairo_fixed_mul (scalex, path->current_point.x) + offx; - path->current_point.y = _cairo_fixed_mul (scaley, path->current_point.y) + offy; - - path->fill_maybe_region = TRUE; - - cairo_path_foreach_buf_start (buf, path) { - for (i = 0; i < buf->num_points; i++) { - if (scalex != CAIRO_FIXED_ONE) - buf->points[i].x = _cairo_fixed_mul (buf->points[i].x, scalex); - buf->points[i].x += offx; - - if (scaley != CAIRO_FIXED_ONE) - buf->points[i].y = _cairo_fixed_mul (buf->points[i].y, scaley); - buf->points[i].y += offy; - - if (path->fill_maybe_region) { - path->fill_maybe_region = _cairo_fixed_is_integer (buf->points[i].x) && - _cairo_fixed_is_integer (buf->points[i].y); - } - } - } cairo_path_foreach_buf_end (buf, path); - - path->fill_maybe_region &= path->fill_is_rectilinear; - - path->extents.p1.x = _cairo_fixed_mul (scalex, path->extents.p1.x) + offx; - path->extents.p2.x = _cairo_fixed_mul (scalex, path->extents.p2.x) + offx; - if (scalex < 0) { - cairo_fixed_t t = path->extents.p1.x; - path->extents.p1.x = path->extents.p2.x; - path->extents.p2.x = t; - } - - path->extents.p1.y = _cairo_fixed_mul (scaley, path->extents.p1.y) + offy; - path->extents.p2.y = _cairo_fixed_mul (scaley, path->extents.p2.y) + offy; - if (scaley < 0) { - cairo_fixed_t t = path->extents.p1.y; - path->extents.p1.y = path->extents.p2.y; - path->extents.p2.y = t; - } -} - -void -_cairo_path_fixed_translate (cairo_path_fixed_t *path, - cairo_fixed_t offx, - cairo_fixed_t offy) -{ - cairo_path_buf_t *buf; - unsigned int i; - - if (offx == 0 && offy == 0) - return; - - path->last_move_point.x += offx; - path->last_move_point.y += offy; - path->current_point.x += offx; - path->current_point.y += offy; - - path->fill_maybe_region = TRUE; - - cairo_path_foreach_buf_start (buf, path) { - for (i = 0; i < buf->num_points; i++) { - buf->points[i].x += offx; - buf->points[i].y += offy; - - if (path->fill_maybe_region) { - path->fill_maybe_region = _cairo_fixed_is_integer (buf->points[i].x) && - _cairo_fixed_is_integer (buf->points[i].y); - } - } - } cairo_path_foreach_buf_end (buf, path); - - path->fill_maybe_region &= path->fill_is_rectilinear; - - path->extents.p1.x += offx; - path->extents.p1.y += offy; - path->extents.p2.x += offx; - path->extents.p2.y += offy; -} - - -static inline void -_cairo_path_fixed_transform_point (cairo_point_t *p, - const cairo_matrix_t *matrix) -{ - double dx, dy; - - dx = _cairo_fixed_to_double (p->x); - dy = _cairo_fixed_to_double (p->y); - cairo_matrix_transform_point (matrix, &dx, &dy); - p->x = _cairo_fixed_from_double (dx); - p->y = _cairo_fixed_from_double (dy); -} - -/** - * _cairo_path_fixed_transform: - * @path: a #cairo_path_fixed_t to be transformed - * @matrix: a #cairo_matrix_t - * - * Transform the fixed-point path according to the given matrix. - * There is a fast path for the case where @matrix has no rotation - * or shear. - **/ -void -_cairo_path_fixed_transform (cairo_path_fixed_t *path, - const cairo_matrix_t *matrix) -{ - cairo_box_t extents; - cairo_point_t point; - cairo_path_buf_t *buf; - unsigned int i; - - if (matrix->yx == 0.0 && matrix->xy == 0.0) { - /* Fast path for the common case of scale+transform */ - _cairo_path_fixed_offset_and_scale (path, - _cairo_fixed_from_double (matrix->x0), - _cairo_fixed_from_double (matrix->y0), - _cairo_fixed_from_double (matrix->xx), - _cairo_fixed_from_double (matrix->yy)); - return; - } - - _cairo_path_fixed_transform_point (&path->last_move_point, matrix); - _cairo_path_fixed_transform_point (&path->current_point, matrix); - - buf = cairo_path_head (path); - if (buf->num_points == 0) - return; - - extents = path->extents; - point = buf->points[0]; - _cairo_path_fixed_transform_point (&point, matrix); - _cairo_box_set (&path->extents, &point, &point); - - cairo_path_foreach_buf_start (buf, path) { - for (i = 0; i < buf->num_points; i++) { - _cairo_path_fixed_transform_point (&buf->points[i], matrix); - _cairo_box_add_point (&path->extents, &buf->points[i]); - } - } cairo_path_foreach_buf_end (buf, path); - - if (path->has_curve_to) { - cairo_bool_t is_tight; - - _cairo_matrix_transform_bounding_box_fixed (matrix, &extents, &is_tight); - if (!is_tight) { - cairo_bool_t has_extents; - - has_extents = _cairo_path_bounder_extents (path, &extents); - assert (has_extents); - } - path->extents = extents; - } - - /* flags might become more strict than needed */ - path->stroke_is_rectilinear = FALSE; - path->fill_is_rectilinear = FALSE; - path->fill_is_empty = FALSE; - path->fill_maybe_region = FALSE; -} - -/* Closure for path flattening */ -typedef struct cairo_path_flattener { - double tolerance; - cairo_point_t current_point; - cairo_path_fixed_move_to_func_t *move_to; - cairo_path_fixed_line_to_func_t *line_to; - cairo_path_fixed_close_path_func_t *close_path; - void *closure; -} cpf_t; - -static cairo_status_t -_cpf_move_to (void *closure, - const cairo_point_t *point) -{ - cpf_t *cpf = closure; - - cpf->current_point = *point; - - return cpf->move_to (cpf->closure, point); -} - -static cairo_status_t -_cpf_line_to (void *closure, - const cairo_point_t *point) -{ - cpf_t *cpf = closure; - - cpf->current_point = *point; - - return cpf->line_to (cpf->closure, point); -} - -static cairo_status_t -_cpf_curve_to (void *closure, - const cairo_point_t *p1, - const cairo_point_t *p2, - const cairo_point_t *p3) -{ - cpf_t *cpf = closure; - cairo_spline_t spline; - - cairo_point_t *p0 = &cpf->current_point; - - if (! _cairo_spline_init (&spline, - (cairo_spline_add_point_func_t)cpf->line_to, - cpf->closure, - p0, p1, p2, p3)) - { - return _cpf_line_to (closure, p3); - } - - cpf->current_point = *p3; - - return _cairo_spline_decompose (&spline, cpf->tolerance); -} - -static cairo_status_t -_cpf_close_path (void *closure) -{ - cpf_t *cpf = closure; - - return cpf->close_path (cpf->closure); -} - -cairo_status_t -_cairo_path_fixed_interpret_flat (const cairo_path_fixed_t *path, - cairo_path_fixed_move_to_func_t *move_to, - cairo_path_fixed_line_to_func_t *line_to, - cairo_path_fixed_close_path_func_t *close_path, - void *closure, - double tolerance) -{ - cpf_t flattener; - - if (! path->has_curve_to) { - return _cairo_path_fixed_interpret (path, - move_to, - line_to, - NULL, - close_path, - closure); - } - - flattener.tolerance = tolerance; - flattener.move_to = move_to; - flattener.line_to = line_to; - flattener.close_path = close_path; - flattener.closure = closure; - return _cairo_path_fixed_interpret (path, - _cpf_move_to, - _cpf_line_to, - _cpf_curve_to, - _cpf_close_path, - &flattener); -} - -static inline void -_canonical_box (cairo_box_t *box, - const cairo_point_t *p1, - const cairo_point_t *p2) -{ - if (p1->x <= p2->x) { - box->p1.x = p1->x; - box->p2.x = p2->x; - } else { - box->p1.x = p2->x; - box->p2.x = p1->x; - } - - if (p1->y <= p2->y) { - box->p1.y = p1->y; - box->p2.y = p2->y; - } else { - box->p1.y = p2->y; - box->p2.y = p1->y; - } -} - -static inline cairo_bool_t -_path_is_quad (const cairo_path_fixed_t *path) -{ - const cairo_path_buf_t *buf = cairo_path_head (path); - - /* Do we have the right number of ops? */ - if (buf->num_ops < 4 || buf->num_ops > 6) - return FALSE; - - /* Check whether the ops are those that would be used for a rectangle */ - if (buf->op[0] != CAIRO_PATH_OP_MOVE_TO || - buf->op[1] != CAIRO_PATH_OP_LINE_TO || - buf->op[2] != CAIRO_PATH_OP_LINE_TO || - buf->op[3] != CAIRO_PATH_OP_LINE_TO) - { - return FALSE; - } - - /* we accept an implicit close for filled paths */ - if (buf->num_ops > 4) { - /* Now, there are choices. The rectangle might end with a LINE_TO - * (to the original point), but this isn't required. If it - * doesn't, then it must end with a CLOSE_PATH. */ - if (buf->op[4] == CAIRO_PATH_OP_LINE_TO) { - if (buf->points[4].x != buf->points[0].x || - buf->points[4].y != buf->points[0].y) - return FALSE; - } else if (buf->op[4] != CAIRO_PATH_OP_CLOSE_PATH) { - return FALSE; - } - - if (buf->num_ops == 6) { - /* A trailing CLOSE_PATH or MOVE_TO is ok */ - if (buf->op[5] != CAIRO_PATH_OP_MOVE_TO && - buf->op[5] != CAIRO_PATH_OP_CLOSE_PATH) - return FALSE; - } - } - - return TRUE; -} - -static inline cairo_bool_t -_points_form_rect (const cairo_point_t *points) -{ - if (points[0].y == points[1].y && - points[1].x == points[2].x && - points[2].y == points[3].y && - points[3].x == points[0].x) - return TRUE; - if (points[0].x == points[1].x && - points[1].y == points[2].y && - points[2].x == points[3].x && - points[3].y == points[0].y) - return TRUE; - return FALSE; -} - -/* - * Check whether the given path contains a single rectangle. - */ -cairo_bool_t -_cairo_path_fixed_is_box (const cairo_path_fixed_t *path, - cairo_box_t *box) -{ - const cairo_path_buf_t *buf; - - if (! path->fill_is_rectilinear) - return FALSE; - - if (! _path_is_quad (path)) - return FALSE; - - buf = cairo_path_head (path); - if (_points_form_rect (buf->points)) { - _canonical_box (box, &buf->points[0], &buf->points[2]); - return TRUE; - } - - return FALSE; -} - -/* Determine whether two lines A->B and C->D intersect based on the - * algorithm described here: http://paulbourke.net/geometry/pointlineplane/ */ -static inline cairo_bool_t -_lines_intersect_or_are_coincident (cairo_point_t a, - cairo_point_t b, - cairo_point_t c, - cairo_point_t d) -{ - cairo_int64_t numerator_a, numerator_b, denominator; - cairo_bool_t denominator_negative; - - denominator = _cairo_int64_sub (_cairo_int32x32_64_mul (d.y - c.y, b.x - a.x), - _cairo_int32x32_64_mul (d.x - c.x, b.y - a.y)); - numerator_a = _cairo_int64_sub (_cairo_int32x32_64_mul (d.x - c.x, a.y - c.y), - _cairo_int32x32_64_mul (d.y - c.y, a.x - c.x)); - numerator_b = _cairo_int64_sub (_cairo_int32x32_64_mul (b.x - a.x, a.y - c.y), - _cairo_int32x32_64_mul (b.y - a.y, a.x - c.x)); - - if (_cairo_int64_is_zero (denominator)) { - /* If the denominator and numerators are both zero, - * the lines are coincident. */ - if (_cairo_int64_is_zero (numerator_a) && _cairo_int64_is_zero (numerator_b)) - return TRUE; - - /* Otherwise, a zero denominator indicates the lines are - * parallel and never intersect. */ - return FALSE; - } - - /* The lines intersect if both quotients are between 0 and 1 (exclusive). */ - - /* We first test whether either quotient is a negative number. */ - denominator_negative = _cairo_int64_negative (denominator); - if (_cairo_int64_negative (numerator_a) ^ denominator_negative) - return FALSE; - if (_cairo_int64_negative (numerator_b) ^ denominator_negative) - return FALSE; - - /* A zero quotient indicates an "intersection" at an endpoint, which - * we aren't considering a true intersection. */ - if (_cairo_int64_is_zero (numerator_a) || _cairo_int64_is_zero (numerator_b)) - return FALSE; - - /* If the absolute value of the numerator is larger than or equal to the - * denominator the result of the division would be greater than or equal - * to one. */ - if (! denominator_negative) { - if (! _cairo_int64_lt (numerator_a, denominator) || - ! _cairo_int64_lt (numerator_b, denominator)) - return FALSE; - } else { - if (! _cairo_int64_lt (denominator, numerator_a) || - ! _cairo_int64_lt (denominator, numerator_b)) - return FALSE; - } - - return TRUE; -} - -cairo_bool_t -_cairo_path_fixed_is_simple_quad (const cairo_path_fixed_t *path) -{ - const cairo_point_t *points; - - if (! _path_is_quad (path)) - return FALSE; - - points = cairo_path_head (path)->points; - if (_points_form_rect (points)) - return TRUE; - - if (_lines_intersect_or_are_coincident (points[0], points[1], - points[3], points[2])) - return FALSE; - - if (_lines_intersect_or_are_coincident (points[0], points[3], - points[1], points[2])) - return FALSE; - - return TRUE; -} - -cairo_bool_t -_cairo_path_fixed_is_stroke_box (const cairo_path_fixed_t *path, - cairo_box_t *box) -{ - const cairo_path_buf_t *buf = cairo_path_head (path); - - if (! path->fill_is_rectilinear) - return FALSE; - - /* Do we have the right number of ops? */ - if (buf->num_ops != 5) - return FALSE; - - /* Check whether the ops are those that would be used for a rectangle */ - if (buf->op[0] != CAIRO_PATH_OP_MOVE_TO || - buf->op[1] != CAIRO_PATH_OP_LINE_TO || - buf->op[2] != CAIRO_PATH_OP_LINE_TO || - buf->op[3] != CAIRO_PATH_OP_LINE_TO || - buf->op[4] != CAIRO_PATH_OP_CLOSE_PATH) - { - return FALSE; - } - - /* Ok, we may have a box, if the points line up */ - if (buf->points[0].y == buf->points[1].y && - buf->points[1].x == buf->points[2].x && - buf->points[2].y == buf->points[3].y && - buf->points[3].x == buf->points[0].x) - { - _canonical_box (box, &buf->points[0], &buf->points[2]); - return TRUE; - } - - if (buf->points[0].x == buf->points[1].x && - buf->points[1].y == buf->points[2].y && - buf->points[2].x == buf->points[3].x && - buf->points[3].y == buf->points[0].y) - { - _canonical_box (box, &buf->points[0], &buf->points[2]); - return TRUE; - } - - return FALSE; -} - -/* - * Check whether the given path contains a single rectangle - * that is logically equivalent to: - * <informalexample><programlisting> - * cairo_move_to (cr, x, y); - * cairo_rel_line_to (cr, width, 0); - * cairo_rel_line_to (cr, 0, height); - * cairo_rel_line_to (cr, -width, 0); - * cairo_close_path (cr); - * </programlisting></informalexample> - */ -cairo_bool_t -_cairo_path_fixed_is_rectangle (const cairo_path_fixed_t *path, - cairo_box_t *box) -{ - const cairo_path_buf_t *buf; - - if (! _cairo_path_fixed_is_box (path, box)) - return FALSE; - - /* This check is valid because the current implementation of - * _cairo_path_fixed_is_box () only accepts rectangles like: - * move,line,line,line[,line|close[,close|move]]. */ - buf = cairo_path_head (path); - if (buf->num_ops > 4) - return TRUE; - - return FALSE; -} - -void -_cairo_path_fixed_iter_init (cairo_path_fixed_iter_t *iter, - const cairo_path_fixed_t *path) -{ - iter->first = iter->buf = cairo_path_head (path); - iter->n_op = 0; - iter->n_point = 0; -} - -static cairo_bool_t -_cairo_path_fixed_iter_next_op (cairo_path_fixed_iter_t *iter) -{ - if (++iter->n_op >= iter->buf->num_ops) { - iter->buf = cairo_path_buf_next (iter->buf); - if (iter->buf == iter->first) { - iter->buf = NULL; - return FALSE; - } - - iter->n_op = 0; - iter->n_point = 0; - } - - return TRUE; -} - -cairo_bool_t -_cairo_path_fixed_iter_is_fill_box (cairo_path_fixed_iter_t *_iter, - cairo_box_t *box) -{ - cairo_point_t points[5]; - cairo_path_fixed_iter_t iter; - - if (_iter->buf == NULL) - return FALSE; - - iter = *_iter; - - if (iter.n_op == iter.buf->num_ops && ! _cairo_path_fixed_iter_next_op (&iter)) - return FALSE; - - /* Check whether the ops are those that would be used for a rectangle */ - if (iter.buf->op[iter.n_op] != CAIRO_PATH_OP_MOVE_TO) - return FALSE; - points[0] = iter.buf->points[iter.n_point++]; - if (! _cairo_path_fixed_iter_next_op (&iter)) - return FALSE; - - if (iter.buf->op[iter.n_op] != CAIRO_PATH_OP_LINE_TO) - return FALSE; - points[1] = iter.buf->points[iter.n_point++]; - if (! _cairo_path_fixed_iter_next_op (&iter)) - return FALSE; - - /* a horizontal/vertical closed line is also a degenerate rectangle */ - switch (iter.buf->op[iter.n_op]) { - case CAIRO_PATH_OP_CLOSE_PATH: - _cairo_path_fixed_iter_next_op (&iter); - case CAIRO_PATH_OP_MOVE_TO: /* implicit close */ - box->p1 = box->p2 = points[0]; - *_iter = iter; - return TRUE; - default: - return FALSE; - case CAIRO_PATH_OP_LINE_TO: - break; - } - - points[2] = iter.buf->points[iter.n_point++]; - if (! _cairo_path_fixed_iter_next_op (&iter)) - return FALSE; - - if (iter.buf->op[iter.n_op] != CAIRO_PATH_OP_LINE_TO) - return FALSE; - points[3] = iter.buf->points[iter.n_point++]; - - /* Now, there are choices. The rectangle might end with a LINE_TO - * (to the original point), but this isn't required. If it - * doesn't, then it must end with a CLOSE_PATH (which may be implicit). */ - if (! _cairo_path_fixed_iter_next_op (&iter)) { - /* implicit close due to fill */ - } else if (iter.buf->op[iter.n_op] == CAIRO_PATH_OP_LINE_TO) { - points[4] = iter.buf->points[iter.n_point++]; - if (points[4].x != points[0].x || points[4].y != points[0].y) - return FALSE; - _cairo_path_fixed_iter_next_op (&iter); - } else if (iter.buf->op[iter.n_op] == CAIRO_PATH_OP_CLOSE_PATH) { - _cairo_path_fixed_iter_next_op (&iter); - } else if (iter.buf->op[iter.n_op] == CAIRO_PATH_OP_MOVE_TO) { - /* implicit close-path due to new-sub-path */ - } else { - return FALSE; - } - - /* Ok, we may have a box, if the points line up */ - if (points[0].y == points[1].y && - points[1].x == points[2].x && - points[2].y == points[3].y && - points[3].x == points[0].x) - { - box->p1 = points[0]; - box->p2 = points[2]; - *_iter = iter; - return TRUE; - } - - if (points[0].x == points[1].x && - points[1].y == points[2].y && - points[2].x == points[3].x && - points[3].y == points[0].y) - { - box->p1 = points[1]; - box->p2 = points[3]; - *_iter = iter; - return TRUE; - } - - return FALSE; -} - -cairo_bool_t -_cairo_path_fixed_iter_at_end (const cairo_path_fixed_iter_t *iter) -{ - if (iter->buf == NULL) - return TRUE; - - return iter->n_op == iter->buf->num_ops; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-path-in-fill.c b/source/libs/cairo/cairo-src/src/cairo-path-in-fill.c deleted file mode 100644 index 1787fb1a3bab05807e6c74ed063a8469c669ad74..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-path-in-fill.c +++ /dev/null @@ -1,290 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2008 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Chris Wilson. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" -#include "cairo-path-fixed-private.h" - -typedef struct cairo_in_fill { - double tolerance; - cairo_bool_t on_edge; - int winding; - - cairo_fixed_t x, y; - - cairo_bool_t has_current_point; - cairo_point_t current_point; - cairo_point_t first_point; -} cairo_in_fill_t; - -static void -_cairo_in_fill_init (cairo_in_fill_t *in_fill, - double tolerance, - double x, - double y) -{ - in_fill->on_edge = FALSE; - in_fill->winding = 0; - in_fill->tolerance = tolerance; - - in_fill->x = _cairo_fixed_from_double (x); - in_fill->y = _cairo_fixed_from_double (y); - - in_fill->has_current_point = FALSE; - in_fill->current_point.x = 0; - in_fill->current_point.y = 0; -} - -static void -_cairo_in_fill_fini (cairo_in_fill_t *in_fill) -{ -} - -static int -edge_compare_for_y_against_x (const cairo_point_t *p1, - const cairo_point_t *p2, - cairo_fixed_t y, - cairo_fixed_t x) -{ - cairo_fixed_t adx, ady; - cairo_fixed_t dx, dy; - cairo_int64_t L, R; - - adx = p2->x - p1->x; - dx = x - p1->x; - - if (adx == 0) - return -dx; - if ((adx ^ dx) < 0) - return adx; - - dy = y - p1->y; - ady = p2->y - p1->y; - - L = _cairo_int32x32_64_mul (dy, adx); - R = _cairo_int32x32_64_mul (dx, ady); - - return _cairo_int64_cmp (L, R); -} - -static void -_cairo_in_fill_add_edge (cairo_in_fill_t *in_fill, - const cairo_point_t *p1, - const cairo_point_t *p2) -{ - int dir; - - if (in_fill->on_edge) - return; - - /* count the number of edge crossing to -∞ */ - - dir = 1; - if (p2->y < p1->y) { - const cairo_point_t *tmp; - - tmp = p1; - p1 = p2; - p2 = tmp; - - dir = -1; - } - - /* First check whether the query is on an edge */ - if ((p1->x == in_fill->x && p1->y == in_fill->y) || - (p2->x == in_fill->x && p2->y == in_fill->y) || - (! (p2->y < in_fill->y || p1->y > in_fill->y || - (p1->x > in_fill->x && p2->x > in_fill->x) || - (p1->x < in_fill->x && p2->x < in_fill->x)) && - edge_compare_for_y_against_x (p1, p2, in_fill->y, in_fill->x) == 0)) - { - in_fill->on_edge = TRUE; - return; - } - - /* edge is entirely above or below, note the shortening rule */ - if (p2->y <= in_fill->y || p1->y > in_fill->y) - return; - - /* edge lies wholly to the right */ - if (p1->x >= in_fill->x && p2->x >= in_fill->x) - return; - - if ((p1->x <= in_fill->x && p2->x <= in_fill->x) || - edge_compare_for_y_against_x (p1, p2, in_fill->y, in_fill->x) < 0) - { - in_fill->winding += dir; - } -} - -static cairo_status_t -_cairo_in_fill_move_to (void *closure, - const cairo_point_t *point) -{ - cairo_in_fill_t *in_fill = closure; - - /* implicit close path */ - if (in_fill->has_current_point) { - _cairo_in_fill_add_edge (in_fill, - &in_fill->current_point, - &in_fill->first_point); - } - - in_fill->first_point = *point; - in_fill->current_point = *point; - in_fill->has_current_point = TRUE; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_in_fill_line_to (void *closure, - const cairo_point_t *point) -{ - cairo_in_fill_t *in_fill = closure; - - if (in_fill->has_current_point) - _cairo_in_fill_add_edge (in_fill, &in_fill->current_point, point); - - in_fill->current_point = *point; - in_fill->has_current_point = TRUE; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_in_fill_curve_to (void *closure, - const cairo_point_t *b, - const cairo_point_t *c, - const cairo_point_t *d) -{ - cairo_in_fill_t *in_fill = closure; - cairo_spline_t spline; - cairo_fixed_t top, bot, left; - - /* first reject based on bbox */ - bot = top = in_fill->current_point.y; - if (b->y < top) top = b->y; - if (b->y > bot) bot = b->y; - if (c->y < top) top = c->y; - if (c->y > bot) bot = c->y; - if (d->y < top) top = d->y; - if (d->y > bot) bot = d->y; - if (bot < in_fill->y || top > in_fill->y) { - in_fill->current_point = *d; - return CAIRO_STATUS_SUCCESS; - } - - left = in_fill->current_point.x; - if (b->x < left) left = b->x; - if (c->x < left) left = c->x; - if (d->x < left) left = d->x; - if (left > in_fill->x) { - in_fill->current_point = *d; - return CAIRO_STATUS_SUCCESS; - } - - /* XXX Investigate direct inspection of the inflections? */ - if (! _cairo_spline_init (&spline, - (cairo_spline_add_point_func_t)_cairo_in_fill_line_to, - in_fill, - &in_fill->current_point, b, c, d)) - { - return CAIRO_STATUS_SUCCESS; - } - - return _cairo_spline_decompose (&spline, in_fill->tolerance); -} - -static cairo_status_t -_cairo_in_fill_close_path (void *closure) -{ - cairo_in_fill_t *in_fill = closure; - - if (in_fill->has_current_point) { - _cairo_in_fill_add_edge (in_fill, - &in_fill->current_point, - &in_fill->first_point); - - in_fill->has_current_point = FALSE; - } - - return CAIRO_STATUS_SUCCESS; -} - -cairo_bool_t -_cairo_path_fixed_in_fill (const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - double x, - double y) -{ - cairo_in_fill_t in_fill; - cairo_status_t status; - cairo_bool_t is_inside; - - if (_cairo_path_fixed_fill_is_empty (path)) - return FALSE; - - _cairo_in_fill_init (&in_fill, tolerance, x, y); - - status = _cairo_path_fixed_interpret (path, - _cairo_in_fill_move_to, - _cairo_in_fill_line_to, - _cairo_in_fill_curve_to, - _cairo_in_fill_close_path, - &in_fill); - assert (status == CAIRO_STATUS_SUCCESS); - - _cairo_in_fill_close_path (&in_fill); - - if (in_fill.on_edge) { - is_inside = TRUE; - } else switch (fill_rule) { - case CAIRO_FILL_RULE_EVEN_ODD: - is_inside = in_fill.winding & 1; - break; - case CAIRO_FILL_RULE_WINDING: - is_inside = in_fill.winding != 0; - break; - default: - ASSERT_NOT_REACHED; - is_inside = FALSE; - break; - } - - _cairo_in_fill_fini (&in_fill); - - return is_inside; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-path-private.h b/source/libs/cairo/cairo-src/src/cairo-path-private.h deleted file mode 100644 index 7b54317e20ef4ccac7c8180253c2195ca556987d..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-path-private.h +++ /dev/null @@ -1,57 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2005 Red Hat, Inc. - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Carl D. Worth <cworth@redhat.com> - */ - -#ifndef CAIRO_PATH_PRIVATE_H -#define CAIRO_PATH_PRIVATE_H - -#include "cairoint.h" - -cairo_private cairo_path_t * -_cairo_path_create (cairo_path_fixed_t *path, - cairo_t *cr); - -cairo_private cairo_path_t * -_cairo_path_create_flat (cairo_path_fixed_t *path, - cairo_t *cr); - -cairo_private cairo_path_t * -_cairo_path_create_in_error (cairo_status_t status); - -cairo_private cairo_status_t -_cairo_path_append_to_context (const cairo_path_t *path, - cairo_t *cr); - -#endif /* CAIRO_PATH_DATA_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-path-stroke-boxes.c b/source/libs/cairo/cairo-src/src/cairo-path-stroke-boxes.c deleted file mode 100644 index 7f25bf76cf744837320331d1d859c73bddc2918c..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-path-stroke-boxes.c +++ /dev/null @@ -1,711 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#define _BSD_SOURCE /* for hypot() */ -#include "cairoint.h" - -#include "cairo-box-inline.h" -#include "cairo-boxes-private.h" -#include "cairo-error-private.h" -#include "cairo-path-fixed-private.h" -#include "cairo-slope-private.h" -#include "cairo-stroke-dash-private.h" - -typedef struct _segment_t { - cairo_point_t p1, p2; - unsigned flags; -#define HORIZONTAL 0x1 -#define FORWARDS 0x2 -#define JOIN 0x4 -} segment_t; - -typedef struct _cairo_rectilinear_stroker { - const cairo_stroke_style_t *stroke_style; - const cairo_matrix_t *ctm; - cairo_antialias_t antialias; - - cairo_fixed_t half_line_x, half_line_y; - cairo_boxes_t *boxes; - cairo_point_t current_point; - cairo_point_t first_point; - cairo_bool_t open_sub_path; - - cairo_stroker_dash_t dash; - - cairo_bool_t has_bounds; - cairo_box_t bounds; - - int num_segments; - int segments_size; - segment_t *segments; - segment_t segments_embedded[8]; /* common case is a single rectangle */ -} cairo_rectilinear_stroker_t; - -static void -_cairo_rectilinear_stroker_limit (cairo_rectilinear_stroker_t *stroker, - const cairo_box_t *boxes, - int num_boxes) -{ - stroker->has_bounds = TRUE; - _cairo_boxes_get_extents (boxes, num_boxes, &stroker->bounds); - - stroker->bounds.p1.x -= stroker->half_line_x; - stroker->bounds.p2.x += stroker->half_line_x; - - stroker->bounds.p1.y -= stroker->half_line_y; - stroker->bounds.p2.y += stroker->half_line_y; -} - -static cairo_bool_t -_cairo_rectilinear_stroker_init (cairo_rectilinear_stroker_t *stroker, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *ctm, - cairo_antialias_t antialias, - cairo_boxes_t *boxes) -{ - /* This special-case rectilinear stroker only supports - * miter-joined lines (not curves) and a translation-only matrix - * (though it could probably be extended to support a matrix with - * uniform, integer scaling). - * - * It also only supports horizontal and vertical line_to - * elements. But we don't catch that here, but instead return - * UNSUPPORTED from _cairo_rectilinear_stroker_line_to if any - * non-rectilinear line_to is encountered. - */ - if (stroke_style->line_join != CAIRO_LINE_JOIN_MITER) - return FALSE; - - /* If the miter limit turns right angles into bevels, then we - * can't use this optimization. Remember, the ratio is - * 1/sin(ɸ/2). So the cutoff is 1/sin(Ï€/4.0) or ⎷2, - * which we round for safety. */ - if (stroke_style->miter_limit < M_SQRT2) - return FALSE; - - if (! (stroke_style->line_cap == CAIRO_LINE_CAP_BUTT || - stroke_style->line_cap == CAIRO_LINE_CAP_SQUARE)) - { - return FALSE; - } - - if (! _cairo_matrix_is_scale (ctm)) - return FALSE; - - stroker->stroke_style = stroke_style; - stroker->ctm = ctm; - stroker->antialias = antialias; - - stroker->half_line_x = - _cairo_fixed_from_double (fabs(ctm->xx) * stroke_style->line_width / 2.0); - stroker->half_line_y = - _cairo_fixed_from_double (fabs(ctm->yy) * stroke_style->line_width / 2.0); - - stroker->open_sub_path = FALSE; - stroker->segments = stroker->segments_embedded; - stroker->segments_size = ARRAY_LENGTH (stroker->segments_embedded); - stroker->num_segments = 0; - - _cairo_stroker_dash_init (&stroker->dash, stroke_style); - - stroker->has_bounds = FALSE; - - stroker->boxes = boxes; - - return TRUE; -} - -static void -_cairo_rectilinear_stroker_fini (cairo_rectilinear_stroker_t *stroker) -{ - if (stroker->segments != stroker->segments_embedded) - free (stroker->segments); -} - -static cairo_status_t -_cairo_rectilinear_stroker_add_segment (cairo_rectilinear_stroker_t *stroker, - const cairo_point_t *p1, - const cairo_point_t *p2, - unsigned flags) -{ - if (CAIRO_INJECT_FAULT ()) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - if (stroker->num_segments == stroker->segments_size) { - int new_size = stroker->segments_size * 2; - segment_t *new_segments; - - if (stroker->segments == stroker->segments_embedded) { - new_segments = _cairo_malloc_ab (new_size, sizeof (segment_t)); - if (unlikely (new_segments == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - memcpy (new_segments, stroker->segments, - stroker->num_segments * sizeof (segment_t)); - } else { - new_segments = _cairo_realloc_ab (stroker->segments, - new_size, sizeof (segment_t)); - if (unlikely (new_segments == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - stroker->segments_size = new_size; - stroker->segments = new_segments; - } - - stroker->segments[stroker->num_segments].p1 = *p1; - stroker->segments[stroker->num_segments].p2 = *p2; - stroker->segments[stroker->num_segments].flags = flags; - stroker->num_segments++; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_rectilinear_stroker_emit_segments (cairo_rectilinear_stroker_t *stroker) -{ - cairo_line_cap_t line_cap = stroker->stroke_style->line_cap; - cairo_fixed_t half_line_x = stroker->half_line_x; - cairo_fixed_t half_line_y = stroker->half_line_y; - cairo_status_t status; - int i, j; - - /* For each segment we generate a single rectangle. - * This rectangle is based on a perpendicular extension (by half the - * line width) of the segment endpoints * after some adjustments of the - * endpoints to account for caps and joins. - */ - for (i = 0; i < stroker->num_segments; i++) { - cairo_bool_t lengthen_initial, lengthen_final; - cairo_point_t *a, *b; - cairo_box_t box; - - a = &stroker->segments[i].p1; - b = &stroker->segments[i].p2; - - /* We adjust the initial point of the segment to extend the - * rectangle to include the previous cap or join, (this - * adjustment applies to all segments except for the first - * segment of open, butt-capped paths). However, we must be - * careful not to emit a miter join across a degenerate segment - * which has been elided. - * - * Overlapping segments will be eliminated by the tessellation. - * Ideally, we would not emit these self-intersections at all, - * but that is tricky with segments shorter than half_line_width. - */ - j = i == 0 ? stroker->num_segments - 1 : i-1; - lengthen_initial = (stroker->segments[i].flags ^ stroker->segments[j].flags) & HORIZONTAL; - j = i == stroker->num_segments - 1 ? 0 : i+1; - lengthen_final = (stroker->segments[i].flags ^ stroker->segments[j].flags) & HORIZONTAL; - if (stroker->open_sub_path) { - if (i == 0) - lengthen_initial = line_cap != CAIRO_LINE_CAP_BUTT; - - if (i == stroker->num_segments - 1) - lengthen_final = line_cap != CAIRO_LINE_CAP_BUTT; - } - - /* Perform the adjustments of the endpoints. */ - if (lengthen_initial | lengthen_final) { - if (a->y == b->y) { - if (a->x < b->x) { - if (lengthen_initial) - a->x -= half_line_x; - if (lengthen_final) - b->x += half_line_x; - } else { - if (lengthen_initial) - a->x += half_line_x; - if (lengthen_final) - b->x -= half_line_x; - } - } else { - if (a->y < b->y) { - if (lengthen_initial) - a->y -= half_line_y; - if (lengthen_final) - b->y += half_line_y; - } else { - if (lengthen_initial) - a->y += half_line_y; - if (lengthen_final) - b->y -= half_line_y; - } - } - } - - /* Form the rectangle by expanding by half the line width in - * either perpendicular direction. */ - if (a->y == b->y) { - a->y -= half_line_y; - b->y += half_line_y; - } else { - a->x -= half_line_x; - b->x += half_line_x; - } - - if (a->x < b->x) { - box.p1.x = a->x; - box.p2.x = b->x; - } else { - box.p1.x = b->x; - box.p2.x = a->x; - } - if (a->y < b->y) { - box.p1.y = a->y; - box.p2.y = b->y; - } else { - box.p1.y = b->y; - box.p2.y = a->y; - } - - status = _cairo_boxes_add (stroker->boxes, stroker->antialias, &box); - if (unlikely (status)) - return status; - } - - stroker->num_segments = 0; - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_rectilinear_stroker_emit_segments_dashed (cairo_rectilinear_stroker_t *stroker) -{ - cairo_status_t status; - cairo_line_cap_t line_cap = stroker->stroke_style->line_cap; - cairo_fixed_t half_line_x = stroker->half_line_x; - cairo_fixed_t half_line_y = stroker->half_line_y; - int i; - - for (i = 0; i < stroker->num_segments; i++) { - cairo_point_t *a, *b; - cairo_bool_t is_horizontal; - cairo_box_t box; - - a = &stroker->segments[i].p1; - b = &stroker->segments[i].p2; - - is_horizontal = stroker->segments[i].flags & HORIZONTAL; - - /* Handle the joins for a potentially degenerate segment. */ - if (line_cap == CAIRO_LINE_CAP_BUTT && - stroker->segments[i].flags & JOIN && - (i != stroker->num_segments - 1 || - (! stroker->open_sub_path && stroker->dash.dash_starts_on))) - { - cairo_slope_t out_slope; - int j = (i + 1) % stroker->num_segments; - cairo_bool_t forwards = !!(stroker->segments[i].flags & FORWARDS); - - _cairo_slope_init (&out_slope, - &stroker->segments[j].p1, - &stroker->segments[j].p2); - box.p2 = box.p1 = stroker->segments[i].p2; - - if (is_horizontal) { - if (forwards) - box.p2.x += half_line_x; - else - box.p1.x -= half_line_x; - - if (out_slope.dy > 0) - box.p1.y -= half_line_y; - else - box.p2.y += half_line_y; - } else { - if (forwards) - box.p2.y += half_line_y; - else - box.p1.y -= half_line_y; - - if (out_slope.dx > 0) - box.p1.x -= half_line_x; - else - box.p2.x += half_line_x; - } - - status = _cairo_boxes_add (stroker->boxes, stroker->antialias, &box); - if (unlikely (status)) - return status; - } - - /* Perform the adjustments of the endpoints. */ - if (is_horizontal) { - if (line_cap == CAIRO_LINE_CAP_SQUARE) { - if (a->x <= b->x) { - a->x -= half_line_x; - b->x += half_line_x; - } else { - a->x += half_line_x; - b->x -= half_line_x; - } - } - - a->y += half_line_y; - b->y -= half_line_y; - } else { - if (line_cap == CAIRO_LINE_CAP_SQUARE) { - if (a->y <= b->y) { - a->y -= half_line_y; - b->y += half_line_y; - } else { - a->y += half_line_y; - b->y -= half_line_y; - } - } - - a->x += half_line_x; - b->x -= half_line_x; - } - - if (a->x == b->x && a->y == b->y) - continue; - - if (a->x < b->x) { - box.p1.x = a->x; - box.p2.x = b->x; - } else { - box.p1.x = b->x; - box.p2.x = a->x; - } - if (a->y < b->y) { - box.p1.y = a->y; - box.p2.y = b->y; - } else { - box.p1.y = b->y; - box.p2.y = a->y; - } - - status = _cairo_boxes_add (stroker->boxes, stroker->antialias, &box); - if (unlikely (status)) - return status; - } - - stroker->num_segments = 0; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_rectilinear_stroker_move_to (void *closure, - const cairo_point_t *point) -{ - cairo_rectilinear_stroker_t *stroker = closure; - cairo_status_t status; - - if (stroker->dash.dashed) - status = _cairo_rectilinear_stroker_emit_segments_dashed (stroker); - else - status = _cairo_rectilinear_stroker_emit_segments (stroker); - if (unlikely (status)) - return status; - - /* reset the dash pattern for new sub paths */ - _cairo_stroker_dash_start (&stroker->dash); - - stroker->current_point = *point; - stroker->first_point = *point; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_rectilinear_stroker_line_to (void *closure, - const cairo_point_t *b) -{ - cairo_rectilinear_stroker_t *stroker = closure; - cairo_point_t *a = &stroker->current_point; - cairo_status_t status; - - /* We only support horizontal or vertical elements. */ - assert (a->x == b->x || a->y == b->y); - - /* We don't draw anything for degenerate paths. */ - if (a->x == b->x && a->y == b->y) - return CAIRO_STATUS_SUCCESS; - - status = _cairo_rectilinear_stroker_add_segment (stroker, a, b, - (a->y == b->y) | JOIN); - - stroker->current_point = *b; - stroker->open_sub_path = TRUE; - - return status; -} - -static cairo_status_t -_cairo_rectilinear_stroker_line_to_dashed (void *closure, - const cairo_point_t *point) -{ - cairo_rectilinear_stroker_t *stroker = closure; - const cairo_point_t *a = &stroker->current_point; - const cairo_point_t *b = point; - cairo_bool_t fully_in_bounds; - double sf, sign, remain; - cairo_fixed_t mag; - cairo_status_t status; - cairo_line_t segment; - cairo_bool_t dash_on = FALSE; - unsigned is_horizontal; - - /* We don't draw anything for degenerate paths. */ - if (a->x == b->x && a->y == b->y) - return CAIRO_STATUS_SUCCESS; - - /* We only support horizontal or vertical elements. */ - assert (a->x == b->x || a->y == b->y); - - fully_in_bounds = TRUE; - if (stroker->has_bounds && - (! _cairo_box_contains_point (&stroker->bounds, a) || - ! _cairo_box_contains_point (&stroker->bounds, b))) - { - fully_in_bounds = FALSE; - } - - is_horizontal = a->y == b->y; - if (is_horizontal) { - mag = b->x - a->x; - sf = fabs (stroker->ctm->xx); - } else { - mag = b->y - a->y; - sf = fabs (stroker->ctm->yy); - } - if (mag < 0) { - remain = _cairo_fixed_to_double (-mag); - sign = 1.; - } else { - remain = _cairo_fixed_to_double (mag); - is_horizontal |= FORWARDS; - sign = -1.; - } - - segment.p2 = segment.p1 = *a; - while (remain > 0.) { - double step_length; - - step_length = MIN (sf * stroker->dash.dash_remain, remain); - remain -= step_length; - - mag = _cairo_fixed_from_double (sign*remain); - if (is_horizontal & 0x1) - segment.p2.x = b->x + mag; - else - segment.p2.y = b->y + mag; - - if (stroker->dash.dash_on && - (fully_in_bounds || - _cairo_box_intersects_line_segment (&stroker->bounds, &segment))) - { - status = _cairo_rectilinear_stroker_add_segment (stroker, - &segment.p1, - &segment.p2, - is_horizontal | (remain <= 0.) << 2); - if (unlikely (status)) - return status; - - dash_on = TRUE; - } - else - { - dash_on = FALSE; - } - - _cairo_stroker_dash_step (&stroker->dash, step_length / sf); - segment.p1 = segment.p2; - } - - if (stroker->dash.dash_on && ! dash_on && - (fully_in_bounds || - _cairo_box_intersects_line_segment (&stroker->bounds, &segment))) - { - - /* This segment ends on a transition to dash_on, compute a new face - * and add cap for the beginning of the next dash_on step. - */ - - status = _cairo_rectilinear_stroker_add_segment (stroker, - &segment.p1, - &segment.p1, - is_horizontal | JOIN); - if (unlikely (status)) - return status; - } - - stroker->current_point = *point; - stroker->open_sub_path = TRUE; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_rectilinear_stroker_close_path (void *closure) -{ - cairo_rectilinear_stroker_t *stroker = closure; - cairo_status_t status; - - /* We don't draw anything for degenerate paths. */ - if (! stroker->open_sub_path) - return CAIRO_STATUS_SUCCESS; - - if (stroker->dash.dashed) { - status = _cairo_rectilinear_stroker_line_to_dashed (stroker, - &stroker->first_point); - } else { - status = _cairo_rectilinear_stroker_line_to (stroker, - &stroker->first_point); - } - if (unlikely (status)) - return status; - - stroker->open_sub_path = FALSE; - - if (stroker->dash.dashed) - status = _cairo_rectilinear_stroker_emit_segments_dashed (stroker); - else - status = _cairo_rectilinear_stroker_emit_segments (stroker); - if (unlikely (status)) - return status; - - return CAIRO_STATUS_SUCCESS; -} - -cairo_int_status_t -_cairo_path_fixed_stroke_rectilinear_to_boxes (const cairo_path_fixed_t *path, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *ctm, - cairo_antialias_t antialias, - cairo_boxes_t *boxes) -{ - cairo_rectilinear_stroker_t rectilinear_stroker; - cairo_int_status_t status; - cairo_box_t box; - - assert (_cairo_path_fixed_stroke_is_rectilinear (path)); - - if (! _cairo_rectilinear_stroker_init (&rectilinear_stroker, - stroke_style, ctm, antialias, - boxes)) - { - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - if (! rectilinear_stroker.dash.dashed && - _cairo_path_fixed_is_stroke_box (path, &box) && - /* if the segments overlap we need to feed them into the tessellator */ - box.p2.x - box.p1.x > 2* rectilinear_stroker.half_line_x && - box.p2.y - box.p1.y > 2* rectilinear_stroker.half_line_y) - { - cairo_box_t b; - - /* top */ - b.p1.x = box.p1.x - rectilinear_stroker.half_line_x; - b.p2.x = box.p2.x + rectilinear_stroker.half_line_x; - b.p1.y = box.p1.y - rectilinear_stroker.half_line_y; - b.p2.y = box.p1.y + rectilinear_stroker.half_line_y; - status = _cairo_boxes_add (boxes, antialias, &b); - assert (status == CAIRO_INT_STATUS_SUCCESS); - - /* left (excluding top/bottom) */ - b.p1.x = box.p1.x - rectilinear_stroker.half_line_x; - b.p2.x = box.p1.x + rectilinear_stroker.half_line_x; - b.p1.y = box.p1.y + rectilinear_stroker.half_line_y; - b.p2.y = box.p2.y - rectilinear_stroker.half_line_y; - status = _cairo_boxes_add (boxes, antialias, &b); - assert (status == CAIRO_INT_STATUS_SUCCESS); - - /* right (excluding top/bottom) */ - b.p1.x = box.p2.x - rectilinear_stroker.half_line_x; - b.p2.x = box.p2.x + rectilinear_stroker.half_line_x; - b.p1.y = box.p1.y + rectilinear_stroker.half_line_y; - b.p2.y = box.p2.y - rectilinear_stroker.half_line_y; - status = _cairo_boxes_add (boxes, antialias, &b); - assert (status == CAIRO_INT_STATUS_SUCCESS); - - /* bottom */ - b.p1.x = box.p1.x - rectilinear_stroker.half_line_x; - b.p2.x = box.p2.x + rectilinear_stroker.half_line_x; - b.p1.y = box.p2.y - rectilinear_stroker.half_line_y; - b.p2.y = box.p2.y + rectilinear_stroker.half_line_y; - status = _cairo_boxes_add (boxes, antialias, &b); - assert (status == CAIRO_INT_STATUS_SUCCESS); - - goto done; - } - - if (boxes->num_limits) { - _cairo_rectilinear_stroker_limit (&rectilinear_stroker, - boxes->limits, - boxes->num_limits); - } - - status = _cairo_path_fixed_interpret (path, - _cairo_rectilinear_stroker_move_to, - rectilinear_stroker.dash.dashed ? - _cairo_rectilinear_stroker_line_to_dashed : - _cairo_rectilinear_stroker_line_to, - NULL, - _cairo_rectilinear_stroker_close_path, - &rectilinear_stroker); - if (unlikely (status)) - goto BAIL; - - if (rectilinear_stroker.dash.dashed) - status = _cairo_rectilinear_stroker_emit_segments_dashed (&rectilinear_stroker); - else - status = _cairo_rectilinear_stroker_emit_segments (&rectilinear_stroker); - if (unlikely (status)) - goto BAIL; - - /* As we incrementally tessellate, we do not eliminate self-intersections */ - status = _cairo_bentley_ottmann_tessellate_boxes (boxes, - CAIRO_FILL_RULE_WINDING, - boxes); - if (unlikely (status)) - goto BAIL; - -done: - _cairo_rectilinear_stroker_fini (&rectilinear_stroker); - return CAIRO_STATUS_SUCCESS; - -BAIL: - _cairo_rectilinear_stroker_fini (&rectilinear_stroker); - _cairo_boxes_clear (boxes); - return status; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-path-stroke-polygon.c b/source/libs/cairo/cairo-src/src/cairo-path-stroke-polygon.c deleted file mode 100644 index e5082bbec68bf4dcf78d62b06f35b4ef024c4562..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-path-stroke-polygon.c +++ /dev/null @@ -1,1364 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#define _BSD_SOURCE /* for hypot() */ -#include "cairoint.h" - -#include "cairo-box-inline.h" -#include "cairo-boxes-private.h" -#include "cairo-contour-inline.h" -#include "cairo-contour-private.h" -#include "cairo-error-private.h" -#include "cairo-path-fixed-private.h" -#include "cairo-slope-private.h" - -#define DEBUG 0 - -struct stroker { - cairo_stroke_style_t style; - -#if DEBUG - cairo_contour_t path; -#endif - - struct stroke_contour { - /* Note that these are not strictly contours as they may intersect */ - cairo_contour_t contour; - } cw, ccw; - cairo_uint64_t contour_tolerance; - cairo_polygon_t *polygon; - - const cairo_matrix_t *ctm; - const cairo_matrix_t *ctm_inverse; - double tolerance; - double spline_cusp_tolerance; - double half_line_width; - cairo_bool_t ctm_det_positive; - - cairo_pen_t pen; - - cairo_point_t first_point; - - cairo_bool_t has_initial_sub_path; - - cairo_bool_t has_current_face; - cairo_stroke_face_t current_face; - - cairo_bool_t has_first_face; - cairo_stroke_face_t first_face; - - cairo_bool_t has_bounds; - cairo_box_t bounds; -}; - -static inline double -normalize_slope (double *dx, double *dy); - -static void -compute_face (const cairo_point_t *point, - const cairo_slope_t *dev_slope, - struct stroker *stroker, - cairo_stroke_face_t *face); - -static cairo_uint64_t -point_distance_sq (const cairo_point_t *p1, - const cairo_point_t *p2) -{ - int32_t dx = p1->x - p2->x; - int32_t dy = p1->y - p2->y; - return _cairo_int32x32_64_mul (dx, dx) + _cairo_int32x32_64_mul (dy, dy); -} - -static cairo_bool_t -within_tolerance (const cairo_point_t *p1, - const cairo_point_t *p2, - cairo_uint64_t tolerance) -{ - return FALSE; - return _cairo_int64_lt (point_distance_sq (p1, p2), tolerance); -} - -static void -contour_add_point (struct stroker *stroker, - struct stroke_contour *c, - const cairo_point_t *point) -{ - if (! within_tolerance (point, _cairo_contour_last_point (&c->contour), - stroker->contour_tolerance)) - _cairo_contour_add_point (&c->contour, point); - //*_cairo_contour_last_point (&c->contour) = *point; -} - -static void -translate_point (cairo_point_t *point, const cairo_point_t *offset) -{ - point->x += offset->x; - point->y += offset->y; -} - -static int -slope_compare_sgn (double dx1, double dy1, double dx2, double dy2) -{ - double c = (dx1 * dy2 - dx2 * dy1); - - if (c > 0) return 1; - if (c < 0) return -1; - return 0; -} - -static inline int -range_step (int i, int step, int max) -{ - i += step; - if (i < 0) - i = max - 1; - if (i >= max) - i = 0; - return i; -} - -/* - * Construct a fan around the midpoint using the vertices from pen between - * inpt and outpt. - */ -static void -add_fan (struct stroker *stroker, - const cairo_slope_t *in_vector, - const cairo_slope_t *out_vector, - const cairo_point_t *midpt, - cairo_bool_t clockwise, - struct stroke_contour *c) -{ - cairo_pen_t *pen = &stroker->pen; - int start, stop; - - if (stroker->has_bounds && - ! _cairo_box_contains_point (&stroker->bounds, midpt)) - return; - - assert (stroker->pen.num_vertices); - - if (clockwise) { - _cairo_pen_find_active_cw_vertices (pen, - in_vector, out_vector, - &start, &stop); - while (start != stop) { - cairo_point_t p = *midpt; - translate_point (&p, &pen->vertices[start].point); - contour_add_point (stroker, c, &p); - - if (++start == pen->num_vertices) - start = 0; - } - } else { - _cairo_pen_find_active_ccw_vertices (pen, - in_vector, out_vector, - &start, &stop); - while (start != stop) { - cairo_point_t p = *midpt; - translate_point (&p, &pen->vertices[start].point); - contour_add_point (stroker, c, &p); - - if (start-- == 0) - start += pen->num_vertices; - } - } -} - -static int -join_is_clockwise (const cairo_stroke_face_t *in, - const cairo_stroke_face_t *out) -{ - return _cairo_slope_compare (&in->dev_vector, &out->dev_vector) < 0; -} - -static void -inner_join (struct stroker *stroker, - const cairo_stroke_face_t *in, - const cairo_stroke_face_t *out, - int clockwise) -{ -#if 0 - cairo_point_t last; - const cairo_point_t *p, *outpt; - struct stroke_contour *inner; - cairo_int64_t d_p, d_last; - cairo_int64_t half_line_width; - cairo_bool_t negate; - - /* XXX line segments shorter than line-width */ - - if (clockwise) { - inner = &stroker->ccw; - outpt = &out->ccw; - negate = 1; - } else { - inner = &stroker->cw; - outpt = &out->cw; - negate = 0; - } - - half_line_width = CAIRO_FIXED_ONE*CAIRO_FIXED_ONE/2 * stroker->style.line_width * out->length + .5; - - /* On the inside, the previous end-point is always - * closer to the new face by definition. - */ - last = *_cairo_contour_last_point (&inner->contour); - d_last = distance_from_face (out, &last, negate); - _cairo_contour_remove_last_point (&inner->contour); - -prev: - if (inner->contour.chain.num_points == 0) { - contour_add_point (stroker, inner, outpt); - return; - } - p = _cairo_contour_last_point (&inner->contour); - d_p = distance_from_face (out, p, negate); - if (_cairo_int64_lt (d_p, half_line_width) && - !_cairo_int64_negative (distance_along_face (out, p))) - { - last = *p; - d_last = d_p; - _cairo_contour_remove_last_point (&inner->contour); - goto prev; - } - - compute_inner_joint (&last, d_last, p, d_p, half_line_width); - contour_add_point (stroker, inner, &last); -#else - const cairo_point_t *outpt; - struct stroke_contour *inner; - - if (clockwise) { - inner = &stroker->ccw; - outpt = &out->ccw; - } else { - inner = &stroker->cw; - outpt = &out->cw; - } - contour_add_point (stroker, inner, &in->point); - contour_add_point (stroker, inner, outpt); -#endif -} - -static void -inner_close (struct stroker *stroker, - const cairo_stroke_face_t *in, - cairo_stroke_face_t *out) -{ -#if 0 - cairo_point_t last; - const cairo_point_t *p, *outpt, *inpt; - struct stroke_contour *inner; - struct _cairo_contour_chain *chain; - - /* XXX line segments shorter than line-width */ - - if (join_is_clockwise (in, out)) { - inner = &stroker->ccw; - outpt = &in->ccw; - inpt = &out->ccw; - } else { - inner = &stroker->cw; - outpt = &in->cw; - inpt = &out->cw; - } - - if (inner->contour.chain.num_points == 0) { - contour_add_point (stroker, inner, &in->point); - contour_add_point (stroker, inner, inpt); - *_cairo_contour_first_point (&inner->contour) = - *_cairo_contour_last_point (&inner->contour); - return; - } - - line_width = stroker->style.line_width/2; - line_width *= CAIRO_FIXED_ONE; - - d_last = sign * distance_from_face (out, outpt); - last = *outpt; - - for (chain = &inner->contour.chain; chain; chain = chain->next) { - for (i = 0; i < chain->num_points; i++) { - p = &chain->points[i]; - if ((d_p = sign * distance_from_face (in, p)) >= line_width && - distance_from_edge (stroker, inpt, &last, p) < line_width) - { - goto out; - } - - if (p->x != last.x || p->y != last.y) { - last = *p; - d_last = d_p; - } - } - } -out: - - if (d_p != d_last) { - double dot = (line_width - d_last) / (d_p - d_last); - last.x += dot * (p->x - last.x); - last.y += dot * (p->y - last.y); - } - *_cairo_contour_last_point (&inner->contour) = last; - - for (chain = &inner->contour.chain; chain; chain = chain->next) { - for (i = 0; i < chain->num_points; i++) { - cairo_point_t *pp = &chain->points[i]; - if (pp == p) - return; - *pp = last; - } - } -#else - const cairo_point_t *inpt; - struct stroke_contour *inner; - - if (join_is_clockwise (in, out)) { - inner = &stroker->ccw; - inpt = &out->ccw; - } else { - inner = &stroker->cw; - inpt = &out->cw; - } - - contour_add_point (stroker, inner, &in->point); - contour_add_point (stroker, inner, inpt); - *_cairo_contour_first_point (&inner->contour) = - *_cairo_contour_last_point (&inner->contour); -#endif -} - -static void -outer_close (struct stroker *stroker, - const cairo_stroke_face_t *in, - const cairo_stroke_face_t *out) -{ - const cairo_point_t *inpt, *outpt; - struct stroke_contour *outer; - int clockwise; - - if (in->cw.x == out->cw.x && in->cw.y == out->cw.y && - in->ccw.x == out->ccw.x && in->ccw.y == out->ccw.y) - { - return; - } - - clockwise = join_is_clockwise (in, out); - if (clockwise) { - inpt = &in->cw; - outpt = &out->cw; - outer = &stroker->cw; - } else { - inpt = &in->ccw; - outpt = &out->ccw; - outer = &stroker->ccw; - } - - if (within_tolerance (inpt, outpt, stroker->contour_tolerance)) { - *_cairo_contour_first_point (&outer->contour) = - *_cairo_contour_last_point (&outer->contour); - return; - } - - switch (stroker->style.line_join) { - case CAIRO_LINE_JOIN_ROUND: - /* construct a fan around the common midpoint */ - if ((in->dev_slope.x * out->dev_slope.x + - in->dev_slope.y * out->dev_slope.y) < stroker->spline_cusp_tolerance) - { - add_fan (stroker, - &in->dev_vector, &out->dev_vector, &in->point, - clockwise, outer); - break; - } - - case CAIRO_LINE_JOIN_MITER: - default: { - /* dot product of incoming slope vector with outgoing slope vector */ - double in_dot_out = in->dev_slope.x * out->dev_slope.x + - in->dev_slope.y * out->dev_slope.y; - double ml = stroker->style.miter_limit; - - /* Check the miter limit -- lines meeting at an acute angle - * can generate long miters, the limit converts them to bevel - * - * Consider the miter join formed when two line segments - * meet at an angle psi: - * - * /.\ - * /. .\ - * /./ \.\ - * /./psi\.\ - * - * We can zoom in on the right half of that to see: - * - * |\ - * | \ psi/2 - * | \ - * | \ - * | \ - * | \ - * miter \ - * length \ - * | \ - * | .\ - * | . \ - * |. line \ - * \ width \ - * \ \ - * - * - * The right triangle in that figure, (the line-width side is - * shown faintly with three '.' characters), gives us the - * following expression relating miter length, angle and line - * width: - * - * 1 /sin (psi/2) = miter_length / line_width - * - * The right-hand side of this relationship is the same ratio - * in which the miter limit (ml) is expressed. We want to know - * when the miter length is within the miter limit. That is - * when the following condition holds: - * - * 1/sin(psi/2) <= ml - * 1 <= ml sin(psi/2) - * 1 <= ml² sin²(psi/2) - * 2 <= ml² 2 sin²(psi/2) - * 2·sin²(psi/2) = 1-cos(psi) - * 2 <= ml² (1-cos(psi)) - * - * in · out = |in| |out| cos (psi) - * - * in and out are both unit vectors, so: - * - * in · out = cos (psi) - * - * 2 <= ml² (1 - in · out) - * - */ - if (2 <= ml * ml * (1 + in_dot_out)) { - double x1, y1, x2, y2; - double mx, my; - double dx1, dx2, dy1, dy2; - double ix, iy; - double fdx1, fdy1, fdx2, fdy2; - double mdx, mdy; - - /* - * we've got the points already transformed to device - * space, but need to do some computation with them and - * also need to transform the slope from user space to - * device space - */ - /* outer point of incoming line face */ - x1 = _cairo_fixed_to_double (inpt->x); - y1 = _cairo_fixed_to_double (inpt->y); - dx1 = in->dev_slope.x; - dy1 = in->dev_slope.y; - - /* outer point of outgoing line face */ - x2 = _cairo_fixed_to_double (outpt->x); - y2 = _cairo_fixed_to_double (outpt->y); - dx2 = out->dev_slope.x; - dy2 = out->dev_slope.y; - - /* - * Compute the location of the outer corner of the miter. - * That's pretty easy -- just the intersection of the two - * outer edges. We've got slopes and points on each - * of those edges. Compute my directly, then compute - * mx by using the edge with the larger dy; that avoids - * dividing by values close to zero. - */ - my = (((x2 - x1) * dy1 * dy2 - y2 * dx2 * dy1 + y1 * dx1 * dy2) / - (dx1 * dy2 - dx2 * dy1)); - if (fabs (dy1) >= fabs (dy2)) - mx = (my - y1) * dx1 / dy1 + x1; - else - mx = (my - y2) * dx2 / dy2 + x2; - - /* - * When the two outer edges are nearly parallel, slight - * perturbations in the position of the outer points of the lines - * caused by representing them in fixed point form can cause the - * intersection point of the miter to move a large amount. If - * that moves the miter intersection from between the two faces, - * then draw a bevel instead. - */ - - ix = _cairo_fixed_to_double (in->point.x); - iy = _cairo_fixed_to_double (in->point.y); - - /* slope of one face */ - fdx1 = x1 - ix; fdy1 = y1 - iy; - - /* slope of the other face */ - fdx2 = x2 - ix; fdy2 = y2 - iy; - - /* slope from the intersection to the miter point */ - mdx = mx - ix; mdy = my - iy; - - /* - * Make sure the miter point line lies between the two - * faces by comparing the slopes - */ - if (slope_compare_sgn (fdx1, fdy1, mdx, mdy) != - slope_compare_sgn (fdx2, fdy2, mdx, mdy)) - { - cairo_point_t p; - - p.x = _cairo_fixed_from_double (mx); - p.y = _cairo_fixed_from_double (my); - - *_cairo_contour_last_point (&outer->contour) = p; - *_cairo_contour_first_point (&outer->contour) = p; - return; - } - } - break; - } - - case CAIRO_LINE_JOIN_BEVEL: - break; - } - contour_add_point (stroker, outer, outpt); -} - -static void -outer_join (struct stroker *stroker, - const cairo_stroke_face_t *in, - const cairo_stroke_face_t *out, - int clockwise) -{ - const cairo_point_t *inpt, *outpt; - struct stroke_contour *outer; - - if (in->cw.x == out->cw.x && in->cw.y == out->cw.y && - in->ccw.x == out->ccw.x && in->ccw.y == out->ccw.y) - { - return; - } - if (clockwise) { - inpt = &in->cw; - outpt = &out->cw; - outer = &stroker->cw; - } else { - inpt = &in->ccw; - outpt = &out->ccw; - outer = &stroker->ccw; - } - - switch (stroker->style.line_join) { - case CAIRO_LINE_JOIN_ROUND: - /* construct a fan around the common midpoint */ - add_fan (stroker, - &in->dev_vector, &out->dev_vector, &in->point, - clockwise, outer); - break; - - case CAIRO_LINE_JOIN_MITER: - default: { - /* dot product of incoming slope vector with outgoing slope vector */ - double in_dot_out = in->dev_slope.x * out->dev_slope.x + - in->dev_slope.y * out->dev_slope.y; - double ml = stroker->style.miter_limit; - - /* Check the miter limit -- lines meeting at an acute angle - * can generate long miters, the limit converts them to bevel - * - * Consider the miter join formed when two line segments - * meet at an angle psi: - * - * /.\ - * /. .\ - * /./ \.\ - * /./psi\.\ - * - * We can zoom in on the right half of that to see: - * - * |\ - * | \ psi/2 - * | \ - * | \ - * | \ - * | \ - * miter \ - * length \ - * | \ - * | .\ - * | . \ - * |. line \ - * \ width \ - * \ \ - * - * - * The right triangle in that figure, (the line-width side is - * shown faintly with three '.' characters), gives us the - * following expression relating miter length, angle and line - * width: - * - * 1 /sin (psi/2) = miter_length / line_width - * - * The right-hand side of this relationship is the same ratio - * in which the miter limit (ml) is expressed. We want to know - * when the miter length is within the miter limit. That is - * when the following condition holds: - * - * 1/sin(psi/2) <= ml - * 1 <= ml sin(psi/2) - * 1 <= ml² sin²(psi/2) - * 2 <= ml² 2 sin²(psi/2) - * 2·sin²(psi/2) = 1-cos(psi) - * 2 <= ml² (1-cos(psi)) - * - * in · out = |in| |out| cos (psi) - * - * in and out are both unit vectors, so: - * - * in · out = cos (psi) - * - * 2 <= ml² (1 - in · out) - * - */ - if (2 <= ml * ml * (1 + in_dot_out)) { - double x1, y1, x2, y2; - double mx, my; - double dx1, dx2, dy1, dy2; - double ix, iy; - double fdx1, fdy1, fdx2, fdy2; - double mdx, mdy; - - /* - * we've got the points already transformed to device - * space, but need to do some computation with them and - * also need to transform the slope from user space to - * device space - */ - /* outer point of incoming line face */ - x1 = _cairo_fixed_to_double (inpt->x); - y1 = _cairo_fixed_to_double (inpt->y); - dx1 = in->dev_slope.x; - dy1 = in->dev_slope.y; - - /* outer point of outgoing line face */ - x2 = _cairo_fixed_to_double (outpt->x); - y2 = _cairo_fixed_to_double (outpt->y); - dx2 = out->dev_slope.x; - dy2 = out->dev_slope.y; - - /* - * Compute the location of the outer corner of the miter. - * That's pretty easy -- just the intersection of the two - * outer edges. We've got slopes and points on each - * of those edges. Compute my directly, then compute - * mx by using the edge with the larger dy; that avoids - * dividing by values close to zero. - */ - my = (((x2 - x1) * dy1 * dy2 - y2 * dx2 * dy1 + y1 * dx1 * dy2) / - (dx1 * dy2 - dx2 * dy1)); - if (fabs (dy1) >= fabs (dy2)) - mx = (my - y1) * dx1 / dy1 + x1; - else - mx = (my - y2) * dx2 / dy2 + x2; - - /* - * When the two outer edges are nearly parallel, slight - * perturbations in the position of the outer points of the lines - * caused by representing them in fixed point form can cause the - * intersection point of the miter to move a large amount. If - * that moves the miter intersection from between the two faces, - * then draw a bevel instead. - */ - - ix = _cairo_fixed_to_double (in->point.x); - iy = _cairo_fixed_to_double (in->point.y); - - /* slope of one face */ - fdx1 = x1 - ix; fdy1 = y1 - iy; - - /* slope of the other face */ - fdx2 = x2 - ix; fdy2 = y2 - iy; - - /* slope from the intersection to the miter point */ - mdx = mx - ix; mdy = my - iy; - - /* - * Make sure the miter point line lies between the two - * faces by comparing the slopes - */ - if (slope_compare_sgn (fdx1, fdy1, mdx, mdy) != - slope_compare_sgn (fdx2, fdy2, mdx, mdy)) - { - cairo_point_t p; - - p.x = _cairo_fixed_from_double (mx); - p.y = _cairo_fixed_from_double (my); - - *_cairo_contour_last_point (&outer->contour) = p; - return; - } - } - break; - } - - case CAIRO_LINE_JOIN_BEVEL: - break; - } - contour_add_point (stroker,outer, outpt); -} - -static void -add_cap (struct stroker *stroker, - const cairo_stroke_face_t *f, - struct stroke_contour *c) -{ - switch (stroker->style.line_cap) { - case CAIRO_LINE_CAP_ROUND: { - cairo_slope_t slope; - - slope.dx = -f->dev_vector.dx; - slope.dy = -f->dev_vector.dy; - - add_fan (stroker, &f->dev_vector, &slope, &f->point, FALSE, c); - break; - } - - case CAIRO_LINE_CAP_SQUARE: { - cairo_slope_t fvector; - cairo_point_t p; - double dx, dy; - - dx = f->usr_vector.x; - dy = f->usr_vector.y; - dx *= stroker->half_line_width; - dy *= stroker->half_line_width; - cairo_matrix_transform_distance (stroker->ctm, &dx, &dy); - fvector.dx = _cairo_fixed_from_double (dx); - fvector.dy = _cairo_fixed_from_double (dy); - - p.x = f->ccw.x + fvector.dx; - p.y = f->ccw.y + fvector.dy; - contour_add_point (stroker, c, &p); - - p.x = f->cw.x + fvector.dx; - p.y = f->cw.y + fvector.dy; - contour_add_point (stroker, c, &p); - } - - case CAIRO_LINE_CAP_BUTT: - default: - break; - } - contour_add_point (stroker, c, &f->cw); -} - -static void -add_leading_cap (struct stroker *stroker, - const cairo_stroke_face_t *face, - struct stroke_contour *c) -{ - cairo_stroke_face_t reversed; - cairo_point_t t; - - reversed = *face; - - /* The initial cap needs an outward facing vector. Reverse everything */ - reversed.usr_vector.x = -reversed.usr_vector.x; - reversed.usr_vector.y = -reversed.usr_vector.y; - reversed.dev_vector.dx = -reversed.dev_vector.dx; - reversed.dev_vector.dy = -reversed.dev_vector.dy; - - t = reversed.cw; - reversed.cw = reversed.ccw; - reversed.ccw = t; - - add_cap (stroker, &reversed, c); -} - -static void -add_trailing_cap (struct stroker *stroker, - const cairo_stroke_face_t *face, - struct stroke_contour *c) -{ - add_cap (stroker, face, c); -} - -static inline double -normalize_slope (double *dx, double *dy) -{ - double dx0 = *dx, dy0 = *dy; - double mag; - - assert (dx0 != 0.0 || dy0 != 0.0); - - if (dx0 == 0.0) { - *dx = 0.0; - if (dy0 > 0.0) { - mag = dy0; - *dy = 1.0; - } else { - mag = -dy0; - *dy = -1.0; - } - } else if (dy0 == 0.0) { - *dy = 0.0; - if (dx0 > 0.0) { - mag = dx0; - *dx = 1.0; - } else { - mag = -dx0; - *dx = -1.0; - } - } else { - mag = hypot (dx0, dy0); - *dx = dx0 / mag; - *dy = dy0 / mag; - } - - return mag; -} - -static void -compute_face (const cairo_point_t *point, - const cairo_slope_t *dev_slope, - struct stroker *stroker, - cairo_stroke_face_t *face) -{ - double face_dx, face_dy; - cairo_point_t offset_ccw, offset_cw; - double slope_dx, slope_dy; - - slope_dx = _cairo_fixed_to_double (dev_slope->dx); - slope_dy = _cairo_fixed_to_double (dev_slope->dy); - face->length = normalize_slope (&slope_dx, &slope_dy); - face->dev_slope.x = slope_dx; - face->dev_slope.y = slope_dy; - - /* - * rotate to get a line_width/2 vector along the face, note that - * the vector must be rotated the right direction in device space, - * but by 90° in user space. So, the rotation depends on - * whether the ctm reflects or not, and that can be determined - * by looking at the determinant of the matrix. - */ - if (! _cairo_matrix_is_identity (stroker->ctm_inverse)) { - /* Normalize the matrix! */ - cairo_matrix_transform_distance (stroker->ctm_inverse, - &slope_dx, &slope_dy); - normalize_slope (&slope_dx, &slope_dy); - - if (stroker->ctm_det_positive) { - face_dx = - slope_dy * stroker->half_line_width; - face_dy = slope_dx * stroker->half_line_width; - } else { - face_dx = slope_dy * stroker->half_line_width; - face_dy = - slope_dx * stroker->half_line_width; - } - - /* back to device space */ - cairo_matrix_transform_distance (stroker->ctm, &face_dx, &face_dy); - } else { - face_dx = - slope_dy * stroker->half_line_width; - face_dy = slope_dx * stroker->half_line_width; - } - - offset_ccw.x = _cairo_fixed_from_double (face_dx); - offset_ccw.y = _cairo_fixed_from_double (face_dy); - offset_cw.x = -offset_ccw.x; - offset_cw.y = -offset_ccw.y; - - face->ccw = *point; - translate_point (&face->ccw, &offset_ccw); - - face->point = *point; - - face->cw = *point; - translate_point (&face->cw, &offset_cw); - - face->usr_vector.x = slope_dx; - face->usr_vector.y = slope_dy; - - face->dev_vector = *dev_slope; -} - -static void -add_caps (struct stroker *stroker) -{ - /* check for a degenerative sub_path */ - if (stroker->has_initial_sub_path && - ! stroker->has_first_face && - ! stroker->has_current_face && - stroker->style.line_cap == CAIRO_LINE_CAP_ROUND) - { - /* pick an arbitrary slope to use */ - cairo_slope_t slope = { CAIRO_FIXED_ONE, 0 }; - cairo_stroke_face_t face; - - /* arbitrarily choose first_point */ - compute_face (&stroker->first_point, &slope, stroker, &face); - - add_leading_cap (stroker, &face, &stroker->ccw); - add_trailing_cap (stroker, &face, &stroker->ccw); - - /* ensure the circle is complete */ - _cairo_contour_add_point (&stroker->ccw.contour, - _cairo_contour_first_point (&stroker->ccw.contour)); - - _cairo_polygon_add_contour (stroker->polygon, &stroker->ccw.contour); - _cairo_contour_reset (&stroker->ccw.contour); - } else { - if (stroker->has_current_face) - add_trailing_cap (stroker, &stroker->current_face, &stroker->ccw); - -#if DEBUG - { - FILE *file = fopen ("contours.txt", "a"); - _cairo_debug_print_contour (file, &stroker->path); - _cairo_debug_print_contour (file, &stroker->cw.contour); - _cairo_debug_print_contour (file, &stroker->ccw.contour); - fclose (file); - _cairo_contour_reset (&stroker->path); - } -#endif - - _cairo_polygon_add_contour (stroker->polygon, &stroker->ccw.contour); - _cairo_contour_reset (&stroker->ccw.contour); - - if (stroker->has_first_face) { - _cairo_contour_add_point (&stroker->ccw.contour, - &stroker->first_face.cw); - add_leading_cap (stroker, &stroker->first_face, &stroker->ccw); -#if DEBUG - { - FILE *file = fopen ("contours.txt", "a"); - _cairo_debug_print_contour (file, &stroker->ccw.contour); - fclose (file); - } -#endif - - _cairo_polygon_add_contour (stroker->polygon, - &stroker->ccw.contour); - _cairo_contour_reset (&stroker->ccw.contour); - } - - _cairo_polygon_add_contour (stroker->polygon, &stroker->cw.contour); - _cairo_contour_reset (&stroker->cw.contour); - } -} - -static cairo_status_t -close_path (void *closure); - -static cairo_status_t -move_to (void *closure, - const cairo_point_t *point) -{ - struct stroker *stroker = closure; - - /* Cap the start and end of the previous sub path as needed */ - add_caps (stroker); - - stroker->has_first_face = FALSE; - stroker->has_current_face = FALSE; - stroker->has_initial_sub_path = FALSE; - - stroker->first_point = *point; - -#if DEBUG - _cairo_contour_add_point (&stroker->path, point); -#endif - - stroker->current_face.point = *point; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -line_to (void *closure, - const cairo_point_t *point) -{ - struct stroker *stroker = closure; - cairo_stroke_face_t start; - cairo_point_t *p1 = &stroker->current_face.point; - cairo_slope_t dev_slope; - - stroker->has_initial_sub_path = TRUE; - - if (p1->x == point->x && p1->y == point->y) - return CAIRO_STATUS_SUCCESS; - -#if DEBUG - _cairo_contour_add_point (&stroker->path, point); -#endif - - _cairo_slope_init (&dev_slope, p1, point); - compute_face (p1, &dev_slope, stroker, &start); - - if (stroker->has_current_face) { - int clockwise = _cairo_slope_compare (&stroker->current_face.dev_vector, - &start.dev_vector); - if (clockwise) { - clockwise = clockwise < 0; - /* Join with final face from previous segment */ - if (! within_tolerance (&stroker->current_face.ccw, &start.ccw, - stroker->contour_tolerance) || - ! within_tolerance (&stroker->current_face.cw, &start.cw, - stroker->contour_tolerance)) - { - outer_join (stroker, &stroker->current_face, &start, clockwise); - inner_join (stroker, &stroker->current_face, &start, clockwise); - } - } - } else { - if (! stroker->has_first_face) { - /* Save sub path's first face in case needed for closing join */ - stroker->first_face = start; - stroker->has_first_face = TRUE; - } - stroker->has_current_face = TRUE; - - contour_add_point (stroker, &stroker->cw, &start.cw); - contour_add_point (stroker, &stroker->ccw, &start.ccw); - } - - stroker->current_face = start; - stroker->current_face.point = *point; - stroker->current_face.ccw.x += dev_slope.dx; - stroker->current_face.ccw.y += dev_slope.dy; - stroker->current_face.cw.x += dev_slope.dx; - stroker->current_face.cw.y += dev_slope.dy; - - contour_add_point (stroker, &stroker->cw, &stroker->current_face.cw); - contour_add_point (stroker, &stroker->ccw, &stroker->current_face.ccw); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -spline_to (void *closure, - const cairo_point_t *point, - const cairo_slope_t *tangent) -{ - struct stroker *stroker = closure; - cairo_stroke_face_t face; - -#if DEBUG - _cairo_contour_add_point (&stroker->path, point); -#endif - if ((tangent->dx | tangent->dy) == 0) { - struct stroke_contour *outer; - cairo_point_t t; - int clockwise; - - face = stroker->current_face; - - face.usr_vector.x = -face.usr_vector.x; - face.usr_vector.y = -face.usr_vector.y; - face.dev_vector.dx = -face.dev_vector.dx; - face.dev_vector.dy = -face.dev_vector.dy; - - t = face.cw; - face.cw = face.ccw; - face.ccw = t; - - clockwise = join_is_clockwise (&stroker->current_face, &face); - if (clockwise) { - outer = &stroker->cw; - } else { - outer = &stroker->ccw; - } - - add_fan (stroker, - &stroker->current_face.dev_vector, - &face.dev_vector, - &stroker->current_face.point, - clockwise, outer); - } else { - compute_face (point, tangent, stroker, &face); - - if ((face.dev_slope.x * stroker->current_face.dev_slope.x + - face.dev_slope.y * stroker->current_face.dev_slope.y) < stroker->spline_cusp_tolerance) - { - struct stroke_contour *outer; - int clockwise = join_is_clockwise (&stroker->current_face, &face); - - stroker->current_face.cw.x += face.point.x - stroker->current_face.point.x; - stroker->current_face.cw.y += face.point.y - stroker->current_face.point.y; - contour_add_point (stroker, &stroker->cw, &stroker->current_face.cw); - - stroker->current_face.ccw.x += face.point.x - stroker->current_face.point.x; - stroker->current_face.ccw.y += face.point.y - stroker->current_face.point.y; - contour_add_point (stroker, &stroker->ccw, &stroker->current_face.ccw); - - if (clockwise) { - outer = &stroker->cw; - } else { - outer = &stroker->ccw; - } - add_fan (stroker, - &stroker->current_face.dev_vector, - &face.dev_vector, - &stroker->current_face.point, - clockwise, outer); - } - - contour_add_point (stroker, &stroker->cw, &face.cw); - contour_add_point (stroker, &stroker->ccw, &face.ccw); - } - - stroker->current_face = face; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -curve_to (void *closure, - const cairo_point_t *b, - const cairo_point_t *c, - const cairo_point_t *d) -{ - struct stroker *stroker = closure; - cairo_spline_t spline; - cairo_stroke_face_t face; - - if (stroker->has_bounds && - ! _cairo_spline_intersects (&stroker->current_face.point, b, c, d, - &stroker->bounds)) - return line_to (closure, d); - - if (! _cairo_spline_init (&spline, spline_to, stroker, - &stroker->current_face.point, b, c, d)) - return line_to (closure, d); - - compute_face (&stroker->current_face.point, &spline.initial_slope, - stroker, &face); - - if (stroker->has_current_face) { - int clockwise = join_is_clockwise (&stroker->current_face, &face); - /* Join with final face from previous segment */ - outer_join (stroker, &stroker->current_face, &face, clockwise); - inner_join (stroker, &stroker->current_face, &face, clockwise); - } else { - if (! stroker->has_first_face) { - /* Save sub path's first face in case needed for closing join */ - stroker->first_face = face; - stroker->has_first_face = TRUE; - } - stroker->has_current_face = TRUE; - - contour_add_point (stroker, &stroker->cw, &face.cw); - contour_add_point (stroker, &stroker->ccw, &face.ccw); - } - stroker->current_face = face; - - return _cairo_spline_decompose (&spline, stroker->tolerance); -} - -static cairo_status_t -close_path (void *closure) -{ - struct stroker *stroker = closure; - cairo_status_t status; - - status = line_to (stroker, &stroker->first_point); - if (unlikely (status)) - return status; - - if (stroker->has_first_face && stroker->has_current_face) { - /* Join first and final faces of sub path */ - outer_close (stroker, &stroker->current_face, &stroker->first_face); - inner_close (stroker, &stroker->current_face, &stroker->first_face); -#if 0 - *_cairo_contour_first_point (&stroker->ccw.contour) = - *_cairo_contour_last_point (&stroker->ccw.contour); - - *_cairo_contour_first_point (&stroker->cw.contour) = - *_cairo_contour_last_point (&stroker->cw.contour); -#endif - - _cairo_polygon_add_contour (stroker->polygon, &stroker->cw.contour); - _cairo_polygon_add_contour (stroker->polygon, &stroker->ccw.contour); - -#if DEBUG - { - FILE *file = fopen ("contours.txt", "a"); - _cairo_debug_print_contour (file, &stroker->path); - _cairo_debug_print_contour (file, &stroker->cw.contour); - _cairo_debug_print_contour (file, &stroker->ccw.contour); - fclose (file); - - _cairo_contour_reset (&stroker->path); - } -#endif - _cairo_contour_reset (&stroker->cw.contour); - _cairo_contour_reset (&stroker->ccw.contour); - } else { - /* Cap the start and end of the sub path as needed */ - add_caps (stroker); - } - - stroker->has_initial_sub_path = FALSE; - stroker->has_first_face = FALSE; - stroker->has_current_face = FALSE; - - return CAIRO_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_path_fixed_stroke_to_polygon (const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_polygon_t *polygon) -{ - struct stroker stroker; - cairo_status_t status; - - if (style->num_dashes) { - return _cairo_path_fixed_stroke_dashed_to_polygon (path, - style, - ctm, - ctm_inverse, - tolerance, - polygon); - } - - stroker.has_bounds = polygon->num_limits; - if (stroker.has_bounds) { - /* Extend the bounds in each direction to account for the maximum area - * we might generate trapezoids, to capture line segments that are - * outside of the bounds but which might generate rendering that's - * within bounds. - */ - double dx, dy; - cairo_fixed_t fdx, fdy; - int i; - - stroker.bounds = polygon->limits[0]; - for (i = 1; i < polygon->num_limits; i++) - _cairo_box_add_box (&stroker.bounds, &polygon->limits[i]); - - _cairo_stroke_style_max_distance_from_path (style, path, ctm, &dx, &dy); - fdx = _cairo_fixed_from_double (dx); - fdy = _cairo_fixed_from_double (dy); - - stroker.bounds.p1.x -= fdx; - stroker.bounds.p2.x += fdx; - stroker.bounds.p1.y -= fdy; - stroker.bounds.p2.y += fdy; - } - - stroker.style = *style; - stroker.ctm = ctm; - stroker.ctm_inverse = ctm_inverse; - stroker.tolerance = tolerance; - stroker.half_line_width = style->line_width / 2.; - /* To test whether we need to join two segments of a spline using - * a round-join or a bevel-join, we can inspect the angle between the - * two segments. If the difference between the chord distance - * (half-line-width times the cosine of the bisection angle) and the - * half-line-width itself is greater than tolerance then we need to - * inject a point. - */ - stroker.spline_cusp_tolerance = 1 - tolerance / stroker.half_line_width; - stroker.spline_cusp_tolerance *= stroker.spline_cusp_tolerance; - stroker.spline_cusp_tolerance *= 2; - stroker.spline_cusp_tolerance -= 1; - stroker.ctm_det_positive = - _cairo_matrix_compute_determinant (ctm) >= 0.0; - - stroker.pen.num_vertices = 0; - if (path->has_curve_to || - style->line_join == CAIRO_LINE_JOIN_ROUND || - style->line_cap == CAIRO_LINE_CAP_ROUND) { - status = _cairo_pen_init (&stroker.pen, - stroker.half_line_width, - tolerance, ctm); - if (unlikely (status)) - return status; - - /* If the line width is so small that the pen is reduced to a - single point, then we have nothing to do. */ - if (stroker.pen.num_vertices <= 1) - return CAIRO_STATUS_SUCCESS; - } - - stroker.has_current_face = FALSE; - stroker.has_first_face = FALSE; - stroker.has_initial_sub_path = FALSE; - -#if DEBUG - remove ("contours.txt"); - remove ("polygons.txt"); - _cairo_contour_init (&stroker.path, 0); -#endif - _cairo_contour_init (&stroker.cw.contour, 1); - _cairo_contour_init (&stroker.ccw.contour, -1); - tolerance *= CAIRO_FIXED_ONE; - tolerance *= tolerance; - stroker.contour_tolerance = tolerance; - stroker.polygon = polygon; - - status = _cairo_path_fixed_interpret (path, - move_to, - line_to, - curve_to, - close_path, - &stroker); - /* Cap the start and end of the final sub path as needed */ - if (likely (status == CAIRO_STATUS_SUCCESS)) - add_caps (&stroker); - - _cairo_contour_fini (&stroker.cw.contour); - _cairo_contour_fini (&stroker.ccw.contour); - if (stroker.pen.num_vertices) - _cairo_pen_fini (&stroker.pen); - -#if DEBUG - { - FILE *file = fopen ("polygons.txt", "a"); - _cairo_debug_print_polygon (file, polygon); - fclose (file); - } -#endif - - return status; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-path-stroke-traps.c b/source/libs/cairo/cairo-src/src/cairo-path-stroke-traps.c deleted file mode 100644 index da54e5a358ff16e3dfd8eeb3722809ceca608367..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-path-stroke-traps.c +++ /dev/null @@ -1,1149 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2013 Intel Corporation - * - * 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> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-box-inline.h" -#include "cairo-path-fixed-private.h" -#include "cairo-slope-private.h" -#include "cairo-stroke-dash-private.h" -#include "cairo-traps-private.h" - -#include <float.h> - -struct stroker { - const cairo_stroke_style_t *style; - - const cairo_matrix_t *ctm; - const cairo_matrix_t *ctm_inverse; - double spline_cusp_tolerance; - double half_line_width; - double tolerance; - double ctm_determinant; - cairo_bool_t ctm_det_positive; - cairo_line_join_t line_join; - - cairo_traps_t *traps; - - cairo_pen_t pen; - - cairo_point_t first_point; - - cairo_bool_t has_initial_sub_path; - - cairo_bool_t has_current_face; - cairo_stroke_face_t current_face; - - cairo_bool_t has_first_face; - cairo_stroke_face_t first_face; - - cairo_stroker_dash_t dash; - - cairo_bool_t has_bounds; - cairo_box_t tight_bounds; - cairo_box_t line_bounds; - cairo_box_t join_bounds; -}; - -static cairo_status_t -stroker_init (struct stroker *stroker, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_traps_t *traps) -{ - cairo_status_t status; - - stroker->style = style; - stroker->ctm = ctm; - stroker->ctm_inverse = NULL; - if (! _cairo_matrix_is_identity (ctm_inverse)) - stroker->ctm_inverse = ctm_inverse; - stroker->line_join = style->line_join; - stroker->half_line_width = style->line_width / 2.0; - stroker->tolerance = tolerance; - stroker->traps = traps; - - /* To test whether we need to join two segments of a spline using - * a round-join or a bevel-join, we can inspect the angle between the - * two segments. If the difference between the chord distance - * (half-line-width times the cosine of the bisection angle) and the - * half-line-width itself is greater than tolerance then we need to - * inject a point. - */ - stroker->spline_cusp_tolerance = 1 - tolerance / stroker->half_line_width; - stroker->spline_cusp_tolerance *= stroker->spline_cusp_tolerance; - stroker->spline_cusp_tolerance *= 2; - stroker->spline_cusp_tolerance -= 1; - - stroker->ctm_determinant = _cairo_matrix_compute_determinant (stroker->ctm); - stroker->ctm_det_positive = stroker->ctm_determinant >= 0.0; - - status = _cairo_pen_init (&stroker->pen, - stroker->half_line_width, - tolerance, ctm); - if (unlikely (status)) - return status; - - stroker->has_current_face = FALSE; - stroker->has_first_face = FALSE; - stroker->has_initial_sub_path = FALSE; - - _cairo_stroker_dash_init (&stroker->dash, style); - - stroker->has_bounds = traps->num_limits; - if (stroker->has_bounds) { - /* Extend the bounds in each direction to account for the maximum area - * we might generate trapezoids, to capture line segments that are outside - * of the bounds but which might generate rendering that's within bounds. - */ - double dx, dy; - cairo_fixed_t fdx, fdy; - - stroker->tight_bounds = traps->bounds; - - _cairo_stroke_style_max_distance_from_path (stroker->style, path, - stroker->ctm, &dx, &dy); - - _cairo_stroke_style_max_line_distance_from_path (stroker->style, path, - stroker->ctm, &dx, &dy); - - fdx = _cairo_fixed_from_double (dx); - fdy = _cairo_fixed_from_double (dy); - - stroker->line_bounds = stroker->tight_bounds; - stroker->line_bounds.p1.x -= fdx; - stroker->line_bounds.p2.x += fdx; - stroker->line_bounds.p1.y -= fdy; - stroker->line_bounds.p2.y += fdy; - - _cairo_stroke_style_max_join_distance_from_path (stroker->style, path, - stroker->ctm, &dx, &dy); - - fdx = _cairo_fixed_from_double (dx); - fdy = _cairo_fixed_from_double (dy); - - stroker->join_bounds = stroker->tight_bounds; - stroker->join_bounds.p1.x -= fdx; - stroker->join_bounds.p2.x += fdx; - stroker->join_bounds.p1.y -= fdy; - stroker->join_bounds.p2.y += fdy; - } - - return CAIRO_STATUS_SUCCESS; -} - -static void -stroker_fini (struct stroker *stroker) -{ - _cairo_pen_fini (&stroker->pen); -} - -static void -translate_point (cairo_point_t *point, cairo_point_t *offset) -{ - point->x += offset->x; - point->y += offset->y; -} - -static int -join_is_clockwise (const cairo_stroke_face_t *in, - const cairo_stroke_face_t *out) -{ - return _cairo_slope_compare (&in->dev_vector, &out->dev_vector) < 0; -} - -static int -slope_compare_sgn (double dx1, double dy1, double dx2, double dy2) -{ - double c = dx1 * dy2 - dx2 * dy1; - if (c > 0) return 1; - if (c < 0) return -1; - return 0; -} - -static cairo_bool_t -stroker_intersects_join (const struct stroker *stroker, - const cairo_point_t *in, - const cairo_point_t *out) -{ - cairo_line_t segment; - - if (! stroker->has_bounds) - return TRUE; - - segment.p1 = *in; - segment.p2 = *out; - return _cairo_box_intersects_line_segment (&stroker->join_bounds, &segment); -} - -static void -join (struct stroker *stroker, - cairo_stroke_face_t *in, - cairo_stroke_face_t *out) -{ - int clockwise = join_is_clockwise (out, in); - cairo_point_t *inpt, *outpt; - - if (in->cw.x == out->cw.x && - in->cw.y == out->cw.y && - in->ccw.x == out->ccw.x && - in->ccw.y == out->ccw.y) - { - return; - } - - if (clockwise) { - inpt = &in->ccw; - outpt = &out->ccw; - } else { - inpt = &in->cw; - outpt = &out->cw; - } - - if (! stroker_intersects_join (stroker, inpt, outpt)) - return; - - switch (stroker->line_join) { - case CAIRO_LINE_JOIN_ROUND: - /* construct a fan around the common midpoint */ - if ((in->dev_slope.x * out->dev_slope.x + - in->dev_slope.y * out->dev_slope.y) < stroker->spline_cusp_tolerance) - { - int start, stop; - cairo_point_t tri[3], edges[4]; - cairo_pen_t *pen = &stroker->pen; - - edges[0] = in->cw; - edges[1] = in->ccw; - tri[0] = in->point; - tri[1] = *inpt; - if (clockwise) { - _cairo_pen_find_active_ccw_vertices (pen, - &in->dev_vector, &out->dev_vector, - &start, &stop); - while (start != stop) { - tri[2] = in->point; - translate_point (&tri[2], &pen->vertices[start].point); - edges[2] = in->point; - edges[3] = tri[2]; - _cairo_traps_tessellate_triangle_with_edges (stroker->traps, - tri, edges); - tri[1] = tri[2]; - edges[0] = edges[2]; - edges[1] = edges[3]; - - if (start-- == 0) - start += pen->num_vertices; - } - } else { - _cairo_pen_find_active_cw_vertices (pen, - &in->dev_vector, &out->dev_vector, - &start, &stop); - while (start != stop) { - tri[2] = in->point; - translate_point (&tri[2], &pen->vertices[start].point); - edges[2] = in->point; - edges[3] = tri[2]; - _cairo_traps_tessellate_triangle_with_edges (stroker->traps, - tri, edges); - tri[1] = tri[2]; - edges[0] = edges[2]; - edges[1] = edges[3]; - - if (++start == pen->num_vertices) - start = 0; - } - } - tri[2] = *outpt; - edges[2] = out->cw; - edges[3] = out->ccw; - _cairo_traps_tessellate_triangle_with_edges (stroker->traps, - tri, edges); - } else { - cairo_point_t t[] = { { in->point.x, in->point.y}, { inpt->x, inpt->y }, { outpt->x, outpt->y } }; - cairo_point_t e[] = { { in->cw.x, in->cw.y}, { in->ccw.x, in->ccw.y }, - { out->cw.x, out->cw.y}, { out->ccw.x, out->ccw.y } }; - _cairo_traps_tessellate_triangle_with_edges (stroker->traps, t, e); - } - break; - - case CAIRO_LINE_JOIN_MITER: - default: { - /* dot product of incoming slope vector with outgoing slope vector */ - double in_dot_out = (-in->usr_vector.x * out->usr_vector.x + - -in->usr_vector.y * out->usr_vector.y); - double ml = stroker->style->miter_limit; - - /* Check the miter limit -- lines meeting at an acute angle - * can generate long miters, the limit converts them to bevel - * - * Consider the miter join formed when two line segments - * meet at an angle psi: - * - * /.\ - * /. .\ - * /./ \.\ - * /./psi\.\ - * - * We can zoom in on the right half of that to see: - * - * |\ - * | \ psi/2 - * | \ - * | \ - * | \ - * | \ - * miter \ - * length \ - * | \ - * | .\ - * | . \ - * |. line \ - * \ width \ - * \ \ - * - * - * The right triangle in that figure, (the line-width side is - * shown faintly with three '.' characters), gives us the - * following expression relating miter length, angle and line - * width: - * - * 1 /sin (psi/2) = miter_length / line_width - * - * The right-hand side of this relationship is the same ratio - * in which the miter limit (ml) is expressed. We want to know - * when the miter length is within the miter limit. That is - * when the following condition holds: - * - * 1/sin(psi/2) <= ml - * 1 <= ml sin(psi/2) - * 1 <= ml² sin²(psi/2) - * 2 <= ml² 2 sin²(psi/2) - * 2·sin²(psi/2) = 1-cos(psi) - * 2 <= ml² (1-cos(psi)) - * - * in · out = |in| |out| cos (psi) - * - * in and out are both unit vectors, so: - * - * in · out = cos (psi) - * - * 2 <= ml² (1 - in · out) - * - */ - if (2 <= ml * ml * (1 - in_dot_out)) { - double x1, y1, x2, y2; - double mx, my; - double dx1, dx2, dy1, dy2; - cairo_point_t outer; - cairo_point_t quad[4]; - double ix, iy; - double fdx1, fdy1, fdx2, fdy2; - double mdx, mdy; - - /* - * we've got the points already transformed to device - * space, but need to do some computation with them and - * also need to transform the slope from user space to - * device space - */ - /* outer point of incoming line face */ - x1 = _cairo_fixed_to_double (inpt->x); - y1 = _cairo_fixed_to_double (inpt->y); - dx1 = in->usr_vector.x; - dy1 = in->usr_vector.y; - cairo_matrix_transform_distance (stroker->ctm, &dx1, &dy1); - - /* outer point of outgoing line face */ - x2 = _cairo_fixed_to_double (outpt->x); - y2 = _cairo_fixed_to_double (outpt->y); - dx2 = out->usr_vector.x; - dy2 = out->usr_vector.y; - cairo_matrix_transform_distance (stroker->ctm, &dx2, &dy2); - - /* - * Compute the location of the outer corner of the miter. - * That's pretty easy -- just the intersection of the two - * outer edges. We've got slopes and points on each - * of those edges. Compute my directly, then compute - * mx by using the edge with the larger dy; that avoids - * dividing by values close to zero. - */ - my = (((x2 - x1) * dy1 * dy2 - y2 * dx2 * dy1 + y1 * dx1 * dy2) / - (dx1 * dy2 - dx2 * dy1)); - if (fabs (dy1) >= fabs (dy2)) - mx = (my - y1) * dx1 / dy1 + x1; - else - mx = (my - y2) * dx2 / dy2 + x2; - - /* - * When the two outer edges are nearly parallel, slight - * perturbations in the position of the outer points of the lines - * caused by representing them in fixed point form can cause the - * intersection point of the miter to move a large amount. If - * that moves the miter intersection from between the two faces, - * then draw a bevel instead. - */ - - ix = _cairo_fixed_to_double (in->point.x); - iy = _cairo_fixed_to_double (in->point.y); - - /* slope of one face */ - fdx1 = x1 - ix; fdy1 = y1 - iy; - - /* slope of the other face */ - fdx2 = x2 - ix; fdy2 = y2 - iy; - - /* slope from the intersection to the miter point */ - mdx = mx - ix; mdy = my - iy; - - /* - * Make sure the miter point line lies between the two - * faces by comparing the slopes - */ - if (slope_compare_sgn (fdx1, fdy1, mdx, mdy) != - slope_compare_sgn (fdx2, fdy2, mdx, mdy)) - { - /* - * Draw the quadrilateral - */ - outer.x = _cairo_fixed_from_double (mx); - outer.y = _cairo_fixed_from_double (my); - - quad[0] = in->point; - quad[1] = *inpt; - quad[2] = outer; - quad[3] = *outpt; - - _cairo_traps_tessellate_convex_quad (stroker->traps, quad); - break; - } - } - /* fall through ... */ - } - - case CAIRO_LINE_JOIN_BEVEL: { - cairo_point_t t[] = { { in->point.x, in->point.y }, { inpt->x, inpt->y }, { outpt->x, outpt->y } }; - cairo_point_t e[] = { { in->cw.x, in->cw.y }, { in->ccw.x, in->ccw.y }, - { out->cw.x, out->cw.y }, { out->ccw.x, out->ccw.y } }; - _cairo_traps_tessellate_triangle_with_edges (stroker->traps, t, e); - break; - } - } -} - -static void -add_cap (struct stroker *stroker, cairo_stroke_face_t *f) -{ - switch (stroker->style->line_cap) { - case CAIRO_LINE_CAP_ROUND: { - int start, stop; - cairo_slope_t in_slope, out_slope; - cairo_point_t tri[3], edges[4]; - cairo_pen_t *pen = &stroker->pen; - - in_slope = f->dev_vector; - out_slope.dx = -in_slope.dx; - out_slope.dy = -in_slope.dy; - _cairo_pen_find_active_cw_vertices (pen, &in_slope, &out_slope, - &start, &stop); - edges[0] = f->cw; - edges[1] = f->ccw; - tri[0] = f->point; - tri[1] = f->cw; - while (start != stop) { - tri[2] = f->point; - translate_point (&tri[2], &pen->vertices[start].point); - edges[2] = f->point; - edges[3] = tri[2]; - _cairo_traps_tessellate_triangle_with_edges (stroker->traps, - tri, edges); - - tri[1] = tri[2]; - edges[0] = edges[2]; - edges[1] = edges[3]; - if (++start == pen->num_vertices) - start = 0; - } - tri[2] = f->ccw; - edges[2] = f->cw; - edges[3] = f->ccw; - _cairo_traps_tessellate_triangle_with_edges (stroker->traps, - tri, edges); - break; - } - - case CAIRO_LINE_CAP_SQUARE: { - double dx, dy; - cairo_slope_t fvector; - cairo_point_t quad[4]; - - dx = f->usr_vector.x; - dy = f->usr_vector.y; - dx *= stroker->half_line_width; - dy *= stroker->half_line_width; - cairo_matrix_transform_distance (stroker->ctm, &dx, &dy); - fvector.dx = _cairo_fixed_from_double (dx); - fvector.dy = _cairo_fixed_from_double (dy); - - quad[0] = f->cw; - quad[1].x = f->cw.x + fvector.dx; - quad[1].y = f->cw.y + fvector.dy; - quad[2].x = f->ccw.x + fvector.dx; - quad[2].y = f->ccw.y + fvector.dy; - quad[3] = f->ccw; - - _cairo_traps_tessellate_convex_quad (stroker->traps, quad); - break; - } - - case CAIRO_LINE_CAP_BUTT: - default: - break; - } -} - -static void -add_leading_cap (struct stroker *stroker, - cairo_stroke_face_t *face) -{ - cairo_stroke_face_t reversed; - cairo_point_t t; - - reversed = *face; - - /* The initial cap needs an outward facing vector. Reverse everything */ - reversed.usr_vector.x = -reversed.usr_vector.x; - reversed.usr_vector.y = -reversed.usr_vector.y; - reversed.dev_vector.dx = -reversed.dev_vector.dx; - reversed.dev_vector.dy = -reversed.dev_vector.dy; - t = reversed.cw; - reversed.cw = reversed.ccw; - reversed.ccw = t; - - add_cap (stroker, &reversed); -} - -static void -add_trailing_cap (struct stroker *stroker, cairo_stroke_face_t *face) -{ - add_cap (stroker, face); -} - -static inline double -normalize_slope (double *dx, double *dy) -{ - double dx0 = *dx, dy0 = *dy; - - if (dx0 == 0.0 && dy0 == 0.0) - return 0; - - if (dx0 == 0.0) { - *dx = 0.0; - if (dy0 > 0.0) { - *dy = 1.0; - return dy0; - } else { - *dy = -1.0; - return -dy0; - } - } else if (dy0 == 0.0) { - *dy = 0.0; - if (dx0 > 0.0) { - *dx = 1.0; - return dx0; - } else { - *dx = -1.0; - return -dx0; - } - } else { - double mag = hypot (dx0, dy0); - *dx = dx0 / mag; - *dy = dy0 / mag; - return mag; - } -} - -static void -compute_face (const cairo_point_t *point, - const cairo_slope_t *dev_slope, - struct stroker *stroker, - cairo_stroke_face_t *face) -{ - double face_dx, face_dy; - cairo_point_t offset_ccw, offset_cw; - double slope_dx, slope_dy; - - slope_dx = _cairo_fixed_to_double (dev_slope->dx); - slope_dy = _cairo_fixed_to_double (dev_slope->dy); - face->length = normalize_slope (&slope_dx, &slope_dy); - face->dev_slope.x = slope_dx; - face->dev_slope.y = slope_dy; - - /* - * rotate to get a line_width/2 vector along the face, note that - * the vector must be rotated the right direction in device space, - * but by 90° in user space. So, the rotation depends on - * whether the ctm reflects or not, and that can be determined - * by looking at the determinant of the matrix. - */ - if (stroker->ctm_inverse) { - cairo_matrix_transform_distance (stroker->ctm_inverse, &slope_dx, &slope_dy); - normalize_slope (&slope_dx, &slope_dy); - - if (stroker->ctm_det_positive) { - face_dx = - slope_dy * stroker->half_line_width; - face_dy = slope_dx * stroker->half_line_width; - } else { - face_dx = slope_dy * stroker->half_line_width; - face_dy = - slope_dx * stroker->half_line_width; - } - - /* back to device space */ - cairo_matrix_transform_distance (stroker->ctm, &face_dx, &face_dy); - } else { - face_dx = - slope_dy * stroker->half_line_width; - face_dy = slope_dx * stroker->half_line_width; - } - - offset_ccw.x = _cairo_fixed_from_double (face_dx); - offset_ccw.y = _cairo_fixed_from_double (face_dy); - offset_cw.x = -offset_ccw.x; - offset_cw.y = -offset_ccw.y; - - face->ccw = *point; - translate_point (&face->ccw, &offset_ccw); - - face->point = *point; - - face->cw = *point; - translate_point (&face->cw, &offset_cw); - - face->usr_vector.x = slope_dx; - face->usr_vector.y = slope_dy; - - face->dev_vector = *dev_slope; -} - -static void -add_caps (struct stroker *stroker) -{ - /* check for a degenerative sub_path */ - if (stroker->has_initial_sub_path && - !stroker->has_first_face && - !stroker->has_current_face && - stroker->style->line_cap == CAIRO_LINE_CAP_ROUND) - { - /* pick an arbitrary slope to use */ - cairo_slope_t slope = { CAIRO_FIXED_ONE, 0 }; - cairo_stroke_face_t face; - - /* arbitrarily choose first_point - * first_point and current_point should be the same */ - compute_face (&stroker->first_point, &slope, stroker, &face); - - add_leading_cap (stroker, &face); - add_trailing_cap (stroker, &face); - } - - if (stroker->has_first_face) - add_leading_cap (stroker, &stroker->first_face); - - if (stroker->has_current_face) - add_trailing_cap (stroker, &stroker->current_face); -} - -static cairo_bool_t -stroker_intersects_edge (const struct stroker *stroker, - const cairo_stroke_face_t *start, - const cairo_stroke_face_t *end) -{ - cairo_box_t box; - - if (! stroker->has_bounds) - return TRUE; - - if (_cairo_box_contains_point (&stroker->tight_bounds, &start->cw)) - return TRUE; - box.p2 = box.p1 = start->cw; - - if (_cairo_box_contains_point (&stroker->tight_bounds, &start->ccw)) - return TRUE; - _cairo_box_add_point (&box, &start->ccw); - - if (_cairo_box_contains_point (&stroker->tight_bounds, &end->cw)) - return TRUE; - _cairo_box_add_point (&box, &end->cw); - - if (_cairo_box_contains_point (&stroker->tight_bounds, &end->ccw)) - return TRUE; - _cairo_box_add_point (&box, &end->ccw); - - return (box.p2.x > stroker->tight_bounds.p1.x && - box.p1.x < stroker->tight_bounds.p2.x && - box.p2.y > stroker->tight_bounds.p1.y && - box.p1.y < stroker->tight_bounds.p2.y); -} - -static void -add_sub_edge (struct stroker *stroker, - const cairo_point_t *p1, const cairo_point_t *p2, - const cairo_slope_t *dev_slope, - cairo_stroke_face_t *start, cairo_stroke_face_t *end) -{ - cairo_point_t rectangle[4]; - - compute_face (p1, dev_slope, stroker, start); - - *end = *start; - end->point = *p2; - rectangle[0].x = p2->x - p1->x; - rectangle[0].y = p2->y - p1->y; - translate_point (&end->ccw, &rectangle[0]); - translate_point (&end->cw, &rectangle[0]); - - if (p1->x == p2->x && p1->y == p2->y) - return; - - if (! stroker_intersects_edge (stroker, start, end)) - return; - - rectangle[0] = start->cw; - rectangle[1] = start->ccw; - rectangle[2] = end->ccw; - rectangle[3] = end->cw; - - _cairo_traps_tessellate_convex_quad (stroker->traps, rectangle); -} - -static cairo_status_t -move_to (void *closure, const cairo_point_t *point) -{ - struct stroker *stroker = closure; - - /* Cap the start and end of the previous sub path as needed */ - add_caps (stroker); - - stroker->first_point = *point; - stroker->current_face.point = *point; - - stroker->has_first_face = FALSE; - stroker->has_current_face = FALSE; - stroker->has_initial_sub_path = FALSE; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -move_to_dashed (void *closure, const cairo_point_t *point) -{ - /* reset the dash pattern for new sub paths */ - struct stroker *stroker = closure; - - _cairo_stroker_dash_start (&stroker->dash); - return move_to (closure, point); -} - -static cairo_status_t -line_to (void *closure, const cairo_point_t *point) -{ - struct stroker *stroker = closure; - cairo_stroke_face_t start, end; - const cairo_point_t *p1 = &stroker->current_face.point; - const cairo_point_t *p2 = point; - cairo_slope_t dev_slope; - - stroker->has_initial_sub_path = TRUE; - - if (p1->x == p2->x && p1->y == p2->y) - return CAIRO_STATUS_SUCCESS; - - _cairo_slope_init (&dev_slope, p1, p2); - add_sub_edge (stroker, p1, p2, &dev_slope, &start, &end); - - if (stroker->has_current_face) { - /* Join with final face from previous segment */ - join (stroker, &stroker->current_face, &start); - } else if (!stroker->has_first_face) { - /* Save sub path's first face in case needed for closing join */ - stroker->first_face = start; - stroker->has_first_face = TRUE; - } - stroker->current_face = end; - stroker->has_current_face = TRUE; - - return CAIRO_STATUS_SUCCESS; -} - -/* - * Dashed lines. Cap each dash end, join around turns when on - */ -static cairo_status_t -line_to_dashed (void *closure, const cairo_point_t *point) -{ - struct stroker *stroker = closure; - double mag, remain, step_length = 0; - double slope_dx, slope_dy; - double dx2, dy2; - cairo_stroke_face_t sub_start, sub_end; - const cairo_point_t *p1 = &stroker->current_face.point; - const cairo_point_t *p2 = point; - cairo_slope_t dev_slope; - cairo_line_t segment; - cairo_bool_t fully_in_bounds; - - stroker->has_initial_sub_path = stroker->dash.dash_starts_on; - - if (p1->x == p2->x && p1->y == p2->y) - return CAIRO_STATUS_SUCCESS; - - fully_in_bounds = TRUE; - if (stroker->has_bounds && - (! _cairo_box_contains_point (&stroker->join_bounds, p1) || - ! _cairo_box_contains_point (&stroker->join_bounds, p2))) - { - fully_in_bounds = FALSE; - } - - _cairo_slope_init (&dev_slope, p1, p2); - - slope_dx = _cairo_fixed_to_double (p2->x - p1->x); - slope_dy = _cairo_fixed_to_double (p2->y - p1->y); - - if (stroker->ctm_inverse) - cairo_matrix_transform_distance (stroker->ctm_inverse, &slope_dx, &slope_dy); - mag = normalize_slope (&slope_dx, &slope_dy); - if (mag <= DBL_EPSILON) - return CAIRO_STATUS_SUCCESS; - - remain = mag; - segment.p1 = *p1; - while (remain) { - step_length = MIN (stroker->dash.dash_remain, remain); - remain -= step_length; - dx2 = slope_dx * (mag - remain); - dy2 = slope_dy * (mag - remain); - cairo_matrix_transform_distance (stroker->ctm, &dx2, &dy2); - segment.p2.x = _cairo_fixed_from_double (dx2) + p1->x; - segment.p2.y = _cairo_fixed_from_double (dy2) + p1->y; - - if (stroker->dash.dash_on && - (fully_in_bounds || - (! stroker->has_first_face && stroker->dash.dash_starts_on) || - _cairo_box_intersects_line_segment (&stroker->join_bounds, &segment))) - { - add_sub_edge (stroker, - &segment.p1, &segment.p2, - &dev_slope, - &sub_start, &sub_end); - - if (stroker->has_current_face) { - /* Join with final face from previous segment */ - join (stroker, &stroker->current_face, &sub_start); - - stroker->has_current_face = FALSE; - } else if (! stroker->has_first_face && stroker->dash.dash_starts_on) { - /* Save sub path's first face in case needed for closing join */ - stroker->first_face = sub_start; - stroker->has_first_face = TRUE; - } else { - /* Cap dash start if not connecting to a previous segment */ - add_leading_cap (stroker, &sub_start); - } - - if (remain) { - /* Cap dash end if not at end of segment */ - add_trailing_cap (stroker, &sub_end); - } else { - stroker->current_face = sub_end; - stroker->has_current_face = TRUE; - } - } else { - if (stroker->has_current_face) { - /* Cap final face from previous segment */ - add_trailing_cap (stroker, &stroker->current_face); - - stroker->has_current_face = FALSE; - } - } - - _cairo_stroker_dash_step (&stroker->dash, step_length); - segment.p1 = segment.p2; - } - - if (stroker->dash.dash_on && ! stroker->has_current_face) { - /* This segment ends on a transition to dash_on, compute a new face - * and add cap for the beginning of the next dash_on step. - * - * Note: this will create a degenerate cap if this is not the last line - * in the path. Whether this behaviour is desirable or not is debatable. - * On one side these degenerate caps can not be reproduced with regular - * path stroking. - * On the other hand, Acroread 7 also produces the degenerate caps. - */ - compute_face (point, &dev_slope, stroker, &stroker->current_face); - - add_leading_cap (stroker, &stroker->current_face); - - stroker->has_current_face = TRUE; - } else - stroker->current_face.point = *point; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -spline_to (void *closure, - const cairo_point_t *point, - const cairo_slope_t *tangent) -{ - struct stroker *stroker = closure; - cairo_stroke_face_t face; - - if ((tangent->dx | tangent->dy) == 0) { - cairo_point_t t; - - face = stroker->current_face; - - face.usr_vector.x = -face.usr_vector.x; - face.usr_vector.y = -face.usr_vector.y; - face.dev_slope.x = -face.dev_slope.x; - face.dev_slope.y = -face.dev_slope.y; - face.dev_vector.dx = -face.dev_vector.dx; - face.dev_vector.dy = -face.dev_vector.dy; - - t = face.cw; - face.cw = face.ccw; - face.ccw = t; - - join (stroker, &stroker->current_face, &face); - } else { - cairo_point_t rectangle[4]; - - compute_face (&stroker->current_face.point, tangent, stroker, &face); - join (stroker, &stroker->current_face, &face); - - rectangle[0] = face.cw; - rectangle[1] = face.ccw; - - rectangle[2].x = point->x - face.point.x; - rectangle[2].y = point->y - face.point.y; - face.point = *point; - translate_point (&face.ccw, &rectangle[2]); - translate_point (&face.cw, &rectangle[2]); - - rectangle[2] = face.ccw; - rectangle[3] = face.cw; - - _cairo_traps_tessellate_convex_quad (stroker->traps, rectangle); - } - - stroker->current_face = face; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -curve_to (void *closure, - const cairo_point_t *b, - const cairo_point_t *c, - const cairo_point_t *d) -{ - struct stroker *stroker = closure; - cairo_line_join_t line_join_save; - cairo_spline_t spline; - cairo_stroke_face_t face; - cairo_status_t status; - - if (stroker->has_bounds && - ! _cairo_spline_intersects (&stroker->current_face.point, b, c, d, - &stroker->line_bounds)) - return line_to (closure, d); - - if (! _cairo_spline_init (&spline, spline_to, stroker, - &stroker->current_face.point, b, c, d)) - return line_to (closure, d); - - compute_face (&stroker->current_face.point, &spline.initial_slope, - stroker, &face); - - if (stroker->has_current_face) { - /* Join with final face from previous segment */ - join (stroker, &stroker->current_face, &face); - } else { - if (! stroker->has_first_face) { - /* Save sub path's first face in case needed for closing join */ - stroker->first_face = face; - stroker->has_first_face = TRUE; - } - stroker->has_current_face = TRUE; - } - stroker->current_face = face; - - /* Temporarily modify the stroker to use round joins to guarantee - * smooth stroked curves. */ - line_join_save = stroker->line_join; - stroker->line_join = CAIRO_LINE_JOIN_ROUND; - - status = _cairo_spline_decompose (&spline, stroker->tolerance); - - stroker->line_join = line_join_save; - - return status; -} - -static cairo_status_t -curve_to_dashed (void *closure, - const cairo_point_t *b, - const cairo_point_t *c, - const cairo_point_t *d) -{ - struct stroker *stroker = closure; - cairo_spline_t spline; - cairo_line_join_t line_join_save; - cairo_spline_add_point_func_t func; - cairo_status_t status; - - func = (cairo_spline_add_point_func_t)line_to_dashed; - - if (stroker->has_bounds && - ! _cairo_spline_intersects (&stroker->current_face.point, b, c, d, - &stroker->line_bounds)) - return func (closure, d, NULL); - - if (! _cairo_spline_init (&spline, func, stroker, - &stroker->current_face.point, b, c, d)) - return func (closure, d, NULL); - - /* Temporarily modify the stroker to use round joins to guarantee - * smooth stroked curves. */ - line_join_save = stroker->line_join; - stroker->line_join = CAIRO_LINE_JOIN_ROUND; - - status = _cairo_spline_decompose (&spline, stroker->tolerance); - - stroker->line_join = line_join_save; - - return status; -} - -static cairo_status_t -_close_path (struct stroker *stroker) -{ - if (stroker->has_first_face && stroker->has_current_face) { - /* Join first and final faces of sub path */ - join (stroker, &stroker->current_face, &stroker->first_face); - } else { - /* Cap the start and end of the sub path as needed */ - add_caps (stroker); - } - - stroker->has_initial_sub_path = FALSE; - stroker->has_first_face = FALSE; - stroker->has_current_face = FALSE; - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -close_path (void *closure) -{ - struct stroker *stroker = closure; - cairo_status_t status; - - status = line_to (stroker, &stroker->first_point); - if (unlikely (status)) - return status; - - return _close_path (stroker); -} - -static cairo_status_t -close_path_dashed (void *closure) -{ - struct stroker *stroker = closure; - cairo_status_t status; - - status = line_to_dashed (stroker, &stroker->first_point); - if (unlikely (status)) - return status; - - return _close_path (stroker); -} - -cairo_int_status_t -_cairo_path_fixed_stroke_to_traps (const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_traps_t *traps) -{ - struct stroker stroker; - cairo_status_t status; - - status = stroker_init (&stroker, path, style, - ctm, ctm_inverse, tolerance, - traps); - if (unlikely (status)) - return status; - - if (stroker.dash.dashed) - status = _cairo_path_fixed_interpret (path, - move_to_dashed, - line_to_dashed, - curve_to_dashed, - close_path_dashed, - &stroker); - else - status = _cairo_path_fixed_interpret (path, - move_to, - line_to, - curve_to, - close_path, - &stroker); - assert(status == CAIRO_STATUS_SUCCESS); - add_caps (&stroker); - - stroker_fini (&stroker); - - return traps->status; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-path-stroke-tristrip.c b/source/libs/cairo/cairo-src/src/cairo-path-stroke-tristrip.c deleted file mode 100644 index 6ce4131cc0fb881f4aab5999925bd71547ba3aca..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-path-stroke-tristrip.c +++ /dev/null @@ -1,1088 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#define _BSD_SOURCE /* for hypot() */ -#include "cairoint.h" - -#include "cairo-box-inline.h" -#include "cairo-boxes-private.h" -#include "cairo-error-private.h" -#include "cairo-path-fixed-private.h" -#include "cairo-slope-private.h" -#include "cairo-tristrip-private.h" - -struct stroker { - cairo_stroke_style_t style; - - cairo_tristrip_t *strip; - - const cairo_matrix_t *ctm; - const cairo_matrix_t *ctm_inverse; - double tolerance; - cairo_bool_t ctm_det_positive; - - cairo_pen_t pen; - - cairo_bool_t has_sub_path; - - cairo_point_t first_point; - - cairo_bool_t has_current_face; - cairo_stroke_face_t current_face; - - cairo_bool_t has_first_face; - cairo_stroke_face_t first_face; - - cairo_box_t limit; - cairo_bool_t has_limits; -}; - -static inline double -normalize_slope (double *dx, double *dy); - -static void -compute_face (const cairo_point_t *point, - const cairo_slope_t *dev_slope, - struct stroker *stroker, - cairo_stroke_face_t *face); - -static void -translate_point (cairo_point_t *point, const cairo_point_t *offset) -{ - point->x += offset->x; - point->y += offset->y; -} - -static int -slope_compare_sgn (double dx1, double dy1, double dx2, double dy2) -{ - double c = (dx1 * dy2 - dx2 * dy1); - - if (c > 0) return 1; - if (c < 0) return -1; - return 0; -} - -static inline int -range_step (int i, int step, int max) -{ - i += step; - if (i < 0) - i = max - 1; - if (i >= max) - i = 0; - return i; -} - -/* - * Construct a fan around the midpoint using the vertices from pen between - * inpt and outpt. - */ -static void -add_fan (struct stroker *stroker, - const cairo_slope_t *in_vector, - const cairo_slope_t *out_vector, - const cairo_point_t *midpt, - const cairo_point_t *inpt, - const cairo_point_t *outpt, - cairo_bool_t clockwise) -{ - int start, stop, step, i, npoints; - - if (clockwise) { - step = 1; - - start = _cairo_pen_find_active_cw_vertex_index (&stroker->pen, - in_vector); - if (_cairo_slope_compare (&stroker->pen.vertices[start].slope_cw, - in_vector) < 0) - start = range_step (start, 1, stroker->pen.num_vertices); - - stop = _cairo_pen_find_active_cw_vertex_index (&stroker->pen, - out_vector); - if (_cairo_slope_compare (&stroker->pen.vertices[stop].slope_ccw, - out_vector) > 0) - { - stop = range_step (stop, -1, stroker->pen.num_vertices); - if (_cairo_slope_compare (&stroker->pen.vertices[stop].slope_cw, - in_vector) < 0) - return; - } - - npoints = stop - start; - } else { - step = -1; - - start = _cairo_pen_find_active_ccw_vertex_index (&stroker->pen, - in_vector); - if (_cairo_slope_compare (&stroker->pen.vertices[start].slope_ccw, - in_vector) < 0) - start = range_step (start, -1, stroker->pen.num_vertices); - - stop = _cairo_pen_find_active_ccw_vertex_index (&stroker->pen, - out_vector); - if (_cairo_slope_compare (&stroker->pen.vertices[stop].slope_cw, - out_vector) > 0) - { - stop = range_step (stop, 1, stroker->pen.num_vertices); - if (_cairo_slope_compare (&stroker->pen.vertices[stop].slope_ccw, - in_vector) < 0) - return; - } - - npoints = start - stop; - } - stop = range_step (stop, step, stroker->pen.num_vertices); - if (npoints < 0) - npoints += stroker->pen.num_vertices; - if (npoints <= 1) - return; - - for (i = start; - i != stop; - i = range_step (i, step, stroker->pen.num_vertices)) - { - cairo_point_t p = *midpt; - translate_point (&p, &stroker->pen.vertices[i].point); - //contour_add_point (stroker, c, &p); - } -} - -static int -join_is_clockwise (const cairo_stroke_face_t *in, - const cairo_stroke_face_t *out) -{ - return _cairo_slope_compare (&in->dev_vector, &out->dev_vector) < 0; -} - -static void -inner_join (struct stroker *stroker, - const cairo_stroke_face_t *in, - const cairo_stroke_face_t *out, - int clockwise) -{ - const cairo_point_t *outpt; - - if (clockwise) { - outpt = &out->ccw; - } else { - outpt = &out->cw; - } - //contour_add_point (stroker, inner, &in->point); - //contour_add_point (stroker, inner, outpt); -} - -static void -inner_close (struct stroker *stroker, - const cairo_stroke_face_t *in, - cairo_stroke_face_t *out) -{ - const cairo_point_t *inpt; - - if (join_is_clockwise (in, out)) { - inpt = &out->ccw; - } else { - inpt = &out->cw; - } - - //contour_add_point (stroker, inner, &in->point); - //contour_add_point (stroker, inner, inpt); - //*_cairo_contour_first_point (&inner->contour) = - //*_cairo_contour_last_point (&inner->contour); -} - -static void -outer_close (struct stroker *stroker, - const cairo_stroke_face_t *in, - const cairo_stroke_face_t *out) -{ - const cairo_point_t *inpt, *outpt; - int clockwise; - - if (in->cw.x == out->cw.x && in->cw.y == out->cw.y && - in->ccw.x == out->ccw.x && in->ccw.y == out->ccw.y) - { - return; - } - clockwise = join_is_clockwise (in, out); - if (clockwise) { - inpt = &in->cw; - outpt = &out->cw; - } else { - inpt = &in->ccw; - outpt = &out->ccw; - } - - switch (stroker->style.line_join) { - case CAIRO_LINE_JOIN_ROUND: - /* construct a fan around the common midpoint */ - add_fan (stroker, - &in->dev_vector, - &out->dev_vector, - &in->point, inpt, outpt, - clockwise); - break; - - case CAIRO_LINE_JOIN_MITER: - default: { - /* dot product of incoming slope vector with outgoing slope vector */ - double in_dot_out = -in->usr_vector.x * out->usr_vector.x + - -in->usr_vector.y * out->usr_vector.y; - double ml = stroker->style.miter_limit; - - /* Check the miter limit -- lines meeting at an acute angle - * can generate long miters, the limit converts them to bevel - * - * Consider the miter join formed when two line segments - * meet at an angle psi: - * - * /.\ - * /. .\ - * /./ \.\ - * /./psi\.\ - * - * We can zoom in on the right half of that to see: - * - * |\ - * | \ psi/2 - * | \ - * | \ - * | \ - * | \ - * miter \ - * length \ - * | \ - * | .\ - * | . \ - * |. line \ - * \ width \ - * \ \ - * - * - * The right triangle in that figure, (the line-width side is - * shown faintly with three '.' characters), gives us the - * following expression relating miter length, angle and line - * width: - * - * 1 /sin (psi/2) = miter_length / line_width - * - * The right-hand side of this relationship is the same ratio - * in which the miter limit (ml) is expressed. We want to know - * when the miter length is within the miter limit. That is - * when the following condition holds: - * - * 1/sin(psi/2) <= ml - * 1 <= ml sin(psi/2) - * 1 <= ml² sin²(psi/2) - * 2 <= ml² 2 sin²(psi/2) - * 2·sin²(psi/2) = 1-cos(psi) - * 2 <= ml² (1-cos(psi)) - * - * in · out = |in| |out| cos (psi) - * - * in and out are both unit vectors, so: - * - * in · out = cos (psi) - * - * 2 <= ml² (1 - in · out) - * - */ - if (2 <= ml * ml * (1 - in_dot_out)) { - double x1, y1, x2, y2; - double mx, my; - double dx1, dx2, dy1, dy2; - double ix, iy; - double fdx1, fdy1, fdx2, fdy2; - double mdx, mdy; - - /* - * we've got the points already transformed to device - * space, but need to do some computation with them and - * also need to transform the slope from user space to - * device space - */ - /* outer point of incoming line face */ - x1 = _cairo_fixed_to_double (inpt->x); - y1 = _cairo_fixed_to_double (inpt->y); - dx1 = in->usr_vector.x; - dy1 = in->usr_vector.y; - cairo_matrix_transform_distance (stroker->ctm, &dx1, &dy1); - - /* outer point of outgoing line face */ - x2 = _cairo_fixed_to_double (outpt->x); - y2 = _cairo_fixed_to_double (outpt->y); - dx2 = out->usr_vector.x; - dy2 = out->usr_vector.y; - cairo_matrix_transform_distance (stroker->ctm, &dx2, &dy2); - - /* - * Compute the location of the outer corner of the miter. - * That's pretty easy -- just the intersection of the two - * outer edges. We've got slopes and points on each - * of those edges. Compute my directly, then compute - * mx by using the edge with the larger dy; that avoids - * dividing by values close to zero. - */ - my = (((x2 - x1) * dy1 * dy2 - y2 * dx2 * dy1 + y1 * dx1 * dy2) / - (dx1 * dy2 - dx2 * dy1)); - if (fabs (dy1) >= fabs (dy2)) - mx = (my - y1) * dx1 / dy1 + x1; - else - mx = (my - y2) * dx2 / dy2 + x2; - - /* - * When the two outer edges are nearly parallel, slight - * perturbations in the position of the outer points of the lines - * caused by representing them in fixed point form can cause the - * intersection point of the miter to move a large amount. If - * that moves the miter intersection from between the two faces, - * then draw a bevel instead. - */ - - ix = _cairo_fixed_to_double (in->point.x); - iy = _cairo_fixed_to_double (in->point.y); - - /* slope of one face */ - fdx1 = x1 - ix; fdy1 = y1 - iy; - - /* slope of the other face */ - fdx2 = x2 - ix; fdy2 = y2 - iy; - - /* slope from the intersection to the miter point */ - mdx = mx - ix; mdy = my - iy; - - /* - * Make sure the miter point line lies between the two - * faces by comparing the slopes - */ - if (slope_compare_sgn (fdx1, fdy1, mdx, mdy) != - slope_compare_sgn (fdx2, fdy2, mdx, mdy)) - { - cairo_point_t p; - - p.x = _cairo_fixed_from_double (mx); - p.y = _cairo_fixed_from_double (my); - - //*_cairo_contour_last_point (&outer->contour) = p; - //*_cairo_contour_first_point (&outer->contour) = p; - return; - } - } - break; - } - - case CAIRO_LINE_JOIN_BEVEL: - break; - } - //contour_add_point (stroker, outer, outpt); -} - -static void -outer_join (struct stroker *stroker, - const cairo_stroke_face_t *in, - const cairo_stroke_face_t *out, - int clockwise) -{ - const cairo_point_t *inpt, *outpt; - - if (in->cw.x == out->cw.x && in->cw.y == out->cw.y && - in->ccw.x == out->ccw.x && in->ccw.y == out->ccw.y) - { - return; - } - if (clockwise) { - inpt = &in->cw; - outpt = &out->cw; - } else { - inpt = &in->ccw; - outpt = &out->ccw; - } - - switch (stroker->style.line_join) { - case CAIRO_LINE_JOIN_ROUND: - /* construct a fan around the common midpoint */ - add_fan (stroker, - &in->dev_vector, - &out->dev_vector, - &in->point, inpt, outpt, - clockwise); - break; - - case CAIRO_LINE_JOIN_MITER: - default: { - /* dot product of incoming slope vector with outgoing slope vector */ - double in_dot_out = -in->usr_vector.x * out->usr_vector.x + - -in->usr_vector.y * out->usr_vector.y; - double ml = stroker->style.miter_limit; - - /* Check the miter limit -- lines meeting at an acute angle - * can generate long miters, the limit converts them to bevel - * - * Consider the miter join formed when two line segments - * meet at an angle psi: - * - * /.\ - * /. .\ - * /./ \.\ - * /./psi\.\ - * - * We can zoom in on the right half of that to see: - * - * |\ - * | \ psi/2 - * | \ - * | \ - * | \ - * | \ - * miter \ - * length \ - * | \ - * | .\ - * | . \ - * |. line \ - * \ width \ - * \ \ - * - * - * The right triangle in that figure, (the line-width side is - * shown faintly with three '.' characters), gives us the - * following expression relating miter length, angle and line - * width: - * - * 1 /sin (psi/2) = miter_length / line_width - * - * The right-hand side of this relationship is the same ratio - * in which the miter limit (ml) is expressed. We want to know - * when the miter length is within the miter limit. That is - * when the following condition holds: - * - * 1/sin(psi/2) <= ml - * 1 <= ml sin(psi/2) - * 1 <= ml² sin²(psi/2) - * 2 <= ml² 2 sin²(psi/2) - * 2·sin²(psi/2) = 1-cos(psi) - * 2 <= ml² (1-cos(psi)) - * - * in · out = |in| |out| cos (psi) - * - * in and out are both unit vectors, so: - * - * in · out = cos (psi) - * - * 2 <= ml² (1 - in · out) - * - */ - if (2 <= ml * ml * (1 - in_dot_out)) { - double x1, y1, x2, y2; - double mx, my; - double dx1, dx2, dy1, dy2; - double ix, iy; - double fdx1, fdy1, fdx2, fdy2; - double mdx, mdy; - - /* - * we've got the points already transformed to device - * space, but need to do some computation with them and - * also need to transform the slope from user space to - * device space - */ - /* outer point of incoming line face */ - x1 = _cairo_fixed_to_double (inpt->x); - y1 = _cairo_fixed_to_double (inpt->y); - dx1 = in->usr_vector.x; - dy1 = in->usr_vector.y; - cairo_matrix_transform_distance (stroker->ctm, &dx1, &dy1); - - /* outer point of outgoing line face */ - x2 = _cairo_fixed_to_double (outpt->x); - y2 = _cairo_fixed_to_double (outpt->y); - dx2 = out->usr_vector.x; - dy2 = out->usr_vector.y; - cairo_matrix_transform_distance (stroker->ctm, &dx2, &dy2); - - /* - * Compute the location of the outer corner of the miter. - * That's pretty easy -- just the intersection of the two - * outer edges. We've got slopes and points on each - * of those edges. Compute my directly, then compute - * mx by using the edge with the larger dy; that avoids - * dividing by values close to zero. - */ - my = (((x2 - x1) * dy1 * dy2 - y2 * dx2 * dy1 + y1 * dx1 * dy2) / - (dx1 * dy2 - dx2 * dy1)); - if (fabs (dy1) >= fabs (dy2)) - mx = (my - y1) * dx1 / dy1 + x1; - else - mx = (my - y2) * dx2 / dy2 + x2; - - /* - * When the two outer edges are nearly parallel, slight - * perturbations in the position of the outer points of the lines - * caused by representing them in fixed point form can cause the - * intersection point of the miter to move a large amount. If - * that moves the miter intersection from between the two faces, - * then draw a bevel instead. - */ - - ix = _cairo_fixed_to_double (in->point.x); - iy = _cairo_fixed_to_double (in->point.y); - - /* slope of one face */ - fdx1 = x1 - ix; fdy1 = y1 - iy; - - /* slope of the other face */ - fdx2 = x2 - ix; fdy2 = y2 - iy; - - /* slope from the intersection to the miter point */ - mdx = mx - ix; mdy = my - iy; - - /* - * Make sure the miter point line lies between the two - * faces by comparing the slopes - */ - if (slope_compare_sgn (fdx1, fdy1, mdx, mdy) != - slope_compare_sgn (fdx2, fdy2, mdx, mdy)) - { - cairo_point_t p; - - p.x = _cairo_fixed_from_double (mx); - p.y = _cairo_fixed_from_double (my); - - //*_cairo_contour_last_point (&outer->contour) = p; - return; - } - } - break; - } - - case CAIRO_LINE_JOIN_BEVEL: - break; - } - //contour_add_point (stroker,outer, outpt); -} - -static void -add_cap (struct stroker *stroker, - const cairo_stroke_face_t *f) -{ - switch (stroker->style.line_cap) { - case CAIRO_LINE_CAP_ROUND: { - cairo_slope_t slope; - - slope.dx = -f->dev_vector.dx; - slope.dy = -f->dev_vector.dy; - - add_fan (stroker, &f->dev_vector, &slope, - &f->point, &f->ccw, &f->cw, - FALSE); - break; - } - - case CAIRO_LINE_CAP_SQUARE: { - double dx, dy; - cairo_slope_t fvector; - cairo_point_t quad[4]; - - dx = f->usr_vector.x; - dy = f->usr_vector.y; - dx *= stroker->style.line_width / 2.0; - dy *= stroker->style.line_width / 2.0; - cairo_matrix_transform_distance (stroker->ctm, &dx, &dy); - fvector.dx = _cairo_fixed_from_double (dx); - fvector.dy = _cairo_fixed_from_double (dy); - - quad[0] = f->ccw; - quad[1].x = f->ccw.x + fvector.dx; - quad[1].y = f->ccw.y + fvector.dy; - quad[2].x = f->cw.x + fvector.dx; - quad[2].y = f->cw.y + fvector.dy; - quad[3] = f->cw; - - //contour_add_point (stroker, c, &quad[1]); - //contour_add_point (stroker, c, &quad[2]); - } - - case CAIRO_LINE_CAP_BUTT: - default: - break; - } - //contour_add_point (stroker, c, &f->cw); -} - -static void -add_leading_cap (struct stroker *stroker, - const cairo_stroke_face_t *face) -{ - cairo_stroke_face_t reversed; - cairo_point_t t; - - reversed = *face; - - /* The initial cap needs an outward facing vector. Reverse everything */ - reversed.usr_vector.x = -reversed.usr_vector.x; - reversed.usr_vector.y = -reversed.usr_vector.y; - reversed.dev_vector.dx = -reversed.dev_vector.dx; - reversed.dev_vector.dy = -reversed.dev_vector.dy; - - t = reversed.cw; - reversed.cw = reversed.ccw; - reversed.ccw = t; - - add_cap (stroker, &reversed); -} - -static void -add_trailing_cap (struct stroker *stroker, - const cairo_stroke_face_t *face) -{ - add_cap (stroker, face); -} - -static inline double -normalize_slope (double *dx, double *dy) -{ - double dx0 = *dx, dy0 = *dy; - double mag; - - assert (dx0 != 0.0 || dy0 != 0.0); - - if (dx0 == 0.0) { - *dx = 0.0; - if (dy0 > 0.0) { - mag = dy0; - *dy = 1.0; - } else { - mag = -dy0; - *dy = -1.0; - } - } else if (dy0 == 0.0) { - *dy = 0.0; - if (dx0 > 0.0) { - mag = dx0; - *dx = 1.0; - } else { - mag = -dx0; - *dx = -1.0; - } - } else { - mag = hypot (dx0, dy0); - *dx = dx0 / mag; - *dy = dy0 / mag; - } - - return mag; -} - -static void -compute_face (const cairo_point_t *point, - const cairo_slope_t *dev_slope, - struct stroker *stroker, - cairo_stroke_face_t *face) -{ - double face_dx, face_dy; - cairo_point_t offset_ccw, offset_cw; - double slope_dx, slope_dy; - - slope_dx = _cairo_fixed_to_double (dev_slope->dx); - slope_dy = _cairo_fixed_to_double (dev_slope->dy); - face->length = normalize_slope (&slope_dx, &slope_dy); - face->dev_slope.x = slope_dx; - face->dev_slope.y = slope_dy; - - /* - * rotate to get a line_width/2 vector along the face, note that - * the vector must be rotated the right direction in device space, - * but by 90° in user space. So, the rotation depends on - * whether the ctm reflects or not, and that can be determined - * by looking at the determinant of the matrix. - */ - if (! _cairo_matrix_is_identity (stroker->ctm_inverse)) { - /* Normalize the matrix! */ - cairo_matrix_transform_distance (stroker->ctm_inverse, - &slope_dx, &slope_dy); - normalize_slope (&slope_dx, &slope_dy); - - if (stroker->ctm_det_positive) { - face_dx = - slope_dy * (stroker->style.line_width / 2.0); - face_dy = slope_dx * (stroker->style.line_width / 2.0); - } else { - face_dx = slope_dy * (stroker->style.line_width / 2.0); - face_dy = - slope_dx * (stroker->style.line_width / 2.0); - } - - /* back to device space */ - cairo_matrix_transform_distance (stroker->ctm, &face_dx, &face_dy); - } else { - face_dx = - slope_dy * (stroker->style.line_width / 2.0); - face_dy = slope_dx * (stroker->style.line_width / 2.0); - } - - offset_ccw.x = _cairo_fixed_from_double (face_dx); - offset_ccw.y = _cairo_fixed_from_double (face_dy); - offset_cw.x = -offset_ccw.x; - offset_cw.y = -offset_ccw.y; - - face->ccw = *point; - translate_point (&face->ccw, &offset_ccw); - - face->point = *point; - - face->cw = *point; - translate_point (&face->cw, &offset_cw); - - face->usr_vector.x = slope_dx; - face->usr_vector.y = slope_dy; - - face->dev_vector = *dev_slope; -} - -static void -add_caps (struct stroker *stroker) -{ - /* check for a degenerative sub_path */ - if (stroker->has_sub_path && - ! stroker->has_first_face && - ! stroker->has_current_face && - stroker->style.line_cap == CAIRO_LINE_CAP_ROUND) - { - /* pick an arbitrary slope to use */ - cairo_slope_t slope = { CAIRO_FIXED_ONE, 0 }; - cairo_stroke_face_t face; - - /* arbitrarily choose first_point */ - compute_face (&stroker->first_point, &slope, stroker, &face); - - add_leading_cap (stroker, &face); - add_trailing_cap (stroker, &face); - - /* ensure the circle is complete */ - //_cairo_contour_add_point (&stroker->ccw.contour, - //_cairo_contour_first_point (&stroker->ccw.contour)); - } else { - if (stroker->has_current_face) - add_trailing_cap (stroker, &stroker->current_face); - - //_cairo_polygon_add_contour (stroker->polygon, &stroker->ccw.contour); - //_cairo_contour_reset (&stroker->ccw.contour); - - if (stroker->has_first_face) { - //_cairo_contour_add_point (&stroker->ccw.contour, - //&stroker->first_face.cw); - add_leading_cap (stroker, &stroker->first_face); - //_cairo_polygon_add_contour (stroker->polygon, - //&stroker->ccw.contour); - //_cairo_contour_reset (&stroker->ccw.contour); - } - } -} - -static cairo_status_t -move_to (void *closure, - const cairo_point_t *point) -{ - struct stroker *stroker = closure; - - /* Cap the start and end of the previous sub path as needed */ - add_caps (stroker); - - stroker->has_first_face = FALSE; - stroker->has_current_face = FALSE; - stroker->has_sub_path = FALSE; - - stroker->first_point = *point; - - stroker->current_face.point = *point; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -line_to (void *closure, - const cairo_point_t *point) -{ - struct stroker *stroker = closure; - cairo_stroke_face_t start; - cairo_point_t *p1 = &stroker->current_face.point; - cairo_slope_t dev_slope; - - stroker->has_sub_path = TRUE; - - if (p1->x == point->x && p1->y == point->y) - return CAIRO_STATUS_SUCCESS; - - _cairo_slope_init (&dev_slope, p1, point); - compute_face (p1, &dev_slope, stroker, &start); - - if (stroker->has_current_face) { - int clockwise = join_is_clockwise (&stroker->current_face, &start); - /* Join with final face from previous segment */ - outer_join (stroker, &stroker->current_face, &start, clockwise); - inner_join (stroker, &stroker->current_face, &start, clockwise); - } else { - if (! stroker->has_first_face) { - /* Save sub path's first face in case needed for closing join */ - stroker->first_face = start; - _cairo_tristrip_move_to (stroker->strip, &start.cw); - stroker->has_first_face = TRUE; - } - stroker->has_current_face = TRUE; - - _cairo_tristrip_add_point (stroker->strip, &start.cw); - _cairo_tristrip_add_point (stroker->strip, &start.ccw); - } - - stroker->current_face = start; - stroker->current_face.point = *point; - stroker->current_face.ccw.x += dev_slope.dx; - stroker->current_face.ccw.y += dev_slope.dy; - stroker->current_face.cw.x += dev_slope.dx; - stroker->current_face.cw.y += dev_slope.dy; - - _cairo_tristrip_add_point (stroker->strip, &stroker->current_face.cw); - _cairo_tristrip_add_point (stroker->strip, &stroker->current_face.ccw); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -spline_to (void *closure, - const cairo_point_t *point, - const cairo_slope_t *tangent) -{ - struct stroker *stroker = closure; - cairo_stroke_face_t face; - - if (tangent->dx == 0 && tangent->dy == 0) { - const cairo_point_t *inpt, *outpt; - cairo_point_t t; - int clockwise; - - face = stroker->current_face; - - face.usr_vector.x = -face.usr_vector.x; - face.usr_vector.y = -face.usr_vector.y; - face.dev_vector.dx = -face.dev_vector.dx; - face.dev_vector.dy = -face.dev_vector.dy; - - t = face.cw; - face.cw = face.ccw; - face.ccw = t; - - clockwise = join_is_clockwise (&stroker->current_face, &face); - if (clockwise) { - inpt = &stroker->current_face.cw; - outpt = &face.cw; - } else { - inpt = &stroker->current_face.ccw; - outpt = &face.ccw; - } - - add_fan (stroker, - &stroker->current_face.dev_vector, - &face.dev_vector, - &stroker->current_face.point, inpt, outpt, - clockwise); - } else { - compute_face (point, tangent, stroker, &face); - - if (face.dev_slope.x * stroker->current_face.dev_slope.x + - face.dev_slope.y * stroker->current_face.dev_slope.y < 0) - { - const cairo_point_t *inpt, *outpt; - int clockwise = join_is_clockwise (&stroker->current_face, &face); - - stroker->current_face.cw.x += face.point.x - stroker->current_face.point.x; - stroker->current_face.cw.y += face.point.y - stroker->current_face.point.y; - //contour_add_point (stroker, &stroker->cw, &stroker->current_face.cw); - - stroker->current_face.ccw.x += face.point.x - stroker->current_face.point.x; - stroker->current_face.ccw.y += face.point.y - stroker->current_face.point.y; - //contour_add_point (stroker, &stroker->ccw, &stroker->current_face.ccw); - - if (clockwise) { - inpt = &stroker->current_face.cw; - outpt = &face.cw; - } else { - inpt = &stroker->current_face.ccw; - outpt = &face.ccw; - } - add_fan (stroker, - &stroker->current_face.dev_vector, - &face.dev_vector, - &stroker->current_face.point, inpt, outpt, - clockwise); - } - - _cairo_tristrip_add_point (stroker->strip, &face.cw); - _cairo_tristrip_add_point (stroker->strip, &face.ccw); - } - - stroker->current_face = face; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -curve_to (void *closure, - const cairo_point_t *b, - const cairo_point_t *c, - const cairo_point_t *d) -{ - struct stroker *stroker = closure; - cairo_spline_t spline; - cairo_stroke_face_t face; - - if (stroker->has_limits) { - if (! _cairo_spline_intersects (&stroker->current_face.point, b, c, d, - &stroker->limit)) - return line_to (closure, d); - } - - if (! _cairo_spline_init (&spline, spline_to, stroker, - &stroker->current_face.point, b, c, d)) - return line_to (closure, d); - - compute_face (&stroker->current_face.point, &spline.initial_slope, - stroker, &face); - - if (stroker->has_current_face) { - int clockwise = join_is_clockwise (&stroker->current_face, &face); - /* Join with final face from previous segment */ - outer_join (stroker, &stroker->current_face, &face, clockwise); - inner_join (stroker, &stroker->current_face, &face, clockwise); - } else { - if (! stroker->has_first_face) { - /* Save sub path's first face in case needed for closing join */ - stroker->first_face = face; - _cairo_tristrip_move_to (stroker->strip, &face.cw); - stroker->has_first_face = TRUE; - } - stroker->has_current_face = TRUE; - - _cairo_tristrip_add_point (stroker->strip, &face.cw); - _cairo_tristrip_add_point (stroker->strip, &face.ccw); - } - stroker->current_face = face; - - return _cairo_spline_decompose (&spline, stroker->tolerance); -} - -static cairo_status_t -close_path (void *closure) -{ - struct stroker *stroker = closure; - cairo_status_t status; - - status = line_to (stroker, &stroker->first_point); - if (unlikely (status)) - return status; - - if (stroker->has_first_face && stroker->has_current_face) { - /* Join first and final faces of sub path */ - outer_close (stroker, &stroker->current_face, &stroker->first_face); - inner_close (stroker, &stroker->current_face, &stroker->first_face); - } else { - /* Cap the start and end of the sub path as needed */ - add_caps (stroker); - } - - stroker->has_sub_path = FALSE; - stroker->has_first_face = FALSE; - stroker->has_current_face = FALSE; - - return CAIRO_STATUS_SUCCESS; -} - -cairo_int_status_t -_cairo_path_fixed_stroke_to_tristrip (const cairo_path_fixed_t *path, - const cairo_stroke_style_t*style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_tristrip_t *strip) -{ - struct stroker stroker; - cairo_int_status_t status; - int i; - - if (style->num_dashes) - return CAIRO_INT_STATUS_UNSUPPORTED; - - stroker.style = *style; - stroker.ctm = ctm; - stroker.ctm_inverse = ctm_inverse; - stroker.tolerance = tolerance; - - stroker.ctm_det_positive = - _cairo_matrix_compute_determinant (ctm) >= 0.0; - - status = _cairo_pen_init (&stroker.pen, - style->line_width / 2.0, - tolerance, ctm); - if (unlikely (status)) - return status; - - if (stroker.pen.num_vertices <= 1) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - stroker.has_current_face = FALSE; - stroker.has_first_face = FALSE; - stroker.has_sub_path = FALSE; - - stroker.has_limits = strip->num_limits > 0; - stroker.limit = strip->limits[0]; - for (i = 1; i < strip->num_limits; i++) - _cairo_box_add_box (&stroker.limit, &strip->limits[i]); - - stroker.strip = strip; - - status = _cairo_path_fixed_interpret (path, - move_to, - line_to, - curve_to, - close_path, - &stroker); - /* Cap the start and end of the final sub path as needed */ - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) - add_caps (&stroker); - - _cairo_pen_fini (&stroker.pen); - - return status; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-path-stroke.c b/source/libs/cairo/cairo-src/src/cairo-path-stroke.c deleted file mode 100644 index 4d4ede8136190c0dd06cad89afe6cefa7abcddf6..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-path-stroke.c +++ /dev/null @@ -1,1485 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#define _BSD_SOURCE /* for hypot() */ -#include "cairoint.h" - -#include "cairo-box-inline.h" -#include "cairo-boxes-private.h" -#include "cairo-error-private.h" -#include "cairo-path-fixed-private.h" -#include "cairo-slope-private.h" -#include "cairo-stroke-dash-private.h" -#include "cairo-traps-private.h" - -typedef struct cairo_stroker { - cairo_stroke_style_t style; - - const cairo_matrix_t *ctm; - const cairo_matrix_t *ctm_inverse; - double half_line_width; - double tolerance; - double spline_cusp_tolerance; - double ctm_determinant; - cairo_bool_t ctm_det_positive; - - void *closure; - cairo_status_t (*add_external_edge) (void *closure, - const cairo_point_t *p1, - const cairo_point_t *p2); - cairo_status_t (*add_triangle) (void *closure, - const cairo_point_t triangle[3]); - cairo_status_t (*add_triangle_fan) (void *closure, - const cairo_point_t *midpt, - const cairo_point_t *points, - int npoints); - cairo_status_t (*add_convex_quad) (void *closure, - const cairo_point_t quad[4]); - - cairo_pen_t pen; - - cairo_point_t current_point; - cairo_point_t first_point; - - cairo_bool_t has_initial_sub_path; - - cairo_bool_t has_current_face; - cairo_stroke_face_t current_face; - - cairo_bool_t has_first_face; - cairo_stroke_face_t first_face; - - cairo_stroker_dash_t dash; - - cairo_bool_t has_bounds; - cairo_box_t bounds; -} cairo_stroker_t; - -static void -_cairo_stroker_limit (cairo_stroker_t *stroker, - const cairo_path_fixed_t *path, - const cairo_box_t *boxes, - int num_boxes) -{ - double dx, dy; - cairo_fixed_t fdx, fdy; - - stroker->has_bounds = TRUE; - _cairo_boxes_get_extents (boxes, num_boxes, &stroker->bounds); - - /* Extend the bounds in each direction to account for the maximum area - * we might generate trapezoids, to capture line segments that are outside - * of the bounds but which might generate rendering that's within bounds. - */ - - _cairo_stroke_style_max_distance_from_path (&stroker->style, path, - stroker->ctm, &dx, &dy); - - fdx = _cairo_fixed_from_double (dx); - fdy = _cairo_fixed_from_double (dy); - - stroker->bounds.p1.x -= fdx; - stroker->bounds.p2.x += fdx; - - stroker->bounds.p1.y -= fdy; - stroker->bounds.p2.y += fdy; -} - -static cairo_status_t -_cairo_stroker_init (cairo_stroker_t *stroker, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - const cairo_box_t *limits, - int num_limits) -{ - cairo_status_t status; - - stroker->style = *stroke_style; - stroker->ctm = ctm; - stroker->ctm_inverse = ctm_inverse; - stroker->tolerance = tolerance; - stroker->half_line_width = stroke_style->line_width / 2.0; - - /* To test whether we need to join two segments of a spline using - * a round-join or a bevel-join, we can inspect the angle between the - * two segments. If the difference between the chord distance - * (half-line-width times the cosine of the bisection angle) and the - * half-line-width itself is greater than tolerance then we need to - * inject a point. - */ - stroker->spline_cusp_tolerance = 1 - tolerance / stroker->half_line_width; - stroker->spline_cusp_tolerance *= stroker->spline_cusp_tolerance; - stroker->spline_cusp_tolerance *= 2; - stroker->spline_cusp_tolerance -= 1; - - stroker->ctm_determinant = _cairo_matrix_compute_determinant (stroker->ctm); - stroker->ctm_det_positive = stroker->ctm_determinant >= 0.0; - - status = _cairo_pen_init (&stroker->pen, - stroker->half_line_width, tolerance, ctm); - if (unlikely (status)) - return status; - - stroker->has_current_face = FALSE; - stroker->has_first_face = FALSE; - stroker->has_initial_sub_path = FALSE; - - _cairo_stroker_dash_init (&stroker->dash, stroke_style); - - stroker->add_external_edge = NULL; - - stroker->has_bounds = FALSE; - if (num_limits) - _cairo_stroker_limit (stroker, path, limits, num_limits); - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_stroker_fini (cairo_stroker_t *stroker) -{ - _cairo_pen_fini (&stroker->pen); -} - -static void -_translate_point (cairo_point_t *point, const cairo_point_t *offset) -{ - point->x += offset->x; - point->y += offset->y; -} - -static int -_cairo_stroker_join_is_clockwise (const cairo_stroke_face_t *in, - const cairo_stroke_face_t *out) -{ - cairo_slope_t in_slope, out_slope; - - _cairo_slope_init (&in_slope, &in->point, &in->cw); - _cairo_slope_init (&out_slope, &out->point, &out->cw); - - return _cairo_slope_compare (&in_slope, &out_slope) < 0; -} - -/** - * _cairo_slope_compare_sgn: - * - * Return -1, 0 or 1 depending on the relative slopes of - * two lines. - **/ -static int -_cairo_slope_compare_sgn (double dx1, double dy1, double dx2, double dy2) -{ - double c = (dx1 * dy2 - dx2 * dy1); - - if (c > 0) return 1; - if (c < 0) return -1; - return 0; -} - -static inline int -_range_step (int i, int step, int max) -{ - i += step; - if (i < 0) - i = max - 1; - if (i >= max) - i = 0; - return i; -} - -/* - * Construct a fan around the midpoint using the vertices from pen between - * inpt and outpt. - */ -static cairo_status_t -_tessellate_fan (cairo_stroker_t *stroker, - const cairo_slope_t *in_vector, - const cairo_slope_t *out_vector, - const cairo_point_t *midpt, - const cairo_point_t *inpt, - const cairo_point_t *outpt, - cairo_bool_t clockwise) -{ - cairo_point_t stack_points[64], *points = stack_points; - cairo_pen_t *pen = &stroker->pen; - int start, stop, num_points = 0; - cairo_status_t status; - - if (stroker->has_bounds && - ! _cairo_box_contains_point (&stroker->bounds, midpt)) - goto BEVEL; - - assert (stroker->pen.num_vertices); - - if (clockwise) { - _cairo_pen_find_active_ccw_vertices (pen, - in_vector, out_vector, - &start, &stop); - if (stroker->add_external_edge) { - cairo_point_t last; - last = *inpt; - while (start != stop) { - cairo_point_t p = *midpt; - _translate_point (&p, &pen->vertices[start].point); - - status = stroker->add_external_edge (stroker->closure, - &last, &p); - if (unlikely (status)) - return status; - last = p; - - if (start-- == 0) - start += pen->num_vertices; - } - status = stroker->add_external_edge (stroker->closure, - &last, outpt); - } else { - if (start == stop) - goto BEVEL; - - num_points = stop - start; - if (num_points < 0) - num_points += pen->num_vertices; - num_points += 2; - if (num_points > ARRAY_LENGTH(stack_points)) { - points = _cairo_malloc_ab (num_points, sizeof (cairo_point_t)); - if (unlikely (points == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - points[0] = *inpt; - num_points = 1; - while (start != stop) { - points[num_points] = *midpt; - _translate_point (&points[num_points], &pen->vertices[start].point); - num_points++; - - if (start-- == 0) - start += pen->num_vertices; - } - points[num_points++] = *outpt; - } - } else { - _cairo_pen_find_active_cw_vertices (pen, - in_vector, out_vector, - &start, &stop); - if (stroker->add_external_edge) { - cairo_point_t last; - last = *inpt; - while (start != stop) { - cairo_point_t p = *midpt; - _translate_point (&p, &pen->vertices[start].point); - - status = stroker->add_external_edge (stroker->closure, - &p, &last); - if (unlikely (status)) - return status; - last = p; - - if (++start == pen->num_vertices) - start = 0; - } - status = stroker->add_external_edge (stroker->closure, - outpt, &last); - } else { - if (start == stop) - goto BEVEL; - - num_points = stop - start; - if (num_points < 0) - num_points += pen->num_vertices; - num_points += 2; - if (num_points > ARRAY_LENGTH(stack_points)) { - points = _cairo_malloc_ab (num_points, sizeof (cairo_point_t)); - if (unlikely (points == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - points[0] = *inpt; - num_points = 1; - while (start != stop) { - points[num_points] = *midpt; - _translate_point (&points[num_points], &pen->vertices[start].point); - num_points++; - - if (++start == pen->num_vertices) - start = 0; - } - points[num_points++] = *outpt; - } - } - - if (num_points) { - status = stroker->add_triangle_fan (stroker->closure, - midpt, points, num_points); - } - - if (points != stack_points) - free (points); - - return status; - -BEVEL: - /* Ensure a leak free connection... */ - if (stroker->add_external_edge != NULL) { - if (clockwise) - return stroker->add_external_edge (stroker->closure, inpt, outpt); - else - return stroker->add_external_edge (stroker->closure, outpt, inpt); - } else { - stack_points[0] = *midpt; - stack_points[1] = *inpt; - stack_points[2] = *outpt; - return stroker->add_triangle (stroker->closure, stack_points); - } -} - -static cairo_status_t -_cairo_stroker_join (cairo_stroker_t *stroker, - const cairo_stroke_face_t *in, - const cairo_stroke_face_t *out) -{ - int clockwise = _cairo_stroker_join_is_clockwise (out, in); - const cairo_point_t *inpt, *outpt; - cairo_point_t points[4]; - cairo_status_t status; - - if (in->cw.x == out->cw.x && in->cw.y == out->cw.y && - in->ccw.x == out->ccw.x && in->ccw.y == out->ccw.y) - { - return CAIRO_STATUS_SUCCESS; - } - - if (clockwise) { - if (stroker->add_external_edge != NULL) { - status = stroker->add_external_edge (stroker->closure, - &out->cw, &in->point); - if (unlikely (status)) - return status; - - status = stroker->add_external_edge (stroker->closure, - &in->point, &in->cw); - if (unlikely (status)) - return status; - } - - inpt = &in->ccw; - outpt = &out->ccw; - } else { - if (stroker->add_external_edge != NULL) { - status = stroker->add_external_edge (stroker->closure, - &in->ccw, &in->point); - if (unlikely (status)) - return status; - - status = stroker->add_external_edge (stroker->closure, - &in->point, &out->ccw); - if (unlikely (status)) - return status; - } - - inpt = &in->cw; - outpt = &out->cw; - } - - switch (stroker->style.line_join) { - case CAIRO_LINE_JOIN_ROUND: - /* construct a fan around the common midpoint */ - return _tessellate_fan (stroker, - &in->dev_vector, - &out->dev_vector, - &in->point, inpt, outpt, - clockwise); - - case CAIRO_LINE_JOIN_MITER: - default: { - /* dot product of incoming slope vector with outgoing slope vector */ - double in_dot_out = -in->usr_vector.x * out->usr_vector.x + - -in->usr_vector.y * out->usr_vector.y; - double ml = stroker->style.miter_limit; - - /* Check the miter limit -- lines meeting at an acute angle - * can generate long miters, the limit converts them to bevel - * - * Consider the miter join formed when two line segments - * meet at an angle psi: - * - * /.\ - * /. .\ - * /./ \.\ - * /./psi\.\ - * - * We can zoom in on the right half of that to see: - * - * |\ - * | \ psi/2 - * | \ - * | \ - * | \ - * | \ - * miter \ - * length \ - * | \ - * | .\ - * | . \ - * |. line \ - * \ width \ - * \ \ - * - * - * The right triangle in that figure, (the line-width side is - * shown faintly with three '.' characters), gives us the - * following expression relating miter length, angle and line - * width: - * - * 1 /sin (psi/2) = miter_length / line_width - * - * The right-hand side of this relationship is the same ratio - * in which the miter limit (ml) is expressed. We want to know - * when the miter length is within the miter limit. That is - * when the following condition holds: - * - * 1/sin(psi/2) <= ml - * 1 <= ml sin(psi/2) - * 1 <= ml² sin²(psi/2) - * 2 <= ml² 2 sin²(psi/2) - * 2·sin²(psi/2) = 1-cos(psi) - * 2 <= ml² (1-cos(psi)) - * - * in · out = |in| |out| cos (psi) - * - * in and out are both unit vectors, so: - * - * in · out = cos (psi) - * - * 2 <= ml² (1 - in · out) - * - */ - if (2 <= ml * ml * (1 - in_dot_out)) { - double x1, y1, x2, y2; - double mx, my; - double dx1, dx2, dy1, dy2; - double ix, iy; - double fdx1, fdy1, fdx2, fdy2; - double mdx, mdy; - - /* - * we've got the points already transformed to device - * space, but need to do some computation with them and - * also need to transform the slope from user space to - * device space - */ - /* outer point of incoming line face */ - x1 = _cairo_fixed_to_double (inpt->x); - y1 = _cairo_fixed_to_double (inpt->y); - dx1 = in->usr_vector.x; - dy1 = in->usr_vector.y; - cairo_matrix_transform_distance (stroker->ctm, &dx1, &dy1); - - /* outer point of outgoing line face */ - x2 = _cairo_fixed_to_double (outpt->x); - y2 = _cairo_fixed_to_double (outpt->y); - dx2 = out->usr_vector.x; - dy2 = out->usr_vector.y; - cairo_matrix_transform_distance (stroker->ctm, &dx2, &dy2); - - /* - * Compute the location of the outer corner of the miter. - * That's pretty easy -- just the intersection of the two - * outer edges. We've got slopes and points on each - * of those edges. Compute my directly, then compute - * mx by using the edge with the larger dy; that avoids - * dividing by values close to zero. - */ - my = (((x2 - x1) * dy1 * dy2 - y2 * dx2 * dy1 + y1 * dx1 * dy2) / - (dx1 * dy2 - dx2 * dy1)); - if (fabs (dy1) >= fabs (dy2)) - mx = (my - y1) * dx1 / dy1 + x1; - else - mx = (my - y2) * dx2 / dy2 + x2; - - /* - * When the two outer edges are nearly parallel, slight - * perturbations in the position of the outer points of the lines - * caused by representing them in fixed point form can cause the - * intersection point of the miter to move a large amount. If - * that moves the miter intersection from between the two faces, - * then draw a bevel instead. - */ - - ix = _cairo_fixed_to_double (in->point.x); - iy = _cairo_fixed_to_double (in->point.y); - - /* slope of one face */ - fdx1 = x1 - ix; fdy1 = y1 - iy; - - /* slope of the other face */ - fdx2 = x2 - ix; fdy2 = y2 - iy; - - /* slope from the intersection to the miter point */ - mdx = mx - ix; mdy = my - iy; - - /* - * Make sure the miter point line lies between the two - * faces by comparing the slopes - */ - if (_cairo_slope_compare_sgn (fdx1, fdy1, mdx, mdy) != - _cairo_slope_compare_sgn (fdx2, fdy2, mdx, mdy)) - { - if (stroker->add_external_edge != NULL) { - points[0].x = _cairo_fixed_from_double (mx); - points[0].y = _cairo_fixed_from_double (my); - - if (clockwise) { - status = stroker->add_external_edge (stroker->closure, - inpt, &points[0]); - if (unlikely (status)) - return status; - - status = stroker->add_external_edge (stroker->closure, - &points[0], outpt); - if (unlikely (status)) - return status; - } else { - status = stroker->add_external_edge (stroker->closure, - outpt, &points[0]); - if (unlikely (status)) - return status; - - status = stroker->add_external_edge (stroker->closure, - &points[0], inpt); - if (unlikely (status)) - return status; - } - - return CAIRO_STATUS_SUCCESS; - } else { - points[0] = in->point; - points[1] = *inpt; - points[2].x = _cairo_fixed_from_double (mx); - points[2].y = _cairo_fixed_from_double (my); - points[3] = *outpt; - - return stroker->add_convex_quad (stroker->closure, points); - } - } - } - } - - /* fall through ... */ - - case CAIRO_LINE_JOIN_BEVEL: - if (stroker->add_external_edge != NULL) { - if (clockwise) { - return stroker->add_external_edge (stroker->closure, - inpt, outpt); - } else { - return stroker->add_external_edge (stroker->closure, - outpt, inpt); - } - } else { - points[0] = in->point; - points[1] = *inpt; - points[2] = *outpt; - - return stroker->add_triangle (stroker->closure, points); - } - } -} - -static cairo_status_t -_cairo_stroker_add_cap (cairo_stroker_t *stroker, - const cairo_stroke_face_t *f) -{ - switch (stroker->style.line_cap) { - case CAIRO_LINE_CAP_ROUND: { - cairo_slope_t slope; - - slope.dx = -f->dev_vector.dx; - slope.dy = -f->dev_vector.dy; - - return _tessellate_fan (stroker, - &f->dev_vector, - &slope, - &f->point, &f->cw, &f->ccw, - FALSE); - - } - - case CAIRO_LINE_CAP_SQUARE: { - double dx, dy; - cairo_slope_t fvector; - cairo_point_t quad[4]; - - dx = f->usr_vector.x; - dy = f->usr_vector.y; - dx *= stroker->half_line_width; - dy *= stroker->half_line_width; - cairo_matrix_transform_distance (stroker->ctm, &dx, &dy); - fvector.dx = _cairo_fixed_from_double (dx); - fvector.dy = _cairo_fixed_from_double (dy); - - quad[0] = f->ccw; - quad[1].x = f->ccw.x + fvector.dx; - quad[1].y = f->ccw.y + fvector.dy; - quad[2].x = f->cw.x + fvector.dx; - quad[2].y = f->cw.y + fvector.dy; - quad[3] = f->cw; - - if (stroker->add_external_edge != NULL) { - cairo_status_t status; - - status = stroker->add_external_edge (stroker->closure, - &quad[0], &quad[1]); - if (unlikely (status)) - return status; - - status = stroker->add_external_edge (stroker->closure, - &quad[1], &quad[2]); - if (unlikely (status)) - return status; - - status = stroker->add_external_edge (stroker->closure, - &quad[2], &quad[3]); - if (unlikely (status)) - return status; - - return CAIRO_STATUS_SUCCESS; - } else { - return stroker->add_convex_quad (stroker->closure, quad); - } - } - - case CAIRO_LINE_CAP_BUTT: - default: - if (stroker->add_external_edge != NULL) { - return stroker->add_external_edge (stroker->closure, - &f->ccw, &f->cw); - } else { - return CAIRO_STATUS_SUCCESS; - } - } -} - -static cairo_status_t -_cairo_stroker_add_leading_cap (cairo_stroker_t *stroker, - const cairo_stroke_face_t *face) -{ - cairo_stroke_face_t reversed; - cairo_point_t t; - - reversed = *face; - - /* The initial cap needs an outward facing vector. Reverse everything */ - reversed.usr_vector.x = -reversed.usr_vector.x; - reversed.usr_vector.y = -reversed.usr_vector.y; - reversed.dev_vector.dx = -reversed.dev_vector.dx; - reversed.dev_vector.dy = -reversed.dev_vector.dy; - t = reversed.cw; - reversed.cw = reversed.ccw; - reversed.ccw = t; - - return _cairo_stroker_add_cap (stroker, &reversed); -} - -static cairo_status_t -_cairo_stroker_add_trailing_cap (cairo_stroker_t *stroker, - const cairo_stroke_face_t *face) -{ - return _cairo_stroker_add_cap (stroker, face); -} - -static inline cairo_bool_t -_compute_normalized_device_slope (double *dx, double *dy, - const cairo_matrix_t *ctm_inverse, - double *mag_out) -{ - double dx0 = *dx, dy0 = *dy; - double mag; - - cairo_matrix_transform_distance (ctm_inverse, &dx0, &dy0); - - if (dx0 == 0.0 && dy0 == 0.0) { - if (mag_out) - *mag_out = 0.0; - return FALSE; - } - - if (dx0 == 0.0) { - *dx = 0.0; - if (dy0 > 0.0) { - mag = dy0; - *dy = 1.0; - } else { - mag = -dy0; - *dy = -1.0; - } - } else if (dy0 == 0.0) { - *dy = 0.0; - if (dx0 > 0.0) { - mag = dx0; - *dx = 1.0; - } else { - mag = -dx0; - *dx = -1.0; - } - } else { - mag = hypot (dx0, dy0); - *dx = dx0 / mag; - *dy = dy0 / mag; - } - - if (mag_out) - *mag_out = mag; - - return TRUE; -} - -static void -_compute_face (const cairo_point_t *point, - const cairo_slope_t *dev_slope, - double slope_dx, - double slope_dy, - cairo_stroker_t *stroker, - cairo_stroke_face_t *face) -{ - double face_dx, face_dy; - cairo_point_t offset_ccw, offset_cw; - - /* - * rotate to get a line_width/2 vector along the face, note that - * the vector must be rotated the right direction in device space, - * but by 90° in user space. So, the rotation depends on - * whether the ctm reflects or not, and that can be determined - * by looking at the determinant of the matrix. - */ - if (stroker->ctm_det_positive) - { - face_dx = - slope_dy * stroker->half_line_width; - face_dy = slope_dx * stroker->half_line_width; - } - else - { - face_dx = slope_dy * stroker->half_line_width; - face_dy = - slope_dx * stroker->half_line_width; - } - - /* back to device space */ - cairo_matrix_transform_distance (stroker->ctm, &face_dx, &face_dy); - - offset_ccw.x = _cairo_fixed_from_double (face_dx); - offset_ccw.y = _cairo_fixed_from_double (face_dy); - offset_cw.x = -offset_ccw.x; - offset_cw.y = -offset_ccw.y; - - face->ccw = *point; - _translate_point (&face->ccw, &offset_ccw); - - face->point = *point; - - face->cw = *point; - _translate_point (&face->cw, &offset_cw); - - face->usr_vector.x = slope_dx; - face->usr_vector.y = slope_dy; - - face->dev_vector = *dev_slope; -} - -static cairo_status_t -_cairo_stroker_add_caps (cairo_stroker_t *stroker) -{ - cairo_status_t status; - - /* check for a degenerative sub_path */ - if (stroker->has_initial_sub_path - && ! stroker->has_first_face - && ! stroker->has_current_face - && stroker->style.line_cap == CAIRO_LINE_CAP_ROUND) - { - /* pick an arbitrary slope to use */ - double dx = 1.0, dy = 0.0; - cairo_slope_t slope = { CAIRO_FIXED_ONE, 0 }; - cairo_stroke_face_t face; - - _compute_normalized_device_slope (&dx, &dy, - stroker->ctm_inverse, NULL); - - /* arbitrarily choose first_point - * first_point and current_point should be the same */ - _compute_face (&stroker->first_point, &slope, dx, dy, stroker, &face); - - status = _cairo_stroker_add_leading_cap (stroker, &face); - if (unlikely (status)) - return status; - - status = _cairo_stroker_add_trailing_cap (stroker, &face); - if (unlikely (status)) - return status; - } - - if (stroker->has_first_face) { - status = _cairo_stroker_add_leading_cap (stroker, - &stroker->first_face); - if (unlikely (status)) - return status; - } - - if (stroker->has_current_face) { - status = _cairo_stroker_add_trailing_cap (stroker, - &stroker->current_face); - if (unlikely (status)) - return status; - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_stroker_add_sub_edge (cairo_stroker_t *stroker, - const cairo_point_t *p1, - const cairo_point_t *p2, - cairo_slope_t *dev_slope, - double slope_dx, double slope_dy, - cairo_stroke_face_t *start, - cairo_stroke_face_t *end) -{ - _compute_face (p1, dev_slope, slope_dx, slope_dy, stroker, start); - *end = *start; - - if (p1->x == p2->x && p1->y == p2->y) - return CAIRO_STATUS_SUCCESS; - - end->point = *p2; - end->ccw.x += p2->x - p1->x; - end->ccw.y += p2->y - p1->y; - end->cw.x += p2->x - p1->x; - end->cw.y += p2->y - p1->y; - - if (stroker->add_external_edge != NULL) { - cairo_status_t status; - - status = stroker->add_external_edge (stroker->closure, - &end->cw, &start->cw); - if (unlikely (status)) - return status; - - status = stroker->add_external_edge (stroker->closure, - &start->ccw, &end->ccw); - if (unlikely (status)) - return status; - - return CAIRO_STATUS_SUCCESS; - } else { - cairo_point_t quad[4]; - - quad[0] = start->cw; - quad[1] = end->cw; - quad[2] = end->ccw; - quad[3] = start->ccw; - - return stroker->add_convex_quad (stroker->closure, quad); - } -} - -static cairo_status_t -_cairo_stroker_move_to (void *closure, - const cairo_point_t *point) -{ - cairo_stroker_t *stroker = closure; - cairo_status_t status; - - /* reset the dash pattern for new sub paths */ - _cairo_stroker_dash_start (&stroker->dash); - - /* Cap the start and end of the previous sub path as needed */ - status = _cairo_stroker_add_caps (stroker); - if (unlikely (status)) - return status; - - stroker->first_point = *point; - stroker->current_point = *point; - - stroker->has_first_face = FALSE; - stroker->has_current_face = FALSE; - stroker->has_initial_sub_path = FALSE; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_stroker_line_to (void *closure, - const cairo_point_t *point) -{ - cairo_stroker_t *stroker = closure; - cairo_stroke_face_t start, end; - cairo_point_t *p1 = &stroker->current_point; - cairo_slope_t dev_slope; - double slope_dx, slope_dy; - cairo_status_t status; - - stroker->has_initial_sub_path = TRUE; - - if (p1->x == point->x && p1->y == point->y) - return CAIRO_STATUS_SUCCESS; - - _cairo_slope_init (&dev_slope, p1, point); - slope_dx = _cairo_fixed_to_double (point->x - p1->x); - slope_dy = _cairo_fixed_to_double (point->y - p1->y); - _compute_normalized_device_slope (&slope_dx, &slope_dy, - stroker->ctm_inverse, NULL); - - status = _cairo_stroker_add_sub_edge (stroker, - p1, point, - &dev_slope, - slope_dx, slope_dy, - &start, &end); - if (unlikely (status)) - return status; - - if (stroker->has_current_face) { - /* Join with final face from previous segment */ - status = _cairo_stroker_join (stroker, - &stroker->current_face, - &start); - if (unlikely (status)) - return status; - } else if (! stroker->has_first_face) { - /* Save sub path's first face in case needed for closing join */ - stroker->first_face = start; - stroker->has_first_face = TRUE; - } - stroker->current_face = end; - stroker->has_current_face = TRUE; - - stroker->current_point = *point; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_stroker_spline_to (void *closure, - const cairo_point_t *point, - const cairo_slope_t *tangent) -{ - cairo_stroker_t *stroker = closure; - cairo_stroke_face_t new_face; - double slope_dx, slope_dy; - cairo_point_t points[3]; - cairo_point_t intersect_point; - - stroker->has_initial_sub_path = TRUE; - - if (stroker->current_point.x == point->x && - stroker->current_point.y == point->y) - return CAIRO_STATUS_SUCCESS; - - slope_dx = _cairo_fixed_to_double (tangent->dx); - slope_dy = _cairo_fixed_to_double (tangent->dy); - - if (! _compute_normalized_device_slope (&slope_dx, &slope_dy, - stroker->ctm_inverse, NULL)) - return CAIRO_STATUS_SUCCESS; - - _compute_face (point, tangent, - slope_dx, slope_dy, - stroker, &new_face); - - assert (stroker->has_current_face); - - if ((new_face.dev_slope.x * stroker->current_face.dev_slope.x + - new_face.dev_slope.y * stroker->current_face.dev_slope.y) < stroker->spline_cusp_tolerance) { - - const cairo_point_t *inpt, *outpt; - int clockwise = _cairo_stroker_join_is_clockwise (&new_face, - &stroker->current_face); - - if (clockwise) { - inpt = &stroker->current_face.cw; - outpt = &new_face.cw; - } else { - inpt = &stroker->current_face.ccw; - outpt = &new_face.ccw; - } - - _tessellate_fan (stroker, - &stroker->current_face.dev_vector, - &new_face.dev_vector, - &stroker->current_face.point, - inpt, outpt, - clockwise); - } - - if (_slow_segment_intersection (&stroker->current_face.cw, - &stroker->current_face.ccw, - &new_face.cw, - &new_face.ccw, - &intersect_point)) { - points[0] = stroker->current_face.ccw; - points[1] = new_face.ccw; - points[2] = intersect_point; - stroker->add_triangle (stroker->closure, points); - - points[0] = stroker->current_face.cw; - points[1] = new_face.cw; - stroker->add_triangle (stroker->closure, points); - } else { - points[0] = stroker->current_face.ccw; - points[1] = stroker->current_face.cw; - points[2] = new_face.cw; - stroker->add_triangle (stroker->closure, points); - - points[0] = stroker->current_face.ccw; - points[1] = new_face.cw; - points[2] = new_face.ccw; - stroker->add_triangle (stroker->closure, points); - } - - stroker->current_face = new_face; - stroker->has_current_face = TRUE; - stroker->current_point = *point; - - return CAIRO_STATUS_SUCCESS; -} - -/* - * Dashed lines. Cap each dash end, join around turns when on - */ -static cairo_status_t -_cairo_stroker_line_to_dashed (void *closure, - const cairo_point_t *p2) -{ - cairo_stroker_t *stroker = closure; - double mag, remain, step_length = 0; - double slope_dx, slope_dy; - double dx2, dy2; - cairo_stroke_face_t sub_start, sub_end; - cairo_point_t *p1 = &stroker->current_point; - cairo_slope_t dev_slope; - cairo_line_t segment; - cairo_bool_t fully_in_bounds; - cairo_status_t status; - - stroker->has_initial_sub_path = stroker->dash.dash_starts_on; - - if (p1->x == p2->x && p1->y == p2->y) - return CAIRO_STATUS_SUCCESS; - - fully_in_bounds = TRUE; - if (stroker->has_bounds && - (! _cairo_box_contains_point (&stroker->bounds, p1) || - ! _cairo_box_contains_point (&stroker->bounds, p2))) - { - fully_in_bounds = FALSE; - } - - _cairo_slope_init (&dev_slope, p1, p2); - - slope_dx = _cairo_fixed_to_double (p2->x - p1->x); - slope_dy = _cairo_fixed_to_double (p2->y - p1->y); - - if (! _compute_normalized_device_slope (&slope_dx, &slope_dy, - stroker->ctm_inverse, &mag)) - { - return CAIRO_STATUS_SUCCESS; - } - - remain = mag; - segment.p1 = *p1; - while (remain) { - step_length = MIN (stroker->dash.dash_remain, remain); - remain -= step_length; - dx2 = slope_dx * (mag - remain); - dy2 = slope_dy * (mag - remain); - cairo_matrix_transform_distance (stroker->ctm, &dx2, &dy2); - segment.p2.x = _cairo_fixed_from_double (dx2) + p1->x; - segment.p2.y = _cairo_fixed_from_double (dy2) + p1->y; - - if (stroker->dash.dash_on && - (fully_in_bounds || - (! stroker->has_first_face && stroker->dash.dash_starts_on) || - _cairo_box_intersects_line_segment (&stroker->bounds, &segment))) - { - status = _cairo_stroker_add_sub_edge (stroker, - &segment.p1, &segment.p2, - &dev_slope, - slope_dx, slope_dy, - &sub_start, &sub_end); - if (unlikely (status)) - return status; - - if (stroker->has_current_face) - { - /* Join with final face from previous segment */ - status = _cairo_stroker_join (stroker, - &stroker->current_face, - &sub_start); - if (unlikely (status)) - return status; - - stroker->has_current_face = FALSE; - } - else if (! stroker->has_first_face && - stroker->dash.dash_starts_on) - { - /* Save sub path's first face in case needed for closing join */ - stroker->first_face = sub_start; - stroker->has_first_face = TRUE; - } - else - { - /* Cap dash start if not connecting to a previous segment */ - status = _cairo_stroker_add_leading_cap (stroker, &sub_start); - if (unlikely (status)) - return status; - } - - if (remain) { - /* Cap dash end if not at end of segment */ - status = _cairo_stroker_add_trailing_cap (stroker, &sub_end); - if (unlikely (status)) - return status; - } else { - stroker->current_face = sub_end; - stroker->has_current_face = TRUE; - } - } else { - if (stroker->has_current_face) { - /* Cap final face from previous segment */ - status = _cairo_stroker_add_trailing_cap (stroker, - &stroker->current_face); - if (unlikely (status)) - return status; - - stroker->has_current_face = FALSE; - } - } - - _cairo_stroker_dash_step (&stroker->dash, step_length); - segment.p1 = segment.p2; - } - - if (stroker->dash.dash_on && ! stroker->has_current_face) { - /* This segment ends on a transition to dash_on, compute a new face - * and add cap for the beginning of the next dash_on step. - * - * Note: this will create a degenerate cap if this is not the last line - * in the path. Whether this behaviour is desirable or not is debatable. - * On one side these degenerate caps can not be reproduced with regular - * path stroking. - * On the other hand, Acroread 7 also produces the degenerate caps. - */ - _compute_face (p2, &dev_slope, - slope_dx, slope_dy, - stroker, - &stroker->current_face); - - status = _cairo_stroker_add_leading_cap (stroker, - &stroker->current_face); - if (unlikely (status)) - return status; - - stroker->has_current_face = TRUE; - } - - stroker->current_point = *p2; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_stroker_curve_to (void *closure, - const cairo_point_t *b, - const cairo_point_t *c, - const cairo_point_t *d) -{ - cairo_stroker_t *stroker = closure; - cairo_spline_t spline; - cairo_line_join_t line_join_save; - cairo_stroke_face_t face; - double slope_dx, slope_dy; - cairo_spline_add_point_func_t line_to; - cairo_spline_add_point_func_t spline_to; - cairo_status_t status = CAIRO_STATUS_SUCCESS; - - line_to = stroker->dash.dashed ? - (cairo_spline_add_point_func_t) _cairo_stroker_line_to_dashed : - (cairo_spline_add_point_func_t) _cairo_stroker_line_to; - - /* spline_to is only capable of rendering non-degenerate splines. */ - spline_to = stroker->dash.dashed ? - (cairo_spline_add_point_func_t) _cairo_stroker_line_to_dashed : - (cairo_spline_add_point_func_t) _cairo_stroker_spline_to; - - if (! _cairo_spline_init (&spline, - spline_to, - stroker, - &stroker->current_point, b, c, d)) - { - cairo_slope_t fallback_slope; - _cairo_slope_init (&fallback_slope, &stroker->current_point, d); - return line_to (closure, d, &fallback_slope); - } - - /* If the line width is so small that the pen is reduced to a - single point, then we have nothing to do. */ - if (stroker->pen.num_vertices <= 1) - return CAIRO_STATUS_SUCCESS; - - /* Compute the initial face */ - if (! stroker->dash.dashed || stroker->dash.dash_on) { - slope_dx = _cairo_fixed_to_double (spline.initial_slope.dx); - slope_dy = _cairo_fixed_to_double (spline.initial_slope.dy); - if (_compute_normalized_device_slope (&slope_dx, &slope_dy, - stroker->ctm_inverse, NULL)) - { - _compute_face (&stroker->current_point, - &spline.initial_slope, - slope_dx, slope_dy, - stroker, &face); - } - if (stroker->has_current_face) { - status = _cairo_stroker_join (stroker, - &stroker->current_face, &face); - if (unlikely (status)) - return status; - } else if (! stroker->has_first_face) { - stroker->first_face = face; - stroker->has_first_face = TRUE; - } - - stroker->current_face = face; - stroker->has_current_face = TRUE; - } - - /* Temporarily modify the stroker to use round joins to guarantee - * smooth stroked curves. */ - line_join_save = stroker->style.line_join; - stroker->style.line_join = CAIRO_LINE_JOIN_ROUND; - - status = _cairo_spline_decompose (&spline, stroker->tolerance); - if (unlikely (status)) - return status; - - /* And join the final face */ - if (! stroker->dash.dashed || stroker->dash.dash_on) { - slope_dx = _cairo_fixed_to_double (spline.final_slope.dx); - slope_dy = _cairo_fixed_to_double (spline.final_slope.dy); - if (_compute_normalized_device_slope (&slope_dx, &slope_dy, - stroker->ctm_inverse, NULL)) - { - _compute_face (&stroker->current_point, - &spline.final_slope, - slope_dx, slope_dy, - stroker, &face); - } - - status = _cairo_stroker_join (stroker, &stroker->current_face, &face); - if (unlikely (status)) - return status; - - stroker->current_face = face; - } - - stroker->style.line_join = line_join_save; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_stroker_close_path (void *closure) -{ - cairo_stroker_t *stroker = closure; - cairo_status_t status; - - if (stroker->dash.dashed) - status = _cairo_stroker_line_to_dashed (stroker, &stroker->first_point); - else - status = _cairo_stroker_line_to (stroker, &stroker->first_point); - if (unlikely (status)) - return status; - - if (stroker->has_first_face && stroker->has_current_face) { - /* Join first and final faces of sub path */ - status = _cairo_stroker_join (stroker, - &stroker->current_face, - &stroker->first_face); - if (unlikely (status)) - return status; - } else { - /* Cap the start and end of the sub path as needed */ - status = _cairo_stroker_add_caps (stroker); - if (unlikely (status)) - return status; - } - - stroker->has_initial_sub_path = FALSE; - stroker->has_first_face = FALSE; - stroker->has_current_face = FALSE; - - return CAIRO_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_path_fixed_stroke_to_shaper (cairo_path_fixed_t *path, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_status_t (*add_triangle) (void *closure, - const cairo_point_t triangle[3]), - cairo_status_t (*add_triangle_fan) (void *closure, - const cairo_point_t *midpt, - const cairo_point_t *points, - int npoints), - cairo_status_t (*add_convex_quad) (void *closure, - const cairo_point_t quad[4]), - void *closure) -{ - cairo_stroker_t stroker; - cairo_status_t status; - - status = _cairo_stroker_init (&stroker, path, stroke_style, - ctm, ctm_inverse, tolerance, - NULL, 0); - if (unlikely (status)) - return status; - - stroker.add_triangle = add_triangle; - stroker.add_triangle_fan = add_triangle_fan; - stroker.add_convex_quad = add_convex_quad; - stroker.closure = closure; - - status = _cairo_path_fixed_interpret (path, - _cairo_stroker_move_to, - stroker.dash.dashed ? - _cairo_stroker_line_to_dashed : - _cairo_stroker_line_to, - _cairo_stroker_curve_to, - _cairo_stroker_close_path, - &stroker); - - if (unlikely (status)) - goto BAIL; - - /* Cap the start and end of the final sub path as needed */ - status = _cairo_stroker_add_caps (&stroker); - -BAIL: - _cairo_stroker_fini (&stroker); - - return status; -} - -cairo_status_t -_cairo_path_fixed_stroke_dashed_to_polygon (const cairo_path_fixed_t *path, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_polygon_t *polygon) -{ - cairo_stroker_t stroker; - cairo_status_t status; - - status = _cairo_stroker_init (&stroker, path, stroke_style, - ctm, ctm_inverse, tolerance, - polygon->limits, polygon->num_limits); - if (unlikely (status)) - return status; - - stroker.add_external_edge = _cairo_polygon_add_external_edge, - stroker.closure = polygon; - - status = _cairo_path_fixed_interpret (path, - _cairo_stroker_move_to, - stroker.dash.dashed ? - _cairo_stroker_line_to_dashed : - _cairo_stroker_line_to, - _cairo_stroker_curve_to, - _cairo_stroker_close_path, - &stroker); - - if (unlikely (status)) - goto BAIL; - - /* Cap the start and end of the final sub path as needed */ - status = _cairo_stroker_add_caps (&stroker); - -BAIL: - _cairo_stroker_fini (&stroker); - - return status; -} - -cairo_int_status_t -_cairo_path_fixed_stroke_polygon_to_traps (const cairo_path_fixed_t *path, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_traps_t *traps) -{ - cairo_int_status_t status; - cairo_polygon_t polygon; - - _cairo_polygon_init (&polygon, traps->limits, traps->num_limits); - status = _cairo_path_fixed_stroke_to_polygon (path, - stroke_style, - ctm, - ctm_inverse, - tolerance, - &polygon); - if (unlikely (status)) - goto BAIL; - - status = _cairo_polygon_status (&polygon); - if (unlikely (status)) - goto BAIL; - - status = _cairo_bentley_ottmann_tessellate_polygon (traps, &polygon, - CAIRO_FILL_RULE_WINDING); - -BAIL: - _cairo_polygon_fini (&polygon); - - return status; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-path.c b/source/libs/cairo/cairo-src/src/cairo-path.c deleted file mode 100644 index 43cd175a3c5235c0d42a28dd89629447b83d1188..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-path.c +++ /dev/null @@ -1,479 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2005 Red Hat, Inc. - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Carl D. Worth <cworth@redhat.com> - */ - -#include "cairoint.h" - -#include "cairo-private.h" -#include "cairo-backend-private.h" -#include "cairo-error-private.h" -#include "cairo-path-private.h" -#include "cairo-path-fixed-private.h" - -/** - * SECTION:cairo-paths - * @Title: Paths - * @Short_Description: Creating paths and manipulating path data - * - * Paths are the most basic drawing tools and are primarily used to implicitly - * generate simple masks. - **/ - -static const cairo_path_t _cairo_path_nil = { CAIRO_STATUS_NO_MEMORY, NULL, 0 }; - -/* Closure for path interpretation. */ -typedef struct cairo_path_count { - int count; -} cpc_t; - -static cairo_status_t -_cpc_move_to (void *closure, - const cairo_point_t *point) -{ - cpc_t *cpc = closure; - - cpc->count += 2; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cpc_line_to (void *closure, - const cairo_point_t *point) -{ - cpc_t *cpc = closure; - - cpc->count += 2; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cpc_curve_to (void *closure, - const cairo_point_t *p1, - const cairo_point_t *p2, - const cairo_point_t *p3) -{ - cpc_t *cpc = closure; - - cpc->count += 4; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cpc_close_path (void *closure) -{ - cpc_t *cpc = closure; - - cpc->count += 1; - - return CAIRO_STATUS_SUCCESS; -} - -static int -_cairo_path_count (cairo_path_t *path, - cairo_path_fixed_t *path_fixed, - double tolerance, - cairo_bool_t flatten) -{ - cairo_status_t status; - cpc_t cpc; - - cpc.count = 0; - - if (flatten) { - status = _cairo_path_fixed_interpret_flat (path_fixed, - _cpc_move_to, - _cpc_line_to, - _cpc_close_path, - &cpc, - tolerance); - } else { - status = _cairo_path_fixed_interpret (path_fixed, - _cpc_move_to, - _cpc_line_to, - _cpc_curve_to, - _cpc_close_path, - &cpc); - } - - if (unlikely (status)) - return -1; - - return cpc.count; -} - -/* Closure for path interpretation. */ -typedef struct cairo_path_populate { - cairo_path_data_t *data; - cairo_t *cr; -} cpp_t; - -static cairo_status_t -_cpp_move_to (void *closure, - const cairo_point_t *point) -{ - cpp_t *cpp = closure; - cairo_path_data_t *data = cpp->data; - double x, y; - - x = _cairo_fixed_to_double (point->x); - y = _cairo_fixed_to_double (point->y); - - _cairo_backend_to_user (cpp->cr, &x, &y); - - data->header.type = CAIRO_PATH_MOVE_TO; - data->header.length = 2; - - /* We index from 1 to leave room for data->header */ - data[1].point.x = x; - data[1].point.y = y; - - cpp->data += data->header.length; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cpp_line_to (void *closure, - const cairo_point_t *point) -{ - cpp_t *cpp = closure; - cairo_path_data_t *data = cpp->data; - double x, y; - - x = _cairo_fixed_to_double (point->x); - y = _cairo_fixed_to_double (point->y); - - _cairo_backend_to_user (cpp->cr, &x, &y); - - data->header.type = CAIRO_PATH_LINE_TO; - data->header.length = 2; - - /* We index from 1 to leave room for data->header */ - data[1].point.x = x; - data[1].point.y = y; - - cpp->data += data->header.length; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cpp_curve_to (void *closure, - const cairo_point_t *p1, - const cairo_point_t *p2, - const cairo_point_t *p3) -{ - cpp_t *cpp = closure; - cairo_path_data_t *data = cpp->data; - double x1, y1; - double x2, y2; - double x3, y3; - - x1 = _cairo_fixed_to_double (p1->x); - y1 = _cairo_fixed_to_double (p1->y); - _cairo_backend_to_user (cpp->cr, &x1, &y1); - - x2 = _cairo_fixed_to_double (p2->x); - y2 = _cairo_fixed_to_double (p2->y); - _cairo_backend_to_user (cpp->cr, &x2, &y2); - - x3 = _cairo_fixed_to_double (p3->x); - y3 = _cairo_fixed_to_double (p3->y); - _cairo_backend_to_user (cpp->cr, &x3, &y3); - - data->header.type = CAIRO_PATH_CURVE_TO; - data->header.length = 4; - - /* We index from 1 to leave room for data->header */ - data[1].point.x = x1; - data[1].point.y = y1; - - data[2].point.x = x2; - data[2].point.y = y2; - - data[3].point.x = x3; - data[3].point.y = y3; - - cpp->data += data->header.length; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cpp_close_path (void *closure) -{ - cpp_t *cpp = closure; - cairo_path_data_t *data = cpp->data; - - data->header.type = CAIRO_PATH_CLOSE_PATH; - data->header.length = 1; - - cpp->data += data->header.length; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_path_populate (cairo_path_t *path, - cairo_path_fixed_t *path_fixed, - cairo_t *cr, - cairo_bool_t flatten) -{ - cairo_status_t status; - cpp_t cpp; - - cpp.data = path->data; - cpp.cr = cr; - - if (flatten) { - status = _cairo_path_fixed_interpret_flat (path_fixed, - _cpp_move_to, - _cpp_line_to, - _cpp_close_path, - &cpp, - cairo_get_tolerance (cr)); - } else { - status = _cairo_path_fixed_interpret (path_fixed, - _cpp_move_to, - _cpp_line_to, - _cpp_curve_to, - _cpp_close_path, - &cpp); - } - - if (unlikely (status)) - return status; - - /* Sanity check the count */ - assert (cpp.data - path->data == path->num_data); - - return CAIRO_STATUS_SUCCESS; -} - -cairo_path_t * -_cairo_path_create_in_error (cairo_status_t status) -{ - cairo_path_t *path; - - /* special case NO_MEMORY so as to avoid allocations */ - if (status == CAIRO_STATUS_NO_MEMORY) - return (cairo_path_t*) &_cairo_path_nil; - - path = malloc (sizeof (cairo_path_t)); - if (unlikely (path == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_path_t*) &_cairo_path_nil; - } - - path->num_data = 0; - path->data = NULL; - path->status = status; - - return path; -} - -static cairo_path_t * -_cairo_path_create_internal (cairo_path_fixed_t *path_fixed, - cairo_t *cr, - cairo_bool_t flatten) -{ - cairo_path_t *path; - - path = malloc (sizeof (cairo_path_t)); - if (unlikely (path == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_path_t*) &_cairo_path_nil; - } - - path->num_data = _cairo_path_count (path, path_fixed, - cairo_get_tolerance (cr), - flatten); - if (path->num_data < 0) { - free (path); - return (cairo_path_t*) &_cairo_path_nil; - } - - if (path->num_data) { - path->data = _cairo_malloc_ab (path->num_data, - sizeof (cairo_path_data_t)); - if (unlikely (path->data == NULL)) { - free (path); - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_path_t*) &_cairo_path_nil; - } - - path->status = _cairo_path_populate (path, path_fixed, cr, flatten); - } else { - path->data = NULL; - path->status = CAIRO_STATUS_SUCCESS; - } - - return path; -} - -/** - * cairo_path_destroy: - * @path: a path previously returned by either cairo_copy_path() or - * cairo_copy_path_flat(). - * - * Immediately releases all memory associated with @path. After a call - * to cairo_path_destroy() the @path pointer is no longer valid and - * should not be used further. - * - * Note: cairo_path_destroy() should only be called with a - * pointer to a #cairo_path_t returned by a cairo function. Any path - * that is created manually (ie. outside of cairo) should be destroyed - * manually as well. - * - * Since: 1.0 - **/ -void -cairo_path_destroy (cairo_path_t *path) -{ - if (path == NULL || path == &_cairo_path_nil) - return; - - free (path->data); - - free (path); -} -slim_hidden_def (cairo_path_destroy); - -/** - * _cairo_path_create: - * @path: a fixed-point, device-space path to be converted and copied - * @cr: the current graphics context - * - * Creates a user-space #cairo_path_t copy of the given device-space - * @path. The @cr parameter provides the inverse CTM for the - * conversion. - * - * Return value: the new copy of the path. If there is insufficient - * memory a pointer to a special static nil #cairo_path_t will be - * returned instead with status==%CAIRO_STATUS_NO_MEMORY and - * data==%NULL. - **/ -cairo_path_t * -_cairo_path_create (cairo_path_fixed_t *path, - cairo_t *cr) -{ - return _cairo_path_create_internal (path, cr, FALSE); -} - -/** - * _cairo_path_create_flat: - * @path: a fixed-point, device-space path to be flattened, converted and copied - * @cr: the current graphics context - * - * Creates a flattened, user-space #cairo_path_t copy of the given - * device-space @path. The @cr parameter provide the inverse CTM - * for the conversion, as well as the tolerance value to control the - * accuracy of the flattening. - * - * Return value: the flattened copy of the path. If there is insufficient - * memory a pointer to a special static nil #cairo_path_t will be - * returned instead with status==%CAIRO_STATUS_NO_MEMORY and - * data==%NULL. - **/ -cairo_path_t * -_cairo_path_create_flat (cairo_path_fixed_t *path, - cairo_t *cr) -{ - return _cairo_path_create_internal (path, cr, TRUE); -} - -/** - * _cairo_path_append_to_context: - * @path: the path data to be appended - * @cr: a cairo context - * - * Append @path to the current path within @cr. - * - * Return value: %CAIRO_STATUS_INVALID_PATH_DATA if the data in @path - * is invalid, and %CAIRO_STATUS_SUCCESS otherwise. - **/ -cairo_status_t -_cairo_path_append_to_context (const cairo_path_t *path, - cairo_t *cr) -{ - const cairo_path_data_t *p, *end; - - end = &path->data[path->num_data]; - for (p = &path->data[0]; p < end; p += p->header.length) { - switch (p->header.type) { - case CAIRO_PATH_MOVE_TO: - if (unlikely (p->header.length < 2)) - return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA); - - cairo_move_to (cr, p[1].point.x, p[1].point.y); - break; - - case CAIRO_PATH_LINE_TO: - if (unlikely (p->header.length < 2)) - return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA); - - cairo_line_to (cr, p[1].point.x, p[1].point.y); - break; - - case CAIRO_PATH_CURVE_TO: - if (unlikely (p->header.length < 4)) - return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA); - - cairo_curve_to (cr, - p[1].point.x, p[1].point.y, - p[2].point.x, p[2].point.y, - p[3].point.x, p[3].point.y); - break; - - case CAIRO_PATH_CLOSE_PATH: - if (unlikely (p->header.length < 1)) - return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA); - - cairo_close_path (cr); - break; - - default: - return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA); - } - - if (unlikely (cr->status)) - return cr->status; - } - - return CAIRO_STATUS_SUCCESS; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-pattern-inline.h b/source/libs/cairo/cairo-src/src/cairo-pattern-inline.h deleted file mode 100644 index 97e8ea034e42c13614374d91eb9d0ff2b6350b0c..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-pattern-inline.h +++ /dev/null @@ -1,65 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Carl D. Worth <cworth@redhat.com> - */ - -#ifndef CAIRO_PATTERN_INLINE_H -#define CAIRO_PATTERN_INLINE_H - -#include "cairo-pattern-private.h" - -#include "cairo-list-inline.h" - -CAIRO_BEGIN_DECLS - -static inline void -_cairo_pattern_add_observer (cairo_pattern_t *pattern, - cairo_pattern_observer_t *observer, - void (*func) (cairo_pattern_observer_t *, - cairo_pattern_t *, - unsigned int)) -{ - observer->notify = func; - cairo_list_add (&observer->link, &pattern->observers); -} - -static inline cairo_surface_t * -_cairo_pattern_get_source (const cairo_surface_pattern_t *pattern, - cairo_rectangle_int_t *extents) -{ - return _cairo_surface_get_source (pattern->surface, extents); -} - -CAIRO_END_DECLS - -#endif /* CAIRO_PATTERN_INLINE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-pattern-private.h b/source/libs/cairo/cairo-src/src/cairo-pattern-private.h deleted file mode 100644 index be8ab9fc239a555bbc9bd0cb4fc9f0966005f24c..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-pattern-private.h +++ /dev/null @@ -1,369 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Carl D. Worth <cworth@redhat.com> - */ - -#ifndef CAIRO_PATTERN_PRIVATE_H -#define CAIRO_PATTERN_PRIVATE_H - -#include "cairo-error-private.h" -#include "cairo-types-private.h" -#include "cairo-list-private.h" -#include "cairo-surface-private.h" - -#include <stdio.h> /* FILE* */ - -CAIRO_BEGIN_DECLS - -typedef struct _cairo_pattern_observer cairo_pattern_observer_t; - -enum { - CAIRO_PATTERN_NOTIFY_MATRIX = 0x1, - CAIRO_PATTERN_NOTIFY_FILTER = 0x2, - CAIRO_PATTERN_NOTIFY_EXTEND = 0x4, - CAIRO_PATTERN_NOTIFY_OPACITY = 0x9, -}; - -struct _cairo_pattern_observer { - void (*notify) (cairo_pattern_observer_t *, - cairo_pattern_t *pattern, - unsigned int flags); - cairo_list_t link; -}; - -struct _cairo_pattern { - cairo_reference_count_t ref_count; - cairo_status_t status; - cairo_user_data_array_t user_data; - cairo_list_t observers; - - cairo_pattern_type_t type; - - cairo_filter_t filter; - cairo_extend_t extend; - cairo_bool_t has_component_alpha; - - cairo_matrix_t matrix; - double opacity; -}; - -struct _cairo_solid_pattern { - cairo_pattern_t base; - cairo_color_t color; -}; - -typedef struct _cairo_surface_pattern { - cairo_pattern_t base; - - cairo_surface_t *surface; -} cairo_surface_pattern_t; - -typedef struct _cairo_gradient_stop { - double offset; - cairo_color_stop_t color; -} cairo_gradient_stop_t; - -typedef struct _cairo_gradient_pattern { - cairo_pattern_t base; - - unsigned int n_stops; - unsigned int stops_size; - cairo_gradient_stop_t *stops; - cairo_gradient_stop_t stops_embedded[2]; -} cairo_gradient_pattern_t; - -typedef struct _cairo_linear_pattern { - cairo_gradient_pattern_t base; - - cairo_point_double_t pd1; - cairo_point_double_t pd2; -} cairo_linear_pattern_t; - -typedef struct _cairo_radial_pattern { - cairo_gradient_pattern_t base; - - cairo_circle_double_t cd1; - cairo_circle_double_t cd2; -} cairo_radial_pattern_t; - -typedef union { - cairo_gradient_pattern_t base; - - cairo_linear_pattern_t linear; - cairo_radial_pattern_t radial; -} cairo_gradient_pattern_union_t; - -/* - * A mesh patch is a tensor-product patch (bicubic Bezier surface - * patch). It has 16 control points. Each set of 4 points along the - * sides of the 4x4 grid of control points is a Bezier curve that - * defines one side of the patch. A color is assigned to each - * corner. The inner 4 points provide additional control over the - * shape and the color mapping. - * - * Cairo uses the same convention as the PDF Reference for numbering - * the points and side of the patch. - * - * - * Side 1 - * - * p[0][3] p[1][3] p[2][3] p[3][3] - * Side 0 p[0][2] p[1][2] p[2][2] p[3][2] Side 2 - * p[0][1] p[1][1] p[2][1] p[3][1] - * p[0][0] p[1][0] p[2][0] p[3][0] - * - * Side 3 - * - * - * Point Color - * ------------------------- - * points[0][0] colors[0] - * points[0][3] colors[1] - * points[3][3] colors[2] - * points[3][0] colors[3] - */ - -typedef struct _cairo_mesh_patch { - cairo_point_double_t points[4][4]; - cairo_color_t colors[4]; -} cairo_mesh_patch_t; - -typedef struct _cairo_mesh_pattern { - cairo_pattern_t base; - - cairo_array_t patches; - cairo_mesh_patch_t *current_patch; - int current_side; - cairo_bool_t has_control_point[4]; - cairo_bool_t has_color[4]; -} cairo_mesh_pattern_t; - -typedef struct _cairo_raster_source_pattern { - cairo_pattern_t base; - - cairo_content_t content; - cairo_rectangle_int_t extents; - - cairo_raster_source_acquire_func_t acquire; - cairo_raster_source_release_func_t release; - cairo_raster_source_snapshot_func_t snapshot; - cairo_raster_source_copy_func_t copy; - cairo_raster_source_finish_func_t finish; - - /* an explicit pre-allocated member in preference to the general user-data */ - void *user_data; -} cairo_raster_source_pattern_t; - -typedef union { - cairo_pattern_t base; - - cairo_solid_pattern_t solid; - cairo_surface_pattern_t surface; - cairo_gradient_pattern_union_t gradient; - cairo_mesh_pattern_t mesh; - cairo_raster_source_pattern_t raster_source; -} cairo_pattern_union_t; - -/* cairo-pattern.c */ - -cairo_private cairo_pattern_t * -_cairo_pattern_create_in_error (cairo_status_t status); - -cairo_private cairo_status_t -_cairo_pattern_create_copy (cairo_pattern_t **pattern, - const cairo_pattern_t *other); - -cairo_private void -_cairo_pattern_init (cairo_pattern_t *pattern, - cairo_pattern_type_t type); - -cairo_private cairo_status_t -_cairo_pattern_init_copy (cairo_pattern_t *pattern, - const cairo_pattern_t *other); - -cairo_private void -_cairo_pattern_init_static_copy (cairo_pattern_t *pattern, - const cairo_pattern_t *other); - -cairo_private cairo_status_t -_cairo_pattern_init_snapshot (cairo_pattern_t *pattern, - const cairo_pattern_t *other); - -cairo_private void -_cairo_pattern_init_solid (cairo_solid_pattern_t *pattern, - const cairo_color_t *color); - -cairo_private void -_cairo_pattern_init_for_surface (cairo_surface_pattern_t *pattern, - cairo_surface_t *surface); - -cairo_private void -_cairo_pattern_fini (cairo_pattern_t *pattern); - -cairo_private cairo_pattern_t * -_cairo_pattern_create_solid (const cairo_color_t *color); - -cairo_private void -_cairo_pattern_transform (cairo_pattern_t *pattern, - const cairo_matrix_t *ctm_inverse); - -cairo_private void -_cairo_pattern_pretransform (cairo_pattern_t *pattern, - const cairo_matrix_t *ctm); - -cairo_private cairo_bool_t -_cairo_pattern_is_opaque_solid (const cairo_pattern_t *pattern); - -cairo_private cairo_bool_t -_cairo_pattern_is_opaque (const cairo_pattern_t *pattern, - const cairo_rectangle_int_t *extents); - -cairo_private cairo_bool_t -_cairo_pattern_is_clear (const cairo_pattern_t *pattern); - -cairo_private cairo_bool_t -_cairo_gradient_pattern_is_solid (const cairo_gradient_pattern_t *gradient, - const cairo_rectangle_int_t *extents, - cairo_color_t *color); - -cairo_private void -_cairo_gradient_pattern_fit_to_range (const cairo_gradient_pattern_t *gradient, - double max_value, - cairo_matrix_t *out_matrix, - cairo_circle_double_t out_circle[2]); - -cairo_private cairo_bool_t -_cairo_radial_pattern_focus_is_inside (const cairo_radial_pattern_t *radial); - -cairo_private void -_cairo_gradient_pattern_box_to_parameter (const cairo_gradient_pattern_t *gradient, - double x0, double y0, - double x1, double y1, - double tolerance, - double out_range[2]); - -cairo_private void -_cairo_gradient_pattern_interpolate (const cairo_gradient_pattern_t *gradient, - double t, - cairo_circle_double_t *out_circle); - -cairo_private void -_cairo_pattern_alpha_range (const cairo_pattern_t *pattern, - double *out_min, - double *out_max); - -cairo_private cairo_bool_t -_cairo_mesh_pattern_coord_box (const cairo_mesh_pattern_t *mesh, - double *out_xmin, - double *out_ymin, - double *out_xmax, - double *out_ymax); - -cairo_private void -_cairo_pattern_sampled_area (const cairo_pattern_t *pattern, - const cairo_rectangle_int_t *extents, - cairo_rectangle_int_t *sample); - -cairo_private void -_cairo_pattern_get_extents (const cairo_pattern_t *pattern, - cairo_rectangle_int_t *extents); - -cairo_private cairo_int_status_t -_cairo_pattern_get_ink_extents (const cairo_pattern_t *pattern, - cairo_rectangle_int_t *extents); - -cairo_private unsigned long -_cairo_pattern_hash (const cairo_pattern_t *pattern); - -cairo_private unsigned long -_cairo_linear_pattern_hash (unsigned long hash, - const cairo_linear_pattern_t *linear); - -cairo_private unsigned long -_cairo_radial_pattern_hash (unsigned long hash, - const cairo_radial_pattern_t *radial); - -cairo_private cairo_bool_t -_cairo_linear_pattern_equal (const cairo_linear_pattern_t *a, - const cairo_linear_pattern_t *b); - -cairo_private unsigned long -_cairo_pattern_size (const cairo_pattern_t *pattern); - -cairo_private cairo_bool_t -_cairo_radial_pattern_equal (const cairo_radial_pattern_t *a, - const cairo_radial_pattern_t *b); - -cairo_private cairo_bool_t -_cairo_pattern_equal (const cairo_pattern_t *a, - const cairo_pattern_t *b); - -cairo_private cairo_filter_t -_cairo_pattern_analyze_filter (const cairo_pattern_t *pattern); - -/* cairo-mesh-pattern-rasterizer.c */ - -cairo_private void -_cairo_mesh_pattern_rasterize (const cairo_mesh_pattern_t *mesh, - void *data, - int width, - int height, - int stride, - double x_offset, - double y_offset); - -cairo_private cairo_surface_t * -_cairo_raster_source_pattern_acquire (const cairo_pattern_t *abstract_pattern, - cairo_surface_t *target, - const cairo_rectangle_int_t *extents); - -cairo_private void -_cairo_raster_source_pattern_release (const cairo_pattern_t *abstract_pattern, - cairo_surface_t *surface); - -cairo_private cairo_status_t -_cairo_raster_source_pattern_snapshot (cairo_pattern_t *abstract_pattern); - -cairo_private cairo_status_t -_cairo_raster_source_pattern_init_copy (cairo_pattern_t *pattern, - const cairo_pattern_t *other); - -cairo_private void -_cairo_raster_source_pattern_finish (cairo_pattern_t *abstract_pattern); - -cairo_private void -_cairo_debug_print_pattern (FILE *file, const cairo_pattern_t *pattern); - -CAIRO_END_DECLS - -#endif /* CAIRO_PATTERN_PRIVATE */ diff --git a/source/libs/cairo/cairo-src/src/cairo-pattern.c b/source/libs/cairo/cairo-src/src/cairo-pattern.c deleted file mode 100644 index f0b879836df3d863fbbd34c6cb4bbf09a0fb9f26..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-pattern.c +++ /dev/null @@ -1,4699 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2004 David Reveman - * Copyright © 2005 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 David - * Reveman not be used in advertising or publicity pertaining to - * distribution of the software without specific, written prior - * permission. David Reveman makes no representations about the - * suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL DAVID REVEMAN 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. - * - * Authors: David Reveman <davidr@novell.com> - * Keith Packard <keithp@keithp.com> - * Carl Worth <cworth@cworth.org> - */ - -#include "cairoint.h" - -#include "cairo-array-private.h" -#include "cairo-error-private.h" -#include "cairo-freed-pool-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-list-inline.h" -#include "cairo-path-private.h" -#include "cairo-pattern-private.h" -#include "cairo-recording-surface-inline.h" -#include "cairo-surface-snapshot-inline.h" - -#include <float.h> - -#define PIXMAN_MAX_INT ((pixman_fixed_1 >> 1) - pixman_fixed_e) /* need to ensure deltas also fit */ - -/** - * SECTION:cairo-pattern - * @Title: cairo_pattern_t - * @Short_Description: Sources for drawing - * @See_Also: #cairo_t, #cairo_surface_t - * - * #cairo_pattern_t is the paint with which cairo draws. - * The primary use of patterns is as the source for all cairo drawing - * operations, although they can also be used as masks, that is, as the - * brush too. - * - * A cairo pattern is created by using one of the many constructors, - * of the form - * <function>cairo_pattern_create_<emphasis>type</emphasis>()</function> - * or implicitly through - * <function>cairo_set_source_<emphasis>type</emphasis>()</function> - * functions. - **/ - -static freed_pool_t freed_pattern_pool[5]; - -static const cairo_solid_pattern_t _cairo_pattern_nil = { - { - CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ - CAIRO_STATUS_NO_MEMORY, /* status */ - { 0, 0, 0, NULL }, /* user_data */ - { NULL, NULL }, /* observers */ - - CAIRO_PATTERN_TYPE_SOLID, /* type */ - CAIRO_FILTER_DEFAULT, /* filter */ - CAIRO_EXTEND_GRADIENT_DEFAULT, /* extend */ - FALSE, /* has component alpha */ - { 1., 0., 0., 1., 0., 0., }, /* matrix */ - 1.0 /* opacity */ - } -}; - -static const cairo_solid_pattern_t _cairo_pattern_nil_null_pointer = { - { - CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ - CAIRO_STATUS_NULL_POINTER, /* status */ - { 0, 0, 0, NULL }, /* user_data */ - { NULL, NULL }, /* observers */ - - CAIRO_PATTERN_TYPE_SOLID, /* type */ - CAIRO_FILTER_DEFAULT, /* filter */ - CAIRO_EXTEND_GRADIENT_DEFAULT, /* extend */ - FALSE, /* has component alpha */ - { 1., 0., 0., 1., 0., 0., }, /* matrix */ - 1.0 /* opacity */ - } -}; - -const cairo_solid_pattern_t _cairo_pattern_black = { - { - CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ - CAIRO_STATUS_SUCCESS, /* status */ - { 0, 0, 0, NULL }, /* user_data */ - { NULL, NULL }, /* observers */ - - CAIRO_PATTERN_TYPE_SOLID, /* type */ - CAIRO_FILTER_NEAREST, /* filter */ - CAIRO_EXTEND_REPEAT, /* extend */ - FALSE, /* has component alpha */ - { 1., 0., 0., 1., 0., 0., }, /* matrix */ - 1.0 /* opacity */ - }, - { 0., 0., 0., 1., 0, 0, 0, 0xffff },/* color (double rgba, short rgba) */ -}; - -const cairo_solid_pattern_t _cairo_pattern_clear = { - { - CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ - CAIRO_STATUS_SUCCESS, /* status */ - { 0, 0, 0, NULL }, /* user_data */ - { NULL, NULL }, /* observers */ - - CAIRO_PATTERN_TYPE_SOLID, /* type */ - CAIRO_FILTER_NEAREST, /* filter */ - CAIRO_EXTEND_REPEAT, /* extend */ - FALSE, /* has component alpha */ - { 1., 0., 0., 1., 0., 0., }, /* matrix */ - 1.0 /* opacity */ - }, - { 0., 0., 0., 0., 0, 0, 0, 0 },/* color (double rgba, short rgba) */ -}; - -const cairo_solid_pattern_t _cairo_pattern_white = { - { - CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ - CAIRO_STATUS_SUCCESS, /* status */ - { 0, 0, 0, NULL }, /* user_data */ - { NULL, NULL }, /* observers */ - - CAIRO_PATTERN_TYPE_SOLID, /* type */ - CAIRO_FILTER_NEAREST, /* filter */ - CAIRO_EXTEND_REPEAT, /* extend */ - FALSE, /* has component alpha */ - { 1., 0., 0., 1., 0., 0., }, /* matrix */ - 1.0 /* opacity */ - }, - { 1., 1., 1., 1., 0xffff, 0xffff, 0xffff, 0xffff },/* color (double rgba, short rgba) */ -}; - -static void -_cairo_pattern_notify_observers (cairo_pattern_t *pattern, - unsigned int flags) -{ - cairo_pattern_observer_t *pos; - - cairo_list_foreach_entry (pos, cairo_pattern_observer_t, &pattern->observers, link) - pos->notify (pos, pattern, flags); -} - -/** - * _cairo_pattern_set_error: - * @pattern: a pattern - * @status: a status value indicating an error - * - * Atomically sets pattern->status to @status and calls _cairo_error; - * Does nothing if status is %CAIRO_STATUS_SUCCESS. - * - * All assignments of an error status to pattern->status should happen - * through _cairo_pattern_set_error(). Note that due to the nature of - * the atomic operation, it is not safe to call this function on the nil - * objects. - * - * The purpose of this function is to allow the user to set a - * breakpoint in _cairo_error() to generate a stack trace for when the - * user causes cairo to detect an error. - **/ -static cairo_status_t -_cairo_pattern_set_error (cairo_pattern_t *pattern, - cairo_status_t status) -{ - if (status == CAIRO_STATUS_SUCCESS) - return status; - - /* Don't overwrite an existing error. This preserves the first - * error, which is the most significant. */ - _cairo_status_set_error (&pattern->status, status); - - return _cairo_error (status); -} - -void -_cairo_pattern_init (cairo_pattern_t *pattern, cairo_pattern_type_t type) -{ -#if HAVE_VALGRIND - switch (type) { - case CAIRO_PATTERN_TYPE_SOLID: - VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_solid_pattern_t)); - break; - case CAIRO_PATTERN_TYPE_SURFACE: - VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_surface_pattern_t)); - break; - case CAIRO_PATTERN_TYPE_LINEAR: - VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_linear_pattern_t)); - break; - case CAIRO_PATTERN_TYPE_RADIAL: - VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_radial_pattern_t)); - break; - case CAIRO_PATTERN_TYPE_MESH: - VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_mesh_pattern_t)); - break; - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - break; - } -#endif - - pattern->type = type; - pattern->status = CAIRO_STATUS_SUCCESS; - - /* Set the reference count to zero for on-stack patterns. - * Callers needs to explicitly increment the count for heap allocations. */ - CAIRO_REFERENCE_COUNT_INIT (&pattern->ref_count, 0); - - _cairo_user_data_array_init (&pattern->user_data); - - if (type == CAIRO_PATTERN_TYPE_SURFACE || - type == CAIRO_PATTERN_TYPE_RASTER_SOURCE) - pattern->extend = CAIRO_EXTEND_SURFACE_DEFAULT; - else - pattern->extend = CAIRO_EXTEND_GRADIENT_DEFAULT; - - pattern->filter = CAIRO_FILTER_DEFAULT; - pattern->opacity = 1.0; - - pattern->has_component_alpha = FALSE; - - cairo_matrix_init_identity (&pattern->matrix); - - cairo_list_init (&pattern->observers); -} - -static cairo_status_t -_cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t *pattern, - const cairo_gradient_pattern_t *other) -{ - if (CAIRO_INJECT_FAULT ()) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - if (other->base.type == CAIRO_PATTERN_TYPE_LINEAR) - { - cairo_linear_pattern_t *dst = (cairo_linear_pattern_t *) pattern; - cairo_linear_pattern_t *src = (cairo_linear_pattern_t *) other; - - *dst = *src; - } - else - { - cairo_radial_pattern_t *dst = (cairo_radial_pattern_t *) pattern; - cairo_radial_pattern_t *src = (cairo_radial_pattern_t *) other; - - *dst = *src; - } - - if (other->stops == other->stops_embedded) - pattern->stops = pattern->stops_embedded; - else if (other->stops) - { - pattern->stops = _cairo_malloc_ab (other->stops_size, - sizeof (cairo_gradient_stop_t)); - if (unlikely (pattern->stops == NULL)) { - pattern->stops_size = 0; - pattern->n_stops = 0; - return _cairo_pattern_set_error (&pattern->base, CAIRO_STATUS_NO_MEMORY); - } - - memcpy (pattern->stops, other->stops, - other->n_stops * sizeof (cairo_gradient_stop_t)); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_mesh_pattern_init_copy (cairo_mesh_pattern_t *pattern, - const cairo_mesh_pattern_t *other) -{ - *pattern = *other; - - _cairo_array_init (&pattern->patches, sizeof (cairo_mesh_patch_t)); - return _cairo_array_append_multiple (&pattern->patches, - _cairo_array_index_const (&other->patches, 0), - _cairo_array_num_elements (&other->patches)); -} - -cairo_status_t -_cairo_pattern_init_copy (cairo_pattern_t *pattern, - const cairo_pattern_t *other) -{ - cairo_status_t status; - - if (other->status) - return _cairo_pattern_set_error (pattern, other->status); - - switch (other->type) { - case CAIRO_PATTERN_TYPE_SOLID: { - cairo_solid_pattern_t *dst = (cairo_solid_pattern_t *) pattern; - cairo_solid_pattern_t *src = (cairo_solid_pattern_t *) other; - - VG (VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_solid_pattern_t))); - - *dst = *src; - } break; - case CAIRO_PATTERN_TYPE_SURFACE: { - cairo_surface_pattern_t *dst = (cairo_surface_pattern_t *) pattern; - cairo_surface_pattern_t *src = (cairo_surface_pattern_t *) other; - - VG (VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_surface_pattern_t))); - - *dst = *src; - cairo_surface_reference (dst->surface); - } break; - case CAIRO_PATTERN_TYPE_LINEAR: - case CAIRO_PATTERN_TYPE_RADIAL: { - cairo_gradient_pattern_t *dst = (cairo_gradient_pattern_t *) pattern; - cairo_gradient_pattern_t *src = (cairo_gradient_pattern_t *) other; - - if (other->type == CAIRO_PATTERN_TYPE_LINEAR) { - VG (VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_linear_pattern_t))); - } else { - VG (VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_radial_pattern_t))); - } - - status = _cairo_gradient_pattern_init_copy (dst, src); - if (unlikely (status)) - return status; - - } break; - case CAIRO_PATTERN_TYPE_MESH: { - cairo_mesh_pattern_t *dst = (cairo_mesh_pattern_t *) pattern; - cairo_mesh_pattern_t *src = (cairo_mesh_pattern_t *) other; - - VG (VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_mesh_pattern_t))); - - status = _cairo_mesh_pattern_init_copy (dst, src); - if (unlikely (status)) - return status; - - } break; - - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: { - status = _cairo_raster_source_pattern_init_copy (pattern, other); - if (unlikely (status)) - return status; - } break; - } - - /* The reference count and user_data array are unique to the copy. */ - CAIRO_REFERENCE_COUNT_INIT (&pattern->ref_count, 0); - _cairo_user_data_array_init (&pattern->user_data); - - return CAIRO_STATUS_SUCCESS; -} - -void -_cairo_pattern_init_static_copy (cairo_pattern_t *pattern, - const cairo_pattern_t *other) -{ - int size; - - assert (other->status == CAIRO_STATUS_SUCCESS); - - switch (other->type) { - default: - ASSERT_NOT_REACHED; - case CAIRO_PATTERN_TYPE_SOLID: - size = sizeof (cairo_solid_pattern_t); - break; - case CAIRO_PATTERN_TYPE_SURFACE: - size = sizeof (cairo_surface_pattern_t); - break; - case CAIRO_PATTERN_TYPE_LINEAR: - size = sizeof (cairo_linear_pattern_t); - break; - case CAIRO_PATTERN_TYPE_RADIAL: - size = sizeof (cairo_radial_pattern_t); - break; - case CAIRO_PATTERN_TYPE_MESH: - size = sizeof (cairo_mesh_pattern_t); - break; - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - size = sizeof (cairo_raster_source_pattern_t); - break; - } - - memcpy (pattern, other, size); - - CAIRO_REFERENCE_COUNT_INIT (&pattern->ref_count, 0); - _cairo_user_data_array_init (&pattern->user_data); -} - -cairo_status_t -_cairo_pattern_init_snapshot (cairo_pattern_t *pattern, - const cairo_pattern_t *other) -{ - cairo_status_t status; - - /* We don't bother doing any fancy copy-on-write implementation - * for the pattern's data. It's generally quite tiny. */ - status = _cairo_pattern_init_copy (pattern, other); - if (unlikely (status)) - return status; - - /* But we do let the surface snapshot stuff be as fancy as it - * would like to be. */ - if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) { - cairo_surface_pattern_t *surface_pattern = - (cairo_surface_pattern_t *) pattern; - cairo_surface_t *surface = surface_pattern->surface; - - surface_pattern->surface = _cairo_surface_snapshot (surface); - - cairo_surface_destroy (surface); - - status = surface_pattern->surface->status; - } else if (pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE) - status = _cairo_raster_source_pattern_snapshot (pattern); - - return status; -} - -void -_cairo_pattern_fini (cairo_pattern_t *pattern) -{ - _cairo_user_data_array_fini (&pattern->user_data); - - switch (pattern->type) { - case CAIRO_PATTERN_TYPE_SOLID: - break; - case CAIRO_PATTERN_TYPE_SURFACE: { - cairo_surface_pattern_t *surface_pattern = - (cairo_surface_pattern_t *) pattern; - - cairo_surface_destroy (surface_pattern->surface); - } break; - case CAIRO_PATTERN_TYPE_LINEAR: - case CAIRO_PATTERN_TYPE_RADIAL: { - cairo_gradient_pattern_t *gradient = - (cairo_gradient_pattern_t *) pattern; - - if (gradient->stops && gradient->stops != gradient->stops_embedded) - free (gradient->stops); - } break; - case CAIRO_PATTERN_TYPE_MESH: { - cairo_mesh_pattern_t *mesh = - (cairo_mesh_pattern_t *) pattern; - - _cairo_array_fini (&mesh->patches); - } break; - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - _cairo_raster_source_pattern_finish (pattern); - break; - } - -#if HAVE_VALGRIND - switch (pattern->type) { - case CAIRO_PATTERN_TYPE_SOLID: - VALGRIND_MAKE_MEM_NOACCESS (pattern, sizeof (cairo_solid_pattern_t)); - break; - case CAIRO_PATTERN_TYPE_SURFACE: - VALGRIND_MAKE_MEM_NOACCESS (pattern, sizeof (cairo_surface_pattern_t)); - break; - case CAIRO_PATTERN_TYPE_LINEAR: - VALGRIND_MAKE_MEM_NOACCESS (pattern, sizeof (cairo_linear_pattern_t)); - break; - case CAIRO_PATTERN_TYPE_RADIAL: - VALGRIND_MAKE_MEM_NOACCESS (pattern, sizeof (cairo_radial_pattern_t)); - break; - case CAIRO_PATTERN_TYPE_MESH: - VALGRIND_MAKE_MEM_NOACCESS (pattern, sizeof (cairo_mesh_pattern_t)); - break; - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - break; - } -#endif -} - -cairo_status_t -_cairo_pattern_create_copy (cairo_pattern_t **pattern_out, - const cairo_pattern_t *other) -{ - cairo_pattern_t *pattern; - cairo_status_t status; - - if (other->status) - return other->status; - - switch (other->type) { - case CAIRO_PATTERN_TYPE_SOLID: - pattern = malloc (sizeof (cairo_solid_pattern_t)); - break; - case CAIRO_PATTERN_TYPE_SURFACE: - pattern = malloc (sizeof (cairo_surface_pattern_t)); - break; - case CAIRO_PATTERN_TYPE_LINEAR: - pattern = malloc (sizeof (cairo_linear_pattern_t)); - break; - case CAIRO_PATTERN_TYPE_RADIAL: - pattern = malloc (sizeof (cairo_radial_pattern_t)); - break; - case CAIRO_PATTERN_TYPE_MESH: - pattern = malloc (sizeof (cairo_mesh_pattern_t)); - break; - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - pattern = malloc (sizeof (cairo_raster_source_pattern_t)); - break; - default: - ASSERT_NOT_REACHED; - return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH); - } - if (unlikely (pattern == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - status = _cairo_pattern_init_copy (pattern, other); - if (unlikely (status)) { - free (pattern); - return status; - } - - CAIRO_REFERENCE_COUNT_INIT (&pattern->ref_count, 1); - *pattern_out = pattern; - return CAIRO_STATUS_SUCCESS; -} - -void -_cairo_pattern_init_solid (cairo_solid_pattern_t *pattern, - const cairo_color_t *color) -{ - _cairo_pattern_init (&pattern->base, CAIRO_PATTERN_TYPE_SOLID); - pattern->color = *color; -} - -void -_cairo_pattern_init_for_surface (cairo_surface_pattern_t *pattern, - cairo_surface_t *surface) -{ - if (surface->status) { - /* Force to solid to simplify the pattern_fini process. */ - _cairo_pattern_init (&pattern->base, CAIRO_PATTERN_TYPE_SOLID); - _cairo_pattern_set_error (&pattern->base, surface->status); - return; - } - - _cairo_pattern_init (&pattern->base, CAIRO_PATTERN_TYPE_SURFACE); - - pattern->surface = cairo_surface_reference (surface); -} - -static void -_cairo_pattern_init_gradient (cairo_gradient_pattern_t *pattern, - cairo_pattern_type_t type) -{ - _cairo_pattern_init (&pattern->base, type); - - pattern->n_stops = 0; - pattern->stops_size = 0; - pattern->stops = NULL; -} - -static void -_cairo_pattern_init_linear (cairo_linear_pattern_t *pattern, - double x0, double y0, double x1, double y1) -{ - _cairo_pattern_init_gradient (&pattern->base, CAIRO_PATTERN_TYPE_LINEAR); - - pattern->pd1.x = x0; - pattern->pd1.y = y0; - pattern->pd2.x = x1; - pattern->pd2.y = y1; -} - -static void -_cairo_pattern_init_radial (cairo_radial_pattern_t *pattern, - double cx0, double cy0, double radius0, - double cx1, double cy1, double radius1) -{ - _cairo_pattern_init_gradient (&pattern->base, CAIRO_PATTERN_TYPE_RADIAL); - - pattern->cd1.center.x = cx0; - pattern->cd1.center.y = cy0; - pattern->cd1.radius = fabs (radius0); - pattern->cd2.center.x = cx1; - pattern->cd2.center.y = cy1; - pattern->cd2.radius = fabs (radius1); -} - -cairo_pattern_t * -_cairo_pattern_create_solid (const cairo_color_t *color) -{ - cairo_solid_pattern_t *pattern; - - pattern = - _freed_pool_get (&freed_pattern_pool[CAIRO_PATTERN_TYPE_SOLID]); - if (unlikely (pattern == NULL)) { - /* None cached, need to create a new pattern. */ - pattern = malloc (sizeof (cairo_solid_pattern_t)); - if (unlikely (pattern == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_pattern_t *) &_cairo_pattern_nil; - } - } - - _cairo_pattern_init_solid (pattern, color); - CAIRO_REFERENCE_COUNT_INIT (&pattern->base.ref_count, 1); - - return &pattern->base; -} - -cairo_pattern_t * -_cairo_pattern_create_in_error (cairo_status_t status) -{ - cairo_pattern_t *pattern; - - if (status == CAIRO_STATUS_NO_MEMORY) - return (cairo_pattern_t *)&_cairo_pattern_nil.base; - - CAIRO_MUTEX_INITIALIZE (); - - pattern = _cairo_pattern_create_solid (CAIRO_COLOR_BLACK); - if (pattern->status == CAIRO_STATUS_SUCCESS) - status = _cairo_pattern_set_error (pattern, status); - - return pattern; -} - -/** - * cairo_pattern_create_rgb: - * @red: red component of the color - * @green: green component of the color - * @blue: blue component of the color - * - * Creates a new #cairo_pattern_t corresponding to an opaque color. The - * color components are floating point numbers in the range 0 to 1. - * If the values passed in are outside that range, they will be - * clamped. - * - * Return value: the newly created #cairo_pattern_t if successful, or - * an error pattern in case of no memory. The caller owns the - * returned object and should call cairo_pattern_destroy() when - * finished with it. - * - * This function will always return a valid pointer, but if an error - * occurred the pattern status will be set to an error. To inspect - * the status of a pattern use cairo_pattern_status(). - * - * Since: 1.0 - **/ -cairo_pattern_t * -cairo_pattern_create_rgb (double red, double green, double blue) -{ - return cairo_pattern_create_rgba (red, green, blue, 1.0); -} -slim_hidden_def (cairo_pattern_create_rgb); - -/** - * cairo_pattern_create_rgba: - * @red: red component of the color - * @green: green component of the color - * @blue: blue component of the color - * @alpha: alpha component of the color - * - * Creates a new #cairo_pattern_t corresponding to a translucent color. - * The color components are floating point numbers in the range 0 to - * 1. If the values passed in are outside that range, they will be - * clamped. - * - * Return value: the newly created #cairo_pattern_t if successful, or - * an error pattern in case of no memory. The caller owns the - * returned object and should call cairo_pattern_destroy() when - * finished with it. - * - * This function will always return a valid pointer, but if an error - * occurred the pattern status will be set to an error. To inspect - * the status of a pattern use cairo_pattern_status(). - * - * Since: 1.0 - **/ -cairo_pattern_t * -cairo_pattern_create_rgba (double red, double green, double blue, - double alpha) -{ - cairo_color_t color; - - red = _cairo_restrict_value (red, 0.0, 1.0); - green = _cairo_restrict_value (green, 0.0, 1.0); - blue = _cairo_restrict_value (blue, 0.0, 1.0); - alpha = _cairo_restrict_value (alpha, 0.0, 1.0); - - _cairo_color_init_rgba (&color, red, green, blue, alpha); - - CAIRO_MUTEX_INITIALIZE (); - - return _cairo_pattern_create_solid (&color); -} -slim_hidden_def (cairo_pattern_create_rgba); - -/** - * cairo_pattern_create_for_surface: - * @surface: the surface - * - * Create a new #cairo_pattern_t for the given surface. - * - * Return value: the newly created #cairo_pattern_t if successful, or - * an error pattern in case of no memory. The caller owns the - * returned object and should call cairo_pattern_destroy() when - * finished with it. - * - * This function will always return a valid pointer, but if an error - * occurred the pattern status will be set to an error. To inspect - * the status of a pattern use cairo_pattern_status(). - * - * Since: 1.0 - **/ -cairo_pattern_t * -cairo_pattern_create_for_surface (cairo_surface_t *surface) -{ - cairo_surface_pattern_t *pattern; - - if (surface == NULL) { - _cairo_error_throw (CAIRO_STATUS_NULL_POINTER); - return (cairo_pattern_t*) &_cairo_pattern_nil_null_pointer; - } - - if (surface->status) - return _cairo_pattern_create_in_error (surface->status); - - pattern = - _freed_pool_get (&freed_pattern_pool[CAIRO_PATTERN_TYPE_SURFACE]); - if (unlikely (pattern == NULL)) { - pattern = malloc (sizeof (cairo_surface_pattern_t)); - if (unlikely (pattern == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_pattern_t *)&_cairo_pattern_nil.base; - } - } - - CAIRO_MUTEX_INITIALIZE (); - - _cairo_pattern_init_for_surface (pattern, surface); - CAIRO_REFERENCE_COUNT_INIT (&pattern->base.ref_count, 1); - - return &pattern->base; -} -slim_hidden_def (cairo_pattern_create_for_surface); - -/** - * cairo_pattern_create_linear: - * @x0: x coordinate of the start point - * @y0: y coordinate of the start point - * @x1: x coordinate of the end point - * @y1: y coordinate of the end point - * - * Create a new linear gradient #cairo_pattern_t along the line defined - * by (x0, y0) and (x1, y1). Before using the gradient pattern, a - * number of color stops should be defined using - * cairo_pattern_add_color_stop_rgb() or - * cairo_pattern_add_color_stop_rgba(). - * - * Note: The coordinates here are in pattern space. For a new pattern, - * pattern space is identical to user space, but the relationship - * between the spaces can be changed with cairo_pattern_set_matrix(). - * - * Return value: the newly created #cairo_pattern_t if successful, or - * an error pattern in case of no memory. The caller owns the - * returned object and should call cairo_pattern_destroy() when - * finished with it. - * - * This function will always return a valid pointer, but if an error - * occurred the pattern status will be set to an error. To inspect - * the status of a pattern use cairo_pattern_status(). - * - * Since: 1.0 - **/ -cairo_pattern_t * -cairo_pattern_create_linear (double x0, double y0, double x1, double y1) -{ - cairo_linear_pattern_t *pattern; - - pattern = - _freed_pool_get (&freed_pattern_pool[CAIRO_PATTERN_TYPE_LINEAR]); - if (unlikely (pattern == NULL)) { - pattern = malloc (sizeof (cairo_linear_pattern_t)); - if (unlikely (pattern == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_pattern_t *) &_cairo_pattern_nil.base; - } - } - - CAIRO_MUTEX_INITIALIZE (); - - _cairo_pattern_init_linear (pattern, x0, y0, x1, y1); - CAIRO_REFERENCE_COUNT_INIT (&pattern->base.base.ref_count, 1); - - return &pattern->base.base; -} - -/** - * cairo_pattern_create_radial: - * @cx0: x coordinate for the center of the start circle - * @cy0: y coordinate for the center of the start circle - * @radius0: radius of the start circle - * @cx1: x coordinate for the center of the end circle - * @cy1: y coordinate for the center of the end circle - * @radius1: radius of the end circle - * - * Creates a new radial gradient #cairo_pattern_t between the two - * circles defined by (cx0, cy0, radius0) and (cx1, cy1, radius1). Before using the - * gradient pattern, a number of color stops should be defined using - * cairo_pattern_add_color_stop_rgb() or - * cairo_pattern_add_color_stop_rgba(). - * - * Note: The coordinates here are in pattern space. For a new pattern, - * pattern space is identical to user space, but the relationship - * between the spaces can be changed with cairo_pattern_set_matrix(). - * - * Return value: the newly created #cairo_pattern_t if successful, or - * an error pattern in case of no memory. The caller owns the - * returned object and should call cairo_pattern_destroy() when - * finished with it. - * - * This function will always return a valid pointer, but if an error - * occurred the pattern status will be set to an error. To inspect - * the status of a pattern use cairo_pattern_status(). - * - * Since: 1.0 - **/ -cairo_pattern_t * -cairo_pattern_create_radial (double cx0, double cy0, double radius0, - double cx1, double cy1, double radius1) -{ - cairo_radial_pattern_t *pattern; - - pattern = - _freed_pool_get (&freed_pattern_pool[CAIRO_PATTERN_TYPE_RADIAL]); - if (unlikely (pattern == NULL)) { - pattern = malloc (sizeof (cairo_radial_pattern_t)); - if (unlikely (pattern == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_pattern_t *) &_cairo_pattern_nil.base; - } - } - - CAIRO_MUTEX_INITIALIZE (); - - _cairo_pattern_init_radial (pattern, cx0, cy0, radius0, cx1, cy1, radius1); - CAIRO_REFERENCE_COUNT_INIT (&pattern->base.base.ref_count, 1); - - return &pattern->base.base; -} - -/* This order is specified in the diagram in the documentation for - * cairo_pattern_create_mesh() */ -static const int mesh_path_point_i[12] = { 0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 2, 1 }; -static const int mesh_path_point_j[12] = { 0, 1, 2, 3, 3, 3, 3, 2, 1, 0, 0, 0 }; -static const int mesh_control_point_i[4] = { 1, 1, 2, 2 }; -static const int mesh_control_point_j[4] = { 1, 2, 2, 1 }; - -/** - * cairo_pattern_create_mesh: - * - * Create a new mesh pattern. - * - * Mesh patterns are tensor-product patch meshes (type 7 shadings in - * PDF). Mesh patterns may also be used to create other types of - * shadings that are special cases of tensor-product patch meshes such - * as Coons patch meshes (type 6 shading in PDF) and Gouraud-shaded - * triangle meshes (type 4 and 5 shadings in PDF). - * - * Mesh patterns consist of one or more tensor-product patches, which - * should be defined before using the mesh pattern. Using a mesh - * pattern with a partially defined patch as source or mask will put - * the context in an error status with a status of - * %CAIRO_STATUS_INVALID_MESH_CONSTRUCTION. - * - * A tensor-product patch is defined by 4 Bézier curves (side 0, 1, 2, - * 3) and by 4 additional control points (P0, P1, P2, P3) that provide - * further control over the patch and complete the definition of the - * tensor-product patch. The corner C0 is the first point of the - * patch. - * - * Degenerate sides are permitted so straight lines may be used. A - * zero length line on one side may be used to create 3 sided patches. - * - * <informalexample><screen> - * C1 Side 1 C2 - * +---------------+ - * | | - * | P1 P2 | - * | | - * Side 0 | | Side 2 - * | | - * | | - * | P0 P3 | - * | | - * +---------------+ - * C0 Side 3 C3 - * </screen></informalexample> - * - * Each patch is constructed by first calling - * cairo_mesh_pattern_begin_patch(), then cairo_mesh_pattern_move_to() - * to specify the first point in the patch (C0). Then the sides are - * specified with calls to cairo_mesh_pattern_curve_to() and - * cairo_mesh_pattern_line_to(). - * - * The four additional control points (P0, P1, P2, P3) in a patch can - * be specified with cairo_mesh_pattern_set_control_point(). - * - * At each corner of the patch (C0, C1, C2, C3) a color may be - * specified with cairo_mesh_pattern_set_corner_color_rgb() or - * cairo_mesh_pattern_set_corner_color_rgba(). Any corner whose color - * is not explicitly specified defaults to transparent black. - * - * A Coons patch is a special case of the tensor-product patch where - * the control points are implicitly defined by the sides of the - * patch. The default value for any control point not specified is the - * implicit value for a Coons patch, i.e. if no control points are - * specified the patch is a Coons patch. - * - * A triangle is a special case of the tensor-product patch where the - * control points are implicitly defined by the sides of the patch, - * all the sides are lines and one of them has length 0, i.e. if the - * patch is specified using just 3 lines, it is a triangle. If the - * corners connected by the 0-length side have the same color, the - * patch is a Gouraud-shaded triangle. - * - * Patches may be oriented differently to the above diagram. For - * example the first point could be at the top left. The diagram only - * shows the relationship between the sides, corners and control - * points. Regardless of where the first point is located, when - * specifying colors, corner 0 will always be the first point, corner - * 1 the point between side 0 and side 1 etc. - * - * Calling cairo_mesh_pattern_end_patch() completes the current - * patch. If less than 4 sides have been defined, the first missing - * side is defined as a line from the current point to the first point - * of the patch (C0) and the other sides are degenerate lines from C0 - * to C0. The corners between the added sides will all be coincident - * with C0 of the patch and their color will be set to be the same as - * the color of C0. - * - * Additional patches may be added with additional calls to - * cairo_mesh_pattern_begin_patch()/cairo_mesh_pattern_end_patch(). - * - * <informalexample><programlisting> - * cairo_pattern_t *pattern = cairo_pattern_create_mesh (); - * - * /* Add a Coons patch */ - * cairo_mesh_pattern_begin_patch (pattern); - * cairo_mesh_pattern_move_to (pattern, 0, 0); - * cairo_mesh_pattern_curve_to (pattern, 30, -30, 60, 30, 100, 0); - * cairo_mesh_pattern_curve_to (pattern, 60, 30, 130, 60, 100, 100); - * cairo_mesh_pattern_curve_to (pattern, 60, 70, 30, 130, 0, 100); - * cairo_mesh_pattern_curve_to (pattern, 30, 70, -30, 30, 0, 0); - * cairo_mesh_pattern_set_corner_color_rgb (pattern, 0, 1, 0, 0); - * cairo_mesh_pattern_set_corner_color_rgb (pattern, 1, 0, 1, 0); - * cairo_mesh_pattern_set_corner_color_rgb (pattern, 2, 0, 0, 1); - * cairo_mesh_pattern_set_corner_color_rgb (pattern, 3, 1, 1, 0); - * cairo_mesh_pattern_end_patch (pattern); - * - * /* Add a Gouraud-shaded triangle */ - * cairo_mesh_pattern_begin_patch (pattern) - * cairo_mesh_pattern_move_to (pattern, 100, 100); - * cairo_mesh_pattern_line_to (pattern, 130, 130); - * cairo_mesh_pattern_line_to (pattern, 130, 70); - * cairo_mesh_pattern_set_corner_color_rgb (pattern, 0, 1, 0, 0); - * cairo_mesh_pattern_set_corner_color_rgb (pattern, 1, 0, 1, 0); - * cairo_mesh_pattern_set_corner_color_rgb (pattern, 2, 0, 0, 1); - * cairo_mesh_pattern_end_patch (pattern) - * </programlisting></informalexample> - * - * When two patches overlap, the last one that has been added is drawn - * over the first one. - * - * When a patch folds over itself, points are sorted depending on - * their parameter coordinates inside the patch. The v coordinate - * ranges from 0 to 1 when moving from side 3 to side 1; the u - * coordinate ranges from 0 to 1 when going from side 0 to side - * 2. Points with higher v coordinate hide points with lower v - * coordinate. When two points have the same v coordinate, the one - * with higher u coordinate is above. This means that points nearer to - * side 1 are above points nearer to side 3; when this is not - * sufficient to decide which point is above (for example when both - * points belong to side 1 or side 3) points nearer to side 2 are - * above points nearer to side 0. - * - * For a complete definition of tensor-product patches, see the PDF - * specification (ISO32000), which describes the parametrization in - * detail. - * - * Note: The coordinates are always in pattern space. For a new - * pattern, pattern space is identical to user space, but the - * relationship between the spaces can be changed with - * cairo_pattern_set_matrix(). - * - * Return value: the newly created #cairo_pattern_t if successful, or - * an error pattern in case of no memory. The caller owns the returned - * object and should call cairo_pattern_destroy() when finished with - * it. - * - * This function will always return a valid pointer, but if an error - * occurred the pattern status will be set to an error. To inspect the - * status of a pattern use cairo_pattern_status(). - * - * Since: 1.12 - **/ -cairo_pattern_t * -cairo_pattern_create_mesh (void) -{ - cairo_mesh_pattern_t *pattern; - - pattern = - _freed_pool_get (&freed_pattern_pool[CAIRO_PATTERN_TYPE_MESH]); - if (unlikely (pattern == NULL)) { - pattern = malloc (sizeof (cairo_mesh_pattern_t)); - if (unlikely (pattern == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_pattern_t *) &_cairo_pattern_nil.base; - } - } - - CAIRO_MUTEX_INITIALIZE (); - - _cairo_pattern_init (&pattern->base, CAIRO_PATTERN_TYPE_MESH); - _cairo_array_init (&pattern->patches, sizeof (cairo_mesh_patch_t)); - pattern->current_patch = NULL; - CAIRO_REFERENCE_COUNT_INIT (&pattern->base.ref_count, 1); - - return &pattern->base; -} - -/** - * cairo_pattern_reference: - * @pattern: a #cairo_pattern_t - * - * Increases the reference count on @pattern by one. This prevents - * @pattern from being destroyed until a matching call to - * cairo_pattern_destroy() is made. - * - * The number of references to a #cairo_pattern_t can be get using - * cairo_pattern_get_reference_count(). - * - * Return value: the referenced #cairo_pattern_t. - * - * Since: 1.0 - **/ -cairo_pattern_t * -cairo_pattern_reference (cairo_pattern_t *pattern) -{ - if (pattern == NULL || - CAIRO_REFERENCE_COUNT_IS_INVALID (&pattern->ref_count)) - return pattern; - - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&pattern->ref_count)); - - _cairo_reference_count_inc (&pattern->ref_count); - - return pattern; -} -slim_hidden_def (cairo_pattern_reference); - -/** - * cairo_pattern_get_type: - * @pattern: a #cairo_pattern_t - * - * This function returns the type a pattern. - * See #cairo_pattern_type_t for available types. - * - * Return value: The type of @pattern. - * - * Since: 1.2 - **/ -cairo_pattern_type_t -cairo_pattern_get_type (cairo_pattern_t *pattern) -{ - return pattern->type; -} - -/** - * cairo_pattern_status: - * @pattern: a #cairo_pattern_t - * - * Checks whether an error has previously occurred for this - * pattern. - * - * Return value: %CAIRO_STATUS_SUCCESS, %CAIRO_STATUS_NO_MEMORY, - * %CAIRO_STATUS_INVALID_MATRIX, %CAIRO_STATUS_PATTERN_TYPE_MISMATCH, - * or %CAIRO_STATUS_INVALID_MESH_CONSTRUCTION. - * - * Since: 1.0 - **/ -cairo_status_t -cairo_pattern_status (cairo_pattern_t *pattern) -{ - return pattern->status; -} - -/** - * cairo_pattern_destroy: - * @pattern: a #cairo_pattern_t - * - * Decreases the reference count on @pattern by one. If the result is - * zero, then @pattern and all associated resources are freed. See - * cairo_pattern_reference(). - * - * Since: 1.0 - **/ -void -cairo_pattern_destroy (cairo_pattern_t *pattern) -{ - cairo_pattern_type_t type; - - if (pattern == NULL || - CAIRO_REFERENCE_COUNT_IS_INVALID (&pattern->ref_count)) - return; - - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&pattern->ref_count)); - - if (! _cairo_reference_count_dec_and_test (&pattern->ref_count)) - return; - - type = pattern->type; - _cairo_pattern_fini (pattern); - - /* maintain a small cache of freed patterns */ - if (type < ARRAY_LENGTH (freed_pattern_pool)) - _freed_pool_put (&freed_pattern_pool[type], pattern); - else - free (pattern); -} -slim_hidden_def (cairo_pattern_destroy); - -/** - * cairo_pattern_get_reference_count: - * @pattern: a #cairo_pattern_t - * - * Returns the current reference count of @pattern. - * - * Return value: the current reference count of @pattern. If the - * object is a nil object, 0 will be returned. - * - * Since: 1.4 - **/ -unsigned int -cairo_pattern_get_reference_count (cairo_pattern_t *pattern) -{ - if (pattern == NULL || - CAIRO_REFERENCE_COUNT_IS_INVALID (&pattern->ref_count)) - return 0; - - return CAIRO_REFERENCE_COUNT_GET_VALUE (&pattern->ref_count); -} - -/** - * cairo_pattern_get_user_data: - * @pattern: a #cairo_pattern_t - * @key: the address of the #cairo_user_data_key_t the user data was - * attached to - * - * Return user data previously attached to @pattern using the - * specified key. If no user data has been attached with the given - * key this function returns %NULL. - * - * Return value: the user data previously attached or %NULL. - * - * Since: 1.4 - **/ -void * -cairo_pattern_get_user_data (cairo_pattern_t *pattern, - const cairo_user_data_key_t *key) -{ - return _cairo_user_data_array_get_data (&pattern->user_data, - key); -} - -/** - * cairo_pattern_set_user_data: - * @pattern: a #cairo_pattern_t - * @key: the address of a #cairo_user_data_key_t to attach the user data to - * @user_data: the user data to attach to the #cairo_pattern_t - * @destroy: a #cairo_destroy_func_t which will be called when the - * #cairo_t is destroyed or when new user data is attached using the - * same key. - * - * Attach user data to @pattern. To remove user data from a surface, - * call this function with the key that was used to set it and %NULL - * for @data. - * - * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a - * slot could not be allocated for the user data. - * - * Since: 1.4 - **/ -cairo_status_t -cairo_pattern_set_user_data (cairo_pattern_t *pattern, - const cairo_user_data_key_t *key, - void *user_data, - cairo_destroy_func_t destroy) -{ - if (CAIRO_REFERENCE_COUNT_IS_INVALID (&pattern->ref_count)) - return pattern->status; - - return _cairo_user_data_array_set_data (&pattern->user_data, - key, user_data, destroy); -} - -/** - * cairo_mesh_pattern_begin_patch: - * @pattern: a #cairo_pattern_t - * - * Begin a patch in a mesh pattern. - * - * After calling this function, the patch shape should be defined with - * cairo_mesh_pattern_move_to(), cairo_mesh_pattern_line_to() and - * cairo_mesh_pattern_curve_to(). - * - * After defining the patch, cairo_mesh_pattern_end_patch() must be - * called before using @pattern as a source or mask. - * - * Note: If @pattern is not a mesh pattern then @pattern will be put - * into an error status with a status of - * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH. If @pattern already has a - * current patch, it will be put into an error status with a status of - * %CAIRO_STATUS_INVALID_MESH_CONSTRUCTION. - * - * Since: 1.12 - **/ -void -cairo_mesh_pattern_begin_patch (cairo_pattern_t *pattern) -{ - cairo_mesh_pattern_t *mesh; - cairo_status_t status; - cairo_mesh_patch_t *current_patch; - int i; - - if (unlikely (pattern->status)) - return; - - if (unlikely (pattern->type != CAIRO_PATTERN_TYPE_MESH)) { - _cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH); - return; - } - - mesh = (cairo_mesh_pattern_t *) pattern; - if (unlikely (mesh->current_patch)) { - _cairo_pattern_set_error (pattern, CAIRO_STATUS_INVALID_MESH_CONSTRUCTION); - return; - } - - status = _cairo_array_allocate (&mesh->patches, 1, (void **) ¤t_patch); - if (unlikely (status)) { - _cairo_pattern_set_error (pattern, status); - return; - } - - mesh->current_patch = current_patch; - mesh->current_side = -2; /* no current point */ - - for (i = 0; i < 4; i++) - mesh->has_control_point[i] = FALSE; - - for (i = 0; i < 4; i++) - mesh->has_color[i] = FALSE; -} - - -static void -_calc_control_point (cairo_mesh_patch_t *patch, int control_point) -{ - /* The Coons patch is a special case of the Tensor Product patch - * where the four control points are: - * - * P11 = S(1/3, 1/3) - * P12 = S(1/3, 2/3) - * P21 = S(2/3, 1/3) - * P22 = S(2/3, 2/3) - * - * where S is the gradient surface. - * - * When one or more control points has not been specified - * calculated the Coons patch control points are substituted. If - * no control points are specified the gradient will be a Coons - * patch. - * - * The equations below are defined in the ISO32000 standard. - */ - cairo_point_double_t *p[3][3]; - int cp_i, cp_j, i, j; - - cp_i = mesh_control_point_i[control_point]; - cp_j = mesh_control_point_j[control_point]; - - for (i = 0; i < 3; i++) - for (j = 0; j < 3; j++) - p[i][j] = &patch->points[cp_i ^ i][cp_j ^ j]; - - p[0][0]->x = (- 4 * p[1][1]->x - + 6 * (p[1][0]->x + p[0][1]->x) - - 2 * (p[1][2]->x + p[2][1]->x) - + 3 * (p[2][0]->x + p[0][2]->x) - - 1 * p[2][2]->x) * (1. / 9); - - p[0][0]->y = (- 4 * p[1][1]->y - + 6 * (p[1][0]->y + p[0][1]->y) - - 2 * (p[1][2]->y + p[2][1]->y) - + 3 * (p[2][0]->y + p[0][2]->y) - - 1 * p[2][2]->y) * (1. / 9); -} - -/** - * cairo_mesh_pattern_end_patch: - * @pattern: a #cairo_pattern_t - * - * Indicates the end of the current patch in a mesh pattern. - * - * If the current patch has less than 4 sides, it is closed with a - * straight line from the current point to the first point of the - * patch as if cairo_mesh_pattern_line_to() was used. - * - * Note: If @pattern is not a mesh pattern then @pattern will be put - * into an error status with a status of - * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH. If @pattern has no current - * patch or the current patch has no current point, @pattern will be - * put into an error status with a status of - * %CAIRO_STATUS_INVALID_MESH_CONSTRUCTION. - * - * Since: 1.12 - **/ -void -cairo_mesh_pattern_end_patch (cairo_pattern_t *pattern) -{ - cairo_mesh_pattern_t *mesh; - cairo_mesh_patch_t *current_patch; - int i; - - if (unlikely (pattern->status)) - return; - - if (unlikely (pattern->type != CAIRO_PATTERN_TYPE_MESH)) { - _cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH); - return; - } - - mesh = (cairo_mesh_pattern_t *) pattern; - current_patch = mesh->current_patch; - if (unlikely (!current_patch)) { - _cairo_pattern_set_error (pattern, CAIRO_STATUS_INVALID_MESH_CONSTRUCTION); - return; - } - - if (unlikely (mesh->current_side == -2)) { - _cairo_pattern_set_error (pattern, CAIRO_STATUS_INVALID_MESH_CONSTRUCTION); - return; - } - - while (mesh->current_side < 3) { - int corner_num; - - cairo_mesh_pattern_line_to (pattern, - current_patch->points[0][0].x, - current_patch->points[0][0].y); - - corner_num = mesh->current_side + 1; - if (corner_num < 4 && ! mesh->has_color[corner_num]) { - current_patch->colors[corner_num] = current_patch->colors[0]; - mesh->has_color[corner_num] = TRUE; - } - } - - for (i = 0; i < 4; i++) { - if (! mesh->has_control_point[i]) - _calc_control_point (current_patch, i); - } - - for (i = 0; i < 4; i++) { - if (! mesh->has_color[i]) - current_patch->colors[i] = *CAIRO_COLOR_TRANSPARENT; - } - - mesh->current_patch = NULL; -} - -/** - * cairo_mesh_pattern_curve_to: - * @pattern: a #cairo_pattern_t - * @x1: the X coordinate of the first control point - * @y1: the Y coordinate of the first control point - * @x2: the X coordinate of the second control point - * @y2: the Y coordinate of the second control point - * @x3: the X coordinate of the end of the curve - * @y3: the Y coordinate of the end of the curve - * - * Adds a cubic Bézier spline to the current patch from the current - * point to position (@x3, @y3) in pattern-space coordinates, using - * (@x1, @y1) and (@x2, @y2) as the control points. - * - * If the current patch has no current point before the call to - * cairo_mesh_pattern_curve_to(), this function will behave as if - * preceded by a call to cairo_mesh_pattern_move_to(@pattern, @x1, - * @y1). - * - * After this call the current point will be (@x3, @y3). - * - * Note: If @pattern is not a mesh pattern then @pattern will be put - * into an error status with a status of - * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH. If @pattern has no current - * patch or the current patch already has 4 sides, @pattern will be - * put into an error status with a status of - * %CAIRO_STATUS_INVALID_MESH_CONSTRUCTION. - * - * Since: 1.12 - **/ -void -cairo_mesh_pattern_curve_to (cairo_pattern_t *pattern, - double x1, double y1, - double x2, double y2, - double x3, double y3) -{ - cairo_mesh_pattern_t *mesh; - int current_point, i, j; - - if (unlikely (pattern->status)) - return; - - if (unlikely (pattern->type != CAIRO_PATTERN_TYPE_MESH)) { - _cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH); - return; - } - - mesh = (cairo_mesh_pattern_t *) pattern; - if (unlikely (!mesh->current_patch)) { - _cairo_pattern_set_error (pattern, CAIRO_STATUS_INVALID_MESH_CONSTRUCTION); - return; - } - - if (unlikely (mesh->current_side == 3)) { - _cairo_pattern_set_error (pattern, CAIRO_STATUS_INVALID_MESH_CONSTRUCTION); - return; - } - - if (mesh->current_side == -2) - cairo_mesh_pattern_move_to (pattern, x1, y1); - - assert (mesh->current_side >= -1); - assert (pattern->status == CAIRO_STATUS_SUCCESS); - - mesh->current_side++; - - current_point = 3 * mesh->current_side; - - current_point++; - i = mesh_path_point_i[current_point]; - j = mesh_path_point_j[current_point]; - mesh->current_patch->points[i][j].x = x1; - mesh->current_patch->points[i][j].y = y1; - - current_point++; - i = mesh_path_point_i[current_point]; - j = mesh_path_point_j[current_point]; - mesh->current_patch->points[i][j].x = x2; - mesh->current_patch->points[i][j].y = y2; - - current_point++; - if (current_point < 12) { - i = mesh_path_point_i[current_point]; - j = mesh_path_point_j[current_point]; - mesh->current_patch->points[i][j].x = x3; - mesh->current_patch->points[i][j].y = y3; - } -} -slim_hidden_def (cairo_mesh_pattern_curve_to); - -/** - * cairo_mesh_pattern_line_to: - * @pattern: a #cairo_pattern_t - * @x: the X coordinate of the end of the new line - * @y: the Y coordinate of the end of the new line - * - * Adds a line to the current patch from the current point to position - * (@x, @y) in pattern-space coordinates. - * - * If there is no current point before the call to - * cairo_mesh_pattern_line_to() this function will behave as - * cairo_mesh_pattern_move_to(@pattern, @x, @y). - * - * After this call the current point will be (@x, @y). - * - * Note: If @pattern is not a mesh pattern then @pattern will be put - * into an error status with a status of - * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH. If @pattern has no current - * patch or the current patch already has 4 sides, @pattern will be - * put into an error status with a status of - * %CAIRO_STATUS_INVALID_MESH_CONSTRUCTION. - * - * Since: 1.12 - **/ -void -cairo_mesh_pattern_line_to (cairo_pattern_t *pattern, - double x, double y) -{ - cairo_mesh_pattern_t *mesh; - cairo_point_double_t last_point; - int last_point_idx, i, j; - - if (unlikely (pattern->status)) - return; - - if (unlikely (pattern->type != CAIRO_PATTERN_TYPE_MESH)) { - _cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH); - return; - } - - mesh = (cairo_mesh_pattern_t *) pattern; - if (unlikely (!mesh->current_patch)) { - _cairo_pattern_set_error (pattern, CAIRO_STATUS_INVALID_MESH_CONSTRUCTION); - return; - } - - if (unlikely (mesh->current_side == 3)) { - _cairo_pattern_set_error (pattern, CAIRO_STATUS_INVALID_MESH_CONSTRUCTION); - return; - } - - if (mesh->current_side == -2) { - cairo_mesh_pattern_move_to (pattern, x, y); - return; - } - - last_point_idx = 3 * (mesh->current_side + 1); - i = mesh_path_point_i[last_point_idx]; - j = mesh_path_point_j[last_point_idx]; - - last_point = mesh->current_patch->points[i][j]; - - cairo_mesh_pattern_curve_to (pattern, - (2 * last_point.x + x) * (1. / 3), - (2 * last_point.y + y) * (1. / 3), - (last_point.x + 2 * x) * (1. / 3), - (last_point.y + 2 * y) * (1. / 3), - x, y); -} -slim_hidden_def (cairo_mesh_pattern_line_to); - -/** - * cairo_mesh_pattern_move_to: - * @pattern: a #cairo_pattern_t - * @x: the X coordinate of the new position - * @y: the Y coordinate of the new position - * - * Define the first point of the current patch in a mesh pattern. - * - * After this call the current point will be (@x, @y). - * - * Note: If @pattern is not a mesh pattern then @pattern will be put - * into an error status with a status of - * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH. If @pattern has no current - * patch or the current patch already has at least one side, @pattern - * will be put into an error status with a status of - * %CAIRO_STATUS_INVALID_MESH_CONSTRUCTION. - * - * Since: 1.12 - **/ -void -cairo_mesh_pattern_move_to (cairo_pattern_t *pattern, - double x, double y) -{ - cairo_mesh_pattern_t *mesh; - - if (unlikely (pattern->status)) - return; - - if (unlikely (pattern->type != CAIRO_PATTERN_TYPE_MESH)) { - _cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH); - return; - } - - mesh = (cairo_mesh_pattern_t *) pattern; - if (unlikely (!mesh->current_patch)) { - _cairo_pattern_set_error (pattern, CAIRO_STATUS_INVALID_MESH_CONSTRUCTION); - return; - } - - if (unlikely (mesh->current_side >= 0)) { - _cairo_pattern_set_error (pattern, CAIRO_STATUS_INVALID_MESH_CONSTRUCTION); - return; - } - - mesh->current_side = -1; - mesh->current_patch->points[0][0].x = x; - mesh->current_patch->points[0][0].y = y; -} -slim_hidden_def (cairo_mesh_pattern_move_to); - -/** - * cairo_mesh_pattern_set_control_point: - * @pattern: a #cairo_pattern_t - * @point_num: the control point to set the position for - * @x: the X coordinate of the control point - * @y: the Y coordinate of the control point - * - * Set an internal control point of the current patch. - * - * Valid values for @point_num are from 0 to 3 and identify the - * control points as explained in cairo_pattern_create_mesh(). - * - * Note: If @pattern is not a mesh pattern then @pattern will be put - * into an error status with a status of - * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH. If @point_num is not valid, - * @pattern will be put into an error status with a status of - * %CAIRO_STATUS_INVALID_INDEX. If @pattern has no current patch, - * @pattern will be put into an error status with a status of - * %CAIRO_STATUS_INVALID_MESH_CONSTRUCTION. - * - * Since: 1.12 - **/ -void -cairo_mesh_pattern_set_control_point (cairo_pattern_t *pattern, - unsigned int point_num, - double x, - double y) -{ - cairo_mesh_pattern_t *mesh; - int i, j; - - if (unlikely (pattern->status)) - return; - - if (unlikely (pattern->type != CAIRO_PATTERN_TYPE_MESH)) { - _cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH); - return; - } - - if (unlikely (point_num > 3)) { - _cairo_pattern_set_error (pattern, CAIRO_STATUS_INVALID_INDEX); - return; - } - - mesh = (cairo_mesh_pattern_t *) pattern; - if (unlikely (!mesh->current_patch)) { - _cairo_pattern_set_error (pattern, CAIRO_STATUS_INVALID_MESH_CONSTRUCTION); - return; - } - - i = mesh_control_point_i[point_num]; - j = mesh_control_point_j[point_num]; - - mesh->current_patch->points[i][j].x = x; - mesh->current_patch->points[i][j].y = y; - mesh->has_control_point[point_num] = TRUE; -} - -/* make room for at least one more color stop */ -static cairo_status_t -_cairo_pattern_gradient_grow (cairo_gradient_pattern_t *pattern) -{ - cairo_gradient_stop_t *new_stops; - int old_size = pattern->stops_size; - int embedded_size = ARRAY_LENGTH (pattern->stops_embedded); - int new_size = 2 * MAX (old_size, 4); - - /* we have a local buffer at pattern->stops_embedded. try to fulfill the request - * from there. */ - if (old_size < embedded_size) { - pattern->stops = pattern->stops_embedded; - pattern->stops_size = embedded_size; - return CAIRO_STATUS_SUCCESS; - } - - if (CAIRO_INJECT_FAULT ()) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - assert (pattern->n_stops <= pattern->stops_size); - - if (pattern->stops == pattern->stops_embedded) { - new_stops = _cairo_malloc_ab (new_size, sizeof (cairo_gradient_stop_t)); - if (new_stops) - memcpy (new_stops, pattern->stops, old_size * sizeof (cairo_gradient_stop_t)); - } else { - new_stops = _cairo_realloc_ab (pattern->stops, - new_size, - sizeof (cairo_gradient_stop_t)); - } - - if (unlikely (new_stops == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - pattern->stops = new_stops; - pattern->stops_size = new_size; - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_mesh_pattern_set_corner_color (cairo_mesh_pattern_t *mesh, - unsigned int corner_num, - double red, double green, double blue, - double alpha) -{ - cairo_color_t *color; - - assert (mesh->current_patch); - assert (corner_num <= 3); - - color = &mesh->current_patch->colors[corner_num]; - color->red = red; - color->green = green; - color->blue = blue; - color->alpha = alpha; - - color->red_short = _cairo_color_double_to_short (red); - color->green_short = _cairo_color_double_to_short (green); - color->blue_short = _cairo_color_double_to_short (blue); - color->alpha_short = _cairo_color_double_to_short (alpha); - - mesh->has_color[corner_num] = TRUE; -} - -/** - * cairo_mesh_pattern_set_corner_color_rgb: - * @pattern: a #cairo_pattern_t - * @corner_num: the corner to set the color for - * @red: red component of color - * @green: green component of color - * @blue: blue component of color - * - * Sets the color of a corner of the current patch in a mesh pattern. - * - * The color is specified in the same way as in cairo_set_source_rgb(). - * - * Valid values for @corner_num are from 0 to 3 and identify the - * corners as explained in cairo_pattern_create_mesh(). - * - * Note: If @pattern is not a mesh pattern then @pattern will be put - * into an error status with a status of - * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH. If @corner_num is not valid, - * @pattern will be put into an error status with a status of - * %CAIRO_STATUS_INVALID_INDEX. If @pattern has no current patch, - * @pattern will be put into an error status with a status of - * %CAIRO_STATUS_INVALID_MESH_CONSTRUCTION. - * - * Since: 1.12 - **/ -void -cairo_mesh_pattern_set_corner_color_rgb (cairo_pattern_t *pattern, - unsigned int corner_num, - double red, double green, double blue) -{ - cairo_mesh_pattern_set_corner_color_rgba (pattern, corner_num, red, green, blue, 1.0); -} - -/** - * cairo_mesh_pattern_set_corner_color_rgba: - * @pattern: a #cairo_pattern_t - * @corner_num: the corner to set the color for - * @red: red component of color - * @green: green component of color - * @blue: blue component of color - * @alpha: alpha component of color - * - * Sets the color of a corner of the current patch in a mesh pattern. - * - * The color is specified in the same way as in cairo_set_source_rgba(). - * - * Valid values for @corner_num are from 0 to 3 and identify the - * corners as explained in cairo_pattern_create_mesh(). - * - * Note: If @pattern is not a mesh pattern then @pattern will be put - * into an error status with a status of - * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH. If @corner_num is not valid, - * @pattern will be put into an error status with a status of - * %CAIRO_STATUS_INVALID_INDEX. If @pattern has no current patch, - * @pattern will be put into an error status with a status of - * %CAIRO_STATUS_INVALID_MESH_CONSTRUCTION. - * - * Since: 1.12 - **/ -void -cairo_mesh_pattern_set_corner_color_rgba (cairo_pattern_t *pattern, - unsigned int corner_num, - double red, double green, double blue, - double alpha) -{ - cairo_mesh_pattern_t *mesh; - - if (unlikely (pattern->status)) - return; - - if (unlikely (pattern->type != CAIRO_PATTERN_TYPE_MESH)) { - _cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH); - return; - } - - if (unlikely (corner_num > 3)) { - _cairo_pattern_set_error (pattern, CAIRO_STATUS_INVALID_INDEX); - return; - } - - mesh = (cairo_mesh_pattern_t *) pattern; - if (unlikely (!mesh->current_patch)) { - _cairo_pattern_set_error (pattern, CAIRO_STATUS_INVALID_MESH_CONSTRUCTION); - return; - } - - red = _cairo_restrict_value (red, 0.0, 1.0); - green = _cairo_restrict_value (green, 0.0, 1.0); - blue = _cairo_restrict_value (blue, 0.0, 1.0); - alpha = _cairo_restrict_value (alpha, 0.0, 1.0); - - _cairo_mesh_pattern_set_corner_color (mesh, corner_num, red, green, blue, alpha); -} -slim_hidden_def (cairo_mesh_pattern_set_corner_color_rgba); - -static void -_cairo_pattern_add_color_stop (cairo_gradient_pattern_t *pattern, - double offset, - double red, - double green, - double blue, - double alpha) -{ - cairo_gradient_stop_t *stops; - unsigned int i; - - if (pattern->n_stops >= pattern->stops_size) { - cairo_status_t status = _cairo_pattern_gradient_grow (pattern); - if (unlikely (status)) { - status = _cairo_pattern_set_error (&pattern->base, status); - return; - } - } - - stops = pattern->stops; - - for (i = 0; i < pattern->n_stops; i++) - { - if (offset < stops[i].offset) - { - memmove (&stops[i + 1], &stops[i], - sizeof (cairo_gradient_stop_t) * (pattern->n_stops - i)); - - break; - } - } - - stops[i].offset = offset; - - stops[i].color.red = red; - stops[i].color.green = green; - stops[i].color.blue = blue; - stops[i].color.alpha = alpha; - - stops[i].color.red_short = _cairo_color_double_to_short (red); - stops[i].color.green_short = _cairo_color_double_to_short (green); - stops[i].color.blue_short = _cairo_color_double_to_short (blue); - stops[i].color.alpha_short = _cairo_color_double_to_short (alpha); - - pattern->n_stops++; -} - -/** - * cairo_pattern_add_color_stop_rgb: - * @pattern: a #cairo_pattern_t - * @offset: an offset in the range [0.0 .. 1.0] - * @red: red component of color - * @green: green component of color - * @blue: blue component of color - * - * Adds an opaque color stop to a gradient pattern. The offset - * specifies the location along the gradient's control vector. For - * example, a linear gradient's control vector is from (x0,y0) to - * (x1,y1) while a radial gradient's control vector is from any point - * on the start circle to the corresponding point on the end circle. - * - * The color is specified in the same way as in cairo_set_source_rgb(). - * - * If two (or more) stops are specified with identical offset values, - * they will be sorted according to the order in which the stops are - * added, (stops added earlier will compare less than stops added - * later). This can be useful for reliably making sharp color - * transitions instead of the typical blend. - * - * - * Note: If the pattern is not a gradient pattern, (eg. a linear or - * radial pattern), then the pattern will be put into an error status - * with a status of %CAIRO_STATUS_PATTERN_TYPE_MISMATCH. - * - * Since: 1.0 - **/ -void -cairo_pattern_add_color_stop_rgb (cairo_pattern_t *pattern, - double offset, - double red, - double green, - double blue) -{ - cairo_pattern_add_color_stop_rgba (pattern, offset, red, green, blue, 1.0); -} - -/** - * cairo_pattern_add_color_stop_rgba: - * @pattern: a #cairo_pattern_t - * @offset: an offset in the range [0.0 .. 1.0] - * @red: red component of color - * @green: green component of color - * @blue: blue component of color - * @alpha: alpha component of color - * - * Adds a translucent color stop to a gradient pattern. The offset - * specifies the location along the gradient's control vector. For - * example, a linear gradient's control vector is from (x0,y0) to - * (x1,y1) while a radial gradient's control vector is from any point - * on the start circle to the corresponding point on the end circle. - * - * The color is specified in the same way as in cairo_set_source_rgba(). - * - * If two (or more) stops are specified with identical offset values, - * they will be sorted according to the order in which the stops are - * added, (stops added earlier will compare less than stops added - * later). This can be useful for reliably making sharp color - * transitions instead of the typical blend. - * - * Note: If the pattern is not a gradient pattern, (eg. a linear or - * radial pattern), then the pattern will be put into an error status - * with a status of %CAIRO_STATUS_PATTERN_TYPE_MISMATCH. - * - * Since: 1.0 - **/ -void -cairo_pattern_add_color_stop_rgba (cairo_pattern_t *pattern, - double offset, - double red, - double green, - double blue, - double alpha) -{ - if (pattern->status) - return; - - if (pattern->type != CAIRO_PATTERN_TYPE_LINEAR && - pattern->type != CAIRO_PATTERN_TYPE_RADIAL) - { - _cairo_pattern_set_error (pattern, CAIRO_STATUS_PATTERN_TYPE_MISMATCH); - return; - } - - offset = _cairo_restrict_value (offset, 0.0, 1.0); - red = _cairo_restrict_value (red, 0.0, 1.0); - green = _cairo_restrict_value (green, 0.0, 1.0); - blue = _cairo_restrict_value (blue, 0.0, 1.0); - alpha = _cairo_restrict_value (alpha, 0.0, 1.0); - - _cairo_pattern_add_color_stop ((cairo_gradient_pattern_t *) pattern, - offset, red, green, blue, alpha); -} -slim_hidden_def (cairo_pattern_add_color_stop_rgba); - -/** - * cairo_pattern_set_matrix: - * @pattern: a #cairo_pattern_t - * @matrix: a #cairo_matrix_t - * - * Sets the pattern's transformation matrix to @matrix. This matrix is - * a transformation from user space to pattern space. - * - * When a pattern is first created it always has the identity matrix - * for its transformation matrix, which means that pattern space is - * initially identical to user space. - * - * Important: Please note that the direction of this transformation - * matrix is from user space to pattern space. This means that if you - * imagine the flow from a pattern to user space (and on to device - * space), then coordinates in that flow will be transformed by the - * inverse of the pattern matrix. - * - * For example, if you want to make a pattern appear twice as large as - * it does by default the correct code to use is: - * - * <informalexample><programlisting> - * cairo_matrix_init_scale (&matrix, 0.5, 0.5); - * cairo_pattern_set_matrix (pattern, &matrix); - * </programlisting></informalexample> - * - * Meanwhile, using values of 2.0 rather than 0.5 in the code above - * would cause the pattern to appear at half of its default size. - * - * Also, please note the discussion of the user-space locking - * semantics of cairo_set_source(). - * - * Since: 1.0 - **/ -void -cairo_pattern_set_matrix (cairo_pattern_t *pattern, - const cairo_matrix_t *matrix) -{ - cairo_matrix_t inverse; - cairo_status_t status; - - if (pattern->status) - return; - - if (memcmp (&pattern->matrix, matrix, sizeof (cairo_matrix_t)) == 0) - return; - - pattern->matrix = *matrix; - _cairo_pattern_notify_observers (pattern, CAIRO_PATTERN_NOTIFY_MATRIX); - - inverse = *matrix; - status = cairo_matrix_invert (&inverse); - if (unlikely (status)) - status = _cairo_pattern_set_error (pattern, status); -} -slim_hidden_def (cairo_pattern_set_matrix); - -/** - * cairo_pattern_get_matrix: - * @pattern: a #cairo_pattern_t - * @matrix: return value for the matrix - * - * Stores the pattern's transformation matrix into @matrix. - * - * Since: 1.0 - **/ -void -cairo_pattern_get_matrix (cairo_pattern_t *pattern, cairo_matrix_t *matrix) -{ - *matrix = pattern->matrix; -} - -/** - * cairo_pattern_set_filter: - * @pattern: a #cairo_pattern_t - * @filter: a #cairo_filter_t describing the filter to use for resizing - * the pattern - * - * Sets the filter to be used for resizing when using this pattern. - * See #cairo_filter_t for details on each filter. - * - * * Note that you might want to control filtering even when you do not - * have an explicit #cairo_pattern_t object, (for example when using - * cairo_set_source_surface()). In these cases, it is convenient to - * use cairo_get_source() to get access to the pattern that cairo - * creates implicitly. For example: - * - * <informalexample><programlisting> - * cairo_set_source_surface (cr, image, x, y); - * cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST); - * </programlisting></informalexample> - * - * Since: 1.0 - **/ -void -cairo_pattern_set_filter (cairo_pattern_t *pattern, cairo_filter_t filter) -{ - if (pattern->status) - return; - - pattern->filter = filter; - _cairo_pattern_notify_observers (pattern, CAIRO_PATTERN_NOTIFY_FILTER); -} - -/** - * cairo_pattern_get_filter: - * @pattern: a #cairo_pattern_t - * - * Gets the current filter for a pattern. See #cairo_filter_t - * for details on each filter. - * - * Return value: the current filter used for resizing the pattern. - * - * Since: 1.0 - **/ -cairo_filter_t -cairo_pattern_get_filter (cairo_pattern_t *pattern) -{ - return pattern->filter; -} - -/** - * cairo_pattern_set_extend: - * @pattern: a #cairo_pattern_t - * @extend: a #cairo_extend_t describing how the area outside of the - * pattern will be drawn - * - * Sets the mode to be used for drawing outside the area of a pattern. - * See #cairo_extend_t for details on the semantics of each extend - * strategy. - * - * The default extend mode is %CAIRO_EXTEND_NONE for surface patterns - * and %CAIRO_EXTEND_PAD for gradient patterns. - * - * Since: 1.0 - **/ -void -cairo_pattern_set_extend (cairo_pattern_t *pattern, cairo_extend_t extend) -{ - if (pattern->status) - return; - - pattern->extend = extend; - _cairo_pattern_notify_observers (pattern, CAIRO_PATTERN_NOTIFY_EXTEND); -} - -/** - * cairo_pattern_get_extend: - * @pattern: a #cairo_pattern_t - * - * Gets the current extend mode for a pattern. See #cairo_extend_t - * for details on the semantics of each extend strategy. - * - * Return value: the current extend strategy used for drawing the - * pattern. - * - * Since: 1.0 - **/ -cairo_extend_t -cairo_pattern_get_extend (cairo_pattern_t *pattern) -{ - return pattern->extend; -} -slim_hidden_def (cairo_pattern_get_extend); - -void -_cairo_pattern_pretransform (cairo_pattern_t *pattern, - const cairo_matrix_t *ctm) -{ - if (pattern->status) - return; - - cairo_matrix_multiply (&pattern->matrix, &pattern->matrix, ctm); -} - -void -_cairo_pattern_transform (cairo_pattern_t *pattern, - const cairo_matrix_t *ctm_inverse) -{ - if (pattern->status) - return; - - cairo_matrix_multiply (&pattern->matrix, ctm_inverse, &pattern->matrix); -} - -static cairo_bool_t -_linear_pattern_is_degenerate (const cairo_linear_pattern_t *linear) -{ - return fabs (linear->pd1.x - linear->pd2.x) < DBL_EPSILON && - fabs (linear->pd1.y - linear->pd2.y) < DBL_EPSILON; -} - -static cairo_bool_t -_radial_pattern_is_degenerate (const cairo_radial_pattern_t *radial) -{ - /* A radial pattern is considered degenerate if it can be - * represented as a solid or clear pattern. This corresponds to - * one of the two cases: - * - * 1) The radii are both very small: - * |dr| < DBL_EPSILON && min (r0, r1) < DBL_EPSILON - * - * 2) The two circles have about the same radius and are very - * close to each other (approximately a cylinder gradient that - * doesn't move with the parameter): - * |dr| < DBL_EPSILON && max (|dx|, |dy|) < 2 * DBL_EPSILON - * - * These checks are consistent with the assumptions used in - * _cairo_radial_pattern_box_to_parameter (). - */ - - return fabs (radial->cd1.radius - radial->cd2.radius) < DBL_EPSILON && - (MIN (radial->cd1.radius, radial->cd2.radius) < DBL_EPSILON || - MAX (fabs (radial->cd1.center.x - radial->cd2.center.x), - fabs (radial->cd1.center.y - radial->cd2.center.y)) < 2 * DBL_EPSILON); -} - -static void -_cairo_linear_pattern_box_to_parameter (const cairo_linear_pattern_t *linear, - double x0, double y0, - double x1, double y1, - double range[2]) -{ - double t0, tdx, tdy; - double p1x, p1y, pdx, pdy, invsqnorm; - - assert (! _linear_pattern_is_degenerate (linear)); - - /* - * Linear gradients are othrogonal to the line passing through - * their extremes. Because of convexity, the parameter range can - * be computed as the convex hull (one the real line) of the - * parameter values of the 4 corners of the box. - * - * The parameter value t for a point (x,y) can be computed as: - * - * t = (p2 - p1) . (x,y) / |p2 - p1|^2 - * - * t0 is the t value for the top left corner - * tdx is the difference between left and right corners - * tdy is the difference between top and bottom corners - */ - - p1x = linear->pd1.x; - p1y = linear->pd1.y; - pdx = linear->pd2.x - p1x; - pdy = linear->pd2.y - p1y; - invsqnorm = 1.0 / (pdx * pdx + pdy * pdy); - pdx *= invsqnorm; - pdy *= invsqnorm; - - t0 = (x0 - p1x) * pdx + (y0 - p1y) * pdy; - tdx = (x1 - x0) * pdx; - tdy = (y1 - y0) * pdy; - - /* - * Because of the linearity of the t value, tdx can simply be - * added the t0 to move along the top edge. After this, range[0] - * and range[1] represent the parameter range for the top edge, so - * extending it to include the whole box simply requires adding - * tdy to the correct extreme. - */ - - range[0] = range[1] = t0; - if (tdx < 0) - range[0] += tdx; - else - range[1] += tdx; - - if (tdy < 0) - range[0] += tdy; - else - range[1] += tdy; -} - -static cairo_bool_t -_extend_range (double range[2], double value, cairo_bool_t valid) -{ - if (!valid) - range[0] = range[1] = value; - else if (value < range[0]) - range[0] = value; - else if (value > range[1]) - range[1] = value; - - return TRUE; -} - -/* - * _cairo_radial_pattern_focus_is_inside: - * - * Returns %TRUE if and only if the focus point exists and is - * contained in one of the two extreme circles. This condition is - * equivalent to one of the two extreme circles being completely - * contained in the other one. - * - * Note: if the focus is on the border of one of the two circles (in - * which case the circles are tangent in the focus point), it is not - * considered as contained in the circle, hence this function returns - * %FALSE. - * - */ -cairo_bool_t -_cairo_radial_pattern_focus_is_inside (const cairo_radial_pattern_t *radial) -{ - double cx, cy, cr, dx, dy, dr; - - cx = radial->cd1.center.x; - cy = radial->cd1.center.y; - cr = radial->cd1.radius; - dx = radial->cd2.center.x - cx; - dy = radial->cd2.center.y - cy; - dr = radial->cd2.radius - cr; - - return dx*dx + dy*dy < dr*dr; -} - -static void -_cairo_radial_pattern_box_to_parameter (const cairo_radial_pattern_t *radial, - double x0, double y0, - double x1, double y1, - double tolerance, - double range[2]) -{ - double cx, cy, cr, dx, dy, dr; - double a, x_focus, y_focus; - double mindr, minx, miny, maxx, maxy; - cairo_bool_t valid; - - assert (! _radial_pattern_is_degenerate (radial)); - assert (x0 < x1); - assert (y0 < y1); - - tolerance = MAX (tolerance, DBL_EPSILON); - - range[0] = range[1] = 0; - valid = FALSE; - - x_focus = y_focus = 0; /* silence gcc */ - - cx = radial->cd1.center.x; - cy = radial->cd1.center.y; - cr = radial->cd1.radius; - dx = radial->cd2.center.x - cx; - dy = radial->cd2.center.y - cy; - dr = radial->cd2.radius - cr; - - /* translate by -(cx, cy) to simplify computations */ - x0 -= cx; - y0 -= cy; - x1 -= cx; - y1 -= cy; - - /* enlarge boundaries slightly to avoid rounding problems in the - * parameter range computation */ - x0 -= DBL_EPSILON; - y0 -= DBL_EPSILON; - x1 += DBL_EPSILON; - y1 += DBL_EPSILON; - - /* enlarge boundaries even more to avoid rounding problems when - * testing if a point belongs to the box */ - minx = x0 - DBL_EPSILON; - miny = y0 - DBL_EPSILON; - maxx = x1 + DBL_EPSILON; - maxy = y1 + DBL_EPSILON; - - /* we dont' allow negative radiuses, so we will be checking that - * t*dr >= mindr to consider t valid */ - mindr = -(cr + DBL_EPSILON); - - /* - * After the previous transformations, the start circle is - * centered in the origin and has radius cr. A 1-unit change in - * the t parameter corresponds to dx,dy,dr changes in the x,y,r of - * the circle (center coordinates, radius). - * - * To compute the minimum range needed to correctly draw the - * pattern, we start with an empty range and extend it to include - * the circles touching the bounding box or within it. - */ - - /* - * Focus, the point where the circle has radius == 0. - * - * r = cr + t * dr = 0 - * t = -cr / dr - * - * If the radius is constant (dr == 0) there is no focus (the - * gradient represents a cylinder instead of a cone). - */ - if (fabs (dr) >= DBL_EPSILON) { - double t_focus; - - t_focus = -cr / dr; - x_focus = t_focus * dx; - y_focus = t_focus * dy; - if (minx <= x_focus && x_focus <= maxx && - miny <= y_focus && y_focus <= maxy) - { - valid = _extend_range (range, t_focus, valid); - } - } - - /* - * Circles externally tangent to box edges. - * - * All circles have center in (dx, dy) * t - * - * If the circle is tangent to the line defined by the edge of the - * box, then at least one of the following holds true: - * - * (dx*t) + (cr + dr*t) == x0 (left edge) - * (dx*t) - (cr + dr*t) == x1 (right edge) - * (dy*t) + (cr + dr*t) == y0 (top edge) - * (dy*t) - (cr + dr*t) == y1 (bottom edge) - * - * The solution is only valid if the tangent point is actually on - * the edge, i.e. if its y coordinate is in [y0,y1] for left/right - * edges and if its x coordinate is in [x0,x1] for top/bottom - * edges. - * - * For the first equation: - * - * (dx + dr) * t = x0 - cr - * t = (x0 - cr) / (dx + dr) - * y = dy * t - * - * in the code this becomes: - * - * t_edge = (num) / (den) - * v = (delta) * t_edge - * - * If the denominator in t is 0, the pattern is tangent to a line - * parallel to the edge under examination. The corner-case where - * the boundary line is the same as the edge is handled by the - * focus point case and/or by the a==0 case. - */ -#define T_EDGE(num,den,delta,lower,upper) \ - if (fabs (den) >= DBL_EPSILON) { \ - double t_edge, v; \ - \ - t_edge = (num) / (den); \ - v = t_edge * (delta); \ - if (t_edge * dr >= mindr && (lower) <= v && v <= (upper)) \ - valid = _extend_range (range, t_edge, valid); \ - } - - /* circles tangent (externally) to left/right/top/bottom edge */ - T_EDGE (x0 - cr, dx + dr, dy, miny, maxy); - T_EDGE (x1 + cr, dx - dr, dy, miny, maxy); - T_EDGE (y0 - cr, dy + dr, dx, minx, maxx); - T_EDGE (y1 + cr, dy - dr, dx, minx, maxx); - -#undef T_EDGE - - /* - * Circles passing through a corner. - * - * A circle passing through the point (x,y) satisfies: - * - * (x-t*dx)^2 + (y-t*dy)^2 == (cr + t*dr)^2 - * - * If we set: - * a = dx^2 + dy^2 - dr^2 - * b = x*dx + y*dy + cr*dr - * c = x^2 + y^2 - cr^2 - * we have: - * a*t^2 - 2*b*t + c == 0 - */ - a = dx * dx + dy * dy - dr * dr; - if (fabs (a) < DBL_EPSILON * DBL_EPSILON) { - double b, maxd2; - - /* Ensure that gradients with both a and dr small are - * considered degenerate. - * The floating point version of the degeneracy test implemented - * in _radial_pattern_is_degenerate() is: - * - * 1) The circles are practically the same size: - * |dr| < DBL_EPSILON - * AND - * 2a) The circles are both very small: - * min (r0, r1) < DBL_EPSILON - * OR - * 2b) The circles are very close to each other: - * max (|dx|, |dy|) < 2 * DBL_EPSILON - * - * Assuming that the gradient is not degenerate, we want to - * show that |a| < DBL_EPSILON^2 implies |dr| >= DBL_EPSILON. - * - * If the gradient is not degenerate yet it has |dr| < - * DBL_EPSILON, (2b) is false, thus: - * - * max (|dx|, |dy|) >= 2*DBL_EPSILON - * which implies: - * 4*DBL_EPSILON^2 <= max (|dx|, |dy|)^2 <= dx^2 + dy^2 - * - * From the definition of a, we get: - * a = dx^2 + dy^2 - dr^2 < DBL_EPSILON^2 - * dx^2 + dy^2 - DBL_EPSILON^2 < dr^2 - * 3*DBL_EPSILON^2 < dr^2 - * - * which is inconsistent with the hypotheses, thus |dr| < - * DBL_EPSILON is false or the gradient is degenerate. - */ - assert (fabs (dr) >= DBL_EPSILON); - - /* - * If a == 0, all the circles are tangent to a line in the - * focus point. If this line is within the box extents, we - * should add the circle with infinite radius, but this would - * make the range unbounded, so we add the smallest circle whose - * distance to the desired (degenerate) circle within the - * bounding box does not exceed tolerance. - * - * The equation of the line is b==0, i.e.: - * x*dx + y*dy + cr*dr == 0 - * - * We compute the intersection of the line with the box and - * keep the intersection with maximum square distance (maxd2) - * from the focus point. - * - * In the code the intersection is represented in another - * coordinate system, whose origin is the focus point and - * which has a u,v axes, which are respectively orthogonal and - * parallel to the edge being intersected. - * - * The intersection is valid only if it belongs to the box, - * otherwise it is ignored. - * - * For example: - * - * y = y0 - * x*dx + y0*dy + cr*dr == 0 - * x = -(y0*dy + cr*dr) / dx - * - * which in (u,v) is: - * u = y0 - y_focus - * v = -(y0*dy + cr*dr) / dx - x_focus - * - * In the code: - * u = (edge) - (u_origin) - * v = -((edge) * (delta) + cr*dr) / (den) - v_focus - */ -#define T_EDGE(edge,delta,den,lower,upper,u_origin,v_origin) \ - if (fabs (den) >= DBL_EPSILON) { \ - double v; \ - \ - v = -((edge) * (delta) + cr * dr) / (den); \ - if ((lower) <= v && v <= (upper)) { \ - double u, d2; \ - \ - u = (edge) - (u_origin); \ - v -= (v_origin); \ - d2 = u*u + v*v; \ - if (maxd2 < d2) \ - maxd2 = d2; \ - } \ - } - - maxd2 = 0; - - /* degenerate circles (lines) passing through each edge */ - T_EDGE (y0, dy, dx, minx, maxx, y_focus, x_focus); - T_EDGE (y1, dy, dx, minx, maxx, y_focus, x_focus); - T_EDGE (x0, dx, dy, miny, maxy, x_focus, y_focus); - T_EDGE (x1, dx, dy, miny, maxy, x_focus, y_focus); - -#undef T_EDGE - - /* - * The limit circle can be transformed rigidly to the y=0 line - * and the circles tangent to it in (0,0) are: - * - * x^2 + (y-r)^2 = r^2 <=> x^2 + y^2 - 2*y*r = 0 - * - * y is the distance from the line, in our case tolerance; - * x is the distance along the line, i.e. sqrt(maxd2), - * so: - * - * r = cr + dr * t = (maxd2 + tolerance^2) / (2*tolerance) - * t = (r - cr) / dr = - * (maxd2 + tolerance^2 - 2*tolerance*cr) / (2*tolerance*dr) - */ - if (maxd2 > 0) { - double t_limit = maxd2 + tolerance*tolerance - 2*tolerance*cr; - t_limit /= 2 * tolerance * dr; - valid = _extend_range (range, t_limit, valid); - } - - /* - * Nondegenerate, nonlimit circles passing through the corners. - * - * a == 0 && a*t^2 - 2*b*t + c == 0 - * - * t = c / (2*b) - * - * The b == 0 case has just been handled, so we only have to - * compute this if b != 0. - */ -#define T_CORNER(x,y) \ - b = (x) * dx + (y) * dy + cr * dr; \ - if (fabs (b) >= DBL_EPSILON) { \ - double t_corner; \ - double x2 = (x) * (x); \ - double y2 = (y) * (y); \ - double cr2 = (cr) * (cr); \ - double c = x2 + y2 - cr2; \ - \ - t_corner = 0.5 * c / b; \ - if (t_corner * dr >= mindr) \ - valid = _extend_range (range, t_corner, valid); \ - } - - /* circles touching each corner */ - T_CORNER (x0, y0); - T_CORNER (x0, y1); - T_CORNER (x1, y0); - T_CORNER (x1, y1); - -#undef T_CORNER - } else { - double inva, b, c, d; - - inva = 1 / a; - - /* - * Nondegenerate, nonlimit circles passing through the corners. - * - * a != 0 && a*t^2 - 2*b*t + c == 0 - * - * t = (b +- sqrt (b*b - a*c)) / a - * - * If the argument of sqrt() is negative, then no circle - * passes through the corner. - */ -#define T_CORNER(x,y) \ - b = (x) * dx + (y) * dy + cr * dr; \ - c = (x) * (x) + (y) * (y) - cr * cr; \ - d = b * b - a * c; \ - if (d >= 0) { \ - double t_corner; \ - \ - d = sqrt (d); \ - t_corner = (b + d) * inva; \ - if (t_corner * dr >= mindr) \ - valid = _extend_range (range, t_corner, valid); \ - t_corner = (b - d) * inva; \ - if (t_corner * dr >= mindr) \ - valid = _extend_range (range, t_corner, valid); \ - } - - /* circles touching each corner */ - T_CORNER (x0, y0); - T_CORNER (x0, y1); - T_CORNER (x1, y0); - T_CORNER (x1, y1); - -#undef T_CORNER - } -} - -/** - * _cairo_gradient_pattern_box_to_parameter: - * - * Compute a interpolation range sufficient to draw (within the given - * tolerance) the gradient in the given box getting the same result as - * using the (-inf, +inf) range. - * - * Assumes that the pattern is not degenerate. This can be guaranteed - * by simplifying it to a solid clear if _cairo_pattern_is_clear or to - * a solid color if _cairo_gradient_pattern_is_solid. - * - * The range isn't guaranteed to be minimal, but it tries to. - **/ -void -_cairo_gradient_pattern_box_to_parameter (const cairo_gradient_pattern_t *gradient, - double x0, double y0, - double x1, double y1, - double tolerance, - double out_range[2]) -{ - assert (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR || - gradient->base.type == CAIRO_PATTERN_TYPE_RADIAL); - - if (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR) { - _cairo_linear_pattern_box_to_parameter ((cairo_linear_pattern_t *) gradient, - x0, y0, x1, y1, out_range); - } else { - _cairo_radial_pattern_box_to_parameter ((cairo_radial_pattern_t *) gradient, - x0, y0, x1, y1, tolerance, out_range); - } -} - -/** - * _cairo_gradient_pattern_interpolate: - * - * Interpolate between the start and end objects of linear or radial - * gradients. The interpolated object is stored in out_circle, with - * the radius being zero in the linear gradient case. - **/ -void -_cairo_gradient_pattern_interpolate (const cairo_gradient_pattern_t *gradient, - double t, - cairo_circle_double_t *out_circle) -{ - assert (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR || - gradient->base.type == CAIRO_PATTERN_TYPE_RADIAL); - -#define lerp(a,b) (a)*(1-t) + (b)*t - - if (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR) { - cairo_linear_pattern_t *linear = (cairo_linear_pattern_t *) gradient; - out_circle->center.x = lerp (linear->pd1.x, linear->pd2.x); - out_circle->center.y = lerp (linear->pd1.y, linear->pd2.y); - out_circle->radius = 0; - } else { - cairo_radial_pattern_t *radial = (cairo_radial_pattern_t *) gradient; - out_circle->center.x = lerp (radial->cd1.center.x, radial->cd2.center.x); - out_circle->center.y = lerp (radial->cd1.center.y, radial->cd2.center.y); - out_circle->radius = lerp (radial->cd1.radius , radial->cd2.radius); - } - -#undef lerp -} - - -/** - * _cairo_gradient_pattern_fit_to_range: - * - * Scale the extremes of a gradient to guarantee that the coordinates - * and their deltas are within the range (-max_value, max_value). The - * new extremes are stored in out_circle. - * - * The pattern matrix is scaled to guarantee that the aspect of the - * gradient is the same and the result is stored in out_matrix. - * - **/ -void -_cairo_gradient_pattern_fit_to_range (const cairo_gradient_pattern_t *gradient, - double max_value, - cairo_matrix_t *out_matrix, - cairo_circle_double_t out_circle[2]) -{ - double dim; - - assert (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR || - gradient->base.type == CAIRO_PATTERN_TYPE_RADIAL); - - if (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR) { - cairo_linear_pattern_t *linear = (cairo_linear_pattern_t *) gradient; - - out_circle[0].center = linear->pd1; - out_circle[0].radius = 0; - out_circle[1].center = linear->pd2; - out_circle[1].radius = 0; - - dim = fabs (linear->pd1.x); - dim = MAX (dim, fabs (linear->pd1.y)); - dim = MAX (dim, fabs (linear->pd2.x)); - dim = MAX (dim, fabs (linear->pd2.y)); - dim = MAX (dim, fabs (linear->pd1.x - linear->pd2.x)); - dim = MAX (dim, fabs (linear->pd1.y - linear->pd2.y)); - } else { - cairo_radial_pattern_t *radial = (cairo_radial_pattern_t *) gradient; - - out_circle[0] = radial->cd1; - out_circle[1] = radial->cd2; - - dim = fabs (radial->cd1.center.x); - dim = MAX (dim, fabs (radial->cd1.center.y)); - dim = MAX (dim, fabs (radial->cd1.radius)); - dim = MAX (dim, fabs (radial->cd2.center.x)); - dim = MAX (dim, fabs (radial->cd2.center.y)); - dim = MAX (dim, fabs (radial->cd2.radius)); - dim = MAX (dim, fabs (radial->cd1.center.x - radial->cd2.center.x)); - dim = MAX (dim, fabs (radial->cd1.center.y - radial->cd2.center.y)); - dim = MAX (dim, fabs (radial->cd1.radius - radial->cd2.radius)); - } - - if (unlikely (dim > max_value)) { - cairo_matrix_t scale; - - dim = max_value / dim; - - out_circle[0].center.x *= dim; - out_circle[0].center.y *= dim; - out_circle[0].radius *= dim; - out_circle[1].center.x *= dim; - out_circle[1].center.y *= dim; - out_circle[1].radius *= dim; - - cairo_matrix_init_scale (&scale, dim, dim); - cairo_matrix_multiply (out_matrix, &gradient->base.matrix, &scale); - } else { - *out_matrix = gradient->base.matrix; - } -} - -static cairo_bool_t -_gradient_is_clear (const cairo_gradient_pattern_t *gradient, - const cairo_rectangle_int_t *extents) -{ - unsigned int i; - - assert (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR || - gradient->base.type == CAIRO_PATTERN_TYPE_RADIAL); - - if (gradient->n_stops == 0 || - (gradient->base.extend == CAIRO_EXTEND_NONE && - gradient->stops[0].offset == gradient->stops[gradient->n_stops - 1].offset)) - return TRUE; - - if (gradient->base.type == CAIRO_PATTERN_TYPE_RADIAL) { - /* degenerate radial gradients are clear */ - if (_radial_pattern_is_degenerate ((cairo_radial_pattern_t *) gradient)) - return TRUE; - } else if (gradient->base.extend == CAIRO_EXTEND_NONE) { - /* EXTEND_NONE degenerate linear gradients are clear */ - if (_linear_pattern_is_degenerate ((cairo_linear_pattern_t *) gradient)) - return TRUE; - } - - /* Check if the extents intersect the drawn part of the pattern. */ - if (extents != NULL && - (gradient->base.extend == CAIRO_EXTEND_NONE || - gradient->base.type == CAIRO_PATTERN_TYPE_RADIAL)) - { - double t[2]; - - _cairo_gradient_pattern_box_to_parameter (gradient, - extents->x, - extents->y, - extents->x + extents->width, - extents->y + extents->height, - DBL_EPSILON, - t); - - if (gradient->base.extend == CAIRO_EXTEND_NONE && - (t[0] >= gradient->stops[gradient->n_stops - 1].offset || - t[1] <= gradient->stops[0].offset)) - { - return TRUE; - } - - if (t[0] == t[1]) - return TRUE; - } - - for (i = 0; i < gradient->n_stops; i++) - if (! CAIRO_COLOR_IS_CLEAR (&gradient->stops[i].color)) - return FALSE; - - return TRUE; -} - -static void -_gradient_color_average (const cairo_gradient_pattern_t *gradient, - cairo_color_t *color) -{ - double delta0, delta1; - double r, g, b, a; - unsigned int i, start = 1, end; - - assert (gradient->n_stops > 0); - assert (gradient->base.extend != CAIRO_EXTEND_NONE); - - if (gradient->n_stops == 1) { - _cairo_color_init_rgba (color, - gradient->stops[0].color.red, - gradient->stops[0].color.green, - gradient->stops[0].color.blue, - gradient->stops[0].color.alpha); - return; - } - - end = gradient->n_stops - 1; - - switch (gradient->base.extend) { - case CAIRO_EXTEND_REPEAT: - /* - * Sa, Sb and Sy, Sz are the first two and last two stops respectively. - * The weight of the first and last stop can be computed as the area of - * the following triangles (taken with height 1, since the whole [0-1] - * will have total weight 1 this way): b*h/2 - * - * + + - * / |\ / | \ - * / | \ / | \ - * / | \ / | \ - * ~~~~~+---+---+---+~~~~~~~+-------+---+---+~~~~~ - * -1+Sz 0 Sa Sb Sy Sz 1 1+Sa - * - * For the first stop: (Sb-(-1+Sz)/2 = (1+Sb-Sz)/2 - * For the last stop: ((1+Sa)-Sy)/2 = (1+Sa-Sy)/2 - * Halving the result is done after summing up all the areas. - */ - delta0 = 1.0 + gradient->stops[1].offset - gradient->stops[end].offset; - delta1 = 1.0 + gradient->stops[0].offset - gradient->stops[end-1].offset; - break; - - case CAIRO_EXTEND_REFLECT: - /* - * Sa, Sb and Sy, Sz are the first two and last two stops respectively. - * The weight of the first and last stop can be computed as the area of - * the following trapezoids (taken with height 1, since the whole [0-1] - * will have total weight 1 this way): (b+B)*h/2 - * - * +-------+ +---+ - * | |\ / | | - * | | \ / | | - * | | \ / | | - * +-------+---+~~~~~~~+-------+---+ - * 0 Sa Sb Sy Sz 1 - * - * For the first stop: (Sa+Sb)/2 - * For the last stop: ((1-Sz) + (1-Sy))/2 = (2-Sy-Sz)/2 - * Halving the result is done after summing up all the areas. - */ - delta0 = gradient->stops[0].offset + gradient->stops[1].offset; - delta1 = 2.0 - gradient->stops[end-1].offset - gradient->stops[end].offset; - break; - - case CAIRO_EXTEND_PAD: - /* PAD is computed as the average of the first and last stop: - * - take both of them with weight 1 (they will be halved - * after the whole sum has been computed). - * - avoid summing any of the inner stops. - */ - delta0 = delta1 = 1.0; - start = end; - break; - - case CAIRO_EXTEND_NONE: - default: - ASSERT_NOT_REACHED; - _cairo_color_init_rgba (color, 0, 0, 0, 0); - return; - } - - r = delta0 * gradient->stops[0].color.red; - g = delta0 * gradient->stops[0].color.green; - b = delta0 * gradient->stops[0].color.blue; - a = delta0 * gradient->stops[0].color.alpha; - - for (i = start; i < end; ++i) { - /* Inner stops weight is the same as the area of the triangle they influence - * (which goes from the stop before to the stop after), again with height 1 - * since the whole must sum up to 1: b*h/2 - * Halving is done after the whole sum has been computed. - */ - double delta = gradient->stops[i+1].offset - gradient->stops[i-1].offset; - r += delta * gradient->stops[i].color.red; - g += delta * gradient->stops[i].color.green; - b += delta * gradient->stops[i].color.blue; - a += delta * gradient->stops[i].color.alpha; - } - - r += delta1 * gradient->stops[end].color.red; - g += delta1 * gradient->stops[end].color.green; - b += delta1 * gradient->stops[end].color.blue; - a += delta1 * gradient->stops[end].color.alpha; - - _cairo_color_init_rgba (color, r * .5, g * .5, b * .5, a * .5); -} - -/** - * _cairo_pattern_alpha_range: - * - * Convenience function to determine the minimum and maximum alpha in - * the drawn part of a pattern (i.e. ignoring clear parts caused by - * extend modes and/or pattern shape). - * - * If not NULL, out_min and out_max will be set respectively to the - * minimum and maximum alpha value of the pattern. - **/ -void -_cairo_pattern_alpha_range (const cairo_pattern_t *pattern, - double *out_min, - double *out_max) -{ - double alpha_min, alpha_max; - - switch (pattern->type) { - case CAIRO_PATTERN_TYPE_SOLID: { - const cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) pattern; - alpha_min = alpha_max = solid->color.alpha; - break; - } - - case CAIRO_PATTERN_TYPE_LINEAR: - case CAIRO_PATTERN_TYPE_RADIAL: { - const cairo_gradient_pattern_t *gradient = (cairo_gradient_pattern_t *) pattern; - unsigned int i; - - assert (gradient->n_stops >= 1); - - alpha_min = alpha_max = gradient->stops[0].color.alpha; - for (i = 1; i < gradient->n_stops; i++) { - if (alpha_min > gradient->stops[i].color.alpha) - alpha_min = gradient->stops[i].color.alpha; - else if (alpha_max < gradient->stops[i].color.alpha) - alpha_max = gradient->stops[i].color.alpha; - } - - break; - } - - case CAIRO_PATTERN_TYPE_MESH: { - const cairo_mesh_pattern_t *mesh = (const cairo_mesh_pattern_t *) pattern; - const cairo_mesh_patch_t *patch = _cairo_array_index_const (&mesh->patches, 0); - unsigned int i, j, n = _cairo_array_num_elements (&mesh->patches); - - assert (n >= 1); - - alpha_min = alpha_max = patch[0].colors[0].alpha; - for (i = 0; i < n; i++) { - for (j = 0; j < 4; j++) { - if (patch[i].colors[j].alpha < alpha_min) - alpha_min = patch[i].colors[j].alpha; - else if (patch[i].colors[j].alpha > alpha_max) - alpha_max = patch[i].colors[j].alpha; - } - } - - break; - } - - default: - ASSERT_NOT_REACHED; - /* fall through */ - - case CAIRO_PATTERN_TYPE_SURFACE: - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - alpha_min = 0; - alpha_max = 1; - break; - } - - if (out_min) - *out_min = alpha_min; - if (out_max) - *out_max = alpha_max; -} - -/** - * _cairo_mesh_pattern_coord_box: - * - * Convenience function to determine the range of the coordinates of - * the points used to define the patches of the mesh. - * - * This is guaranteed to contain the pattern extents, but might not be - * tight, just like a Bezier curve is always inside the convex hull of - * the control points. - * - * This function cannot be used while the mesh is being constructed. - * - * The function returns TRUE and sets the output parametes to define - * the coodrinate range if the mesh pattern contains at least one - * patch, otherwise it returns FALSE. - **/ -cairo_bool_t -_cairo_mesh_pattern_coord_box (const cairo_mesh_pattern_t *mesh, - double *out_xmin, - double *out_ymin, - double *out_xmax, - double *out_ymax) -{ - const cairo_mesh_patch_t *patch; - unsigned int num_patches, i, j, k; - double x0, y0, x1, y1; - - assert (mesh->current_patch == NULL); - - num_patches = _cairo_array_num_elements (&mesh->patches); - - if (num_patches == 0) - return FALSE; - - patch = _cairo_array_index_const (&mesh->patches, 0); - x0 = x1 = patch->points[0][0].x; - y0 = y1 = patch->points[0][0].y; - - for (i = 0; i < num_patches; i++) { - for (j = 0; j < 4; j++) { - for (k = 0; k < 4; k++) { - x0 = MIN (x0, patch[i].points[j][k].x); - y0 = MIN (y0, patch[i].points[j][k].y); - x1 = MAX (x1, patch[i].points[j][k].x); - y1 = MAX (y1, patch[i].points[j][k].y); - } - } - } - - *out_xmin = x0; - *out_ymin = y0; - *out_xmax = x1; - *out_ymax = y1; - - return TRUE; -} - -/** - * _cairo_gradient_pattern_is_solid: - * - * Convenience function to determine whether a gradient pattern is - * a solid color within the given extents. In this case the color - * argument is initialized to the color the pattern represents. - * This functions doesn't handle completely transparent gradients, - * thus it should be called only after _cairo_pattern_is_clear has - * returned FALSE. - * - * Return value: %TRUE if the pattern is a solid color. - **/ -cairo_bool_t -_cairo_gradient_pattern_is_solid (const cairo_gradient_pattern_t *gradient, - const cairo_rectangle_int_t *extents, - cairo_color_t *color) -{ - unsigned int i; - - assert (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR || - gradient->base.type == CAIRO_PATTERN_TYPE_RADIAL); - - /* TODO: radial */ - if (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR) { - cairo_linear_pattern_t *linear = (cairo_linear_pattern_t *) gradient; - if (_linear_pattern_is_degenerate (linear)) { - _gradient_color_average (gradient, color); - return TRUE; - } - - if (gradient->base.extend == CAIRO_EXTEND_NONE) { - double t[2]; - - /* We already know that the pattern is not clear, thus if some - * part of it is clear, the whole is not solid. - */ - - if (extents == NULL) - return FALSE; - - _cairo_linear_pattern_box_to_parameter (linear, - extents->x, - extents->y, - extents->x + extents->width, - extents->y + extents->height, - t); - - if (t[0] < 0.0 || t[1] > 1.0) - return FALSE; - } - } else - return FALSE; - - for (i = 1; i < gradient->n_stops; i++) - if (! _cairo_color_stop_equal (&gradient->stops[0].color, - &gradient->stops[i].color)) - return FALSE; - - _cairo_color_init_rgba (color, - gradient->stops[0].color.red, - gradient->stops[0].color.green, - gradient->stops[0].color.blue, - gradient->stops[0].color.alpha); - - return TRUE; -} - -static cairo_bool_t -_mesh_is_clear (const cairo_mesh_pattern_t *mesh) -{ - double x1, y1, x2, y2; - cairo_bool_t is_valid; - - is_valid = _cairo_mesh_pattern_coord_box (mesh, &x1, &y1, &x2, &y2); - if (!is_valid) - return TRUE; - - if (x2 - x1 < DBL_EPSILON || y2 - y1 < DBL_EPSILON) - return TRUE; - - return FALSE; -} - -/** - * _cairo_pattern_is_opaque_solid: - * - * Convenience function to determine whether a pattern is an opaque - * (alpha==1.0) solid color pattern. This is done by testing whether - * the pattern's alpha value when converted to a byte is 255, so if a - * backend actually supported deep alpha channels this function might - * not do the right thing. - * - * Return value: %TRUE if the pattern is an opaque, solid color. - **/ -cairo_bool_t -_cairo_pattern_is_opaque_solid (const cairo_pattern_t *pattern) -{ - cairo_solid_pattern_t *solid; - - if (pattern->type != CAIRO_PATTERN_TYPE_SOLID) - return FALSE; - - solid = (cairo_solid_pattern_t *) pattern; - - return CAIRO_COLOR_IS_OPAQUE (&solid->color); -} - -static cairo_bool_t -_surface_is_opaque (const cairo_surface_pattern_t *pattern, - const cairo_rectangle_int_t *sample) -{ - cairo_rectangle_int_t extents; - - if (pattern->surface->content & CAIRO_CONTENT_ALPHA) - return FALSE; - - if (pattern->base.extend != CAIRO_EXTEND_NONE) - return TRUE; - - if (! _cairo_surface_get_extents (pattern->surface, &extents)) - return TRUE; - - if (sample == NULL) - return FALSE; - - return _cairo_rectangle_contains_rectangle (&extents, sample); -} - -static cairo_bool_t -_raster_source_is_opaque (const cairo_raster_source_pattern_t *pattern, - const cairo_rectangle_int_t *sample) -{ - if (pattern->content & CAIRO_CONTENT_ALPHA) - return FALSE; - - if (pattern->base.extend != CAIRO_EXTEND_NONE) - return TRUE; - - if (sample == NULL) - return FALSE; - - return _cairo_rectangle_contains_rectangle (&pattern->extents, sample); -} - -static cairo_bool_t -_surface_is_clear (const cairo_surface_pattern_t *pattern) -{ - cairo_rectangle_int_t extents; - - if (_cairo_surface_get_extents (pattern->surface, &extents) && - (extents.width == 0 || extents.height == 0)) - return TRUE; - - return pattern->surface->is_clear && - pattern->surface->content & CAIRO_CONTENT_ALPHA; -} - -static cairo_bool_t -_raster_source_is_clear (const cairo_raster_source_pattern_t *pattern) -{ - return pattern->extents.width == 0 || pattern->extents.height == 0; -} - -static cairo_bool_t -_gradient_is_opaque (const cairo_gradient_pattern_t *gradient, - const cairo_rectangle_int_t *sample) -{ - unsigned int i; - - assert (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR || - gradient->base.type == CAIRO_PATTERN_TYPE_RADIAL); - - if (gradient->n_stops == 0 || - (gradient->base.extend == CAIRO_EXTEND_NONE && - gradient->stops[0].offset == gradient->stops[gradient->n_stops - 1].offset)) - return FALSE; - - if (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR) { - if (gradient->base.extend == CAIRO_EXTEND_NONE) { - double t[2]; - cairo_linear_pattern_t *linear = (cairo_linear_pattern_t *) gradient; - - /* EXTEND_NONE degenerate radial gradients are clear */ - if (_linear_pattern_is_degenerate (linear)) - return FALSE; - - if (sample == NULL) - return FALSE; - - _cairo_linear_pattern_box_to_parameter (linear, - sample->x, - sample->y, - sample->x + sample->width, - sample->y + sample->height, - t); - - if (t[0] < 0.0 || t[1] > 1.0) - return FALSE; - } - } else - return FALSE; /* TODO: check actual intersection */ - - for (i = 0; i < gradient->n_stops; i++) - if (! CAIRO_COLOR_IS_OPAQUE (&gradient->stops[i].color)) - return FALSE; - - return TRUE; -} - -/** - * _cairo_pattern_is_opaque: - * - * Convenience function to determine whether a pattern is an opaque - * pattern (of any type). The same caveats that apply to - * _cairo_pattern_is_opaque_solid apply here as well. - * - * Return value: %TRUE if the pattern is a opaque. - **/ -cairo_bool_t -_cairo_pattern_is_opaque (const cairo_pattern_t *abstract_pattern, - const cairo_rectangle_int_t *sample) -{ - const cairo_pattern_union_t *pattern; - - if (abstract_pattern->has_component_alpha) - return FALSE; - - pattern = (cairo_pattern_union_t *) abstract_pattern; - switch (pattern->base.type) { - case CAIRO_PATTERN_TYPE_SOLID: - return _cairo_pattern_is_opaque_solid (abstract_pattern); - case CAIRO_PATTERN_TYPE_SURFACE: - return _surface_is_opaque (&pattern->surface, sample); - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - return _raster_source_is_opaque (&pattern->raster_source, sample); - case CAIRO_PATTERN_TYPE_LINEAR: - case CAIRO_PATTERN_TYPE_RADIAL: - return _gradient_is_opaque (&pattern->gradient.base, sample); - case CAIRO_PATTERN_TYPE_MESH: - return FALSE; - } - - ASSERT_NOT_REACHED; - return FALSE; -} - -cairo_bool_t -_cairo_pattern_is_clear (const cairo_pattern_t *abstract_pattern) -{ - const cairo_pattern_union_t *pattern; - - if (abstract_pattern->has_component_alpha) - return FALSE; - - pattern = (cairo_pattern_union_t *) abstract_pattern; - switch (abstract_pattern->type) { - case CAIRO_PATTERN_TYPE_SOLID: - return CAIRO_COLOR_IS_CLEAR (&pattern->solid.color); - case CAIRO_PATTERN_TYPE_SURFACE: - return _surface_is_clear (&pattern->surface); - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - return _raster_source_is_clear (&pattern->raster_source); - case CAIRO_PATTERN_TYPE_LINEAR: - case CAIRO_PATTERN_TYPE_RADIAL: - return _gradient_is_clear (&pattern->gradient.base, NULL); - case CAIRO_PATTERN_TYPE_MESH: - return _mesh_is_clear (&pattern->mesh); - } - - ASSERT_NOT_REACHED; - return FALSE; -} - -/* - * Will given row of back-translation matrix work with bilinear scale? - * This is true for scales larger than 1. Also it was judged acceptable - * for scales larger than .75. And if there is integer translation - * then a scale of exactly .5 works. - */ -static int -use_bilinear(double x, double y, double t) -{ - /* This is the inverse matrix! */ - double h = x*x + y*y; - if (h < 1.0 / (0.75 * 0.75)) - return TRUE; /* scale > .75 */ - if ((h > 3.99 && h < 4.01) /* scale is 1/2 */ - && !_cairo_fixed_from_double(x*y) /* parallel to an axis */ - && _cairo_fixed_is_integer (_cairo_fixed_from_double (t))) - return TRUE; - return FALSE; -} - -/** - * _cairo_pattern_analyze_filter: - * @pattern: surface pattern - * Returns: the optimized #cairo_filter_t to use with @pattern. - * - * Possibly optimize the filter to a simpler value depending on transformation - **/ -cairo_filter_t -_cairo_pattern_analyze_filter (const cairo_pattern_t *pattern) -{ - switch (pattern->filter) { - case CAIRO_FILTER_GOOD: - case CAIRO_FILTER_BEST: - case CAIRO_FILTER_BILINEAR: - case CAIRO_FILTER_FAST: - /* If source pixels map 1:1 onto destination pixels, we do - * not need to filter (and do not want to filter, since it - * will cause blurriness) - */ - if (_cairo_matrix_is_pixel_exact (&pattern->matrix)) { - return CAIRO_FILTER_NEAREST; - } else { - /* Use BILINEAR for any scale greater than .75 instead - * of GOOD. For scales of 1 and larger this is identical, - * for the smaller sizes it was judged that the artifacts - * were not worse than the artifacts from a box filer. - * BILINEAR can also be used if the scale is exactly .5 - * and the translation in that direction is an integer. - */ - if (pattern->filter == CAIRO_FILTER_GOOD && - use_bilinear (pattern->matrix.xx, pattern->matrix.xy, - pattern->matrix.x0) && - use_bilinear (pattern->matrix.yx, pattern->matrix.yy, - pattern->matrix.y0)) - return CAIRO_FILTER_BILINEAR; - } - break; - - case CAIRO_FILTER_NEAREST: - case CAIRO_FILTER_GAUSSIAN: - default: - break; - } - - return pattern->filter; -} - -/** - * _cairo_hypot: - * Returns: value similar to hypot(@x,@y) - * - * May want to replace this with Manhattan distance (abs(x)+abs(y)) if - * hypot is too slow, as there is no need for accuracy here. - **/ -static inline double -_cairo_hypot(double x, double y) -{ - return hypot(x, y); -} - -/** - * _cairo_pattern_sampled_area: - * - * Return region of @pattern that will be sampled to fill @extents, - * based on the transformation and filter. - * - * This does not include pixels that are mulitiplied by values very - * close to zero by the ends of filters. This is so that transforms - * that should be the identity or 90 degree rotations do not expand - * the source unexpectedly. - * - * XXX: We don't actually have any way of querying the backend for - * the filter radius, so we just guess base on what we know that - * backends do currently (see bug #10508) - **/ -void -_cairo_pattern_sampled_area (const cairo_pattern_t *pattern, - const cairo_rectangle_int_t *extents, - cairo_rectangle_int_t *sample) -{ - double x1, x2, y1, y2; - double padx, pady; - - /* Assume filters are interpolating, which means identity - cannot change the image */ - if (_cairo_matrix_is_identity (&pattern->matrix)) { - *sample = *extents; - return; - } - - /* Transform the centers of the corner pixels */ - x1 = extents->x + 0.5; - y1 = extents->y + 0.5; - x2 = x1 + (extents->width - 1); - y2 = y1 + (extents->height - 1); - _cairo_matrix_transform_bounding_box (&pattern->matrix, - &x1, &y1, &x2, &y2, - NULL); - - /* How far away from center will it actually sample? - * This is the distance from a transformed pixel center to the - * furthest sample of reasonable size. - */ - switch (pattern->filter) { - case CAIRO_FILTER_NEAREST: - case CAIRO_FILTER_FAST: - /* Correct value is zero, but when the sample is on an integer - * it is unknown if the backend will sample the pixel to the - * left or right. This value makes it include both possible pixels. - */ - padx = pady = 0.004; - break; - case CAIRO_FILTER_BILINEAR: - case CAIRO_FILTER_GAUSSIAN: - default: - /* Correct value is .5 */ - padx = pady = 0.495; - break; - case CAIRO_FILTER_GOOD: - /* Correct value is max(width,1)*.5 */ - padx = _cairo_hypot (pattern->matrix.xx, pattern->matrix.xy); - if (padx <= 1.0) padx = 0.495; - else if (padx >= 16.0) padx = 7.92; - else padx *= 0.495; - pady = _cairo_hypot (pattern->matrix.yx, pattern->matrix.yy); - if (pady <= 1.0) pady = 0.495; - else if (pady >= 16.0) pady = 7.92; - else pady *= 0.495; - break; - case CAIRO_FILTER_BEST: - /* Correct value is width*2 */ - padx = _cairo_hypot (pattern->matrix.xx, pattern->matrix.xy) * 1.98; - if (padx > 7.92) padx = 7.92; - pady = _cairo_hypot (pattern->matrix.yx, pattern->matrix.yy) * 1.98; - if (pady > 7.92) pady = 7.92; - break; - } - - /* round furthest samples to edge of pixels */ - x1 = floor (x1 - padx); - if (x1 < CAIRO_RECT_INT_MIN) x1 = CAIRO_RECT_INT_MIN; - sample->x = x1; - - y1 = floor (y1 - pady); - if (y1 < CAIRO_RECT_INT_MIN) y1 = CAIRO_RECT_INT_MIN; - sample->y = y1; - - x2 = floor (x2 + padx) + 1.0; - if (x2 > CAIRO_RECT_INT_MAX) x2 = CAIRO_RECT_INT_MAX; - sample->width = x2 - x1; - - y2 = floor (y2 + pady) + 1.0; - if (y2 > CAIRO_RECT_INT_MAX) y2 = CAIRO_RECT_INT_MAX; - sample->height = y2 - y1; -} - -/** - * _cairo_pattern_get_extents: - * - * Return the "target-space" extents of @pattern in @extents. - * - * For unbounded patterns, the @extents will be initialized with - * "infinite" extents, (minimum and maximum fixed-point values). - * - * XXX: Currently, bounded gradient patterns will also return - * "infinite" extents, though it would be possible to optimize these - * with a little more work. - **/ -void -_cairo_pattern_get_extents (const cairo_pattern_t *pattern, - cairo_rectangle_int_t *extents) -{ - double x1, y1, x2, y2; - int ix1, ix2, iy1, iy2; - cairo_bool_t round_x = FALSE; - cairo_bool_t round_y = FALSE; - - switch (pattern->type) { - case CAIRO_PATTERN_TYPE_SOLID: - goto UNBOUNDED; - - case CAIRO_PATTERN_TYPE_SURFACE: - { - cairo_rectangle_int_t surface_extents; - const cairo_surface_pattern_t *surface_pattern = - (const cairo_surface_pattern_t *) pattern; - cairo_surface_t *surface = surface_pattern->surface; - - if (! _cairo_surface_get_extents (surface, &surface_extents)) - goto UNBOUNDED; - - if (surface_extents.width == 0 || surface_extents.height == 0) - goto EMPTY; - - if (pattern->extend != CAIRO_EXTEND_NONE) - goto UNBOUNDED; - - x1 = surface_extents.x; - y1 = surface_extents.y; - x2 = surface_extents.x + (int) surface_extents.width; - y2 = surface_extents.y + (int) surface_extents.height; - - goto HANDLE_FILTER; - } - break; - - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - { - const cairo_raster_source_pattern_t *raster = - (const cairo_raster_source_pattern_t *) pattern; - - if (raster->extents.width == 0 || raster->extents.height == 0) - goto EMPTY; - - if (pattern->extend != CAIRO_EXTEND_NONE) - goto UNBOUNDED; - - x1 = raster->extents.x; - y1 = raster->extents.y; - x2 = raster->extents.x + (int) raster->extents.width; - y2 = raster->extents.y + (int) raster->extents.height; - } - HANDLE_FILTER: - switch (pattern->filter) { - case CAIRO_FILTER_NEAREST: - case CAIRO_FILTER_FAST: - round_x = round_y = TRUE; - /* We don't know which way .5 will go, so fudge it slightly. */ - x1 -= 0.004; - y1 -= 0.004; - x2 += 0.004; - y2 += 0.004; - break; - case CAIRO_FILTER_BEST: - /* Assume best filter will produce nice antialiased edges */ - break; - case CAIRO_FILTER_BILINEAR: - case CAIRO_FILTER_GAUSSIAN: - case CAIRO_FILTER_GOOD: - default: - /* These filters can blur the edge out 1/2 pixel when scaling up */ - if (_cairo_hypot (pattern->matrix.xx, pattern->matrix.yx) < 1.0) { - x1 -= 0.5; - x2 += 0.5; - round_x = TRUE; - } - if (_cairo_hypot (pattern->matrix.xy, pattern->matrix.yy) < 1.0) { - y1 -= 0.5; - y2 += 0.5; - round_y = TRUE; - } - break; - } - break; - - case CAIRO_PATTERN_TYPE_RADIAL: - { - const cairo_radial_pattern_t *radial = - (const cairo_radial_pattern_t *) pattern; - double cx1, cy1; - double cx2, cy2; - double r1, r2; - - if (_radial_pattern_is_degenerate (radial)) { - /* cairo-gstate should have optimised degenerate - * patterns to solid clear patterns, so we can ignore - * them here. */ - goto EMPTY; - } - - /* TODO: in some cases (focus outside/on the circle) it is - * half-bounded. */ - if (pattern->extend != CAIRO_EXTEND_NONE) - goto UNBOUNDED; - - cx1 = radial->cd1.center.x; - cy1 = radial->cd1.center.y; - r1 = radial->cd1.radius; - - cx2 = radial->cd2.center.x; - cy2 = radial->cd2.center.y; - r2 = radial->cd2.radius; - - x1 = MIN (cx1 - r1, cx2 - r2); - y1 = MIN (cy1 - r1, cy2 - r2); - x2 = MAX (cx1 + r1, cx2 + r2); - y2 = MAX (cy1 + r1, cy2 + r2); - } - break; - - case CAIRO_PATTERN_TYPE_LINEAR: - { - const cairo_linear_pattern_t *linear = - (const cairo_linear_pattern_t *) pattern; - - if (pattern->extend != CAIRO_EXTEND_NONE) - goto UNBOUNDED; - - if (_linear_pattern_is_degenerate (linear)) { - /* cairo-gstate should have optimised degenerate - * patterns to solid ones, so we can again ignore - * them here. */ - goto EMPTY; - } - - /* TODO: to get tight extents, use the matrix to transform - * the pattern instead of transforming the extents later. */ - if (pattern->matrix.xy != 0. || pattern->matrix.yx != 0.) - goto UNBOUNDED; - - if (linear->pd1.x == linear->pd2.x) { - x1 = -HUGE_VAL; - x2 = HUGE_VAL; - y1 = MIN (linear->pd1.y, linear->pd2.y); - y2 = MAX (linear->pd1.y, linear->pd2.y); - } else if (linear->pd1.y == linear->pd2.y) { - x1 = MIN (linear->pd1.x, linear->pd2.x); - x2 = MAX (linear->pd1.x, linear->pd2.x); - y1 = -HUGE_VAL; - y2 = HUGE_VAL; - } else { - goto UNBOUNDED; - } - - /* The current linear renderer just point-samples in the middle - of the pixels, similar to the NEAREST filter: */ - round_x = round_y = TRUE; - } - break; - - case CAIRO_PATTERN_TYPE_MESH: - { - const cairo_mesh_pattern_t *mesh = - (const cairo_mesh_pattern_t *) pattern; - if (! _cairo_mesh_pattern_coord_box (mesh, &x1, &y1, &x2, &y2)) - goto EMPTY; - } - break; - - default: - ASSERT_NOT_REACHED; - } - - if (_cairo_matrix_is_translation (&pattern->matrix)) { - x1 -= pattern->matrix.x0; x2 -= pattern->matrix.x0; - y1 -= pattern->matrix.y0; y2 -= pattern->matrix.y0; - } else { - cairo_matrix_t imatrix; - cairo_status_t status; - - imatrix = pattern->matrix; - status = cairo_matrix_invert (&imatrix); - /* cairo_pattern_set_matrix ensures the matrix is invertible */ - assert (status == CAIRO_STATUS_SUCCESS); - - _cairo_matrix_transform_bounding_box (&imatrix, - &x1, &y1, &x2, &y2, - NULL); - } - - if (!round_x) { - x1 -= 0.5; - x2 += 0.5; - } - if (x1 < CAIRO_RECT_INT_MIN) - ix1 = CAIRO_RECT_INT_MIN; - else - ix1 = _cairo_lround (x1); - if (x2 > CAIRO_RECT_INT_MAX) - ix2 = CAIRO_RECT_INT_MAX; - else - ix2 = _cairo_lround (x2); - extents->x = ix1; extents->width = ix2 - ix1; - - if (!round_y) { - y1 -= 0.5; - y2 += 0.5; - } - if (y1 < CAIRO_RECT_INT_MIN) - iy1 = CAIRO_RECT_INT_MIN; - else - iy1 = _cairo_lround (y1); - if (y2 > CAIRO_RECT_INT_MAX) - iy2 = CAIRO_RECT_INT_MAX; - else - iy2 = _cairo_lround (y2); - extents->y = iy1; extents->height = iy2 - iy1; - - return; - - UNBOUNDED: - /* unbounded patterns -> 'infinite' extents */ - _cairo_unbounded_rectangle_init (extents); - return; - - EMPTY: - extents->x = extents->y = 0; - extents->width = extents->height = 0; - return; -} - -/** - * _cairo_pattern_get_ink_extents: - * - * Return the "target-space" inked extents of @pattern in @extents. - **/ -cairo_int_status_t -_cairo_pattern_get_ink_extents (const cairo_pattern_t *pattern, - cairo_rectangle_int_t *extents) -{ - if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE && - pattern->extend == CAIRO_EXTEND_NONE) - { - const cairo_surface_pattern_t *surface_pattern = - (const cairo_surface_pattern_t *) pattern; - cairo_surface_t *surface = surface_pattern->surface; - - surface = _cairo_surface_get_source (surface, NULL); - if (_cairo_surface_is_recording (surface)) { - cairo_matrix_t imatrix; - cairo_box_t box; - cairo_status_t status; - - imatrix = pattern->matrix; - status = cairo_matrix_invert (&imatrix); - /* cairo_pattern_set_matrix ensures the matrix is invertible */ - assert (status == CAIRO_STATUS_SUCCESS); - - status = _cairo_recording_surface_get_ink_bbox ((cairo_recording_surface_t *)surface, - &box, &imatrix); - if (unlikely (status)) - return status; - - _cairo_box_round_to_rectangle (&box, extents); - return CAIRO_STATUS_SUCCESS; - } - } - - _cairo_pattern_get_extents (pattern, extents); - return CAIRO_STATUS_SUCCESS; -} - -static unsigned long -_cairo_solid_pattern_hash (unsigned long hash, - const cairo_solid_pattern_t *solid) -{ - hash = _cairo_hash_bytes (hash, &solid->color, sizeof (solid->color)); - - return hash; -} - -static unsigned long -_cairo_gradient_color_stops_hash (unsigned long hash, - const cairo_gradient_pattern_t *gradient) -{ - unsigned int n; - - hash = _cairo_hash_bytes (hash, - &gradient->n_stops, - sizeof (gradient->n_stops)); - - for (n = 0; n < gradient->n_stops; n++) { - hash = _cairo_hash_bytes (hash, - &gradient->stops[n].offset, - sizeof (double)); - hash = _cairo_hash_bytes (hash, - &gradient->stops[n].color, - sizeof (cairo_color_stop_t)); - } - - return hash; -} - -unsigned long -_cairo_linear_pattern_hash (unsigned long hash, - const cairo_linear_pattern_t *linear) -{ - hash = _cairo_hash_bytes (hash, &linear->pd1, sizeof (linear->pd1)); - hash = _cairo_hash_bytes (hash, &linear->pd2, sizeof (linear->pd2)); - - return _cairo_gradient_color_stops_hash (hash, &linear->base); -} - -unsigned long -_cairo_radial_pattern_hash (unsigned long hash, - const cairo_radial_pattern_t *radial) -{ - hash = _cairo_hash_bytes (hash, &radial->cd1.center, sizeof (radial->cd1.center)); - hash = _cairo_hash_bytes (hash, &radial->cd1.radius, sizeof (radial->cd1.radius)); - hash = _cairo_hash_bytes (hash, &radial->cd2.center, sizeof (radial->cd2.center)); - hash = _cairo_hash_bytes (hash, &radial->cd2.radius, sizeof (radial->cd2.radius)); - - return _cairo_gradient_color_stops_hash (hash, &radial->base); -} - -static unsigned long -_cairo_mesh_pattern_hash (unsigned long hash, const cairo_mesh_pattern_t *mesh) -{ - const cairo_mesh_patch_t *patch = _cairo_array_index_const (&mesh->patches, 0); - unsigned int i, n = _cairo_array_num_elements (&mesh->patches); - - for (i = 0; i < n; i++) - hash = _cairo_hash_bytes (hash, patch + i, sizeof (cairo_mesh_patch_t)); - - return hash; -} - -static unsigned long -_cairo_surface_pattern_hash (unsigned long hash, - const cairo_surface_pattern_t *surface) -{ - hash ^= surface->surface->unique_id; - - return hash; -} - -static unsigned long -_cairo_raster_source_pattern_hash (unsigned long hash, - const cairo_raster_source_pattern_t *raster) -{ - hash ^= (uintptr_t)raster->user_data; - - return hash; -} - -unsigned long -_cairo_pattern_hash (const cairo_pattern_t *pattern) -{ - unsigned long hash = _CAIRO_HASH_INIT_VALUE; - - if (pattern->status) - return 0; - - hash = _cairo_hash_bytes (hash, &pattern->type, sizeof (pattern->type)); - if (pattern->type != CAIRO_PATTERN_TYPE_SOLID) { - hash = _cairo_hash_bytes (hash, - &pattern->matrix, sizeof (pattern->matrix)); - hash = _cairo_hash_bytes (hash, - &pattern->filter, sizeof (pattern->filter)); - hash = _cairo_hash_bytes (hash, - &pattern->extend, sizeof (pattern->extend)); - hash = _cairo_hash_bytes (hash, - &pattern->has_component_alpha, - sizeof (pattern->has_component_alpha)); - } - - switch (pattern->type) { - case CAIRO_PATTERN_TYPE_SOLID: - return _cairo_solid_pattern_hash (hash, (cairo_solid_pattern_t *) pattern); - case CAIRO_PATTERN_TYPE_LINEAR: - return _cairo_linear_pattern_hash (hash, (cairo_linear_pattern_t *) pattern); - case CAIRO_PATTERN_TYPE_RADIAL: - return _cairo_radial_pattern_hash (hash, (cairo_radial_pattern_t *) pattern); - case CAIRO_PATTERN_TYPE_MESH: - return _cairo_mesh_pattern_hash (hash, (cairo_mesh_pattern_t *) pattern); - case CAIRO_PATTERN_TYPE_SURFACE: - return _cairo_surface_pattern_hash (hash, (cairo_surface_pattern_t *) pattern); - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - return _cairo_raster_source_pattern_hash (hash, (cairo_raster_source_pattern_t *) pattern); - default: - ASSERT_NOT_REACHED; - return FALSE; - } -} - -static cairo_bool_t -_cairo_solid_pattern_equal (const cairo_solid_pattern_t *a, - const cairo_solid_pattern_t *b) -{ - return _cairo_color_equal (&a->color, &b->color); -} - -static cairo_bool_t -_cairo_gradient_color_stops_equal (const cairo_gradient_pattern_t *a, - const cairo_gradient_pattern_t *b) -{ - unsigned int n; - - if (a->n_stops != b->n_stops) - return FALSE; - - for (n = 0; n < a->n_stops; n++) { - if (a->stops[n].offset != b->stops[n].offset) - return FALSE; - if (! _cairo_color_stop_equal (&a->stops[n].color, &b->stops[n].color)) - return FALSE; - } - - return TRUE; -} - -cairo_bool_t -_cairo_linear_pattern_equal (const cairo_linear_pattern_t *a, - const cairo_linear_pattern_t *b) -{ - if (a->pd1.x != b->pd1.x) - return FALSE; - - if (a->pd1.y != b->pd1.y) - return FALSE; - - if (a->pd2.x != b->pd2.x) - return FALSE; - - if (a->pd2.y != b->pd2.y) - return FALSE; - - return _cairo_gradient_color_stops_equal (&a->base, &b->base); -} - -cairo_bool_t -_cairo_radial_pattern_equal (const cairo_radial_pattern_t *a, - const cairo_radial_pattern_t *b) -{ - if (a->cd1.center.x != b->cd1.center.x) - return FALSE; - - if (a->cd1.center.y != b->cd1.center.y) - return FALSE; - - if (a->cd1.radius != b->cd1.radius) - return FALSE; - - if (a->cd2.center.x != b->cd2.center.x) - return FALSE; - - if (a->cd2.center.y != b->cd2.center.y) - return FALSE; - - if (a->cd2.radius != b->cd2.radius) - return FALSE; - - return _cairo_gradient_color_stops_equal (&a->base, &b->base); -} - -static cairo_bool_t -_cairo_mesh_pattern_equal (const cairo_mesh_pattern_t *a, - const cairo_mesh_pattern_t *b) -{ - const cairo_mesh_patch_t *patch_a, *patch_b; - unsigned int i, num_patches_a, num_patches_b; - - num_patches_a = _cairo_array_num_elements (&a->patches); - num_patches_b = _cairo_array_num_elements (&b->patches); - - if (num_patches_a != num_patches_b) - return FALSE; - - for (i = 0; i < num_patches_a; i++) { - patch_a = _cairo_array_index_const (&a->patches, i); - patch_b = _cairo_array_index_const (&b->patches, i); - if (memcmp (patch_a, patch_b, sizeof(cairo_mesh_patch_t)) != 0) - return FALSE; - } - - return TRUE; -} - -static cairo_bool_t -_cairo_surface_pattern_equal (const cairo_surface_pattern_t *a, - const cairo_surface_pattern_t *b) -{ - return a->surface->unique_id == b->surface->unique_id; -} - -static cairo_bool_t -_cairo_raster_source_pattern_equal (const cairo_raster_source_pattern_t *a, - const cairo_raster_source_pattern_t *b) -{ - return a->user_data == b->user_data; -} - -cairo_bool_t -_cairo_pattern_equal (const cairo_pattern_t *a, const cairo_pattern_t *b) -{ - if (a->status || b->status) - return FALSE; - - if (a == b) - return TRUE; - - if (a->type != b->type) - return FALSE; - - if (a->has_component_alpha != b->has_component_alpha) - return FALSE; - - if (a->type != CAIRO_PATTERN_TYPE_SOLID) { - if (memcmp (&a->matrix, &b->matrix, sizeof (cairo_matrix_t))) - return FALSE; - - if (a->filter != b->filter) - return FALSE; - - if (a->extend != b->extend) - return FALSE; - } - - switch (a->type) { - case CAIRO_PATTERN_TYPE_SOLID: - return _cairo_solid_pattern_equal ((cairo_solid_pattern_t *) a, - (cairo_solid_pattern_t *) b); - case CAIRO_PATTERN_TYPE_LINEAR: - return _cairo_linear_pattern_equal ((cairo_linear_pattern_t *) a, - (cairo_linear_pattern_t *) b); - case CAIRO_PATTERN_TYPE_RADIAL: - return _cairo_radial_pattern_equal ((cairo_radial_pattern_t *) a, - (cairo_radial_pattern_t *) b); - case CAIRO_PATTERN_TYPE_MESH: - return _cairo_mesh_pattern_equal ((cairo_mesh_pattern_t *) a, - (cairo_mesh_pattern_t *) b); - case CAIRO_PATTERN_TYPE_SURFACE: - return _cairo_surface_pattern_equal ((cairo_surface_pattern_t *) a, - (cairo_surface_pattern_t *) b); - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - return _cairo_raster_source_pattern_equal ((cairo_raster_source_pattern_t *) a, - (cairo_raster_source_pattern_t *) b); - default: - ASSERT_NOT_REACHED; - return FALSE; - } -} - -/** - * cairo_pattern_get_rgba: - * @pattern: a #cairo_pattern_t - * @red: return value for red component of color, or %NULL - * @green: return value for green component of color, or %NULL - * @blue: return value for blue component of color, or %NULL - * @alpha: return value for alpha component of color, or %NULL - * - * Gets the solid color for a solid color pattern. - * - * Return value: %CAIRO_STATUS_SUCCESS, or - * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH if the pattern is not a solid - * color pattern. - * - * Since: 1.4 - **/ -cairo_status_t -cairo_pattern_get_rgba (cairo_pattern_t *pattern, - double *red, double *green, - double *blue, double *alpha) -{ - cairo_solid_pattern_t *solid = (cairo_solid_pattern_t*) pattern; - double r0, g0, b0, a0; - - if (pattern->status) - return pattern->status; - - if (pattern->type != CAIRO_PATTERN_TYPE_SOLID) - return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH); - - _cairo_color_get_rgba (&solid->color, &r0, &g0, &b0, &a0); - - if (red) - *red = r0; - if (green) - *green = g0; - if (blue) - *blue = b0; - if (alpha) - *alpha = a0; - - return CAIRO_STATUS_SUCCESS; -} - -/** - * cairo_pattern_get_surface: - * @pattern: a #cairo_pattern_t - * @surface: return value for surface of pattern, or %NULL - * - * Gets the surface of a surface pattern. The reference returned in - * @surface is owned by the pattern; the caller should call - * cairo_surface_reference() if the surface is to be retained. - * - * Return value: %CAIRO_STATUS_SUCCESS, or - * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH if the pattern is not a surface - * pattern. - * - * Since: 1.4 - **/ -cairo_status_t -cairo_pattern_get_surface (cairo_pattern_t *pattern, - cairo_surface_t **surface) -{ - cairo_surface_pattern_t *spat = (cairo_surface_pattern_t*) pattern; - - if (pattern->status) - return pattern->status; - - if (pattern->type != CAIRO_PATTERN_TYPE_SURFACE) - return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH); - - if (surface) - *surface = spat->surface; - - return CAIRO_STATUS_SUCCESS; -} - -/** - * cairo_pattern_get_color_stop_rgba: - * @pattern: a #cairo_pattern_t - * @index: index of the stop to return data for - * @offset: return value for the offset of the stop, or %NULL - * @red: return value for red component of color, or %NULL - * @green: return value for green component of color, or %NULL - * @blue: return value for blue component of color, or %NULL - * @alpha: return value for alpha component of color, or %NULL - * - * Gets the color and offset information at the given @index for a - * gradient pattern. Values of @index range from 0 to n-1 - * where n is the number returned - * by cairo_pattern_get_color_stop_count(). - * - * Return value: %CAIRO_STATUS_SUCCESS, or %CAIRO_STATUS_INVALID_INDEX - * if @index is not valid for the given pattern. If the pattern is - * not a gradient pattern, %CAIRO_STATUS_PATTERN_TYPE_MISMATCH is - * returned. - * - * Since: 1.4 - **/ -cairo_status_t -cairo_pattern_get_color_stop_rgba (cairo_pattern_t *pattern, - int index, double *offset, - double *red, double *green, - double *blue, double *alpha) -{ - cairo_gradient_pattern_t *gradient = (cairo_gradient_pattern_t*) pattern; - - if (pattern->status) - return pattern->status; - - if (pattern->type != CAIRO_PATTERN_TYPE_LINEAR && - pattern->type != CAIRO_PATTERN_TYPE_RADIAL) - return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH); - - if (index < 0 || (unsigned int) index >= gradient->n_stops) - return _cairo_error (CAIRO_STATUS_INVALID_INDEX); - - if (offset) - *offset = gradient->stops[index].offset; - if (red) - *red = gradient->stops[index].color.red; - if (green) - *green = gradient->stops[index].color.green; - if (blue) - *blue = gradient->stops[index].color.blue; - if (alpha) - *alpha = gradient->stops[index].color.alpha; - - return CAIRO_STATUS_SUCCESS; -} - -/** - * cairo_pattern_get_color_stop_count: - * @pattern: a #cairo_pattern_t - * @count: return value for the number of color stops, or %NULL - * - * Gets the number of color stops specified in the given gradient - * pattern. - * - * Return value: %CAIRO_STATUS_SUCCESS, or - * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH if @pattern is not a gradient - * pattern. - * - * Since: 1.4 - **/ -cairo_status_t -cairo_pattern_get_color_stop_count (cairo_pattern_t *pattern, - int *count) -{ - cairo_gradient_pattern_t *gradient = (cairo_gradient_pattern_t*) pattern; - - if (pattern->status) - return pattern->status; - - if (pattern->type != CAIRO_PATTERN_TYPE_LINEAR && - pattern->type != CAIRO_PATTERN_TYPE_RADIAL) - return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH); - - if (count) - *count = gradient->n_stops; - - return CAIRO_STATUS_SUCCESS; -} - -/** - * cairo_pattern_get_linear_points: - * @pattern: a #cairo_pattern_t - * @x0: return value for the x coordinate of the first point, or %NULL - * @y0: return value for the y coordinate of the first point, or %NULL - * @x1: return value for the x coordinate of the second point, or %NULL - * @y1: return value for the y coordinate of the second point, or %NULL - * - * Gets the gradient endpoints for a linear gradient. - * - * Return value: %CAIRO_STATUS_SUCCESS, or - * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH if @pattern is not a linear - * gradient pattern. - * - * Since: 1.4 - **/ -cairo_status_t -cairo_pattern_get_linear_points (cairo_pattern_t *pattern, - double *x0, double *y0, - double *x1, double *y1) -{ - cairo_linear_pattern_t *linear = (cairo_linear_pattern_t*) pattern; - - if (pattern->status) - return pattern->status; - - if (pattern->type != CAIRO_PATTERN_TYPE_LINEAR) - return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH); - - if (x0) - *x0 = linear->pd1.x; - if (y0) - *y0 = linear->pd1.y; - if (x1) - *x1 = linear->pd2.x; - if (y1) - *y1 = linear->pd2.y; - - return CAIRO_STATUS_SUCCESS; -} - -/** - * cairo_pattern_get_radial_circles: - * @pattern: a #cairo_pattern_t - * @x0: return value for the x coordinate of the center of the first circle, or %NULL - * @y0: return value for the y coordinate of the center of the first circle, or %NULL - * @r0: return value for the radius of the first circle, or %NULL - * @x1: return value for the x coordinate of the center of the second circle, or %NULL - * @y1: return value for the y coordinate of the center of the second circle, or %NULL - * @r1: return value for the radius of the second circle, or %NULL - * - * Gets the gradient endpoint circles for a radial gradient, each - * specified as a center coordinate and a radius. - * - * Return value: %CAIRO_STATUS_SUCCESS, or - * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH if @pattern is not a radial - * gradient pattern. - * - * Since: 1.4 - **/ -cairo_status_t -cairo_pattern_get_radial_circles (cairo_pattern_t *pattern, - double *x0, double *y0, double *r0, - double *x1, double *y1, double *r1) -{ - cairo_radial_pattern_t *radial = (cairo_radial_pattern_t*) pattern; - - if (pattern->status) - return pattern->status; - - if (pattern->type != CAIRO_PATTERN_TYPE_RADIAL) - return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH); - - if (x0) - *x0 = radial->cd1.center.x; - if (y0) - *y0 = radial->cd1.center.y; - if (r0) - *r0 = radial->cd1.radius; - if (x1) - *x1 = radial->cd2.center.x; - if (y1) - *y1 = radial->cd2.center.y; - if (r1) - *r1 = radial->cd2.radius; - - return CAIRO_STATUS_SUCCESS; -} - -/** - * cairo_mesh_pattern_get_patch_count: - * @pattern: a #cairo_pattern_t - * @count: return value for the number patches, or %NULL - * - * Gets the number of patches specified in the given mesh pattern. - * - * The number only includes patches which have been finished by - * calling cairo_mesh_pattern_end_patch(). For example it will be 0 - * during the definition of the first patch. - * - * Return value: %CAIRO_STATUS_SUCCESS, or - * %CAIRO_STATUS_PATTERN_TYPE_MISMATCH if @pattern is not a mesh - * pattern. - * - * Since: 1.12 - **/ -cairo_status_t -cairo_mesh_pattern_get_patch_count (cairo_pattern_t *pattern, - unsigned int *count) -{ - cairo_mesh_pattern_t *mesh = (cairo_mesh_pattern_t *) pattern; - - if (unlikely (pattern->status)) - return pattern->status; - - if (unlikely (pattern->type != CAIRO_PATTERN_TYPE_MESH)) - return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH); - - if (count) { - *count = _cairo_array_num_elements (&mesh->patches); - if (mesh->current_patch) - *count -= 1; - } - - return CAIRO_STATUS_SUCCESS; -} -slim_hidden_def (cairo_mesh_pattern_get_patch_count); - -/** - * cairo_mesh_pattern_get_path: - * @pattern: a #cairo_pattern_t - * @patch_num: the patch number to return data for - * - * Gets path defining the patch @patch_num for a mesh - * pattern. - * - * @patch_num can range from 0 to n-1 where n is the number returned by - * cairo_mesh_pattern_get_patch_count(). - * - * Return value: the path defining the patch, or a path with status - * %CAIRO_STATUS_INVALID_INDEX if @patch_num or @point_num is not - * valid for @pattern. If @pattern is not a mesh pattern, a path with - * status %CAIRO_STATUS_PATTERN_TYPE_MISMATCH is returned. - * - * Since: 1.12 - **/ -cairo_path_t * -cairo_mesh_pattern_get_path (cairo_pattern_t *pattern, - unsigned int patch_num) -{ - cairo_mesh_pattern_t *mesh = (cairo_mesh_pattern_t *) pattern; - const cairo_mesh_patch_t *patch; - cairo_path_t *path; - cairo_path_data_t *data; - unsigned int patch_count; - int l, current_point; - - if (unlikely (pattern->status)) - return _cairo_path_create_in_error (pattern->status); - - if (unlikely (pattern->type != CAIRO_PATTERN_TYPE_MESH)) - return _cairo_path_create_in_error (_cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH)); - - patch_count = _cairo_array_num_elements (&mesh->patches); - if (mesh->current_patch) - patch_count--; - - if (unlikely (patch_num >= patch_count)) - return _cairo_path_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_INDEX)); - - patch = _cairo_array_index_const (&mesh->patches, patch_num); - - path = malloc (sizeof (cairo_path_t)); - if (path == NULL) - return _cairo_path_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - path->num_data = 18; - path->data = _cairo_malloc_ab (path->num_data, - sizeof (cairo_path_data_t)); - if (path->data == NULL) { - free (path); - return _cairo_path_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - data = path->data; - data[0].header.type = CAIRO_PATH_MOVE_TO; - data[0].header.length = 2; - data[1].point.x = patch->points[0][0].x; - data[1].point.y = patch->points[0][0].y; - data += data[0].header.length; - - current_point = 0; - - for (l = 0; l < 4; l++) { - int i, j, k; - - data[0].header.type = CAIRO_PATH_CURVE_TO; - data[0].header.length = 4; - - for (k = 1; k < 4; k++) { - current_point = (current_point + 1) % 12; - i = mesh_path_point_i[current_point]; - j = mesh_path_point_j[current_point]; - data[k].point.x = patch->points[i][j].x; - data[k].point.y = patch->points[i][j].y; - } - - data += data[0].header.length; - } - - path->status = CAIRO_STATUS_SUCCESS; - - return path; -} -slim_hidden_def (cairo_mesh_pattern_get_path); - -/** - * cairo_mesh_pattern_get_corner_color_rgba: - * @pattern: a #cairo_pattern_t - * @patch_num: the patch number to return data for - * @corner_num: the corner number to return data for - * @red: return value for red component of color, or %NULL - * @green: return value for green component of color, or %NULL - * @blue: return value for blue component of color, or %NULL - * @alpha: return value for alpha component of color, or %NULL - * - * Gets the color information in corner @corner_num of patch - * @patch_num for a mesh pattern. - * - * @patch_num can range from 0 to n-1 where n is the number returned by - * cairo_mesh_pattern_get_patch_count(). - * - * Valid values for @corner_num are from 0 to 3 and identify the - * corners as explained in cairo_pattern_create_mesh(). - * - * Return value: %CAIRO_STATUS_SUCCESS, or %CAIRO_STATUS_INVALID_INDEX - * if @patch_num or @corner_num is not valid for @pattern. If - * @pattern is not a mesh pattern, %CAIRO_STATUS_PATTERN_TYPE_MISMATCH - * is returned. - * - * Since: 1.12 - **/ -cairo_status_t -cairo_mesh_pattern_get_corner_color_rgba (cairo_pattern_t *pattern, - unsigned int patch_num, - unsigned int corner_num, - double *red, double *green, - double *blue, double *alpha) -{ - cairo_mesh_pattern_t *mesh = (cairo_mesh_pattern_t *) pattern; - unsigned int patch_count; - const cairo_mesh_patch_t *patch; - - if (unlikely (pattern->status)) - return pattern->status; - - if (unlikely (pattern->type != CAIRO_PATTERN_TYPE_MESH)) - return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH); - - if (unlikely (corner_num > 3)) - return _cairo_error (CAIRO_STATUS_INVALID_INDEX); - - patch_count = _cairo_array_num_elements (&mesh->patches); - if (mesh->current_patch) - patch_count--; - - if (unlikely (patch_num >= patch_count)) - return _cairo_error (CAIRO_STATUS_INVALID_INDEX); - - patch = _cairo_array_index_const (&mesh->patches, patch_num); - - if (red) - *red = patch->colors[corner_num].red; - if (green) - *green = patch->colors[corner_num].green; - if (blue) - *blue = patch->colors[corner_num].blue; - if (alpha) - *alpha = patch->colors[corner_num].alpha; - - return CAIRO_STATUS_SUCCESS; -} -slim_hidden_def (cairo_mesh_pattern_get_corner_color_rgba); - -/** - * cairo_mesh_pattern_get_control_point: - * @pattern: a #cairo_pattern_t - * @patch_num: the patch number to return data for - * @point_num: the control point number to return data for - * @x: return value for the x coordinate of the control point, or %NULL - * @y: return value for the y coordinate of the control point, or %NULL - * - * Gets the control point @point_num of patch @patch_num for a mesh - * pattern. - * - * @patch_num can range from 0 to n-1 where n is the number returned by - * cairo_mesh_pattern_get_patch_count(). - * - * Valid values for @point_num are from 0 to 3 and identify the - * control points as explained in cairo_pattern_create_mesh(). - * - * Return value: %CAIRO_STATUS_SUCCESS, or %CAIRO_STATUS_INVALID_INDEX - * if @patch_num or @point_num is not valid for @pattern. If @pattern - * is not a mesh pattern, %CAIRO_STATUS_PATTERN_TYPE_MISMATCH is - * returned. - * - * Since: 1.12 - **/ -cairo_status_t -cairo_mesh_pattern_get_control_point (cairo_pattern_t *pattern, - unsigned int patch_num, - unsigned int point_num, - double *x, double *y) -{ - cairo_mesh_pattern_t *mesh = (cairo_mesh_pattern_t *) pattern; - const cairo_mesh_patch_t *patch; - unsigned int patch_count; - int i, j; - - if (pattern->status) - return pattern->status; - - if (pattern->type != CAIRO_PATTERN_TYPE_MESH) - return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH); - - if (point_num > 3) - return _cairo_error (CAIRO_STATUS_INVALID_INDEX); - - patch_count = _cairo_array_num_elements (&mesh->patches); - if (mesh->current_patch) - patch_count--; - - if (unlikely (patch_num >= patch_count)) - return _cairo_error (CAIRO_STATUS_INVALID_INDEX); - - patch = _cairo_array_index_const (&mesh->patches, patch_num); - - i = mesh_control_point_i[point_num]; - j = mesh_control_point_j[point_num]; - - if (x) - *x = patch->points[i][j].x; - if (y) - *y = patch->points[i][j].y; - - return CAIRO_STATUS_SUCCESS; -} -slim_hidden_def (cairo_mesh_pattern_get_control_point); - -void -_cairo_pattern_reset_static_data (void) -{ - int i; - - for (i = 0; i < ARRAY_LENGTH (freed_pattern_pool); i++) - _freed_pool_reset (&freed_pattern_pool[i]); -} - -static void -_cairo_debug_print_surface_pattern (FILE *file, - const cairo_surface_pattern_t *pattern) -{ - printf (" surface type: %d\n", pattern->surface->type); -} - -static void -_cairo_debug_print_raster_source_pattern (FILE *file, - const cairo_raster_source_pattern_t *raster) -{ - fprintf (file, " content: %x, size %dx%d\n", raster->content, raster->extents.width, raster->extents.height); -} - -static void -_cairo_debug_print_linear_pattern (FILE *file, - const cairo_linear_pattern_t *pattern) -{ -} - -static void -_cairo_debug_print_radial_pattern (FILE *file, - const cairo_radial_pattern_t *pattern) -{ -} - -static void -_cairo_debug_print_mesh_pattern (FILE *file, - const cairo_mesh_pattern_t *pattern) -{ -} - -void -_cairo_debug_print_pattern (FILE *file, const cairo_pattern_t *pattern) -{ - const char *s; - switch (pattern->type) { - case CAIRO_PATTERN_TYPE_SOLID: s = "solid"; break; - case CAIRO_PATTERN_TYPE_SURFACE: s = "surface"; break; - case CAIRO_PATTERN_TYPE_LINEAR: s = "linear"; break; - case CAIRO_PATTERN_TYPE_RADIAL: s = "radial"; break; - case CAIRO_PATTERN_TYPE_MESH: s = "mesh"; break; - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: s = "raster"; break; - default: s = "invalid"; ASSERT_NOT_REACHED; break; - } - - fprintf (file, "pattern: %s\n", s); - if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) - return; - - switch (pattern->extend) { - case CAIRO_EXTEND_NONE: s = "none"; break; - case CAIRO_EXTEND_REPEAT: s = "repeat"; break; - case CAIRO_EXTEND_REFLECT: s = "reflect"; break; - case CAIRO_EXTEND_PAD: s = "pad"; break; - default: s = "invalid"; ASSERT_NOT_REACHED; break; - } - fprintf (file, " extend: %s\n", s); - - switch (pattern->filter) { - case CAIRO_FILTER_FAST: s = "fast"; break; - case CAIRO_FILTER_GOOD: s = "good"; break; - case CAIRO_FILTER_BEST: s = "best"; break; - case CAIRO_FILTER_NEAREST: s = "nearest"; break; - case CAIRO_FILTER_BILINEAR: s = "bilinear"; break; - case CAIRO_FILTER_GAUSSIAN: s = "guassian"; break; - default: s = "invalid"; ASSERT_NOT_REACHED; break; - } - fprintf (file, " filter: %s\n", s); - fprintf (file, " matrix: [%g %g %g %g %g %g]\n", - pattern->matrix.xx, pattern->matrix.yx, - pattern->matrix.xy, pattern->matrix.yy, - pattern->matrix.x0, pattern->matrix.y0); - switch (pattern->type) { - default: - case CAIRO_PATTERN_TYPE_SOLID: - break; - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - _cairo_debug_print_raster_source_pattern (file, (cairo_raster_source_pattern_t *)pattern); - break; - case CAIRO_PATTERN_TYPE_SURFACE: - _cairo_debug_print_surface_pattern (file, (cairo_surface_pattern_t *)pattern); - break; - case CAIRO_PATTERN_TYPE_LINEAR: - _cairo_debug_print_linear_pattern (file, (cairo_linear_pattern_t *)pattern); - break; - case CAIRO_PATTERN_TYPE_RADIAL: - _cairo_debug_print_radial_pattern (file, (cairo_radial_pattern_t *)pattern); - break; - case CAIRO_PATTERN_TYPE_MESH: - _cairo_debug_print_mesh_pattern (file, (cairo_mesh_pattern_t *)pattern); - break; - } -} diff --git a/source/libs/cairo/cairo-src/src/cairo-pdf-operators-private.h b/source/libs/cairo/cairo-src/src/cairo-pdf-operators-private.h deleted file mode 100644 index 4314a042e81914fcf6d819bccaf2984e7b18f5ed..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-pdf-operators-private.h +++ /dev/null @@ -1,176 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2004 Red Hat, Inc - * Copyright © 2006 Red Hat, Inc - * Copyright © 2007 Adrian Johnson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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): - * Kristian Høgsberg <krh@redhat.com> - * Carl Worth <cworth@cworth.org> - * Adrian Johnson <ajohnson@redneon.com> - */ - -#ifndef CAIRO_PDF_OPERATORS_H -#define CAIRO_PDF_OPERATORS_H - -#include "cairo-compiler-private.h" -#include "cairo-error-private.h" -#include "cairo-types-private.h" - -/* The glyph buffer size is based on the expected maximum glyphs in a - * line so that an entire line can be emitted in as one string. If the - * glyphs in a line exceeds this size the only downside is the slight - * overhead of emitting two strings. - */ -#define PDF_GLYPH_BUFFER_SIZE 200 - -typedef cairo_int_status_t -(*cairo_pdf_operators_use_font_subset_t) (unsigned int font_id, - unsigned int subset_id, - void *closure); - -typedef struct _cairo_pdf_glyph { - unsigned int glyph_index; - double x_position; - double x_advance; -} cairo_pdf_glyph_t; - -typedef struct _cairo_pdf_operators { - cairo_output_stream_t *stream; - cairo_matrix_t cairo_to_pdf; - cairo_scaled_font_subsets_t *font_subsets; - cairo_pdf_operators_use_font_subset_t use_font_subset; - void *use_font_subset_closure; - cairo_bool_t ps_output; /* output is for PostScript */ - cairo_bool_t use_actual_text; - cairo_bool_t in_text_object; /* inside BT/ET pair */ - - /* PDF text state */ - cairo_bool_t is_new_text_object; /* text object started but matrix and font not yet selected */ - unsigned int font_id; - unsigned int subset_id; - cairo_matrix_t text_matrix; /* PDF text matrix (Tlm in the PDF reference) */ - cairo_matrix_t cairo_to_pdftext; /* translate cairo coords to PDF text space */ - cairo_matrix_t font_matrix_inverse; - double cur_x; /* Current position in PDF text space (Tm in the PDF reference) */ - double cur_y; - int hex_width; - cairo_bool_t is_latin; - int num_glyphs; - double glyph_buf_x_pos; - cairo_pdf_glyph_t glyphs[PDF_GLYPH_BUFFER_SIZE]; - - /* PDF line style */ - cairo_bool_t has_line_style; - double line_width; - cairo_line_cap_t line_cap; - cairo_line_join_t line_join; - double miter_limit; - cairo_bool_t has_dashes; -} cairo_pdf_operators_t; - -cairo_private void -_cairo_pdf_operators_init (cairo_pdf_operators_t *pdf_operators, - cairo_output_stream_t *stream, - cairo_matrix_t *cairo_to_pdf, - cairo_scaled_font_subsets_t *font_subsets, - cairo_bool_t ps); - -cairo_private cairo_status_t -_cairo_pdf_operators_fini (cairo_pdf_operators_t *pdf_operators); - -cairo_private void -_cairo_pdf_operators_set_font_subsets_callback (cairo_pdf_operators_t *pdf_operators, - cairo_pdf_operators_use_font_subset_t use_font_subset, - void *closure); - -cairo_private void -_cairo_pdf_operators_set_stream (cairo_pdf_operators_t *pdf_operators, - cairo_output_stream_t *stream); - - -cairo_private void -_cairo_pdf_operators_set_cairo_to_pdf_matrix (cairo_pdf_operators_t *pdf_operators, - cairo_matrix_t *cairo_to_pdf); - -cairo_private void -_cairo_pdf_operators_enable_actual_text (cairo_pdf_operators_t *pdf_operators, - cairo_bool_t enable); - -cairo_private cairo_status_t -_cairo_pdf_operators_flush (cairo_pdf_operators_t *pdf_operators); - -cairo_private void -_cairo_pdf_operators_reset (cairo_pdf_operators_t *pdf_operators); - -cairo_private cairo_int_status_t -_cairo_pdf_operators_clip (cairo_pdf_operators_t *pdf_operators, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule); - -cairo_private cairo_int_status_t -_cairo_pdf_operators_emit_stroke_style (cairo_pdf_operators_t *pdf_operators, - const cairo_stroke_style_t *style, - double scale); - -cairo_private cairo_int_status_t -_cairo_pdf_operators_stroke (cairo_pdf_operators_t *pdf_operators, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse); - -cairo_private cairo_int_status_t -_cairo_pdf_operators_fill (cairo_pdf_operators_t *pdf_operators, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule); - -cairo_private cairo_int_status_t -_cairo_pdf_operators_fill_stroke (cairo_pdf_operators_t *pdf_operators, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse); - -cairo_private cairo_int_status_t -_cairo_pdf_operators_show_text_glyphs (cairo_pdf_operators_t *pdf_operators, - const char *utf8, - int utf8_len, - cairo_glyph_t *glyphs, - int num_glyphs, - const cairo_text_cluster_t *clusters, - int num_clusters, - cairo_text_cluster_flags_t cluster_flags, - cairo_scaled_font_t *scaled_font); - -#endif /* CAIRO_PDF_OPERATORS_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-pdf-operators.c b/source/libs/cairo/cairo-src/src/cairo-pdf-operators.c deleted file mode 100644 index dcee25f0c23957730529a736d5b0c24129518201..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-pdf-operators.c +++ /dev/null @@ -1,1560 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2004 Red Hat, Inc - * Copyright © 2006 Red Hat, Inc - * Copyright © 2007, 2008 Adrian Johnson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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): - * Kristian Høgsberg <krh@redhat.com> - * Carl Worth <cworth@cworth.org> - * Adrian Johnson <ajohnson@redneon.com> - */ - -#include "cairoint.h" - -#if CAIRO_HAS_PDF_OPERATORS - -#include "cairo-error-private.h" -#include "cairo-pdf-operators-private.h" -#include "cairo-path-fixed-private.h" -#include "cairo-output-stream-private.h" -#include "cairo-scaled-font-subsets-private.h" - -static cairo_status_t -_cairo_pdf_operators_end_text (cairo_pdf_operators_t *pdf_operators); - - -void -_cairo_pdf_operators_init (cairo_pdf_operators_t *pdf_operators, - cairo_output_stream_t *stream, - cairo_matrix_t *cairo_to_pdf, - cairo_scaled_font_subsets_t *font_subsets, - cairo_bool_t ps) -{ - pdf_operators->stream = stream; - pdf_operators->cairo_to_pdf = *cairo_to_pdf; - pdf_operators->font_subsets = font_subsets; - pdf_operators->ps_output = ps; - pdf_operators->use_font_subset = NULL; - pdf_operators->use_font_subset_closure = NULL; - pdf_operators->in_text_object = FALSE; - pdf_operators->num_glyphs = 0; - pdf_operators->has_line_style = FALSE; - pdf_operators->use_actual_text = FALSE; -} - -cairo_status_t -_cairo_pdf_operators_fini (cairo_pdf_operators_t *pdf_operators) -{ - return _cairo_pdf_operators_flush (pdf_operators); -} - -void -_cairo_pdf_operators_set_font_subsets_callback (cairo_pdf_operators_t *pdf_operators, - cairo_pdf_operators_use_font_subset_t use_font_subset, - void *closure) -{ - pdf_operators->use_font_subset = use_font_subset; - pdf_operators->use_font_subset_closure = closure; -} - -/* Change the output stream to a different stream. - * _cairo_pdf_operators_flush() should always be called before calling - * this function. - */ -void -_cairo_pdf_operators_set_stream (cairo_pdf_operators_t *pdf_operators, - cairo_output_stream_t *stream) -{ - pdf_operators->stream = stream; - pdf_operators->has_line_style = FALSE; -} - -void -_cairo_pdf_operators_set_cairo_to_pdf_matrix (cairo_pdf_operators_t *pdf_operators, - cairo_matrix_t *cairo_to_pdf) -{ - pdf_operators->cairo_to_pdf = *cairo_to_pdf; - pdf_operators->has_line_style = FALSE; -} - -cairo_private void -_cairo_pdf_operators_enable_actual_text (cairo_pdf_operators_t *pdf_operators, - cairo_bool_t enable) -{ - pdf_operators->use_actual_text = enable; -} - -/* Finish writing out any pending commands to the stream. This - * function must be called by the surface before emitting anything - * into the PDF stream. - * - * pdf_operators may leave the emitted PDF for some operations - * unfinished in case subsequent operations can be merged. This - * function will finish off any incomplete operation so the stream - * will be in a state where the surface may emit its own PDF - * operations (eg changing patterns). - * - */ -cairo_status_t -_cairo_pdf_operators_flush (cairo_pdf_operators_t *pdf_operators) -{ - cairo_status_t status = CAIRO_STATUS_SUCCESS; - - if (pdf_operators->in_text_object) - status = _cairo_pdf_operators_end_text (pdf_operators); - - return status; -} - -/* Reset the known graphics state of the PDF consumer. ie no - * assumptions will be made about the state. The next time a - * particular graphics state is required (eg line width) the state - * operator is always emitted and then remembered for subsequent - * operatations. - * - * This should be called when starting a new stream or after emitting - * the 'Q' operator (where pdf-operators functions were called inside - * the q/Q pair). - */ -void -_cairo_pdf_operators_reset (cairo_pdf_operators_t *pdf_operators) -{ - pdf_operators->has_line_style = FALSE; -} - -/* A word wrap stream can be used as a filter to do word wrapping on - * top of an existing output stream. The word wrapping is quite - * simple, using isspace to determine characters that separate - * words. Any word that will cause the column count exceed the given - * max_column will have a '\n' character emitted before it. - * - * The stream is careful to maintain integrity for words that cross - * the boundary from one call to write to the next. - * - * Note: This stream does not guarantee that the output will never - * exceed max_column. In particular, if a single word is larger than - * max_column it will not be broken up. - */ - -typedef enum _cairo_word_wrap_state { - WRAP_STATE_DELIMITER, - WRAP_STATE_WORD, - WRAP_STATE_STRING, - WRAP_STATE_HEXSTRING -} cairo_word_wrap_state_t; - - -typedef struct _word_wrap_stream { - cairo_output_stream_t base; - cairo_output_stream_t *output; - int max_column; - cairo_bool_t ps_output; - int column; - cairo_word_wrap_state_t state; - cairo_bool_t in_escape; - int escape_digits; -} word_wrap_stream_t; - - - -/* Emit word bytes up to the next delimiter character */ -static int -_word_wrap_stream_count_word_up_to (word_wrap_stream_t *stream, - const unsigned char *data, int length) -{ - const unsigned char *s = data; - int count = 0; - - while (length--) { - if (_cairo_isspace (*s) || *s == '<' || *s == '(') { - stream->state = WRAP_STATE_DELIMITER; - break; - } - - count++; - stream->column++; - s++; - } - - if (count) - _cairo_output_stream_write (stream->output, data, count); - - return count; -} - - -/* Emit hexstring bytes up to either the end of the ASCII hexstring or the number - * of columns remaining. - */ -static int -_word_wrap_stream_count_hexstring_up_to (word_wrap_stream_t *stream, - const unsigned char *data, int length) -{ - const unsigned char *s = data; - int count = 0; - cairo_bool_t newline = FALSE; - - while (length--) { - count++; - stream->column++; - if (*s == '>') { - stream->state = WRAP_STATE_DELIMITER; - break; - } - - if (stream->column > stream->max_column) { - newline = TRUE; - break; - } - s++; - } - - if (count) - _cairo_output_stream_write (stream->output, data, count); - - if (newline) { - _cairo_output_stream_printf (stream->output, "\n"); - stream->column = 0; - } - - return count; -} - -/* Count up to either the end of the string or the number of columns - * remaining. - */ -static int -_word_wrap_stream_count_string_up_to (word_wrap_stream_t *stream, - const unsigned char *data, int length) -{ - const unsigned char *s = data; - int count = 0; - cairo_bool_t newline = FALSE; - - while (length--) { - count++; - stream->column++; - if (!stream->in_escape) { - if (*s == ')') { - stream->state = WRAP_STATE_DELIMITER; - break; - } - if (*s == '\\') { - stream->in_escape = TRUE; - stream->escape_digits = 0; - } else if (stream->ps_output && stream->column > stream->max_column) { - newline = TRUE; - break; - } - } else { - if (!_cairo_isdigit(*s) || ++stream->escape_digits == 3) - stream->in_escape = FALSE; - } - s++; - } - - if (count) - _cairo_output_stream_write (stream->output, data, count); - - if (newline) { - _cairo_output_stream_printf (stream->output, "\\\n"); - stream->column = 0; - } - - return count; -} - -static cairo_status_t -_word_wrap_stream_write (cairo_output_stream_t *base, - const unsigned char *data, - unsigned int length) -{ - word_wrap_stream_t *stream = (word_wrap_stream_t *) base; - int count; - - while (length) { - switch (stream->state) { - case WRAP_STATE_WORD: - count = _word_wrap_stream_count_word_up_to (stream, data, length); - break; - case WRAP_STATE_HEXSTRING: - count = _word_wrap_stream_count_hexstring_up_to (stream, data, length); - break; - case WRAP_STATE_STRING: - count = _word_wrap_stream_count_string_up_to (stream, data, length); - break; - case WRAP_STATE_DELIMITER: - count = 1; - stream->column++; - if (*data == '\n' || stream->column >= stream->max_column) { - _cairo_output_stream_printf (stream->output, "\n"); - stream->column = 0; - } else if (*data == '<') { - stream->state = WRAP_STATE_HEXSTRING; - } else if (*data == '(') { - stream->state = WRAP_STATE_STRING; - } else if (!_cairo_isspace (*data)) { - stream->state = WRAP_STATE_WORD; - } - if (*data != '\n') - _cairo_output_stream_write (stream->output, data, 1); - break; - - default: - ASSERT_NOT_REACHED; - count = length; - break; - } - data += count; - length -= count; - } - - return _cairo_output_stream_get_status (stream->output); -} - -static cairo_status_t -_word_wrap_stream_close (cairo_output_stream_t *base) -{ - word_wrap_stream_t *stream = (word_wrap_stream_t *) base; - - return _cairo_output_stream_get_status (stream->output); -} - -static cairo_output_stream_t * -_word_wrap_stream_create (cairo_output_stream_t *output, cairo_bool_t ps, int max_column) -{ - word_wrap_stream_t *stream; - - if (output->status) - return _cairo_output_stream_create_in_error (output->status); - - stream = malloc (sizeof (word_wrap_stream_t)); - if (unlikely (stream == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_output_stream_t *) &_cairo_output_stream_nil; - } - - _cairo_output_stream_init (&stream->base, - _word_wrap_stream_write, - NULL, - _word_wrap_stream_close); - stream->output = output; - stream->max_column = max_column; - stream->ps_output = ps; - stream->column = 0; - stream->state = WRAP_STATE_DELIMITER; - stream->in_escape = FALSE; - stream->escape_digits = 0; - - return &stream->base; -} - -typedef struct _pdf_path_info { - cairo_output_stream_t *output; - cairo_matrix_t *path_transform; - cairo_line_cap_t line_cap; - cairo_point_t last_move_to_point; - cairo_bool_t has_sub_path; -} pdf_path_info_t; - -static cairo_status_t -_cairo_pdf_path_move_to (void *closure, - const cairo_point_t *point) -{ - pdf_path_info_t *info = closure; - double x = _cairo_fixed_to_double (point->x); - double y = _cairo_fixed_to_double (point->y); - - info->last_move_to_point = *point; - info->has_sub_path = FALSE; - cairo_matrix_transform_point (info->path_transform, &x, &y); - _cairo_output_stream_printf (info->output, - "%g %g m ", x, y); - - return _cairo_output_stream_get_status (info->output); -} - -static cairo_status_t -_cairo_pdf_path_line_to (void *closure, - const cairo_point_t *point) -{ - pdf_path_info_t *info = closure; - double x = _cairo_fixed_to_double (point->x); - double y = _cairo_fixed_to_double (point->y); - - if (info->line_cap != CAIRO_LINE_CAP_ROUND && - ! info->has_sub_path && - point->x == info->last_move_to_point.x && - point->y == info->last_move_to_point.y) - { - return CAIRO_STATUS_SUCCESS; - } - - info->has_sub_path = TRUE; - cairo_matrix_transform_point (info->path_transform, &x, &y); - _cairo_output_stream_printf (info->output, - "%g %g l ", x, y); - - return _cairo_output_stream_get_status (info->output); -} - -static cairo_status_t -_cairo_pdf_path_curve_to (void *closure, - const cairo_point_t *b, - const cairo_point_t *c, - const cairo_point_t *d) -{ - pdf_path_info_t *info = closure; - double bx = _cairo_fixed_to_double (b->x); - double by = _cairo_fixed_to_double (b->y); - double cx = _cairo_fixed_to_double (c->x); - double cy = _cairo_fixed_to_double (c->y); - double dx = _cairo_fixed_to_double (d->x); - double dy = _cairo_fixed_to_double (d->y); - - info->has_sub_path = TRUE; - cairo_matrix_transform_point (info->path_transform, &bx, &by); - cairo_matrix_transform_point (info->path_transform, &cx, &cy); - cairo_matrix_transform_point (info->path_transform, &dx, &dy); - _cairo_output_stream_printf (info->output, - "%g %g %g %g %g %g c ", - bx, by, cx, cy, dx, dy); - return _cairo_output_stream_get_status (info->output); -} - -static cairo_status_t -_cairo_pdf_path_close_path (void *closure) -{ - pdf_path_info_t *info = closure; - - if (info->line_cap != CAIRO_LINE_CAP_ROUND && - ! info->has_sub_path) - { - return CAIRO_STATUS_SUCCESS; - } - - _cairo_output_stream_printf (info->output, - "h\n"); - - return _cairo_output_stream_get_status (info->output); -} - -static cairo_status_t -_cairo_pdf_path_rectangle (pdf_path_info_t *info, cairo_box_t *box) -{ - double x1 = _cairo_fixed_to_double (box->p1.x); - double y1 = _cairo_fixed_to_double (box->p1.y); - double x2 = _cairo_fixed_to_double (box->p2.x); - double y2 = _cairo_fixed_to_double (box->p2.y); - - cairo_matrix_transform_point (info->path_transform, &x1, &y1); - cairo_matrix_transform_point (info->path_transform, &x2, &y2); - _cairo_output_stream_printf (info->output, - "%g %g %g %g re ", - x1, y1, x2 - x1, y2 - y1); - - return _cairo_output_stream_get_status (info->output); -} - -/* The line cap value is needed to workaround the fact that PostScript - * and PDF semantics for stroking degenerate sub-paths do not match - * cairo semantics. (PostScript draws something for any line cap - * value, while cairo draws something only for round caps). - * - * When using this function to emit a path to be filled, rather than - * stroked, simply pass %CAIRO_LINE_CAP_ROUND which will guarantee that - * the stroke workaround will not modify the path being emitted. - */ -static cairo_status_t -_cairo_pdf_operators_emit_path (cairo_pdf_operators_t *pdf_operators, - const cairo_path_fixed_t*path, - cairo_matrix_t *path_transform, - cairo_line_cap_t line_cap) -{ - cairo_output_stream_t *word_wrap; - cairo_status_t status, status2; - pdf_path_info_t info; - cairo_box_t box; - - word_wrap = _word_wrap_stream_create (pdf_operators->stream, pdf_operators->ps_output, 72); - status = _cairo_output_stream_get_status (word_wrap); - if (unlikely (status)) - return _cairo_output_stream_destroy (word_wrap); - - info.output = word_wrap; - info.path_transform = path_transform; - info.line_cap = line_cap; - if (_cairo_path_fixed_is_rectangle (path, &box) && - ((path_transform->xx == 0 && path_transform->yy == 0) || - (path_transform->xy == 0 && path_transform->yx == 0))) { - status = _cairo_pdf_path_rectangle (&info, &box); - } else { - status = _cairo_path_fixed_interpret (path, - _cairo_pdf_path_move_to, - _cairo_pdf_path_line_to, - _cairo_pdf_path_curve_to, - _cairo_pdf_path_close_path, - &info); - } - - status2 = _cairo_output_stream_destroy (word_wrap); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - - return status; -} - -cairo_int_status_t -_cairo_pdf_operators_clip (cairo_pdf_operators_t *pdf_operators, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule) -{ - const char *pdf_operator; - cairo_status_t status; - - if (pdf_operators->in_text_object) { - status = _cairo_pdf_operators_end_text (pdf_operators); - if (unlikely (status)) - return status; - } - - if (! path->has_current_point) { - /* construct an empty path */ - _cairo_output_stream_printf (pdf_operators->stream, "0 0 m "); - } else { - status = _cairo_pdf_operators_emit_path (pdf_operators, - path, - &pdf_operators->cairo_to_pdf, - CAIRO_LINE_CAP_ROUND); - if (unlikely (status)) - return status; - } - - switch (fill_rule) { - default: - ASSERT_NOT_REACHED; - case CAIRO_FILL_RULE_WINDING: - pdf_operator = "W"; - break; - case CAIRO_FILL_RULE_EVEN_ODD: - pdf_operator = "W*"; - break; - } - - _cairo_output_stream_printf (pdf_operators->stream, - "%s n\n", - pdf_operator); - - return _cairo_output_stream_get_status (pdf_operators->stream); -} - -static int -_cairo_pdf_line_cap (cairo_line_cap_t cap) -{ - switch (cap) { - case CAIRO_LINE_CAP_BUTT: - return 0; - case CAIRO_LINE_CAP_ROUND: - return 1; - case CAIRO_LINE_CAP_SQUARE: - return 2; - default: - ASSERT_NOT_REACHED; - return 0; - } -} - -static int -_cairo_pdf_line_join (cairo_line_join_t join) -{ - switch (join) { - case CAIRO_LINE_JOIN_MITER: - return 0; - case CAIRO_LINE_JOIN_ROUND: - return 1; - case CAIRO_LINE_JOIN_BEVEL: - return 2; - default: - ASSERT_NOT_REACHED; - return 0; - } -} - -cairo_int_status_t -_cairo_pdf_operators_emit_stroke_style (cairo_pdf_operators_t *pdf_operators, - const cairo_stroke_style_t *style, - double scale) -{ - double *dash = style->dash; - int num_dashes = style->num_dashes; - double dash_offset = style->dash_offset; - double line_width = style->line_width * scale; - - /* PostScript has "special needs" when it comes to zero-length - * dash segments with butt caps. It apparently (at least - * according to ghostscript) draws hairlines for this - * case. That's not what the cairo semantics want, so we first - * touch up the array to eliminate any 0.0 values that will - * result in "on" segments. - */ - if (num_dashes && style->line_cap == CAIRO_LINE_CAP_BUTT) { - int i; - - /* If there's an odd number of dash values they will each get - * interpreted as both on and off. So we first explicitly - * expand the array to remove the duplicate usage so that we - * can modify some of the values. - */ - if (num_dashes % 2) { - dash = _cairo_malloc_abc (num_dashes, 2, sizeof (double)); - if (unlikely (dash == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - memcpy (dash, style->dash, num_dashes * sizeof (double)); - memcpy (dash + num_dashes, style->dash, num_dashes * sizeof (double)); - - num_dashes *= 2; - } - - for (i = 0; i < num_dashes; i += 2) { - if (dash[i] == 0.0) { - /* Do not modify the dashes in-place, as we may need to also - * replay this stroke to an image fallback. - */ - if (dash == style->dash) { - dash = _cairo_malloc_ab (num_dashes, sizeof (double)); - if (unlikely (dash == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - memcpy (dash, style->dash, num_dashes * sizeof (double)); - } - - /* If we're at the front of the list, we first rotate - * two elements from the end of the list to the front - * of the list before folding away the 0.0. Or, if - * there are only two dash elements, then there is - * nothing at all to draw. - */ - if (i == 0) { - double last_two[2]; - - if (num_dashes == 2) { - free (dash); - return CAIRO_INT_STATUS_NOTHING_TO_DO; - } - - /* The cases of num_dashes == 0, 1, or 3 elements - * cannot exist, so the rotation of 2 elements - * will always be safe */ - memcpy (last_two, dash + num_dashes - 2, sizeof (last_two)); - memmove (dash + 2, dash, (num_dashes - 2) * sizeof (double)); - memcpy (dash, last_two, sizeof (last_two)); - dash_offset += dash[0] + dash[1]; - i = 2; - } - dash[i-1] += dash[i+1]; - num_dashes -= 2; - memmove (dash + i, dash + i + 2, (num_dashes - i) * sizeof (double)); - /* If we might have just rotated, it's possible that - * we rotated a 0.0 value to the front of the list. - * Set i to -2 so it will get incremented to 0. */ - if (i == 2) - i = -2; - } - } - } - - if (!pdf_operators->has_line_style || pdf_operators->line_width != line_width) { - _cairo_output_stream_printf (pdf_operators->stream, - "%f w\n", - line_width); - pdf_operators->line_width = line_width; - } - - if (!pdf_operators->has_line_style || pdf_operators->line_cap != style->line_cap) { - _cairo_output_stream_printf (pdf_operators->stream, - "%d J\n", - _cairo_pdf_line_cap (style->line_cap)); - pdf_operators->line_cap = style->line_cap; - } - - if (!pdf_operators->has_line_style || pdf_operators->line_join != style->line_join) { - _cairo_output_stream_printf (pdf_operators->stream, - "%d j\n", - _cairo_pdf_line_join (style->line_join)); - pdf_operators->line_join = style->line_join; - } - - if (num_dashes) { - int d; - - _cairo_output_stream_printf (pdf_operators->stream, "["); - for (d = 0; d < num_dashes; d++) - _cairo_output_stream_printf (pdf_operators->stream, " %f", dash[d] * scale); - _cairo_output_stream_printf (pdf_operators->stream, "] %f d\n", - dash_offset * scale); - pdf_operators->has_dashes = TRUE; - } else if (!pdf_operators->has_line_style || pdf_operators->has_dashes) { - _cairo_output_stream_printf (pdf_operators->stream, "[] 0.0 d\n"); - pdf_operators->has_dashes = FALSE; - } - if (dash != style->dash) - free (dash); - - if (!pdf_operators->has_line_style || pdf_operators->miter_limit != style->miter_limit) { - _cairo_output_stream_printf (pdf_operators->stream, - "%f M ", - style->miter_limit < 1.0 ? 1.0 : style->miter_limit); - pdf_operators->miter_limit = style->miter_limit; - } - pdf_operators->has_line_style = TRUE; - - return _cairo_output_stream_get_status (pdf_operators->stream); -} - -/* Scale the matrix so the largest absolute value of the non - * translation components is 1.0. Return the scale required to restore - * the matrix to the original values. - * - * eg the matrix [ 100 0 0 50 20 10 ] - * - * is rescaled to [ 1 0 0 0.5 0.2 0.1 ] - * and the scale returned is 100 - */ -static void -_cairo_matrix_factor_out_scale (cairo_matrix_t *m, double *scale) -{ - double s; - - s = fabs (m->xx); - if (fabs (m->xy) > s) - s = fabs (m->xy); - if (fabs (m->yx) > s) - s = fabs (m->yx); - if (fabs (m->yy) > s) - s = fabs (m->yy); - *scale = s; - s = 1.0/s; - cairo_matrix_scale (m, s, s); -} - -static cairo_int_status_t -_cairo_pdf_operators_emit_stroke (cairo_pdf_operators_t *pdf_operators, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - const char *pdf_operator) -{ - cairo_int_status_t status; - cairo_matrix_t m, path_transform; - cairo_bool_t has_ctm = TRUE; - double scale = 1.0; - - if (pdf_operators->in_text_object) { - status = _cairo_pdf_operators_end_text (pdf_operators); - if (unlikely (status)) - return status; - } - - /* Optimize away the stroke ctm when it does not affect the - * stroke. There are other ctm cases that could be optimized - * however this is the most common. - */ - if (fabs(ctm->xx) == 1.0 && fabs(ctm->yy) == 1.0 && - fabs(ctm->xy) == 0.0 && fabs(ctm->yx) == 0.0) - { - has_ctm = FALSE; - } - - /* The PDF CTM is transformed to the user space CTM when stroking - * so the corect pen shape will be used. This also requires that - * the path be transformed to user space when emitted. The - * conversion of path coordinates to user space may cause rounding - * errors. For example the device space point (1.234, 3.142) when - * transformed to a user space CTM of [100 0 0 100 0 0] will be - * emitted as (0.012, 0.031). - * - * To avoid the rounding problem we scale the user space CTM - * matrix so that all the non translation components of the matrix - * are <= 1. The line width and and dashes are scaled by the - * inverse of the scale applied to the CTM. This maintains the - * shape of the stroke pen while keeping the user space CTM within - * the range that maximizes the precision of the emitted path. - */ - if (has_ctm) { - m = *ctm; - /* Zero out the translation since it does not affect the pen - * shape however it may cause unnecessary digits to be emitted. - */ - m.x0 = 0.0; - m.y0 = 0.0; - _cairo_matrix_factor_out_scale (&m, &scale); - path_transform = m; - status = cairo_matrix_invert (&path_transform); - if (unlikely (status)) - return status; - - cairo_matrix_multiply (&m, &m, &pdf_operators->cairo_to_pdf); - } - - status = _cairo_pdf_operators_emit_stroke_style (pdf_operators, style, scale); - if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) - return CAIRO_STATUS_SUCCESS; - if (unlikely (status)) - return status; - - if (has_ctm) { - _cairo_output_stream_printf (pdf_operators->stream, "q "); - _cairo_output_stream_print_matrix (pdf_operators->stream, &m); - _cairo_output_stream_printf (pdf_operators->stream, " cm\n"); - } else { - path_transform = pdf_operators->cairo_to_pdf; - } - - status = _cairo_pdf_operators_emit_path (pdf_operators, - path, - &path_transform, - style->line_cap); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (pdf_operators->stream, "%s", pdf_operator); - if (has_ctm) - _cairo_output_stream_printf (pdf_operators->stream, " Q"); - - _cairo_output_stream_printf (pdf_operators->stream, "\n"); - - return _cairo_output_stream_get_status (pdf_operators->stream); -} - -cairo_int_status_t -_cairo_pdf_operators_stroke (cairo_pdf_operators_t *pdf_operators, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse) -{ - return _cairo_pdf_operators_emit_stroke (pdf_operators, - path, - style, - ctm, - ctm_inverse, - "S"); -} - -cairo_int_status_t -_cairo_pdf_operators_fill (cairo_pdf_operators_t *pdf_operators, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule) -{ - const char *pdf_operator; - cairo_status_t status; - - if (pdf_operators->in_text_object) { - status = _cairo_pdf_operators_end_text (pdf_operators); - if (unlikely (status)) - return status; - } - - status = _cairo_pdf_operators_emit_path (pdf_operators, - path, - &pdf_operators->cairo_to_pdf, - CAIRO_LINE_CAP_ROUND); - if (unlikely (status)) - return status; - - switch (fill_rule) { - default: - ASSERT_NOT_REACHED; - case CAIRO_FILL_RULE_WINDING: - pdf_operator = "f"; - break; - case CAIRO_FILL_RULE_EVEN_ODD: - pdf_operator = "f*"; - break; - } - - _cairo_output_stream_printf (pdf_operators->stream, - "%s\n", - pdf_operator); - - return _cairo_output_stream_get_status (pdf_operators->stream); -} - -cairo_int_status_t -_cairo_pdf_operators_fill_stroke (cairo_pdf_operators_t *pdf_operators, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse) -{ - const char *operator; - - switch (fill_rule) { - default: - ASSERT_NOT_REACHED; - case CAIRO_FILL_RULE_WINDING: - operator = "B"; - break; - case CAIRO_FILL_RULE_EVEN_ODD: - operator = "B*"; - break; - } - - return _cairo_pdf_operators_emit_stroke (pdf_operators, - path, - style, - ctm, - ctm_inverse, - operator); -} - -static void -_cairo_pdf_operators_emit_glyph_index (cairo_pdf_operators_t *pdf_operators, - cairo_output_stream_t *stream, - unsigned int glyph) -{ - if (pdf_operators->is_latin) { - if (glyph == '(' || glyph == ')' || glyph == '\\') - _cairo_output_stream_printf (stream, "\\%c", glyph); - else if (glyph >= 0x20 && glyph <= 0x7e) - _cairo_output_stream_printf (stream, "%c", glyph); - else - _cairo_output_stream_printf (stream, "\\%03o", glyph); - } else { - _cairo_output_stream_printf (stream, - "%0*x", - pdf_operators->hex_width, - glyph); - } -} - -#define GLYPH_POSITION_TOLERANCE 0.001 - -/* Emit the string of glyphs using the 'Tj' operator. This requires - * that the glyphs are positioned at their natural glyph advances. */ -static cairo_status_t -_cairo_pdf_operators_emit_glyph_string (cairo_pdf_operators_t *pdf_operators, - cairo_output_stream_t *stream) -{ - int i; - - _cairo_output_stream_printf (stream, "%s", pdf_operators->is_latin ? "(" : "<"); - for (i = 0; i < pdf_operators->num_glyphs; i++) { - _cairo_pdf_operators_emit_glyph_index (pdf_operators, - stream, - pdf_operators->glyphs[i].glyph_index); - pdf_operators->cur_x += pdf_operators->glyphs[i].x_advance; - } - _cairo_output_stream_printf (stream, "%sTj\n", pdf_operators->is_latin ? ")" : ">"); - - return _cairo_output_stream_get_status (stream); -} - -/* Emit the string of glyphs using the 'TJ' operator. - * - * The TJ operator takes an array of strings of glyphs. Each string of - * glyphs is displayed using the glyph advances of each glyph to - * position the glyphs. A relative adjustment to the glyph advance may - * be specified by including the adjustment between two strings. The - * adjustment is in units of text space * -1000. - */ -static cairo_status_t -_cairo_pdf_operators_emit_glyph_string_with_positioning ( - cairo_pdf_operators_t *pdf_operators, - cairo_output_stream_t *stream) -{ - int i; - - _cairo_output_stream_printf (stream, "[%s", pdf_operators->is_latin ? "(" : "<"); - for (i = 0; i < pdf_operators->num_glyphs; i++) { - if (pdf_operators->glyphs[i].x_position != pdf_operators->cur_x) - { - double delta = pdf_operators->glyphs[i].x_position - pdf_operators->cur_x; - int rounded_delta; - - delta = -1000.0*delta; - /* As the delta is in 1/1000 of a unit of text space, - * rounding to an integer should still provide sufficient - * precision. We round the delta before adding to Tm_x so - * that we keep track of the accumulated rounding error in - * the PDF interpreter and compensate for it when - * calculating subsequent deltas. - */ - rounded_delta = _cairo_lround (delta); - if (abs(rounded_delta) < 3) - rounded_delta = 0; - if (rounded_delta != 0) { - if (pdf_operators->is_latin) { - _cairo_output_stream_printf (stream, - ")%d(", - rounded_delta); - } else { - _cairo_output_stream_printf (stream, - ">%d<", - rounded_delta); - } - } - - /* Convert the rounded delta back to text - * space before adding to the current text - * position. */ - delta = rounded_delta/-1000.0; - pdf_operators->cur_x += delta; - } - - _cairo_pdf_operators_emit_glyph_index (pdf_operators, - stream, - pdf_operators->glyphs[i].glyph_index); - pdf_operators->cur_x += pdf_operators->glyphs[i].x_advance; - } - _cairo_output_stream_printf (stream, "%s]TJ\n", pdf_operators->is_latin ? ")" : ">"); - - return _cairo_output_stream_get_status (stream); -} - -static cairo_status_t -_cairo_pdf_operators_flush_glyphs (cairo_pdf_operators_t *pdf_operators) -{ - cairo_output_stream_t *word_wrap_stream; - cairo_status_t status, status2; - int i; - double x; - - if (pdf_operators->num_glyphs == 0) - return CAIRO_STATUS_SUCCESS; - - word_wrap_stream = _word_wrap_stream_create (pdf_operators->stream, pdf_operators->ps_output, 72); - status = _cairo_output_stream_get_status (word_wrap_stream); - if (unlikely (status)) - return _cairo_output_stream_destroy (word_wrap_stream); - - /* Check if glyph advance used to position every glyph */ - x = pdf_operators->cur_x; - for (i = 0; i < pdf_operators->num_glyphs; i++) { - if (fabs(pdf_operators->glyphs[i].x_position - x) > GLYPH_POSITION_TOLERANCE) - break; - x += pdf_operators->glyphs[i].x_advance; - } - if (i == pdf_operators->num_glyphs) { - status = _cairo_pdf_operators_emit_glyph_string (pdf_operators, - word_wrap_stream); - } else { - status = _cairo_pdf_operators_emit_glyph_string_with_positioning ( - pdf_operators, word_wrap_stream); - } - - pdf_operators->num_glyphs = 0; - pdf_operators->glyph_buf_x_pos = pdf_operators->cur_x; - status2 = _cairo_output_stream_destroy (word_wrap_stream); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - - return status; -} - -static cairo_status_t -_cairo_pdf_operators_add_glyph (cairo_pdf_operators_t *pdf_operators, - cairo_scaled_font_subsets_glyph_t *glyph, - double x_position) -{ - double x, y; - - x = glyph->x_advance; - y = glyph->y_advance; - if (glyph->is_scaled) - cairo_matrix_transform_distance (&pdf_operators->font_matrix_inverse, &x, &y); - - pdf_operators->glyphs[pdf_operators->num_glyphs].x_position = x_position; - pdf_operators->glyphs[pdf_operators->num_glyphs].glyph_index = glyph->subset_glyph_index; - pdf_operators->glyphs[pdf_operators->num_glyphs].x_advance = x; - pdf_operators->glyph_buf_x_pos += x; - pdf_operators->num_glyphs++; - if (pdf_operators->num_glyphs == PDF_GLYPH_BUFFER_SIZE) - return _cairo_pdf_operators_flush_glyphs (pdf_operators); - - return CAIRO_STATUS_SUCCESS; -} - -/* Use 'Tm' operator to set the PDF text matrix. */ -static cairo_status_t -_cairo_pdf_operators_set_text_matrix (cairo_pdf_operators_t *pdf_operators, - cairo_matrix_t *matrix) -{ - cairo_matrix_t inverse; - cairo_status_t status; - - /* We require the matrix to be invertable. */ - inverse = *matrix; - status = cairo_matrix_invert (&inverse); - if (unlikely (status)) - return status; - - pdf_operators->text_matrix = *matrix; - pdf_operators->cur_x = 0; - pdf_operators->cur_y = 0; - pdf_operators->glyph_buf_x_pos = 0; - _cairo_output_stream_print_matrix (pdf_operators->stream, &pdf_operators->text_matrix); - _cairo_output_stream_printf (pdf_operators->stream, " Tm\n"); - - pdf_operators->cairo_to_pdftext = *matrix; - status = cairo_matrix_invert (&pdf_operators->cairo_to_pdftext); - assert (status == CAIRO_STATUS_SUCCESS); - cairo_matrix_multiply (&pdf_operators->cairo_to_pdftext, - &pdf_operators->cairo_to_pdf, - &pdf_operators->cairo_to_pdftext); - - return _cairo_output_stream_get_status (pdf_operators->stream); -} - -#define TEXT_MATRIX_TOLERANCE 1e-6 - -/* Set the translation components of the PDF text matrix to x, y. The - * 'Td' operator is used to transform the text matrix. - */ -static cairo_status_t -_cairo_pdf_operators_set_text_position (cairo_pdf_operators_t *pdf_operators, - double x, - double y) -{ - cairo_matrix_t translate, inverse; - cairo_status_t status; - - /* The Td operator transforms the text_matrix with: - * - * text_matrix' = T x text_matrix - * - * where T is a translation matrix with the translation components - * set to the Td operands tx and ty. - */ - inverse = pdf_operators->text_matrix; - status = cairo_matrix_invert (&inverse); - assert (status == CAIRO_STATUS_SUCCESS); - pdf_operators->text_matrix.x0 = x; - pdf_operators->text_matrix.y0 = y; - cairo_matrix_multiply (&translate, &pdf_operators->text_matrix, &inverse); - if (fabs(translate.x0) < TEXT_MATRIX_TOLERANCE) - translate.x0 = 0.0; - if (fabs(translate.y0) < TEXT_MATRIX_TOLERANCE) - translate.y0 = 0.0; - _cairo_output_stream_printf (pdf_operators->stream, - "%f %f Td\n", - translate.x0, - translate.y0); - pdf_operators->cur_x = 0; - pdf_operators->cur_y = 0; - pdf_operators->glyph_buf_x_pos = 0; - - pdf_operators->cairo_to_pdftext = pdf_operators->text_matrix; - status = cairo_matrix_invert (&pdf_operators->cairo_to_pdftext); - assert (status == CAIRO_STATUS_SUCCESS); - cairo_matrix_multiply (&pdf_operators->cairo_to_pdftext, - &pdf_operators->cairo_to_pdf, - &pdf_operators->cairo_to_pdftext); - - return _cairo_output_stream_get_status (pdf_operators->stream); -} - -/* Select the font using the 'Tf' operator. The font size is set to 1 - * as we use the 'Tm' operator to set the font scale. - */ -static cairo_status_t -_cairo_pdf_operators_set_font_subset (cairo_pdf_operators_t *pdf_operators, - cairo_scaled_font_subsets_glyph_t *subset_glyph) -{ - cairo_status_t status; - - _cairo_output_stream_printf (pdf_operators->stream, - "/f-%d-%d 1 Tf\n", - subset_glyph->font_id, - subset_glyph->subset_id); - if (pdf_operators->use_font_subset) { - status = pdf_operators->use_font_subset (subset_glyph->font_id, - subset_glyph->subset_id, - pdf_operators->use_font_subset_closure); - if (unlikely (status)) - return status; - } - pdf_operators->font_id = subset_glyph->font_id; - pdf_operators->subset_id = subset_glyph->subset_id; - pdf_operators->is_latin = subset_glyph->is_latin; - - if (subset_glyph->is_composite) - pdf_operators->hex_width = 4; - else - pdf_operators->hex_width = 2; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_pdf_operators_begin_text (cairo_pdf_operators_t *pdf_operators) -{ - _cairo_output_stream_printf (pdf_operators->stream, "BT\n"); - - pdf_operators->in_text_object = TRUE; - pdf_operators->num_glyphs = 0; - pdf_operators->glyph_buf_x_pos = 0; - - return _cairo_output_stream_get_status (pdf_operators->stream); -} - -static cairo_status_t -_cairo_pdf_operators_end_text (cairo_pdf_operators_t *pdf_operators) -{ - cairo_status_t status; - - status = _cairo_pdf_operators_flush_glyphs (pdf_operators); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (pdf_operators->stream, "ET\n"); - - pdf_operators->in_text_object = FALSE; - - return _cairo_output_stream_get_status (pdf_operators->stream); -} - -/* Compare the scale components of two matrices. The translation - * components are ignored. */ -static cairo_bool_t -_cairo_matrix_scale_equal (cairo_matrix_t *a, cairo_matrix_t *b) -{ - return (a->xx == b->xx && - a->xy == b->xy && - a->yx == b->yx && - a->yy == b->yy); -} - -static cairo_status_t -_cairo_pdf_operators_begin_actualtext (cairo_pdf_operators_t *pdf_operators, - const char *utf8, - int utf8_len) -{ - uint16_t *utf16; - int utf16_len; - cairo_status_t status; - int i; - - _cairo_output_stream_printf (pdf_operators->stream, "/Span << /ActualText <feff"); - if (utf8_len) { - status = _cairo_utf8_to_utf16 (utf8, utf8_len, &utf16, &utf16_len); - if (unlikely (status)) - return status; - - for (i = 0; i < utf16_len; i++) { - _cairo_output_stream_printf (pdf_operators->stream, - "%04x", (int) (utf16[i])); - } - free (utf16); - } - _cairo_output_stream_printf (pdf_operators->stream, "> >> BDC\n"); - - return _cairo_output_stream_get_status (pdf_operators->stream); -} - -static cairo_status_t -_cairo_pdf_operators_end_actualtext (cairo_pdf_operators_t *pdf_operators) -{ - _cairo_output_stream_printf (pdf_operators->stream, "EMC\n"); - - return _cairo_output_stream_get_status (pdf_operators->stream); -} - -static cairo_status_t -_cairo_pdf_operators_emit_glyph (cairo_pdf_operators_t *pdf_operators, - cairo_glyph_t *glyph, - cairo_scaled_font_subsets_glyph_t *subset_glyph) -{ - double x, y; - cairo_status_t status; - - if (pdf_operators->is_new_text_object || - pdf_operators->font_id != subset_glyph->font_id || - pdf_operators->subset_id != subset_glyph->subset_id) - { - status = _cairo_pdf_operators_flush_glyphs (pdf_operators); - if (unlikely (status)) - return status; - - status = _cairo_pdf_operators_set_font_subset (pdf_operators, subset_glyph); - if (unlikely (status)) - return status; - - pdf_operators->is_new_text_object = FALSE; - } - - x = glyph->x; - y = glyph->y; - cairo_matrix_transform_point (&pdf_operators->cairo_to_pdftext, &x, &y); - - /* The TJ operator for displaying text strings can only set - * the horizontal position of the glyphs. If the y position - * (in text space) changes, use the Td operator to change the - * current position to the next glyph. We also use the Td - * operator to move the current position if the horizontal - * position changes by more than 10 (in text space - * units). This is becauses the horizontal glyph positioning - * in the TJ operator is intended for kerning and there may be - * PDF consumers that do not handle very large position - * adjustments in TJ. - */ - if (fabs(x - pdf_operators->glyph_buf_x_pos) > 10 || - fabs(y - pdf_operators->cur_y) > GLYPH_POSITION_TOLERANCE) - { - status = _cairo_pdf_operators_flush_glyphs (pdf_operators); - if (unlikely (status)) - return status; - - x = glyph->x; - y = glyph->y; - cairo_matrix_transform_point (&pdf_operators->cairo_to_pdf, &x, &y); - status = _cairo_pdf_operators_set_text_position (pdf_operators, x, y); - if (unlikely (status)) - return status; - - x = 0.0; - y = 0.0; - } - - status = _cairo_pdf_operators_add_glyph (pdf_operators, - subset_glyph, - x); - return status; -} - -/* A utf8_len of -1 indicates no unicode text. A utf8_len = 0 is an - * empty string. - */ -static cairo_int_status_t -_cairo_pdf_operators_emit_cluster (cairo_pdf_operators_t *pdf_operators, - const char *utf8, - int utf8_len, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_text_cluster_flags_t cluster_flags, - cairo_scaled_font_t *scaled_font) -{ - cairo_scaled_font_subsets_glyph_t subset_glyph; - cairo_glyph_t *cur_glyph; - cairo_status_t status = CAIRO_STATUS_SUCCESS; - int i; - - /* If the cluster maps 1 glyph to 1 or more unicode characters, we - * first try _map_glyph() with the unicode string to see if it can - * use toUnicode to map our glyph to the unicode. This will fail - * if the glyph is already mapped to a different unicode string. - * - * We also go through this path if no unicode mapping was - * supplied (utf8_len < 0). - * - * Mapping a glyph to a zero length unicode string requires the - * use of ActualText. - */ - if (num_glyphs == 1 && utf8_len != 0) { - status = _cairo_scaled_font_subsets_map_glyph (pdf_operators->font_subsets, - scaled_font, - glyphs->index, - utf8, - utf8_len, - &subset_glyph); - if (unlikely (status)) - return status; - - if (subset_glyph.utf8_is_mapped || utf8_len < 0) { - status = _cairo_pdf_operators_emit_glyph (pdf_operators, - glyphs, - &subset_glyph); - if (unlikely (status)) - return status; - - return CAIRO_STATUS_SUCCESS; - } - } - - if (pdf_operators->use_actual_text) { - /* Fallback to using ActualText to map zero or more glyphs to a - * unicode string. */ - status = _cairo_pdf_operators_flush_glyphs (pdf_operators); - if (unlikely (status)) - return status; - - status = _cairo_pdf_operators_begin_actualtext (pdf_operators, utf8, utf8_len); - if (unlikely (status)) - return status; - } - - if (cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD) - cur_glyph = glyphs + num_glyphs - 1; - else - cur_glyph = glyphs; - - /* XXX - * If no glyphs, we should put *something* here for the text to be selectable. */ - for (i = 0; i < num_glyphs; i++) { - status = _cairo_scaled_font_subsets_map_glyph (pdf_operators->font_subsets, - scaled_font, - cur_glyph->index, - NULL, -1, - &subset_glyph); - if (unlikely (status)) - return status; - - status = _cairo_pdf_operators_emit_glyph (pdf_operators, - cur_glyph, - &subset_glyph); - if (unlikely (status)) - return status; - - if ((cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD)) - cur_glyph--; - else - cur_glyph++; - } - - if (pdf_operators->use_actual_text) { - status = _cairo_pdf_operators_flush_glyphs (pdf_operators); - if (unlikely (status)) - return status; - - status = _cairo_pdf_operators_end_actualtext (pdf_operators); - } - - return status; -} - -cairo_int_status_t -_cairo_pdf_operators_show_text_glyphs (cairo_pdf_operators_t *pdf_operators, - const char *utf8, - int utf8_len, - cairo_glyph_t *glyphs, - int num_glyphs, - const cairo_text_cluster_t *clusters, - int num_clusters, - cairo_text_cluster_flags_t cluster_flags, - cairo_scaled_font_t *scaled_font) -{ - cairo_status_t status; - int i; - cairo_matrix_t text_matrix, invert_y_axis; - double x, y; - const char *cur_text; - cairo_glyph_t *cur_glyph; - - pdf_operators->font_matrix_inverse = scaled_font->font_matrix; - status = cairo_matrix_invert (&pdf_operators->font_matrix_inverse); - if (status == CAIRO_STATUS_INVALID_MATRIX) - return CAIRO_STATUS_SUCCESS; - assert (status == CAIRO_STATUS_SUCCESS); - - pdf_operators->is_new_text_object = FALSE; - if (pdf_operators->in_text_object == FALSE) { - status = _cairo_pdf_operators_begin_text (pdf_operators); - if (unlikely (status)) - return status; - - /* Force Tm and Tf to be emitted when starting a new text - * object.*/ - pdf_operators->is_new_text_object = TRUE; - } - - cairo_matrix_init_scale (&invert_y_axis, 1, -1); - text_matrix = scaled_font->scale; - - /* Invert y axis in font space */ - cairo_matrix_multiply (&text_matrix, &text_matrix, &invert_y_axis); - - /* Invert y axis in device space */ - cairo_matrix_multiply (&text_matrix, &invert_y_axis, &text_matrix); - - if (pdf_operators->is_new_text_object || - ! _cairo_matrix_scale_equal (&pdf_operators->text_matrix, &text_matrix)) - { - status = _cairo_pdf_operators_flush_glyphs (pdf_operators); - if (unlikely (status)) - return status; - - x = glyphs[0].x; - y = glyphs[0].y; - cairo_matrix_transform_point (&pdf_operators->cairo_to_pdf, &x, &y); - text_matrix.x0 = x; - text_matrix.y0 = y; - status = _cairo_pdf_operators_set_text_matrix (pdf_operators, &text_matrix); - if (status == CAIRO_STATUS_INVALID_MATRIX) - return CAIRO_STATUS_SUCCESS; - if (unlikely (status)) - return status; - } - - if (num_clusters > 0) { - cur_text = utf8; - if ((cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD)) - cur_glyph = glyphs + num_glyphs; - else - cur_glyph = glyphs; - for (i = 0; i < num_clusters; i++) { - if ((cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD)) - cur_glyph -= clusters[i].num_glyphs; - status = _cairo_pdf_operators_emit_cluster (pdf_operators, - cur_text, - clusters[i].num_bytes, - cur_glyph, - clusters[i].num_glyphs, - cluster_flags, - scaled_font); - if (unlikely (status)) - return status; - - cur_text += clusters[i].num_bytes; - if (!(cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD)) - cur_glyph += clusters[i].num_glyphs; - } - } else { - for (i = 0; i < num_glyphs; i++) { - status = _cairo_pdf_operators_emit_cluster (pdf_operators, - NULL, - -1, /* no unicode string available */ - &glyphs[i], - 1, - FALSE, - scaled_font); - if (unlikely (status)) - return status; - } - } - - return _cairo_output_stream_get_status (pdf_operators->stream); -} - -#endif /* CAIRO_HAS_PDF_OPERATORS */ diff --git a/source/libs/cairo/cairo-src/src/cairo-pdf-shading-private.h b/source/libs/cairo/cairo-src/src/cairo-pdf-shading-private.h deleted file mode 100644 index 0ca8cb7d518fd66a14a218d7dcc5668133ee82d3..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-pdf-shading-private.h +++ /dev/null @@ -1,100 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Adrian Johnson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Adrian Johnson. - * - * Contributor(s): - * Adrian Johnson <ajohnson@redneon.com> - */ - -#ifndef CAIRO_PDF_SHADING_H -#define CAIRO_PDF_SHADING_H - -#include "cairo-compiler-private.h" -#include "cairo-types-private.h" -#include "cairo-pattern-private.h" - - -typedef struct _cairo_pdf_shading { - int shading_type; - int bits_per_coordinate; - int bits_per_component; - int bits_per_flag; - double *decode_array; - int decode_array_length; - unsigned char *data; - unsigned long data_length; -} cairo_pdf_shading_t; - - -/** - * _cairo_pdf_shading_init_color: - * @shading: a #cairo_pdf_shading_t to initialize - * @pattern: the #cairo_mesh_pattern_t to initialize from - * - * Generate the PDF shading dictionary data for the a PDF type 7 - * shading from RGB part of the specified mesh pattern. - * - * Return value: %CAIRO_STATUS_SUCCESS if successful, possible errors - * include %CAIRO_STATUS_NO_MEMORY. - **/ -cairo_private cairo_status_t -_cairo_pdf_shading_init_color (cairo_pdf_shading_t *shading, - const cairo_mesh_pattern_t *pattern); - - -/** - * _cairo_pdf_shading_init_alpha: - * @shading: a #cairo_pdf_shading_t to initialize - * @pattern: the #cairo_mesh_pattern_t to initialize from - * - * Generate the PDF shading dictionary data for a PDF type 7 - * shading from alpha part of the specified mesh pattern. - * - * Return value: %CAIRO_STATUS_SUCCESS if successful, possible errors - * include %CAIRO_STATUS_NO_MEMORY. - **/ -cairo_private cairo_status_t -_cairo_pdf_shading_init_alpha (cairo_pdf_shading_t *shading, - const cairo_mesh_pattern_t *pattern); - -/** - * _cairo_pdf_shading_fini: - * @shading: a #cairo_pdf_shading_t - * - * Free all resources associated with @shading. After this call, - * @shading should not be used again without a subsequent call to - * _cairo_pdf_shading_init() again first. - **/ -cairo_private void -_cairo_pdf_shading_fini (cairo_pdf_shading_t *shading); - - -#endif /* CAIRO_PDF_SHADING_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-pdf-shading.c b/source/libs/cairo/cairo-src/src/cairo-pdf-shading.c deleted file mode 100644 index 646e2cd490273408e7a8b6967d3122936e7fe493..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-pdf-shading.c +++ /dev/null @@ -1,279 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Adrian Johnson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Adrian Johnson. - * - * Contributor(s): - * Adrian Johnson <ajohnson@redneon.com> - */ - -#include "cairoint.h" - -#if CAIRO_HAS_PDF_OPERATORS - -#include "cairo-pdf-shading-private.h" - -#include "cairo-array-private.h" -#include "cairo-error-private.h" -#include <float.h> - -static unsigned char * -encode_coordinate (unsigned char *p, double c) -{ - uint32_t f; - - f = c; - *p++ = f >> 24; - *p++ = (f >> 16) & 0xff; - *p++ = (f >> 8) & 0xff; - *p++ = f & 0xff; - - return p; -} - -static unsigned char * -encode_point (unsigned char *p, const cairo_point_double_t *point) -{ - p = encode_coordinate (p, point->x); - p = encode_coordinate (p, point->y); - - return p; -} - -static unsigned char * -encode_color_component (unsigned char *p, double color) -{ - uint16_t c; - - c = _cairo_color_double_to_short (color); - *p++ = c >> 8; - *p++ = c & 0xff; - - return p; -} - -static unsigned char * -encode_color (unsigned char *p, const cairo_color_t *color) -{ - p = encode_color_component (p, color->red); - p = encode_color_component (p, color->green); - p = encode_color_component (p, color->blue); - - return p; -} - -static unsigned char * -encode_alpha (unsigned char *p, const cairo_color_t *color) -{ - p = encode_color_component (p, color->alpha); - - return p; -} - -static cairo_status_t -_cairo_pdf_shading_generate_decode_array (cairo_pdf_shading_t *shading, - const cairo_mesh_pattern_t *mesh, - cairo_bool_t is_alpha) -{ - unsigned int num_color_components, i; - cairo_bool_t is_valid; - - if (is_alpha) - num_color_components = 1; - else - num_color_components = 3; - - shading->decode_array_length = 4 + num_color_components * 2; - shading->decode_array = _cairo_malloc_ab (shading->decode_array_length, - sizeof (double)); - if (unlikely (shading->decode_array == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - is_valid = _cairo_mesh_pattern_coord_box (mesh, - &shading->decode_array[0], - &shading->decode_array[2], - &shading->decode_array[1], - &shading->decode_array[3]); - - assert (is_valid); - assert (shading->decode_array[1] - shading->decode_array[0] >= DBL_EPSILON); - assert (shading->decode_array[3] - shading->decode_array[2] >= DBL_EPSILON); - - for (i = 0; i < num_color_components; i++) { - shading->decode_array[4 + 2*i] = 0; - shading->decode_array[5 + 2*i] = 1; - } - - return CAIRO_STATUS_SUCCESS; -} - -/* The ISO32000 specification mandates this order for the points which - * define the patch. */ -static const int pdf_points_order_i[16] = { - 0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 2, 1, 1, 1, 2, 2 }; -static const int pdf_points_order_j[16] = { - 0, 1, 2, 3, 3, 3, 3, 2, 1, 0, 0, 0, 1, 2, 2, 1 }; - -static cairo_status_t -_cairo_pdf_shading_generate_data (cairo_pdf_shading_t *shading, - const cairo_mesh_pattern_t *mesh, - cairo_bool_t is_alpha) -{ - const cairo_mesh_patch_t *patch; - double x_off, y_off, x_scale, y_scale; - unsigned int num_patches; - unsigned int num_color_components; - unsigned char *p; - unsigned int i, j; - - if (is_alpha) - num_color_components = 1; - else - num_color_components = 3; - - num_patches = _cairo_array_num_elements (&mesh->patches); - patch = _cairo_array_index_const (&mesh->patches, 0); - - /* Each patch requires: - * - * 1 flag - 1 byte - * 16 points. Each point is 2 coordinates. Each coordinate is - * stored in 4 bytes. - * - * 4 colors. Each color is stored in 2 bytes * num_color_components. - */ - shading->data_length = num_patches * (1 + 16 * 2 * 4 + 4 * 2 * num_color_components); - shading->data = malloc (shading->data_length); - if (unlikely (shading->data == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - x_off = shading->decode_array[0]; - y_off = shading->decode_array[2]; - x_scale = UINT32_MAX / (shading->decode_array[1] - x_off); - y_scale = UINT32_MAX / (shading->decode_array[3] - y_off); - - p = shading->data; - for (i = 0; i < num_patches; i++) { - /* edge flag */ - *p++ = 0; - - /* 16 points */ - for (j = 0; j < 16; j++) { - cairo_point_double_t point; - int pi, pj; - - pi = pdf_points_order_i[j]; - pj = pdf_points_order_j[j]; - point = patch[i].points[pi][pj]; - - /* Transform the point as specified in the decode array */ - point.x -= x_off; - point.y -= y_off; - point.x *= x_scale; - point.y *= y_scale; - - /* Make sure that rounding errors don't cause - * wraparounds */ - point.x = _cairo_restrict_value (point.x, 0, UINT32_MAX); - point.y = _cairo_restrict_value (point.y, 0, UINT32_MAX); - - p = encode_point (p, &point); - } - - /* 4 colors */ - for (j = 0; j < 4; j++) { - if (is_alpha) - p = encode_alpha (p, &patch[i].colors[j]); - else - p = encode_color (p, &patch[i].colors[j]); - } - } - - assert (p == shading->data + shading->data_length); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_pdf_shading_init (cairo_pdf_shading_t *shading, - const cairo_mesh_pattern_t *mesh, - cairo_bool_t is_alpha) -{ - cairo_status_t status; - - assert (mesh->base.status == CAIRO_STATUS_SUCCESS); - assert (mesh->current_patch == NULL); - - shading->shading_type = 7; - - /* - * Coordinates from the minimum to the maximum value of the mesh - * map to the [0..UINT32_MAX] range and are represented as - * uint32_t values. - * - * Color components are represented as uint16_t (in a 0.16 fixed - * point format, as in the rest of cairo). - */ - shading->bits_per_coordinate = 32; - shading->bits_per_component = 16; - shading->bits_per_flag = 8; - - shading->decode_array = NULL; - shading->data = NULL; - - status = _cairo_pdf_shading_generate_decode_array (shading, mesh, is_alpha); - if (unlikely (status)) - return status; - - return _cairo_pdf_shading_generate_data (shading, mesh, is_alpha); -} - -cairo_status_t -_cairo_pdf_shading_init_color (cairo_pdf_shading_t *shading, - const cairo_mesh_pattern_t *pattern) -{ - return _cairo_pdf_shading_init (shading, pattern, FALSE); -} - -cairo_status_t -_cairo_pdf_shading_init_alpha (cairo_pdf_shading_t *shading, - const cairo_mesh_pattern_t *pattern) -{ - return _cairo_pdf_shading_init (shading, pattern, TRUE); -} - -void -_cairo_pdf_shading_fini (cairo_pdf_shading_t *shading) -{ - free (shading->data); - free (shading->decode_array); -} - -#endif /* CAIRO_HAS_PDF_OPERATORS */ diff --git a/source/libs/cairo/cairo-src/src/cairo-pdf-surface-private.h b/source/libs/cairo/cairo-src/src/cairo-pdf-surface-private.h deleted file mode 100644 index 618ca4ede9f9b76c54fdeb00569b71dbdb7e084a..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-pdf-surface-private.h +++ /dev/null @@ -1,218 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2004 Red Hat, Inc - * Copyright © 2006 Red Hat, Inc - * Copyright © 2007, 2008 Adrian Johnson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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): - * Kristian Høgsberg <krh@redhat.com> - * Carl Worth <cworth@cworth.org> - * Adrian Johnson <ajohnson@redneon.com> - */ - -#ifndef CAIRO_PDF_SURFACE_PRIVATE_H -#define CAIRO_PDF_SURFACE_PRIVATE_H - -#include "cairo-pdf.h" - -#include "cairo-surface-private.h" -#include "cairo-surface-clipper-private.h" -#include "cairo-pdf-operators-private.h" -#include "cairo-path-fixed-private.h" - -typedef struct _cairo_pdf_resource { - unsigned int id; -} cairo_pdf_resource_t; - -#define CAIRO_NUM_OPERATORS (CAIRO_OPERATOR_HSL_LUMINOSITY + 1) - -typedef struct _cairo_pdf_group_resources { - cairo_bool_t operators[CAIRO_NUM_OPERATORS]; - cairo_array_t alphas; - cairo_array_t smasks; - cairo_array_t patterns; - cairo_array_t shadings; - cairo_array_t xobjects; - cairo_array_t fonts; -} cairo_pdf_group_resources_t; - -typedef struct _cairo_pdf_source_surface_entry { - cairo_hash_entry_t base; - unsigned int id; - unsigned char *unique_id; - unsigned long unique_id_length; - cairo_operator_t operator; - cairo_bool_t interpolate; - cairo_bool_t stencil_mask; - cairo_bool_t smask; - cairo_pdf_resource_t surface_res; - cairo_pdf_resource_t smask_res; - int width; - int height; - cairo_rectangle_int_t extents; -} cairo_pdf_source_surface_entry_t; - -typedef struct _cairo_pdf_source_surface { - cairo_pattern_type_t type; - cairo_surface_t *surface; - cairo_pattern_t *raster_pattern; - cairo_pdf_source_surface_entry_t *hash_entry; -} cairo_pdf_source_surface_t; - -typedef struct _cairo_pdf_pattern { - double width; - double height; - cairo_rectangle_int_t extents; - cairo_pattern_t *pattern; - cairo_pdf_resource_t pattern_res; - cairo_pdf_resource_t gstate_res; - cairo_operator_t operator; - cairo_bool_t is_shading; -} cairo_pdf_pattern_t; - -typedef enum _cairo_pdf_operation { - PDF_PAINT, - PDF_MASK, - PDF_FILL, - PDF_STROKE, - PDF_SHOW_GLYPHS -} cairo_pdf_operation_t; - -typedef struct _cairo_pdf_smask_group { - double width; - double height; - cairo_rectangle_int_t extents; - cairo_pdf_resource_t group_res; - cairo_pdf_operation_t operation; - cairo_pattern_t *source; - cairo_pdf_resource_t source_res; - cairo_pattern_t *mask; - cairo_path_fixed_t path; - cairo_fill_rule_t fill_rule; - cairo_stroke_style_t style; - cairo_matrix_t ctm; - cairo_matrix_t ctm_inverse; - char *utf8; - int utf8_len; - cairo_glyph_t *glyphs; - int num_glyphs; - cairo_text_cluster_t *clusters; - int num_clusters; - cairo_bool_t cluster_flags; - cairo_scaled_font_t *scaled_font; -} cairo_pdf_smask_group_t; - -typedef struct _cairo_pdf_jbig2_global { - unsigned char *id; - unsigned long id_length; - cairo_pdf_resource_t res; - cairo_bool_t emitted; -} cairo_pdf_jbig2_global_t; - -typedef struct _cairo_pdf_surface cairo_pdf_surface_t; - -struct _cairo_pdf_surface { - cairo_surface_t base; - - /* Prefer the name "output" here to avoid confusion over the - * structure within a PDF document known as a "stream". */ - cairo_output_stream_t *output; - - double width; - double height; - cairo_matrix_t cairo_to_pdf; - - cairo_array_t objects; - cairo_array_t pages; - cairo_array_t rgb_linear_functions; - cairo_array_t alpha_linear_functions; - cairo_array_t page_patterns; - cairo_array_t page_surfaces; - cairo_hash_table_t *all_surfaces; - cairo_array_t smask_groups; - cairo_array_t knockout_group; - cairo_array_t jbig2_global; - - cairo_scaled_font_subsets_t *font_subsets; - cairo_array_t fonts; - - cairo_pdf_resource_t next_available_resource; - cairo_pdf_resource_t pages_resource; - - cairo_pdf_version_t pdf_version; - cairo_bool_t compress_content; - - cairo_pdf_resource_t content; - cairo_pdf_resource_t content_resources; - cairo_pdf_group_resources_t resources; - cairo_bool_t has_fallback_images; - cairo_bool_t header_emitted; - - struct { - cairo_bool_t active; - cairo_pdf_resource_t self; - cairo_pdf_resource_t length; - long start_offset; - cairo_bool_t compressed; - cairo_output_stream_t *old_output; - } pdf_stream; - - struct { - cairo_bool_t active; - cairo_output_stream_t *stream; - cairo_output_stream_t *mem_stream; - cairo_output_stream_t *old_output; - cairo_pdf_resource_t resource; - cairo_box_double_t bbox; - cairo_bool_t is_knockout; - } group_stream; - - cairo_surface_clipper_t clipper; - - cairo_pdf_operators_t pdf_operators; - cairo_paginated_mode_t paginated_mode; - cairo_bool_t select_pattern_gstate_saved; - - cairo_bool_t force_fallbacks; - - cairo_operator_t current_operator; - cairo_bool_t current_pattern_is_solid_color; - cairo_bool_t current_color_is_stroke; - double current_color_red; - double current_color_green; - double current_color_blue; - double current_color_alpha; - - cairo_surface_t *paginated_surface; -}; - -#endif /* CAIRO_PDF_SURFACE_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-pdf-surface.c b/source/libs/cairo/cairo-src/src/cairo-pdf-surface.c deleted file mode 100644 index 4bc2947964ed993d32c09c8a0c80b449bb59b5be..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-pdf-surface.c +++ /dev/null @@ -1,7880 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2004 Red Hat, Inc - * Copyright © 2006 Red Hat, Inc - * Copyright © 2007, 2008 Adrian Johnson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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): - * Kristian Høgsberg <krh@redhat.com> - * Carl Worth <cworth@cworth.org> - * Adrian Johnson <ajohnson@redneon.com> - */ - -#define _BSD_SOURCE /* for snprintf() */ -#include "cairoint.h" - -#include "cairo-pdf.h" -#include "cairo-pdf-surface-private.h" -#include "cairo-pdf-operators-private.h" -#include "cairo-pdf-shading-private.h" - -#include "cairo-array-private.h" -#include "cairo-analysis-surface-private.h" -#include "cairo-composite-rectangles-private.h" -#include "cairo-default-context-private.h" -#include "cairo-error-private.h" -#include "cairo-image-surface-inline.h" -#include "cairo-image-info-private.h" -#include "cairo-recording-surface-private.h" -#include "cairo-output-stream-private.h" -#include "cairo-paginated-private.h" -#include "cairo-scaled-font-subsets-private.h" -#include "cairo-surface-clipper-private.h" -#include "cairo-surface-snapshot-inline.h" -#include "cairo-surface-subsurface-private.h" -#include "cairo-type3-glyph-surface-private.h" - -#include <time.h> -#include <zlib.h> - -/* Issues: - * - * - We embed an image in the stream each time it's composited. We - * could add generation counters to surfaces and remember the stream - * ID for a particular generation for a particular surface. - * - * - Backend specific meta data. - */ - -/* - * Page Structure of the Generated PDF: - * - * Each page requiring fallbacks images contains a knockout group at - * the top level. The first operation of the knockout group paints a - * group containing all the supported drawing operations. Fallback - * images (if any) are painted in the knockout group. This ensures - * that fallback images do not composite with any content under the - * fallback images. - * - * Streams: - * - * This PDF surface has three types of streams: - * - PDF Stream - * - Content Stream - * - Group Stream - * - * Calling _cairo_output_stream_printf (surface->output, ...) will - * write to the currently open stream. - * - * PDF Stream: - * A PDF Stream may be opened and closed with the following functions: - * _cairo_pdf_surface_open stream () - * _cairo_pdf_surface_close_stream () - * - * PDF Streams are written directly to the PDF file. They are used for - * fonts, images and patterns. - * - * Content Stream: - * The Content Stream is opened and closed with the following functions: - * _cairo_pdf_surface_open_content_stream () - * _cairo_pdf_surface_close_content_stream () - * - * The Content Stream contains the text and graphics operators. - * - * Group Stream: - * A Group Stream may be opened and closed with the following functions: - * _cairo_pdf_surface_open_group () - * _cairo_pdf_surface_close_group () - * - * A Group Stream is a Form XObject. It is used for short sequences - * of operators. As the content is very short the group is stored in - * memory until it is closed. This allows some optimization such as - * including the Resource dictionary and stream length inside the - * XObject instead of using an indirect object. - */ - -/** - * SECTION:cairo-pdf - * @Title: PDF Surfaces - * @Short_Description: Rendering PDF documents - * @See_Also: #cairo_surface_t - * - * The PDF surface is used to render cairo graphics to Adobe - * PDF files and is a multi-page vector surface backend. - * - * The following mime types are supported: %CAIRO_MIME_TYPE_JPEG, - * %CAIRO_MIME_TYPE_JP2, %CAIRO_MIME_TYPE_UNIQUE_ID, - * %CAIRO_MIME_TYPE_JBIG2, %CAIRO_MIME_TYPE_JBIG2_GLOBAL, - * %CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID. - * - * JBIG2 data in PDF must be in the embedded format as described in - * ISO/IEC 11544. Image specific JBIG2 data must be in - * %CAIRO_MIME_TYPE_JBIG2. Any global segments in the JBIG2 data - * (segments with page association field set to 0) must be in - * %CAIRO_MIME_TYPE_JBIG2_GLOBAL. The global data may be shared by - * multiple images. All images sharing the same global data must set - * %CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID to a unique identifer. At least - * one of the images must provide the global data using - * %CAIRO_MIME_TYPE_JBIG2_GLOBAL. The global data will only be - * embedded once but shared by all JBIG2 images with the same - * %CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID. - **/ - -static cairo_bool_t -_cairo_pdf_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *rectangle); - -/** - * CAIRO_HAS_PDF_SURFACE: - * - * Defined if the PDF surface backend is available. - * This macro can be used to conditionally compile backend-specific code. - * - * Since: 1.2 - **/ - -static const cairo_pdf_version_t _cairo_pdf_versions[] = -{ - CAIRO_PDF_VERSION_1_4, - CAIRO_PDF_VERSION_1_5 -}; - -#define CAIRO_PDF_VERSION_LAST ARRAY_LENGTH (_cairo_pdf_versions) - -static const char * _cairo_pdf_version_strings[CAIRO_PDF_VERSION_LAST] = -{ - "PDF 1.4", - "PDF 1.5" -}; - -static const char *_cairo_pdf_supported_mime_types[] = -{ - CAIRO_MIME_TYPE_JPEG, - CAIRO_MIME_TYPE_JP2, - CAIRO_MIME_TYPE_UNIQUE_ID, - CAIRO_MIME_TYPE_JBIG2, - CAIRO_MIME_TYPE_JBIG2_GLOBAL, - CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID, - NULL -}; - -typedef struct _cairo_pdf_object { - long offset; -} cairo_pdf_object_t; - -typedef struct _cairo_pdf_font { - unsigned int font_id; - unsigned int subset_id; - cairo_pdf_resource_t subset_resource; -} cairo_pdf_font_t; - -typedef struct _cairo_pdf_rgb_linear_function { - cairo_pdf_resource_t resource; - double color1[3]; - double color2[3]; -} cairo_pdf_rgb_linear_function_t; - -typedef struct _cairo_pdf_alpha_linear_function { - cairo_pdf_resource_t resource; - double alpha1; - double alpha2; -} cairo_pdf_alpha_linear_function_t; - -static cairo_pdf_resource_t -_cairo_pdf_surface_new_object (cairo_pdf_surface_t *surface); - -static void -_cairo_pdf_surface_clear (cairo_pdf_surface_t *surface); - -static void -_cairo_pdf_smask_group_destroy (cairo_pdf_smask_group_t *group); - -static cairo_int_status_t -_cairo_pdf_surface_add_font (unsigned int font_id, - unsigned int subset_id, - void *closure); - -static void -_cairo_pdf_group_resources_init (cairo_pdf_group_resources_t *res); - -static cairo_int_status_t -_cairo_pdf_surface_open_stream (cairo_pdf_surface_t *surface, - cairo_pdf_resource_t *resource, - cairo_bool_t compressed, - const char *fmt, - ...) CAIRO_PRINTF_FORMAT(4, 5); -static cairo_int_status_t -_cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface); - -static cairo_int_status_t -_cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface); - -static void -_cairo_pdf_surface_write_pages (cairo_pdf_surface_t *surface); - -static cairo_pdf_resource_t -_cairo_pdf_surface_write_info (cairo_pdf_surface_t *surface); - -static cairo_pdf_resource_t -_cairo_pdf_surface_write_catalog (cairo_pdf_surface_t *surface); - -static long -_cairo_pdf_surface_write_xref (cairo_pdf_surface_t *surface); - -static cairo_int_status_t -_cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface); - -static cairo_int_status_t -_cairo_pdf_surface_emit_font_subsets (cairo_pdf_surface_t *surface); - -static cairo_bool_t -_cairo_pdf_source_surface_equal (const void *key_a, const void *key_b); - -static const cairo_surface_backend_t cairo_pdf_surface_backend; -static const cairo_paginated_surface_backend_t cairo_pdf_surface_paginated_backend; - -static cairo_pdf_resource_t -_cairo_pdf_surface_new_object (cairo_pdf_surface_t *surface) -{ - cairo_pdf_resource_t resource; - cairo_int_status_t status; - cairo_pdf_object_t object; - - object.offset = _cairo_output_stream_get_position (surface->output); - - status = _cairo_array_append (&surface->objects, &object); - if (unlikely (status)) { - resource.id = 0; - return resource; - } - - resource = surface->next_available_resource; - surface->next_available_resource.id++; - - return resource; -} - -static void -_cairo_pdf_surface_update_object (cairo_pdf_surface_t *surface, - cairo_pdf_resource_t resource) -{ - cairo_pdf_object_t *object; - - object = _cairo_array_index (&surface->objects, resource.id - 1); - object->offset = _cairo_output_stream_get_position (surface->output); -} - -static void -_cairo_pdf_surface_set_size_internal (cairo_pdf_surface_t *surface, - double width, - double height) -{ - surface->width = width; - surface->height = height; - cairo_matrix_init (&surface->cairo_to_pdf, 1, 0, 0, -1, 0, height); - _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators, - &surface->cairo_to_pdf); -} - -static cairo_bool_t -_path_covers_bbox (cairo_pdf_surface_t *surface, - cairo_path_fixed_t *path) -{ - cairo_box_t box; - - return _cairo_path_fixed_is_box (path, &box) && - box.p1.x <= 0 && - box.p1.y <= 0 && - box.p2.x >= _cairo_fixed_from_double (surface->width) && - box.p2.y >= _cairo_fixed_from_double (surface->height); -} - -static cairo_status_t -_cairo_pdf_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper, - cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_pdf_surface_t *surface = cairo_container_of (clipper, - cairo_pdf_surface_t, - clipper); - cairo_int_status_t status; - - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - return status; - - if (path == NULL) { - _cairo_output_stream_printf (surface->output, "Q q\n"); - - surface->current_pattern_is_solid_color = FALSE; - _cairo_pdf_operators_reset (&surface->pdf_operators); - - return CAIRO_STATUS_SUCCESS; - } - - if (_path_covers_bbox (surface, path)) - return CAIRO_STATUS_SUCCESS; - - return _cairo_pdf_operators_clip (&surface->pdf_operators, path, fill_rule); -} - -static cairo_surface_t * -_cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output, - double width, - double height) -{ - cairo_pdf_surface_t *surface; - cairo_status_t status, status_ignored; - - surface = malloc (sizeof (cairo_pdf_surface_t)); - if (unlikely (surface == NULL)) { - /* destroy stream on behalf of caller */ - status = _cairo_output_stream_destroy (output); - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - _cairo_surface_init (&surface->base, - &cairo_pdf_surface_backend, - NULL, /* device */ - CAIRO_CONTENT_COLOR_ALPHA); - - surface->output = output; - surface->width = width; - surface->height = height; - cairo_matrix_init (&surface->cairo_to_pdf, 1, 0, 0, -1, 0, height); - - _cairo_array_init (&surface->objects, sizeof (cairo_pdf_object_t)); - _cairo_array_init (&surface->pages, sizeof (cairo_pdf_resource_t)); - _cairo_array_init (&surface->rgb_linear_functions, sizeof (cairo_pdf_rgb_linear_function_t)); - _cairo_array_init (&surface->alpha_linear_functions, sizeof (cairo_pdf_alpha_linear_function_t)); - _cairo_array_init (&surface->fonts, sizeof (cairo_pdf_font_t)); - _cairo_array_init (&surface->smask_groups, sizeof (cairo_pdf_smask_group_t *)); - _cairo_array_init (&surface->knockout_group, sizeof (cairo_pdf_resource_t)); - - _cairo_array_init (&surface->page_patterns, sizeof (cairo_pdf_pattern_t)); - _cairo_array_init (&surface->page_surfaces, sizeof (cairo_pdf_source_surface_t)); - _cairo_array_init (&surface->jbig2_global, sizeof (cairo_pdf_jbig2_global_t)); - surface->all_surfaces = _cairo_hash_table_create (_cairo_pdf_source_surface_equal); - if (unlikely (surface->all_surfaces == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto BAIL0; - } - - _cairo_pdf_group_resources_init (&surface->resources); - - surface->font_subsets = _cairo_scaled_font_subsets_create_composite (); - if (! surface->font_subsets) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto BAIL1; - } - - _cairo_scaled_font_subsets_enable_latin_subset (surface->font_subsets, TRUE); - - surface->next_available_resource.id = 1; - surface->pages_resource = _cairo_pdf_surface_new_object (surface); - if (surface->pages_resource.id == 0) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto BAIL2; - } - - surface->pdf_version = CAIRO_PDF_VERSION_1_5; - surface->compress_content = TRUE; - surface->pdf_stream.active = FALSE; - surface->pdf_stream.old_output = NULL; - surface->group_stream.active = FALSE; - surface->group_stream.stream = NULL; - surface->group_stream.mem_stream = NULL; - - surface->paginated_mode = CAIRO_PAGINATED_MODE_ANALYZE; - - surface->force_fallbacks = FALSE; - surface->select_pattern_gstate_saved = FALSE; - surface->current_pattern_is_solid_color = FALSE; - surface->current_operator = CAIRO_OPERATOR_OVER; - surface->header_emitted = FALSE; - - _cairo_surface_clipper_init (&surface->clipper, - _cairo_pdf_surface_clipper_intersect_clip_path); - - _cairo_pdf_operators_init (&surface->pdf_operators, - surface->output, - &surface->cairo_to_pdf, - surface->font_subsets, - FALSE); - _cairo_pdf_operators_set_font_subsets_callback (&surface->pdf_operators, - _cairo_pdf_surface_add_font, - surface); - _cairo_pdf_operators_enable_actual_text(&surface->pdf_operators, TRUE); - - surface->paginated_surface = _cairo_paginated_surface_create ( - &surface->base, - CAIRO_CONTENT_COLOR_ALPHA, - &cairo_pdf_surface_paginated_backend); - - status = surface->paginated_surface->status; - if (status == CAIRO_STATUS_SUCCESS) { - /* paginated keeps the only reference to surface now, drop ours */ - cairo_surface_destroy (&surface->base); - return surface->paginated_surface; - } - -BAIL2: - _cairo_scaled_font_subsets_destroy (surface->font_subsets); -BAIL1: - _cairo_hash_table_destroy (surface->all_surfaces); -BAIL0: - _cairo_array_fini (&surface->objects); - free (surface); - - /* destroy stream on behalf of caller */ - status_ignored = _cairo_output_stream_destroy (output); - - return _cairo_surface_create_in_error (status); -} - -/** - * cairo_pdf_surface_create_for_stream: - * @write_func: a #cairo_write_func_t to accept the output data, may be %NULL - * to indicate a no-op @write_func. With a no-op @write_func, - * the surface may be queried or used as a source without - * generating any temporary files. - * @closure: the closure argument for @write_func - * @width_in_points: width of the surface, in points (1 point == 1/72.0 inch) - * @height_in_points: height of the surface, in points (1 point == 1/72.0 inch) - * - * Creates a PDF surface of the specified size in points to be written - * incrementally to the stream represented by @write_func and @closure. - * - * Return value: a pointer to the newly created surface. The caller - * owns the surface and should call cairo_surface_destroy() when done - * with it. - * - * This function always returns a valid pointer, but it will return a - * pointer to a "nil" surface if an error such as out of memory - * occurs. You can use cairo_surface_status() to check for this. - * - * Since: 1.2 - **/ -cairo_surface_t * -cairo_pdf_surface_create_for_stream (cairo_write_func_t write_func, - void *closure, - double width_in_points, - double height_in_points) -{ - cairo_output_stream_t *output; - - output = _cairo_output_stream_create (write_func, NULL, closure); - if (_cairo_output_stream_get_status (output)) - return _cairo_surface_create_in_error (_cairo_output_stream_destroy (output)); - - return _cairo_pdf_surface_create_for_stream_internal (output, - width_in_points, - height_in_points); -} - -/** - * cairo_pdf_surface_create: - * @filename: a filename for the PDF output (must be writable), %NULL may be - * used to specify no output. This will generate a PDF surface that - * may be queried and used as a source, without generating a - * temporary file. - * @width_in_points: width of the surface, in points (1 point == 1/72.0 inch) - * @height_in_points: height of the surface, in points (1 point == 1/72.0 inch) - * - * Creates a PDF surface of the specified size in points to be written - * to @filename. - * - * Return value: a pointer to the newly created surface. The caller - * owns the surface and should call cairo_surface_destroy() when done - * with it. - * - * This function always returns a valid pointer, but it will return a - * pointer to a "nil" surface if an error such as out of memory - * occurs. You can use cairo_surface_status() to check for this. - * - * Since: 1.2 - **/ -cairo_surface_t * -cairo_pdf_surface_create (const char *filename, - double width_in_points, - double height_in_points) -{ - cairo_output_stream_t *output; - - output = _cairo_output_stream_create_for_filename (filename); - if (_cairo_output_stream_get_status (output)) - return _cairo_surface_create_in_error (_cairo_output_stream_destroy (output)); - - return _cairo_pdf_surface_create_for_stream_internal (output, - width_in_points, - height_in_points); -} - -static cairo_bool_t -_cairo_surface_is_pdf (cairo_surface_t *surface) -{ - return surface->backend == &cairo_pdf_surface_backend; -} - -/* If the abstract_surface is a paginated surface, and that paginated - * surface's target is a pdf_surface, then set pdf_surface to that - * target. Otherwise return FALSE. - */ -static cairo_bool_t -_extract_pdf_surface (cairo_surface_t *surface, - cairo_pdf_surface_t **pdf_surface) -{ - cairo_surface_t *target; - cairo_status_t status_ignored; - - if (surface->status) - return FALSE; - if (surface->finished) { - status_ignored = _cairo_surface_set_error (surface, - _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - return FALSE; - } - - if (! _cairo_surface_is_paginated (surface)) { - status_ignored = _cairo_surface_set_error (surface, - _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH)); - return FALSE; - } - - target = _cairo_paginated_surface_get_target (surface); - if (target->status) { - status_ignored = _cairo_surface_set_error (surface, - target->status); - return FALSE; - } - if (target->finished) { - status_ignored = _cairo_surface_set_error (surface, - _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - return FALSE; - } - - if (! _cairo_surface_is_pdf (target)) { - status_ignored = _cairo_surface_set_error (surface, - _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH)); - return FALSE; - } - - *pdf_surface = (cairo_pdf_surface_t *) target; - return TRUE; -} - -/** - * cairo_pdf_surface_restrict_to_version: - * @surface: a PDF #cairo_surface_t - * @version: PDF version - * - * Restricts the generated PDF file to @version. See cairo_pdf_get_versions() - * for a list of available version values that can be used here. - * - * This function should only be called before any drawing operations - * have been performed on the given surface. The simplest way to do - * this is to call this function immediately after creating the - * surface. - * - * Since: 1.10 - **/ -void -cairo_pdf_surface_restrict_to_version (cairo_surface_t *abstract_surface, - cairo_pdf_version_t version) -{ - cairo_pdf_surface_t *surface = NULL; /* hide compiler warning */ - - if (! _extract_pdf_surface (abstract_surface, &surface)) - return; - - if (version < CAIRO_PDF_VERSION_LAST) - surface->pdf_version = version; - - _cairo_pdf_operators_enable_actual_text(&surface->pdf_operators, - version >= CAIRO_PDF_VERSION_1_5); -} - -/** - * cairo_pdf_get_versions: - * @versions: supported version list - * @num_versions: list length - * - * Used to retrieve the list of supported versions. See - * cairo_pdf_surface_restrict_to_version(). - * - * Since: 1.10 - **/ -void -cairo_pdf_get_versions (cairo_pdf_version_t const **versions, - int *num_versions) -{ - if (versions != NULL) - *versions = _cairo_pdf_versions; - - if (num_versions != NULL) - *num_versions = CAIRO_PDF_VERSION_LAST; -} - -/** - * cairo_pdf_version_to_string: - * @version: a version id - * - * Get the string representation of the given @version id. This function - * will return %NULL if @version isn't valid. See cairo_pdf_get_versions() - * for a way to get the list of valid version ids. - * - * Return value: the string associated to given version. - * - * Since: 1.10 - **/ -const char * -cairo_pdf_version_to_string (cairo_pdf_version_t version) -{ - if (version >= CAIRO_PDF_VERSION_LAST) - return NULL; - - return _cairo_pdf_version_strings[version]; -} - -/** - * cairo_pdf_surface_set_size: - * @surface: a PDF #cairo_surface_t - * @width_in_points: new surface width, in points (1 point == 1/72.0 inch) - * @height_in_points: new surface height, in points (1 point == 1/72.0 inch) - * - * Changes the size of a PDF surface for the current (and - * subsequent) pages. - * - * This function should only be called before any drawing operations - * have been performed on the current page. The simplest way to do - * this is to call this function immediately after creating the - * surface or immediately after completing a page with either - * cairo_show_page() or cairo_copy_page(). - * - * Since: 1.2 - **/ -void -cairo_pdf_surface_set_size (cairo_surface_t *surface, - double width_in_points, - double height_in_points) -{ - cairo_pdf_surface_t *pdf_surface = NULL; /* hide compiler warning */ - cairo_status_t status; - - if (! _extract_pdf_surface (surface, &pdf_surface)) - return; - - _cairo_pdf_surface_set_size_internal (pdf_surface, - width_in_points, - height_in_points); - status = _cairo_paginated_surface_set_size (pdf_surface->paginated_surface, - width_in_points, - height_in_points); - if (status) - status = _cairo_surface_set_error (surface, status); -} - -static void -_cairo_pdf_surface_clear (cairo_pdf_surface_t *surface) -{ - int i, size; - cairo_pdf_pattern_t *pattern; - cairo_pdf_source_surface_t *src_surface; - cairo_pdf_smask_group_t *group; - - size = _cairo_array_num_elements (&surface->page_patterns); - for (i = 0; i < size; i++) { - pattern = (cairo_pdf_pattern_t *) _cairo_array_index (&surface->page_patterns, i); - cairo_pattern_destroy (pattern->pattern); - } - _cairo_array_truncate (&surface->page_patterns, 0); - - size = _cairo_array_num_elements (&surface->page_surfaces); - for (i = 0; i < size; i++) { - src_surface = (cairo_pdf_source_surface_t *) _cairo_array_index (&surface->page_surfaces, i); - cairo_surface_destroy (src_surface->surface); - } - _cairo_array_truncate (&surface->page_surfaces, 0); - - size = _cairo_array_num_elements (&surface->smask_groups); - for (i = 0; i < size; i++) { - _cairo_array_copy_element (&surface->smask_groups, i, &group); - _cairo_pdf_smask_group_destroy (group); - } - _cairo_array_truncate (&surface->smask_groups, 0); - _cairo_array_truncate (&surface->knockout_group, 0); -} - -static void -_cairo_pdf_group_resources_init (cairo_pdf_group_resources_t *res) -{ - int i; - - for (i = 0; i < CAIRO_NUM_OPERATORS; i++) - res->operators[i] = FALSE; - - _cairo_array_init (&res->alphas, sizeof (double)); - _cairo_array_init (&res->smasks, sizeof (cairo_pdf_resource_t)); - _cairo_array_init (&res->patterns, sizeof (cairo_pdf_resource_t)); - _cairo_array_init (&res->shadings, sizeof (cairo_pdf_resource_t)); - _cairo_array_init (&res->xobjects, sizeof (cairo_pdf_resource_t)); - _cairo_array_init (&res->fonts, sizeof (cairo_pdf_font_t)); -} - -static void -_cairo_pdf_group_resources_fini (cairo_pdf_group_resources_t *res) -{ - _cairo_array_fini (&res->alphas); - _cairo_array_fini (&res->smasks); - _cairo_array_fini (&res->patterns); - _cairo_array_fini (&res->shadings); - _cairo_array_fini (&res->xobjects); - _cairo_array_fini (&res->fonts); -} - -static void -_cairo_pdf_group_resources_clear (cairo_pdf_group_resources_t *res) -{ - int i; - - for (i = 0; i < CAIRO_NUM_OPERATORS; i++) - res->operators[i] = FALSE; - - _cairo_array_truncate (&res->alphas, 0); - _cairo_array_truncate (&res->smasks, 0); - _cairo_array_truncate (&res->patterns, 0); - _cairo_array_truncate (&res->shadings, 0); - _cairo_array_truncate (&res->xobjects, 0); - _cairo_array_truncate (&res->fonts, 0); -} - -static void -_cairo_pdf_surface_add_operator (cairo_pdf_surface_t *surface, - cairo_operator_t op) -{ - cairo_pdf_group_resources_t *res = &surface->resources; - - res->operators[op] = TRUE; -} - -static cairo_int_status_t -_cairo_pdf_surface_add_alpha (cairo_pdf_surface_t *surface, - double alpha, - int *index) -{ - int num_alphas, i; - double other; - cairo_int_status_t status; - cairo_pdf_group_resources_t *res = &surface->resources; - - num_alphas = _cairo_array_num_elements (&res->alphas); - for (i = 0; i < num_alphas; i++) { - _cairo_array_copy_element (&res->alphas, i, &other); - if (alpha == other) { - *index = i; - return CAIRO_STATUS_SUCCESS; - } - } - - status = _cairo_array_append (&res->alphas, &alpha); - if (unlikely (status)) - return status; - - *index = _cairo_array_num_elements (&res->alphas) - 1; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_pdf_surface_add_smask (cairo_pdf_surface_t *surface, - cairo_pdf_resource_t smask) -{ - return _cairo_array_append (&(surface->resources.smasks), &smask); -} - -static cairo_int_status_t -_cairo_pdf_surface_add_pattern (cairo_pdf_surface_t *surface, - cairo_pdf_resource_t pattern) -{ - return _cairo_array_append (&(surface->resources.patterns), &pattern); -} - -static cairo_int_status_t -_cairo_pdf_surface_add_shading (cairo_pdf_surface_t *surface, - cairo_pdf_resource_t shading) -{ - return _cairo_array_append (&(surface->resources.shadings), &shading); -} - - -static cairo_int_status_t -_cairo_pdf_surface_add_xobject (cairo_pdf_surface_t *surface, - cairo_pdf_resource_t xobject) -{ - return _cairo_array_append (&(surface->resources.xobjects), &xobject); -} - -static cairo_int_status_t -_cairo_pdf_surface_add_font (unsigned int font_id, - unsigned int subset_id, - void *closure) -{ - cairo_pdf_surface_t *surface = closure; - cairo_pdf_font_t font; - int num_fonts, i; - cairo_int_status_t status; - cairo_pdf_group_resources_t *res = &surface->resources; - - num_fonts = _cairo_array_num_elements (&res->fonts); - for (i = 0; i < num_fonts; i++) { - _cairo_array_copy_element (&res->fonts, i, &font); - if (font.font_id == font_id && - font.subset_id == subset_id) - return CAIRO_STATUS_SUCCESS; - } - - num_fonts = _cairo_array_num_elements (&surface->fonts); - for (i = 0; i < num_fonts; i++) { - _cairo_array_copy_element (&surface->fonts, i, &font); - if (font.font_id == font_id && - font.subset_id == subset_id) - return _cairo_array_append (&res->fonts, &font); - } - - font.font_id = font_id; - font.subset_id = subset_id; - font.subset_resource = _cairo_pdf_surface_new_object (surface); - if (font.subset_resource.id == 0) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - status = _cairo_array_append (&surface->fonts, &font); - if (unlikely (status)) - return status; - - return _cairo_array_append (&res->fonts, &font); -} - -static cairo_pdf_resource_t -_cairo_pdf_surface_get_font_resource (cairo_pdf_surface_t *surface, - unsigned int font_id, - unsigned int subset_id) -{ - cairo_pdf_font_t font; - int num_fonts, i; - - num_fonts = _cairo_array_num_elements (&surface->fonts); - for (i = 0; i < num_fonts; i++) { - _cairo_array_copy_element (&surface->fonts, i, &font); - if (font.font_id == font_id && font.subset_id == subset_id) - return font.subset_resource; - } - - font.subset_resource.id = 0; - return font.subset_resource; -} - -static const char * -_cairo_operator_to_pdf_blend_mode (cairo_operator_t op) -{ - switch (op) { - /* The extend blend mode operators */ - case CAIRO_OPERATOR_MULTIPLY: return "Multiply"; - case CAIRO_OPERATOR_SCREEN: return "Screen"; - case CAIRO_OPERATOR_OVERLAY: return "Overlay"; - case CAIRO_OPERATOR_DARKEN: return "Darken"; - case CAIRO_OPERATOR_LIGHTEN: return "Lighten"; - case CAIRO_OPERATOR_COLOR_DODGE: return "ColorDodge"; - case CAIRO_OPERATOR_COLOR_BURN: return "ColorBurn"; - case CAIRO_OPERATOR_HARD_LIGHT: return "HardLight"; - case CAIRO_OPERATOR_SOFT_LIGHT: return "SoftLight"; - case CAIRO_OPERATOR_DIFFERENCE: return "Difference"; - case CAIRO_OPERATOR_EXCLUSION: return "Exclusion"; - case CAIRO_OPERATOR_HSL_HUE: return "Hue"; - case CAIRO_OPERATOR_HSL_SATURATION: return "Saturation"; - case CAIRO_OPERATOR_HSL_COLOR: return "Color"; - case CAIRO_OPERATOR_HSL_LUMINOSITY: return "Luminosity"; - - default: - /* The original Porter-Duff set */ - case CAIRO_OPERATOR_CLEAR: - case CAIRO_OPERATOR_SOURCE: - case CAIRO_OPERATOR_OVER: - case CAIRO_OPERATOR_IN: - case CAIRO_OPERATOR_OUT: - case CAIRO_OPERATOR_ATOP: - case CAIRO_OPERATOR_DEST: - case CAIRO_OPERATOR_DEST_OVER: - case CAIRO_OPERATOR_DEST_IN: - case CAIRO_OPERATOR_DEST_OUT: - case CAIRO_OPERATOR_DEST_ATOP: - case CAIRO_OPERATOR_XOR: - case CAIRO_OPERATOR_ADD: - case CAIRO_OPERATOR_SATURATE: - return "Normal"; - } -} - -static void -_cairo_pdf_surface_emit_group_resources (cairo_pdf_surface_t *surface, - cairo_pdf_group_resources_t *res) -{ - int num_alphas, num_smasks, num_resources, i; - double alpha; - cairo_pdf_resource_t *smask, *pattern, *shading, *xobject; - cairo_pdf_font_t *font; - - _cairo_output_stream_printf (surface->output, "<<\n"); - - num_alphas = _cairo_array_num_elements (&res->alphas); - num_smasks = _cairo_array_num_elements (&res->smasks); - if (num_alphas > 0 || num_smasks > 0) { - _cairo_output_stream_printf (surface->output, - " /ExtGState <<\n"); - - for (i = 0; i < CAIRO_NUM_OPERATORS; i++) { - if (res->operators[i]) { - _cairo_output_stream_printf (surface->output, - " /b%d << /BM /%s >>\n", - i, _cairo_operator_to_pdf_blend_mode(i)); - } - } - - for (i = 0; i < num_alphas; i++) { - _cairo_array_copy_element (&res->alphas, i, &alpha); - _cairo_output_stream_printf (surface->output, - " /a%d << /CA %f /ca %f >>\n", - i, alpha, alpha); - } - - for (i = 0; i < num_smasks; i++) { - smask = _cairo_array_index (&res->smasks, i); - _cairo_output_stream_printf (surface->output, - " /s%d %d 0 R\n", - smask->id, smask->id); - } - - _cairo_output_stream_printf (surface->output, - " >>\n"); - } - - num_resources = _cairo_array_num_elements (&res->patterns); - if (num_resources > 0) { - _cairo_output_stream_printf (surface->output, - " /Pattern <<"); - for (i = 0; i < num_resources; i++) { - pattern = _cairo_array_index (&res->patterns, i); - _cairo_output_stream_printf (surface->output, - " /p%d %d 0 R", - pattern->id, pattern->id); - } - - _cairo_output_stream_printf (surface->output, - " >>\n"); - } - - num_resources = _cairo_array_num_elements (&res->shadings); - if (num_resources > 0) { - _cairo_output_stream_printf (surface->output, - " /Shading <<"); - for (i = 0; i < num_resources; i++) { - shading = _cairo_array_index (&res->shadings, i); - _cairo_output_stream_printf (surface->output, - " /sh%d %d 0 R", - shading->id, shading->id); - } - - _cairo_output_stream_printf (surface->output, - " >>\n"); - } - - num_resources = _cairo_array_num_elements (&res->xobjects); - if (num_resources > 0) { - _cairo_output_stream_printf (surface->output, - " /XObject <<"); - - for (i = 0; i < num_resources; i++) { - xobject = _cairo_array_index (&res->xobjects, i); - _cairo_output_stream_printf (surface->output, - " /x%d %d 0 R", - xobject->id, xobject->id); - } - - _cairo_output_stream_printf (surface->output, - " >>\n"); - } - - num_resources = _cairo_array_num_elements (&res->fonts); - if (num_resources > 0) { - _cairo_output_stream_printf (surface->output," /Font <<\n"); - for (i = 0; i < num_resources; i++) { - font = _cairo_array_index (&res->fonts, i); - _cairo_output_stream_printf (surface->output, - " /f-%d-%d %d 0 R\n", - font->font_id, - font->subset_id, - font->subset_resource.id); - } - _cairo_output_stream_printf (surface->output, " >>\n"); - } - - _cairo_output_stream_printf (surface->output, - ">>\n"); -} - -static cairo_pdf_smask_group_t * -_cairo_pdf_surface_create_smask_group (cairo_pdf_surface_t *surface, - const cairo_rectangle_int_t *extents) -{ - cairo_pdf_smask_group_t *group; - - group = calloc (1, sizeof (cairo_pdf_smask_group_t)); - if (unlikely (group == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return NULL; - } - - group->group_res = _cairo_pdf_surface_new_object (surface); - if (group->group_res.id == 0) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - free (group); - return NULL; - } - group->width = surface->width; - group->height = surface->height; - if (extents != NULL) { - group->extents = *extents; - } else { - group->extents.x = 0; - group->extents.y = 0; - group->extents.width = surface->width; - group->extents.height = surface->height; - } - group->extents = *extents; - - return group; -} - -static void -_cairo_pdf_smask_group_destroy (cairo_pdf_smask_group_t *group) -{ - if (group->operation == PDF_FILL || group->operation == PDF_STROKE) - _cairo_path_fixed_fini (&group->path); - if (group->source) - cairo_pattern_destroy (group->source); - if (group->mask) - cairo_pattern_destroy (group->mask); - free (group->utf8); - free (group->glyphs); - free (group->clusters); - if (group->scaled_font) - cairo_scaled_font_destroy (group->scaled_font); - free (group); -} - -static cairo_int_status_t -_cairo_pdf_surface_add_smask_group (cairo_pdf_surface_t *surface, - cairo_pdf_smask_group_t *group) -{ - return _cairo_array_append (&surface->smask_groups, &group); -} - -static cairo_bool_t -_cairo_pdf_source_surface_equal (const void *key_a, const void *key_b) -{ - const cairo_pdf_source_surface_entry_t *a = key_a; - const cairo_pdf_source_surface_entry_t *b = key_b; - - if (a->interpolate != b->interpolate) - return FALSE; - - if (a->unique_id && b->unique_id && a->unique_id_length == b->unique_id_length) - return (memcmp (a->unique_id, b->unique_id, a->unique_id_length) == 0); - - return (a->id == b->id); -} - -static void -_cairo_pdf_source_surface_init_key (cairo_pdf_source_surface_entry_t *key) -{ - if (key->unique_id && key->unique_id_length > 0) { - key->base.hash = _cairo_hash_bytes (_CAIRO_HASH_INIT_VALUE, - key->unique_id, key->unique_id_length); - } else { - key->base.hash = key->id; - } -} - -static cairo_int_status_t -_cairo_pdf_surface_acquire_source_image_from_pattern (cairo_pdf_surface_t *surface, - const cairo_pattern_t *pattern, - cairo_image_surface_t **image, - void **image_extra) -{ - switch (pattern->type) { - case CAIRO_PATTERN_TYPE_SURFACE: { - cairo_surface_pattern_t *surf_pat = (cairo_surface_pattern_t *) pattern; - return _cairo_surface_acquire_source_image (surf_pat->surface, image, image_extra); - } break; - - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: { - cairo_surface_t *surf; - surf = _cairo_raster_source_pattern_acquire (pattern, &surface->base, NULL); - if (!surf) - return CAIRO_INT_STATUS_UNSUPPORTED; - assert (_cairo_surface_is_image (surf)); - *image = (cairo_image_surface_t *) surf; - } break; - - case CAIRO_PATTERN_TYPE_SOLID: - case CAIRO_PATTERN_TYPE_LINEAR: - case CAIRO_PATTERN_TYPE_RADIAL: - case CAIRO_PATTERN_TYPE_MESH: - default: - ASSERT_NOT_REACHED; - break; - } - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_pdf_surface_release_source_image_from_pattern (cairo_pdf_surface_t *surface, - const cairo_pattern_t *pattern, - cairo_image_surface_t *image, - void *image_extra) -{ - switch (pattern->type) { - case CAIRO_PATTERN_TYPE_SURFACE: { - cairo_surface_pattern_t *surf_pat = (cairo_surface_pattern_t *) pattern; - _cairo_surface_release_source_image (surf_pat->surface, image, image_extra); - } break; - - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - _cairo_raster_source_pattern_release (pattern, &image->base); - break; - - case CAIRO_PATTERN_TYPE_SOLID: - case CAIRO_PATTERN_TYPE_LINEAR: - case CAIRO_PATTERN_TYPE_RADIAL: - case CAIRO_PATTERN_TYPE_MESH: - default: - - ASSERT_NOT_REACHED; - break; - } -} - -static cairo_int_status_t -_get_jbig2_image_info (cairo_surface_t *source, - cairo_image_info_t *info, - const unsigned char **mime_data, - unsigned long *mime_data_length) -{ - cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JBIG2, - mime_data, mime_data_length); - if (*mime_data == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - return _cairo_image_info_get_jbig2_info (info, *mime_data, *mime_data_length); -} - -static cairo_int_status_t -_get_jpx_image_info (cairo_surface_t *source, - cairo_image_info_t *info, - const unsigned char **mime_data, - unsigned long *mime_data_length) -{ - cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JP2, - mime_data, mime_data_length); - if (*mime_data == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - return _cairo_image_info_get_jpx_info (info, *mime_data, *mime_data_length); -} - -static cairo_int_status_t -_get_jpeg_image_info (cairo_surface_t *source, - cairo_image_info_t *info, - const unsigned char **mime_data, - unsigned long *mime_data_length) -{ - cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JPEG, - mime_data, mime_data_length); - if (*mime_data == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - return _cairo_image_info_get_jpeg_info (info, *mime_data, *mime_data_length); -} - -static cairo_int_status_t -_get_source_surface_size (cairo_surface_t *source, - int *width, - int *height, - cairo_rectangle_int_t *extents) -{ - cairo_int_status_t status; - cairo_image_info_t info; - const unsigned char *mime_data; - unsigned long mime_data_length; - - if (source->type == CAIRO_SURFACE_TYPE_RECORDING) { - if (source->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) { - cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) source; - - *extents = sub->extents; - *width = extents->width; - *height = extents->height; - } else { - cairo_surface_t *free_me = NULL; - cairo_rectangle_int_t surf_extents; - cairo_box_t box; - cairo_bool_t bounded; - - if (_cairo_surface_is_snapshot (source)) - free_me = source = _cairo_surface_snapshot_get_target (source); - - status = _cairo_recording_surface_get_ink_bbox ((cairo_recording_surface_t *)source, - &box, NULL); - if (unlikely (status)) { - cairo_surface_destroy (free_me); - return status; - } - - bounded = _cairo_surface_get_extents (source, &surf_extents); - cairo_surface_destroy (free_me); - - *width = surf_extents.width; - *height = surf_extents.height; - - _cairo_box_round_to_rectangle (&box, extents); - } - - return CAIRO_STATUS_SUCCESS; - } - - extents->x = 0; - extents->y = 0; - - status = _get_jbig2_image_info (source, &info, &mime_data, &mime_data_length); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) { - *width = info.width; - *height = info.height; - extents->width = info.width; - extents->height = info.height; - return status; - } - - status = _get_jpx_image_info (source, &info, &mime_data, &mime_data_length); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) { - *width = info.width; - *height = info.height; - extents->width = info.width; - extents->height = info.height; - return status; - } - - status = _get_jpeg_image_info (source, &info, &mime_data, &mime_data_length); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) { - *width = info.width; - *height = info.height; - extents->width = info.width; - extents->height = info.height; - return status; - } - - if (! _cairo_surface_get_extents (source, extents)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - *width = extents->width; - *height = extents->height; - - return CAIRO_STATUS_SUCCESS; -} - -/** - * _cairo_pdf_surface_add_source_surface: - * @surface: the pdf surface - * @source_surface: A #cairo_surface_t to use as the source surface - * @source_pattern: A #cairo_pattern_t of type SURFACE or RASTER_SOURCE to use as the source - * @op: the operator used to composite this source - * @filter: filter type of the source pattern - * @stencil_mask: if true, the surface will be written to the PDF as an /ImageMask - * @smask: if true, only the alpha channel will be written (images only) - * @extents: extents of the operation that is using this source - * @smask_res: if not NULL, the image written will specify this resource as the smask for the image (images only) - * @surface_res: return PDF resource number of the surface - * @width: returns width of surface - * @height: returns height of surface - * @x_offset: x offset of surface - * @t_offset: y offset of surface - * @source_extents: returns extents of source (either ink extents or extents needed to cover @extents) - * - * Add surface or raster_source pattern to list of surfaces to be - * written to the PDF file when the current page is finished. Returns - * a PDF resource to reference the image. A hash table of all images - * in the PDF files (keyed by CAIRO_MIME_TYPE_UNIQUE_ID or surface - * unique_id) to ensure surfaces with the same id are only written - * once to the PDF file. - * - * Only one of @source_pattern or @source_surface is to be - * specified. Set the other to NULL. - **/ -static cairo_int_status_t -_cairo_pdf_surface_add_source_surface (cairo_pdf_surface_t *surface, - cairo_surface_t *source_surface, - const cairo_pattern_t *source_pattern, - cairo_operator_t op, - cairo_filter_t filter, - cairo_bool_t stencil_mask, - cairo_bool_t smask, - const cairo_rectangle_int_t *extents, - cairo_pdf_resource_t *smask_res, - cairo_pdf_resource_t *surface_res, - int *width, - int *height, - double *x_offset, - double *y_offset, - cairo_rectangle_int_t *source_extents) -{ - cairo_pdf_source_surface_t src_surface; - cairo_pdf_source_surface_entry_t surface_key; - cairo_pdf_source_surface_entry_t *surface_entry; - cairo_int_status_t status; - cairo_bool_t interpolate; - unsigned char *unique_id = NULL; - unsigned long unique_id_length = 0; - cairo_image_surface_t *image; - void *image_extra; - - switch (filter) { - default: - case CAIRO_FILTER_GOOD: - case CAIRO_FILTER_BEST: - case CAIRO_FILTER_BILINEAR: - interpolate = TRUE; - break; - case CAIRO_FILTER_FAST: - case CAIRO_FILTER_NEAREST: - case CAIRO_FILTER_GAUSSIAN: - interpolate = FALSE; - break; - } - - *x_offset = 0; - *y_offset = 0; - if (source_pattern) { - if (source_pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE) { - status = _cairo_pdf_surface_acquire_source_image_from_pattern (surface, source_pattern, - &image, &image_extra); - if (unlikely (status)) - return status; - source_surface = &image->base; - cairo_surface_get_device_offset (source_surface, x_offset, y_offset); - } else { - cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) source_pattern; - source_surface = surface_pattern->surface; - } - } - - surface_key.id = source_surface->unique_id; - surface_key.interpolate = interpolate; - cairo_surface_get_mime_data (source_surface, CAIRO_MIME_TYPE_UNIQUE_ID, - (const unsigned char **) &surface_key.unique_id, - &surface_key.unique_id_length); - _cairo_pdf_source_surface_init_key (&surface_key); - surface_entry = _cairo_hash_table_lookup (surface->all_surfaces, &surface_key.base); - if (surface_entry) { - *surface_res = surface_entry->surface_res; - *width = surface_entry->width; - *height = surface_entry->height; - *source_extents = surface_entry->extents; - status = CAIRO_STATUS_SUCCESS; - } else { - status = _get_source_surface_size (source_surface, - width, - height, - source_extents); - if (unlikely(status)) - goto release_source; - - if (surface_key.unique_id && surface_key.unique_id_length > 0) { - unique_id = _cairo_malloc (surface_key.unique_id_length); - if (unique_id == NULL) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto release_source; - } - - unique_id_length = surface_key.unique_id_length; - memcpy (unique_id, surface_key.unique_id, unique_id_length); - } else { - unique_id = NULL; - unique_id_length = 0; - } - } - -release_source: - if (source_pattern && source_pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE) - _cairo_pdf_surface_release_source_image_from_pattern (surface, source_pattern, image, image_extra); - - if (status || surface_entry) - return status; - - surface_entry = malloc (sizeof (cairo_pdf_source_surface_entry_t)); - if (surface_entry == NULL) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail1; - } - - surface_entry->id = surface_key.id; - surface_entry->operator = op; - surface_entry->interpolate = interpolate; - surface_entry->stencil_mask = stencil_mask; - surface_entry->smask = smask; - surface_entry->unique_id_length = unique_id_length; - surface_entry->unique_id = unique_id; - surface_entry->width = *width; - surface_entry->height = *height; - surface_entry->extents = *source_extents; - if (smask_res) - surface_entry->smask_res = *smask_res; - else - surface_entry->smask_res.id = 0; - _cairo_pdf_source_surface_init_key (surface_entry); - - src_surface.hash_entry = surface_entry; - if (source_pattern && source_pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE) { - src_surface.type = CAIRO_PATTERN_TYPE_RASTER_SOURCE; - src_surface.surface = NULL; - status = _cairo_pattern_create_copy (&src_surface.raster_pattern, source_pattern); - if (unlikely (status)) - goto fail2; - - } else { - src_surface.type = CAIRO_PATTERN_TYPE_SURFACE; - src_surface.surface = cairo_surface_reference (source_surface); - src_surface.raster_pattern = NULL; - } - - surface_entry->surface_res = _cairo_pdf_surface_new_object (surface); - if (surface_entry->surface_res.id == 0) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail3; - } - - status = _cairo_array_append (&surface->page_surfaces, &src_surface); - if (unlikely (status)) - goto fail3; - - status = _cairo_hash_table_insert (surface->all_surfaces, - &surface_entry->base); - if (unlikely(status)) - goto fail3; - - *surface_res = surface_entry->surface_res; - - return status; - -fail3: - if (source_pattern && source_pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE) - cairo_pattern_destroy (src_surface.raster_pattern); - else - cairo_surface_destroy (src_surface.surface); - -fail2: - free (surface_entry); - -fail1: - free (unique_id); - - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_add_pdf_pattern_or_shading (cairo_pdf_surface_t *surface, - const cairo_pattern_t *pattern, - cairo_operator_t op, - const cairo_rectangle_int_t *extents, - cairo_bool_t is_shading, - cairo_pdf_resource_t *pattern_res, - cairo_pdf_resource_t *gstate_res) -{ - cairo_pdf_pattern_t pdf_pattern; - cairo_int_status_t status; - - pdf_pattern.is_shading = is_shading; - pdf_pattern.operator = op; - - /* Solid colors are emitted into the content stream */ - if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) { - pattern_res->id = 0; - gstate_res->id = 0; - return CAIRO_INT_STATUS_SUCCESS; - } - - status = _cairo_pattern_create_copy (&pdf_pattern.pattern, pattern); - if (unlikely (status)) - return status; - - pdf_pattern.pattern_res = _cairo_pdf_surface_new_object (surface); - if (pdf_pattern.pattern_res.id == 0) { - cairo_pattern_destroy (pdf_pattern.pattern); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - pdf_pattern.gstate_res.id = 0; - - /* gradient patterns require an smask object to implement transparency */ - if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR || - pattern->type == CAIRO_PATTERN_TYPE_RADIAL || - pattern->type == CAIRO_PATTERN_TYPE_MESH) - { - double min_alpha; - - _cairo_pattern_alpha_range (pattern, &min_alpha, NULL); - if (! CAIRO_ALPHA_IS_OPAQUE (min_alpha)) { - pdf_pattern.gstate_res = _cairo_pdf_surface_new_object (surface); - if (pdf_pattern.gstate_res.id == 0) { - cairo_pattern_destroy (pdf_pattern.pattern); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - } - } - - pdf_pattern.width = surface->width; - pdf_pattern.height = surface->height; - if (extents != NULL) { - pdf_pattern.extents = *extents; - } else { - pdf_pattern.extents.x = 0; - pdf_pattern.extents.y = 0; - pdf_pattern.extents.width = surface->width; - pdf_pattern.extents.height = surface->height; - } - - *pattern_res = pdf_pattern.pattern_res; - *gstate_res = pdf_pattern.gstate_res; - - status = _cairo_array_append (&surface->page_patterns, &pdf_pattern); - if (unlikely (status)) { - cairo_pattern_destroy (pdf_pattern.pattern); - return status; - } - - return CAIRO_INT_STATUS_SUCCESS; -} - -/* Get BBox in PDF coordinates from extents in cairo coordinates */ -static void -_get_bbox_from_extents (double surface_height, - const cairo_rectangle_int_t *extents, - cairo_box_double_t *bbox) -{ - bbox->p1.x = extents->x; - bbox->p1.y = surface_height - (extents->y + extents->height); - bbox->p2.x = extents->x + extents->width; - bbox->p2.y = surface_height - extents->y; -} - -static cairo_int_status_t -_cairo_pdf_surface_add_pdf_shading (cairo_pdf_surface_t *surface, - const cairo_pattern_t *pattern, - cairo_operator_t op, - const cairo_rectangle_int_t *extents, - cairo_pdf_resource_t *shading_res, - cairo_pdf_resource_t *gstate_res) -{ - return _cairo_pdf_surface_add_pdf_pattern_or_shading (surface, - pattern, - op, - extents, - TRUE, - shading_res, - gstate_res); -} - -static cairo_int_status_t -_cairo_pdf_surface_add_pdf_pattern (cairo_pdf_surface_t *surface, - const cairo_pattern_t *pattern, - cairo_operator_t op, - const cairo_rectangle_int_t *extents, - cairo_pdf_resource_t *pattern_res, - cairo_pdf_resource_t *gstate_res) -{ - return _cairo_pdf_surface_add_pdf_pattern_or_shading (surface, - pattern, - op, - extents, - FALSE, - pattern_res, - gstate_res); -} - -static cairo_int_status_t -_cairo_pdf_surface_open_stream (cairo_pdf_surface_t *surface, - cairo_pdf_resource_t *resource, - cairo_bool_t compressed, - const char *fmt, - ...) -{ - va_list ap; - cairo_pdf_resource_t self, length; - cairo_output_stream_t *output = NULL; - - if (resource) { - self = *resource; - _cairo_pdf_surface_update_object (surface, self); - } else { - self = _cairo_pdf_surface_new_object (surface); - if (self.id == 0) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - length = _cairo_pdf_surface_new_object (surface); - if (length.id == 0) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - if (compressed) { - output = _cairo_deflate_stream_create (surface->output); - if (_cairo_output_stream_get_status (output)) - return _cairo_output_stream_destroy (output); - } - - surface->pdf_stream.active = TRUE; - surface->pdf_stream.self = self; - surface->pdf_stream.length = length; - surface->pdf_stream.compressed = compressed; - surface->current_pattern_is_solid_color = FALSE; - surface->current_operator = CAIRO_OPERATOR_OVER; - _cairo_pdf_operators_reset (&surface->pdf_operators); - - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /Length %d 0 R\n", - surface->pdf_stream.self.id, - surface->pdf_stream.length.id); - if (compressed) - _cairo_output_stream_printf (surface->output, - " /Filter /FlateDecode\n"); - - if (fmt != NULL) { - va_start (ap, fmt); - _cairo_output_stream_vprintf (surface->output, fmt, ap); - va_end (ap); - } - - _cairo_output_stream_printf (surface->output, - ">>\n" - "stream\n"); - - surface->pdf_stream.start_offset = _cairo_output_stream_get_position (surface->output); - - if (compressed) { - assert (surface->pdf_stream.old_output == NULL); - surface->pdf_stream.old_output = surface->output; - surface->output = output; - _cairo_pdf_operators_set_stream (&surface->pdf_operators, surface->output); - } - - return _cairo_output_stream_get_status (surface->output); -} - -static cairo_int_status_t -_cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface) -{ - cairo_int_status_t status; - long length; - - if (! surface->pdf_stream.active) - return CAIRO_INT_STATUS_SUCCESS; - - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - - if (surface->pdf_stream.compressed) { - cairo_int_status_t status2; - - status2 = _cairo_output_stream_destroy (surface->output); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) - status = status2; - - surface->output = surface->pdf_stream.old_output; - _cairo_pdf_operators_set_stream (&surface->pdf_operators, surface->output); - surface->pdf_stream.old_output = NULL; - } - - length = _cairo_output_stream_get_position (surface->output) - - surface->pdf_stream.start_offset; - _cairo_output_stream_printf (surface->output, - "\n" - "endstream\n" - "endobj\n"); - - _cairo_pdf_surface_update_object (surface, - surface->pdf_stream.length); - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - " %ld\n" - "endobj\n", - surface->pdf_stream.length.id, - length); - - surface->pdf_stream.active = FALSE; - - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) - status = _cairo_output_stream_get_status (surface->output); - - return status; -} - -static void -_cairo_pdf_surface_write_memory_stream (cairo_pdf_surface_t *surface, - cairo_output_stream_t *mem_stream, - cairo_pdf_resource_t resource, - cairo_pdf_group_resources_t *resources, - cairo_bool_t is_knockout_group, - const cairo_box_double_t *bbox) -{ - _cairo_pdf_surface_update_object (surface, resource); - - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /Type /XObject\n" - " /Length %d\n", - resource.id, - _cairo_memory_stream_length (mem_stream)); - - if (surface->compress_content) { - _cairo_output_stream_printf (surface->output, - " /Filter /FlateDecode\n"); - } - - _cairo_output_stream_printf (surface->output, - " /Subtype /Form\n" - " /BBox [ %f %f %f %f ]\n" - " /Group <<\n" - " /Type /Group\n" - " /S /Transparency\n" - " /I true\n" - " /CS /DeviceRGB\n", - bbox->p1.x, bbox->p1.y, bbox->p2.x, bbox->p2.y); - - if (is_knockout_group) - _cairo_output_stream_printf (surface->output, - " /K true\n"); - - _cairo_output_stream_printf (surface->output, - " >>\n" - " /Resources\n"); - _cairo_pdf_surface_emit_group_resources (surface, resources); - _cairo_output_stream_printf (surface->output, - ">>\n" - "stream\n"); - _cairo_memory_stream_copy (mem_stream, surface->output); - _cairo_output_stream_printf (surface->output, - "endstream\n" - "endobj\n"); -} - -static cairo_int_status_t -_cairo_pdf_surface_open_group (cairo_pdf_surface_t *surface, - const cairo_box_double_t *bbox, - cairo_pdf_resource_t *resource) -{ - cairo_int_status_t status; - - assert (surface->pdf_stream.active == FALSE); - assert (surface->group_stream.active == FALSE); - - surface->group_stream.active = TRUE; - surface->current_pattern_is_solid_color = FALSE; - surface->current_operator = CAIRO_OPERATOR_OVER; - _cairo_pdf_operators_reset (&surface->pdf_operators); - - surface->group_stream.mem_stream = _cairo_memory_stream_create (); - - if (surface->compress_content) { - surface->group_stream.stream = - _cairo_deflate_stream_create (surface->group_stream.mem_stream); - } else { - surface->group_stream.stream = surface->group_stream.mem_stream; - } - status = _cairo_output_stream_get_status (surface->group_stream.stream); - - surface->group_stream.old_output = surface->output; - surface->output = surface->group_stream.stream; - _cairo_pdf_operators_set_stream (&surface->pdf_operators, surface->output); - _cairo_pdf_group_resources_clear (&surface->resources); - - if (resource) { - surface->group_stream.resource = *resource; - } else { - surface->group_stream.resource = _cairo_pdf_surface_new_object (surface); - if (surface->group_stream.resource.id == 0) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - surface->group_stream.is_knockout = FALSE; - surface->group_stream.bbox = *bbox; - - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_open_knockout_group (cairo_pdf_surface_t *surface, - const cairo_box_double_t *bbox) -{ - cairo_int_status_t status; - - status = _cairo_pdf_surface_open_group (surface, bbox, NULL); - if (unlikely (status)) - return status; - - surface->group_stream.is_knockout = TRUE; - - return CAIRO_INT_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_pdf_surface_close_group (cairo_pdf_surface_t *surface, - cairo_pdf_resource_t *group) -{ - cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS, status2; - - assert (surface->pdf_stream.active == FALSE); - assert (surface->group_stream.active == TRUE); - - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - return status; - - if (surface->compress_content) { - status = _cairo_output_stream_destroy (surface->group_stream.stream); - surface->group_stream.stream = NULL; - - _cairo_output_stream_printf (surface->group_stream.mem_stream, - "\n"); - } - surface->output = surface->group_stream.old_output; - _cairo_pdf_operators_set_stream (&surface->pdf_operators, surface->output); - surface->group_stream.active = FALSE; - _cairo_pdf_surface_write_memory_stream (surface, - surface->group_stream.mem_stream, - surface->group_stream.resource, - &surface->resources, - surface->group_stream.is_knockout, - &surface->group_stream.bbox); - if (group) - *group = surface->group_stream.resource; - - status2 = _cairo_output_stream_destroy (surface->group_stream.mem_stream); - if (status == CAIRO_INT_STATUS_SUCCESS) - status = status2; - - surface->group_stream.mem_stream = NULL; - surface->group_stream.stream = NULL; - - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_open_content_stream (cairo_pdf_surface_t *surface, - const cairo_box_double_t *bbox, - cairo_pdf_resource_t *resource, - cairo_bool_t is_form, - cairo_bool_t is_group) -{ - cairo_int_status_t status; - - assert (surface->pdf_stream.active == FALSE); - assert (surface->group_stream.active == FALSE); - - surface->content_resources = _cairo_pdf_surface_new_object (surface); - if (surface->content_resources.id == 0) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - if (is_form) { - assert (bbox != NULL); - - if (is_group) { - status = - _cairo_pdf_surface_open_stream (surface, - resource, - surface->compress_content, - " /Type /XObject\n" - " /Subtype /Form\n" - " /BBox [ %f %f %f %f ]\n" - " /Group <<\n" - " /Type /Group\n" - " /S /Transparency\n" - " /I true\n" - " /CS /DeviceRGB\n" - " >>\n" - " /Resources %d 0 R\n", - bbox->p1.x, - bbox->p1.y, - bbox->p2.x, - bbox->p2.y, - surface->content_resources.id); - } else { - status = - _cairo_pdf_surface_open_stream (surface, - resource, - surface->compress_content, - " /Type /XObject\n" - " /Subtype /Form\n" - " /BBox [ %f %f %f %f ]\n" - " /Resources %d 0 R\n", - bbox->p1.x, - bbox->p1.y, - bbox->p2.x, - bbox->p2.y, - surface->content_resources.id); - } - } else { - status = - _cairo_pdf_surface_open_stream (surface, - resource, - surface->compress_content, - NULL); - } - if (unlikely (status)) - return status; - - surface->content = surface->pdf_stream.self; - - _cairo_output_stream_printf (surface->output, "q\n"); - - return _cairo_output_stream_get_status (surface->output); -} - -static cairo_int_status_t -_cairo_pdf_surface_close_content_stream (cairo_pdf_surface_t *surface) -{ - cairo_int_status_t status; - - assert (surface->pdf_stream.active == TRUE); - assert (surface->group_stream.active == FALSE); - - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->output, "Q\n"); - status = _cairo_pdf_surface_close_stream (surface); - if (unlikely (status)) - return status; - - _cairo_pdf_surface_update_object (surface, surface->content_resources); - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n", - surface->content_resources.id); - _cairo_pdf_surface_emit_group_resources (surface, &surface->resources); - _cairo_output_stream_printf (surface->output, - "endobj\n"); - - return _cairo_output_stream_get_status (surface->output); -} - -static void -_cairo_pdf_source_surface_entry_pluck (void *entry, void *closure) -{ - cairo_pdf_source_surface_entry_t *surface_entry = entry; - cairo_hash_table_t *patterns = closure; - - _cairo_hash_table_remove (patterns, &surface_entry->base); - free (surface_entry->unique_id); - - free (surface_entry); -} - -static cairo_status_t -_cairo_pdf_surface_finish (void *abstract_surface) -{ - cairo_pdf_surface_t *surface = abstract_surface; - long offset; - cairo_pdf_resource_t info, catalog; - cairo_status_t status, status2; - int size, i; - cairo_pdf_jbig2_global_t *global; - - status = surface->base.status; - if (status == CAIRO_STATUS_SUCCESS) - status = _cairo_pdf_surface_emit_font_subsets (surface); - - _cairo_pdf_surface_write_pages (surface); - - info = _cairo_pdf_surface_write_info (surface); - if (info.id == 0 && status == CAIRO_STATUS_SUCCESS) - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - - catalog = _cairo_pdf_surface_write_catalog (surface); - if (catalog.id == 0 && status == CAIRO_STATUS_SUCCESS) - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - - offset = _cairo_pdf_surface_write_xref (surface); - - _cairo_output_stream_printf (surface->output, - "trailer\n" - "<< /Size %d\n" - " /Root %d 0 R\n" - " /Info %d 0 R\n" - ">>\n", - surface->next_available_resource.id, - catalog.id, - info.id); - - _cairo_output_stream_printf (surface->output, - "startxref\n" - "%ld\n" - "%%%%EOF\n", - offset); - - /* pdf_operators has already been flushed when the last stream was - * closed so we should never be writing anything here - however, - * the stream may itself be in an error state. */ - status2 = _cairo_pdf_operators_fini (&surface->pdf_operators); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - - /* close any active streams still open due to fatal errors */ - status2 = _cairo_pdf_surface_close_stream (surface); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - - if (surface->group_stream.stream != NULL) { - status2 = _cairo_output_stream_destroy (surface->group_stream.stream); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - } - if (surface->group_stream.mem_stream != NULL) { - status2 = _cairo_output_stream_destroy (surface->group_stream.mem_stream); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - } - if (surface->pdf_stream.active) - surface->output = surface->pdf_stream.old_output; - if (surface->group_stream.active) - surface->output = surface->group_stream.old_output; - - /* and finish the pdf surface */ - status2 = _cairo_output_stream_destroy (surface->output); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - - _cairo_pdf_surface_clear (surface); - _cairo_pdf_group_resources_fini (&surface->resources); - - _cairo_array_fini (&surface->objects); - _cairo_array_fini (&surface->pages); - _cairo_array_fini (&surface->rgb_linear_functions); - _cairo_array_fini (&surface->alpha_linear_functions); - _cairo_array_fini (&surface->page_patterns); - _cairo_array_fini (&surface->page_surfaces); - _cairo_hash_table_foreach (surface->all_surfaces, - _cairo_pdf_source_surface_entry_pluck, - surface->all_surfaces); - _cairo_hash_table_destroy (surface->all_surfaces); - _cairo_array_fini (&surface->smask_groups); - _cairo_array_fini (&surface->fonts); - _cairo_array_fini (&surface->knockout_group); - - if (surface->font_subsets) { - _cairo_scaled_font_subsets_destroy (surface->font_subsets); - surface->font_subsets = NULL; - } - - size = _cairo_array_num_elements (&surface->jbig2_global); - for (i = 0; i < size; i++) { - global = (cairo_pdf_jbig2_global_t *) _cairo_array_index (&surface->jbig2_global, i); - free(global->id); - if (!global->emitted) - return _cairo_error (CAIRO_STATUS_JBIG2_GLOBAL_MISSING); - } - _cairo_array_fini (&surface->jbig2_global); - - _cairo_array_truncate (&surface->page_surfaces, 0); - - _cairo_surface_clipper_reset (&surface->clipper); - - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_start_page (void *abstract_surface) -{ - cairo_pdf_surface_t *surface = abstract_surface; - - /* Document header */ - if (! surface->header_emitted) { - const char *version; - - switch (surface->pdf_version) { - case CAIRO_PDF_VERSION_1_4: - version = "1.4"; - break; - default: - case CAIRO_PDF_VERSION_1_5: - version = "1.5"; - break; - } - - _cairo_output_stream_printf (surface->output, - "%%PDF-%s\n", version); - _cairo_output_stream_printf (surface->output, - "%%%c%c%c%c\n", 181, 237, 174, 251); - surface->header_emitted = TRUE; - } - - _cairo_pdf_group_resources_clear (&surface->resources); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_pdf_surface_has_fallback_images (void *abstract_surface, - cairo_bool_t has_fallbacks) -{ - cairo_int_status_t status; - cairo_pdf_surface_t *surface = abstract_surface; - cairo_box_double_t bbox; - - surface->has_fallback_images = has_fallbacks; - bbox.p1.x = 0; - bbox.p1.y = 0; - bbox.p2.x = surface->width; - bbox.p2.y = surface->height; - status = _cairo_pdf_surface_open_content_stream (surface, &bbox, NULL, has_fallbacks, has_fallbacks); - if (unlikely (status)) - return status; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_bool_t -_cairo_pdf_surface_supports_fine_grained_fallbacks (void *abstract_surface) -{ - return TRUE; -} - -static cairo_int_status_t -_cairo_pdf_surface_add_padded_image_surface (cairo_pdf_surface_t *surface, - const cairo_pattern_t *source, - const cairo_rectangle_int_t *extents, - cairo_pdf_resource_t *surface_res, - int *width, - int *height, - double *x_offset, - double *y_offset) -{ - cairo_image_surface_t *image; - cairo_surface_t *pad_image; - void *image_extra; - cairo_int_status_t status; - int w, h; - cairo_rectangle_int_t extents2; - cairo_box_t box; - cairo_rectangle_int_t rect; - cairo_surface_pattern_t pad_pattern; - - status = _cairo_pdf_surface_acquire_source_image_from_pattern (surface, source, - &image, &image_extra); - if (unlikely (status)) - return status; - - pad_image = &image->base; - - /* get the operation extents in pattern space */ - _cairo_box_from_rectangle (&box, extents); - _cairo_matrix_transform_bounding_box_fixed (&source->matrix, &box, NULL); - _cairo_box_round_to_rectangle (&box, &rect); - - /* Check if image needs padding to fill extents */ - w = image->width; - h = image->height; - if (_cairo_fixed_integer_ceil(box.p1.x) < 0 || - _cairo_fixed_integer_ceil(box.p1.y) < 0 || - _cairo_fixed_integer_floor(box.p2.x) > w || - _cairo_fixed_integer_floor(box.p2.y) > h) - { - pad_image = _cairo_image_surface_create_with_content (image->base.content, - rect.width, - rect.height); - if (pad_image->status) { - status = pad_image->status; - goto BAIL; - } - - _cairo_pattern_init_for_surface (&pad_pattern, &image->base); - cairo_matrix_init_translate (&pad_pattern.base.matrix, rect.x, rect.y); - pad_pattern.base.extend = CAIRO_EXTEND_PAD; - status = _cairo_surface_paint (pad_image, - CAIRO_OPERATOR_SOURCE, &pad_pattern.base, - NULL); - _cairo_pattern_fini (&pad_pattern.base); - if (unlikely (status)) - goto BAIL; - } - - status = _cairo_pdf_surface_add_source_surface (surface, - pad_image, - NULL, - FALSE, - source->filter, - FALSE, - FALSE, - extents, - NULL, - surface_res, - width, - height, - x_offset, - y_offset, - &extents2); - if (unlikely (status)) - goto BAIL; - - if (pad_image != &image->base) { - /* If using a padded image, replace _add_source_surface - * x/y_offset with padded image offset. Note: - * _add_source_surface only sets a non zero x/y_offset for - * RASTER_SOURCE patterns. _add_source_surface will always set - * x/y_offset to 0 for surfaces so we can ignore the returned - * offset and replace it with the offset required for the - * padded image */ - *x_offset = rect.x; - *y_offset = rect.y; - } - -BAIL: - if (pad_image != &image->base) - cairo_surface_destroy (pad_image); - - _cairo_pdf_surface_release_source_image_from_pattern (surface, source, image, image_extra); - - return status; -} - -/* Emit alpha channel from the image into stream_res. - */ -static cairo_int_status_t -_cairo_pdf_surface_emit_smask (cairo_pdf_surface_t *surface, - cairo_image_surface_t *image, - cairo_bool_t stencil_mask, - cairo_bool_t interpolate, - cairo_pdf_resource_t *stream_res) -{ - cairo_int_status_t status = CAIRO_STATUS_SUCCESS; - char *alpha; - unsigned long alpha_size; - uint32_t *pixel32; - uint8_t *pixel8; - int i, x, y, bit, a; - cairo_image_transparency_t transparency; - - /* This is the only image format we support, which simplifies things. */ - assert (image->format == CAIRO_FORMAT_ARGB32 || - image->format == CAIRO_FORMAT_RGB24 || - image->format == CAIRO_FORMAT_A8 || - image->format == CAIRO_FORMAT_A1 ); - - transparency = _cairo_image_analyze_transparency (image); - if (stencil_mask) { - assert (transparency == CAIRO_IMAGE_IS_OPAQUE || - transparency == CAIRO_IMAGE_HAS_BILEVEL_ALPHA); - } else { - assert (transparency != CAIRO_IMAGE_IS_OPAQUE); - } - - if (transparency == CAIRO_IMAGE_HAS_BILEVEL_ALPHA || transparency == CAIRO_IMAGE_IS_OPAQUE) { - alpha_size = (image->width + 7) / 8 * image->height; - alpha = _cairo_malloc_ab ((image->width+7) / 8, image->height); - } else { - alpha_size = image->height * image->width; - alpha = _cairo_malloc_ab (image->height, image->width); - } - - if (unlikely (alpha == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto CLEANUP; - } - - i = 0; - for (y = 0; y < image->height; y++) { - if (transparency == CAIRO_IMAGE_IS_OPAQUE) { - for (x = 0; x < (image->width + 7) / 8; x++) - alpha[i++] = 0xff; - } else if (image->format == CAIRO_FORMAT_A1) { - pixel8 = (uint8_t *) (image->data + y * image->stride); - - for (x = 0; x < (image->width + 7) / 8; x++, pixel8++) { - a = *pixel8; - a = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (a); - alpha[i++] = a; - } - } else { - pixel8 = (uint8_t *) (image->data + y * image->stride); - pixel32 = (uint32_t *) (image->data + y * image->stride); - bit = 7; - for (x = 0; x < image->width; x++) { - if (image->format == CAIRO_FORMAT_ARGB32) { - a = (*pixel32 & 0xff000000) >> 24; - pixel32++; - } else { - a = *pixel8; - pixel8++; - } - - if (transparency == CAIRO_IMAGE_HAS_ALPHA) { - alpha[i++] = a; - } else { /* transparency == CAIRO_IMAGE_HAS_BILEVEL_ALPHA or CAIRO_IMAGE_IS_OPAQUE */ - if (bit == 7) - alpha[i] = 0; - if (a != 0) - alpha[i] |= (1 << bit); - bit--; - if (bit < 0) { - bit = 7; - i++; - } - } - } - if (bit != 7) - i++; - } - } - - if (stencil_mask) { - status = _cairo_pdf_surface_open_stream (surface, - stream_res, - TRUE, - " /Type /XObject\n" - " /Subtype /Image\n" - " /ImageMask true\n" - " /Width %d\n" - " /Height %d\n" - " /Interpolate %s\n" - " /BitsPerComponent 1\n" - " /Decode [1 0]\n", - image->width, image->height, - interpolate ? "true" : "false"); - } else { - status = _cairo_pdf_surface_open_stream (surface, - stream_res, - TRUE, - " /Type /XObject\n" - " /Subtype /Image\n" - " /Width %d\n" - " /Height %d\n" - " /ColorSpace /DeviceGray\n" - " /Interpolate %s\n" - " /BitsPerComponent %d\n", - image->width, image->height, - interpolate ? "true" : "false", - transparency == CAIRO_IMAGE_HAS_ALPHA ? 8 : 1); - } - if (unlikely (status)) - goto CLEANUP_ALPHA; - - _cairo_output_stream_write (surface->output, alpha, alpha_size); - status = _cairo_pdf_surface_close_stream (surface); - - CLEANUP_ALPHA: - free (alpha); - CLEANUP: - return status; -} - -/** - * _cairo_pdf_surface_emit_image: - * @surface: the pdf surface - * @image_surf: The image to write - * @surface_entry: Contains image resource, smask resource, interpolate and stencil mask parameters. - * - * Emit an image stream using the @image_res resource and write out - * the image data from @image_surf. If @smask_res is not null, @smask_res will - * be specified as the smask for the image. Otherwise emit the an smask if - * the image is requires one. - **/ -static cairo_int_status_t -_cairo_pdf_surface_emit_image (cairo_pdf_surface_t *surface, - cairo_image_surface_t *image_surf, - cairo_pdf_source_surface_entry_t *surface_entry) -{ - cairo_int_status_t status = CAIRO_STATUS_SUCCESS; - char *data; - unsigned long data_size; - uint32_t *pixel; - int i, x, y, bit; - cairo_pdf_resource_t smask = {0}; /* squelch bogus compiler warning */ - cairo_bool_t need_smask; - cairo_image_color_t color; - cairo_image_surface_t *image; - cairo_image_transparency_t transparency; - char smask_buf[30]; - - image = image_surf; - if (image->format != CAIRO_FORMAT_RGB24 && - image->format != CAIRO_FORMAT_ARGB32 && - image->format != CAIRO_FORMAT_A8 && - image->format != CAIRO_FORMAT_A1) - { - cairo_surface_t *surf; - cairo_surface_pattern_t pattern; - - surf = _cairo_image_surface_create_with_content (image_surf->base.content, - image_surf->width, - image_surf->height); - image = (cairo_image_surface_t *) surf; - if (surf->status) { - status = surf->status; - goto CLEANUP; - } - - _cairo_pattern_init_for_surface (&pattern, &image_surf->base); - status = _cairo_surface_paint (surf, - CAIRO_OPERATOR_SOURCE, &pattern.base, - NULL); - _cairo_pattern_fini (&pattern.base); - if (unlikely (status)) - goto CLEANUP; - } - - if (surface_entry->smask || surface_entry->stencil_mask) { - return _cairo_pdf_surface_emit_smask (surface, image, - surface_entry->stencil_mask, - surface_entry->interpolate, - &surface_entry->surface_res); - } - - color = _cairo_image_analyze_color (image); - switch (color) { - default: - case CAIRO_IMAGE_UNKNOWN_COLOR: - ASSERT_NOT_REACHED; - case CAIRO_IMAGE_IS_COLOR: - data_size = image->height * image->width * 3; - data = _cairo_malloc_abc (image->width, image->height, 3); - break; - - case CAIRO_IMAGE_IS_GRAYSCALE: - data_size = image->height * image->width; - data = _cairo_malloc_ab (image->width, image->height); - break; - case CAIRO_IMAGE_IS_MONOCHROME: - data_size = (image->width + 7) / 8 * image->height; - data = _cairo_malloc_ab ((image->width+7) / 8, image->height); - break; - } - if (unlikely (data == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto CLEANUP; - } - - i = 0; - for (y = 0; y < image->height; y++) { - pixel = (uint32_t *) (image->data + y * image->stride); - - bit = 7; - for (x = 0; x < image->width; x++, pixel++) { - int r, g, b; - - /* XXX: We're un-premultiplying alpha here. My reading of the PDF - * specification suggests that we should be able to avoid having - * to do this by filling in the SMask's Matte dictionary - * appropriately, but my attempts to do that so far have - * failed. */ - if (image->format == CAIRO_FORMAT_ARGB32) { - uint8_t a; - a = (*pixel & 0xff000000) >> 24; - if (a == 0) { - r = g = b = 0; - } else { - r = (((*pixel & 0xff0000) >> 16) * 255 + a / 2) / a; - g = (((*pixel & 0x00ff00) >> 8) * 255 + a / 2) / a; - b = (((*pixel & 0x0000ff) >> 0) * 255 + a / 2) / a; - } - } else if (image->format == CAIRO_FORMAT_RGB24) { - r = (*pixel & 0x00ff0000) >> 16; - g = (*pixel & 0x0000ff00) >> 8; - b = (*pixel & 0x000000ff) >> 0; - } else { - r = g = b = 0; - } - - switch (color) { - case CAIRO_IMAGE_IS_COLOR: - case CAIRO_IMAGE_UNKNOWN_COLOR: - data[i++] = r; - data[i++] = g; - data[i++] = b; - break; - - case CAIRO_IMAGE_IS_GRAYSCALE: - data[i++] = r; - break; - - case CAIRO_IMAGE_IS_MONOCHROME: - if (bit == 7) - data[i] = 0; - if (r != 0) - data[i] |= (1 << bit); - bit--; - if (bit < 0) { - bit = 7; - i++; - } - break; - } - } - if (bit != 7) - i++; - } - - if (surface_entry->smask_res.id != 0) { - need_smask = TRUE; - smask = surface_entry->smask_res; - } else { - need_smask = FALSE; - if (image->format == CAIRO_FORMAT_ARGB32 || - image->format == CAIRO_FORMAT_A8 || - image->format == CAIRO_FORMAT_A1) - { - transparency = _cairo_image_analyze_transparency (image); - if (transparency != CAIRO_IMAGE_IS_OPAQUE) { - need_smask = TRUE; - smask = _cairo_pdf_surface_new_object (surface); - if (smask.id == 0) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto CLEANUP_RGB; - } - - status = _cairo_pdf_surface_emit_smask (surface, image, FALSE, surface_entry->interpolate, &smask); - if (unlikely (status)) - goto CLEANUP_RGB; - } - } - } - - if (need_smask) - snprintf(smask_buf, sizeof(smask_buf), " /SMask %d 0 R\n", smask.id); - else - smask_buf[0] = 0; - - status = _cairo_pdf_surface_open_stream (surface, - &surface_entry->surface_res, - TRUE, - " /Type /XObject\n" - " /Subtype /Image\n" - " /Width %d\n" - " /Height %d\n" - " /ColorSpace %s\n" - " /Interpolate %s\n" - " /BitsPerComponent %d\n" - "%s", - image->width, - image->height, - color == CAIRO_IMAGE_IS_COLOR ? "/DeviceRGB" : "/DeviceGray", - surface_entry->interpolate ? "true" : "false", - color == CAIRO_IMAGE_IS_MONOCHROME? 1 : 8, - smask_buf); - if (unlikely (status)) - goto CLEANUP_RGB; - -#undef IMAGE_DICTIONARY - - _cairo_output_stream_write (surface->output, data, data_size); - status = _cairo_pdf_surface_close_stream (surface); - -CLEANUP_RGB: - free (data); -CLEANUP: - if (image != image_surf) - cairo_surface_destroy (&image->base); - - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_lookup_jbig2_global (cairo_pdf_surface_t *surface, - const unsigned char *global_id, - unsigned long global_id_length, - cairo_pdf_jbig2_global_t **entry) -{ - cairo_pdf_jbig2_global_t global; - int size, i; - cairo_int_status_t status; - - size = _cairo_array_num_elements (&surface->jbig2_global); - for (i = 0; i < size; i++) { - *entry = (cairo_pdf_jbig2_global_t *) _cairo_array_index (&surface->jbig2_global, i); - if ((*entry)->id && global_id && (*entry)->id_length == global_id_length - && memcmp((*entry)->id, global_id, global_id_length) == 0) { - return CAIRO_STATUS_SUCCESS; - } - } - - global.id = malloc(global_id_length); - if (unlikely (global.id == NULL)) { - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - memcpy (global.id, global_id, global_id_length); - global.id_length = global_id_length; - global.res = _cairo_pdf_surface_new_object (surface); - if (global.res.id == 0) { - free(global.id); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - global.emitted = FALSE; - status = _cairo_array_append (&surface->jbig2_global, &global); - if (unlikely(status)) - return status; - - size = _cairo_array_num_elements (&surface->jbig2_global); - *entry = (cairo_pdf_jbig2_global_t *) _cairo_array_index (&surface->jbig2_global, size - 1); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_pdf_surface_emit_jbig2_image (cairo_pdf_surface_t *surface, - cairo_surface_t *source, - cairo_pdf_source_surface_entry_t *surface_entry) -{ - cairo_int_status_t status; - const unsigned char *mime_data; - unsigned long mime_data_length; - cairo_image_info_t info; - const unsigned char *global_id; - unsigned long global_id_length; - const unsigned char *global_data; - unsigned long global_data_length; - cairo_pdf_jbig2_global_t *global_entry = NULL; /* hide compiler warning */ - char smask_buf[30]; - char decode_parms_buf[100]; - - cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JBIG2, - &mime_data, &mime_data_length); - if (mime_data == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_image_info_get_jbig2_info (&info, mime_data, mime_data_length); - if (status) - return status; - - cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID, - &global_id, &global_id_length); - if (global_id && global_id_length > 0) { - status = _cairo_pdf_surface_lookup_jbig2_global (surface, global_id, global_id_length, &global_entry); - if (unlikely(status)) - return status; - - if (!global_entry->emitted) { - cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JBIG2_GLOBAL, - &global_data, &global_data_length); - if (global_data) { - status = _cairo_pdf_surface_open_stream (surface, &global_entry->res, FALSE, NULL); - if (unlikely(status)) - return status; - - _cairo_output_stream_write (surface->output, global_data, global_data_length); - status = _cairo_pdf_surface_close_stream (surface); - if (unlikely(status)) - return status; - - global_entry->emitted = TRUE; - } - } - - snprintf(decode_parms_buf, sizeof(decode_parms_buf), - " /DecodeParms << /JBIG2Globals %d 0 R >>\n", global_entry->res.id); - } else { - decode_parms_buf[0] = 0; - } - - if (surface_entry->smask_res.id) - snprintf(smask_buf, sizeof(smask_buf), " /SMask %d 0 R\n", surface_entry->smask_res.id); - else - smask_buf[0] = 0; - - if (surface_entry->stencil_mask) { - status = _cairo_pdf_surface_open_stream (surface, - &surface_entry->surface_res, - FALSE, - " /Type /XObject\n" - " /Subtype /Image\n" - " /ImageMask true\n" - " /Width %d\n" - " /Height %d\n" - " /Interpolate %s\n" - " /BitsPerComponent 1\n" - " /Decode [1 0]\n" - " /Filter /JPXDecode\n" - "%s", - info.width, - info.height, - surface_entry->interpolate ? "true" : "false", - decode_parms_buf); - } else { - status = _cairo_pdf_surface_open_stream (surface, - &surface_entry->surface_res, - FALSE, - " /Type /XObject\n" - " /Subtype /Image\n" - " /Width %d\n" - " /Height %d\n" - " /ColorSpace /DeviceGray\n" - " /BitsPerComponent 1\n" - " /Interpolate %s\n" - "%s" - " /Filter /JBIG2Decode\n" - "%s", - info.width, - info.height, - surface_entry->interpolate ? "true" : "false", - smask_buf, - decode_parms_buf); - } - if (unlikely(status)) - return status; - - _cairo_output_stream_write (surface->output, mime_data, mime_data_length); - status = _cairo_pdf_surface_close_stream (surface); - - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_emit_jpx_image (cairo_pdf_surface_t *surface, - cairo_surface_t *source, - cairo_pdf_source_surface_entry_t *surface_entry) -{ - cairo_int_status_t status; - const unsigned char *mime_data; - unsigned long mime_data_length; - cairo_image_info_t info; - char smask_buf[30]; - - if (surface->pdf_version < CAIRO_PDF_VERSION_1_5) - return CAIRO_INT_STATUS_UNSUPPORTED; - - cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JP2, - &mime_data, &mime_data_length); - if (mime_data == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_image_info_get_jpx_info (&info, mime_data, mime_data_length); - if (status) - return status; - - if ((surface_entry->smask || surface_entry->stencil_mask) && info.num_components != 1) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if ((surface_entry->stencil_mask) && info.bits_per_component != 1) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (surface_entry->smask_res.id) - snprintf(smask_buf, sizeof(smask_buf), " /SMask %d 0 R\n", surface_entry->smask_res.id); - else - smask_buf[0] = 0; - - if (surface_entry->stencil_mask) { - status = _cairo_pdf_surface_open_stream (surface, - &surface_entry->surface_res, - FALSE, - " /Type /XObject\n" - " /Subtype /Image\n" - " /ImageMask true\n" - " /Width %d\n" - " /Height %d\n" - " /Interpolate %s\n" - " /BitsPerComponent 1\n" - " /Decode [1 0]\n" - " /Filter /JPXDecode\n", - info.width, - info.height, - surface_entry->interpolate ? "true" : "false"); - } else { - status = _cairo_pdf_surface_open_stream (surface, - &surface_entry->surface_res, - FALSE, - " /Type /XObject\n" - " /Subtype /Image\n" - " /Width %d\n" - " /Height %d\n" - " /Interpolate %s\n" - "%s" - " /Filter /JPXDecode\n", - info.width, - info.height, - surface_entry->interpolate ? "true" : "false", - smask_buf); - } - if (status) - return status; - - _cairo_output_stream_write (surface->output, mime_data, mime_data_length); - status = _cairo_pdf_surface_close_stream (surface); - - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t *surface, - cairo_surface_t *source, - cairo_pdf_source_surface_entry_t *surface_entry) -{ - cairo_int_status_t status; - const unsigned char *mime_data; - unsigned long mime_data_length; - cairo_image_info_t info; - const char *colorspace; - char smask_buf[30]; - - cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JPEG, - &mime_data, &mime_data_length); - if (unlikely (source->status)) - return source->status; - if (mime_data == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_image_info_get_jpeg_info (&info, mime_data, mime_data_length); - if (unlikely (status)) - return status; - - if ((surface_entry->smask || surface_entry->stencil_mask) && info.num_components != 1) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if ((surface_entry->stencil_mask) && info.bits_per_component != 1) - return CAIRO_INT_STATUS_UNSUPPORTED; - - switch (info.num_components) { - case 1: - colorspace = "/DeviceGray"; - break; - case 3: - colorspace = "/DeviceRGB"; - break; - case 4: - colorspace = "/DeviceCMYK"; - break; - default: - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - if (surface_entry->smask_res.id) - snprintf(smask_buf, sizeof(smask_buf), " /SMask %d 0 R\n", surface_entry->smask_res.id); - else - smask_buf[0] = 0; - - if (surface_entry->stencil_mask) { - status = _cairo_pdf_surface_open_stream (surface, - &surface_entry->surface_res, - FALSE, - " /Type /XObject\n" - " /Subtype /Image\n" - " /ImageMask true\n" - " /Width %d\n" - " /Height %d\n" - " /Interpolate %s\n" - " /BitsPerComponent 1\n" - " /Decode [1 0]\n" - " /Filter /DCTDecode\n", - info.width, - info.height, - surface_entry->interpolate ? "true" : "false"); - } else { - status = _cairo_pdf_surface_open_stream (surface, - &surface_entry->surface_res, - FALSE, - " /Type /XObject\n" - " /Subtype /Image\n" - " /Width %d\n" - " /Height %d\n" - " /ColorSpace %s\n" - " /Interpolate %s\n" - " /BitsPerComponent %d\n" - "%s" - " /Filter /DCTDecode\n", - info.width, - info.height, - colorspace, - surface_entry->interpolate ? "true" : "false", - info.bits_per_component, - smask_buf); - } - if (unlikely (status)) - return status; - - _cairo_output_stream_write (surface->output, mime_data, mime_data_length); - status = _cairo_pdf_surface_close_stream (surface); - - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_emit_image_surface (cairo_pdf_surface_t *surface, - cairo_pdf_source_surface_t *source) -{ - cairo_image_surface_t *image; - void *image_extra; - cairo_int_status_t status; - - if (source->type == CAIRO_PATTERN_TYPE_SURFACE) { - status = _cairo_pdf_surface_emit_jbig2_image (surface, source->surface, source->hash_entry); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - - status = _cairo_pdf_surface_emit_jpx_image (surface, source->surface, source->hash_entry); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - - status = _cairo_pdf_surface_emit_jpeg_image (surface, source->surface, source->hash_entry); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - } - - if (source->type == CAIRO_PATTERN_TYPE_SURFACE) { - status = _cairo_surface_acquire_source_image (source->surface, &image, &image_extra); - } else { - status = _cairo_pdf_surface_acquire_source_image_from_pattern (surface, source->raster_pattern, - &image, &image_extra); - } - if (unlikely (status)) - return status; - - status = _cairo_pdf_surface_emit_image (surface, - image, - source->hash_entry); - - if (source->type == CAIRO_PATTERN_TYPE_SURFACE) - _cairo_surface_release_source_image (source->surface, image, image_extra); - else - _cairo_pdf_surface_release_source_image_from_pattern (surface, source->raster_pattern, - image, image_extra); - - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t *surface, - cairo_pdf_source_surface_t *pdf_source) -{ - double old_width, old_height; - cairo_paginated_mode_t old_paginated_mode; - cairo_surface_clipper_t old_clipper; - cairo_box_double_t bbox; - cairo_int_status_t status; - int alpha = 0; - cairo_surface_t *free_me = NULL; - cairo_surface_t *source; - const cairo_rectangle_int_t *extents; - int width; - int height; - cairo_bool_t is_subsurface; - cairo_bool_t transparency_group; - cairo_recording_surface_t *recording; - - assert (pdf_source->type == CAIRO_PATTERN_TYPE_SURFACE); - extents = &pdf_source->hash_entry->extents; - width = pdf_source->hash_entry->width; - height = pdf_source->hash_entry->height; - is_subsurface = FALSE; - source = pdf_source->surface; - if (_cairo_surface_is_snapshot (source)) { - free_me = source = _cairo_surface_snapshot_get_target (source); - } else if (source->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) { - cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) source; - - source = sub->target; - extents = &sub->extents; - width = extents->width; - height = extents->height; - is_subsurface = TRUE; - } - - assert (source->type == CAIRO_SURFACE_TYPE_RECORDING); - recording = (cairo_recording_surface_t *) source; - - old_width = surface->width; - old_height = surface->height; - old_paginated_mode = surface->paginated_mode; - old_clipper = surface->clipper; - _cairo_surface_clipper_init (&surface->clipper, - _cairo_pdf_surface_clipper_intersect_clip_path); - - _cairo_pdf_surface_set_size_internal (surface, width, height); - - /* Patterns are emitted after fallback images. The paginated mode - * needs to be set to _RENDER while the recording surface is replayed - * back to this surface. - */ - surface->paginated_mode = CAIRO_PAGINATED_MODE_RENDER; - _cairo_pdf_group_resources_clear (&surface->resources); - _get_bbox_from_extents (height, extents, &bbox); - - /* We can optimize away the transparency group allowing the viewer - * to replay the group in place when all operators are OVER and the - * recording contains only opaque and/or clear alpha. - */ - transparency_group = !(pdf_source->hash_entry->operator == CAIRO_OPERATOR_OVER && - _cairo_recording_surface_has_only_bilevel_alpha (recording) && - _cairo_recording_surface_has_only_op_over (recording)); - status = _cairo_pdf_surface_open_content_stream (surface, &bbox, &pdf_source->hash_entry->surface_res, - TRUE, transparency_group); - if (unlikely (status)) - goto err; - - if (source->content == CAIRO_CONTENT_COLOR) { - status = _cairo_pdf_surface_add_alpha (surface, 1.0, &alpha); - if (unlikely (status)) - goto err; - - _cairo_output_stream_printf (surface->output, - "q /a%d gs 0 0 0 rg 0 0 %f %f re f Q\n", - alpha, - surface->width, - surface->height); - } - - status = _cairo_recording_surface_replay_region (source, - is_subsurface ? extents : NULL, - &surface->base, - CAIRO_RECORDING_REGION_NATIVE); - assert (status != CAIRO_INT_STATUS_UNSUPPORTED); - if (unlikely (status)) - goto err; - - status = _cairo_pdf_surface_close_content_stream (surface); - - _cairo_surface_clipper_reset (&surface->clipper); - surface->clipper = old_clipper; - _cairo_pdf_surface_set_size_internal (surface, - old_width, - old_height); - surface->paginated_mode = old_paginated_mode; - -err: - cairo_surface_destroy (free_me); - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_emit_surface (cairo_pdf_surface_t *surface, - cairo_pdf_source_surface_t *src_surface) -{ - if (src_surface->type == CAIRO_PATTERN_TYPE_SURFACE && - src_surface->surface->type == CAIRO_SURFACE_TYPE_RECORDING) - return _cairo_pdf_surface_emit_recording_surface (surface, src_surface); - - return _cairo_pdf_surface_emit_image_surface (surface, src_surface); -} - -static cairo_int_status_t -_cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface, - cairo_pdf_pattern_t *pdf_pattern) -{ - cairo_pattern_t *pattern = pdf_pattern->pattern; - cairo_int_status_t status; - cairo_pdf_resource_t pattern_resource = {0}; - cairo_matrix_t cairo_p2d, pdf_p2d; - cairo_extend_t extend = cairo_pattern_get_extend (pattern); - double xstep, ystep; - cairo_rectangle_int_t pattern_extents; - int pattern_width = 0; /* squelch bogus compiler warning */ - int pattern_height = 0; /* squelch bogus compiler warning */ - double x_offset; - double y_offset; - char draw_surface[200]; - cairo_box_double_t bbox; - - if (pattern->extend == CAIRO_EXTEND_PAD) { - status = _cairo_pdf_surface_add_padded_image_surface (surface, - pattern, - &pdf_pattern->extents, - &pattern_resource, - &pattern_width, - &pattern_height, - &x_offset, - &y_offset); - pattern_extents.x = 0; - pattern_extents.y = 0; - pattern_extents.width = pattern_width; - pattern_extents.height = pattern_height; - } else { - status = _cairo_pdf_surface_add_source_surface (surface, - NULL, - pattern, - pdf_pattern->operator, - pattern->filter, - FALSE, - FALSE, - &pdf_pattern->extents, - NULL, - &pattern_resource, - &pattern_width, - &pattern_height, - &x_offset, - &y_offset, - &pattern_extents); - } - if (unlikely (status)) - return status; - - switch (extend) { - case CAIRO_EXTEND_PAD: - case CAIRO_EXTEND_NONE: - { - /* In PS/PDF, (as far as I can tell), all patterns are - * repeating. So we support cairo's EXTEND_NONE semantics - * by setting the repeat step size to a size large enough - * to guarantee that no more than a single occurrence will - * be visible. - * - * First, map the surface extents into pattern space (since - * xstep and ystep are in pattern space). Then use an upper - * bound on the length of the diagonal of the pattern image - * and the surface as repeat size. This guarantees to never - * repeat visibly. - */ - double x1 = 0.0, y1 = 0.0; - double x2 = surface->width, y2 = surface->height; - _cairo_matrix_transform_bounding_box (&pattern->matrix, - &x1, &y1, &x2, &y2, - NULL); - - /* Rather than computing precise bounds of the union, just - * add the surface extents unconditionally. We only - * required an answer that's large enough, we don't really - * care if it's not as tight as possible.*/ - xstep = ystep = ceil ((x2 - x1) + (y2 - y1) + - pattern_width + pattern_height); - } - break; - case CAIRO_EXTEND_REPEAT: - xstep = pattern_width; - ystep = pattern_height; - break; - case CAIRO_EXTEND_REFLECT: - pattern_extents.x = 0; - pattern_extents.y = 0; - pattern_extents.width = pattern_width*2; - pattern_extents.height = pattern_height*2; - xstep = pattern_width*2; - ystep = pattern_height*2; - break; - /* All the rest (if any) should have been analyzed away, so this - * case should be unreachable. */ - default: - ASSERT_NOT_REACHED; - xstep = 0; - ystep = 0; - } - - /* At this point, (that is, within the surface backend interface), - * the pattern's matrix maps from cairo's device space to cairo's - * pattern space, (both with their origin at the upper-left, and - * cairo's pattern space of size width,height). - * - * Then, we must emit a PDF pattern object that maps from its own - * pattern space, (which has a size that we establish in the BBox - * dictionary entry), to the PDF page's *initial* space, (which - * does not benefit from the Y-axis flipping matrix that we emit - * on each page). So the PDF patterns matrix maps from a - * (width,height) pattern space to a device space with the origin - * in the lower-left corner. - * - * So to handle all of that, we start with an identity matrix for - * the PDF pattern to device matrix. We translate it up by the - * image height then flip it in the Y direction, (moving us from - * the PDF origin to cairo's origin). We then multiply in the - * inverse of the cairo pattern matrix, (since it maps from device - * to pattern, while we're setting up pattern to device). Finally, - * we translate back down by the image height and flip again to - * end up at the lower-left origin that PDF expects. - * - * Additionally, within the stream that paints the pattern itself, - * we are using a PDF image object that has a size of (1,1) so we - * have to scale it up by the image width and height to fill our - * pattern cell. - */ - cairo_p2d = pattern->matrix; - status = cairo_matrix_invert (&cairo_p2d); - /* cairo_pattern_set_matrix ensures the matrix is invertible */ - assert (status == CAIRO_INT_STATUS_SUCCESS); - - cairo_matrix_multiply (&pdf_p2d, &cairo_p2d, &surface->cairo_to_pdf); - cairo_matrix_translate (&pdf_p2d, -x_offset, -y_offset); - cairo_matrix_translate (&pdf_p2d, 0.0, pattern_height); - cairo_matrix_scale (&pdf_p2d, 1.0, -1.0); - - _get_bbox_from_extents (pattern_height, &pattern_extents, &bbox); - _cairo_pdf_surface_update_object (surface, pdf_pattern->pattern_res); - status = _cairo_pdf_surface_open_stream (surface, - &pdf_pattern->pattern_res, - FALSE, - " /PatternType 1\n" - " /BBox [ %f %f %f %f ]\n" - " /XStep %f\n" - " /YStep %f\n" - " /TilingType 1\n" - " /PaintType 1\n" - " /Matrix [ %f %f %f %f %f %f ]\n" - " /Resources << /XObject << /x%d %d 0 R >> >>\n", - bbox.p1.x, bbox.p1.y, bbox.p2.x, bbox.p2.y, - xstep, ystep, - pdf_p2d.xx, pdf_p2d.yx, - pdf_p2d.xy, pdf_p2d.yy, - pdf_p2d.x0, pdf_p2d.y0, - pattern_resource.id, - pattern_resource.id); - if (unlikely (status)) - return status; - - if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE && - ((cairo_surface_pattern_t *) pattern)->surface->type == CAIRO_SURFACE_TYPE_RECORDING) { - snprintf(draw_surface, - sizeof (draw_surface), - "/x%d Do\n", - pattern_resource.id); - } else { - snprintf(draw_surface, - sizeof (draw_surface), - "q %d 0 0 %d 0 0 cm /x%d Do Q", - pattern_width, - pattern_height, - pattern_resource.id); - } - - if (extend == CAIRO_EXTEND_REFLECT) { - _cairo_output_stream_printf (surface->output, - "q 0 0 %d %d re W n %s Q\n" - "q -1 0 0 1 %d 0 cm 0 0 %d %d re W n %s Q\n" - "q 1 0 0 -1 0 %d cm 0 0 %d %d re W n %s Q\n" - "q -1 0 0 -1 %d %d cm 0 0 %d %d re W n %s Q\n", - pattern_width, pattern_height, - draw_surface, - pattern_width*2, pattern_width, pattern_height, - draw_surface, - pattern_height*2, pattern_width, pattern_height, - draw_surface, - pattern_width*2, pattern_height*2, pattern_width, pattern_height, - draw_surface); - } else { - _cairo_output_stream_printf (surface->output, - " %s \n", - draw_surface); - } - - status = _cairo_pdf_surface_close_stream (surface); - if (unlikely (status)) - return status; - - return _cairo_output_stream_get_status (surface->output); -} - -typedef struct _cairo_pdf_color_stop { - double offset; - double color[4]; - cairo_pdf_resource_t resource; -} cairo_pdf_color_stop_t; - -static cairo_int_status_t -cairo_pdf_surface_emit_rgb_linear_function (cairo_pdf_surface_t *surface, - cairo_pdf_color_stop_t *stop1, - cairo_pdf_color_stop_t *stop2, - cairo_pdf_resource_t *function) -{ - int num_elems, i; - cairo_pdf_rgb_linear_function_t elem; - cairo_pdf_resource_t res; - cairo_int_status_t status; - - num_elems = _cairo_array_num_elements (&surface->rgb_linear_functions); - for (i = 0; i < num_elems; i++) { - _cairo_array_copy_element (&surface->rgb_linear_functions, i, &elem); - if (memcmp (&elem.color1[0], &stop1->color[0], sizeof (double)*3) != 0) - continue; - if (memcmp (&elem.color2[0], &stop2->color[0], sizeof (double)*3) != 0) - continue; - *function = elem.resource; - return CAIRO_STATUS_SUCCESS; - } - - res = _cairo_pdf_surface_new_object (surface); - if (res.id == 0) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /FunctionType 2\n" - " /Domain [ 0 1 ]\n" - " /C0 [ %f %f %f ]\n" - " /C1 [ %f %f %f ]\n" - " /N 1\n" - ">>\n" - "endobj\n", - res.id, - stop1->color[0], - stop1->color[1], - stop1->color[2], - stop2->color[0], - stop2->color[1], - stop2->color[2]); - - elem.resource = res; - memcpy (&elem.color1[0], &stop1->color[0], sizeof (double)*3); - memcpy (&elem.color2[0], &stop2->color[0], sizeof (double)*3); - - status = _cairo_array_append (&surface->rgb_linear_functions, &elem); - *function = res; - - return status; -} - -static cairo_int_status_t -cairo_pdf_surface_emit_alpha_linear_function (cairo_pdf_surface_t *surface, - cairo_pdf_color_stop_t *stop1, - cairo_pdf_color_stop_t *stop2, - cairo_pdf_resource_t *function) -{ - int num_elems, i; - cairo_pdf_alpha_linear_function_t elem; - cairo_pdf_resource_t res; - cairo_int_status_t status; - - num_elems = _cairo_array_num_elements (&surface->alpha_linear_functions); - for (i = 0; i < num_elems; i++) { - _cairo_array_copy_element (&surface->alpha_linear_functions, i, &elem); - if (elem.alpha1 != stop1->color[3]) - continue; - if (elem.alpha2 != stop2->color[3]) - continue; - *function = elem.resource; - return CAIRO_STATUS_SUCCESS; - } - - res = _cairo_pdf_surface_new_object (surface); - if (res.id == 0) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /FunctionType 2\n" - " /Domain [ 0 1 ]\n" - " /C0 [ %f ]\n" - " /C1 [ %f ]\n" - " /N 1\n" - ">>\n" - "endobj\n", - res.id, - stop1->color[3], - stop2->color[3]); - - elem.resource = res; - elem.alpha1 = stop1->color[3]; - elem.alpha2 = stop2->color[3]; - - status = _cairo_array_append (&surface->alpha_linear_functions, &elem); - *function = res; - - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_emit_stitched_colorgradient (cairo_pdf_surface_t *surface, - unsigned int n_stops, - cairo_pdf_color_stop_t *stops, - cairo_bool_t is_alpha, - cairo_pdf_resource_t *function) -{ - cairo_pdf_resource_t res; - unsigned int i; - cairo_int_status_t status; - - /* emit linear gradients between pairs of subsequent stops... */ - for (i = 0; i < n_stops-1; i++) { - if (is_alpha) { - status = cairo_pdf_surface_emit_alpha_linear_function (surface, - &stops[i], - &stops[i+1], - &stops[i].resource); - if (unlikely (status)) - return status; - } else { - status = cairo_pdf_surface_emit_rgb_linear_function (surface, - &stops[i], - &stops[i+1], - &stops[i].resource); - if (unlikely (status)) - return status; - } - } - - /* ... and stitch them together */ - res = _cairo_pdf_surface_new_object (surface); - if (res.id == 0) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /FunctionType 3\n" - " /Domain [ %f %f ]\n", - res.id, - stops[0].offset, - stops[n_stops - 1].offset); - - _cairo_output_stream_printf (surface->output, - " /Functions [ "); - for (i = 0; i < n_stops-1; i++) - _cairo_output_stream_printf (surface->output, - "%d 0 R ", stops[i].resource.id); - _cairo_output_stream_printf (surface->output, - "]\n"); - - _cairo_output_stream_printf (surface->output, - " /Bounds [ "); - for (i = 1; i < n_stops-1; i++) - _cairo_output_stream_printf (surface->output, - "%f ", stops[i].offset); - _cairo_output_stream_printf (surface->output, - "]\n"); - - _cairo_output_stream_printf (surface->output, - " /Encode [ "); - for (i = 1; i < n_stops; i++) - _cairo_output_stream_printf (surface->output, - "0 1 "); - _cairo_output_stream_printf (surface->output, - "]\n"); - - _cairo_output_stream_printf (surface->output, - ">>\n" - "endobj\n"); - - *function = res; - - return _cairo_output_stream_get_status (surface->output); -} - - -static void -calc_gradient_color (cairo_pdf_color_stop_t *new_stop, - cairo_pdf_color_stop_t *stop1, - cairo_pdf_color_stop_t *stop2) -{ - int i; - double offset = stop1->offset / (stop1->offset + 1.0 - stop2->offset); - - for (i = 0; i < 4; i++) - new_stop->color[i] = stop1->color[i] + offset*(stop2->color[i] - stop1->color[i]); -} - -#define COLOR_STOP_EPSILON 1e-6 - -static cairo_int_status_t -_cairo_pdf_surface_emit_pattern_stops (cairo_pdf_surface_t *surface, - cairo_gradient_pattern_t *pattern, - cairo_pdf_resource_t *color_function, - cairo_pdf_resource_t *alpha_function) -{ - cairo_pdf_color_stop_t *allstops, *stops; - unsigned int n_stops; - unsigned int i; - cairo_bool_t emit_alpha = FALSE; - cairo_int_status_t status; - - color_function->id = 0; - alpha_function->id = 0; - - allstops = _cairo_malloc_ab ((pattern->n_stops + 2), sizeof (cairo_pdf_color_stop_t)); - if (unlikely (allstops == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - stops = &allstops[1]; - n_stops = pattern->n_stops; - - for (i = 0; i < n_stops; i++) { - stops[i].color[0] = pattern->stops[i].color.red; - stops[i].color[1] = pattern->stops[i].color.green; - stops[i].color[2] = pattern->stops[i].color.blue; - stops[i].color[3] = pattern->stops[i].color.alpha; - if (!CAIRO_ALPHA_IS_OPAQUE (stops[i].color[3])) - emit_alpha = TRUE; - stops[i].offset = pattern->stops[i].offset; - } - - if (pattern->base.extend == CAIRO_EXTEND_REPEAT || - pattern->base.extend == CAIRO_EXTEND_REFLECT) { - if (stops[0].offset > COLOR_STOP_EPSILON) { - if (pattern->base.extend == CAIRO_EXTEND_REFLECT) - memcpy (allstops, stops, sizeof (cairo_pdf_color_stop_t)); - else - calc_gradient_color (&allstops[0], &stops[0], &stops[n_stops-1]); - stops = allstops; - n_stops++; - } - stops[0].offset = 0.0; - - if (stops[n_stops-1].offset < 1.0 - COLOR_STOP_EPSILON) { - if (pattern->base.extend == CAIRO_EXTEND_REFLECT) { - memcpy (&stops[n_stops], - &stops[n_stops - 1], - sizeof (cairo_pdf_color_stop_t)); - } else { - calc_gradient_color (&stops[n_stops], &stops[0], &stops[n_stops-1]); - } - n_stops++; - } - stops[n_stops-1].offset = 1.0; - } - - if (stops[0].offset == stops[n_stops - 1].offset) { - /* - * The first and the last stops have the same offset, but we - * don't want a function with an empty domain, because that - * would provoke underdefined behaviour from rasterisers. - * This can only happen with EXTEND_PAD, because EXTEND_NONE - * is optimised into a clear pattern in cairo-gstate, and - * REFLECT/REPEAT are always transformed to have the first - * stop at t=0 and the last stop at t=1. Thus we want a step - * function going from the first color to the last one. - * - * This can be accomplished by stitching three functions: - * - a constant first color function, - * - a step from the first color to the last color (with empty domain) - * - a constant last color function - */ - cairo_pdf_color_stop_t pad_stops[4]; - - assert (pattern->base.extend == CAIRO_EXTEND_PAD); - - pad_stops[0] = pad_stops[1] = stops[0]; - pad_stops[2] = pad_stops[3] = stops[n_stops - 1]; - - pad_stops[0].offset = 0; - pad_stops[3].offset = 1; - - status = _cairo_pdf_surface_emit_stitched_colorgradient (surface, - 4, - pad_stops, - FALSE, - color_function); - if (unlikely (status)) - goto BAIL; - - if (emit_alpha) { - status = _cairo_pdf_surface_emit_stitched_colorgradient (surface, - 4, - pad_stops, - TRUE, - alpha_function); - if (unlikely (status)) - goto BAIL; - } - } else if (n_stops == 2) { - /* no need for stitched function */ - status = cairo_pdf_surface_emit_rgb_linear_function (surface, - &stops[0], - &stops[n_stops - 1], - color_function); - if (unlikely (status)) - goto BAIL; - - if (emit_alpha) { - status = cairo_pdf_surface_emit_alpha_linear_function (surface, - &stops[0], - &stops[n_stops - 1], - alpha_function); - if (unlikely (status)) - goto BAIL; - } - } else { - /* multiple stops: stitch. XXX possible optimization: regularly spaced - * stops do not require stitching. XXX */ - status = _cairo_pdf_surface_emit_stitched_colorgradient (surface, - n_stops, - stops, - FALSE, - color_function); - if (unlikely (status)) - goto BAIL; - - if (emit_alpha) { - status = _cairo_pdf_surface_emit_stitched_colorgradient (surface, - n_stops, - stops, - TRUE, - alpha_function); - if (unlikely (status)) - goto BAIL; - } - } - -BAIL: - free (allstops); - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_emit_repeating_function (cairo_pdf_surface_t *surface, - cairo_gradient_pattern_t *pattern, - cairo_pdf_resource_t *function, - int begin, - int end) -{ - cairo_pdf_resource_t res; - int i; - - res = _cairo_pdf_surface_new_object (surface); - if (res.id == 0) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /FunctionType 3\n" - " /Domain [ %d %d ]\n", - res.id, - begin, - end); - - _cairo_output_stream_printf (surface->output, - " /Functions [ "); - for (i = begin; i < end; i++) - _cairo_output_stream_printf (surface->output, - "%d 0 R ", function->id); - _cairo_output_stream_printf (surface->output, - "]\n"); - - _cairo_output_stream_printf (surface->output, - " /Bounds [ "); - for (i = begin + 1; i < end; i++) - _cairo_output_stream_printf (surface->output, - "%d ", i); - _cairo_output_stream_printf (surface->output, - "]\n"); - - _cairo_output_stream_printf (surface->output, - " /Encode [ "); - for (i = begin; i < end; i++) { - if ((i % 2) && pattern->base.extend == CAIRO_EXTEND_REFLECT) { - _cairo_output_stream_printf (surface->output, - "1 0 "); - } else { - _cairo_output_stream_printf (surface->output, - "0 1 "); - } - } - _cairo_output_stream_printf (surface->output, - "]\n"); - - _cairo_output_stream_printf (surface->output, - ">>\n" - "endobj\n"); - - *function = res; - - return _cairo_output_stream_get_status (surface->output); -} - -static cairo_int_status_t -cairo_pdf_surface_emit_transparency_group (cairo_pdf_surface_t *surface, - cairo_pdf_pattern_t *pdf_pattern, - cairo_pdf_resource_t gstate_resource, - cairo_pdf_resource_t gradient_mask) -{ - cairo_pdf_resource_t smask_resource; - cairo_int_status_t status; - char buf[100]; - double x1, y1, x2, y2; - - if (pdf_pattern->is_shading) { - snprintf(buf, sizeof(buf), - " /Shading\n" - " << /sh%d %d 0 R >>\n", - gradient_mask.id, - gradient_mask.id); - } else { - snprintf(buf, sizeof(buf), - " /Pattern\n" - " << /p%d %d 0 R >>\n", - gradient_mask.id, - gradient_mask.id); - } - - if (pdf_pattern->is_shading) { - cairo_box_t box; - - /* When emitting a shading operator we are in cairo pattern - * coordinates. _cairo_pdf_surface_paint_gradient has set the - * ctm to the pattern matrix (including the convertion from - * pdf to cairo coordinates) */ - _cairo_box_from_rectangle (&box, &pdf_pattern->extents); - _cairo_box_to_doubles (&box, &x1, &y1, &x2, &y2); - _cairo_matrix_transform_bounding_box (&pdf_pattern->pattern->matrix, &x1, &y1, &x2, &y2, NULL); - } else { - cairo_box_double_t box; - - /* When emitting a shading pattern we are in pdf page - * coordinates. The color and alpha shading patterns painted - * in the XObject below contain the cairo pattern to pdf page - * matrix in the /Matrix entry of the pattern. */ - _get_bbox_from_extents (pdf_pattern->height, &pdf_pattern->extents, &box); - x1 = box.p1.x; - y1 = box.p1.y; - x2 = box.p2.x; - y2 = box.p2.y; - } - status = _cairo_pdf_surface_open_stream (surface, - NULL, - surface->compress_content, - " /Type /XObject\n" - " /Subtype /Form\n" - " /FormType 1\n" - " /BBox [ %f %f %f %f ]\n" - " /Resources\n" - " << /ExtGState\n" - " << /a0 << /ca 1 /CA 1 >>" - " >>\n" - "%s" - " >>\n" - " /Group\n" - " << /Type /Group\n" - " /S /Transparency\n" - " /I true\n" - " /CS /DeviceGray\n" - " >>\n", - x1,y1,x2,y2, - buf); - if (unlikely (status)) - return status; - - if (pdf_pattern->is_shading) { - _cairo_output_stream_printf (surface->output, - "/a0 gs /sh%d sh\n", - gradient_mask.id); - } else { - _cairo_output_stream_printf (surface->output, - "q\n" - "/a0 gs\n" - "/Pattern cs /p%d scn\n" - "0 0 %f %f re\n" - "f\n" - "Q\n", - gradient_mask.id, - surface->width, - surface->height); - } - - status = _cairo_pdf_surface_close_stream (surface); - if (unlikely (status)) - return status; - - smask_resource = _cairo_pdf_surface_new_object (surface); - if (smask_resource.id == 0) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /Type /Mask\n" - " /S /Luminosity\n" - " /G %d 0 R\n" - ">>\n" - "endobj\n", - smask_resource.id, - surface->pdf_stream.self.id); - - /* Create GState which uses the transparency group as an SMask. */ - _cairo_pdf_surface_update_object (surface, gstate_resource); - - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /Type /ExtGState\n" - " /SMask %d 0 R\n" - " /ca 1\n" - " /CA 1\n" - " /AIS false\n" - ">>\n" - "endobj\n", - gstate_resource.id, - smask_resource.id); - - return _cairo_output_stream_get_status (surface->output); -} - -static void -_cairo_pdf_surface_output_gradient (cairo_pdf_surface_t *surface, - const cairo_pdf_pattern_t *pdf_pattern, - cairo_pdf_resource_t pattern_resource, - const cairo_matrix_t *pat_to_pdf, - const cairo_circle_double_t*start, - const cairo_circle_double_t*end, - const double *domain, - const char *colorspace, - cairo_pdf_resource_t color_function) -{ - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n", - pattern_resource.id); - - if (!pdf_pattern->is_shading) { - _cairo_output_stream_printf (surface->output, - "<< /Type /Pattern\n" - " /PatternType 2\n" - " /Matrix [ "); - _cairo_output_stream_print_matrix (surface->output, pat_to_pdf); - _cairo_output_stream_printf (surface->output, - " ]\n" - " /Shading\n"); - } - - if (pdf_pattern->pattern->type == CAIRO_PATTERN_TYPE_LINEAR) { - _cairo_output_stream_printf (surface->output, - " << /ShadingType 2\n" - " /ColorSpace %s\n" - " /Coords [ %f %f %f %f ]\n", - colorspace, - start->center.x, start->center.y, - end->center.x, end->center.y); - } else { - _cairo_output_stream_printf (surface->output, - " << /ShadingType 3\n" - " /ColorSpace %s\n" - " /Coords [ %f %f %f %f %f %f ]\n", - colorspace, - start->center.x, start->center.y, - MAX (start->radius, 0), - end->center.x, end->center.y, - MAX (end->radius, 0)); - } - - _cairo_output_stream_printf (surface->output, - " /Domain [ %f %f ]\n", - domain[0], domain[1]); - - if (pdf_pattern->pattern->extend != CAIRO_EXTEND_NONE) { - _cairo_output_stream_printf (surface->output, - " /Extend [ true true ]\n"); - } else { - _cairo_output_stream_printf (surface->output, - " /Extend [ false false ]\n"); - } - - _cairo_output_stream_printf (surface->output, - " /Function %d 0 R\n" - " >>\n", - color_function.id); - - if (!pdf_pattern->is_shading) { - _cairo_output_stream_printf (surface->output, - ">>\n"); - } - - _cairo_output_stream_printf (surface->output, - "endobj\n"); -} - -static cairo_int_status_t -_cairo_pdf_surface_emit_gradient (cairo_pdf_surface_t *surface, - cairo_pdf_pattern_t *pdf_pattern) -{ - cairo_gradient_pattern_t *pattern = (cairo_gradient_pattern_t *) pdf_pattern->pattern; - cairo_pdf_resource_t color_function, alpha_function; - cairo_matrix_t pat_to_pdf; - cairo_circle_double_t start, end; - double domain[2]; - cairo_int_status_t status; - - assert (pattern->n_stops != 0); - - status = _cairo_pdf_surface_emit_pattern_stops (surface, - pattern, - &color_function, - &alpha_function); - if (unlikely (status)) - return status; - - pat_to_pdf = pattern->base.matrix; - status = cairo_matrix_invert (&pat_to_pdf); - /* cairo_pattern_set_matrix ensures the matrix is invertible */ - assert (status == CAIRO_INT_STATUS_SUCCESS); - cairo_matrix_multiply (&pat_to_pdf, &pat_to_pdf, &surface->cairo_to_pdf); - - if (pattern->base.extend == CAIRO_EXTEND_REPEAT || - pattern->base.extend == CAIRO_EXTEND_REFLECT) - { - double bounds_x1, bounds_x2, bounds_y1, bounds_y2; - double x_scale, y_scale, tolerance; - - /* TODO: use tighter extents */ - bounds_x1 = 0; - bounds_y1 = 0; - bounds_x2 = surface->width; - bounds_y2 = surface->height; - _cairo_matrix_transform_bounding_box (&pattern->base.matrix, - &bounds_x1, &bounds_y1, - &bounds_x2, &bounds_y2, - NULL); - - x_scale = surface->base.x_resolution / surface->base.x_fallback_resolution; - y_scale = surface->base.y_resolution / surface->base.y_fallback_resolution; - - tolerance = fabs (_cairo_matrix_compute_determinant (&pattern->base.matrix)); - tolerance /= _cairo_matrix_transformed_circle_major_axis (&pattern->base.matrix, 1); - tolerance *= MIN (x_scale, y_scale); - - _cairo_gradient_pattern_box_to_parameter (pattern, - bounds_x1, bounds_y1, - bounds_x2, bounds_y2, - tolerance, domain); - } else if (pattern->stops[0].offset == pattern->stops[pattern->n_stops - 1].offset) { - /* - * If the first and the last stop offset are the same, then - * the color function is a step function. - * _cairo_ps_surface_emit_pattern_stops emits it as a stitched - * function no matter how many stops the pattern has. The - * domain of the stitched function will be [0 1] in this case. - * - * This is done to avoid emitting degenerate gradients for - * EXTEND_PAD patterns having a step color function. - */ - domain[0] = 0.0; - domain[1] = 1.0; - - assert (pattern->base.extend == CAIRO_EXTEND_PAD); - } else { - domain[0] = pattern->stops[0].offset; - domain[1] = pattern->stops[pattern->n_stops - 1].offset; - } - - /* PDF requires the first and last stop to be the same as the - * extreme coordinates. For repeating patterns this moves the - * extreme coordinates out to the begin/end of the repeating - * function. For non repeating patterns this may move the extreme - * coordinates in if there are not stops at offset 0 and 1. */ - _cairo_gradient_pattern_interpolate (pattern, domain[0], &start); - _cairo_gradient_pattern_interpolate (pattern, domain[1], &end); - - if (pattern->base.extend == CAIRO_EXTEND_REPEAT || - pattern->base.extend == CAIRO_EXTEND_REFLECT) - { - int repeat_begin, repeat_end; - - repeat_begin = floor (domain[0]); - repeat_end = ceil (domain[1]); - - status = _cairo_pdf_surface_emit_repeating_function (surface, - pattern, - &color_function, - repeat_begin, - repeat_end); - if (unlikely (status)) - return status; - - if (alpha_function.id != 0) { - status = _cairo_pdf_surface_emit_repeating_function (surface, - pattern, - &alpha_function, - repeat_begin, - repeat_end); - if (unlikely (status)) - return status; - } - } else if (pattern->n_stops <= 2) { - /* For EXTEND_NONE and EXTEND_PAD if there are only two stops a - * Type 2 function is used by itself without a stitching - * function. Type 2 functions always have the domain [0 1] */ - domain[0] = 0.0; - domain[1] = 1.0; - } - - _cairo_pdf_surface_update_object (surface, pdf_pattern->pattern_res); - _cairo_pdf_surface_output_gradient (surface, pdf_pattern, - pdf_pattern->pattern_res, - &pat_to_pdf, &start, &end, domain, - "/DeviceRGB", color_function); - - if (alpha_function.id != 0) { - cairo_pdf_resource_t mask_resource; - - assert (pdf_pattern->gstate_res.id != 0); - - /* Create pattern for SMask. */ - mask_resource = _cairo_pdf_surface_new_object (surface); - if (mask_resource.id == 0) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_pdf_surface_output_gradient (surface, pdf_pattern, - mask_resource, - &pat_to_pdf, &start, &end, domain, - "/DeviceGray", alpha_function); - - status = cairo_pdf_surface_emit_transparency_group (surface, - pdf_pattern, - pdf_pattern->gstate_res, - mask_resource); - if (unlikely (status)) - return status; - } - - return _cairo_output_stream_get_status (surface->output); -} - -static cairo_int_status_t -_cairo_pdf_surface_emit_mesh_pattern (cairo_pdf_surface_t *surface, - cairo_pdf_pattern_t *pdf_pattern) -{ - cairo_matrix_t pat_to_pdf; - cairo_int_status_t status; - cairo_pattern_t *pattern = pdf_pattern->pattern; - cairo_pdf_shading_t shading; - int i; - cairo_pdf_resource_t res; - - pat_to_pdf = pattern->matrix; - status = cairo_matrix_invert (&pat_to_pdf); - /* cairo_pattern_set_matrix ensures the matrix is invertible */ - assert (status == CAIRO_INT_STATUS_SUCCESS); - - cairo_matrix_multiply (&pat_to_pdf, &pat_to_pdf, &surface->cairo_to_pdf); - - status = _cairo_pdf_shading_init_color (&shading, (cairo_mesh_pattern_t *) pattern); - if (unlikely (status)) - return status; - - res = _cairo_pdf_surface_new_object (surface); - if (unlikely (res.id == 0)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /ShadingType %d\n" - " /ColorSpace /DeviceRGB\n" - " /BitsPerCoordinate %d\n" - " /BitsPerComponent %d\n" - " /BitsPerFlag %d\n" - " /Decode [", - res.id, - shading.shading_type, - shading.bits_per_coordinate, - shading.bits_per_component, - shading.bits_per_flag); - - for (i = 0; i < shading.decode_array_length; i++) - _cairo_output_stream_printf (surface->output, "%f ", shading.decode_array[i]); - - _cairo_output_stream_printf (surface->output, - "]\n" - " /Length %ld\n" - ">>\n" - "stream\n", - shading.data_length); - - _cairo_output_stream_write (surface->output, shading.data, shading.data_length); - - _cairo_output_stream_printf (surface->output, - "\nendstream\n" - "endobj\n"); - - _cairo_pdf_shading_fini (&shading); - - _cairo_pdf_surface_update_object (surface, pdf_pattern->pattern_res); - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /Type /Pattern\n" - " /PatternType 2\n" - " /Matrix [ ", - pdf_pattern->pattern_res.id); - _cairo_output_stream_print_matrix (surface->output, &pat_to_pdf); - _cairo_output_stream_printf (surface->output, - " ]\n" - " /Shading %d 0 R\n" - ">>\n" - "endobj\n", - res.id); - - if (pdf_pattern->gstate_res.id != 0) { - cairo_pdf_resource_t mask_resource; - - /* Create pattern for SMask. */ - res = _cairo_pdf_surface_new_object (surface); - if (unlikely (res.id == 0)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - status = _cairo_pdf_shading_init_alpha (&shading, (cairo_mesh_pattern_t *) pattern); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /ShadingType %d\n" - " /ColorSpace /DeviceGray\n" - " /BitsPerCoordinate %d\n" - " /BitsPerComponent %d\n" - " /BitsPerFlag %d\n" - " /Decode [", - res.id, - shading.shading_type, - shading.bits_per_coordinate, - shading.bits_per_component, - shading.bits_per_flag); - - for (i = 0; i < shading.decode_array_length; i++) - _cairo_output_stream_printf (surface->output, "%f ", shading.decode_array[i]); - - _cairo_output_stream_printf (surface->output, - "]\n" - " /Length %ld\n" - ">>\n" - "stream\n", - shading.data_length); - - _cairo_output_stream_write (surface->output, shading.data, shading.data_length); - - _cairo_output_stream_printf (surface->output, - "\nendstream\n" - "endobj\n"); - _cairo_pdf_shading_fini (&shading); - - mask_resource = _cairo_pdf_surface_new_object (surface); - if (unlikely (mask_resource.id == 0)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /Type /Pattern\n" - " /PatternType 2\n" - " /Matrix [ ", - mask_resource.id); - _cairo_output_stream_print_matrix (surface->output, &pat_to_pdf); - _cairo_output_stream_printf (surface->output, - " ]\n" - " /Shading %d 0 R\n" - ">>\n" - "endobj\n", - res.id); - - status = cairo_pdf_surface_emit_transparency_group (surface, - pdf_pattern, - pdf_pattern->gstate_res, - mask_resource); - if (unlikely (status)) - return status; - } - - return _cairo_output_stream_get_status (surface->output); -} - -static cairo_int_status_t -_cairo_pdf_surface_emit_pattern (cairo_pdf_surface_t *surface, cairo_pdf_pattern_t *pdf_pattern) -{ - double old_width, old_height; - cairo_int_status_t status; - - old_width = surface->width; - old_height = surface->height; - _cairo_pdf_surface_set_size_internal (surface, - pdf_pattern->width, - pdf_pattern->height); - - switch (pdf_pattern->pattern->type) { - case CAIRO_PATTERN_TYPE_SOLID: - ASSERT_NOT_REACHED; - status = _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH); - break; - - case CAIRO_PATTERN_TYPE_SURFACE: - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - status = _cairo_pdf_surface_emit_surface_pattern (surface, pdf_pattern); - break; - - case CAIRO_PATTERN_TYPE_LINEAR: - case CAIRO_PATTERN_TYPE_RADIAL: - status = _cairo_pdf_surface_emit_gradient (surface, pdf_pattern); - break; - - case CAIRO_PATTERN_TYPE_MESH: - status = _cairo_pdf_surface_emit_mesh_pattern (surface, pdf_pattern); - break; - - default: - ASSERT_NOT_REACHED; - status = _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH); - break; - } - - _cairo_pdf_surface_set_size_internal (surface, - old_width, - old_height); - - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_rectangle_int_t *extents, - cairo_pdf_resource_t *smask_res, - cairo_bool_t stencil_mask) -{ - cairo_pdf_resource_t surface_res; - int width, height; - cairo_matrix_t cairo_p2d, pdf_p2d; - cairo_int_status_t status; - int alpha; - cairo_rectangle_int_t extents2; - double x_offset; - double y_offset; - - if (source->extend == CAIRO_EXTEND_PAD && - !(source->type == CAIRO_PATTERN_TYPE_SURFACE && - ((cairo_surface_pattern_t *)source)->surface->type == CAIRO_SURFACE_TYPE_RECORDING)) - { - status = _cairo_pdf_surface_add_padded_image_surface (surface, - source, - extents, - &surface_res, - &width, - &height, - &x_offset, - &y_offset); - } else { - status = _cairo_pdf_surface_add_source_surface (surface, - NULL, - source, - op, - source->filter, - stencil_mask, - FALSE, - extents, - smask_res, - &surface_res, - &width, - &height, - &x_offset, - &y_offset, - &extents2); - } - if (unlikely (status)) - return status; - - cairo_p2d = source->matrix; - status = cairo_matrix_invert (&cairo_p2d); - /* cairo_pattern_set_matrix ensures the matrix is invertible */ - assert (status == CAIRO_INT_STATUS_SUCCESS); - - pdf_p2d = surface->cairo_to_pdf; - cairo_matrix_multiply (&pdf_p2d, &cairo_p2d, &pdf_p2d); - cairo_matrix_translate (&pdf_p2d, x_offset, y_offset); - cairo_matrix_translate (&pdf_p2d, 0.0, height); - cairo_matrix_scale (&pdf_p2d, 1.0, -1.0); - if (!(source->type == CAIRO_PATTERN_TYPE_SURFACE && - ((cairo_surface_pattern_t *)source)->surface->type == CAIRO_SURFACE_TYPE_RECORDING)) - { - cairo_matrix_scale (&pdf_p2d, width, height); - } - - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - return status; - - if (! _cairo_matrix_is_identity (&pdf_p2d)) { - _cairo_output_stream_print_matrix (surface->output, &pdf_p2d); - _cairo_output_stream_printf (surface->output, " cm\n"); - } - - status = _cairo_pdf_surface_add_alpha (surface, 1.0, &alpha); - if (unlikely (status)) - return status; - - if (stencil_mask) { - _cairo_output_stream_printf (surface->output, - "/x%d Do\n", - surface_res.id); - } else { - _cairo_output_stream_printf (surface->output, - "/a%d gs /x%d Do\n", - alpha, - surface_res.id); - } - - return _cairo_pdf_surface_add_xobject (surface, surface_res); -} - -static cairo_int_status_t -_cairo_pdf_surface_paint_gradient (cairo_pdf_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_rectangle_int_t *extents) -{ - cairo_pdf_resource_t shading_res, gstate_res; - cairo_matrix_t pat_to_pdf; - cairo_int_status_t status; - int alpha; - - status = _cairo_pdf_surface_add_pdf_shading (surface, source, - op, extents, - &shading_res, &gstate_res); - if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO)) - return CAIRO_INT_STATUS_SUCCESS; - if (unlikely (status)) - return status; - - pat_to_pdf = source->matrix; - status = cairo_matrix_invert (&pat_to_pdf); - /* cairo_pattern_set_matrix ensures the matrix is invertible */ - assert (status == CAIRO_INT_STATUS_SUCCESS); - cairo_matrix_multiply (&pat_to_pdf, &pat_to_pdf, &surface->cairo_to_pdf); - - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - return status; - - if (! _cairo_matrix_is_identity (&pat_to_pdf)) { - _cairo_output_stream_print_matrix (surface->output, &pat_to_pdf); - _cairo_output_stream_printf (surface->output, " cm\n"); - } - - status = _cairo_pdf_surface_add_shading (surface, shading_res); - if (unlikely (status)) - return status; - - if (gstate_res.id != 0) { - status = _cairo_pdf_surface_add_smask (surface, gstate_res); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->output, - "/s%d gs /sh%d sh\n", - gstate_res.id, - shading_res.id); - } else { - status = _cairo_pdf_surface_add_alpha (surface, 1.0, &alpha); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->output, - "/a%d gs /sh%d sh\n", - alpha, - shading_res.id); - } - - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_paint_pattern (cairo_pdf_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_rectangle_int_t *extents, - cairo_bool_t mask) -{ - switch (source->type) { - case CAIRO_PATTERN_TYPE_SURFACE: - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - return _cairo_pdf_surface_paint_surface_pattern (surface, - op, - source, - extents, - NULL, - mask); - case CAIRO_PATTERN_TYPE_LINEAR: - case CAIRO_PATTERN_TYPE_RADIAL: - case CAIRO_PATTERN_TYPE_MESH: - return _cairo_pdf_surface_paint_gradient (surface, - op, - source, - extents); - - case CAIRO_PATTERN_TYPE_SOLID: - default: - ASSERT_NOT_REACHED; - return CAIRO_STATUS_SUCCESS; - } -} - -static cairo_bool_t -_can_paint_pattern (const cairo_pattern_t *pattern) -{ - switch (pattern->type) { - case CAIRO_PATTERN_TYPE_SOLID: - return FALSE; - - case CAIRO_PATTERN_TYPE_SURFACE: - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - return (pattern->extend == CAIRO_EXTEND_NONE || - pattern->extend == CAIRO_EXTEND_PAD); - - case CAIRO_PATTERN_TYPE_LINEAR: - case CAIRO_PATTERN_TYPE_RADIAL: - return TRUE; - - case CAIRO_PATTERN_TYPE_MESH: - return FALSE; - - default: - ASSERT_NOT_REACHED; - return FALSE; - } -} - -static cairo_int_status_t -_cairo_pdf_surface_select_operator (cairo_pdf_surface_t *surface, - cairo_operator_t op) -{ - cairo_int_status_t status; - - if (op == surface->current_operator) - return CAIRO_STATUS_SUCCESS; - - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->output, - "/b%d gs\n", op); - surface->current_operator = op; - _cairo_pdf_surface_add_operator (surface, op); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_pdf_surface_select_pattern (cairo_pdf_surface_t *surface, - const cairo_pattern_t *pattern, - cairo_pdf_resource_t pattern_res, - cairo_bool_t is_stroke) -{ - cairo_int_status_t status; - int alpha; - const cairo_color_t *solid_color = NULL; - - if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) { - const cairo_solid_pattern_t *solid = (const cairo_solid_pattern_t *) pattern; - - solid_color = &solid->color; - } - - if (solid_color != NULL) { - if (surface->current_pattern_is_solid_color == FALSE || - surface->current_color_red != solid_color->red || - surface->current_color_green != solid_color->green || - surface->current_color_blue != solid_color->blue || - surface->current_color_is_stroke != is_stroke) - { - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->output, - "%f %f %f ", - solid_color->red, - solid_color->green, - solid_color->blue); - - if (is_stroke) - _cairo_output_stream_printf (surface->output, "RG "); - else - _cairo_output_stream_printf (surface->output, "rg "); - - surface->current_color_red = solid_color->red; - surface->current_color_green = solid_color->green; - surface->current_color_blue = solid_color->blue; - surface->current_color_is_stroke = is_stroke; - } - - if (surface->current_pattern_is_solid_color == FALSE || - surface->current_color_alpha != solid_color->alpha) - { - status = _cairo_pdf_surface_add_alpha (surface, solid_color->alpha, &alpha); - if (unlikely (status)) - return status; - - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->output, - "/a%d gs\n", - alpha); - surface->current_color_alpha = solid_color->alpha; - } - - surface->current_pattern_is_solid_color = TRUE; - } else { - status = _cairo_pdf_surface_add_alpha (surface, 1.0, &alpha); - if (unlikely (status)) - return status; - - status = _cairo_pdf_surface_add_pattern (surface, pattern_res); - if (unlikely (status)) - return status; - - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - return status; - - /* fill-stroke calls select_pattern twice. Don't save if the - * gstate is already saved. */ - if (!surface->select_pattern_gstate_saved) - _cairo_output_stream_printf (surface->output, "q "); - - if (is_stroke) { - _cairo_output_stream_printf (surface->output, - "/Pattern CS /p%d SCN ", - pattern_res.id); - } else { - _cairo_output_stream_printf (surface->output, - "/Pattern cs /p%d scn ", - pattern_res.id); - } - _cairo_output_stream_printf (surface->output, - "/a%d gs\n", - alpha); - surface->select_pattern_gstate_saved = TRUE; - surface->current_pattern_is_solid_color = FALSE; - } - - return _cairo_output_stream_get_status (surface->output); -} - -static cairo_int_status_t -_cairo_pdf_surface_unselect_pattern (cairo_pdf_surface_t *surface) -{ - cairo_int_status_t status; - - if (surface->select_pattern_gstate_saved) { - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->output, "Q\n"); - _cairo_pdf_operators_reset (&surface->pdf_operators); - surface->current_pattern_is_solid_color = FALSE; - } - surface->select_pattern_gstate_saved = FALSE; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_pdf_surface_show_page (void *abstract_surface) -{ - cairo_pdf_surface_t *surface = abstract_surface; - cairo_int_status_t status; - - status = _cairo_pdf_surface_close_content_stream (surface); - if (unlikely (status)) - return status; - - _cairo_surface_clipper_reset (&surface->clipper); - - status = _cairo_pdf_surface_write_page (surface); - if (unlikely (status)) - return status; - - _cairo_pdf_surface_clear (surface); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_bool_t -_cairo_pdf_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *rectangle) -{ - cairo_pdf_surface_t *surface = abstract_surface; - - rectangle->x = 0; - rectangle->y = 0; - - /* XXX: The conversion to integers here is pretty bogus, (not to - * mention the arbitrary limitation of width to a short(!). We - * may need to come up with a better interface for get_size. - */ - rectangle->width = ceil (surface->width); - rectangle->height = ceil (surface->height); - - return TRUE; -} - -static void -_cairo_pdf_surface_get_font_options (void *abstract_surface, - cairo_font_options_t *options) -{ - _cairo_font_options_init_default (options); - - cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_NONE); - cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF); - cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_GRAY); - _cairo_font_options_set_round_glyph_positions (options, CAIRO_ROUND_GLYPH_POS_OFF); -} - -static cairo_pdf_resource_t -_cairo_pdf_surface_write_info (cairo_pdf_surface_t *surface) -{ - cairo_pdf_resource_t info; - - info = _cairo_pdf_surface_new_object (surface); - if (info.id == 0) - return info; - - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /Creator (cairo %s (http://cairographics.org))\n" - " /Producer (cairo %s (http://cairographics.org))\n" - ">>\n" - "endobj\n", - info.id, - cairo_version_string (), - cairo_version_string ()); - - return info; -} - -static void -_cairo_pdf_surface_write_pages (cairo_pdf_surface_t *surface) -{ - cairo_pdf_resource_t page; - int num_pages, i; - - _cairo_pdf_surface_update_object (surface, surface->pages_resource); - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /Type /Pages\n" - " /Kids [ ", - surface->pages_resource.id); - - num_pages = _cairo_array_num_elements (&surface->pages); - for (i = 0; i < num_pages; i++) { - _cairo_array_copy_element (&surface->pages, i, &page); - _cairo_output_stream_printf (surface->output, "%d 0 R ", page.id); - } - - _cairo_output_stream_printf (surface->output, "]\n"); - _cairo_output_stream_printf (surface->output, " /Count %d\n", num_pages); - - - /* TODO: Figure out which other defaults to be inherited by /Page - * objects. */ - _cairo_output_stream_printf (surface->output, - ">>\n" - "endobj\n"); -} - -static cairo_int_status_t -_utf8_to_pdf_string (const char *utf8, char **str_out) -{ - int i; - int len; - cairo_bool_t ascii; - char *str; - cairo_int_status_t status = CAIRO_STATUS_SUCCESS; - - ascii = TRUE; - len = strlen (utf8); - for (i = 0; i < len; i++) { - unsigned c = utf8[i]; - if (c < 32 || c > 126 || c == '(' || c == ')' || c == '\\') { - ascii = FALSE; - break; - } - } - - if (ascii) { - str = malloc (len + 3); - if (str == NULL) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - str[0] = '('; - for (i = 0; i < len; i++) - str[i+1] = utf8[i]; - str[i+1] = ')'; - str[i+2] = 0; - } else { - uint16_t *utf16 = NULL; - int utf16_len = 0; - - status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &utf16_len); - if (unlikely (status)) - return status; - - str = malloc (utf16_len*4 + 7); - if (str == NULL) { - free (utf16); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - strcpy (str, "<FEFF"); - for (i = 0; i < utf16_len; i++) - snprintf (str + 4*i + 5, 5, "%04X", utf16[i]); - - strcat (str, ">"); - free (utf16); - } - *str_out = str; - - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_emit_unicode_for_glyph (cairo_pdf_surface_t *surface, - const char *utf8) -{ - uint16_t *utf16 = NULL; - int utf16_len = 0; - cairo_int_status_t status; - int i; - - if (utf8 && *utf8) { - status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &utf16_len); - if (unlikely (status)) - return status; - } - - _cairo_output_stream_printf (surface->output, "<"); - if (utf16 == NULL || utf16_len == 0) { - /* According to the "ToUnicode Mapping File Tutorial" - * http://www.adobe.com/devnet/acrobat/pdfs/5411.ToUnicode.pdf - * - * Glyphs that do not map to a Unicode code point must be - * mapped to 0xfffd "REPLACEMENT CHARACTER". - */ - _cairo_output_stream_printf (surface->output, - "fffd"); - } else { - for (i = 0; i < utf16_len; i++) - _cairo_output_stream_printf (surface->output, - "%04x", (int) (utf16[i])); - } - _cairo_output_stream_printf (surface->output, ">"); - - free (utf16); - - return CAIRO_STATUS_SUCCESS; -} - -/* Bob Jenkins hash - * - * Public domain code from: - * http://burtleburtle.net/bob/hash/doobs.html - */ - -#define HASH_MIX(a,b,c) \ -{ \ - a -= b; a -= c; a ^= (c>>13); \ - b -= c; b -= a; b ^= (a<<8); \ - c -= a; c -= b; c ^= (b>>13); \ - a -= b; a -= c; a ^= (c>>12); \ - b -= c; b -= a; b ^= (a<<16); \ - c -= a; c -= b; c ^= (b>>5); \ - a -= b; a -= c; a ^= (c>>3); \ - b -= c; b -= a; b ^= (a<<10); \ - c -= a; c -= b; c ^= (b>>15); \ -} - -static uint32_t -_hash_data (const unsigned char *data, int length, uint32_t initval) -{ - uint32_t a, b, c, len; - - len = length; - a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */ - c = initval; /* the previous hash value */ - - while (len >= 12) { - a += (data[0] + ((uint32_t)data[1]<<8) + ((uint32_t)data[2]<<16) + ((uint32_t)data[3]<<24)); - b += (data[4] + ((uint32_t)data[5]<<8) + ((uint32_t)data[6]<<16) + ((uint32_t)data[7]<<24)); - c += (data[8] + ((uint32_t)data[9]<<8) + ((uint32_t)data[10]<<16)+ ((uint32_t)data[11]<<24)); - HASH_MIX (a,b,c); - data += 12; - len -= 12; - } - - c += length; - switch(len) { - case 11: c+= ((uint32_t) data[10] << 24); - case 10: c+= ((uint32_t) data[9] << 16); - case 9 : c+= ((uint32_t) data[8] << 8); - case 8 : b+= ((uint32_t) data[7] << 24); - case 7 : b+= ((uint32_t) data[6] << 16); - case 6 : b+= ((uint32_t) data[5] << 8); - case 5 : b+= data[4]; - case 4 : a+= ((uint32_t) data[3] << 24); - case 3 : a+= ((uint32_t) data[2] << 16); - case 2 : a+= ((uint32_t) data[1] << 8); - case 1 : a+= data[0]; - } - HASH_MIX (a,b,c); - - return c; -} - -static void -_create_font_subset_tag (cairo_scaled_font_subset_t *font_subset, - const char *font_name, - char *tag) -{ - uint32_t hash; - int i; - long numerator; - ldiv_t d; - - hash = _hash_data ((unsigned char *) font_name, strlen(font_name), 0); - hash = _hash_data ((unsigned char *) (font_subset->glyphs), - font_subset->num_glyphs * sizeof(unsigned long), hash); - - numerator = abs (hash); - for (i = 0; i < 6; i++) { - d = ldiv (numerator, 26); - numerator = d.quot; - tag[i] = 'A' + d.rem; - } - tag[i] = 0; -} - -static cairo_int_status_t -_cairo_pdf_surface_emit_to_unicode_stream (cairo_pdf_surface_t *surface, - cairo_scaled_font_subset_t *font_subset, - cairo_pdf_resource_t *stream) -{ - unsigned int i, num_bfchar; - cairo_int_status_t status; - - stream->id = 0; - - status = _cairo_pdf_surface_open_stream (surface, - NULL, - surface->compress_content, - NULL); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->output, - "/CIDInit /ProcSet findresource begin\n" - "12 dict begin\n" - "begincmap\n" - "/CIDSystemInfo\n" - "<< /Registry (Adobe)\n" - " /Ordering (UCS)\n" - " /Supplement 0\n" - ">> def\n" - "/CMapName /Adobe-Identity-UCS def\n" - "/CMapType 2 def\n" - "1 begincodespacerange\n"); - - if (font_subset->is_composite && !font_subset->is_latin) { - _cairo_output_stream_printf (surface->output, - "<0000> <ffff>\n"); - } else { - _cairo_output_stream_printf (surface->output, - "<00> <ff>\n"); - } - - _cairo_output_stream_printf (surface->output, - "endcodespacerange\n"); - - if (font_subset->is_scaled) { - /* Type 3 fonts include glyph 0 in the subset */ - num_bfchar = font_subset->num_glyphs; - - /* The CMap specification has a limit of 100 characters per beginbfchar operator */ - _cairo_output_stream_printf (surface->output, - "%d beginbfchar\n", - num_bfchar > 100 ? 100 : num_bfchar); - - for (i = 0; i < num_bfchar; i++) { - if (i != 0 && i % 100 == 0) { - _cairo_output_stream_printf (surface->output, - "endbfchar\n" - "%d beginbfchar\n", - num_bfchar - i > 100 ? 100 : num_bfchar - i); - } - _cairo_output_stream_printf (surface->output, "<%02x> ", i); - status = _cairo_pdf_surface_emit_unicode_for_glyph (surface, - font_subset->utf8[i]); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->output, - "\n"); - } - } else { - /* Other fonts reserve glyph 0 for .notdef. Omit glyph 0 from the /ToUnicode map */ - num_bfchar = font_subset->num_glyphs - 1; - - /* The CMap specification has a limit of 100 characters per beginbfchar operator */ - _cairo_output_stream_printf (surface->output, - "%d beginbfchar\n", - num_bfchar > 100 ? 100 : num_bfchar); - - for (i = 0; i < num_bfchar; i++) { - if (i != 0 && i % 100 == 0) { - _cairo_output_stream_printf (surface->output, - "endbfchar\n" - "%d beginbfchar\n", - num_bfchar - i > 100 ? 100 : num_bfchar - i); - } - if (font_subset->is_latin) - _cairo_output_stream_printf (surface->output, "<%02x> ", font_subset->to_latin_char[i + 1]); - else if (font_subset->is_composite) - _cairo_output_stream_printf (surface->output, "<%04x> ", i + 1); - else - _cairo_output_stream_printf (surface->output, "<%02x> ", i + 1); - - status = _cairo_pdf_surface_emit_unicode_for_glyph (surface, - font_subset->utf8[i + 1]); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->output, - "\n"); - } - } - - _cairo_output_stream_printf (surface->output, - "endbfchar\n"); - - _cairo_output_stream_printf (surface->output, - "endcmap\n" - "CMapName currentdict /CMap defineresource pop\n" - "end\n" - "end\n"); - - *stream = surface->pdf_stream.self; - return _cairo_pdf_surface_close_stream (surface); -} - -#define PDF_UNITS_PER_EM 1000 - -static cairo_int_status_t -_cairo_pdf_surface_emit_cff_font (cairo_pdf_surface_t *surface, - cairo_scaled_font_subset_t *font_subset, - cairo_cff_subset_t *subset) -{ - cairo_pdf_resource_t stream, descriptor, cidfont_dict; - cairo_pdf_resource_t subset_resource, to_unicode_stream; - cairo_pdf_font_t font; - unsigned int i, last_glyph; - cairo_int_status_t status; - char tag[10]; - - _create_font_subset_tag (font_subset, subset->ps_name, tag); - - subset_resource = _cairo_pdf_surface_get_font_resource (surface, - font_subset->font_id, - font_subset->subset_id); - if (subset_resource.id == 0) - return CAIRO_STATUS_SUCCESS; - - status = _cairo_pdf_surface_open_stream (surface, - NULL, - TRUE, - font_subset->is_latin ? - " /Subtype /Type1C\n" : - " /Subtype /CIDFontType0C\n"); - if (unlikely (status)) - return status; - - stream = surface->pdf_stream.self; - _cairo_output_stream_write (surface->output, - subset->data, subset->data_length); - status = _cairo_pdf_surface_close_stream (surface); - if (unlikely (status)) - return status; - - status = _cairo_pdf_surface_emit_to_unicode_stream (surface, - font_subset, - &to_unicode_stream); - if (_cairo_int_status_is_error (status)) - return status; - - descriptor = _cairo_pdf_surface_new_object (surface); - if (descriptor.id == 0) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /Type /FontDescriptor\n" - " /FontName /%s+%s\n", - descriptor.id, - tag, - subset->ps_name); - - if (subset->family_name_utf8) { - char *pdf_str; - - status = _utf8_to_pdf_string (subset->family_name_utf8, &pdf_str); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->output, - " /FontFamily %s\n", - pdf_str); - free (pdf_str); - } - - _cairo_output_stream_printf (surface->output, - " /Flags 4\n" - " /FontBBox [ %ld %ld %ld %ld ]\n" - " /ItalicAngle 0\n" - " /Ascent %ld\n" - " /Descent %ld\n" - " /CapHeight %ld\n" - " /StemV 80\n" - " /StemH 80\n" - " /FontFile3 %u 0 R\n" - ">>\n" - "endobj\n", - (long)(subset->x_min*PDF_UNITS_PER_EM), - (long)(subset->y_min*PDF_UNITS_PER_EM), - (long)(subset->x_max*PDF_UNITS_PER_EM), - (long)(subset->y_max*PDF_UNITS_PER_EM), - (long)(subset->ascent*PDF_UNITS_PER_EM), - (long)(subset->descent*PDF_UNITS_PER_EM), - (long)(subset->y_max*PDF_UNITS_PER_EM), - stream.id); - - if (font_subset->is_latin) { - /* find last glyph used */ - for (i = 255; i >= 32; i--) - if (font_subset->latin_to_subset_glyph_index[i] > 0) - break; - - last_glyph = i; - _cairo_pdf_surface_update_object (surface, subset_resource); - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /Type /Font\n" - " /Subtype /Type1\n" - " /BaseFont /%s+%s\n" - " /FirstChar 32\n" - " /LastChar %d\n" - " /FontDescriptor %d 0 R\n" - " /Encoding /WinAnsiEncoding\n" - " /Widths [", - subset_resource.id, - tag, - subset->ps_name, - last_glyph, - descriptor.id); - - for (i = 32; i < last_glyph + 1; i++) { - int glyph = font_subset->latin_to_subset_glyph_index[i]; - if (glyph > 0) { - _cairo_output_stream_printf (surface->output, - " %ld", - (long)(subset->widths[glyph]*PDF_UNITS_PER_EM)); - } else { - _cairo_output_stream_printf (surface->output, " 0"); - } - } - - _cairo_output_stream_printf (surface->output, - " ]\n"); - - if (to_unicode_stream.id != 0) - _cairo_output_stream_printf (surface->output, - " /ToUnicode %d 0 R\n", - to_unicode_stream.id); - - _cairo_output_stream_printf (surface->output, - ">>\n" - "endobj\n"); - } else { - cidfont_dict = _cairo_pdf_surface_new_object (surface); - if (cidfont_dict.id == 0) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /Type /Font\n" - " /Subtype /CIDFontType0\n" - " /BaseFont /%s+%s\n" - " /CIDSystemInfo\n" - " << /Registry (Adobe)\n" - " /Ordering (Identity)\n" - " /Supplement 0\n" - " >>\n" - " /FontDescriptor %d 0 R\n" - " /W [0 [", - cidfont_dict.id, - tag, - subset->ps_name, - descriptor.id); - - for (i = 0; i < font_subset->num_glyphs; i++) - _cairo_output_stream_printf (surface->output, - " %ld", - (long)(subset->widths[i]*PDF_UNITS_PER_EM)); - - _cairo_output_stream_printf (surface->output, - " ]]\n" - ">>\n" - "endobj\n"); - - _cairo_pdf_surface_update_object (surface, subset_resource); - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /Type /Font\n" - " /Subtype /Type0\n" - " /BaseFont /%s+%s\n" - " /Encoding /Identity-H\n" - " /DescendantFonts [ %d 0 R]\n", - subset_resource.id, - tag, - subset->ps_name, - cidfont_dict.id); - - if (to_unicode_stream.id != 0) - _cairo_output_stream_printf (surface->output, - " /ToUnicode %d 0 R\n", - to_unicode_stream.id); - - _cairo_output_stream_printf (surface->output, - ">>\n" - "endobj\n"); - } - - font.font_id = font_subset->font_id; - font.subset_id = font_subset->subset_id; - font.subset_resource = subset_resource; - status = _cairo_array_append (&surface->fonts, &font); - - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_emit_cff_font_subset (cairo_pdf_surface_t *surface, - cairo_scaled_font_subset_t *font_subset) -{ - cairo_int_status_t status; - cairo_cff_subset_t subset; - char name[64]; - - snprintf (name, sizeof name, "CairoFont-%d-%d", - font_subset->font_id, font_subset->subset_id); - status = _cairo_cff_subset_init (&subset, name, font_subset); - if (unlikely (status)) - return status; - - status = _cairo_pdf_surface_emit_cff_font (surface, font_subset, &subset); - - _cairo_cff_subset_fini (&subset); - - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_emit_cff_fallback_font (cairo_pdf_surface_t *surface, - cairo_scaled_font_subset_t *font_subset) -{ - cairo_int_status_t status; - cairo_cff_subset_t subset; - char name[64]; - - /* CFF fallback subsetting does not work with 8-bit glyphs unless - * they are a latin subset */ - if (!font_subset->is_composite && !font_subset->is_latin) - return CAIRO_INT_STATUS_UNSUPPORTED; - - snprintf (name, sizeof name, "CairoFont-%d-%d", - font_subset->font_id, font_subset->subset_id); - status = _cairo_cff_fallback_init (&subset, name, font_subset); - if (unlikely (status)) - return status; - - status = _cairo_pdf_surface_emit_cff_font (surface, font_subset, &subset); - - _cairo_cff_fallback_fini (&subset); - - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_emit_type1_font (cairo_pdf_surface_t *surface, - cairo_scaled_font_subset_t *font_subset, - cairo_type1_subset_t *subset) -{ - cairo_pdf_resource_t stream, descriptor, subset_resource, to_unicode_stream; - cairo_pdf_font_t font; - cairo_int_status_t status; - unsigned long length; - unsigned int i, last_glyph; - char tag[10]; - - _create_font_subset_tag (font_subset, subset->base_font, tag); - - subset_resource = _cairo_pdf_surface_get_font_resource (surface, - font_subset->font_id, - font_subset->subset_id); - if (subset_resource.id == 0) - return CAIRO_STATUS_SUCCESS; - - length = subset->header_length + subset->data_length + subset->trailer_length; - status = _cairo_pdf_surface_open_stream (surface, - NULL, - TRUE, - " /Length1 %lu\n" - " /Length2 %lu\n" - " /Length3 %lu\n", - subset->header_length, - subset->data_length, - subset->trailer_length); - if (unlikely (status)) - return status; - - stream = surface->pdf_stream.self; - _cairo_output_stream_write (surface->output, subset->data, length); - status = _cairo_pdf_surface_close_stream (surface); - if (unlikely (status)) - return status; - - status = _cairo_pdf_surface_emit_to_unicode_stream (surface, - font_subset, - &to_unicode_stream); - if (_cairo_int_status_is_error (status)) - return status; - - last_glyph = font_subset->num_glyphs - 1; - if (font_subset->is_latin) { - /* find last glyph used */ - for (i = 255; i >= 32; i--) - if (font_subset->latin_to_subset_glyph_index[i] > 0) - break; - - last_glyph = i; - } - - descriptor = _cairo_pdf_surface_new_object (surface); - if (descriptor.id == 0) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /Type /FontDescriptor\n" - " /FontName /%s+%s\n" - " /Flags 4\n" - " /FontBBox [ %ld %ld %ld %ld ]\n" - " /ItalicAngle 0\n" - " /Ascent %ld\n" - " /Descent %ld\n" - " /CapHeight %ld\n" - " /StemV 80\n" - " /StemH 80\n" - " /FontFile %u 0 R\n" - ">>\n" - "endobj\n", - descriptor.id, - tag, - subset->base_font, - (long)(subset->x_min*PDF_UNITS_PER_EM), - (long)(subset->y_min*PDF_UNITS_PER_EM), - (long)(subset->x_max*PDF_UNITS_PER_EM), - (long)(subset->y_max*PDF_UNITS_PER_EM), - (long)(subset->ascent*PDF_UNITS_PER_EM), - (long)(subset->descent*PDF_UNITS_PER_EM), - (long)(subset->y_max*PDF_UNITS_PER_EM), - stream.id); - - _cairo_pdf_surface_update_object (surface, subset_resource); - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /Type /Font\n" - " /Subtype /Type1\n" - " /BaseFont /%s+%s\n" - " /FirstChar %d\n" - " /LastChar %d\n" - " /FontDescriptor %d 0 R\n", - subset_resource.id, - tag, - subset->base_font, - font_subset->is_latin ? 32 : 0, - last_glyph, - descriptor.id); - - if (font_subset->is_latin) - _cairo_output_stream_printf (surface->output, " /Encoding /WinAnsiEncoding\n"); - - _cairo_output_stream_printf (surface->output, " /Widths ["); - if (font_subset->is_latin) { - for (i = 32; i < last_glyph + 1; i++) { - int glyph = font_subset->latin_to_subset_glyph_index[i]; - if (glyph > 0) { - _cairo_output_stream_printf (surface->output, - " %ld", - (long)(subset->widths[glyph]*PDF_UNITS_PER_EM)); - } else { - _cairo_output_stream_printf (surface->output, " 0"); - } - } - } else { - for (i = 0; i < font_subset->num_glyphs; i++) - _cairo_output_stream_printf (surface->output, - " %ld", - (long)(subset->widths[i]*PDF_UNITS_PER_EM)); - } - - _cairo_output_stream_printf (surface->output, - " ]\n"); - - if (to_unicode_stream.id != 0) - _cairo_output_stream_printf (surface->output, - " /ToUnicode %d 0 R\n", - to_unicode_stream.id); - - _cairo_output_stream_printf (surface->output, - ">>\n" - "endobj\n"); - - font.font_id = font_subset->font_id; - font.subset_id = font_subset->subset_id; - font.subset_resource = subset_resource; - return _cairo_array_append (&surface->fonts, &font); -} - -static cairo_int_status_t -_cairo_pdf_surface_emit_type1_font_subset (cairo_pdf_surface_t *surface, - cairo_scaled_font_subset_t *font_subset) -{ - cairo_int_status_t status; - cairo_type1_subset_t subset; - char name[64]; - - /* 16-bit glyphs not compatible with Type 1 fonts */ - if (font_subset->is_composite && !font_subset->is_latin) - return CAIRO_INT_STATUS_UNSUPPORTED; - - snprintf (name, sizeof name, "CairoFont-%d-%d", - font_subset->font_id, font_subset->subset_id); - status = _cairo_type1_subset_init (&subset, name, font_subset, FALSE); - if (unlikely (status)) - return status; - - status = _cairo_pdf_surface_emit_type1_font (surface, font_subset, &subset); - - _cairo_type1_subset_fini (&subset); - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_emit_type1_fallback_font (cairo_pdf_surface_t *surface, - cairo_scaled_font_subset_t *font_subset) -{ - cairo_int_status_t status; - cairo_type1_subset_t subset; - char name[64]; - - /* 16-bit glyphs not compatible with Type 1 fonts */ - if (font_subset->is_composite && !font_subset->is_latin) - return CAIRO_INT_STATUS_UNSUPPORTED; - - snprintf (name, sizeof name, "CairoFont-%d-%d", - font_subset->font_id, font_subset->subset_id); - status = _cairo_type1_fallback_init_binary (&subset, name, font_subset); - if (unlikely (status)) - return status; - - status = _cairo_pdf_surface_emit_type1_font (surface, font_subset, &subset); - - _cairo_type1_fallback_fini (&subset); - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface, - cairo_scaled_font_subset_t *font_subset) -{ - cairo_pdf_resource_t stream, descriptor, cidfont_dict; - cairo_pdf_resource_t subset_resource, to_unicode_stream; - cairo_int_status_t status; - cairo_pdf_font_t font; - cairo_truetype_subset_t subset; - unsigned int i, last_glyph; - char tag[10]; - - subset_resource = _cairo_pdf_surface_get_font_resource (surface, - font_subset->font_id, - font_subset->subset_id); - if (subset_resource.id == 0) - return CAIRO_STATUS_SUCCESS; - - status = _cairo_truetype_subset_init_pdf (&subset, font_subset); - if (unlikely (status)) - return status; - - _create_font_subset_tag (font_subset, subset.ps_name, tag); - - status = _cairo_pdf_surface_open_stream (surface, - NULL, - TRUE, - " /Length1 %lu\n", - subset.data_length); - if (unlikely (status)) { - _cairo_truetype_subset_fini (&subset); - return status; - } - - stream = surface->pdf_stream.self; - _cairo_output_stream_write (surface->output, - subset.data, subset.data_length); - status = _cairo_pdf_surface_close_stream (surface); - if (unlikely (status)) { - _cairo_truetype_subset_fini (&subset); - return status; - } - - status = _cairo_pdf_surface_emit_to_unicode_stream (surface, - font_subset, - &to_unicode_stream); - if (_cairo_int_status_is_error (status)) { - _cairo_truetype_subset_fini (&subset); - return status; - } - - descriptor = _cairo_pdf_surface_new_object (surface); - if (descriptor.id == 0) { - _cairo_truetype_subset_fini (&subset); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /Type /FontDescriptor\n" - " /FontName /%s+%s\n", - descriptor.id, - tag, - subset.ps_name); - - if (subset.family_name_utf8) { - char *pdf_str; - - status = _utf8_to_pdf_string (subset.family_name_utf8, &pdf_str); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->output, - " /FontFamily %s\n", - pdf_str); - free (pdf_str); - } - - _cairo_output_stream_printf (surface->output, - " /Flags %d\n" - " /FontBBox [ %ld %ld %ld %ld ]\n" - " /ItalicAngle 0\n" - " /Ascent %ld\n" - " /Descent %ld\n" - " /CapHeight %ld\n" - " /StemV 80\n" - " /StemH 80\n" - " /FontFile2 %u 0 R\n" - ">>\n" - "endobj\n", - font_subset->is_latin ? 32 : 4, - (long)(subset.x_min*PDF_UNITS_PER_EM), - (long)(subset.y_min*PDF_UNITS_PER_EM), - (long)(subset.x_max*PDF_UNITS_PER_EM), - (long)(subset.y_max*PDF_UNITS_PER_EM), - (long)(subset.ascent*PDF_UNITS_PER_EM), - (long)(subset.descent*PDF_UNITS_PER_EM), - (long)(subset.y_max*PDF_UNITS_PER_EM), - stream.id); - - if (font_subset->is_latin) { - /* find last glyph used */ - for (i = 255; i >= 32; i--) - if (font_subset->latin_to_subset_glyph_index[i] > 0) - break; - - last_glyph = i; - _cairo_pdf_surface_update_object (surface, subset_resource); - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /Type /Font\n" - " /Subtype /TrueType\n" - " /BaseFont /%s+%s\n" - " /FirstChar 32\n" - " /LastChar %d\n" - " /FontDescriptor %d 0 R\n" - " /Encoding /WinAnsiEncoding\n" - " /Widths [", - subset_resource.id, - tag, - subset.ps_name, - last_glyph, - descriptor.id); - - for (i = 32; i < last_glyph + 1; i++) { - int glyph = font_subset->latin_to_subset_glyph_index[i]; - if (glyph > 0) { - _cairo_output_stream_printf (surface->output, - " %ld", - (long)(subset.widths[glyph]*PDF_UNITS_PER_EM)); - } else { - _cairo_output_stream_printf (surface->output, " 0"); - } - } - - _cairo_output_stream_printf (surface->output, - " ]\n"); - - if (to_unicode_stream.id != 0) - _cairo_output_stream_printf (surface->output, - " /ToUnicode %d 0 R\n", - to_unicode_stream.id); - - _cairo_output_stream_printf (surface->output, - ">>\n" - "endobj\n"); - } else { - cidfont_dict = _cairo_pdf_surface_new_object (surface); - if (cidfont_dict.id == 0) { - _cairo_truetype_subset_fini (&subset); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /Type /Font\n" - " /Subtype /CIDFontType2\n" - " /BaseFont /%s+%s\n" - " /CIDSystemInfo\n" - " << /Registry (Adobe)\n" - " /Ordering (Identity)\n" - " /Supplement 0\n" - " >>\n" - " /FontDescriptor %d 0 R\n" - " /W [0 [", - cidfont_dict.id, - tag, - subset.ps_name, - descriptor.id); - - for (i = 0; i < font_subset->num_glyphs; i++) - _cairo_output_stream_printf (surface->output, - " %ld", - (long)(subset.widths[i]*PDF_UNITS_PER_EM)); - - _cairo_output_stream_printf (surface->output, - " ]]\n" - ">>\n" - "endobj\n"); - - _cairo_pdf_surface_update_object (surface, subset_resource); - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /Type /Font\n" - " /Subtype /Type0\n" - " /BaseFont /%s+%s\n" - " /Encoding /Identity-H\n" - " /DescendantFonts [ %d 0 R]\n", - subset_resource.id, - tag, - subset.ps_name, - cidfont_dict.id); - - if (to_unicode_stream.id != 0) - _cairo_output_stream_printf (surface->output, - " /ToUnicode %d 0 R\n", - to_unicode_stream.id); - - _cairo_output_stream_printf (surface->output, - ">>\n" - "endobj\n"); - } - - font.font_id = font_subset->font_id; - font.subset_id = font_subset->subset_id; - font.subset_resource = subset_resource; - status = _cairo_array_append (&surface->fonts, &font); - - _cairo_truetype_subset_fini (&subset); - - return status; -} - -static cairo_int_status_t -_cairo_pdf_emit_imagemask (cairo_image_surface_t *image, - cairo_output_stream_t *stream) -{ - uint8_t *byte, output_byte; - int row, col, num_cols; - - /* The only image type supported by Type 3 fonts are 1-bit image - * masks */ - assert (image->format == CAIRO_FORMAT_A1); - - _cairo_output_stream_printf (stream, - "BI\n" - "/IM true\n" - "/W %d\n" - "/H %d\n" - "/BPC 1\n" - "/D [1 0]\n", - image->width, - image->height); - - _cairo_output_stream_printf (stream, - "ID "); - - num_cols = (image->width + 7) / 8; - for (row = 0; row < image->height; row++) { - byte = image->data + row * image->stride; - for (col = 0; col < num_cols; col++) { - output_byte = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (*byte); - _cairo_output_stream_write (stream, &output_byte, 1); - byte++; - } - } - - _cairo_output_stream_printf (stream, - "\nEI\n"); - - return _cairo_output_stream_get_status (stream); -} - -static cairo_int_status_t -_cairo_pdf_surface_analyze_user_font_subset (cairo_scaled_font_subset_t *font_subset, - void *closure) -{ - cairo_pdf_surface_t *surface = closure; - cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS; - cairo_int_status_t status2; - unsigned int i; - cairo_surface_t *type3_surface; - cairo_output_stream_t *null_stream; - - null_stream = _cairo_null_stream_create (); - type3_surface = _cairo_type3_glyph_surface_create (font_subset->scaled_font, - null_stream, - _cairo_pdf_emit_imagemask, - surface->font_subsets, - FALSE); - if (unlikely (type3_surface->status)) { - status2 = _cairo_output_stream_destroy (null_stream); - return type3_surface->status; - } - - _cairo_type3_glyph_surface_set_font_subsets_callback (type3_surface, - _cairo_pdf_surface_add_font, - surface); - - for (i = 0; i < font_subset->num_glyphs; i++) { - status = _cairo_type3_glyph_surface_analyze_glyph (type3_surface, - font_subset->glyphs[i]); - if (unlikely (status)) - break; - } - - cairo_surface_destroy (type3_surface); - status2 = _cairo_output_stream_destroy (null_stream); - if (status == CAIRO_INT_STATUS_SUCCESS) - status = status2; - - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface, - cairo_scaled_font_subset_t *font_subset) -{ - cairo_int_status_t status = CAIRO_STATUS_SUCCESS; - cairo_pdf_resource_t *glyphs, encoding, char_procs, subset_resource, to_unicode_stream; - cairo_pdf_font_t font; - double *widths; - unsigned int i; - cairo_box_t font_bbox = {{0,0},{0,0}}; - cairo_box_t bbox = {{0,0},{0,0}}; - cairo_surface_t *type3_surface; - - if (font_subset->num_glyphs == 0) - return CAIRO_STATUS_SUCCESS; - - subset_resource = _cairo_pdf_surface_get_font_resource (surface, - font_subset->font_id, - font_subset->subset_id); - if (subset_resource.id == 0) - return CAIRO_STATUS_SUCCESS; - - glyphs = _cairo_malloc_ab (font_subset->num_glyphs, sizeof (cairo_pdf_resource_t)); - if (unlikely (glyphs == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - widths = _cairo_malloc_ab (font_subset->num_glyphs, sizeof (double)); - if (unlikely (widths == NULL)) { - free (glyphs); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - _cairo_pdf_group_resources_clear (&surface->resources); - type3_surface = _cairo_type3_glyph_surface_create (font_subset->scaled_font, - NULL, - _cairo_pdf_emit_imagemask, - surface->font_subsets, - FALSE); - if (unlikely (type3_surface->status)) { - free (glyphs); - free (widths); - return type3_surface->status; - } - - _cairo_type3_glyph_surface_set_font_subsets_callback (type3_surface, - _cairo_pdf_surface_add_font, - surface); - - for (i = 0; i < font_subset->num_glyphs; i++) { - status = _cairo_pdf_surface_open_stream (surface, - NULL, - surface->compress_content, - NULL); - if (unlikely (status)) - break; - - glyphs[i] = surface->pdf_stream.self; - status = _cairo_type3_glyph_surface_emit_glyph (type3_surface, - surface->output, - font_subset->glyphs[i], - &bbox, - &widths[i]); - if (unlikely (status)) - break; - - status = _cairo_pdf_surface_close_stream (surface); - if (unlikely (status)) - break; - - if (i == 0) { - font_bbox.p1.x = bbox.p1.x; - font_bbox.p1.y = bbox.p1.y; - font_bbox.p2.x = bbox.p2.x; - font_bbox.p2.y = bbox.p2.y; - } else { - if (bbox.p1.x < font_bbox.p1.x) - font_bbox.p1.x = bbox.p1.x; - if (bbox.p1.y < font_bbox.p1.y) - font_bbox.p1.y = bbox.p1.y; - if (bbox.p2.x > font_bbox.p2.x) - font_bbox.p2.x = bbox.p2.x; - if (bbox.p2.y > font_bbox.p2.y) - font_bbox.p2.y = bbox.p2.y; - } - } - cairo_surface_destroy (type3_surface); - if (unlikely (status)) { - free (glyphs); - free (widths); - return status; - } - - encoding = _cairo_pdf_surface_new_object (surface); - if (encoding.id == 0) { - free (glyphs); - free (widths); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /Type /Encoding\n" - " /Differences [0", encoding.id); - for (i = 0; i < font_subset->num_glyphs; i++) - _cairo_output_stream_printf (surface->output, - " /%d", i); - _cairo_output_stream_printf (surface->output, - "]\n" - ">>\n" - "endobj\n"); - - char_procs = _cairo_pdf_surface_new_object (surface); - if (char_procs.id == 0) { - free (glyphs); - free (widths); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<<\n", char_procs.id); - for (i = 0; i < font_subset->num_glyphs; i++) - _cairo_output_stream_printf (surface->output, - " /%d %d 0 R\n", - i, glyphs[i].id); - _cairo_output_stream_printf (surface->output, - ">>\n" - "endobj\n"); - - free (glyphs); - - status = _cairo_pdf_surface_emit_to_unicode_stream (surface, - font_subset, - &to_unicode_stream); - if (_cairo_int_status_is_error (status)) { - free (widths); - return status; - } - - _cairo_pdf_surface_update_object (surface, subset_resource); - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /Type /Font\n" - " /Subtype /Type3\n" - " /FontBBox [%f %f %f %f]\n" - " /FontMatrix [ 1 0 0 1 0 0 ]\n" - " /Encoding %d 0 R\n" - " /CharProcs %d 0 R\n" - " /FirstChar 0\n" - " /LastChar %d\n", - subset_resource.id, - _cairo_fixed_to_double (font_bbox.p1.x), - - _cairo_fixed_to_double (font_bbox.p2.y), - _cairo_fixed_to_double (font_bbox.p2.x), - - _cairo_fixed_to_double (font_bbox.p1.y), - encoding.id, - char_procs.id, - font_subset->num_glyphs - 1); - - _cairo_output_stream_printf (surface->output, - " /Widths ["); - for (i = 0; i < font_subset->num_glyphs; i++) - _cairo_output_stream_printf (surface->output, " %f", widths[i]); - _cairo_output_stream_printf (surface->output, - "]\n"); - free (widths); - - _cairo_output_stream_printf (surface->output, - " /Resources\n"); - _cairo_pdf_surface_emit_group_resources (surface, &surface->resources); - - if (to_unicode_stream.id != 0) - _cairo_output_stream_printf (surface->output, - " /ToUnicode %d 0 R\n", - to_unicode_stream.id); - - _cairo_output_stream_printf (surface->output, - ">>\n" - "endobj\n"); - - font.font_id = font_subset->font_id; - font.subset_id = font_subset->subset_id; - font.subset_resource = subset_resource; - return _cairo_array_append (&surface->fonts, &font); -} - -static cairo_int_status_t -_cairo_pdf_surface_emit_unscaled_font_subset (cairo_scaled_font_subset_t *font_subset, - void *closure) -{ - cairo_pdf_surface_t *surface = closure; - cairo_int_status_t status; - - status = _cairo_pdf_surface_emit_cff_font_subset (surface, font_subset); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - - status = _cairo_pdf_surface_emit_truetype_font_subset (surface, font_subset); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - - status = _cairo_pdf_surface_emit_type1_font_subset (surface, font_subset); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - - status = _cairo_pdf_surface_emit_cff_fallback_font (surface, font_subset); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - - status = _cairo_pdf_surface_emit_type1_fallback_font (surface, font_subset); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - - ASSERT_NOT_REACHED; - return CAIRO_INT_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_pdf_surface_emit_scaled_font_subset (cairo_scaled_font_subset_t *font_subset, - void *closure) -{ - cairo_pdf_surface_t *surface = closure; - cairo_int_status_t status; - - status = _cairo_pdf_surface_emit_type3_font_subset (surface, font_subset); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - - ASSERT_NOT_REACHED; - return CAIRO_INT_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_pdf_surface_emit_font_subsets (cairo_pdf_surface_t *surface) -{ - cairo_int_status_t status; - - status = _cairo_scaled_font_subsets_foreach_user (surface->font_subsets, - _cairo_pdf_surface_analyze_user_font_subset, - surface); - if (unlikely (status)) - goto BAIL; - - status = _cairo_scaled_font_subsets_foreach_unscaled (surface->font_subsets, - _cairo_pdf_surface_emit_unscaled_font_subset, - surface); - if (unlikely (status)) - goto BAIL; - - status = _cairo_scaled_font_subsets_foreach_scaled (surface->font_subsets, - _cairo_pdf_surface_emit_scaled_font_subset, - surface); - if (unlikely (status)) - goto BAIL; - - status = _cairo_scaled_font_subsets_foreach_user (surface->font_subsets, - _cairo_pdf_surface_emit_scaled_font_subset, - surface); - -BAIL: - _cairo_scaled_font_subsets_destroy (surface->font_subsets); - surface->font_subsets = NULL; - - return status; -} - -static cairo_pdf_resource_t -_cairo_pdf_surface_write_catalog (cairo_pdf_surface_t *surface) -{ - cairo_pdf_resource_t catalog; - - catalog = _cairo_pdf_surface_new_object (surface); - if (catalog.id == 0) - return catalog; - - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /Type /Catalog\n" - " /Pages %d 0 R\n" - ">>\n" - "endobj\n", - catalog.id, - surface->pages_resource.id); - - return catalog; -} - -static long -_cairo_pdf_surface_write_xref (cairo_pdf_surface_t *surface) -{ - cairo_pdf_object_t *object; - int num_objects, i; - long offset; - char buffer[11]; - - num_objects = _cairo_array_num_elements (&surface->objects); - - offset = _cairo_output_stream_get_position (surface->output); - _cairo_output_stream_printf (surface->output, - "xref\n" - "%d %d\n", - 0, num_objects + 1); - - _cairo_output_stream_printf (surface->output, - "0000000000 65535 f \n"); - for (i = 0; i < num_objects; i++) { - object = _cairo_array_index (&surface->objects, i); - snprintf (buffer, sizeof buffer, "%010ld", object->offset); - _cairo_output_stream_printf (surface->output, - "%s 00000 n \n", buffer); - } - - return offset; -} - -static cairo_int_status_t -_cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface, - cairo_pdf_smask_group_t *group) -{ - cairo_pdf_resource_t mask_group; - cairo_pdf_resource_t smask; - cairo_pdf_smask_group_t *smask_group; - cairo_pdf_resource_t pattern_res, gstate_res; - cairo_int_status_t status; - cairo_box_double_t bbox; - - /* Create mask group */ - _get_bbox_from_extents (group->height, &group->extents, &bbox); - status = _cairo_pdf_surface_open_group (surface, &bbox, NULL); - if (unlikely (status)) - return status; - - if (_can_paint_pattern (group->mask)) { - _cairo_output_stream_printf (surface->output, "q\n"); - status = _cairo_pdf_surface_paint_pattern (surface, - CAIRO_OPERATOR_OVER, - group->mask, - &group->extents, - FALSE); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->output, "Q\n"); - } else { - pattern_res.id = 0; - gstate_res.id = 0; - status = _cairo_pdf_surface_add_pdf_pattern (surface, group->mask, - CAIRO_OPERATOR_OVER, - NULL, - &pattern_res, &gstate_res); - if (unlikely (status)) - return status; - - if (gstate_res.id != 0) { - smask_group = _cairo_pdf_surface_create_smask_group (surface, &group->extents); - if (unlikely (smask_group == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - smask_group->width = group->width; - smask_group->height = group->height; - smask_group->operation = PDF_PAINT; - smask_group->source = cairo_pattern_reference (group->mask); - smask_group->source_res = pattern_res; - status = _cairo_pdf_surface_add_smask_group (surface, smask_group); - if (unlikely (status)) { - _cairo_pdf_smask_group_destroy (smask_group); - return status; - } - - status = _cairo_pdf_surface_add_smask (surface, gstate_res); - if (unlikely (status)) - return status; - - status = _cairo_pdf_surface_add_xobject (surface, smask_group->group_res); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->output, - "q /s%d gs /x%d Do Q\n", - gstate_res.id, - smask_group->group_res.id); - } else { - status = _cairo_pdf_surface_select_pattern (surface, group->mask, pattern_res, FALSE); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->output, - "%f %f %f %f re f\n", - bbox.p1.x, - bbox.p1.y, - bbox.p2.x - bbox.p1.x, - bbox.p2.y - bbox.p1.y); - - status = _cairo_pdf_surface_unselect_pattern (surface); - if (unlikely (status)) - return status; - } - } - - status = _cairo_pdf_surface_close_group (surface, &mask_group); - if (unlikely (status)) - return status; - - /* Create source group */ - status = _cairo_pdf_surface_open_group (surface, &bbox, &group->source_res); - if (unlikely (status)) - return status; - - if (_can_paint_pattern (group->source)) { - _cairo_output_stream_printf (surface->output, "q\n"); - status = _cairo_pdf_surface_paint_pattern (surface, - CAIRO_OPERATOR_OVER, - group->source, - &group->extents, - FALSE); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->output, "Q\n"); - } else { - pattern_res.id = 0; - gstate_res.id = 0; - status = _cairo_pdf_surface_add_pdf_pattern (surface, group->source, - CAIRO_OPERATOR_OVER, - NULL, - &pattern_res, &gstate_res); - if (unlikely (status)) - return status; - - if (gstate_res.id != 0) { - smask_group = _cairo_pdf_surface_create_smask_group (surface, &group->extents); - if (unlikely (smask_group == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - smask_group->operation = PDF_PAINT; - smask_group->source = cairo_pattern_reference (group->source); - smask_group->source_res = pattern_res; - status = _cairo_pdf_surface_add_smask_group (surface, smask_group); - if (unlikely (status)) { - _cairo_pdf_smask_group_destroy (smask_group); - return status; - } - - status = _cairo_pdf_surface_add_smask (surface, gstate_res); - if (unlikely (status)) - return status; - - status = _cairo_pdf_surface_add_xobject (surface, smask_group->group_res); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->output, - "q /s%d gs /x%d Do Q\n", - gstate_res.id, - smask_group->group_res.id); - } else { - status = _cairo_pdf_surface_select_pattern (surface, group->source, pattern_res, FALSE); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->output, - "%f %f %f %f re f\n", - bbox.p1.x, - bbox.p1.y, - bbox.p2.x - bbox.p1.x, - bbox.p2.y - bbox.p1.y); - - status = _cairo_pdf_surface_unselect_pattern (surface); - if (unlikely (status)) - return status; - } - } - - status = _cairo_pdf_surface_close_group (surface, NULL); - if (unlikely (status)) - return status; - - /* Create an smask based on the alpha component of mask_group */ - smask = _cairo_pdf_surface_new_object (surface); - if (smask.id == 0) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /Type /Mask\n" - " /S /Alpha\n" - " /G %d 0 R\n" - ">>\n" - "endobj\n", - smask.id, - mask_group.id); - - /* Create a GState that uses the smask */ - _cairo_pdf_surface_update_object (surface, group->group_res); - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /Type /ExtGState\n" - " /SMask %d 0 R\n" - " /ca 1\n" - " /CA 1\n" - " /AIS false\n" - ">>\n" - "endobj\n", - group->group_res.id, - smask.id); - - return _cairo_output_stream_get_status (surface->output); -} - -static cairo_int_status_t -_cairo_pdf_surface_write_smask_group (cairo_pdf_surface_t *surface, - cairo_pdf_smask_group_t *group) -{ - double old_width, old_height; - cairo_int_status_t status; - cairo_box_double_t bbox; - - old_width = surface->width; - old_height = surface->height; - _cairo_pdf_surface_set_size_internal (surface, - group->width, - group->height); - /* _mask is a special case that requires two groups - source - * and mask as well as a smask and gstate dictionary */ - if (group->operation == PDF_MASK) { - status = _cairo_pdf_surface_write_mask_group (surface, group); - goto RESTORE_SIZE; - } - - _get_bbox_from_extents (group->height, &group->extents, &bbox); - status = _cairo_pdf_surface_open_group (surface, &bbox, &group->group_res); - if (unlikely (status)) - return status; - - status = _cairo_pdf_surface_select_pattern (surface, - group->source, - group->source_res, - group->operation == PDF_STROKE); - if (unlikely (status)) - return status; - - switch (group->operation) { - case PDF_PAINT: - _cairo_output_stream_printf (surface->output, - "0 0 %f %f re f\n", - surface->width, surface->height); - break; - case PDF_MASK: - ASSERT_NOT_REACHED; - break; - case PDF_FILL: - status = _cairo_pdf_operators_fill (&surface->pdf_operators, - &group->path, - group->fill_rule); - break; - case PDF_STROKE: - status = _cairo_pdf_operators_stroke (&surface->pdf_operators, - &group->path, - &group->style, - &group->ctm, - &group->ctm_inverse); - break; - case PDF_SHOW_GLYPHS: - status = _cairo_pdf_operators_show_text_glyphs (&surface->pdf_operators, - group->utf8, group->utf8_len, - group->glyphs, group->num_glyphs, - group->clusters, group->num_clusters, - group->cluster_flags, - group->scaled_font); - break; - } - if (unlikely (status)) - return status; - - status = _cairo_pdf_surface_unselect_pattern (surface); - if (unlikely (status)) - return status; - - status = _cairo_pdf_surface_close_group (surface, NULL); - -RESTORE_SIZE: - _cairo_pdf_surface_set_size_internal (surface, - old_width, - old_height); - - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_write_patterns_and_smask_groups (cairo_pdf_surface_t *surface) -{ - cairo_pdf_pattern_t pattern; - cairo_pdf_smask_group_t *group; - cairo_pdf_source_surface_t src_surface; - unsigned int pattern_index, group_index, surface_index; - cairo_int_status_t status; - - /* Writing out PDF_MASK groups will cause additional smask groups - * to be appended to surface->smask_groups. Additional patterns - * may also be appended to surface->patterns. - * - * Writing recording surface patterns will cause additional patterns - * and groups to be appended. - */ - pattern_index = 0; - group_index = 0; - surface_index = 0; - while ((pattern_index < _cairo_array_num_elements (&surface->page_patterns)) || - (group_index < _cairo_array_num_elements (&surface->smask_groups)) || - (surface_index < _cairo_array_num_elements (&surface->page_surfaces))) - { - for (; group_index < _cairo_array_num_elements (&surface->smask_groups); group_index++) { - _cairo_array_copy_element (&surface->smask_groups, group_index, &group); - status = _cairo_pdf_surface_write_smask_group (surface, group); - if (unlikely (status)) - return status; - } - - for (; pattern_index < _cairo_array_num_elements (&surface->page_patterns); pattern_index++) { - _cairo_array_copy_element (&surface->page_patterns, pattern_index, &pattern); - status = _cairo_pdf_surface_emit_pattern (surface, &pattern); - if (unlikely (status)) - return status; - } - - for (; surface_index < _cairo_array_num_elements (&surface->page_surfaces); surface_index++) { - _cairo_array_copy_element (&surface->page_surfaces, surface_index, &src_surface); - status = _cairo_pdf_surface_emit_surface (surface, &src_surface); - if (unlikely (status)) - return status; - } - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface) -{ - cairo_pdf_resource_t page, knockout, res; - cairo_int_status_t status; - unsigned int i, len; - - _cairo_pdf_group_resources_clear (&surface->resources); - if (surface->has_fallback_images) { - cairo_rectangle_int_t extents; - cairo_box_double_t bbox; - - extents.x = 0; - extents.y = 0; - extents.width = ceil (surface->width); - extents.height = ceil (surface->height); - _get_bbox_from_extents (surface->height, &extents, &bbox); - status = _cairo_pdf_surface_open_knockout_group (surface, &bbox); - if (unlikely (status)) - return status; - - len = _cairo_array_num_elements (&surface->knockout_group); - for (i = 0; i < len; i++) { - _cairo_array_copy_element (&surface->knockout_group, i, &res); - _cairo_output_stream_printf (surface->output, - "/x%d Do\n", - res.id); - status = _cairo_pdf_surface_add_xobject (surface, res); - if (unlikely (status)) - return status; - } - _cairo_output_stream_printf (surface->output, - "/x%d Do\n", - surface->content.id); - status = _cairo_pdf_surface_add_xobject (surface, surface->content); - if (unlikely (status)) - return status; - - status = _cairo_pdf_surface_close_group (surface, &knockout); - if (unlikely (status)) - return status; - - _cairo_pdf_group_resources_clear (&surface->resources); - status = _cairo_pdf_surface_open_content_stream (surface, NULL, NULL, FALSE, FALSE); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->output, - "/x%d Do\n", - knockout.id); - status = _cairo_pdf_surface_add_xobject (surface, knockout); - if (unlikely (status)) - return status; - - status = _cairo_pdf_surface_close_content_stream (surface); - if (unlikely (status)) - return status; - } - - page = _cairo_pdf_surface_new_object (surface); - if (page.id == 0) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_output_stream_printf (surface->output, - "%d 0 obj\n" - "<< /Type /Page\n" - " /Parent %d 0 R\n" - " /MediaBox [ 0 0 %f %f ]\n" - " /Contents %d 0 R\n" - " /Group <<\n" - " /Type /Group\n" - " /S /Transparency\n" - " /I true\n" - " /CS /DeviceRGB\n" - " >>\n" - " /Resources %d 0 R\n" - ">>\n" - "endobj\n", - page.id, - surface->pages_resource.id, - surface->width, - surface->height, - surface->content.id, - surface->content_resources.id); - - status = _cairo_array_append (&surface->pages, &page); - if (unlikely (status)) - return status; - - status = _cairo_pdf_surface_write_patterns_and_smask_groups (surface); - if (unlikely (status)) - return status; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_pdf_surface_analyze_surface_pattern_transparency (cairo_pdf_surface_t *surface, - cairo_surface_pattern_t *pattern) -{ - cairo_image_surface_t *image; - void *image_extra; - cairo_int_status_t status; - cairo_image_transparency_t transparency; - - status = _cairo_surface_acquire_source_image (pattern->surface, - &image, - &image_extra); - if (unlikely (status)) - return status; - - if (image->base.status) - return image->base.status; - - transparency = _cairo_image_analyze_transparency (image); - if (transparency == CAIRO_IMAGE_IS_OPAQUE) - status = CAIRO_STATUS_SUCCESS; - else - status = CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY; - - _cairo_surface_release_source_image (pattern->surface, image, image_extra); - - return status; -} - -static cairo_bool_t -_surface_pattern_supported (cairo_surface_pattern_t *pattern) -{ - cairo_extend_t extend; - - if (pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING) - return TRUE; - - if (pattern->surface->backend->acquire_source_image == NULL) - return FALSE; - - /* Does an ALPHA-only source surface even make sense? Maybe, but I - * don't think it's worth the extra code to support it. */ - -/* XXX: Need to write this function here... - if (pattern->surface->content == CAIRO_CONTENT_ALPHA) - return FALSE; -*/ - - extend = cairo_pattern_get_extend (&pattern->base); - switch (extend) { - case CAIRO_EXTEND_NONE: - case CAIRO_EXTEND_REPEAT: - case CAIRO_EXTEND_REFLECT: - /* There's no point returning FALSE for EXTEND_PAD, as the image - * surface does not currently implement it either */ - case CAIRO_EXTEND_PAD: - return TRUE; - } - - ASSERT_NOT_REACHED; - return FALSE; -} - -static cairo_bool_t -_pattern_supported (const cairo_pattern_t *pattern) -{ - switch (pattern->type) { - case CAIRO_PATTERN_TYPE_SOLID: - case CAIRO_PATTERN_TYPE_LINEAR: - case CAIRO_PATTERN_TYPE_RADIAL: - case CAIRO_PATTERN_TYPE_MESH: - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - return TRUE; - - case CAIRO_PATTERN_TYPE_SURFACE: - return _surface_pattern_supported ((cairo_surface_pattern_t *) pattern); - - default: - ASSERT_NOT_REACHED; - return FALSE; - } -} - -static cairo_bool_t -_pdf_operator_supported (cairo_operator_t op) -{ - switch (op) { - case CAIRO_OPERATOR_OVER: - case CAIRO_OPERATOR_MULTIPLY: - case CAIRO_OPERATOR_SCREEN: - case CAIRO_OPERATOR_OVERLAY: - case CAIRO_OPERATOR_DARKEN: - case CAIRO_OPERATOR_LIGHTEN: - case CAIRO_OPERATOR_COLOR_DODGE: - case CAIRO_OPERATOR_COLOR_BURN: - case CAIRO_OPERATOR_HARD_LIGHT: - case CAIRO_OPERATOR_SOFT_LIGHT: - case CAIRO_OPERATOR_DIFFERENCE: - case CAIRO_OPERATOR_EXCLUSION: - case CAIRO_OPERATOR_HSL_HUE: - case CAIRO_OPERATOR_HSL_SATURATION: - case CAIRO_OPERATOR_HSL_COLOR: - case CAIRO_OPERATOR_HSL_LUMINOSITY: - return TRUE; - - default: - case CAIRO_OPERATOR_CLEAR: - case CAIRO_OPERATOR_SOURCE: - case CAIRO_OPERATOR_IN: - case CAIRO_OPERATOR_OUT: - case CAIRO_OPERATOR_ATOP: - case CAIRO_OPERATOR_DEST: - case CAIRO_OPERATOR_DEST_OVER: - case CAIRO_OPERATOR_DEST_IN: - case CAIRO_OPERATOR_DEST_OUT: - case CAIRO_OPERATOR_DEST_ATOP: - case CAIRO_OPERATOR_XOR: - case CAIRO_OPERATOR_ADD: - case CAIRO_OPERATOR_SATURATE: - return FALSE; - } -} - -static cairo_int_status_t -_cairo_pdf_surface_analyze_operation (cairo_pdf_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *pattern, - const cairo_rectangle_int_t *extents) -{ - if (surface->force_fallbacks && - surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) - { - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - if (! _pattern_supported (pattern)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (_pdf_operator_supported (op)) { - if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) { - cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) pattern; - - if (surface_pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING) { - if (pattern->extend == CAIRO_EXTEND_PAD) { - cairo_box_t box; - cairo_rectangle_int_t rect; - cairo_rectangle_int_t rec_extents; - - /* get the operation extents in pattern space */ - _cairo_box_from_rectangle (&box, extents); - _cairo_matrix_transform_bounding_box_fixed (&pattern->matrix, &box, NULL); - _cairo_box_round_to_rectangle (&box, &rect); - - /* Check if surface needs padding to fill extents */ - if (_cairo_surface_get_extents (surface_pattern->surface, &rec_extents)) { - if (_cairo_fixed_integer_ceil(box.p1.x) < rec_extents.x || - _cairo_fixed_integer_ceil(box.p1.y) < rec_extents.y || - _cairo_fixed_integer_floor(box.p2.y) > rec_extents.x + rec_extents.width || - _cairo_fixed_integer_floor(box.p2.y) > rec_extents.y + rec_extents.height) - { - return CAIRO_INT_STATUS_UNSUPPORTED; - } - } - } - return CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN; - } - } - - return CAIRO_STATUS_SUCCESS; - } - - - /* The SOURCE operator is supported if the pattern is opaque or if - * there is nothing painted underneath. */ - if (op == CAIRO_OPERATOR_SOURCE) { - if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) { - cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) pattern; - - if (surface_pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING) { - if (_cairo_pattern_is_opaque (pattern, extents)) { - return CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN; - } else { - /* FIXME: The analysis surface does not yet have - * the capability to analyze a non opaque recording - * surface and mark it supported if there is - * nothing underneath. For now recording surfaces of - * type CONTENT_COLOR_ALPHA painted with - * OPERATOR_SOURCE will result in a fallback - * image. */ - - return CAIRO_INT_STATUS_UNSUPPORTED; - } - } else { - return _cairo_pdf_surface_analyze_surface_pattern_transparency (surface, - surface_pattern); - } - } - - if (_cairo_pattern_is_opaque (pattern, extents)) - return CAIRO_STATUS_SUCCESS; - else - return CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY; - } - - return CAIRO_INT_STATUS_UNSUPPORTED; -} - -static cairo_bool_t -_cairo_pdf_surface_operation_supported (cairo_pdf_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *pattern, - const cairo_rectangle_int_t *extents) -{ - return _cairo_pdf_surface_analyze_operation (surface, op, pattern, extents) != CAIRO_INT_STATUS_UNSUPPORTED; -} - -static cairo_int_status_t -_cairo_pdf_surface_start_fallback (cairo_pdf_surface_t *surface) -{ - cairo_box_double_t bbox; - cairo_int_status_t status; - - status = _cairo_pdf_surface_close_content_stream (surface); - if (unlikely (status)) - return status; - - status = _cairo_array_append (&surface->knockout_group, &surface->content); - if (unlikely (status)) - return status; - - _cairo_pdf_group_resources_clear (&surface->resources); - bbox.p1.x = 0; - bbox.p1.y = 0; - bbox.p2.x = surface->width; - bbox.p2.y = surface->height; - return _cairo_pdf_surface_open_content_stream (surface, &bbox, NULL, TRUE, TRUE); -} - -/* If source is an opaque image and mask is an image and both images - * have the same bounding box we can emit them as a image/smask pair. - */ -static cairo_int_status_t -_cairo_pdf_surface_emit_combined_smask (cairo_pdf_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_rectangle_int_t *extents) -{ - cairo_int_status_t status; - cairo_image_surface_t *image; - void *image_extra; - cairo_image_transparency_t transparency; - cairo_pdf_resource_t smask_res; - int src_width, src_height; - int mask_width, mask_height; - double src_x_offset, src_y_offset; - double mask_x_offset, mask_y_offset; - double src_x1, src_y1, src_x2, src_y2; - double mask_x1, mask_y1, mask_x2, mask_y2; - cairo_matrix_t p2u; - double src_radius, mask_radius, e; - cairo_rectangle_int_t extents2; - cairo_bool_t need_smask; - - /* Check that source and mask are images */ - - if (!((source->type == CAIRO_PATTERN_TYPE_SURFACE || source->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE) && - (mask->type == CAIRO_PATTERN_TYPE_SURFACE || mask->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE))) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (source->type == CAIRO_PATTERN_TYPE_SURFACE && - ((cairo_surface_pattern_t *) source)->surface->type == CAIRO_SURFACE_TYPE_RECORDING) - { - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - if (mask->type == CAIRO_PATTERN_TYPE_SURFACE && - ((cairo_surface_pattern_t *) mask)->surface->type == CAIRO_SURFACE_TYPE_RECORDING) - { - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - if (source->extend != CAIRO_EXTEND_NONE || mask->extend != CAIRO_EXTEND_NONE) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* Check that source is opaque and get image sizes */ - - status = _cairo_pdf_surface_acquire_source_image_from_pattern (surface, source, - &image, &image_extra); - if (unlikely (status)) - return status; - - if (image->base.status) - return image->base.status; - - src_width = image->width; - src_height = image->height; - if (source->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE) { - cairo_surface_get_device_offset (&image->base, &src_x_offset, &src_y_offset); - } else { - src_x_offset = 0; - src_y_offset = 0; - } - - transparency = _cairo_image_analyze_transparency (image); - _cairo_pdf_surface_release_source_image_from_pattern (surface, source, image, image_extra); - - if (transparency != CAIRO_IMAGE_IS_OPAQUE) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_pdf_surface_acquire_source_image_from_pattern (surface, mask, - &image, &image_extra); - if (unlikely (status)) - return status; - - if (image->base.status) - return image->base.status; - - mask_width = image->width; - mask_height = image->height; - if (mask->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE) { - cairo_surface_get_device_offset (&image->base, &mask_x_offset, &mask_y_offset); - } else { - mask_x_offset = 0; - mask_y_offset = 0; - } - - transparency = _cairo_image_analyze_transparency (image); - need_smask = transparency != CAIRO_IMAGE_IS_OPAQUE; - - _cairo_pdf_surface_release_source_image_from_pattern (surface, mask, image, image_extra); - - /* Check that both images have the same extents with a tolerance - * of half the smallest source pixel. */ - - p2u = source->matrix; - status = cairo_matrix_invert (&p2u); - /* cairo_pattern_set_matrix ensures the matrix is invertible */ - assert (status == CAIRO_INT_STATUS_SUCCESS); - src_x1 = 0; - src_y1 = 0; - src_x2 = src_width; - src_y2 = src_height; - cairo_matrix_transform_point (&p2u, &src_x1, &src_y1); - cairo_matrix_transform_point (&p2u, &src_x2, &src_y2); - src_radius = _cairo_matrix_transformed_circle_major_axis (&p2u, 0.5); - - p2u = mask->matrix; - status = cairo_matrix_invert (&p2u); - /* cairo_pattern_set_matrix ensures the matrix is invertible */ - assert (status == CAIRO_INT_STATUS_SUCCESS); - mask_x1 = 0; - mask_y1 = 0; - mask_x2 = mask_width; - mask_y2 = mask_height; - cairo_matrix_transform_point (&p2u, &mask_x1, &mask_y1); - cairo_matrix_transform_point (&p2u, &mask_x2, &mask_y2); - mask_radius = _cairo_matrix_transformed_circle_major_axis (&p2u, 0.5); - - if (src_radius < mask_radius) - e = src_radius; - else - e = mask_radius; - - if (fabs(src_x1 - mask_x1) > e || - fabs(src_x2 - mask_x2) > e || - fabs(src_y1 - mask_y1) > e || - fabs(src_y2 - mask_y2) > e) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* Check both images have same device offset */ - if (fabs(src_x_offset - mask_x_offset) > e || - fabs(src_y_offset - mask_y_offset) > e) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (need_smask) { - status = _cairo_pdf_surface_add_source_surface (surface, - NULL, - mask, - op, - source->filter, - FALSE, - TRUE, - extents, - NULL, - &smask_res, - &mask_width, - &mask_height, - &mask_x_offset, - &mask_y_offset, - &extents2); - if (unlikely (status)) - return status; - } - - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->output, "q\n"); - status = _cairo_pdf_surface_paint_surface_pattern (surface, op, source, extents, - need_smask ? &smask_res : NULL, - FALSE); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->output, "Q\n"); - - status = _cairo_output_stream_get_status (surface->output); - - - return status; -} - -/* A PDF stencil mask is an A1 mask used with the current color */ -static cairo_int_status_t -_cairo_pdf_surface_emit_stencil_mask (cairo_pdf_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_rectangle_int_t *extents) -{ - cairo_int_status_t status; - cairo_image_surface_t *image; - void *image_extra; - cairo_image_transparency_t transparency; - cairo_pdf_resource_t pattern_res = {0}; - - if (! (source->type == CAIRO_PATTERN_TYPE_SOLID && - (mask->type == CAIRO_PATTERN_TYPE_SURFACE || mask->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE))) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (mask->type == CAIRO_PATTERN_TYPE_SURFACE && - ((cairo_surface_pattern_t *) mask)->surface->type == CAIRO_SURFACE_TYPE_RECORDING) - { - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - status = _cairo_pdf_surface_acquire_source_image_from_pattern (surface, mask, - &image, &image_extra); - if (unlikely (status)) - return status; - - if (image->base.status) - return image->base.status; - - transparency = _cairo_image_analyze_transparency (image); - if (transparency != CAIRO_IMAGE_IS_OPAQUE && - transparency != CAIRO_IMAGE_HAS_BILEVEL_ALPHA) - { - status = CAIRO_INT_STATUS_UNSUPPORTED; - goto cleanup; - } - - status = _cairo_pdf_surface_select_pattern (surface, source, - pattern_res, FALSE); - if (unlikely (status)) - return status; - - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->output, "q\n"); - status = _cairo_pdf_surface_paint_surface_pattern (surface, op, mask, extents, NULL, TRUE); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->output, "Q\n"); - - status = _cairo_output_stream_get_status (surface->output); - -cleanup: - _cairo_pdf_surface_release_source_image_from_pattern (surface, mask, image, image_extra); - - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_set_clip (cairo_pdf_surface_t *surface, - cairo_composite_rectangles_t *composite) -{ - cairo_clip_t *clip = composite->clip; - - if (_cairo_composite_rectangles_can_reduce_clip (composite, clip)) - clip = NULL; - - if (clip == NULL) { - if (_cairo_composite_rectangles_can_reduce_clip (composite, - surface->clipper.clip)) - return CAIRO_STATUS_SUCCESS; - } - - return _cairo_surface_clipper_set_clip (&surface->clipper, clip); -} - -static cairo_int_status_t -_cairo_pdf_surface_paint (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - cairo_pdf_surface_t *surface = abstract_surface; - cairo_pdf_smask_group_t *group; - cairo_pdf_resource_t pattern_res, gstate_res; - cairo_composite_rectangles_t extents; - cairo_int_status_t status; - - status = _cairo_composite_rectangles_init_for_paint (&extents, - &surface->base, - op, source, clip); - if (unlikely (status)) - return status; - - if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) { - status = _cairo_pdf_surface_analyze_operation (surface, op, source, &extents.bounded); - goto cleanup; - } else if (surface->paginated_mode == CAIRO_PAGINATED_MODE_FALLBACK) { - status = _cairo_pdf_surface_start_fallback (surface); - if (unlikely (status)) - goto cleanup; - } - - assert (_cairo_pdf_surface_operation_supported (surface, op, source, &extents.bounded)); - - status = _cairo_pdf_surface_set_clip (surface, &extents); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_surface_select_operator (surface, op); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - goto cleanup; - - if (_can_paint_pattern (source)) { - _cairo_output_stream_printf (surface->output, "q\n"); - status = _cairo_pdf_surface_paint_pattern (surface, - op, - source, - &extents.bounded, - FALSE); - if (unlikely (status)) - goto cleanup; - - _cairo_output_stream_printf (surface->output, "Q\n"); - _cairo_composite_rectangles_fini (&extents); - return _cairo_output_stream_get_status (surface->output); - } - - pattern_res.id = 0; - gstate_res.id = 0; - status = _cairo_pdf_surface_add_pdf_pattern (surface, source, op, - &extents.bounded, - &pattern_res, &gstate_res); - if (unlikely (status)) - goto cleanup; - - if (gstate_res.id != 0) { - group = _cairo_pdf_surface_create_smask_group (surface, &extents.bounded); - if (unlikely (group == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto cleanup; - } - - group->operation = PDF_PAINT; - status = _cairo_pattern_create_copy (&group->source, source); - if (unlikely (status)) { - _cairo_pdf_smask_group_destroy (group); - goto cleanup; - } - group->source_res = pattern_res; - status = _cairo_pdf_surface_add_smask_group (surface, group); - if (unlikely (status)) { - _cairo_pdf_smask_group_destroy (group); - goto cleanup; - } - - status = _cairo_pdf_surface_add_smask (surface, gstate_res); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_surface_add_xobject (surface, group->group_res); - if (unlikely (status)) - goto cleanup; - - _cairo_output_stream_printf (surface->output, - "q /s%d gs /x%d Do Q\n", - gstate_res.id, - group->group_res.id); - } else { - status = _cairo_pdf_surface_select_pattern (surface, source, - pattern_res, FALSE); - if (unlikely (status)) - goto cleanup; - - _cairo_output_stream_printf (surface->output, - "0 0 %f %f re f\n", - surface->width, surface->height); - - status = _cairo_pdf_surface_unselect_pattern (surface); - if (unlikely (status)) - goto cleanup; - } - - _cairo_composite_rectangles_fini (&extents); - return _cairo_output_stream_get_status (surface->output); - -cleanup: - _cairo_composite_rectangles_fini (&extents); - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_mask (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - cairo_pdf_surface_t *surface = abstract_surface; - cairo_pdf_smask_group_t *group; - cairo_composite_rectangles_t extents; - cairo_int_status_t status; - cairo_rectangle_int_t r; - cairo_box_t box; - - status = _cairo_composite_rectangles_init_for_mask (&extents, - &surface->base, - op, source, mask, clip); - if (unlikely (status)) - return status; - - if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) { - cairo_int_status_t source_status, mask_status; - - status = _cairo_pdf_surface_analyze_operation (surface, op, source, &extents.bounded); - if (_cairo_int_status_is_error (status)) - goto cleanup; - source_status = status; - - if (mask->has_component_alpha) { - status = CAIRO_INT_STATUS_UNSUPPORTED; - } else { - status = _cairo_pdf_surface_analyze_operation (surface, op, mask, &extents.bounded); - if (_cairo_int_status_is_error (status)) - goto cleanup; - } - mask_status = status; - - _cairo_composite_rectangles_fini (&extents); - return _cairo_analysis_surface_merge_status (source_status, - mask_status); - } else if (surface->paginated_mode == CAIRO_PAGINATED_MODE_FALLBACK) { - status = _cairo_pdf_surface_start_fallback (surface); - if (unlikely (status)) - goto cleanup; - } - - assert (_cairo_pdf_surface_operation_supported (surface, op, source, &extents.bounded)); - assert (_cairo_pdf_surface_operation_supported (surface, op, mask, &extents.bounded)); - - /* get the accurate extents */ - status = _cairo_pattern_get_ink_extents (source, &r); - if (unlikely (status)) - goto cleanup; - - /* XXX slight impedance mismatch */ - _cairo_box_from_rectangle (&box, &r); - status = _cairo_composite_rectangles_intersect_source_extents (&extents, - &box); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pattern_get_ink_extents (mask, &r); - if (unlikely (status)) - goto cleanup; - - _cairo_box_from_rectangle (&box, &r); - status = _cairo_composite_rectangles_intersect_mask_extents (&extents, - &box); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_surface_set_clip (surface, &extents); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_surface_select_operator (surface, op); - if (unlikely (status)) - goto cleanup; - - /* Check if we can combine source and mask into a smask image */ - status = _cairo_pdf_surface_emit_combined_smask (surface, op, source, mask, &extents.bounded); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - goto cleanup; - - /* Check if we can use a stencil mask */ - status = _cairo_pdf_surface_emit_stencil_mask (surface, op, source, mask, &extents.bounded); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - goto cleanup; - - group = _cairo_pdf_surface_create_smask_group (surface, &extents.bounded); - if (unlikely (group == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto cleanup; - } - - group->operation = PDF_MASK; - status = _cairo_pattern_create_copy (&group->source, source); - if (unlikely (status)) { - _cairo_pdf_smask_group_destroy (group); - goto cleanup; - } - status = _cairo_pattern_create_copy (&group->mask, mask); - if (unlikely (status)) { - _cairo_pdf_smask_group_destroy (group); - goto cleanup; - } - group->source_res = _cairo_pdf_surface_new_object (surface); - if (group->source_res.id == 0) { - _cairo_pdf_smask_group_destroy (group); - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto cleanup; - } - - status = _cairo_pdf_surface_add_smask_group (surface, group); - if (unlikely (status)) { - _cairo_pdf_smask_group_destroy (group); - goto cleanup; - } - - status = _cairo_pdf_surface_add_smask (surface, group->group_res); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_surface_add_xobject (surface, group->source_res); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - goto cleanup; - - _cairo_output_stream_printf (surface->output, - "q /s%d gs /x%d Do Q\n", - group->group_res.id, - group->source_res.id); - - _cairo_composite_rectangles_fini (&extents); - return _cairo_output_stream_get_status (surface->output); - -cleanup: - _cairo_composite_rectangles_fini (&extents); - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_stroke (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_pdf_surface_t *surface = abstract_surface; - cairo_pdf_smask_group_t *group; - cairo_pdf_resource_t pattern_res, gstate_res; - cairo_composite_rectangles_t extents; - cairo_int_status_t status; - - status = _cairo_composite_rectangles_init_for_stroke (&extents, - &surface->base, - op, source, - path, style, ctm, - clip); - if (unlikely (status)) - return status; - - /* use the more accurate extents */ - if (extents.is_bounded) { - cairo_rectangle_int_t mask; - cairo_box_t box; - - status = _cairo_path_fixed_stroke_extents (path, style, - ctm, ctm_inverse, - tolerance, - &mask); - if (unlikely (status)) - goto cleanup; - - _cairo_box_from_rectangle (&box, &mask); - status = _cairo_composite_rectangles_intersect_mask_extents (&extents, - &box); - if (unlikely (status)) - goto cleanup; - } - - if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) { - status = _cairo_pdf_surface_analyze_operation (surface, op, source, &extents.bounded); - goto cleanup; - } - - assert (_cairo_pdf_surface_operation_supported (surface, op, source, &extents.bounded)); - - status = _cairo_pdf_surface_set_clip (surface, &extents); - if (unlikely (status)) - goto cleanup; - - pattern_res.id = 0; - gstate_res.id = 0; - status = _cairo_pdf_surface_add_pdf_pattern (surface, source, op, - &extents.bounded, - &pattern_res, &gstate_res); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_surface_select_operator (surface, op); - if (unlikely (status)) - goto cleanup; - - if (gstate_res.id != 0) { - group = _cairo_pdf_surface_create_smask_group (surface, &extents.bounded); - if (unlikely (group == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto cleanup; - } - - group->operation = PDF_STROKE; - status = _cairo_pattern_create_copy (&group->source, source); - if (unlikely (status)) { - _cairo_pdf_smask_group_destroy (group); - goto cleanup; - } - group->source_res = pattern_res; - status = _cairo_path_fixed_init_copy (&group->path, path); - if (unlikely (status)) { - _cairo_pdf_smask_group_destroy (group); - goto cleanup; - } - - group->style = *style; - group->ctm = *ctm; - group->ctm_inverse = *ctm_inverse; - status = _cairo_pdf_surface_add_smask_group (surface, group); - if (unlikely (status)) { - _cairo_pdf_smask_group_destroy (group); - goto cleanup; - } - - status = _cairo_pdf_surface_add_smask (surface, gstate_res); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_surface_add_xobject (surface, group->group_res); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - goto cleanup; - - _cairo_output_stream_printf (surface->output, - "q /s%d gs /x%d Do Q\n", - gstate_res.id, - group->group_res.id); - } else { - status = _cairo_pdf_surface_select_pattern (surface, source, pattern_res, TRUE); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_operators_stroke (&surface->pdf_operators, - path, - style, - ctm, - ctm_inverse); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_surface_unselect_pattern (surface); - if (unlikely (status)) - goto cleanup; - } - - _cairo_composite_rectangles_fini (&extents); - return _cairo_output_stream_get_status (surface->output); - -cleanup: - _cairo_composite_rectangles_fini (&extents); - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_fill (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t*path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_pdf_surface_t *surface = abstract_surface; - cairo_int_status_t status; - cairo_pdf_smask_group_t *group; - cairo_pdf_resource_t pattern_res, gstate_res; - cairo_composite_rectangles_t extents; - - status = _cairo_composite_rectangles_init_for_fill (&extents, - &surface->base, - op, source, path, - clip); - if (unlikely (status)) - return status; - - /* use the more accurate extents */ - if (extents.is_bounded) { - cairo_rectangle_int_t mask; - cairo_box_t box; - - _cairo_path_fixed_fill_extents (path, - fill_rule, - tolerance, - &mask); - - _cairo_box_from_rectangle (&box, &mask); - status = _cairo_composite_rectangles_intersect_mask_extents (&extents, - &box); - if (unlikely (status)) - goto cleanup; - } - - if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) { - status = _cairo_pdf_surface_analyze_operation (surface, op, source, &extents.bounded); - goto cleanup; - } else if (surface->paginated_mode == CAIRO_PAGINATED_MODE_FALLBACK) { - status = _cairo_pdf_surface_start_fallback (surface); - if (unlikely (status)) - goto cleanup; - } - - assert (_cairo_pdf_surface_operation_supported (surface, op, source, &extents.bounded)); - - status = _cairo_pdf_surface_set_clip (surface, &extents); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_surface_select_operator (surface, op); - if (unlikely (status)) - goto cleanup; - - if (_can_paint_pattern (source)) { - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - goto cleanup; - - _cairo_output_stream_printf (surface->output, "q\n"); - status = _cairo_pdf_operators_clip (&surface->pdf_operators, - path, - fill_rule); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_surface_paint_pattern (surface, - op, - source, - &extents.bounded, - FALSE); - if (unlikely (status)) - goto cleanup; - - _cairo_output_stream_printf (surface->output, "Q\n"); - status = _cairo_output_stream_get_status (surface->output); - goto cleanup; - } - - pattern_res.id = 0; - gstate_res.id = 0; - status = _cairo_pdf_surface_add_pdf_pattern (surface, source, op, - &extents.bounded, - &pattern_res, &gstate_res); - if (unlikely (status)) - goto cleanup; - - if (gstate_res.id != 0) { - group = _cairo_pdf_surface_create_smask_group (surface, &extents.bounded); - if (unlikely (group == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto cleanup; - } - - group->operation = PDF_FILL; - status = _cairo_pattern_create_copy (&group->source, source); - if (unlikely (status)) { - _cairo_pdf_smask_group_destroy (group); - goto cleanup; - } - group->source_res = pattern_res; - status = _cairo_path_fixed_init_copy (&group->path, path); - if (unlikely (status)) { - _cairo_pdf_smask_group_destroy (group); - goto cleanup; - } - - group->fill_rule = fill_rule; - status = _cairo_pdf_surface_add_smask_group (surface, group); - if (unlikely (status)) { - _cairo_pdf_smask_group_destroy (group); - goto cleanup; - } - - status = _cairo_pdf_surface_add_smask (surface, gstate_res); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_surface_add_xobject (surface, group->group_res); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - goto cleanup; - - _cairo_output_stream_printf (surface->output, - "q /s%d gs /x%d Do Q\n", - gstate_res.id, - group->group_res.id); - } else { - status = _cairo_pdf_surface_select_pattern (surface, source, pattern_res, FALSE); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_operators_fill (&surface->pdf_operators, - path, - fill_rule); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_surface_unselect_pattern (surface); - if (unlikely (status)) - goto cleanup; - } - - _cairo_composite_rectangles_fini (&extents); - return _cairo_output_stream_get_status (surface->output); - -cleanup: - _cairo_composite_rectangles_fini (&extents); - return status; -} - -static cairo_int_status_t -_cairo_pdf_surface_fill_stroke (void *abstract_surface, - cairo_operator_t fill_op, - const cairo_pattern_t *fill_source, - cairo_fill_rule_t fill_rule, - double fill_tolerance, - cairo_antialias_t fill_antialias, - const cairo_path_fixed_t*path, - cairo_operator_t stroke_op, - const cairo_pattern_t *stroke_source, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *stroke_ctm, - const cairo_matrix_t *stroke_ctm_inverse, - double stroke_tolerance, - cairo_antialias_t stroke_antialias, - const cairo_clip_t *clip) -{ - cairo_pdf_surface_t *surface = abstract_surface; - cairo_int_status_t status; - cairo_pdf_resource_t fill_pattern_res, stroke_pattern_res, gstate_res; - cairo_composite_rectangles_t extents; - - /* During analysis we return unsupported and let the _fill and - * _stroke functions that are on the fallback path do the analysis - * for us. During render we may still encounter unsupported - * combinations of fill/stroke patterns. However we can return - * unsupported anytime to let the _fill and _stroke functions take - * over. - */ - if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* PDF rendering of fill-stroke is not the same as cairo when - * either the fill or stroke is not opaque. - */ - if ( !_cairo_pattern_is_opaque (fill_source, NULL) || - !_cairo_pattern_is_opaque (stroke_source, NULL)) - { - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - if (fill_op != stroke_op) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* Compute the operation extents using the stroke which will naturally - * be larger than the fill extents. - */ - status = _cairo_composite_rectangles_init_for_stroke (&extents, - &surface->base, - stroke_op, stroke_source, - path, stroke_style, stroke_ctm, - clip); - if (unlikely (status)) - return status; - - /* use the more accurate extents */ - if (extents.is_bounded) { - cairo_rectangle_int_t mask; - cairo_box_t box; - - status = _cairo_path_fixed_stroke_extents (path, stroke_style, - stroke_ctm, stroke_ctm_inverse, - stroke_tolerance, - &mask); - if (unlikely (status)) - goto cleanup; - - _cairo_box_from_rectangle (&box, &mask); - status = _cairo_composite_rectangles_intersect_mask_extents (&extents, - &box); - if (unlikely (status)) - goto cleanup; - } - - status = _cairo_pdf_surface_set_clip (surface, &extents); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_surface_select_operator (surface, fill_op); - if (unlikely (status)) - goto cleanup; - - /* use the more accurate extents */ - if (extents.is_bounded) { - cairo_rectangle_int_t mask; - cairo_box_t box; - - _cairo_path_fixed_fill_extents (path, - fill_rule, - fill_tolerance, - &mask); - - _cairo_box_from_rectangle (&box, &mask); - status = _cairo_composite_rectangles_intersect_mask_extents (&extents, - &box); - if (unlikely (status)) - goto cleanup; - } - - fill_pattern_res.id = 0; - gstate_res.id = 0; - status = _cairo_pdf_surface_add_pdf_pattern (surface, fill_source, - fill_op, - &extents.bounded, - &fill_pattern_res, - &gstate_res); - if (unlikely (status)) - goto cleanup; - - assert (gstate_res.id == 0); - - stroke_pattern_res.id = 0; - gstate_res.id = 0; - status = _cairo_pdf_surface_add_pdf_pattern (surface, - stroke_source, - stroke_op, - &extents.bounded, - &stroke_pattern_res, - &gstate_res); - if (unlikely (status)) - goto cleanup; - - assert (gstate_res.id == 0); - - /* As PDF has separate graphics state for fill and stroke we can - * select both at the same time */ - status = _cairo_pdf_surface_select_pattern (surface, fill_source, - fill_pattern_res, FALSE); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_surface_select_pattern (surface, stroke_source, - stroke_pattern_res, TRUE); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_operators_fill_stroke (&surface->pdf_operators, - path, - fill_rule, - stroke_style, - stroke_ctm, - stroke_ctm_inverse); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_surface_unselect_pattern (surface); - if (unlikely (status)) - goto cleanup; - - _cairo_composite_rectangles_fini (&extents); - return _cairo_output_stream_get_status (surface->output); - -cleanup: - _cairo_composite_rectangles_fini (&extents); - return status; -} - -static cairo_bool_t -_cairo_pdf_surface_has_show_text_glyphs (void *abstract_surface) -{ - return TRUE; -} - -static cairo_int_status_t -_cairo_pdf_surface_show_text_glyphs (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const char *utf8, - int utf8_len, - cairo_glyph_t *glyphs, - int num_glyphs, - const cairo_text_cluster_t *clusters, - int num_clusters, - cairo_text_cluster_flags_t cluster_flags, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - cairo_pdf_surface_t *surface = abstract_surface; - cairo_pdf_smask_group_t *group; - cairo_pdf_resource_t pattern_res, gstate_res; - cairo_composite_rectangles_t extents; - cairo_bool_t overlap; - cairo_int_status_t status; - - status = _cairo_composite_rectangles_init_for_glyphs (&extents, - &surface->base, - op, source, - scaled_font, - glyphs, num_glyphs, - clip, - &overlap); - if (unlikely (status)) - return status; - - if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) { - status = _cairo_pdf_surface_analyze_operation (surface, op, source, &extents.bounded); - goto cleanup; - } - - assert (_cairo_pdf_surface_operation_supported (surface, op, source, &extents.bounded)); - - status = _cairo_pdf_surface_set_clip (surface, &extents); - if (unlikely (status)) - goto cleanup; - - pattern_res.id = 0; - gstate_res.id = 0; - status = _cairo_pdf_surface_add_pdf_pattern (surface, source, op, - &extents.bounded, - &pattern_res, &gstate_res); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_surface_select_operator (surface, op); - if (unlikely (status)) - goto cleanup; - - if (gstate_res.id != 0) { - group = _cairo_pdf_surface_create_smask_group (surface, &extents.bounded); - if (unlikely (group == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto cleanup; - } - - group->operation = PDF_SHOW_GLYPHS; - status = _cairo_pattern_create_copy (&group->source, source); - if (unlikely (status)) { - _cairo_pdf_smask_group_destroy (group); - goto cleanup; - } - group->source_res = pattern_res; - - if (utf8_len) { - group->utf8 = malloc (utf8_len); - if (unlikely (group->utf8 == NULL)) { - _cairo_pdf_smask_group_destroy (group); - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto cleanup; - } - memcpy (group->utf8, utf8, utf8_len); - } - group->utf8_len = utf8_len; - - if (num_glyphs) { - group->glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); - if (unlikely (group->glyphs == NULL)) { - _cairo_pdf_smask_group_destroy (group); - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto cleanup; - } - memcpy (group->glyphs, glyphs, sizeof (cairo_glyph_t) * num_glyphs); - } - group->num_glyphs = num_glyphs; - - if (num_clusters) { - group->clusters = _cairo_malloc_ab (num_clusters, sizeof (cairo_text_cluster_t)); - if (unlikely (group->clusters == NULL)) { - _cairo_pdf_smask_group_destroy (group); - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto cleanup; - } - memcpy (group->clusters, clusters, sizeof (cairo_text_cluster_t) * num_clusters); - } - group->num_clusters = num_clusters; - - group->scaled_font = cairo_scaled_font_reference (scaled_font); - status = _cairo_pdf_surface_add_smask_group (surface, group); - if (unlikely (status)) { - _cairo_pdf_smask_group_destroy (group); - goto cleanup; - } - - status = _cairo_pdf_surface_add_smask (surface, gstate_res); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_surface_add_xobject (surface, group->group_res); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - goto cleanup; - - _cairo_output_stream_printf (surface->output, - "q /s%d gs /x%d Do Q\n", - gstate_res.id, - group->group_res.id); - } else { - status = _cairo_pdf_surface_select_pattern (surface, source, pattern_res, FALSE); - if (unlikely (status)) - goto cleanup; - - /* Each call to show_glyphs() with a transclucent pattern must - * be in a separate text object otherwise overlapping text - * from separate calls to show_glyphs will not composite with - * each other. */ - if (! _cairo_pattern_is_opaque (source, &extents.bounded)) { - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - goto cleanup; - } - - status = _cairo_pdf_operators_show_text_glyphs (&surface->pdf_operators, - utf8, utf8_len, - glyphs, num_glyphs, - clusters, num_clusters, - cluster_flags, - scaled_font); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_surface_unselect_pattern (surface); - if (unlikely (status)) - goto cleanup; - } - - _cairo_composite_rectangles_fini (&extents); - return _cairo_output_stream_get_status (surface->output); - -cleanup: - _cairo_composite_rectangles_fini (&extents); - return status; -} - -static const char ** -_cairo_pdf_surface_get_supported_mime_types (void *abstract_surface) -{ - return _cairo_pdf_supported_mime_types; -} - -static void -_cairo_pdf_surface_set_paginated_mode (void *abstract_surface, - cairo_paginated_mode_t paginated_mode) -{ - cairo_pdf_surface_t *surface = abstract_surface; - - surface->paginated_mode = paginated_mode; -} - -static const cairo_surface_backend_t cairo_pdf_surface_backend = { - CAIRO_SURFACE_TYPE_PDF, - _cairo_pdf_surface_finish, - - _cairo_default_context_create, - - NULL, /* create similar: handled by wrapper */ - NULL, /* create similar image */ - NULL, /* map to image */ - NULL, /* unmap image */ - - _cairo_surface_default_source, - NULL, /* acquire_source_image */ - NULL, /* release_source_image */ - NULL, /* snapshot */ - - NULL, /* _cairo_pdf_surface_copy_page */ - _cairo_pdf_surface_show_page, - - _cairo_pdf_surface_get_extents, - _cairo_pdf_surface_get_font_options, - - NULL, /* flush */ - NULL, /* mark_dirty_rectangle */ - - /* Here are the drawing functions */ - _cairo_pdf_surface_paint, - _cairo_pdf_surface_mask, - _cairo_pdf_surface_stroke, - _cairo_pdf_surface_fill, - _cairo_pdf_surface_fill_stroke, - NULL, /* show_glyphs */ - _cairo_pdf_surface_has_show_text_glyphs, - _cairo_pdf_surface_show_text_glyphs, - _cairo_pdf_surface_get_supported_mime_types, -}; - -static const cairo_paginated_surface_backend_t -cairo_pdf_surface_paginated_backend = { - _cairo_pdf_surface_start_page, - _cairo_pdf_surface_set_paginated_mode, - NULL, /* set_bounding_box */ - _cairo_pdf_surface_has_fallback_images, - _cairo_pdf_surface_supports_fine_grained_fallbacks, -}; diff --git a/source/libs/cairo/cairo-src/src/cairo-pdf.h b/source/libs/cairo/cairo-src/src/cairo-pdf.h deleted file mode 100644 index 1bc8524f2b1464855122a93c22a486f33bd87d1f..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-pdf.h +++ /dev/null @@ -1,94 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - */ - -#ifndef CAIRO_PDF_H -#define CAIRO_PDF_H - -#include "cairo.h" - -#if CAIRO_HAS_PDF_SURFACE - -CAIRO_BEGIN_DECLS - -/** - * cairo_pdf_version_t: - * @CAIRO_PDF_VERSION_1_4: The version 1.4 of the PDF specification. (Since 1.10) - * @CAIRO_PDF_VERSION_1_5: The version 1.5 of the PDF specification. (Since 1.10) - * - * #cairo_pdf_version_t is used to describe the version number of the PDF - * specification that a generated PDF file will conform to. - * - * Since: 1.10 - **/ -typedef enum _cairo_pdf_version { - CAIRO_PDF_VERSION_1_4, - CAIRO_PDF_VERSION_1_5 -} cairo_pdf_version_t; - -cairo_public cairo_surface_t * -cairo_pdf_surface_create (const char *filename, - double width_in_points, - double height_in_points); - -cairo_public cairo_surface_t * -cairo_pdf_surface_create_for_stream (cairo_write_func_t write_func, - void *closure, - double width_in_points, - double height_in_points); - -cairo_public void -cairo_pdf_surface_restrict_to_version (cairo_surface_t *surface, - cairo_pdf_version_t version); - -cairo_public void -cairo_pdf_get_versions (cairo_pdf_version_t const **versions, - int *num_versions); - -cairo_public const char * -cairo_pdf_version_to_string (cairo_pdf_version_t version); - -cairo_public void -cairo_pdf_surface_set_size (cairo_surface_t *surface, - double width_in_points, - double height_in_points); - -CAIRO_END_DECLS - -#else /* CAIRO_HAS_PDF_SURFACE */ -# error Cairo was not compiled with support for the pdf backend -#endif /* CAIRO_HAS_PDF_SURFACE */ - -#endif /* CAIRO_PDF_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-pen.c b/source/libs/cairo/cairo-src/src/cairo-pen.c deleted file mode 100644 index 61be0e8299dec505d34d99921aa17b1ac893c727..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-pen.c +++ /dev/null @@ -1,475 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2008 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-error-private.h" -#include "cairo-slope-private.h" - -static void -_cairo_pen_compute_slopes (cairo_pen_t *pen); - -cairo_status_t -_cairo_pen_init (cairo_pen_t *pen, - double radius, - double tolerance, - const cairo_matrix_t *ctm) -{ - int i; - int reflect; - - if (CAIRO_INJECT_FAULT ()) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - VG (VALGRIND_MAKE_MEM_UNDEFINED (pen, sizeof (cairo_pen_t))); - - pen->radius = radius; - pen->tolerance = tolerance; - - reflect = _cairo_matrix_compute_determinant (ctm) < 0.; - - pen->num_vertices = _cairo_pen_vertices_needed (tolerance, - radius, - ctm); - - if (pen->num_vertices > ARRAY_LENGTH (pen->vertices_embedded)) { - pen->vertices = _cairo_malloc_ab (pen->num_vertices, - sizeof (cairo_pen_vertex_t)); - if (unlikely (pen->vertices == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } else { - pen->vertices = pen->vertices_embedded; - } - - /* - * Compute pen coordinates. To generate the right ellipse, compute points around - * a circle in user space and transform them to device space. To get a consistent - * orientation in device space, flip the pen if the transformation matrix - * is reflecting - */ - for (i=0; i < pen->num_vertices; i++) { - cairo_pen_vertex_t *v = &pen->vertices[i]; - double theta = 2 * M_PI * i / (double) pen->num_vertices, dx, dy; - if (reflect) - theta = -theta; - dx = radius * cos (theta); - dy = radius * sin (theta); - cairo_matrix_transform_distance (ctm, &dx, &dy); - v->point.x = _cairo_fixed_from_double (dx); - v->point.y = _cairo_fixed_from_double (dy); - } - - _cairo_pen_compute_slopes (pen); - - return CAIRO_STATUS_SUCCESS; -} - -void -_cairo_pen_fini (cairo_pen_t *pen) -{ - if (pen->vertices != pen->vertices_embedded) - free (pen->vertices); - - - VG (VALGRIND_MAKE_MEM_NOACCESS (pen, sizeof (cairo_pen_t))); -} - -cairo_status_t -_cairo_pen_init_copy (cairo_pen_t *pen, const cairo_pen_t *other) -{ - VG (VALGRIND_MAKE_MEM_UNDEFINED (pen, sizeof (cairo_pen_t))); - - *pen = *other; - - if (CAIRO_INJECT_FAULT ()) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - pen->vertices = pen->vertices_embedded; - if (pen->num_vertices) { - if (pen->num_vertices > ARRAY_LENGTH (pen->vertices_embedded)) { - pen->vertices = _cairo_malloc_ab (pen->num_vertices, - sizeof (cairo_pen_vertex_t)); - if (unlikely (pen->vertices == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - memcpy (pen->vertices, other->vertices, - pen->num_vertices * sizeof (cairo_pen_vertex_t)); - } - - return CAIRO_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_pen_add_points (cairo_pen_t *pen, cairo_point_t *point, int num_points) -{ - cairo_status_t status; - int num_vertices; - int i; - - if (CAIRO_INJECT_FAULT ()) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - num_vertices = pen->num_vertices + num_points; - if (num_vertices > ARRAY_LENGTH (pen->vertices_embedded) || - pen->vertices != pen->vertices_embedded) - { - cairo_pen_vertex_t *vertices; - - if (pen->vertices == pen->vertices_embedded) { - vertices = _cairo_malloc_ab (num_vertices, - sizeof (cairo_pen_vertex_t)); - if (unlikely (vertices == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - memcpy (vertices, pen->vertices, - pen->num_vertices * sizeof (cairo_pen_vertex_t)); - } else { - vertices = _cairo_realloc_ab (pen->vertices, - num_vertices, - sizeof (cairo_pen_vertex_t)); - if (unlikely (vertices == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - pen->vertices = vertices; - } - - pen->num_vertices = num_vertices; - - /* initialize new vertices */ - for (i=0; i < num_points; i++) - pen->vertices[pen->num_vertices-num_points+i].point = point[i]; - - status = _cairo_hull_compute (pen->vertices, &pen->num_vertices); - if (unlikely (status)) - return status; - - _cairo_pen_compute_slopes (pen); - - return CAIRO_STATUS_SUCCESS; -} - -/* -The circular pen in user space is transformed into an ellipse in -device space. - -We construct the pen by computing points along the circumference -using equally spaced angles. - -We show that this approximation to the ellipse has maximum error at the -major axis of the ellipse. - -Set - - M = major axis length - m = minor axis length - -Align 'M' along the X axis and 'm' along the Y axis and draw -an ellipse parameterized by angle 't': - - x = M cos t y = m sin t - -Perturb t by ± d and compute two new points (x+,y+), (x-,y-). -The distance from the average of these two points to (x,y) represents -the maximum error in approximating the ellipse with a polygon formed -from vertices 2∆ radians apart. - - x+ = M cos (t+∆) y+ = m sin (t+∆) - x- = M cos (t-∆) y- = m sin (t-∆) - -Now compute the approximation error, E: - - Ex = (x - (x+ + x-) / 2) - Ex = (M cos(t) - (Mcos(t+∆) + Mcos(t-∆))/2) - = M (cos(t) - (cos(t)cos(∆) + sin(t)sin(∆) + - cos(t)cos(∆) - sin(t)sin(∆))/2) - = M(cos(t) - cos(t)cos(∆)) - = M cos(t) (1 - cos(∆)) - - Ey = y - (y+ - y-) / 2 - = m sin (t) - (m sin(t+∆) + m sin(t-∆)) / 2 - = m (sin(t) - (sin(t)cos(∆) + cos(t)sin(∆) + - sin(t)cos(∆) - cos(t)sin(∆))/2) - = m (sin(t) - sin(t)cos(∆)) - = m sin(t) (1 - cos(∆)) - - E² = Ex² + Ey² - = (M cos(t) (1 - cos (∆)))² + (m sin(t) (1-cos(∆)))² - = (1 - cos(∆))² (M² cos²(t) + m² sin²(t)) - = (1 - cos(∆))² ((m² + M² - m²) cos² (t) + m² sin²(t)) - = (1 - cos(∆))² (M² - m²) cos² (t) + (1 - cos(∆))² m² - -Find the extremum by differentiation wrt t and setting that to zero - -∂(E²)/∂(t) = (1-cos(∆))² (M² - m²) (-2 cos(t) sin(t)) - - 0 = 2 cos (t) sin (t) - 0 = sin (2t) - t = nÏ€ - -Which is to say that the maximum and minimum errors occur on the -axes of the ellipse at 0 and Ï€ radians: - - E²(0) = (1-cos(∆))² (M² - m²) + (1-cos(∆))² m² - = (1-cos(∆))² M² - E²(Ï€) = (1-cos(∆))² m² - -maximum error = M (1-cos(∆)) -minimum error = m (1-cos(∆)) - -We must make maximum error ≤ tolerance, so compute the ∆ needed: - - tolerance = M (1-cos(∆)) - tolerance / M = 1 - cos (∆) - cos(∆) = 1 - tolerance/M - ∆ = acos (1 - tolerance / M); - -Remembering that ∆ is half of our angle between vertices, -the number of vertices is then - - vertices = ceil(2Ï€/2∆). - = ceil(Ï€/∆). - -Note that this also equation works for M == m (a circle) as it -doesn't matter where on the circle the error is computed. -*/ - -int -_cairo_pen_vertices_needed (double tolerance, - double radius, - const cairo_matrix_t *matrix) -{ - /* - * the pen is a circle that gets transformed to an ellipse by matrix. - * compute major axis length for a pen with the specified radius. - * we don't need the minor axis length. - */ - double major_axis = _cairo_matrix_transformed_circle_major_axis (matrix, - radius); - int num_vertices; - - if (tolerance >= 4*major_axis) { /* XXX relaxed from 2*major for inkscape */ - num_vertices = 1; - } else if (tolerance >= major_axis) { - num_vertices = 4; - } else { - num_vertices = ceil (2*M_PI / acos (1 - tolerance / major_axis)); - - /* number of vertices must be even */ - if (num_vertices % 2) - num_vertices++; - - /* And we must always have at least 4 vertices. */ - if (num_vertices < 4) - num_vertices = 4; - } - - return num_vertices; -} - -static void -_cairo_pen_compute_slopes (cairo_pen_t *pen) -{ - int i, i_prev; - cairo_pen_vertex_t *prev, *v, *next; - - for (i=0, i_prev = pen->num_vertices - 1; - i < pen->num_vertices; - i_prev = i++) { - prev = &pen->vertices[i_prev]; - v = &pen->vertices[i]; - next = &pen->vertices[(i + 1) % pen->num_vertices]; - - _cairo_slope_init (&v->slope_cw, &prev->point, &v->point); - _cairo_slope_init (&v->slope_ccw, &v->point, &next->point); - } -} -/* - * Find active pen vertex for clockwise edge of stroke at the given slope. - * - * The strictness of the inequalities here is delicate. The issue is - * that the slope_ccw member of one pen vertex will be equivalent to - * the slope_cw member of the next pen vertex in a counterclockwise - * order. However, for this function, we care strongly about which - * vertex is returned. - * - * [I think the "care strongly" above has to do with ensuring that the - * pen's "extra points" from the spline's initial and final slopes are - * properly found when beginning the spline stroking.] - */ -int -_cairo_pen_find_active_cw_vertex_index (const cairo_pen_t *pen, - const cairo_slope_t *slope) -{ - int i; - - for (i=0; i < pen->num_vertices; i++) { - if ((_cairo_slope_compare (slope, &pen->vertices[i].slope_ccw) < 0) && - (_cairo_slope_compare (slope, &pen->vertices[i].slope_cw) >= 0)) - break; - } - - /* If the desired slope cannot be found between any of the pen - * vertices, then we must have a degenerate pen, (such as a pen - * that's been transformed to a line). In that case, we consider - * the first pen vertex as the appropriate clockwise vertex. - */ - if (i == pen->num_vertices) - i = 0; - - return i; -} - -/* Find active pen vertex for counterclockwise edge of stroke at the given slope. - * - * Note: See the comments for _cairo_pen_find_active_cw_vertex_index - * for some details about the strictness of the inequalities here. - */ -int -_cairo_pen_find_active_ccw_vertex_index (const cairo_pen_t *pen, - const cairo_slope_t *slope) -{ - cairo_slope_t slope_reverse; - int i; - - slope_reverse = *slope; - slope_reverse.dx = -slope_reverse.dx; - slope_reverse.dy = -slope_reverse.dy; - - for (i=pen->num_vertices-1; i >= 0; i--) { - if ((_cairo_slope_compare (&pen->vertices[i].slope_ccw, &slope_reverse) >= 0) && - (_cairo_slope_compare (&pen->vertices[i].slope_cw, &slope_reverse) < 0)) - break; - } - - /* If the desired slope cannot be found between any of the pen - * vertices, then we must have a degenerate pen, (such as a pen - * that's been transformed to a line). In that case, we consider - * the last pen vertex as the appropriate counterclockwise vertex. - */ - if (i < 0) - i = pen->num_vertices - 1; - - return i; -} - -void -_cairo_pen_find_active_cw_vertices (const cairo_pen_t *pen, - const cairo_slope_t *in, - const cairo_slope_t *out, - int *start, int *stop) -{ - - int lo = 0, hi = pen->num_vertices; - int i; - - i = (lo + hi) >> 1; - do { - if (_cairo_slope_compare (&pen->vertices[i].slope_cw, in) < 0) - lo = i; - else - hi = i; - i = (lo + hi) >> 1; - } while (hi - lo > 1); - if (_cairo_slope_compare (&pen->vertices[i].slope_cw, in) < 0) - if (++i == pen->num_vertices) - i = 0; - *start = i; - - if (_cairo_slope_compare (out, &pen->vertices[i].slope_ccw) >= 0) { - lo = i; - hi = i + pen->num_vertices; - i = (lo + hi) >> 1; - do { - int j = i; - if (j >= pen->num_vertices) - j -= pen->num_vertices; - if (_cairo_slope_compare (&pen->vertices[j].slope_cw, out) > 0) - hi = i; - else - lo = i; - i = (lo + hi) >> 1; - } while (hi - lo > 1); - if (i >= pen->num_vertices) - i -= pen->num_vertices; - } - *stop = i; -} - -void -_cairo_pen_find_active_ccw_vertices (const cairo_pen_t *pen, - const cairo_slope_t *in, - const cairo_slope_t *out, - int *start, int *stop) -{ - int lo = 0, hi = pen->num_vertices; - int i; - - i = (lo + hi) >> 1; - do { - if (_cairo_slope_compare (in, &pen->vertices[i].slope_ccw) < 0) - lo = i; - else - hi = i; - i = (lo + hi) >> 1; - } while (hi - lo > 1); - if (_cairo_slope_compare (in, &pen->vertices[i].slope_ccw) < 0) - if (++i == pen->num_vertices) - i = 0; - *start = i; - - if (_cairo_slope_compare (&pen->vertices[i].slope_cw, out) <= 0) { - lo = i; - hi = i + pen->num_vertices; - i = (lo + hi) >> 1; - do { - int j = i; - if (j >= pen->num_vertices) - j -= pen->num_vertices; - if (_cairo_slope_compare (out, &pen->vertices[j].slope_ccw) > 0) - hi = i; - else - lo = i; - i = (lo + hi) >> 1; - } while (hi - lo > 1); - if (i >= pen->num_vertices) - i -= pen->num_vertices; - } - *stop = i; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-pixman-private.h b/source/libs/cairo/cairo-src/src/cairo-pixman-private.h deleted file mode 100644 index d705025c8ee7b8cf96ecbc8107c2ac36ced4b26a..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-pixman-private.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright ©2013 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_PIXMAN_PRIVATE_H -#define CAIRO_PIXMAN_PRIVATE_H - -#include "cairo-pixman-private.h" /* keep make check happy */ - -#include <pixman.h> - -#if PIXMAN_VERSION < PIXMAN_VERSION_ENCODE(0,22,0) -#define pixman_image_composite32 pixman_image_composite -#define pixman_image_get_component_alpha(i) 0 -#define pixman_image_set_component_alpha(i, x) do { } while (0) -#endif - -#endif diff --git a/source/libs/cairo/cairo-src/src/cairo-png.c b/source/libs/cairo/cairo-src/src/cairo-png.c deleted file mode 100644 index 068617d588d8b0cc3947024c409dfaac95c10803..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-png.c +++ /dev/null @@ -1,819 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2003 University of Southern California - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Kristian Høgsberg <krh@redhat.com> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-error-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-output-stream-private.h" - -#include <stdio.h> -#include <errno.h> -#include <png.h> - -/** - * SECTION:cairo-png - * @Title: PNG Support - * @Short_Description: Reading and writing PNG images - * @See_Also: #cairo_surface_t - * - * The PNG functions allow reading PNG images into image surfaces, and writing - * any surface to a PNG file. - * - * It is a toy API. It only offers very simple support for reading and - * writing PNG files, which is sufficient for testing and - * demonstration purposes. Applications which need more control over - * the generated PNG file should access the pixel data directly, using - * cairo_image_surface_get_data() or a backend-specific access - * function, and process it with another library, e.g. gdk-pixbuf or - * libpng. - **/ - -/** - * CAIRO_HAS_PNG_FUNCTIONS: - * - * Defined if the PNG functions are available. - * This macro can be used to conditionally compile code using the cairo - * PNG functions. - * - * Since: 1.0 - **/ - -struct png_read_closure_t { - cairo_read_func_t read_func; - void *closure; - cairo_output_stream_t *png_data; -}; - - -/* Unpremultiplies data and converts native endian ARGB => RGBA bytes */ -static void -unpremultiply_data (png_structp png, png_row_infop row_info, png_bytep data) -{ - unsigned int i; - - for (i = 0; i < row_info->rowbytes; i += 4) { - uint8_t *b = &data[i]; - uint32_t pixel; - uint8_t alpha; - - memcpy (&pixel, b, sizeof (uint32_t)); - alpha = (pixel & 0xff000000) >> 24; - if (alpha == 0) { - b[0] = b[1] = b[2] = b[3] = 0; - } else { - b[0] = (((pixel & 0xff0000) >> 16) * 255 + alpha / 2) / alpha; - b[1] = (((pixel & 0x00ff00) >> 8) * 255 + alpha / 2) / alpha; - b[2] = (((pixel & 0x0000ff) >> 0) * 255 + alpha / 2) / alpha; - b[3] = alpha; - } - } -} - -/* Converts native endian xRGB => RGBx bytes */ -static void -convert_data_to_bytes (png_structp png, png_row_infop row_info, png_bytep data) -{ - unsigned int i; - - for (i = 0; i < row_info->rowbytes; i += 4) { - uint8_t *b = &data[i]; - uint32_t pixel; - - memcpy (&pixel, b, sizeof (uint32_t)); - - b[0] = (pixel & 0xff0000) >> 16; - b[1] = (pixel & 0x00ff00) >> 8; - b[2] = (pixel & 0x0000ff) >> 0; - b[3] = 0; - } -} - -/* Use a couple of simple error callbacks that do not print anything to - * stderr and rely on the user to check for errors via the #cairo_status_t - * return. - */ -static void -png_simple_error_callback (png_structp png, - png_const_charp error_msg) -{ - cairo_status_t *error = png_get_error_ptr (png); - - /* default to the most likely error */ - if (*error == CAIRO_STATUS_SUCCESS) - *error = _cairo_error (CAIRO_STATUS_NO_MEMORY); - -#ifdef PNG_SETJMP_SUPPORTED - longjmp (png_jmpbuf (png), 1); -#endif - - /* if we get here, then we have to choice but to abort ... */ -} - -static void -png_simple_warning_callback (png_structp png, - png_const_charp error_msg) -{ - /* png does not expect to abort and will try to tidy up and continue - * loading the image after a warning. So we also want to return the - * (incorrect?) surface. - * - * We use our own warning callback to squelch any attempts by libpng - * to write to stderr as we may not be in control of that output. - */ -} - - -/* Starting with libpng-1.2.30, we must explicitly specify an output_flush_fn. - * Otherwise, we will segfault if we are writing to a stream. */ -static void -png_simple_output_flush_fn (png_structp png_ptr) -{ -} - -static cairo_status_t -write_png (cairo_surface_t *surface, - png_rw_ptr write_func, - void *closure) -{ - int i; - cairo_int_status_t status; - cairo_image_surface_t *image; - cairo_image_surface_t * volatile clone; - void *image_extra; - png_struct *png; - png_info *info; - png_byte **volatile rows = NULL; - png_color_16 white; - int png_color_type; - int bpc; - - status = _cairo_surface_acquire_source_image (surface, - &image, - &image_extra); - - if (status == CAIRO_INT_STATUS_UNSUPPORTED) - return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - else if (unlikely (status)) - return status; - - /* PNG complains about "Image width or height is zero in IHDR" */ - if (image->width == 0 || image->height == 0) { - status = _cairo_error (CAIRO_STATUS_WRITE_ERROR); - goto BAIL1; - } - - /* Handle the various fallback formats (e.g. low bit-depth XServers) - * by coercing them to a simpler format using pixman. - */ - clone = _cairo_image_surface_coerce (image); - status = clone->base.status; - if (unlikely (status)) - goto BAIL1; - - rows = _cairo_malloc_ab (clone->height, sizeof (png_byte*)); - if (unlikely (rows == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto BAIL2; - } - - for (i = 0; i < clone->height; i++) - rows[i] = (png_byte *) clone->data + i * clone->stride; - - png = png_create_write_struct (PNG_LIBPNG_VER_STRING, &status, - png_simple_error_callback, - png_simple_warning_callback); - if (unlikely (png == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto BAIL3; - } - - info = png_create_info_struct (png); - if (unlikely (info == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto BAIL4; - } - -#ifdef PNG_SETJMP_SUPPORTED - if (setjmp (png_jmpbuf (png))) - goto BAIL4; -#endif - - png_set_write_fn (png, closure, write_func, png_simple_output_flush_fn); - - switch (clone->format) { - case CAIRO_FORMAT_ARGB32: - bpc = 8; - if (_cairo_image_analyze_transparency (clone) == CAIRO_IMAGE_IS_OPAQUE) - png_color_type = PNG_COLOR_TYPE_RGB; - else - png_color_type = PNG_COLOR_TYPE_RGB_ALPHA; - break; - case CAIRO_FORMAT_RGB30: - bpc = 10; - png_color_type = PNG_COLOR_TYPE_RGB; - break; - case CAIRO_FORMAT_RGB24: - bpc = 8; - png_color_type = PNG_COLOR_TYPE_RGB; - break; - case CAIRO_FORMAT_A8: - bpc = 8; - png_color_type = PNG_COLOR_TYPE_GRAY; - break; - case CAIRO_FORMAT_A1: - bpc = 1; - png_color_type = PNG_COLOR_TYPE_GRAY; -#ifndef WORDS_BIGENDIAN - png_set_packswap (png); -#endif - break; - case CAIRO_FORMAT_INVALID: - case CAIRO_FORMAT_RGB16_565: - default: - status = _cairo_error (CAIRO_STATUS_INVALID_FORMAT); - goto BAIL4; - } - - png_set_IHDR (png, info, - clone->width, - clone->height, bpc, - png_color_type, - PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - - white.gray = (1 << bpc) - 1; - white.red = white.blue = white.green = white.gray; - png_set_bKGD (png, info, &white); - - if (0) { /* XXX extract meta-data from surface (i.e. creation date) */ - png_time pt; - - png_convert_from_time_t (&pt, time (NULL)); - png_set_tIME (png, info, &pt); - } - - /* We have to call png_write_info() before setting up the write - * transformation, since it stores data internally in 'png' - * that is needed for the write transformation functions to work. - */ - png_write_info (png, info); - - if (png_color_type == PNG_COLOR_TYPE_RGB_ALPHA) { - png_set_write_user_transform_fn (png, unpremultiply_data); - } else if (png_color_type == PNG_COLOR_TYPE_RGB) { - png_set_write_user_transform_fn (png, convert_data_to_bytes); - png_set_filler (png, 0, PNG_FILLER_AFTER); - } - - png_write_image (png, rows); - png_write_end (png, info); - -BAIL4: - png_destroy_write_struct (&png, &info); -BAIL3: - free (rows); -BAIL2: - cairo_surface_destroy (&clone->base); -BAIL1: - _cairo_surface_release_source_image (surface, image, image_extra); - - return status; -} - -static void -stdio_write_func (png_structp png, png_bytep data, png_size_t size) -{ - FILE *fp; - - fp = png_get_io_ptr (png); - while (size) { - size_t ret = fwrite (data, 1, size, fp); - size -= ret; - data += ret; - if (size && ferror (fp)) { - cairo_status_t *error = png_get_error_ptr (png); - if (*error == CAIRO_STATUS_SUCCESS) - *error = _cairo_error (CAIRO_STATUS_WRITE_ERROR); - png_error (png, NULL); - } - } -} - -/** - * cairo_surface_write_to_png: - * @surface: a #cairo_surface_t with pixel contents - * @filename: the name of a file to write to - * - * Writes the contents of @surface to a new file @filename as a PNG - * image. - * - * Return value: %CAIRO_STATUS_SUCCESS if the PNG file was written - * successfully. Otherwise, %CAIRO_STATUS_NO_MEMORY if memory could not - * be allocated for the operation or - * %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface does not have - * pixel contents, or %CAIRO_STATUS_WRITE_ERROR if an I/O error occurs - * while attempting to write the file. - * - * Since: 1.0 - **/ -cairo_status_t -cairo_surface_write_to_png (cairo_surface_t *surface, - const char *filename) -{ - FILE *fp; - cairo_status_t status; - - if (surface->status) - return surface->status; - - if (surface->finished) - return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED); - - fp = fopen (filename, "wb"); - if (fp == NULL) { - switch (errno) { - case ENOMEM: - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - default: - return _cairo_error (CAIRO_STATUS_WRITE_ERROR); - } - } - - status = write_png (surface, stdio_write_func, fp); - - if (fclose (fp) && status == CAIRO_STATUS_SUCCESS) - status = _cairo_error (CAIRO_STATUS_WRITE_ERROR); - - return status; -} - -struct png_write_closure_t { - cairo_write_func_t write_func; - void *closure; -}; - -static void -stream_write_func (png_structp png, png_bytep data, png_size_t size) -{ - cairo_status_t status; - struct png_write_closure_t *png_closure; - - png_closure = png_get_io_ptr (png); - status = png_closure->write_func (png_closure->closure, data, size); - if (unlikely (status)) { - cairo_status_t *error = png_get_error_ptr (png); - if (*error == CAIRO_STATUS_SUCCESS) - *error = status; - png_error (png, NULL); - } -} - -/** - * cairo_surface_write_to_png_stream: - * @surface: a #cairo_surface_t with pixel contents - * @write_func: a #cairo_write_func_t - * @closure: closure data for the write function - * - * Writes the image surface to the write function. - * - * Return value: %CAIRO_STATUS_SUCCESS if the PNG file was written - * successfully. Otherwise, %CAIRO_STATUS_NO_MEMORY is returned if - * memory could not be allocated for the operation, - * %CAIRO_STATUS_SURFACE_TYPE_MISMATCH if the surface does not have - * pixel contents. - * - * Since: 1.0 - **/ -cairo_status_t -cairo_surface_write_to_png_stream (cairo_surface_t *surface, - cairo_write_func_t write_func, - void *closure) -{ - struct png_write_closure_t png_closure; - - if (surface->status) - return surface->status; - - if (surface->finished) - return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED); - - png_closure.write_func = write_func; - png_closure.closure = closure; - - return write_png (surface, stream_write_func, &png_closure); -} -slim_hidden_def (cairo_surface_write_to_png_stream); - -static inline int -multiply_alpha (int alpha, int color) -{ - int temp = (alpha * color) + 0x80; - return ((temp + (temp >> 8)) >> 8); -} - -/* Premultiplies data and converts RGBA bytes => native endian */ -static void -premultiply_data (png_structp png, - png_row_infop row_info, - png_bytep data) -{ - unsigned int i; - - for (i = 0; i < row_info->rowbytes; i += 4) { - uint8_t *base = &data[i]; - uint8_t alpha = base[3]; - uint32_t p; - - if (alpha == 0) { - p = 0; - } else { - uint8_t red = base[0]; - uint8_t green = base[1]; - uint8_t blue = base[2]; - - if (alpha != 0xff) { - red = multiply_alpha (alpha, red); - green = multiply_alpha (alpha, green); - blue = multiply_alpha (alpha, blue); - } - p = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0); - } - memcpy (base, &p, sizeof (uint32_t)); - } -} - -/* Converts RGBx bytes to native endian xRGB */ -static void -convert_bytes_to_data (png_structp png, png_row_infop row_info, png_bytep data) -{ - unsigned int i; - - for (i = 0; i < row_info->rowbytes; i += 4) { - uint8_t *base = &data[i]; - uint8_t red = base[0]; - uint8_t green = base[1]; - uint8_t blue = base[2]; - uint32_t pixel; - - pixel = (0xff << 24) | (red << 16) | (green << 8) | (blue << 0); - memcpy (base, &pixel, sizeof (uint32_t)); - } -} - -static cairo_status_t -stdio_read_func (void *closure, unsigned char *data, unsigned int size) -{ - FILE *file = closure; - - while (size) { - size_t ret; - - ret = fread (data, 1, size, file); - size -= ret; - data += ret; - - if (size && (feof (file) || ferror (file))) - return _cairo_error (CAIRO_STATUS_READ_ERROR); - } - - return CAIRO_STATUS_SUCCESS; -} - -static void -stream_read_func (png_structp png, png_bytep data, png_size_t size) -{ - cairo_status_t status; - struct png_read_closure_t *png_closure; - - png_closure = png_get_io_ptr (png); - status = png_closure->read_func (png_closure->closure, data, size); - if (unlikely (status)) { - cairo_status_t *error = png_get_error_ptr (png); - if (*error == CAIRO_STATUS_SUCCESS) - *error = status; - png_error (png, NULL); - } - - _cairo_output_stream_write (png_closure->png_data, data, size); -} - -static cairo_surface_t * -read_png (struct png_read_closure_t *png_closure) -{ - cairo_surface_t *surface; - png_struct *png = NULL; - png_info *info; - png_byte *data = NULL; - png_byte **row_pointers = NULL; - png_uint_32 png_width, png_height; - int depth, color_type, interlace, stride; - unsigned int i; - cairo_format_t format; - cairo_status_t status; - unsigned char *mime_data; - unsigned long mime_data_length; - - png_closure->png_data = _cairo_memory_stream_create (); - - /* XXX: Perhaps we'll want some other error handlers? */ - png = png_create_read_struct (PNG_LIBPNG_VER_STRING, - &status, - png_simple_error_callback, - png_simple_warning_callback); - if (unlikely (png == NULL)) { - surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - goto BAIL; - } - - info = png_create_info_struct (png); - if (unlikely (info == NULL)) { - surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - goto BAIL; - } - - png_set_read_fn (png, png_closure, stream_read_func); - - status = CAIRO_STATUS_SUCCESS; -#ifdef PNG_SETJMP_SUPPORTED - if (setjmp (png_jmpbuf (png))) { - surface = _cairo_surface_create_in_error (status); - goto BAIL; - } -#endif - - png_read_info (png, info); - - png_get_IHDR (png, info, - &png_width, &png_height, &depth, - &color_type, &interlace, NULL, NULL); - if (unlikely (status)) { /* catch any early warnings */ - surface = _cairo_surface_create_in_error (status); - goto BAIL; - } - - /* convert palette/gray image to rgb */ - if (color_type == PNG_COLOR_TYPE_PALETTE) - png_set_palette_to_rgb (png); - - /* expand gray bit depth if needed */ - if (color_type == PNG_COLOR_TYPE_GRAY) { -#if PNG_LIBPNG_VER >= 10209 - png_set_expand_gray_1_2_4_to_8 (png); -#else - png_set_gray_1_2_4_to_8 (png); -#endif - } - - /* transform transparency to alpha */ - if (png_get_valid (png, info, PNG_INFO_tRNS)) - png_set_tRNS_to_alpha (png); - - if (depth == 16) - png_set_strip_16 (png); - - if (depth < 8) - png_set_packing (png); - - /* convert grayscale to RGB */ - if (color_type == PNG_COLOR_TYPE_GRAY || - color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - { - png_set_gray_to_rgb (png); - } - - if (interlace != PNG_INTERLACE_NONE) - png_set_interlace_handling (png); - - png_set_filler (png, 0xff, PNG_FILLER_AFTER); - - /* recheck header after setting EXPAND options */ - png_read_update_info (png, info); - png_get_IHDR (png, info, - &png_width, &png_height, &depth, - &color_type, &interlace, NULL, NULL); - if (depth != 8 || - ! (color_type == PNG_COLOR_TYPE_RGB || - color_type == PNG_COLOR_TYPE_RGB_ALPHA)) - { - surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_READ_ERROR)); - goto BAIL; - } - - switch (color_type) { - default: - ASSERT_NOT_REACHED; - /* fall-through just in case ;-) */ - - case PNG_COLOR_TYPE_RGB_ALPHA: - format = CAIRO_FORMAT_ARGB32; - png_set_read_user_transform_fn (png, premultiply_data); - break; - - case PNG_COLOR_TYPE_RGB: - format = CAIRO_FORMAT_RGB24; - png_set_read_user_transform_fn (png, convert_bytes_to_data); - break; - } - - stride = cairo_format_stride_for_width (format, png_width); - if (stride < 0) { - surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE)); - goto BAIL; - } - - data = _cairo_malloc_ab (png_height, stride); - if (unlikely (data == NULL)) { - surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - goto BAIL; - } - - row_pointers = _cairo_malloc_ab (png_height, sizeof (char *)); - if (unlikely (row_pointers == NULL)) { - surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - goto BAIL; - } - - for (i = 0; i < png_height; i++) - row_pointers[i] = &data[i * stride]; - - png_read_image (png, row_pointers); - png_read_end (png, info); - - if (unlikely (status)) { /* catch any late warnings - probably hit an error already */ - surface = _cairo_surface_create_in_error (status); - goto BAIL; - } - - surface = cairo_image_surface_create_for_data (data, format, - png_width, png_height, - stride); - if (surface->status) - goto BAIL; - - _cairo_image_surface_assume_ownership_of_data ((cairo_image_surface_t*)surface); - data = NULL; - - _cairo_debug_check_image_surface_is_defined (surface); - - status = _cairo_memory_stream_destroy (png_closure->png_data, - &mime_data, - &mime_data_length); - png_closure->png_data = NULL; - if (unlikely (status)) { - cairo_surface_destroy (surface); - surface = _cairo_surface_create_in_error (status); - goto BAIL; - } - - status = cairo_surface_set_mime_data (surface, - CAIRO_MIME_TYPE_PNG, - mime_data, - mime_data_length, - free, - mime_data); - if (unlikely (status)) { - free (mime_data); - cairo_surface_destroy (surface); - surface = _cairo_surface_create_in_error (status); - goto BAIL; - } - - BAIL: - free (row_pointers); - free (data); - if (png != NULL) - png_destroy_read_struct (&png, &info, NULL); - if (png_closure->png_data != NULL) { - cairo_status_t status_ignored; - - status_ignored = _cairo_output_stream_destroy (png_closure->png_data); - } - - return surface; -} - -/** - * cairo_image_surface_create_from_png: - * @filename: name of PNG file to load - * - * Creates a new image surface and initializes the contents to the - * given PNG file. - * - * Return value: a new #cairo_surface_t initialized with the contents - * of the PNG file, or a "nil" surface if any error occurred. A nil - * surface can be checked for with cairo_surface_status(surface) which - * may return one of the following values: - * - * %CAIRO_STATUS_NO_MEMORY - * %CAIRO_STATUS_FILE_NOT_FOUND - * %CAIRO_STATUS_READ_ERROR - * - * Alternatively, you can allow errors to propagate through the drawing - * operations and check the status on the context upon completion - * using cairo_status(). - * - * Since: 1.0 - **/ -cairo_surface_t * -cairo_image_surface_create_from_png (const char *filename) -{ - struct png_read_closure_t png_closure; - cairo_surface_t *surface; - - png_closure.closure = fopen (filename, "rb"); - if (png_closure.closure == NULL) { - cairo_status_t status; - switch (errno) { - case ENOMEM: - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - break; - case ENOENT: - status = _cairo_error (CAIRO_STATUS_FILE_NOT_FOUND); - break; - default: - status = _cairo_error (CAIRO_STATUS_READ_ERROR); - break; - } - return _cairo_surface_create_in_error (status); - } - - png_closure.read_func = stdio_read_func; - - surface = read_png (&png_closure); - - fclose (png_closure.closure); - - return surface; -} - -/** - * cairo_image_surface_create_from_png_stream: - * @read_func: function called to read the data of the file - * @closure: data to pass to @read_func. - * - * Creates a new image surface from PNG data read incrementally - * via the @read_func function. - * - * Return value: a new #cairo_surface_t initialized with the contents - * of the PNG file or a "nil" surface if the data read is not a valid PNG image - * or memory could not be allocated for the operation. A nil - * surface can be checked for with cairo_surface_status(surface) which - * may return one of the following values: - * - * %CAIRO_STATUS_NO_MEMORY - * %CAIRO_STATUS_READ_ERROR - * - * Alternatively, you can allow errors to propagate through the drawing - * operations and check the status on the context upon completion - * using cairo_status(). - * - * Since: 1.0 - **/ -cairo_surface_t * -cairo_image_surface_create_from_png_stream (cairo_read_func_t read_func, - void *closure) -{ - struct png_read_closure_t png_closure; - - png_closure.read_func = read_func; - png_closure.closure = closure; - - return read_png (&png_closure); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-polygon-intersect.c b/source/libs/cairo/cairo-src/src/cairo-polygon-intersect.c deleted file mode 100644 index 8cb8fb1208b13f7ef57090b823955a72143f12e1..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-polygon-intersect.c +++ /dev/null @@ -1,1471 +0,0 @@ -/* - * Copyright © 2004 Carl Worth - * Copyright © 2006 Red Hat, Inc. - * Copyright © 2008 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Carl Worth - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -/* Provide definitions for standalone compilation */ -#include "cairoint.h" - -#include "cairo-error-private.h" -#include "cairo-freelist-private.h" -#include "cairo-combsort-inline.h" - - -typedef struct _cairo_bo_intersect_ordinate { - int32_t ordinate; - enum { EXCESS = -1, EXACT = 0, DEFAULT = 1 } approx; -} cairo_bo_intersect_ordinate_t; - -typedef struct _cairo_bo_intersect_point { - cairo_bo_intersect_ordinate_t x; - cairo_bo_intersect_ordinate_t y; -} cairo_bo_intersect_point_t; - -typedef struct _cairo_bo_edge cairo_bo_edge_t; - -typedef struct _cairo_bo_deferred { - cairo_bo_edge_t *other; - int32_t top; -} cairo_bo_deferred_t; - -struct _cairo_bo_edge { - int a_or_b; - cairo_edge_t edge; - cairo_bo_edge_t *prev; - cairo_bo_edge_t *next; - cairo_bo_deferred_t deferred; -}; - -/* the parent is always given by index/2 */ -#define PQ_PARENT_INDEX(i) ((i) >> 1) -#define PQ_FIRST_ENTRY 1 - -/* left and right children are index * 2 and (index * 2) +1 respectively */ -#define PQ_LEFT_CHILD_INDEX(i) ((i) << 1) - -typedef enum { - CAIRO_BO_EVENT_TYPE_STOP = -1, - CAIRO_BO_EVENT_TYPE_INTERSECTION, - CAIRO_BO_EVENT_TYPE_START -} cairo_bo_event_type_t; - -typedef struct _cairo_bo_event { - cairo_bo_event_type_t type; - cairo_bo_intersect_point_t point; -} cairo_bo_event_t; - -typedef struct _cairo_bo_start_event { - cairo_bo_event_type_t type; - cairo_bo_intersect_point_t point; - cairo_bo_edge_t edge; -} cairo_bo_start_event_t; - -typedef struct _cairo_bo_queue_event { - cairo_bo_event_type_t type; - cairo_bo_intersect_point_t point; - cairo_bo_edge_t *e1; - cairo_bo_edge_t *e2; -} cairo_bo_queue_event_t; - -typedef struct _pqueue { - int size, max_size; - - cairo_bo_event_t **elements; - cairo_bo_event_t *elements_embedded[1024]; -} pqueue_t; - -typedef struct _cairo_bo_event_queue { - cairo_freepool_t pool; - pqueue_t pqueue; - cairo_bo_event_t **start_events; -} cairo_bo_event_queue_t; - -typedef struct _cairo_bo_sweep_line { - cairo_bo_edge_t *head; - int32_t current_y; - cairo_bo_edge_t *current_edge; -} cairo_bo_sweep_line_t; - -static cairo_fixed_t -_line_compute_intersection_x_for_y (const cairo_line_t *line, - cairo_fixed_t y) -{ - cairo_fixed_t x, dy; - - if (y == line->p1.y) - return line->p1.x; - if (y == line->p2.y) - return line->p2.x; - - x = line->p1.x; - dy = line->p2.y - line->p1.y; - if (dy != 0) { - x += _cairo_fixed_mul_div_floor (y - line->p1.y, - line->p2.x - line->p1.x, - dy); - } - - return x; -} - -static inline int -_cairo_bo_point32_compare (cairo_bo_intersect_point_t const *a, - cairo_bo_intersect_point_t const *b) -{ - int cmp; - - cmp = a->y.ordinate - b->y.ordinate; - if (cmp) - return cmp; - - cmp = a->y.approx - b->y.approx; - if (cmp) - return cmp; - - return a->x.ordinate - b->x.ordinate; -} - -/* Compare the slope of a to the slope of b, returning 1, 0, -1 if the - * slope a is respectively greater than, equal to, or less than the - * slope of b. - * - * For each edge, consider the direction vector formed from: - * - * top -> bottom - * - * which is: - * - * (dx, dy) = (line.p2.x - line.p1.x, line.p2.y - line.p1.y) - * - * We then define the slope of each edge as dx/dy, (which is the - * inverse of the slope typically used in math instruction). We never - * compute a slope directly as the value approaches infinity, but we - * can derive a slope comparison without division as follows, (where - * the ? represents our compare operator). - * - * 1. slope(a) ? slope(b) - * 2. adx/ady ? bdx/bdy - * 3. (adx * bdy) ? (bdx * ady) - * - * Note that from step 2 to step 3 there is no change needed in the - * sign of the result since both ady and bdy are guaranteed to be - * greater than or equal to 0. - * - * When using this slope comparison to sort edges, some care is needed - * when interpreting the results. Since the slope compare operates on - * distance vectors from top to bottom it gives a correct left to - * right sort for edges that have a common top point, (such as two - * edges with start events at the same location). On the other hand, - * the sense of the result will be exactly reversed for two edges that - * have a common stop point. - */ -static inline int -_slope_compare (const cairo_bo_edge_t *a, - const cairo_bo_edge_t *b) -{ - /* XXX: We're assuming here that dx and dy will still fit in 32 - * bits. That's not true in general as there could be overflow. We - * should prevent that before the tessellation algorithm - * begins. - */ - int32_t adx = a->edge.line.p2.x - a->edge.line.p1.x; - int32_t bdx = b->edge.line.p2.x - b->edge.line.p1.x; - - /* Since the dy's are all positive by construction we can fast - * path several common cases. - */ - - /* First check for vertical lines. */ - if (adx == 0) - return -bdx; - if (bdx == 0) - return adx; - - /* Then where the two edges point in different directions wrt x. */ - if ((adx ^ bdx) < 0) - return adx; - - /* Finally we actually need to do the general comparison. */ - { - int32_t ady = a->edge.line.p2.y - a->edge.line.p1.y; - int32_t bdy = b->edge.line.p2.y - b->edge.line.p1.y; - cairo_int64_t adx_bdy = _cairo_int32x32_64_mul (adx, bdy); - cairo_int64_t bdx_ady = _cairo_int32x32_64_mul (bdx, ady); - - return _cairo_int64_cmp (adx_bdy, bdx_ady); - } -} - -/* - * We need to compare the x-coordinates of a pair of lines for a particular y, - * without loss of precision. - * - * The x-coordinate along an edge for a given y is: - * X = A_x + (Y - A_y) * A_dx / A_dy - * - * So the inequality we wish to test is: - * A_x + (Y - A_y) * A_dx / A_dy ∘ B_x + (Y - B_y) * B_dx / B_dy, - * where ∘ is our inequality operator. - * - * By construction, we know that A_dy and B_dy (and (Y - A_y), (Y - B_y)) are - * all positive, so we can rearrange it thus without causing a sign change: - * A_dy * B_dy * (A_x - B_x) ∘ (Y - B_y) * B_dx * A_dy - * - (Y - A_y) * A_dx * B_dy - * - * Given the assumption that all the deltas fit within 32 bits, we can compute - * this comparison directly using 128 bit arithmetic. For certain, but common, - * input we can reduce this down to a single 32 bit compare by inspecting the - * deltas. - * - * (And put the burden of the work on developing fast 128 bit ops, which are - * required throughout the tessellator.) - * - * See the similar discussion for _slope_compare(). - */ -static int -edges_compare_x_for_y_general (const cairo_bo_edge_t *a, - const cairo_bo_edge_t *b, - int32_t y) -{ - /* XXX: We're assuming here that dx and dy will still fit in 32 - * bits. That's not true in general as there could be overflow. We - * should prevent that before the tessellation algorithm - * begins. - */ - int32_t dx; - int32_t adx, ady; - int32_t bdx, bdy; - enum { - HAVE_NONE = 0x0, - HAVE_DX = 0x1, - HAVE_ADX = 0x2, - HAVE_DX_ADX = HAVE_DX | HAVE_ADX, - HAVE_BDX = 0x4, - HAVE_DX_BDX = HAVE_DX | HAVE_BDX, - HAVE_ADX_BDX = HAVE_ADX | HAVE_BDX, - HAVE_ALL = HAVE_DX | HAVE_ADX | HAVE_BDX - } have_dx_adx_bdx = HAVE_ALL; - - /* don't bother solving for abscissa if the edges' bounding boxes - * can be used to order them. */ - { - int32_t amin, amax; - int32_t bmin, bmax; - if (a->edge.line.p1.x < a->edge.line.p2.x) { - amin = a->edge.line.p1.x; - amax = a->edge.line.p2.x; - } else { - amin = a->edge.line.p2.x; - amax = a->edge.line.p1.x; - } - if (b->edge.line.p1.x < b->edge.line.p2.x) { - bmin = b->edge.line.p1.x; - bmax = b->edge.line.p2.x; - } else { - bmin = b->edge.line.p2.x; - bmax = b->edge.line.p1.x; - } - if (amax < bmin) return -1; - if (amin > bmax) return +1; - } - - ady = a->edge.line.p2.y - a->edge.line.p1.y; - adx = a->edge.line.p2.x - a->edge.line.p1.x; - if (adx == 0) - have_dx_adx_bdx &= ~HAVE_ADX; - - bdy = b->edge.line.p2.y - b->edge.line.p1.y; - bdx = b->edge.line.p2.x - b->edge.line.p1.x; - if (bdx == 0) - have_dx_adx_bdx &= ~HAVE_BDX; - - dx = a->edge.line.p1.x - b->edge.line.p1.x; - if (dx == 0) - have_dx_adx_bdx &= ~HAVE_DX; - -#define L _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (ady, bdy), dx) -#define A _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (adx, bdy), y - a->edge.line.p1.y) -#define B _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (bdx, ady), y - b->edge.line.p1.y) - switch (have_dx_adx_bdx) { - default: - case HAVE_NONE: - return 0; - case HAVE_DX: - /* A_dy * B_dy * (A_x - B_x) ∘ 0 */ - return dx; /* ady * bdy is positive definite */ - case HAVE_ADX: - /* 0 ∘ - (Y - A_y) * A_dx * B_dy */ - return adx; /* bdy * (y - a->top.y) is positive definite */ - case HAVE_BDX: - /* 0 ∘ (Y - B_y) * B_dx * A_dy */ - return -bdx; /* ady * (y - b->top.y) is positive definite */ - case HAVE_ADX_BDX: - /* 0 ∘ (Y - B_y) * B_dx * A_dy - (Y - A_y) * A_dx * B_dy */ - if ((adx ^ bdx) < 0) { - return adx; - } else if (a->edge.line.p1.y == b->edge.line.p1.y) { /* common origin */ - cairo_int64_t adx_bdy, bdx_ady; - - /* ∴ A_dx * B_dy ∘ B_dx * A_dy */ - - adx_bdy = _cairo_int32x32_64_mul (adx, bdy); - bdx_ady = _cairo_int32x32_64_mul (bdx, ady); - - return _cairo_int64_cmp (adx_bdy, bdx_ady); - } else - return _cairo_int128_cmp (A, B); - case HAVE_DX_ADX: - /* A_dy * (A_x - B_x) ∘ - (Y - A_y) * A_dx */ - if ((-adx ^ dx) < 0) { - return dx; - } else { - cairo_int64_t ady_dx, dy_adx; - - ady_dx = _cairo_int32x32_64_mul (ady, dx); - dy_adx = _cairo_int32x32_64_mul (a->edge.line.p1.y - y, adx); - - return _cairo_int64_cmp (ady_dx, dy_adx); - } - case HAVE_DX_BDX: - /* B_dy * (A_x - B_x) ∘ (Y - B_y) * B_dx */ - if ((bdx ^ dx) < 0) { - return dx; - } else { - cairo_int64_t bdy_dx, dy_bdx; - - bdy_dx = _cairo_int32x32_64_mul (bdy, dx); - dy_bdx = _cairo_int32x32_64_mul (y - b->edge.line.p1.y, bdx); - - return _cairo_int64_cmp (bdy_dx, dy_bdx); - } - case HAVE_ALL: - /* XXX try comparing (a->edge.line.p2.x - b->edge.line.p2.x) et al */ - return _cairo_int128_cmp (L, _cairo_int128_sub (B, A)); - } -#undef B -#undef A -#undef L -} - -/* - * We need to compare the x-coordinate of a line for a particular y wrt to a - * given x, without loss of precision. - * - * The x-coordinate along an edge for a given y is: - * X = A_x + (Y - A_y) * A_dx / A_dy - * - * So the inequality we wish to test is: - * A_x + (Y - A_y) * A_dx / A_dy ∘ X - * where ∘ is our inequality operator. - * - * By construction, we know that A_dy (and (Y - A_y)) are - * all positive, so we can rearrange it thus without causing a sign change: - * (Y - A_y) * A_dx ∘ (X - A_x) * A_dy - * - * Given the assumption that all the deltas fit within 32 bits, we can compute - * this comparison directly using 64 bit arithmetic. - * - * See the similar discussion for _slope_compare() and - * edges_compare_x_for_y_general(). - */ -static int -edge_compare_for_y_against_x (const cairo_bo_edge_t *a, - int32_t y, - int32_t x) -{ - int32_t adx, ady; - int32_t dx, dy; - cairo_int64_t L, R; - - if (x < a->edge.line.p1.x && x < a->edge.line.p2.x) - return 1; - if (x > a->edge.line.p1.x && x > a->edge.line.p2.x) - return -1; - - adx = a->edge.line.p2.x - a->edge.line.p1.x; - dx = x - a->edge.line.p1.x; - - if (adx == 0) - return -dx; - if (dx == 0 || (adx ^ dx) < 0) - return adx; - - dy = y - a->edge.line.p1.y; - ady = a->edge.line.p2.y - a->edge.line.p1.y; - - L = _cairo_int32x32_64_mul (dy, adx); - R = _cairo_int32x32_64_mul (dx, ady); - - return _cairo_int64_cmp (L, R); -} - -static int -edges_compare_x_for_y (const cairo_bo_edge_t *a, - const cairo_bo_edge_t *b, - int32_t y) -{ - /* If the sweep-line is currently on an end-point of a line, - * then we know its precise x value (and considering that we often need to - * compare events at end-points, this happens frequently enough to warrant - * special casing). - */ - enum { - HAVE_NEITHER = 0x0, - HAVE_AX = 0x1, - HAVE_BX = 0x2, - HAVE_BOTH = HAVE_AX | HAVE_BX - } have_ax_bx = HAVE_BOTH; - int32_t ax, bx; - - if (y == a->edge.line.p1.y) - ax = a->edge.line.p1.x; - else if (y == a->edge.line.p2.y) - ax = a->edge.line.p2.x; - else - have_ax_bx &= ~HAVE_AX; - - if (y == b->edge.line.p1.y) - bx = b->edge.line.p1.x; - else if (y == b->edge.line.p2.y) - bx = b->edge.line.p2.x; - else - have_ax_bx &= ~HAVE_BX; - - switch (have_ax_bx) { - default: - case HAVE_NEITHER: - return edges_compare_x_for_y_general (a, b, y); - case HAVE_AX: - return -edge_compare_for_y_against_x (b, y, ax); - case HAVE_BX: - return edge_compare_for_y_against_x (a, y, bx); - case HAVE_BOTH: - return ax - bx; - } -} - -static inline int -_line_equal (const cairo_line_t *a, const cairo_line_t *b) -{ - return a->p1.x == b->p1.x && a->p1.y == b->p1.y && - a->p2.x == b->p2.x && a->p2.y == b->p2.y; -} - -static int -_cairo_bo_sweep_line_compare_edges (cairo_bo_sweep_line_t *sweep_line, - const cairo_bo_edge_t *a, - const cairo_bo_edge_t *b) -{ - int cmp; - - /* compare the edges if not identical */ - if (! _line_equal (&a->edge.line, &b->edge.line)) { - cmp = edges_compare_x_for_y (a, b, sweep_line->current_y); - if (cmp) - return cmp; - - /* The two edges intersect exactly at y, so fall back on slope - * comparison. We know that this compare_edges function will be - * called only when starting a new edge, (not when stopping an - * edge), so we don't have to worry about conditionally inverting - * the sense of _slope_compare. */ - cmp = _slope_compare (a, b); - if (cmp) - return cmp; - } - - /* We've got two collinear edges now. */ - return b->edge.bottom - a->edge.bottom; -} - -static inline cairo_int64_t -det32_64 (int32_t a, int32_t b, - int32_t c, int32_t d) -{ - /* det = a * d - b * c */ - return _cairo_int64_sub (_cairo_int32x32_64_mul (a, d), - _cairo_int32x32_64_mul (b, c)); -} - -static inline cairo_int128_t -det64x32_128 (cairo_int64_t a, int32_t b, - cairo_int64_t c, int32_t d) -{ - /* det = a * d - b * c */ - return _cairo_int128_sub (_cairo_int64x32_128_mul (a, d), - _cairo_int64x32_128_mul (c, b)); -} - -static inline cairo_bo_intersect_ordinate_t -round_to_nearest (cairo_quorem64_t d, - cairo_int64_t den) -{ - cairo_bo_intersect_ordinate_t ordinate; - int32_t quo = d.quo; - cairo_int64_t drem_2 = _cairo_int64_mul (d.rem, _cairo_int32_to_int64 (2)); - - /* assert (! _cairo_int64_negative (den));*/ - - if (_cairo_int64_lt (drem_2, _cairo_int64_negate (den))) { - quo -= 1; - drem_2 = _cairo_int64_negate (drem_2); - } else if (_cairo_int64_le (den, drem_2)) { - quo += 1; - drem_2 = _cairo_int64_negate (drem_2); - } - - ordinate.ordinate = quo; - ordinate.approx = _cairo_int64_is_zero (drem_2) ? EXACT : _cairo_int64_negative (drem_2) ? EXCESS : DEFAULT; - - return ordinate; -} - -/* Compute the intersection of two lines as defined by two edges. The - * result is provided as a coordinate pair of 128-bit integers. - * - * Returns %CAIRO_BO_STATUS_INTERSECTION if there is an intersection or - * %CAIRO_BO_STATUS_PARALLEL if the two lines are exactly parallel. - */ -static cairo_bool_t -intersect_lines (cairo_bo_edge_t *a, - cairo_bo_edge_t *b, - cairo_bo_intersect_point_t *intersection) -{ - cairo_int64_t a_det, b_det; - - /* XXX: We're assuming here that dx and dy will still fit in 32 - * bits. That's not true in general as there could be overflow. We - * should prevent that before the tessellation algorithm begins. - * What we're doing to mitigate this is to perform clamping in - * cairo_bo_tessellate_polygon(). - */ - int32_t dx1 = a->edge.line.p1.x - a->edge.line.p2.x; - int32_t dy1 = a->edge.line.p1.y - a->edge.line.p2.y; - - int32_t dx2 = b->edge.line.p1.x - b->edge.line.p2.x; - int32_t dy2 = b->edge.line.p1.y - b->edge.line.p2.y; - - cairo_int64_t den_det; - cairo_int64_t R; - cairo_quorem64_t qr; - - den_det = det32_64 (dx1, dy1, dx2, dy2); - - /* Q: Can we determine that the lines do not intersect (within range) - * much more cheaply than computing the intersection point i.e. by - * avoiding the division? - * - * X = ax + t * adx = bx + s * bdx; - * Y = ay + t * ady = by + s * bdy; - * ∴ t * (ady*bdx - bdy*adx) = bdx * (by - ay) + bdy * (ax - bx) - * => t * L = R - * - * Therefore we can reject any intersection (under the criteria for - * valid intersection events) if: - * L^R < 0 => t < 0, or - * L<R => t > 1 - * - * (where top/bottom must at least extend to the line endpoints). - * - * A similar substitution can be performed for s, yielding: - * s * (ady*bdx - bdy*adx) = ady * (ax - bx) - adx * (ay - by) - */ - R = det32_64 (dx2, dy2, - b->edge.line.p1.x - a->edge.line.p1.x, - b->edge.line.p1.y - a->edge.line.p1.y); - if (_cairo_int64_le (den_det, R)) - return FALSE; - - R = det32_64 (dy1, dx1, - a->edge.line.p1.y - b->edge.line.p1.y, - a->edge.line.p1.x - b->edge.line.p1.x); - if (_cairo_int64_le (den_det, R)) - return FALSE; - - /* We now know that the two lines should intersect within range. */ - - a_det = det32_64 (a->edge.line.p1.x, a->edge.line.p1.y, - a->edge.line.p2.x, a->edge.line.p2.y); - b_det = det32_64 (b->edge.line.p1.x, b->edge.line.p1.y, - b->edge.line.p2.x, b->edge.line.p2.y); - - /* x = det (a_det, dx1, b_det, dx2) / den_det */ - qr = _cairo_int_96by64_32x64_divrem (det64x32_128 (a_det, dx1, - b_det, dx2), - den_det); - if (_cairo_int64_eq (qr.rem, den_det)) - return FALSE; - - intersection->x = round_to_nearest (qr, den_det); - - /* y = det (a_det, dy1, b_det, dy2) / den_det */ - qr = _cairo_int_96by64_32x64_divrem (det64x32_128 (a_det, dy1, - b_det, dy2), - den_det); - if (_cairo_int64_eq (qr.rem, den_det)) - return FALSE; - - intersection->y = round_to_nearest (qr, den_det); - - return TRUE; -} - -static int -_cairo_bo_intersect_ordinate_32_compare (cairo_bo_intersect_ordinate_t a, - int32_t b) -{ - /* First compare the quotient */ - if (a.ordinate > b) - return +1; - if (a.ordinate < b) - return -1; - - return a.approx; /* == EXCESS ? -1 : a.approx == EXACT ? 0 : 1;*/ -} - -/* Does the given edge contain the given point. The point must already - * be known to be contained within the line determined by the edge, - * (most likely the point results from an intersection of this edge - * with another). - * - * If we had exact arithmetic, then this function would simply be a - * matter of examining whether the y value of the point lies within - * the range of y values of the edge. But since intersection points - * are not exact due to being rounded to the nearest integer within - * the available precision, we must also examine the x value of the - * point. - * - * The definition of "contains" here is that the given intersection - * point will be seen by the sweep line after the start event for the - * given edge and before the stop event for the edge. See the comments - * in the implementation for more details. - */ -static cairo_bool_t -_cairo_bo_edge_contains_intersect_point (cairo_bo_edge_t *edge, - cairo_bo_intersect_point_t *point) -{ - return _cairo_bo_intersect_ordinate_32_compare (point->y, - edge->edge.bottom) < 0; -} - -/* Compute the intersection of two edges. The result is provided as a - * coordinate pair of 128-bit integers. - * - * Returns %CAIRO_BO_STATUS_INTERSECTION if there is an intersection - * that is within both edges, %CAIRO_BO_STATUS_NO_INTERSECTION if the - * intersection of the lines defined by the edges occurs outside of - * one or both edges, and %CAIRO_BO_STATUS_PARALLEL if the two edges - * are exactly parallel. - * - * Note that when determining if a candidate intersection is "inside" - * an edge, we consider both the infinitesimal shortening and the - * infinitesimal tilt rules described by John Hobby. Specifically, if - * the intersection is exactly the same as an edge point, it is - * effectively outside (no intersection is returned). Also, if the - * intersection point has the same - */ -static cairo_bool_t -_cairo_bo_edge_intersect (cairo_bo_edge_t *a, - cairo_bo_edge_t *b, - cairo_bo_intersect_point_t *intersection) -{ - if (! intersect_lines (a, b, intersection)) - return FALSE; - - if (! _cairo_bo_edge_contains_intersect_point (a, intersection)) - return FALSE; - - if (! _cairo_bo_edge_contains_intersect_point (b, intersection)) - return FALSE; - - return TRUE; -} - -static inline int -cairo_bo_event_compare (const cairo_bo_event_t *a, - const cairo_bo_event_t *b) -{ - int cmp; - - cmp = _cairo_bo_point32_compare (&a->point, &b->point); - if (cmp) - return cmp; - - cmp = a->type - b->type; - if (cmp) - return cmp; - - return a < b ? -1 : a == b ? 0 : 1; -} - -static inline void -_pqueue_init (pqueue_t *pq) -{ - pq->max_size = ARRAY_LENGTH (pq->elements_embedded); - pq->size = 0; - - pq->elements = pq->elements_embedded; -} - -static inline void -_pqueue_fini (pqueue_t *pq) -{ - if (pq->elements != pq->elements_embedded) - free (pq->elements); -} - -static cairo_status_t -_pqueue_grow (pqueue_t *pq) -{ - cairo_bo_event_t **new_elements; - pq->max_size *= 2; - - if (pq->elements == pq->elements_embedded) { - new_elements = _cairo_malloc_ab (pq->max_size, - sizeof (cairo_bo_event_t *)); - if (unlikely (new_elements == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - memcpy (new_elements, pq->elements_embedded, - sizeof (pq->elements_embedded)); - } else { - new_elements = _cairo_realloc_ab (pq->elements, - pq->max_size, - sizeof (cairo_bo_event_t *)); - if (unlikely (new_elements == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - pq->elements = new_elements; - return CAIRO_STATUS_SUCCESS; -} - -static inline cairo_status_t -_pqueue_push (pqueue_t *pq, cairo_bo_event_t *event) -{ - cairo_bo_event_t **elements; - int i, parent; - - if (unlikely (pq->size + 1 == pq->max_size)) { - cairo_status_t status; - - status = _pqueue_grow (pq); - if (unlikely (status)) - return status; - } - - elements = pq->elements; - - for (i = ++pq->size; - i != PQ_FIRST_ENTRY && - cairo_bo_event_compare (event, - elements[parent = PQ_PARENT_INDEX (i)]) < 0; - i = parent) - { - elements[i] = elements[parent]; - } - - elements[i] = event; - - return CAIRO_STATUS_SUCCESS; -} - -static inline void -_pqueue_pop (pqueue_t *pq) -{ - cairo_bo_event_t **elements = pq->elements; - cairo_bo_event_t *tail; - int child, i; - - tail = elements[pq->size--]; - if (pq->size == 0) { - elements[PQ_FIRST_ENTRY] = NULL; - return; - } - - for (i = PQ_FIRST_ENTRY; - (child = PQ_LEFT_CHILD_INDEX (i)) <= pq->size; - i = child) - { - if (child != pq->size && - cairo_bo_event_compare (elements[child+1], - elements[child]) < 0) - { - child++; - } - - if (cairo_bo_event_compare (elements[child], tail) >= 0) - break; - - elements[i] = elements[child]; - } - elements[i] = tail; -} - -static inline cairo_status_t -_cairo_bo_event_queue_insert (cairo_bo_event_queue_t *queue, - cairo_bo_event_type_t type, - cairo_bo_edge_t *e1, - cairo_bo_edge_t *e2, - const cairo_bo_intersect_point_t *point) -{ - cairo_bo_queue_event_t *event; - - event = _cairo_freepool_alloc (&queue->pool); - if (unlikely (event == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - event->type = type; - event->e1 = e1; - event->e2 = e2; - event->point = *point; - - return _pqueue_push (&queue->pqueue, (cairo_bo_event_t *) event); -} - -static void -_cairo_bo_event_queue_delete (cairo_bo_event_queue_t *queue, - cairo_bo_event_t *event) -{ - _cairo_freepool_free (&queue->pool, event); -} - -static cairo_bo_event_t * -_cairo_bo_event_dequeue (cairo_bo_event_queue_t *event_queue) -{ - cairo_bo_event_t *event, *cmp; - - event = event_queue->pqueue.elements[PQ_FIRST_ENTRY]; - cmp = *event_queue->start_events; - if (event == NULL || - (cmp != NULL && cairo_bo_event_compare (cmp, event) < 0)) - { - event = cmp; - event_queue->start_events++; - } - else - { - _pqueue_pop (&event_queue->pqueue); - } - - return event; -} - -CAIRO_COMBSORT_DECLARE (_cairo_bo_event_queue_sort, - cairo_bo_event_t *, - cairo_bo_event_compare) - -static void -_cairo_bo_event_queue_init (cairo_bo_event_queue_t *event_queue, - cairo_bo_event_t **start_events, - int num_events) -{ - _cairo_bo_event_queue_sort (start_events, num_events); - start_events[num_events] = NULL; - - event_queue->start_events = start_events; - - _cairo_freepool_init (&event_queue->pool, - sizeof (cairo_bo_queue_event_t)); - _pqueue_init (&event_queue->pqueue); - event_queue->pqueue.elements[PQ_FIRST_ENTRY] = NULL; -} - -static cairo_status_t -event_queue_insert_stop (cairo_bo_event_queue_t *event_queue, - cairo_bo_edge_t *edge) -{ - cairo_bo_intersect_point_t point; - - point.y.ordinate = edge->edge.bottom; - point.y.approx = EXACT; - point.x.ordinate = _line_compute_intersection_x_for_y (&edge->edge.line, - point.y.ordinate); - point.x.approx = EXACT; - - return _cairo_bo_event_queue_insert (event_queue, - CAIRO_BO_EVENT_TYPE_STOP, - edge, NULL, - &point); -} - -static void -_cairo_bo_event_queue_fini (cairo_bo_event_queue_t *event_queue) -{ - _pqueue_fini (&event_queue->pqueue); - _cairo_freepool_fini (&event_queue->pool); -} - -static inline cairo_status_t -event_queue_insert_if_intersect_below_current_y (cairo_bo_event_queue_t *event_queue, - cairo_bo_edge_t *left, - cairo_bo_edge_t *right) -{ - cairo_bo_intersect_point_t intersection; - - if (_line_equal (&left->edge.line, &right->edge.line)) - return CAIRO_STATUS_SUCCESS; - - /* The names "left" and "right" here are correct descriptions of - * the order of the two edges within the active edge list. So if a - * slope comparison also puts left less than right, then we know - * that the intersection of these two segments has already - * occurred before the current sweep line position. */ - if (_slope_compare (left, right) <= 0) - return CAIRO_STATUS_SUCCESS; - - if (! _cairo_bo_edge_intersect (left, right, &intersection)) - return CAIRO_STATUS_SUCCESS; - - return _cairo_bo_event_queue_insert (event_queue, - CAIRO_BO_EVENT_TYPE_INTERSECTION, - left, right, - &intersection); -} - -static void -_cairo_bo_sweep_line_init (cairo_bo_sweep_line_t *sweep_line) -{ - sweep_line->head = NULL; - sweep_line->current_y = INT32_MIN; - sweep_line->current_edge = NULL; -} - -static cairo_status_t -sweep_line_insert (cairo_bo_sweep_line_t *sweep_line, - cairo_bo_edge_t *edge) -{ - if (sweep_line->current_edge != NULL) { - cairo_bo_edge_t *prev, *next; - int cmp; - - cmp = _cairo_bo_sweep_line_compare_edges (sweep_line, - sweep_line->current_edge, - edge); - if (cmp < 0) { - prev = sweep_line->current_edge; - next = prev->next; - while (next != NULL && - _cairo_bo_sweep_line_compare_edges (sweep_line, - next, edge) < 0) - { - prev = next, next = prev->next; - } - - prev->next = edge; - edge->prev = prev; - edge->next = next; - if (next != NULL) - next->prev = edge; - } else if (cmp > 0) { - next = sweep_line->current_edge; - prev = next->prev; - while (prev != NULL && - _cairo_bo_sweep_line_compare_edges (sweep_line, - prev, edge) > 0) - { - next = prev, prev = next->prev; - } - - next->prev = edge; - edge->next = next; - edge->prev = prev; - if (prev != NULL) - prev->next = edge; - else - sweep_line->head = edge; - } else { - prev = sweep_line->current_edge; - edge->prev = prev; - edge->next = prev->next; - if (prev->next != NULL) - prev->next->prev = edge; - prev->next = edge; - } - } else { - sweep_line->head = edge; - } - - sweep_line->current_edge = edge; - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_bo_sweep_line_delete (cairo_bo_sweep_line_t *sweep_line, - cairo_bo_edge_t *edge) -{ - if (edge->prev != NULL) - edge->prev->next = edge->next; - else - sweep_line->head = edge->next; - - if (edge->next != NULL) - edge->next->prev = edge->prev; - - if (sweep_line->current_edge == edge) - sweep_line->current_edge = edge->prev ? edge->prev : edge->next; -} - -static void -_cairo_bo_sweep_line_swap (cairo_bo_sweep_line_t *sweep_line, - cairo_bo_edge_t *left, - cairo_bo_edge_t *right) -{ - if (left->prev != NULL) - left->prev->next = right; - else - sweep_line->head = right; - - if (right->next != NULL) - right->next->prev = left; - - left->next = right->next; - right->next = left; - - right->prev = left->prev; - left->prev = right; -} - -static inline cairo_bool_t -edges_colinear (const cairo_bo_edge_t *a, const cairo_bo_edge_t *b) -{ - if (_line_equal (&a->edge.line, &b->edge.line)) - return TRUE; - - if (_slope_compare (a, b)) - return FALSE; - - /* The choice of y is not truly arbitrary since we must guarantee that it - * is greater than the start of either line. - */ - if (a->edge.line.p1.y == b->edge.line.p1.y) { - return a->edge.line.p1.x == b->edge.line.p1.x; - } else if (a->edge.line.p1.y < b->edge.line.p1.y) { - return edge_compare_for_y_against_x (b, - a->edge.line.p1.y, - a->edge.line.p1.x) == 0; - } else { - return edge_compare_for_y_against_x (a, - b->edge.line.p1.y, - b->edge.line.p1.x) == 0; - } -} - -static void -edges_end (cairo_bo_edge_t *left, - int32_t bot, - cairo_polygon_t *polygon) -{ - cairo_bo_deferred_t *l = &left->deferred; - cairo_bo_edge_t *right = l->other; - - assert(right->deferred.other == NULL); - if (likely (l->top < bot)) { - _cairo_polygon_add_line (polygon, &left->edge.line, l->top, bot, 1); - _cairo_polygon_add_line (polygon, &right->edge.line, l->top, bot, -1); - } - - l->other = NULL; -} - -static inline void -edges_start_or_continue (cairo_bo_edge_t *left, - cairo_bo_edge_t *right, - int top, - cairo_polygon_t *polygon) -{ - assert (right->deferred.other == NULL); - - if (left->deferred.other == right) - return; - - if (left->deferred.other != NULL) { - if (right != NULL && edges_colinear (left->deferred.other, right)) { - cairo_bo_edge_t *old = left->deferred.other; - - /* continuation on right, extend right to cover both */ - assert (old->deferred.other == NULL); - assert (old->edge.line.p2.y > old->edge.line.p1.y); - - if (old->edge.line.p1.y < right->edge.line.p1.y) - right->edge.line.p1 = old->edge.line.p1; - if (old->edge.line.p2.y > right->edge.line.p2.y) - right->edge.line.p2 = old->edge.line.p2; - left->deferred.other = right; - return; - } - - edges_end (left, top, polygon); - } - - if (right != NULL && ! edges_colinear (left, right)) { - left->deferred.top = top; - left->deferred.other = right; - } -} - -#define is_zero(w) ((w)[0] == 0 || (w)[1] == 0) - -static inline void -active_edges (cairo_bo_edge_t *left, - int32_t top, - cairo_polygon_t *polygon) -{ - cairo_bo_edge_t *right; - int winding[2] = {0, 0}; - - /* Yes, this is naive. Consider this a placeholder. */ - - while (left != NULL) { - assert (is_zero (winding)); - - do { - winding[left->a_or_b] += left->edge.dir; - if (! is_zero (winding)) - break; - - if unlikely ((left->deferred.other)) - edges_end (left, top, polygon); - - left = left->next; - if (! left) - return; - } while (1); - - right = left->next; - do { - if unlikely ((right->deferred.other)) - edges_end (right, top, polygon); - - winding[right->a_or_b] += right->edge.dir; - if (is_zero (winding)) { - if (right->next == NULL || - ! edges_colinear (right, right->next)) - break; - } - - right = right->next; - } while (1); - - edges_start_or_continue (left, right, top, polygon); - - left = right->next; - } -} - -static cairo_status_t -intersection_sweep (cairo_bo_event_t **start_events, - int num_events, - cairo_polygon_t *polygon) -{ - cairo_status_t status = CAIRO_STATUS_SUCCESS; /* silence compiler */ - cairo_bo_event_queue_t event_queue; - cairo_bo_sweep_line_t sweep_line; - cairo_bo_event_t *event; - cairo_bo_edge_t *left, *right; - cairo_bo_edge_t *e1, *e2; - - _cairo_bo_event_queue_init (&event_queue, start_events, num_events); - _cairo_bo_sweep_line_init (&sweep_line); - - while ((event = _cairo_bo_event_dequeue (&event_queue))) { - if (event->point.y.ordinate != sweep_line.current_y) { - active_edges (sweep_line.head, - sweep_line.current_y, - polygon); - sweep_line.current_y = event->point.y.ordinate; - } - - switch (event->type) { - case CAIRO_BO_EVENT_TYPE_START: - e1 = &((cairo_bo_start_event_t *) event)->edge; - - status = sweep_line_insert (&sweep_line, e1); - if (unlikely (status)) - goto unwind; - - status = event_queue_insert_stop (&event_queue, e1); - if (unlikely (status)) - goto unwind; - - left = e1->prev; - right = e1->next; - - if (left != NULL) { - status = event_queue_insert_if_intersect_below_current_y (&event_queue, left, e1); - if (unlikely (status)) - goto unwind; - } - - if (right != NULL) { - status = event_queue_insert_if_intersect_below_current_y (&event_queue, e1, right); - if (unlikely (status)) - goto unwind; - } - - break; - - case CAIRO_BO_EVENT_TYPE_STOP: - e1 = ((cairo_bo_queue_event_t *) event)->e1; - _cairo_bo_event_queue_delete (&event_queue, event); - - if (e1->deferred.other) - edges_end (e1, sweep_line.current_y, polygon); - - left = e1->prev; - right = e1->next; - - _cairo_bo_sweep_line_delete (&sweep_line, e1); - - if (left != NULL && right != NULL) { - status = event_queue_insert_if_intersect_below_current_y (&event_queue, left, right); - if (unlikely (status)) - goto unwind; - } - - break; - - case CAIRO_BO_EVENT_TYPE_INTERSECTION: - e1 = ((cairo_bo_queue_event_t *) event)->e1; - e2 = ((cairo_bo_queue_event_t *) event)->e2; - _cairo_bo_event_queue_delete (&event_queue, event); - - /* skip this intersection if its edges are not adjacent */ - if (e2 != e1->next) - break; - - if (e1->deferred.other) - edges_end (e1, sweep_line.current_y, polygon); - if (e2->deferred.other) - edges_end (e2, sweep_line.current_y, polygon); - - left = e1->prev; - right = e2->next; - - _cairo_bo_sweep_line_swap (&sweep_line, e1, e2); - - /* after the swap e2 is left of e1 */ - - if (left != NULL) { - status = event_queue_insert_if_intersect_below_current_y (&event_queue, left, e2); - if (unlikely (status)) - goto unwind; - } - - if (right != NULL) { - status = event_queue_insert_if_intersect_below_current_y (&event_queue, e1, right); - if (unlikely (status)) - goto unwind; - } - - break; - } - } - - unwind: - _cairo_bo_event_queue_fini (&event_queue); - - return status; -} - -cairo_status_t -_cairo_polygon_intersect (cairo_polygon_t *a, int winding_a, - cairo_polygon_t *b, int winding_b) -{ - cairo_status_t status; - cairo_bo_start_event_t stack_events[CAIRO_STACK_ARRAY_LENGTH (cairo_bo_start_event_t)]; - cairo_bo_start_event_t *events; - cairo_bo_event_t *stack_event_ptrs[ARRAY_LENGTH (stack_events) + 1]; - cairo_bo_event_t **event_ptrs; - int num_events; - int i, j; - - /* XXX lazy */ - if (winding_a != CAIRO_FILL_RULE_WINDING) { - status = _cairo_polygon_reduce (a, winding_a); - if (unlikely (status)) - return status; - } - - if (winding_b != CAIRO_FILL_RULE_WINDING) { - status = _cairo_polygon_reduce (b, winding_b); - if (unlikely (status)) - return status; - } - - if (unlikely (0 == a->num_edges)) - return CAIRO_STATUS_SUCCESS; - - if (unlikely (0 == b->num_edges)) { - a->num_edges = 0; - return CAIRO_STATUS_SUCCESS; - } - - events = stack_events; - event_ptrs = stack_event_ptrs; - num_events = a->num_edges + b->num_edges; - if (num_events > ARRAY_LENGTH (stack_events)) { - events = _cairo_malloc_ab_plus_c (num_events, - sizeof (cairo_bo_start_event_t) + - sizeof (cairo_bo_event_t *), - sizeof (cairo_bo_event_t *)); - if (unlikely (events == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - event_ptrs = (cairo_bo_event_t **) (events + num_events); - } - - j = 0; - for (i = 0; i < a->num_edges; i++) { - event_ptrs[j] = (cairo_bo_event_t *) &events[j]; - - events[j].type = CAIRO_BO_EVENT_TYPE_START; - events[j].point.y.ordinate = a->edges[i].top; - events[j].point.y.approx = EXACT; - events[j].point.x.ordinate = - _line_compute_intersection_x_for_y (&a->edges[i].line, - events[j].point.y.ordinate); - events[j].point.x.approx = EXACT; - - events[j].edge.a_or_b = 0; - events[j].edge.edge = a->edges[i]; - events[j].edge.deferred.other = NULL; - events[j].edge.prev = NULL; - events[j].edge.next = NULL; - j++; - } - - for (i = 0; i < b->num_edges; i++) { - event_ptrs[j] = (cairo_bo_event_t *) &events[j]; - - events[j].type = CAIRO_BO_EVENT_TYPE_START; - events[j].point.y.ordinate = b->edges[i].top; - events[j].point.y.approx = EXACT; - events[j].point.x.ordinate = - _line_compute_intersection_x_for_y (&b->edges[i].line, - events[j].point.y.ordinate); - events[j].point.x.approx = EXACT; - - events[j].edge.a_or_b = 1; - events[j].edge.edge = b->edges[i]; - events[j].edge.deferred.other = NULL; - events[j].edge.prev = NULL; - events[j].edge.next = NULL; - j++; - } - assert (j == num_events); - -#if 0 - { - FILE *file = fopen ("clip_a.txt", "w"); - _cairo_debug_print_polygon (file, a); - fclose (file); - } - { - FILE *file = fopen ("clip_b.txt", "w"); - _cairo_debug_print_polygon (file, b); - fclose (file); - } -#endif - - a->num_edges = 0; - status = intersection_sweep (event_ptrs, num_events, a); - if (events != stack_events) - free (events); - -#if 0 - { - FILE *file = fopen ("clip_result.txt", "w"); - _cairo_debug_print_polygon (file, a); - fclose (file); - } -#endif - - return status; -} - -cairo_status_t -_cairo_polygon_intersect_with_boxes (cairo_polygon_t *polygon, - cairo_fill_rule_t *winding, - cairo_box_t *boxes, - int num_boxes) -{ - cairo_polygon_t b; - cairo_status_t status; - int n; - - if (num_boxes == 0) { - polygon->num_edges = 0; - return CAIRO_STATUS_SUCCESS; - } - - for (n = 0; n < num_boxes; n++) { - if (polygon->extents.p1.x >= boxes[n].p1.x && - polygon->extents.p2.x <= boxes[n].p2.x && - polygon->extents.p1.y >= boxes[n].p1.y && - polygon->extents.p2.y <= boxes[n].p2.y) - { - return CAIRO_STATUS_SUCCESS; - } - } - - _cairo_polygon_init (&b, NULL, 0); - for (n = 0; n < num_boxes; n++) { - if (boxes[n].p2.x > polygon->extents.p1.x && - boxes[n].p1.x < polygon->extents.p2.x && - boxes[n].p2.y > polygon->extents.p1.y && - boxes[n].p1.y < polygon->extents.p2.y) - { - cairo_point_t p1, p2; - - p1.y = boxes[n].p1.y; - p2.y = boxes[n].p2.y; - - p2.x = p1.x = boxes[n].p1.x; - _cairo_polygon_add_external_edge (&b, &p1, &p2); - - p2.x = p1.x = boxes[n].p2.x; - _cairo_polygon_add_external_edge (&b, &p2, &p1); - } - } - - status = _cairo_polygon_intersect (polygon, *winding, - &b, CAIRO_FILL_RULE_WINDING); - _cairo_polygon_fini (&b); - - *winding = CAIRO_FILL_RULE_WINDING; - return status; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-polygon-reduce.c b/source/libs/cairo/cairo-src/src/cairo-polygon-reduce.c deleted file mode 100644 index ea457fe4edffbd7a54109ec07fc1e870088d3ac0..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-polygon-reduce.c +++ /dev/null @@ -1,1438 +0,0 @@ -/* - * Copyright © 2004 Carl Worth - * Copyright © 2006 Red Hat, Inc. - * Copyright © 2008 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Carl Worth - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -/* Provide definitions for standalone compilation */ -#include "cairoint.h" - -#include "cairo-error-private.h" -#include "cairo-freelist-private.h" -#include "cairo-combsort-inline.h" - -#define DEBUG_POLYGON 0 - -typedef cairo_point_t cairo_bo_point32_t; - -typedef struct _cairo_bo_intersect_ordinate { - int32_t ordinate; - enum { EXACT, INEXACT } exactness; -} cairo_bo_intersect_ordinate_t; - -typedef struct _cairo_bo_intersect_point { - cairo_bo_intersect_ordinate_t x; - cairo_bo_intersect_ordinate_t y; -} cairo_bo_intersect_point_t; - -typedef struct _cairo_bo_edge cairo_bo_edge_t; - -typedef struct _cairo_bo_deferred { - cairo_bo_edge_t *right; - int32_t top; -} cairo_bo_deferred_t; - -struct _cairo_bo_edge { - cairo_edge_t edge; - cairo_bo_edge_t *prev; - cairo_bo_edge_t *next; - cairo_bo_deferred_t deferred; -}; - -/* the parent is always given by index/2 */ -#define PQ_PARENT_INDEX(i) ((i) >> 1) -#define PQ_FIRST_ENTRY 1 - -/* left and right children are index * 2 and (index * 2) +1 respectively */ -#define PQ_LEFT_CHILD_INDEX(i) ((i) << 1) - -typedef enum { - CAIRO_BO_EVENT_TYPE_STOP, - CAIRO_BO_EVENT_TYPE_INTERSECTION, - CAIRO_BO_EVENT_TYPE_START -} cairo_bo_event_type_t; - -typedef struct _cairo_bo_event { - cairo_bo_event_type_t type; - cairo_point_t point; -} cairo_bo_event_t; - -typedef struct _cairo_bo_start_event { - cairo_bo_event_type_t type; - cairo_point_t point; - cairo_bo_edge_t edge; -} cairo_bo_start_event_t; - -typedef struct _cairo_bo_queue_event { - cairo_bo_event_type_t type; - cairo_point_t point; - cairo_bo_edge_t *e1; - cairo_bo_edge_t *e2; -} cairo_bo_queue_event_t; - -typedef struct _pqueue { - int size, max_size; - - cairo_bo_event_t **elements; - cairo_bo_event_t *elements_embedded[1024]; -} pqueue_t; - -typedef struct _cairo_bo_event_queue { - cairo_freepool_t pool; - pqueue_t pqueue; - cairo_bo_event_t **start_events; -} cairo_bo_event_queue_t; - -typedef struct _cairo_bo_sweep_line { - cairo_bo_edge_t *head; - int32_t current_y; - cairo_bo_edge_t *current_edge; -} cairo_bo_sweep_line_t; - -static cairo_fixed_t -_line_compute_intersection_x_for_y (const cairo_line_t *line, - cairo_fixed_t y) -{ - cairo_fixed_t x, dy; - - if (y == line->p1.y) - return line->p1.x; - if (y == line->p2.y) - return line->p2.x; - - x = line->p1.x; - dy = line->p2.y - line->p1.y; - if (dy != 0) { - x += _cairo_fixed_mul_div_floor (y - line->p1.y, - line->p2.x - line->p1.x, - dy); - } - - return x; -} - -static inline int -_cairo_bo_point32_compare (cairo_bo_point32_t const *a, - cairo_bo_point32_t const *b) -{ - int cmp; - - cmp = a->y - b->y; - if (cmp) - return cmp; - - return a->x - b->x; -} - -/* Compare the slope of a to the slope of b, returning 1, 0, -1 if the - * slope a is respectively greater than, equal to, or less than the - * slope of b. - * - * For each edge, consider the direction vector formed from: - * - * top -> bottom - * - * which is: - * - * (dx, dy) = (line.p2.x - line.p1.x, line.p2.y - line.p1.y) - * - * We then define the slope of each edge as dx/dy, (which is the - * inverse of the slope typically used in math instruction). We never - * compute a slope directly as the value approaches infinity, but we - * can derive a slope comparison without division as follows, (where - * the ? represents our compare operator). - * - * 1. slope(a) ? slope(b) - * 2. adx/ady ? bdx/bdy - * 3. (adx * bdy) ? (bdx * ady) - * - * Note that from step 2 to step 3 there is no change needed in the - * sign of the result since both ady and bdy are guaranteed to be - * greater than or equal to 0. - * - * When using this slope comparison to sort edges, some care is needed - * when interpreting the results. Since the slope compare operates on - * distance vectors from top to bottom it gives a correct left to - * right sort for edges that have a common top point, (such as two - * edges with start events at the same location). On the other hand, - * the sense of the result will be exactly reversed for two edges that - * have a common stop point. - */ -static inline int -_slope_compare (const cairo_bo_edge_t *a, - const cairo_bo_edge_t *b) -{ - /* XXX: We're assuming here that dx and dy will still fit in 32 - * bits. That's not true in general as there could be overflow. We - * should prevent that before the tessellation algorithm - * begins. - */ - int32_t adx = a->edge.line.p2.x - a->edge.line.p1.x; - int32_t bdx = b->edge.line.p2.x - b->edge.line.p1.x; - - /* Since the dy's are all positive by construction we can fast - * path several common cases. - */ - - /* First check for vertical lines. */ - if (adx == 0) - return -bdx; - if (bdx == 0) - return adx; - - /* Then where the two edges point in different directions wrt x. */ - if ((adx ^ bdx) < 0) - return adx; - - /* Finally we actually need to do the general comparison. */ - { - int32_t ady = a->edge.line.p2.y - a->edge.line.p1.y; - int32_t bdy = b->edge.line.p2.y - b->edge.line.p1.y; - cairo_int64_t adx_bdy = _cairo_int32x32_64_mul (adx, bdy); - cairo_int64_t bdx_ady = _cairo_int32x32_64_mul (bdx, ady); - - return _cairo_int64_cmp (adx_bdy, bdx_ady); - } -} - -/* - * We need to compare the x-coordinates of a pair of lines for a particular y, - * without loss of precision. - * - * The x-coordinate along an edge for a given y is: - * X = A_x + (Y - A_y) * A_dx / A_dy - * - * So the inequality we wish to test is: - * A_x + (Y - A_y) * A_dx / A_dy ∘ B_x + (Y - B_y) * B_dx / B_dy, - * where ∘ is our inequality operator. - * - * By construction, we know that A_dy and B_dy (and (Y - A_y), (Y - B_y)) are - * all positive, so we can rearrange it thus without causing a sign change: - * A_dy * B_dy * (A_x - B_x) ∘ (Y - B_y) * B_dx * A_dy - * - (Y - A_y) * A_dx * B_dy - * - * Given the assumption that all the deltas fit within 32 bits, we can compute - * this comparison directly using 128 bit arithmetic. For certain, but common, - * input we can reduce this down to a single 32 bit compare by inspecting the - * deltas. - * - * (And put the burden of the work on developing fast 128 bit ops, which are - * required throughout the tessellator.) - * - * See the similar discussion for _slope_compare(). - */ -static int -edges_compare_x_for_y_general (const cairo_bo_edge_t *a, - const cairo_bo_edge_t *b, - int32_t y) -{ - /* XXX: We're assuming here that dx and dy will still fit in 32 - * bits. That's not true in general as there could be overflow. We - * should prevent that before the tessellation algorithm - * begins. - */ - int32_t dx; - int32_t adx, ady; - int32_t bdx, bdy; - enum { - HAVE_NONE = 0x0, - HAVE_DX = 0x1, - HAVE_ADX = 0x2, - HAVE_DX_ADX = HAVE_DX | HAVE_ADX, - HAVE_BDX = 0x4, - HAVE_DX_BDX = HAVE_DX | HAVE_BDX, - HAVE_ADX_BDX = HAVE_ADX | HAVE_BDX, - HAVE_ALL = HAVE_DX | HAVE_ADX | HAVE_BDX - } have_dx_adx_bdx = HAVE_ALL; - - /* don't bother solving for abscissa if the edges' bounding boxes - * can be used to order them. */ - { - int32_t amin, amax; - int32_t bmin, bmax; - if (a->edge.line.p1.x < a->edge.line.p2.x) { - amin = a->edge.line.p1.x; - amax = a->edge.line.p2.x; - } else { - amin = a->edge.line.p2.x; - amax = a->edge.line.p1.x; - } - if (b->edge.line.p1.x < b->edge.line.p2.x) { - bmin = b->edge.line.p1.x; - bmax = b->edge.line.p2.x; - } else { - bmin = b->edge.line.p2.x; - bmax = b->edge.line.p1.x; - } - if (amax < bmin) return -1; - if (amin > bmax) return +1; - } - - ady = a->edge.line.p2.y - a->edge.line.p1.y; - adx = a->edge.line.p2.x - a->edge.line.p1.x; - if (adx == 0) - have_dx_adx_bdx &= ~HAVE_ADX; - - bdy = b->edge.line.p2.y - b->edge.line.p1.y; - bdx = b->edge.line.p2.x - b->edge.line.p1.x; - if (bdx == 0) - have_dx_adx_bdx &= ~HAVE_BDX; - - dx = a->edge.line.p1.x - b->edge.line.p1.x; - if (dx == 0) - have_dx_adx_bdx &= ~HAVE_DX; - -#define L _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (ady, bdy), dx) -#define A _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (adx, bdy), y - a->edge.line.p1.y) -#define B _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (bdx, ady), y - b->edge.line.p1.y) - switch (have_dx_adx_bdx) { - default: - case HAVE_NONE: - return 0; - case HAVE_DX: - /* A_dy * B_dy * (A_x - B_x) ∘ 0 */ - return dx; /* ady * bdy is positive definite */ - case HAVE_ADX: - /* 0 ∘ - (Y - A_y) * A_dx * B_dy */ - return adx; /* bdy * (y - a->top.y) is positive definite */ - case HAVE_BDX: - /* 0 ∘ (Y - B_y) * B_dx * A_dy */ - return -bdx; /* ady * (y - b->top.y) is positive definite */ - case HAVE_ADX_BDX: - /* 0 ∘ (Y - B_y) * B_dx * A_dy - (Y - A_y) * A_dx * B_dy */ - if ((adx ^ bdx) < 0) { - return adx; - } else if (a->edge.line.p1.y == b->edge.line.p1.y) { /* common origin */ - cairo_int64_t adx_bdy, bdx_ady; - - /* ∴ A_dx * B_dy ∘ B_dx * A_dy */ - - adx_bdy = _cairo_int32x32_64_mul (adx, bdy); - bdx_ady = _cairo_int32x32_64_mul (bdx, ady); - - return _cairo_int64_cmp (adx_bdy, bdx_ady); - } else - return _cairo_int128_cmp (A, B); - case HAVE_DX_ADX: - /* A_dy * (A_x - B_x) ∘ - (Y - A_y) * A_dx */ - if ((-adx ^ dx) < 0) { - return dx; - } else { - cairo_int64_t ady_dx, dy_adx; - - ady_dx = _cairo_int32x32_64_mul (ady, dx); - dy_adx = _cairo_int32x32_64_mul (a->edge.line.p1.y - y, adx); - - return _cairo_int64_cmp (ady_dx, dy_adx); - } - case HAVE_DX_BDX: - /* B_dy * (A_x - B_x) ∘ (Y - B_y) * B_dx */ - if ((bdx ^ dx) < 0) { - return dx; - } else { - cairo_int64_t bdy_dx, dy_bdx; - - bdy_dx = _cairo_int32x32_64_mul (bdy, dx); - dy_bdx = _cairo_int32x32_64_mul (y - b->edge.line.p1.y, bdx); - - return _cairo_int64_cmp (bdy_dx, dy_bdx); - } - case HAVE_ALL: - /* XXX try comparing (a->edge.line.p2.x - b->edge.line.p2.x) et al */ - return _cairo_int128_cmp (L, _cairo_int128_sub (B, A)); - } -#undef B -#undef A -#undef L -} - -/* - * We need to compare the x-coordinate of a line for a particular y wrt to a - * given x, without loss of precision. - * - * The x-coordinate along an edge for a given y is: - * X = A_x + (Y - A_y) * A_dx / A_dy - * - * So the inequality we wish to test is: - * A_x + (Y - A_y) * A_dx / A_dy ∘ X - * where ∘ is our inequality operator. - * - * By construction, we know that A_dy (and (Y - A_y)) are - * all positive, so we can rearrange it thus without causing a sign change: - * (Y - A_y) * A_dx ∘ (X - A_x) * A_dy - * - * Given the assumption that all the deltas fit within 32 bits, we can compute - * this comparison directly using 64 bit arithmetic. - * - * See the similar discussion for _slope_compare() and - * edges_compare_x_for_y_general(). - */ -static int -edge_compare_for_y_against_x (const cairo_bo_edge_t *a, - int32_t y, - int32_t x) -{ - int32_t adx, ady; - int32_t dx, dy; - cairo_int64_t L, R; - - if (x < a->edge.line.p1.x && x < a->edge.line.p2.x) - return 1; - if (x > a->edge.line.p1.x && x > a->edge.line.p2.x) - return -1; - - adx = a->edge.line.p2.x - a->edge.line.p1.x; - dx = x - a->edge.line.p1.x; - - if (adx == 0) - return -dx; - if (dx == 0 || (adx ^ dx) < 0) - return adx; - - dy = y - a->edge.line.p1.y; - ady = a->edge.line.p2.y - a->edge.line.p1.y; - - L = _cairo_int32x32_64_mul (dy, adx); - R = _cairo_int32x32_64_mul (dx, ady); - - return _cairo_int64_cmp (L, R); -} - -static int -edges_compare_x_for_y (const cairo_bo_edge_t *a, - const cairo_bo_edge_t *b, - int32_t y) -{ - /* If the sweep-line is currently on an end-point of a line, - * then we know its precise x value (and considering that we often need to - * compare events at end-points, this happens frequently enough to warrant - * special casing). - */ - enum { - HAVE_NEITHER = 0x0, - HAVE_AX = 0x1, - HAVE_BX = 0x2, - HAVE_BOTH = HAVE_AX | HAVE_BX - } have_ax_bx = HAVE_BOTH; - int32_t ax, bx; - - if (y == a->edge.line.p1.y) - ax = a->edge.line.p1.x; - else if (y == a->edge.line.p2.y) - ax = a->edge.line.p2.x; - else - have_ax_bx &= ~HAVE_AX; - - if (y == b->edge.line.p1.y) - bx = b->edge.line.p1.x; - else if (y == b->edge.line.p2.y) - bx = b->edge.line.p2.x; - else - have_ax_bx &= ~HAVE_BX; - - switch (have_ax_bx) { - default: - case HAVE_NEITHER: - return edges_compare_x_for_y_general (a, b, y); - case HAVE_AX: - return -edge_compare_for_y_against_x (b, y, ax); - case HAVE_BX: - return edge_compare_for_y_against_x (a, y, bx); - case HAVE_BOTH: - return ax - bx; - } -} - -static inline int -_line_equal (const cairo_line_t *a, const cairo_line_t *b) -{ - return (a->p1.x == b->p1.x && a->p1.y == b->p1.y && - a->p2.x == b->p2.x && a->p2.y == b->p2.y); -} - -static int -_cairo_bo_sweep_line_compare_edges (cairo_bo_sweep_line_t *sweep_line, - const cairo_bo_edge_t *a, - const cairo_bo_edge_t *b) -{ - int cmp; - - /* compare the edges if not identical */ - if (! _line_equal (&a->edge.line, &b->edge.line)) { - cmp = edges_compare_x_for_y (a, b, sweep_line->current_y); - if (cmp) - return cmp; - - /* The two edges intersect exactly at y, so fall back on slope - * comparison. We know that this compare_edges function will be - * called only when starting a new edge, (not when stopping an - * edge), so we don't have to worry about conditionally inverting - * the sense of _slope_compare. */ - cmp = _slope_compare (a, b); - if (cmp) - return cmp; - } - - /* We've got two collinear edges now. */ - return b->edge.bottom - a->edge.bottom; -} - -static inline cairo_int64_t -det32_64 (int32_t a, int32_t b, - int32_t c, int32_t d) -{ - /* det = a * d - b * c */ - return _cairo_int64_sub (_cairo_int32x32_64_mul (a, d), - _cairo_int32x32_64_mul (b, c)); -} - -static inline cairo_int128_t -det64x32_128 (cairo_int64_t a, int32_t b, - cairo_int64_t c, int32_t d) -{ - /* det = a * d - b * c */ - return _cairo_int128_sub (_cairo_int64x32_128_mul (a, d), - _cairo_int64x32_128_mul (c, b)); -} - -/* Compute the intersection of two lines as defined by two edges. The - * result is provided as a coordinate pair of 128-bit integers. - * - * Returns %CAIRO_BO_STATUS_INTERSECTION if there is an intersection or - * %CAIRO_BO_STATUS_PARALLEL if the two lines are exactly parallel. - */ -static cairo_bool_t -intersect_lines (cairo_bo_edge_t *a, - cairo_bo_edge_t *b, - cairo_bo_intersect_point_t *intersection) -{ - cairo_int64_t a_det, b_det; - - /* XXX: We're assuming here that dx and dy will still fit in 32 - * bits. That's not true in general as there could be overflow. We - * should prevent that before the tessellation algorithm begins. - * What we're doing to mitigate this is to perform clamping in - * cairo_bo_tessellate_polygon(). - */ - int32_t dx1 = a->edge.line.p1.x - a->edge.line.p2.x; - int32_t dy1 = a->edge.line.p1.y - a->edge.line.p2.y; - - int32_t dx2 = b->edge.line.p1.x - b->edge.line.p2.x; - int32_t dy2 = b->edge.line.p1.y - b->edge.line.p2.y; - - cairo_int64_t den_det; - cairo_int64_t R; - cairo_quorem64_t qr; - - den_det = det32_64 (dx1, dy1, dx2, dy2); - - /* Q: Can we determine that the lines do not intersect (within range) - * much more cheaply than computing the intersection point i.e. by - * avoiding the division? - * - * X = ax + t * adx = bx + s * bdx; - * Y = ay + t * ady = by + s * bdy; - * ∴ t * (ady*bdx - bdy*adx) = bdx * (by - ay) + bdy * (ax - bx) - * => t * L = R - * - * Therefore we can reject any intersection (under the criteria for - * valid intersection events) if: - * L^R < 0 => t < 0, or - * L<R => t > 1 - * - * (where top/bottom must at least extend to the line endpoints). - * - * A similar substitution can be performed for s, yielding: - * s * (ady*bdx - bdy*adx) = ady * (ax - bx) - adx * (ay - by) - */ - R = det32_64 (dx2, dy2, - b->edge.line.p1.x - a->edge.line.p1.x, - b->edge.line.p1.y - a->edge.line.p1.y); - if (_cairo_int64_negative (den_det)) { - if (_cairo_int64_ge (den_det, R)) - return FALSE; - } else { - if (_cairo_int64_le (den_det, R)) - return FALSE; - } - - R = det32_64 (dy1, dx1, - a->edge.line.p1.y - b->edge.line.p1.y, - a->edge.line.p1.x - b->edge.line.p1.x); - if (_cairo_int64_negative (den_det)) { - if (_cairo_int64_ge (den_det, R)) - return FALSE; - } else { - if (_cairo_int64_le (den_det, R)) - return FALSE; - } - - /* We now know that the two lines should intersect within range. */ - - a_det = det32_64 (a->edge.line.p1.x, a->edge.line.p1.y, - a->edge.line.p2.x, a->edge.line.p2.y); - b_det = det32_64 (b->edge.line.p1.x, b->edge.line.p1.y, - b->edge.line.p2.x, b->edge.line.p2.y); - - /* x = det (a_det, dx1, b_det, dx2) / den_det */ - qr = _cairo_int_96by64_32x64_divrem (det64x32_128 (a_det, dx1, - b_det, dx2), - den_det); - if (_cairo_int64_eq (qr.rem, den_det)) - return FALSE; -#if 0 - intersection->x.exactness = _cairo_int64_is_zero (qr.rem) ? EXACT : INEXACT; -#else - intersection->x.exactness = EXACT; - if (! _cairo_int64_is_zero (qr.rem)) { - if (_cairo_int64_negative (den_det) ^ _cairo_int64_negative (qr.rem)) - qr.rem = _cairo_int64_negate (qr.rem); - qr.rem = _cairo_int64_mul (qr.rem, _cairo_int32_to_int64 (2)); - if (_cairo_int64_ge (qr.rem, den_det)) { - qr.quo = _cairo_int64_add (qr.quo, - _cairo_int32_to_int64 (_cairo_int64_negative (qr.quo) ? -1 : 1)); - } else - intersection->x.exactness = INEXACT; - } -#endif - intersection->x.ordinate = _cairo_int64_to_int32 (qr.quo); - - /* y = det (a_det, dy1, b_det, dy2) / den_det */ - qr = _cairo_int_96by64_32x64_divrem (det64x32_128 (a_det, dy1, - b_det, dy2), - den_det); - if (_cairo_int64_eq (qr.rem, den_det)) - return FALSE; -#if 0 - intersection->y.exactness = _cairo_int64_is_zero (qr.rem) ? EXACT : INEXACT; -#else - intersection->y.exactness = EXACT; - if (! _cairo_int64_is_zero (qr.rem)) { - if (_cairo_int64_negative (den_det) ^ _cairo_int64_negative (qr.rem)) - qr.rem = _cairo_int64_negate (qr.rem); - qr.rem = _cairo_int64_mul (qr.rem, _cairo_int32_to_int64 (2)); - if (_cairo_int64_ge (qr.rem, den_det)) { - qr.quo = _cairo_int64_add (qr.quo, - _cairo_int32_to_int64 (_cairo_int64_negative (qr.quo) ? -1 : 1)); - } else - intersection->y.exactness = INEXACT; - } -#endif - intersection->y.ordinate = _cairo_int64_to_int32 (qr.quo); - - return TRUE; -} - -static int -_cairo_bo_intersect_ordinate_32_compare (cairo_bo_intersect_ordinate_t a, - int32_t b) -{ - /* First compare the quotient */ - if (a.ordinate > b) - return +1; - if (a.ordinate < b) - return -1; - /* With quotient identical, if remainder is 0 then compare equal */ - /* Otherwise, the non-zero remainder makes a > b */ - return INEXACT == a.exactness; -} - -/* Does the given edge contain the given point. The point must already - * be known to be contained within the line determined by the edge, - * (most likely the point results from an intersection of this edge - * with another). - * - * If we had exact arithmetic, then this function would simply be a - * matter of examining whether the y value of the point lies within - * the range of y values of the edge. But since intersection points - * are not exact due to being rounded to the nearest integer within - * the available precision, we must also examine the x value of the - * point. - * - * The definition of "contains" here is that the given intersection - * point will be seen by the sweep line after the start event for the - * given edge and before the stop event for the edge. See the comments - * in the implementation for more details. - */ -static cairo_bool_t -_cairo_bo_edge_contains_intersect_point (cairo_bo_edge_t *edge, - cairo_bo_intersect_point_t *point) -{ - int cmp_top, cmp_bottom; - - /* XXX: When running the actual algorithm, we don't actually need to - * compare against edge->top at all here, since any intersection above - * top is eliminated early via a slope comparison. We're leaving these - * here for now only for the sake of the quadratic-time intersection - * finder which needs them. - */ - - cmp_top = _cairo_bo_intersect_ordinate_32_compare (point->y, - edge->edge.top); - cmp_bottom = _cairo_bo_intersect_ordinate_32_compare (point->y, - edge->edge.bottom); - - if (cmp_top < 0 || cmp_bottom > 0) - { - return FALSE; - } - - if (cmp_top > 0 && cmp_bottom < 0) - { - return TRUE; - } - - /* At this stage, the point lies on the same y value as either - * edge->top or edge->bottom, so we have to examine the x value in - * order to properly determine containment. */ - - /* If the y value of the point is the same as the y value of the - * top of the edge, then the x value of the point must be greater - * to be considered as inside the edge. Similarly, if the y value - * of the point is the same as the y value of the bottom of the - * edge, then the x value of the point must be less to be - * considered as inside. */ - - if (cmp_top == 0) { - cairo_fixed_t top_x; - - top_x = _line_compute_intersection_x_for_y (&edge->edge.line, - edge->edge.top); - return _cairo_bo_intersect_ordinate_32_compare (point->x, top_x) > 0; - } else { /* cmp_bottom == 0 */ - cairo_fixed_t bot_x; - - bot_x = _line_compute_intersection_x_for_y (&edge->edge.line, - edge->edge.bottom); - return _cairo_bo_intersect_ordinate_32_compare (point->x, bot_x) < 0; - } -} - -/* Compute the intersection of two edges. The result is provided as a - * coordinate pair of 128-bit integers. - * - * Returns %CAIRO_BO_STATUS_INTERSECTION if there is an intersection - * that is within both edges, %CAIRO_BO_STATUS_NO_INTERSECTION if the - * intersection of the lines defined by the edges occurs outside of - * one or both edges, and %CAIRO_BO_STATUS_PARALLEL if the two edges - * are exactly parallel. - * - * Note that when determining if a candidate intersection is "inside" - * an edge, we consider both the infinitesimal shortening and the - * infinitesimal tilt rules described by John Hobby. Specifically, if - * the intersection is exactly the same as an edge point, it is - * effectively outside (no intersection is returned). Also, if the - * intersection point has the same - */ -static cairo_bool_t -_cairo_bo_edge_intersect (cairo_bo_edge_t *a, - cairo_bo_edge_t *b, - cairo_bo_point32_t *intersection) -{ - cairo_bo_intersect_point_t quorem; - - if (! intersect_lines (a, b, &quorem)) - return FALSE; - - if (! _cairo_bo_edge_contains_intersect_point (a, &quorem)) - return FALSE; - - if (! _cairo_bo_edge_contains_intersect_point (b, &quorem)) - return FALSE; - - /* Now that we've correctly compared the intersection point and - * determined that it lies within the edge, then we know that we - * no longer need any more bits of storage for the intersection - * than we do for our edge coordinates. We also no longer need the - * remainder from the division. */ - intersection->x = quorem.x.ordinate; - intersection->y = quorem.y.ordinate; - - return TRUE; -} - -static inline int -cairo_bo_event_compare (const cairo_bo_event_t *a, - const cairo_bo_event_t *b) -{ - int cmp; - - cmp = _cairo_bo_point32_compare (&a->point, &b->point); - if (cmp) - return cmp; - - cmp = a->type - b->type; - if (cmp) - return cmp; - - return a - b; -} - -static inline void -_pqueue_init (pqueue_t *pq) -{ - pq->max_size = ARRAY_LENGTH (pq->elements_embedded); - pq->size = 0; - - pq->elements = pq->elements_embedded; -} - -static inline void -_pqueue_fini (pqueue_t *pq) -{ - if (pq->elements != pq->elements_embedded) - free (pq->elements); -} - -static cairo_status_t -_pqueue_grow (pqueue_t *pq) -{ - cairo_bo_event_t **new_elements; - pq->max_size *= 2; - - if (pq->elements == pq->elements_embedded) { - new_elements = _cairo_malloc_ab (pq->max_size, - sizeof (cairo_bo_event_t *)); - if (unlikely (new_elements == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - memcpy (new_elements, pq->elements_embedded, - sizeof (pq->elements_embedded)); - } else { - new_elements = _cairo_realloc_ab (pq->elements, - pq->max_size, - sizeof (cairo_bo_event_t *)); - if (unlikely (new_elements == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - pq->elements = new_elements; - return CAIRO_STATUS_SUCCESS; -} - -static inline cairo_status_t -_pqueue_push (pqueue_t *pq, cairo_bo_event_t *event) -{ - cairo_bo_event_t **elements; - int i, parent; - - if (unlikely (pq->size + 1 == pq->max_size)) { - cairo_status_t status; - - status = _pqueue_grow (pq); - if (unlikely (status)) - return status; - } - - elements = pq->elements; - - for (i = ++pq->size; - i != PQ_FIRST_ENTRY && - cairo_bo_event_compare (event, - elements[parent = PQ_PARENT_INDEX (i)]) < 0; - i = parent) - { - elements[i] = elements[parent]; - } - - elements[i] = event; - - return CAIRO_STATUS_SUCCESS; -} - -static inline void -_pqueue_pop (pqueue_t *pq) -{ - cairo_bo_event_t **elements = pq->elements; - cairo_bo_event_t *tail; - int child, i; - - tail = elements[pq->size--]; - if (pq->size == 0) { - elements[PQ_FIRST_ENTRY] = NULL; - return; - } - - for (i = PQ_FIRST_ENTRY; - (child = PQ_LEFT_CHILD_INDEX (i)) <= pq->size; - i = child) - { - if (child != pq->size && - cairo_bo_event_compare (elements[child+1], - elements[child]) < 0) - { - child++; - } - - if (cairo_bo_event_compare (elements[child], tail) >= 0) - break; - - elements[i] = elements[child]; - } - elements[i] = tail; -} - -static inline cairo_status_t -_cairo_bo_event_queue_insert (cairo_bo_event_queue_t *queue, - cairo_bo_event_type_t type, - cairo_bo_edge_t *e1, - cairo_bo_edge_t *e2, - const cairo_point_t *point) -{ - cairo_bo_queue_event_t *event; - - event = _cairo_freepool_alloc (&queue->pool); - if (unlikely (event == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - event->type = type; - event->e1 = e1; - event->e2 = e2; - event->point = *point; - - return _pqueue_push (&queue->pqueue, (cairo_bo_event_t *) event); -} - -static void -_cairo_bo_event_queue_delete (cairo_bo_event_queue_t *queue, - cairo_bo_event_t *event) -{ - _cairo_freepool_free (&queue->pool, event); -} - -static cairo_bo_event_t * -_cairo_bo_event_dequeue (cairo_bo_event_queue_t *event_queue) -{ - cairo_bo_event_t *event, *cmp; - - event = event_queue->pqueue.elements[PQ_FIRST_ENTRY]; - cmp = *event_queue->start_events; - if (event == NULL || - (cmp != NULL && cairo_bo_event_compare (cmp, event) < 0)) - { - event = cmp; - event_queue->start_events++; - } - else - { - _pqueue_pop (&event_queue->pqueue); - } - - return event; -} - -CAIRO_COMBSORT_DECLARE (_cairo_bo_event_queue_sort, - cairo_bo_event_t *, - cairo_bo_event_compare) - -static void -_cairo_bo_event_queue_init (cairo_bo_event_queue_t *event_queue, - cairo_bo_event_t **start_events, - int num_events) -{ - _cairo_bo_event_queue_sort (start_events, num_events); - start_events[num_events] = NULL; - - event_queue->start_events = start_events; - - _cairo_freepool_init (&event_queue->pool, - sizeof (cairo_bo_queue_event_t)); - _pqueue_init (&event_queue->pqueue); - event_queue->pqueue.elements[PQ_FIRST_ENTRY] = NULL; -} - -static cairo_status_t -_cairo_bo_event_queue_insert_stop (cairo_bo_event_queue_t *event_queue, - cairo_bo_edge_t *edge) -{ - cairo_bo_point32_t point; - - point.y = edge->edge.bottom; - point.x = _line_compute_intersection_x_for_y (&edge->edge.line, - point.y); - return _cairo_bo_event_queue_insert (event_queue, - CAIRO_BO_EVENT_TYPE_STOP, - edge, NULL, - &point); -} - -static void -_cairo_bo_event_queue_fini (cairo_bo_event_queue_t *event_queue) -{ - _pqueue_fini (&event_queue->pqueue); - _cairo_freepool_fini (&event_queue->pool); -} - -static inline cairo_status_t -_cairo_bo_event_queue_insert_if_intersect_below_current_y (cairo_bo_event_queue_t *event_queue, - cairo_bo_edge_t *left, - cairo_bo_edge_t *right) -{ - cairo_bo_point32_t intersection; - - if (_line_equal (&left->edge.line, &right->edge.line)) - return CAIRO_STATUS_SUCCESS; - - /* The names "left" and "right" here are correct descriptions of - * the order of the two edges within the active edge list. So if a - * slope comparison also puts left less than right, then we know - * that the intersection of these two segments has already - * occurred before the current sweep line position. */ - if (_slope_compare (left, right) <= 0) - return CAIRO_STATUS_SUCCESS; - - if (! _cairo_bo_edge_intersect (left, right, &intersection)) - return CAIRO_STATUS_SUCCESS; - - return _cairo_bo_event_queue_insert (event_queue, - CAIRO_BO_EVENT_TYPE_INTERSECTION, - left, right, - &intersection); -} - -static void -_cairo_bo_sweep_line_init (cairo_bo_sweep_line_t *sweep_line) -{ - sweep_line->head = NULL; - sweep_line->current_y = INT32_MIN; - sweep_line->current_edge = NULL; -} - -static cairo_status_t -_cairo_bo_sweep_line_insert (cairo_bo_sweep_line_t *sweep_line, - cairo_bo_edge_t *edge) -{ - if (sweep_line->current_edge != NULL) { - cairo_bo_edge_t *prev, *next; - int cmp; - - cmp = _cairo_bo_sweep_line_compare_edges (sweep_line, - sweep_line->current_edge, - edge); - if (cmp < 0) { - prev = sweep_line->current_edge; - next = prev->next; - while (next != NULL && - _cairo_bo_sweep_line_compare_edges (sweep_line, - next, edge) < 0) - { - prev = next, next = prev->next; - } - - prev->next = edge; - edge->prev = prev; - edge->next = next; - if (next != NULL) - next->prev = edge; - } else if (cmp > 0) { - next = sweep_line->current_edge; - prev = next->prev; - while (prev != NULL && - _cairo_bo_sweep_line_compare_edges (sweep_line, - prev, edge) > 0) - { - next = prev, prev = next->prev; - } - - next->prev = edge; - edge->next = next; - edge->prev = prev; - if (prev != NULL) - prev->next = edge; - else - sweep_line->head = edge; - } else { - prev = sweep_line->current_edge; - edge->prev = prev; - edge->next = prev->next; - if (prev->next != NULL) - prev->next->prev = edge; - prev->next = edge; - } - } else { - sweep_line->head = edge; - } - - sweep_line->current_edge = edge; - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_bo_sweep_line_delete (cairo_bo_sweep_line_t *sweep_line, - cairo_bo_edge_t *edge) -{ - if (edge->prev != NULL) - edge->prev->next = edge->next; - else - sweep_line->head = edge->next; - - if (edge->next != NULL) - edge->next->prev = edge->prev; - - if (sweep_line->current_edge == edge) - sweep_line->current_edge = edge->prev ? edge->prev : edge->next; -} - -static void -_cairo_bo_sweep_line_swap (cairo_bo_sweep_line_t *sweep_line, - cairo_bo_edge_t *left, - cairo_bo_edge_t *right) -{ - if (left->prev != NULL) - left->prev->next = right; - else - sweep_line->head = right; - - if (right->next != NULL) - right->next->prev = left; - - left->next = right->next; - right->next = left; - - right->prev = left->prev; - left->prev = right; -} - -static inline cairo_bool_t -edges_colinear (const cairo_bo_edge_t *a, const cairo_bo_edge_t *b) -{ - if (_line_equal (&a->edge.line, &b->edge.line)) - return TRUE; - - if (_slope_compare (a, b)) - return FALSE; - - /* The choice of y is not truly arbitrary since we must guarantee that it - * is greater than the start of either line. - */ - if (a->edge.line.p1.y == b->edge.line.p1.y) { - return a->edge.line.p1.x == b->edge.line.p1.x; - } else if (a->edge.line.p2.y == b->edge.line.p2.y) { - return a->edge.line.p2.x == b->edge.line.p2.x; - } else if (a->edge.line.p1.y < b->edge.line.p1.y) { - return edge_compare_for_y_against_x (b, - a->edge.line.p1.y, - a->edge.line.p1.x) == 0; - } else { - return edge_compare_for_y_against_x (a, - b->edge.line.p1.y, - b->edge.line.p1.x) == 0; - } -} - -static void -_cairo_bo_edge_end (cairo_bo_edge_t *left, - int32_t bot, - cairo_polygon_t *polygon) -{ - cairo_bo_deferred_t *d = &left->deferred; - - if (likely (d->top < bot)) { - _cairo_polygon_add_line (polygon, - &left->edge.line, - d->top, bot, - 1); - _cairo_polygon_add_line (polygon, - &d->right->edge.line, - d->top, bot, - -1); - } - - d->right = NULL; -} - - -static inline void -_cairo_bo_edge_start_or_continue (cairo_bo_edge_t *left, - cairo_bo_edge_t *right, - int top, - cairo_polygon_t *polygon) -{ - if (left->deferred.right == right) - return; - - if (left->deferred.right != NULL) { - if (right != NULL && edges_colinear (left->deferred.right, right)) - { - /* continuation on right, so just swap edges */ - left->deferred.right = right; - return; - } - - _cairo_bo_edge_end (left, top, polygon); - } - - if (right != NULL && ! edges_colinear (left, right)) { - left->deferred.top = top; - left->deferred.right = right; - } -} - -static inline void -_active_edges_to_polygon (cairo_bo_edge_t *left, - int32_t top, - cairo_fill_rule_t fill_rule, - cairo_polygon_t *polygon) -{ - cairo_bo_edge_t *right; - unsigned int mask; - - if (fill_rule == CAIRO_FILL_RULE_WINDING) - mask = ~0; - else - mask = 1; - - while (left != NULL) { - int in_out = left->edge.dir; - - right = left->next; - if (left->deferred.right == NULL) { - while (right != NULL && right->deferred.right == NULL) - right = right->next; - - if (right != NULL && edges_colinear (left, right)) { - /* continuation on left */ - left->deferred = right->deferred; - right->deferred.right = NULL; - } - } - - right = left->next; - while (right != NULL) { - if (right->deferred.right != NULL) - _cairo_bo_edge_end (right, top, polygon); - - in_out += right->edge.dir; - if ((in_out & mask) == 0) { - /* skip co-linear edges */ - if (right->next == NULL || !edges_colinear (right, right->next)) - break; - } - - right = right->next; - } - - _cairo_bo_edge_start_or_continue (left, right, top, polygon); - - left = right; - if (left != NULL) - left = left->next; - } -} - - -static cairo_status_t -_cairo_bentley_ottmann_tessellate_bo_edges (cairo_bo_event_t **start_events, - int num_events, - cairo_fill_rule_t fill_rule, - cairo_polygon_t *polygon) -{ - cairo_status_t status = CAIRO_STATUS_SUCCESS; /* silence compiler */ - cairo_bo_event_queue_t event_queue; - cairo_bo_sweep_line_t sweep_line; - cairo_bo_event_t *event; - cairo_bo_edge_t *left, *right; - cairo_bo_edge_t *e1, *e2; - - _cairo_bo_event_queue_init (&event_queue, start_events, num_events); - _cairo_bo_sweep_line_init (&sweep_line); - - while ((event = _cairo_bo_event_dequeue (&event_queue))) { - if (event->point.y != sweep_line.current_y) { - _active_edges_to_polygon (sweep_line.head, - sweep_line.current_y, - fill_rule, polygon); - - sweep_line.current_y = event->point.y; - } - - switch (event->type) { - case CAIRO_BO_EVENT_TYPE_START: - e1 = &((cairo_bo_start_event_t *) event)->edge; - - status = _cairo_bo_sweep_line_insert (&sweep_line, e1); - if (unlikely (status)) - goto unwind; - - status = _cairo_bo_event_queue_insert_stop (&event_queue, e1); - if (unlikely (status)) - goto unwind; - - left = e1->prev; - right = e1->next; - - if (left != NULL) { - status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, e1); - if (unlikely (status)) - goto unwind; - } - - if (right != NULL) { - status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, e1, right); - if (unlikely (status)) - goto unwind; - } - - break; - - case CAIRO_BO_EVENT_TYPE_STOP: - e1 = ((cairo_bo_queue_event_t *) event)->e1; - _cairo_bo_event_queue_delete (&event_queue, event); - - left = e1->prev; - right = e1->next; - - _cairo_bo_sweep_line_delete (&sweep_line, e1); - - if (e1->deferred.right != NULL) - _cairo_bo_edge_end (e1, e1->edge.bottom, polygon); - - if (left != NULL && right != NULL) { - status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, right); - if (unlikely (status)) - goto unwind; - } - - break; - - case CAIRO_BO_EVENT_TYPE_INTERSECTION: - e1 = ((cairo_bo_queue_event_t *) event)->e1; - e2 = ((cairo_bo_queue_event_t *) event)->e2; - _cairo_bo_event_queue_delete (&event_queue, event); - - /* skip this intersection if its edges are not adjacent */ - if (e2 != e1->next) - break; - - left = e1->prev; - right = e2->next; - - _cairo_bo_sweep_line_swap (&sweep_line, e1, e2); - - /* after the swap e2 is left of e1 */ - - if (left != NULL) { - status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, e2); - if (unlikely (status)) - goto unwind; - } - - if (right != NULL) { - status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, e1, right); - if (unlikely (status)) - goto unwind; - } - - break; - } - } - - unwind: - _cairo_bo_event_queue_fini (&event_queue); - - return status; -} - -cairo_status_t -_cairo_polygon_reduce (cairo_polygon_t *polygon, - cairo_fill_rule_t fill_rule) -{ - cairo_status_t status; - cairo_bo_start_event_t stack_events[CAIRO_STACK_ARRAY_LENGTH (cairo_bo_start_event_t)]; - cairo_bo_start_event_t *events; - cairo_bo_event_t *stack_event_ptrs[ARRAY_LENGTH (stack_events) + 1]; - cairo_bo_event_t **event_ptrs; - int num_limits; - int num_events; - int i; - - num_events = polygon->num_edges; - if (unlikely (0 == num_events)) - return CAIRO_STATUS_SUCCESS; - - if (DEBUG_POLYGON) { - FILE *file = fopen ("reduce_in.txt", "w"); - _cairo_debug_print_polygon (file, polygon); - fclose (file); - } - - events = stack_events; - event_ptrs = stack_event_ptrs; - if (num_events > ARRAY_LENGTH (stack_events)) { - events = _cairo_malloc_ab_plus_c (num_events, - sizeof (cairo_bo_start_event_t) + - sizeof (cairo_bo_event_t *), - sizeof (cairo_bo_event_t *)); - if (unlikely (events == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - event_ptrs = (cairo_bo_event_t **) (events + num_events); - } - - for (i = 0; i < num_events; i++) { - event_ptrs[i] = (cairo_bo_event_t *) &events[i]; - - events[i].type = CAIRO_BO_EVENT_TYPE_START; - events[i].point.y = polygon->edges[i].top; - events[i].point.x = - _line_compute_intersection_x_for_y (&polygon->edges[i].line, - events[i].point.y); - - events[i].edge.edge = polygon->edges[i]; - events[i].edge.deferred.right = NULL; - events[i].edge.prev = NULL; - events[i].edge.next = NULL; - } - - num_limits = polygon->num_limits; polygon->num_limits = 0; - polygon->num_edges = 0; - - status = _cairo_bentley_ottmann_tessellate_bo_edges (event_ptrs, - num_events, - fill_rule, - polygon); - polygon->num_limits = num_limits; - - if (events != stack_events) - free (events); - - if (DEBUG_POLYGON) { - FILE *file = fopen ("reduce_out.txt", "w"); - _cairo_debug_print_polygon (file, polygon); - fclose (file); - } - - return status; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-polygon.c b/source/libs/cairo/cairo-src/src/cairo-polygon.c deleted file mode 100644 index b0424f6e72efb5be57dbbb1d8a65b349c18ec51d..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-polygon.c +++ /dev/null @@ -1,608 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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" - -#include "cairo-boxes-private.h" -#include "cairo-contour-private.h" -#include "cairo-error-private.h" - -#define DEBUG_POLYGON 0 - -#if DEBUG_POLYGON && !NDEBUG -static void -assert_last_edge_is_valid(cairo_polygon_t *polygon, - const cairo_box_t *limit) -{ - cairo_edge_t *edge; - cairo_fixed_t x; - - edge = &polygon->edges[polygon->num_edges-1]; - - assert (edge->bottom > edge->top); - assert (edge->top >= limit->p1.y); - assert (edge->bottom <= limit->p2.y); - - x = _cairo_edge_compute_intersection_x_for_y (&edge->line.p1, - &edge->line.p2, - edge->top); - assert (x >= limit->p1.x); - assert (x <= limit->p2.x); - - x = _cairo_edge_compute_intersection_x_for_y (&edge->line.p1, - &edge->line.p2, - edge->bottom); - assert (x >= limit->p1.x); - assert (x <= limit->p2.x); -} -#else -#define assert_last_edge_is_valid(p, l) -#endif - -static void -_cairo_polygon_add_edge (cairo_polygon_t *polygon, - const cairo_point_t *p1, - const cairo_point_t *p2, - int dir); - -void -_cairo_polygon_limit (cairo_polygon_t *polygon, - const cairo_box_t *limits, - int num_limits) -{ - int n; - - polygon->limits = limits; - polygon->num_limits = num_limits; - - if (polygon->num_limits) { - polygon->limit = limits[0]; - for (n = 1; n < num_limits; n++) { - if (limits[n].p1.x < polygon->limit.p1.x) - polygon->limit.p1.x = limits[n].p1.x; - - if (limits[n].p1.y < polygon->limit.p1.y) - polygon->limit.p1.y = limits[n].p1.y; - - if (limits[n].p2.x > polygon->limit.p2.x) - polygon->limit.p2.x = limits[n].p2.x; - - if (limits[n].p2.y > polygon->limit.p2.y) - polygon->limit.p2.y = limits[n].p2.y; - } - } -} - -void -_cairo_polygon_limit_to_clip (cairo_polygon_t *polygon, - const cairo_clip_t *clip) -{ - if (clip) - _cairo_polygon_limit (polygon, clip->boxes, clip->num_boxes); - else - _cairo_polygon_limit (polygon, 0, 0); -} - -void -_cairo_polygon_init (cairo_polygon_t *polygon, - const cairo_box_t *limits, - int num_limits) -{ - VG (VALGRIND_MAKE_MEM_UNDEFINED (polygon, sizeof (cairo_polygon_t))); - - polygon->status = CAIRO_STATUS_SUCCESS; - - polygon->num_edges = 0; - - polygon->edges = polygon->edges_embedded; - polygon->edges_size = ARRAY_LENGTH (polygon->edges_embedded); - - polygon->extents.p1.x = polygon->extents.p1.y = INT32_MAX; - polygon->extents.p2.x = polygon->extents.p2.y = INT32_MIN; - - _cairo_polygon_limit (polygon, limits, num_limits); -} - -void -_cairo_polygon_init_with_clip (cairo_polygon_t *polygon, - const cairo_clip_t *clip) -{ - if (clip) - _cairo_polygon_init (polygon, clip->boxes, clip->num_boxes); - else - _cairo_polygon_init (polygon, 0, 0); -} - -cairo_status_t -_cairo_polygon_init_boxes (cairo_polygon_t *polygon, - const cairo_boxes_t *boxes) -{ - const struct _cairo_boxes_chunk *chunk; - int i; - - VG (VALGRIND_MAKE_MEM_UNDEFINED (polygon, sizeof (cairo_polygon_t))); - - polygon->status = CAIRO_STATUS_SUCCESS; - - polygon->num_edges = 0; - - polygon->edges = polygon->edges_embedded; - polygon->edges_size = ARRAY_LENGTH (polygon->edges_embedded); - if (boxes->num_boxes > ARRAY_LENGTH (polygon->edges_embedded)/2) { - polygon->edges_size = 2 * boxes->num_boxes; - polygon->edges = _cairo_malloc_ab (polygon->edges_size, - 2*sizeof(cairo_edge_t)); - if (unlikely (polygon->edges == NULL)) - return polygon->status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - polygon->extents.p1.x = polygon->extents.p1.y = INT32_MAX; - polygon->extents.p2.x = polygon->extents.p2.y = INT32_MIN; - - polygon->limits = NULL; - polygon->num_limits = 0; - - for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) { - cairo_point_t p1, p2; - - p1 = chunk->base[i].p1; - p2.x = p1.x; - p2.y = chunk->base[i].p2.y; - _cairo_polygon_add_edge (polygon, &p1, &p2, 1); - - p1 = chunk->base[i].p2; - p2.x = p1.x; - p2.y = chunk->base[i].p1.y; - _cairo_polygon_add_edge (polygon, &p1, &p2, 1); - } - } - - return polygon->status; -} - -cairo_status_t -_cairo_polygon_init_box_array (cairo_polygon_t *polygon, - cairo_box_t *boxes, - int num_boxes) -{ - int i; - - VG (VALGRIND_MAKE_MEM_UNDEFINED (polygon, sizeof (cairo_polygon_t))); - - polygon->status = CAIRO_STATUS_SUCCESS; - - polygon->num_edges = 0; - - polygon->edges = polygon->edges_embedded; - polygon->edges_size = ARRAY_LENGTH (polygon->edges_embedded); - if (num_boxes > ARRAY_LENGTH (polygon->edges_embedded)/2) { - polygon->edges_size = 2 * num_boxes; - polygon->edges = _cairo_malloc_ab (polygon->edges_size, - 2*sizeof(cairo_edge_t)); - if (unlikely (polygon->edges == NULL)) - return polygon->status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - polygon->extents.p1.x = polygon->extents.p1.y = INT32_MAX; - polygon->extents.p2.x = polygon->extents.p2.y = INT32_MIN; - - polygon->limits = NULL; - polygon->num_limits = 0; - - for (i = 0; i < num_boxes; i++) { - cairo_point_t p1, p2; - - p1 = boxes[i].p1; - p2.x = p1.x; - p2.y = boxes[i].p2.y; - _cairo_polygon_add_edge (polygon, &p1, &p2, 1); - - p1 = boxes[i].p2; - p2.x = p1.x; - p2.y = boxes[i].p1.y; - _cairo_polygon_add_edge (polygon, &p1, &p2, 1); - } - - return polygon->status; -} - - -void -_cairo_polygon_fini (cairo_polygon_t *polygon) -{ - if (polygon->edges != polygon->edges_embedded) - free (polygon->edges); - - VG (VALGRIND_MAKE_MEM_NOACCESS (polygon, sizeof (cairo_polygon_t))); -} - -/* make room for at least one more edge */ -static cairo_bool_t -_cairo_polygon_grow (cairo_polygon_t *polygon) -{ - cairo_edge_t *new_edges; - int old_size = polygon->edges_size; - int new_size = 4 * old_size; - - if (CAIRO_INJECT_FAULT ()) { - polygon->status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - return FALSE; - } - - if (polygon->edges == polygon->edges_embedded) { - new_edges = _cairo_malloc_ab (new_size, sizeof (cairo_edge_t)); - if (new_edges != NULL) - memcpy (new_edges, polygon->edges, old_size * sizeof (cairo_edge_t)); - } else { - new_edges = _cairo_realloc_ab (polygon->edges, - new_size, sizeof (cairo_edge_t)); - } - - if (unlikely (new_edges == NULL)) { - polygon->status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - return FALSE; - } - - polygon->edges = new_edges; - polygon->edges_size = new_size; - - return TRUE; -} - -static void -_add_edge (cairo_polygon_t *polygon, - const cairo_point_t *p1, - const cairo_point_t *p2, - int top, int bottom, - int dir) -{ - cairo_edge_t *edge; - - assert (top < bottom); - - if (unlikely (polygon->num_edges == polygon->edges_size)) { - if (! _cairo_polygon_grow (polygon)) - return; - } - - edge = &polygon->edges[polygon->num_edges++]; - edge->line.p1 = *p1; - edge->line.p2 = *p2; - edge->top = top; - edge->bottom = bottom; - edge->dir = dir; - - if (top < polygon->extents.p1.y) - polygon->extents.p1.y = top; - if (bottom > polygon->extents.p2.y) - polygon->extents.p2.y = bottom; - - if (p1->x < polygon->extents.p1.x || p1->x > polygon->extents.p2.x) { - cairo_fixed_t x = p1->x; - if (top != p1->y) - x = _cairo_edge_compute_intersection_x_for_y (p1, p2, top); - if (x < polygon->extents.p1.x) - polygon->extents.p1.x = x; - if (x > polygon->extents.p2.x) - polygon->extents.p2.x = x; - } - - if (p2->x < polygon->extents.p1.x || p2->x > polygon->extents.p2.x) { - cairo_fixed_t x = p2->x; - if (bottom != p2->y) - x = _cairo_edge_compute_intersection_x_for_y (p1, p2, bottom); - if (x < polygon->extents.p1.x) - polygon->extents.p1.x = x; - if (x > polygon->extents.p2.x) - polygon->extents.p2.x = x; - } -} - -static void -_add_clipped_edge (cairo_polygon_t *polygon, - const cairo_point_t *p1, - const cairo_point_t *p2, - const int top, const int bottom, - const int dir) -{ - cairo_point_t bot_left, top_right; - cairo_fixed_t top_y, bot_y; - int n; - - for (n = 0; n < polygon->num_limits; n++) { - const cairo_box_t *limits = &polygon->limits[n]; - cairo_fixed_t pleft, pright; - - if (top >= limits->p2.y) - continue; - if (bottom <= limits->p1.y) - continue; - - bot_left.x = limits->p1.x; - bot_left.y = limits->p2.y; - - top_right.x = limits->p2.x; - top_right.y = limits->p1.y; - - /* The useful region */ - top_y = MAX (top, limits->p1.y); - bot_y = MIN (bottom, limits->p2.y); - - /* The projection of the edge on the horizontal axis */ - pleft = MIN (p1->x, p2->x); - pright = MAX (p1->x, p2->x); - - if (limits->p1.x <= pleft && pright <= limits->p2.x) { - /* Projection of the edge completely contained in the box: - * clip vertically by restricting top and bottom */ - - _add_edge (polygon, p1, p2, top_y, bot_y, dir); - assert_last_edge_is_valid (polygon, limits); - } else if (pright <= limits->p1.x) { - /* Projection of the edge to the left of the box: - * replace with the left side of the box (clipped top/bottom) */ - - _add_edge (polygon, &limits->p1, &bot_left, top_y, bot_y, dir); - assert_last_edge_is_valid (polygon, limits); - } else if (limits->p2.x <= pleft) { - /* Projection of the edge to the right of the box: - * replace with the right side of the box (clipped top/bottom) */ - - _add_edge (polygon, &top_right, &limits->p2, top_y, bot_y, dir); - assert_last_edge_is_valid (polygon, limits); - } else { - /* The edge and the box intersect in a generic way */ - cairo_fixed_t left_y, right_y; - cairo_bool_t top_left_to_bottom_right; - - /* - * The edge intersects the lines corresponding to the left - * and right sides of the limit box at left_y and right_y, - * but we need to add edges for the range from top_y to - * bot_y. - * - * For both intersections, there are three cases: - * - * 1) It is outside the vertical range of the limit - * box. In this case we can simply further clip the - * edge we will be emitting (i.e. restrict its - * top/bottom limits to those of the limit box). - * - * 2) It is inside the vertical range of the limit - * box. In this case, we need to add the vertical edge - * connecting the correct vertex to the intersection, - * in order to preserve the winding count. - * - * 3) It is exactly on the box. In this case, do nothing. - * - * These operations restrict the active range (stored in - * top_y/bot_y) so that the p1-p2 edge is completely - * inside the box if it is clipped to this vertical range. - */ - - top_left_to_bottom_right = (p1->x <= p2->x) == (p1->y <= p2->y); - if (top_left_to_bottom_right) { - if (pleft >= limits->p1.x) { - left_y = top_y; - } else { - left_y = _cairo_edge_compute_intersection_y_for_x (p1, p2, - limits->p1.x); - if (_cairo_edge_compute_intersection_x_for_y (p1, p2, left_y) < limits->p1.x) - left_y++; - } - - left_y = MIN (left_y, bot_y); - if (top_y < left_y) { - _add_edge (polygon, &limits->p1, &bot_left, - top_y, left_y, dir); - assert_last_edge_is_valid (polygon, limits); - top_y = left_y; - } - - if (pright <= limits->p2.x) { - right_y = bot_y; - } else { - right_y = _cairo_edge_compute_intersection_y_for_x (p1, p2, - limits->p2.x); - if (_cairo_edge_compute_intersection_x_for_y (p1, p2, right_y) > limits->p2.x) - right_y--; - } - - right_y = MAX (right_y, top_y); - if (bot_y > right_y) { - _add_edge (polygon, &top_right, &limits->p2, - right_y, bot_y, dir); - assert_last_edge_is_valid (polygon, limits); - bot_y = right_y; - } - } else { - if (pright <= limits->p2.x) { - right_y = top_y; - } else { - right_y = _cairo_edge_compute_intersection_y_for_x (p1, p2, - limits->p2.x); - if (_cairo_edge_compute_intersection_x_for_y (p1, p2, right_y) > limits->p2.x) - right_y++; - } - - right_y = MIN (right_y, bot_y); - if (top_y < right_y) { - _add_edge (polygon, &top_right, &limits->p2, - top_y, right_y, dir); - assert_last_edge_is_valid (polygon, limits); - top_y = right_y; - } - - if (pleft >= limits->p1.x) { - left_y = bot_y; - } else { - left_y = _cairo_edge_compute_intersection_y_for_x (p1, p2, - limits->p1.x); - if (_cairo_edge_compute_intersection_x_for_y (p1, p2, left_y) < limits->p1.x) - left_y--; - } - - left_y = MAX (left_y, top_y); - if (bot_y > left_y) { - _add_edge (polygon, &limits->p1, &bot_left, - left_y, bot_y, dir); - assert_last_edge_is_valid (polygon, limits); - bot_y = left_y; - } - } - - if (top_y != bot_y) { - _add_edge (polygon, p1, p2, top_y, bot_y, dir); - assert_last_edge_is_valid (polygon, limits); - } - } - } -} - -static void -_cairo_polygon_add_edge (cairo_polygon_t *polygon, - const cairo_point_t *p1, - const cairo_point_t *p2, - int dir) -{ - /* drop horizontal edges */ - if (p1->y == p2->y) - return; - - if (p1->y > p2->y) { - const cairo_point_t *t; - t = p1, p1 = p2, p2 = t; - dir = -dir; - } - - if (polygon->num_limits) { - if (p2->y <= polygon->limit.p1.y) - return; - - if (p1->y >= polygon->limit.p2.y) - return; - - _add_clipped_edge (polygon, p1, p2, p1->y, p2->y, dir); - } else - _add_edge (polygon, p1, p2, p1->y, p2->y, dir); -} - -cairo_status_t -_cairo_polygon_add_external_edge (void *polygon, - const cairo_point_t *p1, - const cairo_point_t *p2) -{ - _cairo_polygon_add_edge (polygon, p1, p2, 1); - return _cairo_polygon_status (polygon); -} - -cairo_status_t -_cairo_polygon_add_line (cairo_polygon_t *polygon, - const cairo_line_t *line, - int top, int bottom, - int dir) -{ - /* drop horizontal edges */ - if (line->p1.y == line->p2.y) - return CAIRO_STATUS_SUCCESS; - - if (bottom <= top) - return CAIRO_STATUS_SUCCESS; - - if (polygon->num_limits) { - if (line->p2.y <= polygon->limit.p1.y) - return CAIRO_STATUS_SUCCESS; - - if (line->p1.y >= polygon->limit.p2.y) - return CAIRO_STATUS_SUCCESS; - - _add_clipped_edge (polygon, &line->p1, &line->p2, top, bottom, dir); - } else - _add_edge (polygon, &line->p1, &line->p2, top, bottom, dir); - - return polygon->status; -} - -cairo_status_t -_cairo_polygon_add_contour (cairo_polygon_t *polygon, - const cairo_contour_t *contour) -{ - const struct _cairo_contour_chain *chain; - const cairo_point_t *prev = NULL; - int i; - - if (contour->chain.num_points <= 1) - return CAIRO_INT_STATUS_SUCCESS; - - prev = &contour->chain.points[0]; - for (chain = &contour->chain; chain; chain = chain->next) { - for (i = 0; i < chain->num_points; i++) { - _cairo_polygon_add_edge (polygon, prev, &chain->points[i], - contour->direction); - prev = &chain->points[i]; - } - } - - return polygon->status; -} - -void -_cairo_polygon_translate (cairo_polygon_t *polygon, int dx, int dy) -{ - int n; - - dx = _cairo_fixed_from_int (dx); - dy = _cairo_fixed_from_int (dy); - - polygon->extents.p1.x += dx; - polygon->extents.p2.x += dx; - polygon->extents.p1.y += dy; - polygon->extents.p2.y += dy; - - for (n = 0; n < polygon->num_edges; n++) { - cairo_edge_t *e = &polygon->edges[n]; - - e->top += dy; - e->bottom += dy; - - e->line.p1.x += dx; - e->line.p2.x += dx; - e->line.p1.y += dy; - e->line.p2.y += dy; - } -} diff --git a/source/libs/cairo/cairo-src/src/cairo-private.h b/source/libs/cairo/cairo-src/src/cairo-private.h deleted file mode 100644 index 9f4f55b7cea60260889172145e9bc6efa39cc1eb..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-private.h +++ /dev/null @@ -1,64 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Carl D. Worth <cworth@redhat.com> - */ - -#ifndef CAIRO_PRIVATE_H -#define CAIRO_PRIVATE_H - -#include "cairo-types-private.h" -#include "cairo-reference-count-private.h" - -CAIRO_BEGIN_DECLS - -struct _cairo { - cairo_reference_count_t ref_count; - cairo_status_t status; - cairo_user_data_array_t user_data; - - const cairo_backend_t *backend; -}; - -cairo_private cairo_t * -_cairo_create_in_error (cairo_status_t status); - -cairo_private void -_cairo_init (cairo_t *cr, - const cairo_backend_t *backend); - -cairo_private void -_cairo_fini (cairo_t *cr); - -CAIRO_END_DECLS - -#endif /* CAIRO_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-ps-surface-private.h b/source/libs/cairo/cairo-src/src/cairo-ps-surface-private.h deleted file mode 100644 index 1d5d27d4910a486de75e005895de2a1b30da6e19..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-ps-surface-private.h +++ /dev/null @@ -1,104 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2003 University of Southern California - * Copyright © 2005 Red Hat, Inc - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Kristian Høgsberg <krh@redhat.com> - * Keith Packard <keithp@keithp.com> - */ - -#ifndef CAIRO_PS_SURFACE_PRIVATE_H -#define CAIRO_PS_SURFACE_PRIVATE_H - -#include "cairo-ps.h" - -#include "cairo-surface-private.h" -#include "cairo-surface-clipper-private.h" -#include "cairo-pdf-operators-private.h" - -#include <time.h> - -typedef struct cairo_ps_surface { - cairo_surface_t base; - - /* Here final_stream corresponds to the stream/file passed to - * cairo_ps_surface_create surface is built. Meanwhile stream is a - * temporary stream in which the file output is built, (so that - * the header can be built and inserted into the target stream - * before the contents of the temporary stream are copied). */ - cairo_output_stream_t *final_stream; - - FILE *tmpfile; - cairo_output_stream_t *stream; - - cairo_bool_t eps; - cairo_content_t content; - double width; - double height; - cairo_rectangle_int_t page_bbox; - int bbox_x1, bbox_y1, bbox_x2, bbox_y2; - cairo_matrix_t cairo_to_ps; - - cairo_bool_t use_string_datasource; - - cairo_bool_t current_pattern_is_solid_color; - cairo_color_t current_color; - - int num_pages; - - cairo_paginated_mode_t paginated_mode; - - cairo_bool_t force_fallbacks; - cairo_bool_t has_creation_date; - time_t creation_date; - - cairo_scaled_font_subsets_t *font_subsets; - - cairo_list_t document_media; - cairo_array_t dsc_header_comments; - cairo_array_t dsc_setup_comments; - cairo_array_t dsc_page_setup_comments; - - cairo_array_t *dsc_comment_target; - - cairo_ps_level_t ps_level; - cairo_ps_level_t ps_level_used; - - cairo_surface_clipper_t clipper; - - cairo_pdf_operators_t pdf_operators; - cairo_surface_t *paginated_surface; -} cairo_ps_surface_t; - -#endif /* CAIRO_PS_SURFACE_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-ps-surface.c b/source/libs/cairo/cairo-src/src/cairo-ps-surface.c deleted file mode 100644 index 03eba62db5dd0f228aac5c39704db6f9f528a6e5..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-ps-surface.c +++ /dev/null @@ -1,4694 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2003 University of Southern California - * Copyright © 2005 Red Hat, Inc - * Copyright © 2007,2008 Adrian Johnson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Kristian Høgsberg <krh@redhat.com> - * Keith Packard <keithp@keithp.com> - * Adrian Johnson <ajohnson@redneon.com> - */ - - -/* - * Design of the PS output: - * - * The PS output is harmonised with the PDF operations using PS procedures - * to emulate the PDF operators. - * - * This has a number of advantages: - * 1. A large chunk of code is shared between the PDF and PS backends. - * See cairo-pdf-operators. - * 2. Using gs to do PS -> PDF and PDF -> PS will always work well. - */ - -#define _BSD_SOURCE /* for ctime_r(), snprintf(), strdup() */ -#include "cairoint.h" - -#include "cairo-ps.h" -#include "cairo-ps-surface-private.h" - -#include "cairo-pdf-operators-private.h" -#include "cairo-pdf-shading-private.h" - -#include "cairo-array-private.h" -#include "cairo-composite-rectangles-private.h" -#include "cairo-default-context-private.h" -#include "cairo-error-private.h" -#include "cairo-image-surface-inline.h" -#include "cairo-list-inline.h" -#include "cairo-scaled-font-subsets-private.h" -#include "cairo-paginated-private.h" -#include "cairo-recording-surface-private.h" -#include "cairo-surface-clipper-private.h" -#include "cairo-surface-snapshot-inline.h" -#include "cairo-surface-subsurface-private.h" -#include "cairo-output-stream-private.h" -#include "cairo-type3-glyph-surface-private.h" -#include "cairo-image-info-private.h" - -#include <stdio.h> -#include <ctype.h> -#include <time.h> -#include <zlib.h> -#include <errno.h> - -#define DEBUG_PS 0 - -#if DEBUG_PS -#define DEBUG_FALLBACK(s) \ - fprintf (stderr, "%s::%d -- %s\n", __FUNCTION__, __LINE__, (s)) -#else -#define DEBUG_FALLBACK(s) -#endif - -#ifndef HAVE_CTIME_R -#define ctime_r(T, BUF) ctime (T) -#endif - -/** - * SECTION:cairo-ps - * @Title: PostScript Surfaces - * @Short_Description: Rendering PostScript documents - * @See_Also: #cairo_surface_t - * - * The PostScript surface is used to render cairo graphics to Adobe - * PostScript files and is a multi-page vector surface backend. - **/ - -/** - * CAIRO_HAS_PS_SURFACE: - * - * Defined if the PostScript surface backend is available. - * This macro can be used to conditionally compile backend-specific code. - * - * Since: 1.2 - **/ - -typedef enum { - CAIRO_PS_COMPRESS_NONE, - CAIRO_PS_COMPRESS_LZW, - CAIRO_PS_COMPRESS_DEFLATE - } cairo_ps_compress_t; - -static const cairo_surface_backend_t cairo_ps_surface_backend; -static const cairo_paginated_surface_backend_t cairo_ps_surface_paginated_backend; - -static cairo_bool_t -_cairo_ps_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *rectangle); - -static const cairo_ps_level_t _cairo_ps_levels[] = -{ - CAIRO_PS_LEVEL_2, - CAIRO_PS_LEVEL_3 -}; - -#define CAIRO_PS_LEVEL_LAST ARRAY_LENGTH (_cairo_ps_levels) - -static const char * _cairo_ps_level_strings[CAIRO_PS_LEVEL_LAST] = -{ - "PS Level 2", - "PS Level 3" -}; - -static const char *_cairo_ps_supported_mime_types[] = -{ - CAIRO_MIME_TYPE_JPEG, - NULL -}; - -typedef struct _cairo_page_standard_media { - const char *name; - int width; - int height; -} cairo_page_standard_media_t; - -static const cairo_page_standard_media_t _cairo_page_standard_media[] = -{ - { "A0", 2384, 3371 }, - { "A1", 1685, 2384 }, - { "A2", 1190, 1684 }, - { "A3", 842, 1190 }, - { "A4", 595, 842 }, - { "A5", 420, 595 }, - { "B4", 729, 1032 }, - { "B5", 516, 729 }, - { "Letter", 612, 792 }, - { "Tabloid", 792, 1224 }, - { "Ledger", 1224, 792 }, - { "Legal", 612, 1008 }, - { "Statement", 396, 612 }, - { "Executive", 540, 720 }, - { "Folio", 612, 936 }, - { "Quarto", 610, 780 }, - { "10x14", 720, 1008 }, -}; - -typedef struct _cairo_page_media { - char *name; - int width; - int height; - cairo_list_t link; -} cairo_page_media_t; - -static void -_cairo_ps_surface_emit_header (cairo_ps_surface_t *surface) -{ - char ctime_buf[26]; - time_t now; - char **comments; - int i, num_comments; - int level; - const char *eps_header = ""; - cairo_bool_t has_bbox; - - if (surface->has_creation_date) - now = surface->creation_date; - else - now = time (NULL); - - if (surface->ps_level_used == CAIRO_PS_LEVEL_2) - level = 2; - else - level = 3; - - if (surface->eps) - eps_header = " EPSF-3.0"; - - _cairo_output_stream_printf (surface->final_stream, - "%%!PS-Adobe-3.0%s\n" - "%%%%Creator: cairo %s (http://cairographics.org)\n" - "%%%%CreationDate: %s" - "%%%%Pages: %d\n", - eps_header, - cairo_version_string (), - ctime_r (&now, ctime_buf), - surface->num_pages); - - _cairo_output_stream_printf (surface->final_stream, - "%%%%DocumentData: Clean7Bit\n" - "%%%%LanguageLevel: %d\n", - level); - - if (!cairo_list_is_empty (&surface->document_media)) { - cairo_page_media_t *page; - cairo_bool_t first = TRUE; - - cairo_list_foreach_entry (page, cairo_page_media_t, &surface->document_media, link) { - if (first) { - _cairo_output_stream_printf (surface->final_stream, - "%%%%DocumentMedia: "); - first = FALSE; - } else { - _cairo_output_stream_printf (surface->final_stream, - "%%%%+ "); - } - _cairo_output_stream_printf (surface->final_stream, - "%s %d %d 0 () ()\n", - page->name, - page->width, - page->height); - } - } - - has_bbox = FALSE; - num_comments = _cairo_array_num_elements (&surface->dsc_header_comments); - comments = _cairo_array_index (&surface->dsc_header_comments, 0); - for (i = 0; i < num_comments; i++) { - _cairo_output_stream_printf (surface->final_stream, - "%s\n", comments[i]); - if (strncmp (comments[i], "%%BoundingBox:", 14) == 0) - has_bbox = TRUE; - - free (comments[i]); - comments[i] = NULL; - } - - if (!has_bbox) { - _cairo_output_stream_printf (surface->final_stream, - "%%%%BoundingBox: %d %d %d %d\n", - surface->bbox_x1, - surface->bbox_y1, - surface->bbox_x2, - surface->bbox_y2); - } - - _cairo_output_stream_printf (surface->final_stream, - "%%%%EndComments\n"); - - _cairo_output_stream_printf (surface->final_stream, - "%%%%BeginProlog\n"); - - if (surface->eps) { - _cairo_output_stream_printf (surface->final_stream, - "save\n" - "50 dict begin\n"); - } else { - _cairo_output_stream_printf (surface->final_stream, - "/languagelevel where\n" - "{ pop languagelevel } { 1 } ifelse\n" - "%d lt { /Helvetica findfont 12 scalefont setfont 50 500 moveto\n" - " (This print job requires a PostScript Language Level %d printer.) show\n" - " showpage quit } if\n", - level, - level); - } - - _cairo_output_stream_printf (surface->final_stream, - "/q { gsave } bind def\n" - "/Q { grestore } bind def\n" - "/cm { 6 array astore concat } bind def\n" - "/w { setlinewidth } bind def\n" - "/J { setlinecap } bind def\n" - "/j { setlinejoin } bind def\n" - "/M { setmiterlimit } bind def\n" - "/d { setdash } bind def\n" - "/m { moveto } bind def\n" - "/l { lineto } bind def\n" - "/c { curveto } bind def\n" - "/h { closepath } bind def\n" - "/re { exch dup neg 3 1 roll 5 3 roll moveto 0 rlineto\n" - " 0 exch rlineto 0 rlineto closepath } bind def\n" - "/S { stroke } bind def\n" - "/f { fill } bind def\n" - "/f* { eofill } bind def\n" - "/n { newpath } bind def\n" - "/W { clip } bind def\n" - "/W* { eoclip } bind def\n" - "/BT { } bind def\n" - "/ET { } bind def\n" - "/pdfmark where { pop globaldict /?pdfmark /exec load put }\n" - " { globaldict begin /?pdfmark /pop load def /pdfmark\n" - " /cleartomark load def end } ifelse\n" - "/BDC { mark 3 1 roll /BDC pdfmark } bind def\n" - "/EMC { mark /EMC pdfmark } bind def\n" - "/cairo_store_point { /cairo_point_y exch def /cairo_point_x exch def } def\n" - "/Tj { show currentpoint cairo_store_point } bind def\n" - "/TJ {\n" - " {\n" - " dup\n" - " type /stringtype eq\n" - " { show } { -0.001 mul 0 cairo_font_matrix dtransform rmoveto } ifelse\n" - " } forall\n" - " currentpoint cairo_store_point\n" - "} bind def\n" - "/cairo_selectfont { cairo_font_matrix aload pop pop pop 0 0 6 array astore\n" - " cairo_font exch selectfont cairo_point_x cairo_point_y moveto } bind def\n" - "/Tf { pop /cairo_font exch def /cairo_font_matrix where\n" - " { pop cairo_selectfont } if } bind def\n" - "/Td { matrix translate cairo_font_matrix matrix concatmatrix dup\n" - " /cairo_font_matrix exch def dup 4 get exch 5 get cairo_store_point\n" - " /cairo_font where { pop cairo_selectfont } if } bind def\n" - "/Tm { 2 copy 8 2 roll 6 array astore /cairo_font_matrix exch def\n" - " cairo_store_point /cairo_font where { pop cairo_selectfont } if } bind def\n" - "/g { setgray } bind def\n" - "/rg { setrgbcolor } bind def\n" - "/d1 { setcachedevice } bind def\n"); - - if (!surface->eps) { - _cairo_output_stream_printf (surface->final_stream, - "/cairo_set_page_size {\n" - " %% Change paper size, but only if different from previous paper size otherwise\n" - " %% duplex fails. PLRM specifies a tolerance of 5 pts when matching paper size\n" - " %% so we use the same when checking if the size changes.\n" - " /setpagedevice where {\n" - " pop currentpagedevice\n" - " /PageSize known {\n" - " 2 copy\n" - " currentpagedevice /PageSize get aload pop\n" - " exch 4 1 roll\n" - " sub abs 5 gt\n" - " 3 1 roll\n" - " sub abs 5 gt\n" - " or\n" - " } {\n" - " true\n" - " } ifelse\n" - " {\n" - " 2 array astore\n" - " 2 dict begin\n" - " /PageSize exch def\n" - " /ImagingBBox null def\n" - " currentdict end\n" - " setpagedevice\n" - " } {\n" - " pop pop\n" - " } ifelse\n" - " } {\n" - " pop\n" - " } ifelse\n" - "} def\n"); - } - - _cairo_output_stream_printf (surface->final_stream, - "%%%%EndProlog\n"); - _cairo_output_stream_printf (surface->final_stream, - "%%%%BeginSetup\n"); - - num_comments = _cairo_array_num_elements (&surface->dsc_setup_comments); - if (num_comments) { - comments = _cairo_array_index (&surface->dsc_setup_comments, 0); - for (i = 0; i < num_comments; i++) { - _cairo_output_stream_printf (surface->final_stream, - "%s\n", comments[i]); - free (comments[i]); - comments[i] = NULL; - } - } -} - -static cairo_status_t -_cairo_ps_surface_emit_type1_font_subset (cairo_ps_surface_t *surface, - cairo_scaled_font_subset_t *font_subset) - - -{ - cairo_type1_subset_t subset; - cairo_status_t status; - int length; - char name[64]; - - snprintf (name, sizeof name, "f-%d-%d", - font_subset->font_id, font_subset->subset_id); - status = _cairo_type1_subset_init (&subset, name, font_subset, TRUE); - if (unlikely (status)) - return status; - - /* FIXME: Figure out document structure convention for fonts */ - -#if DEBUG_PS - _cairo_output_stream_printf (surface->final_stream, - "%% _cairo_ps_surface_emit_type1_font_subset\n"); -#endif - - _cairo_output_stream_printf (surface->final_stream, - "%%%%BeginResource: font %s\n", - subset.base_font); - length = subset.header_length + subset.data_length + subset.trailer_length; - _cairo_output_stream_write (surface->final_stream, subset.data, length); - _cairo_output_stream_printf (surface->final_stream, - "%%%%EndResource\n"); - - _cairo_type1_subset_fini (&subset); - - return CAIRO_STATUS_SUCCESS; -} - - -static cairo_status_t -_cairo_ps_surface_emit_type1_font_fallback (cairo_ps_surface_t *surface, - cairo_scaled_font_subset_t *font_subset) -{ - cairo_type1_subset_t subset; - cairo_status_t status; - int length; - char name[64]; - - snprintf (name, sizeof name, "f-%d-%d", - font_subset->font_id, font_subset->subset_id); - status = _cairo_type1_fallback_init_hex (&subset, name, font_subset); - if (unlikely (status)) - return status; - -#if DEBUG_PS - _cairo_output_stream_printf (surface->final_stream, - "%% _cairo_ps_surface_emit_type1_font_fallback\n"); -#endif - - _cairo_output_stream_printf (surface->final_stream, - "%%%%BeginResource: font %s\n", - subset.base_font); - length = subset.header_length + subset.data_length + subset.trailer_length; - _cairo_output_stream_write (surface->final_stream, subset.data, length); - _cairo_output_stream_printf (surface->final_stream, - "%%%%EndResource\n"); - - _cairo_type1_fallback_fini (&subset); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_ps_surface_emit_truetype_font_subset (cairo_ps_surface_t *surface, - cairo_scaled_font_subset_t *font_subset) - - -{ - cairo_truetype_subset_t subset; - cairo_status_t status; - unsigned int i, begin, end; - - status = _cairo_truetype_subset_init_ps (&subset, font_subset); - if (unlikely (status)) - return status; - - /* FIXME: Figure out document structure convention for fonts */ - -#if DEBUG_PS - _cairo_output_stream_printf (surface->final_stream, - "%% _cairo_ps_surface_emit_truetype_font_subset\n"); -#endif - - _cairo_output_stream_printf (surface->final_stream, - "%%%%BeginResource: font %s\n", - subset.ps_name); - _cairo_output_stream_printf (surface->final_stream, - "11 dict begin\n" - "/FontType 42 def\n" - "/FontName /%s def\n" - "/PaintType 0 def\n" - "/FontMatrix [ 1 0 0 1 0 0 ] def\n" - "/FontBBox [ 0 0 0 0 ] def\n" - "/Encoding 256 array def\n" - "0 1 255 { Encoding exch /.notdef put } for\n", - subset.ps_name); - - /* FIXME: Figure out how subset->x_max etc maps to the /FontBBox */ - - if (font_subset->is_latin) { - for (i = 1; i < 256; i++) { - if (font_subset->latin_to_subset_glyph_index[i] > 0) { - if (font_subset->glyph_names != NULL) { - _cairo_output_stream_printf (surface->final_stream, - "Encoding %d /%s put\n", - i, font_subset->glyph_names[font_subset->latin_to_subset_glyph_index[i]]); - } else { - _cairo_output_stream_printf (surface->final_stream, - "Encoding %d /g%ld put\n", i, font_subset->latin_to_subset_glyph_index[i]); - } - } - } - } else { - for (i = 1; i < font_subset->num_glyphs; i++) { - if (font_subset->glyph_names != NULL) { - _cairo_output_stream_printf (surface->final_stream, - "Encoding %d /%s put\n", - i, font_subset->glyph_names[i]); - } else { - _cairo_output_stream_printf (surface->final_stream, - "Encoding %d /g%d put\n", i, i); - } - } - } - - _cairo_output_stream_printf (surface->final_stream, - "/CharStrings %d dict dup begin\n" - "/.notdef 0 def\n", - font_subset->num_glyphs); - - for (i = 1; i < font_subset->num_glyphs; i++) { - if (font_subset->glyph_names != NULL) { - _cairo_output_stream_printf (surface->final_stream, - "/%s %d def\n", - font_subset->glyph_names[i], i); - } else { - _cairo_output_stream_printf (surface->final_stream, - "/g%d %d def\n", i, i); - } - } - - _cairo_output_stream_printf (surface->final_stream, - "end readonly def\n"); - - _cairo_output_stream_printf (surface->final_stream, - "/sfnts [\n"); - begin = 0; - end = 0; - for (i = 0; i < subset.num_string_offsets; i++) { - end = subset.string_offsets[i]; - _cairo_output_stream_printf (surface->final_stream,"<"); - _cairo_output_stream_write_hex_string (surface->final_stream, - subset.data + begin, end - begin); - _cairo_output_stream_printf (surface->final_stream,"00>\n"); - begin = end; - } - if (subset.data_length > end) { - _cairo_output_stream_printf (surface->final_stream,"<"); - _cairo_output_stream_write_hex_string (surface->final_stream, - subset.data + end, subset.data_length - end); - _cairo_output_stream_printf (surface->final_stream,"00>\n"); - } - - _cairo_output_stream_printf (surface->final_stream, - "] def\n" - "/f-%d-%d currentdict end definefont pop\n", - font_subset->font_id, - font_subset->subset_id); - _cairo_output_stream_printf (surface->final_stream, - "%%%%EndResource\n"); - _cairo_truetype_subset_fini (&subset); - - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_ps_emit_imagemask (cairo_image_surface_t *image, - cairo_output_stream_t *stream) -{ - uint8_t *row, *byte; - int rows, cols; - - /* The only image type supported by Type 3 fonts are 1-bit image - * masks */ - assert (image->format == CAIRO_FORMAT_A1); - - _cairo_output_stream_printf (stream, - "<<\n" - " /ImageType 1\n" - " /Width %d\n" - " /Height %d\n" - " /ImageMatrix [%d 0 0 %d 0 %d]\n" - " /Decode [1 0]\n" - " /BitsPerComponent 1\n", - image->width, - image->height, - image->width, - -image->height, - image->height); - - _cairo_output_stream_printf (stream, - " /DataSource {<\n "); - for (row = image->data, rows = image->height; rows; row += image->stride, rows--) { - for (byte = row, cols = (image->width + 7) / 8; cols; byte++, cols--) { - uint8_t output_byte = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (*byte); - _cairo_output_stream_printf (stream, "%02x ", output_byte); - } - _cairo_output_stream_printf (stream, "\n "); - } - _cairo_output_stream_printf (stream, ">}\n>>\n"); - - _cairo_output_stream_printf (stream, - "imagemask\n"); - - return _cairo_output_stream_get_status (stream); -} - -static cairo_int_status_t -_cairo_ps_surface_analyze_user_font_subset (cairo_scaled_font_subset_t *font_subset, - void *closure) -{ - cairo_ps_surface_t *surface = closure; - cairo_status_t status = CAIRO_STATUS_SUCCESS; - unsigned int i; - cairo_surface_t *type3_surface; - - type3_surface = _cairo_type3_glyph_surface_create (font_subset->scaled_font, - NULL, - _cairo_ps_emit_imagemask, - surface->font_subsets, - TRUE); - - for (i = 0; i < font_subset->num_glyphs; i++) { - status = _cairo_type3_glyph_surface_analyze_glyph (type3_surface, - font_subset->glyphs[i]); - if (unlikely (status)) - break; - - } - cairo_surface_finish (type3_surface); - cairo_surface_destroy (type3_surface); - - return status; -} - -static cairo_status_t -_cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t *surface, - cairo_scaled_font_subset_t *font_subset) - - -{ - cairo_status_t status; - unsigned int i; - cairo_box_t font_bbox = {{0,0},{0,0}}; - cairo_box_t bbox = {{0,0},{0,0}}; - cairo_surface_t *type3_surface; - double width; - - if (font_subset->num_glyphs == 0) - return CAIRO_STATUS_SUCCESS; - -#if DEBUG_PS - _cairo_output_stream_printf (surface->final_stream, - "%% _cairo_ps_surface_emit_type3_font_subset\n"); -#endif - - _cairo_output_stream_printf (surface->final_stream, - "%%%%BeginResource: font\n"); - _cairo_output_stream_printf (surface->final_stream, - "8 dict begin\n" - "/FontType 3 def\n" - "/FontMatrix [1 0 0 1 0 0] def\n" - "/Encoding 256 array def\n" - "0 1 255 { Encoding exch /.notdef put } for\n"); - - type3_surface = _cairo_type3_glyph_surface_create (font_subset->scaled_font, - NULL, - _cairo_ps_emit_imagemask, - surface->font_subsets, - TRUE); - status = type3_surface->status; - if (unlikely (status)) - return status; - - for (i = 0; i < font_subset->num_glyphs; i++) { - if (font_subset->glyph_names != NULL) { - _cairo_output_stream_printf (surface->final_stream, - "Encoding %d /%s put\n", - i, font_subset->glyph_names[i]); - } else { - _cairo_output_stream_printf (surface->final_stream, - "Encoding %d /g%d put\n", i, i); - } - } - - _cairo_output_stream_printf (surface->final_stream, - "/Glyphs [\n"); - - for (i = 0; i < font_subset->num_glyphs; i++) { - _cairo_output_stream_printf (surface->final_stream, - " { %% %d\n", i); - status = _cairo_type3_glyph_surface_emit_glyph (type3_surface, - surface->final_stream, - font_subset->glyphs[i], - &bbox, - &width); - if (unlikely (status)) - break; - - _cairo_output_stream_printf (surface->final_stream, - " }\n"); - if (i == 0) { - font_bbox.p1.x = bbox.p1.x; - font_bbox.p1.y = bbox.p1.y; - font_bbox.p2.x = bbox.p2.x; - font_bbox.p2.y = bbox.p2.y; - } else { - if (bbox.p1.x < font_bbox.p1.x) - font_bbox.p1.x = bbox.p1.x; - if (bbox.p1.y < font_bbox.p1.y) - font_bbox.p1.y = bbox.p1.y; - if (bbox.p2.x > font_bbox.p2.x) - font_bbox.p2.x = bbox.p2.x; - if (bbox.p2.y > font_bbox.p2.y) - font_bbox.p2.y = bbox.p2.y; - } - } - cairo_surface_finish (type3_surface); - cairo_surface_destroy (type3_surface); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->final_stream, - "] def\n" - "/FontBBox [%f %f %f %f] def\n" - "/BuildChar {\n" - " exch /Glyphs get\n" - " exch get\n" - " 10 dict begin exec end\n" - "} bind def\n" - "currentdict\n" - "end\n" - "/f-%d-%d exch definefont pop\n", - _cairo_fixed_to_double (font_bbox.p1.x), - - _cairo_fixed_to_double (font_bbox.p2.y), - _cairo_fixed_to_double (font_bbox.p2.x), - - _cairo_fixed_to_double (font_bbox.p1.y), - font_subset->font_id, - font_subset->subset_id); - _cairo_output_stream_printf (surface->final_stream, - "%%%%EndResource\n"); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_ps_surface_emit_unscaled_font_subset (cairo_scaled_font_subset_t *font_subset, - void *closure) -{ - cairo_ps_surface_t *surface = closure; - cairo_int_status_t status; - - status = _cairo_scaled_font_subset_create_glyph_names (font_subset); - if (_cairo_int_status_is_error (status)) - return status; - - status = _cairo_ps_surface_emit_type1_font_subset (surface, font_subset); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - - status = _cairo_ps_surface_emit_truetype_font_subset (surface, font_subset); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - - status = _cairo_ps_surface_emit_type1_font_fallback (surface, font_subset); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - - ASSERT_NOT_REACHED; - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_ps_surface_emit_scaled_font_subset (cairo_scaled_font_subset_t *font_subset, - void *closure) -{ - cairo_ps_surface_t *surface = closure; - cairo_int_status_t status; - - status = _cairo_scaled_font_subset_create_glyph_names (font_subset); - if (_cairo_int_status_is_error (status)) - return status; - - status = _cairo_ps_surface_emit_type3_font_subset (surface, font_subset); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - - ASSERT_NOT_REACHED; - return CAIRO_INT_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_ps_surface_emit_font_subsets (cairo_ps_surface_t *surface) -{ - cairo_status_t status; - -#if DEBUG_PS - _cairo_output_stream_printf (surface->final_stream, - "%% _cairo_ps_surface_emit_font_subsets\n"); -#endif - - status = _cairo_scaled_font_subsets_foreach_user (surface->font_subsets, - _cairo_ps_surface_analyze_user_font_subset, - surface); - if (unlikely (status)) - return status; - - status = _cairo_scaled_font_subsets_foreach_unscaled (surface->font_subsets, - _cairo_ps_surface_emit_unscaled_font_subset, - surface); - if (unlikely (status)) - return status; - - status = _cairo_scaled_font_subsets_foreach_scaled (surface->font_subsets, - _cairo_ps_surface_emit_scaled_font_subset, - surface); - if (unlikely (status)) - return status; - - return _cairo_scaled_font_subsets_foreach_user (surface->font_subsets, - _cairo_ps_surface_emit_scaled_font_subset, - surface); -} - -static cairo_status_t -_cairo_ps_surface_emit_body (cairo_ps_surface_t *surface) -{ - char buf[4096]; - int n; - - if (ferror (surface->tmpfile) != 0) - return _cairo_error (CAIRO_STATUS_TEMP_FILE_ERROR); - - rewind (surface->tmpfile); - while ((n = fread (buf, 1, sizeof (buf), surface->tmpfile)) > 0) - _cairo_output_stream_write (surface->final_stream, buf, n); - - if (ferror (surface->tmpfile) != 0) - return _cairo_error (CAIRO_STATUS_TEMP_FILE_ERROR); - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_ps_surface_emit_footer (cairo_ps_surface_t *surface) -{ - _cairo_output_stream_printf (surface->final_stream, - "%%%%Trailer\n"); - - if (surface->eps) { - _cairo_output_stream_printf (surface->final_stream, - "end restore\n"); - } - - _cairo_output_stream_printf (surface->final_stream, - "%%%%EOF\n"); -} - -static cairo_bool_t -_path_covers_bbox (cairo_ps_surface_t *surface, - cairo_path_fixed_t *path) -{ - cairo_box_t box; - - if (_cairo_path_fixed_is_box (path, &box)) { - cairo_rectangle_int_t rect; - - _cairo_box_round_to_rectangle (&box, &rect); - - /* skip trivial whole-page clips */ - if (_cairo_rectangle_intersect (&rect, &surface->page_bbox)) { - if (rect.x == surface->page_bbox.x && - rect.width == surface->page_bbox.width && - rect.y == surface->page_bbox.y && - rect.height == surface->page_bbox.height) - { - return TRUE; - } - } - } - - return FALSE; -} - -static cairo_status_t -_cairo_ps_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper, - cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_ps_surface_t *surface = cairo_container_of (clipper, - cairo_ps_surface_t, - clipper); - cairo_output_stream_t *stream = surface->stream; - cairo_status_t status; - - assert (surface->paginated_mode != CAIRO_PAGINATED_MODE_ANALYZE); - -#if DEBUG_PS - _cairo_output_stream_printf (stream, - "%% _cairo_ps_surface_intersect_clip_path\n"); -#endif - - if (path == NULL) { - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (stream, "Q q\n"); - - surface->current_pattern_is_solid_color = FALSE; - _cairo_pdf_operators_reset (&surface->pdf_operators); - - return CAIRO_STATUS_SUCCESS; - } - - if (_path_covers_bbox (surface, path)) - return CAIRO_STATUS_SUCCESS; - - return _cairo_pdf_operators_clip (&surface->pdf_operators, - path, - fill_rule); -} - -/* PLRM specifies a tolerance of 5 points when matching page sizes */ -static cairo_bool_t -_ps_page_dimension_equal (int a, int b) -{ - return (abs (a - b) < 5); -} - -static const char * -_cairo_ps_surface_get_page_media (cairo_ps_surface_t *surface) -{ - int width, height, i; - char buf[50]; - cairo_page_media_t *page; - const char *page_name; - - width = _cairo_lround (surface->width); - height = _cairo_lround (surface->height); - - /* search previously used page sizes */ - cairo_list_foreach_entry (page, cairo_page_media_t, &surface->document_media, link) { - if (_ps_page_dimension_equal (width, page->width) && - _ps_page_dimension_equal (height, page->height)) - return page->name; - } - - /* search list of standard page sizes */ - page_name = NULL; - for (i = 0; i < ARRAY_LENGTH (_cairo_page_standard_media); i++) { - if (_ps_page_dimension_equal (width, _cairo_page_standard_media[i].width) && - _ps_page_dimension_equal (height, _cairo_page_standard_media[i].height)) - { - page_name = _cairo_page_standard_media[i].name; - width = _cairo_page_standard_media[i].width; - height = _cairo_page_standard_media[i].height; - break; - } - } - - page = malloc (sizeof (cairo_page_media_t)); - if (unlikely (page == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return NULL; - } - - if (page_name) { - page->name = strdup (page_name); - } else { - snprintf (buf, sizeof (buf), "%dx%dmm", - (int) _cairo_lround (surface->width * 25.4/72), - (int) _cairo_lround (surface->height * 25.4/72)); - page->name = strdup (buf); - } - - if (unlikely (page->name == NULL)) { - free (page); - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return NULL; - } - - page->width = width; - page->height = height; - cairo_list_add_tail (&page->link, &surface->document_media); - - return page->name; -} - -static cairo_surface_t * -_cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream, - double width, - double height) -{ - cairo_status_t status, status_ignored; - cairo_ps_surface_t *surface; - - surface = malloc (sizeof (cairo_ps_surface_t)); - if (unlikely (surface == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto CLEANUP; - } - - _cairo_surface_init (&surface->base, - &cairo_ps_surface_backend, - NULL, /* device */ - CAIRO_CONTENT_COLOR_ALPHA); - - surface->final_stream = stream; - - surface->tmpfile = tmpfile (); - if (surface->tmpfile == NULL) { - switch (errno) { - case ENOMEM: - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - break; - default: - status = _cairo_error (CAIRO_STATUS_TEMP_FILE_ERROR); - break; - } - goto CLEANUP_SURFACE; - } - - surface->stream = _cairo_output_stream_create_for_file (surface->tmpfile); - status = _cairo_output_stream_get_status (surface->stream); - if (unlikely (status)) - goto CLEANUP_OUTPUT_STREAM; - - surface->font_subsets = _cairo_scaled_font_subsets_create_simple (); - if (unlikely (surface->font_subsets == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto CLEANUP_OUTPUT_STREAM; - } - - _cairo_scaled_font_subsets_enable_latin_subset (surface->font_subsets, TRUE); - surface->has_creation_date = FALSE; - surface->eps = FALSE; - surface->ps_level = CAIRO_PS_LEVEL_3; - surface->ps_level_used = CAIRO_PS_LEVEL_2; - surface->width = width; - surface->height = height; - cairo_matrix_init (&surface->cairo_to_ps, 1, 0, 0, -1, 0, height); - surface->paginated_mode = CAIRO_PAGINATED_MODE_ANALYZE; - surface->force_fallbacks = FALSE; - surface->content = CAIRO_CONTENT_COLOR_ALPHA; - surface->use_string_datasource = FALSE; - surface->current_pattern_is_solid_color = FALSE; - - surface->page_bbox.x = 0; - surface->page_bbox.y = 0; - surface->page_bbox.width = width; - surface->page_bbox.height = height; - - _cairo_surface_clipper_init (&surface->clipper, - _cairo_ps_surface_clipper_intersect_clip_path); - - _cairo_pdf_operators_init (&surface->pdf_operators, - surface->stream, - &surface->cairo_to_ps, - surface->font_subsets, - TRUE); - surface->num_pages = 0; - - cairo_list_init (&surface->document_media); - _cairo_array_init (&surface->dsc_header_comments, sizeof (char *)); - _cairo_array_init (&surface->dsc_setup_comments, sizeof (char *)); - _cairo_array_init (&surface->dsc_page_setup_comments, sizeof (char *)); - - surface->dsc_comment_target = &surface->dsc_header_comments; - - surface->paginated_surface = _cairo_paginated_surface_create ( - &surface->base, - CAIRO_CONTENT_COLOR_ALPHA, - &cairo_ps_surface_paginated_backend); - status = surface->paginated_surface->status; - if (status == CAIRO_STATUS_SUCCESS) { - /* paginated keeps the only reference to surface now, drop ours */ - cairo_surface_destroy (&surface->base); - return surface->paginated_surface; - } - - _cairo_scaled_font_subsets_destroy (surface->font_subsets); - CLEANUP_OUTPUT_STREAM: - status_ignored = _cairo_output_stream_destroy (surface->stream); - fclose (surface->tmpfile); - CLEANUP_SURFACE: - free (surface); - CLEANUP: - /* destroy stream on behalf of caller */ - status_ignored = _cairo_output_stream_destroy (stream); - - return _cairo_surface_create_in_error (status); -} - -/** - * cairo_ps_surface_create: - * @filename: a filename for the PS output (must be writable), %NULL may be - * used to specify no output. This will generate a PS surface that - * may be queried and used as a source, without generating a - * temporary file. - * @width_in_points: width of the surface, in points (1 point == 1/72.0 inch) - * @height_in_points: height of the surface, in points (1 point == 1/72.0 inch) - * - * Creates a PostScript surface of the specified size in points to be - * written to @filename. See cairo_ps_surface_create_for_stream() for - * a more flexible mechanism for handling the PostScript output than - * simply writing it to a named file. - * - * Note that the size of individual pages of the PostScript output can - * vary. See cairo_ps_surface_set_size(). - * - * Return value: a pointer to the newly created surface. The caller - * owns the surface and should call cairo_surface_destroy() when done - * with it. - * - * This function always returns a valid pointer, but it will return a - * pointer to a "nil" surface if an error such as out of memory - * occurs. You can use cairo_surface_status() to check for this. - * - * Since: 1.2 - **/ -cairo_surface_t * -cairo_ps_surface_create (const char *filename, - double width_in_points, - double height_in_points) -{ - cairo_output_stream_t *stream; - - stream = _cairo_output_stream_create_for_filename (filename); - if (_cairo_output_stream_get_status (stream)) - return _cairo_surface_create_in_error (_cairo_output_stream_destroy (stream)); - - return _cairo_ps_surface_create_for_stream_internal (stream, - width_in_points, - height_in_points); -} - -/** - * cairo_ps_surface_create_for_stream: - * @write_func: a #cairo_write_func_t to accept the output data, may be %NULL - * to indicate a no-op @write_func. With a no-op @write_func, - * the surface may be queried or used as a source without - * generating any temporary files. - * @closure: the closure argument for @write_func - * @width_in_points: width of the surface, in points (1 point == 1/72.0 inch) - * @height_in_points: height of the surface, in points (1 point == 1/72.0 inch) - * - * Creates a PostScript surface of the specified size in points to be - * written incrementally to the stream represented by @write_func and - * @closure. See cairo_ps_surface_create() for a more convenient way - * to simply direct the PostScript output to a named file. - * - * Note that the size of individual pages of the PostScript - * output can vary. See cairo_ps_surface_set_size(). - * - * Return value: a pointer to the newly created surface. The caller - * owns the surface and should call cairo_surface_destroy() when done - * with it. - * - * This function always returns a valid pointer, but it will return a - * pointer to a "nil" surface if an error such as out of memory - * occurs. You can use cairo_surface_status() to check for this. - * - * Since: 1.2 - **/ -cairo_surface_t * -cairo_ps_surface_create_for_stream (cairo_write_func_t write_func, - void *closure, - double width_in_points, - double height_in_points) -{ - cairo_output_stream_t *stream; - - stream = _cairo_output_stream_create (write_func, NULL, closure); - if (_cairo_output_stream_get_status (stream)) - return _cairo_surface_create_in_error (_cairo_output_stream_destroy (stream)); - - return _cairo_ps_surface_create_for_stream_internal (stream, - width_in_points, - height_in_points); -} - -static cairo_bool_t -_cairo_surface_is_ps (cairo_surface_t *surface) -{ - return surface->backend == &cairo_ps_surface_backend; -} - -/* If the abstract_surface is a paginated surface, and that paginated - * surface's target is a ps_surface, then set ps_surface to that - * target. Otherwise return FALSE. - */ -static cairo_bool_t -_extract_ps_surface (cairo_surface_t *surface, - cairo_bool_t set_error_on_failure, - cairo_ps_surface_t **ps_surface) -{ - cairo_surface_t *target; - - if (surface->status) - return FALSE; - if (surface->finished) { - if (set_error_on_failure) - _cairo_surface_set_error (surface, - _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - return FALSE; - } - - if (! _cairo_surface_is_paginated (surface)) { - if (set_error_on_failure) - _cairo_surface_set_error (surface, - _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH)); - return FALSE; - } - - target = _cairo_paginated_surface_get_target (surface); - if (target->status) { - if (set_error_on_failure) - _cairo_surface_set_error (surface, target->status); - return FALSE; - } - if (target->finished) { - if (set_error_on_failure) - _cairo_surface_set_error (surface, - _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - return FALSE; - } - - if (! _cairo_surface_is_ps (target)) { - if (set_error_on_failure) - _cairo_surface_set_error (surface, - _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH)); - return FALSE; - } - - *ps_surface = (cairo_ps_surface_t *) target; - return TRUE; -} - -/** - * cairo_ps_surface_restrict_to_level: - * @surface: a PostScript #cairo_surface_t - * @level: PostScript level - * - * Restricts the generated PostSript file to @level. See - * cairo_ps_get_levels() for a list of available level values that - * can be used here. - * - * This function should only be called before any drawing operations - * have been performed on the given surface. The simplest way to do - * this is to call this function immediately after creating the - * surface. - * - * Since: 1.6 - **/ -void -cairo_ps_surface_restrict_to_level (cairo_surface_t *surface, - cairo_ps_level_t level) -{ - cairo_ps_surface_t *ps_surface = NULL; - - if (! _extract_ps_surface (surface, TRUE, &ps_surface)) - return; - - if (level < CAIRO_PS_LEVEL_LAST) - ps_surface->ps_level = level; -} - -/** - * cairo_ps_get_levels: - * @levels: supported level list - * @num_levels: list length - * - * Used to retrieve the list of supported levels. See - * cairo_ps_surface_restrict_to_level(). - * - * Since: 1.6 - **/ -void -cairo_ps_get_levels (cairo_ps_level_t const **levels, - int *num_levels) -{ - if (levels != NULL) - *levels = _cairo_ps_levels; - - if (num_levels != NULL) - *num_levels = CAIRO_PS_LEVEL_LAST; -} - -/** - * cairo_ps_level_to_string: - * @level: a level id - * - * Get the string representation of the given @level id. This function - * will return %NULL if @level id isn't valid. See cairo_ps_get_levels() - * for a way to get the list of valid level ids. - * - * Return value: the string associated to given level. - * - * Since: 1.6 - **/ -const char * -cairo_ps_level_to_string (cairo_ps_level_t level) -{ - if (level >= CAIRO_PS_LEVEL_LAST) - return NULL; - - return _cairo_ps_level_strings[level]; -} - -/** - * cairo_ps_surface_set_eps: - * @surface: a PostScript #cairo_surface_t - * @eps: %TRUE to output EPS format PostScript - * - * If @eps is %TRUE, the PostScript surface will output Encapsulated - * PostScript. - * - * This function should only be called before any drawing operations - * have been performed on the current page. The simplest way to do - * this is to call this function immediately after creating the - * surface. An Encapsulated PostScript file should never contain more - * than one page. - * - * Since: 1.6 - **/ -void -cairo_ps_surface_set_eps (cairo_surface_t *surface, - cairo_bool_t eps) -{ - cairo_ps_surface_t *ps_surface = NULL; - - if (! _extract_ps_surface (surface, TRUE, &ps_surface)) - return; - - ps_surface->eps = eps; -} - -/** - * cairo_ps_surface_get_eps: - * @surface: a PostScript #cairo_surface_t - * - * Check whether the PostScript surface will output Encapsulated PostScript. - * - * Return value: %TRUE if the surface will output Encapsulated PostScript. - * - * Since: 1.6 - **/ -cairo_public cairo_bool_t -cairo_ps_surface_get_eps (cairo_surface_t *surface) -{ - cairo_ps_surface_t *ps_surface = NULL; - - if (! _extract_ps_surface (surface, FALSE, &ps_surface)) - return FALSE; - - return ps_surface->eps; -} - -/** - * cairo_ps_surface_set_size: - * @surface: a PostScript #cairo_surface_t - * @width_in_points: new surface width, in points (1 point == 1/72.0 inch) - * @height_in_points: new surface height, in points (1 point == 1/72.0 inch) - * - * Changes the size of a PostScript surface for the current (and - * subsequent) pages. - * - * This function should only be called before any drawing operations - * have been performed on the current page. The simplest way to do - * this is to call this function immediately after creating the - * surface or immediately after completing a page with either - * cairo_show_page() or cairo_copy_page(). - * - * Since: 1.2 - **/ -void -cairo_ps_surface_set_size (cairo_surface_t *surface, - double width_in_points, - double height_in_points) -{ - cairo_ps_surface_t *ps_surface = NULL; - cairo_status_t status; - - if (! _extract_ps_surface (surface, TRUE, &ps_surface)) - return; - - ps_surface->width = width_in_points; - ps_surface->height = height_in_points; - cairo_matrix_init (&ps_surface->cairo_to_ps, 1, 0, 0, -1, 0, height_in_points); - _cairo_pdf_operators_set_cairo_to_pdf_matrix (&ps_surface->pdf_operators, - &ps_surface->cairo_to_ps); - status = _cairo_paginated_surface_set_size (ps_surface->paginated_surface, - width_in_points, - height_in_points); - if (status) - status = _cairo_surface_set_error (surface, status); -} - -/** - * cairo_ps_surface_dsc_comment: - * @surface: a PostScript #cairo_surface_t - * @comment: a comment string to be emitted into the PostScript output - * - * Emit a comment into the PostScript output for the given surface. - * - * The comment is expected to conform to the PostScript Language - * Document Structuring Conventions (DSC). Please see that manual for - * details on the available comments and their meanings. In - * particular, the \%\%IncludeFeature comment allows a - * device-independent means of controlling printer device features. So - * the PostScript Printer Description Files Specification will also be - * a useful reference. - * - * The comment string must begin with a percent character (\%) and the - * total length of the string (including any initial percent - * characters) must not exceed 255 characters. Violating either of - * these conditions will place @surface into an error state. But - * beyond these two conditions, this function will not enforce - * conformance of the comment with any particular specification. - * - * The comment string should not have a trailing newline. - * - * The DSC specifies different sections in which particular comments - * can appear. This function provides for comments to be emitted - * within three sections: the header, the Setup section, and the - * PageSetup section. Comments appearing in the first two sections - * apply to the entire document while comments in the BeginPageSetup - * section apply only to a single page. - * - * For comments to appear in the header section, this function should - * be called after the surface is created, but before a call to - * cairo_ps_surface_dsc_begin_setup(). - * - * For comments to appear in the Setup section, this function should - * be called after a call to cairo_ps_surface_dsc_begin_setup() but - * before a call to cairo_ps_surface_dsc_begin_page_setup(). - * - * For comments to appear in the PageSetup section, this function - * should be called after a call to - * cairo_ps_surface_dsc_begin_page_setup(). - * - * Note that it is only necessary to call - * cairo_ps_surface_dsc_begin_page_setup() for the first page of any - * surface. After a call to cairo_show_page() or cairo_copy_page() - * comments are unambiguously directed to the PageSetup section of the - * current page. But it doesn't hurt to call this function at the - * beginning of every page as that consistency may make the calling - * code simpler. - * - * As a final note, cairo automatically generates several comments on - * its own. As such, applications must not manually generate any of - * the following comments: - * - * Header section: \%!PS-Adobe-3.0, \%\%Creator, \%\%CreationDate, \%\%Pages, - * \%\%BoundingBox, \%\%DocumentData, \%\%LanguageLevel, \%\%EndComments. - * - * Setup section: \%\%BeginSetup, \%\%EndSetup - * - * PageSetup section: \%\%BeginPageSetup, \%\%PageBoundingBox, \%\%EndPageSetup. - * - * Other sections: \%\%BeginProlog, \%\%EndProlog, \%\%Page, \%\%Trailer, \%\%EOF - * - * Here is an example sequence showing how this function might be used: - * - * <informalexample><programlisting> - * cairo_surface_t *surface = cairo_ps_surface_create (filename, width, height); - * ... - * cairo_ps_surface_dsc_comment (surface, "%%Title: My excellent document"); - * cairo_ps_surface_dsc_comment (surface, "%%Copyright: Copyright (C) 2006 Cairo Lover") - * ... - * cairo_ps_surface_dsc_begin_setup (surface); - * cairo_ps_surface_dsc_comment (surface, "%%IncludeFeature: *MediaColor White"); - * ... - * cairo_ps_surface_dsc_begin_page_setup (surface); - * cairo_ps_surface_dsc_comment (surface, "%%IncludeFeature: *PageSize A3"); - * cairo_ps_surface_dsc_comment (surface, "%%IncludeFeature: *InputSlot LargeCapacity"); - * cairo_ps_surface_dsc_comment (surface, "%%IncludeFeature: *MediaType Glossy"); - * cairo_ps_surface_dsc_comment (surface, "%%IncludeFeature: *MediaColor Blue"); - * ... draw to first page here .. - * cairo_show_page (cr); - * ... - * cairo_ps_surface_dsc_comment (surface, "%%IncludeFeature: *PageSize A5"); - * ... - * </programlisting></informalexample> - * - * Since: 1.2 - **/ -void -cairo_ps_surface_dsc_comment (cairo_surface_t *surface, - const char *comment) -{ - cairo_ps_surface_t *ps_surface = NULL; - cairo_status_t status; - char *comment_copy; - - if (! _extract_ps_surface (surface, TRUE, &ps_surface)) - return; - - /* A couple of sanity checks on the comment value. */ - if (comment == NULL) { - status = _cairo_surface_set_error (surface, CAIRO_STATUS_NULL_POINTER); - return; - } - - if (comment[0] != '%' || strlen (comment) > 255) { - status = _cairo_surface_set_error (surface, CAIRO_STATUS_INVALID_DSC_COMMENT); - return; - } - - /* Then, copy the comment and store it in the appropriate array. */ - comment_copy = strdup (comment); - if (unlikely (comment_copy == NULL)) { - status = _cairo_surface_set_error (surface, CAIRO_STATUS_NO_MEMORY); - return; - } - - status = _cairo_array_append (ps_surface->dsc_comment_target, &comment_copy); - if (unlikely (status)) { - free (comment_copy); - status = _cairo_surface_set_error (surface, status); - return; - } -} - -/** - * cairo_ps_surface_dsc_begin_setup: - * @surface: a PostScript #cairo_surface_t - * - * This function indicates that subsequent calls to - * cairo_ps_surface_dsc_comment() should direct comments to the Setup - * section of the PostScript output. - * - * This function should be called at most once per surface, and must - * be called before any call to cairo_ps_surface_dsc_begin_page_setup() - * and before any drawing is performed to the surface. - * - * See cairo_ps_surface_dsc_comment() for more details. - * - * Since: 1.2 - **/ -void -cairo_ps_surface_dsc_begin_setup (cairo_surface_t *surface) -{ - cairo_ps_surface_t *ps_surface = NULL; - - if (! _extract_ps_surface (surface, TRUE, &ps_surface)) - return; - - if (ps_surface->dsc_comment_target == &ps_surface->dsc_header_comments) - ps_surface->dsc_comment_target = &ps_surface->dsc_setup_comments; -} - -/** - * cairo_ps_surface_dsc_begin_page_setup: - * @surface: a PostScript #cairo_surface_t - * - * This function indicates that subsequent calls to - * cairo_ps_surface_dsc_comment() should direct comments to the - * PageSetup section of the PostScript output. - * - * This function call is only needed for the first page of a - * surface. It should be called after any call to - * cairo_ps_surface_dsc_begin_setup() and before any drawing is - * performed to the surface. - * - * See cairo_ps_surface_dsc_comment() for more details. - * - * Since: 1.2 - **/ -void -cairo_ps_surface_dsc_begin_page_setup (cairo_surface_t *surface) -{ - cairo_ps_surface_t *ps_surface = NULL; - - if (! _extract_ps_surface (surface, TRUE, &ps_surface)) - return; - - if (ps_surface->dsc_comment_target == &ps_surface->dsc_header_comments || - ps_surface->dsc_comment_target == &ps_surface->dsc_setup_comments) - { - ps_surface->dsc_comment_target = &ps_surface->dsc_page_setup_comments; - } -} - -static cairo_status_t -_cairo_ps_surface_finish (void *abstract_surface) -{ - cairo_status_t status, status2; - cairo_ps_surface_t *surface = abstract_surface; - int i, num_comments; - char **comments; - - status = surface->base.status; - if (unlikely (status)) - goto CLEANUP; - - _cairo_ps_surface_emit_header (surface); - - status = _cairo_ps_surface_emit_font_subsets (surface); - if (unlikely (status)) - goto CLEANUP; - - _cairo_output_stream_printf (surface->final_stream, - "%%%%EndSetup\n"); - - status = _cairo_ps_surface_emit_body (surface); - if (unlikely (status)) - goto CLEANUP; - - _cairo_ps_surface_emit_footer (surface); - -CLEANUP: - _cairo_scaled_font_subsets_destroy (surface->font_subsets); - - status2 = _cairo_output_stream_destroy (surface->stream); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - - fclose (surface->tmpfile); - - status2 = _cairo_output_stream_destroy (surface->final_stream); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - - while (! cairo_list_is_empty (&surface->document_media)) { - cairo_page_media_t *page; - - page = cairo_list_first_entry (&surface->document_media, - cairo_page_media_t, - link); - cairo_list_del (&page->link); - free (page->name); - free (page); - } - - num_comments = _cairo_array_num_elements (&surface->dsc_header_comments); - comments = _cairo_array_index (&surface->dsc_header_comments, 0); - for (i = 0; i < num_comments; i++) - free (comments[i]); - _cairo_array_fini (&surface->dsc_header_comments); - - num_comments = _cairo_array_num_elements (&surface->dsc_setup_comments); - comments = _cairo_array_index (&surface->dsc_setup_comments, 0); - for (i = 0; i < num_comments; i++) - free (comments[i]); - _cairo_array_fini (&surface->dsc_setup_comments); - - num_comments = _cairo_array_num_elements (&surface->dsc_page_setup_comments); - comments = _cairo_array_index (&surface->dsc_page_setup_comments, 0); - for (i = 0; i < num_comments; i++) - free (comments[i]); - _cairo_array_fini (&surface->dsc_page_setup_comments); - - _cairo_surface_clipper_reset (&surface->clipper); - - return status; -} - -static cairo_int_status_t -_cairo_ps_surface_start_page (void *abstract_surface) -{ - cairo_ps_surface_t *surface = abstract_surface; - - /* Increment before print so page numbers start at 1. */ - surface->num_pages++; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_ps_surface_show_page (void *abstract_surface) -{ - cairo_ps_surface_t *surface = abstract_surface; - cairo_int_status_t status; - - if (surface->clipper.clip != NULL) - _cairo_surface_clipper_reset (&surface->clipper); - - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->stream, - "Q Q\n" - "showpage\n"); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_bool_t -color_is_gray (double red, double green, double blue) -{ - const double epsilon = 0.00001; - - return (fabs (red - green) < epsilon && - fabs (red - blue) < epsilon); -} - -/** - * _cairo_ps_surface_acquire_source_surface_from_pattern: - * @surface: the ps surface - * @pattern: A #cairo_pattern_t of type SURFACE or RASTER_SOURCE to use as the source - * @extents: extents of the operation that is using this source - * @width: returns width of surface - * @height: returns height of surface - * @x_offset: returns x offset of surface - * @y_offset: returns y offset of surface - * @surface: returns surface of type image surface or recording surface - * @image_extra: returns image extra for image type surface - * - * Acquire source surface or raster source pattern. - **/ -static cairo_status_t -_cairo_ps_surface_acquire_source_surface_from_pattern (cairo_ps_surface_t *surface, - const cairo_pattern_t *pattern, - const cairo_rectangle_int_t *extents, - int *width, - int *height, - double *x_offset, - double *y_offset, - cairo_surface_t **source_surface, - void **image_extra) -{ - cairo_status_t status; - cairo_image_surface_t *image; - - *x_offset = *y_offset = 0; - switch (pattern->type) { - case CAIRO_PATTERN_TYPE_SURFACE: { - cairo_surface_t *surf = ((cairo_surface_pattern_t *) pattern)->surface; - - if (surf->type == CAIRO_SURFACE_TYPE_RECORDING) { - if (surf->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) { - cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) surf; - - *width = sub->extents.width; - *height = sub->extents.height; - } else { - cairo_surface_t *free_me = NULL; - cairo_recording_surface_t *recording_surface; - cairo_box_t bbox; - cairo_rectangle_int_t extents; - - recording_surface = (cairo_recording_surface_t *) surf; - if (_cairo_surface_is_snapshot (&recording_surface->base)) { - free_me = _cairo_surface_snapshot_get_target (&recording_surface->base); - recording_surface = (cairo_recording_surface_t *) free_me; - } - - status = _cairo_recording_surface_get_bbox (recording_surface, &bbox, NULL); - cairo_surface_destroy (free_me); - if (unlikely (status)) - return status; - - _cairo_box_round_to_rectangle (&bbox, &extents); - *width = extents.width; - *height = extents.height; - } - *source_surface = surf; - - return CAIRO_STATUS_SUCCESS; - } else { - status = _cairo_surface_acquire_source_image (surf, &image, image_extra); - if (unlikely (status)) - return status; - } - } break; - - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: { - cairo_surface_t *surf; - cairo_box_t box; - cairo_rectangle_int_t rect; - - /* get the operation extents in pattern space */ - _cairo_box_from_rectangle (&box, extents); - _cairo_matrix_transform_bounding_box_fixed (&pattern->matrix, &box, NULL); - _cairo_box_round_to_rectangle (&box, &rect); - surf = _cairo_raster_source_pattern_acquire (pattern, &surface->base, &rect); - if (!surf) - return CAIRO_INT_STATUS_UNSUPPORTED; - assert (_cairo_surface_is_image (surf)); - image = (cairo_image_surface_t *) surf; - } break; - - case CAIRO_PATTERN_TYPE_SOLID: - case CAIRO_PATTERN_TYPE_LINEAR: - case CAIRO_PATTERN_TYPE_RADIAL: - case CAIRO_PATTERN_TYPE_MESH: - default: - ASSERT_NOT_REACHED; - break; - } - - *width = image->width; - *height = image->height; - *source_surface = &image->base; - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_ps_surface_release_source_surface_from_pattern (cairo_ps_surface_t *surface, - const cairo_pattern_t *pattern, - cairo_surface_t *source, - void *image_extra) -{ - switch (pattern->type) { - case CAIRO_PATTERN_TYPE_SURFACE: { - cairo_surface_pattern_t *surf_pat = (cairo_surface_pattern_t *) pattern; - if (surf_pat->surface->type != CAIRO_SURFACE_TYPE_RECORDING) { - cairo_image_surface_t *image = (cairo_image_surface_t *) source; - _cairo_surface_release_source_image (surf_pat->surface, image, image_extra); - } - } break; - - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - _cairo_raster_source_pattern_release (pattern, source); - break; - - case CAIRO_PATTERN_TYPE_SOLID: - case CAIRO_PATTERN_TYPE_LINEAR: - case CAIRO_PATTERN_TYPE_RADIAL: - case CAIRO_PATTERN_TYPE_MESH: - default: - - ASSERT_NOT_REACHED; - break; - } -} - -/** - * _cairo_ps_surface_create_padded_image_from_image: - * @surface: the ps surface - * @source: The source image - * @extents: extents of the operation that is using this source - * @width: returns width of padded image - * @height: returns height of padded image - * @x_offset: returns x offset of padded image - * @y_offset: returns y offset of padded image - * @image: returns the padded image or NULL if padding not required to fill @extents - * - * Creates a padded image if the source image does not fill the extents. - **/ -static cairo_status_t -_cairo_ps_surface_create_padded_image_from_image (cairo_ps_surface_t *surface, - cairo_image_surface_t *source, - const cairo_matrix_t *source_matrix, - const cairo_rectangle_int_t *extents, - int *width, - int *height, - double *x_offset, - double *y_offset, - cairo_image_surface_t **image) -{ - cairo_box_t box; - cairo_rectangle_int_t rect; - cairo_surface_t *pad_image; - cairo_surface_pattern_t pad_pattern; - int w, h; - cairo_int_status_t status; - - /* get the operation extents in pattern space */ - _cairo_box_from_rectangle (&box, extents); - _cairo_matrix_transform_bounding_box_fixed (source_matrix, &box, NULL); - _cairo_box_round_to_rectangle (&box, &rect); - - /* Check if image needs padding to fill extents. */ - w = source->width; - h = source->height; - if (_cairo_fixed_integer_ceil(box.p1.x) < 0 || - _cairo_fixed_integer_ceil(box.p1.y) < 0 || - _cairo_fixed_integer_floor(box.p2.y) > w || - _cairo_fixed_integer_floor(box.p2.y) > h) - { - pad_image = - _cairo_image_surface_create_with_pixman_format (NULL, - source->pixman_format, - rect.width, rect.height, - 0); - if (pad_image->status) - return pad_image->status; - - _cairo_pattern_init_for_surface (&pad_pattern, &source->base); - cairo_matrix_init_translate (&pad_pattern.base.matrix, rect.x, rect.y); - pad_pattern.base.extend = CAIRO_EXTEND_PAD; - status = _cairo_surface_paint (pad_image, - CAIRO_OPERATOR_SOURCE, - &pad_pattern.base, - NULL); - _cairo_pattern_fini (&pad_pattern.base); - *image = (cairo_image_surface_t *) pad_image; - *width = rect.width; - *height = rect.height; - *x_offset = rect.x; - *y_offset = rect.y; - } else { - *image = NULL; - status = CAIRO_STATUS_SUCCESS; - } - - return status; -} - -static cairo_int_status_t -_cairo_ps_surface_analyze_surface_pattern_transparency (cairo_ps_surface_t *surface, - const cairo_pattern_t *pattern, - const cairo_rectangle_int_t *extents) -{ - int width, height; - double x_offset, y_offset; - cairo_surface_t *source; - cairo_image_surface_t *image; - void *image_extra; - cairo_int_status_t status; - cairo_image_transparency_t transparency; - - status = _cairo_ps_surface_acquire_source_surface_from_pattern (surface, - pattern, - extents, - &width, - &height, - &x_offset, - &y_offset, - &source, - &image_extra); - if (unlikely (status)) - return status; - - image = (cairo_image_surface_t *) source; - if (image->base.status) - return image->base.status; - - transparency = _cairo_image_analyze_transparency (image); - switch (transparency) { - case CAIRO_IMAGE_IS_OPAQUE: - status = CAIRO_STATUS_SUCCESS; - break; - - case CAIRO_IMAGE_HAS_BILEVEL_ALPHA: - if (surface->ps_level == CAIRO_PS_LEVEL_2) { - status = CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY; - } else { - surface->ps_level_used = CAIRO_PS_LEVEL_3; - status = CAIRO_STATUS_SUCCESS; - } - break; - - case CAIRO_IMAGE_HAS_ALPHA: - status = CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY; - break; - - case CAIRO_IMAGE_UNKNOWN: - ASSERT_NOT_REACHED; - } - - _cairo_ps_surface_release_source_surface_from_pattern (surface, pattern, source, image_extra); - - return status; -} - -static cairo_bool_t -surface_pattern_supported (const cairo_surface_pattern_t *pattern) -{ - if (pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING) - return TRUE; - - if (pattern->surface->backend->acquire_source_image == NULL) - return FALSE; - - /* Does an ALPHA-only source surface even make sense? Maybe, but I - * don't think it's worth the extra code to support it. */ - -/* XXX: Need to write this function here... - content = pattern->surface->content; - if (content == CAIRO_CONTENT_ALPHA) - return FALSE; -*/ - - return TRUE; -} - -static cairo_bool_t -_gradient_pattern_supported (cairo_ps_surface_t *surface, - const cairo_pattern_t *pattern) -{ - double min_alpha, max_alpha; - - if (surface->ps_level == CAIRO_PS_LEVEL_2) - return FALSE; - - /* Alpha gradients are only supported (by flattening the alpha) - * if there is no variation in the alpha across the gradient. */ - _cairo_pattern_alpha_range (pattern, &min_alpha, &max_alpha); - if (min_alpha != max_alpha) - return FALSE; - - surface->ps_level_used = CAIRO_PS_LEVEL_3; - - return TRUE; -} - -static cairo_bool_t -pattern_supported (cairo_ps_surface_t *surface, const cairo_pattern_t *pattern) -{ - switch (pattern->type) { - case CAIRO_PATTERN_TYPE_SOLID: - return TRUE; - - case CAIRO_PATTERN_TYPE_LINEAR: - case CAIRO_PATTERN_TYPE_RADIAL: - case CAIRO_PATTERN_TYPE_MESH: - return _gradient_pattern_supported (surface, pattern); - - case CAIRO_PATTERN_TYPE_SURFACE: - return surface_pattern_supported ((cairo_surface_pattern_t *) pattern); - - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - return TRUE; - - default: - ASSERT_NOT_REACHED; - return FALSE; - } -} - -static cairo_bool_t -mask_supported (cairo_ps_surface_t *surface, - const cairo_pattern_t *mask, - const cairo_rectangle_int_t *extents) -{ - if (surface->ps_level == CAIRO_PS_LEVEL_2) - return FALSE; - - if (mask->type == CAIRO_PATTERN_TYPE_SURFACE) { - cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) mask; - if (surface_pattern->surface->type == CAIRO_SURFACE_TYPE_IMAGE) { - /* check if mask if opaque or bilevel alpha */ - if (_cairo_ps_surface_analyze_surface_pattern_transparency (surface, mask, extents) == CAIRO_INT_STATUS_SUCCESS) { - surface->ps_level_used = CAIRO_PS_LEVEL_3; - return TRUE; - } - } - } - - return FALSE; -} - -static cairo_int_status_t -_cairo_ps_surface_analyze_operation (cairo_ps_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *pattern, - const cairo_pattern_t *mask, - const cairo_rectangle_int_t *extents) -{ - double min_alpha; - - if (surface->force_fallbacks && - surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) - { - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - if (! pattern_supported (surface, pattern)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (! (op == CAIRO_OPERATOR_SOURCE || op == CAIRO_OPERATOR_OVER)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* Mask is only supported when the mask is an image with opaque or bilevel alpha. */ - if (mask && !mask_supported (surface, mask, extents)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) { - cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) pattern; - - if (surface_pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING) { - if (pattern->extend == CAIRO_EXTEND_PAD) { - cairo_box_t box; - cairo_rectangle_int_t rect; - cairo_rectangle_int_t rec_extents; - - /* get the operation extents in pattern space */ - _cairo_box_from_rectangle (&box, extents); - _cairo_matrix_transform_bounding_box_fixed (&pattern->matrix, &box, NULL); - _cairo_box_round_to_rectangle (&box, &rect); - - /* Check if surface needs padding to fill extents */ - if (_cairo_surface_get_extents (surface_pattern->surface, &rec_extents)) { - if (_cairo_fixed_integer_ceil(box.p1.x) < rec_extents.x || - _cairo_fixed_integer_ceil(box.p1.y) < rec_extents.y || - _cairo_fixed_integer_floor(box.p2.y) > rec_extents.x + rec_extents.width || - _cairo_fixed_integer_floor(box.p2.y) > rec_extents.y + rec_extents.height) - { - return CAIRO_INT_STATUS_UNSUPPORTED; - } - } - } - return CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN; - } - } - - if (op == CAIRO_OPERATOR_SOURCE) { - if (mask) - return CAIRO_INT_STATUS_UNSUPPORTED; - else - return CAIRO_STATUS_SUCCESS; - } - - /* CAIRO_OPERATOR_OVER is only supported for opaque patterns. If - * the pattern contains transparency, we return - * CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY to the analysis - * surface. If the analysis surface determines that there is - * anything drawn under this operation, a fallback image will be - * used. Otherwise the operation will be replayed during the - * render stage and we blend the transparency into the white - * background to convert the pattern to opaque. - */ - if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE || pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE) - return _cairo_ps_surface_analyze_surface_pattern_transparency (surface, pattern, extents); - - /* Patterns whose drawn part is opaque are directly supported; - those whose drawn part is partially transparent can be - supported by flattening the alpha. */ - _cairo_pattern_alpha_range (pattern, &min_alpha, NULL); - if (CAIRO_ALPHA_IS_OPAQUE (min_alpha)) - return CAIRO_STATUS_SUCCESS; - - return CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY; -} - -static cairo_bool_t -_cairo_ps_surface_operation_supported (cairo_ps_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *pattern, - const cairo_pattern_t *mask, - const cairo_rectangle_int_t *extents) -{ - return _cairo_ps_surface_analyze_operation (surface, op, pattern, mask, extents) != 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 base; - cairo_output_stream_t *output; - int column; - int string_size; - cairo_bool_t use_strings; -} string_array_stream_t; - -static cairo_status_t -_string_array_stream_write (cairo_output_stream_t *base, - const unsigned char *data, - unsigned int length) -{ - string_array_stream_t *stream = (string_array_stream_t *) base; - unsigned char c; - const unsigned char backslash = '\\'; - - if (length == 0) - return CAIRO_STATUS_SUCCESS; - - while (length--) { - if (stream->string_size == 0 && stream->use_strings) { - _cairo_output_stream_printf (stream->output, "("); - stream->column++; - } - - c = *data++; - if (stream->use_strings) { - switch (c) { - case '\\': - case '(': - case ')': - _cairo_output_stream_write (stream->output, &backslash, 1); - stream->column++; - stream->string_size++; - break; - } - } - /* Have to be careful to never split the final ~> sequence. */ - if (c == '~') { - _cairo_output_stream_write (stream->output, &c, 1); - stream->column++; - stream->string_size++; - - if (length-- == 0) - break; - - c = *data++; - } - _cairo_output_stream_write (stream->output, &c, 1); - stream->column++; - stream->string_size++; - - if (stream->use_strings && - 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 (cairo_output_stream_t *base) -{ - cairo_status_t status; - string_array_stream_t *stream = (string_array_stream_t *) base; - - if (stream->use_strings) - _cairo_output_stream_printf (stream->output, ")\n"); - - status = _cairo_output_stream_get_status (stream->output); - - return status; -} - -/* A string_array_stream wraps an existing output stream. It takes the - * data provided to it and output one or more consecutive string - * objects, each within the standard PostScript implementation limit - * of 65k characters. - * - * The strings are each separated by a space character for easy - * inclusion within an array object, (but the array delimiters are not - * added by the string_array_stream). - * - * The string array stream is also careful to wrap the output within - * STRING_ARRAY_MAX_COLUMN columns (+/- 1). The stream also adds - * necessary escaping for special characters within a string, - * (specifically '\', '(', and ')'). - */ -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 (unlikely (stream == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_output_stream_t *) &_cairo_output_stream_nil; - } - - _cairo_output_stream_init (&stream->base, - _string_array_stream_write, - NULL, - _string_array_stream_close); - stream->output = output; - stream->column = 0; - stream->string_size = 0; - stream->use_strings = TRUE; - - return &stream->base; -} - -/* A base85_array_stream wraps an existing output stream. It wraps the - * output within STRING_ARRAY_MAX_COLUMN columns (+/- 1). The output - * is not enclosed in strings like string_array_stream. - */ -static cairo_output_stream_t * -_base85_array_stream_create (cairo_output_stream_t *output) -{ - string_array_stream_t *stream; - - stream = malloc (sizeof (string_array_stream_t)); - if (unlikely (stream == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_output_stream_t *) &_cairo_output_stream_nil; - } - - _cairo_output_stream_init (&stream->base, - _string_array_stream_write, - NULL, - _string_array_stream_close); - stream->output = output; - stream->column = 0; - stream->string_size = 0; - stream->use_strings = FALSE; - - return &stream->base; -} - - -/* PS Output - this section handles output of the parts of the recording - * surface we can render natively in PS. */ - -static cairo_status_t -_cairo_ps_surface_flatten_image_transparency (cairo_ps_surface_t *surface, - cairo_image_surface_t *image, - cairo_image_surface_t **opaque_image) -{ - cairo_surface_t *opaque; - cairo_surface_pattern_t pattern; - cairo_status_t status; - - opaque = cairo_image_surface_create (CAIRO_FORMAT_RGB24, - image->width, - image->height); - if (unlikely (opaque->status)) - return opaque->status; - - if (surface->content == CAIRO_CONTENT_COLOR_ALPHA) { - status = _cairo_surface_paint (opaque, - CAIRO_OPERATOR_SOURCE, - &_cairo_pattern_white.base, - NULL); - if (unlikely (status)) { - cairo_surface_destroy (opaque); - return status; - } - } - - _cairo_pattern_init_for_surface (&pattern, &image->base); - pattern.base.filter = CAIRO_FILTER_NEAREST; - status = _cairo_surface_paint (opaque, CAIRO_OPERATOR_OVER, &pattern.base, NULL); - _cairo_pattern_fini (&pattern.base); - if (unlikely (status)) { - cairo_surface_destroy (opaque); - return status; - } - - *opaque_image = (cairo_image_surface_t *) opaque; - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_ps_surface_emit_base85_string (cairo_ps_surface_t *surface, - const unsigned char *data, - unsigned long length, - cairo_ps_compress_t compress, - cairo_bool_t use_strings) -{ - cairo_output_stream_t *base85_stream, *string_array_stream, *deflate_stream; - unsigned char *data_compressed; - unsigned long data_compressed_size; - cairo_status_t status, status2; - - if (use_strings) - string_array_stream = _string_array_stream_create (surface->stream); - else - string_array_stream = _base85_array_stream_create (surface->stream); - - status = _cairo_output_stream_get_status (string_array_stream); - if (unlikely (status)) - return _cairo_output_stream_destroy (string_array_stream); - - base85_stream = _cairo_base85_stream_create (string_array_stream); - status = _cairo_output_stream_get_status (base85_stream); - if (unlikely (status)) { - status2 = _cairo_output_stream_destroy (string_array_stream); - return _cairo_output_stream_destroy (base85_stream); - } - - switch (compress) { - case CAIRO_PS_COMPRESS_NONE: - _cairo_output_stream_write (base85_stream, data, length); - break; - - case CAIRO_PS_COMPRESS_LZW: - /* XXX: Should fix cairo-lzw to provide a stream-based interface - * instead. */ - data_compressed_size = length; - data_compressed = _cairo_lzw_compress ((unsigned char*)data, &data_compressed_size); - if (unlikely (data_compressed == NULL)) { - status = _cairo_output_stream_destroy (string_array_stream); - status = _cairo_output_stream_destroy (base85_stream); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - _cairo_output_stream_write (base85_stream, data_compressed, data_compressed_size); - free (data_compressed); - break; - - case CAIRO_PS_COMPRESS_DEFLATE: - deflate_stream = _cairo_deflate_stream_create (base85_stream); - if (_cairo_output_stream_get_status (deflate_stream)) { - return _cairo_output_stream_destroy (deflate_stream); - } - _cairo_output_stream_write (deflate_stream, data, length); - status = _cairo_output_stream_destroy (deflate_stream); - if (unlikely (status)) { - status2 = _cairo_output_stream_destroy (string_array_stream); - status2 = _cairo_output_stream_destroy (base85_stream); - return _cairo_output_stream_destroy (deflate_stream); - } - break; - } - status = _cairo_output_stream_destroy (base85_stream); - - /* Mark end of base85 data */ - _cairo_output_stream_printf (string_array_stream, "~>"); - status2 = _cairo_output_stream_destroy (string_array_stream); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - - return status; -} - -static cairo_status_t -_cairo_ps_surface_emit_image (cairo_ps_surface_t *surface, - cairo_image_surface_t *image_surf, - cairo_operator_t op, - cairo_filter_t filter, - cairo_bool_t stencil_mask) -{ - cairo_status_t status; - unsigned char *data; - unsigned long data_size; - cairo_image_surface_t *ps_image; - int x, y, i, a; - cairo_image_transparency_t transparency; - cairo_bool_t use_mask; - uint32_t *pixel32; - uint8_t *pixel8; - int bit; - cairo_image_color_t color; - const char *interpolate; - cairo_ps_compress_t compress; - const char *compress_filter; - cairo_image_surface_t *image; - - if (image_surf->base.status) - return image_surf->base.status; - - image = image_surf; - if (image->format != CAIRO_FORMAT_RGB24 && - image->format != CAIRO_FORMAT_ARGB32 && - image->format != CAIRO_FORMAT_A8 && - image->format != CAIRO_FORMAT_A1) - { - cairo_surface_t *surf; - cairo_surface_pattern_t pattern; - - surf = _cairo_image_surface_create_with_content (image_surf->base.content, - image_surf->width, - image_surf->height); - image = (cairo_image_surface_t *) surf; - if (surf->status) { - status = surf->status; - goto bail0; - } - - _cairo_pattern_init_for_surface (&pattern, &image_surf->base); - status = _cairo_surface_paint (surf, - CAIRO_OPERATOR_SOURCE, &pattern.base, - NULL); - _cairo_pattern_fini (&pattern.base); - if (unlikely (status)) - goto bail0; - } - ps_image = image; - - switch (filter) { - default: - case CAIRO_FILTER_GOOD: - case CAIRO_FILTER_BEST: - case CAIRO_FILTER_BILINEAR: - interpolate = "true"; - break; - case CAIRO_FILTER_FAST: - case CAIRO_FILTER_NEAREST: - case CAIRO_FILTER_GAUSSIAN: - interpolate = "false"; - break; - } - - if (stencil_mask) { - use_mask = FALSE; - color = CAIRO_IMAGE_IS_MONOCHROME; - transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA; - } else { - transparency = _cairo_image_analyze_transparency (image); - - /* PostScript can not represent the alpha channel, so we blend the - current image over a white (or black for CONTENT_COLOR - surfaces) RGB surface to eliminate it. */ - - if (op == CAIRO_OPERATOR_SOURCE || - transparency == CAIRO_IMAGE_HAS_ALPHA || - (transparency == CAIRO_IMAGE_HAS_BILEVEL_ALPHA && - surface->ps_level == CAIRO_PS_LEVEL_2)) - { - status = _cairo_ps_surface_flatten_image_transparency (surface, - image, - &ps_image); - if (unlikely (status)) - return status; - - use_mask = FALSE; - } else if (transparency == CAIRO_IMAGE_IS_OPAQUE) { - use_mask = FALSE; - } else { /* transparency == CAIRO_IMAGE_HAS_BILEVEL_ALPHA */ - use_mask = TRUE; - } - - color = _cairo_image_analyze_color (ps_image); - } - - /* Type 2 (mask and image interleaved) has the mask and image - * samples interleaved by row. The mask row is first, one bit per - * pixel with (bit 7 first). The row is padded to byte - * boundaries. The image data is 3 bytes per pixel RGB format. */ - switch (color) { - default: - case CAIRO_IMAGE_UNKNOWN_COLOR: - ASSERT_NOT_REACHED; - case CAIRO_IMAGE_IS_COLOR: - data_size = ps_image->width * 3; - break; - case CAIRO_IMAGE_IS_GRAYSCALE: - data_size = ps_image->width; - break; - case CAIRO_IMAGE_IS_MONOCHROME: - data_size = (ps_image->width + 7)/8; - break; - } - if (use_mask) - data_size += (ps_image->width + 7)/8; - data_size *= ps_image->height; - data = malloc (data_size); - if (unlikely (data == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto bail1; - } - - i = 0; - for (y = 0; y < ps_image->height; y++) { - if (stencil_mask || use_mask) { - /* mask row */ - if (ps_image->format == CAIRO_FORMAT_A1) { - pixel8 = (uint8_t *) (ps_image->data + y * ps_image->stride); - - for (x = 0; x < (ps_image->width + 7) / 8; x++, pixel8++) { - a = *pixel8; - a = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (a); - data[i++] = a; - } - } else { - pixel8 = (uint8_t *) (ps_image->data + y * ps_image->stride); - pixel32 = (uint32_t *) (ps_image->data + y * ps_image->stride); - bit = 7; - for (x = 0; x < ps_image->width; x++) { - if (ps_image->format == CAIRO_FORMAT_ARGB32) { - a = (*pixel32 & 0xff000000) >> 24; - pixel32++; - } else { - a = *pixel8; - pixel8++; - } - - if (transparency == CAIRO_IMAGE_HAS_ALPHA) { - data[i++] = a; - } else { /* transparency == CAIRO_IMAGE_HAS_BILEVEL_ALPHA or CAIRO_IMAGE_IS_OPAQUE */ - if (bit == 7) - data[i] = 0; - if (a != 0) - data[i] |= (1 << bit); - bit--; - if (bit < 0) { - bit = 7; - i++; - } - } - } - if (bit != 7) - i++; - } - } - if (stencil_mask) - continue; - - /* image row*/ - pixel32 = (uint32_t *) (ps_image->data + y * ps_image->stride); - bit = 7; - for (x = 0; x < ps_image->width; x++, pixel32++) { - int r, g, b; - - if (ps_image->format == CAIRO_FORMAT_ARGB32) { - /* At this point ARGB32 images are either opaque or - * bilevel alpha so we don't need to unpremultiply. */ - if (((*pixel32 & 0xff000000) >> 24) == 0) { - r = g = b = 0; - } else { - r = (*pixel32 & 0x00ff0000) >> 16; - g = (*pixel32 & 0x0000ff00) >> 8; - b = (*pixel32 & 0x000000ff) >> 0; - } - } else if (ps_image->format == CAIRO_FORMAT_RGB24) { - r = (*pixel32 & 0x00ff0000) >> 16; - g = (*pixel32 & 0x0000ff00) >> 8; - b = (*pixel32 & 0x000000ff) >> 0; - } else { - r = g = b = 0; - } - - switch (color) { - case CAIRO_IMAGE_IS_COLOR: - case CAIRO_IMAGE_UNKNOWN_COLOR: - data[i++] = r; - data[i++] = g; - data[i++] = b; - break; - - case CAIRO_IMAGE_IS_GRAYSCALE: - data[i++] = r; - break; - - case CAIRO_IMAGE_IS_MONOCHROME: - if (bit == 7) - data[i] = 0; - if (r != 0) - data[i] |= (1 << bit); - bit--; - if (bit < 0) { - bit = 7; - i++; - } - break; - } - } - if (bit != 7) - i++; - } - - if (surface->ps_level == CAIRO_PS_LEVEL_2) { - compress = CAIRO_PS_COMPRESS_LZW; - compress_filter = "LZWDecode"; - } else { - compress = CAIRO_PS_COMPRESS_DEFLATE; - compress_filter = "FlateDecode"; - surface->ps_level_used = CAIRO_PS_LEVEL_3; - } - - if (surface->use_string_datasource) { - /* 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, - "/CairoImageData [\n"); - - status = _cairo_ps_surface_emit_base85_string (surface, - data, - data_size, - compress, - TRUE); - if (unlikely (status)) - goto bail2; - - _cairo_output_stream_printf (surface->stream, - "] def\n"); - _cairo_output_stream_printf (surface->stream, - "/CairoImageDataIndex 0 def\n"); - } - - if (use_mask) { - _cairo_output_stream_printf (surface->stream, - "%s setcolorspace\n" - "5 dict dup begin\n" - " /ImageType 3 def\n" - " /InterleaveType 2 def\n" - " /DataDict 8 dict def\n" - " DataDict begin\n" - " /ImageType 1 def\n" - " /Width %d def\n" - " /Height %d def\n" - " /Interpolate %s def\n" - " /BitsPerComponent %d def\n" - " /Decode [ %s ] def\n", - color == CAIRO_IMAGE_IS_COLOR ? "/DeviceRGB" : "/DeviceGray", - ps_image->width, - ps_image->height, - interpolate, - color == CAIRO_IMAGE_IS_MONOCHROME ? 1 : 8, - color == CAIRO_IMAGE_IS_COLOR ? "0 1 0 1 0 1" : "0 1"); - - if (surface->use_string_datasource) { - _cairo_output_stream_printf (surface->stream, - " /DataSource {\n" - " CairoImageData CairoImageDataIndex get\n" - " /CairoImageDataIndex CairoImageDataIndex 1 add def\n" - " CairoImageDataIndex CairoImageData length 1 sub gt\n" - " { /CairoImageDataIndex 0 def } if\n" - " } /ASCII85Decode filter /%s filter def\n", - compress_filter); - } else { - _cairo_output_stream_printf (surface->stream, - " /DataSource currentfile /ASCII85Decode filter /%s filter def\n", - compress_filter); - } - - _cairo_output_stream_printf (surface->stream, - " /ImageMatrix [ 1 0 0 -1 0 %d ] def\n" - " end\n" - " /MaskDict 8 dict def\n" - " MaskDict begin\n" - " /ImageType 1 def\n" - " /Width %d def\n" - " /Height %d def\n" - " /Interpolate %s def\n" - " /BitsPerComponent 1 def\n" - " /Decode [ 1 0 ] def\n" - " /ImageMatrix [ 1 0 0 -1 0 %d ] def\n" - " end\n" - "end\n" - "image\n", - ps_image->height, - ps_image->width, - ps_image->height, - interpolate, - ps_image->height); - } else { - if (!stencil_mask) { - _cairo_output_stream_printf (surface->stream, - "%s setcolorspace\n", - color == CAIRO_IMAGE_IS_COLOR ? "/DeviceRGB" : "/DeviceGray"); - } - _cairo_output_stream_printf (surface->stream, - "8 dict dup begin\n" - " /ImageType 1 def\n" - " /Width %d def\n" - " /Height %d def\n" - " /Interpolate %s def\n" - " /BitsPerComponent %d def\n" - " /Decode [ %s ] def\n", - ps_image->width, - ps_image->height, - interpolate, - color == CAIRO_IMAGE_IS_MONOCHROME ? 1 : 8, - stencil_mask ? "1 0" : color == CAIRO_IMAGE_IS_COLOR ? "0 1 0 1 0 1" : "0 1"); - if (surface->use_string_datasource) { - _cairo_output_stream_printf (surface->stream, - " /DataSource {\n" - " CairoImageData CairoImageDataIndex get\n" - " /CairoImageDataIndex CairoImageDataIndex 1 add def\n" - " CairoImageDataIndex CairoImageData length 1 sub gt\n" - " { /CairoImageDataIndex 0 def } if\n" - " } /ASCII85Decode filter /%s filter def\n", - compress_filter); - } else { - _cairo_output_stream_printf (surface->stream, - " /DataSource currentfile /ASCII85Decode filter /%s filter def\n", - compress_filter); - } - - _cairo_output_stream_printf (surface->stream, - " /ImageMatrix [ 1 0 0 -1 0 %d ] def\n" - "end\n" - "%s\n", - ps_image->height, - stencil_mask ? "imagemask" : "image"); - } - - if (!surface->use_string_datasource) { - /* Emit the image data as a base85-encoded string which will - * be used as the data source for the image operator. */ - status = _cairo_ps_surface_emit_base85_string (surface, - data, - data_size, - compress, - FALSE); - _cairo_output_stream_printf (surface->stream, "\n"); - } else { - status = CAIRO_STATUS_SUCCESS; - } - -bail2: - free (data); - -bail1: - if (!use_mask && ps_image != image) - cairo_surface_destroy (&ps_image->base); - -bail0: - if (image != image_surf) - cairo_surface_destroy (&image->base); - - return status; -} - -static cairo_status_t -_cairo_ps_surface_emit_jpeg_image (cairo_ps_surface_t *surface, - cairo_surface_t *source, - int width, - int height) -{ - cairo_status_t status; - const unsigned char *mime_data; - unsigned long mime_data_length; - cairo_image_info_t info; - const char *colorspace; - const char *decode; - - cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JPEG, - &mime_data, &mime_data_length); - if (unlikely (source->status)) - return source->status; - if (mime_data == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_image_info_get_jpeg_info (&info, mime_data, mime_data_length); - if (unlikely (status)) - return status; - - switch (info.num_components) { - case 1: - colorspace = "/DeviceGray"; - decode = "0 1"; - break; - case 3: - colorspace = "/DeviceRGB"; - decode = "0 1 0 1 0 1"; - break; - case 4: - colorspace = "/DeviceCMYK"; - decode = "0 1 0 1 0 1 0 1"; - break; - default: - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - if (surface->use_string_datasource) { - /* 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, - "/CairoImageData [\n"); - - status = _cairo_ps_surface_emit_base85_string (surface, - mime_data, - mime_data_length, - CAIRO_PS_COMPRESS_NONE, - TRUE); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->stream, - "] def\n"); - _cairo_output_stream_printf (surface->stream, - "/CairoImageDataIndex 0 def\n"); - } - - _cairo_output_stream_printf (surface->stream, - "%s setcolorspace\n" - "8 dict dup begin\n" - " /ImageType 1 def\n" - " /Width %d def\n" - " /Height %d def\n" - " /BitsPerComponent %d def\n" - " /Decode [ %s ] def\n", - colorspace, - info.width, - info.height, - info.bits_per_component, - decode); - - if (surface->use_string_datasource) { - _cairo_output_stream_printf (surface->stream, - " /DataSource {\n" - " CairoImageData CairoImageDataIndex get\n" - " /CairoImageDataIndex CairoImageDataIndex 1 add def\n" - " CairoImageDataIndex CairoImageData length 1 sub gt\n" - " { /CairoImageDataIndex 0 def } if\n" - " } /ASCII85Decode filter /DCTDecode filter def\n"); - } else { - _cairo_output_stream_printf (surface->stream, - " /DataSource currentfile /ASCII85Decode filter /DCTDecode filter def\n"); - } - - _cairo_output_stream_printf (surface->stream, - " /ImageMatrix [ 1 0 0 -1 0 %d ] def\n" - "end\n" - "image\n", - info.height); - - if (!surface->use_string_datasource) { - /* Emit the image data as a base85-encoded string which will - * be used as the data source for the image operator. */ - status = _cairo_ps_surface_emit_base85_string (surface, - mime_data, - mime_data_length, - CAIRO_PS_COMPRESS_NONE, - FALSE); - } - - return status; -} - -static cairo_status_t -_cairo_ps_surface_emit_recording_surface (cairo_ps_surface_t *surface, - cairo_surface_t *recording_surface) -{ - double old_width, old_height; - cairo_matrix_t old_cairo_to_ps; - cairo_content_t old_content; - cairo_rectangle_int_t old_page_bbox; - cairo_surface_t *free_me = NULL; - cairo_surface_clipper_t old_clipper; - cairo_box_t bbox; - cairo_int_status_t status; - - old_content = surface->content; - old_width = surface->width; - old_height = surface->height; - old_page_bbox = surface->page_bbox; - old_cairo_to_ps = surface->cairo_to_ps; - old_clipper = surface->clipper; - _cairo_surface_clipper_init (&surface->clipper, - _cairo_ps_surface_clipper_intersect_clip_path); - - if (_cairo_surface_is_snapshot (recording_surface)) - free_me = recording_surface = _cairo_surface_snapshot_get_target (recording_surface); - - status = - _cairo_recording_surface_get_bbox ((cairo_recording_surface_t *) recording_surface, - &bbox, - NULL); - if (unlikely (status)) - goto err; - -#if DEBUG_PS - _cairo_output_stream_printf (surface->stream, - "%% _cairo_ps_surface_emit_recording_surface (%f, %f), (%f, %f)\n", - _cairo_fixed_to_double (bbox.p1.x), - _cairo_fixed_to_double (bbox.p1.y), - _cairo_fixed_to_double (bbox.p2.x), - _cairo_fixed_to_double (bbox.p2.y)); -#endif - - surface->width = _cairo_fixed_to_double (bbox.p2.x - bbox.p1.x); - surface->height = _cairo_fixed_to_double (bbox.p2.y - bbox.p1.y); - _cairo_box_round_to_rectangle (&bbox, &surface->page_bbox); - - surface->current_pattern_is_solid_color = FALSE; - _cairo_pdf_operators_reset (&surface->pdf_operators); - cairo_matrix_init (&surface->cairo_to_ps, 1, 0, 0, -1, 0, surface->height); - _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators, - &surface->cairo_to_ps); - _cairo_output_stream_printf (surface->stream, " q\n"); - - if (recording_surface->content == CAIRO_CONTENT_COLOR) { - surface->content = CAIRO_CONTENT_COLOR; - _cairo_output_stream_printf (surface->stream, - " 0 g %d %d %d %d rectfill\n", - surface->page_bbox.x, - surface->page_bbox.y, - surface->page_bbox.width, - surface->page_bbox.height); - } - - status = _cairo_recording_surface_replay_region (recording_surface, - NULL, - &surface->base, - CAIRO_RECORDING_REGION_NATIVE); - assert (status != CAIRO_INT_STATUS_UNSUPPORTED); - if (unlikely (status)) - goto err; - - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - goto err; - - _cairo_output_stream_printf (surface->stream, " Q\n"); - - _cairo_surface_clipper_reset (&surface->clipper); - surface->clipper = old_clipper; - surface->content = old_content; - surface->width = old_width; - surface->height = old_height; - surface->page_bbox = old_page_bbox; - surface->current_pattern_is_solid_color = FALSE; - _cairo_pdf_operators_reset (&surface->pdf_operators); - surface->cairo_to_ps = old_cairo_to_ps; - - _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators, - &surface->cairo_to_ps); - -err: - cairo_surface_destroy (free_me); - return status; -} - -static cairo_int_status_t -_cairo_ps_surface_emit_recording_subsurface (cairo_ps_surface_t *surface, - cairo_surface_t *recording_surface, - const cairo_rectangle_int_t *extents) -{ - double old_width, old_height; - cairo_matrix_t old_cairo_to_ps; - cairo_content_t old_content; - cairo_rectangle_int_t old_page_bbox; - cairo_surface_clipper_t old_clipper; - cairo_surface_t *free_me = NULL; - cairo_int_status_t status; - - old_content = surface->content; - old_width = surface->width; - old_height = surface->height; - old_page_bbox = surface->page_bbox; - old_cairo_to_ps = surface->cairo_to_ps; - old_clipper = surface->clipper; - _cairo_surface_clipper_init (&surface->clipper, - _cairo_ps_surface_clipper_intersect_clip_path); - -#if DEBUG_PS - _cairo_output_stream_printf (surface->stream, - "%% _cairo_ps_surface_emit_recording_subsurface (%d, %d), (%d, %d)\n", - extents->x, extents->y, - extents->width, extents->height); -#endif - - surface->page_bbox.x = surface->page_bbox.y = 0; - surface->page_bbox.width = surface->width = extents->width; - surface->page_bbox.height = surface->height = extents->height; - - surface->current_pattern_is_solid_color = FALSE; - _cairo_pdf_operators_reset (&surface->pdf_operators); - cairo_matrix_init (&surface->cairo_to_ps, 1, 0, 0, -1, 0, surface->height); - _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators, - &surface->cairo_to_ps); - _cairo_output_stream_printf (surface->stream, " q\n"); - - if (_cairo_surface_is_snapshot (recording_surface)) - free_me = recording_surface = _cairo_surface_snapshot_get_target (recording_surface); - - if (recording_surface->content == CAIRO_CONTENT_COLOR) { - surface->content = CAIRO_CONTENT_COLOR; - _cairo_output_stream_printf (surface->stream, - " 0 g %d %d %d %d rectfill\n", - surface->page_bbox.x, - surface->page_bbox.y, - surface->page_bbox.width, - surface->page_bbox.height); - } - - status = _cairo_recording_surface_replay_region (recording_surface, - extents, - &surface->base, - CAIRO_RECORDING_REGION_NATIVE); - assert (status != CAIRO_INT_STATUS_UNSUPPORTED); - if (unlikely (status)) - goto err; - - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - goto err; - - _cairo_output_stream_printf (surface->stream, " Q\n"); - - _cairo_surface_clipper_reset (&surface->clipper); - surface->clipper = old_clipper; - surface->content = old_content; - surface->width = old_width; - surface->height = old_height; - surface->page_bbox = old_page_bbox; - surface->current_pattern_is_solid_color = FALSE; - _cairo_pdf_operators_reset (&surface->pdf_operators); - surface->cairo_to_ps = old_cairo_to_ps; - - _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators, - &surface->cairo_to_ps); - -err: - cairo_surface_destroy (free_me); - return status; -} - -static void -_cairo_ps_surface_flatten_transparency (cairo_ps_surface_t *surface, - const cairo_color_t *color, - double *red, - double *green, - double *blue) -{ - *red = color->red; - *green = color->green; - *blue = color->blue; - - if (! CAIRO_COLOR_IS_OPAQUE (color)) { - *red *= color->alpha; - *green *= color->alpha; - *blue *= color->alpha; - if (surface->content == CAIRO_CONTENT_COLOR_ALPHA) { - double one_minus_alpha = 1. - color->alpha; - *red += one_minus_alpha; - *green += one_minus_alpha; - *blue += one_minus_alpha; - } - } -} - -static void -_cairo_ps_surface_emit_solid_pattern (cairo_ps_surface_t *surface, - cairo_solid_pattern_t *pattern) -{ - double red, green, blue; - - _cairo_ps_surface_flatten_transparency (surface, &pattern->color, &red, &green, &blue); - - if (color_is_gray (red, green, blue)) - _cairo_output_stream_printf (surface->stream, - "%f g\n", - red); - else - _cairo_output_stream_printf (surface->stream, - "%f %f %f rg\n", - red, green, blue); -} - -static cairo_status_t -_cairo_ps_surface_emit_surface (cairo_ps_surface_t *surface, - cairo_pattern_t *source_pattern, - cairo_surface_t *source_surface, - cairo_operator_t op, - int width, - int height, - cairo_bool_t stencil_mask) -{ - cairo_int_status_t status; - - if (source_pattern->type == CAIRO_PATTERN_TYPE_SURFACE && - source_pattern->extend != CAIRO_EXTEND_PAD) - { - cairo_surface_t *surf = ((cairo_surface_pattern_t *) source_pattern)->surface; - - status = _cairo_ps_surface_emit_jpeg_image (surface, surf, width, height); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - } - - if (source_surface->type == CAIRO_SURFACE_TYPE_RECORDING) { - if (source_surface->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) { - cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) source_surface; - status = _cairo_ps_surface_emit_recording_subsurface (surface, sub->target, &sub->extents); - } else { - status = _cairo_ps_surface_emit_recording_surface (surface, source_surface); - } - } else { - cairo_image_surface_t *image = (cairo_image_surface_t *) source_surface; - - status = _cairo_ps_surface_emit_image (surface, image, - op, source_pattern->filter, stencil_mask); - } - - return status; -} - - -static void -_path_fixed_init_rectangle (cairo_path_fixed_t *path, - cairo_rectangle_int_t *rect) -{ - cairo_status_t status; - - _cairo_path_fixed_init (path); - - status = _cairo_path_fixed_move_to (path, - _cairo_fixed_from_int (rect->x), - _cairo_fixed_from_int (rect->y)); - assert (status == CAIRO_STATUS_SUCCESS); - status = _cairo_path_fixed_rel_line_to (path, - _cairo_fixed_from_int (rect->width), - _cairo_fixed_from_int (0)); - assert (status == CAIRO_STATUS_SUCCESS); - status = _cairo_path_fixed_rel_line_to (path, - _cairo_fixed_from_int (0), - _cairo_fixed_from_int (rect->height)); - assert (status == CAIRO_STATUS_SUCCESS); - status = _cairo_path_fixed_rel_line_to (path, - _cairo_fixed_from_int (-rect->width), - _cairo_fixed_from_int (0)); - assert (status == CAIRO_STATUS_SUCCESS); - - status = _cairo_path_fixed_close_path (path); - assert (status == CAIRO_STATUS_SUCCESS); -} - -static cairo_status_t -_cairo_ps_surface_paint_surface (cairo_ps_surface_t *surface, - cairo_pattern_t *pattern, - cairo_rectangle_int_t *extents, - cairo_operator_t op, - cairo_bool_t stencil_mask) -{ - cairo_status_t status; - int width, height; - cairo_matrix_t cairo_p2d, ps_p2d; - cairo_path_fixed_t path; - double x_offset, y_offset; - cairo_surface_t *source; - cairo_image_surface_t *image = NULL; - void *image_extra; - - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - return status; - - status = _cairo_ps_surface_acquire_source_surface_from_pattern (surface, - pattern, - extents, - &width, &height, - &x_offset, &y_offset, - &source, - &image_extra); - if (unlikely (status)) - return status; - - if (pattern->extend == CAIRO_EXTEND_PAD && - pattern->type == CAIRO_PATTERN_TYPE_SURFACE && - ((cairo_surface_pattern_t *)pattern)->surface->type == CAIRO_SURFACE_TYPE_IMAGE) { - cairo_image_surface_t *img; - - img = (cairo_image_surface_t *) source; - status = _cairo_ps_surface_create_padded_image_from_image (surface, - img, - &pattern->matrix, - extents, - &width, &height, - &x_offset, &y_offset, - &image); - if (unlikely (status)) - goto release_source; - } - - _path_fixed_init_rectangle (&path, extents); - status = _cairo_pdf_operators_clip (&surface->pdf_operators, - &path, - CAIRO_FILL_RULE_WINDING); - _cairo_path_fixed_fini (&path); - if (unlikely (status)) - goto release_source; - - cairo_p2d = pattern->matrix; - - if (surface->paginated_mode == CAIRO_PAGINATED_MODE_FALLBACK) { - double x_scale = cairo_p2d.xx; - double y_scale = cairo_p2d.yy; - - _cairo_output_stream_printf (surface->stream, - "%% Fallback Image: x=%f y=%f w=%d h=%d ", - -cairo_p2d.x0/x_scale, - -cairo_p2d.y0/y_scale, - (int)(width/x_scale), - (int)(height/y_scale)); - if (x_scale == y_scale) { - _cairo_output_stream_printf (surface->stream, - "res=%fppi ", - x_scale*72); - } else { - _cairo_output_stream_printf (surface->stream, - "res=%fx%fppi ", - x_scale*72, - y_scale*72); - } - _cairo_output_stream_printf (surface->stream, - "size=%ld\n", - (long)width*height*3); - } else { - if (op == CAIRO_OPERATOR_SOURCE) { - _cairo_output_stream_printf (surface->stream, - "%d g 0 0 %f %f rectfill\n", - surface->content == CAIRO_CONTENT_COLOR ? 0 : 1, - surface->width, - surface->height); - } - } - - status = cairo_matrix_invert (&cairo_p2d); - /* cairo_pattern_set_matrix ensures the matrix is invertible */ - assert (status == CAIRO_STATUS_SUCCESS); - - ps_p2d = surface->cairo_to_ps; - cairo_matrix_multiply (&ps_p2d, &cairo_p2d, &ps_p2d); - cairo_matrix_translate (&ps_p2d, x_offset, y_offset); - cairo_matrix_translate (&ps_p2d, 0.0, height); - cairo_matrix_scale (&ps_p2d, 1.0, -1.0); - - if (! _cairo_matrix_is_identity (&ps_p2d)) { - _cairo_output_stream_printf (surface->stream, "[ "); - _cairo_output_stream_print_matrix (surface->stream, &ps_p2d); - _cairo_output_stream_printf (surface->stream, " ] concat\n"); - } - - status = _cairo_ps_surface_emit_surface (surface, - pattern, - image ? &image->base : source, - op, - width, height, - stencil_mask); - - release_source: - if (image) - cairo_surface_destroy (&image->base); - - _cairo_ps_surface_release_source_surface_from_pattern (surface, pattern, source, image_extra); - - return status; -} - -static cairo_status_t -_cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface, - cairo_pattern_t *pattern, - cairo_rectangle_int_t *extents, - cairo_operator_t op) -{ - cairo_status_t status; - int pattern_width = 0; /* squelch bogus compiler warning */ - int pattern_height = 0; /* squelch bogus compiler warning */ - double xstep, ystep; - cairo_matrix_t cairo_p2d, ps_p2d; - cairo_bool_t old_use_string_datasource; - double x_offset, y_offset; - cairo_surface_t *source; - cairo_image_surface_t *image = NULL; - void *image_extra; - - cairo_p2d = pattern->matrix; - status = cairo_matrix_invert (&cairo_p2d); - /* cairo_pattern_set_matrix ensures the matrix is invertible */ - assert (status == CAIRO_STATUS_SUCCESS); - - status = _cairo_ps_surface_acquire_source_surface_from_pattern (surface, - pattern, - extents, - &pattern_width, &pattern_height, - &x_offset, &y_offset, - &source, - &image_extra); - if (unlikely (status)) - return status; - - if (pattern->extend == CAIRO_EXTEND_PAD) { - cairo_image_surface_t *img; - - assert (source->type == CAIRO_SURFACE_TYPE_IMAGE); - img = (cairo_image_surface_t *) source; - status = _cairo_ps_surface_create_padded_image_from_image (surface, - img, - &pattern->matrix, - extents, - &pattern_width, &pattern_height, - &x_offset, &y_offset, - &image); - if (unlikely (status)) - goto release_source; - } - if (unlikely (status)) - goto release_source; - - switch (pattern->extend) { - case CAIRO_EXTEND_PAD: - case CAIRO_EXTEND_NONE: - { - /* In PS/PDF, (as far as I can tell), all patterns are - * repeating. So we support cairo's EXTEND_NONE semantics - * by setting the repeat step size to a size large enough - * to guarantee that no more than a single occurrence will - * be visible. - * - * First, map the surface extents into pattern space (since - * xstep and ystep are in pattern space). Then use an upper - * bound on the length of the diagonal of the pattern image - * and the surface as repeat size. This guarantees to never - * repeat visibly. - */ - double x1 = 0.0, y1 = 0.0; - double x2 = surface->width, y2 = surface->height; - _cairo_matrix_transform_bounding_box (&pattern->matrix, - &x1, &y1, &x2, &y2, - NULL); - - /* Rather than computing precise bounds of the union, just - * add the surface extents unconditionally. We only - * required an answer that's large enough, we don't really - * care if it's not as tight as possible.*/ - xstep = ystep = ceil ((x2 - x1) + (y2 - y1) + - pattern_width + pattern_height); - break; - } - case CAIRO_EXTEND_REPEAT: - xstep = pattern_width; - ystep = pattern_height; - break; - case CAIRO_EXTEND_REFLECT: - xstep = pattern_width*2; - ystep = pattern_height*2; - break; - /* All the rest (if any) should have been analyzed away, so these - * cases should be unreachable. */ - default: - ASSERT_NOT_REACHED; - xstep = 0; - ystep = 0; - } - - _cairo_output_stream_printf (surface->stream, - "/CairoPattern {\n"); - - old_use_string_datasource = surface->use_string_datasource; - surface->use_string_datasource = TRUE; - if (op == CAIRO_OPERATOR_SOURCE) { - _cairo_output_stream_printf (surface->stream, - "%d g 0 0 %f %f rectfill\n", - surface->content == CAIRO_CONTENT_COLOR ? 0 : 1, - xstep, ystep); - } - status = _cairo_ps_surface_emit_surface (surface, - pattern, - image ? &image->base : source, - op, - pattern_width, pattern_height, FALSE); - if (unlikely (status)) - goto release_source; - - surface->use_string_datasource = old_use_string_datasource; - _cairo_output_stream_printf (surface->stream, - "} bind def\n"); - - _cairo_output_stream_printf (surface->stream, - "<< /PatternType 1\n" - " /PaintType 1\n" - " /TilingType 1\n"); - _cairo_output_stream_printf (surface->stream, - " /XStep %f /YStep %f\n", - xstep, ystep); - - if (pattern->extend == CAIRO_EXTEND_REFLECT) { - _cairo_output_stream_printf (surface->stream, - " /BBox [0 0 %d %d]\n" - " /PaintProc {\n" - " pop CairoPattern\n" - " [-1 0 0 1 %d 0] concat CairoPattern\n" - " [ 1 0 0 -1 0 %d] concat CairoPattern\n" - " [-1 0 0 1 %d 0] concat CairoPattern\n" - " CairoPattern\n" - " } bind\n", - pattern_width*2, pattern_height*2, - pattern_width*2, - pattern_height*2, - pattern_width*2); - } else { - if (op == CAIRO_OPERATOR_SOURCE) { - _cairo_output_stream_printf (surface->stream, - " /BBox [0 0 %f %f]\n", - xstep, ystep); - } else { - _cairo_output_stream_printf (surface->stream, - " /BBox [0 0 %d %d]\n", - pattern_width, pattern_height); - } - _cairo_output_stream_printf (surface->stream, - " /PaintProc { pop CairoPattern }\n"); - } - - _cairo_output_stream_printf (surface->stream, - ">>\n"); - - cairo_p2d = pattern->matrix; - status = cairo_matrix_invert (&cairo_p2d); - /* cairo_pattern_set_matrix ensures the matrix is invertible */ - assert (status == CAIRO_STATUS_SUCCESS); - - cairo_matrix_init_identity (&ps_p2d); - cairo_matrix_translate (&ps_p2d, 0.0, surface->height); - cairo_matrix_scale (&ps_p2d, 1.0, -1.0); - cairo_matrix_multiply (&ps_p2d, &cairo_p2d, &ps_p2d); - cairo_matrix_translate (&ps_p2d, 0.0, pattern_height); - cairo_matrix_scale (&ps_p2d, 1.0, -1.0); - - _cairo_output_stream_printf (surface->stream, "[ "); - _cairo_output_stream_print_matrix (surface->stream, &ps_p2d); - _cairo_output_stream_printf (surface->stream, - " ]\n" - "makepattern setpattern\n"); - - release_source: - if (image) - cairo_surface_destroy (&image->base); - - _cairo_ps_surface_release_source_surface_from_pattern (surface, pattern, source, image_extra); - - return status; -} - -typedef struct _cairo_ps_color_stop { - double offset; - double color[4]; -} cairo_ps_color_stop_t; - -static void -_cairo_ps_surface_emit_linear_colorgradient (cairo_ps_surface_t *surface, - cairo_ps_color_stop_t *stop1, - cairo_ps_color_stop_t *stop2) -{ - _cairo_output_stream_printf (surface->stream, - " << /FunctionType 2\n" - " /Domain [ 0 1 ]\n" - " /C0 [ %f %f %f ]\n" - " /C1 [ %f %f %f ]\n" - " /N 1\n" - " >>\n", - stop1->color[0], - stop1->color[1], - stop1->color[2], - stop2->color[0], - stop2->color[1], - stop2->color[2]); -} - -static void -_cairo_ps_surface_emit_stitched_colorgradient (cairo_ps_surface_t *surface, - unsigned int n_stops, - cairo_ps_color_stop_t stops[]) -{ - unsigned int i; - - _cairo_output_stream_printf (surface->stream, - "<< /FunctionType 3\n" - " /Domain [ 0 1 ]\n" - " /Functions [\n"); - for (i = 0; i < n_stops - 1; i++) - _cairo_ps_surface_emit_linear_colorgradient (surface, &stops[i], &stops[i+1]); - - _cairo_output_stream_printf (surface->stream, " ]\n"); - - _cairo_output_stream_printf (surface->stream, " /Bounds [ "); - for (i = 1; i < n_stops-1; i++) - _cairo_output_stream_printf (surface->stream, "%f ", stops[i].offset); - _cairo_output_stream_printf (surface->stream, "]\n"); - - _cairo_output_stream_printf (surface->stream, " /Encode [ 1 1 %d { pop 0 1 } for ]\n", - n_stops - 1); - - _cairo_output_stream_printf (surface->stream, ">>\n"); -} - -static void -calc_gradient_color (cairo_ps_color_stop_t *new_stop, - cairo_ps_color_stop_t *stop1, - cairo_ps_color_stop_t *stop2) -{ - int i; - double offset = stop1->offset / (stop1->offset + 1.0 - stop2->offset); - - for (i = 0; i < 4; i++) - new_stop->color[i] = stop1->color[i] + offset*(stop2->color[i] - stop1->color[i]); -} - -#define COLOR_STOP_EPSILON 1e-6 - -static cairo_status_t -_cairo_ps_surface_emit_pattern_stops (cairo_ps_surface_t *surface, - cairo_gradient_pattern_t *pattern) -{ - cairo_ps_color_stop_t *allstops, *stops; - unsigned int i, n_stops; - - allstops = _cairo_malloc_ab ((pattern->n_stops + 2), sizeof (cairo_ps_color_stop_t)); - if (unlikely (allstops == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - stops = &allstops[1]; - n_stops = pattern->n_stops; - - for (i = 0; i < n_stops; i++) { - cairo_gradient_stop_t *stop = &pattern->stops[i]; - - stops[i].color[0] = stop->color.red; - stops[i].color[1] = stop->color.green; - stops[i].color[2] = stop->color.blue; - stops[i].color[3] = stop->color.alpha; - stops[i].offset = pattern->stops[i].offset; - } - - if (pattern->base.extend == CAIRO_EXTEND_REPEAT || - pattern->base.extend == CAIRO_EXTEND_REFLECT) - { - if (stops[0].offset > COLOR_STOP_EPSILON) { - if (pattern->base.extend == CAIRO_EXTEND_REFLECT) - memcpy (allstops, stops, sizeof (cairo_ps_color_stop_t)); - else - calc_gradient_color (&allstops[0], &stops[0], &stops[n_stops-1]); - stops = allstops; - n_stops++; - } - stops[0].offset = 0.0; - - if (stops[n_stops-1].offset < 1.0 - COLOR_STOP_EPSILON) { - if (pattern->base.extend == CAIRO_EXTEND_REFLECT) { - memcpy (&stops[n_stops], - &stops[n_stops - 1], - sizeof (cairo_ps_color_stop_t)); - } else { - calc_gradient_color (&stops[n_stops], &stops[0], &stops[n_stops-1]); - } - n_stops++; - } - stops[n_stops-1].offset = 1.0; - } - - for (i = 0; i < n_stops; i++) { - double red, green, blue; - cairo_color_t color; - - _cairo_color_init_rgba (&color, - stops[i].color[0], - stops[i].color[1], - stops[i].color[2], - stops[i].color[3]); - _cairo_ps_surface_flatten_transparency (surface, &color, - &red, &green, &blue); - stops[i].color[0] = red; - stops[i].color[1] = green; - stops[i].color[2] = blue; - } - - _cairo_output_stream_printf (surface->stream, - "/CairoFunction\n"); - if (stops[0].offset == stops[n_stops - 1].offset) { - /* - * The first and the last stops have the same offset, but we - * don't want a function with an empty domain, because that - * would provoke underdefined behaviour from rasterisers. - * This can only happen with EXTEND_PAD, because EXTEND_NONE - * is optimised into a clear pattern in cairo-gstate, and - * REFLECT/REPEAT are always transformed to have the first - * stop at t=0 and the last stop at t=1. Thus we want a step - * function going from the first color to the last one. - * - * This can be accomplished by stitching three functions: - * - a constant first color function, - * - a step from the first color to the last color (with empty domain) - * - a constant last color function - */ - cairo_ps_color_stop_t pad_stops[4]; - - assert (pattern->base.extend == CAIRO_EXTEND_PAD); - - pad_stops[0] = pad_stops[1] = stops[0]; - pad_stops[2] = pad_stops[3] = stops[n_stops - 1]; - - pad_stops[0].offset = 0; - pad_stops[3].offset = 1; - - _cairo_ps_surface_emit_stitched_colorgradient (surface, 4, pad_stops); - } else if (n_stops == 2) { - /* no need for stitched function */ - _cairo_ps_surface_emit_linear_colorgradient (surface, &stops[0], &stops[1]); - } else { - /* multiple stops: stitch. XXX possible optimization: regulary spaced - * stops do not require stitching. XXX */ - _cairo_ps_surface_emit_stitched_colorgradient (surface, n_stops, stops); - } - _cairo_output_stream_printf (surface->stream, - "def\n"); - - free (allstops); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_ps_surface_emit_repeating_function (cairo_ps_surface_t *surface, - cairo_gradient_pattern_t *pattern, - int begin, - int end) -{ - _cairo_output_stream_printf (surface->stream, - "/CairoFunction\n" - "<< /FunctionType 3\n" - " /Domain [ %d %d ]\n" - " /Functions [ %d {CairoFunction} repeat ]\n" - " /Bounds [ %d 1 %d {} for ]\n", - begin, - end, - end - begin, - begin + 1, - end - 1); - - if (pattern->base.extend == CAIRO_EXTEND_REFLECT) { - _cairo_output_stream_printf (surface->stream, " /Encode [ %d 1 %d { 2 mod 0 eq {0 1} {1 0} ifelse } for ]\n", - begin, - end - 1); - } else { - _cairo_output_stream_printf (surface->stream, " /Encode [ %d 1 %d { pop 0 1 } for ]\n", - begin, - end - 1); - } - - _cairo_output_stream_printf (surface->stream, ">> def\n"); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_ps_surface_emit_gradient (cairo_ps_surface_t *surface, - cairo_gradient_pattern_t *pattern, - cairo_bool_t is_ps_pattern) -{ - cairo_matrix_t pat_to_ps; - cairo_circle_double_t start, end; - double domain[2]; - cairo_status_t status; - - assert (pattern->n_stops != 0); - - status = _cairo_ps_surface_emit_pattern_stops (surface, pattern); - if (unlikely (status)) - return status; - - pat_to_ps = pattern->base.matrix; - status = cairo_matrix_invert (&pat_to_ps); - /* cairo_pattern_set_matrix ensures the matrix is invertible */ - assert (status == CAIRO_STATUS_SUCCESS); - cairo_matrix_multiply (&pat_to_ps, &pat_to_ps, &surface->cairo_to_ps); - - if (pattern->base.extend == CAIRO_EXTEND_REPEAT || - pattern->base.extend == CAIRO_EXTEND_REFLECT) - { - double bounds_x1, bounds_x2, bounds_y1, bounds_y2; - double x_scale, y_scale, tolerance; - - /* TODO: use tighter extents */ - bounds_x1 = 0; - bounds_y1 = 0; - bounds_x2 = surface->width; - bounds_y2 = surface->height; - _cairo_matrix_transform_bounding_box (&pattern->base.matrix, - &bounds_x1, &bounds_y1, - &bounds_x2, &bounds_y2, - NULL); - - x_scale = surface->base.x_resolution / surface->base.x_fallback_resolution; - y_scale = surface->base.y_resolution / surface->base.y_fallback_resolution; - - tolerance = fabs (_cairo_matrix_compute_determinant (&pattern->base.matrix)); - tolerance /= _cairo_matrix_transformed_circle_major_axis (&pattern->base.matrix, 1); - tolerance *= MIN (x_scale, y_scale); - - _cairo_gradient_pattern_box_to_parameter (pattern, - bounds_x1, bounds_y1, - bounds_x2, bounds_y2, - tolerance, domain); - } else if (pattern->stops[0].offset == pattern->stops[pattern->n_stops - 1].offset) { - /* - * If the first and the last stop offset are the same, then - * the color function is a step function. - * _cairo_ps_surface_emit_pattern_stops emits it as a stitched - * function no matter how many stops the pattern has. The - * domain of the stitched function will be [0 1] in this case. - * - * This is done to avoid emitting degenerate gradients for - * EXTEND_PAD patterns having a step color function. - */ - domain[0] = 0.0; - domain[1] = 1.0; - - assert (pattern->base.extend == CAIRO_EXTEND_PAD); - } else { - domain[0] = pattern->stops[0].offset; - domain[1] = pattern->stops[pattern->n_stops - 1].offset; - } - - /* PS requires the first and last stop to be the same as the - * extreme coordinates. For repeating patterns this moves the - * extreme coordinates out to the begin/end of the repeating - * function. For non repeating patterns this may move the extreme - * coordinates in if there are not stops at offset 0 and 1. */ - _cairo_gradient_pattern_interpolate (pattern, domain[0], &start); - _cairo_gradient_pattern_interpolate (pattern, domain[1], &end); - - if (pattern->base.extend == CAIRO_EXTEND_REPEAT || - pattern->base.extend == CAIRO_EXTEND_REFLECT) - { - int repeat_begin, repeat_end; - - repeat_begin = floor (domain[0]); - repeat_end = ceil (domain[1]); - - status = _cairo_ps_surface_emit_repeating_function (surface, - pattern, - repeat_begin, - repeat_end); - if (unlikely (status)) - return status; - } else if (pattern->n_stops <= 2) { - /* For EXTEND_NONE and EXTEND_PAD if there are only two stops a - * Type 2 function is used by itself without a stitching - * function. Type 2 functions always have the domain [0 1] */ - domain[0] = 0.0; - domain[1] = 1.0; - } - - if (is_ps_pattern) { - _cairo_output_stream_printf (surface->stream, - "<< /PatternType 2\n" - " /Shading\n"); - } - - if (pattern->base.type == CAIRO_PATTERN_TYPE_LINEAR) { - _cairo_output_stream_printf (surface->stream, - " << /ShadingType 2\n" - " /ColorSpace /DeviceRGB\n" - " /Coords [ %f %f %f %f ]\n", - start.center.x, start.center.y, - end.center.x, end.center.y); - } else { - _cairo_output_stream_printf (surface->stream, - " << /ShadingType 3\n" - " /ColorSpace /DeviceRGB\n" - " /Coords [ %f %f %f %f %f %f ]\n", - start.center.x, start.center.y, - MAX (start.radius, 0), - end.center.x, end.center.y, - MAX (end.radius, 0)); - } - - if (pattern->base.extend != CAIRO_EXTEND_NONE) { - _cairo_output_stream_printf (surface->stream, - " /Extend [ true true ]\n"); - } else { - _cairo_output_stream_printf (surface->stream, - " /Extend [ false false ]\n"); - } - - if (domain[0] == 0.0 && domain[1] == 1.0) { - _cairo_output_stream_printf (surface->stream, - " /Function CairoFunction\n"); - } else { - _cairo_output_stream_printf (surface->stream, - " /Function <<\n" - " /FunctionType 3\n" - " /Domain [ 0 1 ]\n" - " /Bounds [ ]\n" - " /Encode [ %f %f ]\n" - " /Functions [ CairoFunction ]\n" - " >>\n", - domain[0], domain[1]); - } - - _cairo_output_stream_printf (surface->stream, - " >>\n"); - - if (is_ps_pattern) { - _cairo_output_stream_printf (surface->stream, - ">>\n" - "[ "); - _cairo_output_stream_print_matrix (surface->stream, &pat_to_ps); - _cairo_output_stream_printf (surface->stream, " ]\n" - "makepattern setpattern\n"); - } else { - _cairo_output_stream_printf (surface->stream, - "shfill\n"); - } - - return status; -} - -static cairo_status_t -_cairo_ps_surface_emit_mesh_pattern (cairo_ps_surface_t *surface, - cairo_mesh_pattern_t *pattern, - cairo_bool_t is_ps_pattern) -{ - cairo_matrix_t pat_to_ps; - cairo_status_t status; - cairo_pdf_shading_t shading; - int i; - - if (_cairo_array_num_elements (&pattern->patches) == 0) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - pat_to_ps = pattern->base.matrix; - status = cairo_matrix_invert (&pat_to_ps); - /* cairo_pattern_set_matrix ensures the matrix is invertible */ - assert (status == CAIRO_STATUS_SUCCESS); - - cairo_matrix_multiply (&pat_to_ps, &pat_to_ps, &surface->cairo_to_ps); - - status = _cairo_pdf_shading_init_color (&shading, pattern); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->stream, - "currentfile\n" - "/ASCII85Decode filter /FlateDecode filter /ReusableStreamDecode filter\n"); - - status = _cairo_ps_surface_emit_base85_string (surface, - shading.data, - shading.data_length, - CAIRO_PS_COMPRESS_DEFLATE, - FALSE); - if (status) - return status; - - _cairo_output_stream_printf (surface->stream, - "\n" - "/CairoData exch def\n"); - - if (is_ps_pattern) { - _cairo_output_stream_printf (surface->stream, - "<< /PatternType 2\n" - " /Shading\n"); - } - - _cairo_output_stream_printf (surface->stream, - " << /ShadingType %d\n" - " /ColorSpace /DeviceRGB\n" - " /DataSource CairoData\n" - " /BitsPerCoordinate %d\n" - " /BitsPerComponent %d\n" - " /BitsPerFlag %d\n" - " /Decode [", - shading.shading_type, - shading.bits_per_coordinate, - shading.bits_per_component, - shading.bits_per_flag); - - for (i = 0; i < shading.decode_array_length; i++) - _cairo_output_stream_printf (surface->stream, "%f ", shading.decode_array[i]); - - _cairo_output_stream_printf (surface->stream, - "]\n" - " >>\n"); - - if (is_ps_pattern) { - _cairo_output_stream_printf (surface->stream, - ">>\n" - "[ \n"); - _cairo_output_stream_print_matrix (surface->stream, &pat_to_ps); - _cairo_output_stream_printf (surface->stream, - " ]\n" - "makepattern\n" - "setpattern\n"); - } else { - _cairo_output_stream_printf (surface->stream, "shfill\n"); - } - - _cairo_output_stream_printf (surface->stream, - "currentdict /CairoData undef\n"); - - _cairo_pdf_shading_fini (&shading); - - return status; -} - -static cairo_status_t -_cairo_ps_surface_emit_pattern (cairo_ps_surface_t *surface, - const cairo_pattern_t *pattern, - cairo_rectangle_int_t *extents, - cairo_operator_t op) -{ - cairo_status_t status; - - if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) { - cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) pattern; - - if (surface->current_pattern_is_solid_color == FALSE || - ! _cairo_color_equal (&surface->current_color, &solid->color)) - { - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - return status; - - _cairo_ps_surface_emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern); - - surface->current_pattern_is_solid_color = TRUE; - surface->current_color = solid->color; - } - - return CAIRO_STATUS_SUCCESS; - } - - surface->current_pattern_is_solid_color = FALSE; - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - return status; - - switch (pattern->type) { - case CAIRO_PATTERN_TYPE_SOLID: - - _cairo_ps_surface_emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern); - break; - - case CAIRO_PATTERN_TYPE_SURFACE: - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - status = _cairo_ps_surface_emit_surface_pattern (surface, - (cairo_pattern_t *)pattern, - extents, - op); - if (unlikely (status)) - return status; - break; - - case CAIRO_PATTERN_TYPE_LINEAR: - case CAIRO_PATTERN_TYPE_RADIAL: - status = _cairo_ps_surface_emit_gradient (surface, - (cairo_gradient_pattern_t *) pattern, - TRUE); - if (unlikely (status)) - return status; - break; - - case CAIRO_PATTERN_TYPE_MESH: - status = _cairo_ps_surface_emit_mesh_pattern (surface, - (cairo_mesh_pattern_t *) pattern, - TRUE); - if (unlikely (status)) - return status; - break; - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_ps_surface_paint_gradient (cairo_ps_surface_t *surface, - const cairo_pattern_t *source, - const cairo_rectangle_int_t *extents) -{ - cairo_matrix_t pat_to_ps; - cairo_status_t status; - - pat_to_ps = source->matrix; - status = cairo_matrix_invert (&pat_to_ps); - /* cairo_pattern_set_matrix ensures the matrix is invertible */ - assert (status == CAIRO_STATUS_SUCCESS); - cairo_matrix_multiply (&pat_to_ps, &pat_to_ps, &surface->cairo_to_ps); - - if (! _cairo_matrix_is_identity (&pat_to_ps)) { - _cairo_output_stream_printf (surface->stream, "["); - _cairo_output_stream_print_matrix (surface->stream, &pat_to_ps); - _cairo_output_stream_printf (surface->stream, "] concat\n"); - } - - if (source->type == CAIRO_PATTERN_TYPE_MESH) { - status = _cairo_ps_surface_emit_mesh_pattern (surface, - (cairo_mesh_pattern_t *)source, - FALSE); - if (unlikely (status)) - return status; - } else { - status = _cairo_ps_surface_emit_gradient (surface, - (cairo_gradient_pattern_t *)source, - FALSE); - if (unlikely (status)) - return status; - } - - return status; -} - -static cairo_status_t -_cairo_ps_surface_paint_pattern (cairo_ps_surface_t *surface, - const cairo_pattern_t *source, - cairo_rectangle_int_t *extents, - cairo_operator_t op, - cairo_bool_t stencil_mask) -{ - switch (source->type) { - case CAIRO_PATTERN_TYPE_SURFACE: - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - return _cairo_ps_surface_paint_surface (surface, - (cairo_pattern_t *)source, - extents, - op, - stencil_mask); - - case CAIRO_PATTERN_TYPE_LINEAR: - case CAIRO_PATTERN_TYPE_RADIAL: - case CAIRO_PATTERN_TYPE_MESH: - return _cairo_ps_surface_paint_gradient (surface, - source, - extents); - - case CAIRO_PATTERN_TYPE_SOLID: - default: - ASSERT_NOT_REACHED; - return CAIRO_STATUS_SUCCESS; - } -} - -static cairo_bool_t -_can_paint_pattern (const cairo_pattern_t *pattern) -{ - switch (pattern->type) { - case CAIRO_PATTERN_TYPE_SOLID: - return FALSE; - - case CAIRO_PATTERN_TYPE_SURFACE: - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - return (pattern->extend == CAIRO_EXTEND_NONE || - pattern->extend == CAIRO_EXTEND_PAD); - - case CAIRO_PATTERN_TYPE_LINEAR: - case CAIRO_PATTERN_TYPE_RADIAL: - case CAIRO_PATTERN_TYPE_MESH: - return TRUE; - - default: - ASSERT_NOT_REACHED; - return FALSE; - } -} - -static cairo_bool_t -_cairo_ps_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *rectangle) -{ - cairo_ps_surface_t *surface = abstract_surface; - - rectangle->x = 0; - rectangle->y = 0; - - /* XXX: The conversion to integers here is pretty bogus, (not to - * mention the aribitray limitation of width to a short(!). We - * may need to come up with a better interface for get_extents. - */ - rectangle->width = ceil (surface->width); - rectangle->height = ceil (surface->height); - - return TRUE; -} - -static void -_cairo_ps_surface_get_font_options (void *abstract_surface, - cairo_font_options_t *options) -{ - _cairo_font_options_init_default (options); - - cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_NONE); - cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF); - cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_GRAY); - _cairo_font_options_set_round_glyph_positions (options, CAIRO_ROUND_GLYPH_POS_OFF); -} - -static cairo_int_status_t -_cairo_ps_surface_set_clip (cairo_ps_surface_t *surface, - cairo_composite_rectangles_t *composite) -{ - cairo_clip_t *clip = composite->clip; - - if (_cairo_composite_rectangles_can_reduce_clip (composite, clip)) - clip = NULL; - - if (clip == NULL) { - if (_cairo_composite_rectangles_can_reduce_clip (composite, - surface->clipper.clip)) - return CAIRO_STATUS_SUCCESS; - } - - return _cairo_surface_clipper_set_clip (&surface->clipper, clip); -} - -static cairo_int_status_t -_cairo_ps_surface_paint (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - cairo_ps_surface_t *surface = abstract_surface; - cairo_output_stream_t *stream = surface->stream; - cairo_composite_rectangles_t extents; - cairo_status_t status; - - status = _cairo_composite_rectangles_init_for_paint (&extents, - &surface->base, - op, source, clip); - if (unlikely (status)) - return status; - - if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) { - status = _cairo_ps_surface_analyze_operation (surface, op, source, NULL, &extents.bounded); - goto cleanup_composite; - } - - assert (_cairo_ps_surface_operation_supported (surface, op, source, NULL, &extents.bounded)); - -#if DEBUG_PS - _cairo_output_stream_printf (stream, - "%% _cairo_ps_surface_paint\n"); -#endif - - status = _cairo_ps_surface_set_clip (surface, &extents); - if (unlikely (status)) - goto cleanup_composite; - - if (_can_paint_pattern (source)) { - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - goto cleanup_composite; - - _cairo_output_stream_printf (stream, "q\n"); - status = _cairo_ps_surface_paint_pattern (surface, - source, - &extents.bounded, op, FALSE); - if (unlikely (status)) - goto cleanup_composite; - - _cairo_output_stream_printf (stream, "Q\n"); - } else { - status = _cairo_ps_surface_emit_pattern (surface, source, &extents.bounded, op); - if (unlikely (status)) - goto cleanup_composite; - - _cairo_output_stream_printf (stream, "0 0 %f %f rectfill\n", - surface->width, surface->height); - } - -cleanup_composite: - _cairo_composite_rectangles_fini (&extents); - return status; -} - -static cairo_int_status_t -_cairo_ps_surface_mask (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - cairo_ps_surface_t *surface = abstract_surface; - cairo_output_stream_t *stream = surface->stream; - cairo_composite_rectangles_t extents; - cairo_status_t status; - - status = _cairo_composite_rectangles_init_for_mask (&extents, - &surface->base, - op, source, mask, clip); - if (unlikely (status)) - return status; - - if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) { - status = _cairo_ps_surface_analyze_operation (surface, op, source, mask, &extents.bounded); - goto cleanup_composite; - } - - assert (_cairo_ps_surface_operation_supported (surface, op, source, mask, &extents.bounded)); - -#if DEBUG_PS - _cairo_output_stream_printf (stream, - "%% _cairo_ps_surface_mask\n"); -#endif - - status = _cairo_ps_surface_set_clip (surface, &extents); - if (unlikely (status)) - goto cleanup_composite; - - status = _cairo_ps_surface_emit_pattern (surface, source, &extents.bounded, op); - if (unlikely (status)) - goto cleanup_composite; - - _cairo_output_stream_printf (stream, "q\n"); - status = _cairo_ps_surface_paint_pattern (surface, - mask, - &extents.bounded, op, TRUE); - if (unlikely (status)) - goto cleanup_composite; - - _cairo_output_stream_printf (stream, "Q\n"); - -cleanup_composite: - _cairo_composite_rectangles_fini (&extents); - return status; -} - -static cairo_int_status_t -_cairo_ps_surface_stroke (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_ps_surface_t *surface = abstract_surface; - cairo_composite_rectangles_t extents; - cairo_int_status_t status; - - status = _cairo_composite_rectangles_init_for_stroke (&extents, - &surface->base, - op, source, - path, style, ctm, - clip); - if (unlikely (status)) - return status; - - /* use the more accurate extents */ - { - cairo_rectangle_int_t r; - cairo_box_t b; - - status = _cairo_path_fixed_stroke_extents (path, style, - ctm, ctm_inverse, - tolerance, - &r); - if (unlikely (status)) - goto cleanup_composite; - - _cairo_box_from_rectangle (&b, &r); - status = _cairo_composite_rectangles_intersect_mask_extents (&extents, &b); - if (unlikely (status)) - goto cleanup_composite; - } - - if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) { - status = _cairo_ps_surface_analyze_operation (surface, op, source, NULL, &extents.bounded); - goto cleanup_composite; - } - - assert (_cairo_ps_surface_operation_supported (surface, op, source, NULL, &extents.bounded)); - -#if DEBUG_PS - _cairo_output_stream_printf (surface->stream, - "%% _cairo_ps_surface_stroke\n"); -#endif - - status = _cairo_ps_surface_set_clip (surface, &extents); - if (unlikely (status)) - goto cleanup_composite; - - status = _cairo_ps_surface_emit_pattern (surface, source, &extents.bounded, op); - if (unlikely (status)) - goto cleanup_composite; - - status = _cairo_pdf_operators_stroke (&surface->pdf_operators, - path, - style, - ctm, - ctm_inverse); - -cleanup_composite: - _cairo_composite_rectangles_fini (&extents); - return status; -} - -static cairo_int_status_t -_cairo_ps_surface_fill (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t*path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_ps_surface_t *surface = abstract_surface; - cairo_composite_rectangles_t extents; - cairo_int_status_t status; - - status = _cairo_composite_rectangles_init_for_fill (&extents, - &surface->base, - op, source, path, - clip); - if (unlikely (status)) - return status; - - /* use the more accurate extents */ - { - cairo_rectangle_int_t r; - cairo_box_t b; - - _cairo_path_fixed_fill_extents (path, - fill_rule, - tolerance, - &r); - - _cairo_box_from_rectangle (&b, &r); - status = _cairo_composite_rectangles_intersect_mask_extents (&extents, &b); - if (unlikely (status)) - goto cleanup_composite; - } - - if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) { - status = _cairo_ps_surface_analyze_operation (surface, op, source, NULL, &extents.bounded); - goto cleanup_composite; - } - - assert (_cairo_ps_surface_operation_supported (surface, op, source, NULL, &extents.bounded)); - -#if DEBUG_PS - _cairo_output_stream_printf (surface->stream, - "%% _cairo_ps_surface_fill\n"); -#endif - - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - goto cleanup_composite; - - status = _cairo_ps_surface_set_clip (surface, &extents); - if (unlikely (status)) - goto cleanup_composite; - - if (_can_paint_pattern (source)) { - _cairo_output_stream_printf (surface->stream, "q\n"); - - status = _cairo_pdf_operators_clip (&surface->pdf_operators, - path, - fill_rule); - if (unlikely (status)) - goto cleanup_composite; - - status = _cairo_ps_surface_paint_pattern (surface, - source, - &extents.bounded, op, FALSE); - if (unlikely (status)) - goto cleanup_composite; - - _cairo_output_stream_printf (surface->stream, "Q\n"); - _cairo_pdf_operators_reset (&surface->pdf_operators); - } else { - status = _cairo_ps_surface_emit_pattern (surface, source, &extents.bounded, op); - if (unlikely (status)) - goto cleanup_composite; - - status = _cairo_pdf_operators_fill (&surface->pdf_operators, - path, - fill_rule); - } - -cleanup_composite: - _cairo_composite_rectangles_fini (&extents); - return status; -} - -static cairo_bool_t -_cairo_ps_surface_has_show_text_glyphs (void *abstract_surface) -{ - return TRUE; -} - -static cairo_int_status_t -_cairo_ps_surface_show_text_glyphs (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const char *utf8, - int utf8_len, - cairo_glyph_t *glyphs, - int num_glyphs, - const cairo_text_cluster_t *clusters, - int num_clusters, - cairo_text_cluster_flags_t cluster_flags, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - cairo_ps_surface_t *surface = abstract_surface; - cairo_composite_rectangles_t extents; - cairo_bool_t overlap; - cairo_status_t status; - - status = _cairo_composite_rectangles_init_for_glyphs (&extents, - &surface->base, - op, source, - scaled_font, - glyphs, num_glyphs, - clip, - &overlap); - if (unlikely (status)) - return status; - - if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) { - status = _cairo_ps_surface_analyze_operation (surface, op, source, NULL, &extents.bounded); - goto cleanup_composite; - } - - assert (_cairo_ps_surface_operation_supported (surface, op, source, NULL, &extents.bounded)); - -#if DEBUG_PS - _cairo_output_stream_printf (surface->stream, - "%% _cairo_ps_surface_show_glyphs\n"); -#endif - - status = _cairo_ps_surface_set_clip (surface, &extents); - if (unlikely (status)) - goto cleanup_composite; - - status = _cairo_ps_surface_emit_pattern (surface, source, &extents.bounded, op); - if (unlikely (status)) - goto cleanup_composite; - - status = _cairo_pdf_operators_show_text_glyphs (&surface->pdf_operators, - utf8, utf8_len, - glyphs, num_glyphs, - clusters, num_clusters, - cluster_flags, - scaled_font); - -cleanup_composite: - _cairo_composite_rectangles_fini (&extents); - return status; -} - -static const char ** -_cairo_ps_surface_get_supported_mime_types (void *abstract_surface) -{ - return _cairo_ps_supported_mime_types; -} - -static void -_cairo_ps_surface_set_paginated_mode (void *abstract_surface, - cairo_paginated_mode_t paginated_mode) -{ - cairo_ps_surface_t *surface = abstract_surface; - cairo_status_t status; - - surface->paginated_mode = paginated_mode; - - if (surface->clipper.clip != NULL) { - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - - _cairo_output_stream_printf (surface->stream, "Q q\n"); - _cairo_surface_clipper_reset (&surface->clipper); - } -} - -static cairo_int_status_t -_cairo_ps_surface_set_bounding_box (void *abstract_surface, - cairo_box_t *bbox) -{ - cairo_ps_surface_t *surface = abstract_surface; - int i, num_comments; - char **comments; - int x1, y1, x2, y2; - cairo_bool_t has_page_media, has_page_bbox; - const char *page_media; - - x1 = floor (_cairo_fixed_to_double (bbox->p1.x)); - y1 = floor (surface->height - _cairo_fixed_to_double (bbox->p2.y)); - x2 = ceil (_cairo_fixed_to_double (bbox->p2.x)); - y2 = ceil (surface->height - _cairo_fixed_to_double (bbox->p1.y)); - - surface->page_bbox.x = x1; - surface->page_bbox.y = y1; - surface->page_bbox.width = x2 - x1; - surface->page_bbox.height = y2 - y1; - - _cairo_output_stream_printf (surface->stream, - "%%%%Page: %d %d\n", - surface->num_pages, - surface->num_pages); - - _cairo_output_stream_printf (surface->stream, - "%%%%BeginPageSetup\n"); - - has_page_media = FALSE; - has_page_bbox = FALSE; - num_comments = _cairo_array_num_elements (&surface->dsc_page_setup_comments); - comments = _cairo_array_index (&surface->dsc_page_setup_comments, 0); - for (i = 0; i < num_comments; i++) { - _cairo_output_stream_printf (surface->stream, - "%s\n", comments[i]); - if (strncmp (comments[i], "%%PageMedia:", 11) == 0) - has_page_media = TRUE; - - if (strncmp (comments[i], "%%PageBoundingBox:", 18) == 0) - has_page_bbox = TRUE; - - free (comments[i]); - comments[i] = NULL; - } - _cairo_array_truncate (&surface->dsc_page_setup_comments, 0); - - if (!has_page_media && !surface->eps) { - page_media = _cairo_ps_surface_get_page_media (surface); - if (unlikely (page_media == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_output_stream_printf (surface->stream, - "%%%%PageMedia: %s\n", - page_media); - } - - if (!has_page_bbox) { - _cairo_output_stream_printf (surface->stream, - "%%%%PageBoundingBox: %d %d %d %d\n", - x1, y1, x2, y2); - } - - if (!surface->eps) { - _cairo_output_stream_printf (surface->stream, - "%f %f cairo_set_page_size\n", - ceil(surface->width), - ceil(surface->height)); - } - - _cairo_output_stream_printf (surface->stream, - "%%%%EndPageSetup\n" - "q %d %d %d %d rectclip q\n", - surface->page_bbox.x, - surface->page_bbox.y, - surface->page_bbox.width, - surface->page_bbox.height); - - if (surface->num_pages == 1) { - surface->bbox_x1 = x1; - surface->bbox_y1 = y1; - surface->bbox_x2 = x2; - surface->bbox_y2 = y2; - } else { - if (x1 < surface->bbox_x1) - surface->bbox_x1 = x1; - if (y1 < surface->bbox_y1) - surface->bbox_y1 = y1; - if (x2 > surface->bbox_x2) - surface->bbox_x2 = x2; - if (y2 > surface->bbox_y2) - surface->bbox_y2 = y2; - } - surface->current_pattern_is_solid_color = FALSE; - _cairo_pdf_operators_reset (&surface->pdf_operators); - - return _cairo_output_stream_get_status (surface->stream); -} - -static cairo_bool_t -_cairo_ps_surface_supports_fine_grained_fallbacks (void *abstract_surface) -{ - return TRUE; -} - -static const cairo_surface_backend_t cairo_ps_surface_backend = { - CAIRO_SURFACE_TYPE_PS, - _cairo_ps_surface_finish, - - _cairo_default_context_create, - - NULL, /* create similar: handled by wrapper */ - NULL, /* create similar image */ - NULL, /* map to image */ - NULL, /* unmap image */ - - _cairo_surface_default_source, - NULL, /* acquire_source_image */ - NULL, /* release_source_image */ - NULL, /* snapshot */ - - NULL, /* cairo_ps_surface_copy_page */ - _cairo_ps_surface_show_page, - - _cairo_ps_surface_get_extents, - _cairo_ps_surface_get_font_options, - - NULL, /* flush */ - NULL, /* mark_dirty_rectangle */ - - /* Here are the drawing functions */ - - _cairo_ps_surface_paint, /* paint */ - _cairo_ps_surface_mask, - _cairo_ps_surface_stroke, - _cairo_ps_surface_fill, - NULL, /* fill-stroke */ - NULL, /* show_glyphs */ - _cairo_ps_surface_has_show_text_glyphs, - _cairo_ps_surface_show_text_glyphs, - _cairo_ps_surface_get_supported_mime_types, -}; - -static const cairo_paginated_surface_backend_t cairo_ps_surface_paginated_backend = { - _cairo_ps_surface_start_page, - _cairo_ps_surface_set_paginated_mode, - _cairo_ps_surface_set_bounding_box, - NULL, /* _cairo_ps_surface_has_fallback_images, */ - _cairo_ps_surface_supports_fine_grained_fallbacks, -}; diff --git a/source/libs/cairo/cairo-src/src/cairo-ps.h b/source/libs/cairo/cairo-src/src/cairo-ps.h deleted file mode 100644 index 33d0e0d941bbaa3d5c8d1b572b9554453bfc7990..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-ps.h +++ /dev/null @@ -1,116 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - */ - -#ifndef CAIRO_PS_H -#define CAIRO_PS_H - -#include "cairo.h" - -#if CAIRO_HAS_PS_SURFACE - -#include <stdio.h> - -CAIRO_BEGIN_DECLS - -/* PS-surface functions */ - -/** - * cairo_ps_level_t: - * @CAIRO_PS_LEVEL_2: The language level 2 of the PostScript specification. (Since 1.6) - * @CAIRO_PS_LEVEL_3: The language level 3 of the PostScript specification. (Since 1.6) - * - * #cairo_ps_level_t is used to describe the language level of the - * PostScript Language Reference that a generated PostScript file will - * conform to. - * - * Since: 1.6 - **/ -typedef enum _cairo_ps_level { - CAIRO_PS_LEVEL_2, - CAIRO_PS_LEVEL_3 -} cairo_ps_level_t; - -cairo_public cairo_surface_t * -cairo_ps_surface_create (const char *filename, - double width_in_points, - double height_in_points); - -cairo_public cairo_surface_t * -cairo_ps_surface_create_for_stream (cairo_write_func_t write_func, - void *closure, - double width_in_points, - double height_in_points); - -cairo_public void -cairo_ps_surface_restrict_to_level (cairo_surface_t *surface, - cairo_ps_level_t level); - -cairo_public void -cairo_ps_get_levels (cairo_ps_level_t const **levels, - int *num_levels); - -cairo_public const char * -cairo_ps_level_to_string (cairo_ps_level_t level); - -cairo_public void -cairo_ps_surface_set_eps (cairo_surface_t *surface, - cairo_bool_t eps); - -cairo_public cairo_bool_t -cairo_ps_surface_get_eps (cairo_surface_t *surface); - -cairo_public void -cairo_ps_surface_set_size (cairo_surface_t *surface, - double width_in_points, - double height_in_points); - -cairo_public void -cairo_ps_surface_dsc_comment (cairo_surface_t *surface, - const char *comment); - -cairo_public void -cairo_ps_surface_dsc_begin_setup (cairo_surface_t *surface); - -cairo_public void -cairo_ps_surface_dsc_begin_page_setup (cairo_surface_t *surface); - -CAIRO_END_DECLS - -#else /* CAIRO_HAS_PS_SURFACE */ -# error Cairo was not compiled with support for the ps backend -#endif /* CAIRO_HAS_PS_SURFACE */ - -#endif /* CAIRO_PS_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-qt-surface.cpp b/source/libs/cairo/cairo-src/src/cairo-qt-surface.cpp deleted file mode 100644 index 7ddad77df374a16d3f7a9031fc8ecb58ed19eb1d..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-qt-surface.cpp +++ /dev/null @@ -1,1738 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2008 Mozilla Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Mozilla Corporation. - * - * Contributor(s): - * Vladimir Vukicevic <vladimir@mozilla.com> - */ - -/* Get INT16_MIN etc. as per C99 */ -#define __STDC_LIMIT_MACROS - -#include "cairoint.h" - -#include "cairo-clip-private.h" -#include "cairo-default-context-private.h" -#include "cairo-error-private.h" -#include "cairo-region-private.h" -#include "cairo-surface-clipper-private.h" -#include "cairo-types-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-pattern-private.h" -#include "cairo-surface-backend-private.h" -#include "cairo-surface-fallback-private.h" - -#include "cairo-ft.h" -#include "cairo-qt.h" - -#include <memory> - -#include <QtGui/QPainter> -#include <QtGui/QPaintEngine> -#include <QtGui/QPaintDevice> -#include <QtGui/QImage> -#include <QtGui/QPixmap> -#include <QtGui/QBrush> -#include <QtGui/QPen> -#include <QWidget> -#include <QtCore/QVarLengthArray> - -#if ((QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)) || defined(QT_GLYPHS_API_BACKPORT)) && 0 -extern void qt_draw_glyphs(QPainter *, const quint32 *glyphs, const QPointF *positions, int count); -#endif - -#include <sys/time.h> - -/* Enable workaround slow regional Qt paths */ -#define ENABLE_FAST_FILL 0 -#define ENABLE_FAST_CLIP 0 - -#if 0 -#define D(x) x -static const char * -_opstr (cairo_operator_t op) -{ - const char *ops[] = { - "CLEAR", - "SOURCE", - "OVER", - "IN", - "OUT", - "ATOP", - "DEST", - "DEST_OVER", - "DEST_IN", - "DEST_OUT", - "DEST_ATOP", - "XOR", - "ADD", - "SATURATE" - }; - - if (op < CAIRO_OPERATOR_CLEAR || op > CAIRO_OPERATOR_SATURATE) - return "(\?\?\?)"; - - return ops[op]; -} -#else -#define D(x) do { } while(0) -#endif - -#ifndef CAIRO_INT_STATUS_SUCCESS -#define CAIRO_INT_STATUS_SUCCESS ((cairo_int_status_t) CAIRO_STATUS_SUCCESS) -#endif - -/* Qt::PenStyle optimization based on the assumption that dots are 1*w and dashes are 3*w. */ -#define DOT_LENGTH 1.0 -#define DASH_LENGTH 3.0 - -struct cairo_qt_surface_t { - cairo_surface_t base; - - cairo_bool_t supports_porter_duff; - - QPainter *p; - - /* The pixmap/image constructors will store their objects here */ - QPixmap *pixmap; - QImage *image; - - QRect window; - - cairo_surface_clipper_t clipper; - - cairo_surface_t *image_equiv; -}; - -/* Will be true if we ever try to create a QPixmap and end - * up with one without an alpha channel. - */ -static cairo_bool_t _qpixmaps_have_no_alpha = FALSE; - -/* - * Helper methods - */ - -static QPainter::CompositionMode -_qpainter_compositionmode_from_cairo_op (cairo_operator_t op) -{ - switch (op) { - case CAIRO_OPERATOR_CLEAR: - return QPainter::CompositionMode_Clear; - - case CAIRO_OPERATOR_SOURCE: - return QPainter::CompositionMode_Source; - case CAIRO_OPERATOR_OVER: - return QPainter::CompositionMode_SourceOver; - case CAIRO_OPERATOR_IN: - return QPainter::CompositionMode_SourceIn; - case CAIRO_OPERATOR_OUT: - return QPainter::CompositionMode_SourceOut; - case CAIRO_OPERATOR_ATOP: - return QPainter::CompositionMode_SourceAtop; - - case CAIRO_OPERATOR_DEST: - return QPainter::CompositionMode_Destination; - case CAIRO_OPERATOR_DEST_OVER: - return QPainter::CompositionMode_DestinationOver; - case CAIRO_OPERATOR_DEST_IN: - return QPainter::CompositionMode_DestinationIn; - case CAIRO_OPERATOR_DEST_OUT: - return QPainter::CompositionMode_DestinationOut; - case CAIRO_OPERATOR_DEST_ATOP: - return QPainter::CompositionMode_DestinationAtop; - - case CAIRO_OPERATOR_XOR: - return QPainter::CompositionMode_Xor; - - default: - case CAIRO_OPERATOR_ADD: - case CAIRO_OPERATOR_SATURATE: - case CAIRO_OPERATOR_MULTIPLY: - case CAIRO_OPERATOR_SCREEN: - case CAIRO_OPERATOR_OVERLAY: - case CAIRO_OPERATOR_DARKEN: - case CAIRO_OPERATOR_LIGHTEN: - case CAIRO_OPERATOR_COLOR_DODGE: - case CAIRO_OPERATOR_COLOR_BURN: - case CAIRO_OPERATOR_HARD_LIGHT: - case CAIRO_OPERATOR_SOFT_LIGHT: - case CAIRO_OPERATOR_DIFFERENCE: - case CAIRO_OPERATOR_EXCLUSION: - case CAIRO_OPERATOR_HSL_HUE: - case CAIRO_OPERATOR_HSL_SATURATION: - case CAIRO_OPERATOR_HSL_COLOR: - case CAIRO_OPERATOR_HSL_LUMINOSITY: - ASSERT_NOT_REACHED; - } -} - -static bool -_op_is_supported (cairo_qt_surface_t *qs, cairo_operator_t op) -{ - if (qs->p == NULL) - return false; - - if (qs->supports_porter_duff) { - switch (op) { - case CAIRO_OPERATOR_CLEAR: - case CAIRO_OPERATOR_SOURCE: - case CAIRO_OPERATOR_OVER: - case CAIRO_OPERATOR_IN: - case CAIRO_OPERATOR_OUT: - case CAIRO_OPERATOR_ATOP: - - case CAIRO_OPERATOR_DEST: - case CAIRO_OPERATOR_DEST_OVER: - case CAIRO_OPERATOR_DEST_IN: - case CAIRO_OPERATOR_DEST_OUT: - case CAIRO_OPERATOR_DEST_ATOP: - - case CAIRO_OPERATOR_XOR: - return TRUE; - - default: - ASSERT_NOT_REACHED; - case CAIRO_OPERATOR_ADD: - case CAIRO_OPERATOR_SATURATE: - case CAIRO_OPERATOR_MULTIPLY: - case CAIRO_OPERATOR_SCREEN: - case CAIRO_OPERATOR_OVERLAY: - case CAIRO_OPERATOR_DARKEN: - case CAIRO_OPERATOR_LIGHTEN: - case CAIRO_OPERATOR_COLOR_DODGE: - case CAIRO_OPERATOR_COLOR_BURN: - case CAIRO_OPERATOR_HARD_LIGHT: - case CAIRO_OPERATOR_SOFT_LIGHT: - case CAIRO_OPERATOR_DIFFERENCE: - case CAIRO_OPERATOR_EXCLUSION: - case CAIRO_OPERATOR_HSL_HUE: - case CAIRO_OPERATOR_HSL_SATURATION: - case CAIRO_OPERATOR_HSL_COLOR: - case CAIRO_OPERATOR_HSL_LUMINOSITY: - return FALSE; - - } - } else { - return op == CAIRO_OPERATOR_OVER; - } -} - -static cairo_format_t -_cairo_format_from_qimage_format (QImage::Format fmt) -{ - switch (fmt) { - case QImage::Format_ARGB32_Premultiplied: - return CAIRO_FORMAT_ARGB32; - case QImage::Format_RGB32: - return CAIRO_FORMAT_RGB24; - case QImage::Format_Indexed8: // XXX not quite - return CAIRO_FORMAT_A8; -#ifdef WORDS_BIGENDIAN - case QImage::Format_Mono: -#else - case QImage::Format_MonoLSB: -#endif - return CAIRO_FORMAT_A1; - - case QImage::Format_Invalid: -#ifdef WORDS_BIGENDIAN - case QImage::Format_MonoLSB: -#else - case QImage::Format_Mono: -#endif - case QImage::Format_ARGB32: - case QImage::Format_RGB16: - case QImage::Format_ARGB8565_Premultiplied: - case QImage::Format_RGB666: - case QImage::Format_ARGB6666_Premultiplied: - case QImage::Format_RGB555: - case QImage::Format_ARGB8555_Premultiplied: - case QImage::Format_RGB888: - case QImage::Format_RGB444: - case QImage::Format_ARGB4444_Premultiplied: - case QImage::NImageFormats: - default: - ASSERT_NOT_REACHED; - return (cairo_format_t) -1; - } -} - -static QImage::Format -_qimage_format_from_cairo_format (cairo_format_t fmt) -{ - switch (fmt) { - case CAIRO_FORMAT_INVALID: - ASSERT_NOT_REACHED; - case CAIRO_FORMAT_ARGB32: - return QImage::Format_ARGB32_Premultiplied; - case CAIRO_FORMAT_RGB24: - return QImage::Format_RGB32; - case CAIRO_FORMAT_RGB16_565: - return QImage::Format_RGB16; - case CAIRO_FORMAT_A8: - return QImage::Format_Indexed8; // XXX not quite - case CAIRO_FORMAT_A1: -#ifdef WORDS_BIGENDIAN - return QImage::Format_Mono; // XXX think we need to choose between this and LSB -#else - return QImage::Format_MonoLSB; -#endif - case CAIRO_FORMAT_RGB30: - return QImage::Format_Mono; - } - - return QImage::Format_Mono; -} - -static inline QMatrix -_qmatrix_from_cairo_matrix (const cairo_matrix_t& m) -{ - return QMatrix(m.xx, m.yx, m.xy, m.yy, m.x0, m.y0); -} - -/* Path conversion */ -typedef struct _qpainter_path_transform { - QPainterPath path; - const cairo_matrix_t *ctm_inverse; -} qpainter_path_data; - -/* cairo path -> execute in context */ -static cairo_status_t -_cairo_path_to_qpainterpath_move_to (void *closure, const cairo_point_t *point) -{ - qpainter_path_data *pdata = static_cast <qpainter_path_data *> (closure); - double x = _cairo_fixed_to_double (point->x); - double y = _cairo_fixed_to_double (point->y); - - if (pdata->ctm_inverse) - cairo_matrix_transform_point (pdata->ctm_inverse, &x, &y); - - pdata->path.moveTo(x, y); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_path_to_qpainterpath_line_to (void *closure, const cairo_point_t *point) -{ - qpainter_path_data *pdata = static_cast <qpainter_path_data *> (closure); - double x = _cairo_fixed_to_double (point->x); - double y = _cairo_fixed_to_double (point->y); - - if (pdata->ctm_inverse) - cairo_matrix_transform_point (pdata->ctm_inverse, &x, &y); - - pdata->path.lineTo(x, y); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_path_to_qpainterpath_curve_to (void *closure, const cairo_point_t *p0, const cairo_point_t *p1, const cairo_point_t *p2) -{ - qpainter_path_data *pdata = static_cast <qpainter_path_data *> (closure); - double x0 = _cairo_fixed_to_double (p0->x); - double y0 = _cairo_fixed_to_double (p0->y); - double x1 = _cairo_fixed_to_double (p1->x); - double y1 = _cairo_fixed_to_double (p1->y); - double x2 = _cairo_fixed_to_double (p2->x); - double y2 = _cairo_fixed_to_double (p2->y); - - if (pdata->ctm_inverse) { - cairo_matrix_transform_point (pdata->ctm_inverse, &x0, &y0); - cairo_matrix_transform_point (pdata->ctm_inverse, &x1, &y1); - cairo_matrix_transform_point (pdata->ctm_inverse, &x2, &y2); - } - - pdata->path.cubicTo (x0, y0, x1, y1, x2, y2); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_path_to_qpainterpath_close_path (void *closure) -{ - qpainter_path_data *pdata = static_cast <qpainter_path_data *> (closure); - - pdata->path.closeSubpath(); - - return CAIRO_STATUS_SUCCESS; -} - -static QPainterPath -path_to_qt (const cairo_path_fixed_t *path, - const cairo_matrix_t *ctm_inverse = NULL) -{ - qpainter_path_data data; - cairo_status_t status; - - if (ctm_inverse && _cairo_matrix_is_identity (ctm_inverse)) - ctm_inverse = NULL; - data.ctm_inverse = ctm_inverse; - - status = _cairo_path_fixed_interpret (path, - _cairo_path_to_qpainterpath_move_to, - _cairo_path_to_qpainterpath_line_to, - _cairo_path_to_qpainterpath_curve_to, - _cairo_path_to_qpainterpath_close_path, - &data); - assert (status == CAIRO_STATUS_SUCCESS); - - return data.path; -} - -static inline QPainterPath -path_to_qt (const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - cairo_matrix_t *ctm_inverse = NULL) -{ - QPainterPath qpath = path_to_qt (path, ctm_inverse); - - qpath.setFillRule (fill_rule == CAIRO_FILL_RULE_WINDING ? - Qt::WindingFill : - Qt::OddEvenFill); - - return qpath; -} - -/* - * Surface backend methods - */ -static cairo_surface_t * -_cairo_qt_surface_create_similar (void *abstract_surface, - cairo_content_t content, - int width, - int height) -{ - cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; - bool use_pixmap; - - D(fprintf(stderr, "q[%p] create_similar: %d %d [%d] -> ", abstract_surface, width, height, content)); - - use_pixmap = qs->image == NULL; - if (use_pixmap) { - switch (content) { - case CAIRO_CONTENT_ALPHA: - use_pixmap = FALSE; - break; - case CAIRO_CONTENT_COLOR: - break; - case CAIRO_CONTENT_COLOR_ALPHA: - use_pixmap = ! _qpixmaps_have_no_alpha; - break; - } - } - - if (use_pixmap) { - cairo_surface_t *result = - cairo_qt_surface_create_with_qpixmap (content, width, height); - - /* XXX result->content is always content. ??? */ - if (result->content == content) { - D(fprintf(stderr, "qpixmap content: %d\n", content)); - return result; - } - - _qpixmaps_have_no_alpha = TRUE; - cairo_surface_destroy (result); - } - - D(fprintf (stderr, "qimage\n")); - return cairo_qt_surface_create_with_qimage - (_cairo_format_from_content (content), width, height); -} - -static cairo_status_t -_cairo_qt_surface_finish (void *abstract_surface) -{ - cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; - - D(fprintf(stderr, "q[%p] finish\n", abstract_surface)); - - /* Only delete p if we created it */ - if (qs->image || qs->pixmap) - delete qs->p; - else - qs->p->restore (); - - if (qs->image_equiv) - cairo_surface_destroy (qs->image_equiv); - - _cairo_surface_clipper_reset (&qs->clipper); - - if (qs->image) - delete qs->image; - - if (qs->pixmap) - delete qs->pixmap; - - return CAIRO_STATUS_SUCCESS; -} - -static void -_qimg_destroy (void *closure) -{ - QImage *qimg = (QImage *) closure; - delete qimg; -} - -static cairo_status_t -_cairo_qt_surface_acquire_source_image (void *abstract_surface, - cairo_image_surface_t **image_out, - void **image_extra) -{ - cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; - - D(fprintf(stderr, "q[%p] acquire_source_image\n", abstract_surface)); - - *image_extra = NULL; - - if (qs->image_equiv) { - *image_out = (cairo_image_surface_t*) - cairo_surface_reference (qs->image_equiv); - - return CAIRO_STATUS_SUCCESS; - } - - if (qs->pixmap) { - QImage *qimg = new QImage(qs->pixmap->toImage()); - cairo_surface_t *image; - cairo_status_t status; - - image = cairo_image_surface_create_for_data (qimg->bits(), - _cairo_format_from_qimage_format (qimg->format()), - qimg->width(), qimg->height(), - qimg->bytesPerLine()); - - status = _cairo_user_data_array_set_data (&image->user_data, - (const cairo_user_data_key_t *)&_qimg_destroy, - qimg, - _qimg_destroy); - if (status) { - cairo_surface_destroy (image); - return status; - } - - *image_out = (cairo_image_surface_t *) image; - return CAIRO_STATUS_SUCCESS; - } - - return _cairo_error (CAIRO_STATUS_NO_MEMORY); -} - -static void -_cairo_qt_surface_release_source_image (void *abstract_surface, - cairo_image_surface_t *image, - void *image_extra) -{ - //cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; - - D(fprintf(stderr, "q[%p] release_source_image\n", abstract_surface)); - - cairo_surface_destroy (&image->base); -} - -struct _qimage_surface { - cairo_image_surface_t image; - QImage *qimg; -}; - -static cairo_surface_t * -map_qimage_to_image (QImage *qimg, const cairo_rectangle_int_t *extents) -{ - struct _qimage_surface *surface; - pixman_image_t *pixman_image; - pixman_format_code_t pixman_format; - uint8_t *data; - - if (qimg == NULL) - return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY); - - switch (qimg->format()) { - case QImage::Format_ARGB32_Premultiplied: - pixman_format = PIXMAN_a8r8g8b8; - break; - case QImage::Format_RGB32: - pixman_format = PIXMAN_x8r8g8b8; - break; - case QImage::Format_Indexed8: // XXX not quite - pixman_format = PIXMAN_a8; - break; -#ifdef WORDS_BIGENDIAN - case QImage::Format_Mono: -#else - case QImage::Format_MonoLSB: -#endif - pixman_format = PIXMAN_a1; - break; - - case QImage::Format_Invalid: -#ifdef WORDS_BIGENDIAN - case QImage::Format_MonoLSB: -#else - case QImage::Format_Mono: -#endif - case QImage::Format_ARGB32: - case QImage::Format_RGB16: - case QImage::Format_ARGB8565_Premultiplied: - case QImage::Format_RGB666: - case QImage::Format_ARGB6666_Premultiplied: - case QImage::Format_RGB555: - case QImage::Format_ARGB8555_Premultiplied: - case QImage::Format_RGB888: - case QImage::Format_RGB444: - case QImage::Format_ARGB4444_Premultiplied: - case QImage::NImageFormats: - default: - delete qimg; - return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_FORMAT); - } - - data = qimg->bits(); - data += extents->y * qimg->bytesPerLine(); - data += extents->x * PIXMAN_FORMAT_BPP (pixman_format) / 8; - - pixman_image = pixman_image_create_bits (pixman_format, - extents->width, - extents->height, - (uint32_t *)data, - qimg->bytesPerLine()); - if (pixman_image == NULL) { - delete qimg; - return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY); - } - - surface = (struct _qimage_surface *) malloc (sizeof(*surface)); - if (unlikely (surface == NULL)) { - pixman_image_unref (pixman_image); - delete qimg; - return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY); - } - - _cairo_image_surface_init (&surface->image, pixman_image, pixman_format); - surface->qimg = qimg; - - cairo_surface_set_device_offset (&surface->image.base, - -extents->x, -extents->y); - - return &surface->image.base; -} - -static cairo_image_surface_t * -_cairo_qt_surface_map_to_image (void *abstract_surface, - const cairo_rectangle_int_t *extents) -{ - cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; - QImage *qimg = NULL; - - D(fprintf(stderr, "q[%p] acquire_dest_image\n", abstract_surface)); - - if (qs->image_equiv) - return _cairo_image_surface_map_to_image (qs->image_equiv, - extents); - - QPoint offset; - - if (qs->pixmap) { - qimg = new QImage(qs->pixmap->toImage()); - } else { - // Try to figure out what kind of QPaintDevice we have, and - // how we can grab an image from it - QPaintDevice *pd = qs->p->device(); - if (!pd) - return (cairo_image_surface_t *) _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY); - - QPaintDevice *rpd = QPainter::redirected(pd, &offset); - if (rpd) - pd = rpd; - - if (pd->devType() == QInternal::Image) { - qimg = new QImage(((QImage*) pd)->copy()); - } else if (pd->devType() == QInternal::Pixmap) { - qimg = new QImage(((QPixmap*) pd)->toImage()); - } else if (pd->devType() == QInternal::Widget) { - qimg = new QImage(QPixmap::grabWindow(((QWidget*)pd)->winId()).toImage()); - } - } - - return (cairo_image_surface_t *) map_qimage_to_image (qimg, extents); -} - -static cairo_int_status_t -_cairo_qt_surface_unmap_image (void *abstract_surface, - cairo_image_surface_t *image) -{ - cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; - - D(fprintf(stderr, "q[%p] release_dest_image\n", abstract_surface)); - - if (!qs->image_equiv) { - struct _qimage_surface *qimage = (struct _qimage_surface *)image; - - // XXX should I be using setBackgroundMode here instead of setCompositionMode? - if (qs->supports_porter_duff) - qs->p->setCompositionMode (QPainter::CompositionMode_Source); - - qs->p->drawImage ((int)qimage->image.base.device_transform.x0, - (int)qimage->image.base.device_transform.y0, - *qimage->qimg, - (int)qimage->image.base.device_transform.x0, - (int)qimage->image.base.device_transform.y0, - (int)qimage->image.width, - (int)qimage->image.height); - - if (qs->supports_porter_duff) - qs->p->setCompositionMode (QPainter::CompositionMode_SourceOver); - - delete qimage->qimg; - } - - cairo_surface_finish (&image->base); - cairo_surface_destroy (&image->base); - - return CAIRO_INT_STATUS_SUCCESS; -} - -static cairo_bool_t -_cairo_qt_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *extents) -{ - cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; - - extents->x = qs->window.x(); - extents->y = qs->window.y(); - extents->width = qs->window.width(); - extents->height = qs->window.height(); - - return TRUE; -} - -static cairo_status_t -_cairo_qt_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper, - cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_qt_surface_t *qs = cairo_container_of (clipper, - cairo_qt_surface_t, - clipper); - - if (path == NULL) { - if (qs->pixmap || qs->image) { - // we own p - qs->p->setClipping (false); - } else { - qs->p->restore (); - qs->p->save (); - } - } else { - // XXX Antialiasing is ignored - qs->p->setClipPath (path_to_qt (path, fill_rule), Qt::IntersectClip); - } - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_qt_surface_set_clip_region (cairo_qt_surface_t *qs, - const cairo_region_t *clip_region) -{ - _cairo_surface_clipper_reset (&qs->clipper); - - if (clip_region == NULL) { - // How the clip path is reset depends on whether we own p or not - if (qs->pixmap || qs->image) { - // we own p - qs->p->setClipping (false); - } else { - qs->p->restore (); - qs->p->save (); - } - } else { - QRegion qr; - int num_rects = cairo_region_num_rectangles (clip_region); - for (int i = 0; i < num_rects; ++i) { - cairo_rectangle_int_t rect; - - cairo_region_get_rectangle (clip_region, i, &rect); - - QRect r(rect.x, rect.y, rect.width, rect.height); - qr = qr.unite(r); - } - - qs->p->setClipRegion (qr, Qt::IntersectClip); - } -} - -static cairo_int_status_t -_cairo_qt_surface_set_clip (cairo_qt_surface_t *qs, - const cairo_clip_t *clip) -{ - cairo_int_status_t status; - - D(fprintf(stderr, "q[%p] intersect_clip_path %s\n", abstract_surface, path ? "(path)" : "(clear)")); - - if (clip == NULL) { - _cairo_surface_clipper_reset (&qs->clipper); - // How the clip path is reset depends on whether we own p or not - if (qs->pixmap || qs->image) { - // we own p - qs->p->setClipping (false); - } else { - qs->p->restore (); - qs->p->save (); - } - - return CAIRO_INT_STATUS_SUCCESS; - } - -#if ENABLE_FAST_CLIP - // Qt will implicitly enable clipping, and will use ReplaceClip - // instead of IntersectClip if clipping was disabled before - - // Note: Qt is really bad at dealing with clip paths. It doesn't - // seem to usefully recognize rectangular paths, instead going down - // extremely slow paths whenever a clip path is set. So, - // we do a bunch of work here to try to get rectangles or regions - // down to Qt for clipping. - - cairo_region_t *clip_region = NULL; - - status = _cairo_clip_get_region (clip, &clip_region); - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - // We weren't able to extract a region from the traps. - // Just hand the path down to QPainter. - status = (cairo_int_status_t) - _cairo_surface_clipper_set_clip (&qs->clipper, clip); - } else if (status == CAIRO_INT_STATUS_SUCCESS) { - _cairo_qt_surface_set_clip_region (qs, clip_region); - status = CAIRO_INT_STATUS_SUCCESS; - } -#else - status = (cairo_int_status_t) - _cairo_surface_clipper_set_clip (&qs->clipper, clip); -#endif - - return status; -} - -/* - * Brush conversion - */ - -struct PatternToBrushConverter { - PatternToBrushConverter (const cairo_pattern_t *pattern) - __attribute__ ((noinline)) : - mAcquiredImageParent(0), - mAcquiredImage(0), - mAcquiredImageExtra(0) - { - if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) { - cairo_solid_pattern_t *solid = (cairo_solid_pattern_t*) pattern; - QColor color; - color.setRgbF(solid->color.red, - solid->color.green, - solid->color.blue, - solid->color.alpha); - - mBrush = QBrush(color); - } else if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) { - cairo_surface_pattern_t *spattern = (cairo_surface_pattern_t*) pattern; - cairo_surface_t *surface = spattern->surface; - - if (surface->type == CAIRO_SURFACE_TYPE_QT) { - cairo_qt_surface_t *qs = (cairo_qt_surface_t*) surface; - - if (qs->image) { - mBrush = QBrush(*qs->image); - } else if (qs->pixmap) { - mBrush = QBrush(*qs->pixmap); - } else { - // do something smart - mBrush = QBrush(0xff0000ff); - } - } else { - cairo_image_surface_t *isurf = NULL; - - if (surface->type == CAIRO_SURFACE_TYPE_IMAGE) { - isurf = (cairo_image_surface_t*) surface; - } else { - void *image_extra; - - if (_cairo_surface_acquire_source_image (surface, &isurf, &image_extra) == CAIRO_STATUS_SUCCESS) { - mAcquiredImageParent = surface; - mAcquiredImage = isurf; - mAcquiredImageExtra = image_extra; - } else { - isurf = NULL; - } - } - - if (isurf) { - mBrush = QBrush (QImage ((const uchar *) isurf->data, - isurf->width, - isurf->height, - isurf->stride, - _qimage_format_from_cairo_format (isurf->format))); - } else { - mBrush = QBrush(0x0000ffff); - } - } - } else if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR || - pattern->type == CAIRO_PATTERN_TYPE_RADIAL) - { - QGradient *grad; - cairo_bool_t reverse_stops = FALSE; - cairo_bool_t emulate_reflect = FALSE; - double offset = 0.0; - - cairo_extend_t extend = pattern->extend; - - cairo_gradient_pattern_t *gpat = (cairo_gradient_pattern_t *) pattern; - - if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR) { - cairo_linear_pattern_t *lpat = (cairo_linear_pattern_t *) pattern; - grad = new QLinearGradient (lpat->pd1.x, lpat->pd1.y, - lpat->pd2.x, lpat->pd2.y); - } else if (pattern->type == CAIRO_PATTERN_TYPE_RADIAL) { - cairo_radial_pattern_t *rpat = (cairo_radial_pattern_t *) pattern; - - /* Based on the SVG surface code */ - - cairo_circle_double_t *c0, *c1; - double x0, y0, r0, x1, y1, r1; - - if (rpat->cd1.radius < rpat->cd2.radius) { - c0 = &rpat->cd1; - c1 = &rpat->cd2; - reverse_stops = FALSE; - } else { - c0 = &rpat->cd2; - c1 = &rpat->cd1; - reverse_stops = TRUE; - } - - x0 = c0->center.x; - y0 = c0->center.y; - r0 = c0->radius; - x1 = c1->center.x; - y1 = c1->center.y; - r1 = c1->radius; - - if (r0 == r1) { - grad = new QRadialGradient (x1, y1, r1, x1, y1); - } else { - double fx = (r1 * x0 - r0 * x1) / (r1 - r0); - double fy = (r1 * y0 - r0 * y1) / (r1 - r0); - - /* QPainter doesn't support the inner circle and use instead a gradient focal. - * That means we need to emulate the cairo behaviour by processing the - * cairo gradient stops. - * The CAIRO_EXTENT_NONE and CAIRO_EXTENT_PAD modes are quite easy to handle, - * it's just a matter of stop position translation and calculation of - * the corresponding SVG radial gradient focal. - * The CAIRO_EXTENT_REFLECT and CAIRO_EXTEND_REPEAT modes require to compute a new - * radial gradient, with an new outer circle, equal to r1 - r0 in the CAIRO_EXTEND_REPEAT - * case, and 2 * (r1 - r0) in the CAIRO_EXTENT_REFLECT case, and a new gradient stop - * list that maps to the original cairo stop list. - */ - if ((extend == CAIRO_EXTEND_REFLECT || extend == CAIRO_EXTEND_REPEAT) && r0 > 0.0) { - double r_org = r1; - double r, x, y; - - if (extend == CAIRO_EXTEND_REFLECT) { - r1 = 2 * r1 - r0; - emulate_reflect = TRUE; - } - - offset = fmod (r1, r1 - r0) / (r1 - r0) - 1.0; - r = r1 - r0; - - /* New position of outer circle. */ - x = r * (x1 - fx) / r_org + fx; - y = r * (y1 - fy) / r_org + fy; - - x1 = x; - y1 = y; - r1 = r; - r0 = 0.0; - } else { - offset = r0 / r1; - } - - grad = new QRadialGradient (x1, y1, r1, fx, fy); - - if (extend == CAIRO_EXTEND_NONE && r0 != 0.0) - grad->setColorAt (r0 / r1, Qt::transparent); - } - } - - switch (extend) { - case CAIRO_EXTEND_NONE: - case CAIRO_EXTEND_PAD: - grad->setSpread(QGradient::PadSpread); - - grad->setColorAt (0.0, Qt::transparent); - grad->setColorAt (1.0, Qt::transparent); - break; - - case CAIRO_EXTEND_REFLECT: - grad->setSpread(QGradient::ReflectSpread); - break; - - case CAIRO_EXTEND_REPEAT: - grad->setSpread(QGradient::RepeatSpread); - break; - } - - for (unsigned int i = 0; i < gpat->n_stops; i++) { - int index = i; - if (reverse_stops) - index = gpat->n_stops - i - 1; - - double offset = gpat->stops[i].offset; - QColor color; - color.setRgbF (gpat->stops[i].color.red, - gpat->stops[i].color.green, - gpat->stops[i].color.blue, - gpat->stops[i].color.alpha); - - if (emulate_reflect) { - offset = offset / 2.0; - grad->setColorAt (1.0 - offset, color); - } - - grad->setColorAt (offset, color); - } - - mBrush = QBrush(*grad); - - delete grad; - } - - if (mBrush.style() != Qt::NoBrush && - pattern->type != CAIRO_PATTERN_TYPE_SOLID && - ! _cairo_matrix_is_identity (&pattern->matrix)) - { - cairo_matrix_t pm = pattern->matrix; - cairo_status_t status = cairo_matrix_invert (&pm); - assert (status == CAIRO_STATUS_SUCCESS); - mBrush.setMatrix (_qmatrix_from_cairo_matrix (pm)); - } - } - - ~PatternToBrushConverter () __attribute__ ((noinline)){ - if (mAcquiredImageParent) - _cairo_surface_release_source_image (mAcquiredImageParent, mAcquiredImage, mAcquiredImageExtra); - } - - operator QBrush& () { - return mBrush; - } - - QBrush mBrush; - - private: - cairo_surface_t *mAcquiredImageParent; - cairo_image_surface_t *mAcquiredImage; - void *mAcquiredImageExtra; -}; - -struct PatternToPenConverter { - PatternToPenConverter (const cairo_pattern_t *source, - const cairo_stroke_style_t *style) : - mBrushConverter(source) - { - Qt::PenJoinStyle join = Qt::MiterJoin; - Qt::PenCapStyle cap = Qt::SquareCap; - - switch (style->line_cap) { - case CAIRO_LINE_CAP_BUTT: - cap = Qt::FlatCap; - break; - case CAIRO_LINE_CAP_ROUND: - cap = Qt::RoundCap; - break; - case CAIRO_LINE_CAP_SQUARE: - cap = Qt::SquareCap; - break; - } - - switch (style->line_join) { - case CAIRO_LINE_JOIN_MITER: - join = Qt::MiterJoin; - break; - case CAIRO_LINE_JOIN_ROUND: - join = Qt::RoundJoin; - break; - case CAIRO_LINE_JOIN_BEVEL: - join = Qt::BevelJoin; - break; - } - - mPen = QPen(mBrushConverter, style->line_width, Qt::SolidLine, cap, join); - mPen.setMiterLimit (style->miter_limit); - - if (style->dash && style->num_dashes) { - Qt::PenStyle pstyle = Qt::NoPen; - - if (style->num_dashes == 2) { - if ((style->dash[0] == style->line_width && - style->dash[1] == style->line_width && style->line_width <= 2.0) || - (style->dash[0] == 0.0 && - style->dash[1] == style->line_width * 2 && cap == Qt::RoundCap)) - { - pstyle = Qt::DotLine; - } else if (style->dash[0] == style->line_width * DASH_LENGTH && - style->dash[1] == style->line_width * DASH_LENGTH && - cap == Qt::FlatCap) - { - pstyle = Qt::DashLine; - } - } - - if (pstyle != Qt::NoPen) { - mPen.setStyle(pstyle); - return; - } - - unsigned int odd_dash = style->num_dashes % 2; - - QVector<qreal> dashes (odd_dash ? style->num_dashes * 2 : style->num_dashes); - for (unsigned int i = 0; i < odd_dash+1; i++) { - for (unsigned int j = 0; j < style->num_dashes; j++) { - // In Qt, the dash lengths are given in units of line width, whereas - // in cairo, they are in user-space units. We'll always apply the CTM, - // so all we have to do here is divide cairo's dash lengths by the line - // width. - dashes.append (style->dash[j] / style->line_width); - } - } - - mPen.setDashPattern(dashes); - mPen.setDashOffset(style->dash_offset / style->line_width); - } - } - - ~PatternToPenConverter() { } - - operator QPen& () { - return mPen; - } - - QPen mPen; - PatternToBrushConverter mBrushConverter; -}; - -/* - * Core drawing operations - */ - -static bool -_cairo_qt_fast_fill (cairo_qt_surface_t *qs, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path = NULL, - cairo_fill_rule_t fill_rule = CAIRO_FILL_RULE_WINDING, - double tolerance = 0.0, - cairo_antialias_t antialias = CAIRO_ANTIALIAS_NONE) -{ -#if ENABLE_FAST_FILL - QImage *qsSrc_image = NULL; - QPixmap *qsSrc_pixmap = NULL; - std::auto_ptr<QImage> qsSrc_image_d; - - - if (source->type == CAIRO_PATTERN_TYPE_SURFACE) { - cairo_surface_pattern_t *spattern = (cairo_surface_pattern_t*) source; - if (spattern->surface->type == CAIRO_SURFACE_TYPE_QT) { - cairo_qt_surface_t *p = (cairo_qt_surface_t*) spattern->surface; - - qsSrc_image = p->image; - qsSrc_pixmap = p->pixmap; - } else if (spattern->surface->type == CAIRO_SURFACE_TYPE_IMAGE) { - cairo_image_surface_t *p = (cairo_image_surface_t*) spattern->surface; - qsSrc_image = new QImage((const uchar*) p->data, - p->width, - p->height, - p->stride, - _qimage_format_from_cairo_format(p->format)); - qsSrc_image_d.reset(qsSrc_image); - } - } - - if (!qsSrc_image && !qsSrc_pixmap) - return false; - - // We can only drawTiledPixmap; there's no drawTiledImage - if (! qsSrc_pixmap && - (source->extend == CAIRO_EXTEND_REPEAT || - source->extend == CAIRO_EXTEND_REFLECT)) - { - return false; - } - - QMatrix sourceMatrix = _qmatrix_from_cairo_matrix (source->matrix); - - // We can draw this faster by clipping and calling drawImage/drawPixmap. - // Use our own clipping function so that we can get the - // region handling to end up with the fastest possible clip. - // - // XXX Antialiasing will fail pretty hard here, since we can't clip with AA - // with QPainter. - qs->p->save(); - - if (path) { - cairo_int_status_t status; - - cairo_clip_t clip, old_clip = qs->clipper.clip; - - _cairo_clip_init_copy (&clip, &qs->clipper.clip); - status = (cairo_int_status_t) _cairo_clip_clip (&clip, - path, - fill_rule, - tolerance, - antialias); - if (unlikely (status)) { - qs->p->restore(); - return false; - } - - status = _cairo_qt_surface_set_clip (qs, &clip); - if (unlikely (status)) { - qs->p->restore(); - return false; - } - - _cairo_clip_reset (&clip); - qs->clipper.clip = old_clip; - } - - qs->p->setWorldMatrix (sourceMatrix.inverted(), true); - - switch (source->extend) { - case CAIRO_EXTEND_REPEAT: - // XXX handle reflect by tiling 4 times first - case CAIRO_EXTEND_REFLECT: { - assert (qsSrc_pixmap); - - // Render the tiling to cover the entire destination window (because - // it'll be clipped). Transform the window rect by the inverse - // of the current world transform so that the device coordinates - // end up as the right thing. - QRectF dest = qs->p->worldTransform().inverted().mapRect(QRectF(qs->window)); - QPointF origin = sourceMatrix.map(QPointF(0.0, 0.0)); - - qs->p->drawTiledPixmap (dest, *qsSrc_pixmap, origin); - } - break; - case CAIRO_EXTEND_NONE: - case CAIRO_EXTEND_PAD: // XXX not exactly right, but good enough - default: - if (qsSrc_image) - qs->p->drawImage (0, 0, *qsSrc_image); - else if (qsSrc_pixmap) - qs->p->drawPixmap (0, 0, *qsSrc_pixmap); - break; - } - - qs->p->restore(); - - return true; -#else - return false; -#endif -} - -static cairo_int_status_t -_cairo_qt_surface_paint (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; - cairo_int_status_t status; - - D(fprintf(stderr, "q[%p] paint op:%s\n", abstract_surface, _opstr(op))); - - if (! _op_is_supported (qs, op)) - return _cairo_surface_fallback_paint (abstract_surface, op, source, clip); - - status = _cairo_qt_surface_set_clip (qs, clip); - if (unlikely (status)) - return status; - - if (qs->supports_porter_duff) - qs->p->setCompositionMode (_qpainter_compositionmode_from_cairo_op (op)); - - if (! _cairo_qt_fast_fill (qs, source)) { - PatternToBrushConverter brush (source); - qs->p->fillRect (qs->window, brush); - } - - if (qs->supports_porter_duff) - qs->p->setCompositionMode (QPainter::CompositionMode_SourceOver); - - return CAIRO_INT_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_qt_surface_fill (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; - - D(fprintf(stderr, "q[%p] fill op:%s\n", abstract_surface, _opstr(op))); - - if (! _op_is_supported (qs, op)) - return _cairo_surface_fallback_fill (abstract_surface, op, - source, path, fill_rule, - tolerance, antialias, clip); - - cairo_int_status_t status = _cairo_qt_surface_set_clip (qs, clip); - if (unlikely (status)) - return status; - - if (qs->supports_porter_duff) - qs->p->setCompositionMode (_qpainter_compositionmode_from_cairo_op (op)); - - // XXX Qt4.3, 4.4 misrenders some complex paths if antialiasing is - // enabled - //qs->p->setRenderHint (QPainter::Antialiasing, antialias == CAIRO_ANTIALIAS_NONE ? false : true); - qs->p->setRenderHint (QPainter::SmoothPixmapTransform, source->filter != CAIRO_FILTER_FAST); - - if (! _cairo_qt_fast_fill (qs, source, - path, fill_rule, tolerance, antialias)) - { - PatternToBrushConverter brush(source); - qs->p->fillPath (path_to_qt (path, fill_rule), brush); - } - - if (qs->supports_porter_duff) - qs->p->setCompositionMode (QPainter::CompositionMode_SourceOver); - - return CAIRO_INT_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_qt_surface_stroke (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; - - D(fprintf(stderr, "q[%p] stroke op:%s\n", abstract_surface, _opstr(op))); - - if (! _op_is_supported (qs, op)) - return _cairo_surface_fallback_stroke (abstract_surface, op, - source, path, style, ctm, - ctm_inverse, tolerance, - antialias, clip); - - cairo_int_status_t int_status = _cairo_qt_surface_set_clip (qs, clip); - if (unlikely (int_status)) - return int_status; - - QMatrix savedMatrix = qs->p->worldMatrix(); - - if (qs->supports_porter_duff) - qs->p->setCompositionMode (_qpainter_compositionmode_from_cairo_op (op)); - - qs->p->setWorldMatrix (_qmatrix_from_cairo_matrix (*ctm), true); - // XXX Qt4.3, 4.4 misrenders some complex paths if antialiasing is - // enabled - //qs->p->setRenderHint (QPainter::Antialiasing, antialias == CAIRO_ANTIALIAS_NONE ? false : true); - qs->p->setRenderHint (QPainter::SmoothPixmapTransform, source->filter != CAIRO_FILTER_FAST); - - PatternToPenConverter pen(source, style); - - qs->p->setPen(pen); - qs->p->drawPath(path_to_qt (path, ctm_inverse)); - qs->p->setPen(Qt::black); - - qs->p->setWorldMatrix (savedMatrix, false); - - if (qs->supports_porter_duff) - qs->p->setCompositionMode (QPainter::CompositionMode_SourceOver); - - return CAIRO_INT_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_qt_surface_show_glyphs (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ -#if ((QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)) || defined(QT_GLYPHS_API_BACKPORT)) && 0 - cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; - - // pick out the colour to use from the cairo source - cairo_solid_pattern_t *solid = (cairo_solid_pattern_t*) source; - cairo_scaled_glyph_t* glyph; - // documentation says you have to freeze the cache, but I don't believe it - _cairo_scaled_font_freeze_cache(scaled_font); - - QColor tempColour(solid->color.red * 255, solid->color.green * 255, solid->color.blue * 255); - QVarLengthArray<QPointF> positions(num_glyphs); - QVarLengthArray<unsigned int> glyphss(num_glyphs); - FT_Face face = cairo_ft_scaled_font_lock_face (scaled_font); - const FT_Size_Metrics& ftMetrics = face->size->metrics; - QFont font(face->family_name); - font.setStyleStrategy(QFont::NoFontMerging); - font.setBold(face->style_flags & FT_STYLE_FLAG_BOLD); - font.setItalic(face->style_flags & FT_STYLE_FLAG_ITALIC); - font.setKerning(face->face_flags & FT_FACE_FLAG_KERNING); - font.setPixelSize(ftMetrics.y_ppem); - cairo_ft_scaled_font_unlock_face(scaled_font); - qs->p->setFont(font); - qs->p->setPen(tempColour); - for (int currentGlyph = 0; currentGlyph < num_glyphs; currentGlyph++) { - positions[currentGlyph].setX(glyphs[currentGlyph].x); - positions[currentGlyph].setY(glyphs[currentGlyph].y); - glyphss[currentGlyph] = glyphs[currentGlyph].index; - } - qt_draw_glyphs(qs->p, glyphss.data(), positions.data(), num_glyphs); - _cairo_scaled_font_thaw_cache(scaled_font); - return CAIRO_INT_STATUS_SUCCESS; -#else - return _cairo_surface_fallback_glyphs (abstract_surface, op, - source, glyphs, num_glyphs, - scaled_font, clip); -#endif -} - -static cairo_int_status_t -_cairo_qt_surface_mask (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; - - D(fprintf(stderr, "q[%p] mask op:%s\n", abstract_surface, _opstr(op))); - - if (qs->p && mask->type == CAIRO_PATTERN_TYPE_SOLID) { - cairo_solid_pattern_t *solid_mask = (cairo_solid_pattern_t *) mask; - cairo_int_status_t result; - - qs->p->setOpacity (solid_mask->color.alpha); - - result = _cairo_qt_surface_paint (abstract_surface, op, source, clip); - - qs->p->setOpacity (1.0); - - return result; - } - - // otherwise skip for now - return _cairo_surface_fallback_mask (abstract_surface, op, source, mask, clip); -} - -static cairo_status_t -_cairo_qt_surface_mark_dirty (void *abstract_surface, - int x, int y, - int width, int height) -{ - cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; - - if (qs->p && !(qs->image || qs->pixmap)) - qs->p->save (); - - return CAIRO_STATUS_SUCCESS; -} - -/* - * Backend struct - */ - -static const cairo_surface_backend_t cairo_qt_surface_backend = { - CAIRO_SURFACE_TYPE_QT, - _cairo_qt_surface_finish, - - _cairo_default_context_create, /* XXX */ - - _cairo_qt_surface_create_similar, - NULL, /* similar image */ - _cairo_qt_surface_map_to_image, - _cairo_qt_surface_unmap_image, - - _cairo_surface_default_source, - _cairo_qt_surface_acquire_source_image, - _cairo_qt_surface_release_source_image, - NULL, /* snapshot */ - - NULL, /* copy_page */ - NULL, /* show_page */ - - _cairo_qt_surface_get_extents, - NULL, /* get_font_options */ - - NULL, /* flush */ - _cairo_qt_surface_mark_dirty, - - _cairo_qt_surface_paint, - _cairo_qt_surface_mask, - _cairo_qt_surface_stroke, - _cairo_qt_surface_fill, - NULL, /* fill_stroke */ - _cairo_qt_surface_show_glyphs -}; - -cairo_surface_t * -cairo_qt_surface_create (QPainter *painter) -{ - cairo_qt_surface_t *qs; - - qs = (cairo_qt_surface_t *) malloc (sizeof(cairo_qt_surface_t)); - if (qs == NULL) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - memset (qs, 0, sizeof(cairo_qt_surface_t)); - - _cairo_surface_init (&qs->base, - &cairo_qt_surface_backend, - NULL, /* device */ - CAIRO_CONTENT_COLOR_ALPHA); - - _cairo_surface_clipper_init (&qs->clipper, - _cairo_qt_surface_clipper_intersect_clip_path); - - qs->p = painter; - if (qs->p->paintEngine()) - qs->supports_porter_duff = qs->p->paintEngine()->hasFeature(QPaintEngine::PorterDuff); - else - qs->supports_porter_duff = FALSE; - - // Save so that we can always get back to the original state - qs->p->save(); - - qs->window = painter->window(); - - D(fprintf(stderr, "qpainter_surface_create: window: [%d %d %d %d] pd:%d\n", - qs->window.x(), qs->window.y(), qs->window.width(), qs->window.height(), - qs->supports_porter_duff)); - - return &qs->base; -} - -cairo_surface_t * -cairo_qt_surface_create_with_qimage (cairo_format_t format, - int width, - int height) -{ - cairo_qt_surface_t *qs; - - qs = (cairo_qt_surface_t *) malloc (sizeof(cairo_qt_surface_t)); - if (qs == NULL) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - memset (qs, 0, sizeof(cairo_qt_surface_t)); - - _cairo_surface_init (&qs->base, - &cairo_qt_surface_backend, - NULL, /* device */ - _cairo_content_from_format (format)); - - _cairo_surface_clipper_init (&qs->clipper, - _cairo_qt_surface_clipper_intersect_clip_path); - - - QImage *image = new QImage (width, height, - _qimage_format_from_cairo_format (format)); - - qs->image = image; - - if (!image->isNull()) { - qs->p = new QPainter(image); - qs->supports_porter_duff = qs->p->paintEngine()->hasFeature(QPaintEngine::PorterDuff); - } - - qs->image_equiv = cairo_image_surface_create_for_data (image->bits(), - format, - width, height, - image->bytesPerLine()); - - qs->window = QRect(0, 0, width, height); - - D(fprintf(stderr, "qpainter_surface_create: qimage: [%d %d %d %d] pd:%d\n", - qs->window.x(), qs->window.y(), qs->window.width(), qs->window.height(), - qs->supports_porter_duff)); - - return &qs->base; -} - -cairo_surface_t * -cairo_qt_surface_create_with_qpixmap (cairo_content_t content, - int width, - int height) -{ - cairo_qt_surface_t *qs; - - if ((content & CAIRO_CONTENT_COLOR) == 0) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT)); - - qs = (cairo_qt_surface_t *) malloc (sizeof(cairo_qt_surface_t)); - if (qs == NULL) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - memset (qs, 0, sizeof(cairo_qt_surface_t)); - - QPixmap *pixmap = new QPixmap (width, height); - if (pixmap == NULL) { - free (qs); - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - // By default, a QPixmap is opaque; however, if it's filled - // with a color with a transparency component, it is converted - // to a format that preserves transparency. - if (content == CAIRO_CONTENT_COLOR_ALPHA) - pixmap->fill(Qt::transparent); - - _cairo_surface_init (&qs->base, - &cairo_qt_surface_backend, - NULL, /* device */ - content); - - _cairo_surface_clipper_init (&qs->clipper, - _cairo_qt_surface_clipper_intersect_clip_path); - - qs->pixmap = pixmap; - - if (!pixmap->isNull()) { - qs->p = new QPainter(pixmap); - qs->supports_porter_duff = qs->p->paintEngine()->hasFeature(QPaintEngine::PorterDuff); - } - - qs->window = QRect(0, 0, width, height); - - D(fprintf(stderr, "qpainter_surface_create: qpixmap: [%d %d %d %d] pd:%d\n", - qs->window.x(), qs->window.y(), qs->window.width(), qs->window.height(), - qs->supports_porter_duff)); - - return &qs->base; -} - -/** - * _cairo_surface_is_qt: - * @surface: a #cairo_surface_t - * - * Checks if a surface is a #cairo_qt_surface_t - * - * Return value: True if the surface is an qt surface - **/ -static inline cairo_bool_t -_cairo_surface_is_qt (cairo_surface_t *surface) -{ - return surface->backend == &cairo_qt_surface_backend; -} - -QPainter * -cairo_qt_surface_get_qpainter (cairo_surface_t *surface) -{ - cairo_qt_surface_t *qs = (cairo_qt_surface_t*) surface; - - /* Throw an error for a non-qt surface */ - if (! _cairo_surface_is_qt (surface)) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return NULL; - } - - return qs->p; -} - -QImage * -cairo_qt_surface_get_qimage (cairo_surface_t *surface) -{ - cairo_qt_surface_t *qs = (cairo_qt_surface_t*) surface; - - /* Throw an error for a non-qt surface */ - if (! _cairo_surface_is_qt (surface)) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return NULL; - } - - return qs->image; -} - -cairo_surface_t * -cairo_qt_surface_get_image (cairo_surface_t *surface) -{ - cairo_qt_surface_t *qs = (cairo_qt_surface_t*) surface; - - /* Throw an error for a non-qt surface */ - if (! _cairo_surface_is_qt (surface)) { - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH)); - } - - return qs->image_equiv; -} - -/* - * TODO: - * - * - Figure out why QBrush isn't working with non-repeated images - * - * - Correct repeat mode; right now, every surface source is EXTEND_REPEAT - * - implement EXTEND_NONE (?? probably need to clip to the extents of the source) - * - implement EXTEND_REFLECT (create temporary and copy 4x, then EXTEND_REPEAT that) - * - * - stroke-image failure - * - * - Implement mask() with non-solid masks (probably will need to use a temporary and use IN) - * - * - Implement gradient sources - * - * - Make create_similar smarter -- create QPixmaps in more circumstances - * (e.g. if the pixmap can have alpha) - * - * - Implement show_glyphs() in terms of Qt - * - */ diff --git a/source/libs/cairo/cairo-src/src/cairo-qt.h b/source/libs/cairo/cairo-src/src/cairo-qt.h deleted file mode 100644 index c20bbb18d0b893340b0c5a5690b40a86b61f98f0..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-qt.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2008 Mozilla Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Mozilla Corporation. - * - * Contributor(s): - * Vladimir Vukicevic <vladimir@mozilla.com> - */ - -#ifndef CAIRO_QT_H -#define CAIRO_QT_H - -#include "cairo.h" - -#if CAIRO_HAS_QT_SURFACE - -#include <QtGui/QImage> -#include <QtGui/QPainter> - -CAIRO_BEGIN_DECLS - -cairo_public cairo_surface_t * -cairo_qt_surface_create (QPainter *painter); - -cairo_public cairo_surface_t * -cairo_qt_surface_create_with_qimage (cairo_format_t format, - int width, - int height); - -cairo_public cairo_surface_t * -cairo_qt_surface_create_with_qpixmap (cairo_content_t content, - int width, - int height); - -cairo_public QPainter * -cairo_qt_surface_get_qpainter (cairo_surface_t *surface); - -/* XXX needs hooking to generic surface layer, my vote is for -cairo_public cairo_surface_t * -cairo_surface_map_image (cairo_surface_t *surface); -cairo_public void -cairo_surface_unmap_image (cairo_surface_t *surface, cairo_surface_t *image); -*/ -cairo_public cairo_surface_t * -cairo_qt_surface_get_image (cairo_surface_t *surface); - -cairo_public QImage * -cairo_qt_surface_get_qimage (cairo_surface_t *surface); - -CAIRO_END_DECLS - -#else /* CAIRO_HAS_QT_SURFACE */ - -# error Cairo was not compiled with support for the Qt backend - -#endif /* CAIRO_HAS_QT_SURFACE */ - -#endif /* CAIRO_QT_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-quartz-font.c b/source/libs/cairo/cairo-src/src/cairo-quartz-font.c deleted file mode 100644 index feee61a0d861fad1190aa545b5de65b09c13e7f8..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-quartz-font.c +++ /dev/null @@ -1,859 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright � 2008 Mozilla Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Mozilla Foundation. - * - * Contributor(s): - * Vladimir Vukicevic <vladimir@mozilla.com> - */ - -#include "cairoint.h" - -#include <dlfcn.h> - -#include "cairo-image-surface-private.h" -#include "cairo-quartz.h" -#include "cairo-quartz-private.h" - -#include "cairo-error-private.h" - -/** - * SECTION:cairo-quartz-fonts - * @Title: Quartz (CGFont) Fonts - * @Short_Description: Font support via CGFont on OS X - * @See_Also: #cairo_font_face_t - * - * The Quartz font backend is primarily used to render text on Apple - * MacOS X systems. The CGFont API is used for the internal - * implementation of the font backend methods. - **/ - -/** - * CAIRO_HAS_QUARTZ_FONT: - * - * Defined if the Quartz font backend is available. - * This macro can be used to conditionally compile backend-specific code. - * - * Since: 1.6 - **/ - -static CFDataRef (*CGFontCopyTableForTagPtr) (CGFontRef font, uint32_t tag) = NULL; - -/* CreateWithFontName exists in 10.5, but not in 10.4; CreateWithName isn't public in 10.4 */ -static CGFontRef (*CGFontCreateWithFontNamePtr) (CFStringRef) = NULL; -static CGFontRef (*CGFontCreateWithNamePtr) (const char *) = NULL; - -/* These aren't public before 10.5, and some have different names in 10.4 */ -static int (*CGFontGetUnitsPerEmPtr) (CGFontRef) = NULL; -static bool (*CGFontGetGlyphAdvancesPtr) (CGFontRef, const CGGlyph[], size_t, int[]) = NULL; -static bool (*CGFontGetGlyphBBoxesPtr) (CGFontRef, const CGGlyph[], size_t, CGRect[]) = NULL; -static CGRect (*CGFontGetFontBBoxPtr) (CGFontRef) = NULL; - -/* Not public, but present */ -static void (*CGFontGetGlyphsForUnicharsPtr) (CGFontRef, const UniChar[], const CGGlyph[], size_t) = NULL; -static void (*CGContextSetAllowsFontSmoothingPtr) (CGContextRef, bool) = NULL; -static bool (*CGContextGetAllowsFontSmoothingPtr) (CGContextRef) = NULL; - -/* CGFontGetHMetrics isn't public, but the other functions are public/present in 10.5 */ -typedef struct { - int ascent; - int descent; - int leading; -} quartz_CGFontMetrics; -static quartz_CGFontMetrics* (*CGFontGetHMetricsPtr) (CGFontRef fontRef) = NULL; -static int (*CGFontGetAscentPtr) (CGFontRef fontRef) = NULL; -static int (*CGFontGetDescentPtr) (CGFontRef fontRef) = NULL; -static int (*CGFontGetLeadingPtr) (CGFontRef fontRef) = NULL; - -/* Not public anymore in 64-bits nor in 10.7 */ -static ATSFontRef (*FMGetATSFontRefFromFontPtr) (FMFont iFont) = NULL; - -static cairo_bool_t _cairo_quartz_font_symbol_lookup_done = FALSE; -static cairo_bool_t _cairo_quartz_font_symbols_present = FALSE; - -static void -quartz_font_ensure_symbols(void) -{ - if (_cairo_quartz_font_symbol_lookup_done) - return; - - CGFontCopyTableForTagPtr = dlsym(RTLD_DEFAULT, "CGFontCopyTableForTag"); - - /* Look for the 10.5 versions first */ - CGFontGetGlyphBBoxesPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphBBoxes"); - if (!CGFontGetGlyphBBoxesPtr) - CGFontGetGlyphBBoxesPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphBoundingBoxes"); - - CGFontGetGlyphsForUnicharsPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphsForUnichars"); - if (!CGFontGetGlyphsForUnicharsPtr) - CGFontGetGlyphsForUnicharsPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphsForUnicodes"); - - CGFontGetFontBBoxPtr = dlsym(RTLD_DEFAULT, "CGFontGetFontBBox"); - - /* We just need one of these two */ - CGFontCreateWithFontNamePtr = dlsym(RTLD_DEFAULT, "CGFontCreateWithFontName"); - CGFontCreateWithNamePtr = dlsym(RTLD_DEFAULT, "CGFontCreateWithName"); - - /* These have the same name in 10.4 and 10.5 */ - CGFontGetUnitsPerEmPtr = dlsym(RTLD_DEFAULT, "CGFontGetUnitsPerEm"); - CGFontGetGlyphAdvancesPtr = dlsym(RTLD_DEFAULT, "CGFontGetGlyphAdvances"); - - CGFontGetHMetricsPtr = dlsym(RTLD_DEFAULT, "CGFontGetHMetrics"); - CGFontGetAscentPtr = dlsym(RTLD_DEFAULT, "CGFontGetAscent"); - CGFontGetDescentPtr = dlsym(RTLD_DEFAULT, "CGFontGetDescent"); - CGFontGetLeadingPtr = dlsym(RTLD_DEFAULT, "CGFontGetLeading"); - - CGContextGetAllowsFontSmoothingPtr = dlsym(RTLD_DEFAULT, "CGContextGetAllowsFontSmoothing"); - CGContextSetAllowsFontSmoothingPtr = dlsym(RTLD_DEFAULT, "CGContextSetAllowsFontSmoothing"); - - FMGetATSFontRefFromFontPtr = dlsym(RTLD_DEFAULT, "FMGetATSFontRefFromFont"); - - if ((CGFontCreateWithFontNamePtr || CGFontCreateWithNamePtr) && - CGFontGetGlyphBBoxesPtr && - CGFontGetGlyphsForUnicharsPtr && - CGFontGetUnitsPerEmPtr && - CGFontGetGlyphAdvancesPtr && - (CGFontGetHMetricsPtr || (CGFontGetAscentPtr && CGFontGetDescentPtr && CGFontGetLeadingPtr))) - _cairo_quartz_font_symbols_present = TRUE; - - _cairo_quartz_font_symbol_lookup_done = TRUE; -} - -typedef struct _cairo_quartz_font_face cairo_quartz_font_face_t; -typedef struct _cairo_quartz_scaled_font cairo_quartz_scaled_font_t; - -struct _cairo_quartz_scaled_font { - cairo_scaled_font_t base; -}; - -struct _cairo_quartz_font_face { - cairo_font_face_t base; - - CGFontRef cgFont; -}; - -/* - * font face backend - */ - -static cairo_status_t -_cairo_quartz_font_face_create_for_toy (cairo_toy_font_face_t *toy_face, - cairo_font_face_t **font_face) -{ - const char *family; - char *full_name; - CFStringRef cgFontName = NULL; - CGFontRef cgFont = NULL; - int loop; - - quartz_font_ensure_symbols(); - if (! _cairo_quartz_font_symbols_present) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - family = toy_face->family; - full_name = malloc (strlen (family) + 64); // give us a bit of room to tack on Bold, Oblique, etc. - /* handle CSS-ish faces */ - if (!strcmp(family, "serif") || !strcmp(family, "Times Roman")) - family = "Times"; - else if (!strcmp(family, "sans-serif") || !strcmp(family, "sans")) - family = "Helvetica"; - else if (!strcmp(family, "cursive")) - family = "Apple Chancery"; - else if (!strcmp(family, "fantasy")) - family = "Papyrus"; - else if (!strcmp(family, "monospace") || !strcmp(family, "mono")) - family = "Courier"; - - /* Try to build up the full name, e.g. "Helvetica Bold Oblique" first, - * then drop the bold, then drop the slant, then drop both.. finally - * just use "Helvetica". And if Helvetica doesn't exist, give up. - */ - for (loop = 0; loop < 5; loop++) { - if (loop == 4) - family = "Helvetica"; - - strcpy (full_name, family); - - if (loop < 3 && (loop & 1) == 0) { - if (toy_face->weight == CAIRO_FONT_WEIGHT_BOLD) - strcat (full_name, " Bold"); - } - - if (loop < 3 && (loop & 2) == 0) { - if (toy_face->slant == CAIRO_FONT_SLANT_ITALIC) - strcat (full_name, " Italic"); - else if (toy_face->slant == CAIRO_FONT_SLANT_OBLIQUE) - strcat (full_name, " Oblique"); - } - - if (CGFontCreateWithFontNamePtr) { - cgFontName = CFStringCreateWithCString (NULL, full_name, kCFStringEncodingASCII); - cgFont = CGFontCreateWithFontNamePtr (cgFontName); - CFRelease (cgFontName); - } else { - cgFont = CGFontCreateWithNamePtr (full_name); - } - - if (cgFont) - break; - } - - if (!cgFont) { - /* Give up */ - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - *font_face = cairo_quartz_font_face_create_for_cgfont (cgFont); - CGFontRelease (cgFont); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_bool_t -_cairo_quartz_font_face_destroy (void *abstract_face) -{ - cairo_quartz_font_face_t *font_face = (cairo_quartz_font_face_t*) abstract_face; - - CGFontRelease (font_face->cgFont); - return TRUE; -} - -static const cairo_scaled_font_backend_t _cairo_quartz_scaled_font_backend; - -static cairo_status_t -_cairo_quartz_font_face_scaled_font_create (void *abstract_face, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options, - cairo_scaled_font_t **font_out) -{ - cairo_quartz_font_face_t *font_face = abstract_face; - cairo_quartz_scaled_font_t *font = NULL; - cairo_status_t status; - cairo_font_extents_t fs_metrics; - double ems; - CGRect bbox; - - quartz_font_ensure_symbols(); - if (!_cairo_quartz_font_symbols_present) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - font = malloc(sizeof(cairo_quartz_scaled_font_t)); - if (font == NULL) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - memset (font, 0, sizeof(cairo_quartz_scaled_font_t)); - - status = _cairo_scaled_font_init (&font->base, - &font_face->base, font_matrix, ctm, options, - &_cairo_quartz_scaled_font_backend); - if (status) - goto FINISH; - - ems = CGFontGetUnitsPerEmPtr (font_face->cgFont); - - /* initialize metrics */ - if (CGFontGetFontBBoxPtr && CGFontGetAscentPtr) { - fs_metrics.ascent = (CGFontGetAscentPtr (font_face->cgFont) / ems); - fs_metrics.descent = - (CGFontGetDescentPtr (font_face->cgFont) / ems); - fs_metrics.height = fs_metrics.ascent + fs_metrics.descent + - (CGFontGetLeadingPtr (font_face->cgFont) / ems); - - bbox = CGFontGetFontBBoxPtr (font_face->cgFont); - fs_metrics.max_x_advance = CGRectGetMaxX(bbox) / ems; - fs_metrics.max_y_advance = 0.0; - } else { - CGGlyph wGlyph; - UniChar u; - - quartz_CGFontMetrics *m; - m = CGFontGetHMetricsPtr (font_face->cgFont); - - /* On OX 10.4, GetHMetricsPtr sometimes returns NULL for unknown reasons */ - if (!m) { - status = _cairo_error(CAIRO_STATUS_NULL_POINTER); - goto FINISH; - } - - fs_metrics.ascent = (m->ascent / ems); - fs_metrics.descent = - (m->descent / ems); - fs_metrics.height = fs_metrics.ascent + fs_metrics.descent + (m->leading / ems); - - /* We kind of have to guess here; W's big, right? */ - u = (UniChar) 'W'; - CGFontGetGlyphsForUnicharsPtr (font_face->cgFont, &u, &wGlyph, 1); - if (wGlyph && CGFontGetGlyphBBoxesPtr (font_face->cgFont, &wGlyph, 1, &bbox)) { - fs_metrics.max_x_advance = CGRectGetMaxX(bbox) / ems; - fs_metrics.max_y_advance = 0.0; - } else { - fs_metrics.max_x_advance = 0.0; - fs_metrics.max_y_advance = 0.0; - } - } - - status = _cairo_scaled_font_set_metrics (&font->base, &fs_metrics); - -FINISH: - if (status != CAIRO_STATUS_SUCCESS) { - free (font); - } else { - *font_out = (cairo_scaled_font_t*) font; - } - - return status; -} - -const cairo_font_face_backend_t _cairo_quartz_font_face_backend = { - CAIRO_FONT_TYPE_QUARTZ, - _cairo_quartz_font_face_create_for_toy, - _cairo_quartz_font_face_destroy, - _cairo_quartz_font_face_scaled_font_create -}; - -/** - * cairo_quartz_font_face_create_for_cgfont: - * @font: a #CGFontRef obtained through a method external to cairo. - * - * Creates a new font for the Quartz font backend based on a - * #CGFontRef. This font can then be used with - * cairo_set_font_face() or cairo_scaled_font_create(). - * - * Return value: a newly created #cairo_font_face_t. Free with - * cairo_font_face_destroy() when you are done using it. - * - * Since: 1.6 - **/ -cairo_font_face_t * -cairo_quartz_font_face_create_for_cgfont (CGFontRef font) -{ - cairo_quartz_font_face_t *font_face; - - quartz_font_ensure_symbols(); - - font_face = malloc (sizeof (cairo_quartz_font_face_t)); - if (!font_face) { - cairo_status_t ignore_status; - ignore_status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - return (cairo_font_face_t *)&_cairo_font_face_nil; - } - - font_face->cgFont = CGFontRetain (font); - - _cairo_font_face_init (&font_face->base, &_cairo_quartz_font_face_backend); - - return &font_face->base; -} - -/* - * scaled font backend - */ - -static cairo_quartz_font_face_t * -_cairo_quartz_scaled_to_face (void *abstract_font) -{ - cairo_quartz_scaled_font_t *sfont = (cairo_quartz_scaled_font_t*) abstract_font; - cairo_font_face_t *font_face = sfont->base.font_face; - assert (font_face->backend->type == CAIRO_FONT_TYPE_QUARTZ); - return (cairo_quartz_font_face_t*) font_face; -} - -static void -_cairo_quartz_scaled_font_fini(void *abstract_font) -{ -} - -#define INVALID_GLYPH 0x00 - -static inline CGGlyph -_cairo_quartz_scaled_glyph_index (cairo_scaled_glyph_t *scaled_glyph) { - unsigned long index = _cairo_scaled_glyph_index (scaled_glyph); - if (index > 0xffff) - return INVALID_GLYPH; - return (CGGlyph) index; -} - -static cairo_int_status_t -_cairo_quartz_init_glyph_metrics (cairo_quartz_scaled_font_t *font, - cairo_scaled_glyph_t *scaled_glyph) -{ - cairo_int_status_t status = CAIRO_STATUS_SUCCESS; - - cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font); - cairo_text_extents_t extents = {0, 0, 0, 0, 0, 0}; - CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph); - int advance; - CGRect bbox; - double emscale = CGFontGetUnitsPerEmPtr (font_face->cgFont); - double xmin, ymin, xmax, ymax; - - if (glyph == INVALID_GLYPH) - goto FAIL; - - if (!CGFontGetGlyphAdvancesPtr (font_face->cgFont, &glyph, 1, &advance) || - !CGFontGetGlyphBBoxesPtr (font_face->cgFont, &glyph, 1, &bbox)) - goto FAIL; - - /* broken fonts like Al Bayan return incorrect bounds for some null characters, - see https://bugzilla.mozilla.org/show_bug.cgi?id=534260 */ - if (unlikely (bbox.origin.x == -32767 && - bbox.origin.y == -32767 && - bbox.size.width == 65534 && - bbox.size.height == 65534)) { - bbox.origin.x = bbox.origin.y = 0; - bbox.size.width = bbox.size.height = 0; - } - - bbox = CGRectMake (bbox.origin.x / emscale, - bbox.origin.y / emscale, - bbox.size.width / emscale, - bbox.size.height / emscale); - - /* Should we want to always integer-align glyph extents, we can do so in this way */ -#if 0 - { - CGAffineTransform textMatrix; - textMatrix = CGAffineTransformMake (font->base.scale.xx, - -font->base.scale.yx, - -font->base.scale.xy, - font->base.scale.yy, - 0.0f, 0.0f); - - bbox = CGRectApplyAffineTransform (bbox, textMatrix); - bbox = CGRectIntegral (bbox); - bbox = CGRectApplyAffineTransform (bbox, CGAffineTransformInvert (textMatrix)); - } -#endif - -#if 0 - fprintf (stderr, "[0x%04x] bbox: %f %f %f %f\n", glyph, - bbox.origin.x / emscale, bbox.origin.y / emscale, - bbox.size.width / emscale, bbox.size.height / emscale); -#endif - - xmin = CGRectGetMinX(bbox); - ymin = CGRectGetMinY(bbox); - xmax = CGRectGetMaxX(bbox); - ymax = CGRectGetMaxY(bbox); - - extents.x_bearing = xmin; - extents.y_bearing = - ymax; - extents.width = xmax - xmin; - extents.height = ymax - ymin; - - extents.x_advance = (double) advance / emscale; - extents.y_advance = 0.0; - -#if 0 - fprintf (stderr, "[0x%04x] extents: bearings: %f %f dim: %f %f adv: %f\n\n", glyph, - extents.x_bearing, extents.y_bearing, extents.width, extents.height, extents.x_advance); -#endif - - FAIL: - _cairo_scaled_glyph_set_metrics (scaled_glyph, - &font->base, - &extents); - - return status; -} - -static void -_cairo_quartz_path_apply_func (void *info, const CGPathElement *el) -{ - cairo_path_fixed_t *path = (cairo_path_fixed_t *) info; - cairo_status_t status; - - switch (el->type) { - case kCGPathElementMoveToPoint: - status = _cairo_path_fixed_move_to (path, - _cairo_fixed_from_double(el->points[0].x), - _cairo_fixed_from_double(el->points[0].y)); - assert(!status); - break; - case kCGPathElementAddLineToPoint: - status = _cairo_path_fixed_line_to (path, - _cairo_fixed_from_double(el->points[0].x), - _cairo_fixed_from_double(el->points[0].y)); - assert(!status); - break; - case kCGPathElementAddQuadCurveToPoint: { - cairo_fixed_t fx, fy; - double x, y; - if (!_cairo_path_fixed_get_current_point (path, &fx, &fy)) - fx = fy = 0; - x = _cairo_fixed_to_double (fx); - y = _cairo_fixed_to_double (fy); - - status = _cairo_path_fixed_curve_to (path, - _cairo_fixed_from_double((x + el->points[0].x * 2.0) / 3.0), - _cairo_fixed_from_double((y + el->points[0].y * 2.0) / 3.0), - _cairo_fixed_from_double((el->points[0].x * 2.0 + el->points[1].x) / 3.0), - _cairo_fixed_from_double((el->points[0].y * 2.0 + el->points[1].y) / 3.0), - _cairo_fixed_from_double(el->points[1].x), - _cairo_fixed_from_double(el->points[1].y)); - } - assert(!status); - break; - case kCGPathElementAddCurveToPoint: - status = _cairo_path_fixed_curve_to (path, - _cairo_fixed_from_double(el->points[0].x), - _cairo_fixed_from_double(el->points[0].y), - _cairo_fixed_from_double(el->points[1].x), - _cairo_fixed_from_double(el->points[1].y), - _cairo_fixed_from_double(el->points[2].x), - _cairo_fixed_from_double(el->points[2].y)); - assert(!status); - break; - case kCGPathElementCloseSubpath: - status = _cairo_path_fixed_close_path (path); - assert(!status); - break; - } -} - -static cairo_int_status_t -_cairo_quartz_init_glyph_path (cairo_quartz_scaled_font_t *font, - cairo_scaled_glyph_t *scaled_glyph) -{ - cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font); - CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph); - CGAffineTransform textMatrix; - CGPathRef glyphPath; - CTFontRef ctFont; - cairo_path_fixed_t *path; - - if (glyph == INVALID_GLYPH) { - _cairo_scaled_glyph_set_path (scaled_glyph, &font->base, _cairo_path_fixed_create()); - return CAIRO_STATUS_SUCCESS; - } - - /* scale(1,-1) * font->base.scale */ - textMatrix = CGAffineTransformMake (font->base.scale.xx, - font->base.scale.yx, - -font->base.scale.xy, - -font->base.scale.yy, - 0, 0); - - ctFont = CTFontCreateWithGraphicsFont (font_face->cgFont, 1.0, NULL, NULL); - glyphPath = CTFontCreatePathForGlyph (ctFont, glyph, &textMatrix); - CFRelease (ctFont); - if (!glyphPath) - return CAIRO_INT_STATUS_UNSUPPORTED; - - path = _cairo_path_fixed_create (); - if (!path) { - CGPathRelease (glyphPath); - return _cairo_error(CAIRO_STATUS_NO_MEMORY); - } - - CGPathApply (glyphPath, path, _cairo_quartz_path_apply_func); - - CGPathRelease (glyphPath); - - _cairo_scaled_glyph_set_path (scaled_glyph, &font->base, path); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font, - cairo_scaled_glyph_t *scaled_glyph) -{ - cairo_int_status_t status = CAIRO_STATUS_SUCCESS; - - cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font); - - cairo_image_surface_t *surface = NULL; - - CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph); - - int advance; - CGRect bbox; - double width, height; - double emscale = CGFontGetUnitsPerEmPtr (font_face->cgFont); - - CGContextRef cgContext = NULL; - CGAffineTransform textMatrix; - CGRect glyphRect, glyphRectInt; - CGPoint glyphOrigin; - - //fprintf (stderr, "scaled_glyph: %p surface: %p\n", scaled_glyph, scaled_glyph->surface); - - /* Create blank 2x2 image if we don't have this character. - * Maybe we should draw a better missing-glyph slug or something, - * but this is ok for now. - */ - if (glyph == INVALID_GLYPH) { - surface = (cairo_image_surface_t*) cairo_image_surface_create (CAIRO_FORMAT_A8, 2, 2); - status = cairo_surface_status ((cairo_surface_t *) surface); - if (status) - return status; - - _cairo_scaled_glyph_set_surface (scaled_glyph, - &font->base, - surface); - return CAIRO_STATUS_SUCCESS; - } - - if (!CGFontGetGlyphAdvancesPtr (font_face->cgFont, &glyph, 1, &advance) || - !CGFontGetGlyphBBoxesPtr (font_face->cgFont, &glyph, 1, &bbox)) - { - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - /* scale(1,-1) * font->base.scale * scale(1,-1) */ - textMatrix = CGAffineTransformMake (font->base.scale.xx, - -font->base.scale.yx, - -font->base.scale.xy, - font->base.scale.yy, - 0, -0); - glyphRect = CGRectMake (bbox.origin.x / emscale, - bbox.origin.y / emscale, - bbox.size.width / emscale, - bbox.size.height / emscale); - - glyphRect = CGRectApplyAffineTransform (glyphRect, textMatrix); - - /* Round the rectangle outwards, so that we don't have to deal - * with non-integer-pixel origins or dimensions. - */ - glyphRectInt = CGRectIntegral (glyphRect); - -#if 0 - fprintf (stderr, "glyphRect[o]: %f %f %f %f\n", - glyphRect.origin.x, glyphRect.origin.y, glyphRect.size.width, glyphRect.size.height); - fprintf (stderr, "glyphRectInt: %f %f %f %f\n", - glyphRectInt.origin.x, glyphRectInt.origin.y, glyphRectInt.size.width, glyphRectInt.size.height); -#endif - - glyphOrigin = glyphRectInt.origin; - - //textMatrix = CGAffineTransformConcat (textMatrix, CGAffineTransformInvert (ctm)); - - width = glyphRectInt.size.width; - height = glyphRectInt.size.height; - - //fprintf (stderr, "glyphRect[n]: %f %f %f %f\n", glyphRect.origin.x, glyphRect.origin.y, glyphRect.size.width, glyphRect.size.height); - - surface = (cairo_image_surface_t*) cairo_image_surface_create (CAIRO_FORMAT_A8, width, height); - if (surface->base.status) - return surface->base.status; - - if (surface->width != 0 && surface->height != 0) { - cgContext = CGBitmapContextCreate (surface->data, - surface->width, - surface->height, - 8, - surface->stride, - NULL, - kCGImageAlphaOnly); - - if (cgContext == NULL) { - cairo_surface_destroy (&surface->base); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - CGContextSetFont (cgContext, font_face->cgFont); - CGContextSetFontSize (cgContext, 1.0); - CGContextSetTextMatrix (cgContext, textMatrix); - - switch (font->base.options.antialias) { - case CAIRO_ANTIALIAS_SUBPIXEL: - case CAIRO_ANTIALIAS_BEST: - CGContextSetShouldAntialias (cgContext, TRUE); - CGContextSetShouldSmoothFonts (cgContext, TRUE); - if (CGContextSetAllowsFontSmoothingPtr && - !CGContextGetAllowsFontSmoothingPtr (cgContext)) - CGContextSetAllowsFontSmoothingPtr (cgContext, TRUE); - break; - case CAIRO_ANTIALIAS_NONE: - CGContextSetShouldAntialias (cgContext, FALSE); - break; - case CAIRO_ANTIALIAS_GRAY: - case CAIRO_ANTIALIAS_GOOD: - case CAIRO_ANTIALIAS_FAST: - CGContextSetShouldAntialias (cgContext, TRUE); - CGContextSetShouldSmoothFonts (cgContext, FALSE); - break; - case CAIRO_ANTIALIAS_DEFAULT: - default: - /* Don't do anything */ - break; - } - - CGContextSetAlpha (cgContext, 1.0); - CGContextShowGlyphsAtPoint (cgContext, - glyphOrigin.x, - glyphOrigin.y, &glyph, 1); - - CGContextRelease (cgContext); - } - - cairo_surface_set_device_offset (&surface->base, - - glyphOrigin.x, - height + glyphOrigin.y); - - _cairo_scaled_glyph_set_surface (scaled_glyph, &font->base, surface); - - return status; -} - -static cairo_int_status_t -_cairo_quartz_scaled_glyph_init (void *abstract_font, - cairo_scaled_glyph_t *scaled_glyph, - cairo_scaled_glyph_info_t info) -{ - cairo_quartz_scaled_font_t *font = (cairo_quartz_scaled_font_t *) abstract_font; - cairo_int_status_t status = CAIRO_STATUS_SUCCESS; - - if (!status && (info & CAIRO_SCALED_GLYPH_INFO_METRICS)) - status = _cairo_quartz_init_glyph_metrics (font, scaled_glyph); - - if (!status && (info & CAIRO_SCALED_GLYPH_INFO_PATH)) - status = _cairo_quartz_init_glyph_path (font, scaled_glyph); - - if (!status && (info & CAIRO_SCALED_GLYPH_INFO_SURFACE)) - status = _cairo_quartz_init_glyph_surface (font, scaled_glyph); - - return status; -} - -static unsigned long -_cairo_quartz_ucs4_to_index (void *abstract_font, - uint32_t ucs4) -{ - cairo_quartz_scaled_font_t *font = (cairo_quartz_scaled_font_t*) abstract_font; - cairo_quartz_font_face_t *ffont = _cairo_quartz_scaled_to_face(font); - UniChar u = (UniChar) ucs4; - CGGlyph glyph; - - CGFontGetGlyphsForUnicharsPtr (ffont->cgFont, &u, &glyph, 1); - - return glyph; -} - -static cairo_int_status_t -_cairo_quartz_load_truetype_table (void *abstract_font, - unsigned long tag, - long offset, - unsigned char *buffer, - unsigned long *length) -{ - cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face (abstract_font); - CFDataRef data = NULL; - - if (likely (CGFontCopyTableForTagPtr)) - data = CGFontCopyTableForTagPtr (font_face->cgFont, tag); - - if (!data) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (buffer == NULL) { - *length = CFDataGetLength (data); - CFRelease (data); - return CAIRO_STATUS_SUCCESS; - } - - if (CFDataGetLength (data) < offset + (long) *length) { - CFRelease (data); - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - CFDataGetBytes (data, CFRangeMake (offset, *length), buffer); - CFRelease (data); - - return CAIRO_STATUS_SUCCESS; -} - -static const cairo_scaled_font_backend_t _cairo_quartz_scaled_font_backend = { - CAIRO_FONT_TYPE_QUARTZ, - _cairo_quartz_scaled_font_fini, - _cairo_quartz_scaled_glyph_init, - NULL, /* text_to_glyphs */ - _cairo_quartz_ucs4_to_index, - _cairo_quartz_load_truetype_table, - NULL, /* map_glyphs_to_unicode */ -}; - -/* - * private methods that the quartz surface uses - */ - -CGFontRef -_cairo_quartz_scaled_font_get_cg_font_ref (cairo_scaled_font_t *abstract_font) -{ - cairo_quartz_font_face_t *ffont = _cairo_quartz_scaled_to_face(abstract_font); - - return ffont->cgFont; -} - -/* - * compat with old ATSUI backend - */ - -/** - * cairo_quartz_font_face_create_for_atsu_font_id: - * @font_id: an ATSUFontID for the font. - * - * Creates a new font for the Quartz font backend based on an - * #ATSUFontID. This font can then be used with - * cairo_set_font_face() or cairo_scaled_font_create(). - * - * Return value: a newly created #cairo_font_face_t. Free with - * cairo_font_face_destroy() when you are done using it. - * - * Since: 1.6 - **/ -cairo_font_face_t * -cairo_quartz_font_face_create_for_atsu_font_id (ATSUFontID font_id) -{ - quartz_font_ensure_symbols(); - - if (FMGetATSFontRefFromFontPtr != NULL) { - ATSFontRef atsFont = FMGetATSFontRefFromFontPtr (font_id); - CGFontRef cgFont = CGFontCreateWithPlatformFont (&atsFont); - cairo_font_face_t *ff; - - ff = cairo_quartz_font_face_create_for_cgfont (cgFont); - - CGFontRelease (cgFont); - - return ff; - } else { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_font_face_t *)&_cairo_font_face_nil; - } -} - -/* This is the old name for the above function, exported for compat purposes */ -cairo_font_face_t *cairo_atsui_font_face_create_for_atsu_font_id (ATSUFontID font_id); - -cairo_font_face_t * -cairo_atsui_font_face_create_for_atsu_font_id (ATSUFontID font_id) -{ - return cairo_quartz_font_face_create_for_atsu_font_id (font_id); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-quartz-image-surface.c b/source/libs/cairo/cairo-src/src/cairo-quartz-image-surface.c deleted file mode 100644 index 498a7b06436a0e407d54a130c6b14c66b2806e91..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-quartz-image-surface.c +++ /dev/null @@ -1,387 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright � 2008 Mozilla Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Mozilla Foundation. - * - * Contributor(s): - * Vladimir Vukicevic <vladimir@mozilla.com> - */ - -#include "cairoint.h" - -#include "cairo-image-surface-inline.h" -#include "cairo-quartz-image.h" -#include "cairo-quartz-private.h" -#include "cairo-surface-backend-private.h" - -#include "cairo-error-private.h" -#include "cairo-default-context-private.h" - -#define SURFACE_ERROR_NO_MEMORY (_cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_MEMORY))) -#define SURFACE_ERROR_TYPE_MISMATCH (_cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_SURFACE_TYPE_MISMATCH))) -#define SURFACE_ERROR_INVALID_SIZE (_cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_INVALID_SIZE))) -#define SURFACE_ERROR_INVALID_FORMAT (_cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_INVALID_FORMAT))) - -static void -DataProviderReleaseCallback (void *info, const void *data, size_t size) -{ - cairo_surface_t *surface = (cairo_surface_t *) info; - cairo_surface_destroy (surface); -} - -static cairo_surface_t * -_cairo_quartz_image_surface_create_similar (void *asurface, - cairo_content_t content, - int width, - int height) -{ - cairo_surface_t *isurf = - _cairo_image_surface_create_with_content (content, width, height); - cairo_surface_t *result = cairo_quartz_image_surface_create (isurf); - cairo_surface_destroy (isurf); - - return result; -} - -static cairo_surface_t * -_cairo_quartz_image_surface_create_similar_image (void *asurface, - cairo_format_t format, - int width, - int height) -{ - cairo_surface_t *isurf = cairo_image_surface_create (format, width, height); - cairo_surface_t *result = cairo_quartz_image_surface_create (isurf); - cairo_surface_destroy (isurf); - - return result; -} - -static cairo_status_t -_cairo_quartz_image_surface_finish (void *asurface) -{ - cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) asurface; - - /* the imageSurface will be destroyed by the data provider's release callback */ - CGImageRelease (surface->image); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_quartz_image_surface_acquire_source_image (void *asurface, - cairo_image_surface_t **image_out, - void **image_extra) -{ - cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) asurface; - - *image_out = surface->imageSurface; - *image_extra = NULL; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_image_surface_t * -_cairo_quartz_image_surface_map_to_image (void *asurface, - const cairo_rectangle_int_t *extents) -{ - cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) asurface; - return _cairo_surface_map_to_image (&surface->imageSurface->base, extents); -} - -static cairo_int_status_t -_cairo_quartz_image_surface_unmap_image (void *asurface, - cairo_image_surface_t *image) -{ - cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) asurface; - return _cairo_surface_unmap_image (&surface->imageSurface->base, image); -} - -static cairo_bool_t -_cairo_quartz_image_surface_get_extents (void *asurface, - cairo_rectangle_int_t *extents) -{ - cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) asurface; - - extents->x = 0; - extents->y = 0; - extents->width = surface->width; - extents->height = surface->height; - return TRUE; -} - -/* we assume some drawing happened to the image buffer; make sure it's - * represented in the CGImage on flush() - */ - -static cairo_status_t -_cairo_quartz_image_surface_flush (void *asurface, - unsigned flags) -{ - cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) asurface; - CGImageRef oldImage = surface->image; - CGImageRef newImage = NULL; - - if (flags) - return CAIRO_STATUS_SUCCESS; - - /* XXX only flush if the image has been modified. */ - - /* To be released by the ReleaseCallback */ - cairo_surface_reference ((cairo_surface_t*) surface->imageSurface); - - newImage = CairoQuartzCreateCGImage (surface->imageSurface->format, - surface->imageSurface->width, - surface->imageSurface->height, - surface->imageSurface->stride, - surface->imageSurface->data, - TRUE, - NULL, - DataProviderReleaseCallback, - surface->imageSurface); - - surface->image = newImage; - CGImageRelease (oldImage); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_quartz_image_surface_paint (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - cairo_quartz_image_surface_t *surface = abstract_surface; - return _cairo_surface_paint (&surface->imageSurface->base, - op, source, clip); -} - -static cairo_int_status_t -_cairo_quartz_image_surface_mask (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - cairo_quartz_image_surface_t *surface = abstract_surface; - return _cairo_surface_mask (&surface->imageSurface->base, - op, source, mask, clip); -} - -static cairo_int_status_t -_cairo_quartz_image_surface_stroke (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_quartz_image_surface_t *surface = abstract_surface; - return _cairo_surface_stroke (&surface->imageSurface->base, - op, source, path, - style, ctm, ctm_inverse, - tolerance, antialias, clip); -} - -static cairo_int_status_t -_cairo_quartz_image_surface_fill (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_quartz_image_surface_t *surface = abstract_surface; - return _cairo_surface_fill (&surface->imageSurface->base, - op, source, path, - fill_rule, tolerance, antialias, - clip); -} - -static cairo_int_status_t -_cairo_quartz_image_surface_glyphs (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - cairo_quartz_image_surface_t *surface = abstract_surface; - return _cairo_surface_show_text_glyphs (&surface->imageSurface->base, - op, source, - NULL, 0, - glyphs, num_glyphs, - NULL, 0, 0, - scaled_font, clip); -} - - -static const cairo_surface_backend_t cairo_quartz_image_surface_backend = { - CAIRO_SURFACE_TYPE_QUARTZ_IMAGE, - _cairo_quartz_image_surface_finish, - - _cairo_default_context_create, - - _cairo_quartz_image_surface_create_similar, - _cairo_quartz_image_surface_create_similar_image, - _cairo_quartz_image_surface_map_to_image, - _cairo_quartz_image_surface_unmap_image, - - _cairo_surface_default_source, - _cairo_quartz_image_surface_acquire_source_image, - NULL, /* release_source_image */ - NULL, /* snapshot */ - - NULL, /* copy_page */ - NULL, /* show_page */ - - _cairo_quartz_image_surface_get_extents, - NULL, /* get_font_options */ - - _cairo_quartz_image_surface_flush, - NULL, /* mark_dirty_rectangle */ - - _cairo_quartz_image_surface_paint, - _cairo_quartz_image_surface_mask, - _cairo_quartz_image_surface_stroke, - _cairo_quartz_image_surface_fill, - NULL, /* fill-stroke */ - _cairo_quartz_image_surface_glyphs, -}; - -/** - * cairo_quartz_image_surface_create: - * @image_surface: a cairo image surface to wrap with a quartz image surface - * - * Creates a Quartz surface backed by a CGImageRef that references the - * given image surface. The resulting surface can be rendered quickly - * when used as a source when rendering to a #cairo_quartz_surface. If - * the data in the image surface is ever updated, cairo_surface_flush() - * must be called on the #cairo_quartz_image_surface to ensure that the - * CGImageRef refers to the updated data. - * - * Return value: the newly created surface. - * - * Since: 1.6 - **/ -cairo_surface_t * -cairo_quartz_image_surface_create (cairo_surface_t *surface) -{ - cairo_quartz_image_surface_t *qisurf; - - CGImageRef image; - - cairo_image_surface_t *image_surface; - int width, height, stride; - cairo_format_t format; - unsigned char *data; - - if (surface->status) - return surface; - - if (! _cairo_surface_is_image (surface)) - return SURFACE_ERROR_TYPE_MISMATCH; - - image_surface = (cairo_image_surface_t*) surface; - width = image_surface->width; - height = image_surface->height; - stride = image_surface->stride; - format = image_surface->format; - data = image_surface->data; - - if (!_cairo_quartz_verify_surface_size(width, height)) - return SURFACE_ERROR_INVALID_SIZE; - - if (width == 0 || height == 0) - return SURFACE_ERROR_INVALID_SIZE; - - if (format != CAIRO_FORMAT_ARGB32 && format != CAIRO_FORMAT_RGB24) - return SURFACE_ERROR_INVALID_FORMAT; - - qisurf = malloc(sizeof(cairo_quartz_image_surface_t)); - if (qisurf == NULL) - return SURFACE_ERROR_NO_MEMORY; - - memset (qisurf, 0, sizeof(cairo_quartz_image_surface_t)); - - /* In case the create_cgimage fails, this ref will - * be released via the callback (which will be called in - * case of failure.) - */ - cairo_surface_reference (surface); - - image = CairoQuartzCreateCGImage (format, - width, height, - stride, - data, - TRUE, - NULL, - DataProviderReleaseCallback, - image_surface); - - if (!image) { - free (qisurf); - return SURFACE_ERROR_NO_MEMORY; - } - - _cairo_surface_init (&qisurf->base, - &cairo_quartz_image_surface_backend, - NULL, /* device */ - _cairo_content_from_format (format)); - - qisurf->width = width; - qisurf->height = height; - - qisurf->image = image; - qisurf->imageSurface = image_surface; - - return &qisurf->base; -} - - -cairo_surface_t * -cairo_quartz_image_surface_get_image (cairo_surface_t *asurface) -{ - cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t*) asurface; - - /* Throw an error for a non-quartz surface */ - if (! _cairo_surface_is_quartz (asurface)) { - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH)); - } - - return (cairo_surface_t*) surface->imageSurface; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-quartz-image.h b/source/libs/cairo/cairo-src/src/cairo-quartz-image.h deleted file mode 100644 index dae234dacae73ce9c46ca993b1b2d82831023e9d..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-quartz-image.h +++ /dev/null @@ -1,59 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2008 Mozilla Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Mozilla Foundation. - * - * Contributor(s): - * Vladimir Vukicevic <vladimir@mozilla.com> - */ - -#ifndef CAIRO_QUARTZ_IMAGE_H -#define CAIRO_QUARTZ_IMAGE_H - -#include "cairo.h" - -#if CAIRO_HAS_QUARTZ_IMAGE_SURFACE - -#include <Carbon/Carbon.h> - -CAIRO_BEGIN_DECLS - -cairo_public cairo_surface_t * -cairo_quartz_image_surface_create (cairo_surface_t *image_surface); - -cairo_public cairo_surface_t * -cairo_quartz_image_surface_get_image (cairo_surface_t *surface); - -CAIRO_END_DECLS - -#else /* CAIRO_HAS_QUARTZ_IMAGE_SURFACE */ -# error Cairo was not compiled with support for the quartz-image backend -#endif /* CAIRO_HAS_QUARTZ_IMAGE_SURFACE */ - -#endif /* CAIRO_QUARTZ_IMAGE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-quartz-private.h b/source/libs/cairo/cairo-src/src/cairo-quartz-private.h deleted file mode 100644 index 3ef14c3ae60ad8beb99a16cd7caa154a06259e06..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-quartz-private.h +++ /dev/null @@ -1,109 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2004 Calum Robinson - * Copyright (C) 2006,2007 Mozilla Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Calum Robinson - * - * Contributor(s): - * Calum Robinson <calumr@mac.com> - * Vladimir Vukicevic <vladimir@mozilla.com> - */ - -#ifndef CAIRO_QUARTZ_PRIVATE_H -#define CAIRO_QUARTZ_PRIVATE_H - -#include "cairoint.h" - -#if CAIRO_HAS_QUARTZ_SURFACE -#include "cairo-quartz.h" -#include "cairo-surface-clipper-private.h" - -#ifdef CGFLOAT_DEFINED -typedef CGFloat cairo_quartz_float_t; -#else -typedef float cairo_quartz_float_t; -#endif - -typedef enum { - DO_DIRECT, - DO_SHADING, - DO_IMAGE, - DO_TILED_IMAGE -} cairo_quartz_action_t; - -typedef struct cairo_quartz_surface { - cairo_surface_t base; - - CGContextRef cgContext; - CGAffineTransform cgContextBaseCTM; - - void *imageData; - cairo_surface_t *imageSurfaceEquiv; - - cairo_surface_clipper_t clipper; - cairo_rectangle_int_t extents; - cairo_rectangle_int_t virtual_extents; -} cairo_quartz_surface_t; - -typedef struct cairo_quartz_image_surface { - cairo_surface_t base; - - int width, height; - - CGImageRef image; - cairo_image_surface_t *imageSurface; -} cairo_quartz_image_surface_t; - -cairo_private cairo_bool_t -_cairo_quartz_verify_surface_size(int width, int height); - -cairo_private cairo_bool_t -_cairo_surface_is_quartz (const cairo_surface_t *surface); - -cairo_private CGImageRef -CairoQuartzCreateCGImage (cairo_format_t format, - unsigned int width, - unsigned int height, - unsigned int stride, - void *data, - cairo_bool_t interpolate, - CGColorSpaceRef colorSpaceOverride, - CGDataProviderReleaseDataCallback releaseCallback, - void *releaseInfo); - -cairo_private CGFontRef -_cairo_quartz_scaled_font_get_cg_font_ref (cairo_scaled_font_t *sfont); - -#else - -# error Cairo was not compiled with support for the quartz backend - -#endif /* CAIRO_HAS_QUARTZ_SURFACE */ - -#endif /* CAIRO_QUARTZ_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-quartz-surface.c b/source/libs/cairo/cairo-src/src/cairo-quartz-surface.c deleted file mode 100644 index 1116ff94c1ec39de8aea8729c9ffcf15f4b212aa..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-quartz-surface.c +++ /dev/null @@ -1,2574 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright � 2006, 2007 Mozilla Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Mozilla Foundation. - * - * Contributor(s): - * Vladimir Vukicevic <vladimir@mozilla.com> - */ - -#define _GNU_SOURCE /* required for RTLD_DEFAULT */ -#include "cairoint.h" - -#include "cairo-quartz-private.h" - -#include "cairo-composite-rectangles-private.h" -#include "cairo-compositor-private.h" -#include "cairo-default-context-private.h" -#include "cairo-error-private.h" -#include "cairo-image-surface-inline.h" -#include "cairo-pattern-private.h" -#include "cairo-surface-backend-private.h" -#include "cairo-surface-clipper-private.h" -#include "cairo-recording-surface-private.h" - -#include <dlfcn.h> - -#ifndef RTLD_DEFAULT -#define RTLD_DEFAULT ((void *) 0) -#endif - -#include <limits.h> - -#undef QUARTZ_DEBUG - -#ifdef QUARTZ_DEBUG -#define ND(_x) fprintf _x -#else -#define ND(_x) do {} while(0) -#endif - -#define IS_EMPTY(s) ((s)->extents.width == 0 || (s)->extents.height == 0) - -/** - * SECTION:cairo-quartz - * @Title: Quartz Surfaces - * @Short_Description: Rendering to Quartz surfaces - * @See_Also: #cairo_surface_t - * - * The Quartz surface is used to render cairo graphics targeting the - * Apple OS X Quartz rendering system. - **/ - -/** - * CAIRO_HAS_QUARTZ_SURFACE: - * - * Defined if the Quartz surface backend is available. - * This macro can be used to conditionally compile backend-specific code. - * - * Since: 1.6 - **/ - -#if __MAC_OS_X_VERSION_MIN_REQUIRED < 1050 -/* This method is private, but it exists. Its params are are exposed - * as args to the NS* method, but not as CG. - */ -enum PrivateCGCompositeMode { - kPrivateCGCompositeClear = 0, - kPrivateCGCompositeCopy = 1, - kPrivateCGCompositeSourceOver = 2, - kPrivateCGCompositeSourceIn = 3, - kPrivateCGCompositeSourceOut = 4, - kPrivateCGCompositeSourceAtop = 5, - kPrivateCGCompositeDestinationOver = 6, - kPrivateCGCompositeDestinationIn = 7, - kPrivateCGCompositeDestinationOut = 8, - kPrivateCGCompositeDestinationAtop = 9, - kPrivateCGCompositeXOR = 10, - kPrivateCGCompositePlusDarker = 11, // (max (0, (1-d) + (1-s))) - kPrivateCGCompositePlusLighter = 12, // (min (1, s + d)) -}; -typedef enum PrivateCGCompositeMode PrivateCGCompositeMode; -CG_EXTERN void CGContextSetCompositeOperation (CGContextRef, PrivateCGCompositeMode); -#endif - -/* Some of these are present in earlier versions of the OS than where - * they are public; other are not public at all - */ -/* public since 10.5 */ -static void (*CGContextDrawTiledImagePtr) (CGContextRef, CGRect, CGImageRef) = NULL; - -/* public since 10.6 */ -static CGPathRef (*CGContextCopyPathPtr) (CGContextRef) = NULL; -static void (*CGContextSetAllowsFontSmoothingPtr) (CGContextRef, bool) = NULL; - -/* not yet public */ -static unsigned int (*CGContextGetTypePtr) (CGContextRef) = NULL; -static bool (*CGContextGetAllowsFontSmoothingPtr) (CGContextRef) = NULL; - -static cairo_bool_t _cairo_quartz_symbol_lookup_done = FALSE; - -/* - * Utility functions - */ - -#ifdef QUARTZ_DEBUG -static void quartz_surface_to_png (cairo_quartz_surface_t *nq, char *dest); -static void quartz_image_to_png (CGImageRef, char *dest); -#endif - -static cairo_quartz_surface_t * -_cairo_quartz_surface_create_internal (CGContextRef cgContext, - cairo_content_t content, - unsigned int width, - unsigned int height); - -/* Load all extra symbols */ -static void quartz_ensure_symbols (void) -{ - if (likely (_cairo_quartz_symbol_lookup_done)) - return; - - CGContextDrawTiledImagePtr = dlsym (RTLD_DEFAULT, "CGContextDrawTiledImage"); - CGContextGetTypePtr = dlsym (RTLD_DEFAULT, "CGContextGetType"); - CGContextCopyPathPtr = dlsym (RTLD_DEFAULT, "CGContextCopyPath"); - CGContextGetAllowsFontSmoothingPtr = dlsym (RTLD_DEFAULT, "CGContextGetAllowsFontSmoothing"); - CGContextSetAllowsFontSmoothingPtr = dlsym (RTLD_DEFAULT, "CGContextSetAllowsFontSmoothing"); - - _cairo_quartz_symbol_lookup_done = TRUE; -} - -CGImageRef -CairoQuartzCreateCGImage (cairo_format_t format, - unsigned int width, - unsigned int height, - unsigned int stride, - void *data, - cairo_bool_t interpolate, - CGColorSpaceRef colorSpaceOverride, - CGDataProviderReleaseDataCallback releaseCallback, - void *releaseInfo) -{ - CGImageRef image = NULL; - CGDataProviderRef dataProvider = NULL; - CGColorSpaceRef colorSpace = colorSpaceOverride; - CGBitmapInfo bitinfo = kCGBitmapByteOrder32Host; - int bitsPerComponent, bitsPerPixel; - - switch (format) { - case CAIRO_FORMAT_ARGB32: - if (colorSpace == NULL) - colorSpace = CGColorSpaceCreateDeviceRGB (); - bitinfo |= kCGImageAlphaPremultipliedFirst; - bitsPerComponent = 8; - bitsPerPixel = 32; - break; - - case CAIRO_FORMAT_RGB24: - if (colorSpace == NULL) - colorSpace = CGColorSpaceCreateDeviceRGB (); - bitinfo |= kCGImageAlphaNoneSkipFirst; - bitsPerComponent = 8; - bitsPerPixel = 32; - break; - - case CAIRO_FORMAT_A8: - bitsPerComponent = 8; - bitsPerPixel = 8; - break; - - case CAIRO_FORMAT_A1: -#ifdef WORDS_BIGENDIAN - bitsPerComponent = 1; - bitsPerPixel = 1; - break; -#endif - - case CAIRO_FORMAT_RGB30: - case CAIRO_FORMAT_RGB16_565: - case CAIRO_FORMAT_INVALID: - default: - return NULL; - } - - dataProvider = CGDataProviderCreateWithData (releaseInfo, - data, - height * stride, - releaseCallback); - - if (unlikely (!dataProvider)) { - // manually release - if (releaseCallback) - releaseCallback (releaseInfo, data, height * stride); - goto FINISH; - } - - if (format == CAIRO_FORMAT_A8 || format == CAIRO_FORMAT_A1) { - cairo_quartz_float_t decode[] = {1.0, 0.0}; - image = CGImageMaskCreate (width, height, - bitsPerComponent, - bitsPerPixel, - stride, - dataProvider, - decode, - interpolate); - } else - image = CGImageCreate (width, height, - bitsPerComponent, - bitsPerPixel, - stride, - colorSpace, - bitinfo, - dataProvider, - NULL, - interpolate, - kCGRenderingIntentDefault); - -FINISH: - - CGDataProviderRelease (dataProvider); - - if (colorSpace != colorSpaceOverride) - CGColorSpaceRelease (colorSpace); - - return image; -} - -static inline cairo_bool_t -_cairo_quartz_is_cgcontext_bitmap_context (CGContextRef cgc) -{ - if (unlikely (cgc == NULL)) - return FALSE; - - if (likely (CGContextGetTypePtr)) { - /* 4 is the type value of a bitmap context */ - return CGContextGetTypePtr (cgc) == 4; - } - - /* This will cause a (harmless) warning to be printed if called on a non-bitmap context */ - return CGBitmapContextGetBitsPerPixel (cgc) != 0; -} - -/* CoreGraphics limitation with flipped CTM surfaces: height must be less than signed 16-bit max */ - -#define CG_MAX_HEIGHT SHRT_MAX -#define CG_MAX_WIDTH USHRT_MAX - -/* is the desired size of the surface within bounds? */ -cairo_bool_t -_cairo_quartz_verify_surface_size (int width, int height) -{ - /* hmmm, allow width, height == 0 ? */ - if (width < 0 || height < 0) - return FALSE; - - if (width > CG_MAX_WIDTH || height > CG_MAX_HEIGHT) - return FALSE; - - return TRUE; -} - -/* - * Cairo path -> Quartz path conversion helpers - */ - -/* cairo path -> execute in context */ -static cairo_status_t -_cairo_path_to_quartz_context_move_to (void *closure, - const cairo_point_t *point) -{ - //ND ((stderr, "moveto: %f %f\n", _cairo_fixed_to_double (point->x), _cairo_fixed_to_double (point->y))); - double x = _cairo_fixed_to_double (point->x); - double y = _cairo_fixed_to_double (point->y); - - CGContextMoveToPoint (closure, x, y); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_path_to_quartz_context_line_to (void *closure, - const cairo_point_t *point) -{ - //ND ((stderr, "lineto: %f %f\n", _cairo_fixed_to_double (point->x), _cairo_fixed_to_double (point->y))); - double x = _cairo_fixed_to_double (point->x); - double y = _cairo_fixed_to_double (point->y); - - CGContextAddLineToPoint (closure, x, y); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_path_to_quartz_context_curve_to (void *closure, - const cairo_point_t *p0, - const cairo_point_t *p1, - const cairo_point_t *p2) -{ - //ND ((stderr, "curveto: %f,%f %f,%f %f,%f\n", - // _cairo_fixed_to_double (p0->x), _cairo_fixed_to_double (p0->y), - // _cairo_fixed_to_double (p1->x), _cairo_fixed_to_double (p1->y), - // _cairo_fixed_to_double (p2->x), _cairo_fixed_to_double (p2->y))); - double x0 = _cairo_fixed_to_double (p0->x); - double y0 = _cairo_fixed_to_double (p0->y); - double x1 = _cairo_fixed_to_double (p1->x); - double y1 = _cairo_fixed_to_double (p1->y); - double x2 = _cairo_fixed_to_double (p2->x); - double y2 = _cairo_fixed_to_double (p2->y); - - CGContextAddCurveToPoint (closure, x0, y0, x1, y1, x2, y2); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_path_to_quartz_context_close_path (void *closure) -{ - //ND ((stderr, "closepath\n")); - CGContextClosePath (closure); - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_quartz_cairo_path_to_quartz_context (const cairo_path_fixed_t *path, - CGContextRef closure) -{ - cairo_status_t status; - - CGContextBeginPath (closure); - status = _cairo_path_fixed_interpret (path, - _cairo_path_to_quartz_context_move_to, - _cairo_path_to_quartz_context_line_to, - _cairo_path_to_quartz_context_curve_to, - _cairo_path_to_quartz_context_close_path, - closure); - - assert (status == CAIRO_STATUS_SUCCESS); -} - -/* - * Misc helpers/callbacks - */ - -#if __MAC_OS_X_VERSION_MIN_REQUIRED < 1050 -static PrivateCGCompositeMode -_cairo_quartz_cairo_operator_to_quartz_composite (cairo_operator_t op) -{ - switch (op) { - case CAIRO_OPERATOR_CLEAR: - return kPrivateCGCompositeClear; - case CAIRO_OPERATOR_SOURCE: - return kPrivateCGCompositeCopy; - case CAIRO_OPERATOR_OVER: - return kPrivateCGCompositeSourceOver; - case CAIRO_OPERATOR_IN: - return kPrivateCGCompositeSourceIn; - case CAIRO_OPERATOR_OUT: - return kPrivateCGCompositeSourceOut; - case CAIRO_OPERATOR_ATOP: - return kPrivateCGCompositeSourceAtop; - case CAIRO_OPERATOR_DEST_OVER: - return kPrivateCGCompositeDestinationOver; - case CAIRO_OPERATOR_DEST_IN: - return kPrivateCGCompositeDestinationIn; - case CAIRO_OPERATOR_DEST_OUT: - return kPrivateCGCompositeDestinationOut; - case CAIRO_OPERATOR_DEST_ATOP: - return kPrivateCGCompositeDestinationAtop; - case CAIRO_OPERATOR_XOR: - return kPrivateCGCompositeXOR; - case CAIRO_OPERATOR_ADD: - return kPrivateCGCompositePlusLighter; - - case CAIRO_OPERATOR_DEST: - case CAIRO_OPERATOR_SATURATE: - case CAIRO_OPERATOR_MULTIPLY: - case CAIRO_OPERATOR_SCREEN: - case CAIRO_OPERATOR_OVERLAY: - case CAIRO_OPERATOR_DARKEN: - case CAIRO_OPERATOR_LIGHTEN: - case CAIRO_OPERATOR_COLOR_DODGE: - case CAIRO_OPERATOR_COLOR_BURN: - case CAIRO_OPERATOR_HARD_LIGHT: - case CAIRO_OPERATOR_SOFT_LIGHT: - case CAIRO_OPERATOR_DIFFERENCE: - case CAIRO_OPERATOR_EXCLUSION: - case CAIRO_OPERATOR_HSL_HUE: - case CAIRO_OPERATOR_HSL_SATURATION: - case CAIRO_OPERATOR_HSL_COLOR: - case CAIRO_OPERATOR_HSL_LUMINOSITY: - default: - ASSERT_NOT_REACHED; - } -} -#endif - -static CGBlendMode -_cairo_quartz_cairo_operator_to_quartz_blend (cairo_operator_t op) -{ - switch (op) { - case CAIRO_OPERATOR_MULTIPLY: - return kCGBlendModeMultiply; - case CAIRO_OPERATOR_SCREEN: - return kCGBlendModeScreen; - case CAIRO_OPERATOR_OVERLAY: - return kCGBlendModeOverlay; - case CAIRO_OPERATOR_DARKEN: - return kCGBlendModeDarken; - case CAIRO_OPERATOR_LIGHTEN: - return kCGBlendModeLighten; - case CAIRO_OPERATOR_COLOR_DODGE: - return kCGBlendModeColorDodge; - case CAIRO_OPERATOR_COLOR_BURN: - return kCGBlendModeColorBurn; - case CAIRO_OPERATOR_HARD_LIGHT: - return kCGBlendModeHardLight; - case CAIRO_OPERATOR_SOFT_LIGHT: - return kCGBlendModeSoftLight; - case CAIRO_OPERATOR_DIFFERENCE: - return kCGBlendModeDifference; - case CAIRO_OPERATOR_EXCLUSION: - return kCGBlendModeExclusion; - case CAIRO_OPERATOR_HSL_HUE: - return kCGBlendModeHue; - case CAIRO_OPERATOR_HSL_SATURATION: - return kCGBlendModeSaturation; - case CAIRO_OPERATOR_HSL_COLOR: - return kCGBlendModeColor; - case CAIRO_OPERATOR_HSL_LUMINOSITY: - return kCGBlendModeLuminosity; - -#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 - case CAIRO_OPERATOR_CLEAR: - return kCGBlendModeClear; - case CAIRO_OPERATOR_SOURCE: - return kCGBlendModeCopy; - case CAIRO_OPERATOR_OVER: - return kCGBlendModeNormal; - case CAIRO_OPERATOR_IN: - return kCGBlendModeSourceIn; - case CAIRO_OPERATOR_OUT: - return kCGBlendModeSourceOut; - case CAIRO_OPERATOR_ATOP: - return kCGBlendModeSourceAtop; - case CAIRO_OPERATOR_DEST_OVER: - return kCGBlendModeDestinationOver; - case CAIRO_OPERATOR_DEST_IN: - return kCGBlendModeDestinationIn; - case CAIRO_OPERATOR_DEST_OUT: - return kCGBlendModeDestinationOut; - case CAIRO_OPERATOR_DEST_ATOP: - return kCGBlendModeDestinationAtop; - case CAIRO_OPERATOR_XOR: - return kCGBlendModeXOR; - case CAIRO_OPERATOR_ADD: - return kCGBlendModePlusLighter; -#else - case CAIRO_OPERATOR_CLEAR: - case CAIRO_OPERATOR_SOURCE: - case CAIRO_OPERATOR_OVER: - case CAIRO_OPERATOR_IN: - case CAIRO_OPERATOR_OUT: - case CAIRO_OPERATOR_ATOP: - case CAIRO_OPERATOR_DEST_OVER: - case CAIRO_OPERATOR_DEST_IN: - case CAIRO_OPERATOR_DEST_OUT: - case CAIRO_OPERATOR_DEST_ATOP: - case CAIRO_OPERATOR_XOR: - case CAIRO_OPERATOR_ADD: -#endif - - case CAIRO_OPERATOR_DEST: - case CAIRO_OPERATOR_SATURATE: - default: - ASSERT_NOT_REACHED; - } -} - -static cairo_int_status_t -_cairo_cgcontext_set_cairo_operator (CGContextRef context, cairo_operator_t op) -{ - CGBlendMode blendmode; - - assert (op != CAIRO_OPERATOR_DEST); - - /* Quartz doesn't support SATURATE at all. COLOR_DODGE and - * COLOR_BURN in Quartz follow the ISO32000 definition, but cairo - * uses the definition from the Adobe Supplement. - */ - if (op == CAIRO_OPERATOR_SATURATE || - op == CAIRO_OPERATOR_COLOR_DODGE || - op == CAIRO_OPERATOR_COLOR_BURN) - { - return CAIRO_INT_STATUS_UNSUPPORTED; - } - -#if __MAC_OS_X_VERSION_MIN_REQUIRED < 1050 - if (op <= CAIRO_OPERATOR_ADD) { - PrivateCGCompositeMode compmode; - - compmode = _cairo_quartz_cairo_operator_to_quartz_composite (op); - CGContextSetCompositeOperation (context, compmode); - return CAIRO_STATUS_SUCCESS; - } -#endif - - blendmode = _cairo_quartz_cairo_operator_to_quartz_blend (op); - CGContextSetBlendMode (context, blendmode); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_quartz_surface_set_cairo_operator (cairo_quartz_surface_t *surface, cairo_operator_t op) -{ - ND((stderr, "%p _cairo_quartz_surface_set_cairo_operator %d\n", surface, op)); - - /* When the destination has no color components, we can avoid some - * fallbacks, but we have to workaround operators which behave - * differently in Quartz. */ - if (surface->base.content == CAIRO_CONTENT_ALPHA) { - assert (op != CAIRO_OPERATOR_ATOP); /* filtered by surface layer */ - - if (op == CAIRO_OPERATOR_SOURCE || - op == CAIRO_OPERATOR_IN || - op == CAIRO_OPERATOR_OUT || - op == CAIRO_OPERATOR_DEST_IN || - op == CAIRO_OPERATOR_DEST_ATOP || - op == CAIRO_OPERATOR_XOR) - { - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - if (op == CAIRO_OPERATOR_DEST_OVER) - op = CAIRO_OPERATOR_OVER; - else if (op == CAIRO_OPERATOR_SATURATE) - op = CAIRO_OPERATOR_ADD; - else if (op == CAIRO_OPERATOR_COLOR_DODGE) - op = CAIRO_OPERATOR_OVER; - else if (op == CAIRO_OPERATOR_COLOR_BURN) - op = CAIRO_OPERATOR_OVER; - } - - return _cairo_cgcontext_set_cairo_operator (surface->cgContext, op); -} - -static inline CGLineCap -_cairo_quartz_cairo_line_cap_to_quartz (cairo_line_cap_t ccap) -{ - switch (ccap) { - default: - ASSERT_NOT_REACHED; - - case CAIRO_LINE_CAP_BUTT: - return kCGLineCapButt; - - case CAIRO_LINE_CAP_ROUND: - return kCGLineCapRound; - - case CAIRO_LINE_CAP_SQUARE: - return kCGLineCapSquare; - } -} - -static inline CGLineJoin -_cairo_quartz_cairo_line_join_to_quartz (cairo_line_join_t cjoin) -{ - switch (cjoin) { - default: - ASSERT_NOT_REACHED; - - case CAIRO_LINE_JOIN_MITER: - return kCGLineJoinMiter; - - case CAIRO_LINE_JOIN_ROUND: - return kCGLineJoinRound; - - case CAIRO_LINE_JOIN_BEVEL: - return kCGLineJoinBevel; - } -} - -static inline CGInterpolationQuality -_cairo_quartz_filter_to_quartz (cairo_filter_t filter) -{ - switch (filter) { - case CAIRO_FILTER_NEAREST: - case CAIRO_FILTER_FAST: - return kCGInterpolationNone; - - case CAIRO_FILTER_BEST: - case CAIRO_FILTER_GOOD: - case CAIRO_FILTER_BILINEAR: - case CAIRO_FILTER_GAUSSIAN: - return kCGInterpolationDefault; - - default: - ASSERT_NOT_REACHED; - return kCGInterpolationDefault; - } -} - -static inline void -_cairo_quartz_cairo_matrix_to_quartz (const cairo_matrix_t *src, - CGAffineTransform *dst) -{ - dst->a = src->xx; - dst->b = src->yx; - dst->c = src->xy; - dst->d = src->yy; - dst->tx = src->x0; - dst->ty = src->y0; -} - - -/* - * Source -> Quartz setup and finish functions - */ - -static void -ComputeGradientValue (void *info, - const cairo_quartz_float_t *in, - cairo_quartz_float_t *out) -{ - double fdist = *in; - const cairo_gradient_pattern_t *grad = (cairo_gradient_pattern_t*) info; - unsigned int i; - - /* Put fdist back in the 0.0..1.0 range if we're doing - * REPEAT/REFLECT - */ - if (grad->base.extend == CAIRO_EXTEND_REPEAT) { - fdist = fdist - floor (fdist); - } else if (grad->base.extend == CAIRO_EXTEND_REFLECT) { - fdist = fmod (fabs (fdist), 2.0); - if (fdist > 1.0) - fdist = 2.0 - fdist; - } - - for (i = 0; i < grad->n_stops; i++) - if (grad->stops[i].offset > fdist) - break; - - if (i == 0 || i == grad->n_stops) { - if (i == grad->n_stops) - --i; - out[0] = grad->stops[i].color.red; - out[1] = grad->stops[i].color.green; - out[2] = grad->stops[i].color.blue; - out[3] = grad->stops[i].color.alpha; - } else { - cairo_quartz_float_t ax = grad->stops[i-1].offset; - cairo_quartz_float_t bx = grad->stops[i].offset - ax; - cairo_quartz_float_t bp = (fdist - ax)/bx; - cairo_quartz_float_t ap = 1.0 - bp; - - out[0] = - grad->stops[i-1].color.red * ap + - grad->stops[i].color.red * bp; - out[1] = - grad->stops[i-1].color.green * ap + - grad->stops[i].color.green * bp; - out[2] = - grad->stops[i-1].color.blue * ap + - grad->stops[i].color.blue * bp; - out[3] = - grad->stops[i-1].color.alpha * ap + - grad->stops[i].color.alpha * bp; - } -} - -static const cairo_quartz_float_t gradient_output_value_ranges[8] = { - 0.f, 1.f, 0.f, 1.f, 0.f, 1.f, 0.f, 1.f -}; -static const CGFunctionCallbacks gradient_callbacks = { - 0, ComputeGradientValue, (CGFunctionReleaseInfoCallback) cairo_pattern_destroy -}; - -/* Quartz computes a small number of samples of the gradient color - * function. On MacOS X 10.5 it apparently computes only 1024 - * samples. */ -#define MAX_GRADIENT_RANGE 1024 - -static CGFunctionRef -CairoQuartzCreateGradientFunction (const cairo_gradient_pattern_t *gradient, - const cairo_rectangle_int_t *extents, - cairo_circle_double_t *start, - cairo_circle_double_t *end) -{ - cairo_pattern_t *pat; - cairo_quartz_float_t input_value_range[2]; - - if (gradient->base.extend != CAIRO_EXTEND_NONE) { - double bounds_x1, bounds_x2, bounds_y1, bounds_y2; - double t[2], tolerance; - - tolerance = fabs (_cairo_matrix_compute_determinant (&gradient->base.matrix)); - tolerance /= _cairo_matrix_transformed_circle_major_axis (&gradient->base.matrix, 1); - - bounds_x1 = extents->x; - bounds_y1 = extents->y; - bounds_x2 = extents->x + extents->width; - bounds_y2 = extents->y + extents->height; - _cairo_matrix_transform_bounding_box (&gradient->base.matrix, - &bounds_x1, &bounds_y1, - &bounds_x2, &bounds_y2, - NULL); - - _cairo_gradient_pattern_box_to_parameter (gradient, - bounds_x1, bounds_y1, - bounds_x2, bounds_y2, - tolerance, - t); - - if (gradient->base.extend == CAIRO_EXTEND_PAD) { - t[0] = MAX (t[0], -0.5); - t[1] = MIN (t[1], 1.5); - } else if (t[1] - t[0] > MAX_GRADIENT_RANGE) - return NULL; - - /* set the input range for the function -- the function knows how - to map values outside of 0.0 .. 1.0 to the correct color */ - input_value_range[0] = t[0]; - input_value_range[1] = t[1]; - } else { - input_value_range[0] = 0; - input_value_range[1] = 1; - } - - _cairo_gradient_pattern_interpolate (gradient, input_value_range[0], start); - _cairo_gradient_pattern_interpolate (gradient, input_value_range[1], end); - - if (_cairo_pattern_create_copy (&pat, &gradient->base)) - return NULL; - - return CGFunctionCreate (pat, - 1, - input_value_range, - 4, - gradient_output_value_ranges, - &gradient_callbacks); -} - -/* Obtain a CGImageRef from a #cairo_surface_t * */ - -typedef struct { - cairo_surface_t *surface; - cairo_image_surface_t *image_out; - void *image_extra; -} quartz_source_image_t; - -static void -DataProviderReleaseCallback (void *info, const void *data, size_t size) -{ - quartz_source_image_t *source_img = info; - _cairo_surface_release_source_image (source_img->surface, source_img->image_out, source_img->image_extra); - free (source_img); -} - -static cairo_status_t -_cairo_surface_to_cgimage (cairo_surface_t *source, - cairo_rectangle_int_t *extents, - cairo_format_t format, - cairo_matrix_t *matrix, - const cairo_clip_t *clip, - CGImageRef *image_out) -{ - cairo_status_t status; - quartz_source_image_t *source_img; - cairo_image_surface_t *image_surface; - - if (source->backend && source->backend->type == CAIRO_SURFACE_TYPE_QUARTZ_IMAGE) { - cairo_quartz_image_surface_t *surface = (cairo_quartz_image_surface_t *) source; - *image_out = CGImageRetain (surface->image); - return CAIRO_STATUS_SUCCESS; - } - - if (_cairo_surface_is_quartz (source)) { - cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) source; - if (IS_EMPTY (surface)) { - *image_out = NULL; - return CAIRO_INT_STATUS_NOTHING_TO_DO; - } - - if (_cairo_quartz_is_cgcontext_bitmap_context (surface->cgContext)) { - *image_out = CGBitmapContextCreateImage (surface->cgContext); - if (*image_out) - return CAIRO_STATUS_SUCCESS; - } - } - - source_img = malloc (sizeof (quartz_source_image_t)); - if (unlikely (source_img == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - source_img->surface = source; - - if (source->type == CAIRO_SURFACE_TYPE_RECORDING) { - image_surface = (cairo_image_surface_t *) - cairo_image_surface_create (format, extents->width, extents->height); - if (unlikely (image_surface->base.status)) { - status = image_surface->base.status; - cairo_surface_destroy (&image_surface->base); - free (source_img); - return status; - } - - status = _cairo_recording_surface_replay_with_clip (source, - matrix, - &image_surface->base, - NULL); - if (unlikely (status)) { - cairo_surface_destroy (&image_surface->base); - free (source_img); - return status; - } - - source_img->image_out = image_surface; - source_img->image_extra = NULL; - - cairo_matrix_init_identity (matrix); - } - else { - status = _cairo_surface_acquire_source_image (source_img->surface, - &source_img->image_out, - &source_img->image_extra); - if (unlikely (status)) { - free (source_img); - return status; - } - } - - if (source_img->image_out->width == 0 || source_img->image_out->height == 0) { - *image_out = NULL; - DataProviderReleaseCallback (source_img, - source_img->image_out->data, - source_img->image_out->height * source_img->image_out->stride); - } else { - *image_out = CairoQuartzCreateCGImage (source_img->image_out->format, - source_img->image_out->width, - source_img->image_out->height, - source_img->image_out->stride, - source_img->image_out->data, - TRUE, - NULL, - DataProviderReleaseCallback, - source_img); - - /* TODO: differentiate memory error and unsupported surface type */ - if (unlikely (*image_out == NULL)) - status = CAIRO_INT_STATUS_UNSUPPORTED; - } - - return status; -} - -/* Generic #cairo_pattern_t -> CGPattern function */ - -typedef struct { - CGImageRef image; - CGRect imageBounds; - cairo_bool_t do_reflect; -} SurfacePatternDrawInfo; - -static void -SurfacePatternDrawFunc (void *ainfo, CGContextRef context) -{ - SurfacePatternDrawInfo *info = (SurfacePatternDrawInfo*) ainfo; - - CGContextTranslateCTM (context, 0, info->imageBounds.size.height); - CGContextScaleCTM (context, 1, -1); - - CGContextDrawImage (context, info->imageBounds, info->image); - if (info->do_reflect) { - /* draw 3 more copies of the image, flipped. - * DrawImage draws the image according to the current Y-direction into the rectangle given - * (imageBounds); at the time of the first DrawImage above, the origin is at the bottom left - * of the base image position, and the Y axis is extending upwards. - */ - - /* Make the y axis extend downwards, and draw a flipped image below */ - CGContextScaleCTM (context, 1, -1); - CGContextDrawImage (context, info->imageBounds, info->image); - - /* Shift over to the right, and flip vertically (translation is 2x, - * since we'll be flipping and thus rendering the rectangle "backwards" - */ - CGContextTranslateCTM (context, 2 * info->imageBounds.size.width, 0); - CGContextScaleCTM (context, -1, 1); - CGContextDrawImage (context, info->imageBounds, info->image); - - /* Then unflip the Y-axis again, and draw the image above the point. */ - CGContextScaleCTM (context, 1, -1); - CGContextDrawImage (context, info->imageBounds, info->image); - } -} - -static void -SurfacePatternReleaseInfoFunc (void *ainfo) -{ - SurfacePatternDrawInfo *info = (SurfacePatternDrawInfo*) ainfo; - - CGImageRelease (info->image); - free (info); -} - -static cairo_int_status_t -_cairo_quartz_cairo_repeating_surface_pattern_to_quartz (cairo_quartz_surface_t *dest, - const cairo_pattern_t *apattern, - const cairo_clip_t *clip, - CGPatternRef *cgpat) -{ - cairo_surface_pattern_t *spattern; - cairo_surface_t *pat_surf; - cairo_rectangle_int_t extents; - cairo_format_t format = _cairo_format_from_content (dest->base.content); - - CGImageRef image; - CGRect pbounds; - CGAffineTransform ptransform, stransform; - CGPatternCallbacks cb = { 0, - SurfacePatternDrawFunc, - SurfacePatternReleaseInfoFunc }; - SurfacePatternDrawInfo *info; - cairo_quartz_float_t rw, rh; - cairo_status_t status; - cairo_bool_t is_bounded; - - cairo_matrix_t m; - - /* SURFACE is the only type we'll handle here */ - assert (apattern->type == CAIRO_PATTERN_TYPE_SURFACE); - - spattern = (cairo_surface_pattern_t *) apattern; - pat_surf = spattern->surface; - - if (pat_surf->type != CAIRO_SURFACE_TYPE_RECORDING) { - is_bounded = _cairo_surface_get_extents (pat_surf, &extents); - assert (is_bounded); - } - else - _cairo_surface_get_extents (&dest->base, &extents); - - m = spattern->base.matrix; - status = _cairo_surface_to_cgimage (pat_surf, &extents, format, - &m, clip, &image); - if (unlikely (status)) - return status; - - info = malloc (sizeof (SurfacePatternDrawInfo)); - if (unlikely (!info)) - return CAIRO_STATUS_NO_MEMORY; - - /* XXX -- if we're printing, we may need to call CGImageCreateCopy to make sure - * that the data will stick around for this image when the printer gets to it. - * Otherwise, the underlying data store may disappear from under us! - * - * _cairo_surface_to_cgimage will copy when it converts non-Quartz surfaces, - * since the Quartz surfaces have a higher chance of sticking around. If the - * source is a quartz image surface, then it's set up to retain a ref to the - * image surface that it's backed by. - */ - info->image = image; - info->imageBounds = CGRectMake (0, 0, extents.width, extents.height); - info->do_reflect = FALSE; - - pbounds.origin.x = 0; - pbounds.origin.y = 0; - - if (spattern->base.extend == CAIRO_EXTEND_REFLECT) { - pbounds.size.width = 2.0 * extents.width; - pbounds.size.height = 2.0 * extents.height; - info->do_reflect = TRUE; - } else { - pbounds.size.width = extents.width; - pbounds.size.height = extents.height; - } - rw = pbounds.size.width; - rh = pbounds.size.height; - - cairo_matrix_invert (&m); - _cairo_quartz_cairo_matrix_to_quartz (&m, &stransform); - - /* The pattern matrix is relative to the bottom left, again; the - * incoming cairo pattern matrix is relative to the upper left. - * So we take the pattern matrix and the original context matrix, - * which gives us the correct base translation/y flip. - */ - ptransform = CGAffineTransformConcat (stransform, dest->cgContextBaseCTM); - -#ifdef QUARTZ_DEBUG - ND ((stderr, " pbounds: %f %f %f %f\n", pbounds.origin.x, pbounds.origin.y, pbounds.size.width, pbounds.size.height)); - ND ((stderr, " pattern xform: t: %f %f xx: %f xy: %f yx: %f yy: %f\n", ptransform.tx, ptransform.ty, ptransform.a, ptransform.b, ptransform.c, ptransform.d)); - CGAffineTransform xform = CGContextGetCTM (dest->cgContext); - ND ((stderr, " context xform: t: %f %f xx: %f xy: %f yx: %f yy: %f\n", xform.tx, xform.ty, xform.a, xform.b, xform.c, xform.d)); -#endif - - *cgpat = CGPatternCreate (info, - pbounds, - ptransform, - rw, rh, - kCGPatternTilingConstantSpacing, /* kCGPatternTilingNoDistortion, */ - TRUE, - &cb); - - return CAIRO_STATUS_SUCCESS; -} - -/* State used during a drawing operation. */ -typedef struct { - /* The destination of the mask */ - CGContextRef cgMaskContext; - - /* The destination of the drawing of the source */ - CGContextRef cgDrawContext; - - /* The filter to be used when drawing the source */ - CGInterpolationQuality filter; - - /* Action type */ - cairo_quartz_action_t action; - - /* Destination rect */ - CGRect rect; - - /* Used with DO_SHADING, DO_IMAGE and DO_TILED_IMAGE */ - CGAffineTransform transform; - - /* Used with DO_IMAGE and DO_TILED_IMAGE */ - CGImageRef image; - - /* Used with DO_SHADING */ - CGShadingRef shading; - - /* Temporary destination for unbounded operations */ - CGLayerRef layer; - CGRect clipRect; -} cairo_quartz_drawing_state_t; - -/* -Quartz does not support repeating radients. We handle repeating gradients -by manually extending the gradient and repeating color stops. We need to -minimize the number of repetitions since Quartz seems to sample our color -function across the entire range, even if part of that range is not needed -for the visible area of the gradient, and it samples with some fixed resolution, -so if the gradient range is too large it samples with very low resolution and -the gradient is very coarse. _cairo_quartz_create_gradient_function computes -the number of repetitions needed based on the extents. -*/ -static cairo_int_status_t -_cairo_quartz_setup_gradient_source (cairo_quartz_drawing_state_t *state, - const cairo_gradient_pattern_t *gradient, - const cairo_rectangle_int_t *extents) -{ - cairo_matrix_t mat; - cairo_circle_double_t start, end; - CGFunctionRef gradFunc; - CGColorSpaceRef rgb; - bool extend = gradient->base.extend != CAIRO_EXTEND_NONE; - - assert (gradient->n_stops > 0); - - mat = gradient->base.matrix; - cairo_matrix_invert (&mat); - _cairo_quartz_cairo_matrix_to_quartz (&mat, &state->transform); - - gradFunc = CairoQuartzCreateGradientFunction (gradient, extents, - &start, &end); - - if (unlikely (gradFunc == NULL)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - rgb = CGColorSpaceCreateDeviceRGB (); - - if (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR) { - state->shading = CGShadingCreateAxial (rgb, - CGPointMake (start.center.x, - start.center.y), - CGPointMake (end.center.x, - end.center.y), - gradFunc, - extend, extend); - } else { - state->shading = CGShadingCreateRadial (rgb, - CGPointMake (start.center.x, - start.center.y), - MAX (start.radius, 0), - CGPointMake (end.center.x, - end.center.y), - MAX (end.radius, 0), - gradFunc, - extend, extend); - } - - CGColorSpaceRelease (rgb); - CGFunctionRelease (gradFunc); - - state->action = DO_SHADING; - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_quartz_setup_state (cairo_quartz_drawing_state_t *state, - cairo_composite_rectangles_t *composite) -{ - cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) composite->surface; - cairo_operator_t op = composite->op; - const cairo_pattern_t *source = &composite->source_pattern.base; - const cairo_clip_t *clip = composite->clip; - cairo_bool_t needs_temp; - cairo_status_t status; - cairo_format_t format = _cairo_format_from_content (composite->surface->content); - - state->layer = NULL; - state->image = NULL; - state->shading = NULL; - state->cgDrawContext = NULL; - state->cgMaskContext = NULL; - - status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); - if (unlikely (status)) - return status; - - status = _cairo_quartz_surface_set_cairo_operator (surface, op); - if (unlikely (status)) - return status; - - /* Save before we change the pattern, colorspace, etc. so that - * we can restore and make sure that quartz releases our - * pattern (which may be stack allocated) - */ - - CGContextSaveGState (surface->cgContext); - state->clipRect = CGContextGetClipBoundingBox (surface->cgContext); - state->clipRect = CGRectIntegral (state->clipRect); - state->rect = state->clipRect; - - state->cgMaskContext = surface->cgContext; - state->cgDrawContext = state->cgMaskContext; - - state->filter = _cairo_quartz_filter_to_quartz (source->filter); - - if (op == CAIRO_OPERATOR_CLEAR) { - CGContextSetRGBFillColor (state->cgDrawContext, 0, 0, 0, 1); - - state->action = DO_DIRECT; - return CAIRO_STATUS_SUCCESS; - } - - /* - * To implement mask unbounded operations Quartz needs a temporary - * surface which will be composited entirely (ignoring the mask). - * To implement source unbounded operations Quartz needs a - * temporary surface which allows extending the source to a size - * covering the whole mask, but there are some optimization - * opportunities: - * - * - CLEAR completely ignores the source, thus we can just use a - * solid color fill. - * - * - SOURCE can be implemented by drawing the source and clearing - * outside of the source as long as the two regions have no - * intersection. This happens when the source is a pixel-aligned - * rectangle. If the source is at least as big as the - * intersection between the clip rectangle and the mask - * rectangle, no clear operation is needed. - */ - needs_temp = ! _cairo_operator_bounded_by_mask (op); - - if (needs_temp) { - state->layer = CGLayerCreateWithContext (surface->cgContext, - state->clipRect.size, - NULL); - state->cgDrawContext = CGLayerGetContext (state->layer); - state->cgMaskContext = state->cgDrawContext; - CGContextTranslateCTM (state->cgDrawContext, - -state->clipRect.origin.x, - -state->clipRect.origin.y); - } - - if (source->type == CAIRO_PATTERN_TYPE_SOLID) { - cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) source; - - CGContextSetRGBStrokeColor (state->cgDrawContext, - solid->color.red, - solid->color.green, - solid->color.blue, - solid->color.alpha); - CGContextSetRGBFillColor (state->cgDrawContext, - solid->color.red, - solid->color.green, - solid->color.blue, - solid->color.alpha); - - state->action = DO_DIRECT; - return CAIRO_STATUS_SUCCESS; - } - - if (source->type == CAIRO_PATTERN_TYPE_LINEAR || - source->type == CAIRO_PATTERN_TYPE_RADIAL) - { - const cairo_gradient_pattern_t *gpat = (const cairo_gradient_pattern_t *)source; - cairo_rectangle_int_t extents; - - extents = surface->virtual_extents; - extents.x -= surface->base.device_transform.x0; - extents.y -= surface->base.device_transform.y0; - _cairo_rectangle_union (&extents, &surface->extents); - - return _cairo_quartz_setup_gradient_source (state, gpat, &extents); - } - - if (source->type == CAIRO_PATTERN_TYPE_SURFACE && - (source->extend == CAIRO_EXTEND_NONE || (CGContextDrawTiledImagePtr && source->extend == CAIRO_EXTEND_REPEAT))) - { - const cairo_surface_pattern_t *spat = (const cairo_surface_pattern_t *) source; - cairo_surface_t *pat_surf = spat->surface; - CGImageRef img; - cairo_matrix_t m = spat->base.matrix; - cairo_rectangle_int_t extents; - CGAffineTransform xform; - CGRect srcRect; - cairo_fixed_t fw, fh; - cairo_bool_t is_bounded; - - _cairo_surface_get_extents (composite->surface, &extents); - status = _cairo_surface_to_cgimage (pat_surf, &extents, format, - &m, clip, &img); - if (unlikely (status)) - return status; - - state->image = img; - - if (state->filter == kCGInterpolationNone && _cairo_matrix_is_translation (&m)) { - m.x0 = -ceil (m.x0 - 0.5); - m.y0 = -ceil (m.y0 - 0.5); - } else { - cairo_matrix_invert (&m); - } - - _cairo_quartz_cairo_matrix_to_quartz (&m, &state->transform); - - if (pat_surf->type != CAIRO_SURFACE_TYPE_RECORDING) { - is_bounded = _cairo_surface_get_extents (pat_surf, &extents); - assert (is_bounded); - } - - srcRect = CGRectMake (0, 0, extents.width, extents.height); - - if (source->extend == CAIRO_EXTEND_NONE) { - int x, y; - if (op == CAIRO_OPERATOR_SOURCE && - (pat_surf->content == CAIRO_CONTENT_ALPHA || - ! _cairo_matrix_is_integer_translation (&m, &x, &y))) - { - state->layer = CGLayerCreateWithContext (surface->cgContext, - state->clipRect.size, - NULL); - state->cgDrawContext = CGLayerGetContext (state->layer); - CGContextTranslateCTM (state->cgDrawContext, - -state->clipRect.origin.x, - -state->clipRect.origin.y); - } - - CGContextSetRGBFillColor (state->cgDrawContext, 0, 0, 0, 1); - - state->rect = srcRect; - state->action = DO_IMAGE; - return CAIRO_STATUS_SUCCESS; - } - - CGContextSetRGBFillColor (state->cgDrawContext, 0, 0, 0, 1); - - /* Quartz seems to tile images at pixel-aligned regions only -- this - * leads to seams if the image doesn't end up scaling to fill the - * space exactly. The CGPattern tiling approach doesn't have this - * problem. Check if we're going to fill up the space (within some - * epsilon), and if not, fall back to the CGPattern type. - */ - - xform = CGAffineTransformConcat (CGContextGetCTM (state->cgDrawContext), - state->transform); - - srcRect = CGRectApplyAffineTransform (srcRect, xform); - - fw = _cairo_fixed_from_double (srcRect.size.width); - fh = _cairo_fixed_from_double (srcRect.size.height); - - if ((fw & CAIRO_FIXED_FRAC_MASK) <= CAIRO_FIXED_EPSILON && - (fh & CAIRO_FIXED_FRAC_MASK) <= CAIRO_FIXED_EPSILON) - { - /* We're good to use DrawTiledImage, but ensure that - * the math works out */ - - srcRect.size.width = round (srcRect.size.width); - srcRect.size.height = round (srcRect.size.height); - - xform = CGAffineTransformInvert (xform); - - srcRect = CGRectApplyAffineTransform (srcRect, xform); - - state->rect = srcRect; - state->action = DO_TILED_IMAGE; - return CAIRO_STATUS_SUCCESS; - } - - /* Fall through to generic SURFACE case */ - } - - if (source->type == CAIRO_PATTERN_TYPE_SURFACE) { - cairo_quartz_float_t patternAlpha = 1.0f; - CGColorSpaceRef patternSpace; - CGPatternRef pattern = NULL; - cairo_int_status_t status; - - status = _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (surface, source, clip, &pattern); - if (unlikely (status)) - return status; - - patternSpace = CGColorSpaceCreatePattern (NULL); - CGContextSetFillColorSpace (state->cgDrawContext, patternSpace); - CGContextSetFillPattern (state->cgDrawContext, pattern, &patternAlpha); - CGContextSetStrokeColorSpace (state->cgDrawContext, patternSpace); - CGContextSetStrokePattern (state->cgDrawContext, pattern, &patternAlpha); - CGColorSpaceRelease (patternSpace); - - /* Quartz likes to munge the pattern phase (as yet unexplained - * why); force it to 0,0 as we've already baked in the correct - * pattern translation into the pattern matrix - */ - CGContextSetPatternPhase (state->cgDrawContext, CGSizeMake (0, 0)); - - CGPatternRelease (pattern); - - state->action = DO_DIRECT; - return CAIRO_STATUS_SUCCESS; - } - - return CAIRO_INT_STATUS_UNSUPPORTED; -} - -static void -_cairo_quartz_teardown_state (cairo_quartz_drawing_state_t *state, - cairo_composite_rectangles_t *extents) -{ - cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) extents->surface; - - if (state->layer) { - CGContextDrawLayerInRect (surface->cgContext, - state->clipRect, - state->layer); - CGLayerRelease (state->layer); - } - - if (state->cgMaskContext) - CGContextRestoreGState (surface->cgContext); - - if (state->image) - CGImageRelease (state->image); - - if (state->shading) - CGShadingRelease (state->shading); -} - -static void -_cairo_quartz_draw_source (cairo_quartz_drawing_state_t *state, - cairo_operator_t op) -{ - CGContextSetShouldAntialias (state->cgDrawContext, state->filter != kCGInterpolationNone); - CGContextSetInterpolationQuality(state->cgDrawContext, state->filter); - - if (state->action == DO_DIRECT) { - CGContextFillRect (state->cgDrawContext, state->rect); - return; - } - - CGContextConcatCTM (state->cgDrawContext, state->transform); - - if (state->action == DO_SHADING) { - CGContextDrawShading (state->cgDrawContext, state->shading); - return; - } - - CGContextTranslateCTM (state->cgDrawContext, 0, state->rect.size.height); - CGContextScaleCTM (state->cgDrawContext, 1, -1); - - if (state->action == DO_IMAGE) { - CGContextDrawImage (state->cgDrawContext, state->rect, state->image); - if (op == CAIRO_OPERATOR_SOURCE && - state->cgDrawContext == state->cgMaskContext) - { - CGContextBeginPath (state->cgDrawContext); - CGContextAddRect (state->cgDrawContext, state->rect); - - CGContextTranslateCTM (state->cgDrawContext, 0, state->rect.size.height); - CGContextScaleCTM (state->cgDrawContext, 1, -1); - CGContextConcatCTM (state->cgDrawContext, - CGAffineTransformInvert (state->transform)); - - CGContextAddRect (state->cgDrawContext, state->clipRect); - - CGContextSetRGBFillColor (state->cgDrawContext, 0, 0, 0, 0); - CGContextEOFillPath (state->cgDrawContext); - } - } else { - CGContextDrawTiledImagePtr (state->cgDrawContext, state->rect, state->image); - } -} - -static cairo_image_surface_t * -_cairo_quartz_surface_map_to_image (void *abstract_surface, - const cairo_rectangle_int_t *extents) -{ - cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface; - unsigned int stride, bitinfo, bpp, color_comps; - CGColorSpaceRef colorspace; - void *imageData; - cairo_format_t format; - - if (surface->imageSurfaceEquiv) - return _cairo_surface_map_to_image (surface->imageSurfaceEquiv, extents); - - if (IS_EMPTY (surface)) - return (cairo_image_surface_t *) cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0); - - if (! _cairo_quartz_is_cgcontext_bitmap_context (surface->cgContext)) - return _cairo_image_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - bitinfo = CGBitmapContextGetBitmapInfo (surface->cgContext); - bpp = CGBitmapContextGetBitsPerPixel (surface->cgContext); - - // let's hope they don't add YUV under us - colorspace = CGBitmapContextGetColorSpace (surface->cgContext); - color_comps = CGColorSpaceGetNumberOfComponents (colorspace); - - /* XXX TODO: We can handle many more data formats by - * converting to pixman_format_t */ - - if (bpp == 32 && color_comps == 3 && - (bitinfo & kCGBitmapAlphaInfoMask) == kCGImageAlphaPremultipliedFirst && - (bitinfo & kCGBitmapByteOrderMask) == kCGBitmapByteOrder32Host) - { - format = CAIRO_FORMAT_ARGB32; - } - else if (bpp == 32 && color_comps == 3 && - (bitinfo & kCGBitmapAlphaInfoMask) == kCGImageAlphaNoneSkipFirst && - (bitinfo & kCGBitmapByteOrderMask) == kCGBitmapByteOrder32Host) - { - format = CAIRO_FORMAT_RGB24; - } - else if (bpp == 8 && color_comps == 1) - { - format = CAIRO_FORMAT_A1; - } - else - { - return _cairo_image_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - imageData = CGBitmapContextGetData (surface->cgContext); - stride = CGBitmapContextGetBytesPerRow (surface->cgContext); - - return (cairo_image_surface_t *) cairo_image_surface_create_for_data (imageData, - format, - extents->width, - extents->height, - stride); -} - -static cairo_int_status_t -_cairo_quartz_surface_unmap_image (void *abstract_surface, - cairo_image_surface_t *image) -{ - cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface; - - if (surface->imageSurfaceEquiv) - return _cairo_surface_unmap_image (surface->imageSurfaceEquiv, image); - - cairo_surface_finish (&image->base); - cairo_surface_destroy (&image->base); - - return CAIRO_STATUS_SUCCESS; -} - - -/* - * Cairo surface backend implementations - */ - -static cairo_status_t -_cairo_quartz_surface_finish (void *abstract_surface) -{ - cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface; - - ND ((stderr, "_cairo_quartz_surface_finish[%p] cgc: %p\n", surface, surface->cgContext)); - - if (IS_EMPTY (surface)) - return CAIRO_STATUS_SUCCESS; - - /* Restore our saved gstate that we use to reset clipping */ - CGContextRestoreGState (surface->cgContext); - _cairo_surface_clipper_reset (&surface->clipper); - - CGContextRelease (surface->cgContext); - - surface->cgContext = NULL; - - if (surface->imageSurfaceEquiv) { - cairo_surface_destroy (surface->imageSurfaceEquiv); - surface->imageSurfaceEquiv = NULL; - } - - free (surface->imageData); - surface->imageData = NULL; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_quartz_surface_acquire_source_image (void *abstract_surface, - cairo_image_surface_t **image_out, - void **image_extra) -{ - cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface; - - //ND ((stderr, "%p _cairo_quartz_surface_acquire_source_image\n", surface)); - - *image_extra = NULL; - - *image_out = _cairo_quartz_surface_map_to_image (surface, &surface->extents); - if (unlikely (cairo_surface_status(&(*image_out)->base))) { - cairo_surface_destroy (&(*image_out)->base); - *image_out = NULL; - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_quartz_surface_release_source_image (void *abstract_surface, - cairo_image_surface_t *image, - void *image_extra) -{ - _cairo_quartz_surface_unmap_image (abstract_surface, image); -} - -static cairo_surface_t * -_cairo_quartz_surface_create_similar (void *abstract_surface, - cairo_content_t content, - int width, - int height) -{ - cairo_quartz_surface_t *surface, *similar_quartz; - cairo_surface_t *similar; - cairo_format_t format; - - if (content == CAIRO_CONTENT_COLOR_ALPHA) - format = CAIRO_FORMAT_ARGB32; - else if (content == CAIRO_CONTENT_COLOR) - format = CAIRO_FORMAT_RGB24; - else if (content == CAIRO_CONTENT_ALPHA) - format = CAIRO_FORMAT_A8; - else - return NULL; - - // verify width and height of surface - if (!_cairo_quartz_verify_surface_size (width, height)) { - return _cairo_surface_create_in_error (_cairo_error - (CAIRO_STATUS_INVALID_SIZE)); - } - - similar = cairo_quartz_surface_create (format, width, height); - if (unlikely (similar->status)) - return similar; - - surface = (cairo_quartz_surface_t *) abstract_surface; - similar_quartz = (cairo_quartz_surface_t *) similar; - similar_quartz->virtual_extents = surface->virtual_extents; - - return similar; -} - -static cairo_bool_t -_cairo_quartz_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *extents) -{ - cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface; - - *extents = surface->extents; - return TRUE; -} - -static cairo_int_status_t -_cairo_quartz_cg_paint (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *extents) -{ - cairo_quartz_drawing_state_t state; - cairo_int_status_t rv; - - ND ((stderr, "%p _cairo_quartz_surface_paint op %d source->type %d\n", - extents->surface, extents->op, extents->source_pattern.base.type)); - - rv = _cairo_quartz_setup_state (&state, extents); - if (unlikely (rv)) - goto BAIL; - - _cairo_quartz_draw_source (&state, extents->op); - -BAIL: - _cairo_quartz_teardown_state (&state, extents); - - ND ((stderr, "-- paint\n")); - return rv; -} - -static cairo_int_status_t -_cairo_quartz_cg_mask_with_surface (cairo_composite_rectangles_t *extents, - cairo_surface_t *mask_surf, - const cairo_matrix_t *mask_mat, - CGInterpolationQuality filter) -{ - CGRect rect; - CGImageRef img; - cairo_status_t status; - CGAffineTransform mask_matrix; - cairo_quartz_drawing_state_t state; - cairo_format_t format = _cairo_format_from_content (extents->surface->content); - cairo_rectangle_int_t dest_extents; - cairo_matrix_t m = *mask_mat; - - _cairo_surface_get_extents (extents->surface, &dest_extents); - status = _cairo_surface_to_cgimage (mask_surf, &dest_extents, format, - &m, extents->clip, &img); - if (unlikely (status)) - return status; - - status = _cairo_quartz_setup_state (&state, extents); - if (unlikely (status)) - goto BAIL; - - rect = CGRectMake (0.0, 0.0, CGImageGetWidth (img), CGImageGetHeight (img)); - _cairo_quartz_cairo_matrix_to_quartz (&m, &mask_matrix); - - /* ClipToMask is essentially drawing an image, so we need to flip the CTM - * to get the image to appear oriented the right way */ - CGContextConcatCTM (state.cgMaskContext, CGAffineTransformInvert (mask_matrix)); - CGContextTranslateCTM (state.cgMaskContext, 0.0, rect.size.height); - CGContextScaleCTM (state.cgMaskContext, 1.0, -1.0); - - state.filter = filter; - - CGContextSetInterpolationQuality (state.cgMaskContext, filter); - CGContextSetShouldAntialias (state.cgMaskContext, filter != kCGInterpolationNone); - - CGContextClipToMask (state.cgMaskContext, rect, img); - - CGContextScaleCTM (state.cgMaskContext, 1.0, -1.0); - CGContextTranslateCTM (state.cgMaskContext, 0.0, -rect.size.height); - CGContextConcatCTM (state.cgMaskContext, mask_matrix); - - _cairo_quartz_draw_source (&state, extents->op); - -BAIL: - _cairo_quartz_teardown_state (&state, extents); - - CGImageRelease (img); - - return status; -} - -static cairo_int_status_t -_cairo_quartz_cg_mask_with_solid (cairo_quartz_surface_t *surface, - cairo_composite_rectangles_t *extents) -{ - cairo_quartz_drawing_state_t state; - double alpha = extents->mask_pattern.solid.color.alpha; - cairo_status_t status; - - status = _cairo_quartz_setup_state (&state, extents); - if (unlikely (status)) - return status; - - CGContextSetAlpha (surface->cgContext, alpha); - _cairo_quartz_draw_source (&state, extents->op); - - _cairo_quartz_teardown_state (&state, extents); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_quartz_cg_mask (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *extents) -{ - cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *)extents->surface; - const cairo_pattern_t *source = &extents->source_pattern.base; - const cairo_pattern_t *mask = &extents->mask_pattern.base; - cairo_surface_t *mask_surf; - cairo_matrix_t matrix; - cairo_status_t status; - cairo_bool_t need_temp; - CGInterpolationQuality filter; - - ND ((stderr, "%p _cairo_quartz_surface_mask op %d source->type %d mask->type %d\n", - extents->surface, extents->op, extents->source_pattern.base.type, - extents->mask_pattern.base.type)); - - if (mask->type == CAIRO_PATTERN_TYPE_SOLID) - return _cairo_quartz_cg_mask_with_solid (surface, extents); - - need_temp = (mask->type != CAIRO_PATTERN_TYPE_SURFACE || - mask->extend != CAIRO_EXTEND_NONE); - - filter = _cairo_quartz_filter_to_quartz (source->filter); - - if (! need_temp) { - mask_surf = extents->mask_pattern.surface.surface; - - /* When an opaque surface used as a mask in Quartz, its - * luminosity is used as the alpha value, so we con only use - * surfaces with alpha without creating a temporary mask. */ - need_temp = ! (mask_surf->content & CAIRO_CONTENT_ALPHA); - } - - if (! need_temp) { - CGInterpolationQuality mask_filter; - cairo_bool_t simple_transform; - - matrix = mask->matrix; - - mask_filter = _cairo_quartz_filter_to_quartz (mask->filter); - if (mask_filter == kCGInterpolationNone) { - simple_transform = _cairo_matrix_is_translation (&matrix); - if (simple_transform) { - matrix.x0 = ceil (matrix.x0 - 0.5); - matrix.y0 = ceil (matrix.y0 - 0.5); - } - } else { - simple_transform = _cairo_matrix_is_integer_translation (&matrix, - NULL, - NULL); - } - - /* Quartz only allows one interpolation to be set for mask and - * source, so we can skip the temp surface only if the source - * filtering makes the mask look correct. */ - if (source->type == CAIRO_PATTERN_TYPE_SURFACE) - need_temp = ! (simple_transform || filter == mask_filter); - else - filter = mask_filter; - } - - if (need_temp) { - /* Render the mask to a surface */ - mask_surf = _cairo_quartz_surface_create_similar (surface, - CAIRO_CONTENT_ALPHA, - surface->extents.width, - surface->extents.height); - status = mask_surf->status; - if (unlikely (status)) - goto BAIL; - - /* mask_surf is clear, so use OVER instead of SOURCE to avoid a - * temporary layer or fallback to cairo-image. */ - status = _cairo_surface_paint (mask_surf, CAIRO_OPERATOR_OVER, mask, NULL); - if (unlikely (status)) - goto BAIL; - - cairo_matrix_init_identity (&matrix); - } - - status = _cairo_quartz_cg_mask_with_surface (extents, - mask_surf, &matrix, filter); - -BAIL: - - if (need_temp) - cairo_surface_destroy (mask_surf); - - return status; -} - -static cairo_int_status_t -_cairo_quartz_cg_fill (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_quartz_drawing_state_t state; - cairo_int_status_t rv = CAIRO_STATUS_SUCCESS; - - ND ((stderr, "%p _cairo_quartz_surface_fill op %d source->type %d\n", - extents->surface, extents->op, extents->source_pattern.base.type)); - - rv = _cairo_quartz_setup_state (&state, extents); - if (unlikely (rv)) - goto BAIL; - - CGContextSetShouldAntialias (state.cgMaskContext, (antialias != CAIRO_ANTIALIAS_NONE)); - - _cairo_quartz_cairo_path_to_quartz_context (path, state.cgMaskContext); - - if (state.action == DO_DIRECT) { - assert (state.cgDrawContext == state.cgMaskContext); - if (fill_rule == CAIRO_FILL_RULE_WINDING) - CGContextFillPath (state.cgMaskContext); - else - CGContextEOFillPath (state.cgMaskContext); - } else { - if (fill_rule == CAIRO_FILL_RULE_WINDING) - CGContextClip (state.cgMaskContext); - else - CGContextEOClip (state.cgMaskContext); - - _cairo_quartz_draw_source (&state, extents->op); - } - -BAIL: - _cairo_quartz_teardown_state (&state, extents); - - ND ((stderr, "-- fill\n")); - return rv; -} - -static cairo_int_status_t -_cairo_quartz_cg_stroke (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_quartz_drawing_state_t state; - cairo_int_status_t rv = CAIRO_STATUS_SUCCESS; - CGAffineTransform strokeTransform, invStrokeTransform; - - ND ((stderr, "%p _cairo_quartz_surface_stroke op %d source->type %d\n", - extents->surface, extents->op, extents->source_pattern.base.type)); - - rv = _cairo_quartz_setup_state (&state, extents); - if (unlikely (rv)) - goto BAIL; - - // Turning antialiasing off used to cause misrendering with - // single-pixel lines (e.g. 20,10.5 -> 21,10.5 end up being rendered as 2 pixels). - // That's been since fixed in at least 10.5, and in the latest 10.4 dot releases. - CGContextSetShouldAntialias (state.cgMaskContext, (antialias != CAIRO_ANTIALIAS_NONE)); - CGContextSetLineWidth (state.cgMaskContext, style->line_width); - CGContextSetLineCap (state.cgMaskContext, _cairo_quartz_cairo_line_cap_to_quartz (style->line_cap)); - CGContextSetLineJoin (state.cgMaskContext, _cairo_quartz_cairo_line_join_to_quartz (style->line_join)); - CGContextSetMiterLimit (state.cgMaskContext, style->miter_limit); - - if (style->dash && style->num_dashes) { - cairo_quartz_float_t sdash[CAIRO_STACK_ARRAY_LENGTH (cairo_quartz_float_t)]; - cairo_quartz_float_t *fdash = sdash; - unsigned int max_dashes = style->num_dashes; - unsigned int k; - - if (style->num_dashes%2) - max_dashes *= 2; - if (max_dashes > ARRAY_LENGTH (sdash)) - fdash = _cairo_malloc_ab (max_dashes, sizeof (cairo_quartz_float_t)); - if (unlikely (fdash == NULL)) { - rv = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto BAIL; - } - - for (k = 0; k < max_dashes; k++) - fdash[k] = (cairo_quartz_float_t) style->dash[k % style->num_dashes]; - - CGContextSetLineDash (state.cgMaskContext, style->dash_offset, fdash, max_dashes); - if (fdash != sdash) - free (fdash); - } else - CGContextSetLineDash (state.cgMaskContext, 0, NULL, 0); - - _cairo_quartz_cairo_path_to_quartz_context (path, state.cgMaskContext); - - _cairo_quartz_cairo_matrix_to_quartz (ctm, &strokeTransform); - CGContextConcatCTM (state.cgMaskContext, strokeTransform); - - if (state.action == DO_DIRECT) { - assert (state.cgDrawContext == state.cgMaskContext); - CGContextStrokePath (state.cgMaskContext); - } else { - CGContextReplacePathWithStrokedPath (state.cgMaskContext); - CGContextClip (state.cgMaskContext); - - _cairo_quartz_cairo_matrix_to_quartz (ctm_inverse, &invStrokeTransform); - CGContextConcatCTM (state.cgMaskContext, invStrokeTransform); - - _cairo_quartz_draw_source (&state, extents->op); - } - -BAIL: - _cairo_quartz_teardown_state (&state, extents); - - ND ((stderr, "-- stroke\n")); - return rv; -} - -#if CAIRO_HAS_QUARTZ_FONT -static cairo_int_status_t -_cairo_quartz_cg_glyphs (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_bool_t overlap) -{ - CGAffineTransform textTransform, invTextTransform; - CGGlyph glyphs_static[CAIRO_STACK_ARRAY_LENGTH (CGSize)]; - CGSize cg_advances_static[CAIRO_STACK_ARRAY_LENGTH (CGSize)]; - CGGlyph *cg_glyphs = &glyphs_static[0]; - CGSize *cg_advances = &cg_advances_static[0]; - COMPILE_TIME_ASSERT (sizeof (CGGlyph) <= sizeof (CGSize)); - - cairo_quartz_drawing_state_t state; - cairo_int_status_t rv = CAIRO_INT_STATUS_UNSUPPORTED; - cairo_quartz_float_t xprev, yprev; - int i; - CGFontRef cgfref = NULL; - - cairo_bool_t didForceFontSmoothing = FALSE; - - if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_QUARTZ) - return CAIRO_INT_STATUS_UNSUPPORTED; - - rv = _cairo_quartz_setup_state (&state, extents); - if (unlikely (rv)) - goto BAIL; - - if (state.action == DO_DIRECT) { - assert (state.cgDrawContext == state.cgMaskContext); - CGContextSetTextDrawingMode (state.cgMaskContext, kCGTextFill); - } else { - CGContextSetTextDrawingMode (state.cgMaskContext, kCGTextClip); - } - - /* this doesn't addref */ - cgfref = _cairo_quartz_scaled_font_get_cg_font_ref (scaled_font); - CGContextSetFont (state.cgMaskContext, cgfref); - CGContextSetFontSize (state.cgMaskContext, 1.0); - - switch (scaled_font->options.antialias) { - case CAIRO_ANTIALIAS_SUBPIXEL: - case CAIRO_ANTIALIAS_BEST: - CGContextSetShouldAntialias (state.cgMaskContext, TRUE); - CGContextSetShouldSmoothFonts (state.cgMaskContext, TRUE); - if (CGContextSetAllowsFontSmoothingPtr && - !CGContextGetAllowsFontSmoothingPtr (state.cgMaskContext)) - { - didForceFontSmoothing = TRUE; - CGContextSetAllowsFontSmoothingPtr (state.cgMaskContext, TRUE); - } - break; - case CAIRO_ANTIALIAS_NONE: - CGContextSetShouldAntialias (state.cgMaskContext, FALSE); - break; - case CAIRO_ANTIALIAS_GRAY: - case CAIRO_ANTIALIAS_GOOD: - case CAIRO_ANTIALIAS_FAST: - CGContextSetShouldAntialias (state.cgMaskContext, TRUE); - CGContextSetShouldSmoothFonts (state.cgMaskContext, FALSE); - break; - case CAIRO_ANTIALIAS_DEFAULT: - /* Don't do anything */ - break; - } - - if (num_glyphs > ARRAY_LENGTH (glyphs_static)) { - cg_glyphs = (CGGlyph*) _cairo_malloc_ab (num_glyphs, sizeof (CGGlyph) + sizeof (CGSize)); - if (unlikely (cg_glyphs == NULL)) { - rv = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto BAIL; - } - - cg_advances = (CGSize*) (cg_glyphs + num_glyphs); - } - - /* scale(1,-1) * scaled_font->scale */ - textTransform = CGAffineTransformMake (scaled_font->scale.xx, - scaled_font->scale.yx, - -scaled_font->scale.xy, - -scaled_font->scale.yy, - 0.0, 0.0); - - /* scaled_font->scale_inverse * scale(1,-1) */ - invTextTransform = CGAffineTransformMake (scaled_font->scale_inverse.xx, - -scaled_font->scale_inverse.yx, - scaled_font->scale_inverse.xy, - -scaled_font->scale_inverse.yy, - 0.0, 0.0); - - CGContextSetTextPosition (state.cgMaskContext, 0.0, 0.0); - CGContextSetTextMatrix (state.cgMaskContext, CGAffineTransformIdentity); - - /* Convert our glyph positions to glyph advances. We need n-1 advances, - * since the advance at index 0 is applied after glyph 0. */ - xprev = glyphs[0].x; - yprev = glyphs[0].y; - - cg_glyphs[0] = glyphs[0].index; - - for (i = 1; i < num_glyphs; i++) { - cairo_quartz_float_t xf = glyphs[i].x; - cairo_quartz_float_t yf = glyphs[i].y; - cg_glyphs[i] = glyphs[i].index; - cg_advances[i - 1] = CGSizeApplyAffineTransform (CGSizeMake (xf - xprev, yf - yprev), invTextTransform); - xprev = xf; - yprev = yf; - } - - /* Translate to the first glyph's position before drawing */ - CGContextTranslateCTM (state.cgMaskContext, glyphs[0].x, glyphs[0].y); - CGContextConcatCTM (state.cgMaskContext, textTransform); - - CGContextShowGlyphsWithAdvances (state.cgMaskContext, - cg_glyphs, - cg_advances, - num_glyphs); - - CGContextConcatCTM (state.cgMaskContext, invTextTransform); - CGContextTranslateCTM (state.cgMaskContext, -glyphs[0].x, -glyphs[0].y); - - if (state.action != DO_DIRECT) - _cairo_quartz_draw_source (&state, extents->op); - -BAIL: - if (didForceFontSmoothing) - CGContextSetAllowsFontSmoothingPtr (state.cgMaskContext, FALSE); - - _cairo_quartz_teardown_state (&state, extents); - - if (cg_glyphs != glyphs_static) - free (cg_glyphs); - - return rv; -} -#endif /* CAIRO_HAS_QUARTZ_FONT */ - -static const cairo_compositor_t _cairo_quartz_cg_compositor = { - &_cairo_fallback_compositor, - - _cairo_quartz_cg_paint, - _cairo_quartz_cg_mask, - _cairo_quartz_cg_stroke, - _cairo_quartz_cg_fill, -#if CAIRO_HAS_QUARTZ_FONT - _cairo_quartz_cg_glyphs, -#else - NULL, -#endif -}; - -static cairo_int_status_t -_cairo_quartz_surface_paint (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - return _cairo_compositor_paint (&_cairo_quartz_cg_compositor, - surface, op, source, clip); -} - -static cairo_int_status_t -_cairo_quartz_surface_mask (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - return _cairo_compositor_mask (&_cairo_quartz_cg_compositor, - surface, op, source, mask, - clip); -} - -static cairo_int_status_t -_cairo_quartz_surface_fill (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - return _cairo_compositor_fill (&_cairo_quartz_cg_compositor, - surface, op, source, path, - fill_rule, tolerance, antialias, - clip); -} - -static cairo_int_status_t -_cairo_quartz_surface_stroke (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - return _cairo_compositor_stroke (&_cairo_quartz_cg_compositor, - surface, op, source, path, - style, ctm,ctm_inverse, - tolerance, antialias, clip); -} - -static cairo_int_status_t -_cairo_quartz_surface_glyphs (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - return _cairo_compositor_glyphs (&_cairo_quartz_cg_compositor, - surface, op, source, - glyphs, num_glyphs, scaled_font, - clip); -} - -static cairo_status_t -_cairo_quartz_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper, - cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_quartz_surface_t *surface = - cairo_container_of (clipper, cairo_quartz_surface_t, clipper); - - ND ((stderr, "%p _cairo_quartz_surface_intersect_clip_path path: %p\n", surface, path)); - - if (IS_EMPTY (surface)) - return CAIRO_STATUS_SUCCESS; - - if (path == NULL) { - /* If we're being asked to reset the clip, we can only do it - * by restoring the gstate to our previous saved one, and - * saving it again. - * - * Note that this assumes that ALL quartz surface creation - * functions will do a SaveGState first; we do this in create_internal. - */ - CGContextRestoreGState (surface->cgContext); - CGContextSaveGState (surface->cgContext); - } else { - CGContextSetShouldAntialias (surface->cgContext, (antialias != CAIRO_ANTIALIAS_NONE)); - - _cairo_quartz_cairo_path_to_quartz_context (path, surface->cgContext); - - if (fill_rule == CAIRO_FILL_RULE_WINDING) - CGContextClip (surface->cgContext); - else - CGContextEOClip (surface->cgContext); - } - - ND ((stderr, "-- intersect_clip_path\n")); - - return CAIRO_STATUS_SUCCESS; -} - -// XXXtodo implement show_page; need to figure out how to handle begin/end - -static const struct _cairo_surface_backend cairo_quartz_surface_backend = { - CAIRO_SURFACE_TYPE_QUARTZ, - _cairo_quartz_surface_finish, - - _cairo_default_context_create, - - _cairo_quartz_surface_create_similar, - NULL, /* similar image */ - _cairo_quartz_surface_map_to_image, - _cairo_quartz_surface_unmap_image, - - _cairo_surface_default_source, - _cairo_quartz_surface_acquire_source_image, - _cairo_quartz_surface_release_source_image, - NULL, /* snapshot */ - - NULL, /* copy_page */ - NULL, /* show_page */ - - _cairo_quartz_surface_get_extents, - NULL, /* get_font_options */ - - NULL, /* flush */ - NULL, /* mark_dirty_rectangle */ - - _cairo_quartz_surface_paint, - _cairo_quartz_surface_mask, - _cairo_quartz_surface_stroke, - _cairo_quartz_surface_fill, - NULL, /* fill-stroke */ - _cairo_quartz_surface_glyphs, -}; - -cairo_quartz_surface_t * -_cairo_quartz_surface_create_internal (CGContextRef cgContext, - cairo_content_t content, - unsigned int width, - unsigned int height) -{ - cairo_quartz_surface_t *surface; - - quartz_ensure_symbols (); - - /* Init the base surface */ - surface = malloc (sizeof (cairo_quartz_surface_t)); - if (unlikely (surface == NULL)) - return (cairo_quartz_surface_t*) _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - memset (surface, 0, sizeof (cairo_quartz_surface_t)); - - _cairo_surface_init (&surface->base, - &cairo_quartz_surface_backend, - NULL, /* device */ - content); - - _cairo_surface_clipper_init (&surface->clipper, - _cairo_quartz_surface_clipper_intersect_clip_path); - - /* Save our extents */ - surface->extents.x = surface->extents.y = 0; - surface->extents.width = width; - surface->extents.height = height; - surface->virtual_extents = surface->extents; - - if (IS_EMPTY (surface)) { - surface->cgContext = NULL; - surface->cgContextBaseCTM = CGAffineTransformIdentity; - surface->imageData = NULL; - surface->base.is_clear = TRUE; - return surface; - } - - /* Save so we can always get back to a known-good CGContext -- this is - * required for proper behaviour of intersect_clip_path(NULL) - */ - CGContextSaveGState (cgContext); - - surface->cgContext = cgContext; - surface->cgContextBaseCTM = CGContextGetCTM (cgContext); - - surface->imageData = NULL; - surface->imageSurfaceEquiv = NULL; - - return surface; -} - -/** - * cairo_quartz_surface_create_for_cg_context: - * @cgContext: the existing CGContext for which to create the surface - * @width: width of the surface, in pixels - * @height: height of the surface, in pixels - * - * Creates a Quartz surface that wraps the given CGContext. The - * CGContext is assumed to be in the standard Cairo coordinate space - * (that is, with the origin at the upper left and the Y axis - * increasing downward). If the CGContext is in the Quartz coordinate - * space (with the origin at the bottom left), then it should be - * flipped before this function is called. The flip can be accomplished - * using a translate and a scale; for example: - * - * <informalexample><programlisting> - * CGContextTranslateCTM (cgContext, 0.0, height); - * CGContextScaleCTM (cgContext, 1.0, -1.0); - * </programlisting></informalexample> - * - * All Cairo operations are implemented in terms of Quartz operations, - * as long as Quartz-compatible elements are used (such as Quartz fonts). - * - * Return value: the newly created Cairo surface. - * - * Since: 1.6 - **/ - -cairo_surface_t * -cairo_quartz_surface_create_for_cg_context (CGContextRef cgContext, - unsigned int width, - unsigned int height) -{ - cairo_quartz_surface_t *surf; - - surf = _cairo_quartz_surface_create_internal (cgContext, CAIRO_CONTENT_COLOR_ALPHA, - width, height); - if (likely (!surf->base.status)) - CGContextRetain (cgContext); - - return &surf->base; -} - -/** - * cairo_quartz_surface_create: - * @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 Quartz surface backed by a CGBitmap. The surface is - * created using the Device RGB (or Device Gray, for A8) color space. - * All Cairo operations, including those that require software - * rendering, will succeed on this surface. - * - * Return value: the newly created surface. - * - * Since: 1.6 - **/ -cairo_surface_t * -cairo_quartz_surface_create (cairo_format_t format, - unsigned int width, - unsigned int height) -{ - cairo_quartz_surface_t *surf; - CGContextRef cgc; - CGColorSpaceRef cgColorspace; - CGBitmapInfo bitinfo; - void *imageData; - int stride; - int bitsPerComponent; - - if (!_cairo_quartz_verify_surface_size (width, height)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE)); - - if (width == 0 || height == 0) { - return &_cairo_quartz_surface_create_internal (NULL, _cairo_content_from_format (format), - width, height)->base; - } - - if (format == CAIRO_FORMAT_ARGB32 || - format == CAIRO_FORMAT_RGB24) - { - cgColorspace = CGColorSpaceCreateDeviceRGB (); - bitinfo = kCGBitmapByteOrder32Host; - if (format == CAIRO_FORMAT_ARGB32) - bitinfo |= kCGImageAlphaPremultipliedFirst; - else - bitinfo |= kCGImageAlphaNoneSkipFirst; - bitsPerComponent = 8; - stride = width * 4; - } else if (format == CAIRO_FORMAT_A8) { - cgColorspace = NULL; - stride = width; - bitinfo = kCGImageAlphaOnly; - bitsPerComponent = 8; - } else if (format == CAIRO_FORMAT_A1) { - /* I don't think we can usefully support this, as defined by - * cairo_format_t -- these are 1-bit pixels stored in 32-bit - * quantities. - */ - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT)); - } else { - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT)); - } - - /* The Apple docs say that for best performance, the stride and the data - * pointer should be 16-byte aligned. malloc already aligns to 16-bytes, - * so we don't have to anything special on allocation. - */ - stride = (stride + 15) & ~15; - - imageData = _cairo_malloc_ab (height, stride); - if (unlikely (!imageData)) { - CGColorSpaceRelease (cgColorspace); - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - /* zero the memory to match the image surface behaviour */ - memset (imageData, 0, height * stride); - - cgc = CGBitmapContextCreate (imageData, - width, - height, - bitsPerComponent, - stride, - cgColorspace, - bitinfo); - CGColorSpaceRelease (cgColorspace); - - if (!cgc) { - free (imageData); - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - /* flip the Y axis */ - CGContextTranslateCTM (cgc, 0.0, height); - CGContextScaleCTM (cgc, 1.0, -1.0); - - surf = _cairo_quartz_surface_create_internal (cgc, _cairo_content_from_format (format), - width, height); - if (surf->base.status) { - CGContextRelease (cgc); - free (imageData); - // create_internal will have set an error - return &surf->base; - } - - surf->base.is_clear = TRUE; - - surf->imageData = imageData; - surf->imageSurfaceEquiv = cairo_image_surface_create_for_data (imageData, format, width, height, stride); - - return &surf->base; -} - -/** - * cairo_quartz_surface_get_cg_context: - * @surface: the Cairo Quartz surface - * - * Returns the CGContextRef that the given Quartz surface is backed - * by. - * - * A call to cairo_surface_flush() is required before using the - * CGContextRef to ensure that all pending drawing operations are - * finished and to restore any temporary modification cairo has made - * to its state. A call to cairo_surface_mark_dirty() is required - * after the state or the content of the CGContextRef has been - * modified. - * - * Return value: the CGContextRef for the given surface. - * - * Since: 1.6 - **/ -CGContextRef -cairo_quartz_surface_get_cg_context (cairo_surface_t *surface) -{ - if (surface && _cairo_surface_is_quartz (surface)) { - cairo_quartz_surface_t *quartz = (cairo_quartz_surface_t *) surface; - return quartz->cgContext; - } else - return NULL; -} - -/** - * _cairo_surface_is_quartz: - * @surface: a #cairo_surface_t - * - * Checks if a surface is a #cairo_quartz_surface_t - * - * Return value: True if the surface is an quartz surface - **/ -cairo_bool_t -_cairo_surface_is_quartz (const cairo_surface_t *surface) -{ - return surface->backend == &cairo_quartz_surface_backend; -} - -/* Debug stuff */ - -#ifdef QUARTZ_DEBUG - -#include <Movies.h> - -void ExportCGImageToPNGFile (CGImageRef inImageRef, char* dest) -{ - Handle dataRef = NULL; - OSType dataRefType; - CFStringRef inPath = CFStringCreateWithCString (NULL, dest, kCFStringEncodingASCII); - - GraphicsExportComponent grex = 0; - unsigned long sizeWritten; - - ComponentResult result; - - // create the data reference - result = QTNewDataReferenceFromFullPathCFString (inPath, kQTNativeDefaultPathStyle, - 0, &dataRef, &dataRefType); - - if (NULL != dataRef && noErr == result) { - // get the PNG exporter - result = OpenADefaultComponent (GraphicsExporterComponentType, kQTFileTypePNG, - &grex); - - if (grex) { - // tell the exporter where to find its source image - result = GraphicsExportSetInputCGImage (grex, inImageRef); - - if (noErr == result) { - // tell the exporter where to save the exporter image - result = GraphicsExportSetOutputDataReference (grex, dataRef, - dataRefType); - - if (noErr == result) { - // write the PNG file - result = GraphicsExportDoExport (grex, &sizeWritten); - } - } - - // remember to close the component - CloseComponent (grex); - } - - // remember to dispose of the data reference handle - DisposeHandle (dataRef); - } -} - -void -quartz_image_to_png (CGImageRef imgref, char *dest) -{ - static int sctr = 0; - char sptr[] = "/Users/vladimir/Desktop/barXXXXX.png"; - - if (dest == NULL) { - fprintf (stderr, "** Writing %p to bar%d\n", imgref, sctr); - sprintf (sptr, "/Users/vladimir/Desktop/bar%d.png", sctr); - sctr++; - dest = sptr; - } - - ExportCGImageToPNGFile (imgref, dest); -} - -void -quartz_surface_to_png (cairo_quartz_surface_t *nq, char *dest) -{ - static int sctr = 0; - char sptr[] = "/Users/vladimir/Desktop/fooXXXXX.png"; - - if (nq->base.type != CAIRO_SURFACE_TYPE_QUARTZ) { - fprintf (stderr, "** quartz_surface_to_png: surface %p isn't quartz!\n", nq); - return; - } - - if (dest == NULL) { - fprintf (stderr, "** Writing %p to foo%d\n", nq, sctr); - sprintf (sptr, "/Users/vladimir/Desktop/foo%d.png", sctr); - sctr++; - dest = sptr; - } - - CGImageRef imgref = CGBitmapContextCreateImage (nq->cgContext); - if (imgref == NULL) { - fprintf (stderr, "quartz surface at %p is not a bitmap context!\n", nq); - return; - } - - ExportCGImageToPNGFile (imgref, dest); - - CGImageRelease (imgref); -} - -#endif /* QUARTZ_DEBUG */ diff --git a/source/libs/cairo/cairo-src/src/cairo-quartz.h b/source/libs/cairo/cairo-src/src/cairo-quartz.h deleted file mode 100644 index 9be5f9ae5cfb2cfac084969f39c9d6ae37b1d90e..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-quartz.h +++ /dev/null @@ -1,82 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2006, 2007 Mozilla Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Mozilla Foundation. - * - * Contributor(s): - * Vladimir Vukicevic <vladimir@mozilla.com> - */ - -#ifndef CAIRO_QUARTZ_H -#define CAIRO_QUARTZ_H - -#include "cairo.h" - -#if CAIRO_HAS_QUARTZ_SURFACE - -#include <ApplicationServices/ApplicationServices.h> - -CAIRO_BEGIN_DECLS - -cairo_public cairo_surface_t * -cairo_quartz_surface_create (cairo_format_t format, - unsigned int width, - unsigned int height); - -cairo_public cairo_surface_t * -cairo_quartz_surface_create_for_cg_context (CGContextRef cgContext, - unsigned int width, - unsigned int height); - -cairo_public CGContextRef -cairo_quartz_surface_get_cg_context (cairo_surface_t *surface); - -#if CAIRO_HAS_QUARTZ_FONT - -/* - * Quartz font support - */ - -cairo_public cairo_font_face_t * -cairo_quartz_font_face_create_for_cgfont (CGFontRef font); - -cairo_public cairo_font_face_t * -cairo_quartz_font_face_create_for_atsu_font_id (ATSUFontID font_id); - -#endif /* CAIRO_HAS_QUARTZ_FONT */ - -CAIRO_END_DECLS - -#else - -# error Cairo was not compiled with support for the quartz backend - -#endif /* CAIRO_HAS_QUARTZ_SURFACE */ - -#endif /* CAIRO_QUARTZ_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-raster-source-pattern.c b/source/libs/cairo/cairo-src/src/cairo-raster-source-pattern.c deleted file mode 100644 index 64520feae5228ff82cd7caed0cda40680e5e2660..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-raster-source-pattern.c +++ /dev/null @@ -1,430 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" -#include "cairo-error-private.h" -#include "cairo-pattern-private.h" - -/** - * SECTION:cairo-raster-source - * @Title: Raster Sources - * @Short_Description: Supplying arbitrary image data - * @See_Also: #cairo_pattern_t - * - * The raster source provides the ability to supply arbitrary pixel data - * whilst rendering. The pixels are queried at the time of rasterisation - * by means of user callback functions, allowing for the ultimate - * flexibility. For example, in handling compressed image sources, you - * may keep a MRU cache of decompressed images and decompress sources on the - * fly and discard old ones to conserve memory. - * - * For the raster source to be effective, you must at least specify - * the acquire and release callbacks which are used to retrieve the pixel - * data for the region of interest and demark when it can be freed afterwards. - * Other callbacks are provided for when the pattern is copied temporarily - * during rasterisation, or more permanently as a snapshot in order to keep - * the pixel data available for printing. - **/ - -cairo_surface_t * -_cairo_raster_source_pattern_acquire (const cairo_pattern_t *abstract_pattern, - cairo_surface_t *target, - const cairo_rectangle_int_t *extents) -{ - cairo_raster_source_pattern_t *pattern = - (cairo_raster_source_pattern_t *) abstract_pattern; - - if (pattern->acquire == NULL) - return NULL; - - if (extents == NULL) - extents = &pattern->extents; - - return pattern->acquire (&pattern->base, pattern->user_data, - target, extents); -} - -void -_cairo_raster_source_pattern_release (const cairo_pattern_t *abstract_pattern, - cairo_surface_t *surface) -{ - cairo_raster_source_pattern_t *pattern = - (cairo_raster_source_pattern_t *) abstract_pattern; - - if (pattern->release == NULL) - return; - - pattern->release (&pattern->base, pattern->user_data, surface); -} - -cairo_status_t -_cairo_raster_source_pattern_init_copy (cairo_pattern_t *abstract_pattern, - const cairo_pattern_t *other) -{ - cairo_raster_source_pattern_t *pattern = - (cairo_raster_source_pattern_t *) abstract_pattern; - cairo_status_t status; - - VG (VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_raster_source_pattern_t))); - memcpy(pattern, other, sizeof (cairo_raster_source_pattern_t)); - - status = CAIRO_STATUS_SUCCESS; - if (pattern->copy) - status = pattern->copy (&pattern->base, pattern->user_data, other); - - return status; -} - -cairo_status_t -_cairo_raster_source_pattern_snapshot (cairo_pattern_t *abstract_pattern) -{ - cairo_raster_source_pattern_t *pattern = - (cairo_raster_source_pattern_t *) abstract_pattern; - - if (pattern->snapshot == NULL) - return CAIRO_STATUS_SUCCESS; - - return pattern->snapshot (&pattern->base, pattern->user_data); -} - -void -_cairo_raster_source_pattern_finish (cairo_pattern_t *abstract_pattern) -{ - cairo_raster_source_pattern_t *pattern = - (cairo_raster_source_pattern_t *) abstract_pattern; - - if (pattern->finish == NULL) - return; - - pattern->finish (&pattern->base, pattern->user_data); -} - -/* Public interface */ - -/** - * cairo_pattern_create_raster_source: - * @user_data: the user data to be passed to all callbacks - * @content: content type for the pixel data that will be returned. Knowing - * the content type ahead of time is used for analysing the operation and - * picking the appropriate rendering path. - * @width: maximum size of the sample area - * @height: maximum size of the sample area - * - * Creates a new user pattern for providing pixel data. - * - * Use the setter functions to associate callbacks with the returned - * pattern. The only mandatory callback is acquire. - * - * Return value: a newly created #cairo_pattern_t. Free with - * cairo_pattern_destroy() when you are done using it. - * - * Since: 1.12 - **/ -cairo_pattern_t * -cairo_pattern_create_raster_source (void *user_data, - cairo_content_t content, - int width, int height) -{ - cairo_raster_source_pattern_t *pattern; - - CAIRO_MUTEX_INITIALIZE (); - - if (width < 0 || height < 0) - return _cairo_pattern_create_in_error (CAIRO_STATUS_INVALID_SIZE); - - if (! CAIRO_CONTENT_VALID (content)) - return _cairo_pattern_create_in_error (CAIRO_STATUS_INVALID_CONTENT); - - pattern = calloc (1, sizeof (*pattern)); - if (unlikely (pattern == NULL)) - return _cairo_pattern_create_in_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_pattern_init (&pattern->base, - CAIRO_PATTERN_TYPE_RASTER_SOURCE); - CAIRO_REFERENCE_COUNT_INIT (&pattern->base.ref_count, 1); - - pattern->content = content; - - pattern->extents.x = 0; - pattern->extents.y = 0; - pattern->extents.width = width; - pattern->extents.height = height; - - pattern->user_data = user_data; - - return &pattern->base; -} - -/** - * cairo_raster_source_pattern_set_callback_data: - * @pattern: the pattern to update - * @data: the user data to be passed to all callbacks - * - * Updates the user data that is provided to all callbacks. - * - * Since: 1.12 - **/ -void -cairo_raster_source_pattern_set_callback_data (cairo_pattern_t *abstract_pattern, - void *data) -{ - cairo_raster_source_pattern_t *pattern; - - if (abstract_pattern->type != CAIRO_PATTERN_TYPE_RASTER_SOURCE) - return; - - pattern = (cairo_raster_source_pattern_t *) abstract_pattern; - pattern->user_data = data; -} - -/** - * cairo_raster_source_pattern_get_callback_data: - * @pattern: the pattern to update - * - * Queries the current user data. - * - * Return value: the current user-data passed to each callback - * - * Since: 1.12 - **/ -void * -cairo_raster_source_pattern_get_callback_data (cairo_pattern_t *abstract_pattern) -{ - cairo_raster_source_pattern_t *pattern; - - if (abstract_pattern->type != CAIRO_PATTERN_TYPE_RASTER_SOURCE) - return NULL; - - pattern = (cairo_raster_source_pattern_t *) abstract_pattern; - return pattern->user_data; -} - -/** - * cairo_raster_source_pattern_set_acquire: - * @pattern: the pattern to update - * @acquire: acquire callback - * @release: release callback - * - * Specifies the callbacks used to generate the image surface for a rendering - * operation (acquire) and the function used to cleanup that surface afterwards. - * - * The @acquire callback should create a surface (preferably an image - * surface created to match the target using - * cairo_surface_create_similar_image()) that defines at least the region - * of interest specified by extents. The surface is allowed to be the entire - * sample area, but if it does contain a subsection of the sample area, - * the surface extents should be provided by setting the device offset (along - * with its width and height) using cairo_surface_set_device_offset(). - * - * Since: 1.12 - **/ -void -cairo_raster_source_pattern_set_acquire (cairo_pattern_t *abstract_pattern, - cairo_raster_source_acquire_func_t acquire, - cairo_raster_source_release_func_t release) -{ - cairo_raster_source_pattern_t *pattern; - - if (abstract_pattern->type != CAIRO_PATTERN_TYPE_RASTER_SOURCE) - return; - - pattern = (cairo_raster_source_pattern_t *) abstract_pattern; - pattern->acquire = acquire; - pattern->release = release; -} - -/** - * cairo_raster_source_pattern_get_acquire: - * @pattern: the pattern to query - * @acquire: return value for the current acquire callback - * @release: return value for the current release callback - * - * Queries the current acquire and release callbacks. - * - * Since: 1.12 - **/ -void -cairo_raster_source_pattern_get_acquire (cairo_pattern_t *abstract_pattern, - cairo_raster_source_acquire_func_t *acquire, - cairo_raster_source_release_func_t *release) -{ - cairo_raster_source_pattern_t *pattern; - - if (abstract_pattern->type != CAIRO_PATTERN_TYPE_RASTER_SOURCE) - return; - - pattern = (cairo_raster_source_pattern_t *) abstract_pattern; - if (acquire) - *acquire = pattern->acquire; - if (release) - *release = pattern->release; -} - -/** - * cairo_raster_source_pattern_set_snapshot: - * @pattern: the pattern to update - * @snapshot: snapshot callback - * - * Sets the callback that will be used whenever a snapshot is taken of the - * pattern, that is whenever the current contents of the pattern should be - * preserved for later use. This is typically invoked whilst printing. - * - * Since: 1.12 - **/ -void -cairo_raster_source_pattern_set_snapshot (cairo_pattern_t *abstract_pattern, - cairo_raster_source_snapshot_func_t snapshot) -{ - cairo_raster_source_pattern_t *pattern; - - if (abstract_pattern->type != CAIRO_PATTERN_TYPE_RASTER_SOURCE) - return; - - pattern = (cairo_raster_source_pattern_t *) abstract_pattern; - pattern->snapshot = snapshot; -} - -/** - * cairo_raster_source_pattern_get_snapshot: - * @pattern: the pattern to query - * - * Queries the current snapshot callback. - * - * Return value: the current snapshot callback - * - * Since: 1.12 - **/ -cairo_raster_source_snapshot_func_t -cairo_raster_source_pattern_get_snapshot (cairo_pattern_t *abstract_pattern) -{ - cairo_raster_source_pattern_t *pattern; - - if (abstract_pattern->type != CAIRO_PATTERN_TYPE_RASTER_SOURCE) - return NULL; - - pattern = (cairo_raster_source_pattern_t *) abstract_pattern; - return pattern->snapshot; -} - -/** - * cairo_raster_source_pattern_set_copy: - * @pattern: the pattern to update - * @copy: the copy callback - * - * Updates the copy callback which is used whenever a temporary copy of the - * pattern is taken. - * - * Since: 1.12 - **/ -void -cairo_raster_source_pattern_set_copy (cairo_pattern_t *abstract_pattern, - cairo_raster_source_copy_func_t copy) -{ - cairo_raster_source_pattern_t *pattern; - - if (abstract_pattern->type != CAIRO_PATTERN_TYPE_RASTER_SOURCE) - return; - - pattern = (cairo_raster_source_pattern_t *) abstract_pattern; - pattern->copy = copy; -} - -/** - * cairo_raster_source_pattern_get_copy: - * @pattern: the pattern to query - * - * Queries the current copy callback. - * - * Return value: the current copy callback - * - * Since: 1.12 - **/ -cairo_raster_source_copy_func_t -cairo_raster_source_pattern_get_copy (cairo_pattern_t *abstract_pattern) -{ - cairo_raster_source_pattern_t *pattern; - - if (abstract_pattern->type != CAIRO_PATTERN_TYPE_RASTER_SOURCE) - return NULL; - - pattern = (cairo_raster_source_pattern_t *) abstract_pattern; - return pattern->copy; -} - -/** - * cairo_raster_source_pattern_set_finish: - * @pattern: the pattern to update - * @finish: the finish callback - * - * Updates the finish callback which is used whenever a pattern (or a copy - * thereof) will no longer be used. - * - * Since: 1.12 - **/ -void -cairo_raster_source_pattern_set_finish (cairo_pattern_t *abstract_pattern, - cairo_raster_source_finish_func_t finish) -{ - cairo_raster_source_pattern_t *pattern; - - if (abstract_pattern->type != CAIRO_PATTERN_TYPE_RASTER_SOURCE) - return; - - pattern = (cairo_raster_source_pattern_t *) abstract_pattern; - pattern->finish = finish; -} - -/** - * cairo_raster_source_pattern_get_finish: - * @pattern: the pattern to query - * - * Queries the current finish callback. - * - * Return value: the current finish callback - * - * Since: 1.12 - **/ -cairo_raster_source_finish_func_t -cairo_raster_source_pattern_get_finish (cairo_pattern_t *abstract_pattern) -{ - cairo_raster_source_pattern_t *pattern; - - if (abstract_pattern->type != CAIRO_PATTERN_TYPE_RASTER_SOURCE) - return NULL; - - pattern = (cairo_raster_source_pattern_t *) abstract_pattern; - return pattern->finish; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-recording-surface-inline.h b/source/libs/cairo/cairo-src/src/cairo-recording-surface-inline.h deleted file mode 100644 index 9002ccd69381b7b080c61876bbaf7c7df4cd31a5..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-recording-surface-inline.h +++ /dev/null @@ -1,68 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Kristian Høgsberg <krh@redhat.com> - * Adrian Johnson <ajohnson@redneon.com> - */ - -#ifndef CAIRO_RECORDING_SURFACE_INLINE_H -#define CAIRO_RECORDING_SURFACE_INLINE_H - -#include "cairo-recording-surface-private.h" - -static inline cairo_bool_t -_cairo_recording_surface_get_bounds (cairo_surface_t *surface, - cairo_rectangle_t *extents) -{ - cairo_recording_surface_t *recording = (cairo_recording_surface_t *)surface; - if (recording->unbounded) - return FALSE; - - *extents = recording->extents_pixels; - return TRUE; -} - -/** - * _cairo_surface_is_recording: - * @surface: a #cairo_surface_t - * - * Checks if a surface is a #cairo_recording_surface_t - * - * Return value: %TRUE if the surface is a recording surface - **/ -static inline cairo_bool_t -_cairo_surface_is_recording (const cairo_surface_t *surface) -{ - return surface->backend->type == CAIRO_SURFACE_TYPE_RECORDING; -} - -#endif /* CAIRO_RECORDING_SURFACE_INLINE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-recording-surface-private.h b/source/libs/cairo/cairo-src/src/cairo-recording-surface-private.h deleted file mode 100644 index 456c63389b72816fd6a0f4838f80c22f626df728..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-recording-surface-private.h +++ /dev/null @@ -1,195 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Kristian Høgsberg <krh@redhat.com> - * Adrian Johnson <ajohnson@redneon.com> - */ - -#ifndef CAIRO_RECORDING_SURFACE_H -#define CAIRO_RECORDING_SURFACE_H - -#include "cairoint.h" -#include "cairo-path-fixed-private.h" -#include "cairo-pattern-private.h" -#include "cairo-surface-backend-private.h" - -typedef enum { - /* The 5 basic drawing operations. */ - CAIRO_COMMAND_PAINT, - CAIRO_COMMAND_MASK, - CAIRO_COMMAND_STROKE, - CAIRO_COMMAND_FILL, - CAIRO_COMMAND_SHOW_TEXT_GLYPHS, -} cairo_command_type_t; - -typedef enum { - CAIRO_RECORDING_REGION_ALL, - CAIRO_RECORDING_REGION_NATIVE, - CAIRO_RECORDING_REGION_IMAGE_FALLBACK -} cairo_recording_region_type_t; - -typedef struct _cairo_command_header { - cairo_command_type_t type; - cairo_recording_region_type_t region; - cairo_operator_t op; - cairo_rectangle_int_t extents; - cairo_clip_t *clip; - - int index; - struct _cairo_command_header *chain; -} cairo_command_header_t; - -typedef struct _cairo_command_paint { - cairo_command_header_t header; - cairo_pattern_union_t source; -} cairo_command_paint_t; - -typedef struct _cairo_command_mask { - cairo_command_header_t header; - cairo_pattern_union_t source; - cairo_pattern_union_t mask; -} cairo_command_mask_t; - -typedef struct _cairo_command_stroke { - cairo_command_header_t header; - cairo_pattern_union_t source; - cairo_path_fixed_t path; - cairo_stroke_style_t style; - cairo_matrix_t ctm; - cairo_matrix_t ctm_inverse; - double tolerance; - cairo_antialias_t antialias; -} cairo_command_stroke_t; - -typedef struct _cairo_command_fill { - cairo_command_header_t header; - cairo_pattern_union_t source; - cairo_path_fixed_t path; - cairo_fill_rule_t fill_rule; - double tolerance; - cairo_antialias_t antialias; -} cairo_command_fill_t; - -typedef struct _cairo_command_show_text_glyphs { - cairo_command_header_t header; - cairo_pattern_union_t source; - char *utf8; - int utf8_len; - cairo_glyph_t *glyphs; - unsigned int num_glyphs; - cairo_text_cluster_t *clusters; - int num_clusters; - cairo_text_cluster_flags_t cluster_flags; - cairo_scaled_font_t *scaled_font; -} cairo_command_show_text_glyphs_t; - -typedef union _cairo_command { - cairo_command_header_t header; - - cairo_command_paint_t paint; - cairo_command_mask_t mask; - cairo_command_stroke_t stroke; - cairo_command_fill_t fill; - cairo_command_show_text_glyphs_t show_text_glyphs; -} cairo_command_t; - -typedef struct _cairo_recording_surface { - cairo_surface_t base; - - /* A recording-surface is logically unbounded, but when used as a - * source we need to render it to an image, so we need a size at - * which to create that image. */ - cairo_rectangle_t extents_pixels; - cairo_rectangle_int_t extents; - cairo_bool_t unbounded; - - cairo_array_t commands; - unsigned int *indices; - unsigned int num_indices; - cairo_bool_t optimize_clears; - cairo_bool_t has_bilevel_alpha; - cairo_bool_t has_only_op_over; - - struct bbtree { - cairo_box_t extents; - struct bbtree *left, *right; - cairo_command_header_t *chain; - } bbtree; -} cairo_recording_surface_t; - -slim_hidden_proto (cairo_recording_surface_create); - -cairo_private cairo_int_status_t -_cairo_recording_surface_get_path (cairo_surface_t *surface, - cairo_path_fixed_t *path); - -cairo_private cairo_status_t -_cairo_recording_surface_replay_one (cairo_recording_surface_t *surface, - long unsigned index, - cairo_surface_t *target); - -cairo_private cairo_status_t -_cairo_recording_surface_replay (cairo_surface_t *surface, - cairo_surface_t *target); - -cairo_private cairo_status_t -_cairo_recording_surface_replay_with_clip (cairo_surface_t *surface, - const cairo_matrix_t *surface_transform, - cairo_surface_t *target, - const cairo_clip_t *target_clip); - -cairo_private cairo_status_t -_cairo_recording_surface_replay_and_create_regions (cairo_surface_t *surface, - cairo_surface_t *target); -cairo_private cairo_status_t -_cairo_recording_surface_replay_region (cairo_surface_t *surface, - const cairo_rectangle_int_t *surface_extents, - cairo_surface_t *target, - cairo_recording_region_type_t region); - -cairo_private cairo_status_t -_cairo_recording_surface_get_bbox (cairo_recording_surface_t *recording, - cairo_box_t *bbox, - const cairo_matrix_t *transform); - -cairo_private cairo_status_t -_cairo_recording_surface_get_ink_bbox (cairo_recording_surface_t *surface, - cairo_box_t *bbox, - const cairo_matrix_t *transform); - -cairo_private cairo_bool_t -_cairo_recording_surface_has_only_bilevel_alpha (cairo_recording_surface_t *surface); - -cairo_private cairo_bool_t -_cairo_recording_surface_has_only_op_over (cairo_recording_surface_t *surface); - -#endif /* CAIRO_RECORDING_SURFACE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-recording-surface.c b/source/libs/cairo/cairo-src/src/cairo-recording-surface.c deleted file mode 100644 index 78e7cfa7efc62bbc7c22ba0e1797a7970f1fd28e..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-recording-surface.c +++ /dev/null @@ -1,2188 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2005 Red Hat, Inc - * Copyright © 2007 Adrian Johnson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Kristian Høgsberg <krh@redhat.com> - * Carl Worth <cworth@cworth.org> - * Adrian Johnson <ajohnson@redneon.com> - */ - -/** - * SECTION:cairo-recording - * @Title: Recording Surfaces - * @Short_Description: Records all drawing operations - * @See_Also: #cairo_surface_t - * - * A recording surface is a surface that records all drawing operations at - * the highest level of the surface backend interface, (that is, the - * level of paint, mask, stroke, fill, and show_text_glyphs). The recording - * surface can then be "replayed" against any target surface by using it - * as a source surface. - * - * If you want to replay a surface so that the results in target will be - * identical to the results that would have been obtained if the original - * operations applied to the recording surface had instead been applied to the - * target surface, you can use code like this: - * <informalexample><programlisting> - * cairo_t *cr; - * - * cr = cairo_create (target); - * cairo_set_source_surface (cr, recording_surface, 0.0, 0.0); - * cairo_paint (cr); - * cairo_destroy (cr); - * </programlisting></informalexample> - * - * A recording surface is logically unbounded, i.e. it has no implicit constraint - * on the size of the drawing surface. However, in practice this is rarely - * useful as you wish to replay against a particular target surface with - * known bounds. For this case, it is more efficient to specify the target - * extents to the recording surface upon creation. - * - * The recording phase of the recording surface is careful to snapshot all - * necessary objects (paths, patterns, etc.), in order to achieve - * accurate replay. The efficiency of the recording surface could be - * improved by improving the implementation of snapshot for the - * various objects. For example, it would be nice to have a - * copy-on-write implementation for _cairo_surface_snapshot. - **/ - -#include "cairoint.h" - -#include "cairo-array-private.h" -#include "cairo-analysis-surface-private.h" -#include "cairo-clip-private.h" -#include "cairo-combsort-inline.h" -#include "cairo-composite-rectangles-private.h" -#include "cairo-default-context-private.h" -#include "cairo-error-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-recording-surface-inline.h" -#include "cairo-surface-snapshot-inline.h" -#include "cairo-surface-wrapper-private.h" -#include "cairo-traps-private.h" - -typedef enum { - CAIRO_RECORDING_REPLAY, - CAIRO_RECORDING_CREATE_REGIONS -} cairo_recording_replay_type_t; - -static const cairo_surface_backend_t cairo_recording_surface_backend; - -/** - * CAIRO_HAS_RECORDING_SURFACE: - * - * Defined if the recording surface backend is available. - * The recording surface backend is always built in. - * This macro was added for completeness in cairo 1.10. - * - * Since: 1.10 - **/ - -/* Currently all recording surfaces do have a size which should be passed - * in as the maximum size of any target surface against which the - * recording-surface will ever be replayed. - * - * XXX: The naming of "pixels" in the size here is a misnomer. It's - * actually a size in whatever device-space units are desired (again, - * according to the intended replay target). - */ - -static int bbtree_left_or_right (struct bbtree *bbt, - const cairo_box_t *box) -{ - int left, right; - - if (bbt->left) { - cairo_box_t *e = &bbt->left->extents; - cairo_box_t b; - - b.p1.x = MIN (e->p1.x, box->p1.x); - b.p1.y = MIN (e->p1.y, box->p1.y); - b.p2.x = MAX (e->p2.x, box->p2.x); - b.p2.y = MAX (e->p2.y, box->p2.y); - - left = _cairo_fixed_integer_part (b.p2.x - b.p1.x) * _cairo_fixed_integer_part (b.p2.y - b.p1.y); - left -= _cairo_fixed_integer_part (e->p2.x - e->p1.x) * _cairo_fixed_integer_part (e->p2.y - e->p1.y); - } else - left = 0; - - if (bbt->right) { - cairo_box_t *e = &bbt->right->extents; - cairo_box_t b; - - b.p1.x = MIN (e->p1.x, box->p1.x); - b.p1.y = MIN (e->p1.y, box->p1.y); - b.p2.x = MAX (e->p2.x, box->p2.x); - b.p2.y = MAX (e->p2.y, box->p2.y); - - right = _cairo_fixed_integer_part (b.p2.x - b.p1.x) * _cairo_fixed_integer_part (b.p2.y - b.p1.y); - right -= _cairo_fixed_integer_part (e->p2.x - e->p1.x) * _cairo_fixed_integer_part (e->p2.y - e->p1.y); - } else - right = 0; - - return left <= right; -} - -#define INVALID_CHAIN ((cairo_command_header_t *)-1) - -static struct bbtree * -bbtree_new (const cairo_box_t *box, cairo_command_header_t *chain) -{ - struct bbtree *bbt = malloc (sizeof (*bbt)); - if (bbt == NULL) - return NULL; - bbt->extents = *box; - bbt->left = bbt->right = NULL; - bbt->chain = chain; - return bbt; -} - -static void -bbtree_init (struct bbtree *bbt, cairo_command_header_t *header) -{ - _cairo_box_from_rectangle (&bbt->extents, &header->extents); - bbt->chain = header; -} - -static cairo_status_t -bbtree_add (struct bbtree *bbt, - cairo_command_header_t *header, - const cairo_box_t *box) -{ - if (box->p1.x < bbt->extents.p1.x || box->p1.y < bbt->extents.p1.y || - box->p2.x > bbt->extents.p2.x || box->p2.y > bbt->extents.p2.y) - { - if (bbt->chain) { - if (bbtree_left_or_right (bbt, &bbt->extents)) { - if (bbt->left == NULL) { - bbt->left = bbtree_new (&bbt->extents, bbt->chain); - if (unlikely (bbt->left == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } else - bbtree_add (bbt->left, bbt->chain, &bbt->extents); - } else { - if (bbt->right == NULL) { - bbt->right = bbtree_new (&bbt->extents, bbt->chain); - if (unlikely (bbt->right == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } else - bbtree_add (bbt->right, bbt->chain, &bbt->extents); - } - - bbt->chain = NULL; - } - - bbt->extents.p1.x = MIN (bbt->extents.p1.x, box->p1.x); - bbt->extents.p1.y = MIN (bbt->extents.p1.y, box->p1.y); - bbt->extents.p2.x = MAX (bbt->extents.p2.x, box->p2.x); - bbt->extents.p2.y = MAX (bbt->extents.p2.y, box->p2.y); - } - - if (box->p1.x == bbt->extents.p1.x && box->p1.y == bbt->extents.p1.y && - box->p2.x == bbt->extents.p2.x && box->p2.y == bbt->extents.p2.y) - { - cairo_command_header_t *last = header; - while (last->chain) /* expected to be infrequent */ - last = last->chain; - last->chain = bbt->chain; - bbt->chain = header; - return CAIRO_STATUS_SUCCESS; - } - - if (bbtree_left_or_right (bbt, box)) { - if (bbt->left == NULL) { - bbt->left = bbtree_new (box, header); - if (unlikely (bbt->left == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } else - return bbtree_add (bbt->left, header, box); - } else { - if (bbt->right == NULL) { - bbt->right = bbtree_new (box, header); - if (unlikely (bbt->right == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } else - return bbtree_add (bbt->right, header, box); - } - - return CAIRO_STATUS_SUCCESS; -} - -static void bbtree_del (struct bbtree *bbt) -{ - if (bbt->left) - bbtree_del (bbt->left); - if (bbt->right) - bbtree_del (bbt->right); - - free (bbt); -} - -static cairo_bool_t box_outside (const cairo_box_t *a, const cairo_box_t *b) -{ - return - a->p1.x >= b->p2.x || a->p1.y >= b->p2.y || - a->p2.x <= b->p1.x || a->p2.y <= b->p1.y; -} - -static void -bbtree_foreach_mark_visible (struct bbtree *bbt, - const cairo_box_t *box, - unsigned int **indices) -{ - cairo_command_header_t *chain; - - for (chain = bbt->chain; chain; chain = chain->chain) - *(*indices)++ = chain->index; - - if (bbt->left && ! box_outside (box, &bbt->left->extents)) - bbtree_foreach_mark_visible (bbt->left, box, indices); - if (bbt->right && ! box_outside (box, &bbt->right->extents)) - bbtree_foreach_mark_visible (bbt->right, box, indices); -} - -static inline int intcmp (const unsigned int a, const unsigned int b) -{ - return a - b; -} -CAIRO_COMBSORT_DECLARE (sort_indices, unsigned int, intcmp) - -static inline int sizecmp (unsigned int a, unsigned int b, cairo_command_header_t **elements) -{ - const cairo_rectangle_int_t *r; - - r = &elements[a]->extents; - a = r->width * r->height; - - r = &elements[b]->extents; - b = r->width * r->height; - - return b - a; -} -CAIRO_COMBSORT_DECLARE_WITH_DATA (sort_commands, unsigned int, sizecmp) - -static void -_cairo_recording_surface_destroy_bbtree (cairo_recording_surface_t *surface) -{ - cairo_command_t **elements; - int i, num_elements; - - if (surface->bbtree.chain == INVALID_CHAIN) - return; - - if (surface->bbtree.left) { - bbtree_del (surface->bbtree.left); - surface->bbtree.left = NULL; - } - if (surface->bbtree.right) { - bbtree_del (surface->bbtree.right); - surface->bbtree.right = NULL; - } - - elements = _cairo_array_index (&surface->commands, 0); - num_elements = surface->commands.num_elements; - for (i = 0; i < num_elements; i++) - elements[i]->header.chain = NULL; - - surface->bbtree.chain = INVALID_CHAIN; -} - -static cairo_status_t -_cairo_recording_surface_create_bbtree (cairo_recording_surface_t *surface) -{ - cairo_command_t **elements = _cairo_array_index (&surface->commands, 0); - unsigned int *indices; - cairo_status_t status; - unsigned int i, count; - - count = surface->commands.num_elements; - if (count > surface->num_indices) { - free (surface->indices); - surface->indices = _cairo_malloc_ab (count, sizeof (int)); - if (unlikely (surface->indices == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - surface->num_indices = count; - } - - indices = surface->indices; - for (i = 0; i < count; i++) - indices[i] = i; - - sort_commands (indices, count, elements); - - bbtree_init (&surface->bbtree, &elements[indices[0]]->header); - for (i = 1; i < count; i++) { - cairo_command_header_t *header = &elements[indices[i]]->header; - cairo_box_t box; - - _cairo_box_from_rectangle (&box, &header->extents); - status = bbtree_add (&surface->bbtree, header, &box); - if (unlikely (status)) - goto cleanup; - } - - return CAIRO_STATUS_SUCCESS; - -cleanup: - bbtree_del (&surface->bbtree); - return status; -} - -/** - * cairo_recording_surface_create: - * @content: the content of the recording surface - * @extents: the extents to record in pixels, can be %NULL to record - * unbounded operations. - * - * Creates a recording-surface which can be used to record all drawing operations - * at the highest level (that is, the level of paint, mask, stroke, fill - * and show_text_glyphs). The recording surface can then be "replayed" against - * any target surface by using it as a source to drawing operations. - * - * The recording phase of the recording surface is careful to snapshot all - * necessary objects (paths, patterns, etc.), in order to achieve - * accurate replay. - * - * Return value: a pointer to the newly created surface. The caller - * owns the surface and should call cairo_surface_destroy() when done - * with it. - * - * Since: 1.10 - **/ -cairo_surface_t * -cairo_recording_surface_create (cairo_content_t content, - const cairo_rectangle_t *extents) -{ - cairo_recording_surface_t *surface; - - surface = malloc (sizeof (cairo_recording_surface_t)); - if (unlikely (surface == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - _cairo_surface_init (&surface->base, - &cairo_recording_surface_backend, - NULL, /* device */ - content); - - - surface->unbounded = TRUE; - - /* unbounded -> 'infinite' extents */ - if (extents != NULL) { - surface->extents_pixels = *extents; - - /* XXX check for overflow */ - surface->extents.x = floor (extents->x); - surface->extents.y = floor (extents->y); - surface->extents.width = ceil (extents->x + extents->width) - surface->extents.x; - surface->extents.height = ceil (extents->y + extents->height) - surface->extents.y; - - surface->unbounded = FALSE; - } - - _cairo_array_init (&surface->commands, sizeof (cairo_command_t *)); - - surface->base.is_clear = TRUE; - - surface->bbtree.left = surface->bbtree.right = NULL; - surface->bbtree.chain = INVALID_CHAIN; - - surface->indices = NULL; - surface->num_indices = 0; - surface->optimize_clears = TRUE; - surface->has_bilevel_alpha = FALSE; - surface->has_only_op_over = FALSE; - - return &surface->base; -} -slim_hidden_def (cairo_recording_surface_create); - -static cairo_surface_t * -_cairo_recording_surface_create_similar (void *abstract_surface, - cairo_content_t content, - int width, - int height) -{ - cairo_rectangle_t extents; - extents.x = extents.y = 0; - extents.width = width; - extents.height = height; - return cairo_recording_surface_create (content, &extents); -} - -static cairo_status_t -_cairo_recording_surface_finish (void *abstract_surface) -{ - cairo_recording_surface_t *surface = abstract_surface; - cairo_command_t **elements; - int i, num_elements; - - num_elements = surface->commands.num_elements; - elements = _cairo_array_index (&surface->commands, 0); - for (i = 0; i < num_elements; i++) { - cairo_command_t *command = elements[i]; - - switch (command->header.type) { - case CAIRO_COMMAND_PAINT: - _cairo_pattern_fini (&command->paint.source.base); - break; - - case CAIRO_COMMAND_MASK: - _cairo_pattern_fini (&command->mask.source.base); - _cairo_pattern_fini (&command->mask.mask.base); - break; - - case CAIRO_COMMAND_STROKE: - _cairo_pattern_fini (&command->stroke.source.base); - _cairo_path_fixed_fini (&command->stroke.path); - _cairo_stroke_style_fini (&command->stroke.style); - break; - - case CAIRO_COMMAND_FILL: - _cairo_pattern_fini (&command->fill.source.base); - _cairo_path_fixed_fini (&command->fill.path); - break; - - case CAIRO_COMMAND_SHOW_TEXT_GLYPHS: - _cairo_pattern_fini (&command->show_text_glyphs.source.base); - free (command->show_text_glyphs.utf8); - free (command->show_text_glyphs.glyphs); - free (command->show_text_glyphs.clusters); - cairo_scaled_font_destroy (command->show_text_glyphs.scaled_font); - break; - - default: - ASSERT_NOT_REACHED; - } - - _cairo_clip_destroy (command->header.clip); - free (command); - } - - _cairo_array_fini (&surface->commands); - - if (surface->bbtree.left) - bbtree_del (surface->bbtree.left); - if (surface->bbtree.right) - bbtree_del (surface->bbtree.right); - - free (surface->indices); - - return CAIRO_STATUS_SUCCESS; -} - -struct proxy { - cairo_surface_t base; - cairo_surface_t *image; -}; - -static cairo_status_t -proxy_acquire_source_image (void *abstract_surface, - cairo_image_surface_t **image_out, - void **image_extra) -{ - struct proxy *proxy = abstract_surface; - return _cairo_surface_acquire_source_image (proxy->image, image_out, image_extra); -} - -static void -proxy_release_source_image (void *abstract_surface, - cairo_image_surface_t *image, - void *image_extra) -{ - struct proxy *proxy = abstract_surface; - _cairo_surface_release_source_image (proxy->image, image, image_extra); -} - -static cairo_status_t -proxy_finish (void *abstract_surface) -{ - return CAIRO_STATUS_SUCCESS; -} - -static const cairo_surface_backend_t proxy_backend = { - CAIRO_INTERNAL_SURFACE_TYPE_NULL, - proxy_finish, - NULL, - - NULL, /* create similar */ - NULL, /* create similar image */ - NULL, /* map to image */ - NULL, /* unmap image */ - - _cairo_surface_default_source, - proxy_acquire_source_image, - proxy_release_source_image, -}; - -static cairo_surface_t * -attach_proxy (cairo_surface_t *source, - cairo_surface_t *image) -{ - struct proxy *proxy; - - proxy = malloc (sizeof (*proxy)); - if (unlikely (proxy == NULL)) - return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_surface_init (&proxy->base, &proxy_backend, NULL, image->content); - - proxy->image = image; - _cairo_surface_attach_snapshot (source, &proxy->base, NULL); - - return &proxy->base; -} - -static void -detach_proxy (cairo_surface_t *source, - cairo_surface_t *proxy) -{ - cairo_surface_finish (proxy); - cairo_surface_destroy (proxy); -} - -static cairo_surface_t * -get_proxy (cairo_surface_t *proxy) -{ - return ((struct proxy *)proxy)->image; -} - -static cairo_status_t -_cairo_recording_surface_acquire_source_image (void *abstract_surface, - cairo_image_surface_t **image_out, - void **image_extra) -{ - cairo_recording_surface_t *surface = abstract_surface; - cairo_surface_t *image, *proxy; - cairo_status_t status; - - proxy = _cairo_surface_has_snapshot (abstract_surface, &proxy_backend); - if (proxy != NULL) { - *image_out = (cairo_image_surface_t *) - cairo_surface_reference (get_proxy (proxy)); - *image_extra = NULL; - return CAIRO_STATUS_SUCCESS; - } - - assert (! surface->unbounded); - image = _cairo_image_surface_create_with_content (surface->base.content, - surface->extents.width, - surface->extents.height); - if (unlikely (image->status)) - return image->status; - - /* Handle recursion by returning future reads from the current image */ - proxy = attach_proxy (abstract_surface, image); - status = _cairo_recording_surface_replay (&surface->base, image); - detach_proxy (abstract_surface, proxy); - - if (unlikely (status)) { - cairo_surface_destroy (image); - return status; - } - - *image_out = (cairo_image_surface_t *) image; - *image_extra = NULL; - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_recording_surface_release_source_image (void *abstract_surface, - cairo_image_surface_t *image, - void *image_extra) -{ - cairo_surface_destroy (&image->base); -} - -static cairo_status_t -_command_init (cairo_recording_surface_t *surface, - cairo_command_header_t *command, - cairo_command_type_t type, - cairo_operator_t op, - cairo_composite_rectangles_t *composite) -{ - cairo_status_t status = CAIRO_STATUS_SUCCESS; - - command->type = type; - command->op = op; - command->region = CAIRO_RECORDING_REGION_ALL; - - command->extents = composite->unbounded; - command->chain = NULL; - command->index = surface->commands.num_elements; - - /* steal the clip */ - command->clip = NULL; - if (! _cairo_composite_rectangles_can_reduce_clip (composite, - composite->clip)) - { - command->clip = composite->clip; - composite->clip = NULL; - } - - return status; -} - -static void -_cairo_recording_surface_break_self_copy_loop (cairo_recording_surface_t *surface) -{ - cairo_surface_flush (&surface->base); -} - -static cairo_status_t -_cairo_recording_surface_commit (cairo_recording_surface_t *surface, - cairo_command_header_t *command) -{ - _cairo_recording_surface_break_self_copy_loop (surface); - return _cairo_array_append (&surface->commands, &command); -} - -static void -_cairo_recording_surface_reset (cairo_recording_surface_t *surface) -{ - /* Reset the commands and temporaries */ - _cairo_recording_surface_finish (surface); - - surface->bbtree.left = surface->bbtree.right = NULL; - surface->bbtree.chain = INVALID_CHAIN; - - surface->indices = NULL; - surface->num_indices = 0; - - _cairo_array_init (&surface->commands, sizeof (cairo_command_t *)); -} - -static cairo_bool_t -is_identity_recording_pattern (const cairo_pattern_t *pattern) -{ - cairo_surface_t *surface; - - if (pattern->type != CAIRO_PATTERN_TYPE_SURFACE) - return FALSE; - - if (!_cairo_matrix_is_identity(&pattern->matrix)) - return FALSE; - - surface = ((cairo_surface_pattern_t *)pattern)->surface; - return surface->backend->type == CAIRO_SURFACE_TYPE_RECORDING; -} - -static cairo_int_status_t -_cairo_recording_surface_paint (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - cairo_status_t status; - cairo_recording_surface_t *surface = abstract_surface; - cairo_command_paint_t *command; - cairo_composite_rectangles_t composite; - - TRACE ((stderr, "%s: surface=%d\n", __FUNCTION__, surface->base.unique_id)); - - if (op == CAIRO_OPERATOR_CLEAR && clip == NULL) { - if (surface->optimize_clears) { - _cairo_recording_surface_reset (surface); - return CAIRO_STATUS_SUCCESS; - } - } - - if (clip == NULL && surface->optimize_clears && - (op == CAIRO_OPERATOR_SOURCE || - (op == CAIRO_OPERATOR_OVER && - (surface->base.is_clear || _cairo_pattern_is_opaque_solid (source))))) - { - _cairo_recording_surface_reset (surface); - if (is_identity_recording_pattern (source)) { - cairo_surface_t *src = ((cairo_surface_pattern_t *)source)->surface; - return _cairo_recording_surface_replay (src, &surface->base); - } - } - - status = _cairo_composite_rectangles_init_for_paint (&composite, - &surface->base, - op, source, - clip); - if (unlikely (status)) - return status; - - command = malloc (sizeof (cairo_command_paint_t)); - if (unlikely (command == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto CLEANUP_COMPOSITE; - } - - status = _command_init (surface, - &command->header, CAIRO_COMMAND_PAINT, op, - &composite); - if (unlikely (status)) - goto CLEANUP_COMMAND; - - status = _cairo_pattern_init_snapshot (&command->source.base, source); - if (unlikely (status)) - goto CLEANUP_COMMAND; - - status = _cairo_recording_surface_commit (surface, &command->header); - if (unlikely (status)) - goto CLEANUP_SOURCE; - - _cairo_recording_surface_destroy_bbtree (surface); - - _cairo_composite_rectangles_fini (&composite); - return CAIRO_STATUS_SUCCESS; - - CLEANUP_SOURCE: - _cairo_pattern_fini (&command->source.base); - CLEANUP_COMMAND: - _cairo_clip_destroy (command->header.clip); - free (command); -CLEANUP_COMPOSITE: - _cairo_composite_rectangles_fini (&composite); - return status; -} - -static cairo_int_status_t -_cairo_recording_surface_mask (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - cairo_status_t status; - cairo_recording_surface_t *surface = abstract_surface; - cairo_command_mask_t *command; - cairo_composite_rectangles_t composite; - - TRACE ((stderr, "%s: surface=%d\n", __FUNCTION__, surface->base.unique_id)); - - status = _cairo_composite_rectangles_init_for_mask (&composite, - &surface->base, - op, source, mask, - clip); - if (unlikely (status)) - return status; - - command = malloc (sizeof (cairo_command_mask_t)); - if (unlikely (command == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto CLEANUP_COMPOSITE; - } - - status = _command_init (surface, - &command->header, CAIRO_COMMAND_MASK, op, - &composite); - if (unlikely (status)) - goto CLEANUP_COMMAND; - - status = _cairo_pattern_init_snapshot (&command->source.base, source); - if (unlikely (status)) - goto CLEANUP_COMMAND; - - status = _cairo_pattern_init_snapshot (&command->mask.base, mask); - if (unlikely (status)) - goto CLEANUP_SOURCE; - - status = _cairo_recording_surface_commit (surface, &command->header); - if (unlikely (status)) - goto CLEANUP_MASK; - - _cairo_recording_surface_destroy_bbtree (surface); - - _cairo_composite_rectangles_fini (&composite); - return CAIRO_STATUS_SUCCESS; - - CLEANUP_MASK: - _cairo_pattern_fini (&command->mask.base); - CLEANUP_SOURCE: - _cairo_pattern_fini (&command->source.base); - CLEANUP_COMMAND: - _cairo_clip_destroy (command->header.clip); - free (command); -CLEANUP_COMPOSITE: - _cairo_composite_rectangles_fini (&composite); - return status; -} - -static cairo_int_status_t -_cairo_recording_surface_stroke (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_status_t status; - cairo_recording_surface_t *surface = abstract_surface; - cairo_command_stroke_t *command; - cairo_composite_rectangles_t composite; - - TRACE ((stderr, "%s: surface=%d\n", __FUNCTION__, surface->base.unique_id)); - - status = _cairo_composite_rectangles_init_for_stroke (&composite, - &surface->base, - op, source, - path, style, ctm, - clip); - if (unlikely (status)) - return status; - - command = malloc (sizeof (cairo_command_stroke_t)); - if (unlikely (command == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto CLEANUP_COMPOSITE; - } - - status = _command_init (surface, - &command->header, CAIRO_COMMAND_STROKE, op, - &composite); - if (unlikely (status)) - goto CLEANUP_COMMAND; - - status = _cairo_pattern_init_snapshot (&command->source.base, source); - if (unlikely (status)) - goto CLEANUP_COMMAND; - - status = _cairo_path_fixed_init_copy (&command->path, path); - if (unlikely (status)) - goto CLEANUP_SOURCE; - - status = _cairo_stroke_style_init_copy (&command->style, style); - if (unlikely (status)) - goto CLEANUP_PATH; - - command->ctm = *ctm; - command->ctm_inverse = *ctm_inverse; - command->tolerance = tolerance; - command->antialias = antialias; - - status = _cairo_recording_surface_commit (surface, &command->header); - if (unlikely (status)) - goto CLEANUP_STYLE; - - _cairo_recording_surface_destroy_bbtree (surface); - - _cairo_composite_rectangles_fini (&composite); - return CAIRO_STATUS_SUCCESS; - - CLEANUP_STYLE: - _cairo_stroke_style_fini (&command->style); - CLEANUP_PATH: - _cairo_path_fixed_fini (&command->path); - CLEANUP_SOURCE: - _cairo_pattern_fini (&command->source.base); - CLEANUP_COMMAND: - _cairo_clip_destroy (command->header.clip); - free (command); -CLEANUP_COMPOSITE: - _cairo_composite_rectangles_fini (&composite); - return status; -} - -static cairo_int_status_t -_cairo_recording_surface_fill (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_status_t status; - cairo_recording_surface_t *surface = abstract_surface; - cairo_command_fill_t *command; - cairo_composite_rectangles_t composite; - - TRACE ((stderr, "%s: surface=%d\n", __FUNCTION__, surface->base.unique_id)); - - status = _cairo_composite_rectangles_init_for_fill (&composite, - &surface->base, - op, source, path, - clip); - if (unlikely (status)) - return status; - - command = malloc (sizeof (cairo_command_fill_t)); - if (unlikely (command == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto CLEANUP_COMPOSITE; - } - - status =_command_init (surface, - &command->header, CAIRO_COMMAND_FILL, op, - &composite); - if (unlikely (status)) - goto CLEANUP_COMMAND; - - status = _cairo_pattern_init_snapshot (&command->source.base, source); - if (unlikely (status)) - goto CLEANUP_COMMAND; - - status = _cairo_path_fixed_init_copy (&command->path, path); - if (unlikely (status)) - goto CLEANUP_SOURCE; - - command->fill_rule = fill_rule; - command->tolerance = tolerance; - command->antialias = antialias; - - status = _cairo_recording_surface_commit (surface, &command->header); - if (unlikely (status)) - goto CLEANUP_PATH; - - _cairo_recording_surface_destroy_bbtree (surface); - - _cairo_composite_rectangles_fini (&composite); - return CAIRO_STATUS_SUCCESS; - - CLEANUP_PATH: - _cairo_path_fixed_fini (&command->path); - CLEANUP_SOURCE: - _cairo_pattern_fini (&command->source.base); - CLEANUP_COMMAND: - _cairo_clip_destroy (command->header.clip); - free (command); -CLEANUP_COMPOSITE: - _cairo_composite_rectangles_fini (&composite); - return status; -} - -static cairo_bool_t -_cairo_recording_surface_has_show_text_glyphs (void *abstract_surface) -{ - return TRUE; -} - -static cairo_int_status_t -_cairo_recording_surface_show_text_glyphs (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const char *utf8, - int utf8_len, - cairo_glyph_t *glyphs, - int num_glyphs, - const cairo_text_cluster_t *clusters, - int num_clusters, - cairo_text_cluster_flags_t cluster_flags, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - cairo_status_t status; - cairo_recording_surface_t *surface = abstract_surface; - cairo_command_show_text_glyphs_t *command; - cairo_composite_rectangles_t composite; - - TRACE ((stderr, "%s: surface=%d\n", __FUNCTION__, surface->base.unique_id)); - - status = _cairo_composite_rectangles_init_for_glyphs (&composite, - &surface->base, - op, source, - scaled_font, - glyphs, num_glyphs, - clip, - NULL); - if (unlikely (status)) - return status; - - command = malloc (sizeof (cairo_command_show_text_glyphs_t)); - if (unlikely (command == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto CLEANUP_COMPOSITE; - } - - status = _command_init (surface, - &command->header, CAIRO_COMMAND_SHOW_TEXT_GLYPHS, - op, &composite); - if (unlikely (status)) - goto CLEANUP_COMMAND; - - status = _cairo_pattern_init_snapshot (&command->source.base, source); - if (unlikely (status)) - goto CLEANUP_COMMAND; - - command->utf8 = NULL; - command->utf8_len = utf8_len; - command->glyphs = NULL; - command->num_glyphs = num_glyphs; - command->clusters = NULL; - command->num_clusters = num_clusters; - - if (utf8_len) { - command->utf8 = malloc (utf8_len); - if (unlikely (command->utf8 == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto CLEANUP_ARRAYS; - } - memcpy (command->utf8, utf8, utf8_len); - } - if (num_glyphs) { - command->glyphs = _cairo_malloc_ab (num_glyphs, sizeof (glyphs[0])); - if (unlikely (command->glyphs == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto CLEANUP_ARRAYS; - } - memcpy (command->glyphs, glyphs, sizeof (glyphs[0]) * num_glyphs); - } - if (num_clusters) { - command->clusters = _cairo_malloc_ab (num_clusters, sizeof (clusters[0])); - if (unlikely (command->clusters == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto CLEANUP_ARRAYS; - } - memcpy (command->clusters, clusters, sizeof (clusters[0]) * num_clusters); - } - - command->cluster_flags = cluster_flags; - - command->scaled_font = cairo_scaled_font_reference (scaled_font); - - status = _cairo_recording_surface_commit (surface, &command->header); - if (unlikely (status)) - goto CLEANUP_SCALED_FONT; - - _cairo_composite_rectangles_fini (&composite); - return CAIRO_STATUS_SUCCESS; - - CLEANUP_SCALED_FONT: - cairo_scaled_font_destroy (command->scaled_font); - CLEANUP_ARRAYS: - free (command->utf8); - free (command->glyphs); - free (command->clusters); - - _cairo_pattern_fini (&command->source.base); - CLEANUP_COMMAND: - _cairo_clip_destroy (command->header.clip); - free (command); -CLEANUP_COMPOSITE: - _cairo_composite_rectangles_fini (&composite); - return status; -} - -static void -_command_init_copy (cairo_recording_surface_t *surface, - cairo_command_header_t *dst, - const cairo_command_header_t *src) -{ - dst->type = src->type; - dst->op = src->op; - dst->region = CAIRO_RECORDING_REGION_ALL; - - dst->extents = src->extents; - dst->chain = NULL; - dst->index = surface->commands.num_elements; - - dst->clip = _cairo_clip_copy (src->clip); -} - -static cairo_status_t -_cairo_recording_surface_copy__paint (cairo_recording_surface_t *surface, - const cairo_command_t *src) -{ - cairo_command_paint_t *command; - cairo_status_t status; - - command = malloc (sizeof (*command)); - if (unlikely (command == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto err; - } - - _command_init_copy (surface, &command->header, &src->header); - - status = _cairo_pattern_init_copy (&command->source.base, - &src->paint.source.base); - if (unlikely (status)) - goto err_command; - - status = _cairo_recording_surface_commit (surface, &command->header); - if (unlikely (status)) - goto err_source; - - return CAIRO_STATUS_SUCCESS; - -err_source: - _cairo_pattern_fini (&command->source.base); -err_command: - free(command); -err: - return status; -} - -static cairo_status_t -_cairo_recording_surface_copy__mask (cairo_recording_surface_t *surface, - const cairo_command_t *src) -{ - cairo_command_mask_t *command; - cairo_status_t status; - - command = malloc (sizeof (*command)); - if (unlikely (command == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto err; - } - - _command_init_copy (surface, &command->header, &src->header); - - status = _cairo_pattern_init_copy (&command->source.base, - &src->mask.source.base); - if (unlikely (status)) - goto err_command; - - status = _cairo_pattern_init_copy (&command->mask.base, - &src->mask.mask.base); - if (unlikely (status)) - goto err_source; - - status = _cairo_recording_surface_commit (surface, &command->header); - if (unlikely (status)) - goto err_mask; - - return CAIRO_STATUS_SUCCESS; - -err_mask: - _cairo_pattern_fini (&command->mask.base); -err_source: - _cairo_pattern_fini (&command->source.base); -err_command: - free(command); -err: - return status; -} - -static cairo_status_t -_cairo_recording_surface_copy__stroke (cairo_recording_surface_t *surface, - const cairo_command_t *src) -{ - cairo_command_stroke_t *command; - cairo_status_t status; - - command = malloc (sizeof (*command)); - if (unlikely (command == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto err; - } - - _command_init_copy (surface, &command->header, &src->header); - - status = _cairo_pattern_init_copy (&command->source.base, - &src->stroke.source.base); - if (unlikely (status)) - goto err_command; - - status = _cairo_path_fixed_init_copy (&command->path, &src->stroke.path); - if (unlikely (status)) - goto err_source; - - status = _cairo_stroke_style_init_copy (&command->style, - &src->stroke.style); - if (unlikely (status)) - goto err_path; - - command->ctm = src->stroke.ctm; - command->ctm_inverse = src->stroke.ctm_inverse; - command->tolerance = src->stroke.tolerance; - command->antialias = src->stroke.antialias; - - status = _cairo_recording_surface_commit (surface, &command->header); - if (unlikely (status)) - goto err_style; - - return CAIRO_STATUS_SUCCESS; - -err_style: - _cairo_stroke_style_fini (&command->style); -err_path: - _cairo_path_fixed_fini (&command->path); -err_source: - _cairo_pattern_fini (&command->source.base); -err_command: - free(command); -err: - return status; -} - -static cairo_status_t -_cairo_recording_surface_copy__fill (cairo_recording_surface_t *surface, - const cairo_command_t *src) -{ - cairo_command_fill_t *command; - cairo_status_t status; - - command = malloc (sizeof (*command)); - if (unlikely (command == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto err; - } - - _command_init_copy (surface, &command->header, &src->header); - - status = _cairo_pattern_init_copy (&command->source.base, - &src->fill.source.base); - if (unlikely (status)) - goto err_command; - - status = _cairo_path_fixed_init_copy (&command->path, &src->fill.path); - if (unlikely (status)) - goto err_source; - - command->fill_rule = src->fill.fill_rule; - command->tolerance = src->fill.tolerance; - command->antialias = src->fill.antialias; - - status = _cairo_recording_surface_commit (surface, &command->header); - if (unlikely (status)) - goto err_path; - - return CAIRO_STATUS_SUCCESS; - -err_path: - _cairo_path_fixed_fini (&command->path); -err_source: - _cairo_pattern_fini (&command->source.base); -err_command: - free(command); -err: - return status; -} - -static cairo_status_t -_cairo_recording_surface_copy__glyphs (cairo_recording_surface_t *surface, - const cairo_command_t *src) -{ - cairo_command_show_text_glyphs_t *command; - cairo_status_t status; - - command = malloc (sizeof (*command)); - if (unlikely (command == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto err; - } - - _command_init_copy (surface, &command->header, &src->header); - - status = _cairo_pattern_init_copy (&command->source.base, - &src->show_text_glyphs.source.base); - if (unlikely (status)) - goto err_command; - - command->utf8 = NULL; - command->utf8_len = src->show_text_glyphs.utf8_len; - command->glyphs = NULL; - command->num_glyphs = src->show_text_glyphs.num_glyphs; - command->clusters = NULL; - command->num_clusters = src->show_text_glyphs.num_clusters; - - if (command->utf8_len) { - command->utf8 = malloc (command->utf8_len); - if (unlikely (command->utf8 == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto err_arrays; - } - memcpy (command->utf8, src->show_text_glyphs.utf8, command->utf8_len); - } - if (command->num_glyphs) { - command->glyphs = _cairo_malloc_ab (command->num_glyphs, - sizeof (command->glyphs[0])); - if (unlikely (command->glyphs == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto err_arrays; - } - memcpy (command->glyphs, src->show_text_glyphs.glyphs, - sizeof (command->glyphs[0]) * command->num_glyphs); - } - if (command->num_clusters) { - command->clusters = _cairo_malloc_ab (command->num_clusters, - sizeof (command->clusters[0])); - if (unlikely (command->clusters == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto err_arrays; - } - memcpy (command->clusters, src->show_text_glyphs.clusters, - sizeof (command->clusters[0]) * command->num_clusters); - } - - command->cluster_flags = src->show_text_glyphs.cluster_flags; - - command->scaled_font = - cairo_scaled_font_reference (src->show_text_glyphs.scaled_font); - - status = _cairo_recording_surface_commit (surface, &command->header); - if (unlikely (status)) - goto err_arrays; - - return CAIRO_STATUS_SUCCESS; - -err_arrays: - free (command->utf8); - free (command->glyphs); - free (command->clusters); - _cairo_pattern_fini (&command->source.base); -err_command: - free(command); -err: - return status; -} - -static cairo_status_t -_cairo_recording_surface_copy (cairo_recording_surface_t *dst, - cairo_recording_surface_t *src) -{ - cairo_command_t **elements; - int i, num_elements; - cairo_status_t status; - - elements = _cairo_array_index (&src->commands, 0); - num_elements = src->commands.num_elements; - for (i = 0; i < num_elements; i++) { - const cairo_command_t *command = elements[i]; - - switch (command->header.type) { - case CAIRO_COMMAND_PAINT: - status = _cairo_recording_surface_copy__paint (dst, command); - break; - - case CAIRO_COMMAND_MASK: - status = _cairo_recording_surface_copy__mask (dst, command); - break; - - case CAIRO_COMMAND_STROKE: - status = _cairo_recording_surface_copy__stroke (dst, command); - break; - - case CAIRO_COMMAND_FILL: - status = _cairo_recording_surface_copy__fill (dst, command); - break; - - case CAIRO_COMMAND_SHOW_TEXT_GLYPHS: - status = _cairo_recording_surface_copy__glyphs (dst, command); - break; - - default: - ASSERT_NOT_REACHED; - } - - if (unlikely (status)) - return status; - } - - return CAIRO_STATUS_SUCCESS; -} - -/** - * _cairo_recording_surface_snapshot: - * @surface: a #cairo_surface_t which must be a recording surface - * - * Make an immutable copy of @surface. It is an error to call a - * surface-modifying function on the result of this function. - * - * The caller owns the return value and should call - * cairo_surface_destroy() when finished with it. This function will not - * return %NULL, but will return a nil surface instead. - * - * Return value: The snapshot surface. - **/ -static cairo_surface_t * -_cairo_recording_surface_snapshot (void *abstract_other) -{ - cairo_recording_surface_t *other = abstract_other; - cairo_recording_surface_t *surface; - cairo_status_t status; - - surface = malloc (sizeof (cairo_recording_surface_t)); - if (unlikely (surface == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - _cairo_surface_init (&surface->base, - &cairo_recording_surface_backend, - NULL, /* device */ - other->base.content); - - surface->extents_pixels = other->extents_pixels; - surface->extents = other->extents; - surface->unbounded = other->unbounded; - - surface->base.is_clear = other->base.is_clear; - - surface->bbtree.left = surface->bbtree.right = NULL; - surface->bbtree.chain = INVALID_CHAIN; - - surface->indices = NULL; - surface->num_indices = 0; - surface->optimize_clears = TRUE; - - _cairo_array_init (&surface->commands, sizeof (cairo_command_t *)); - status = _cairo_recording_surface_copy (surface, other); - if (unlikely (status)) { - cairo_surface_destroy (&surface->base); - return _cairo_surface_create_in_error (status); - } - - return &surface->base; -} - -static cairo_bool_t -_cairo_recording_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *rectangle) -{ - cairo_recording_surface_t *surface = abstract_surface; - - if (surface->unbounded) - return FALSE; - - *rectangle = surface->extents; - return TRUE; -} - -static const cairo_surface_backend_t cairo_recording_surface_backend = { - CAIRO_SURFACE_TYPE_RECORDING, - _cairo_recording_surface_finish, - - _cairo_default_context_create, - - _cairo_recording_surface_create_similar, - NULL, /* create similar image */ - NULL, /* map to image */ - NULL, /* unmap image */ - - _cairo_surface_default_source, - _cairo_recording_surface_acquire_source_image, - _cairo_recording_surface_release_source_image, - _cairo_recording_surface_snapshot, - - NULL, /* copy_page */ - NULL, /* show_page */ - - _cairo_recording_surface_get_extents, - NULL, /* get_font_options */ - - NULL, /* flush */ - NULL, /* mark_dirty_rectangle */ - - /* Here are the 5 basic drawing operations, (which are in some - * sense the only things that cairo_recording_surface should need to - * implement). However, we implement the more generic show_text_glyphs - * instead of show_glyphs. One or the other is eough. */ - - _cairo_recording_surface_paint, - _cairo_recording_surface_mask, - _cairo_recording_surface_stroke, - _cairo_recording_surface_fill, - NULL, /* fill-stroke */ - NULL, - _cairo_recording_surface_has_show_text_glyphs, - _cairo_recording_surface_show_text_glyphs, -}; - -cairo_int_status_t -_cairo_recording_surface_get_path (cairo_surface_t *abstract_surface, - cairo_path_fixed_t *path) -{ - cairo_recording_surface_t *surface; - cairo_command_t **elements; - int i, num_elements; - cairo_int_status_t status; - - if (unlikely (abstract_surface->status)) - return abstract_surface->status; - - surface = (cairo_recording_surface_t *) abstract_surface; - status = CAIRO_STATUS_SUCCESS; - - num_elements = surface->commands.num_elements; - elements = _cairo_array_index (&surface->commands, 0); - for (i = 0; i < num_elements; i++) { - cairo_command_t *command = elements[i]; - - switch (command->header.type) { - case CAIRO_COMMAND_PAINT: - case CAIRO_COMMAND_MASK: - status = CAIRO_INT_STATUS_UNSUPPORTED; - break; - - case CAIRO_COMMAND_STROKE: - { - cairo_traps_t traps; - - _cairo_traps_init (&traps); - - /* XXX call cairo_stroke_to_path() when that is implemented */ - status = _cairo_path_fixed_stroke_polygon_to_traps (&command->stroke.path, - &command->stroke.style, - &command->stroke.ctm, - &command->stroke.ctm_inverse, - command->stroke.tolerance, - &traps); - - if (status == CAIRO_INT_STATUS_SUCCESS) - status = _cairo_traps_path (&traps, path); - - _cairo_traps_fini (&traps); - break; - } - case CAIRO_COMMAND_FILL: - { - status = _cairo_path_fixed_append (path, - &command->fill.path, - 0, 0); - break; - } - case CAIRO_COMMAND_SHOW_TEXT_GLYPHS: - { - status = _cairo_scaled_font_glyph_path (command->show_text_glyphs.scaled_font, - command->show_text_glyphs.glyphs, - command->show_text_glyphs.num_glyphs, - path); - break; - } - - default: - ASSERT_NOT_REACHED; - } - - if (unlikely (status)) - break; - } - - return status; -} - -static int -_cairo_recording_surface_get_visible_commands (cairo_recording_surface_t *surface, - const cairo_rectangle_int_t *extents) -{ - unsigned int num_visible, *indices; - cairo_box_t box; - - if (surface->commands.num_elements == 0) - return 0; - - _cairo_box_from_rectangle (&box, extents); - - if (surface->bbtree.chain == INVALID_CHAIN) - _cairo_recording_surface_create_bbtree (surface); - - indices = surface->indices; - bbtree_foreach_mark_visible (&surface->bbtree, &box, &indices); - num_visible = indices - surface->indices; - if (num_visible > 1) - sort_indices (surface->indices, num_visible); - - return num_visible; -} - -static void -_cairo_recording_surface_merge_source_attributes (cairo_recording_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source) -{ - if (op != CAIRO_OPERATOR_OVER) - surface->has_only_op_over = FALSE; - - if (source->type == CAIRO_PATTERN_TYPE_SURFACE) { - cairo_surface_pattern_t *surf_pat = (cairo_surface_pattern_t *) source; - cairo_surface_t *surf = surf_pat->surface; - cairo_surface_t *free_me = NULL; - - if (_cairo_surface_is_snapshot (surf)) - free_me = surf = _cairo_surface_snapshot_get_target (surf); - - if (surf->type == CAIRO_SURFACE_TYPE_RECORDING) { - cairo_recording_surface_t *rec_surf = (cairo_recording_surface_t *) surf; - - if (! _cairo_recording_surface_has_only_bilevel_alpha (rec_surf)) - surface->has_bilevel_alpha = FALSE; - - if (! _cairo_recording_surface_has_only_op_over (rec_surf)) - surface->has_only_op_over = FALSE; - - } else if (surf->type == CAIRO_SURFACE_TYPE_IMAGE) { - cairo_image_surface_t *img_surf = (cairo_image_surface_t *) surf; - - if (_cairo_image_analyze_transparency (img_surf) == CAIRO_IMAGE_HAS_ALPHA) - surface->has_bilevel_alpha = FALSE; - - } else { - if (!_cairo_pattern_is_clear (source) && !_cairo_pattern_is_opaque (source, NULL)) - surface->has_bilevel_alpha = FALSE; - } - - cairo_surface_destroy (free_me); - return; - - } else if (source->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE) { - cairo_surface_t *image; - cairo_surface_t *raster; - - image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1); - raster = _cairo_raster_source_pattern_acquire (source, image, NULL); - cairo_surface_destroy (image); - if (raster) { - if (raster->type == CAIRO_SURFACE_TYPE_IMAGE) { - if (_cairo_image_analyze_transparency ((cairo_image_surface_t *)raster) == CAIRO_IMAGE_HAS_ALPHA) - surface->has_bilevel_alpha = FALSE; - } - - _cairo_raster_source_pattern_release (source, raster); - if (raster->type == CAIRO_SURFACE_TYPE_IMAGE) - return; - } - } - - if (!_cairo_pattern_is_clear (source) && !_cairo_pattern_is_opaque (source, NULL)) - surface->has_bilevel_alpha = FALSE; -} - -static cairo_status_t -_cairo_recording_surface_replay_internal (cairo_recording_surface_t *surface, - const cairo_rectangle_int_t *surface_extents, - const cairo_matrix_t *surface_transform, - cairo_surface_t *target, - const cairo_clip_t *target_clip, - cairo_recording_replay_type_t type, - cairo_recording_region_type_t region) -{ - cairo_surface_wrapper_t wrapper; - cairo_command_t **elements; - cairo_bool_t replay_all = - type == CAIRO_RECORDING_REPLAY && - region == CAIRO_RECORDING_REGION_ALL; - cairo_int_status_t status = CAIRO_STATUS_SUCCESS; - cairo_rectangle_int_t extents; - cairo_bool_t use_indices = FALSE; - const cairo_rectangle_int_t *r; - unsigned int i, num_elements; - - if (unlikely (surface->base.status)) - return surface->base.status; - - if (unlikely (target->status)) - return target->status; - - if (unlikely (surface->base.finished)) - return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED); - - if (surface->base.is_clear) - return CAIRO_STATUS_SUCCESS; - - assert (_cairo_surface_is_recording (&surface->base)); - - _cairo_surface_wrapper_init (&wrapper, target); - if (surface_extents) - _cairo_surface_wrapper_intersect_extents (&wrapper, surface_extents); - r = &_cairo_unbounded_rectangle; - if (! surface->unbounded) { - _cairo_surface_wrapper_intersect_extents (&wrapper, &surface->extents); - r = &surface->extents; - } - _cairo_surface_wrapper_set_inverse_transform (&wrapper, surface_transform); - _cairo_surface_wrapper_set_clip (&wrapper, target_clip); - - /* Compute the extents of the target clip in recorded device space */ - if (! _cairo_surface_wrapper_get_target_extents (&wrapper, &extents)) - goto done; - - surface->has_bilevel_alpha = TRUE; - surface->has_only_op_over = TRUE; - - num_elements = surface->commands.num_elements; - elements = _cairo_array_index (&surface->commands, 0); - if (extents.width < r->width || extents.height < r->height) { - num_elements = - _cairo_recording_surface_get_visible_commands (surface, &extents); - use_indices = num_elements != surface->commands.num_elements; - } - - for (i = 0; i < num_elements; i++) { - cairo_command_t *command = elements[use_indices ? surface->indices[i] : i]; - - if (! replay_all && command->header.region != region) - continue; - - if (! _cairo_rectangle_intersects (&extents, &command->header.extents)) - continue; - - switch (command->header.type) { - case CAIRO_COMMAND_PAINT: - status = _cairo_surface_wrapper_paint (&wrapper, - command->header.op, - &command->paint.source.base, - command->header.clip); - if (type == CAIRO_RECORDING_CREATE_REGIONS) { - _cairo_recording_surface_merge_source_attributes (surface, - command->header.op, - &command->paint.source.base); - } - break; - - case CAIRO_COMMAND_MASK: - status = _cairo_surface_wrapper_mask (&wrapper, - command->header.op, - &command->mask.source.base, - &command->mask.mask.base, - command->header.clip); - if (type == CAIRO_RECORDING_CREATE_REGIONS) { - _cairo_recording_surface_merge_source_attributes (surface, - command->header.op, - &command->mask.source.base); - _cairo_recording_surface_merge_source_attributes (surface, - command->header.op, - &command->mask.mask.base); - } - break; - - case CAIRO_COMMAND_STROKE: - status = _cairo_surface_wrapper_stroke (&wrapper, - command->header.op, - &command->stroke.source.base, - &command->stroke.path, - &command->stroke.style, - &command->stroke.ctm, - &command->stroke.ctm_inverse, - command->stroke.tolerance, - command->stroke.antialias, - command->header.clip); - if (type == CAIRO_RECORDING_CREATE_REGIONS) { - _cairo_recording_surface_merge_source_attributes (surface, - command->header.op, - &command->stroke.source.base); - } - break; - - case CAIRO_COMMAND_FILL: - status = CAIRO_INT_STATUS_UNSUPPORTED; - if (_cairo_surface_wrapper_has_fill_stroke (&wrapper)) { - cairo_command_t *stroke_command; - - stroke_command = NULL; - if (type != CAIRO_RECORDING_CREATE_REGIONS && i < num_elements - 1) - stroke_command = elements[i + 1]; - - if (stroke_command != NULL && - type == CAIRO_RECORDING_REPLAY && - region != CAIRO_RECORDING_REGION_ALL) - { - if (stroke_command->header.region != region) - stroke_command = NULL; - } - - if (stroke_command != NULL && - stroke_command->header.type == CAIRO_COMMAND_STROKE && - _cairo_path_fixed_equal (&command->fill.path, - &stroke_command->stroke.path) && - _cairo_clip_equal (command->header.clip, - stroke_command->header.clip)) - { - status = _cairo_surface_wrapper_fill_stroke (&wrapper, - command->header.op, - &command->fill.source.base, - command->fill.fill_rule, - command->fill.tolerance, - command->fill.antialias, - &command->fill.path, - stroke_command->header.op, - &stroke_command->stroke.source.base, - &stroke_command->stroke.style, - &stroke_command->stroke.ctm, - &stroke_command->stroke.ctm_inverse, - stroke_command->stroke.tolerance, - stroke_command->stroke.antialias, - command->header.clip); - if (type == CAIRO_RECORDING_CREATE_REGIONS) { - _cairo_recording_surface_merge_source_attributes (surface, - command->header.op, - &command->fill.source.base); - _cairo_recording_surface_merge_source_attributes (surface, - command->header.op, - &command->stroke.source.base); - } - i++; - } - } - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - status = _cairo_surface_wrapper_fill (&wrapper, - command->header.op, - &command->fill.source.base, - &command->fill.path, - command->fill.fill_rule, - command->fill.tolerance, - command->fill.antialias, - command->header.clip); - if (type == CAIRO_RECORDING_CREATE_REGIONS) { - _cairo_recording_surface_merge_source_attributes (surface, - command->header.op, - &command->fill.source.base); - } - } - break; - - case CAIRO_COMMAND_SHOW_TEXT_GLYPHS: - status = _cairo_surface_wrapper_show_text_glyphs (&wrapper, - command->header.op, - &command->show_text_glyphs.source.base, - command->show_text_glyphs.utf8, command->show_text_glyphs.utf8_len, - command->show_text_glyphs.glyphs, command->show_text_glyphs.num_glyphs, - command->show_text_glyphs.clusters, command->show_text_glyphs.num_clusters, - command->show_text_glyphs.cluster_flags, - command->show_text_glyphs.scaled_font, - command->header.clip); - if (type == CAIRO_RECORDING_CREATE_REGIONS) { - _cairo_recording_surface_merge_source_attributes (surface, - command->header.op, - &command->show_text_glyphs.source.base); - } - break; - - default: - ASSERT_NOT_REACHED; - } - - if (type == CAIRO_RECORDING_CREATE_REGIONS) { - if (status == CAIRO_INT_STATUS_SUCCESS) { - command->header.region = CAIRO_RECORDING_REGION_NATIVE; - } else if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK) { - command->header.region = CAIRO_RECORDING_REGION_IMAGE_FALLBACK; - status = CAIRO_INT_STATUS_SUCCESS; - } else { - assert (_cairo_int_status_is_error (status)); - } - } - - if (unlikely (status)) - break; - } - -done: - _cairo_surface_wrapper_fini (&wrapper); - return _cairo_surface_set_error (&surface->base, status); -} - -cairo_status_t -_cairo_recording_surface_replay_one (cairo_recording_surface_t *surface, - long unsigned index, - cairo_surface_t *target) -{ - cairo_surface_wrapper_t wrapper; - cairo_command_t **elements, *command; - cairo_int_status_t status; - - if (unlikely (surface->base.status)) - return surface->base.status; - - if (unlikely (target->status)) - return target->status; - - if (unlikely (surface->base.finished)) - return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED); - - assert (_cairo_surface_is_recording (&surface->base)); - - /* XXX - * Use a surface wrapper because we may want to do transformed - * replay in the future. - */ - _cairo_surface_wrapper_init (&wrapper, target); - - if (index > surface->commands.num_elements) - return _cairo_error (CAIRO_STATUS_READ_ERROR); - - elements = _cairo_array_index (&surface->commands, 0); - command = elements[index]; - switch (command->header.type) { - case CAIRO_COMMAND_PAINT: - status = _cairo_surface_wrapper_paint (&wrapper, - command->header.op, - &command->paint.source.base, - command->header.clip); - break; - - case CAIRO_COMMAND_MASK: - status = _cairo_surface_wrapper_mask (&wrapper, - command->header.op, - &command->mask.source.base, - &command->mask.mask.base, - command->header.clip); - break; - - case CAIRO_COMMAND_STROKE: - status = _cairo_surface_wrapper_stroke (&wrapper, - command->header.op, - &command->stroke.source.base, - &command->stroke.path, - &command->stroke.style, - &command->stroke.ctm, - &command->stroke.ctm_inverse, - command->stroke.tolerance, - command->stroke.antialias, - command->header.clip); - break; - - case CAIRO_COMMAND_FILL: - status = _cairo_surface_wrapper_fill (&wrapper, - command->header.op, - &command->fill.source.base, - &command->fill.path, - command->fill.fill_rule, - command->fill.tolerance, - command->fill.antialias, - command->header.clip); - break; - - case CAIRO_COMMAND_SHOW_TEXT_GLYPHS: - status = _cairo_surface_wrapper_show_text_glyphs (&wrapper, - command->header.op, - &command->show_text_glyphs.source.base, - command->show_text_glyphs.utf8, command->show_text_glyphs.utf8_len, - command->show_text_glyphs.glyphs, command->show_text_glyphs.num_glyphs, - command->show_text_glyphs.clusters, command->show_text_glyphs.num_clusters, - command->show_text_glyphs.cluster_flags, - command->show_text_glyphs.scaled_font, - command->header.clip); - break; - - default: - ASSERT_NOT_REACHED; - } - - _cairo_surface_wrapper_fini (&wrapper); - return _cairo_surface_set_error (&surface->base, status); -} -/** - * _cairo_recording_surface_replay: - * @surface: the #cairo_recording_surface_t - * @target: a target #cairo_surface_t onto which to replay the operations - * @width_pixels: width of the surface, in pixels - * @height_pixels: height of the surface, in pixels - * - * A recording surface can be "replayed" against any target surface, - * after which the results in target will be identical to the results - * that would have been obtained if the original operations applied to - * the recording surface had instead been applied to the target surface. - **/ -cairo_status_t -_cairo_recording_surface_replay (cairo_surface_t *surface, - cairo_surface_t *target) -{ - return _cairo_recording_surface_replay_internal ((cairo_recording_surface_t *) surface, NULL, NULL, - target, NULL, - CAIRO_RECORDING_REPLAY, - CAIRO_RECORDING_REGION_ALL); -} - -cairo_status_t -_cairo_recording_surface_replay_with_clip (cairo_surface_t *surface, - const cairo_matrix_t *surface_transform, - cairo_surface_t *target, - const cairo_clip_t *target_clip) -{ - return _cairo_recording_surface_replay_internal ((cairo_recording_surface_t *) surface, NULL, surface_transform, - target, target_clip, - CAIRO_RECORDING_REPLAY, - CAIRO_RECORDING_REGION_ALL); -} - -/* Replay recording to surface. When the return status of each operation is - * one of %CAIRO_STATUS_SUCCESS, %CAIRO_INT_STATUS_UNSUPPORTED, or - * %CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY the status of each operation - * will be stored in the recording surface. Any other status will abort the - * replay and return the status. - */ -cairo_status_t -_cairo_recording_surface_replay_and_create_regions (cairo_surface_t *surface, - cairo_surface_t *target) -{ - return _cairo_recording_surface_replay_internal ((cairo_recording_surface_t *) surface, NULL, NULL, - target, NULL, - CAIRO_RECORDING_CREATE_REGIONS, - CAIRO_RECORDING_REGION_ALL); -} - -cairo_status_t -_cairo_recording_surface_replay_region (cairo_surface_t *surface, - const cairo_rectangle_int_t *surface_extents, - cairo_surface_t *target, - cairo_recording_region_type_t region) -{ - return _cairo_recording_surface_replay_internal ((cairo_recording_surface_t *) surface, - surface_extents, NULL, - target, NULL, - CAIRO_RECORDING_REPLAY, - region); -} - -static cairo_status_t -_recording_surface_get_ink_bbox (cairo_recording_surface_t *surface, - cairo_box_t *bbox, - const cairo_matrix_t *transform) -{ - cairo_surface_t *null_surface; - cairo_surface_t *analysis_surface; - cairo_status_t status; - - null_surface = _cairo_null_surface_create (surface->base.content); - analysis_surface = _cairo_analysis_surface_create (null_surface); - cairo_surface_destroy (null_surface); - - status = analysis_surface->status; - if (unlikely (status)) - return status; - - if (transform != NULL) - _cairo_analysis_surface_set_ctm (analysis_surface, transform); - - status = _cairo_recording_surface_replay (&surface->base, analysis_surface); - _cairo_analysis_surface_get_bounding_box (analysis_surface, bbox); - cairo_surface_destroy (analysis_surface); - - return status; -} - -/** - * cairo_recording_surface_ink_extents: - * @surface: a #cairo_recording_surface_t - * @x0: the x-coordinate of the top-left of the ink bounding box - * @y0: the y-coordinate of the top-left of the ink bounding box - * @width: the width of the ink bounding box - * @height: the height of the ink bounding box - * - * Measures the extents of the operations stored within the recording-surface. - * This is useful to compute the required size of an image surface (or - * equivalent) into which to replay the full sequence of drawing operations. - * - * Since: 1.10 - **/ -void -cairo_recording_surface_ink_extents (cairo_surface_t *surface, - double *x0, - double *y0, - double *width, - double *height) -{ - cairo_status_t status; - cairo_box_t bbox; - - memset (&bbox, 0, sizeof (bbox)); - - if (surface->status || ! _cairo_surface_is_recording (surface)) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - goto DONE; - } - - status = _recording_surface_get_ink_bbox ((cairo_recording_surface_t *) surface, - &bbox, - NULL); - if (unlikely (status)) - status = _cairo_surface_set_error (surface, status); - -DONE: - if (x0) - *x0 = _cairo_fixed_to_double (bbox.p1.x); - if (y0) - *y0 = _cairo_fixed_to_double (bbox.p1.y); - if (width) - *width = _cairo_fixed_to_double (bbox.p2.x - bbox.p1.x); - if (height) - *height = _cairo_fixed_to_double (bbox.p2.y - bbox.p1.y); -} - -cairo_status_t -_cairo_recording_surface_get_bbox (cairo_recording_surface_t *surface, - cairo_box_t *bbox, - const cairo_matrix_t *transform) -{ - if (! surface->unbounded) { - _cairo_box_from_rectangle (bbox, &surface->extents); - if (transform != NULL) - _cairo_matrix_transform_bounding_box_fixed (transform, bbox, NULL); - - return CAIRO_STATUS_SUCCESS; - } - - return _recording_surface_get_ink_bbox (surface, bbox, transform); -} - -cairo_status_t -_cairo_recording_surface_get_ink_bbox (cairo_recording_surface_t *surface, - cairo_box_t *bbox, - const cairo_matrix_t *transform) -{ - return _recording_surface_get_ink_bbox (surface, bbox, transform); -} - -/** - * cairo_recording_surface_get_extents: - * @surface: a #cairo_recording_surface_t - * @extents: the #cairo_rectangle_t to be assigned the extents - * - * Get the extents of the recording-surface. - * - * Return value: %TRUE if the surface is bounded, of recording type, and - * not in an error state, otherwise %FALSE - * - * Since: 1.12 - **/ -cairo_bool_t -cairo_recording_surface_get_extents (cairo_surface_t *surface, - cairo_rectangle_t *extents) -{ - cairo_recording_surface_t *record; - - if (surface->status || ! _cairo_surface_is_recording (surface)) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return FALSE; - } - - record = (cairo_recording_surface_t *)surface; - if (record->unbounded) - return FALSE; - - *extents = record->extents_pixels; - return TRUE; -} - -cairo_bool_t -_cairo_recording_surface_has_only_bilevel_alpha (cairo_recording_surface_t *surface) -{ - return surface->has_bilevel_alpha; -} - -cairo_bool_t -_cairo_recording_surface_has_only_op_over (cairo_recording_surface_t *surface) -{ - return surface->has_only_op_over; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-rectangle.c b/source/libs/cairo/cairo-src/src/cairo-rectangle.c deleted file mode 100644 index 2d51d7b10a4b657d6b16971191d2dc5af966bfd3..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-rectangle.c +++ /dev/null @@ -1,299 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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" - -#include "cairo-box-inline.h" - -const cairo_rectangle_int_t _cairo_empty_rectangle = { 0, 0, 0, 0 }; -const cairo_rectangle_int_t _cairo_unbounded_rectangle = { - CAIRO_RECT_INT_MIN, CAIRO_RECT_INT_MIN, - CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN, - CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN, -}; - -cairo_private void -_cairo_box_from_doubles (cairo_box_t *box, - double *x1, double *y1, - double *x2, double *y2) -{ - box->p1.x = _cairo_fixed_from_double (*x1); - box->p1.y = _cairo_fixed_from_double (*y1); - box->p2.x = _cairo_fixed_from_double (*x2); - box->p2.y = _cairo_fixed_from_double (*y2); -} - -cairo_private void -_cairo_box_to_doubles (const cairo_box_t *box, - double *x1, double *y1, - double *x2, double *y2) -{ - *x1 = _cairo_fixed_to_double (box->p1.x); - *y1 = _cairo_fixed_to_double (box->p1.y); - *x2 = _cairo_fixed_to_double (box->p2.x); - *y2 = _cairo_fixed_to_double (box->p2.y); -} - -void -_cairo_box_from_rectangle (cairo_box_t *box, - const cairo_rectangle_int_t *rect) -{ - box->p1.x = _cairo_fixed_from_int (rect->x); - box->p1.y = _cairo_fixed_from_int (rect->y); - box->p2.x = _cairo_fixed_from_int (rect->x + rect->width); - box->p2.y = _cairo_fixed_from_int (rect->y + rect->height); -} - -void -_cairo_boxes_get_extents (const cairo_box_t *boxes, - int num_boxes, - cairo_box_t *extents) -{ - assert (num_boxes > 0); - *extents = *boxes; - while (--num_boxes) - _cairo_box_add_box (extents, ++boxes); -} - -/* XXX We currently have a confusing mix of boxes and rectangles as - * exemplified by this function. A #cairo_box_t is a rectangular area - * represented by the coordinates of the upper left and lower right - * corners, expressed in fixed point numbers. A #cairo_rectangle_int_t is - * also a rectangular area, but represented by the upper left corner - * and the width and the height, as integer numbers. - * - * This function converts a #cairo_box_t to a #cairo_rectangle_int_t by - * increasing the area to the nearest integer coordinates. We should - * standardize on #cairo_rectangle_fixed_t and #cairo_rectangle_int_t, and - * this function could be renamed to the more reasonable - * _cairo_rectangle_fixed_round. - */ - -void -_cairo_box_round_to_rectangle (const cairo_box_t *box, - cairo_rectangle_int_t *rectangle) -{ - rectangle->x = _cairo_fixed_integer_floor (box->p1.x); - rectangle->y = _cairo_fixed_integer_floor (box->p1.y); - rectangle->width = _cairo_fixed_integer_ceil (box->p2.x) - rectangle->x; - rectangle->height = _cairo_fixed_integer_ceil (box->p2.y) - rectangle->y; -} - -cairo_bool_t -_cairo_rectangle_intersect (cairo_rectangle_int_t *dst, - const cairo_rectangle_int_t *src) -{ - int x1, y1, x2, y2; - - x1 = MAX (dst->x, src->x); - y1 = MAX (dst->y, src->y); - /* Beware the unsigned promotion, fortunately we have bits to spare - * as (CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN) < UINT_MAX - */ - x2 = MIN (dst->x + (int) dst->width, src->x + (int) src->width); - y2 = MIN (dst->y + (int) dst->height, src->y + (int) src->height); - - if (x1 >= x2 || y1 >= y2) { - dst->x = 0; - dst->y = 0; - dst->width = 0; - dst->height = 0; - - return FALSE; - } else { - dst->x = x1; - dst->y = y1; - dst->width = x2 - x1; - dst->height = y2 - y1; - - return TRUE; - } -} - -/* Extends the dst rectangle to also contain src. - * If one of the rectangles is empty, the result is undefined - */ -void -_cairo_rectangle_union (cairo_rectangle_int_t *dst, - const cairo_rectangle_int_t *src) -{ - int x1, y1, x2, y2; - - x1 = MIN (dst->x, src->x); - y1 = MIN (dst->y, src->y); - /* Beware the unsigned promotion, fortunately we have bits to spare - * as (CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN) < UINT_MAX - */ - x2 = MAX (dst->x + (int) dst->width, src->x + (int) src->width); - y2 = MAX (dst->y + (int) dst->height, src->y + (int) src->height); - - dst->x = x1; - dst->y = y1; - dst->width = x2 - x1; - dst->height = y2 - y1; -} - -#define P1x (line->p1.x) -#define P1y (line->p1.y) -#define P2x (line->p2.x) -#define P2y (line->p2.y) -#define B1x (box->p1.x) -#define B1y (box->p1.y) -#define B2x (box->p2.x) -#define B2y (box->p2.y) - -/* - * Check whether any part of line intersects box. This function essentially - * computes whether the ray starting at line->p1 in the direction of line->p2 - * intersects the box before it reaches p2. Normally, this is done - * by dividing by the lengths of the line projected onto each axis. Because - * we're in fixed point, this function does a bit more work to avoid having to - * do the division -- we don't care about the actual intersection point, so - * it's of no interest to us. - */ - -cairo_bool_t -_cairo_box_intersects_line_segment (const cairo_box_t *box, cairo_line_t *line) -{ - cairo_fixed_t t1=0, t2=0, t3=0, t4=0; - cairo_int64_t t1y, t2y, t3x, t4x; - - cairo_fixed_t xlen, ylen; - - if (_cairo_box_contains_point (box, &line->p1) || - _cairo_box_contains_point (box, &line->p2)) - return TRUE; - - xlen = P2x - P1x; - ylen = P2y - P1y; - - if (xlen) { - if (xlen > 0) { - t1 = B1x - P1x; - t2 = B2x - P1x; - } else { - t1 = P1x - B2x; - t2 = P1x - B1x; - xlen = - xlen; - } - - if ((t1 < 0 || t1 > xlen) && - (t2 < 0 || t2 > xlen)) - return FALSE; - } else { - /* Fully vertical line -- check that X is in bounds */ - if (P1x < B1x || P1x > B2x) - return FALSE; - } - - if (ylen) { - if (ylen > 0) { - t3 = B1y - P1y; - t4 = B2y - P1y; - } else { - t3 = P1y - B2y; - t4 = P1y - B1y; - ylen = - ylen; - } - - if ((t3 < 0 || t3 > ylen) && - (t4 < 0 || t4 > ylen)) - return FALSE; - } else { - /* Fully horizontal line -- check Y */ - if (P1y < B1y || P1y > B2y) - return FALSE; - } - - /* If we had a horizontal or vertical line, then it's already been checked */ - if (P1x == P2x || P1y == P2y) - return TRUE; - - /* Check overlap. Note that t1 < t2 and t3 < t4 here. */ - t1y = _cairo_int32x32_64_mul (t1, ylen); - t2y = _cairo_int32x32_64_mul (t2, ylen); - t3x = _cairo_int32x32_64_mul (t3, xlen); - t4x = _cairo_int32x32_64_mul (t4, xlen); - - if (_cairo_int64_lt(t1y, t4x) && - _cairo_int64_lt(t3x, t2y)) - return TRUE; - - return FALSE; -} - -static cairo_status_t -_cairo_box_add_spline_point (void *closure, - const cairo_point_t *point, - const cairo_slope_t *tangent) -{ - _cairo_box_add_point (closure, point); - - return CAIRO_STATUS_SUCCESS; -} - -/* assumes a has been previously added */ -void -_cairo_box_add_curve_to (cairo_box_t *extents, - const cairo_point_t *a, - const cairo_point_t *b, - const cairo_point_t *c, - const cairo_point_t *d) -{ - _cairo_box_add_point (extents, d); - if (!_cairo_box_contains_point (extents, b) || - !_cairo_box_contains_point (extents, c)) - { - cairo_status_t status; - - status = _cairo_spline_bound (_cairo_box_add_spline_point, - extents, a, b, c, d); - assert (status == CAIRO_STATUS_SUCCESS); - } -} - -void -_cairo_rectangle_int_from_double (cairo_rectangle_int_t *recti, - const cairo_rectangle_t *rectf) -{ - recti->x = floor (rectf->x); - recti->y = floor (rectf->y); - recti->width = ceil (rectf->x + rectf->width) - floor (rectf->x); - recti->height = ceil (rectf->y + rectf->height) - floor (rectf->y); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-rectangular-scan-converter.c b/source/libs/cairo/cairo-src/src/cairo-rectangular-scan-converter.c deleted file mode 100644 index e353b34e853732149061701c1b1b1682417dc04f..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-rectangular-scan-converter.c +++ /dev/null @@ -1,791 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-combsort-inline.h" -#include "cairo-error-private.h" -#include "cairo-freelist-private.h" -#include "cairo-list-private.h" -#include "cairo-spans-private.h" - -#include <setjmp.h> - -typedef struct _rectangle { - struct _rectangle *next, *prev; - cairo_fixed_t left, right; - cairo_fixed_t top, bottom; - int32_t top_y, bottom_y; - int dir; -} rectangle_t; - -#define UNROLL3(x) x x x - -/* the parent is always given by index/2 */ -#define PQ_PARENT_INDEX(i) ((i) >> 1) -#define PQ_FIRST_ENTRY 1 - -/* left and right children are index * 2 and (index * 2) +1 respectively */ -#define PQ_LEFT_CHILD_INDEX(i) ((i) << 1) - -typedef struct _pqueue { - int size, max_size; - - rectangle_t **elements; - rectangle_t *elements_embedded[1024]; -} pqueue_t; - -typedef struct { - rectangle_t **start; - pqueue_t stop; - rectangle_t head, tail; - rectangle_t *insert_cursor; - int32_t current_y; - int32_t xmin, xmax; - - struct coverage { - struct cell { - struct cell *prev, *next; - int x, covered, uncovered; - } head, tail, *cursor; - unsigned int count; - cairo_freepool_t pool; - } coverage; - - cairo_half_open_span_t spans_stack[CAIRO_STACK_ARRAY_LENGTH (cairo_half_open_span_t)]; - cairo_half_open_span_t *spans; - unsigned int num_spans; - unsigned int size_spans; - - jmp_buf jmpbuf; -} sweep_line_t; - -static inline int -rectangle_compare_start (const rectangle_t *a, - const rectangle_t *b) -{ - int cmp; - - cmp = a->top_y - b->top_y; - if (cmp) - return cmp; - - return a->left - b->left; -} - -static inline int -rectangle_compare_stop (const rectangle_t *a, - const rectangle_t *b) -{ - return a->bottom_y - b->bottom_y; -} - -static inline void -pqueue_init (pqueue_t *pq) -{ - pq->max_size = ARRAY_LENGTH (pq->elements_embedded); - pq->size = 0; - - pq->elements = pq->elements_embedded; - pq->elements[PQ_FIRST_ENTRY] = NULL; -} - -static inline void -pqueue_fini (pqueue_t *pq) -{ - if (pq->elements != pq->elements_embedded) - free (pq->elements); -} - -static cairo_bool_t -pqueue_grow (pqueue_t *pq) -{ - rectangle_t **new_elements; - pq->max_size *= 2; - - if (pq->elements == pq->elements_embedded) { - new_elements = _cairo_malloc_ab (pq->max_size, - sizeof (rectangle_t *)); - if (unlikely (new_elements == NULL)) - return FALSE; - - memcpy (new_elements, pq->elements_embedded, - sizeof (pq->elements_embedded)); - } else { - new_elements = _cairo_realloc_ab (pq->elements, - pq->max_size, - sizeof (rectangle_t *)); - if (unlikely (new_elements == NULL)) - return FALSE; - } - - pq->elements = new_elements; - return TRUE; -} - -static inline void -pqueue_push (sweep_line_t *sweep, rectangle_t *rectangle) -{ - rectangle_t **elements; - int i, parent; - - if (unlikely (sweep->stop.size + 1 == sweep->stop.max_size)) { - if (unlikely (! pqueue_grow (&sweep->stop))) - longjmp (sweep->jmpbuf, - _cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - elements = sweep->stop.elements; - for (i = ++sweep->stop.size; - i != PQ_FIRST_ENTRY && - rectangle_compare_stop (rectangle, - elements[parent = PQ_PARENT_INDEX (i)]) < 0; - i = parent) - { - elements[i] = elements[parent]; - } - - elements[i] = rectangle; -} - -static inline void -pqueue_pop (pqueue_t *pq) -{ - rectangle_t **elements = pq->elements; - rectangle_t *tail; - int child, i; - - tail = elements[pq->size--]; - if (pq->size == 0) { - elements[PQ_FIRST_ENTRY] = NULL; - return; - } - - for (i = PQ_FIRST_ENTRY; - (child = PQ_LEFT_CHILD_INDEX (i)) <= pq->size; - i = child) - { - if (child != pq->size && - rectangle_compare_stop (elements[child+1], - elements[child]) < 0) - { - child++; - } - - if (rectangle_compare_stop (elements[child], tail) >= 0) - break; - - elements[i] = elements[child]; - } - elements[i] = tail; -} - -static inline rectangle_t * -peek_stop (sweep_line_t *sweep) -{ - return sweep->stop.elements[PQ_FIRST_ENTRY]; -} - -CAIRO_COMBSORT_DECLARE (rectangle_sort, rectangle_t *, rectangle_compare_start) - -static void -sweep_line_init (sweep_line_t *sweep) -{ - sweep->head.left = INT_MIN; - sweep->head.next = &sweep->tail; - sweep->tail.left = INT_MAX; - sweep->tail.prev = &sweep->head; - sweep->insert_cursor = &sweep->tail; - - _cairo_freepool_init (&sweep->coverage.pool, sizeof (struct cell)); - - sweep->spans = sweep->spans_stack; - sweep->size_spans = ARRAY_LENGTH (sweep->spans_stack); - - sweep->coverage.head.prev = NULL; - sweep->coverage.head.x = INT_MIN; - sweep->coverage.tail.next = NULL; - sweep->coverage.tail.x = INT_MAX; - - pqueue_init (&sweep->stop); -} - -static void -sweep_line_fini (sweep_line_t *sweep) -{ - _cairo_freepool_fini (&sweep->coverage.pool); - pqueue_fini (&sweep->stop); - - if (sweep->spans != sweep->spans_stack) - free (sweep->spans); -} - -static inline void -add_cell (sweep_line_t *sweep, int x, int covered, int uncovered) -{ - struct cell *cell; - - cell = sweep->coverage.cursor; - if (cell->x > x) { - do { - UNROLL3({ - if (cell->prev->x < x) - break; - cell = cell->prev; - }) - } while (TRUE); - } else { - if (cell->x == x) - goto found; - - do { - UNROLL3({ - cell = cell->next; - if (cell->x >= x) - break; - }) - } while (TRUE); - } - - if (x != cell->x) { - struct cell *c; - - sweep->coverage.count++; - - c = _cairo_freepool_alloc (&sweep->coverage.pool); - if (unlikely (c == NULL)) { - longjmp (sweep->jmpbuf, - _cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - cell->prev->next = c; - c->prev = cell->prev; - c->next = cell; - cell->prev = c; - - c->x = x; - c->covered = 0; - c->uncovered = 0; - - cell = c; - } - -found: - cell->covered += covered; - cell->uncovered += uncovered; - sweep->coverage.cursor = cell; -} - -static inline void -_active_edges_to_spans (sweep_line_t *sweep) -{ - int32_t y = sweep->current_y; - rectangle_t *rectangle; - int coverage, prev_coverage; - int prev_x; - struct cell *cell; - - sweep->num_spans = 0; - if (sweep->head.next == &sweep->tail) - return; - - sweep->coverage.head.next = &sweep->coverage.tail; - sweep->coverage.tail.prev = &sweep->coverage.head; - sweep->coverage.cursor = &sweep->coverage.tail; - sweep->coverage.count = 0; - - /* XXX cell coverage only changes when a rectangle appears or - * disappears. Try only modifying coverage at such times. - */ - for (rectangle = sweep->head.next; - rectangle != &sweep->tail; - rectangle = rectangle->next) - { - int height; - int frac, i; - - if (y == rectangle->bottom_y) { - height = rectangle->bottom & CAIRO_FIXED_FRAC_MASK; - if (height == 0) - continue; - } else - height = CAIRO_FIXED_ONE; - if (y == rectangle->top_y) - height -= rectangle->top & CAIRO_FIXED_FRAC_MASK; - height *= rectangle->dir; - - i = _cairo_fixed_integer_part (rectangle->left), - frac = _cairo_fixed_fractional_part (rectangle->left); - add_cell (sweep, i, - (CAIRO_FIXED_ONE-frac) * height, - frac * height); - - i = _cairo_fixed_integer_part (rectangle->right), - frac = _cairo_fixed_fractional_part (rectangle->right); - add_cell (sweep, i, - -(CAIRO_FIXED_ONE-frac) * height, - -frac * height); - } - - if (2*sweep->coverage.count >= sweep->size_spans) { - unsigned size; - - size = sweep->size_spans; - while (size <= 2*sweep->coverage.count) - size <<= 1; - - if (sweep->spans != sweep->spans_stack) - free (sweep->spans); - - sweep->spans = _cairo_malloc_ab (size, sizeof (cairo_half_open_span_t)); - if (unlikely (sweep->spans == NULL)) - longjmp (sweep->jmpbuf, _cairo_error (CAIRO_STATUS_NO_MEMORY)); - - sweep->size_spans = size; - } - - prev_coverage = coverage = 0; - prev_x = INT_MIN; - for (cell = sweep->coverage.head.next; cell != &sweep->coverage.tail; cell = cell->next) { - if (cell->x != prev_x && coverage != prev_coverage) { - int n = sweep->num_spans++; - int c = coverage >> (CAIRO_FIXED_FRAC_BITS * 2 - 8); - sweep->spans[n].x = prev_x; - sweep->spans[n].inverse = 0; - sweep->spans[n].coverage = c - (c >> 8); - prev_coverage = coverage; - } - - coverage += cell->covered; - if (coverage != prev_coverage) { - int n = sweep->num_spans++; - int c = coverage >> (CAIRO_FIXED_FRAC_BITS * 2 - 8); - sweep->spans[n].x = cell->x; - sweep->spans[n].inverse = 0; - sweep->spans[n].coverage = c - (c >> 8); - prev_coverage = coverage; - } - coverage += cell->uncovered; - prev_x = cell->x + 1; - } - _cairo_freepool_reset (&sweep->coverage.pool); - - if (sweep->num_spans) { - if (prev_x <= sweep->xmax) { - int n = sweep->num_spans++; - int c = coverage >> (CAIRO_FIXED_FRAC_BITS * 2 - 8); - sweep->spans[n].x = prev_x; - sweep->spans[n].inverse = 0; - sweep->spans[n].coverage = c - (c >> 8); - } - - if (coverage && prev_x < sweep->xmax) { - int n = sweep->num_spans++; - sweep->spans[n].x = sweep->xmax; - sweep->spans[n].inverse = 1; - sweep->spans[n].coverage = 0; - } - } -} - -static inline void -sweep_line_delete (sweep_line_t *sweep, - rectangle_t *rectangle) -{ - if (sweep->insert_cursor == rectangle) - sweep->insert_cursor = rectangle->next; - - rectangle->prev->next = rectangle->next; - rectangle->next->prev = rectangle->prev; - - pqueue_pop (&sweep->stop); -} - -static inline void -sweep_line_insert (sweep_line_t *sweep, - rectangle_t *rectangle) -{ - rectangle_t *pos; - - pos = sweep->insert_cursor; - if (pos->left != rectangle->left) { - if (pos->left > rectangle->left) { - do { - UNROLL3({ - if (pos->prev->left < rectangle->left) - break; - pos = pos->prev; - }) - } while (TRUE); - } else { - do { - UNROLL3({ - pos = pos->next; - if (pos->left >= rectangle->left) - break; - }); - } while (TRUE); - } - } - - pos->prev->next = rectangle; - rectangle->prev = pos->prev; - rectangle->next = pos; - pos->prev = rectangle; - sweep->insert_cursor = rectangle; - - pqueue_push (sweep, rectangle); -} - -static void -render_rows (sweep_line_t *sweep_line, - cairo_span_renderer_t *renderer, - int height) -{ - cairo_status_t status; - - _active_edges_to_spans (sweep_line); - - status = renderer->render_rows (renderer, - sweep_line->current_y, height, - sweep_line->spans, - sweep_line->num_spans); - if (unlikely (status)) - longjmp (sweep_line->jmpbuf, status); -} - -static cairo_status_t -generate (cairo_rectangular_scan_converter_t *self, - cairo_span_renderer_t *renderer, - rectangle_t **rectangles) -{ - sweep_line_t sweep_line; - rectangle_t *start, *stop; - cairo_status_t status; - - sweep_line_init (&sweep_line); - sweep_line.xmin = _cairo_fixed_integer_part (self->extents.p1.x); - sweep_line.xmax = _cairo_fixed_integer_part (self->extents.p2.x); - sweep_line.start = rectangles; - if ((status = setjmp (sweep_line.jmpbuf))) - goto out; - - sweep_line.current_y = _cairo_fixed_integer_part (self->extents.p1.y); - start = *sweep_line.start++; - do { - if (start->top_y != sweep_line.current_y) { - render_rows (&sweep_line, renderer, - start->top_y - sweep_line.current_y); - sweep_line.current_y = start->top_y; - } - - do { - sweep_line_insert (&sweep_line, start); - start = *sweep_line.start++; - if (start == NULL) - goto end; - if (start->top_y != sweep_line.current_y) - break; - } while (TRUE); - - render_rows (&sweep_line, renderer, 1); - - stop = peek_stop (&sweep_line); - while (stop->bottom_y == sweep_line.current_y) { - sweep_line_delete (&sweep_line, stop); - stop = peek_stop (&sweep_line); - if (stop == NULL) - break; - } - - sweep_line.current_y++; - - while (stop != NULL && stop->bottom_y < start->top_y) { - if (stop->bottom_y != sweep_line.current_y) { - render_rows (&sweep_line, renderer, - stop->bottom_y - sweep_line.current_y); - sweep_line.current_y = stop->bottom_y; - } - - render_rows (&sweep_line, renderer, 1); - - do { - sweep_line_delete (&sweep_line, stop); - stop = peek_stop (&sweep_line); - } while (stop != NULL && stop->bottom_y == sweep_line.current_y); - - sweep_line.current_y++; - } - } while (TRUE); - - end: - render_rows (&sweep_line, renderer, 1); - - stop = peek_stop (&sweep_line); - while (stop->bottom_y == sweep_line.current_y) { - sweep_line_delete (&sweep_line, stop); - stop = peek_stop (&sweep_line); - if (stop == NULL) - goto out; - } - - while (++sweep_line.current_y < _cairo_fixed_integer_part (self->extents.p2.y)) { - if (stop->bottom_y != sweep_line.current_y) { - render_rows (&sweep_line, renderer, - stop->bottom_y - sweep_line.current_y); - sweep_line.current_y = stop->bottom_y; - } - - render_rows (&sweep_line, renderer, 1); - - do { - sweep_line_delete (&sweep_line, stop); - stop = peek_stop (&sweep_line); - if (stop == NULL) - goto out; - } while (stop->bottom_y == sweep_line.current_y); - - } - - out: - sweep_line_fini (&sweep_line); - - return status; -} -static void generate_row(cairo_span_renderer_t *renderer, - const rectangle_t *r, - int y, int h, - uint16_t coverage) -{ - cairo_half_open_span_t spans[4]; - unsigned int num_spans = 0; - int x1 = _cairo_fixed_integer_part (r->left); - int x2 = _cairo_fixed_integer_part (r->right); - if (x2 > x1) { - if (! _cairo_fixed_is_integer (r->left)) { - spans[num_spans].x = x1; - spans[num_spans].coverage = - coverage * (256 - _cairo_fixed_fractional_part (r->left)) >> 8; - num_spans++; - x1++; - } - - if (x2 > x1) { - spans[num_spans].x = x1; - spans[num_spans].coverage = coverage - (coverage >> 8); - num_spans++; - } - - if (! _cairo_fixed_is_integer (r->right)) { - spans[num_spans].x = x2++; - spans[num_spans].coverage = - coverage * _cairo_fixed_fractional_part (r->right) >> 8; - num_spans++; - } - } else { - spans[num_spans].x = x2++; - spans[num_spans].coverage = coverage * (r->right - r->left) >> 8; - num_spans++; - } - - spans[num_spans].x = x2; - spans[num_spans].coverage = 0; - num_spans++; - - renderer->render_rows (renderer, y, h, spans, num_spans); -} - -static cairo_status_t -generate_box (cairo_rectangular_scan_converter_t *self, - cairo_span_renderer_t *renderer) -{ - const rectangle_t *r = self->chunks.base; - int y1 = _cairo_fixed_integer_part (r->top); - int y2 = _cairo_fixed_integer_part (r->bottom); - if (y2 > y1) { - if (! _cairo_fixed_is_integer (r->top)) { - generate_row(renderer, r, y1, 1, - 256 - _cairo_fixed_fractional_part (r->top)); - y1++; - } - - if (y2 > y1) - generate_row(renderer, r, y1, y2-y1, 256); - - if (! _cairo_fixed_is_integer (r->bottom)) - generate_row(renderer, r, y2, 1, - _cairo_fixed_fractional_part (r->bottom)); - } else - generate_row(renderer, r, y1, 1, r->bottom - r->top); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_rectangular_scan_converter_generate (void *converter, - cairo_span_renderer_t *renderer) -{ - cairo_rectangular_scan_converter_t *self = converter; - rectangle_t *rectangles_stack[CAIRO_STACK_ARRAY_LENGTH (rectangle_t *)]; - rectangle_t **rectangles; - struct _cairo_rectangular_scan_converter_chunk *chunk; - cairo_status_t status; - int i, j; - - if (unlikely (self->num_rectangles == 0)) { - return renderer->render_rows (renderer, - _cairo_fixed_integer_part (self->extents.p1.y), - _cairo_fixed_integer_part (self->extents.p2.y - self->extents.p1.y), - NULL, 0); - } - - if (self->num_rectangles == 1) - return generate_box (self, renderer); - - rectangles = rectangles_stack; - if (unlikely (self->num_rectangles >= ARRAY_LENGTH (rectangles_stack))) { - rectangles = _cairo_malloc_ab (self->num_rectangles + 1, - sizeof (rectangle_t *)); - if (unlikely (rectangles == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - j = 0; - for (chunk = &self->chunks; chunk != NULL; chunk = chunk->next) { - rectangle_t *rectangle; - - rectangle = chunk->base; - for (i = 0; i < chunk->count; i++) - rectangles[j++] = &rectangle[i]; - } - rectangle_sort (rectangles, j); - rectangles[j] = NULL; - - status = generate (self, renderer, rectangles); - - if (rectangles != rectangles_stack) - free (rectangles); - - return status; -} - -static rectangle_t * -_allocate_rectangle (cairo_rectangular_scan_converter_t *self) -{ - rectangle_t *rectangle; - struct _cairo_rectangular_scan_converter_chunk *chunk; - - chunk = self->tail; - if (chunk->count == chunk->size) { - int size; - - size = chunk->size * 2; - chunk->next = _cairo_malloc_ab_plus_c (size, - sizeof (rectangle_t), - sizeof (struct _cairo_rectangular_scan_converter_chunk)); - - if (unlikely (chunk->next == NULL)) - return NULL; - - chunk = chunk->next; - chunk->next = NULL; - chunk->count = 0; - chunk->size = size; - chunk->base = chunk + 1; - self->tail = chunk; - } - - rectangle = chunk->base; - return rectangle + chunk->count++; -} - -cairo_status_t -_cairo_rectangular_scan_converter_add_box (cairo_rectangular_scan_converter_t *self, - const cairo_box_t *box, - int dir) -{ - rectangle_t *rectangle; - - rectangle = _allocate_rectangle (self); - if (unlikely (rectangle == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - rectangle->dir = dir; - rectangle->left = MAX (box->p1.x, self->extents.p1.x); - rectangle->right = MIN (box->p2.x, self->extents.p2.x); - if (unlikely (rectangle->right <= rectangle->left)) { - self->tail->count--; - return CAIRO_STATUS_SUCCESS; - } - - rectangle->top = MAX (box->p1.y, self->extents.p1.y); - rectangle->top_y = _cairo_fixed_integer_floor (rectangle->top); - rectangle->bottom = MIN (box->p2.y, self->extents.p2.y); - rectangle->bottom_y = _cairo_fixed_integer_floor (rectangle->bottom); - if (likely (rectangle->bottom > rectangle->top)) - self->num_rectangles++; - else - self->tail->count--; - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_rectangular_scan_converter_destroy (void *converter) -{ - cairo_rectangular_scan_converter_t *self = converter; - struct _cairo_rectangular_scan_converter_chunk *chunk, *next; - - for (chunk = self->chunks.next; chunk != NULL; chunk = next) { - next = chunk->next; - free (chunk); - } -} - -void -_cairo_rectangular_scan_converter_init (cairo_rectangular_scan_converter_t *self, - const cairo_rectangle_int_t *extents) -{ - self->base.destroy = _cairo_rectangular_scan_converter_destroy; - self->base.generate = _cairo_rectangular_scan_converter_generate; - - _cairo_box_from_rectangle (&self->extents, extents); - - self->chunks.base = self->buf; - self->chunks.next = NULL; - self->chunks.count = 0; - self->chunks.size = sizeof (self->buf) / sizeof (rectangle_t); - self->tail = &self->chunks; - - self->num_rectangles = 0; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-reference-count-private.h b/source/libs/cairo/cairo-src/src/cairo-reference-count-private.h deleted file mode 100644 index 75fdf3538f572449910c599b0e04e023a6a63529..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-reference-count-private.h +++ /dev/null @@ -1,62 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2007 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_REFRENCE_COUNT_PRIVATE_H -#define CAIRO_REFRENCE_COUNT_PRIVATE_H - -#include "cairo-atomic-private.h" - -/* Encapsulate operations on the object's reference count */ -typedef struct { - cairo_atomic_int_t ref_count; -} cairo_reference_count_t; - -#define _cairo_reference_count_inc(RC) _cairo_atomic_int_inc (&(RC)->ref_count) -#define _cairo_reference_count_dec(RC) _cairo_atomic_int_dec (&(RC)->ref_count) -#define _cairo_reference_count_dec_and_test(RC) _cairo_atomic_int_dec_and_test (&(RC)->ref_count) - -#define CAIRO_REFERENCE_COUNT_INIT(RC, VALUE) ((RC)->ref_count = (VALUE)) - -#define CAIRO_REFERENCE_COUNT_GET_VALUE(RC) _cairo_atomic_int_get (&(RC)->ref_count) - -#define CAIRO_REFERENCE_COUNT_INVALID_VALUE ((cairo_atomic_int_t) -1) -#define CAIRO_REFERENCE_COUNT_INVALID {CAIRO_REFERENCE_COUNT_INVALID_VALUE} - -#define CAIRO_REFERENCE_COUNT_IS_INVALID(RC) (CAIRO_REFERENCE_COUNT_GET_VALUE (RC) == CAIRO_REFERENCE_COUNT_INVALID_VALUE) - -#define CAIRO_REFERENCE_COUNT_HAS_REFERENCE(RC) (CAIRO_REFERENCE_COUNT_GET_VALUE (RC) > 0) - -#endif diff --git a/source/libs/cairo/cairo-src/src/cairo-region-private.h b/source/libs/cairo/cairo-src/src/cairo-region-private.h deleted file mode 100644 index 549e508789825bdb6b3a4d32e9574d74e463a2a3..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-region-private.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2005 Red Hat, Inc. - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Owen Taylor <otaylor@redhat.com> - * Vladimir Vukicevic <vladimir@pobox.com> - * Søren Sandmann <sandmann@daimi.au.dk> - */ - -#ifndef CAIRO_REGION_PRIVATE_H -#define CAIRO_REGION_PRIVATE_H - -#include "cairo-types-private.h" -#include "cairo-reference-count-private.h" - -#include <pixman.h> - -CAIRO_BEGIN_DECLS - -struct _cairo_region { - cairo_reference_count_t ref_count; - cairo_status_t status; - - pixman_region32_t rgn; -}; - -cairo_private cairo_region_t * -_cairo_region_create_in_error (cairo_status_t status); - -cairo_private void -_cairo_region_init (cairo_region_t *region); - -cairo_private void -_cairo_region_init_rectangle (cairo_region_t *region, - const cairo_rectangle_int_t *rectangle); - -cairo_private void -_cairo_region_fini (cairo_region_t *region); - -cairo_private cairo_region_t * -_cairo_region_create_from_boxes (const cairo_box_t *boxes, int count); - -cairo_private cairo_box_t * -_cairo_region_get_boxes (const cairo_region_t *region, int *nbox); - -CAIRO_END_DECLS - -#endif /* CAIRO_REGION_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-region.c b/source/libs/cairo/cairo-src/src/cairo-region.c deleted file mode 100644 index ccfb2200e14f6007db9cf07b363f58288aebe736..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-region.c +++ /dev/null @@ -1,939 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2005 Red Hat, Inc. - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Owen Taylor <otaylor@redhat.com> - * Vladimir Vukicevic <vladimir@pobox.com> - * Søren Sandmann <sandmann@daimi.au.dk> - */ - -#include "cairoint.h" - -#include "cairo-error-private.h" -#include "cairo-region-private.h" - -/* XXX need to update pixman headers to be const as appropriate */ -#define CONST_CAST (pixman_region32_t *) - -/** - * SECTION:cairo-region - * @Title: Regions - * @Short_Description: Representing a pixel-aligned area - * - * Regions are a simple graphical data type representing an area of - * integer-aligned rectangles. They are often used on raster surfaces - * to track areas of interest, such as change or clip areas. - **/ - -static const cairo_region_t _cairo_region_nil = { - CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ - CAIRO_STATUS_NO_MEMORY, /* status */ -}; - -cairo_region_t * -_cairo_region_create_in_error (cairo_status_t status) -{ - switch (status) { - case CAIRO_STATUS_NO_MEMORY: - return (cairo_region_t *) &_cairo_region_nil; - - case CAIRO_STATUS_SUCCESS: - case CAIRO_STATUS_LAST_STATUS: - ASSERT_NOT_REACHED; - /* fall-through */ - case CAIRO_STATUS_SURFACE_TYPE_MISMATCH: - case CAIRO_STATUS_INVALID_STATUS: - case CAIRO_STATUS_INVALID_CONTENT: - case CAIRO_STATUS_INVALID_FORMAT: - case CAIRO_STATUS_INVALID_VISUAL: - case CAIRO_STATUS_READ_ERROR: - case CAIRO_STATUS_WRITE_ERROR: - case CAIRO_STATUS_FILE_NOT_FOUND: - case CAIRO_STATUS_TEMP_FILE_ERROR: - case CAIRO_STATUS_INVALID_STRIDE: - case CAIRO_STATUS_INVALID_SIZE: - case CAIRO_STATUS_DEVICE_TYPE_MISMATCH: - case CAIRO_STATUS_DEVICE_ERROR: - case CAIRO_STATUS_INVALID_RESTORE: - case CAIRO_STATUS_INVALID_POP_GROUP: - case CAIRO_STATUS_NO_CURRENT_POINT: - case CAIRO_STATUS_INVALID_MATRIX: - case CAIRO_STATUS_NULL_POINTER: - case CAIRO_STATUS_INVALID_STRING: - case CAIRO_STATUS_INVALID_PATH_DATA: - case CAIRO_STATUS_SURFACE_FINISHED: - case CAIRO_STATUS_PATTERN_TYPE_MISMATCH: - case CAIRO_STATUS_INVALID_DASH: - case CAIRO_STATUS_INVALID_DSC_COMMENT: - case CAIRO_STATUS_INVALID_INDEX: - case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE: - case CAIRO_STATUS_FONT_TYPE_MISMATCH: - case CAIRO_STATUS_USER_FONT_IMMUTABLE: - case CAIRO_STATUS_USER_FONT_ERROR: - case CAIRO_STATUS_NEGATIVE_COUNT: - case CAIRO_STATUS_INVALID_CLUSTERS: - case CAIRO_STATUS_INVALID_SLANT: - case CAIRO_STATUS_INVALID_WEIGHT: - case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: - case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION: - case CAIRO_STATUS_DEVICE_FINISHED: - case CAIRO_STATUS_JBIG2_GLOBAL_MISSING: - default: - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_region_t *) &_cairo_region_nil; - } -} - -/** - * _cairo_region_set_error: - * @region: a region - * @status: a status value indicating an error - * - * Atomically sets region->status to @status and calls _cairo_error; - * Does nothing if status is %CAIRO_STATUS_SUCCESS or any of the internal - * status values. - * - * All assignments of an error status to region->status should happen - * through _cairo_region_set_error(). Note that due to the nature of - * the atomic operation, it is not safe to call this function on the - * nil objects. - * - * The purpose of this function is to allow the user to set a - * breakpoint in _cairo_error() to generate a stack trace for when the - * user causes cairo to detect an error. - * - * Return value: the error status. - **/ -static cairo_status_t -_cairo_region_set_error (cairo_region_t *region, - cairo_status_t status) -{ - if (status == CAIRO_STATUS_SUCCESS) - return CAIRO_STATUS_SUCCESS; - - /* Don't overwrite an existing error. This preserves the first - * error, which is the most significant. */ - _cairo_status_set_error (®ion->status, status); - - return _cairo_error (status); -} - -void -_cairo_region_init (cairo_region_t *region) -{ - VG (VALGRIND_MAKE_MEM_UNDEFINED (region, sizeof (cairo_region_t))); - - region->status = CAIRO_STATUS_SUCCESS; - CAIRO_REFERENCE_COUNT_INIT (®ion->ref_count, 0); - pixman_region32_init (®ion->rgn); -} - -void -_cairo_region_init_rectangle (cairo_region_t *region, - const cairo_rectangle_int_t *rectangle) -{ - VG (VALGRIND_MAKE_MEM_UNDEFINED (region, sizeof (cairo_region_t))); - - region->status = CAIRO_STATUS_SUCCESS; - CAIRO_REFERENCE_COUNT_INIT (®ion->ref_count, 0); - pixman_region32_init_rect (®ion->rgn, - rectangle->x, rectangle->y, - rectangle->width, rectangle->height); -} - -void -_cairo_region_fini (cairo_region_t *region) -{ - assert (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (®ion->ref_count)); - pixman_region32_fini (®ion->rgn); - VG (VALGRIND_MAKE_MEM_NOACCESS (region, sizeof (cairo_region_t))); -} - -/** - * cairo_region_create: - * - * Allocates a new empty region object. - * - * Return value: A newly allocated #cairo_region_t. Free with - * cairo_region_destroy(). This function always returns a - * valid pointer; if memory cannot be allocated, then a special - * error object is returned where all operations on the object do nothing. - * You can check for this with cairo_region_status(). - * - * Since: 1.10 - **/ -cairo_region_t * -cairo_region_create (void) -{ - cairo_region_t *region; - - region = _cairo_malloc (sizeof (cairo_region_t)); - if (region == NULL) - return (cairo_region_t *) &_cairo_region_nil; - - region->status = CAIRO_STATUS_SUCCESS; - CAIRO_REFERENCE_COUNT_INIT (®ion->ref_count, 1); - - pixman_region32_init (®ion->rgn); - - return region; -} -slim_hidden_def (cairo_region_create); - -/** - * cairo_region_create_rectangles: - * @rects: an array of @count rectangles - * @count: number of rectangles - * - * Allocates a new region object containing the union of all given @rects. - * - * Return value: A newly allocated #cairo_region_t. Free with - * cairo_region_destroy(). This function always returns a - * valid pointer; if memory cannot be allocated, then a special - * error object is returned where all operations on the object do nothing. - * You can check for this with cairo_region_status(). - * - * Since: 1.10 - **/ -cairo_region_t * -cairo_region_create_rectangles (const cairo_rectangle_int_t *rects, - int count) -{ - pixman_box32_t stack_pboxes[CAIRO_STACK_ARRAY_LENGTH (pixman_box32_t)]; - pixman_box32_t *pboxes = stack_pboxes; - cairo_region_t *region; - int i; - - region = _cairo_malloc (sizeof (cairo_region_t)); - if (unlikely (region == NULL)) - return _cairo_region_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - CAIRO_REFERENCE_COUNT_INIT (®ion->ref_count, 1); - region->status = CAIRO_STATUS_SUCCESS; - - if (count == 1) { - pixman_region32_init_rect (®ion->rgn, - rects->x, rects->y, - rects->width, rects->height); - - return region; - } - - if (count > ARRAY_LENGTH (stack_pboxes)) { - pboxes = _cairo_malloc_ab (count, sizeof (pixman_box32_t)); - if (unlikely (pboxes == NULL)) { - free (region); - return _cairo_region_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - } - - for (i = 0; i < count; i++) { - pboxes[i].x1 = rects[i].x; - pboxes[i].y1 = rects[i].y; - pboxes[i].x2 = rects[i].x + rects[i].width; - pboxes[i].y2 = rects[i].y + rects[i].height; - } - - i = pixman_region32_init_rects (®ion->rgn, pboxes, count); - - if (pboxes != stack_pboxes) - free (pboxes); - - if (unlikely (i == 0)) { - free (region); - return _cairo_region_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - return region; -} -slim_hidden_def (cairo_region_create_rectangles); - -cairo_region_t * -_cairo_region_create_from_boxes (const cairo_box_t *boxes, int count) -{ - cairo_region_t *region; - - region = _cairo_malloc (sizeof (cairo_region_t)); - if (unlikely (region == NULL)) - return _cairo_region_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - CAIRO_REFERENCE_COUNT_INIT (®ion->ref_count, 1); - region->status = CAIRO_STATUS_SUCCESS; - - if (! pixman_region32_init_rects (®ion->rgn, - (pixman_box32_t *)boxes, count)) { - free (region); - return _cairo_region_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - return region; -} - -cairo_box_t * -_cairo_region_get_boxes (const cairo_region_t *region, int *nbox) -{ - if (region->status) { - nbox = 0; - return NULL; - } - - return (cairo_box_t *) pixman_region32_rectangles (CONST_CAST ®ion->rgn, nbox); -} - -/** - * cairo_region_create_rectangle: - * @rectangle: a #cairo_rectangle_int_t - * - * Allocates a new region object containing @rectangle. - * - * Return value: A newly allocated #cairo_region_t. Free with - * cairo_region_destroy(). This function always returns a - * valid pointer; if memory cannot be allocated, then a special - * error object is returned where all operations on the object do nothing. - * You can check for this with cairo_region_status(). - * - * Since: 1.10 - **/ -cairo_region_t * -cairo_region_create_rectangle (const cairo_rectangle_int_t *rectangle) -{ - cairo_region_t *region; - - region = _cairo_malloc (sizeof (cairo_region_t)); - if (unlikely (region == NULL)) - return (cairo_region_t *) &_cairo_region_nil; - - region->status = CAIRO_STATUS_SUCCESS; - CAIRO_REFERENCE_COUNT_INIT (®ion->ref_count, 1); - - pixman_region32_init_rect (®ion->rgn, - rectangle->x, rectangle->y, - rectangle->width, rectangle->height); - - return region; -} -slim_hidden_def (cairo_region_create_rectangle); - -/** - * cairo_region_copy: - * @original: a #cairo_region_t - * - * Allocates a new region object copying the area from @original. - * - * Return value: A newly allocated #cairo_region_t. Free with - * cairo_region_destroy(). This function always returns a - * valid pointer; if memory cannot be allocated, then a special - * error object is returned where all operations on the object do nothing. - * You can check for this with cairo_region_status(). - * - * Since: 1.10 - **/ -cairo_region_t * -cairo_region_copy (const cairo_region_t *original) -{ - cairo_region_t *copy; - - if (original != NULL && original->status) - return (cairo_region_t *) &_cairo_region_nil; - - copy = cairo_region_create (); - if (unlikely (copy->status)) - return copy; - - if (original != NULL && - ! pixman_region32_copy (©->rgn, CONST_CAST &original->rgn)) - { - cairo_region_destroy (copy); - return (cairo_region_t *) &_cairo_region_nil; - } - - return copy; -} -slim_hidden_def (cairo_region_copy); - -/** - * cairo_region_reference: - * @region: a #cairo_region_t - * - * Increases the reference count on @region by one. This prevents - * @region from being destroyed until a matching call to - * cairo_region_destroy() is made. - * - * Return value: the referenced #cairo_region_t. - * - * Since: 1.10 - **/ -cairo_region_t * -cairo_region_reference (cairo_region_t *region) -{ - if (region == NULL || CAIRO_REFERENCE_COUNT_IS_INVALID (®ion->ref_count)) - return NULL; - - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (®ion->ref_count)); - - _cairo_reference_count_inc (®ion->ref_count); - return region; -} -slim_hidden_def (cairo_region_reference); - -/** - * cairo_region_destroy: - * @region: a #cairo_region_t - * - * Destroys a #cairo_region_t object created with - * cairo_region_create(), cairo_region_copy(), or - * or cairo_region_create_rectangle(). - * - * Since: 1.10 - **/ -void -cairo_region_destroy (cairo_region_t *region) -{ - if (region == NULL || CAIRO_REFERENCE_COUNT_IS_INVALID (®ion->ref_count)) - return; - - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (®ion->ref_count)); - - if (! _cairo_reference_count_dec_and_test (®ion->ref_count)) - return; - - _cairo_region_fini (region); - free (region); -} -slim_hidden_def (cairo_region_destroy); - -/** - * cairo_region_num_rectangles: - * @region: a #cairo_region_t - * - * Returns the number of rectangles contained in @region. - * - * Return value: The number of rectangles contained in @region. - * - * Since: 1.10 - **/ -int -cairo_region_num_rectangles (const cairo_region_t *region) -{ - if (region->status) - return 0; - - return pixman_region32_n_rects (CONST_CAST ®ion->rgn); -} -slim_hidden_def (cairo_region_num_rectangles); - -/** - * cairo_region_get_rectangle: - * @region: a #cairo_region_t - * @nth: a number indicating which rectangle should be returned - * @rectangle: return location for a #cairo_rectangle_int_t - * - * Stores the @nth rectangle from the region in @rectangle. - * - * Since: 1.10 - **/ -void -cairo_region_get_rectangle (const cairo_region_t *region, - int nth, - cairo_rectangle_int_t *rectangle) -{ - pixman_box32_t *pbox; - - if (region->status) { - rectangle->x = rectangle->y = 0; - rectangle->width = rectangle->height = 0; - return; - } - - pbox = pixman_region32_rectangles (CONST_CAST ®ion->rgn, NULL) + nth; - - rectangle->x = pbox->x1; - rectangle->y = pbox->y1; - rectangle->width = pbox->x2 - pbox->x1; - rectangle->height = pbox->y2 - pbox->y1; -} -slim_hidden_def (cairo_region_get_rectangle); - -/** - * cairo_region_get_extents: - * @region: a #cairo_region_t - * @extents: rectangle into which to store the extents - * - * Gets the bounding rectangle of @region as a #cairo_rectangle_int_t - * - * Since: 1.10 - **/ -void -cairo_region_get_extents (const cairo_region_t *region, - cairo_rectangle_int_t *extents) -{ - pixman_box32_t *pextents; - - if (region->status) { - extents->x = extents->y = 0; - extents->width = extents->height = 0; - return; - } - - pextents = pixman_region32_extents (CONST_CAST ®ion->rgn); - - extents->x = pextents->x1; - extents->y = pextents->y1; - extents->width = pextents->x2 - pextents->x1; - extents->height = pextents->y2 - pextents->y1; -} -slim_hidden_def (cairo_region_get_extents); - -/** - * cairo_region_status: - * @region: a #cairo_region_t - * - * Checks whether an error has previous occurred for this - * region object. - * - * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY - * - * Since: 1.10 - **/ -cairo_status_t -cairo_region_status (const cairo_region_t *region) -{ - return region->status; -} -slim_hidden_def (cairo_region_status); - -/** - * cairo_region_subtract: - * @dst: a #cairo_region_t - * @other: another #cairo_region_t - * - * Subtracts @other from @dst and places the result in @dst - * - * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY - * - * Since: 1.10 - **/ -cairo_status_t -cairo_region_subtract (cairo_region_t *dst, const cairo_region_t *other) -{ - if (dst->status) - return dst->status; - - if (other->status) - return _cairo_region_set_error (dst, other->status); - - if (! pixman_region32_subtract (&dst->rgn, - &dst->rgn, - CONST_CAST &other->rgn)) - { - return _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); - } - - return CAIRO_STATUS_SUCCESS; -} -slim_hidden_def (cairo_region_subtract); - -/** - * cairo_region_subtract_rectangle: - * @dst: a #cairo_region_t - * @rectangle: a #cairo_rectangle_int_t - * - * Subtracts @rectangle from @dst and places the result in @dst - * - * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY - * - * Since: 1.10 - **/ -cairo_status_t -cairo_region_subtract_rectangle (cairo_region_t *dst, - const cairo_rectangle_int_t *rectangle) -{ - cairo_status_t status = CAIRO_STATUS_SUCCESS; - pixman_region32_t region; - - if (dst->status) - return dst->status; - - pixman_region32_init_rect (®ion, - rectangle->x, rectangle->y, - rectangle->width, rectangle->height); - - if (! pixman_region32_subtract (&dst->rgn, &dst->rgn, ®ion)) - status = _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); - - pixman_region32_fini (®ion); - - return status; -} -slim_hidden_def (cairo_region_subtract_rectangle); - -/** - * cairo_region_intersect: - * @dst: a #cairo_region_t - * @other: another #cairo_region_t - * - * Computes the intersection of @dst with @other and places the result in @dst - * - * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY - * - * Since: 1.10 - **/ -cairo_status_t -cairo_region_intersect (cairo_region_t *dst, const cairo_region_t *other) -{ - if (dst->status) - return dst->status; - - if (other->status) - return _cairo_region_set_error (dst, other->status); - - if (! pixman_region32_intersect (&dst->rgn, &dst->rgn, CONST_CAST &other->rgn)) - return _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); - - return CAIRO_STATUS_SUCCESS; -} -slim_hidden_def (cairo_region_intersect); - -/** - * cairo_region_intersect_rectangle: - * @dst: a #cairo_region_t - * @rectangle: a #cairo_rectangle_int_t - * - * Computes the intersection of @dst with @rectangle and places the - * result in @dst - * - * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY - * - * Since: 1.10 - **/ -cairo_status_t -cairo_region_intersect_rectangle (cairo_region_t *dst, - const cairo_rectangle_int_t *rectangle) -{ - cairo_status_t status = CAIRO_STATUS_SUCCESS; - pixman_region32_t region; - - if (dst->status) - return dst->status; - - pixman_region32_init_rect (®ion, - rectangle->x, rectangle->y, - rectangle->width, rectangle->height); - - if (! pixman_region32_intersect (&dst->rgn, &dst->rgn, ®ion)) - status = _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); - - pixman_region32_fini (®ion); - - return status; -} -slim_hidden_def (cairo_region_intersect_rectangle); - -/** - * cairo_region_union: - * @dst: a #cairo_region_t - * @other: another #cairo_region_t - * - * Computes the union of @dst with @other and places the result in @dst - * - * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY - * - * Since: 1.10 - **/ -cairo_status_t -cairo_region_union (cairo_region_t *dst, - const cairo_region_t *other) -{ - if (dst->status) - return dst->status; - - if (other->status) - return _cairo_region_set_error (dst, other->status); - - if (! pixman_region32_union (&dst->rgn, &dst->rgn, CONST_CAST &other->rgn)) - return _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); - - return CAIRO_STATUS_SUCCESS; -} -slim_hidden_def (cairo_region_union); - -/** - * cairo_region_union_rectangle: - * @dst: a #cairo_region_t - * @rectangle: a #cairo_rectangle_int_t - * - * Computes the union of @dst with @rectangle and places the result in @dst. - * - * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY - * - * Since: 1.10 - **/ -cairo_status_t -cairo_region_union_rectangle (cairo_region_t *dst, - const cairo_rectangle_int_t *rectangle) -{ - cairo_status_t status = CAIRO_STATUS_SUCCESS; - pixman_region32_t region; - - if (dst->status) - return dst->status; - - pixman_region32_init_rect (®ion, - rectangle->x, rectangle->y, - rectangle->width, rectangle->height); - - if (! pixman_region32_union (&dst->rgn, &dst->rgn, ®ion)) - status = _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); - - pixman_region32_fini (®ion); - - return status; -} -slim_hidden_def (cairo_region_union_rectangle); - -/** - * cairo_region_xor: - * @dst: a #cairo_region_t - * @other: another #cairo_region_t - * - * Computes the exclusive difference of @dst with @other and places the - * result in @dst. That is, @dst will be set to contain all areas that - * are either in @dst or in @other, but not in both. - * - * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY - * - * Since: 1.10 - **/ -cairo_status_t -cairo_region_xor (cairo_region_t *dst, const cairo_region_t *other) -{ - cairo_status_t status = CAIRO_STATUS_SUCCESS; - pixman_region32_t tmp; - - if (dst->status) - return dst->status; - - if (other->status) - return _cairo_region_set_error (dst, other->status); - - pixman_region32_init (&tmp); - - /* XXX: get an xor function into pixman */ - if (! pixman_region32_subtract (&tmp, CONST_CAST &other->rgn, &dst->rgn) || - ! pixman_region32_subtract (&dst->rgn, &dst->rgn, CONST_CAST &other->rgn) || - ! pixman_region32_union (&dst->rgn, &dst->rgn, &tmp)) - status = _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); - - pixman_region32_fini (&tmp); - - return status; -} -slim_hidden_def (cairo_region_xor); - -/** - * cairo_region_xor_rectangle: - * @dst: a #cairo_region_t - * @rectangle: a #cairo_rectangle_int_t - * - * Computes the exclusive difference of @dst with @rectangle and places the - * result in @dst. That is, @dst will be set to contain all areas that are - * either in @dst or in @rectangle, but not in both. - * - * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY - * - * Since: 1.10 - **/ -cairo_status_t -cairo_region_xor_rectangle (cairo_region_t *dst, - const cairo_rectangle_int_t *rectangle) -{ - cairo_status_t status = CAIRO_STATUS_SUCCESS; - pixman_region32_t region, tmp; - - if (dst->status) - return dst->status; - - pixman_region32_init_rect (®ion, - rectangle->x, rectangle->y, - rectangle->width, rectangle->height); - pixman_region32_init (&tmp); - - /* XXX: get an xor function into pixman */ - if (! pixman_region32_subtract (&tmp, ®ion, &dst->rgn) || - ! pixman_region32_subtract (&dst->rgn, &dst->rgn, ®ion) || - ! pixman_region32_union (&dst->rgn, &dst->rgn, &tmp)) - status = _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); - - pixman_region32_fini (&tmp); - pixman_region32_fini (®ion); - - return status; -} -slim_hidden_def (cairo_region_xor_rectangle); - -/** - * cairo_region_is_empty: - * @region: a #cairo_region_t - * - * Checks whether @region is empty. - * - * Return value: %TRUE if @region is empty, %FALSE if it isn't. - * - * Since: 1.10 - **/ -cairo_bool_t -cairo_region_is_empty (const cairo_region_t *region) -{ - if (region->status) - return TRUE; - - return ! pixman_region32_not_empty (CONST_CAST ®ion->rgn); -} -slim_hidden_def (cairo_region_is_empty); - -/** - * cairo_region_translate: - * @region: a #cairo_region_t - * @dx: Amount to translate in the x direction - * @dy: Amount to translate in the y direction - * - * Translates @region by (@dx, @dy). - * - * Since: 1.10 - **/ -void -cairo_region_translate (cairo_region_t *region, - int dx, int dy) -{ - if (region->status) - return; - - pixman_region32_translate (®ion->rgn, dx, dy); -} -slim_hidden_def (cairo_region_translate); - -/** - * cairo_region_contains_rectangle: - * @region: a #cairo_region_t - * @rectangle: a #cairo_rectangle_int_t - * - * Checks whether @rectangle is inside, outside or partially contained - * in @region - * - * Return value: - * %CAIRO_REGION_OVERLAP_IN if @rectangle is entirely inside @region, - * %CAIRO_REGION_OVERLAP_OUT if @rectangle is entirely outside @region, or - * %CAIRO_REGION_OVERLAP_PART if @rectangle is partially inside and partially outside @region. - * - * Since: 1.10 - **/ -cairo_region_overlap_t -cairo_region_contains_rectangle (const cairo_region_t *region, - const cairo_rectangle_int_t *rectangle) -{ - pixman_box32_t pbox; - pixman_region_overlap_t poverlap; - - if (region->status) - return CAIRO_REGION_OVERLAP_OUT; - - pbox.x1 = rectangle->x; - pbox.y1 = rectangle->y; - pbox.x2 = rectangle->x + rectangle->width; - pbox.y2 = rectangle->y + rectangle->height; - - poverlap = pixman_region32_contains_rectangle (CONST_CAST ®ion->rgn, - &pbox); - switch (poverlap) { - default: - case PIXMAN_REGION_OUT: return CAIRO_REGION_OVERLAP_OUT; - case PIXMAN_REGION_IN: return CAIRO_REGION_OVERLAP_IN; - case PIXMAN_REGION_PART: return CAIRO_REGION_OVERLAP_PART; - } -} -slim_hidden_def (cairo_region_contains_rectangle); - -/** - * cairo_region_contains_point: - * @region: a #cairo_region_t - * @x: the x coordinate of a point - * @y: the y coordinate of a point - * - * Checks whether (@x, @y) is contained in @region. - * - * Return value: %TRUE if (@x, @y) is contained in @region, %FALSE if it is not. - * - * Since: 1.10 - **/ -cairo_bool_t -cairo_region_contains_point (const cairo_region_t *region, - int x, int y) -{ - pixman_box32_t box; - - if (region->status) - return FALSE; - - return pixman_region32_contains_point (CONST_CAST ®ion->rgn, x, y, &box); -} -slim_hidden_def (cairo_region_contains_point); - -/** - * cairo_region_equal: - * @a: a #cairo_region_t or %NULL - * @b: a #cairo_region_t or %NULL - * - * Compares whether region_a is equivalent to region_b. %NULL as an argument - * is equal to itself, but not to any non-%NULL region. - * - * Return value: %TRUE if both regions contained the same coverage, - * %FALSE if it is not or any region is in an error status. - * - * Since: 1.10 - **/ -cairo_bool_t -cairo_region_equal (const cairo_region_t *a, - const cairo_region_t *b) -{ - /* error objects are never equal */ - if ((a != NULL && a->status) || (b != NULL && b->status)) - return FALSE; - - if (a == b) - return TRUE; - - if (a == NULL || b == NULL) - return FALSE; - - return pixman_region32_equal (CONST_CAST &a->rgn, CONST_CAST &b->rgn); -} -slim_hidden_def (cairo_region_equal); diff --git a/source/libs/cairo/cairo-src/src/cairo-rtree-private.h b/source/libs/cairo/cairo-src/src/cairo-rtree-private.h deleted file mode 100644 index 27806cab6033d5096a4ef72ae26ba630147e047b..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-rtree-private.h +++ /dev/null @@ -1,142 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Chris Wilson. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -#ifndef CAIRO_RTREE_PRIVATE_H -#define CAIRO_RTREE_PRIVATE_H - -#include "cairo-compiler-private.h" -#include "cairo-error-private.h" -#include "cairo-types-private.h" - -#include "cairo-freelist-private.h" -#include "cairo-list-inline.h" - -enum { - CAIRO_RTREE_NODE_AVAILABLE, - CAIRO_RTREE_NODE_DIVIDED, - CAIRO_RTREE_NODE_OCCUPIED, -}; - -typedef struct _cairo_rtree_node { - struct _cairo_rtree_node *children[4], *parent; - cairo_list_t link; - uint16_t pinned; - uint16_t state; - uint16_t x, y; - uint16_t width, height; -} cairo_rtree_node_t; - -typedef struct _cairo_rtree { - cairo_rtree_node_t root; - int min_size; - cairo_list_t pinned; - cairo_list_t available; - cairo_list_t evictable; - void (*destroy) (cairo_rtree_node_t *); - cairo_freepool_t node_freepool; -} cairo_rtree_t; - -cairo_private cairo_rtree_node_t * -_cairo_rtree_node_create (cairo_rtree_t *rtree, - cairo_rtree_node_t *parent, - int x, - int y, - int width, - int height); - -cairo_private cairo_status_t -_cairo_rtree_node_insert (cairo_rtree_t *rtree, - cairo_rtree_node_t *node, - int width, - int height, - cairo_rtree_node_t **out); - -cairo_private void -_cairo_rtree_node_collapse (cairo_rtree_t *rtree, cairo_rtree_node_t *node); - -cairo_private void -_cairo_rtree_node_remove (cairo_rtree_t *rtree, cairo_rtree_node_t *node); - -cairo_private void -_cairo_rtree_node_destroy (cairo_rtree_t *rtree, cairo_rtree_node_t *node); - -cairo_private void -_cairo_rtree_init (cairo_rtree_t *rtree, - int width, - int height, - int min_size, - int node_size, - void (*destroy)(cairo_rtree_node_t *)); - -cairo_private cairo_int_status_t -_cairo_rtree_insert (cairo_rtree_t *rtree, - int width, - int height, - cairo_rtree_node_t **out); - -cairo_private cairo_int_status_t -_cairo_rtree_evict_random (cairo_rtree_t *rtree, - int width, - int height, - cairo_rtree_node_t **out); - -cairo_private void -_cairo_rtree_foreach (cairo_rtree_t *rtree, - void (*func)(cairo_rtree_node_t *, void *data), - void *data); - -static inline void * -_cairo_rtree_pin (cairo_rtree_t *rtree, cairo_rtree_node_t *node) -{ - assert (node->state == CAIRO_RTREE_NODE_OCCUPIED); - if (! node->pinned) { - cairo_list_move (&node->link, &rtree->pinned); - node->pinned = 1; - } - - return node; -} - -cairo_private void -_cairo_rtree_unpin (cairo_rtree_t *rtree); - -cairo_private void -_cairo_rtree_reset (cairo_rtree_t *rtree); - -cairo_private void -_cairo_rtree_fini (cairo_rtree_t *rtree); - -#endif /* CAIRO_RTREE_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-rtree.c b/source/libs/cairo/cairo-src/src/cairo-rtree.c deleted file mode 100644 index dbc040929af820dd8c3b0a9e5c5e3369516b7cbe..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-rtree.c +++ /dev/null @@ -1,388 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Chris Wilson. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - * - */ - -#include "cairoint.h" - -#include "cairo-error-private.h" -#include "cairo-rtree-private.h" - -cairo_rtree_node_t * -_cairo_rtree_node_create (cairo_rtree_t *rtree, - cairo_rtree_node_t *parent, - int x, - int y, - int width, - int height) -{ - cairo_rtree_node_t *node; - - node = _cairo_freepool_alloc (&rtree->node_freepool); - if (node == NULL) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return NULL; - } - - node->children[0] = NULL; - node->parent = parent; - node->state = CAIRO_RTREE_NODE_AVAILABLE; - node->pinned = FALSE; - node->x = x; - node->y = y; - node->width = width; - node->height = height; - - cairo_list_add (&node->link, &rtree->available); - - return node; -} - -void -_cairo_rtree_node_destroy (cairo_rtree_t *rtree, cairo_rtree_node_t *node) -{ - int i; - - cairo_list_del (&node->link); - - if (node->state == CAIRO_RTREE_NODE_OCCUPIED) { - rtree->destroy (node); - } else { - for (i = 0; i < 4 && node->children[i] != NULL; i++) - _cairo_rtree_node_destroy (rtree, node->children[i]); - } - - _cairo_freepool_free (&rtree->node_freepool, node); -} - -void -_cairo_rtree_node_collapse (cairo_rtree_t *rtree, cairo_rtree_node_t *node) -{ - int i; - - do { - assert (node->state == CAIRO_RTREE_NODE_DIVIDED); - - for (i = 0; i < 4 && node->children[i] != NULL; i++) - if (node->children[i]->state != CAIRO_RTREE_NODE_AVAILABLE) - return; - - for (i = 0; i < 4 && node->children[i] != NULL; i++) - _cairo_rtree_node_destroy (rtree, node->children[i]); - - node->children[0] = NULL; - node->state = CAIRO_RTREE_NODE_AVAILABLE; - cairo_list_move (&node->link, &rtree->available); - } while ((node = node->parent) != NULL); -} - -cairo_status_t -_cairo_rtree_node_insert (cairo_rtree_t *rtree, - cairo_rtree_node_t *node, - int width, - int height, - cairo_rtree_node_t **out) -{ - int w, h, i; - - assert (node->state == CAIRO_RTREE_NODE_AVAILABLE); - assert (node->pinned == FALSE); - - if (node->width - width > rtree->min_size || - node->height - height > rtree->min_size) - { - w = node->width - width; - h = node->height - height; - - i = 0; - node->children[i] = _cairo_rtree_node_create (rtree, node, - node->x, node->y, - width, height); - if (unlikely (node->children[i] == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - i++; - - if (w > rtree->min_size) { - node->children[i] = _cairo_rtree_node_create (rtree, node, - node->x + width, - node->y, - w, height); - if (unlikely (node->children[i] == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - i++; - } - - if (h > rtree->min_size) { - node->children[i] = _cairo_rtree_node_create (rtree, node, - node->x, - node->y + height, - width, h); - if (unlikely (node->children[i] == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - i++; - - if (w > rtree->min_size) { - node->children[i] = _cairo_rtree_node_create (rtree, node, - node->x + width, - node->y + height, - w, h); - if (unlikely (node->children[i] == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - i++; - } - } - - if (i < 4) - node->children[i] = NULL; - - node->state = CAIRO_RTREE_NODE_DIVIDED; - cairo_list_move (&node->link, &rtree->evictable); - node = node->children[0]; - } - - node->state = CAIRO_RTREE_NODE_OCCUPIED; - cairo_list_move (&node->link, &rtree->evictable); - *out = node; - - return CAIRO_STATUS_SUCCESS; -} - -void -_cairo_rtree_node_remove (cairo_rtree_t *rtree, cairo_rtree_node_t *node) -{ - assert (node->state == CAIRO_RTREE_NODE_OCCUPIED); - assert (node->pinned == FALSE); - - rtree->destroy (node); - - node->state = CAIRO_RTREE_NODE_AVAILABLE; - cairo_list_move (&node->link, &rtree->available); - - _cairo_rtree_node_collapse (rtree, node->parent); -} - -cairo_int_status_t -_cairo_rtree_insert (cairo_rtree_t *rtree, - int width, - int height, - cairo_rtree_node_t **out) -{ - cairo_rtree_node_t *node; - - cairo_list_foreach_entry (node, cairo_rtree_node_t, - &rtree->available, link) - { - if (node->width >= width && node->height >= height) - return _cairo_rtree_node_insert (rtree, node, width, height, out); - } - - return CAIRO_INT_STATUS_UNSUPPORTED; -} - -static uint32_t -hars_petruska_f54_1_random (void) -{ -#define rol(x,k) ((x << k) | (x >> (32-k))) - static uint32_t x; - return x = (x ^ rol (x, 5) ^ rol (x, 24)) + 0x37798849; -#undef rol -} - -cairo_int_status_t -_cairo_rtree_evict_random (cairo_rtree_t *rtree, - int width, - int height, - cairo_rtree_node_t **out) -{ - cairo_int_status_t ret = CAIRO_INT_STATUS_UNSUPPORTED; - cairo_rtree_node_t *node, *next; - cairo_list_t tmp_pinned; - int i, cnt; - - cairo_list_init (&tmp_pinned); - - /* propagate pinned from children to root */ - cairo_list_foreach_entry_safe (node, next, - cairo_rtree_node_t, &rtree->pinned, link) { - node = node->parent; - while (node && ! node->pinned) { - node->pinned = 1; - cairo_list_move (&node->link, &tmp_pinned); - node = node->parent; - } - } - - cnt = 0; - cairo_list_foreach_entry (node, cairo_rtree_node_t, - &rtree->evictable, link) - { - if (node->width >= width && node->height >= height) - cnt++; - } - - if (cnt == 0) - goto out; - - cnt = hars_petruska_f54_1_random () % cnt; - cairo_list_foreach_entry (node, cairo_rtree_node_t, - &rtree->evictable, link) - { - if (node->width >= width && node->height >= height && cnt-- == 0) { - if (node->state == CAIRO_RTREE_NODE_OCCUPIED) { - rtree->destroy (node); - } else { - for (i = 0; i < 4 && node->children[i] != NULL; i++) - _cairo_rtree_node_destroy (rtree, node->children[i]); - node->children[0] = NULL; - } - - node->state = CAIRO_RTREE_NODE_AVAILABLE; - cairo_list_move (&node->link, &rtree->available); - - *out = node; - ret = CAIRO_STATUS_SUCCESS; - break; - } - } - -out: - while (! cairo_list_is_empty (&tmp_pinned)) { - node = cairo_list_first_entry (&tmp_pinned, cairo_rtree_node_t, link); - node->pinned = 0; - cairo_list_move (&node->link, &rtree->evictable); - } - return ret; -} - -void -_cairo_rtree_unpin (cairo_rtree_t *rtree) -{ - while (! cairo_list_is_empty (&rtree->pinned)) { - cairo_rtree_node_t *node = cairo_list_first_entry (&rtree->pinned, - cairo_rtree_node_t, - link); - node->pinned = 0; - cairo_list_move (&node->link, &rtree->evictable); - } -} - -void -_cairo_rtree_init (cairo_rtree_t *rtree, - int width, - int height, - int min_size, - int node_size, - void (*destroy) (cairo_rtree_node_t *)) -{ - assert (node_size >= (int) sizeof (cairo_rtree_node_t)); - _cairo_freepool_init (&rtree->node_freepool, node_size); - - cairo_list_init (&rtree->available); - cairo_list_init (&rtree->pinned); - cairo_list_init (&rtree->evictable); - - rtree->min_size = min_size; - rtree->destroy = destroy; - - memset (&rtree->root, 0, sizeof (rtree->root)); - rtree->root.width = width; - rtree->root.height = height; - rtree->root.state = CAIRO_RTREE_NODE_AVAILABLE; - cairo_list_add (&rtree->root.link, &rtree->available); -} - -void -_cairo_rtree_reset (cairo_rtree_t *rtree) -{ - int i; - - if (rtree->root.state == CAIRO_RTREE_NODE_OCCUPIED) { - rtree->destroy (&rtree->root); - } else { - for (i = 0; i < 4 && rtree->root.children[i] != NULL; i++) - _cairo_rtree_node_destroy (rtree, rtree->root.children[i]); - rtree->root.children[0] = NULL; - } - - cairo_list_init (&rtree->available); - cairo_list_init (&rtree->evictable); - cairo_list_init (&rtree->pinned); - - rtree->root.state = CAIRO_RTREE_NODE_AVAILABLE; - rtree->root.pinned = FALSE; - cairo_list_add (&rtree->root.link, &rtree->available); -} - -static void -_cairo_rtree_node_foreach (cairo_rtree_node_t *node, - void (*func)(cairo_rtree_node_t *, void *data), - void *data) -{ - int i; - - for (i = 0; i < 4 && node->children[i] != NULL; i++) - _cairo_rtree_node_foreach(node->children[i], func, data); - - func(node, data); -} - -void -_cairo_rtree_foreach (cairo_rtree_t *rtree, - void (*func)(cairo_rtree_node_t *, void *data), - void *data) -{ - int i; - - if (rtree->root.state == CAIRO_RTREE_NODE_OCCUPIED) { - func(&rtree->root, data); - } else { - for (i = 0; i < 4 && rtree->root.children[i] != NULL; i++) - _cairo_rtree_node_foreach (rtree->root.children[i], func, data); - } -} - -void -_cairo_rtree_fini (cairo_rtree_t *rtree) -{ - int i; - - if (rtree->root.state == CAIRO_RTREE_NODE_OCCUPIED) { - rtree->destroy (&rtree->root); - } else { - for (i = 0; i < 4 && rtree->root.children[i] != NULL; i++) - _cairo_rtree_node_destroy (rtree, rtree->root.children[i]); - } - - _cairo_freepool_fini (&rtree->node_freepool); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-scaled-font-private.h b/source/libs/cairo/cairo-src/src/cairo-scaled-font-private.h deleted file mode 100644 index da7b34698344b44806a7f4dfa34d256463f1ca2d..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-scaled-font-private.h +++ /dev/null @@ -1,183 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - */ - -#ifndef CAIRO_SCALED_FONT_PRIVATE_H -#define CAIRO_SCALED_FONT_PRIVATE_H - -#include "cairo.h" - -#include "cairo-types-private.h" -#include "cairo-list-private.h" -#include "cairo-mutex-type-private.h" -#include "cairo-reference-count-private.h" - -CAIRO_BEGIN_DECLS - -typedef struct _cairo_scaled_glyph_page cairo_scaled_glyph_page_t; - -struct _cairo_scaled_font { - /* For most cairo objects, the rule for multiple threads is that - * the user is responsible for any locking if the same object is - * manipulated from multiple threads simultaneously. - * - * However, with the caching that cairo does for scaled fonts, a - * user can easily end up with the same cairo_scaled_font object - * being manipulated from multiple threads without the user ever - * being aware of this, (and in fact, unable to control it). - * - * So, as a special exception, the cairo implementation takes care - * of all locking needed for cairo_scaled_font_t. Most of what is - * in the scaled font is immutable, (which is what allows for the - * sharing in the first place). The things that are modified and - * the locks protecting them are as follows: - * - * 1. The reference count (scaled_font->ref_count) - * - * Modifications to the reference count are protected by the - * _cairo_scaled_font_map_mutex. This is because the reference - * count of a scaled font is intimately related with the font - * map itself, (and the magic holdovers array). - * - * 2. The cache of glyphs (scaled_font->glyphs) - * 3. The backend private data (scaled_font->surface_backend, - * scaled_font->surface_private) - * - * Modifications to these fields are protected with locks on - * scaled_font->mutex in the generic scaled_font code. - */ - - cairo_hash_entry_t hash_entry; - - /* useful bits for _cairo_scaled_font_nil */ - cairo_status_t status; - cairo_reference_count_t ref_count; - cairo_user_data_array_t user_data; - - cairo_font_face_t *original_font_face; /* may be NULL */ - - /* hash key members */ - cairo_font_face_t *font_face; /* may be NULL */ - cairo_matrix_t font_matrix; /* font space => user space */ - cairo_matrix_t ctm; /* user space => device space */ - cairo_font_options_t options; - - unsigned int placeholder : 1; /* protected by fontmap mutex */ - unsigned int holdover : 1; - unsigned int finished : 1; - - /* "live" scaled_font members */ - cairo_matrix_t scale; /* font space => device space */ - cairo_matrix_t scale_inverse; /* device space => font space */ - double max_scale; /* maximum x/y expansion of scale */ - cairo_font_extents_t extents; /* user space */ - cairo_font_extents_t fs_extents; /* font space */ - - /* The mutex protects modification to all subsequent fields. */ - cairo_mutex_t mutex; - - cairo_hash_table_t *glyphs; - cairo_list_t glyph_pages; - cairo_bool_t cache_frozen; - cairo_bool_t global_cache_frozen; - - cairo_list_t dev_privates; - - /* font backend managing this scaled font */ - const cairo_scaled_font_backend_t *backend; - cairo_list_t link; -}; - -struct _cairo_scaled_font_private { - cairo_list_t link; - const void *key; - void (*destroy) (cairo_scaled_font_private_t *, - cairo_scaled_font_t *); -}; - -struct _cairo_scaled_glyph { - cairo_hash_entry_t hash_entry; - - cairo_text_extents_t metrics; /* user-space metrics */ - cairo_text_extents_t fs_metrics; /* font-space metrics */ - cairo_box_t bbox; /* device-space bounds */ - int16_t x_advance; /* device-space rounded X advance */ - int16_t y_advance; /* device-space rounded Y advance */ - - unsigned int has_info; - cairo_image_surface_t *surface; /* device-space image */ - cairo_path_fixed_t *path; /* device-space outline */ - cairo_surface_t *recording_surface; /* device-space recording-surface */ - - const void *dev_private_key; - void *dev_private; - cairo_list_t dev_privates; -}; - -struct _cairo_scaled_glyph_private { - cairo_list_t link; - const void *key; - void (*destroy) (cairo_scaled_glyph_private_t *, - cairo_scaled_glyph_t *, - cairo_scaled_font_t *); -}; - -cairo_private cairo_scaled_font_private_t * -_cairo_scaled_font_find_private (cairo_scaled_font_t *scaled_font, - const void *key); - -cairo_private void -_cairo_scaled_font_attach_private (cairo_scaled_font_t *scaled_font, - cairo_scaled_font_private_t *priv, - const void *key, - void (*destroy) (cairo_scaled_font_private_t *, - cairo_scaled_font_t *)); - -cairo_private cairo_scaled_glyph_private_t * -_cairo_scaled_glyph_find_private (cairo_scaled_glyph_t *scaled_glyph, - const void *key); - -cairo_private void -_cairo_scaled_glyph_attach_private (cairo_scaled_glyph_t *scaled_glyph, - cairo_scaled_glyph_private_t *priv, - const void *key, - void (*destroy) (cairo_scaled_glyph_private_t *, - cairo_scaled_glyph_t *, - cairo_scaled_font_t *)); - -CAIRO_END_DECLS - -#endif /* CAIRO_SCALED_FONT_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-scaled-font-subsets-private.h b/source/libs/cairo/cairo-src/src/cairo-scaled-font-subsets-private.h deleted file mode 100644 index 866e63d7bca8dd6a7f1569700fc8c3e45ef7974d..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-scaled-font-subsets-private.h +++ /dev/null @@ -1,735 +0,0 @@ -/* 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - */ - -#ifndef CAIRO_SCALED_FONT_SUBSETS_PRIVATE_H -#define CAIRO_SCALED_FONT_SUBSETS_PRIVATE_H - -#include "cairoint.h" - -#if CAIRO_HAS_FONT_SUBSET - -typedef struct _cairo_scaled_font_subsets_glyph { - unsigned int font_id; - unsigned int subset_id; - unsigned int subset_glyph_index; - cairo_bool_t is_scaled; - cairo_bool_t is_composite; - cairo_bool_t is_latin; - double x_advance; - double y_advance; - cairo_bool_t utf8_is_mapped; - uint32_t unicode; -} cairo_scaled_font_subsets_glyph_t; - -/** - * _cairo_scaled_font_subsets_create_scaled: - * - * Create a new #cairo_scaled_font_subsets_t object which can be used - * to create subsets of any number of #cairo_scaled_font_t - * objects. This allows the (arbitrarily large and sparse) glyph - * indices of a #cairo_scaled_font_t to be mapped to one or more font - * subsets with glyph indices packed into the range - * [0 .. max_glyphs_per_subset). - * - * Return value: a pointer to the newly creates font subsets. The - * caller owns this object and should call - * _cairo_scaled_font_subsets_destroy() when done with it. - **/ -cairo_private cairo_scaled_font_subsets_t * -_cairo_scaled_font_subsets_create_scaled (void); - -/** - * _cairo_scaled_font_subsets_create_simple: - * - * Create a new #cairo_scaled_font_subsets_t object which can be used - * to create font subsets suitable for embedding as Postscript or PDF - * simple fonts. - * - * Glyphs with an outline path available will be mapped to one font - * subset for each font face. Glyphs from bitmap fonts will mapped to - * separate font subsets for each #cairo_scaled_font_t object. - * - * The maximum number of glyphs per subset is 256. Each subset - * reserves the first glyph for the .notdef glyph. - * - * Return value: a pointer to the newly creates font subsets. The - * caller owns this object and should call - * _cairo_scaled_font_subsets_destroy() when done with it. - **/ -cairo_private cairo_scaled_font_subsets_t * -_cairo_scaled_font_subsets_create_simple (void); - -/** - * _cairo_scaled_font_subsets_create_composite: - * - * Create a new #cairo_scaled_font_subsets_t object which can be used - * to create font subsets suitable for embedding as Postscript or PDF - * composite fonts. - * - * Glyphs with an outline path available will be mapped to one font - * subset for each font face. Each unscaled subset has a maximum of - * 65536 glyphs except for Type1 fonts which have a maximum of 256 glyphs. - * - * Glyphs from bitmap fonts will mapped to separate font subsets for - * each #cairo_scaled_font_t object. Each unscaled subset has a maximum - * of 256 glyphs. - * - * Each subset reserves the first glyph for the .notdef glyph. - * - * Return value: a pointer to the newly creates font subsets. The - * caller owns this object and should call - * _cairo_scaled_font_subsets_destroy() when done with it. - **/ -cairo_private cairo_scaled_font_subsets_t * -_cairo_scaled_font_subsets_create_composite (void); - -/** - * _cairo_scaled_font_subsets_destroy: - * @font_subsets: a #cairo_scaled_font_subsets_t object to be destroyed - * - * Destroys @font_subsets and all resources associated with it. - **/ -cairo_private void -_cairo_scaled_font_subsets_destroy (cairo_scaled_font_subsets_t *font_subsets); - -/** - * _cairo_scaled_font_subsets_enable_latin_subset: - * @font_subsets: a #cairo_scaled_font_subsets_t object to be destroyed - * @use_latin: a #cairo_bool_t indicating if a latin subset is to be used - * - * If enabled, all CP1252 characters will be placed in a separate - * 8-bit latin subset. - **/ -cairo_private void -_cairo_scaled_font_subsets_enable_latin_subset (cairo_scaled_font_subsets_t *font_subsets, - cairo_bool_t use_latin); - -/** - * _cairo_scaled_font_subsets_map_glyph: - * @font_subsets: a #cairo_scaled_font_subsets_t - * @scaled_font: the font of the glyph to be mapped - * @scaled_font_glyph_index: the index of the glyph to be mapped - * @utf8: a string of text encoded in UTF-8 - * @utf8_len: length of @utf8 in bytes - * @subset_glyph_ret: return structure containing subset font and glyph id - * - * Map a glyph from a #cairo_scaled_font to a new index within a - * subset of that font. The mapping performed is from the tuple: - * - * (scaled_font, scaled_font_glyph_index) - * - * to the tuple: - * - * (font_id, subset_id, subset_glyph_index) - * - * This mapping is 1:1. If the input tuple has previously mapped, the - * the output tuple previously returned will be returned again. - * - * Otherwise, the return tuple will be constructed as follows: - * - * 1) There is a 1:1 correspondence between the input scaled_font - * value and the output font_id value. If no mapping has been - * previously performed with the scaled_font value then the - * smallest unused font_id value will be returned. - * - * 2) Within the set of output tuples of the same font_id value the - * smallest value of subset_id will be returned such that - * subset_glyph_index does not exceed max_glyphs_per_subset (as - * passed to _cairo_scaled_font_subsets_create()) and that the - * resulting tuple is unique. - * - * 3) The smallest value of subset_glyph_index is returned such that - * the resulting tuple is unique. - * - * The net result is that any #cairo_scaled_font_t will be represented - * by one or more font subsets. Each subset is effectively a tuple of - * (scaled_font, font_id, subset_id) and within each subset there - * exists a mapping of scaled_glyph_font_index to subset_glyph_index. - * - * This final description of a font subset is the same representation - * used by #cairo_scaled_font_subset_t as provided by - * _cairo_scaled_font_subsets_foreach. - * - * @utf8 and @utf8_len specify a string of unicode characters that the - * glyph @scaled_font_glyph_index maps to. If @utf8_is_mapped in - * @subset_glyph_ret is %TRUE, the font subsetting will (where index to - * unicode mapping is supported) ensure that @scaled_font_glyph_index - * maps to @utf8. If @utf8_is_mapped is %FALSE, - * @scaled_font_glyph_index has already been mapped to a different - * unicode string. - * - * The returned values in the #cairo_scaled_font_subsets_glyph_t struct are: - * - * @font_id: The font ID of the mapped glyph - * @subset_id : The subset ID of the mapped glyph within the @font_id - * @subset_glyph_index: The index of the mapped glyph within the @subset_id subset - * @is_scaled: If true, the mapped glyph is from a bitmap font, and separate font - * subset is created for each font scale used. If false, the outline of the mapped glyph - * is available. One font subset for each font face is created. - * @x_advance, @y_advance: When @is_scaled is true, @x_advance and @y_advance contain - * the x and y advance for the mapped glyph in device space. - * When @is_scaled is false, @x_advance and @y_advance contain the x and y advance for - * the the mapped glyph from an unhinted 1 point font. - * @utf8_is_mapped: If true the utf8 string provided to _cairo_scaled_font_subsets_map_glyph() - * is (or already was) the utf8 string mapped to this glyph. If false the glyph is already - * mapped to a different utf8 string. - * @unicode: the unicode character mapped to this glyph by the font backend. - * - * Return value: %CAIRO_STATUS_SUCCESS if successful, or a non-zero - * value indicating an error. Possible errors include - * %CAIRO_STATUS_NO_MEMORY. - **/ -cairo_private cairo_status_t -_cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *font_subsets, - cairo_scaled_font_t *scaled_font, - unsigned long scaled_font_glyph_index, - const char * utf8, - int utf8_len, - cairo_scaled_font_subsets_glyph_t *subset_glyph_ret); - -typedef cairo_int_status_t -(*cairo_scaled_font_subset_callback_func_t) (cairo_scaled_font_subset_t *font_subset, - void *closure); - -/** - * _cairo_scaled_font_subsets_foreach_scaled: - * @font_subsets: a #cairo_scaled_font_subsets_t - * @font_subset_callback: a function to be called for each font subset - * @closure: closure data for the callback function - * - * Iterate over each unique scaled font subset as created by calls to - * _cairo_scaled_font_subsets_map_glyph(). A subset is determined by - * unique pairs of (font_id, subset_id) as returned by - * _cairo_scaled_font_subsets_map_glyph(). - * - * For each subset, @font_subset_callback will be called and will be - * provided with both a #cairo_scaled_font_subset_t object containing - * all the glyphs in the subset as well as the value of @closure. - * - * The #cairo_scaled_font_subset_t object contains the scaled_font, - * the font_id, and the subset_id corresponding to all glyphs - * belonging to the subset. In addition, it contains an array providing - * a mapping between subset glyph indices and the original scaled font - * glyph indices. - * - * The index of the array corresponds to subset_glyph_index values - * returned by _cairo_scaled_font_subsets_map_glyph() while the - * values of the array correspond to the scaled_font_glyph_index - * values passed as input to the same function. - * - * Return value: %CAIRO_STATUS_SUCCESS if successful, or a non-zero - * value indicating an error. Possible errors include - * %CAIRO_STATUS_NO_MEMORY. - **/ -cairo_private cairo_status_t -_cairo_scaled_font_subsets_foreach_scaled (cairo_scaled_font_subsets_t *font_subsets, - cairo_scaled_font_subset_callback_func_t font_subset_callback, - void *closure); - -/** - * _cairo_scaled_font_subsets_foreach_unscaled: - * @font_subsets: a #cairo_scaled_font_subsets_t - * @font_subset_callback: a function to be called for each font subset - * @closure: closure data for the callback function - * - * Iterate over each unique unscaled font subset as created by calls to - * _cairo_scaled_font_subsets_map_glyph(). A subset is determined by - * unique pairs of (font_id, subset_id) as returned by - * _cairo_scaled_font_subsets_map_glyph(). - * - * For each subset, @font_subset_callback will be called and will be - * provided with both a #cairo_scaled_font_subset_t object containing - * all the glyphs in the subset as well as the value of @closure. - * - * The #cairo_scaled_font_subset_t object contains the scaled_font, - * the font_id, and the subset_id corresponding to all glyphs - * belonging to the subset. In addition, it contains an array providing - * a mapping between subset glyph indices and the original scaled font - * glyph indices. - * - * The index of the array corresponds to subset_glyph_index values - * returned by _cairo_scaled_font_subsets_map_glyph() while the - * values of the array correspond to the scaled_font_glyph_index - * values passed as input to the same function. - * - * Return value: %CAIRO_STATUS_SUCCESS if successful, or a non-zero - * value indicating an error. Possible errors include - * %CAIRO_STATUS_NO_MEMORY. - **/ -cairo_private cairo_status_t -_cairo_scaled_font_subsets_foreach_unscaled (cairo_scaled_font_subsets_t *font_subsets, - cairo_scaled_font_subset_callback_func_t font_subset_callback, - void *closure); - -/** - * _cairo_scaled_font_subsets_foreach_user: - * @font_subsets: a #cairo_scaled_font_subsets_t - * @font_subset_callback: a function to be called for each font subset - * @closure: closure data for the callback function - * - * Iterate over each unique scaled font subset as created by calls to - * _cairo_scaled_font_subsets_map_glyph(). A subset is determined by - * unique pairs of (font_id, subset_id) as returned by - * _cairo_scaled_font_subsets_map_glyph(). - * - * For each subset, @font_subset_callback will be called and will be - * provided with both a #cairo_scaled_font_subset_t object containing - * all the glyphs in the subset as well as the value of @closure. - * - * The #cairo_scaled_font_subset_t object contains the scaled_font, - * the font_id, and the subset_id corresponding to all glyphs - * belonging to the subset. In addition, it contains an array providing - * a mapping between subset glyph indices and the original scaled font - * glyph indices. - * - * The index of the array corresponds to subset_glyph_index values - * returned by _cairo_scaled_font_subsets_map_glyph() while the - * values of the array correspond to the scaled_font_glyph_index - * values passed as input to the same function. - * - * Return value: %CAIRO_STATUS_SUCCESS if successful, or a non-zero - * value indicating an error. Possible errors include - * %CAIRO_STATUS_NO_MEMORY. - **/ -cairo_private cairo_status_t -_cairo_scaled_font_subsets_foreach_user (cairo_scaled_font_subsets_t *font_subsets, - cairo_scaled_font_subset_callback_func_t font_subset_callback, - void *closure); - -/** - * _cairo_scaled_font_subset_create_glyph_names: - * @font_subsets: a #cairo_scaled_font_subsets_t - * - * Create an array of strings containing the glyph name for each glyph - * in @font_subsets. The array as store in font_subsets->glyph_names. - * - * Return value: %CAIRO_STATUS_SUCCESS if successful, - * %CAIRO_INT_STATUS_UNSUPPORTED if the font backend does not support - * mapping the glyph indices to unicode characters. Possible errors - * include %CAIRO_STATUS_NO_MEMORY. - **/ -cairo_private cairo_int_status_t -_cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset); - -typedef struct _cairo_cff_subset { - char *family_name_utf8; - char *ps_name; - double *widths; - double x_min, y_min, x_max, y_max; - double ascent, descent; - char *data; - unsigned long data_length; -} cairo_cff_subset_t; - -/** - * _cairo_cff_subset_init: - * @cff_subset: a #cairo_cff_subset_t to initialize - * @font_subset: the #cairo_scaled_font_subset_t to initialize from - * - * If possible (depending on the format of the underlying - * #cairo_scaled_font_t and the font backend in use) generate a - * cff file corresponding to @font_subset and initialize - * @cff_subset with information about the subset and the cff - * data. - * - * Return value: %CAIRO_STATUS_SUCCESS if successful, - * %CAIRO_INT_STATUS_UNSUPPORTED if the font can't be subset as a - * cff file, or an non-zero value indicating an error. Possible - * errors include %CAIRO_STATUS_NO_MEMORY. - **/ -cairo_private cairo_status_t -_cairo_cff_subset_init (cairo_cff_subset_t *cff_subset, - const char *name, - cairo_scaled_font_subset_t *font_subset); - -/** - * _cairo_cff_subset_fini: - * @cff_subset: a #cairo_cff_subset_t - * - * Free all resources associated with @cff_subset. After this - * call, @cff_subset should not be used again without a - * subsequent call to _cairo_cff_subset_init() again first. - **/ -cairo_private void -_cairo_cff_subset_fini (cairo_cff_subset_t *cff_subset); - -/** - * _cairo_cff_scaled_font_is_cid_cff: - * @scaled_font: a #cairo_scaled_font_t - * - * Return %TRUE if @scaled_font is a CID CFF font, otherwise return %FALSE. - **/ -cairo_private cairo_bool_t -_cairo_cff_scaled_font_is_cid_cff (cairo_scaled_font_t *scaled_font); - -/** - * _cairo_cff_fallback_init: - * @cff_subset: a #cairo_cff_subset_t to initialize - * @font_subset: the #cairo_scaled_font_subset_t to initialize from - * - * If possible (depending on the format of the underlying - * #cairo_scaled_font_t and the font backend in use) generate a cff - * file corresponding to @font_subset and initialize @cff_subset - * with information about the subset and the cff data. - * - * Return value: %CAIRO_STATUS_SUCCESS if successful, - * %CAIRO_INT_STATUS_UNSUPPORTED if the font can't be subset as a - * cff file, or an non-zero value indicating an error. Possible - * errors include %CAIRO_STATUS_NO_MEMORY. - **/ -cairo_private cairo_status_t -_cairo_cff_fallback_init (cairo_cff_subset_t *cff_subset, - const char *name, - cairo_scaled_font_subset_t *font_subset); - -/** - * _cairo_cff_fallback_fini: - * @cff_subset: a #cairo_cff_subset_t - * - * Free all resources associated with @cff_subset. After this - * call, @cff_subset should not be used again without a - * subsequent call to _cairo_cff_subset_init() again first. - **/ -cairo_private void -_cairo_cff_fallback_fini (cairo_cff_subset_t *cff_subset); - -typedef struct _cairo_truetype_subset { - char *family_name_utf8; - char *ps_name; - double *widths; - double x_min, y_min, x_max, y_max; - double ascent, descent; - unsigned char *data; - unsigned long data_length; - unsigned long *string_offsets; - unsigned long num_string_offsets; -} cairo_truetype_subset_t; - -/** - * _cairo_truetype_subset_init_ps: - * @truetype_subset: a #cairo_truetype_subset_t to initialize - * @font_subset: the #cairo_scaled_font_subset_t to initialize from - * - * If possible (depending on the format of the underlying - * #cairo_scaled_font_t and the font backend in use) generate a - * truetype file corresponding to @font_subset and initialize - * @truetype_subset with information about the subset and the truetype - * data. The generated font will be suitable for embedding in - * PostScript. - * - * Return value: %CAIRO_STATUS_SUCCESS if successful, - * %CAIRO_INT_STATUS_UNSUPPORTED if the font can't be subset as a - * truetype file, or an non-zero value indicating an error. Possible - * errors include %CAIRO_STATUS_NO_MEMORY. - **/ -cairo_private cairo_status_t -_cairo_truetype_subset_init_ps (cairo_truetype_subset_t *truetype_subset, - cairo_scaled_font_subset_t *font_subset); - -/** - * _cairo_truetype_subset_init_pdf: - * @truetype_subset: a #cairo_truetype_subset_t to initialize - * @font_subset: the #cairo_scaled_font_subset_t to initialize from - * - * If possible (depending on the format of the underlying - * #cairo_scaled_font_t and the font backend in use) generate a - * truetype file corresponding to @font_subset and initialize - * @truetype_subset with information about the subset and the truetype - * data. The generated font will be suitable for embedding in - * PDF. - * - * Return value: %CAIRO_STATUS_SUCCESS if successful, - * %CAIRO_INT_STATUS_UNSUPPORTED if the font can't be subset as a - * truetype file, or an non-zero value indicating an error. Possible - * errors include %CAIRO_STATUS_NO_MEMORY. - **/ -cairo_private cairo_status_t -_cairo_truetype_subset_init_pdf (cairo_truetype_subset_t *truetype_subset, - cairo_scaled_font_subset_t *font_subset); - -/** - * _cairo_truetype_subset_fini: - * @truetype_subset: a #cairo_truetype_subset_t - * - * Free all resources associated with @truetype_subset. After this - * call, @truetype_subset should not be used again without a - * subsequent call to _cairo_truetype_subset_init() again first. - **/ -cairo_private void -_cairo_truetype_subset_fini (cairo_truetype_subset_t *truetype_subset); - -cairo_private const char * -_cairo_ps_standard_encoding_to_glyphname (int glyph); - -cairo_private int -_cairo_unicode_to_winansi (unsigned long unicode); - -cairo_private const char * -_cairo_winansi_to_glyphname (int glyph); - -typedef struct _cairo_type1_subset { - char *base_font; - double *widths; - double x_min, y_min, x_max, y_max; - double ascent, descent; - char *data; - unsigned long header_length; - unsigned long data_length; - unsigned long trailer_length; -} cairo_type1_subset_t; - - -/** - * _cairo_type1_subset_init: - * @type1_subset: a #cairo_type1_subset_t to initialize - * @font_subset: the #cairo_scaled_font_subset_t to initialize from - * @hex_encode: if true the encrypted portion of the font is hex encoded - * - * If possible (depending on the format of the underlying - * #cairo_scaled_font_t and the font backend in use) generate a type1 - * file corresponding to @font_subset and initialize @type1_subset - * with information about the subset and the type1 data. - * - * Return value: %CAIRO_STATUS_SUCCESS if successful, - * %CAIRO_INT_STATUS_UNSUPPORTED if the font can't be subset as a type1 - * file, or an non-zero value indicating an error. Possible errors - * include %CAIRO_STATUS_NO_MEMORY. - **/ -cairo_private cairo_status_t -_cairo_type1_subset_init (cairo_type1_subset_t *type_subset, - const char *name, - cairo_scaled_font_subset_t *font_subset, - cairo_bool_t hex_encode); - -/** - * _cairo_type1_subset_fini: - * @type1_subset: a #cairo_type1_subset_t - * - * Free all resources associated with @type1_subset. After this call, - * @type1_subset should not be used again without a subsequent call to - * _cairo_truetype_type1_init() again first. - **/ -cairo_private void -_cairo_type1_subset_fini (cairo_type1_subset_t *subset); - -/** - * _cairo_type1_scaled_font_is_type1: - * @scaled_font: a #cairo_scaled_font_t - * - * Return %TRUE if @scaled_font is a Type 1 font, otherwise return %FALSE. - **/ -cairo_private cairo_bool_t -_cairo_type1_scaled_font_is_type1 (cairo_scaled_font_t *scaled_font); - -/** - * _cairo_type1_fallback_init_binary: - * @type1_subset: a #cairo_type1_subset_t to initialize - * @font_subset: the #cairo_scaled_font_subset_t to initialize from - * - * If possible (depending on the format of the underlying - * #cairo_scaled_font_t and the font backend in use) generate a type1 - * file corresponding to @font_subset and initialize @type1_subset - * with information about the subset and the type1 data. The encrypted - * part of the font is binary encoded. - * - * Return value: %CAIRO_STATUS_SUCCESS if successful, - * %CAIRO_INT_STATUS_UNSUPPORTED if the font can't be subset as a type1 - * file, or an non-zero value indicating an error. Possible errors - * include %CAIRO_STATUS_NO_MEMORY. - **/ -cairo_private cairo_status_t -_cairo_type1_fallback_init_binary (cairo_type1_subset_t *type_subset, - const char *name, - cairo_scaled_font_subset_t *font_subset); - -/** - * _cairo_type1_fallback_init_hex: - * @type1_subset: a #cairo_type1_subset_t to initialize - * @font_subset: the #cairo_scaled_font_subset_t to initialize from - * - * If possible (depending on the format of the underlying - * #cairo_scaled_font_t and the font backend in use) generate a type1 - * file corresponding to @font_subset and initialize @type1_subset - * with information about the subset and the type1 data. The encrypted - * part of the font is hex encoded. - * - * Return value: %CAIRO_STATUS_SUCCESS if successful, - * %CAIRO_INT_STATUS_UNSUPPORTED if the font can't be subset as a type1 - * file, or an non-zero value indicating an error. Possible errors - * include %CAIRO_STATUS_NO_MEMORY. - **/ -cairo_private cairo_status_t -_cairo_type1_fallback_init_hex (cairo_type1_subset_t *type_subset, - const char *name, - cairo_scaled_font_subset_t *font_subset); - -/** - * _cairo_type1_fallback_fini: - * @type1_subset: a #cairo_type1_subset_t - * - * Free all resources associated with @type1_subset. After this call, - * @type1_subset should not be used again without a subsequent call to - * _cairo_truetype_type1_init() again first. - **/ -cairo_private void -_cairo_type1_fallback_fini (cairo_type1_subset_t *subset); - -typedef struct _cairo_type2_charstrings { - int *widths; - long x_min, y_min, x_max, y_max; - long ascent, descent; - cairo_array_t charstrings; -} cairo_type2_charstrings_t; - -/** - * _cairo_type2_charstrings_init: - * @type2_subset: a #cairo_type2_subset_t to initialize - * @font_subset: the #cairo_scaled_font_subset_t to initialize from - * - * If possible (depending on the format of the underlying - * #cairo_scaled_font_t and the font backend in use) generate type2 - * charstrings to @font_subset and initialize @type2_subset - * with information about the subset. - * - * Return value: %CAIRO_STATUS_SUCCESS if successful, - * %CAIRO_INT_STATUS_UNSUPPORTED if the font can't be subset as a type2 - * charstrings, or an non-zero value indicating an error. Possible errors - * include %CAIRO_STATUS_NO_MEMORY. - **/ -cairo_private cairo_status_t -_cairo_type2_charstrings_init (cairo_type2_charstrings_t *charstrings, - cairo_scaled_font_subset_t *font_subset); - -/** - * _cairo_type2_charstrings_fini: - * @subset: a #cairo_type2_charstrings_t - * - * Free all resources associated with @type2_charstring. After this call, - * @type2_charstring should not be used again without a subsequent call to - * _cairo_type2_charstring_init() again first. - **/ -cairo_private void -_cairo_type2_charstrings_fini (cairo_type2_charstrings_t *charstrings); - -/** - * _cairo_truetype_index_to_ucs4: - * @scaled_font: the #cairo_scaled_font_t - * @index: the glyph index - * @ucs4: return value for the unicode value of the glyph - * - * If possible (depending on the format of the underlying - * #cairo_scaled_font_t and the font backend in use) assign - * the unicode character of the glyph to @ucs4. - * - * If mapping glyph indices to unicode is supported but the unicode - * value of the specified glyph is not available, @ucs4 is set to -1. - * - * Return value: %CAIRO_STATUS_SUCCESS if successful, - * %CAIRO_INT_STATUS_UNSUPPORTED if mapping glyph indices to unicode - * is not supported. Possible errors include %CAIRO_STATUS_NO_MEMORY. - **/ -cairo_private cairo_int_status_t -_cairo_truetype_index_to_ucs4 (cairo_scaled_font_t *scaled_font, - unsigned long index, - uint32_t *ucs4); - -/** - * _cairo_truetype_read_font_name: - * @scaled_font: the #cairo_scaled_font_t - * @ps_name: returns the PostScript name of the font - * or %NULL if the name could not be found. - * @font_name: returns the font name or %NULL if the name could not be found. - * - * If possible (depending on the format of the underlying - * #cairo_scaled_font_t and the font backend in use) read the - * PostScript and Font names from a TrueType/OpenType font. - * - * The font name is the full name of the font eg "DejaVu Sans Bold". - * The PostScript name is a shortened name with spaces removed - * suitable for use as the font name in a PS or PDF file eg - * "DejaVuSans-Bold". - * - * Return value: %CAIRO_STATUS_SUCCESS if successful, - * %CAIRO_INT_STATUS_UNSUPPORTED if the font is not TrueType/OpenType - * or the name table is not present. Possible errors include - * %CAIRO_STATUS_NO_MEMORY. - **/ -cairo_private cairo_int_status_t -_cairo_truetype_read_font_name (cairo_scaled_font_t *scaled_font, - char **ps_name, - char **font_name); - -/** - * _cairo_truetype_get_style: - * @scaled_font: the #cairo_scaled_font_t - * @weight: returns the font weight from the OS/2 table - * @bold: returns true if font is bold - * @italic: returns true if font is italic - * - * If the font is a truetype/opentype font with an OS/2 table, get the - * weight, bold, and italic data from the OS/2 table. The weight - * values have the same meaning as the lfWeight field of the Windows - * LOGFONT structure. Refer to the TrueType Specification for - * definition of the weight values. - * - * Return value: %CAIRO_STATUS_SUCCESS if successful, - * %CAIRO_INT_STATUS_UNSUPPORTED if the font is not TrueType/OpenType - * or the OS/2 table is not present. - **/ -cairo_private cairo_int_status_t -_cairo_truetype_get_style (cairo_scaled_font_t *scaled_font, - int *weight, - cairo_bool_t *bold, - cairo_bool_t *italic); - -/** - * _cairo_escape_ps_name: - * @ps_name: returns the PostScript name with all invalid characters escaped - * - * Ensure that PostSript name is a valid PDF/PostSript name object. - * In PDF names are treated as UTF8 and non ASCII bytes, ' ', - * and '#' are encoded as '#' followed by 2 hex digits that - * encode the byte. - * - * Return value: %CAIRO_STATUS_SUCCESS if successful. Possible errors include - * %CAIRO_STATUS_NO_MEMORY. - **/ -cairo_private cairo_int_status_t -_cairo_escape_ps_name (char **ps_name); - -#endif /* CAIRO_HAS_FONT_SUBSET */ - -#endif /* CAIRO_SCALED_FONT_SUBSETS_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-scaled-font-subsets.c b/source/libs/cairo/cairo-src/src/cairo-scaled-font-subsets.c deleted file mode 100644 index 196fa999aa727352f50e1af669ac6894b3164faa..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-scaled-font-subsets.c +++ /dev/null @@ -1,1301 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2003 University of Southern California - * Copyright © 2005 Red Hat, Inc - * Copyright © 2006 Keith Packard - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Kristian Høgsberg <krh@redhat.com> - * Keith Packard <keithp@keithp.com> - * Adrian Johnson <ajohnson@redneon.com> - */ - -#define _BSD_SOURCE /* for snprintf(), strdup() */ -#include "cairoint.h" -#include "cairo-error-private.h" - -#if CAIRO_HAS_FONT_SUBSET - -#include "cairo-scaled-font-subsets-private.h" -#include "cairo-user-font-private.h" - -#define MAX_GLYPHS_PER_SIMPLE_FONT 256 -#define MAX_GLYPHS_PER_COMPOSITE_FONT 65536 - -typedef enum { - CAIRO_SUBSETS_SCALED, - CAIRO_SUBSETS_SIMPLE, - CAIRO_SUBSETS_COMPOSITE -} cairo_subsets_type_t; - -typedef enum { - CAIRO_SUBSETS_FOREACH_UNSCALED, - CAIRO_SUBSETS_FOREACH_SCALED, - CAIRO_SUBSETS_FOREACH_USER -} cairo_subsets_foreach_type_t; - -typedef struct _cairo_sub_font { - cairo_hash_entry_t base; - - cairo_bool_t is_scaled; - cairo_bool_t is_composite; - cairo_bool_t is_user; - cairo_bool_t use_latin_subset; - cairo_scaled_font_subsets_t *parent; - cairo_scaled_font_t *scaled_font; - unsigned int font_id; - - int current_subset; - int num_glyphs_in_current_subset; - int num_glyphs_in_latin_subset; - int max_glyphs_per_subset; - char latin_char_map[256]; - - cairo_hash_table_t *sub_font_glyphs; - struct _cairo_sub_font *next; -} cairo_sub_font_t; - -struct _cairo_scaled_font_subsets { - cairo_subsets_type_t type; - cairo_bool_t use_latin_subset; - - int max_glyphs_per_unscaled_subset_used; - cairo_hash_table_t *unscaled_sub_fonts; - cairo_sub_font_t *unscaled_sub_fonts_list; - cairo_sub_font_t *unscaled_sub_fonts_list_end; - - int max_glyphs_per_scaled_subset_used; - cairo_hash_table_t *scaled_sub_fonts; - cairo_sub_font_t *scaled_sub_fonts_list; - cairo_sub_font_t *scaled_sub_fonts_list_end; - - int num_sub_fonts; -}; - -typedef struct _cairo_sub_font_glyph { - cairo_hash_entry_t base; - - unsigned int subset_id; - unsigned int subset_glyph_index; - double x_advance; - double y_advance; - - cairo_bool_t is_latin; - int latin_character; - cairo_bool_t is_mapped; - uint32_t unicode; - char *utf8; - int utf8_len; -} cairo_sub_font_glyph_t; - -typedef struct _cairo_sub_font_collection { - unsigned long *glyphs; /* scaled_font_glyph_index */ - char **utf8; - unsigned int glyphs_size; - int *to_latin_char; - unsigned long *latin_to_subset_glyph_index; - unsigned int max_glyph; - unsigned int num_glyphs; - - unsigned int subset_id; - - cairo_status_t status; - cairo_scaled_font_subset_callback_func_t font_subset_callback; - void *font_subset_callback_closure; -} cairo_sub_font_collection_t; - -typedef struct _cairo_string_entry { - cairo_hash_entry_t base; - char *string; -} cairo_string_entry_t; - -static cairo_status_t -_cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font, - unsigned long scaled_font_glyph_index, - const char * utf8, - int utf8_len, - cairo_scaled_font_subsets_glyph_t *subset_glyph); - -static void -_cairo_sub_font_glyph_init_key (cairo_sub_font_glyph_t *sub_font_glyph, - unsigned long scaled_font_glyph_index) -{ - sub_font_glyph->base.hash = scaled_font_glyph_index; -} - -static cairo_sub_font_glyph_t * -_cairo_sub_font_glyph_create (unsigned long scaled_font_glyph_index, - unsigned int subset_id, - unsigned int subset_glyph_index, - double x_advance, - double y_advance, - int latin_character, - uint32_t unicode, - char *utf8, - int utf8_len) -{ - cairo_sub_font_glyph_t *sub_font_glyph; - - sub_font_glyph = malloc (sizeof (cairo_sub_font_glyph_t)); - if (unlikely (sub_font_glyph == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return NULL; - } - - _cairo_sub_font_glyph_init_key (sub_font_glyph, scaled_font_glyph_index); - sub_font_glyph->subset_id = subset_id; - sub_font_glyph->subset_glyph_index = subset_glyph_index; - sub_font_glyph->x_advance = x_advance; - sub_font_glyph->y_advance = y_advance; - sub_font_glyph->is_latin = (latin_character >= 0); - sub_font_glyph->latin_character = latin_character; - sub_font_glyph->is_mapped = FALSE; - sub_font_glyph->unicode = unicode; - sub_font_glyph->utf8 = utf8; - sub_font_glyph->utf8_len = utf8_len; - - return sub_font_glyph; -} - -static void -_cairo_sub_font_glyph_destroy (cairo_sub_font_glyph_t *sub_font_glyph) -{ - free (sub_font_glyph->utf8); - - free (sub_font_glyph); -} - -static void -_cairo_sub_font_glyph_pluck (void *entry, void *closure) -{ - cairo_sub_font_glyph_t *sub_font_glyph = entry; - cairo_hash_table_t *sub_font_glyphs = closure; - - _cairo_hash_table_remove (sub_font_glyphs, &sub_font_glyph->base); - _cairo_sub_font_glyph_destroy (sub_font_glyph); -} - -static void -_cairo_sub_font_glyph_collect (void *entry, void *closure) -{ - cairo_sub_font_glyph_t *sub_font_glyph = entry; - cairo_sub_font_collection_t *collection = closure; - unsigned long scaled_font_glyph_index; - unsigned int subset_glyph_index; - - if (sub_font_glyph->subset_id != collection->subset_id) - return; - - scaled_font_glyph_index = sub_font_glyph->base.hash; - subset_glyph_index = sub_font_glyph->subset_glyph_index; - - /* Ensure we don't exceed the allocated bounds. */ - assert (subset_glyph_index < collection->glyphs_size); - - collection->glyphs[subset_glyph_index] = scaled_font_glyph_index; - collection->utf8[subset_glyph_index] = sub_font_glyph->utf8; - collection->to_latin_char[subset_glyph_index] = sub_font_glyph->latin_character; - if (sub_font_glyph->is_latin) - collection->latin_to_subset_glyph_index[sub_font_glyph->latin_character] = subset_glyph_index; - - if (subset_glyph_index > collection->max_glyph) - collection->max_glyph = subset_glyph_index; - - collection->num_glyphs++; -} - -static cairo_bool_t -_cairo_sub_fonts_equal (const void *key_a, const void *key_b) -{ - const cairo_sub_font_t *sub_font_a = key_a; - const cairo_sub_font_t *sub_font_b = key_b; - cairo_scaled_font_t *a = sub_font_a->scaled_font; - cairo_scaled_font_t *b = sub_font_b->scaled_font; - - if (sub_font_a->is_scaled) - return a == b; - else - return a->font_face == b->font_face || a->original_font_face == b->original_font_face; -} - -static void -_cairo_sub_font_init_key (cairo_sub_font_t *sub_font, - cairo_scaled_font_t *scaled_font) -{ - if (sub_font->is_scaled) - { - sub_font->base.hash = (unsigned long) scaled_font; - sub_font->scaled_font = scaled_font; - } - else - { - sub_font->base.hash = (unsigned long) scaled_font->font_face; - sub_font->scaled_font = scaled_font; - } -} - -static cairo_status_t -_cairo_sub_font_create (cairo_scaled_font_subsets_t *parent, - cairo_scaled_font_t *scaled_font, - unsigned int font_id, - int max_glyphs_per_subset, - cairo_bool_t is_scaled, - cairo_bool_t is_composite, - cairo_sub_font_t **sub_font_out) -{ - cairo_sub_font_t *sub_font; - int i; - - sub_font = malloc (sizeof (cairo_sub_font_t)); - if (unlikely (sub_font == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - sub_font->is_scaled = is_scaled; - sub_font->is_composite = is_composite; - sub_font->is_user = _cairo_font_face_is_user (scaled_font->font_face); - _cairo_sub_font_init_key (sub_font, scaled_font); - - sub_font->parent = parent; - sub_font->scaled_font = scaled_font; - sub_font->font_id = font_id; - - sub_font->use_latin_subset = parent->use_latin_subset; - - /* latin subsets of Type 3 and CID CFF fonts are not supported */ - if (sub_font->is_user || sub_font->is_scaled || - _cairo_cff_scaled_font_is_cid_cff (scaled_font) ) - { - sub_font->use_latin_subset = FALSE; - } - - if (sub_font->use_latin_subset) - sub_font->current_subset = 1; /* reserve subset 0 for latin glyphs */ - else - sub_font->current_subset = 0; - - sub_font->num_glyphs_in_current_subset = 0; - sub_font->num_glyphs_in_latin_subset = 0; - sub_font->max_glyphs_per_subset = max_glyphs_per_subset; - for (i = 0; i < 256; i++) - sub_font->latin_char_map[i] = FALSE; - - sub_font->sub_font_glyphs = _cairo_hash_table_create (NULL); - if (unlikely (sub_font->sub_font_glyphs == NULL)) { - free (sub_font); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - sub_font->next = NULL; - *sub_font_out = sub_font; - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_sub_font_destroy (cairo_sub_font_t *sub_font) -{ - _cairo_hash_table_foreach (sub_font->sub_font_glyphs, - _cairo_sub_font_glyph_pluck, - sub_font->sub_font_glyphs); - _cairo_hash_table_destroy (sub_font->sub_font_glyphs); - cairo_scaled_font_destroy (sub_font->scaled_font); - free (sub_font); -} - -static void -_cairo_sub_font_pluck (void *entry, void *closure) -{ - cairo_sub_font_t *sub_font = entry; - cairo_hash_table_t *sub_fonts = closure; - - _cairo_hash_table_remove (sub_fonts, &sub_font->base); - _cairo_sub_font_destroy (sub_font); -} - -/* Characters 0x80 to 0x9f in the winansi encoding. - * All other characters in the range 0x00 to 0xff map 1:1 to unicode */ -static unsigned int _winansi_0x80_to_0x9f[] = { - 0x20ac, 0x0000, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, - 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017d, 0x0000, - 0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, - 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x0000, 0x017e, 0x0178 -}; - -int -_cairo_unicode_to_winansi (unsigned long uni) -{ - int i; - - /* exclude the extra "hyphen" at 0xad to avoid duplicate glyphnames */ - if ((uni >= 0x20 && uni <= 0x7e) || - (uni >= 0xa1 && uni <= 0xff && uni != 0xad) || - uni == 0) - return uni; - - for (i = 0; i < 32; i++) - if (_winansi_0x80_to_0x9f[i] == uni) - return i + 0x80; - - return -1; -} - -static cairo_status_t -_cairo_sub_font_glyph_lookup_unicode (cairo_scaled_font_t *scaled_font, - unsigned long scaled_font_glyph_index, - uint32_t *unicode_out, - char **utf8_out, - int *utf8_len_out) -{ - uint32_t unicode; - char buf[8]; - int len; - cairo_status_t status; - - /* Do a reverse lookup on the glyph index. unicode is -1 if the - * index could not be mapped to a unicode character. */ - unicode = -1; - status = _cairo_truetype_index_to_ucs4 (scaled_font, - scaled_font_glyph_index, - &unicode); - if (_cairo_status_is_error (status)) - return status; - - if (unicode == (uint32_t)-1 && scaled_font->backend->index_to_ucs4) { - status = scaled_font->backend->index_to_ucs4 (scaled_font, - scaled_font_glyph_index, - &unicode); - if (unlikely (status)) - return status; - } - - *unicode_out = unicode; - *utf8_out = NULL; - *utf8_len_out = 0; - if (unicode != (uint32_t) -1) { - len = _cairo_ucs4_to_utf8 (unicode, buf); - if (len > 0) { - *utf8_out = malloc (len + 1); - if (unlikely (*utf8_out == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - memcpy (*utf8_out, buf, len); - (*utf8_out)[len] = 0; - *utf8_len_out = len; - } - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_sub_font_glyph_map_to_unicode (cairo_sub_font_glyph_t *sub_font_glyph, - const char *utf8, - int utf8_len, - cairo_bool_t *is_mapped) -{ - *is_mapped = FALSE; - - if (utf8_len < 0) - return CAIRO_STATUS_SUCCESS; - - if (utf8 != NULL && utf8_len != 0 && utf8[utf8_len - 1] == '\0') - utf8_len--; - - if (utf8 != NULL && utf8_len != 0) { - if (sub_font_glyph->utf8 != NULL) { - if (utf8_len == sub_font_glyph->utf8_len && - memcmp (utf8, sub_font_glyph->utf8, utf8_len) == 0) - { - /* Requested utf8 mapping matches the existing mapping */ - *is_mapped = TRUE; - } - } else { - /* No existing mapping. Use the requested mapping */ - sub_font_glyph->utf8 = malloc (utf8_len + 1); - if (unlikely (sub_font_glyph->utf8 == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - memcpy (sub_font_glyph->utf8, utf8, utf8_len); - sub_font_glyph->utf8[utf8_len] = 0; - sub_font_glyph->utf8_len = utf8_len; - *is_mapped = TRUE; - } - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_sub_font_lookup_glyph (cairo_sub_font_t *sub_font, - unsigned long scaled_font_glyph_index, - const char *utf8, - int utf8_len, - cairo_scaled_font_subsets_glyph_t *subset_glyph) -{ - cairo_sub_font_glyph_t key, *sub_font_glyph; - cairo_int_status_t status; - - _cairo_sub_font_glyph_init_key (&key, scaled_font_glyph_index); - sub_font_glyph = _cairo_hash_table_lookup (sub_font->sub_font_glyphs, - &key.base); - if (sub_font_glyph != NULL) { - subset_glyph->font_id = sub_font->font_id; - subset_glyph->subset_id = sub_font_glyph->subset_id; - if (sub_font_glyph->is_latin) - subset_glyph->subset_glyph_index = sub_font_glyph->latin_character; - else - subset_glyph->subset_glyph_index = sub_font_glyph->subset_glyph_index; - - subset_glyph->is_scaled = sub_font->is_scaled; - subset_glyph->is_composite = sub_font->is_composite; - subset_glyph->is_latin = sub_font_glyph->is_latin; - subset_glyph->x_advance = sub_font_glyph->x_advance; - subset_glyph->y_advance = sub_font_glyph->y_advance; - status = _cairo_sub_font_glyph_map_to_unicode (sub_font_glyph, - utf8, utf8_len, - &subset_glyph->utf8_is_mapped); - subset_glyph->unicode = sub_font_glyph->unicode; - - return status; - } - - return CAIRO_INT_STATUS_UNSUPPORTED; -} - -static cairo_status_t -_cairo_sub_font_add_glyph (cairo_sub_font_t *sub_font, - unsigned long scaled_font_glyph_index, - cairo_bool_t is_latin, - int latin_character, - uint32_t unicode, - char *utf8, - int utf8_len, - cairo_sub_font_glyph_t **sub_font_glyph_out) -{ - cairo_scaled_glyph_t *scaled_glyph; - cairo_sub_font_glyph_t *sub_font_glyph; - int *num_glyphs_in_subset_ptr; - double x_advance; - double y_advance; - cairo_int_status_t status; - - _cairo_scaled_font_freeze_cache (sub_font->scaled_font); - status = _cairo_scaled_glyph_lookup (sub_font->scaled_font, - scaled_font_glyph_index, - CAIRO_SCALED_GLYPH_INFO_METRICS, - &scaled_glyph); - assert (status != CAIRO_INT_STATUS_UNSUPPORTED); - if (unlikely (status)) { - _cairo_scaled_font_thaw_cache (sub_font->scaled_font); - return status; - } - - x_advance = scaled_glyph->metrics.x_advance; - y_advance = scaled_glyph->metrics.y_advance; - _cairo_scaled_font_thaw_cache (sub_font->scaled_font); - - if (!is_latin && sub_font->num_glyphs_in_current_subset == sub_font->max_glyphs_per_subset) - { - sub_font->current_subset++; - sub_font->num_glyphs_in_current_subset = 0; - } - - if (is_latin) - num_glyphs_in_subset_ptr = &sub_font->num_glyphs_in_latin_subset; - else - num_glyphs_in_subset_ptr = &sub_font->num_glyphs_in_current_subset; - - /* Reserve first glyph in subset for the .notdef glyph except for - * Type 3 fonts */ - if (*num_glyphs_in_subset_ptr == 0 && - scaled_font_glyph_index != 0 && - ! _cairo_font_face_is_user (sub_font->scaled_font->font_face)) - { - status = _cairo_sub_font_add_glyph (sub_font, - 0, - is_latin, - 0, - 0, - NULL, - -1, - &sub_font_glyph); - if (unlikely (status)) - return status; - } - - sub_font_glyph = _cairo_sub_font_glyph_create (scaled_font_glyph_index, - is_latin ? 0 : sub_font->current_subset, - *num_glyphs_in_subset_ptr, - x_advance, - y_advance, - is_latin ? latin_character : -1, - unicode, - utf8, - utf8_len); - - if (unlikely (sub_font_glyph == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - status = _cairo_hash_table_insert (sub_font->sub_font_glyphs, &sub_font_glyph->base); - if (unlikely (status)) { - _cairo_sub_font_glyph_destroy (sub_font_glyph); - return status; - } - - (*num_glyphs_in_subset_ptr)++; - if (sub_font->is_scaled) { - if (*num_glyphs_in_subset_ptr > sub_font->parent->max_glyphs_per_scaled_subset_used) - sub_font->parent->max_glyphs_per_scaled_subset_used = *num_glyphs_in_subset_ptr; - } else { - if (*num_glyphs_in_subset_ptr > sub_font->parent->max_glyphs_per_unscaled_subset_used) - sub_font->parent->max_glyphs_per_unscaled_subset_used = *num_glyphs_in_subset_ptr; - } - - *sub_font_glyph_out = sub_font_glyph; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font, - unsigned long scaled_font_glyph_index, - const char *text_utf8, - int text_utf8_len, - cairo_scaled_font_subsets_glyph_t *subset_glyph) -{ - cairo_sub_font_glyph_t key, *sub_font_glyph; - cairo_status_t status; - - _cairo_sub_font_glyph_init_key (&key, scaled_font_glyph_index); - sub_font_glyph = _cairo_hash_table_lookup (sub_font->sub_font_glyphs, - &key.base); - if (sub_font_glyph == NULL) { - uint32_t font_unicode; - char *font_utf8; - int font_utf8_len; - cairo_bool_t is_latin; - int latin_character; - - status = _cairo_sub_font_glyph_lookup_unicode (sub_font->scaled_font, - scaled_font_glyph_index, - &font_unicode, - &font_utf8, - &font_utf8_len); - if (unlikely(status)) - return status; - - /* If the supplied utf8 is a valid single character, use it - * instead of the font lookup */ - if (text_utf8 != NULL && text_utf8_len > 0) { - uint32_t *ucs4; - int ucs4_len; - - status = _cairo_utf8_to_ucs4 (text_utf8, text_utf8_len, - &ucs4, &ucs4_len); - if (status == CAIRO_STATUS_SUCCESS) { - if (ucs4_len == 1) { - font_unicode = ucs4[0]; - free (font_utf8); - font_utf8 = malloc (text_utf8_len + 1); - if (font_utf8 == NULL) { - free (ucs4); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - memcpy (font_utf8, text_utf8, text_utf8_len); - font_utf8[text_utf8_len] = 0; - font_utf8_len = text_utf8_len; - } - free (ucs4); - } - } - - /* If glyph is in the winansi encoding and font is not a user - * font, put glyph in the latin subset. If glyph is .notdef - * the latin subset is preferred but only if the latin subset - * already contains at least one glyph. We don't want to - * create a separate subset just for the .notdef glyph. - */ - is_latin = FALSE; - latin_character = -1; - if (sub_font->use_latin_subset && - (! _cairo_font_face_is_user (sub_font->scaled_font->font_face))) - { - latin_character = _cairo_unicode_to_winansi (font_unicode); - if (latin_character > 0 || - (latin_character == 0 && sub_font->num_glyphs_in_latin_subset > 0)) - { - if (!sub_font->latin_char_map[latin_character]) { - sub_font->latin_char_map[latin_character] = TRUE; - is_latin = TRUE; - } - } - } - - status = _cairo_sub_font_add_glyph (sub_font, - scaled_font_glyph_index, - is_latin, - latin_character, - font_unicode, - font_utf8, - font_utf8_len, - &sub_font_glyph); - if (unlikely(status)) - return status; - } - - subset_glyph->font_id = sub_font->font_id; - subset_glyph->subset_id = sub_font_glyph->subset_id; - if (sub_font_glyph->is_latin) - subset_glyph->subset_glyph_index = sub_font_glyph->latin_character; - else - subset_glyph->subset_glyph_index = sub_font_glyph->subset_glyph_index; - - subset_glyph->is_scaled = sub_font->is_scaled; - subset_glyph->is_composite = sub_font->is_composite; - subset_glyph->is_latin = sub_font_glyph->is_latin; - subset_glyph->x_advance = sub_font_glyph->x_advance; - subset_glyph->y_advance = sub_font_glyph->y_advance; - status = _cairo_sub_font_glyph_map_to_unicode (sub_font_glyph, - text_utf8, text_utf8_len, - &subset_glyph->utf8_is_mapped); - subset_glyph->unicode = sub_font_glyph->unicode; - - return status; -} - -static void -_cairo_sub_font_collect (void *entry, void *closure) -{ - cairo_sub_font_t *sub_font = entry; - cairo_sub_font_collection_t *collection = closure; - cairo_scaled_font_subset_t subset; - int i; - unsigned int j; - - if (collection->status) - return; - - collection->status = sub_font->scaled_font->status; - if (collection->status) - return; - - for (i = 0; i <= sub_font->current_subset; i++) { - collection->subset_id = i; - collection->num_glyphs = 0; - collection->max_glyph = 0; - memset (collection->latin_to_subset_glyph_index, 0, 256*sizeof(unsigned long)); - - _cairo_hash_table_foreach (sub_font->sub_font_glyphs, - _cairo_sub_font_glyph_collect, collection); - if (collection->status) - break; - if (collection->num_glyphs == 0) - continue; - - /* Ensure the resulting array has no uninitialized holes */ - assert (collection->num_glyphs == collection->max_glyph + 1); - - subset.scaled_font = sub_font->scaled_font; - subset.is_composite = sub_font->is_composite; - subset.is_scaled = sub_font->is_scaled; - subset.font_id = sub_font->font_id; - subset.subset_id = i; - subset.glyphs = collection->glyphs; - subset.utf8 = collection->utf8; - subset.num_glyphs = collection->num_glyphs; - subset.glyph_names = NULL; - - subset.is_latin = FALSE; - if (sub_font->use_latin_subset && i == 0) { - subset.is_latin = TRUE; - subset.to_latin_char = collection->to_latin_char; - subset.latin_to_subset_glyph_index = collection->latin_to_subset_glyph_index; - } else { - subset.to_latin_char = NULL; - subset.latin_to_subset_glyph_index = NULL; - } - - collection->status = (collection->font_subset_callback) (&subset, - collection->font_subset_callback_closure); - - if (subset.glyph_names != NULL) { - for (j = 0; j < collection->num_glyphs; j++) - free (subset.glyph_names[j]); - free (subset.glyph_names); - } - - if (collection->status) - break; - } -} - -static cairo_scaled_font_subsets_t * -_cairo_scaled_font_subsets_create_internal (cairo_subsets_type_t type) -{ - cairo_scaled_font_subsets_t *subsets; - - subsets = malloc (sizeof (cairo_scaled_font_subsets_t)); - if (unlikely (subsets == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return NULL; - } - - subsets->type = type; - subsets->use_latin_subset = FALSE; - subsets->max_glyphs_per_unscaled_subset_used = 0; - subsets->max_glyphs_per_scaled_subset_used = 0; - subsets->num_sub_fonts = 0; - - subsets->unscaled_sub_fonts = _cairo_hash_table_create (_cairo_sub_fonts_equal); - if (! subsets->unscaled_sub_fonts) { - free (subsets); - return NULL; - } - subsets->unscaled_sub_fonts_list = NULL; - subsets->unscaled_sub_fonts_list_end = NULL; - - subsets->scaled_sub_fonts = _cairo_hash_table_create (_cairo_sub_fonts_equal); - if (! subsets->scaled_sub_fonts) { - _cairo_hash_table_destroy (subsets->unscaled_sub_fonts); - free (subsets); - return NULL; - } - subsets->scaled_sub_fonts_list = NULL; - subsets->scaled_sub_fonts_list_end = NULL; - - return subsets; -} - -cairo_scaled_font_subsets_t * -_cairo_scaled_font_subsets_create_scaled (void) -{ - return _cairo_scaled_font_subsets_create_internal (CAIRO_SUBSETS_SCALED); -} - -cairo_scaled_font_subsets_t * -_cairo_scaled_font_subsets_create_simple (void) -{ - return _cairo_scaled_font_subsets_create_internal (CAIRO_SUBSETS_SIMPLE); -} - -cairo_scaled_font_subsets_t * -_cairo_scaled_font_subsets_create_composite (void) -{ - return _cairo_scaled_font_subsets_create_internal (CAIRO_SUBSETS_COMPOSITE); -} - -void -_cairo_scaled_font_subsets_destroy (cairo_scaled_font_subsets_t *subsets) -{ - _cairo_hash_table_foreach (subsets->scaled_sub_fonts, _cairo_sub_font_pluck, subsets->scaled_sub_fonts); - _cairo_hash_table_destroy (subsets->scaled_sub_fonts); - - _cairo_hash_table_foreach (subsets->unscaled_sub_fonts, _cairo_sub_font_pluck, subsets->unscaled_sub_fonts); - _cairo_hash_table_destroy (subsets->unscaled_sub_fonts); - - free (subsets); -} - -void -_cairo_scaled_font_subsets_enable_latin_subset (cairo_scaled_font_subsets_t *font_subsets, - cairo_bool_t use_latin) -{ - font_subsets->use_latin_subset = use_latin; -} - -cairo_status_t -_cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets, - cairo_scaled_font_t *scaled_font, - unsigned long scaled_font_glyph_index, - const char * utf8, - int utf8_len, - cairo_scaled_font_subsets_glyph_t *subset_glyph) -{ - cairo_sub_font_t key, *sub_font; - cairo_scaled_glyph_t *scaled_glyph; - cairo_font_face_t *font_face; - cairo_matrix_t identity; - cairo_font_options_t font_options; - cairo_scaled_font_t *unscaled_font; - cairo_int_status_t status; - int max_glyphs; - cairo_bool_t type1_font; - - /* Lookup glyph in unscaled subsets */ - if (subsets->type != CAIRO_SUBSETS_SCALED) { - key.is_scaled = FALSE; - _cairo_sub_font_init_key (&key, scaled_font); - sub_font = _cairo_hash_table_lookup (subsets->unscaled_sub_fonts, - &key.base); - if (sub_font != NULL) { - status = _cairo_sub_font_lookup_glyph (sub_font, - scaled_font_glyph_index, - utf8, utf8_len, - subset_glyph); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - } - } - - /* Lookup glyph in scaled subsets */ - key.is_scaled = TRUE; - _cairo_sub_font_init_key (&key, scaled_font); - sub_font = _cairo_hash_table_lookup (subsets->scaled_sub_fonts, - &key.base); - if (sub_font != NULL) { - status = _cairo_sub_font_lookup_glyph (sub_font, - scaled_font_glyph_index, - utf8, utf8_len, - subset_glyph); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - } - - /* Glyph not found. Determine whether the glyph is outline or - * bitmap and add to the appropriate subset. - * - * glyph_index 0 (the .notdef glyph) is a special case. Some fonts - * will return CAIRO_INT_STATUS_UNSUPPORTED when doing a - * _scaled_glyph_lookup(_GLYPH_INFO_PATH). Type1-fallback creates - * empty glyphs in this case so we can put the glyph in a unscaled - * subset. */ - if (scaled_font_glyph_index == 0 || - _cairo_font_face_is_user (scaled_font->font_face)) { - status = CAIRO_STATUS_SUCCESS; - } else { - _cairo_scaled_font_freeze_cache (scaled_font); - status = _cairo_scaled_glyph_lookup (scaled_font, - scaled_font_glyph_index, - CAIRO_SCALED_GLYPH_INFO_PATH, - &scaled_glyph); - _cairo_scaled_font_thaw_cache (scaled_font); - } - if (_cairo_int_status_is_error (status)) - return status; - - if (status == CAIRO_INT_STATUS_SUCCESS && - subsets->type != CAIRO_SUBSETS_SCALED && - ! _cairo_font_face_is_user (scaled_font->font_face)) - { - /* Path available. Add to unscaled subset. */ - key.is_scaled = FALSE; - _cairo_sub_font_init_key (&key, scaled_font); - sub_font = _cairo_hash_table_lookup (subsets->unscaled_sub_fonts, - &key.base); - if (sub_font == NULL) { - font_face = cairo_scaled_font_get_font_face (scaled_font); - cairo_matrix_init_identity (&identity); - _cairo_font_options_init_default (&font_options); - cairo_font_options_set_hint_style (&font_options, CAIRO_HINT_STYLE_NONE); - cairo_font_options_set_hint_metrics (&font_options, CAIRO_HINT_METRICS_OFF); - unscaled_font = cairo_scaled_font_create (font_face, - &identity, - &identity, - &font_options); - if (unlikely (unscaled_font->status)) - return unscaled_font->status; - - subset_glyph->is_scaled = FALSE; - type1_font = _cairo_type1_scaled_font_is_type1 (unscaled_font); - if (subsets->type == CAIRO_SUBSETS_COMPOSITE && !type1_font) { - max_glyphs = MAX_GLYPHS_PER_COMPOSITE_FONT; - subset_glyph->is_composite = TRUE; - } else { - max_glyphs = MAX_GLYPHS_PER_SIMPLE_FONT; - subset_glyph->is_composite = FALSE; - } - - status = _cairo_sub_font_create (subsets, - unscaled_font, - subsets->num_sub_fonts, - max_glyphs, - subset_glyph->is_scaled, - subset_glyph->is_composite, - &sub_font); - - if (unlikely (status)) { - cairo_scaled_font_destroy (unscaled_font); - return status; - } - - status = _cairo_hash_table_insert (subsets->unscaled_sub_fonts, - &sub_font->base); - - if (unlikely (status)) { - _cairo_sub_font_destroy (sub_font); - return status; - } - if (!subsets->unscaled_sub_fonts_list) - subsets->unscaled_sub_fonts_list = sub_font; - else - subsets->unscaled_sub_fonts_list_end->next = sub_font; - subsets->unscaled_sub_fonts_list_end = sub_font; - subsets->num_sub_fonts++; - } - } else { - /* No path available. Add to scaled subset. */ - key.is_scaled = TRUE; - _cairo_sub_font_init_key (&key, scaled_font); - sub_font = _cairo_hash_table_lookup (subsets->scaled_sub_fonts, - &key.base); - if (sub_font == NULL) { - subset_glyph->is_scaled = TRUE; - subset_glyph->is_composite = FALSE; - if (subsets->type == CAIRO_SUBSETS_SCALED) - max_glyphs = INT_MAX; - else - max_glyphs = MAX_GLYPHS_PER_SIMPLE_FONT; - - status = _cairo_sub_font_create (subsets, - cairo_scaled_font_reference (scaled_font), - subsets->num_sub_fonts, - max_glyphs, - subset_glyph->is_scaled, - subset_glyph->is_composite, - &sub_font); - if (unlikely (status)) { - cairo_scaled_font_destroy (scaled_font); - return status; - } - - status = _cairo_hash_table_insert (subsets->scaled_sub_fonts, - &sub_font->base); - if (unlikely (status)) { - _cairo_sub_font_destroy (sub_font); - return status; - } - if (!subsets->scaled_sub_fonts_list) - subsets->scaled_sub_fonts_list = sub_font; - else - subsets->scaled_sub_fonts_list_end->next = sub_font; - subsets->scaled_sub_fonts_list_end = sub_font; - subsets->num_sub_fonts++; - } - } - - return _cairo_sub_font_map_glyph (sub_font, - scaled_font_glyph_index, - utf8, utf8_len, - subset_glyph); -} - -static cairo_status_t -_cairo_scaled_font_subsets_foreach_internal (cairo_scaled_font_subsets_t *font_subsets, - cairo_scaled_font_subset_callback_func_t font_subset_callback, - void *closure, - cairo_subsets_foreach_type_t type) -{ - cairo_sub_font_collection_t collection; - cairo_sub_font_t *sub_font; - cairo_bool_t is_scaled, is_user; - - is_scaled = FALSE; - is_user = FALSE; - - if (type == CAIRO_SUBSETS_FOREACH_USER) - is_user = TRUE; - - if (type == CAIRO_SUBSETS_FOREACH_SCALED || - type == CAIRO_SUBSETS_FOREACH_USER) - { - is_scaled = TRUE; - } - - if (is_scaled) - collection.glyphs_size = font_subsets->max_glyphs_per_scaled_subset_used; - else - collection.glyphs_size = font_subsets->max_glyphs_per_unscaled_subset_used; - - if (! collection.glyphs_size) - return CAIRO_STATUS_SUCCESS; - - collection.glyphs = _cairo_malloc_ab (collection.glyphs_size, sizeof(unsigned long)); - collection.utf8 = _cairo_malloc_ab (collection.glyphs_size, sizeof(char *)); - collection.to_latin_char = _cairo_malloc_ab (collection.glyphs_size, sizeof(int)); - collection.latin_to_subset_glyph_index = _cairo_malloc_ab (256, sizeof(unsigned long)); - if (unlikely (collection.glyphs == NULL || - collection.utf8 == NULL || - collection.to_latin_char == NULL || - collection.latin_to_subset_glyph_index == NULL)) { - free (collection.glyphs); - free (collection.utf8); - free (collection.to_latin_char); - free (collection.latin_to_subset_glyph_index); - - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - collection.font_subset_callback = font_subset_callback; - collection.font_subset_callback_closure = closure; - collection.status = CAIRO_STATUS_SUCCESS; - - if (is_scaled) - sub_font = font_subsets->scaled_sub_fonts_list; - else - sub_font = font_subsets->unscaled_sub_fonts_list; - - while (sub_font) { - if (sub_font->is_user == is_user) - _cairo_sub_font_collect (sub_font, &collection); - - sub_font = sub_font->next; - } - free (collection.utf8); - free (collection.glyphs); - free (collection.to_latin_char); - free (collection.latin_to_subset_glyph_index); - - return collection.status; -} - -cairo_status_t -_cairo_scaled_font_subsets_foreach_scaled (cairo_scaled_font_subsets_t *font_subsets, - cairo_scaled_font_subset_callback_func_t font_subset_callback, - void *closure) -{ - return _cairo_scaled_font_subsets_foreach_internal (font_subsets, - font_subset_callback, - closure, - CAIRO_SUBSETS_FOREACH_SCALED); -} - -cairo_status_t -_cairo_scaled_font_subsets_foreach_unscaled (cairo_scaled_font_subsets_t *font_subsets, - cairo_scaled_font_subset_callback_func_t font_subset_callback, - void *closure) -{ - return _cairo_scaled_font_subsets_foreach_internal (font_subsets, - font_subset_callback, - closure, - CAIRO_SUBSETS_FOREACH_UNSCALED); -} - -cairo_status_t -_cairo_scaled_font_subsets_foreach_user (cairo_scaled_font_subsets_t *font_subsets, - cairo_scaled_font_subset_callback_func_t font_subset_callback, - void *closure) -{ - return _cairo_scaled_font_subsets_foreach_internal (font_subsets, - font_subset_callback, - closure, - CAIRO_SUBSETS_FOREACH_USER); -} - -static cairo_bool_t -_cairo_string_equal (const void *key_a, const void *key_b) -{ - const cairo_string_entry_t *a = key_a; - const cairo_string_entry_t *b = key_b; - - if (strcmp (a->string, b->string) == 0) - return TRUE; - else - return FALSE; -} - -static void -_cairo_string_init_key (cairo_string_entry_t *key, char *s) -{ - unsigned long sum = 0; - unsigned int i; - - for (i = 0; i < strlen(s); i++) - sum += s[i]; - key->base.hash = sum; - key->string = s; -} - -static cairo_status_t -create_string_entry (char *s, cairo_string_entry_t **entry) -{ - *entry = malloc (sizeof (cairo_string_entry_t)); - if (unlikely (*entry == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_string_init_key (*entry, s); - - return CAIRO_STATUS_SUCCESS; -} - -static void -_pluck_entry (void *entry, void *closure) -{ - _cairo_hash_table_remove (closure, entry); - free (entry); -} - -cairo_int_status_t -_cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset) -{ - unsigned int i; - cairo_hash_table_t *names; - cairo_string_entry_t key, *entry; - char buf[30]; - char *utf8; - uint16_t *utf16; - int utf16_len; - cairo_status_t status = CAIRO_STATUS_SUCCESS; - - names = _cairo_hash_table_create (_cairo_string_equal); - if (unlikely (names == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - subset->glyph_names = calloc (subset->num_glyphs, sizeof (char *)); - if (unlikely (subset->glyph_names == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto CLEANUP_HASH; - } - - i = 0; - if (! subset->is_scaled) { - subset->glyph_names[0] = strdup (".notdef"); - if (unlikely (subset->glyph_names[0] == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto CLEANUP_HASH; - } - - status = create_string_entry (subset->glyph_names[0], &entry); - if (unlikely (status)) - goto CLEANUP_HASH; - - status = _cairo_hash_table_insert (names, &entry->base); - if (unlikely (status)) { - free (entry); - goto CLEANUP_HASH; - } - i++; - } - - for (; i < subset->num_glyphs; i++) { - utf8 = subset->utf8[i]; - utf16 = NULL; - utf16_len = 0; - if (utf8 && *utf8) { - status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &utf16_len); - if (unlikely (status)) - goto CLEANUP_HASH; - } - - if (utf16_len == 1) { - int ch = _cairo_unicode_to_winansi (utf16[0]); - if (ch > 0 && _cairo_winansi_to_glyphname (ch)) { - strncpy (buf, _cairo_winansi_to_glyphname (ch), sizeof (buf)); - buf[sizeof (buf)-1] = '\0'; - } else { - snprintf (buf, sizeof (buf), "uni%04X", (int) utf16[0]); - } - - _cairo_string_init_key (&key, buf); - entry = _cairo_hash_table_lookup (names, &key.base); - if (entry != NULL) - snprintf (buf, sizeof (buf), "g%d", i); - } else { - snprintf (buf, sizeof (buf), "g%d", i); - } - free (utf16); - - subset->glyph_names[i] = strdup (buf); - if (unlikely (subset->glyph_names[i] == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto CLEANUP_HASH; - } - - status = create_string_entry (subset->glyph_names[i], &entry); - if (unlikely (status)) - goto CLEANUP_HASH; - - status = _cairo_hash_table_insert (names, &entry->base); - if (unlikely (status)) { - free (entry); - goto CLEANUP_HASH; - } - } - -CLEANUP_HASH: - _cairo_hash_table_foreach (names, _pluck_entry, names); - _cairo_hash_table_destroy (names); - - if (likely (status == CAIRO_STATUS_SUCCESS)) - return CAIRO_STATUS_SUCCESS; - - if (subset->glyph_names != NULL) { - for (i = 0; i < subset->num_glyphs; i++) { - free (subset->glyph_names[i]); - } - - free (subset->glyph_names); - subset->glyph_names = NULL; - } - - return status; -} - -cairo_int_status_t -_cairo_escape_ps_name (char **ps_name) -{ - cairo_status_t status = CAIRO_STATUS_SUCCESS; - - /* Ensure PS name is a valid PDF/PS name object. In PDF names are - * treated as UTF8 and non ASCII bytes, ' ', and '#' are encoded - * as '#' followed by 2 hex digits that encode the byte. By also - * encoding the characters in the reserved string we ensure the - * name is also PS compatible. */ - if (*ps_name) { - static const char *reserved = "()<>[]{}/%#\\"; - char buf[128]; /* max name length is 127 bytes */ - char *src = *ps_name; - char *dst = buf; - - while (*src && dst < buf + 127) { - unsigned char c = *src; - if (c < 0x21 || c > 0x7e || strchr (reserved, c)) { - if (dst + 4 > buf + 127) - break; - - snprintf (dst, 4, "#%02X", c); - src++; - dst += 3; - } else { - *dst++ = *src++; - } - } - *dst = 0; - free (*ps_name); - *ps_name = strdup (buf); - if (*ps_name == NULL) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - } - - return status; -} - -#endif /* CAIRO_HAS_FONT_SUBSET */ diff --git a/source/libs/cairo/cairo-src/src/cairo-scaled-font.c b/source/libs/cairo/cairo-src/src/cairo-scaled-font.c deleted file mode 100644 index a22b36eef19e499bfbe34e3461235476190047b2..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-scaled-font.c +++ /dev/null @@ -1,3170 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* - * Copyright © 2005 Keith Packard - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Keith Packard - * - * Contributor(s): - * Keith Packard <keithp@keithp.com> - * Carl D. Worth <cworth@cworth.org> - * Graydon Hoare <graydon@redhat.com> - * Owen Taylor <otaylor@redhat.com> - * Behdad Esfahbod <behdad@behdad.org> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" -#include "cairo-error-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-list-inline.h" -#include "cairo-pattern-private.h" -#include "cairo-scaled-font-private.h" -#include "cairo-surface-backend-private.h" - -#if _XOPEN_SOURCE >= 600 || defined (_ISOC99_SOURCE) -#define ISFINITE(x) isfinite (x) -#else -#define ISFINITE(x) ((x) * (x) >= 0.) /* check for NaNs */ -#endif - -/** - * SECTION:cairo-scaled-font - * @Title: cairo_scaled_font_t - * @Short_Description: Font face at particular size and options - * @See_Also: #cairo_font_face_t, #cairo_matrix_t, #cairo_font_options_t - * - * #cairo_scaled_font_t represents a realization of a font face at a particular - * size and transformation and a certain set of font options. - **/ - -static uint32_t -_cairo_scaled_font_compute_hash (cairo_scaled_font_t *scaled_font); - -/* Global Glyph Cache - * - * We maintain a global pool of glyphs split between all active fonts. This - * allows a heavily used individual font to cache more glyphs than we could - * manage if we used per-font glyph caches, but at the same time maintains - * fairness across all fonts and provides a cap on the maximum number of - * global glyphs. - * - * The glyphs are allocated in pages, which are capped in the global pool. - * Using pages means we can reduce the frequency at which we have to probe the - * global pool and ameliorates the memory allocation pressure. - */ - -/* XXX: This number is arbitrary---we've never done any measurement of this. */ -#define MAX_GLYPH_PAGES_CACHED 512 -static cairo_cache_t cairo_scaled_glyph_page_cache; - -#define CAIRO_SCALED_GLYPH_PAGE_SIZE 32 -struct _cairo_scaled_glyph_page { - cairo_cache_entry_t cache_entry; - - cairo_list_t link; - - unsigned int num_glyphs; - cairo_scaled_glyph_t glyphs[CAIRO_SCALED_GLYPH_PAGE_SIZE]; -}; - -/* - * Notes: - * - * To store rasterizations of glyphs, we use an image surface and the - * device offset to represent the glyph origin. - * - * A device_transform converts from device space (a conceptual space) to - * surface space. For simple cases of translation only, it's called a - * device_offset and is public API (cairo_surface_[gs]et_device_offset()). - * A possibly better name for those functions could have been - * cairo_surface_[gs]et_origin(). So, that's what they do: they set where - * the device-space origin (0,0) is in the surface. If the origin is inside - * the surface, device_offset values are positive. It may look like this: - * - * Device space: - * (-x,-y) <-- negative numbers - * +----------------+ - * | . | - * | . | - * |......(0,0) <---|-- device-space origin - * | | - * | | - * +----------------+ - * (width-x,height-y) - * - * Surface space: - * (0,0) <-- surface-space origin - * +---------------+ - * | . | - * | . | - * |......(x,y) <--|-- device_offset - * | | - * | | - * +---------------+ - * (width,height) - * - * In other words: device_offset is the coordinates of the device-space - * origin relative to the top-left of the surface. - * - * We use device offsets in a couple of places: - * - * - Public API: To let toolkits like Gtk+ give user a surface that - * only represents part of the final destination (say, the expose - * area), but has the same device space as the destination. In these - * cases device_offset is typically negative. Example: - * - * application window - * +---------------+ - * | . | - * | (x,y). | - * |......+---+ | - * | | | <--|-- expose area - * | +---+ | - * +---------------+ - * - * In this case, the user of cairo API can set the device_space on - * the expose area to (-x,-y) to move the device space origin to that - * of the application window, such that drawing in the expose area - * surface and painting it in the application window has the same - * effect as drawing in the application window directly. Gtk+ has - * been using this feature. - * - * - Glyph surfaces: In most font rendering systems, glyph surfaces - * have an origin at (0,0) and a bounding box that is typically - * represented as (x_bearing,y_bearing,width,height). Depending on - * which way y progresses in the system, y_bearing may typically be - * negative (for systems similar to cairo, with origin at top left), - * or be positive (in systems like PDF with origin at bottom left). - * No matter which is the case, it is important to note that - * (x_bearing,y_bearing) is the coordinates of top-left of the glyph - * relative to the glyph origin. That is, for example: - * - * Scaled-glyph space: - * - * (x_bearing,y_bearing) <-- negative numbers - * +----------------+ - * | . | - * | . | - * |......(0,0) <---|-- glyph origin - * | | - * | | - * +----------------+ - * (width+x_bearing,height+y_bearing) - * - * Note the similarity of the origin to the device space. That is - * exactly how we use the device_offset to represent scaled glyphs: - * to use the device-space origin as the glyph origin. - * - * Now compare the scaled-glyph space to device-space and surface-space - * and convince yourself that: - * - * (x_bearing,y_bearing) = (-x,-y) = - device_offset - * - * That's right. If you are not convinced yet, contrast the definition - * of the two: - * - * "(x_bearing,y_bearing) is the coordinates of top-left of the - * glyph relative to the glyph origin." - * - * "In other words: device_offset is the coordinates of the - * device-space origin relative to the top-left of the surface." - * - * and note that glyph origin = device-space origin. - */ - -static void -_cairo_scaled_font_fini_internal (cairo_scaled_font_t *scaled_font); - -static void -_cairo_scaled_glyph_fini (cairo_scaled_font_t *scaled_font, - cairo_scaled_glyph_t *scaled_glyph) -{ - while (! cairo_list_is_empty (&scaled_glyph->dev_privates)) { - cairo_scaled_glyph_private_t *private = - cairo_list_first_entry (&scaled_glyph->dev_privates, - cairo_scaled_glyph_private_t, - link); - private->destroy (private, scaled_glyph, scaled_font); - } - - _cairo_image_scaled_glyph_fini (scaled_font, scaled_glyph); - - if (scaled_glyph->surface != NULL) - cairo_surface_destroy (&scaled_glyph->surface->base); - - if (scaled_glyph->path != NULL) - _cairo_path_fixed_destroy (scaled_glyph->path); - - if (scaled_glyph->recording_surface != NULL) { - cairo_surface_finish (scaled_glyph->recording_surface); - cairo_surface_destroy (scaled_glyph->recording_surface); - } -} - -#define ZOMBIE 0 -static const cairo_scaled_font_t _cairo_scaled_font_nil = { - { ZOMBIE }, /* hash_entry */ - CAIRO_STATUS_NO_MEMORY, /* status */ - CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ - { 0, 0, 0, NULL }, /* user_data */ - NULL, /* original_font_face */ - NULL, /* font_face */ - { 1., 0., 0., 1., 0, 0}, /* font_matrix */ - { 1., 0., 0., 1., 0, 0}, /* ctm */ - { CAIRO_ANTIALIAS_DEFAULT, /* options */ - CAIRO_SUBPIXEL_ORDER_DEFAULT, - CAIRO_HINT_STYLE_DEFAULT, - CAIRO_HINT_METRICS_DEFAULT} , - FALSE, /* placeholder */ - FALSE, /* holdover */ - TRUE, /* finished */ - { 1., 0., 0., 1., 0, 0}, /* scale */ - { 1., 0., 0., 1., 0, 0}, /* scale_inverse */ - 1., /* max_scale */ - { 0., 0., 0., 0., 0. }, /* extents */ - { 0., 0., 0., 0., 0. }, /* fs_extents */ - CAIRO_MUTEX_NIL_INITIALIZER,/* mutex */ - NULL, /* glyphs */ - { NULL, NULL }, /* pages */ - FALSE, /* cache_frozen */ - FALSE, /* global_cache_frozen */ - { NULL, NULL }, /* privates */ - NULL /* backend */ -}; - -/** - * _cairo_scaled_font_set_error: - * @scaled_font: a scaled_font - * @status: a status value indicating an error - * - * Atomically sets scaled_font->status to @status and calls _cairo_error; - * Does nothing if status is %CAIRO_STATUS_SUCCESS. - * - * All assignments of an error status to scaled_font->status should happen - * through _cairo_scaled_font_set_error(). Note that due to the nature of - * the atomic operation, it is not safe to call this function on the nil - * objects. - * - * The purpose of this function is to allow the user to set a - * breakpoint in _cairo_error() to generate a stack trace for when the - * user causes cairo to detect an error. - * - * Return value: the error status. - **/ -cairo_status_t -_cairo_scaled_font_set_error (cairo_scaled_font_t *scaled_font, - cairo_status_t status) -{ - if (status == CAIRO_STATUS_SUCCESS) - return status; - - /* Don't overwrite an existing error. This preserves the first - * error, which is the most significant. */ - _cairo_status_set_error (&scaled_font->status, status); - - return _cairo_error (status); -} - -/** - * cairo_scaled_font_get_type: - * @scaled_font: a #cairo_scaled_font_t - * - * This function returns the type of the backend used to create - * a scaled font. See #cairo_font_type_t for available types. - * However, this function never returns %CAIRO_FONT_TYPE_TOY. - * - * Return value: The type of @scaled_font. - * - * Since: 1.2 - **/ -cairo_font_type_t -cairo_scaled_font_get_type (cairo_scaled_font_t *scaled_font) -{ - if (CAIRO_REFERENCE_COUNT_IS_INVALID (&scaled_font->ref_count)) - return CAIRO_FONT_TYPE_TOY; - - return scaled_font->backend->type; -} - -/** - * cairo_scaled_font_status: - * @scaled_font: a #cairo_scaled_font_t - * - * Checks whether an error has previously occurred for this - * scaled_font. - * - * Return value: %CAIRO_STATUS_SUCCESS or another error such as - * %CAIRO_STATUS_NO_MEMORY. - * - * Since: 1.0 - **/ -cairo_status_t -cairo_scaled_font_status (cairo_scaled_font_t *scaled_font) -{ - return scaled_font->status; -} -slim_hidden_def (cairo_scaled_font_status); - -/* Here we keep a unique mapping from - * font_face/matrix/ctm/font_options => #cairo_scaled_font_t. - * - * Here are the things that we want to map: - * - * a) All otherwise referenced #cairo_scaled_font_t's - * b) Some number of not otherwise referenced #cairo_scaled_font_t's - * - * The implementation uses a hash table which covers (a) - * completely. Then, for (b) we have an array of otherwise - * unreferenced fonts (holdovers) which are expired in - * least-recently-used order. - * - * The cairo_scaled_font_create() code gets to treat this like a regular - * hash table. All of the magic for the little holdover cache is in - * cairo_scaled_font_reference() and cairo_scaled_font_destroy(). - */ - -/* This defines the size of the holdover array ... that is, the number - * of scaled fonts we keep around even when not otherwise referenced - */ -#define CAIRO_SCALED_FONT_MAX_HOLDOVERS 256 - -typedef struct _cairo_scaled_font_map { - cairo_scaled_font_t *mru_scaled_font; - cairo_hash_table_t *hash_table; - cairo_scaled_font_t *holdovers[CAIRO_SCALED_FONT_MAX_HOLDOVERS]; - int num_holdovers; -} cairo_scaled_font_map_t; - -static cairo_scaled_font_map_t *cairo_scaled_font_map; - -static int -_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) -{ - CAIRO_MUTEX_LOCK (_cairo_scaled_font_map_mutex); - - if (cairo_scaled_font_map == NULL) { - cairo_scaled_font_map = malloc (sizeof (cairo_scaled_font_map_t)); - if (unlikely (cairo_scaled_font_map == NULL)) - goto CLEANUP_MUTEX_LOCK; - - cairo_scaled_font_map->mru_scaled_font = NULL; - cairo_scaled_font_map->hash_table = - _cairo_hash_table_create (_cairo_scaled_font_keys_equal); - - if (unlikely (cairo_scaled_font_map->hash_table == NULL)) - goto CLEANUP_SCALED_FONT_MAP; - - cairo_scaled_font_map->num_holdovers = 0; - } - - return cairo_scaled_font_map; - - CLEANUP_SCALED_FONT_MAP: - free (cairo_scaled_font_map); - cairo_scaled_font_map = NULL; - CLEANUP_MUTEX_LOCK: - CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_map_mutex); - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return NULL; -} - -static void -_cairo_scaled_font_map_unlock (void) -{ - CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_map_mutex); -} - -void -_cairo_scaled_font_map_destroy (void) -{ - cairo_scaled_font_map_t *font_map; - cairo_scaled_font_t *scaled_font; - - CAIRO_MUTEX_LOCK (_cairo_scaled_font_map_mutex); - - font_map = cairo_scaled_font_map; - if (unlikely (font_map == NULL)) { - goto CLEANUP_MUTEX_LOCK; - } - - scaled_font = font_map->mru_scaled_font; - if (scaled_font != NULL) { - CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_map_mutex); - cairo_scaled_font_destroy (scaled_font); - CAIRO_MUTEX_LOCK (_cairo_scaled_font_map_mutex); - } - - /* remove scaled_fonts starting from the end so that font_map->holdovers - * is always in a consistent state when we release the mutex. */ - while (font_map->num_holdovers) { - scaled_font = font_map->holdovers[font_map->num_holdovers-1]; - assert (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&scaled_font->ref_count)); - _cairo_hash_table_remove (font_map->hash_table, - &scaled_font->hash_entry); - - font_map->num_holdovers--; - - /* This releases the font_map lock to avoid the possibility of a - * recursive deadlock when the scaled font destroy closure gets - * called - */ - _cairo_scaled_font_fini (scaled_font); - - free (scaled_font); - } - - _cairo_hash_table_destroy (font_map->hash_table); - - free (cairo_scaled_font_map); - cairo_scaled_font_map = NULL; - - CLEANUP_MUTEX_LOCK: - CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_map_mutex); -} - -static void -_cairo_scaled_glyph_page_destroy (cairo_scaled_font_t *scaled_font, - cairo_scaled_glyph_page_t *page) -{ - unsigned int n; - - assert (!scaled_font->cache_frozen); - assert (!scaled_font->global_cache_frozen); - - for (n = 0; n < page->num_glyphs; n++) { - _cairo_hash_table_remove (scaled_font->glyphs, - &page->glyphs[n].hash_entry); - _cairo_scaled_glyph_fini (scaled_font, &page->glyphs[n]); - } - - cairo_list_del (&page->link); - free (page); -} - -static void -_cairo_scaled_glyph_page_pluck (void *closure) -{ - cairo_scaled_glyph_page_t *page = closure; - cairo_scaled_font_t *scaled_font; - - assert (! cairo_list_is_empty (&page->link)); - - scaled_font = (cairo_scaled_font_t *) page->cache_entry.hash; - - CAIRO_MUTEX_LOCK (scaled_font->mutex); - _cairo_scaled_glyph_page_destroy (scaled_font, page); - CAIRO_MUTEX_UNLOCK (scaled_font->mutex); -} - -/* If a scaled font wants to unlock the font map while still being - * created (needed for user-fonts), we need to take extra care not - * ending up with multiple identical scaled fonts being created. - * - * What we do is, we create a fake identical scaled font, and mark - * it as placeholder, lock its mutex, and insert that in the fontmap - * hash table. This makes other code trying to create an identical - * scaled font to just wait and retry. - * - * The reason we have to create a fake scaled font instead of just using - * scaled_font is for lifecycle management: we need to (or rather, - * other code needs to) reference the scaled_font in the hash table. - * We can't do that on the input scaled_font as it may be freed by - * font backend upon error. - */ - -cairo_status_t -_cairo_scaled_font_register_placeholder_and_unlock_font_map (cairo_scaled_font_t *scaled_font) -{ - cairo_status_t status; - cairo_scaled_font_t *placeholder_scaled_font; - - assert (CAIRO_MUTEX_IS_LOCKED (_cairo_scaled_font_map_mutex)); - - status = scaled_font->status; - if (unlikely (status)) - return status; - - placeholder_scaled_font = malloc (sizeof (cairo_scaled_font_t)); - if (unlikely (placeholder_scaled_font == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - /* full initialization is wasteful, but who cares... */ - status = _cairo_scaled_font_init (placeholder_scaled_font, - scaled_font->font_face, - &scaled_font->font_matrix, - &scaled_font->ctm, - &scaled_font->options, - NULL); - if (unlikely (status)) - goto FREE_PLACEHOLDER; - - placeholder_scaled_font->placeholder = TRUE; - - placeholder_scaled_font->hash_entry.hash - = _cairo_scaled_font_compute_hash (placeholder_scaled_font); - status = _cairo_hash_table_insert (cairo_scaled_font_map->hash_table, - &placeholder_scaled_font->hash_entry); - if (unlikely (status)) - goto FINI_PLACEHOLDER; - - CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_map_mutex); - CAIRO_MUTEX_LOCK (placeholder_scaled_font->mutex); - - return CAIRO_STATUS_SUCCESS; - - FINI_PLACEHOLDER: - _cairo_scaled_font_fini_internal (placeholder_scaled_font); - FREE_PLACEHOLDER: - free (placeholder_scaled_font); - - return _cairo_scaled_font_set_error (scaled_font, status); -} - -void -_cairo_scaled_font_unregister_placeholder_and_lock_font_map (cairo_scaled_font_t *scaled_font) -{ - cairo_scaled_font_t *placeholder_scaled_font; - - CAIRO_MUTEX_LOCK (_cairo_scaled_font_map_mutex); - - /* temporary hash value to match the placeholder */ - scaled_font->hash_entry.hash - = _cairo_scaled_font_compute_hash (scaled_font); - placeholder_scaled_font = - _cairo_hash_table_lookup (cairo_scaled_font_map->hash_table, - &scaled_font->hash_entry); - assert (placeholder_scaled_font != NULL); - assert (placeholder_scaled_font->placeholder); - assert (CAIRO_MUTEX_IS_LOCKED (placeholder_scaled_font->mutex)); - - _cairo_hash_table_remove (cairo_scaled_font_map->hash_table, - &placeholder_scaled_font->hash_entry); - - CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_map_mutex); - - CAIRO_MUTEX_UNLOCK (placeholder_scaled_font->mutex); - cairo_scaled_font_destroy (placeholder_scaled_font); - - CAIRO_MUTEX_LOCK (_cairo_scaled_font_map_mutex); -} - -static void -_cairo_scaled_font_placeholder_wait_for_creation_to_finish (cairo_scaled_font_t *placeholder_scaled_font) -{ - /* reference the place holder so it doesn't go away */ - cairo_scaled_font_reference (placeholder_scaled_font); - - /* now unlock the fontmap mutex so creation has a chance to finish */ - CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_map_mutex); - - /* wait on placeholder mutex until we are awaken */ - CAIRO_MUTEX_LOCK (placeholder_scaled_font->mutex); - - /* ok, creation done. just clean up and back out */ - CAIRO_MUTEX_UNLOCK (placeholder_scaled_font->mutex); - cairo_scaled_font_destroy (placeholder_scaled_font); - - CAIRO_MUTEX_LOCK (_cairo_scaled_font_map_mutex); -} - -/* Fowler / Noll / Vo (FNV) Hash (http://www.isthe.com/chongo/tech/comp/fnv/) - * - * Not necessarily better than a lot of other hashes, but should be OK, and - * well tested with binary data. - */ - -#define FNV_32_PRIME ((uint32_t)0x01000193) -#define FNV1_32_INIT ((uint32_t)0x811c9dc5) - -static uint32_t -_hash_matrix_fnv (const cairo_matrix_t *matrix, - uint32_t hval) -{ - const uint8_t *buffer = (const uint8_t *) matrix; - int len = sizeof (cairo_matrix_t); - do { - hval *= FNV_32_PRIME; - hval ^= *buffer++; - } while (--len); - - return hval; -} - -static uint32_t -_hash_mix_bits (uint32_t hash) -{ - hash += hash << 12; - hash ^= hash >> 7; - hash += hash << 3; - hash ^= hash >> 17; - hash += hash << 5; - return hash; -} - -static uint32_t -_cairo_scaled_font_compute_hash (cairo_scaled_font_t *scaled_font) -{ - uint32_t hash = FNV1_32_INIT; - - /* We do a bytewise hash on the font matrices */ - hash = _hash_matrix_fnv (&scaled_font->font_matrix, hash); - hash = _hash_matrix_fnv (&scaled_font->ctm, hash); - hash = _hash_mix_bits (hash); - - hash ^= (unsigned long) scaled_font->original_font_face; - hash ^= cairo_font_options_hash (&scaled_font->options); - - /* final mixing of bits */ - hash = _hash_mix_bits (hash); - assert (hash != ZOMBIE); - - return hash; -} - -static void -_cairo_scaled_font_init_key (cairo_scaled_font_t *scaled_font, - cairo_font_face_t *font_face, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options) -{ - scaled_font->status = CAIRO_STATUS_SUCCESS; - scaled_font->placeholder = FALSE; - scaled_font->font_face = font_face; - scaled_font->original_font_face = font_face; - scaled_font->font_matrix = *font_matrix; - scaled_font->ctm = *ctm; - /* ignore translation values in the ctm */ - scaled_font->ctm.x0 = 0.; - scaled_font->ctm.y0 = 0.; - _cairo_font_options_init_copy (&scaled_font->options, options); - - scaled_font->hash_entry.hash = - _cairo_scaled_font_compute_hash (scaled_font); -} - -static cairo_bool_t -_cairo_scaled_font_keys_equal (const void *abstract_key_a, - const void *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->original_font_face == key_b->original_font_face && - memcmp ((unsigned char *)(&key_a->font_matrix.xx), - (unsigned char *)(&key_b->font_matrix.xx), - sizeof(cairo_matrix_t)) == 0 && - memcmp ((unsigned char *)(&key_a->ctm.xx), - (unsigned char *)(&key_b->ctm.xx), - sizeof(cairo_matrix_t)) == 0 && - cairo_font_options_equal (&key_a->options, &key_b->options); -} - -static cairo_bool_t -_cairo_scaled_font_matches (const cairo_scaled_font_t *scaled_font, - const cairo_font_face_t *font_face, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options) -{ - return scaled_font->original_font_face == font_face && - memcmp ((unsigned char *)(&scaled_font->font_matrix.xx), - (unsigned char *)(&font_matrix->xx), - sizeof(cairo_matrix_t)) == 0 && - memcmp ((unsigned char *)(&scaled_font->ctm.xx), - (unsigned char *)(&ctm->xx), - sizeof(cairo_matrix_t)) == 0 && - cairo_font_options_equal (&scaled_font->options, options); -} - -/* - * Basic #cairo_scaled_font_t object management - */ - -cairo_status_t -_cairo_scaled_font_init (cairo_scaled_font_t *scaled_font, - cairo_font_face_t *font_face, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options, - const cairo_scaled_font_backend_t *backend) -{ - cairo_status_t status; - - status = cairo_font_options_status ((cairo_font_options_t *) options); - if (unlikely (status)) - return status; - - scaled_font->status = CAIRO_STATUS_SUCCESS; - scaled_font->placeholder = FALSE; - scaled_font->font_face = font_face; - scaled_font->original_font_face = font_face; - scaled_font->font_matrix = *font_matrix; - scaled_font->ctm = *ctm; - /* ignore translation values in the ctm */ - scaled_font->ctm.x0 = 0.; - scaled_font->ctm.y0 = 0.; - _cairo_font_options_init_copy (&scaled_font->options, options); - - cairo_matrix_multiply (&scaled_font->scale, - &scaled_font->font_matrix, - &scaled_font->ctm); - - scaled_font->max_scale = MAX (fabs (scaled_font->scale.xx) + fabs (scaled_font->scale.xy), - fabs (scaled_font->scale.yx) + fabs (scaled_font->scale.yy)); - scaled_font->scale_inverse = scaled_font->scale; - status = cairo_matrix_invert (&scaled_font->scale_inverse); - if (unlikely (status)) { - /* If the font scale matrix is rank 0, just using an all-zero inverse matrix - * makes everything work correctly. This make font size 0 work without - * producing an error. - * - * FIXME: If the scale is rank 1, we still go into error mode. But then - * again, that's what we do everywhere in cairo. - * - * Also, the check for == 0. below may be too harsh... - */ - if (_cairo_matrix_is_scale_0 (&scaled_font->scale)) { - cairo_matrix_init (&scaled_font->scale_inverse, - 0, 0, 0, 0, - -scaled_font->scale.x0, - -scaled_font->scale.y0); - } else - return status; - } - - scaled_font->glyphs = _cairo_hash_table_create (NULL); - if (unlikely (scaled_font->glyphs == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - cairo_list_init (&scaled_font->glyph_pages); - scaled_font->cache_frozen = FALSE; - scaled_font->global_cache_frozen = FALSE; - - scaled_font->holdover = FALSE; - scaled_font->finished = FALSE; - - CAIRO_REFERENCE_COUNT_INIT (&scaled_font->ref_count, 1); - - _cairo_user_data_array_init (&scaled_font->user_data); - - cairo_font_face_reference (font_face); - scaled_font->original_font_face = NULL; - - CAIRO_MUTEX_INIT (scaled_font->mutex); - - cairo_list_init (&scaled_font->dev_privates); - - scaled_font->backend = backend; - cairo_list_init (&scaled_font->link); - - return CAIRO_STATUS_SUCCESS; -} - -void -_cairo_scaled_font_freeze_cache (cairo_scaled_font_t *scaled_font) -{ - /* ensure we do not modify an error object */ - assert (scaled_font->status == CAIRO_STATUS_SUCCESS); - - CAIRO_MUTEX_LOCK (scaled_font->mutex); - scaled_font->cache_frozen = TRUE; -} - -void -_cairo_scaled_font_thaw_cache (cairo_scaled_font_t *scaled_font) -{ - assert (scaled_font->cache_frozen); - - if (scaled_font->global_cache_frozen) { - CAIRO_MUTEX_LOCK (_cairo_scaled_glyph_page_cache_mutex); - _cairo_cache_thaw (&cairo_scaled_glyph_page_cache); - CAIRO_MUTEX_UNLOCK (_cairo_scaled_glyph_page_cache_mutex); - scaled_font->global_cache_frozen = FALSE; - } - - scaled_font->cache_frozen = FALSE; - CAIRO_MUTEX_UNLOCK (scaled_font->mutex); -} - -void -_cairo_scaled_font_reset_cache (cairo_scaled_font_t *scaled_font) -{ - cairo_scaled_glyph_page_t *page; - - CAIRO_MUTEX_LOCK (scaled_font->mutex); - assert (! scaled_font->cache_frozen); - assert (! scaled_font->global_cache_frozen); - CAIRO_MUTEX_LOCK (_cairo_scaled_glyph_page_cache_mutex); - - cairo_list_foreach_entry (page, - cairo_scaled_glyph_page_t, - &scaled_font->glyph_pages, - link) { - cairo_scaled_glyph_page_cache.size -= page->cache_entry.size; - _cairo_hash_table_remove (cairo_scaled_glyph_page_cache.hash_table, - (cairo_hash_entry_t *) &page->cache_entry); - } - - CAIRO_MUTEX_UNLOCK (_cairo_scaled_glyph_page_cache_mutex); - - /* Destroy scaled_font's pages while holding its lock only, and not the - * global page cache lock. The destructor can cause us to recurse and - * end up back here for a different scaled_font. */ - - while (! cairo_list_is_empty (&scaled_font->glyph_pages)) { - page = cairo_list_first_entry (&scaled_font->glyph_pages, - cairo_scaled_glyph_page_t, - link); - _cairo_scaled_glyph_page_destroy (scaled_font, page); - } - - CAIRO_MUTEX_UNLOCK (scaled_font->mutex); -} - -cairo_status_t -_cairo_scaled_font_set_metrics (cairo_scaled_font_t *scaled_font, - cairo_font_extents_t *fs_metrics) -{ - cairo_status_t status; - double font_scale_x, font_scale_y; - - scaled_font->fs_extents = *fs_metrics; - - status = _cairo_matrix_compute_basis_scale_factors (&scaled_font->font_matrix, - &font_scale_x, &font_scale_y, - 1); - if (unlikely (status)) - return status; - - /* - * The font responded in unscaled units, scale by the font - * matrix scale factors to get to user space - */ - - scaled_font->extents.ascent = fs_metrics->ascent * font_scale_y; - scaled_font->extents.descent = fs_metrics->descent * font_scale_y; - scaled_font->extents.height = fs_metrics->height * font_scale_y; - scaled_font->extents.max_x_advance = fs_metrics->max_x_advance * font_scale_x; - scaled_font->extents.max_y_advance = fs_metrics->max_y_advance * font_scale_y; - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_scaled_font_fini_internal (cairo_scaled_font_t *scaled_font) -{ - assert (! scaled_font->cache_frozen); - assert (! scaled_font->global_cache_frozen); - scaled_font->finished = TRUE; - - _cairo_scaled_font_reset_cache (scaled_font); - _cairo_hash_table_destroy (scaled_font->glyphs); - - cairo_font_face_destroy (scaled_font->font_face); - cairo_font_face_destroy (scaled_font->original_font_face); - - CAIRO_MUTEX_FINI (scaled_font->mutex); - - while (! cairo_list_is_empty (&scaled_font->dev_privates)) { - cairo_scaled_font_private_t *private = - cairo_list_first_entry (&scaled_font->dev_privates, - cairo_scaled_font_private_t, - link); - private->destroy (private, scaled_font); - } - - if (scaled_font->backend != NULL && scaled_font->backend->fini != NULL) - scaled_font->backend->fini (scaled_font); - - _cairo_user_data_array_fini (&scaled_font->user_data); -} - -void -_cairo_scaled_font_fini (cairo_scaled_font_t *scaled_font) -{ - /* Release the lock to avoid the possibility of a recursive - * deadlock when the scaled font destroy closure gets called. */ - CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_map_mutex); - _cairo_scaled_font_fini_internal (scaled_font); - CAIRO_MUTEX_LOCK (_cairo_scaled_font_map_mutex); -} - -void -_cairo_scaled_font_attach_private (cairo_scaled_font_t *scaled_font, - cairo_scaled_font_private_t *private, - const void *key, - void (*destroy) (cairo_scaled_font_private_t *, - cairo_scaled_font_t *)) -{ - private->key = key; - private->destroy = destroy; - cairo_list_add (&private->link, &scaled_font->dev_privates); -} - -cairo_scaled_font_private_t * -_cairo_scaled_font_find_private (cairo_scaled_font_t *scaled_font, - const void *key) -{ - cairo_scaled_font_private_t *priv; - - cairo_list_foreach_entry (priv, cairo_scaled_font_private_t, - &scaled_font->dev_privates, link) - { - if (priv->key == key) { - if (priv->link.prev != &scaled_font->dev_privates) - cairo_list_move (&priv->link, &scaled_font->dev_privates); - return priv; - } - } - - return NULL; -} - -void -_cairo_scaled_glyph_attach_private (cairo_scaled_glyph_t *scaled_glyph, - cairo_scaled_glyph_private_t *private, - const void *key, - void (*destroy) (cairo_scaled_glyph_private_t *, - cairo_scaled_glyph_t *, - cairo_scaled_font_t *)) -{ - private->key = key; - private->destroy = destroy; - cairo_list_add (&private->link, &scaled_glyph->dev_privates); -} - -cairo_scaled_glyph_private_t * -_cairo_scaled_glyph_find_private (cairo_scaled_glyph_t *scaled_glyph, - const void *key) -{ - cairo_scaled_glyph_private_t *priv; - - cairo_list_foreach_entry (priv, cairo_scaled_glyph_private_t, - &scaled_glyph->dev_privates, link) - { - if (priv->key == key) { - if (priv->link.prev != &scaled_glyph->dev_privates) - cairo_list_move (&priv->link, &scaled_glyph->dev_privates); - return priv; - } - } - - return NULL; -} - -/** - * cairo_scaled_font_create: - * @font_face: a #cairo_font_face_t - * @font_matrix: font space to user space transformation matrix for the - * font. In the simplest case of a N point font, this matrix is - * just a scale by N, but it can also be used to shear the font - * or stretch it unequally along the two axes. See - * cairo_set_font_matrix(). - * @ctm: user to device transformation matrix with which the font will - * be used. - * @options: options to use when getting metrics for the font and - * rendering with it. - * - * Creates a #cairo_scaled_font_t object from a font face and matrices that - * describe the size of the font and the environment in which it will - * be used. - * - * Return value: a newly created #cairo_scaled_font_t. Destroy with - * cairo_scaled_font_destroy() - * - * Since: 1.0 - **/ -cairo_scaled_font_t * -cairo_scaled_font_create (cairo_font_face_t *font_face, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options) -{ - cairo_status_t status; - cairo_scaled_font_map_t *font_map; - cairo_font_face_t *original_font_face = font_face; - cairo_scaled_font_t key, *old = NULL, *scaled_font = NULL, *dead = NULL; - double det; - - status = font_face->status; - if (unlikely (status)) - return _cairo_scaled_font_create_in_error (status); - - det = _cairo_matrix_compute_determinant (font_matrix); - if (! ISFINITE (det)) - return _cairo_scaled_font_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_MATRIX)); - - det = _cairo_matrix_compute_determinant (ctm); - if (! ISFINITE (det)) - return _cairo_scaled_font_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_MATRIX)); - - status = cairo_font_options_status ((cairo_font_options_t *) options); - if (unlikely (status)) - return _cairo_scaled_font_create_in_error (status); - - /* Note that degenerate ctm or font_matrix *are* allowed. - * We want to support a font size of 0. */ - - font_map = _cairo_scaled_font_map_lock (); - if (unlikely (font_map == NULL)) - return _cairo_scaled_font_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - scaled_font = font_map->mru_scaled_font; - if (scaled_font != NULL && - _cairo_scaled_font_matches (scaled_font, - font_face, font_matrix, ctm, options)) - { - assert (scaled_font->hash_entry.hash != ZOMBIE); - assert (! scaled_font->placeholder); - - if (likely (scaled_font->status == CAIRO_STATUS_SUCCESS)) { - /* We increment the reference count manually here, (rather - * than calling into cairo_scaled_font_reference), since we - * must modify the reference count while our lock is still - * held. */ - _cairo_reference_count_inc (&scaled_font->ref_count); - _cairo_scaled_font_map_unlock (); - return scaled_font; - } - - /* the font has been put into an error status - abandon the cache */ - _cairo_hash_table_remove (font_map->hash_table, - &scaled_font->hash_entry); - scaled_font->hash_entry.hash = ZOMBIE; - dead = scaled_font; - font_map->mru_scaled_font = NULL; - } - - _cairo_scaled_font_init_key (&key, font_face, font_matrix, ctm, options); - - while ((scaled_font = _cairo_hash_table_lookup (font_map->hash_table, - &key.hash_entry))) - { - if (! scaled_font->placeholder) - break; - - /* If the scaled font is being created (happens for user-font), - * just wait until it's done, then retry */ - _cairo_scaled_font_placeholder_wait_for_creation_to_finish (scaled_font); - } - - if (scaled_font != NULL) { - /* If the original reference count is 0, then this font must have - * been found in font_map->holdovers, (which means this caching is - * actually working). So now we remove it from the holdovers - * array, unless we caught the font in the middle of destruction. - */ - if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&scaled_font->ref_count)) { - if (scaled_font->holdover) { - int i; - - for (i = 0; i < font_map->num_holdovers; i++) { - if (font_map->holdovers[i] == scaled_font) { - font_map->num_holdovers--; - memmove (&font_map->holdovers[i], - &font_map->holdovers[i+1], - (font_map->num_holdovers - i) * sizeof (cairo_scaled_font_t*)); - break; - } - } - - scaled_font->holdover = FALSE; - } - - /* reset any error status */ - scaled_font->status = CAIRO_STATUS_SUCCESS; - } - - if (likely (scaled_font->status == CAIRO_STATUS_SUCCESS)) { - /* We increment the reference count manually here, (rather - * than calling into cairo_scaled_font_reference), since we - * must modify the reference count while our lock is still - * held. */ - - old = font_map->mru_scaled_font; - font_map->mru_scaled_font = scaled_font; - /* increment reference count for the mru cache */ - _cairo_reference_count_inc (&scaled_font->ref_count); - /* and increment for the returned reference */ - _cairo_reference_count_inc (&scaled_font->ref_count); - _cairo_scaled_font_map_unlock (); - - cairo_scaled_font_destroy (old); - if (font_face != original_font_face) - cairo_font_face_destroy (font_face); - - return scaled_font; - } - - /* the font has been put into an error status - abandon the cache */ - _cairo_hash_table_remove (font_map->hash_table, - &scaled_font->hash_entry); - scaled_font->hash_entry.hash = ZOMBIE; - } - - - /* Otherwise create it and insert it into the hash table. */ - if (font_face->backend->get_implementation != NULL) { - font_face = font_face->backend->get_implementation (font_face, - font_matrix, - ctm, - options); - if (unlikely (font_face->status)) { - _cairo_scaled_font_map_unlock (); - return _cairo_scaled_font_create_in_error (font_face->status); - } - } - - status = font_face->backend->scaled_font_create (font_face, font_matrix, - ctm, options, &scaled_font); - /* Did we leave the backend in an error state? */ - if (unlikely (status)) { - _cairo_scaled_font_map_unlock (); - if (font_face != original_font_face) - cairo_font_face_destroy (font_face); - - if (dead != NULL) - cairo_scaled_font_destroy (dead); - - status = _cairo_font_face_set_error (font_face, status); - return _cairo_scaled_font_create_in_error (status); - } - /* Or did we encounter an error whilst constructing the scaled font? */ - if (unlikely (scaled_font->status)) { - _cairo_scaled_font_map_unlock (); - if (font_face != original_font_face) - cairo_font_face_destroy (font_face); - - if (dead != NULL) - cairo_scaled_font_destroy (dead); - - return scaled_font; - } - - /* Our caching above is defeated if the backend switches fonts on us - - * e.g. old incarnations of toy-font-face and lazily resolved - * ft-font-faces - */ - assert (scaled_font->font_face == font_face); - assert (! scaled_font->cache_frozen); - assert (! scaled_font->global_cache_frozen); - - scaled_font->original_font_face = - cairo_font_face_reference (original_font_face); - - scaled_font->hash_entry.hash = _cairo_scaled_font_compute_hash(scaled_font); - - status = _cairo_hash_table_insert (font_map->hash_table, - &scaled_font->hash_entry); - if (likely (status == CAIRO_STATUS_SUCCESS)) { - old = font_map->mru_scaled_font; - font_map->mru_scaled_font = scaled_font; - _cairo_reference_count_inc (&scaled_font->ref_count); - } - - _cairo_scaled_font_map_unlock (); - - cairo_scaled_font_destroy (old); - if (font_face != original_font_face) - cairo_font_face_destroy (font_face); - - if (dead != NULL) - cairo_scaled_font_destroy (dead); - - if (unlikely (status)) { - /* We can't call _cairo_scaled_font_destroy here since it expects - * that the font has already been successfully inserted into the - * hash table. */ - _cairo_scaled_font_fini_internal (scaled_font); - free (scaled_font); - return _cairo_scaled_font_create_in_error (status); - } - - return scaled_font; -} -slim_hidden_def (cairo_scaled_font_create); - -static cairo_scaled_font_t *_cairo_scaled_font_nil_objects[CAIRO_STATUS_LAST_STATUS + 1]; - -/* XXX This should disappear in favour of a common pool of error objects. */ -cairo_scaled_font_t * -_cairo_scaled_font_create_in_error (cairo_status_t status) -{ - cairo_scaled_font_t *scaled_font; - - assert (status != CAIRO_STATUS_SUCCESS); - - if (status == CAIRO_STATUS_NO_MEMORY) - return (cairo_scaled_font_t *) &_cairo_scaled_font_nil; - - CAIRO_MUTEX_LOCK (_cairo_scaled_font_error_mutex); - scaled_font = _cairo_scaled_font_nil_objects[status]; - if (unlikely (scaled_font == NULL)) { - scaled_font = malloc (sizeof (cairo_scaled_font_t)); - if (unlikely (scaled_font == NULL)) { - CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_error_mutex); - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_scaled_font_t *) &_cairo_scaled_font_nil; - } - - *scaled_font = _cairo_scaled_font_nil; - scaled_font->status = status; - _cairo_scaled_font_nil_objects[status] = scaled_font; - } - CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_error_mutex); - - return scaled_font; -} - -void -_cairo_scaled_font_reset_static_data (void) -{ - int status; - - CAIRO_MUTEX_LOCK (_cairo_scaled_font_error_mutex); - for (status = CAIRO_STATUS_SUCCESS; - status <= CAIRO_STATUS_LAST_STATUS; - status++) - { - free (_cairo_scaled_font_nil_objects[status]); - _cairo_scaled_font_nil_objects[status] = NULL; - } - CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_error_mutex); - - CAIRO_MUTEX_LOCK (_cairo_scaled_glyph_page_cache_mutex); - if (cairo_scaled_glyph_page_cache.hash_table != NULL) { - _cairo_cache_fini (&cairo_scaled_glyph_page_cache); - cairo_scaled_glyph_page_cache.hash_table = NULL; - } - CAIRO_MUTEX_UNLOCK (_cairo_scaled_glyph_page_cache_mutex); -} - -/** - * cairo_scaled_font_reference: - * @scaled_font: a #cairo_scaled_font_t, (may be %NULL in which case - * this function does nothing) - * - * Increases the reference count on @scaled_font by one. This prevents - * @scaled_font from being destroyed until a matching call to - * cairo_scaled_font_destroy() is made. - * - * The number of references to a #cairo_scaled_font_t can be get using - * cairo_scaled_font_get_reference_count(). - * - * Returns: the referenced #cairo_scaled_font_t - * - * Since: 1.0 - **/ -cairo_scaled_font_t * -cairo_scaled_font_reference (cairo_scaled_font_t *scaled_font) -{ - if (scaled_font == NULL || - CAIRO_REFERENCE_COUNT_IS_INVALID (&scaled_font->ref_count)) - return scaled_font; - - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&scaled_font->ref_count)); - - _cairo_reference_count_inc (&scaled_font->ref_count); - - return scaled_font; -} -slim_hidden_def (cairo_scaled_font_reference); - -/** - * cairo_scaled_font_destroy: - * @scaled_font: a #cairo_scaled_font_t - * - * Decreases the reference count on @font by one. If the result - * is zero, then @font and all associated resources are freed. - * See cairo_scaled_font_reference(). - * - * Since: 1.0 - **/ -void -cairo_scaled_font_destroy (cairo_scaled_font_t *scaled_font) -{ - cairo_scaled_font_t *lru = NULL; - cairo_scaled_font_map_t *font_map; - - assert (CAIRO_MUTEX_IS_UNLOCKED (_cairo_scaled_font_map_mutex)); - - if (scaled_font == NULL || - CAIRO_REFERENCE_COUNT_IS_INVALID (&scaled_font->ref_count)) - return; - - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&scaled_font->ref_count)); - - if (! _cairo_reference_count_dec_and_test (&scaled_font->ref_count)) - return; - - assert (! scaled_font->cache_frozen); - assert (! scaled_font->global_cache_frozen); - - font_map = _cairo_scaled_font_map_lock (); - assert (font_map != NULL); - - /* Another thread may have resurrected the font whilst we waited */ - if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&scaled_font->ref_count)) { - if (! scaled_font->placeholder && - scaled_font->hash_entry.hash != ZOMBIE) - { - /* Another thread may have already inserted us into the holdovers */ - if (scaled_font->holdover) - goto unlock; - - /* Rather than immediately destroying this object, we put it into - * the font_map->holdovers array in case it will get used again - * soon (and is why we must hold the lock over the atomic op on - * the reference count). To make room for it, we do actually - * destroy the least-recently-used holdover. - */ - - if (font_map->num_holdovers == CAIRO_SCALED_FONT_MAX_HOLDOVERS) { - lru = font_map->holdovers[0]; - assert (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&lru->ref_count)); - - _cairo_hash_table_remove (font_map->hash_table, - &lru->hash_entry); - - font_map->num_holdovers--; - memmove (&font_map->holdovers[0], - &font_map->holdovers[1], - font_map->num_holdovers * sizeof (cairo_scaled_font_t*)); - } - - font_map->holdovers[font_map->num_holdovers++] = scaled_font; - scaled_font->holdover = TRUE; - } else - lru = scaled_font; - } - - unlock: - _cairo_scaled_font_map_unlock (); - - /* If we pulled an item from the holdovers array, (while the font - * map lock was held, of course), then there is no way that anyone - * else could have acquired a reference to it. So we can now - * safely call fini on it without any lock held. This is desirable - * as we never want to call into any backend function with a lock - * held. */ - if (lru != NULL) { - _cairo_scaled_font_fini_internal (lru); - free (lru); - } -} -slim_hidden_def (cairo_scaled_font_destroy); - -/** - * cairo_scaled_font_get_reference_count: - * @scaled_font: a #cairo_scaled_font_t - * - * Returns the current reference count of @scaled_font. - * - * Return value: the current reference count of @scaled_font. If the - * object is a nil object, 0 will be returned. - * - * Since: 1.4 - **/ -unsigned int -cairo_scaled_font_get_reference_count (cairo_scaled_font_t *scaled_font) -{ - if (scaled_font == NULL || - CAIRO_REFERENCE_COUNT_IS_INVALID (&scaled_font->ref_count)) - return 0; - - return CAIRO_REFERENCE_COUNT_GET_VALUE (&scaled_font->ref_count); -} - -/** - * cairo_scaled_font_get_user_data: - * @scaled_font: a #cairo_scaled_font_t - * @key: the address of the #cairo_user_data_key_t the user data was - * attached to - * - * Return user data previously attached to @scaled_font using the - * specified key. If no user data has been attached with the given - * key this function returns %NULL. - * - * Return value: the user data previously attached or %NULL. - * - * Since: 1.4 - **/ -void * -cairo_scaled_font_get_user_data (cairo_scaled_font_t *scaled_font, - const cairo_user_data_key_t *key) -{ - return _cairo_user_data_array_get_data (&scaled_font->user_data, - key); -} -slim_hidden_def (cairo_scaled_font_get_user_data); - -/** - * cairo_scaled_font_set_user_data: - * @scaled_font: a #cairo_scaled_font_t - * @key: the address of a #cairo_user_data_key_t to attach the user data to - * @user_data: the user data to attach to the #cairo_scaled_font_t - * @destroy: a #cairo_destroy_func_t which will be called when the - * #cairo_t is destroyed or when new user data is attached using the - * same key. - * - * Attach user data to @scaled_font. To remove user data from a surface, - * call this function with the key that was used to set it and %NULL - * for @data. - * - * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a - * slot could not be allocated for the user data. - * - * Since: 1.4 - **/ -cairo_status_t -cairo_scaled_font_set_user_data (cairo_scaled_font_t *scaled_font, - const cairo_user_data_key_t *key, - void *user_data, - cairo_destroy_func_t destroy) -{ - if (CAIRO_REFERENCE_COUNT_IS_INVALID (&scaled_font->ref_count)) - return scaled_font->status; - - return _cairo_user_data_array_set_data (&scaled_font->user_data, - key, user_data, destroy); -} -slim_hidden_def (cairo_scaled_font_set_user_data); - -/* Public font API follows. */ - -/** - * cairo_scaled_font_extents: - * @scaled_font: a #cairo_scaled_font_t - * @extents: a #cairo_font_extents_t which to store the retrieved extents. - * - * Gets the metrics for a #cairo_scaled_font_t. - * - * Since: 1.0 - **/ -void -cairo_scaled_font_extents (cairo_scaled_font_t *scaled_font, - cairo_font_extents_t *extents) -{ - if (scaled_font->status) { - extents->ascent = 0.0; - extents->descent = 0.0; - extents->height = 0.0; - extents->max_x_advance = 0.0; - extents->max_y_advance = 0.0; - return; - } - - *extents = scaled_font->extents; -} -slim_hidden_def (cairo_scaled_font_extents); - -/** - * cairo_scaled_font_text_extents: - * @scaled_font: a #cairo_scaled_font_t - * @utf8: a NUL-terminated string of text, encoded in UTF-8 - * @extents: a #cairo_text_extents_t which to store the retrieved extents. - * - * Gets the extents for a string of text. The extents describe a - * user-space rectangle that encloses the "inked" portion of the text - * drawn at the origin (0,0) (as it would be drawn by cairo_show_text() - * if the cairo graphics state were set to the same font_face, - * font_matrix, ctm, and font_options as @scaled_font). Additionally, - * the x_advance and y_advance values indicate the amount by which the - * current point would be advanced by cairo_show_text(). - * - * Note that whitespace characters do not directly contribute to the - * size of the rectangle (extents.width and extents.height). They do - * contribute indirectly by changing the position of non-whitespace - * characters. In particular, trailing whitespace characters are - * likely to not affect the size of the rectangle, though they will - * affect the x_advance and y_advance values. - * - * Since: 1.2 - **/ -void -cairo_scaled_font_text_extents (cairo_scaled_font_t *scaled_font, - const char *utf8, - cairo_text_extents_t *extents) -{ - cairo_status_t status; - cairo_glyph_t *glyphs = NULL; - int num_glyphs; - - if (scaled_font->status) - goto ZERO_EXTENTS; - - if (utf8 == NULL) - goto ZERO_EXTENTS; - - status = cairo_scaled_font_text_to_glyphs (scaled_font, 0., 0., - utf8, -1, - &glyphs, &num_glyphs, - NULL, NULL, - NULL); - if (unlikely (status)) { - status = _cairo_scaled_font_set_error (scaled_font, status); - goto ZERO_EXTENTS; - } - - cairo_scaled_font_glyph_extents (scaled_font, glyphs, num_glyphs, extents); - free (glyphs); - - return; - -ZERO_EXTENTS: - extents->x_bearing = 0.0; - extents->y_bearing = 0.0; - extents->width = 0.0; - extents->height = 0.0; - extents->x_advance = 0.0; - extents->y_advance = 0.0; -} - -/** - * cairo_scaled_font_glyph_extents: - * @scaled_font: a #cairo_scaled_font_t - * @glyphs: an array of glyph IDs with X and Y offsets. - * @num_glyphs: the number of glyphs in the @glyphs array - * @extents: a #cairo_text_extents_t which to store the retrieved extents. - * - * Gets the extents for an array of glyphs. The extents describe a - * user-space rectangle that encloses the "inked" portion of the - * glyphs, (as they would be drawn by cairo_show_glyphs() if the cairo - * graphics state were set to the same font_face, font_matrix, ctm, - * and font_options as @scaled_font). Additionally, the x_advance and - * y_advance values indicate the amount by which the current point - * would be advanced by cairo_show_glyphs(). - * - * Note that whitespace glyphs do not contribute to the size of the - * rectangle (extents.width and extents.height). - * - * Since: 1.0 - **/ -void -cairo_scaled_font_glyph_extents (cairo_scaled_font_t *scaled_font, - const cairo_glyph_t *glyphs, - int num_glyphs, - cairo_text_extents_t *extents) -{ - cairo_status_t status; - int i; - double min_x = 0.0, min_y = 0.0, max_x = 0.0, max_y = 0.0; - cairo_bool_t visible = FALSE; - cairo_scaled_glyph_t *scaled_glyph = NULL; - - extents->x_bearing = 0.0; - extents->y_bearing = 0.0; - extents->width = 0.0; - extents->height = 0.0; - extents->x_advance = 0.0; - extents->y_advance = 0.0; - - if (unlikely (scaled_font->status)) - goto ZERO_EXTENTS; - - if (num_glyphs == 0) - goto ZERO_EXTENTS; - - if (unlikely (num_glyphs < 0)) { - _cairo_error_throw (CAIRO_STATUS_NEGATIVE_COUNT); - /* XXX Can't propagate error */ - goto ZERO_EXTENTS; - } - - if (unlikely (glyphs == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NULL_POINTER); - /* XXX Can't propagate error */ - goto ZERO_EXTENTS; - } - - _cairo_scaled_font_freeze_cache (scaled_font); - - for (i = 0; i < num_glyphs; i++) { - double left, top, right, bottom; - - status = _cairo_scaled_glyph_lookup (scaled_font, - glyphs[i].index, - CAIRO_SCALED_GLYPH_INFO_METRICS, - &scaled_glyph); - if (unlikely (status)) { - status = _cairo_scaled_font_set_error (scaled_font, status); - goto UNLOCK; - } - - /* "Ink" extents should skip "invisible" glyphs */ - if (scaled_glyph->metrics.width == 0 || scaled_glyph->metrics.height == 0) - continue; - - left = scaled_glyph->metrics.x_bearing + glyphs[i].x; - right = left + scaled_glyph->metrics.width; - top = scaled_glyph->metrics.y_bearing + glyphs[i].y; - bottom = top + scaled_glyph->metrics.height; - - if (!visible) { - visible = TRUE; - min_x = left; - max_x = right; - min_y = top; - max_y = bottom; - } else { - if (left < min_x) min_x = left; - if (right > max_x) max_x = right; - if (top < min_y) min_y = top; - if (bottom > max_y) max_y = bottom; - } - } - - if (visible) { - extents->x_bearing = min_x - glyphs[0].x; - extents->y_bearing = min_y - glyphs[0].y; - extents->width = max_x - min_x; - extents->height = max_y - min_y; - } else { - extents->x_bearing = 0.0; - extents->y_bearing = 0.0; - extents->width = 0.0; - extents->height = 0.0; - } - - if (num_glyphs) { - double x0, y0, x1, y1; - - x0 = glyphs[0].x; - y0 = glyphs[0].y; - - /* scaled_glyph contains the glyph for num_glyphs - 1 already. */ - x1 = glyphs[num_glyphs - 1].x + scaled_glyph->metrics.x_advance; - y1 = glyphs[num_glyphs - 1].y + scaled_glyph->metrics.y_advance; - - extents->x_advance = x1 - x0; - extents->y_advance = y1 - y0; - } else { - extents->x_advance = 0.0; - extents->y_advance = 0.0; - } - - UNLOCK: - _cairo_scaled_font_thaw_cache (scaled_font); - return; - -ZERO_EXTENTS: - extents->x_bearing = 0.0; - extents->y_bearing = 0.0; - extents->width = 0.0; - extents->height = 0.0; - extents->x_advance = 0.0; - extents->y_advance = 0.0; -} -slim_hidden_def (cairo_scaled_font_glyph_extents); - -#define GLYPH_LUT_SIZE 64 -static cairo_status_t -cairo_scaled_font_text_to_glyphs_internal_cached (cairo_scaled_font_t *scaled_font, - double x, - double y, - const char *utf8, - cairo_glyph_t *glyphs, - cairo_text_cluster_t **clusters, - int num_chars) -{ - struct glyph_lut_elt { - unsigned long index; - double x_advance; - double y_advance; - } glyph_lut[GLYPH_LUT_SIZE]; - uint32_t glyph_lut_unicode[GLYPH_LUT_SIZE]; - cairo_status_t status; - const char *p; - int i; - - for (i = 0; i < GLYPH_LUT_SIZE; i++) - glyph_lut_unicode[i] = ~0U; - - p = utf8; - for (i = 0; i < num_chars; i++) { - int idx, num_bytes; - uint32_t unicode; - cairo_scaled_glyph_t *scaled_glyph; - struct glyph_lut_elt *glyph_slot; - - num_bytes = _cairo_utf8_get_char_validated (p, &unicode); - p += num_bytes; - - glyphs[i].x = x; - glyphs[i].y = y; - - idx = unicode % ARRAY_LENGTH (glyph_lut); - glyph_slot = &glyph_lut[idx]; - if (glyph_lut_unicode[idx] == unicode) { - glyphs[i].index = glyph_slot->index; - x += glyph_slot->x_advance; - y += glyph_slot->y_advance; - } else { - unsigned long g; - - g = scaled_font->backend->ucs4_to_index (scaled_font, unicode); - status = _cairo_scaled_glyph_lookup (scaled_font, - g, - CAIRO_SCALED_GLYPH_INFO_METRICS, - &scaled_glyph); - if (unlikely (status)) - return status; - - x += scaled_glyph->metrics.x_advance; - y += scaled_glyph->metrics.y_advance; - - glyph_lut_unicode[idx] = unicode; - glyph_slot->index = g; - glyph_slot->x_advance = scaled_glyph->metrics.x_advance; - glyph_slot->y_advance = scaled_glyph->metrics.y_advance; - - glyphs[i].index = g; - } - - if (clusters) { - (*clusters)[i].num_bytes = num_bytes; - (*clusters)[i].num_glyphs = 1; - } - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_scaled_font_text_to_glyphs_internal_uncached (cairo_scaled_font_t *scaled_font, - double x, - double y, - const char *utf8, - cairo_glyph_t *glyphs, - cairo_text_cluster_t **clusters, - int num_chars) -{ - const char *p; - int i; - - p = utf8; - for (i = 0; i < num_chars; i++) { - unsigned long g; - int num_bytes; - uint32_t unicode; - cairo_scaled_glyph_t *scaled_glyph; - cairo_status_t status; - - num_bytes = _cairo_utf8_get_char_validated (p, &unicode); - p += num_bytes; - - glyphs[i].x = x; - glyphs[i].y = y; - - g = scaled_font->backend->ucs4_to_index (scaled_font, unicode); - - /* - * No advance needed for a single character string. So, let's speed up - * one-character strings by skipping glyph lookup. - */ - if (num_chars > 1) { - status = _cairo_scaled_glyph_lookup (scaled_font, - g, - CAIRO_SCALED_GLYPH_INFO_METRICS, - &scaled_glyph); - if (unlikely (status)) - return status; - - x += scaled_glyph->metrics.x_advance; - y += scaled_glyph->metrics.y_advance; - } - - glyphs[i].index = g; - - if (clusters) { - (*clusters)[i].num_bytes = num_bytes; - (*clusters)[i].num_glyphs = 1; - } - } - - return CAIRO_STATUS_SUCCESS; -} - -/** - * cairo_scaled_font_text_to_glyphs: - * @x: X position to place first glyph - * @y: Y position to place first glyph - * @scaled_font: a #cairo_scaled_font_t - * @utf8: a string of text encoded in UTF-8 - * @utf8_len: length of @utf8 in bytes, or -1 if it is NUL-terminated - * @glyphs: pointer to array of glyphs to fill - * @num_glyphs: pointer to number of glyphs - * @clusters: pointer to array of cluster mapping information to fill, or %NULL - * @num_clusters: pointer to number of clusters, or %NULL - * @cluster_flags: pointer to location to store cluster flags corresponding to the - * output @clusters, or %NULL - * - * Converts UTF-8 text to an array of glyphs, optionally with cluster - * mapping, that can be used to render later using @scaled_font. - * - * If @glyphs initially points to a non-%NULL value, that array is used - * as a glyph buffer, and @num_glyphs should point to the number of glyph - * entries available there. If the provided glyph array is too short for - * the conversion, a new glyph array is allocated using cairo_glyph_allocate() - * and placed in @glyphs. Upon return, @num_glyphs always contains the - * number of generated glyphs. If the value @glyphs points to has changed - * after the call, the user is responsible for freeing the allocated glyph - * array using cairo_glyph_free(). This may happen even if the provided - * array was large enough. - * - * If @clusters is not %NULL, @num_clusters and @cluster_flags should not be %NULL, - * and cluster mapping will be computed. - * The semantics of how cluster array allocation works is similar to the glyph - * array. That is, - * if @clusters initially points to a non-%NULL value, that array is used - * as a cluster buffer, and @num_clusters should point to the number of cluster - * entries available there. If the provided cluster array is too short for - * the conversion, a new cluster array is allocated using cairo_text_cluster_allocate() - * and placed in @clusters. Upon return, @num_clusters always contains the - * number of generated clusters. If the value @clusters points at has changed - * after the call, the user is responsible for freeing the allocated cluster - * array using cairo_text_cluster_free(). This may happen even if the provided - * array was large enough. - * - * In the simplest case, @glyphs and @clusters can point to %NULL initially - * and a suitable array will be allocated. In code: - * <informalexample><programlisting> - * cairo_status_t status; - * - * cairo_glyph_t *glyphs = NULL; - * int num_glyphs; - * cairo_text_cluster_t *clusters = NULL; - * int num_clusters; - * cairo_text_cluster_flags_t cluster_flags; - * - * status = cairo_scaled_font_text_to_glyphs (scaled_font, - * x, y, - * utf8, utf8_len, - * &glyphs, &num_glyphs, - * &clusters, &num_clusters, &cluster_flags); - * - * if (status == CAIRO_STATUS_SUCCESS) { - * cairo_show_text_glyphs (cr, - * utf8, utf8_len, - * glyphs, num_glyphs, - * clusters, num_clusters, cluster_flags); - * - * cairo_glyph_free (glyphs); - * cairo_text_cluster_free (clusters); - * } - * </programlisting></informalexample> - * - * If no cluster mapping is needed: - * <informalexample><programlisting> - * cairo_status_t status; - * - * cairo_glyph_t *glyphs = NULL; - * int num_glyphs; - * - * status = cairo_scaled_font_text_to_glyphs (scaled_font, - * x, y, - * utf8, utf8_len, - * &glyphs, &num_glyphs, - * NULL, NULL, - * NULL); - * - * if (status == CAIRO_STATUS_SUCCESS) { - * cairo_show_glyphs (cr, glyphs, num_glyphs); - * cairo_glyph_free (glyphs); - * } - * </programlisting></informalexample> - * - * If stack-based glyph and cluster arrays are to be used for small - * arrays: - * <informalexample><programlisting> - * cairo_status_t status; - * - * cairo_glyph_t stack_glyphs[40]; - * cairo_glyph_t *glyphs = stack_glyphs; - * int num_glyphs = sizeof (stack_glyphs) / sizeof (stack_glyphs[0]); - * cairo_text_cluster_t stack_clusters[40]; - * cairo_text_cluster_t *clusters = stack_clusters; - * int num_clusters = sizeof (stack_clusters) / sizeof (stack_clusters[0]); - * cairo_text_cluster_flags_t cluster_flags; - * - * status = cairo_scaled_font_text_to_glyphs (scaled_font, - * x, y, - * utf8, utf8_len, - * &glyphs, &num_glyphs, - * &clusters, &num_clusters, &cluster_flags); - * - * if (status == CAIRO_STATUS_SUCCESS) { - * cairo_show_text_glyphs (cr, - * utf8, utf8_len, - * glyphs, num_glyphs, - * clusters, num_clusters, cluster_flags); - * - * if (glyphs != stack_glyphs) - * cairo_glyph_free (glyphs); - * if (clusters != stack_clusters) - * cairo_text_cluster_free (clusters); - * } - * </programlisting></informalexample> - * - * For details of how @clusters, @num_clusters, and @cluster_flags map input - * UTF-8 text to the output glyphs see cairo_show_text_glyphs(). - * - * The output values can be readily passed to cairo_show_text_glyphs() - * cairo_show_glyphs(), or related functions, assuming that the exact - * same @scaled_font is used for the operation. - * - * Return value: %CAIRO_STATUS_SUCCESS upon success, or an error status - * if the input values are wrong or if conversion failed. If the input - * values are correct but the conversion failed, the error status is also - * set on @scaled_font. - * - * Since: 1.8 - **/ -#define CACHING_THRESHOLD 16 -cairo_status_t -cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font, - double x, - double y, - const char *utf8, - int utf8_len, - cairo_glyph_t **glyphs, - int *num_glyphs, - cairo_text_cluster_t **clusters, - int *num_clusters, - cairo_text_cluster_flags_t *cluster_flags) -{ - int num_chars = 0; - cairo_int_status_t status; - cairo_glyph_t *orig_glyphs; - cairo_text_cluster_t *orig_clusters; - - status = scaled_font->status; - if (unlikely (status)) - return status; - - /* A slew of sanity checks */ - - /* glyphs and num_glyphs can't be NULL */ - if (glyphs == NULL || - num_glyphs == NULL) { - status = _cairo_error (CAIRO_STATUS_NULL_POINTER); - goto BAIL; - } - - /* Special case for NULL and -1 */ - if (utf8 == NULL && utf8_len == -1) - utf8_len = 0; - - /* No NULLs for non-NULLs! */ - if ((utf8_len && utf8 == NULL) || - (clusters && num_clusters == NULL) || - (clusters && cluster_flags == NULL)) { - status = _cairo_error (CAIRO_STATUS_NULL_POINTER); - goto BAIL; - } - - /* A -1 for utf8_len means NUL-terminated */ - if (utf8_len == -1) - utf8_len = strlen (utf8); - - /* A NULL *glyphs means no prealloced glyphs array */ - if (glyphs && *glyphs == NULL) - *num_glyphs = 0; - - /* A NULL *clusters means no prealloced clusters array */ - if (clusters && *clusters == NULL) - *num_clusters = 0; - - if (!clusters && num_clusters) { - num_clusters = NULL; - } - - if (cluster_flags) { - *cluster_flags = FALSE; - } - - if (!clusters && cluster_flags) { - cluster_flags = NULL; - } - - /* Apart from that, no negatives */ - if (utf8_len < 0 || - *num_glyphs < 0 || - (num_clusters && *num_clusters < 0)) { - status = _cairo_error (CAIRO_STATUS_NEGATIVE_COUNT); - goto BAIL; - } - - if (utf8_len == 0) { - status = CAIRO_STATUS_SUCCESS; - goto BAIL; - } - - /* validate input so backend does not have to */ - status = _cairo_utf8_to_ucs4 (utf8, utf8_len, NULL, &num_chars); - if (unlikely (status)) - goto BAIL; - - _cairo_scaled_font_freeze_cache (scaled_font); - - orig_glyphs = *glyphs; - orig_clusters = clusters ? *clusters : NULL; - - if (scaled_font->backend->text_to_glyphs) { - status = scaled_font->backend->text_to_glyphs (scaled_font, x, y, - utf8, utf8_len, - glyphs, num_glyphs, - clusters, num_clusters, - cluster_flags); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) { - if (status == CAIRO_INT_STATUS_SUCCESS) { - /* The checks here are crude; we only should do them in - * user-font backend, but they don't hurt here. This stuff - * can be hard to get right. */ - - if (*num_glyphs < 0) { - status = _cairo_error (CAIRO_STATUS_NEGATIVE_COUNT); - goto DONE; - } - if (num_glyphs && *glyphs == NULL) { - status = _cairo_error (CAIRO_STATUS_NULL_POINTER); - goto DONE; - } - - if (clusters) { - if (*num_clusters < 0) { - status = _cairo_error (CAIRO_STATUS_NEGATIVE_COUNT); - goto DONE; - } - if (num_clusters && *clusters == NULL) { - status = _cairo_error (CAIRO_STATUS_NULL_POINTER); - goto DONE; - } - - /* Don't trust the backend, validate clusters! */ - status = - _cairo_validate_text_clusters (utf8, utf8_len, - *glyphs, *num_glyphs, - *clusters, *num_clusters, - *cluster_flags); - } - } - - goto DONE; - } - } - - if (*num_glyphs < num_chars) { - *glyphs = cairo_glyph_allocate (num_chars); - if (unlikely (*glyphs == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto DONE; - } - } - *num_glyphs = num_chars; - - if (clusters) { - if (*num_clusters < num_chars) { - *clusters = cairo_text_cluster_allocate (num_chars); - if (unlikely (*clusters == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto DONE; - } - } - *num_clusters = num_chars; - } - - if (num_chars > CACHING_THRESHOLD) - status = cairo_scaled_font_text_to_glyphs_internal_cached (scaled_font, - x, y, - utf8, - *glyphs, - clusters, - num_chars); - else - status = cairo_scaled_font_text_to_glyphs_internal_uncached (scaled_font, - x, y, - utf8, - *glyphs, - clusters, - num_chars); - - DONE: /* error that should be logged on scaled_font happened */ - _cairo_scaled_font_thaw_cache (scaled_font); - - if (unlikely (status)) { - *num_glyphs = 0; - if (*glyphs != orig_glyphs) { - cairo_glyph_free (*glyphs); - *glyphs = orig_glyphs; - } - - if (clusters) { - *num_clusters = 0; - if (*clusters != orig_clusters) { - cairo_text_cluster_free (*clusters); - *clusters = orig_clusters; - } - } - } - - return _cairo_scaled_font_set_error (scaled_font, status); - - BAIL: /* error with input arguments */ - - if (num_glyphs) - *num_glyphs = 0; - - if (num_clusters) - *num_clusters = 0; - - return status; -} -slim_hidden_def (cairo_scaled_font_text_to_glyphs); - -static inline cairo_bool_t -_range_contains_glyph (const cairo_box_t *extents, - cairo_fixed_t left, - cairo_fixed_t top, - cairo_fixed_t right, - cairo_fixed_t bottom) -{ - if (left == right || top == bottom) - return FALSE; - - return right > extents->p1.x && - left < extents->p2.x && - bottom > extents->p1.y && - top < extents->p2.y; -} - -static cairo_status_t -_cairo_scaled_font_single_glyph_device_extents (cairo_scaled_font_t *scaled_font, - const cairo_glyph_t *glyph, - cairo_rectangle_int_t *extents) -{ - cairo_scaled_glyph_t *scaled_glyph; - cairo_status_t status; - - _cairo_scaled_font_freeze_cache (scaled_font); - status = _cairo_scaled_glyph_lookup (scaled_font, - glyph->index, - CAIRO_SCALED_GLYPH_INFO_METRICS, - &scaled_glyph); - if (likely (status == CAIRO_STATUS_SUCCESS)) { - cairo_bool_t round_xy = _cairo_font_options_get_round_glyph_positions (&scaled_font->options) == CAIRO_ROUND_GLYPH_POS_ON; - cairo_box_t box; - cairo_fixed_t v; - - if (round_xy) - v = _cairo_fixed_from_int (_cairo_lround (glyph->x)); - else - v = _cairo_fixed_from_double (glyph->x); - box.p1.x = v + scaled_glyph->bbox.p1.x; - box.p2.x = v + scaled_glyph->bbox.p2.x; - - if (round_xy) - v = _cairo_fixed_from_int (_cairo_lround (glyph->y)); - else - v = _cairo_fixed_from_double (glyph->y); - box.p1.y = v + scaled_glyph->bbox.p1.y; - box.p2.y = v + scaled_glyph->bbox.p2.y; - - _cairo_box_round_to_rectangle (&box, extents); - } - _cairo_scaled_font_thaw_cache (scaled_font); - return status; -} - -/* - * Compute a device-space bounding box for the glyphs. - */ -cairo_status_t -_cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font, - const cairo_glyph_t *glyphs, - int num_glyphs, - cairo_rectangle_int_t *extents, - cairo_bool_t *overlap_out) -{ - cairo_status_t status = CAIRO_STATUS_SUCCESS; - cairo_box_t box = { { INT_MAX, INT_MAX }, { INT_MIN, INT_MIN }}; - cairo_scaled_glyph_t *glyph_cache[64]; - cairo_bool_t overlap = overlap_out ? FALSE : TRUE; - cairo_round_glyph_positions_t round_glyph_positions = _cairo_font_options_get_round_glyph_positions (&scaled_font->options); - int i; - - if (unlikely (scaled_font->status)) - return scaled_font->status; - - if (num_glyphs == 1) { - if (overlap_out) - *overlap_out = FALSE; - return _cairo_scaled_font_single_glyph_device_extents (scaled_font, - glyphs, - extents); - } - - _cairo_scaled_font_freeze_cache (scaled_font); - - memset (glyph_cache, 0, sizeof (glyph_cache)); - - for (i = 0; i < num_glyphs; i++) { - cairo_scaled_glyph_t *scaled_glyph; - cairo_fixed_t x, y, x1, y1, x2, y2; - int cache_index = glyphs[i].index % ARRAY_LENGTH (glyph_cache); - - scaled_glyph = glyph_cache[cache_index]; - if (scaled_glyph == NULL || - _cairo_scaled_glyph_index (scaled_glyph) != glyphs[i].index) - { - status = _cairo_scaled_glyph_lookup (scaled_font, - glyphs[i].index, - CAIRO_SCALED_GLYPH_INFO_METRICS, - &scaled_glyph); - if (unlikely (status)) - break; - - glyph_cache[cache_index] = scaled_glyph; - } - - if (round_glyph_positions == CAIRO_ROUND_GLYPH_POS_ON) - x = _cairo_fixed_from_int (_cairo_lround (glyphs[i].x)); - else - x = _cairo_fixed_from_double (glyphs[i].x); - x1 = x + scaled_glyph->bbox.p1.x; - x2 = x + scaled_glyph->bbox.p2.x; - - if (round_glyph_positions == CAIRO_ROUND_GLYPH_POS_ON) - y = _cairo_fixed_from_int (_cairo_lround (glyphs[i].y)); - else - y = _cairo_fixed_from_double (glyphs[i].y); - y1 = y + scaled_glyph->bbox.p1.y; - y2 = y + scaled_glyph->bbox.p2.y; - - if (overlap == FALSE) - overlap = _range_contains_glyph (&box, x1, y1, x2, y2); - - if (x1 < box.p1.x) box.p1.x = x1; - if (x2 > box.p2.x) box.p2.x = x2; - if (y1 < box.p1.y) box.p1.y = y1; - if (y2 > box.p2.y) box.p2.y = y2; - } - - _cairo_scaled_font_thaw_cache (scaled_font); - if (unlikely (status)) - return _cairo_scaled_font_set_error (scaled_font, status); - - if (box.p1.x < box.p2.x) { - _cairo_box_round_to_rectangle (&box, extents); - } else { - extents->x = extents->y = 0; - extents->width = extents->height = 0; - } - - if (overlap_out != NULL) - *overlap_out = overlap; - - return CAIRO_STATUS_SUCCESS; -} - -cairo_bool_t -_cairo_scaled_font_glyph_approximate_extents (cairo_scaled_font_t *scaled_font, - const cairo_glyph_t *glyphs, - int num_glyphs, - cairo_rectangle_int_t *extents) -{ - double x0, x1, y0, y1, pad; - int i; - - /* If any of the factors are suspect (i.e. the font is broken), bail */ - if (scaled_font->fs_extents.max_x_advance == 0 || - scaled_font->fs_extents.height == 0 || - scaled_font->max_scale == 0) - { - return FALSE; - } - - assert (num_glyphs); - - x0 = x1 = glyphs[0].x; - y0 = y1 = glyphs[0].y; - for (i = 1; i < num_glyphs; i++) { - double g; - - g = glyphs[i].x; - if (g < x0) x0 = g; - if (g > x1) x1 = g; - - g = glyphs[i].y; - if (g < y0) y0 = g; - if (g > y1) y1 = g; - } - - pad = MAX(scaled_font->fs_extents.max_x_advance, - scaled_font->fs_extents.height); - pad *= scaled_font->max_scale; - - extents->x = floor (x0 - pad); - extents->width = ceil (x1 + pad) - extents->x; - extents->y = floor (y0 - pad); - extents->height = ceil (y1 + pad) - extents->y; - return TRUE; -} - -#if 0 -/* XXX win32 */ -cairo_status_t -_cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font, - cairo_operator_t op, - const cairo_pattern_t *pattern, - cairo_surface_t *surface, - int source_x, - int source_y, - int dest_x, - int dest_y, - unsigned int width, - unsigned int height, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_region_t *clip_region) -{ - cairo_int_status_t status; - cairo_surface_t *mask = NULL; - cairo_format_t mask_format = CAIRO_FORMAT_A1; /* shut gcc up */ - cairo_surface_pattern_t mask_pattern; - int i; - - /* These operators aren't interpreted the same way by the backends; - * they are implemented in terms of other operators in cairo-gstate.c - */ - assert (op != CAIRO_OPERATOR_SOURCE && op != CAIRO_OPERATOR_CLEAR); - - if (scaled_font->status) - return scaled_font->status; - - if (!num_glyphs) - return CAIRO_STATUS_SUCCESS; - - if (scaled_font->backend->show_glyphs != NULL) { - int remaining_glyphs = num_glyphs; - status = scaled_font->backend->show_glyphs (scaled_font, - op, pattern, - surface, - source_x, source_y, - dest_x, dest_y, - width, height, - glyphs, num_glyphs, - clip_region, - &remaining_glyphs); - glyphs += num_glyphs - remaining_glyphs; - num_glyphs = remaining_glyphs; - if (remaining_glyphs == 0) - status = CAIRO_INT_STATUS_SUCCESS; - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return _cairo_scaled_font_set_error (scaled_font, status); - } - - /* Font display routine either does not exist or failed. */ - - _cairo_scaled_font_freeze_cache (scaled_font); - - for (i = 0; i < num_glyphs; i++) { - int x, y; - cairo_image_surface_t *glyph_surface; - cairo_scaled_glyph_t *scaled_glyph; - - status = _cairo_scaled_glyph_lookup (scaled_font, - glyphs[i].index, - CAIRO_SCALED_GLYPH_INFO_SURFACE, - &scaled_glyph); - - if (unlikely (status)) - goto CLEANUP_MASK; - - glyph_surface = scaled_glyph->surface; - - /* To start, create the mask using the format from the first - * glyph. Later we'll deal with different formats. */ - if (mask == NULL) { - mask_format = glyph_surface->format; - mask = cairo_image_surface_create (mask_format, width, height); - status = mask->status; - if (unlikely (status)) - goto CLEANUP_MASK; - } - - /* If we have glyphs of different formats, we "upgrade" the mask - * to the wider of the formats. */ - if (glyph_surface->format != mask_format && - _cairo_format_bits_per_pixel (mask_format) < - _cairo_format_bits_per_pixel (glyph_surface->format) ) - { - cairo_surface_t *new_mask; - - switch (glyph_surface->format) { - case CAIRO_FORMAT_ARGB32: - case CAIRO_FORMAT_A8: - case CAIRO_FORMAT_A1: - mask_format = glyph_surface->format; - break; - case CAIRO_FORMAT_RGB16_565: - case CAIRO_FORMAT_RGB24: - case CAIRO_FORMAT_RGB30: - case CAIRO_FORMAT_INVALID: - default: - ASSERT_NOT_REACHED; - mask_format = CAIRO_FORMAT_ARGB32; - break; - } - - new_mask = cairo_image_surface_create (mask_format, width, height); - status = new_mask->status; - if (unlikely (status)) { - cairo_surface_destroy (new_mask); - goto CLEANUP_MASK; - } - - _cairo_pattern_init_for_surface (&mask_pattern, mask); - /* Note that we only upgrade masks, i.e. A1 -> A8 -> ARGB32, so there is - * never any component alpha here. - */ - status = _cairo_surface_composite (CAIRO_OPERATOR_ADD, - &_cairo_pattern_white.base, - &mask_pattern.base, - new_mask, - 0, 0, - 0, 0, - 0, 0, - width, height, - NULL); - - _cairo_pattern_fini (&mask_pattern.base); - - if (unlikely (status)) { - cairo_surface_destroy (new_mask); - goto CLEANUP_MASK; - } - - cairo_surface_destroy (mask); - mask = new_mask; - } - - if (glyph_surface->width && glyph_surface->height) { - cairo_surface_pattern_t glyph_pattern; - - /* round glyph locations to the nearest pixel */ - /* XXX: FRAGILE: We're ignoring device_transform scaling here. A bug? */ - x = _cairo_lround (glyphs[i].x - - glyph_surface->base.device_transform.x0); - y = _cairo_lround (glyphs[i].y - - glyph_surface->base.device_transform.y0); - - _cairo_pattern_init_for_surface (&glyph_pattern, - &glyph_surface->base); - if (mask_format == CAIRO_FORMAT_ARGB32) - glyph_pattern.base.has_component_alpha = TRUE; - - status = _cairo_surface_composite (CAIRO_OPERATOR_ADD, - &_cairo_pattern_white.base, - &glyph_pattern.base, - mask, - 0, 0, - 0, 0, - x - dest_x, y - dest_y, - glyph_surface->width, - glyph_surface->height, - NULL); - - _cairo_pattern_fini (&glyph_pattern.base); - - if (unlikely (status)) - goto CLEANUP_MASK; - } - } - - _cairo_pattern_init_for_surface (&mask_pattern, mask); - if (mask_format == CAIRO_FORMAT_ARGB32) - mask_pattern.base.has_component_alpha = TRUE; - - status = _cairo_surface_composite (op, pattern, &mask_pattern.base, - surface, - source_x, source_y, - 0, 0, - dest_x, dest_y, - width, height, - clip_region); - - _cairo_pattern_fini (&mask_pattern.base); - -CLEANUP_MASK: - _cairo_scaled_font_thaw_cache (scaled_font); - - if (mask != NULL) - cairo_surface_destroy (mask); - return _cairo_scaled_font_set_error (scaled_font, status); -} -#endif - -/* Add a single-device-unit rectangle to a path. */ -static cairo_status_t -_add_unit_rectangle_to_path (cairo_path_fixed_t *path, - cairo_fixed_t x, - cairo_fixed_t y) -{ - cairo_status_t status; - - status = _cairo_path_fixed_move_to (path, x, y); - if (unlikely (status)) - return status; - - status = _cairo_path_fixed_rel_line_to (path, - _cairo_fixed_from_int (1), - _cairo_fixed_from_int (0)); - if (unlikely (status)) - return status; - - status = _cairo_path_fixed_rel_line_to (path, - _cairo_fixed_from_int (0), - _cairo_fixed_from_int (1)); - if (unlikely (status)) - return status; - - status = _cairo_path_fixed_rel_line_to (path, - _cairo_fixed_from_int (-1), - _cairo_fixed_from_int (0)); - if (unlikely (status)) - return status; - - return _cairo_path_fixed_close_path (path); -} - -/** - * _trace_mask_to_path: - * @bitmap: An alpha mask (either %CAIRO_FORMAT_A1 or %CAIRO_FORMAT_A8) - * @path: An initialized path to hold the result - * - * Given a mask surface, (an alpha image), fill out the provided path - * so that when filled it would result in something that approximates - * the mask. - * - * Note: The current tracing code here is extremely primitive. It - * operates only on an A1 surface, (converting an A8 surface to A1 if - * necessary), and performs the tracing by drawing a little square - * around each pixel that is on in the mask. We do not pretend that - * this is a high-quality result. But we are leaving it up to someone - * who cares enough about getting a better result to implement - * something more sophisticated. - **/ -static cairo_status_t -_trace_mask_to_path (cairo_image_surface_t *mask, - cairo_path_fixed_t *path, - double tx, double ty) -{ - const uint8_t *row; - int rows, cols, bytes_per_row; - int x, y, bit; - double xoff, yoff; - cairo_fixed_t x0, y0; - cairo_fixed_t px, py; - cairo_status_t status; - - mask = _cairo_image_surface_coerce_to_format (mask, CAIRO_FORMAT_A1); - status = mask->base.status; - if (unlikely (status)) - return status; - - cairo_surface_get_device_offset (&mask->base, &xoff, &yoff); - x0 = _cairo_fixed_from_double (tx - xoff); - y0 = _cairo_fixed_from_double (ty - yoff); - - bytes_per_row = (mask->width + 7) / 8; - row = mask->data; - for (y = 0, rows = mask->height; rows--; row += mask->stride, y++) { - const uint8_t *byte_ptr = row; - x = 0; - py = _cairo_fixed_from_int (y); - for (cols = bytes_per_row; cols--; ) { - uint8_t byte = *byte_ptr++; - if (byte == 0) { - x += 8; - continue; - } - - byte = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (byte); - for (bit = 1 << 7; bit && x < mask->width; bit >>= 1, x++) { - if (byte & bit) { - px = _cairo_fixed_from_int (x); - status = _add_unit_rectangle_to_path (path, - px + x0, - py + y0); - if (unlikely (status)) - goto BAIL; - } - } - } - } - -BAIL: - cairo_surface_destroy (&mask->base); - - return status; -} - -cairo_status_t -_cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font, - const cairo_glyph_t *glyphs, - int num_glyphs, - cairo_path_fixed_t *path) -{ - cairo_int_status_t status; - int i; - - status = scaled_font->status; - if (unlikely (status)) - return status; - - _cairo_scaled_font_freeze_cache (scaled_font); - for (i = 0; i < num_glyphs; i++) { - cairo_scaled_glyph_t *scaled_glyph; - - status = _cairo_scaled_glyph_lookup (scaled_font, - glyphs[i].index, - CAIRO_SCALED_GLYPH_INFO_PATH, - &scaled_glyph); - if (status == CAIRO_INT_STATUS_SUCCESS) { - status = _cairo_path_fixed_append (path, - scaled_glyph->path, - _cairo_fixed_from_double (glyphs[i].x), - _cairo_fixed_from_double (glyphs[i].y)); - - } else if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - /* If the font is incapable of providing a path, then we'll - * have to trace our own from a surface. - */ - status = _cairo_scaled_glyph_lookup (scaled_font, - glyphs[i].index, - CAIRO_SCALED_GLYPH_INFO_SURFACE, - &scaled_glyph); - if (unlikely (status)) - goto BAIL; - - status = _trace_mask_to_path (scaled_glyph->surface, path, - glyphs[i].x, glyphs[i].y); - } - - if (unlikely (status)) - goto BAIL; - } - BAIL: - _cairo_scaled_font_thaw_cache (scaled_font); - - return _cairo_scaled_font_set_error (scaled_font, status); -} - -/** - * _cairo_scaled_glyph_set_metrics: - * @scaled_glyph: a #cairo_scaled_glyph_t - * @scaled_font: a #cairo_scaled_font_t - * @fs_metrics: a #cairo_text_extents_t in font space - * - * _cairo_scaled_glyph_set_metrics() stores user space metrics - * for the specified glyph given font space metrics. It is - * called by the font backend when initializing a glyph with - * %CAIRO_SCALED_GLYPH_INFO_METRICS. - **/ -void -_cairo_scaled_glyph_set_metrics (cairo_scaled_glyph_t *scaled_glyph, - cairo_scaled_font_t *scaled_font, - cairo_text_extents_t *fs_metrics) -{ - cairo_bool_t first = TRUE; - double hm, wm; - double min_user_x = 0.0, max_user_x = 0.0, min_user_y = 0.0, max_user_y = 0.0; - double min_device_x = 0.0, max_device_x = 0.0, min_device_y = 0.0, max_device_y = 0.0; - double device_x_advance, device_y_advance; - - scaled_glyph->fs_metrics = *fs_metrics; - - for (hm = 0.0; hm <= 1.0; hm += 1.0) - for (wm = 0.0; wm <= 1.0; wm += 1.0) { - double x, y; - - /* Transform this corner to user space */ - x = fs_metrics->x_bearing + fs_metrics->width * wm; - y = fs_metrics->y_bearing + fs_metrics->height * hm; - cairo_matrix_transform_point (&scaled_font->font_matrix, - &x, &y); - if (first) { - min_user_x = max_user_x = x; - min_user_y = max_user_y = y; - } else { - if (x < min_user_x) min_user_x = x; - if (x > max_user_x) max_user_x = x; - if (y < min_user_y) min_user_y = y; - if (y > max_user_y) max_user_y = y; - } - - /* Transform this corner to device space from glyph origin */ - x = fs_metrics->x_bearing + fs_metrics->width * wm; - y = fs_metrics->y_bearing + fs_metrics->height * hm; - cairo_matrix_transform_distance (&scaled_font->scale, - &x, &y); - - if (first) { - min_device_x = max_device_x = x; - min_device_y = max_device_y = y; - } else { - if (x < min_device_x) min_device_x = x; - if (x > max_device_x) max_device_x = x; - if (y < min_device_y) min_device_y = y; - if (y > max_device_y) max_device_y = y; - } - first = FALSE; - } - scaled_glyph->metrics.x_bearing = min_user_x; - scaled_glyph->metrics.y_bearing = min_user_y; - scaled_glyph->metrics.width = max_user_x - min_user_x; - scaled_glyph->metrics.height = max_user_y - min_user_y; - - scaled_glyph->metrics.x_advance = fs_metrics->x_advance; - scaled_glyph->metrics.y_advance = fs_metrics->y_advance; - cairo_matrix_transform_distance (&scaled_font->font_matrix, - &scaled_glyph->metrics.x_advance, - &scaled_glyph->metrics.y_advance); - - device_x_advance = fs_metrics->x_advance; - device_y_advance = fs_metrics->y_advance; - cairo_matrix_transform_distance (&scaled_font->scale, - &device_x_advance, - &device_y_advance); - - scaled_glyph->bbox.p1.x = _cairo_fixed_from_double (min_device_x); - scaled_glyph->bbox.p1.y = _cairo_fixed_from_double (min_device_y); - scaled_glyph->bbox.p2.x = _cairo_fixed_from_double (max_device_x); - scaled_glyph->bbox.p2.y = _cairo_fixed_from_double (max_device_y); - - scaled_glyph->x_advance = _cairo_lround (device_x_advance); - scaled_glyph->y_advance = _cairo_lround (device_y_advance); - - scaled_glyph->has_info |= CAIRO_SCALED_GLYPH_INFO_METRICS; -} - -void -_cairo_scaled_glyph_set_surface (cairo_scaled_glyph_t *scaled_glyph, - cairo_scaled_font_t *scaled_font, - cairo_image_surface_t *surface) -{ - if (scaled_glyph->surface != NULL) - cairo_surface_destroy (&scaled_glyph->surface->base); - - /* sanity check the backend glyph contents */ - _cairo_debug_check_image_surface_is_defined (&surface->base); - scaled_glyph->surface = surface; - - if (surface != NULL) - scaled_glyph->has_info |= CAIRO_SCALED_GLYPH_INFO_SURFACE; - else - scaled_glyph->has_info &= ~CAIRO_SCALED_GLYPH_INFO_SURFACE; -} - -void -_cairo_scaled_glyph_set_path (cairo_scaled_glyph_t *scaled_glyph, - cairo_scaled_font_t *scaled_font, - cairo_path_fixed_t *path) -{ - if (scaled_glyph->path != NULL) - _cairo_path_fixed_destroy (scaled_glyph->path); - - scaled_glyph->path = path; - - if (path != NULL) - scaled_glyph->has_info |= CAIRO_SCALED_GLYPH_INFO_PATH; - else - scaled_glyph->has_info &= ~CAIRO_SCALED_GLYPH_INFO_PATH; -} - -void -_cairo_scaled_glyph_set_recording_surface (cairo_scaled_glyph_t *scaled_glyph, - cairo_scaled_font_t *scaled_font, - cairo_surface_t *recording_surface) -{ - if (scaled_glyph->recording_surface != NULL) { - cairo_surface_finish (scaled_glyph->recording_surface); - cairo_surface_destroy (scaled_glyph->recording_surface); - } - - scaled_glyph->recording_surface = recording_surface; - - if (recording_surface != NULL) - scaled_glyph->has_info |= CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE; - else - scaled_glyph->has_info &= ~CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE; -} - -static cairo_bool_t -_cairo_scaled_glyph_page_can_remove (const void *closure) -{ - const cairo_scaled_glyph_page_t *page = closure; - const cairo_scaled_font_t *scaled_font; - - scaled_font = (cairo_scaled_font_t *) page->cache_entry.hash; - return scaled_font->cache_frozen == 0; -} - -static cairo_status_t -_cairo_scaled_font_allocate_glyph (cairo_scaled_font_t *scaled_font, - cairo_scaled_glyph_t **scaled_glyph) -{ - cairo_scaled_glyph_page_t *page; - cairo_status_t status; - - assert (scaled_font->cache_frozen); - - /* only the first page in the list may contain available slots */ - if (! cairo_list_is_empty (&scaled_font->glyph_pages)) { - page = cairo_list_last_entry (&scaled_font->glyph_pages, - cairo_scaled_glyph_page_t, - link); - if (page->num_glyphs < CAIRO_SCALED_GLYPH_PAGE_SIZE) { - *scaled_glyph = &page->glyphs[page->num_glyphs++]; - return CAIRO_STATUS_SUCCESS; - } - } - - page = malloc (sizeof (cairo_scaled_glyph_page_t)); - if (unlikely (page == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - page->cache_entry.hash = (unsigned long) scaled_font; - page->cache_entry.size = 1; /* XXX occupancy weighting? */ - page->num_glyphs = 0; - - CAIRO_MUTEX_LOCK (_cairo_scaled_glyph_page_cache_mutex); - if (scaled_font->global_cache_frozen == FALSE) { - if (unlikely (cairo_scaled_glyph_page_cache.hash_table == NULL)) { - status = _cairo_cache_init (&cairo_scaled_glyph_page_cache, - NULL, - _cairo_scaled_glyph_page_can_remove, - _cairo_scaled_glyph_page_pluck, - MAX_GLYPH_PAGES_CACHED); - if (unlikely (status)) { - CAIRO_MUTEX_UNLOCK (_cairo_scaled_glyph_page_cache_mutex); - free (page); - return status; - } - } - - _cairo_cache_freeze (&cairo_scaled_glyph_page_cache); - scaled_font->global_cache_frozen = TRUE; - } - - status = _cairo_cache_insert (&cairo_scaled_glyph_page_cache, - &page->cache_entry); - CAIRO_MUTEX_UNLOCK (_cairo_scaled_glyph_page_cache_mutex); - if (unlikely (status)) { - free (page); - return status; - } - - cairo_list_add_tail (&page->link, &scaled_font->glyph_pages); - - *scaled_glyph = &page->glyphs[page->num_glyphs++]; - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_scaled_font_free_last_glyph (cairo_scaled_font_t *scaled_font, - cairo_scaled_glyph_t *scaled_glyph) -{ - cairo_scaled_glyph_page_t *page; - - assert (! cairo_list_is_empty (&scaled_font->glyph_pages)); - page = cairo_list_last_entry (&scaled_font->glyph_pages, - cairo_scaled_glyph_page_t, - link); - assert (scaled_glyph == &page->glyphs[page->num_glyphs-1]); - - _cairo_scaled_glyph_fini (scaled_font, scaled_glyph); - - if (--page->num_glyphs == 0) { - CAIRO_MUTEX_LOCK (_cairo_scaled_glyph_page_cache_mutex); - /* Temporarily disconnect callback to avoid recursive locking */ - cairo_scaled_glyph_page_cache.entry_destroy = NULL; - _cairo_cache_remove (&cairo_scaled_glyph_page_cache, - &page->cache_entry); - _cairo_scaled_glyph_page_destroy (scaled_font, page); - cairo_scaled_glyph_page_cache.entry_destroy = _cairo_scaled_glyph_page_pluck; - CAIRO_MUTEX_UNLOCK (_cairo_scaled_glyph_page_cache_mutex); - } -} - -/** - * _cairo_scaled_glyph_lookup: - * @scaled_font: a #cairo_scaled_font_t - * @index: the glyph to create - * @info: a #cairo_scaled_glyph_info_t marking which portions of - * the glyph should be filled in. - * @scaled_glyph_ret: a #cairo_scaled_glyph_t where the glyph - * is returned. - * - * If the desired info is not available, (for example, when trying to - * get INFO_PATH with a bitmapped font), this function will return - * %CAIRO_INT_STATUS_UNSUPPORTED. - * - * Note: This function must be called with the scaled font frozen, and it must - * remain frozen for as long as the @scaled_glyph_ret is alive. (If the scaled - * font was not frozen, then there is no guarantee that the glyph would not be - * evicted before you tried to access it.) See - * _cairo_scaled_font_freeze_cache() and _cairo_scaled_font_thaw_cache(). - * - * Returns: a glyph with the requested portions filled in. Glyph - * lookup is cached and glyph will be automatically freed along - * with the scaled_font so no explicit free is required. - * @info can be one or more of: - * %CAIRO_SCALED_GLYPH_INFO_METRICS - glyph metrics and bounding box - * %CAIRO_SCALED_GLYPH_INFO_SURFACE - surface holding glyph image - * %CAIRO_SCALED_GLYPH_INFO_PATH - path holding glyph outline in device space - **/ -cairo_int_status_t -_cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font, - unsigned long index, - cairo_scaled_glyph_info_t info, - cairo_scaled_glyph_t **scaled_glyph_ret) -{ - cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS; - cairo_scaled_glyph_t *scaled_glyph; - cairo_scaled_glyph_info_t need_info; - - *scaled_glyph_ret = NULL; - - if (unlikely (scaled_font->status)) - return scaled_font->status; - - assert (CAIRO_MUTEX_IS_LOCKED(scaled_font->mutex)); - assert (scaled_font->cache_frozen); - - if (CAIRO_INJECT_FAULT ()) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - /* - * Check cache for glyph - */ - scaled_glyph = _cairo_hash_table_lookup (scaled_font->glyphs, - (cairo_hash_entry_t *) &index); - if (scaled_glyph == NULL) { - status = _cairo_scaled_font_allocate_glyph (scaled_font, &scaled_glyph); - if (unlikely (status)) - goto err; - - memset (scaled_glyph, 0, sizeof (cairo_scaled_glyph_t)); - _cairo_scaled_glyph_set_index (scaled_glyph, index); - cairo_list_init (&scaled_glyph->dev_privates); - - /* ask backend to initialize metrics and shape fields */ - status = - scaled_font->backend->scaled_glyph_init (scaled_font, - scaled_glyph, - info | CAIRO_SCALED_GLYPH_INFO_METRICS); - if (unlikely (status)) { - _cairo_scaled_font_free_last_glyph (scaled_font, scaled_glyph); - goto err; - } - - status = _cairo_hash_table_insert (scaled_font->glyphs, - &scaled_glyph->hash_entry); - if (unlikely (status)) { - _cairo_scaled_font_free_last_glyph (scaled_font, scaled_glyph); - goto err; - } - } - - /* - * Check and see if the glyph, as provided, - * already has the requested data and amend it if not - */ - need_info = info & ~scaled_glyph->has_info; - if (need_info) { - status = scaled_font->backend->scaled_glyph_init (scaled_font, - scaled_glyph, - need_info); - if (unlikely (status)) - goto err; - - /* Don't trust the scaled_glyph_init() return value, the font - * backend may not even know about some of the info. For example, - * no backend other than the user-fonts knows about recording-surface - * glyph info. */ - if (info & ~scaled_glyph->has_info) - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - *scaled_glyph_ret = scaled_glyph; - return CAIRO_STATUS_SUCCESS; - -err: - /* It's not an error for the backend to not support the info we want. */ - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - status = _cairo_scaled_font_set_error (scaled_font, status); - return status; -} - -double -_cairo_scaled_font_get_max_scale (cairo_scaled_font_t *scaled_font) -{ - return scaled_font->max_scale; -} - - -/** - * cairo_scaled_font_get_font_face: - * @scaled_font: a #cairo_scaled_font_t - * - * Gets the font face that this scaled font uses. This might be the - * font face passed to cairo_scaled_font_create(), but this does not - * hold true for all possible cases. - * - * Return value: The #cairo_font_face_t with which @scaled_font was - * created. This object is owned by cairo. To keep a reference to it, - * you must call cairo_scaled_font_reference(). - * - * Since: 1.2 - **/ -cairo_font_face_t * -cairo_scaled_font_get_font_face (cairo_scaled_font_t *scaled_font) -{ - if (scaled_font->status) - return (cairo_font_face_t*) &_cairo_font_face_nil; - - if (scaled_font->original_font_face != NULL) - return scaled_font->original_font_face; - - return scaled_font->font_face; -} -slim_hidden_def (cairo_scaled_font_get_font_face); - -/** - * cairo_scaled_font_get_font_matrix: - * @scaled_font: a #cairo_scaled_font_t - * @font_matrix: return value for the matrix - * - * Stores the font matrix with which @scaled_font was created into - * @matrix. - * - * Since: 1.2 - **/ -void -cairo_scaled_font_get_font_matrix (cairo_scaled_font_t *scaled_font, - cairo_matrix_t *font_matrix) -{ - if (scaled_font->status) { - cairo_matrix_init_identity (font_matrix); - return; - } - - *font_matrix = scaled_font->font_matrix; -} -slim_hidden_def (cairo_scaled_font_get_font_matrix); - -/** - * cairo_scaled_font_get_ctm: - * @scaled_font: a #cairo_scaled_font_t - * @ctm: return value for the CTM - * - * Stores the CTM with which @scaled_font was created into @ctm. - * Note that the translation offsets (x0, y0) of the CTM are ignored - * by cairo_scaled_font_create(). So, the matrix this - * function returns always has 0,0 as x0,y0. - * - * Since: 1.2 - **/ -void -cairo_scaled_font_get_ctm (cairo_scaled_font_t *scaled_font, - cairo_matrix_t *ctm) -{ - if (scaled_font->status) { - cairo_matrix_init_identity (ctm); - return; - } - - *ctm = scaled_font->ctm; -} -slim_hidden_def (cairo_scaled_font_get_ctm); - -/** - * cairo_scaled_font_get_scale_matrix: - * @scaled_font: a #cairo_scaled_font_t - * @scale_matrix: return value for the matrix - * - * Stores the scale matrix of @scaled_font into @matrix. - * The scale matrix is product of the font matrix and the ctm - * associated with the scaled font, and hence is the matrix mapping from - * font space to device space. - * - * Since: 1.8 - **/ -void -cairo_scaled_font_get_scale_matrix (cairo_scaled_font_t *scaled_font, - cairo_matrix_t *scale_matrix) -{ - if (scaled_font->status) { - cairo_matrix_init_identity (scale_matrix); - return; - } - - *scale_matrix = scaled_font->scale; -} - -/** - * cairo_scaled_font_get_font_options: - * @scaled_font: a #cairo_scaled_font_t - * @options: return value for the font options - * - * Stores the font options with which @scaled_font was created into - * @options. - * - * Since: 1.2 - **/ -void -cairo_scaled_font_get_font_options (cairo_scaled_font_t *scaled_font, - cairo_font_options_t *options) -{ - if (cairo_font_options_status (options)) - return; - - if (scaled_font->status) { - _cairo_font_options_init_default (options); - return; - } - - _cairo_font_options_init_copy (options, &scaled_font->options); -} -slim_hidden_def (cairo_scaled_font_get_font_options); diff --git a/source/libs/cairo/cairo-src/src/cairo-script-private.h b/source/libs/cairo/cairo-src/src/cairo-script-private.h deleted file mode 100644 index 5b506f500cd078c37f1aa487e9868dfa5eead8a4..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-script-private.h +++ /dev/null @@ -1,59 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2008 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Chris Wilson - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_SCRIPT_PRIVATE_H -#define CAIRO_SCRIPT_PRIVATE_H - -#include "cairo.h" -#include "cairo-script.h" - -#include "cairo-compiler-private.h" -#include "cairo-output-stream-private.h" -#include "cairo-types-private.h" - -CAIRO_BEGIN_DECLS - -cairo_private cairo_device_t * -_cairo_script_context_create_internal (cairo_output_stream_t *stream); - -cairo_private void -_cairo_script_context_attach_snapshots (cairo_device_t *device, - cairo_bool_t enable); - -slim_hidden_proto (cairo_script_surface_create); - -CAIRO_END_DECLS - -#endif /* CAIRO_SCRIPT_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-script-surface.c b/source/libs/cairo/cairo-src/src/cairo-script-surface.c deleted file mode 100644 index a4cefdebb4be5d85fe2130ce00e34c086114c6ca..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-script-surface.c +++ /dev/null @@ -1,3999 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2008 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Chris Wilson. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -/* The script surface is one that records all operations performed on - * it in the form of a procedural script, similar in fashion to - * PostScript but using Cairo's imaging model. In essence, this is - * equivalent to the recording-surface, but as there is no impedance mismatch - * between Cairo and CairoScript, we can generate output immediately - * without having to copy and hold the data in memory. - */ - -/** - * SECTION:cairo-script - * @Title: Script Surfaces - * @Short_Description: Rendering to replayable scripts - * @See_Also: #cairo_surface_t - * - * The script surface provides the ability to render to a native - * script that matches the cairo drawing model. The scripts can - * be replayed using tools under the util/cairo-script directory, - * or with cairo-perf-trace. - **/ - -/** - * CAIRO_HAS_SCRIPT_SURFACE: - * - * Defined if the script surface backend is available. - * The script surface backend is always built in since 1.12. - * - * Since: 1.12 - **/ - - -#include "cairoint.h" - -#include "cairo-script.h" -#include "cairo-script-private.h" - -#include "cairo-analysis-surface-private.h" -#include "cairo-default-context-private.h" -#include "cairo-device-private.h" -#include "cairo-error-private.h" -#include "cairo-list-inline.h" -#include "cairo-image-surface-private.h" -#include "cairo-output-stream-private.h" -#include "cairo-pattern-private.h" -#include "cairo-recording-surface-inline.h" -#include "cairo-scaled-font-private.h" -#include "cairo-surface-clipper-private.h" -#include "cairo-surface-snapshot-inline.h" -#include "cairo-surface-subsurface-private.h" -#include "cairo-surface-wrapper-private.h" - -#if CAIRO_HAS_FT_FONT -#include "cairo-ft-private.h" -#endif - -#include <ctype.h> - -#ifdef WORDS_BIGENDIAN -#define to_be32(x) x -#else -#define to_be32(x) bswap_32(x) -#endif - -#define _cairo_output_stream_puts(S, STR) \ - _cairo_output_stream_write ((S), (STR), strlen (STR)) - -#define static cairo_warn static - -typedef struct _cairo_script_context cairo_script_context_t; -typedef struct _cairo_script_surface cairo_script_surface_t; -typedef struct _cairo_script_implicit_context cairo_script_implicit_context_t; -typedef struct _cairo_script_font cairo_script_font_t; - -typedef struct _operand { - enum { - SURFACE, - DEFERRED, - } type; - cairo_list_t link; -} operand_t; - - -struct deferred_finish { - cairo_list_t link; - operand_t operand; -}; - -struct _cairo_script_context { - cairo_device_t base; - - int active; - int attach_snapshots; - - cairo_bool_t owns_stream; - cairo_output_stream_t *stream; - cairo_script_mode_t mode; - - struct _bitmap { - unsigned long min; - unsigned long count; - unsigned int map[64]; - struct _bitmap *next; - } surface_id, font_id; - - cairo_list_t operands; - cairo_list_t deferred; - - cairo_list_t fonts; - cairo_list_t defines; -}; - -struct _cairo_script_font { - cairo_scaled_font_private_t base; - - cairo_bool_t has_sfnt; - unsigned long id; - unsigned long subset_glyph_index; - cairo_list_t link; - cairo_scaled_font_t *parent; -}; - -struct _cairo_script_implicit_context { - cairo_operator_t current_operator; - cairo_fill_rule_t current_fill_rule; - double current_tolerance; - cairo_antialias_t current_antialias; - cairo_stroke_style_t current_style; - cairo_pattern_union_t current_source; - cairo_matrix_t current_ctm; - cairo_matrix_t current_stroke_matrix; - cairo_matrix_t current_font_matrix; - cairo_font_options_t current_font_options; - cairo_scaled_font_t *current_scaled_font; - cairo_path_fixed_t current_path; - cairo_bool_t has_clip; -}; - -struct _cairo_script_surface { - cairo_surface_t base; - - cairo_surface_wrapper_t wrapper; - - cairo_surface_clipper_t clipper; - - operand_t operand; - cairo_bool_t emitted; - cairo_bool_t defined; - cairo_bool_t active; - - double width, height; - - /* implicit flattened context */ - cairo_script_implicit_context_t cr; -}; - -static const cairo_surface_backend_t _cairo_script_surface_backend; - -static cairo_script_surface_t * -_cairo_script_surface_create_internal (cairo_script_context_t *ctx, - cairo_content_t content, - cairo_rectangle_t *extents, - cairo_surface_t *passthrough); - -static void -_cairo_script_scaled_font_fini (cairo_scaled_font_private_t *abstract_private, - cairo_scaled_font_t *scaled_font); - -static void -_cairo_script_implicit_context_init (cairo_script_implicit_context_t *cr); - -static void -_cairo_script_implicit_context_reset (cairo_script_implicit_context_t *cr); - -static void -_bitmap_release_id (struct _bitmap *b, unsigned long token) -{ - struct _bitmap **prev = NULL; - - do { - if (token < b->min + sizeof (b->map) * CHAR_BIT) { - unsigned int bit, elem; - - token -= b->min; - elem = token / (sizeof (b->map[0]) * CHAR_BIT); - bit = token % (sizeof (b->map[0]) * CHAR_BIT); - b->map[elem] &= ~(1 << bit); - if (! --b->count && prev) { - *prev = b->next; - free (b); - } - return; - } - prev = &b->next; - b = b->next; - } while (b != NULL); -} - -static cairo_status_t -_bitmap_next_id (struct _bitmap *b, - unsigned long *id) -{ - struct _bitmap *bb, **prev = NULL; - unsigned long min = 0; - - do { - if (b->min != min) - break; - - if (b->count < sizeof (b->map) * CHAR_BIT) { - unsigned int n, m, bit; - for (n = 0; n < ARRAY_LENGTH (b->map); n++) { - if (b->map[n] == (unsigned int) -1) - continue; - - for (m=0, bit=1; m<sizeof (b->map[0])*CHAR_BIT; m++, bit<<=1) { - if ((b->map[n] & bit) == 0) { - b->map[n] |= bit; - b->count++; - *id = n * sizeof (b->map[0])*CHAR_BIT + m + b->min; - return CAIRO_STATUS_SUCCESS; - } - } - } - } - min += sizeof (b->map) * CHAR_BIT; - - prev = &b->next; - b = b->next; - } while (b != NULL); - - bb = malloc (sizeof (struct _bitmap)); - if (unlikely (bb == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - *prev = bb; - bb->next = b; - bb->min = min; - bb->count = 1; - bb->map[0] = 0x1; - memset (bb->map + 1, 0, sizeof (bb->map) - sizeof (bb->map[0])); - *id = min; - - return CAIRO_STATUS_SUCCESS; -} - -static void -_bitmap_fini (struct _bitmap *b) -{ - while (b != NULL) { - struct _bitmap *next = b->next; - free (b); - b = next; - } -} - -static const char * -_direction_to_string (cairo_bool_t backward) -{ - static const char *names[] = { - "FORWARD", - "BACKWARD" - }; - assert (backward < ARRAY_LENGTH (names)); - return names[backward]; -} - -static const char * -_operator_to_string (cairo_operator_t op) -{ - static const char *names[] = { - "CLEAR", /* CAIRO_OPERATOR_CLEAR */ - - "SOURCE", /* CAIRO_OPERATOR_SOURCE */ - "OVER", /* CAIRO_OPERATOR_OVER */ - "IN", /* CAIRO_OPERATOR_IN */ - "OUT", /* CAIRO_OPERATOR_OUT */ - "ATOP", /* CAIRO_OPERATOR_ATOP */ - - "DEST", /* CAIRO_OPERATOR_DEST */ - "DEST_OVER", /* CAIRO_OPERATOR_DEST_OVER */ - "DEST_IN", /* CAIRO_OPERATOR_DEST_IN */ - "DEST_OUT", /* CAIRO_OPERATOR_DEST_OUT */ - "DEST_ATOP", /* CAIRO_OPERATOR_DEST_ATOP */ - - "XOR", /* CAIRO_OPERATOR_XOR */ - "ADD", /* CAIRO_OPERATOR_ADD */ - "SATURATE", /* CAIRO_OPERATOR_SATURATE */ - - "MULTIPLY", /* CAIRO_OPERATOR_MULTIPLY */ - "SCREEN", /* CAIRO_OPERATOR_SCREEN */ - "OVERLAY", /* CAIRO_OPERATOR_OVERLAY */ - "DARKEN", /* CAIRO_OPERATOR_DARKEN */ - "LIGHTEN", /* CAIRO_OPERATOR_LIGHTEN */ - "DODGE", /* CAIRO_OPERATOR_COLOR_DODGE */ - "BURN", /* CAIRO_OPERATOR_COLOR_BURN */ - "HARD_LIGHT", /* CAIRO_OPERATOR_HARD_LIGHT */ - "SOFT_LIGHT", /* CAIRO_OPERATOR_SOFT_LIGHT */ - "DIFFERENCE", /* CAIRO_OPERATOR_DIFFERENCE */ - "EXCLUSION", /* CAIRO_OPERATOR_EXCLUSION */ - "HSL_HUE", /* CAIRO_OPERATOR_HSL_HUE */ - "HSL_SATURATION", /* CAIRO_OPERATOR_HSL_SATURATION */ - "HSL_COLOR", /* CAIRO_OPERATOR_HSL_COLOR */ - "HSL_LUMINOSITY" /* CAIRO_OPERATOR_HSL_LUMINOSITY */ - }; - assert (op < ARRAY_LENGTH (names)); - return names[op]; -} - -static const char * -_extend_to_string (cairo_extend_t extend) -{ - static const char *names[] = { - "EXTEND_NONE", /* CAIRO_EXTEND_NONE */ - "EXTEND_REPEAT", /* CAIRO_EXTEND_REPEAT */ - "EXTEND_REFLECT", /* CAIRO_EXTEND_REFLECT */ - "EXTEND_PAD" /* CAIRO_EXTEND_PAD */ - }; - assert (extend < ARRAY_LENGTH (names)); - return names[extend]; -} - -static const char * -_filter_to_string (cairo_filter_t filter) -{ - static const char *names[] = { - "FILTER_FAST", /* CAIRO_FILTER_FAST */ - "FILTER_GOOD", /* CAIRO_FILTER_GOOD */ - "FILTER_BEST", /* CAIRO_FILTER_BEST */ - "FILTER_NEAREST", /* CAIRO_FILTER_NEAREST */ - "FILTER_BILINEAR", /* CAIRO_FILTER_BILINEAR */ - "FILTER_GAUSSIAN", /* CAIRO_FILTER_GAUSSIAN */ - }; - assert (filter < ARRAY_LENGTH (names)); - return names[filter]; -} - -static const char * -_fill_rule_to_string (cairo_fill_rule_t rule) -{ - static const char *names[] = { - "WINDING", /* CAIRO_FILL_RULE_WINDING */ - "EVEN_ODD" /* CAIRO_FILL_RILE_EVEN_ODD */ - }; - assert (rule < ARRAY_LENGTH (names)); - return names[rule]; -} - -static const char * -_antialias_to_string (cairo_antialias_t antialias) -{ - static const char *names[] = { - "ANTIALIAS_DEFAULT", /* CAIRO_ANTIALIAS_DEFAULT */ - "ANTIALIAS_NONE", /* CAIRO_ANTIALIAS_NONE */ - "ANTIALIAS_GRAY", /* CAIRO_ANTIALIAS_GRAY */ - "ANTIALIAS_SUBPIXEL", /* CAIRO_ANTIALIAS_SUBPIXEL */ - "ANTIALIAS_FAST", /* CAIRO_ANTIALIAS_FAST */ - "ANTIALIAS_GOOD", /* CAIRO_ANTIALIAS_GOOD */ - "ANTIALIAS_BEST" /* CAIRO_ANTIALIAS_BEST */ - }; - assert (antialias < ARRAY_LENGTH (names)); - return names[antialias]; -} - -static const char * -_line_cap_to_string (cairo_line_cap_t line_cap) -{ - static const char *names[] = { - "LINE_CAP_BUTT", /* CAIRO_LINE_CAP_BUTT */ - "LINE_CAP_ROUND", /* CAIRO_LINE_CAP_ROUND */ - "LINE_CAP_SQUARE" /* CAIRO_LINE_CAP_SQUARE */ - }; - assert (line_cap < ARRAY_LENGTH (names)); - return names[line_cap]; -} - -static const char * -_line_join_to_string (cairo_line_join_t line_join) -{ - static const char *names[] = { - "LINE_JOIN_MITER", /* CAIRO_LINE_JOIN_MITER */ - "LINE_JOIN_ROUND", /* CAIRO_LINE_JOIN_ROUND */ - "LINE_JOIN_BEVEL", /* CAIRO_LINE_JOIN_BEVEL */ - }; - assert (line_join < ARRAY_LENGTH (names)); - return names[line_join]; -} - -static inline cairo_script_context_t * -to_context (cairo_script_surface_t *surface) -{ - return (cairo_script_context_t *) surface->base.device; -} - -static cairo_bool_t -target_is_active (cairo_script_surface_t *surface) -{ - return cairo_list_is_first (&surface->operand.link, - &to_context (surface)->operands); -} - -static void -target_push (cairo_script_surface_t *surface) -{ - cairo_list_move (&surface->operand.link, &to_context (surface)->operands); -} - -static int -target_depth (cairo_script_surface_t *surface) -{ - cairo_list_t *link; - int depth = 0; - - cairo_list_foreach (link, &to_context (surface)->operands) { - if (link == &surface->operand.link) - break; - depth++; - } - - return depth; -} - -static void -_get_target (cairo_script_surface_t *surface) -{ - cairo_script_context_t *ctx = to_context (surface); - - if (target_is_active (surface)) { - _cairo_output_stream_puts (ctx->stream, "dup "); - return; - } - - if (surface->defined) { - _cairo_output_stream_printf (ctx->stream, "s%u ", - surface->base.unique_id); - } else { - int depth = target_depth (surface); - - assert (! cairo_list_is_empty (&surface->operand.link)); - assert (! target_is_active (surface)); - - if (ctx->active) { - _cairo_output_stream_printf (ctx->stream, "%d index ", depth); - _cairo_output_stream_puts (ctx->stream, "/target get exch pop "); - } else { - if (depth == 1) { - _cairo_output_stream_puts (ctx->stream, "exch "); - } else { - _cairo_output_stream_printf (ctx->stream, - "%d -1 roll ", depth); - } - target_push (surface); - _cairo_output_stream_puts (ctx->stream, "dup "); - } - } -} - -static const char * -_content_to_string (cairo_content_t content) -{ - switch (content) { - case CAIRO_CONTENT_ALPHA: return "ALPHA"; - case CAIRO_CONTENT_COLOR: return "COLOR"; - default: - case CAIRO_CONTENT_COLOR_ALPHA: return "COLOR_ALPHA"; - } -} - -static cairo_status_t -_emit_surface (cairo_script_surface_t *surface) -{ - cairo_script_context_t *ctx = to_context (surface); - - _cairo_output_stream_printf (ctx->stream, - "<< /content //%s", - _content_to_string (surface->base.content)); - if (surface->width != -1 && surface->height != -1) { - _cairo_output_stream_printf (ctx->stream, - " /width %f /height %f", - surface->width, - surface->height); - } - - if (surface->base.x_fallback_resolution != - CAIRO_SURFACE_FALLBACK_RESOLUTION_DEFAULT || - surface->base.y_fallback_resolution != - CAIRO_SURFACE_FALLBACK_RESOLUTION_DEFAULT) - { - _cairo_output_stream_printf (ctx->stream, - " /fallback-resolution [%f %f]", - surface->base.x_fallback_resolution, - surface->base.y_fallback_resolution); - } - - if (surface->base.device_transform.x0 != 0. || - surface->base.device_transform.y0 != 0.) - { - /* XXX device offset is encoded into the pattern matrices etc. */ - if (0) { - _cairo_output_stream_printf (ctx->stream, - " /device-offset [%f %f]", - surface->base.device_transform.x0, - surface->base.device_transform.y0); - } - } - - _cairo_output_stream_puts (ctx->stream, " >> surface context\n"); - surface->emitted = TRUE; - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_emit_context (cairo_script_surface_t *surface) -{ - cairo_script_context_t *ctx = to_context (surface); - - if (target_is_active (surface)) - return CAIRO_STATUS_SUCCESS; - - while (! cairo_list_is_empty (&ctx->operands)) { - operand_t *op; - cairo_script_surface_t *old; - - op = cairo_list_first_entry (&ctx->operands, - operand_t, - link); - if (op->type == DEFERRED) - break; - - old = cairo_container_of (op, cairo_script_surface_t, operand); - if (old == surface) - break; - if (old->active) - break; - - if (! old->defined) { - assert (old->emitted); - _cairo_output_stream_printf (ctx->stream, - "/target get /s%u exch def pop\n", - old->base.unique_id); - old->defined = TRUE; - } else { - _cairo_output_stream_puts (ctx->stream, "pop\n"); - } - - cairo_list_del (&old->operand.link); - } - - if (target_is_active (surface)) - return CAIRO_STATUS_SUCCESS; - - if (! surface->emitted) { - cairo_status_t status; - - status = _emit_surface (surface); - if (unlikely (status)) - return status; - } else if (cairo_list_is_empty (&surface->operand.link)) { - assert (surface->defined); - _cairo_output_stream_printf (ctx->stream, - "s%u context\n", - surface->base.unique_id); - _cairo_script_implicit_context_reset (&surface->cr); - _cairo_surface_clipper_reset (&surface->clipper); - } else { - int depth = target_depth (surface); - if (depth == 1) { - _cairo_output_stream_puts (ctx->stream, "exch\n"); - } else { - _cairo_output_stream_printf (ctx->stream, - "%d -1 roll\n", - depth); - } - } - target_push (surface); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_emit_operator (cairo_script_surface_t *surface, - cairo_operator_t op) -{ - assert (target_is_active (surface)); - - if (surface->cr.current_operator == op) - return CAIRO_STATUS_SUCCESS; - - surface->cr.current_operator = op; - - _cairo_output_stream_printf (to_context (surface)->stream, - "//%s set-operator\n", - _operator_to_string (op)); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_emit_fill_rule (cairo_script_surface_t *surface, - cairo_fill_rule_t fill_rule) -{ - assert (target_is_active (surface)); - - if (surface->cr.current_fill_rule == fill_rule) - return CAIRO_STATUS_SUCCESS; - - surface->cr.current_fill_rule = fill_rule; - - _cairo_output_stream_printf (to_context (surface)->stream, - "//%s set-fill-rule\n", - _fill_rule_to_string (fill_rule)); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_emit_tolerance (cairo_script_surface_t *surface, - double tolerance, - cairo_bool_t force) -{ - assert (target_is_active (surface)); - - if ((! force || - fabs (tolerance - CAIRO_GSTATE_TOLERANCE_DEFAULT) < 1e-5) && - surface->cr.current_tolerance == tolerance) - { - return CAIRO_STATUS_SUCCESS; - } - - surface->cr.current_tolerance = tolerance; - - _cairo_output_stream_printf (to_context (surface)->stream, - "%f set-tolerance\n", - tolerance); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_emit_antialias (cairo_script_surface_t *surface, - cairo_antialias_t antialias) -{ - assert (target_is_active (surface)); - - if (surface->cr.current_antialias == antialias) - return CAIRO_STATUS_SUCCESS; - - surface->cr.current_antialias = antialias; - - _cairo_output_stream_printf (to_context (surface)->stream, - "//%s set-antialias\n", - _antialias_to_string (antialias)); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_emit_line_width (cairo_script_surface_t *surface, - double line_width, - cairo_bool_t force) -{ - assert (target_is_active (surface)); - - if ((! force || - fabs (line_width - CAIRO_GSTATE_LINE_WIDTH_DEFAULT) < 1e-5) && - surface->cr.current_style.line_width == line_width) - { - return CAIRO_STATUS_SUCCESS; - } - - surface->cr.current_style.line_width = line_width; - - _cairo_output_stream_printf (to_context (surface)->stream, - "%f set-line-width\n", - line_width); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_emit_line_cap (cairo_script_surface_t *surface, - cairo_line_cap_t line_cap) -{ - assert (target_is_active (surface)); - - if (surface->cr.current_style.line_cap == line_cap) - return CAIRO_STATUS_SUCCESS; - - surface->cr.current_style.line_cap = line_cap; - - _cairo_output_stream_printf (to_context (surface)->stream, - "//%s set-line-cap\n", - _line_cap_to_string (line_cap)); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_emit_line_join (cairo_script_surface_t *surface, - cairo_line_join_t line_join) -{ - assert (target_is_active (surface)); - - if (surface->cr.current_style.line_join == line_join) - return CAIRO_STATUS_SUCCESS; - - surface->cr.current_style.line_join = line_join; - - _cairo_output_stream_printf (to_context (surface)->stream, - "//%s set-line-join\n", - _line_join_to_string (line_join)); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_emit_miter_limit (cairo_script_surface_t *surface, - double miter_limit, - cairo_bool_t force) -{ - assert (target_is_active (surface)); - - if ((! force || - fabs (miter_limit - CAIRO_GSTATE_MITER_LIMIT_DEFAULT) < 1e-5) && - surface->cr.current_style.miter_limit == miter_limit) - { - return CAIRO_STATUS_SUCCESS; - } - - surface->cr.current_style.miter_limit = miter_limit; - - _cairo_output_stream_printf (to_context (surface)->stream, - "%f set-miter-limit\n", - miter_limit); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_bool_t -_dashes_equal (const double *a, const double *b, int num_dashes) -{ - while (num_dashes--) { - if (fabs (*a - *b) > 1e-5) - return FALSE; - a++, b++; - } - - return TRUE; -} - -static cairo_status_t -_emit_dash (cairo_script_surface_t *surface, - const double *dash, - unsigned int num_dashes, - double offset, - cairo_bool_t force) -{ - unsigned int n; - - assert (target_is_active (surface)); - - if (force && - num_dashes == 0 && - surface->cr.current_style.num_dashes == 0) - { - return CAIRO_STATUS_SUCCESS; - } - - if (! force && - (surface->cr.current_style.num_dashes == num_dashes && - (num_dashes == 0 || - (fabs (surface->cr.current_style.dash_offset - offset) < 1e-5 && - _dashes_equal (surface->cr.current_style.dash, dash, num_dashes))))) - { - return CAIRO_STATUS_SUCCESS; - } - - - if (num_dashes) { - surface->cr.current_style.dash = _cairo_realloc_ab - (surface->cr.current_style.dash, num_dashes, sizeof (double)); - if (unlikely (surface->cr.current_style.dash == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - memcpy (surface->cr.current_style.dash, dash, - sizeof (double) * num_dashes); - } else { - free (surface->cr.current_style.dash); - surface->cr.current_style.dash = NULL; - } - - surface->cr.current_style.num_dashes = num_dashes; - surface->cr.current_style.dash_offset = offset; - - _cairo_output_stream_puts (to_context (surface)->stream, "["); - for (n = 0; n < num_dashes; n++) { - _cairo_output_stream_printf (to_context (surface)->stream, "%f", dash[n]); - if (n < num_dashes-1) - _cairo_output_stream_puts (to_context (surface)->stream, " "); - } - _cairo_output_stream_printf (to_context (surface)->stream, - "] %f set-dash\n", - offset); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_emit_stroke_style (cairo_script_surface_t *surface, - const cairo_stroke_style_t *style, - cairo_bool_t force) -{ - cairo_status_t status; - - assert (target_is_active (surface)); - - status = _emit_line_width (surface, style->line_width, force); - if (unlikely (status)) - return status; - - status = _emit_line_cap (surface, style->line_cap); - if (unlikely (status)) - return status; - - status = _emit_line_join (surface, style->line_join); - if (unlikely (status)) - return status; - - status = _emit_miter_limit (surface, style->miter_limit, force); - if (unlikely (status)) - return status; - - status = _emit_dash (surface, - style->dash, style->num_dashes, style->dash_offset, - force); - if (unlikely (status)) - return status; - - return CAIRO_STATUS_SUCCESS; -} - -static const char * -_format_to_string (cairo_format_t format) -{ - switch (format) { - case CAIRO_FORMAT_ARGB32: return "ARGB32"; - case CAIRO_FORMAT_RGB30: return "RGB30"; - case CAIRO_FORMAT_RGB24: return "RGB24"; - case CAIRO_FORMAT_RGB16_565: return "RGB16_565"; - case CAIRO_FORMAT_A8: return "A8"; - case CAIRO_FORMAT_A1: return "A1"; - case CAIRO_FORMAT_INVALID: return "INVALID"; - } - ASSERT_NOT_REACHED; - return "INVALID"; -} - -static cairo_status_t -_emit_solid_pattern (cairo_script_surface_t *surface, - const cairo_pattern_t *pattern) -{ - cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) pattern; - cairo_script_context_t *ctx = to_context (surface); - - if (! CAIRO_COLOR_IS_OPAQUE (&solid->color)) - { - if (! (surface->base.content & CAIRO_CONTENT_COLOR) || - ((solid->color.red_short == 0 || solid->color.red_short == 0xffff) && - (solid->color.green_short == 0 || solid->color.green_short == 0xffff) && - (solid->color.blue_short == 0 || solid->color.blue_short == 0xffff) )) - { - _cairo_output_stream_printf (ctx->stream, - "%f a", - solid->color.alpha); - } - else - { - _cairo_output_stream_printf (ctx->stream, - "%f %f %f %f rgba", - solid->color.red, - solid->color.green, - solid->color.blue, - solid->color.alpha); - } - } - else - { - if (solid->color.red_short == solid->color.green_short && - solid->color.red_short == solid->color.blue_short) - { - _cairo_output_stream_printf (ctx->stream, - "%f g", - solid->color.red); - } - else - { - _cairo_output_stream_printf (ctx->stream, - "%f %f %f rgb", - solid->color.red, - solid->color.green, - solid->color.blue); - } - } - - return CAIRO_STATUS_SUCCESS; -} - - -static cairo_status_t -_emit_gradient_color_stops (cairo_gradient_pattern_t *gradient, - cairo_output_stream_t *output) -{ - unsigned int n; - - for (n = 0; n < gradient->n_stops; n++) { - _cairo_output_stream_printf (output, - "\n %f %f %f %f %f add-color-stop", - gradient->stops[n].offset, - gradient->stops[n].color.red, - gradient->stops[n].color.green, - gradient->stops[n].color.blue, - gradient->stops[n].color.alpha); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_emit_linear_pattern (cairo_script_surface_t *surface, - const cairo_pattern_t *pattern) -{ - cairo_script_context_t *ctx = to_context (surface); - cairo_linear_pattern_t *linear; - - linear = (cairo_linear_pattern_t *) pattern; - - _cairo_output_stream_printf (ctx->stream, - "%f %f %f %f linear", - linear->pd1.x, linear->pd1.y, - linear->pd2.x, linear->pd2.y); - return _emit_gradient_color_stops (&linear->base, ctx->stream); -} - -static cairo_status_t -_emit_radial_pattern (cairo_script_surface_t *surface, - const cairo_pattern_t *pattern) -{ - cairo_script_context_t *ctx = to_context (surface); - cairo_radial_pattern_t *radial; - - radial = (cairo_radial_pattern_t *) pattern; - - _cairo_output_stream_printf (ctx->stream, - "%f %f %f %f %f %f radial", - radial->cd1.center.x, - radial->cd1.center.y, - radial->cd1.radius, - radial->cd2.center.x, - radial->cd2.center.y, - radial->cd2.radius); - return _emit_gradient_color_stops (&radial->base, ctx->stream); -} - -static cairo_status_t -_emit_mesh_pattern (cairo_script_surface_t *surface, - const cairo_pattern_t *pattern) -{ - cairo_script_context_t *ctx = to_context (surface); - cairo_pattern_t *mesh; - cairo_status_t status; - unsigned int i, n; - - mesh = (cairo_pattern_t *) pattern; - status = cairo_mesh_pattern_get_patch_count (mesh, &n); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (ctx->stream, "mesh"); - for (i = 0; i < n; i++) { - cairo_path_t *path; - cairo_path_data_t *data; - int j; - - _cairo_output_stream_printf (ctx->stream, "\n begin-patch"); - - path = cairo_mesh_pattern_get_path (mesh, i); - if (unlikely (path->status)) - return path->status; - - for (j = 0; j < path->num_data; j+=data[0].header.length) { - data = &path->data[j]; - switch (data->header.type) { - case CAIRO_PATH_MOVE_TO: - _cairo_output_stream_printf (ctx->stream, - "\n %f %f m", - data[1].point.x, data[1].point.y); - break; - case CAIRO_PATH_LINE_TO: - _cairo_output_stream_printf (ctx->stream, - "\n %f %f l", - data[1].point.x, data[1].point.y); - break; - case CAIRO_PATH_CURVE_TO: - _cairo_output_stream_printf (ctx->stream, - "\n %f %f %f %f %f %f c", - data[1].point.x, data[1].point.y, - data[2].point.x, data[2].point.y, - data[3].point.x, data[3].point.y); - break; - case CAIRO_PATH_CLOSE_PATH: - break; - } - } - cairo_path_destroy (path); - - for (j = 0; j < 4; j++) { - double x, y; - - status = cairo_mesh_pattern_get_control_point (mesh, i, j, &x, &y); - if (unlikely (status)) - return status; - _cairo_output_stream_printf (ctx->stream, - "\n %d %f %f set-control-point", - j, x, y); - } - - for (j = 0; j < 4; j++) { - double r, g, b, a; - - status = cairo_mesh_pattern_get_corner_color_rgba (mesh, i, j, &r, &g, &b, &a); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (ctx->stream, - "\n %d %f %f %f %f set-corner-color", - j, r, g, b, a); - } - - _cairo_output_stream_printf (ctx->stream, "\n end-patch"); - } - - return CAIRO_STATUS_SUCCESS; -} - -struct script_snapshot { - cairo_surface_t base; -}; - -static cairo_status_t -script_snapshot_finish (void *abstract_surface) -{ - return CAIRO_STATUS_SUCCESS; -} - -static const cairo_surface_backend_t script_snapshot_backend = { - CAIRO_SURFACE_TYPE_SCRIPT, - script_snapshot_finish, -}; - -static void -detach_snapshot (cairo_surface_t *abstract_surface) -{ - cairo_script_surface_t *surface = (cairo_script_surface_t *)abstract_surface; - cairo_script_context_t *ctx = to_context (surface); - - _cairo_output_stream_printf (ctx->stream, - "/s%d undef\n", - surface->base.unique_id); -} - -static void -attach_snapshot (cairo_script_context_t *ctx, - cairo_surface_t *source) -{ - struct script_snapshot *surface; - - if (! ctx->attach_snapshots) - return; - - surface = malloc (sizeof (*surface)); - if (unlikely (surface == NULL)) - return; - - _cairo_surface_init (&surface->base, - &script_snapshot_backend, - &ctx->base, - source->content); - - _cairo_output_stream_printf (ctx->stream, - "dup /s%d exch def ", - surface->base.unique_id); - - _cairo_surface_attach_snapshot (source, &surface->base, detach_snapshot); - cairo_surface_destroy (&surface->base); -} - -static cairo_status_t -_emit_recording_surface_pattern (cairo_script_surface_t *surface, - cairo_recording_surface_t *source) -{ - cairo_script_implicit_context_t old_cr; - cairo_script_context_t *ctx = to_context (surface); - cairo_script_surface_t *similar; - cairo_surface_t *snapshot; - cairo_rectangle_t r, *extents; - cairo_status_t status; - - snapshot = _cairo_surface_has_snapshot (&source->base, &script_snapshot_backend); - if (snapshot) { - _cairo_output_stream_printf (ctx->stream, "s%d", snapshot->unique_id); - return CAIRO_INT_STATUS_SUCCESS; - } - - extents = NULL; - if (_cairo_recording_surface_get_bounds (&source->base, &r)) - extents = &r; - - similar = _cairo_script_surface_create_internal (ctx, - source->base.content, - extents, - NULL); - if (unlikely (similar->base.status)) - return similar->base.status; - - similar->base.is_clear = TRUE; - - _cairo_output_stream_printf (ctx->stream, "//%s ", - _content_to_string (source->base.content)); - if (extents) { - _cairo_output_stream_printf (ctx->stream, "[%f %f %f %f]", - extents->x, extents->y, - extents->width, extents->height); - } else - _cairo_output_stream_puts (ctx->stream, "[]"); - _cairo_output_stream_puts (ctx->stream, " record\n"); - - attach_snapshot (ctx, &source->base); - - _cairo_output_stream_puts (ctx->stream, "dup context\n"); - - target_push (similar); - similar->emitted = TRUE; - - - old_cr = surface->cr; - _cairo_script_implicit_context_init (&surface->cr); - status = _cairo_recording_surface_replay (&source->base, &similar->base); - surface->cr = old_cr; - - if (unlikely (status)) { - cairo_surface_destroy (&similar->base); - return status; - } - - cairo_list_del (&similar->operand.link); - assert (target_is_active (surface)); - - _cairo_output_stream_puts (ctx->stream, "pop "); - cairo_surface_destroy (&similar->base); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_emit_script_surface_pattern (cairo_script_surface_t *surface, - cairo_script_surface_t *source) -{ - _get_target (source); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_write_image_surface (cairo_output_stream_t *output, - const cairo_image_surface_t *image) -{ - int stride, row, width; - uint8_t row_stack[CAIRO_STACK_BUFFER_SIZE]; - uint8_t *rowdata; - uint8_t *data; - - stride = image->stride; - width = image->width; - data = image->data; -#if WORDS_BIGENDIAN - switch (image->format) { - case CAIRO_FORMAT_A1: - for (row = image->height; row--; ) { - _cairo_output_stream_write (output, data, (width+7)/8); - data += stride; - } - break; - case CAIRO_FORMAT_A8: - for (row = image->height; row--; ) { - _cairo_output_stream_write (output, data, width); - data += stride; - } - break; - case CAIRO_FORMAT_RGB16_565: - for (row = image->height; row--; ) { - _cairo_output_stream_write (output, data, 2*width); - data += stride; - } - break; - case CAIRO_FORMAT_RGB24: - for (row = image->height; row--; ) { - int col; - rowdata = data; - for (col = width; col--; ) { - _cairo_output_stream_write (output, rowdata, 3); - rowdata+=4; - } - data += stride; - } - break; - case CAIRO_FORMAT_ARGB32: - for (row = image->height; row--; ) { - _cairo_output_stream_write (output, data, 4*width); - data += stride; - } - break; - case CAIRO_FORMAT_INVALID: - default: - ASSERT_NOT_REACHED; - break; - } -#else - if (stride > ARRAY_LENGTH (row_stack)) { - rowdata = malloc (stride); - if (unlikely (rowdata == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } else - rowdata = row_stack; - - switch (image->format) { - case CAIRO_FORMAT_A1: - for (row = image->height; row--; ) { - int col; - for (col = 0; col < (width + 7)/8; col++) - rowdata[col] = CAIRO_BITSWAP8 (data[col]); - _cairo_output_stream_write (output, rowdata, (width+7)/8); - data += stride; - } - break; - case CAIRO_FORMAT_A8: - for (row = image->height; row--; ) { - _cairo_output_stream_write (output, data, width); - data += stride; - } - break; - case CAIRO_FORMAT_RGB16_565: - for (row = image->height; row--; ) { - uint16_t *src = (uint16_t *) data; - uint16_t *dst = (uint16_t *) rowdata; - int col; - for (col = 0; col < width; col++) - dst[col] = bswap_16 (src[col]); - _cairo_output_stream_write (output, rowdata, 2*width); - data += stride; - } - break; - case CAIRO_FORMAT_RGB24: - for (row = image->height; row--; ) { - uint8_t *src = data; - int col; - for (col = 0; col < width; col++) { - rowdata[3*col+2] = *src++; - rowdata[3*col+1] = *src++; - rowdata[3*col+0] = *src++; - src++; - } - _cairo_output_stream_write (output, rowdata, 3*width); - data += stride; - } - break; - case CAIRO_FORMAT_RGB30: - case CAIRO_FORMAT_ARGB32: - for (row = image->height; row--; ) { - uint32_t *src = (uint32_t *) data; - uint32_t *dst = (uint32_t *) rowdata; - int col; - for (col = 0; col < width; col++) - dst[col] = bswap_32 (src[col]); - _cairo_output_stream_write (output, rowdata, 4*width); - data += stride; - } - break; - case CAIRO_FORMAT_INVALID: - default: - ASSERT_NOT_REACHED; - break; - } - if (rowdata != row_stack) - free (rowdata); -#endif - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_emit_png_surface (cairo_script_surface_t *surface, - cairo_image_surface_t *image) -{ - cairo_script_context_t *ctx = to_context (surface); - cairo_output_stream_t *base85_stream; - cairo_status_t status; - const uint8_t *mime_data; - unsigned long mime_data_length; - - cairo_surface_get_mime_data (&image->base, CAIRO_MIME_TYPE_PNG, - &mime_data, &mime_data_length); - if (mime_data == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - _cairo_output_stream_printf (ctx->stream, - "<< " - "/width %d " - "/height %d " - "/format //%s " - "/mime-type (image/png) " - "/source <~", - image->width, image->height, - _format_to_string (image->format)); - - base85_stream = _cairo_base85_stream_create (ctx->stream); - _cairo_output_stream_write (base85_stream, mime_data, mime_data_length); - status = _cairo_output_stream_destroy (base85_stream); - if (unlikely (status)) - return status; - - _cairo_output_stream_puts (ctx->stream, "~> >> image "); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_emit_image_surface (cairo_script_surface_t *surface, - cairo_image_surface_t *image) -{ - cairo_script_context_t *ctx = to_context (surface); - cairo_output_stream_t *base85_stream; - cairo_output_stream_t *zlib_stream; - cairo_int_status_t status, status2; - cairo_surface_t *snapshot; - const uint8_t *mime_data; - unsigned long mime_data_length; - - snapshot = _cairo_surface_has_snapshot (&image->base, - &script_snapshot_backend); - if (snapshot) { - _cairo_output_stream_printf (ctx->stream, "s%u ", snapshot->unique_id); - return CAIRO_INT_STATUS_SUCCESS; - } - - status = _emit_png_surface (surface, image); - if (_cairo_int_status_is_error (status)) { - return status; - } else if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - cairo_image_surface_t *clone; - uint32_t len; - - if (image->format == CAIRO_FORMAT_INVALID) { - clone = _cairo_image_surface_coerce (image); - } else { - clone = (cairo_image_surface_t *) - cairo_surface_reference (&image->base); - } - - _cairo_output_stream_printf (ctx->stream, - "<< " - "/width %d " - "/height %d " - "/format //%s " - "/source ", - clone->width, clone->height, - _format_to_string (clone->format)); - - switch (clone->format) { - case CAIRO_FORMAT_A1: - len = (clone->width + 7)/8; - break; - case CAIRO_FORMAT_A8: - len = clone->width; - break; - case CAIRO_FORMAT_RGB16_565: - len = clone->width * 2; - break; - case CAIRO_FORMAT_RGB24: - len = clone->width * 3; - break; - case CAIRO_FORMAT_RGB30: - case CAIRO_FORMAT_ARGB32: - len = clone->width * 4; - break; - case CAIRO_FORMAT_INVALID: - default: - ASSERT_NOT_REACHED; - len = 0; - break; - } - len *= clone->height; - - if (len > 24) { - _cairo_output_stream_puts (ctx->stream, "<|"); - - base85_stream = _cairo_base85_stream_create (ctx->stream); - - len = to_be32 (len); - _cairo_output_stream_write (base85_stream, &len, sizeof (len)); - - zlib_stream = _cairo_deflate_stream_create (base85_stream); - status = _write_image_surface (zlib_stream, clone); - - status2 = _cairo_output_stream_destroy (zlib_stream); - if (status == CAIRO_INT_STATUS_SUCCESS) - status = status2; - status2 = _cairo_output_stream_destroy (base85_stream); - if (status == CAIRO_INT_STATUS_SUCCESS) - status = status2; - if (unlikely (status)) - return status; - } else { - _cairo_output_stream_puts (ctx->stream, "<~"); - - base85_stream = _cairo_base85_stream_create (ctx->stream); - status = _write_image_surface (base85_stream, clone); - status2 = _cairo_output_stream_destroy (base85_stream); - if (status == CAIRO_INT_STATUS_SUCCESS) - status = status2; - if (unlikely (status)) - return status; - } - _cairo_output_stream_puts (ctx->stream, "~> >> image "); - - cairo_surface_destroy (&clone->base); - } - - cairo_surface_get_mime_data (&image->base, CAIRO_MIME_TYPE_JPEG, - &mime_data, &mime_data_length); - if (mime_data != NULL) { - _cairo_output_stream_printf (ctx->stream, - "\n (%s) <~", - CAIRO_MIME_TYPE_JPEG); - - base85_stream = _cairo_base85_stream_create (ctx->stream); - _cairo_output_stream_write (base85_stream, mime_data, mime_data_length); - status = _cairo_output_stream_destroy (base85_stream); - if (unlikely (status)) - return status; - - _cairo_output_stream_puts (ctx->stream, "~> set-mime-data\n"); - } - - cairo_surface_get_mime_data (&image->base, CAIRO_MIME_TYPE_JP2, - &mime_data, &mime_data_length); - if (mime_data != NULL) { - _cairo_output_stream_printf (ctx->stream, - "\n (%s) <~", - CAIRO_MIME_TYPE_JP2); - - base85_stream = _cairo_base85_stream_create (ctx->stream); - _cairo_output_stream_write (base85_stream, mime_data, mime_data_length); - status = _cairo_output_stream_destroy (base85_stream); - if (unlikely (status)) - return status; - - _cairo_output_stream_puts (ctx->stream, "~> set-mime-data\n"); - } - - return CAIRO_INT_STATUS_SUCCESS; -} - -static cairo_int_status_t -_emit_image_surface_pattern (cairo_script_surface_t *surface, - cairo_surface_t *source) -{ - cairo_image_surface_t *image; - cairo_status_t status; - void *extra; - - status = _cairo_surface_acquire_source_image (source, &image, &extra); - if (likely (status == CAIRO_STATUS_SUCCESS)) { - status = _emit_image_surface (surface, image); - _cairo_surface_release_source_image (source, image, extra); - } - - return status; -} - -static cairo_int_status_t -_emit_subsurface_pattern (cairo_script_surface_t *surface, - cairo_surface_subsurface_t *sub) -{ - cairo_surface_t *source = sub->target; - cairo_int_status_t status; - - switch ((int) source->backend->type) { - case CAIRO_SURFACE_TYPE_RECORDING: - status = _emit_recording_surface_pattern (surface, (cairo_recording_surface_t *) source); - break; - case CAIRO_SURFACE_TYPE_SCRIPT: - status = _emit_script_surface_pattern (surface, (cairo_script_surface_t *) source); - break; - default: - status = _emit_image_surface_pattern (surface, source); - break; - } - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (to_context (surface)->stream, - "%d %d %d %d subsurface ", - sub->extents.x, - sub->extents.y, - sub->extents.width, - sub->extents.height); - return CAIRO_INT_STATUS_SUCCESS; -} - -static cairo_int_status_t -_emit_surface_pattern (cairo_script_surface_t *surface, - const cairo_pattern_t *pattern) -{ - cairo_script_context_t *ctx = to_context (surface); - cairo_surface_pattern_t *surface_pattern; - cairo_surface_t *source, *snapshot, *free_me = NULL; - cairo_surface_t *take_snapshot = NULL; - cairo_int_status_t status; - - surface_pattern = (cairo_surface_pattern_t *) pattern; - source = surface_pattern->surface; - - if (_cairo_surface_is_snapshot (source)) { - snapshot = _cairo_surface_has_snapshot (source, &script_snapshot_backend); - if (snapshot) { - _cairo_output_stream_printf (ctx->stream, - "s%d pattern ", - snapshot->unique_id); - return CAIRO_INT_STATUS_SUCCESS; - } - - if (_cairo_surface_snapshot_is_reused (source)) - take_snapshot = source; - - free_me = source = _cairo_surface_snapshot_get_target (source); - } - - switch ((int) source->backend->type) { - case CAIRO_SURFACE_TYPE_RECORDING: - status = _emit_recording_surface_pattern (surface, (cairo_recording_surface_t *) source); - break; - case CAIRO_SURFACE_TYPE_SCRIPT: - status = _emit_script_surface_pattern (surface, (cairo_script_surface_t *) source); - break; - case CAIRO_SURFACE_TYPE_SUBSURFACE: - status = _emit_subsurface_pattern (surface, (cairo_surface_subsurface_t *) source); - break; - default: - status = _emit_image_surface_pattern (surface, source); - break; - } - cairo_surface_destroy (free_me); - if (unlikely (status)) - return status; - - if (take_snapshot) - attach_snapshot (ctx, take_snapshot); - - _cairo_output_stream_puts (ctx->stream, "pattern"); - return CAIRO_INT_STATUS_SUCCESS; -} - -static cairo_int_status_t -_emit_raster_pattern (cairo_script_surface_t *surface, - const cairo_pattern_t *pattern) -{ - cairo_surface_t *source; - cairo_int_status_t status; - - source = _cairo_raster_source_pattern_acquire (pattern, &surface->base, NULL); - if (unlikely (source == NULL)) { - ASSERT_NOT_REACHED; - return CAIRO_INT_STATUS_UNSUPPORTED; - } - if (unlikely (source->status)) - return source->status; - - status = _emit_image_surface_pattern (surface, source); - _cairo_raster_source_pattern_release (pattern, source); - if (unlikely (status)) - return status; - - _cairo_output_stream_puts (to_context(surface)->stream, "pattern"); - return CAIRO_INT_STATUS_SUCCESS; -} - -static cairo_int_status_t -_emit_pattern (cairo_script_surface_t *surface, - const cairo_pattern_t *pattern) -{ - cairo_script_context_t *ctx = to_context (surface); - cairo_int_status_t status; - cairo_bool_t is_default_extend; - cairo_bool_t need_newline = TRUE; - - switch (pattern->type) { - case CAIRO_PATTERN_TYPE_SOLID: - /* solid colors do not need filter/extend/matrix */ - return _emit_solid_pattern (surface, pattern); - - case CAIRO_PATTERN_TYPE_LINEAR: - status = _emit_linear_pattern (surface, pattern); - is_default_extend = pattern->extend == CAIRO_EXTEND_GRADIENT_DEFAULT; - break; - case CAIRO_PATTERN_TYPE_RADIAL: - status = _emit_radial_pattern (surface, pattern); - is_default_extend = pattern->extend == CAIRO_EXTEND_GRADIENT_DEFAULT; - break; - case CAIRO_PATTERN_TYPE_MESH: - status = _emit_mesh_pattern (surface, pattern); - is_default_extend = TRUE; - break; - case CAIRO_PATTERN_TYPE_SURFACE: - status = _emit_surface_pattern (surface, pattern); - is_default_extend = pattern->extend == CAIRO_EXTEND_SURFACE_DEFAULT; - break; - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - status = _emit_raster_pattern (surface, pattern); - is_default_extend = pattern->extend == CAIRO_EXTEND_SURFACE_DEFAULT; - break; - - default: - ASSERT_NOT_REACHED; - status = CAIRO_INT_STATUS_UNSUPPORTED; - } - if (unlikely (status)) - return status; - - if (! _cairo_matrix_is_identity (&pattern->matrix)) { - if (need_newline) { - _cairo_output_stream_puts (ctx->stream, "\n "); - need_newline = FALSE; - } - - _cairo_output_stream_printf (ctx->stream, - " [%f %f %f %f %f %f] set-matrix\n ", - pattern->matrix.xx, pattern->matrix.yx, - pattern->matrix.xy, pattern->matrix.yy, - pattern->matrix.x0, pattern->matrix.y0); - } - - /* XXX need to discriminate the user explicitly setting the default */ - if (pattern->filter != CAIRO_FILTER_DEFAULT) { - if (need_newline) { - _cairo_output_stream_puts (ctx->stream, "\n "); - need_newline = FALSE; - } - - _cairo_output_stream_printf (ctx->stream, - " //%s set-filter\n ", - _filter_to_string (pattern->filter)); - } - if (! is_default_extend ){ - if (need_newline) { - _cairo_output_stream_puts (ctx->stream, "\n "); - need_newline = FALSE; - } - - _cairo_output_stream_printf (ctx->stream, - " //%s set-extend\n ", - _extend_to_string (pattern->extend)); - } - - if (need_newline) - _cairo_output_stream_puts (ctx->stream, "\n "); - - return CAIRO_INT_STATUS_SUCCESS; -} - -static cairo_int_status_t -_emit_identity (cairo_script_surface_t *surface, - cairo_bool_t *matrix_updated) -{ - assert (target_is_active (surface)); - - if (_cairo_matrix_is_identity (&surface->cr.current_ctm)) - return CAIRO_INT_STATUS_SUCCESS; - - _cairo_output_stream_puts (to_context (surface)->stream, - "identity set-matrix\n"); - - *matrix_updated = TRUE; - cairo_matrix_init_identity (&surface->cr.current_ctm); - - return CAIRO_INT_STATUS_SUCCESS; -} - -static cairo_int_status_t -_emit_source (cairo_script_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source) -{ - cairo_bool_t matrix_updated = FALSE; - cairo_int_status_t status; - - assert (target_is_active (surface)); - - if (op == CAIRO_OPERATOR_CLEAR) { - /* the source is ignored, so don't change it */ - return CAIRO_INT_STATUS_SUCCESS; - } - - if (_cairo_pattern_equal (&surface->cr.current_source.base, source)) - return CAIRO_INT_STATUS_SUCCESS; - - _cairo_pattern_fini (&surface->cr.current_source.base); - status = _cairo_pattern_init_copy (&surface->cr.current_source.base, - source); - if (unlikely (status)) - return status; - - status = _emit_identity (surface, &matrix_updated); - if (unlikely (status)) - return status; - - status = _emit_pattern (surface, source); - if (unlikely (status)) - return status; - - assert (target_is_active (surface)); - _cairo_output_stream_puts (to_context (surface)->stream, - " set-source\n"); - return CAIRO_INT_STATUS_SUCCESS; -} - -static cairo_status_t -_path_move_to (void *closure, - const cairo_point_t *point) -{ - _cairo_output_stream_printf (closure, - " %f %f m", - _cairo_fixed_to_double (point->x), - _cairo_fixed_to_double (point->y)); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_path_line_to (void *closure, - const cairo_point_t *point) -{ - _cairo_output_stream_printf (closure, - " %f %f l", - _cairo_fixed_to_double (point->x), - _cairo_fixed_to_double (point->y)); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_path_curve_to (void *closure, - const cairo_point_t *p1, - const cairo_point_t *p2, - const cairo_point_t *p3) -{ - _cairo_output_stream_printf (closure, - " %f %f %f %f %f %f c", - _cairo_fixed_to_double (p1->x), - _cairo_fixed_to_double (p1->y), - _cairo_fixed_to_double (p2->x), - _cairo_fixed_to_double (p2->y), - _cairo_fixed_to_double (p3->x), - _cairo_fixed_to_double (p3->y)); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_path_close (void *closure) -{ - _cairo_output_stream_printf (closure, - " h"); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_emit_path_boxes (cairo_script_surface_t *surface, - const cairo_path_fixed_t *path) -{ - cairo_script_context_t *ctx = to_context (surface); - cairo_path_fixed_iter_t iter; - cairo_status_t status; - struct _cairo_boxes_chunk *chunk; - cairo_boxes_t boxes; - cairo_box_t box; - int i; - - _cairo_boxes_init (&boxes); - _cairo_path_fixed_iter_init (&iter, path); - while (_cairo_path_fixed_iter_is_fill_box (&iter, &box)) { - if (box.p1.y == box.p2.y || box.p1.x == box.p2.x) - continue; - - status = _cairo_boxes_add (&boxes, CAIRO_ANTIALIAS_DEFAULT, &box); - if (unlikely (status)) { - _cairo_boxes_fini (&boxes); - return status; - } - } - - if (! _cairo_path_fixed_iter_at_end (&iter)) { - _cairo_boxes_fini (&boxes); - return CAIRO_STATUS_INVALID_PATH_DATA; - } - - for (chunk = &boxes.chunks; chunk; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) { - const cairo_box_t *b = &chunk->base[i]; - double x1 = _cairo_fixed_to_double (b->p1.x); - double y1 = _cairo_fixed_to_double (b->p1.y); - double x2 = _cairo_fixed_to_double (b->p2.x); - double y2 = _cairo_fixed_to_double (b->p2.y); - - _cairo_output_stream_printf (ctx->stream, - "\n %f %f %f %f rectangle", - x1, y1, x2 - x1, y2 - y1); - } - } - - _cairo_boxes_fini (&boxes); - return status; -} - -static cairo_status_t -_emit_path (cairo_script_surface_t *surface, - const cairo_path_fixed_t *path, - cairo_bool_t is_fill) -{ - cairo_script_context_t *ctx = to_context (surface); - cairo_box_t box; - cairo_int_status_t status; - - assert (target_is_active (surface)); - assert (_cairo_matrix_is_identity (&surface->cr.current_ctm)); - - if (_cairo_path_fixed_equal (&surface->cr.current_path, path)) - return CAIRO_STATUS_SUCCESS; - - _cairo_path_fixed_fini (&surface->cr.current_path); - - _cairo_output_stream_puts (ctx->stream, "n"); - - if (path == NULL) { - _cairo_path_fixed_init (&surface->cr.current_path); - _cairo_output_stream_puts (ctx->stream, "\n"); - return CAIRO_STATUS_SUCCESS; - } - - status = _cairo_path_fixed_init_copy (&surface->cr.current_path, path); - if (unlikely (status)) - return status; - - status = CAIRO_INT_STATUS_UNSUPPORTED; - if (_cairo_path_fixed_is_rectangle (path, &box)) { - double x1 = _cairo_fixed_to_double (box.p1.x); - double y1 = _cairo_fixed_to_double (box.p1.y); - double x2 = _cairo_fixed_to_double (box.p2.x); - double y2 = _cairo_fixed_to_double (box.p2.y); - - assert (x1 > -9999); - - _cairo_output_stream_printf (ctx->stream, - " %f %f %f %f rectangle", - x1, y1, x2 - x1, y2 - y1); - status = CAIRO_INT_STATUS_SUCCESS; - } else if (is_fill && _cairo_path_fixed_fill_is_rectilinear (path)) { - status = _emit_path_boxes (surface, path); - } - - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - status = _cairo_path_fixed_interpret (path, - _path_move_to, - _path_line_to, - _path_curve_to, - _path_close, - ctx->stream); - } - - _cairo_output_stream_puts (ctx->stream, "\n"); - - return status; -} -static cairo_bool_t -_scaling_matrix_equal (const cairo_matrix_t *a, - const cairo_matrix_t *b) -{ - return fabs (a->xx - b->xx) < 1e-5 && - fabs (a->xy - b->xy) < 1e-5 && - fabs (a->yx - b->yx) < 1e-5 && - fabs (a->yy - b->yy) < 1e-5; -} - -static cairo_status_t -_emit_scaling_matrix (cairo_script_surface_t *surface, - const cairo_matrix_t *ctm, - cairo_bool_t *matrix_updated) -{ - cairo_script_context_t *ctx = to_context (surface); - cairo_bool_t was_identity; - assert (target_is_active (surface)); - - if (_scaling_matrix_equal (&surface->cr.current_ctm, ctm)) - return CAIRO_STATUS_SUCCESS; - - was_identity = _cairo_matrix_is_identity (&surface->cr.current_ctm); - - *matrix_updated = TRUE; - surface->cr.current_ctm = *ctm; - surface->cr.current_ctm.x0 = 0.; - surface->cr.current_ctm.y0 = 0.; - - if (_cairo_matrix_is_identity (&surface->cr.current_ctm)) { - _cairo_output_stream_puts (ctx->stream, - "identity set-matrix\n"); - } else if (was_identity && fabs (ctm->yx) < 1e-5 && fabs (ctm->xy) < 1e-5) { - _cairo_output_stream_printf (ctx->stream, - "%f %f scale\n", - ctm->xx, ctm->yy); - } else { - _cairo_output_stream_printf (ctx->stream, - "[%f %f %f %f 0 0] set-matrix\n", - ctm->xx, ctm->yx, - ctm->xy, ctm->yy); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_emit_font_matrix (cairo_script_surface_t *surface, - const cairo_matrix_t *font_matrix) -{ - cairo_script_context_t *ctx = to_context (surface); - assert (target_is_active (surface)); - - if (memcmp (&surface->cr.current_font_matrix, - font_matrix, - sizeof (cairo_matrix_t)) == 0) - { - return CAIRO_STATUS_SUCCESS; - } - - surface->cr.current_font_matrix = *font_matrix; - - if (_cairo_matrix_is_identity (font_matrix)) { - _cairo_output_stream_puts (ctx->stream, - "identity set-font-matrix\n"); - } else { - _cairo_output_stream_printf (ctx->stream, - "[%f %f %f %f %f %f] set-font-matrix\n", - font_matrix->xx, font_matrix->yx, - font_matrix->xy, font_matrix->yy, - font_matrix->x0, font_matrix->y0); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_surface_t * -_cairo_script_surface_create_similar (void *abstract_surface, - cairo_content_t content, - int width, - int height) -{ - cairo_script_surface_t *surface, *other = abstract_surface; - cairo_surface_t *passthrough = NULL; - cairo_script_context_t *ctx; - cairo_rectangle_t extents; - cairo_status_t status; - - ctx = to_context (other); - - status = cairo_device_acquire (&ctx->base); - if (unlikely (status)) - return _cairo_surface_create_in_error (status); - - if (! other->emitted) { - status = _emit_surface (other); - if (unlikely (status)) { - cairo_device_release (&ctx->base); - return _cairo_surface_create_in_error (status); - } - - target_push (other); - } - - if (_cairo_surface_wrapper_is_active (&other->wrapper)) { - passthrough = - _cairo_surface_wrapper_create_similar (&other->wrapper, - content, width, height); - if (unlikely (passthrough->status)) { - cairo_device_release (&ctx->base); - return passthrough; - } - } - - extents.x = extents.y = 0; - extents.width = width; - extents.height = height; - surface = _cairo_script_surface_create_internal (ctx, content, - &extents, passthrough); - cairo_surface_destroy (passthrough); - - if (unlikely (surface->base.status)) { - cairo_device_release (&ctx->base); - return &surface->base; - } - - _get_target (other); - _cairo_output_stream_printf (ctx->stream, - "%u %u //%s similar dup /s%u exch def context\n", - width, height, - _content_to_string (content), - surface->base.unique_id); - - surface->emitted = TRUE; - surface->defined = TRUE; - surface->base.is_clear = TRUE; - target_push (surface); - - cairo_device_release (&ctx->base); - return &surface->base; -} - -static cairo_status_t -_device_flush (void *abstract_device) -{ - cairo_script_context_t *ctx = abstract_device; - - return _cairo_output_stream_flush (ctx->stream); -} - -static void -_device_destroy (void *abstract_device) -{ - cairo_script_context_t *ctx = abstract_device; - cairo_status_t status; - - while (! cairo_list_is_empty (&ctx->fonts)) { - cairo_script_font_t *font; - - font = cairo_list_first_entry (&ctx->fonts, cairo_script_font_t, link); - cairo_list_del (&font->base.link); - cairo_list_del (&font->link); - free (font); - } - - _bitmap_fini (ctx->surface_id.next); - _bitmap_fini (ctx->font_id.next); - - if (ctx->owns_stream) - status = _cairo_output_stream_destroy (ctx->stream); - - free (ctx); -} - -static cairo_surface_t * -_cairo_script_surface_source (void *abstract_surface, - cairo_rectangle_int_t *extents) -{ - cairo_script_surface_t *surface = abstract_surface; - - if (extents) { - extents->x = extents->y = 0; - extents->width = surface->width; - extents->height = surface->height; - } - - return &surface->base; -} - -static cairo_status_t -_cairo_script_surface_acquire_source_image (void *abstract_surface, - cairo_image_surface_t **image_out, - void **image_extra) -{ - cairo_script_surface_t *surface = abstract_surface; - - if (_cairo_surface_wrapper_is_active (&surface->wrapper)) { - return _cairo_surface_wrapper_acquire_source_image (&surface->wrapper, - image_out, - image_extra); - } - - return CAIRO_INT_STATUS_UNSUPPORTED; -} - -static void -_cairo_script_surface_release_source_image (void *abstract_surface, - cairo_image_surface_t *image, - void *image_extra) -{ - cairo_script_surface_t *surface = abstract_surface; - - assert (_cairo_surface_wrapper_is_active (&surface->wrapper)); - _cairo_surface_wrapper_release_source_image (&surface->wrapper, - image, - image_extra); -} - -static cairo_status_t -_cairo_script_surface_finish (void *abstract_surface) -{ - cairo_script_surface_t *surface = abstract_surface; - cairo_script_context_t *ctx = to_context (surface); - cairo_status_t status = CAIRO_STATUS_SUCCESS, status2; - - _cairo_surface_wrapper_fini (&surface->wrapper); - - free (surface->cr.current_style.dash); - surface->cr.current_style.dash = NULL; - - _cairo_pattern_fini (&surface->cr.current_source.base); - _cairo_path_fixed_fini (&surface->cr.current_path); - _cairo_surface_clipper_reset (&surface->clipper); - - status = cairo_device_acquire (&ctx->base); - if (unlikely (status)) - return status; - - if (surface->emitted) { - assert (! surface->active); - - if (! cairo_list_is_empty (&surface->operand.link)) { - if (! ctx->active) { - if (target_is_active (surface)) { - _cairo_output_stream_printf (ctx->stream, - "pop\n"); - } else { - int depth = target_depth (surface); - if (depth == 1) { - _cairo_output_stream_printf (ctx->stream, - "exch pop\n"); - } else { - _cairo_output_stream_printf (ctx->stream, - "%d -1 roll pop\n", - depth); - } - } - cairo_list_del (&surface->operand.link); - } else { - struct deferred_finish *link = malloc (sizeof (*link)); - if (link == NULL) { - status2 = _cairo_error (CAIRO_STATUS_NO_MEMORY); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - cairo_list_del (&surface->operand.link); - } else { - link->operand.type = DEFERRED; - cairo_list_swap (&link->operand.link, - &surface->operand.link); - cairo_list_add (&link->link, &ctx->deferred); - } - } - } - - if (surface->defined) { - _cairo_output_stream_printf (ctx->stream, - "/s%u undef\n", - surface->base.unique_id); - } - } - - if (status == CAIRO_STATUS_SUCCESS) - status = _cairo_output_stream_flush (to_context (surface)->stream); - - cairo_device_release (&ctx->base); - - return status; -} - -static cairo_int_status_t -_cairo_script_surface_copy_page (void *abstract_surface) -{ - cairo_script_surface_t *surface = abstract_surface; - cairo_status_t status; - - status = cairo_device_acquire (surface->base.device); - if (unlikely (status)) - return status; - - status = _emit_context (surface); - if (unlikely (status)) - goto BAIL; - - _cairo_output_stream_puts (to_context (surface)->stream, "copy-page\n"); - -BAIL: - cairo_device_release (surface->base.device); - return status; -} - -static cairo_int_status_t -_cairo_script_surface_show_page (void *abstract_surface) -{ - cairo_script_surface_t *surface = abstract_surface; - cairo_status_t status; - - status = cairo_device_acquire (surface->base.device); - if (unlikely (status)) - return status; - - status = _emit_context (surface); - if (unlikely (status)) - goto BAIL; - - _cairo_output_stream_puts (to_context (surface)->stream, "show-page\n"); - -BAIL: - cairo_device_release (surface->base.device); - return status; -} - -static cairo_status_t -_cairo_script_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper, - cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_script_surface_t *surface = cairo_container_of (clipper, - cairo_script_surface_t, - clipper); - cairo_script_context_t *ctx = to_context (surface); - cairo_bool_t matrix_updated = FALSE; - cairo_status_t status; - cairo_box_t box; - - status = _emit_context (surface); - if (unlikely (status)) - return status; - - if (path == NULL) { - if (surface->cr.has_clip) { - _cairo_output_stream_puts (ctx->stream, "reset-clip\n"); - surface->cr.has_clip = FALSE; - } - return CAIRO_STATUS_SUCCESS; - } - - /* skip the trivial clip covering the surface extents */ - if (surface->width >= 0 && surface->height >= 0 && - _cairo_path_fixed_is_box (path, &box)) - { - if (box.p1.x <= 0 && box.p1.y <= 0 && - box.p2.x >= _cairo_fixed_from_double (surface->width) && - box.p2.y >= _cairo_fixed_from_double (surface->height)) - { - return CAIRO_STATUS_SUCCESS; - } - } - - status = _emit_identity (surface, &matrix_updated); - if (unlikely (status)) - return status; - - status = _emit_fill_rule (surface, fill_rule); - if (unlikely (status)) - return status; - - if (path->has_curve_to) { - status = _emit_tolerance (surface, tolerance, matrix_updated); - if (unlikely (status)) - return status; - } - - if (! _cairo_path_fixed_fill_maybe_region (path)) { - status = _emit_antialias (surface, antialias); - if (unlikely (status)) - return status; - } - - status = _emit_path (surface, path, TRUE); - if (unlikely (status)) - return status; - - _cairo_output_stream_puts (ctx->stream, "clip+\n"); - surface->cr.has_clip = TRUE; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -active (cairo_script_surface_t *surface) -{ - cairo_status_t status; - - status = cairo_device_acquire (surface->base.device); - if (unlikely (status)) - return status; - - if (surface->active++ == 0) - to_context (surface)->active++; - - return CAIRO_STATUS_SUCCESS; -} - -static void -inactive (cairo_script_surface_t *surface) -{ - cairo_script_context_t *ctx = to_context (surface); - cairo_list_t sorted; - - assert (surface->active > 0); - if (--surface->active) - goto DONE; - - assert (ctx->active > 0); - if (--ctx->active) - goto DONE; - - cairo_list_init (&sorted); - while (! cairo_list_is_empty (&ctx->deferred)) { - struct deferred_finish *df; - cairo_list_t *operand; - int depth; - - df = cairo_list_first_entry (&ctx->deferred, - struct deferred_finish, - link); - - depth = 0; - cairo_list_foreach (operand, &ctx->operands) { - if (operand == &df->operand.link) - break; - depth++; - } - - df->operand.type = depth; - - if (cairo_list_is_empty (&sorted)) { - cairo_list_move (&df->link, &sorted); - } else { - struct deferred_finish *pos; - - cairo_list_foreach_entry (pos, struct deferred_finish, - &sorted, - link) - { - if (df->operand.type < pos->operand.type) - break; - } - cairo_list_move_tail (&df->link, &pos->link); - } - } - - while (! cairo_list_is_empty (&sorted)) { - struct deferred_finish *df; - cairo_list_t *operand; - int depth; - - df = cairo_list_first_entry (&sorted, - struct deferred_finish, - link); - - depth = 0; - cairo_list_foreach (operand, &ctx->operands) { - if (operand == &df->operand.link) - break; - depth++; - } - - if (depth == 0) { - _cairo_output_stream_printf (ctx->stream, - "pop\n"); - } else if (depth == 1) { - _cairo_output_stream_printf (ctx->stream, - "exch pop\n"); - } else { - _cairo_output_stream_printf (ctx->stream, - "%d -1 roll pop\n", - depth); - } - - cairo_list_del (&df->operand.link); - cairo_list_del (&df->link); - free (df); - } - -DONE: - cairo_device_release (surface->base.device); -} - -static cairo_int_status_t -_cairo_script_surface_paint (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - cairo_script_surface_t *surface = abstract_surface; - cairo_status_t status; - - status = active (surface); - if (unlikely (status)) - return status; - - status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); - if (unlikely (status)) - goto BAIL; - - status = _emit_context (surface); - if (unlikely (status)) - goto BAIL; - - status = _emit_source (surface, op, source); - if (unlikely (status)) - goto BAIL; - - status = _emit_operator (surface, op); - if (unlikely (status)) - goto BAIL; - - _cairo_output_stream_puts (to_context (surface)->stream, - "paint\n"); - - inactive (surface); - - if (_cairo_surface_wrapper_is_active (&surface->wrapper)) { - return _cairo_surface_wrapper_paint (&surface->wrapper, - op, source, clip); - } - - return CAIRO_STATUS_SUCCESS; - -BAIL: - inactive (surface); - return status; -} - -static cairo_int_status_t -_cairo_script_surface_mask (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - cairo_script_surface_t *surface = abstract_surface; - cairo_status_t status; - - status = active (surface); - if (unlikely (status)) - return status; - - status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); - if (unlikely (status)) - goto BAIL; - - status = _emit_context (surface); - if (unlikely (status)) - goto BAIL; - - status = _emit_source (surface, op, source); - if (unlikely (status)) - goto BAIL; - - status = _emit_operator (surface, op); - if (unlikely (status)) - goto BAIL; - - if (_cairo_pattern_equal (source, mask)) { - _cairo_output_stream_puts (to_context (surface)->stream, "/source get"); - } else { - status = _emit_pattern (surface, mask); - if (unlikely (status)) - goto BAIL; - } - - assert (surface->cr.current_operator == op); - - _cairo_output_stream_puts (to_context (surface)->stream, - " mask\n"); - - inactive (surface); - - if (_cairo_surface_wrapper_is_active (&surface->wrapper)) { - return _cairo_surface_wrapper_mask (&surface->wrapper, - op, source, mask, clip); - } - - return CAIRO_STATUS_SUCCESS; - -BAIL: - inactive (surface); - return status; -} - -static cairo_int_status_t -_cairo_script_surface_stroke (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_script_surface_t *surface = abstract_surface; - cairo_bool_t matrix_updated = FALSE; - cairo_status_t status; - - status = active (surface); - if (unlikely (status)) - return status; - - status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); - if (unlikely (status)) - goto BAIL; - - status = _emit_context (surface); - if (unlikely (status)) - goto BAIL; - - status = _emit_identity (surface, &matrix_updated); - if (unlikely (status)) - goto BAIL; - - status = _emit_path (surface, path, FALSE); - if (unlikely (status)) - goto BAIL; - - status = _emit_source (surface, op, source); - if (unlikely (status)) - goto BAIL; - - status = _emit_scaling_matrix (surface, ctm, &matrix_updated); - if (unlikely (status)) - goto BAIL; - - status = _emit_operator (surface, op); - if (unlikely (status)) - goto BAIL; - - if (_scaling_matrix_equal (&surface->cr.current_ctm, - &surface->cr.current_stroke_matrix)) - { - matrix_updated = FALSE; - } - else - { - matrix_updated = TRUE; - surface->cr.current_stroke_matrix = surface->cr.current_ctm; - } - - status = _emit_stroke_style (surface, style, matrix_updated); - if (unlikely (status)) - goto BAIL; - - status = _emit_tolerance (surface, tolerance, matrix_updated); - if (unlikely (status)) - goto BAIL; - - status = _emit_antialias (surface, antialias); - if (unlikely (status)) - goto BAIL; - - _cairo_output_stream_puts (to_context (surface)->stream, "stroke+\n"); - - inactive (surface); - - if (_cairo_surface_wrapper_is_active (&surface->wrapper)) { - return _cairo_surface_wrapper_stroke (&surface->wrapper, - op, source, path, - style, - ctm, ctm_inverse, - tolerance, antialias, - clip); - } - - return CAIRO_STATUS_SUCCESS; - -BAIL: - inactive (surface); - return status; -} - -static cairo_int_status_t -_cairo_script_surface_fill (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_script_surface_t *surface = abstract_surface; - cairo_bool_t matrix_updated = FALSE; - cairo_status_t status; - cairo_box_t box; - - status = active (surface); - if (unlikely (status)) - return status; - - status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); - if (unlikely (status)) - goto BAIL; - - status = _emit_context (surface); - if (unlikely (status)) - goto BAIL; - - status = _emit_identity (surface, &matrix_updated); - if (unlikely (status)) - goto BAIL; - - status = _emit_source (surface, op, source); - if (unlikely (status)) - goto BAIL; - - if (! _cairo_path_fixed_is_box (path, &box)) { - status = _emit_fill_rule (surface, fill_rule); - if (unlikely (status)) - goto BAIL; - } - - if (path->has_curve_to) { - status = _emit_tolerance (surface, tolerance, matrix_updated); - if (unlikely (status)) - goto BAIL; - } - - if (! _cairo_path_fixed_fill_maybe_region (path)) { - status = _emit_antialias (surface, antialias); - if (unlikely (status)) - goto BAIL; - } - - status = _emit_path (surface, path, TRUE); - if (unlikely (status)) - goto BAIL; - - status = _emit_operator (surface, op); - if (unlikely (status)) - goto BAIL; - - _cairo_output_stream_puts (to_context (surface)->stream, "fill+\n"); - - inactive (surface); - - if (_cairo_surface_wrapper_is_active (&surface->wrapper)) { - return _cairo_surface_wrapper_fill (&surface->wrapper, - op, source, path, - fill_rule, - tolerance, - antialias, - clip); - } - - return CAIRO_STATUS_SUCCESS; - -BAIL: - inactive (surface); - return status; -} - -static cairo_surface_t * -_cairo_script_surface_snapshot (void *abstract_surface) -{ - cairo_script_surface_t *surface = abstract_surface; - - if (_cairo_surface_wrapper_is_active (&surface->wrapper)) - return _cairo_surface_wrapper_snapshot (&surface->wrapper); - - return NULL; -} - -static cairo_bool_t -_cairo_script_surface_has_show_text_glyphs (void *abstract_surface) -{ - return TRUE; -} - -static const char * -_subpixel_order_to_string (cairo_subpixel_order_t subpixel_order) -{ - static const char *names[] = { - "SUBPIXEL_ORDER_DEFAULT", /* CAIRO_SUBPIXEL_ORDER_DEFAULT */ - "SUBPIXEL_ORDER_RGB", /* CAIRO_SUBPIXEL_ORDER_RGB */ - "SUBPIXEL_ORDER_BGR", /* CAIRO_SUBPIXEL_ORDER_BGR */ - "SUBPIXEL_ORDER_VRGB", /* CAIRO_SUBPIXEL_ORDER_VRGB */ - "SUBPIXEL_ORDER_VBGR" /* CAIRO_SUBPIXEL_ORDER_VBGR */ - }; - return names[subpixel_order]; -} -static const char * -_hint_style_to_string (cairo_hint_style_t hint_style) -{ - static const char *names[] = { - "HINT_STYLE_DEFAULT", /* CAIRO_HINT_STYLE_DEFAULT */ - "HINT_STYLE_NONE", /* CAIRO_HINT_STYLE_NONE */ - "HINT_STYLE_SLIGHT", /* CAIRO_HINT_STYLE_SLIGHT */ - "HINT_STYLE_MEDIUM", /* CAIRO_HINT_STYLE_MEDIUM */ - "HINT_STYLE_FULL" /* CAIRO_HINT_STYLE_FULL */ - }; - return names[hint_style]; -} -static const char * -_hint_metrics_to_string (cairo_hint_metrics_t hint_metrics) -{ - static const char *names[] = { - "HINT_METRICS_DEFAULT", /* CAIRO_HINT_METRICS_DEFAULT */ - "HINT_METRICS_OFF", /* CAIRO_HINT_METRICS_OFF */ - "HINT_METRICS_ON" /* CAIRO_HINT_METRICS_ON */ - }; - return names[hint_metrics]; -} - -static cairo_status_t -_emit_font_options (cairo_script_surface_t *surface, - cairo_font_options_t *font_options) -{ - cairo_script_context_t *ctx = to_context (surface); - - if (cairo_font_options_equal (&surface->cr.current_font_options, - font_options)) - { - return CAIRO_STATUS_SUCCESS; - } - - _cairo_output_stream_printf (ctx->stream, "<<"); - - if (font_options->antialias != surface->cr.current_font_options.antialias) { - _cairo_output_stream_printf (ctx->stream, - " /antialias //%s", - _antialias_to_string (font_options->antialias)); - } - - if (font_options->subpixel_order != - surface->cr.current_font_options.subpixel_order) - { - _cairo_output_stream_printf (ctx->stream, - " /subpixel-order //%s", - _subpixel_order_to_string (font_options->subpixel_order)); - } - - if (font_options->hint_style != - surface->cr.current_font_options.hint_style) - { - _cairo_output_stream_printf (ctx->stream, - " /hint-style //%s", - _hint_style_to_string (font_options->hint_style)); - } - - if (font_options->hint_metrics != - surface->cr.current_font_options.hint_metrics) - { - _cairo_output_stream_printf (ctx->stream, - " /hint-metrics //%s", - _hint_metrics_to_string (font_options->hint_metrics)); - } - - _cairo_output_stream_printf (ctx->stream, - " >> set-font-options\n"); - - surface->cr.current_font_options = *font_options; - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_script_scaled_font_fini (cairo_scaled_font_private_t *abstract_private, - cairo_scaled_font_t *scaled_font) -{ - cairo_script_font_t *priv = (cairo_script_font_t *)abstract_private; - cairo_script_context_t *ctx = (cairo_script_context_t *)abstract_private->key; - cairo_status_t status; - - status = cairo_device_acquire (&ctx->base); - if (likely (status == CAIRO_STATUS_SUCCESS)) { - _cairo_output_stream_printf (ctx->stream, - "/f%lu undef /sf%lu undef\n", - priv->id, - priv->id); - - _bitmap_release_id (&ctx->font_id, priv->id); - cairo_device_release (&ctx->base); - } - - cairo_list_del (&priv->link); - cairo_list_del (&priv->base.link); - free (priv); -} - -static cairo_script_font_t * -_cairo_script_font_get (cairo_script_context_t *ctx, cairo_scaled_font_t *font) -{ - return (cairo_script_font_t *) _cairo_scaled_font_find_private (font, ctx); -} - -static long unsigned -_cairo_script_font_id (cairo_script_context_t *ctx, cairo_scaled_font_t *font) -{ - return _cairo_script_font_get (ctx, font)->id; -} - -static cairo_status_t -_emit_type42_font (cairo_script_surface_t *surface, - cairo_scaled_font_t *scaled_font) -{ - cairo_script_context_t *ctx = to_context (surface); - const cairo_scaled_font_backend_t *backend; - cairo_output_stream_t *base85_stream; - cairo_output_stream_t *zlib_stream; - cairo_status_t status, status2; - unsigned long size; - unsigned int load_flags; - uint32_t len; - uint8_t *buf; - - backend = scaled_font->backend; - if (backend->load_truetype_table == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - size = 0; - status = backend->load_truetype_table (scaled_font, 0, 0, NULL, &size); - if (unlikely (status)) - return status; - - buf = malloc (size); - if (unlikely (buf == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - status = backend->load_truetype_table (scaled_font, 0, 0, buf, &size); - if (unlikely (status)) { - free (buf); - return status; - } - -#if CAIRO_HAS_FT_FONT - load_flags = _cairo_ft_scaled_font_get_load_flags (scaled_font); -#else - load_flags = 0; -#endif - _cairo_output_stream_printf (ctx->stream, - "<< " - "/type 42 " - "/index 0 " - "/flags %d " - "/source <|", - load_flags); - - base85_stream = _cairo_base85_stream_create (ctx->stream); - len = to_be32 (size); - _cairo_output_stream_write (base85_stream, &len, sizeof (len)); - - zlib_stream = _cairo_deflate_stream_create (base85_stream); - - _cairo_output_stream_write (zlib_stream, buf, size); - free (buf); - - status2 = _cairo_output_stream_destroy (zlib_stream); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - - status2 = _cairo_output_stream_destroy (base85_stream); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - - _cairo_output_stream_printf (ctx->stream, - "~> >> font dup /f%lu exch def set-font-face", - _cairo_script_font_id (ctx, scaled_font)); - - return status; -} - -static cairo_status_t -_emit_scaled_font_init (cairo_script_surface_t *surface, - cairo_scaled_font_t *scaled_font, - cairo_script_font_t **font_out) -{ - cairo_script_context_t *ctx = to_context (surface); - cairo_script_font_t *font_private; - cairo_int_status_t status; - - font_private = malloc (sizeof (cairo_script_font_t)); - if (unlikely (font_private == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_scaled_font_attach_private (scaled_font, &font_private->base, ctx, - _cairo_script_scaled_font_fini); - - font_private->parent = scaled_font; - font_private->subset_glyph_index = 0; - font_private->has_sfnt = TRUE; - - cairo_list_add (&font_private->link, &ctx->fonts); - - status = _bitmap_next_id (&ctx->font_id, - &font_private->id); - if (unlikely (status)) { - free (font_private); - return status; - } - - status = _emit_context (surface); - if (unlikely (status)) { - free (font_private); - return status; - } - - status = _emit_type42_font (surface, scaled_font); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) { - *font_out = font_private; - return status; - } - - font_private->has_sfnt = FALSE; - _cairo_output_stream_printf (ctx->stream, - "dict\n" - " /type 3 set\n" - " /metrics [%f %f %f %f %f] set\n" - " /glyphs array set\n" - " font dup /f%lu exch def set-font-face", - scaled_font->fs_extents.ascent, - scaled_font->fs_extents.descent, - scaled_font->fs_extents.height, - scaled_font->fs_extents.max_x_advance, - scaled_font->fs_extents.max_y_advance, - font_private->id); - - *font_out = font_private; - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_emit_scaled_font (cairo_script_surface_t *surface, - cairo_scaled_font_t *scaled_font) -{ - cairo_script_context_t *ctx = to_context (surface); - cairo_matrix_t matrix; - cairo_font_options_t options; - cairo_bool_t matrix_updated = FALSE; - cairo_status_t status; - cairo_script_font_t *font_private; - - cairo_scaled_font_get_ctm (scaled_font, &matrix); - status = _emit_scaling_matrix (surface, &matrix, &matrix_updated); - if (unlikely (status)) - return status; - - if (! matrix_updated && surface->cr.current_scaled_font == scaled_font) - return CAIRO_STATUS_SUCCESS; - - surface->cr.current_scaled_font = scaled_font; - - font_private = _cairo_script_font_get (ctx, scaled_font); - if (font_private == NULL) { - cairo_scaled_font_get_font_matrix (scaled_font, &matrix); - status = _emit_font_matrix (surface, &matrix); - if (unlikely (status)) - return status; - - cairo_scaled_font_get_font_options (scaled_font, &options); - status = _emit_font_options (surface, &options); - if (unlikely (status)) - return status; - - status = _emit_scaled_font_init (surface, scaled_font, &font_private); - if (unlikely (status)) - return status; - - assert (target_is_active (surface)); - _cairo_output_stream_printf (ctx->stream, - " /scaled-font get /sf%lu exch def\n", - font_private->id); - } else { - _cairo_output_stream_printf (ctx->stream, - "sf%lu set-scaled-font\n", - font_private->id); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_emit_scaled_glyph_vector (cairo_script_surface_t *surface, - cairo_scaled_font_t *scaled_font, - cairo_script_font_t *font_private, - cairo_scaled_glyph_t *scaled_glyph) -{ - cairo_script_context_t *ctx = to_context (surface); - cairo_script_implicit_context_t old_cr; - cairo_status_t status; - unsigned long index; - - index = ++font_private->subset_glyph_index; - scaled_glyph->dev_private_key = ctx; - scaled_glyph->dev_private = (void *) index; - - _cairo_output_stream_printf (ctx->stream, - "%lu <<\n" - " /metrics [%f %f %f %f %f %f]\n" - " /render {\n", - index, - scaled_glyph->fs_metrics.x_bearing, - scaled_glyph->fs_metrics.y_bearing, - scaled_glyph->fs_metrics.width, - scaled_glyph->fs_metrics.height, - scaled_glyph->fs_metrics.x_advance, - scaled_glyph->fs_metrics.y_advance); - - if (! _cairo_matrix_is_identity (&scaled_font->scale_inverse)) { - _cairo_output_stream_printf (ctx->stream, - "[%f %f %f %f %f %f] transform\n", - scaled_font->scale_inverse.xx, - scaled_font->scale_inverse.yx, - scaled_font->scale_inverse.xy, - scaled_font->scale_inverse.yy, - scaled_font->scale_inverse.x0, - scaled_font->scale_inverse.y0); - } - - old_cr = surface->cr; - _cairo_script_implicit_context_init (&surface->cr); - status = _cairo_recording_surface_replay (scaled_glyph->recording_surface, - &surface->base); - surface->cr = old_cr; - - _cairo_output_stream_puts (ctx->stream, "} >> set\n"); - - return status; -} - -static cairo_status_t -_emit_scaled_glyph_bitmap (cairo_script_surface_t *surface, - cairo_scaled_font_t *scaled_font, - cairo_script_font_t *font_private, - cairo_scaled_glyph_t *scaled_glyph) -{ - cairo_script_context_t *ctx = to_context (surface); - cairo_status_t status; - unsigned long index; - - index = ++font_private->subset_glyph_index; - scaled_glyph->dev_private_key = ctx; - scaled_glyph->dev_private = (void *) index; - - _cairo_output_stream_printf (ctx->stream, - "%lu <<\n" - " /metrics [%f %f %f %f %f %f]\n" - " /render {\n" - "%f %f translate\n", - index, - scaled_glyph->fs_metrics.x_bearing, - scaled_glyph->fs_metrics.y_bearing, - scaled_glyph->fs_metrics.width, - scaled_glyph->fs_metrics.height, - scaled_glyph->fs_metrics.x_advance, - scaled_glyph->fs_metrics.y_advance, - scaled_glyph->fs_metrics.x_bearing, - scaled_glyph->fs_metrics.y_bearing); - - status = _emit_image_surface (surface, scaled_glyph->surface); - if (unlikely (status)) - return status; - - _cairo_output_stream_puts (ctx->stream, "pattern "); - - if (! _cairo_matrix_is_identity (&scaled_font->font_matrix)) { - _cairo_output_stream_printf (ctx->stream, - "\n [%f %f %f %f %f %f] set-matrix\n", - scaled_font->font_matrix.xx, - scaled_font->font_matrix.yx, - scaled_font->font_matrix.xy, - scaled_font->font_matrix.yy, - scaled_font->font_matrix.x0, - scaled_font->font_matrix.y0); - } - _cairo_output_stream_puts (ctx->stream, - "mask\n} >> set\n"); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_emit_scaled_glyph_prologue (cairo_script_surface_t *surface, - cairo_scaled_font_t *scaled_font) -{ - cairo_script_context_t *ctx = to_context (surface); - - _cairo_output_stream_printf (ctx->stream, "f%lu /glyphs get\n", - _cairo_script_font_id (ctx, scaled_font)); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_emit_scaled_glyphs (cairo_script_surface_t *surface, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - unsigned int num_glyphs) -{ - cairo_script_context_t *ctx = to_context (surface); - cairo_script_font_t *font_private; - cairo_status_t status; - unsigned int n; - cairo_bool_t have_glyph_prologue = FALSE; - - if (num_glyphs == 0) - return CAIRO_STATUS_SUCCESS; - - font_private = _cairo_script_font_get (ctx, scaled_font); - if (font_private->has_sfnt) - return CAIRO_STATUS_SUCCESS; - - _cairo_scaled_font_freeze_cache (scaled_font); - for (n = 0; n < num_glyphs; n++) { - cairo_scaled_glyph_t *scaled_glyph; - - status = _cairo_scaled_glyph_lookup (scaled_font, - glyphs[n].index, - CAIRO_SCALED_GLYPH_INFO_METRICS, - &scaled_glyph); - if (unlikely (status)) - break; - - if (scaled_glyph->dev_private_key == ctx) - continue; - - status = _cairo_scaled_glyph_lookup (scaled_font, - glyphs[n].index, - CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE, - &scaled_glyph); - if (_cairo_status_is_error (status)) - break; - - if (status == CAIRO_STATUS_SUCCESS) { - if (! have_glyph_prologue) { - status = _emit_scaled_glyph_prologue (surface, scaled_font); - if (unlikely (status)) - break; - - have_glyph_prologue = TRUE; - } - - status = _emit_scaled_glyph_vector (surface, - scaled_font, font_private, - scaled_glyph); - if (unlikely (status)) - break; - - continue; - } - - status = _cairo_scaled_glyph_lookup (scaled_font, - glyphs[n].index, - CAIRO_SCALED_GLYPH_INFO_SURFACE, - &scaled_glyph); - if (_cairo_status_is_error (status)) - break; - - if (status == CAIRO_STATUS_SUCCESS) { - if (! have_glyph_prologue) { - status = _emit_scaled_glyph_prologue (surface, scaled_font); - if (unlikely (status)) - break; - - have_glyph_prologue = TRUE; - } - - status = _emit_scaled_glyph_bitmap (surface, - scaled_font, - font_private, - scaled_glyph); - if (unlikely (status)) - break; - - continue; - } - } - _cairo_scaled_font_thaw_cache (scaled_font); - - if (have_glyph_prologue) { - _cairo_output_stream_puts (to_context (surface)->stream, "pop pop\n"); - } - - return status; -} - -static void -to_octal (int value, char *buf, size_t size) -{ - do { - buf[--size] = '0' + (value & 7); - value >>= 3; - } while (size); -} - -static void -_emit_string_literal (cairo_script_surface_t *surface, - const char *utf8, int len) -{ - cairo_script_context_t *ctx = to_context (surface); - char c; - const char *end; - - _cairo_output_stream_puts (ctx->stream, "("); - - if (utf8 == NULL) { - end = utf8; - } else { - if (len < 0) - len = strlen (utf8); - end = utf8 + len; - } - - while (utf8 < end) { - switch ((c = *utf8++)) { - case '\n': - c = 'n'; - goto ESCAPED_CHAR; - case '\r': - c = 'r'; - goto ESCAPED_CHAR; - case '\t': - c = 't'; - goto ESCAPED_CHAR; - case '\b': - c = 'b'; - goto ESCAPED_CHAR; - case '\f': - c = 'f'; - goto ESCAPED_CHAR; - case '\\': - case '(': - case ')': -ESCAPED_CHAR: - _cairo_output_stream_printf (ctx->stream, "\\%c", c); - break; - default: - if (isprint (c) || isspace (c)) { - _cairo_output_stream_printf (ctx->stream, "%c", c); - } else { - char buf[4] = { '\\' }; - - to_octal (c, buf+1, 3); - _cairo_output_stream_write (ctx->stream, buf, 4); - } - break; - } - } - _cairo_output_stream_puts (ctx->stream, ")"); -} - -static cairo_int_status_t -_cairo_script_surface_show_text_glyphs (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const char *utf8, - int utf8_len, - cairo_glyph_t *glyphs, - int num_glyphs, - const cairo_text_cluster_t *clusters, - int num_clusters, - cairo_text_cluster_flags_t backward, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - cairo_script_surface_t *surface = abstract_surface; - cairo_script_context_t *ctx = to_context (surface); - cairo_script_font_t *font_private; - cairo_scaled_glyph_t *scaled_glyph; - cairo_matrix_t matrix; - cairo_status_t status; - double x, y, ix, iy; - int n; - cairo_output_stream_t *base85_stream = NULL; - - status = active (surface); - if (unlikely (status)) - return status; - - status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); - if (unlikely (status)) - goto BAIL; - - status = _emit_context (surface); - if (unlikely (status)) - goto BAIL; - - status = _emit_source (surface, op, source); - if (unlikely (status)) - goto BAIL; - - status = _emit_scaled_font (surface, scaled_font); - if (unlikely (status)) - goto BAIL; - - status = _emit_operator (surface, op); - if (unlikely (status)) - goto BAIL; - - status = _emit_scaled_glyphs (surface, scaled_font, glyphs, num_glyphs); - if (unlikely (status)) - goto BAIL; - - /* (utf8) [cx cy [glyphs]] [clusters] backward show_text_glyphs */ - /* [cx cy [glyphs]] show_glyphs */ - - if (utf8 != NULL && clusters != NULL) { - _emit_string_literal (surface, utf8, utf8_len); - _cairo_output_stream_puts (ctx->stream, " "); - } - - matrix = surface->cr.current_ctm; - status = cairo_matrix_invert (&matrix); - assert (status == CAIRO_STATUS_SUCCESS); - - ix = x = glyphs[0].x; - iy = y = glyphs[0].y; - cairo_matrix_transform_point (&matrix, &ix, &iy); - ix -= scaled_font->font_matrix.x0; - iy -= scaled_font->font_matrix.y0; - - _cairo_scaled_font_freeze_cache (scaled_font); - font_private = _cairo_script_font_get (ctx, scaled_font); - - _cairo_output_stream_printf (ctx->stream, - "[%f %f ", - ix, iy); - - for (n = 0; n < num_glyphs; n++) { - if (font_private->has_sfnt) { - if (glyphs[n].index > 256) - break; - } else { - status = _cairo_scaled_glyph_lookup (scaled_font, - glyphs[n].index, - CAIRO_SCALED_GLYPH_INFO_METRICS, - &scaled_glyph); - if (unlikely (status)) { - _cairo_scaled_font_thaw_cache (scaled_font); - goto BAIL; - } - - if ((long unsigned) scaled_glyph->dev_private > 256) - break; - } - } - - if (n == num_glyphs) { - _cairo_output_stream_puts (ctx->stream, "<~"); - base85_stream = _cairo_base85_stream_create (ctx->stream); - } else - _cairo_output_stream_puts (ctx->stream, "["); - - for (n = 0; n < num_glyphs; n++) { - double dx, dy; - - status = _cairo_scaled_glyph_lookup (scaled_font, - glyphs[n].index, - CAIRO_SCALED_GLYPH_INFO_METRICS, - &scaled_glyph); - if (unlikely (status)) { - _cairo_scaled_font_thaw_cache (scaled_font); - goto BAIL; - } - - if (fabs (glyphs[n].x - x) > 1e-5 || fabs (glyphs[n].y - y) > 1e-5) { - if (fabs (glyphs[n].y - y) < 1e-5) { - if (base85_stream != NULL) { - status = _cairo_output_stream_destroy (base85_stream); - if (unlikely (status)) { - base85_stream = NULL; - break; - } - - _cairo_output_stream_printf (ctx->stream, - "~> %f <~", glyphs[n].x - x); - base85_stream = _cairo_base85_stream_create (ctx->stream); - } else { - _cairo_output_stream_printf (ctx->stream, - " ] %f [ ", glyphs[n].x - x); - } - - x = glyphs[n].x; - } else { - ix = x = glyphs[n].x; - iy = y = glyphs[n].y; - cairo_matrix_transform_point (&matrix, &ix, &iy); - ix -= scaled_font->font_matrix.x0; - iy -= scaled_font->font_matrix.y0; - if (base85_stream != NULL) { - status = _cairo_output_stream_destroy (base85_stream); - if (unlikely (status)) { - base85_stream = NULL; - break; - } - - _cairo_output_stream_printf (ctx->stream, - "~> %f %f <~", - ix, iy); - base85_stream = _cairo_base85_stream_create (ctx->stream); - } else { - _cairo_output_stream_printf (ctx->stream, - " ] %f %f [ ", - ix, iy); - } - } - } - if (base85_stream != NULL) { - uint8_t c; - - if (font_private->has_sfnt) - c = glyphs[n].index; - else - c = (uint8_t) (long unsigned) scaled_glyph->dev_private; - - _cairo_output_stream_write (base85_stream, &c, 1); - } else { - if (font_private->has_sfnt) - _cairo_output_stream_printf (ctx->stream, " %lu", - glyphs[n].index); - else - _cairo_output_stream_printf (ctx->stream, " %lu", - (long unsigned) scaled_glyph->dev_private); - } - - dx = scaled_glyph->metrics.x_advance; - dy = scaled_glyph->metrics.y_advance; - cairo_matrix_transform_distance (&scaled_font->ctm, &dx, &dy); - x += dx; - y += dy; - } - _cairo_scaled_font_thaw_cache (scaled_font); - - if (base85_stream != NULL) { - cairo_status_t status2; - - status2 = _cairo_output_stream_destroy (base85_stream); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - - _cairo_output_stream_printf (ctx->stream, "~>"); - } else { - _cairo_output_stream_puts (ctx->stream, " ]"); - } - if (unlikely (status)) - return status; - - if (utf8 != NULL && clusters != NULL) { - for (n = 0; n < num_clusters; n++) { - if (clusters[n].num_bytes > UCHAR_MAX || - clusters[n].num_glyphs > UCHAR_MAX) - { - break; - } - } - - if (n < num_clusters) { - _cairo_output_stream_puts (ctx->stream, "] [ "); - for (n = 0; n < num_clusters; n++) { - _cairo_output_stream_printf (ctx->stream, - "%d %d ", - clusters[n].num_bytes, - clusters[n].num_glyphs); - } - _cairo_output_stream_puts (ctx->stream, "]"); - } - else - { - _cairo_output_stream_puts (ctx->stream, "] <~"); - base85_stream = _cairo_base85_stream_create (ctx->stream); - for (n = 0; n < num_clusters; n++) { - uint8_t c[2]; - c[0] = clusters[n].num_bytes; - c[1] = clusters[n].num_glyphs; - _cairo_output_stream_write (base85_stream, c, 2); - } - status = _cairo_output_stream_destroy (base85_stream); - if (unlikely (status)) - goto BAIL; - - _cairo_output_stream_puts (ctx->stream, "~>"); - } - - _cairo_output_stream_printf (ctx->stream, - " //%s show-text-glyphs\n", - _direction_to_string (backward)); - } else { - _cairo_output_stream_puts (ctx->stream, - "] show-glyphs\n"); - } - - inactive (surface); - - if (_cairo_surface_wrapper_is_active (&surface->wrapper)){ - return _cairo_surface_wrapper_show_text_glyphs (&surface->wrapper, - op, source, - utf8, utf8_len, - glyphs, num_glyphs, - clusters, num_clusters, - backward, - scaled_font, - clip); - } - - return CAIRO_STATUS_SUCCESS; - -BAIL: - inactive (surface); - return status; -} - -static cairo_bool_t -_cairo_script_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *rectangle) -{ - cairo_script_surface_t *surface = abstract_surface; - - if (_cairo_surface_wrapper_is_active (&surface->wrapper)) { - return _cairo_surface_wrapper_get_extents (&surface->wrapper, - rectangle); - } - - if (surface->width < 0 || surface->height < 0) - return FALSE; - - rectangle->x = 0; - rectangle->y = 0; - rectangle->width = surface->width; - rectangle->height = surface->height; - - return TRUE; -} - -static const cairo_surface_backend_t -_cairo_script_surface_backend = { - CAIRO_SURFACE_TYPE_SCRIPT, - _cairo_script_surface_finish, - - _cairo_default_context_create, - - _cairo_script_surface_create_similar, - NULL, /* create similar image */ - NULL, /* map to image */ - NULL, /* unmap image */ - - _cairo_script_surface_source, - _cairo_script_surface_acquire_source_image, - _cairo_script_surface_release_source_image, - _cairo_script_surface_snapshot, - - _cairo_script_surface_copy_page, - _cairo_script_surface_show_page, - - _cairo_script_surface_get_extents, - NULL, /* get_font_options */ - - NULL, /* flush */ - NULL, /* mark_dirty_rectangle */ - - _cairo_script_surface_paint, - _cairo_script_surface_mask, - _cairo_script_surface_stroke, - _cairo_script_surface_fill, - NULL, /* fill/stroke */ - NULL, /* glyphs */ - _cairo_script_surface_has_show_text_glyphs, - _cairo_script_surface_show_text_glyphs -}; - -static void -_cairo_script_implicit_context_init (cairo_script_implicit_context_t *cr) -{ - cr->current_operator = CAIRO_GSTATE_OPERATOR_DEFAULT; - cr->current_fill_rule = CAIRO_GSTATE_FILL_RULE_DEFAULT; - cr->current_tolerance = CAIRO_GSTATE_TOLERANCE_DEFAULT; - cr->current_antialias = CAIRO_ANTIALIAS_DEFAULT; - _cairo_stroke_style_init (&cr->current_style); - _cairo_pattern_init_solid (&cr->current_source.solid, - CAIRO_COLOR_BLACK); - _cairo_path_fixed_init (&cr->current_path); - cairo_matrix_init_identity (&cr->current_ctm); - cairo_matrix_init_identity (&cr->current_stroke_matrix); - cairo_matrix_init_identity (&cr->current_font_matrix); - _cairo_font_options_init_default (&cr->current_font_options); - cr->current_scaled_font = NULL; - cr->has_clip = FALSE; -} - -static void -_cairo_script_implicit_context_reset (cairo_script_implicit_context_t *cr) -{ - free (cr->current_style.dash); - cr->current_style.dash = NULL; - - _cairo_pattern_fini (&cr->current_source.base); - _cairo_path_fixed_fini (&cr->current_path); - - _cairo_script_implicit_context_init (cr); -} - -static cairo_script_surface_t * -_cairo_script_surface_create_internal (cairo_script_context_t *ctx, - cairo_content_t content, - cairo_rectangle_t *extents, - cairo_surface_t *passthrough) -{ - cairo_script_surface_t *surface; - - if (unlikely (ctx == NULL)) - return (cairo_script_surface_t *) _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NULL_POINTER)); - - surface = malloc (sizeof (cairo_script_surface_t)); - if (unlikely (surface == NULL)) - return (cairo_script_surface_t *) _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - _cairo_surface_init (&surface->base, - &_cairo_script_surface_backend, - &ctx->base, - content); - - _cairo_surface_wrapper_init (&surface->wrapper, passthrough); - - _cairo_surface_clipper_init (&surface->clipper, - _cairo_script_surface_clipper_intersect_clip_path); - - surface->width = surface->height = -1; - if (extents) { - surface->width = extents->width; - surface->height = extents->height; - cairo_surface_set_device_offset (&surface->base, - -extents->x, -extents->y); - } - - surface->emitted = FALSE; - surface->defined = FALSE; - surface->active = FALSE; - surface->operand.type = SURFACE; - cairo_list_init (&surface->operand.link); - - _cairo_script_implicit_context_init (&surface->cr); - - return surface; -} - -static const cairo_device_backend_t _cairo_script_device_backend = { - CAIRO_DEVICE_TYPE_SCRIPT, - - NULL, NULL, /* lock, unlock */ - - _device_flush, /* flush */ - NULL, /* finish */ - _device_destroy -}; - -cairo_device_t * -_cairo_script_context_create_internal (cairo_output_stream_t *stream) -{ - cairo_script_context_t *ctx; - - ctx = malloc (sizeof (cairo_script_context_t)); - if (unlikely (ctx == NULL)) - return _cairo_device_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - memset (ctx, 0, sizeof (cairo_script_context_t)); - - _cairo_device_init (&ctx->base, &_cairo_script_device_backend); - - cairo_list_init (&ctx->operands); - cairo_list_init (&ctx->deferred); - ctx->stream = stream; - ctx->mode = CAIRO_SCRIPT_MODE_ASCII; - - cairo_list_init (&ctx->fonts); - cairo_list_init (&ctx->defines); - - ctx->attach_snapshots = TRUE; - - return &ctx->base; -} - -void -_cairo_script_context_attach_snapshots (cairo_device_t *device, - cairo_bool_t enable) -{ - cairo_script_context_t *ctx; - - ctx = (cairo_script_context_t *) device; - ctx->attach_snapshots = enable; -} - -static cairo_device_t * -_cairo_script_context_create (cairo_output_stream_t *stream) -{ - cairo_script_context_t *ctx; - - ctx = (cairo_script_context_t *) - _cairo_script_context_create_internal (stream); - if (unlikely (ctx->base.status)) - return &ctx->base; - - ctx->owns_stream = TRUE; - _cairo_output_stream_puts (ctx->stream, "%!CairoScript\n"); - return &ctx->base; -} - -/** - * cairo_script_create: - * @filename: the name (path) of the file to write the script to - * - * Creates a output device for emitting the script, used when - * creating the individual surfaces. - * - * Return value: a pointer to the newly created device. The caller - * owns the surface and should call cairo_device_destroy() when done - * with it. - * - * This function always returns a valid pointer, but it will return a - * pointer to a "nil" device if an error such as out of memory - * occurs. You can use cairo_device_status() to check for this. - * - * Since: 1.12 - **/ -cairo_device_t * -cairo_script_create (const char *filename) -{ - cairo_output_stream_t *stream; - cairo_status_t status; - - stream = _cairo_output_stream_create_for_filename (filename); - if ((status = _cairo_output_stream_get_status (stream))) - return _cairo_device_create_in_error (status); - - return _cairo_script_context_create (stream); -} - -/** - * cairo_script_create_for_stream: - * @write_func: callback function passed the bytes written to the script - * @closure: user data to be passed to the callback - * - * Creates a output device for emitting the script, used when - * creating the individual surfaces. - * - * Return value: a pointer to the newly created device. The caller - * owns the surface and should call cairo_device_destroy() when done - * with it. - * - * This function always returns a valid pointer, but it will return a - * pointer to a "nil" device if an error such as out of memory - * occurs. You can use cairo_device_status() to check for this. - * - * Since: 1.12 - **/ -cairo_device_t * -cairo_script_create_for_stream (cairo_write_func_t write_func, - void *closure) -{ - cairo_output_stream_t *stream; - cairo_status_t status; - - stream = _cairo_output_stream_create (write_func, NULL, closure); - if ((status = _cairo_output_stream_get_status (stream))) - return _cairo_device_create_in_error (status); - - return _cairo_script_context_create (stream); -} - -/** - * cairo_script_write_comment: - * @script: the script (output device) - * @comment: the string to emit - * @len:the length of the sting to write, or -1 to use strlen() - * - * Emit a string verbatim into the script. - * - * Since: 1.12 - **/ -void -cairo_script_write_comment (cairo_device_t *script, - const char *comment, - int len) -{ - cairo_script_context_t *context = (cairo_script_context_t *) script; - - if (len < 0) - len = strlen (comment); - - _cairo_output_stream_puts (context->stream, "% "); - _cairo_output_stream_write (context->stream, comment, len); - _cairo_output_stream_puts (context->stream, "\n"); -} - -/** - * cairo_script_set_mode: - * @script: The script (output device) - * @mode: the new mode - * - * Change the output mode of the script - * - * Since: 1.12 - **/ -void -cairo_script_set_mode (cairo_device_t *script, - cairo_script_mode_t mode) -{ - cairo_script_context_t *context = (cairo_script_context_t *) script; - - context->mode = mode; -} - -/** - * cairo_script_get_mode: - * @script: The script (output device) to query - * - * Queries the script for its current output mode. - * - * Return value: the current output mode of the script - * - * Since: 1.12 - **/ -cairo_script_mode_t -cairo_script_get_mode (cairo_device_t *script) -{ - cairo_script_context_t *context = (cairo_script_context_t *) script; - - return context->mode; -} - -/** - * cairo_script_surface_create: - * @script: the script (output device) - * @content: the content of the surface - * @width: width in pixels - * @height: height in pixels - * - * Create a new surface that will emit its rendering through @script - * - * Return value: a pointer to the newly created surface. The caller - * owns the surface and should call cairo_surface_destroy() when done - * with it. - * - * This function always returns a valid pointer, but it will return a - * pointer to a "nil" surface if an error such as out of memory - * occurs. You can use cairo_surface_status() to check for this. - * - * Since: 1.12 - **/ -cairo_surface_t * -cairo_script_surface_create (cairo_device_t *script, - cairo_content_t content, - double width, - double height) -{ - cairo_rectangle_t *extents, r; - - if (unlikely (script->backend->type != CAIRO_DEVICE_TYPE_SCRIPT)) - return _cairo_surface_create_in_error (CAIRO_STATUS_DEVICE_TYPE_MISMATCH); - - if (unlikely (script->status)) - return _cairo_surface_create_in_error (script->status); - - extents = NULL; - if (width > 0 && height > 0) { - r.x = r.y = 0; - r.width = width; - r.height = height; - extents = &r; - } - return &_cairo_script_surface_create_internal ((cairo_script_context_t *) script, - content, extents, - NULL)->base; -} -slim_hidden_def (cairo_script_surface_create); - -/** - * cairo_script_surface_create_for_target: - * @script: the script (output device) - * @target: a target surface to wrap - * - * Create a pxoy surface that will render to @target and record - * the operations to @device. - * - * Return value: a pointer to the newly created surface. The caller - * owns the surface and should call cairo_surface_destroy() when done - * with it. - * - * This function always returns a valid pointer, but it will return a - * pointer to a "nil" surface if an error such as out of memory - * occurs. You can use cairo_surface_status() to check for this. - * - * Since: 1.12 - **/ -cairo_surface_t * -cairo_script_surface_create_for_target (cairo_device_t *script, - cairo_surface_t *target) -{ - cairo_rectangle_int_t extents; - cairo_rectangle_t rect, *r; - - if (unlikely (script->backend->type != CAIRO_DEVICE_TYPE_SCRIPT)) - return _cairo_surface_create_in_error (CAIRO_STATUS_DEVICE_TYPE_MISMATCH); - - if (unlikely (script->status)) - return _cairo_surface_create_in_error (script->status); - - if (unlikely (target->status)) - return _cairo_surface_create_in_error (target->status); - - r = NULL; - if (_cairo_surface_get_extents (target, &extents)) { - rect.x = rect.y = 0; - rect.width = extents.width; - rect.height = extents.height; - r= ▭ - } - return &_cairo_script_surface_create_internal ((cairo_script_context_t *) script, - target->content, r, - target)->base; -} - -/** - * cairo_script_from_recording_surface: - * @script: the script (output device) - * @recording_surface: the recording surface to replay - * - * Converts the record operations in @recording_surface into a script. - * - * Return value: #CAIRO_STATUS_SUCCESS on successful completion or an error code. - * - * Since: 1.12 - **/ -cairo_status_t -cairo_script_from_recording_surface (cairo_device_t *script, - cairo_surface_t *recording_surface) -{ - cairo_rectangle_t r, *extents; - cairo_surface_t *surface; - cairo_status_t status; - - if (unlikely (script->backend->type != CAIRO_DEVICE_TYPE_SCRIPT)) - return _cairo_error (CAIRO_STATUS_DEVICE_TYPE_MISMATCH); - - if (unlikely (script->status)) - return _cairo_error (script->status); - - if (unlikely (recording_surface->status)) - return recording_surface->status; - - if (unlikely (! _cairo_surface_is_recording (recording_surface))) - return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - - extents = NULL; - if (_cairo_recording_surface_get_bounds (recording_surface, &r)) - extents = &r; - - surface = &_cairo_script_surface_create_internal ((cairo_script_context_t *) script, - recording_surface->content, - extents, - NULL)->base; - if (unlikely (surface->status)) - return surface->status; - - status = _cairo_recording_surface_replay (recording_surface, surface); - cairo_surface_destroy (surface); - - return status; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-script.h b/source/libs/cairo/cairo-src/src/cairo-script.h deleted file mode 100644 index b5a8cf32d0b633f4a4347d4a46ff7e6a32f91492..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-script.h +++ /dev/null @@ -1,98 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2008 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Chris Wilson - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_SCRIPT_H -#define CAIRO_SCRIPT_H - -#include "cairo.h" - -#if CAIRO_HAS_SCRIPT_SURFACE - -CAIRO_BEGIN_DECLS - -/** - * cairo_script_mode_t: - * @CAIRO_SCRIPT_MODE_ASCII: the output will be in readable text (default). (Since 1.12) - * @CAIRO_SCRIPT_MODE_BINARY: the output will use byte codes. (Since 1.12) - * - * A set of script output variants. - * - * Since: 1.12 - **/ -typedef enum { - CAIRO_SCRIPT_MODE_ASCII, - CAIRO_SCRIPT_MODE_BINARY -} cairo_script_mode_t; - -cairo_public cairo_device_t * -cairo_script_create (const char *filename); - -cairo_public cairo_device_t * -cairo_script_create_for_stream (cairo_write_func_t write_func, - void *closure); - -cairo_public void -cairo_script_write_comment (cairo_device_t *script, - const char *comment, - int len); - -cairo_public void -cairo_script_set_mode (cairo_device_t *script, - cairo_script_mode_t mode); - -cairo_public cairo_script_mode_t -cairo_script_get_mode (cairo_device_t *script); - -cairo_public cairo_surface_t * -cairo_script_surface_create (cairo_device_t *script, - cairo_content_t content, - double width, - double height); - -cairo_public cairo_surface_t * -cairo_script_surface_create_for_target (cairo_device_t *script, - cairo_surface_t *target); - -cairo_public cairo_status_t -cairo_script_from_recording_surface (cairo_device_t *script, - cairo_surface_t *recording_surface); - -CAIRO_END_DECLS - -#else /*CAIRO_HAS_SCRIPT_SURFACE*/ -# error Cairo was not compiled with support for the CairoScript backend -#endif /*CAIRO_HAS_SCRIPT_SURFACE*/ - -#endif /*CAIRO_SCRIPT_H*/ diff --git a/source/libs/cairo/cairo-src/src/cairo-shape-mask-compositor.c b/source/libs/cairo/cairo-src/src/cairo-shape-mask-compositor.c deleted file mode 100644 index 3117267cccf13303d0c1065b4aa2e28d4c870412..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-shape-mask-compositor.c +++ /dev/null @@ -1,340 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2012 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-compositor-private.h" -#include "cairo-clip-private.h" -#include "cairo-pattern-private.h" -#include "cairo-surface-private.h" -#include "cairo-surface-offset-private.h" - -static cairo_int_status_t -_cairo_shape_mask_compositor_stroke (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_surface_t *mask; - cairo_surface_pattern_t pattern; - cairo_int_status_t status; - cairo_clip_t *clip; - - if (! extents->is_bounded) - return CAIRO_INT_STATUS_UNSUPPORTED; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - mask = _cairo_surface_create_scratch (extents->surface, - CAIRO_CONTENT_ALPHA, - extents->bounded.width, - extents->bounded.height, - NULL); - if (unlikely (mask->status)) - return mask->status; - - clip = extents->clip; - if (! _cairo_clip_is_region (clip)) - clip = _cairo_clip_copy_region (clip); - - if (! mask->is_clear) { - status = _cairo_surface_offset_paint (mask, - extents->bounded.x, - extents->bounded.y, - CAIRO_OPERATOR_CLEAR, - &_cairo_pattern_clear.base, - clip); - if (unlikely (status)) - goto error; - } - - status = _cairo_surface_offset_stroke (mask, - extents->bounded.x, - extents->bounded.y, - CAIRO_OPERATOR_ADD, - &_cairo_pattern_white.base, - path, style, ctm, ctm_inverse, - tolerance, antialias, - clip); - if (unlikely (status)) - goto error; - - if (clip != extents->clip) { - status = _cairo_clip_combine_with_surface (extents->clip, mask, - extents->bounded.x, - extents->bounded.y); - if (unlikely (status)) - goto error; - } - - _cairo_pattern_init_for_surface (&pattern, mask); - cairo_matrix_init_translate (&pattern.base.matrix, - -extents->bounded.x, - -extents->bounded.y); - pattern.base.filter = CAIRO_FILTER_NEAREST; - pattern.base.extend = CAIRO_EXTEND_NONE; - if (extents->op == CAIRO_OPERATOR_SOURCE) { - status = _cairo_surface_mask (extents->surface, - CAIRO_OPERATOR_DEST_OUT, - &_cairo_pattern_white.base, - &pattern.base, - clip); - if ((status == CAIRO_INT_STATUS_SUCCESS)) { - status = _cairo_surface_mask (extents->surface, - CAIRO_OPERATOR_ADD, - &extents->source_pattern.base, - &pattern.base, - clip); - } - } else { - status = _cairo_surface_mask (extents->surface, - extents->op, - &extents->source_pattern.base, - &pattern.base, - clip); - } - _cairo_pattern_fini (&pattern.base); - -error: - cairo_surface_destroy (mask); - if (clip != extents->clip) - _cairo_clip_destroy (clip); - return status; -} - -static cairo_int_status_t -_cairo_shape_mask_compositor_fill (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_surface_t *mask; - cairo_surface_pattern_t pattern; - cairo_int_status_t status; - cairo_clip_t *clip; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - if (! extents->is_bounded) - return CAIRO_INT_STATUS_UNSUPPORTED; - - mask = _cairo_surface_create_scratch (extents->surface, - CAIRO_CONTENT_ALPHA, - extents->bounded.width, - extents->bounded.height, - NULL); - if (unlikely (mask->status)) - return mask->status; - - clip = extents->clip; - if (! _cairo_clip_is_region (clip)) - clip = _cairo_clip_copy_region (clip); - - if (! mask->is_clear) { - status = _cairo_surface_offset_paint (mask, - extents->bounded.x, - extents->bounded.y, - CAIRO_OPERATOR_CLEAR, - &_cairo_pattern_clear.base, - clip); - if (unlikely (status)) - goto error; - } - - status = _cairo_surface_offset_fill (mask, - extents->bounded.x, - extents->bounded.y, - CAIRO_OPERATOR_ADD, - &_cairo_pattern_white.base, - path, fill_rule, tolerance, antialias, - clip); - if (unlikely (status)) - goto error; - - if (clip != extents->clip) { - status = _cairo_clip_combine_with_surface (extents->clip, mask, - extents->bounded.x, - extents->bounded.y); - if (unlikely (status)) - goto error; - } - - _cairo_pattern_init_for_surface (&pattern, mask); - cairo_matrix_init_translate (&pattern.base.matrix, - -extents->bounded.x, - -extents->bounded.y); - pattern.base.filter = CAIRO_FILTER_NEAREST; - pattern.base.extend = CAIRO_EXTEND_NONE; - if (extents->op == CAIRO_OPERATOR_SOURCE) { - status = _cairo_surface_mask (extents->surface, - CAIRO_OPERATOR_DEST_OUT, - &_cairo_pattern_white.base, - &pattern.base, - clip); - if ((status == CAIRO_INT_STATUS_SUCCESS)) { - status = _cairo_surface_mask (extents->surface, - CAIRO_OPERATOR_ADD, - &extents->source_pattern.base, - &pattern.base, - clip); - } - } else { - status = _cairo_surface_mask (extents->surface, - extents->op, - &extents->source_pattern.base, - &pattern.base, - clip); - } - _cairo_pattern_fini (&pattern.base); - -error: - if (clip != extents->clip) - _cairo_clip_destroy (clip); - cairo_surface_destroy (mask); - return status; -} - -static cairo_int_status_t -_cairo_shape_mask_compositor_glyphs (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_bool_t overlap) -{ - cairo_surface_t *mask; - cairo_surface_pattern_t pattern; - cairo_int_status_t status; - cairo_clip_t *clip; - - if (! extents->is_bounded) - return CAIRO_INT_STATUS_UNSUPPORTED; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - mask = _cairo_surface_create_scratch (extents->surface, - CAIRO_CONTENT_ALPHA, - extents->bounded.width, - extents->bounded.height, - NULL); - if (unlikely (mask->status)) - return mask->status; - - clip = extents->clip; - if (! _cairo_clip_is_region (clip)) - clip = _cairo_clip_copy_region (clip); - - if (! mask->is_clear) { - status = _cairo_surface_offset_paint (mask, - extents->bounded.x, - extents->bounded.y, - CAIRO_OPERATOR_CLEAR, - &_cairo_pattern_clear.base, - clip); - if (unlikely (status)) - goto error; - } - - status = _cairo_surface_offset_glyphs (mask, - extents->bounded.x, - extents->bounded.y, - CAIRO_OPERATOR_ADD, - &_cairo_pattern_white.base, - scaled_font, glyphs, num_glyphs, - clip); - if (unlikely (status)) - goto error; - - if (clip != extents->clip) { - status = _cairo_clip_combine_with_surface (extents->clip, mask, - extents->bounded.x, - extents->bounded.y); - if (unlikely (status)) - goto error; - } - - _cairo_pattern_init_for_surface (&pattern, mask); - cairo_matrix_init_translate (&pattern.base.matrix, - -extents->bounded.x, - -extents->bounded.y); - pattern.base.filter = CAIRO_FILTER_NEAREST; - pattern.base.extend = CAIRO_EXTEND_NONE; - if (extents->op == CAIRO_OPERATOR_SOURCE) { - status = _cairo_surface_mask (extents->surface, - CAIRO_OPERATOR_DEST_OUT, - &_cairo_pattern_white.base, - &pattern.base, - clip); - if ((status == CAIRO_INT_STATUS_SUCCESS)) { - status = _cairo_surface_mask (extents->surface, - CAIRO_OPERATOR_ADD, - &extents->source_pattern.base, - &pattern.base, - clip); - } - } else { - status = _cairo_surface_mask (extents->surface, - extents->op, - &extents->source_pattern.base, - &pattern.base, - clip); - } - _cairo_pattern_fini (&pattern.base); - -error: - if (clip != extents->clip) - _cairo_clip_destroy (clip); - cairo_surface_destroy (mask); - return status; -} - -void -_cairo_shape_mask_compositor_init (cairo_compositor_t *compositor, - const cairo_compositor_t *delegate) -{ - compositor->delegate = delegate; - - compositor->paint = NULL; - compositor->mask = NULL; - compositor->fill = _cairo_shape_mask_compositor_fill; - compositor->stroke = _cairo_shape_mask_compositor_stroke; - compositor->glyphs = _cairo_shape_mask_compositor_glyphs; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-skia.h b/source/libs/cairo/cairo-src/src/cairo-skia.h deleted file mode 100644 index 99b92865699086742f35c7f089fc66949b354d7a..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-skia.h +++ /dev/null @@ -1,66 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - */ - -#ifndef CAIRO_SKIA_H -#define CAIRO_SKIA_H - -#include "cairo.h" - -#if CAIRO_HAS_SKIA_SURFACE - -CAIRO_BEGIN_DECLS - -cairo_public cairo_surface_t * -cairo_skia_surface_create (cairo_format_t format, - int width, - int height); - -cairo_public cairo_surface_t * -cairo_skia_surface_create_for_data (unsigned char *data, - cairo_format_t format, - int width, - int height, - int stride); - -CAIRO_END_DECLS - -#else - -# error Cairo was not compiled with support for the Skia backend - -#endif - -#endif diff --git a/source/libs/cairo/cairo-src/src/cairo-slope-private.h b/source/libs/cairo/cairo-src/src/cairo-slope-private.h deleted file mode 100644 index 6a58c9f456d66b8cd8c91c9cf12859e3062a5678..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-slope-private.h +++ /dev/null @@ -1,72 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - */ - -#ifndef _CAIRO_SLOPE_PRIVATE_H -#define _CAIRO_SLOPE_PRIVATE_H - -#include "cairo-types-private.h" -#include "cairo-fixed-private.h" - -static inline void -_cairo_slope_init (cairo_slope_t *slope, - const cairo_point_t *a, - const cairo_point_t *b) -{ - slope->dx = b->x - a->x; - slope->dy = b->y - a->y; -} - -static inline cairo_bool_t -_cairo_slope_equal (const cairo_slope_t *a, const cairo_slope_t *b) -{ - return _cairo_int64_eq (_cairo_int32x32_64_mul (a->dy, b->dx), - _cairo_int32x32_64_mul (b->dy, a->dx)); -} - -static inline cairo_bool_t -_cairo_slope_backwards (const cairo_slope_t *a, const cairo_slope_t *b) -{ - return _cairo_int64_negative (_cairo_int64_add (_cairo_int32x32_64_mul (a->dx, b->dx), - _cairo_int32x32_64_mul (a->dy, b->dy))); -} - -cairo_private int -_cairo_slope_compare (const cairo_slope_t *a, - const cairo_slope_t *b) cairo_pure; - - -#endif /* _CAIRO_SLOPE_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-slope.c b/source/libs/cairo/cairo-src/src/cairo-slope.c deleted file mode 100644 index cc5f30cb0b3996abf9defdb52052d1d5524b59fd..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-slope.c +++ /dev/null @@ -1,99 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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" - -#include "cairo-slope-private.h" - -/* Compare two slopes. Slope angles begin at 0 in the direction of the - positive X axis and increase in the direction of the positive Y - axis. - - This function always compares the slope vectors based on the - smaller angular difference between them, (that is based on an - angular difference that is strictly less than pi). To break ties - when comparing slope vectors with an angular difference of exactly - pi, the vector with a positive dx (or positive dy if dx's are zero) - is considered to be more positive than the other. - - Also, all slope vectors with both dx==0 and dy==0 are considered - equal and more positive than any non-zero vector. - - < 0 => a less positive than b - == 0 => a equal to b - > 0 => a more positive than b -*/ -int -_cairo_slope_compare (const cairo_slope_t *a, const cairo_slope_t *b) -{ - cairo_int64_t ady_bdx = _cairo_int32x32_64_mul (a->dy, b->dx); - cairo_int64_t bdy_adx = _cairo_int32x32_64_mul (b->dy, a->dx); - int cmp; - - cmp = _cairo_int64_cmp (ady_bdx, bdy_adx); - if (cmp) - return cmp; - - /* special-case zero vectors. the intended logic here is: - * zero vectors all compare equal, and more positive than any - * non-zero vector. - */ - if (a->dx == 0 && a->dy == 0 && b->dx == 0 && b->dy ==0) - return 0; - if (a->dx == 0 && a->dy == 0) - return 1; - if (b->dx == 0 && b->dy ==0) - return -1; - - /* Finally, we're looking at two vectors that are either equal or - * that differ by exactly pi. We can identify the "differ by pi" - * case by looking for a change in sign in either dx or dy between - * a and b. - * - * And in these cases, we eliminate the ambiguity by reducing the angle - * of b by an infinitesimally small amount, (that is, 'a' will - * always be considered less than 'b'). - */ - if ((a->dx ^ b->dx) < 0 || (a->dy ^ b->dy) < 0) { - if (a->dx > 0 || (a->dx == 0 && a->dy > 0)) - return -1; - else - return +1; - } - - /* Finally, for identical slopes, we obviously return 0. */ - return 0; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-spans-compositor-private.h b/source/libs/cairo/cairo-src/src/cairo-spans-compositor-private.h deleted file mode 100644 index 0babebd26b582689776930547a876b9c928ccbea..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-spans-compositor-private.h +++ /dev/null @@ -1,111 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_SPANS_COMPOSITOR_PRIVATE_H -#define CAIRO_SPANS_COMPOSITOR_PRIVATE_H - -#include "cairo-compositor-private.h" -#include "cairo-types-private.h" -#include "cairo-spans-private.h" - -CAIRO_BEGIN_DECLS - -typedef struct _cairo_abstract_span_renderer { - cairo_span_renderer_t base; - char data[4096]; -} cairo_abstract_span_renderer_t; - -struct cairo_spans_compositor { - cairo_compositor_t base; - - unsigned int flags; -#define CAIRO_SPANS_COMPOSITOR_HAS_LERP 0x1 - - /* pixel-aligned fast paths */ - cairo_int_status_t (*fill_boxes) (void *surface, - cairo_operator_t op, - const cairo_color_t *color, - cairo_boxes_t *boxes); - - cairo_int_status_t (*draw_image_boxes) (void *surface, - cairo_image_surface_t *image, - cairo_boxes_t *boxes, - int dx, int dy); - - cairo_int_status_t (*copy_boxes) (void *surface, - cairo_surface_t *src, - cairo_boxes_t *boxes, - const cairo_rectangle_int_t *extents, - int dx, int dy); - - cairo_surface_t * (*pattern_to_surface) (cairo_surface_t *dst, - const cairo_pattern_t *pattern, - cairo_bool_t is_mask, - const cairo_rectangle_int_t *extents, - const cairo_rectangle_int_t *sample, - int *src_x, int *src_y); - - cairo_int_status_t (*composite_boxes) (void *surface, - cairo_operator_t op, - cairo_surface_t *source, - cairo_surface_t *mask, - int src_x, - int src_y, - int mask_x, - int mask_y, - int dst_x, - int dst_y, - cairo_boxes_t *boxes, - const cairo_rectangle_int_t *extents); - - /* general shape masks using a span renderer */ - cairo_int_status_t (*renderer_init) (cairo_abstract_span_renderer_t *renderer, - const cairo_composite_rectangles_t *extents, - cairo_antialias_t antialias, - cairo_bool_t needs_clip); - - void (*renderer_fini) (cairo_abstract_span_renderer_t *renderer, - cairo_int_status_t status); -}; - -cairo_private void -_cairo_spans_compositor_init (cairo_spans_compositor_t *compositor, - const cairo_compositor_t *delegate); - -CAIRO_END_DECLS - -#endif /* CAIRO_SPANS_COMPOSITOR_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-spans-compositor.c b/source/libs/cairo/cairo-src/src/cairo-spans-compositor.c deleted file mode 100644 index efbae254bf4829a93ac15242be3469e9fc2e5320..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-spans-compositor.c +++ /dev/null @@ -1,1201 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Joonas Pihlaja <jpihlaja@cc.helsinki.fi> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-compositor-private.h" -#include "cairo-clip-inline.h" -#include "cairo-clip-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-paginated-private.h" -#include "cairo-pattern-inline.h" -#include "cairo-region-private.h" -#include "cairo-recording-surface-inline.h" -#include "cairo-spans-compositor-private.h" -#include "cairo-surface-subsurface-private.h" -#include "cairo-surface-snapshot-private.h" -#include "cairo-surface-observer-private.h" - -typedef struct { - cairo_polygon_t *polygon; - cairo_fill_rule_t fill_rule; - cairo_antialias_t antialias; -} composite_spans_info_t; - -static cairo_int_status_t -composite_polygon (const cairo_spans_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - cairo_polygon_t *polygon, - cairo_fill_rule_t fill_rule, - cairo_antialias_t antialias); - -static cairo_int_status_t -composite_boxes (const cairo_spans_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - cairo_boxes_t *boxes); - -static cairo_int_status_t -clip_and_composite_polygon (const cairo_spans_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - cairo_polygon_t *polygon, - cairo_fill_rule_t fill_rule, - cairo_antialias_t antialias); -static cairo_surface_t * -get_clip_surface (const cairo_spans_compositor_t *compositor, - cairo_surface_t *dst, - const cairo_clip_t *clip, - const cairo_rectangle_int_t *extents) -{ - cairo_composite_rectangles_t composite; - cairo_surface_t *surface; - cairo_box_t box; - cairo_polygon_t polygon; - const cairo_clip_path_t *clip_path; - cairo_antialias_t antialias; - cairo_fill_rule_t fill_rule; - cairo_int_status_t status; - - assert (clip->path); - - surface = _cairo_surface_create_scratch (dst, - CAIRO_CONTENT_ALPHA, - extents->width, - extents->height, - CAIRO_COLOR_TRANSPARENT); - - _cairo_box_from_rectangle (&box, extents); - _cairo_polygon_init (&polygon, &box, 1); - - clip_path = clip->path; - status = _cairo_path_fixed_fill_to_polygon (&clip_path->path, - clip_path->tolerance, - &polygon); - if (unlikely (status)) - goto cleanup_polygon; - - polygon.num_limits = 0; - - antialias = clip_path->antialias; - fill_rule = clip_path->fill_rule; - - if (clip->boxes) { - cairo_polygon_t intersect; - cairo_boxes_t tmp; - - _cairo_boxes_init_for_array (&tmp, clip->boxes, clip->num_boxes); - status= _cairo_polygon_init_boxes (&intersect, &tmp); - if (unlikely (status)) - goto cleanup_polygon; - - status = _cairo_polygon_intersect (&polygon, fill_rule, - &intersect, CAIRO_FILL_RULE_WINDING); - _cairo_polygon_fini (&intersect); - - if (unlikely (status)) - goto cleanup_polygon; - - fill_rule = CAIRO_FILL_RULE_WINDING; - } - - polygon.limits = NULL; - polygon.num_limits = 0; - - clip_path = clip_path->prev; - while (clip_path) { - if (clip_path->antialias == antialias) { - cairo_polygon_t next; - - _cairo_polygon_init (&next, NULL, 0); - status = _cairo_path_fixed_fill_to_polygon (&clip_path->path, - clip_path->tolerance, - &next); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) - status = _cairo_polygon_intersect (&polygon, fill_rule, - &next, clip_path->fill_rule); - _cairo_polygon_fini (&next); - if (unlikely (status)) - goto cleanup_polygon; - - fill_rule = CAIRO_FILL_RULE_WINDING; - } - - clip_path = clip_path->prev; - } - - _cairo_polygon_translate (&polygon, -extents->x, -extents->y); - status = _cairo_composite_rectangles_init_for_polygon (&composite, surface, - CAIRO_OPERATOR_ADD, - &_cairo_pattern_white.base, - &polygon, - NULL); - if (unlikely (status)) - goto cleanup_polygon; - - status = composite_polygon (compositor, &composite, - &polygon, fill_rule, antialias); - _cairo_composite_rectangles_fini (&composite); - _cairo_polygon_fini (&polygon); - if (unlikely (status)) - goto error; - - _cairo_polygon_init (&polygon, &box, 1); - - clip_path = clip->path; - antialias = clip_path->antialias == CAIRO_ANTIALIAS_DEFAULT ? CAIRO_ANTIALIAS_NONE : CAIRO_ANTIALIAS_DEFAULT; - clip_path = clip_path->prev; - while (clip_path) { - if (clip_path->antialias == antialias) { - if (polygon.num_edges == 0) { - status = _cairo_path_fixed_fill_to_polygon (&clip_path->path, - clip_path->tolerance, - &polygon); - - fill_rule = clip_path->fill_rule; - polygon.limits = NULL; - polygon.num_limits = 0; - } else { - cairo_polygon_t next; - - _cairo_polygon_init (&next, NULL, 0); - status = _cairo_path_fixed_fill_to_polygon (&clip_path->path, - clip_path->tolerance, - &next); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) - status = _cairo_polygon_intersect (&polygon, fill_rule, - &next, clip_path->fill_rule); - _cairo_polygon_fini (&next); - fill_rule = CAIRO_FILL_RULE_WINDING; - } - if (unlikely (status)) - goto error; - } - - clip_path = clip_path->prev; - } - - if (polygon.num_edges) { - _cairo_polygon_translate (&polygon, -extents->x, -extents->y); - status = _cairo_composite_rectangles_init_for_polygon (&composite, surface, - CAIRO_OPERATOR_IN, - &_cairo_pattern_white.base, - &polygon, - NULL); - if (unlikely (status)) - goto cleanup_polygon; - - status = composite_polygon (compositor, &composite, - &polygon, fill_rule, antialias); - _cairo_composite_rectangles_fini (&composite); - _cairo_polygon_fini (&polygon); - if (unlikely (status)) - goto error; - } - - return surface; - -cleanup_polygon: - _cairo_polygon_fini (&polygon); -error: - cairo_surface_destroy (surface); - return _cairo_int_surface_create_in_error (status); -} - -static cairo_int_status_t -fixup_unbounded_mask (const cairo_spans_compositor_t *compositor, - const cairo_composite_rectangles_t *extents, - cairo_boxes_t *boxes) -{ - cairo_composite_rectangles_t composite; - cairo_surface_t *clip; - cairo_int_status_t status; - - TRACE((stderr, "%s\n", __FUNCTION__)); - - clip = get_clip_surface (compositor, extents->surface, extents->clip, - &extents->unbounded); - if (unlikely (clip->status)) { - if ((cairo_int_status_t)clip->status == CAIRO_INT_STATUS_NOTHING_TO_DO) - return CAIRO_STATUS_SUCCESS; - - return clip->status; - } - - status = _cairo_composite_rectangles_init_for_boxes (&composite, - extents->surface, - CAIRO_OPERATOR_CLEAR, - &_cairo_pattern_clear.base, - boxes, - NULL); - if (unlikely (status)) - goto cleanup_clip; - - _cairo_pattern_init_for_surface (&composite.mask_pattern.surface, clip); - composite.mask_pattern.base.filter = CAIRO_FILTER_NEAREST; - composite.mask_pattern.base.extend = CAIRO_EXTEND_NONE; - - status = composite_boxes (compositor, &composite, boxes); - - _cairo_pattern_fini (&composite.mask_pattern.base); - _cairo_composite_rectangles_fini (&composite); - -cleanup_clip: - cairo_surface_destroy (clip); - return status; -} - -static cairo_int_status_t -fixup_unbounded_polygon (const cairo_spans_compositor_t *compositor, - const cairo_composite_rectangles_t *extents, - cairo_boxes_t *boxes) -{ - cairo_polygon_t polygon, intersect; - cairo_composite_rectangles_t composite; - cairo_fill_rule_t fill_rule; - cairo_antialias_t antialias; - cairo_int_status_t status; - - TRACE((stderr, "%s\n", __FUNCTION__)); - - /* Can we treat the clip as a regular clear-polygon and use it to fill? */ - status = _cairo_clip_get_polygon (extents->clip, &polygon, - &fill_rule, &antialias); - if (status == CAIRO_INT_STATUS_UNSUPPORTED) - return status; - - status= _cairo_polygon_init_boxes (&intersect, boxes); - if (unlikely (status)) - goto cleanup_polygon; - - status = _cairo_polygon_intersect (&polygon, fill_rule, - &intersect, CAIRO_FILL_RULE_WINDING); - _cairo_polygon_fini (&intersect); - - if (unlikely (status)) - goto cleanup_polygon; - - status = _cairo_composite_rectangles_init_for_polygon (&composite, - extents->surface, - CAIRO_OPERATOR_CLEAR, - &_cairo_pattern_clear.base, - &polygon, - NULL); - if (unlikely (status)) - goto cleanup_polygon; - - status = composite_polygon (compositor, &composite, - &polygon, fill_rule, antialias); - - _cairo_composite_rectangles_fini (&composite); -cleanup_polygon: - _cairo_polygon_fini (&polygon); - - return status; -} - -static cairo_int_status_t -fixup_unbounded_boxes (const cairo_spans_compositor_t *compositor, - const cairo_composite_rectangles_t *extents, - cairo_boxes_t *boxes) -{ - cairo_boxes_t tmp, clear; - cairo_box_t box; - cairo_int_status_t status; - - assert (boxes->is_pixel_aligned); - - TRACE ((stderr, "%s\n", __FUNCTION__)); - if (extents->bounded.width == extents->unbounded.width && - extents->bounded.height == extents->unbounded.height) - { - return CAIRO_STATUS_SUCCESS; - } - - /* subtract the drawn boxes from the unbounded area */ - _cairo_boxes_init (&clear); - - box.p1.x = _cairo_fixed_from_int (extents->unbounded.x + extents->unbounded.width); - box.p1.y = _cairo_fixed_from_int (extents->unbounded.y); - box.p2.x = _cairo_fixed_from_int (extents->unbounded.x); - box.p2.y = _cairo_fixed_from_int (extents->unbounded.y + extents->unbounded.height); - - if (boxes->num_boxes) { - _cairo_boxes_init (&tmp); - - status = _cairo_boxes_add (&tmp, CAIRO_ANTIALIAS_DEFAULT, &box); - assert (status == CAIRO_INT_STATUS_SUCCESS); - - tmp.chunks.next = &boxes->chunks; - tmp.num_boxes += boxes->num_boxes; - - status = _cairo_bentley_ottmann_tessellate_boxes (&tmp, - CAIRO_FILL_RULE_WINDING, - &clear); - tmp.chunks.next = NULL; - if (unlikely (status)) - goto error; - } else { - box.p1.x = _cairo_fixed_from_int (extents->unbounded.x); - box.p2.x = _cairo_fixed_from_int (extents->unbounded.x + extents->unbounded.width); - - status = _cairo_boxes_add (&clear, CAIRO_ANTIALIAS_DEFAULT, &box); - assert (status == CAIRO_INT_STATUS_SUCCESS); - } - - /* If we have a clip polygon, we need to intersect with that as well */ - if (extents->clip->path) { - status = fixup_unbounded_polygon (compositor, extents, &clear); - if (status == CAIRO_INT_STATUS_UNSUPPORTED) - status = fixup_unbounded_mask (compositor, extents, &clear); - } else { - /* Otherwise just intersect with the clip boxes */ - if (extents->clip->num_boxes) { - _cairo_boxes_init_for_array (&tmp, - extents->clip->boxes, - extents->clip->num_boxes); - status = _cairo_boxes_intersect (&clear, &tmp, &clear); - if (unlikely (status)) - goto error; - } - - if (clear.is_pixel_aligned) { - status = compositor->fill_boxes (extents->surface, - CAIRO_OPERATOR_CLEAR, - CAIRO_COLOR_TRANSPARENT, - &clear); - } else { - cairo_composite_rectangles_t composite; - - status = _cairo_composite_rectangles_init_for_boxes (&composite, - extents->surface, - CAIRO_OPERATOR_CLEAR, - &_cairo_pattern_clear.base, - &clear, - NULL); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) { - status = composite_boxes (compositor, &composite, &clear); - _cairo_composite_rectangles_fini (&composite); - } - } - } - -error: - _cairo_boxes_fini (&clear); - return status; -} - -static cairo_surface_t * -unwrap_source (const cairo_pattern_t *pattern) -{ - cairo_rectangle_int_t limit; - - return _cairo_pattern_get_source ((cairo_surface_pattern_t *)pattern, - &limit); -} - -static cairo_bool_t -is_recording_pattern (const cairo_pattern_t *pattern) -{ - cairo_surface_t *surface; - - if (pattern->type != CAIRO_PATTERN_TYPE_SURFACE) - return FALSE; - - surface = ((const cairo_surface_pattern_t *) pattern)->surface; - return _cairo_surface_is_recording (surface); -} - -static cairo_bool_t -recording_pattern_contains_sample (const cairo_pattern_t *pattern, - const cairo_rectangle_int_t *sample) -{ - cairo_recording_surface_t *surface; - - if (! is_recording_pattern (pattern)) - return FALSE; - - if (pattern->extend == CAIRO_EXTEND_NONE) - return TRUE; - - surface = (cairo_recording_surface_t *) unwrap_source (pattern); - if (surface->unbounded) - return TRUE; - - return _cairo_rectangle_contains_rectangle (&surface->extents, sample); -} - -static cairo_bool_t -op_reduces_to_source (const cairo_composite_rectangles_t *extents, - cairo_bool_t no_mask) -{ - if (extents->op == CAIRO_OPERATOR_SOURCE) - return TRUE; - - if (extents->surface->is_clear) - return extents->op == CAIRO_OPERATOR_OVER || extents->op == CAIRO_OPERATOR_ADD; - - if (no_mask && extents->op == CAIRO_OPERATOR_OVER) - return _cairo_pattern_is_opaque (&extents->source_pattern.base, - &extents->source_sample_area); - - return FALSE; -} - -static cairo_status_t -upload_boxes (const cairo_spans_compositor_t *compositor, - const cairo_composite_rectangles_t *extents, - cairo_boxes_t *boxes) -{ - cairo_surface_t *dst = extents->surface; - const cairo_surface_pattern_t *source = &extents->source_pattern.surface; - cairo_surface_t *src; - cairo_rectangle_int_t limit; - cairo_int_status_t status; - int tx, ty; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - src = _cairo_pattern_get_source(source, &limit); - if (!(src->type == CAIRO_SURFACE_TYPE_IMAGE || src->type == dst->type)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (! _cairo_matrix_is_integer_translation (&source->base.matrix, &tx, &ty)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* Check that the data is entirely within the image */ - if (extents->bounded.x + tx < limit.x || extents->bounded.y + ty < limit.y) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (extents->bounded.x + extents->bounded.width + tx > limit.x + limit.width || - extents->bounded.y + extents->bounded.height + ty > limit.y + limit.height) - return CAIRO_INT_STATUS_UNSUPPORTED; - - tx += limit.x; - ty += limit.y; - - if (src->type == CAIRO_SURFACE_TYPE_IMAGE) - status = compositor->draw_image_boxes (dst, - (cairo_image_surface_t *)src, - boxes, tx, ty); - else - status = compositor->copy_boxes (dst, src, boxes, &extents->bounded, - tx, ty); - - return status; -} - -static cairo_bool_t -_clip_is_region (const cairo_clip_t *clip) -{ - int i; - - if (clip->is_region) - return TRUE; - - if (clip->path) - return FALSE; - - for (i = 0; i < clip->num_boxes; i++) { - const cairo_box_t *b = &clip->boxes[i]; - if (!_cairo_fixed_is_integer (b->p1.x | b->p1.y | b->p2.x | b->p2.y)) - return FALSE; - } - - return TRUE; -} - -static cairo_int_status_t -composite_aligned_boxes (const cairo_spans_compositor_t *compositor, - const cairo_composite_rectangles_t *extents, - cairo_boxes_t *boxes) -{ - cairo_surface_t *dst = extents->surface; - cairo_operator_t op = extents->op; - const cairo_pattern_t *source = &extents->source_pattern.base; - cairo_int_status_t status; - cairo_bool_t need_clip_mask = ! _clip_is_region (extents->clip); - cairo_bool_t op_is_source; - cairo_bool_t no_mask; - cairo_bool_t inplace; - - TRACE ((stderr, "%s: need_clip_mask=%d, is-bounded=%d\n", - __FUNCTION__, need_clip_mask, extents->is_bounded)); - if (need_clip_mask && ! extents->is_bounded) { - TRACE ((stderr, "%s: unsupported clip\n", __FUNCTION__)); - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - no_mask = extents->mask_pattern.base.type == CAIRO_PATTERN_TYPE_SOLID && - CAIRO_COLOR_IS_OPAQUE (&extents->mask_pattern.solid.color); - op_is_source = op_reduces_to_source (extents, no_mask); - inplace = ! need_clip_mask && op_is_source && no_mask; - - TRACE ((stderr, "%s: op-is-source=%d [op=%d], no-mask=%d, inplace=%d\n", - __FUNCTION__, op_is_source, op, no_mask, inplace)); - - if (op == CAIRO_OPERATOR_SOURCE && (need_clip_mask || ! no_mask)) { - /* SOURCE with a mask is actually a LERP in cairo semantics */ - if ((compositor->flags & CAIRO_SPANS_COMPOSITOR_HAS_LERP) == 0) { - TRACE ((stderr, "%s: unsupported lerp\n", __FUNCTION__)); - return CAIRO_INT_STATUS_UNSUPPORTED; - } - } - - /* Are we just copying a recording surface? */ - if (inplace && - recording_pattern_contains_sample (&extents->source_pattern.base, - &extents->source_sample_area)) - { - cairo_clip_t *recording_clip; - const cairo_pattern_t *source = &extents->source_pattern.base; - const cairo_matrix_t *m; - cairo_matrix_t matrix; - - /* XXX could also do tiling repeat modes... */ - - /* first clear the area about to be overwritten */ - if (! dst->is_clear) { - status = compositor->fill_boxes (dst, - CAIRO_OPERATOR_CLEAR, - CAIRO_COLOR_TRANSPARENT, - boxes); - if (unlikely (status)) - return status; - - dst->is_clear = TRUE; - } - - m = &source->matrix; - if (_cairo_surface_has_device_transform (dst)) { - cairo_matrix_multiply (&matrix, - &source->matrix, - &dst->device_transform); - m = &matrix; - } - - recording_clip = _cairo_clip_from_boxes (boxes); - status = _cairo_recording_surface_replay_with_clip (unwrap_source (source), - m, dst, recording_clip); - _cairo_clip_destroy (recording_clip); - - return status; - } - - status = CAIRO_INT_STATUS_UNSUPPORTED; - if (! need_clip_mask && no_mask && source->type == CAIRO_PATTERN_TYPE_SOLID) { - const cairo_color_t *color; - - color = &((cairo_solid_pattern_t *) source)->color; - if (op_is_source) - op = CAIRO_OPERATOR_SOURCE; - status = compositor->fill_boxes (dst, op, color, boxes); - } else if (inplace && source->type == CAIRO_PATTERN_TYPE_SURFACE) { - status = upload_boxes (compositor, extents, boxes); - } - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - cairo_surface_t *src; - cairo_surface_t *mask = NULL; - int src_x, src_y; - int mask_x = 0, mask_y = 0; - - /* All typical cases will have been resolved before now... */ - if (need_clip_mask) { - mask = get_clip_surface (compositor, dst, extents->clip, - &extents->bounded); - if (unlikely (mask->status)) - return mask->status; - - mask_x = -extents->bounded.x; - mask_y = -extents->bounded.y; - } - - /* XXX but this is still ugly */ - if (! no_mask) { - src = compositor->pattern_to_surface (dst, - &extents->mask_pattern.base, - TRUE, - &extents->bounded, - &extents->mask_sample_area, - &src_x, &src_y); - if (unlikely (src->status)) { - cairo_surface_destroy (mask); - return src->status; - } - - if (mask != NULL) { - status = compositor->composite_boxes (mask, CAIRO_OPERATOR_IN, - src, NULL, - src_x, src_y, - 0, 0, - mask_x, mask_y, - boxes, &extents->bounded); - - cairo_surface_destroy (src); - } else { - mask = src; - mask_x = src_x; - mask_y = src_y; - } - } - - src = compositor->pattern_to_surface (dst, source, FALSE, - &extents->bounded, - &extents->source_sample_area, - &src_x, &src_y); - if (likely (src->status == CAIRO_STATUS_SUCCESS)) { - status = compositor->composite_boxes (dst, op, src, mask, - src_x, src_y, - mask_x, mask_y, - 0, 0, - boxes, &extents->bounded); - cairo_surface_destroy (src); - } else - status = src->status; - - cairo_surface_destroy (mask); - } - - if (status == CAIRO_INT_STATUS_SUCCESS && ! extents->is_bounded) - status = fixup_unbounded_boxes (compositor, extents, boxes); - - return status; -} - -static cairo_bool_t -composite_needs_clip (const cairo_composite_rectangles_t *composite, - const cairo_box_t *extents) -{ - return !_cairo_clip_contains_box (composite->clip, extents); -} - -static cairo_int_status_t -composite_boxes (const cairo_spans_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - cairo_boxes_t *boxes) -{ - cairo_abstract_span_renderer_t renderer; - cairo_rectangular_scan_converter_t converter; - const struct _cairo_boxes_chunk *chunk; - cairo_int_status_t status; - cairo_box_t box; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - _cairo_box_from_rectangle (&box, &extents->unbounded); - if (composite_needs_clip (extents, &box)) { - TRACE ((stderr, "%s: unsupported clip\n", __FUNCTION__)); - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - _cairo_rectangular_scan_converter_init (&converter, &extents->unbounded); - for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) { - const cairo_box_t *box = chunk->base; - int i; - - for (i = 0; i < chunk->count; i++) { - status = _cairo_rectangular_scan_converter_add_box (&converter, &box[i], 1); - if (unlikely (status)) - goto cleanup_converter; - } - } - - status = compositor->renderer_init (&renderer, extents, - CAIRO_ANTIALIAS_DEFAULT, FALSE); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) - status = converter.base.generate (&converter.base, &renderer.base); - compositor->renderer_fini (&renderer, status); - -cleanup_converter: - converter.base.destroy (&converter.base); - return status; -} - -static cairo_int_status_t -composite_polygon (const cairo_spans_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - cairo_polygon_t *polygon, - cairo_fill_rule_t fill_rule, - cairo_antialias_t antialias) -{ - cairo_abstract_span_renderer_t renderer; - cairo_scan_converter_t *converter; - cairo_bool_t needs_clip; - cairo_int_status_t status; - - if (extents->is_bounded) - needs_clip = extents->clip->path != NULL; - else - needs_clip = !_clip_is_region (extents->clip) || extents->clip->num_boxes > 1; - TRACE ((stderr, "%s - needs_clip=%d\n", __FUNCTION__, needs_clip)); - if (needs_clip) { - TRACE ((stderr, "%s: unsupported clip\n", __FUNCTION__)); - return CAIRO_INT_STATUS_UNSUPPORTED; - converter = _cairo_clip_tor_scan_converter_create (extents->clip, - polygon, - fill_rule, antialias); - } else { - const cairo_rectangle_int_t *r = &extents->unbounded; - - if (antialias == CAIRO_ANTIALIAS_FAST) { - converter = _cairo_tor22_scan_converter_create (r->x, r->y, - r->x + r->width, - r->y + r->height, - fill_rule, antialias); - status = _cairo_tor22_scan_converter_add_polygon (converter, polygon); - } else if (antialias == CAIRO_ANTIALIAS_NONE) { - converter = _cairo_mono_scan_converter_create (r->x, r->y, - r->x + r->width, - r->y + r->height, - fill_rule); - status = _cairo_mono_scan_converter_add_polygon (converter, polygon); - } else { - converter = _cairo_tor_scan_converter_create (r->x, r->y, - r->x + r->width, - r->y + r->height, - fill_rule, antialias); - status = _cairo_tor_scan_converter_add_polygon (converter, polygon); - } - } - if (unlikely (status)) - goto cleanup_converter; - - status = compositor->renderer_init (&renderer, extents, - antialias, needs_clip); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) - status = converter->generate (converter, &renderer.base); - compositor->renderer_fini (&renderer, status); - -cleanup_converter: - converter->destroy (converter); - return status; -} - -static cairo_int_status_t -trim_extents_to_boxes (cairo_composite_rectangles_t *extents, - cairo_boxes_t *boxes) -{ - cairo_box_t box; - - _cairo_boxes_extents (boxes, &box); - return _cairo_composite_rectangles_intersect_mask_extents (extents, &box); -} - -static cairo_int_status_t -trim_extents_to_polygon (cairo_composite_rectangles_t *extents, - cairo_polygon_t *polygon) -{ - return _cairo_composite_rectangles_intersect_mask_extents (extents, - &polygon->extents); -} - -static cairo_int_status_t -clip_and_composite_boxes (const cairo_spans_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - cairo_boxes_t *boxes) -{ - cairo_int_status_t status; - cairo_polygon_t polygon; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - status = trim_extents_to_boxes (extents, boxes); - if (unlikely (status)) - return status; - - if (boxes->num_boxes == 0) { - if (extents->is_bounded) - return CAIRO_STATUS_SUCCESS; - - return fixup_unbounded_boxes (compositor, extents, boxes); - } - - /* Can we reduce drawing through a clip-mask to simply drawing the clip? */ - if (extents->clip->path != NULL && extents->is_bounded) { - cairo_polygon_t polygon; - cairo_fill_rule_t fill_rule; - cairo_antialias_t antialias; - cairo_clip_t *clip; - - clip = _cairo_clip_copy (extents->clip); - clip = _cairo_clip_intersect_boxes (clip, boxes); - if (_cairo_clip_is_all_clipped (clip)) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - status = _cairo_clip_get_polygon (clip, &polygon, - &fill_rule, &antialias); - _cairo_clip_path_destroy (clip->path); - clip->path = NULL; - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) { - cairo_clip_t *saved_clip = extents->clip; - extents->clip = clip; - - status = clip_and_composite_polygon (compositor, extents, &polygon, - fill_rule, antialias); - - clip = extents->clip; - extents->clip = saved_clip; - - _cairo_polygon_fini (&polygon); - } - _cairo_clip_destroy (clip); - - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - } - - if (boxes->is_pixel_aligned) { - status = composite_aligned_boxes (compositor, extents, boxes); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - } - - status = composite_boxes (compositor, extents, boxes); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - - status = _cairo_polygon_init_boxes (&polygon, boxes); - if (unlikely (status)) - return status; - - status = composite_polygon (compositor, extents, &polygon, - CAIRO_FILL_RULE_WINDING, - CAIRO_ANTIALIAS_DEFAULT); - _cairo_polygon_fini (&polygon); - - return status; -} - -static cairo_int_status_t -clip_and_composite_polygon (const cairo_spans_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - cairo_polygon_t *polygon, - cairo_fill_rule_t fill_rule, - cairo_antialias_t antialias) -{ - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - /* XXX simply uses polygon limits.point extemities, tessellation? */ - status = trim_extents_to_polygon (extents, polygon); - if (unlikely (status)) - return status; - - if (_cairo_polygon_is_empty (polygon)) { - cairo_boxes_t boxes; - - if (extents->is_bounded) - return CAIRO_STATUS_SUCCESS; - - _cairo_boxes_init (&boxes); - extents->bounded.width = extents->bounded.height = 0; - return fixup_unbounded_boxes (compositor, extents, &boxes); - } - - if (extents->is_bounded && extents->clip->path) { - cairo_polygon_t clipper; - cairo_antialias_t clip_antialias; - cairo_fill_rule_t clip_fill_rule; - - TRACE((stderr, "%s - combining shape with clip polygon\n", - __FUNCTION__)); - - status = _cairo_clip_get_polygon (extents->clip, - &clipper, - &clip_fill_rule, - &clip_antialias); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) { - cairo_clip_t *old_clip; - - if (clip_antialias == antialias) { - status = _cairo_polygon_intersect (polygon, fill_rule, - &clipper, clip_fill_rule); - _cairo_polygon_fini (&clipper); - if (unlikely (status)) - return status; - - old_clip = extents->clip; - extents->clip = _cairo_clip_copy_region (extents->clip); - _cairo_clip_destroy (old_clip); - - status = trim_extents_to_polygon (extents, polygon); - if (unlikely (status)) - return status; - - fill_rule = CAIRO_FILL_RULE_WINDING; - } else { - _cairo_polygon_fini (&clipper); - } - } - } - - return composite_polygon (compositor, extents, - polygon, fill_rule, antialias); -} - -/* high-level compositor interface */ - -static cairo_int_status_t -_cairo_spans_compositor_paint (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents) -{ - const cairo_spans_compositor_t *compositor = (cairo_spans_compositor_t*)_compositor; - cairo_boxes_t boxes; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - _cairo_clip_steal_boxes (extents->clip, &boxes); - status = clip_and_composite_boxes (compositor, extents, &boxes); - _cairo_clip_unsteal_boxes (extents->clip, &boxes); - - return status; -} - -static cairo_int_status_t -_cairo_spans_compositor_mask (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents) -{ - const cairo_spans_compositor_t *compositor = (cairo_spans_compositor_t*)_compositor; - cairo_int_status_t status; - cairo_boxes_t boxes; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - _cairo_clip_steal_boxes (extents->clip, &boxes); - status = clip_and_composite_boxes (compositor, extents, &boxes); - _cairo_clip_unsteal_boxes (extents->clip, &boxes); - - return status; -} - -static cairo_int_status_t -_cairo_spans_compositor_stroke (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias) -{ - const cairo_spans_compositor_t *compositor = (cairo_spans_compositor_t*)_compositor; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - TRACE_ (_cairo_debug_print_path (stderr, path)); - TRACE_ (_cairo_debug_print_clip (stderr, extents->clip)); - - status = CAIRO_INT_STATUS_UNSUPPORTED; - if (_cairo_path_fixed_stroke_is_rectilinear (path)) { - cairo_boxes_t boxes; - - _cairo_boxes_init (&boxes); - if (! _cairo_clip_contains_rectangle (extents->clip, &extents->mask)) - _cairo_boxes_limit (&boxes, - extents->clip->boxes, - extents->clip->num_boxes); - - status = _cairo_path_fixed_stroke_rectilinear_to_boxes (path, - style, - ctm, - antialias, - &boxes); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) - status = clip_and_composite_boxes (compositor, extents, &boxes); - _cairo_boxes_fini (&boxes); - } - - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - cairo_polygon_t polygon; - cairo_fill_rule_t fill_rule = CAIRO_FILL_RULE_WINDING; - - if (! _cairo_rectangle_contains_rectangle (&extents->unbounded, - &extents->mask)) - { - if (extents->clip->num_boxes == 1) { - _cairo_polygon_init (&polygon, extents->clip->boxes, 1); - } else { - cairo_box_t limits; - _cairo_box_from_rectangle (&limits, &extents->unbounded); - _cairo_polygon_init (&polygon, &limits, 1); - } - } - else - { - _cairo_polygon_init (&polygon, NULL, 0); - } - status = _cairo_path_fixed_stroke_to_polygon (path, - style, - ctm, ctm_inverse, - tolerance, - &polygon); - TRACE_ (_cairo_debug_print_polygon (stderr, &polygon)); - polygon.num_limits = 0; - - if (status == CAIRO_INT_STATUS_SUCCESS && extents->clip->num_boxes > 1) { - status = _cairo_polygon_intersect_with_boxes (&polygon, &fill_rule, - extents->clip->boxes, - extents->clip->num_boxes); - } - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) { - cairo_clip_t *saved_clip = extents->clip; - - if (extents->is_bounded) { - extents->clip = _cairo_clip_copy_path (extents->clip); - extents->clip = _cairo_clip_intersect_box(extents->clip, - &polygon.extents); - } - - status = clip_and_composite_polygon (compositor, extents, &polygon, - fill_rule, antialias); - - if (extents->is_bounded) { - _cairo_clip_destroy (extents->clip); - extents->clip = saved_clip; - } - } - _cairo_polygon_fini (&polygon); - } - - return status; -} - -static cairo_int_status_t -_cairo_spans_compositor_fill (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - const cairo_spans_compositor_t *compositor = (cairo_spans_compositor_t*)_compositor; - cairo_int_status_t status; - - TRACE((stderr, "%s op=%d, antialias=%d\n", __FUNCTION__, extents->op, antialias)); - - status = CAIRO_INT_STATUS_UNSUPPORTED; - if (_cairo_path_fixed_fill_is_rectilinear (path)) { - cairo_boxes_t boxes; - - TRACE((stderr, "%s - rectilinear\n", __FUNCTION__)); - - _cairo_boxes_init (&boxes); - if (! _cairo_clip_contains_rectangle (extents->clip, &extents->mask)) - _cairo_boxes_limit (&boxes, - extents->clip->boxes, - extents->clip->num_boxes); - status = _cairo_path_fixed_fill_rectilinear_to_boxes (path, - fill_rule, - antialias, - &boxes); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) - status = clip_and_composite_boxes (compositor, extents, &boxes); - _cairo_boxes_fini (&boxes); - } - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - cairo_polygon_t polygon; - - TRACE((stderr, "%s - polygon\n", __FUNCTION__)); - - if (! _cairo_rectangle_contains_rectangle (&extents->unbounded, - &extents->mask)) - { - TRACE((stderr, "%s - clipping to bounds\n", __FUNCTION__)); - if (extents->clip->num_boxes == 1) { - _cairo_polygon_init (&polygon, extents->clip->boxes, 1); - } else { - cairo_box_t limits; - _cairo_box_from_rectangle (&limits, &extents->unbounded); - _cairo_polygon_init (&polygon, &limits, 1); - } - } - else - { - _cairo_polygon_init (&polygon, NULL, 0); - } - - status = _cairo_path_fixed_fill_to_polygon (path, tolerance, &polygon); - TRACE_ (_cairo_debug_print_polygon (stderr, &polygon)); - polygon.num_limits = 0; - - if (status == CAIRO_INT_STATUS_SUCCESS && extents->clip->num_boxes > 1) { - TRACE((stderr, "%s - polygon intersect with %d clip boxes\n", - __FUNCTION__, extents->clip->num_boxes)); - status = _cairo_polygon_intersect_with_boxes (&polygon, &fill_rule, - extents->clip->boxes, - extents->clip->num_boxes); - } - TRACE_ (_cairo_debug_print_polygon (stderr, &polygon)); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) { - cairo_clip_t *saved_clip = extents->clip; - - if (extents->is_bounded) { - TRACE((stderr, "%s - polygon discard clip boxes\n", - __FUNCTION__)); - extents->clip = _cairo_clip_copy_path (extents->clip); - extents->clip = _cairo_clip_intersect_box(extents->clip, - &polygon.extents); - } - - status = clip_and_composite_polygon (compositor, extents, &polygon, - fill_rule, antialias); - - if (extents->is_bounded) { - _cairo_clip_destroy (extents->clip); - extents->clip = saved_clip; - } - } - _cairo_polygon_fini (&polygon); - - TRACE((stderr, "%s - polygon status=%d\n", __FUNCTION__, status)); - } - - return status; -} - -void -_cairo_spans_compositor_init (cairo_spans_compositor_t *compositor, - const cairo_compositor_t *delegate) -{ - compositor->base.delegate = delegate; - - compositor->base.paint = _cairo_spans_compositor_paint; - compositor->base.mask = _cairo_spans_compositor_mask; - compositor->base.fill = _cairo_spans_compositor_fill; - compositor->base.stroke = _cairo_spans_compositor_stroke; - compositor->base.glyphs = NULL; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-spans-private.h b/source/libs/cairo/cairo-src/src/cairo-spans-private.h deleted file mode 100644 index b158f4d360ac382cf8e83331f334413bcb2eeb74..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-spans-private.h +++ /dev/null @@ -1,206 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright (c) 2008 M Joonas Pihlaja - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef CAIRO_SPANS_PRIVATE_H -#define CAIRO_SPANS_PRIVATE_H -#include "cairo-types-private.h" -#include "cairo-compiler-private.h" - -/* Number of bits of precision used for alpha. */ -#define CAIRO_SPANS_UNIT_COVERAGE_BITS 8 -#define CAIRO_SPANS_UNIT_COVERAGE ((1 << CAIRO_SPANS_UNIT_COVERAGE_BITS)-1) - -/* A structure representing an open-ended horizontal span of constant - * pixel coverage. */ -typedef struct _cairo_half_open_span { - int32_t x; /* The inclusive x-coordinate of the start of the span. */ - uint8_t coverage; /* The pixel coverage for the pixels to the right. */ - uint8_t inverse; /* between regular mask and clip */ -} cairo_half_open_span_t; - -/* Span renderer interface. Instances of renderers are provided by - * surfaces if they want to composite spans instead of trapezoids. */ -typedef struct _cairo_span_renderer cairo_span_renderer_t; -struct _cairo_span_renderer { - /* Private status variable. */ - cairo_status_t status; - - /* Called to destroy the renderer. */ - cairo_destroy_func_t destroy; - - /* Render the spans on row y of the destination by whatever compositing - * method is required. */ - cairo_status_t - (*render_rows) (void *abstract_renderer, - int y, int height, - const cairo_half_open_span_t *coverages, - unsigned num_coverages); - - /* Called after all rows have been rendered to perform whatever - * final rendering step is required. This function is called just - * once before the renderer is destroyed. */ - cairo_status_t (*finish) (void *abstract_renderer); -}; - -/* Scan converter interface. */ -typedef struct _cairo_scan_converter cairo_scan_converter_t; -struct _cairo_scan_converter { - /* Destroy this scan converter. */ - cairo_destroy_func_t destroy; - - /* Generates coverage spans for rows for the added edges and calls - * the renderer function for each row. After generating spans the - * only valid thing to do with the converter is to destroy it. */ - cairo_status_t (*generate) (void *abstract_converter, - cairo_span_renderer_t *renderer); - - /* Private status. Read with _cairo_scan_converter_status(). */ - cairo_status_t status; -}; - -/* Scan converter constructors. */ - -cairo_private cairo_scan_converter_t * -_cairo_tor_scan_converter_create (int xmin, - int ymin, - int xmax, - int ymax, - cairo_fill_rule_t fill_rule, - cairo_antialias_t antialias); -cairo_private cairo_status_t -_cairo_tor_scan_converter_add_polygon (void *converter, - const cairo_polygon_t *polygon); - -cairo_private cairo_scan_converter_t * -_cairo_tor22_scan_converter_create (int xmin, - int ymin, - int xmax, - int ymax, - cairo_fill_rule_t fill_rule, - cairo_antialias_t antialias); -cairo_private cairo_status_t -_cairo_tor22_scan_converter_add_polygon (void *converter, - const cairo_polygon_t *polygon); - -cairo_private cairo_scan_converter_t * -_cairo_mono_scan_converter_create (int xmin, - int ymin, - int xmax, - int ymax, - cairo_fill_rule_t fill_rule); -cairo_private cairo_status_t -_cairo_mono_scan_converter_add_polygon (void *converter, - const cairo_polygon_t *polygon); - -cairo_private cairo_scan_converter_t * -_cairo_clip_tor_scan_converter_create (cairo_clip_t *clip, - cairo_polygon_t *polygon, - cairo_fill_rule_t fill_rule, - cairo_antialias_t antialias); - -typedef struct _cairo_rectangular_scan_converter { - cairo_scan_converter_t base; - - cairo_box_t extents; - - struct _cairo_rectangular_scan_converter_chunk { - struct _cairo_rectangular_scan_converter_chunk *next; - void *base; - int count; - int size; - } chunks, *tail; - char buf[CAIRO_STACK_BUFFER_SIZE]; - int num_rectangles; -} cairo_rectangular_scan_converter_t; - -cairo_private void -_cairo_rectangular_scan_converter_init (cairo_rectangular_scan_converter_t *self, - const cairo_rectangle_int_t *extents); - -cairo_private cairo_status_t -_cairo_rectangular_scan_converter_add_box (cairo_rectangular_scan_converter_t *self, - const cairo_box_t *box, - int dir); - -typedef struct _cairo_botor_scan_converter { - cairo_scan_converter_t base; - - cairo_box_t extents; - cairo_fill_rule_t fill_rule; - - int xmin, xmax; - - struct _cairo_botor_scan_converter_chunk { - struct _cairo_botor_scan_converter_chunk *next; - void *base; - int count; - int size; - } chunks, *tail; - char buf[CAIRO_STACK_BUFFER_SIZE]; - int num_edges; -} cairo_botor_scan_converter_t; - -cairo_private void -_cairo_botor_scan_converter_init (cairo_botor_scan_converter_t *self, - const cairo_box_t *extents, - cairo_fill_rule_t fill_rule); - -/* cairo-spans.c: */ - -cairo_private cairo_scan_converter_t * -_cairo_scan_converter_create_in_error (cairo_status_t error); - -cairo_private cairo_status_t -_cairo_scan_converter_status (void *abstract_converter); - -cairo_private cairo_status_t -_cairo_scan_converter_set_error (void *abstract_converter, - cairo_status_t error); - -cairo_private cairo_span_renderer_t * -_cairo_span_renderer_create_in_error (cairo_status_t error); - -cairo_private cairo_status_t -_cairo_span_renderer_status (void *abstract_renderer); - -/* Set the renderer into an error state. This sets all the method - * pointers except ->destroy() of the renderer to no-op - * implementations that just return the error status. */ -cairo_private cairo_status_t -_cairo_span_renderer_set_error (void *abstract_renderer, - cairo_status_t error); - -cairo_private cairo_status_t -_cairo_surface_composite_polygon (cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *pattern, - cairo_fill_rule_t fill_rule, - cairo_antialias_t antialias, - const cairo_composite_rectangles_t *rects, - cairo_polygon_t *polygon, - cairo_region_t *clip_region); - -#endif /* CAIRO_SPANS_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-spans.c b/source/libs/cairo/cairo-src/src/cairo-spans.c deleted file mode 100644 index 182390c205ae9a0d5e7a2a23e1c19d7802b5ec16..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-spans.c +++ /dev/null @@ -1,250 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright (c) 2008 M Joonas Pihlaja - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -#include "cairoint.h" - -#include "cairo-composite-rectangles-private.h" -#include "cairo-clip-private.h" -#include "cairo-error-private.h" -#include "cairo-fixed-private.h" -#include "cairo-types-private.h" - -static void -_cairo_nil_destroy (void *abstract) -{ - (void) abstract; -} - -static cairo_status_t -_cairo_nil_scan_converter_generate (void *abstract_converter, - cairo_span_renderer_t *renderer) -{ - (void) abstract_converter; - (void) renderer; - return _cairo_scan_converter_status (abstract_converter); -} - -cairo_status_t -_cairo_scan_converter_status (void *abstract_converter) -{ - cairo_scan_converter_t *converter = abstract_converter; - return converter->status; -} - -cairo_status_t -_cairo_scan_converter_set_error (void *abstract_converter, - cairo_status_t error) -{ - cairo_scan_converter_t *converter = abstract_converter; - if (error == CAIRO_STATUS_SUCCESS) - ASSERT_NOT_REACHED; - if (converter->status == CAIRO_STATUS_SUCCESS) { - converter->generate = _cairo_nil_scan_converter_generate; - converter->status = error; - } - return converter->status; -} - -static void -_cairo_nil_scan_converter_init (cairo_scan_converter_t *converter, - cairo_status_t status) -{ - converter->destroy = _cairo_nil_destroy; - converter->status = CAIRO_STATUS_SUCCESS; - status = _cairo_scan_converter_set_error (converter, status); -} - -cairo_scan_converter_t * -_cairo_scan_converter_create_in_error (cairo_status_t status) -{ -#define RETURN_NIL {\ - static cairo_scan_converter_t nil;\ - _cairo_nil_scan_converter_init (&nil, status);\ - return &nil;\ - } - switch (status) { - case CAIRO_STATUS_SUCCESS: - case CAIRO_STATUS_LAST_STATUS: - ASSERT_NOT_REACHED; - break; - case CAIRO_STATUS_INVALID_RESTORE: RETURN_NIL; - case CAIRO_STATUS_INVALID_POP_GROUP: RETURN_NIL; - case CAIRO_STATUS_NO_CURRENT_POINT: RETURN_NIL; - case CAIRO_STATUS_INVALID_MATRIX: RETURN_NIL; - case CAIRO_STATUS_INVALID_STATUS: RETURN_NIL; - case CAIRO_STATUS_NULL_POINTER: RETURN_NIL; - case CAIRO_STATUS_INVALID_STRING: RETURN_NIL; - case CAIRO_STATUS_INVALID_PATH_DATA: RETURN_NIL; - case CAIRO_STATUS_READ_ERROR: RETURN_NIL; - case CAIRO_STATUS_WRITE_ERROR: RETURN_NIL; - case CAIRO_STATUS_SURFACE_FINISHED: RETURN_NIL; - case CAIRO_STATUS_SURFACE_TYPE_MISMATCH: RETURN_NIL; - case CAIRO_STATUS_PATTERN_TYPE_MISMATCH: RETURN_NIL; - case CAIRO_STATUS_INVALID_CONTENT: RETURN_NIL; - case CAIRO_STATUS_INVALID_FORMAT: RETURN_NIL; - case CAIRO_STATUS_INVALID_VISUAL: RETURN_NIL; - case CAIRO_STATUS_FILE_NOT_FOUND: RETURN_NIL; - case CAIRO_STATUS_INVALID_DASH: RETURN_NIL; - case CAIRO_STATUS_INVALID_DSC_COMMENT: RETURN_NIL; - case CAIRO_STATUS_INVALID_INDEX: RETURN_NIL; - case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE: RETURN_NIL; - case CAIRO_STATUS_TEMP_FILE_ERROR: RETURN_NIL; - case CAIRO_STATUS_INVALID_STRIDE: RETURN_NIL; - case CAIRO_STATUS_FONT_TYPE_MISMATCH: RETURN_NIL; - case CAIRO_STATUS_USER_FONT_IMMUTABLE: RETURN_NIL; - case CAIRO_STATUS_USER_FONT_ERROR: RETURN_NIL; - case CAIRO_STATUS_NEGATIVE_COUNT: RETURN_NIL; - case CAIRO_STATUS_INVALID_CLUSTERS: RETURN_NIL; - case CAIRO_STATUS_INVALID_SLANT: RETURN_NIL; - case CAIRO_STATUS_INVALID_WEIGHT: RETURN_NIL; - case CAIRO_STATUS_NO_MEMORY: RETURN_NIL; - case CAIRO_STATUS_INVALID_SIZE: RETURN_NIL; - case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: RETURN_NIL; - case CAIRO_STATUS_DEVICE_TYPE_MISMATCH: RETURN_NIL; - case CAIRO_STATUS_DEVICE_ERROR: RETURN_NIL; - case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION: RETURN_NIL; - case CAIRO_STATUS_DEVICE_FINISHED: RETURN_NIL; - case CAIRO_STATUS_JBIG2_GLOBAL_MISSING: - default: - break; - } - status = CAIRO_STATUS_NO_MEMORY; - RETURN_NIL; -#undef RETURN_NIL -} - -static cairo_status_t -_cairo_nil_span_renderer_render_rows ( - void *abstract_renderer, - int y, - int height, - const cairo_half_open_span_t *coverages, - unsigned num_coverages) -{ - (void) y; - (void) height; - (void) coverages; - (void) num_coverages; - return _cairo_span_renderer_status (abstract_renderer); -} - -static cairo_status_t -_cairo_nil_span_renderer_finish (void *abstract_renderer) -{ - return _cairo_span_renderer_status (abstract_renderer); -} - -cairo_status_t -_cairo_span_renderer_status (void *abstract_renderer) -{ - cairo_span_renderer_t *renderer = abstract_renderer; - return renderer->status; -} - -cairo_status_t -_cairo_span_renderer_set_error ( - void *abstract_renderer, - cairo_status_t error) -{ - cairo_span_renderer_t *renderer = abstract_renderer; - if (error == CAIRO_STATUS_SUCCESS) { - ASSERT_NOT_REACHED; - } - if (renderer->status == CAIRO_STATUS_SUCCESS) { - renderer->render_rows = _cairo_nil_span_renderer_render_rows; - renderer->finish = _cairo_nil_span_renderer_finish; - renderer->status = error; - } - return renderer->status; -} - -static void -_cairo_nil_span_renderer_init (cairo_span_renderer_t *renderer, - cairo_status_t status) -{ - renderer->destroy = _cairo_nil_destroy; - renderer->status = CAIRO_STATUS_SUCCESS; - status = _cairo_span_renderer_set_error (renderer, status); -} - -cairo_span_renderer_t * -_cairo_span_renderer_create_in_error (cairo_status_t status) -{ -#define RETURN_NIL {\ - static cairo_span_renderer_t nil;\ - _cairo_nil_span_renderer_init (&nil, status);\ - return &nil;\ - } - switch (status) { - case CAIRO_STATUS_SUCCESS: - case CAIRO_STATUS_LAST_STATUS: - ASSERT_NOT_REACHED; - break; - case CAIRO_STATUS_INVALID_RESTORE: RETURN_NIL; - case CAIRO_STATUS_INVALID_POP_GROUP: RETURN_NIL; - case CAIRO_STATUS_NO_CURRENT_POINT: RETURN_NIL; - case CAIRO_STATUS_INVALID_MATRIX: RETURN_NIL; - case CAIRO_STATUS_INVALID_STATUS: RETURN_NIL; - case CAIRO_STATUS_NULL_POINTER: RETURN_NIL; - case CAIRO_STATUS_INVALID_STRING: RETURN_NIL; - case CAIRO_STATUS_INVALID_PATH_DATA: RETURN_NIL; - case CAIRO_STATUS_READ_ERROR: RETURN_NIL; - case CAIRO_STATUS_WRITE_ERROR: RETURN_NIL; - case CAIRO_STATUS_SURFACE_FINISHED: RETURN_NIL; - case CAIRO_STATUS_SURFACE_TYPE_MISMATCH: RETURN_NIL; - case CAIRO_STATUS_PATTERN_TYPE_MISMATCH: RETURN_NIL; - case CAIRO_STATUS_INVALID_CONTENT: RETURN_NIL; - case CAIRO_STATUS_INVALID_FORMAT: RETURN_NIL; - case CAIRO_STATUS_INVALID_VISUAL: RETURN_NIL; - case CAIRO_STATUS_FILE_NOT_FOUND: RETURN_NIL; - case CAIRO_STATUS_INVALID_DASH: RETURN_NIL; - case CAIRO_STATUS_INVALID_DSC_COMMENT: RETURN_NIL; - case CAIRO_STATUS_INVALID_INDEX: RETURN_NIL; - case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE: RETURN_NIL; - case CAIRO_STATUS_TEMP_FILE_ERROR: RETURN_NIL; - case CAIRO_STATUS_INVALID_STRIDE: RETURN_NIL; - case CAIRO_STATUS_FONT_TYPE_MISMATCH: RETURN_NIL; - case CAIRO_STATUS_USER_FONT_IMMUTABLE: RETURN_NIL; - case CAIRO_STATUS_USER_FONT_ERROR: RETURN_NIL; - case CAIRO_STATUS_NEGATIVE_COUNT: RETURN_NIL; - case CAIRO_STATUS_INVALID_CLUSTERS: RETURN_NIL; - case CAIRO_STATUS_INVALID_SLANT: RETURN_NIL; - case CAIRO_STATUS_INVALID_WEIGHT: RETURN_NIL; - case CAIRO_STATUS_NO_MEMORY: RETURN_NIL; - case CAIRO_STATUS_INVALID_SIZE: RETURN_NIL; - case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: RETURN_NIL; - case CAIRO_STATUS_DEVICE_TYPE_MISMATCH: RETURN_NIL; - case CAIRO_STATUS_DEVICE_ERROR: RETURN_NIL; - case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION: RETURN_NIL; - case CAIRO_STATUS_DEVICE_FINISHED: RETURN_NIL; - case CAIRO_STATUS_JBIG2_GLOBAL_MISSING: RETURN_NIL; - default: - break; - } - status = CAIRO_STATUS_NO_MEMORY; - RETURN_NIL; -#undef RETURN_NIL -} diff --git a/source/libs/cairo/cairo-src/src/cairo-spline.c b/source/libs/cairo/cairo-src/src/cairo-spline.c deleted file mode 100644 index 44634faec859be3872024f490c96fdb66554ba31..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-spline.c +++ /dev/null @@ -1,424 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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" - -#include "cairo-box-inline.h" -#include "cairo-slope-private.h" - -cairo_bool_t -_cairo_spline_intersects (const cairo_point_t *a, - const cairo_point_t *b, - const cairo_point_t *c, - const cairo_point_t *d, - const cairo_box_t *box) -{ - cairo_box_t bounds; - - if (_cairo_box_contains_point (box, a) || - _cairo_box_contains_point (box, b) || - _cairo_box_contains_point (box, c) || - _cairo_box_contains_point (box, d)) - { - return TRUE; - } - - bounds.p2 = bounds.p1 = *a; - _cairo_box_add_point (&bounds, b); - _cairo_box_add_point (&bounds, c); - _cairo_box_add_point (&bounds, d); - - if (bounds.p2.x <= box->p1.x || bounds.p1.x >= box->p2.x || - bounds.p2.y <= box->p1.y || bounds.p1.y >= box->p2.y) - { - return FALSE; - } - -#if 0 /* worth refining? */ - bounds.p2 = bounds.p1 = *a; - _cairo_box_add_curve_to (&bounds, b, c, d); - if (bounds.p2.x <= box->p1.x || bounds.p1.x >= box->p2.x || - bounds.p2.y <= box->p1.y || bounds.p1.y >= box->p2.y) - { - return FALSE; - } -#endif - - return TRUE; -} - -cairo_bool_t -_cairo_spline_init (cairo_spline_t *spline, - cairo_spline_add_point_func_t add_point_func, - void *closure, - const cairo_point_t *a, const cairo_point_t *b, - const cairo_point_t *c, const cairo_point_t *d) -{ - /* If both tangents are zero, this is just a straight line */ - if (a->x == b->x && a->y == b->y && c->x == d->x && c->y == d->y) - return FALSE; - - spline->add_point_func = add_point_func; - spline->closure = closure; - - spline->knots.a = *a; - spline->knots.b = *b; - spline->knots.c = *c; - spline->knots.d = *d; - - if (a->x != b->x || a->y != b->y) - _cairo_slope_init (&spline->initial_slope, &spline->knots.a, &spline->knots.b); - else if (a->x != c->x || a->y != c->y) - _cairo_slope_init (&spline->initial_slope, &spline->knots.a, &spline->knots.c); - else if (a->x != d->x || a->y != d->y) - _cairo_slope_init (&spline->initial_slope, &spline->knots.a, &spline->knots.d); - else - return FALSE; - - if (c->x != d->x || c->y != d->y) - _cairo_slope_init (&spline->final_slope, &spline->knots.c, &spline->knots.d); - else if (b->x != d->x || b->y != d->y) - _cairo_slope_init (&spline->final_slope, &spline->knots.b, &spline->knots.d); - else - return FALSE; /* just treat this as a straight-line from a -> d */ - - /* XXX if the initial, final and vector are all equal, this is just a line */ - - return TRUE; -} - -static cairo_status_t -_cairo_spline_add_point (cairo_spline_t *spline, - const cairo_point_t *point, - const cairo_point_t *knot) -{ - cairo_point_t *prev; - cairo_slope_t slope; - - prev = &spline->last_point; - if (prev->x == point->x && prev->y == point->y) - return CAIRO_STATUS_SUCCESS; - - _cairo_slope_init (&slope, point, knot); - - spline->last_point = *point; - return spline->add_point_func (spline->closure, point, &slope); -} - -static void -_lerp_half (const cairo_point_t *a, const cairo_point_t *b, cairo_point_t *result) -{ - result->x = a->x + ((b->x - a->x) >> 1); - result->y = a->y + ((b->y - a->y) >> 1); -} - -static void -_de_casteljau (cairo_spline_knots_t *s1, cairo_spline_knots_t *s2) -{ - cairo_point_t ab, bc, cd; - cairo_point_t abbc, bccd; - cairo_point_t final; - - _lerp_half (&s1->a, &s1->b, &ab); - _lerp_half (&s1->b, &s1->c, &bc); - _lerp_half (&s1->c, &s1->d, &cd); - _lerp_half (&ab, &bc, &abbc); - _lerp_half (&bc, &cd, &bccd); - _lerp_half (&abbc, &bccd, &final); - - s2->a = final; - s2->b = bccd; - s2->c = cd; - s2->d = s1->d; - - s1->b = ab; - s1->c = abbc; - s1->d = final; -} - -/* Return an upper bound on the error (squared) that could result from - * approximating a spline as a line segment connecting the two endpoints. */ -static double -_cairo_spline_error_squared (const cairo_spline_knots_t *knots) -{ - double bdx, bdy, berr; - double cdx, cdy, cerr; - - /* We are going to compute the distance (squared) between each of the the b - * and c control points and the segment a-b. The maximum of these two - * distances will be our approximation error. */ - - bdx = _cairo_fixed_to_double (knots->b.x - knots->a.x); - bdy = _cairo_fixed_to_double (knots->b.y - knots->a.y); - - cdx = _cairo_fixed_to_double (knots->c.x - knots->a.x); - cdy = _cairo_fixed_to_double (knots->c.y - knots->a.y); - - if (knots->a.x != knots->d.x || knots->a.y != knots->d.y) { - /* Intersection point (px): - * px = p1 + u(p2 - p1) - * (p - px) ∙ (p2 - p1) = 0 - * Thus: - * u = ((p - p1) ∙ (p2 - p1)) / ∥p2 - p1∥²; - */ - - double dx, dy, u, v; - - dx = _cairo_fixed_to_double (knots->d.x - knots->a.x); - dy = _cairo_fixed_to_double (knots->d.y - knots->a.y); - v = dx * dx + dy * dy; - - u = bdx * dx + bdy * dy; - if (u <= 0) { - /* bdx -= 0; - * bdy -= 0; - */ - } else if (u >= v) { - bdx -= dx; - bdy -= dy; - } else { - bdx -= u/v * dx; - bdy -= u/v * dy; - } - - u = cdx * dx + cdy * dy; - if (u <= 0) { - /* cdx -= 0; - * cdy -= 0; - */ - } else if (u >= v) { - cdx -= dx; - cdy -= dy; - } else { - cdx -= u/v * dx; - cdy -= u/v * dy; - } - } - - berr = bdx * bdx + bdy * bdy; - cerr = cdx * cdx + cdy * cdy; - if (berr > cerr) - return berr; - else - return cerr; -} - -static cairo_status_t -_cairo_spline_decompose_into (cairo_spline_knots_t *s1, - double tolerance_squared, - cairo_spline_t *result) -{ - cairo_spline_knots_t s2; - cairo_status_t status; - - if (_cairo_spline_error_squared (s1) < tolerance_squared) - return _cairo_spline_add_point (result, &s1->a, &s1->b); - - _de_casteljau (s1, &s2); - - status = _cairo_spline_decompose_into (s1, tolerance_squared, result); - if (unlikely (status)) - return status; - - return _cairo_spline_decompose_into (&s2, tolerance_squared, result); -} - -cairo_status_t -_cairo_spline_decompose (cairo_spline_t *spline, double tolerance) -{ - cairo_spline_knots_t s1; - cairo_status_t status; - - s1 = spline->knots; - spline->last_point = s1.a; - status = _cairo_spline_decompose_into (&s1, tolerance * tolerance, spline); - if (unlikely (status)) - return status; - - return spline->add_point_func (spline->closure, - &spline->knots.d, &spline->final_slope); -} - -/* Note: this function is only good for computing bounds in device space. */ -cairo_status_t -_cairo_spline_bound (cairo_spline_add_point_func_t add_point_func, - void *closure, - const cairo_point_t *p0, const cairo_point_t *p1, - const cairo_point_t *p2, const cairo_point_t *p3) -{ - double x0, x1, x2, x3; - double y0, y1, y2, y3; - double a, b, c; - double t[4]; - int t_num = 0, i; - cairo_status_t status; - - x0 = _cairo_fixed_to_double (p0->x); - y0 = _cairo_fixed_to_double (p0->y); - x1 = _cairo_fixed_to_double (p1->x); - y1 = _cairo_fixed_to_double (p1->y); - x2 = _cairo_fixed_to_double (p2->x); - y2 = _cairo_fixed_to_double (p2->y); - x3 = _cairo_fixed_to_double (p3->x); - y3 = _cairo_fixed_to_double (p3->y); - - /* The spline can be written as a polynomial of the four points: - * - * (1-t)³p0 + 3t(1-t)²p1 + 3t²(1-t)p2 + t³p3 - * - * for 0≤t≤1. Now, the X and Y components of the spline follow the - * same polynomial but with x and y replaced for p. To find the - * bounds of the spline, we just need to find the X and Y bounds. - * To find the bound, we take the derivative and equal it to zero, - * and solve to find the t's that give the extreme points. - * - * Here is the derivative of the curve, sorted on t: - * - * 3t²(-p0+3p1-3p2+p3) + 2t(3p0-6p1+3p2) -3p0+3p1 - * - * Let: - * - * a = -p0+3p1-3p2+p3 - * b = p0-2p1+p2 - * c = -p0+p1 - * - * Gives: - * - * a.t² + 2b.t + c = 0 - * - * With: - * - * delta = b*b - a*c - * - * the extreme points are at -c/2b if a is zero, at (-b±√delta)/a if - * delta is positive, and at -b/a if delta is zero. - */ - -#define ADD(t0) \ - { \ - double _t0 = (t0); \ - if (0 < _t0 && _t0 < 1) \ - t[t_num++] = _t0; \ - } - -#define FIND_EXTREMES(a,b,c) \ - { \ - if (a == 0) { \ - if (b != 0) \ - ADD (-c / (2*b)); \ - } else { \ - double b2 = b * b; \ - double delta = b2 - a * c; \ - if (delta > 0) { \ - cairo_bool_t feasible; \ - double _2ab = 2 * a * b; \ - /* We are only interested in solutions t that satisfy 0<t<1 \ - * here. We do some checks to avoid sqrt if the solutions \ - * are not in that range. The checks can be derived from: \ - * \ - * 0 < (-b±√delta)/a < 1 \ - */ \ - if (_2ab >= 0) \ - feasible = delta > b2 && delta < a*a + b2 + _2ab; \ - else if (-b / a >= 1) \ - feasible = delta < b2 && delta > a*a + b2 + _2ab; \ - else \ - feasible = delta < b2 || delta < a*a + b2 + _2ab; \ - \ - if (unlikely (feasible)) { \ - double sqrt_delta = sqrt (delta); \ - ADD ((-b - sqrt_delta) / a); \ - ADD ((-b + sqrt_delta) / a); \ - } \ - } else if (delta == 0) { \ - ADD (-b / a); \ - } \ - } \ - } - - /* Find X extremes */ - a = -x0 + 3*x1 - 3*x2 + x3; - b = x0 - 2*x1 + x2; - c = -x0 + x1; - FIND_EXTREMES (a, b, c); - - /* Find Y extremes */ - a = -y0 + 3*y1 - 3*y2 + y3; - b = y0 - 2*y1 + y2; - c = -y0 + y1; - FIND_EXTREMES (a, b, c); - - status = add_point_func (closure, p0, NULL); - if (unlikely (status)) - return status; - - for (i = 0; i < t_num; i++) { - cairo_point_t p; - double x, y; - double t_1_0, t_0_1; - double t_2_0, t_0_2; - double t_3_0, t_2_1_3, t_1_2_3, t_0_3; - - t_1_0 = t[i]; /* t */ - t_0_1 = 1 - t_1_0; /* (1 - t) */ - - t_2_0 = t_1_0 * t_1_0; /* t * t */ - t_0_2 = t_0_1 * t_0_1; /* (1 - t) * (1 - t) */ - - t_3_0 = t_2_0 * t_1_0; /* t * t * t */ - t_2_1_3 = t_2_0 * t_0_1 * 3; /* t * t * (1 - t) * 3 */ - t_1_2_3 = t_1_0 * t_0_2 * 3; /* t * (1 - t) * (1 - t) * 3 */ - t_0_3 = t_0_1 * t_0_2; /* (1 - t) * (1 - t) * (1 - t) */ - - /* Bezier polynomial */ - x = x0 * t_0_3 - + x1 * t_1_2_3 - + x2 * t_2_1_3 - + x3 * t_3_0; - y = y0 * t_0_3 - + y1 * t_1_2_3 - + y2 * t_2_1_3 - + y3 * t_3_0; - - p.x = _cairo_fixed_from_double (x); - p.y = _cairo_fixed_from_double (y); - status = add_point_func (closure, &p, NULL); - if (unlikely (status)) - return status; - } - - return add_point_func (closure, p3, NULL); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-stroke-dash-private.h b/source/libs/cairo/cairo-src/src/cairo-stroke-dash-private.h deleted file mode 100644 index 75c000cd73a7e4f7f3698736407a1a061fa9ab6a..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-stroke-dash-private.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_STROKE_DASH_PRIVATE_H -#define CAIRO_STROKE_DASH_PRIVATE_H - -#include "cairoint.h" - -CAIRO_BEGIN_DECLS - -typedef struct _cairo_stroker_dash { - cairo_bool_t dashed; - unsigned int dash_index; - cairo_bool_t dash_on; - cairo_bool_t dash_starts_on; - double dash_remain; - - double dash_offset; - const double *dashes; - unsigned int num_dashes; -} cairo_stroker_dash_t; - -cairo_private void -_cairo_stroker_dash_init (cairo_stroker_dash_t *dash, - const cairo_stroke_style_t *style); - -cairo_private void -_cairo_stroker_dash_start (cairo_stroker_dash_t *dash); - -cairo_private void -_cairo_stroker_dash_step (cairo_stroker_dash_t *dash, double step); - -CAIRO_END_DECLS - -#endif /* CAIRO_STROKE_DASH_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-stroke-dash.c b/source/libs/cairo/cairo-src/src/cairo-stroke-dash.c deleted file mode 100644 index 9494010f5613a46eee616b73575fb2ba0cfe44b0..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-stroke-dash.c +++ /dev/null @@ -1,96 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-stroke-dash-private.h" - -void -_cairo_stroker_dash_start (cairo_stroker_dash_t *dash) -{ - double offset; - cairo_bool_t on = TRUE; - unsigned int i = 0; - - if (! dash->dashed) - return; - - offset = dash->dash_offset; - - /* We stop searching for a starting point as soon as the - offset reaches zero. Otherwise when an initial dash - segment shrinks to zero it will be skipped over. */ - while (offset > 0.0 && offset >= dash->dashes[i]) { - offset -= dash->dashes[i]; - on = !on; - if (++i == dash->num_dashes) - i = 0; - } - - dash->dash_index = i; - dash->dash_on = dash->dash_starts_on = on; - dash->dash_remain = dash->dashes[i] - offset; -} - -void -_cairo_stroker_dash_step (cairo_stroker_dash_t *dash, double step) -{ - dash->dash_remain -= step; - if (dash->dash_remain < CAIRO_FIXED_ERROR_DOUBLE) { - if (++dash->dash_index == dash->num_dashes) - dash->dash_index = 0; - - dash->dash_on = ! dash->dash_on; - dash->dash_remain += dash->dashes[dash->dash_index]; - } -} - -void -_cairo_stroker_dash_init (cairo_stroker_dash_t *dash, - const cairo_stroke_style_t *style) -{ - dash->dashed = style->dash != NULL; - if (! dash->dashed) - return; - - dash->dashes = style->dash; - dash->num_dashes = style->num_dashes; - dash->dash_offset = style->dash_offset; - - _cairo_stroker_dash_start (dash); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-stroke-style.c b/source/libs/cairo/cairo-src/src/cairo-stroke-style.c deleted file mode 100644 index 51c9414c042b8a494701cf2394d384be84c0b688..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-stroke-style.c +++ /dev/null @@ -1,354 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Carl Worth <cworth@cworth.org> - */ - -#include "cairoint.h" -#include "cairo-error-private.h" - -void -_cairo_stroke_style_init (cairo_stroke_style_t *style) -{ - VG (VALGRIND_MAKE_MEM_UNDEFINED (style, sizeof (cairo_stroke_style_t))); - - style->line_width = CAIRO_GSTATE_LINE_WIDTH_DEFAULT; - style->line_cap = CAIRO_GSTATE_LINE_CAP_DEFAULT; - style->line_join = CAIRO_GSTATE_LINE_JOIN_DEFAULT; - style->miter_limit = CAIRO_GSTATE_MITER_LIMIT_DEFAULT; - - style->dash = NULL; - style->num_dashes = 0; - style->dash_offset = 0.0; -} - -cairo_status_t -_cairo_stroke_style_init_copy (cairo_stroke_style_t *style, - const cairo_stroke_style_t *other) -{ - if (CAIRO_INJECT_FAULT ()) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - VG (VALGRIND_MAKE_MEM_UNDEFINED (style, sizeof (cairo_stroke_style_t))); - - style->line_width = other->line_width; - style->line_cap = other->line_cap; - style->line_join = other->line_join; - style->miter_limit = other->miter_limit; - - style->num_dashes = other->num_dashes; - - if (other->dash == NULL) { - style->dash = NULL; - } else { - style->dash = _cairo_malloc_ab (style->num_dashes, sizeof (double)); - if (unlikely (style->dash == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - memcpy (style->dash, other->dash, - style->num_dashes * sizeof (double)); - } - - style->dash_offset = other->dash_offset; - - return CAIRO_STATUS_SUCCESS; -} - -void -_cairo_stroke_style_fini (cairo_stroke_style_t *style) -{ - free (style->dash); - style->dash = NULL; - - style->num_dashes = 0; - - VG (VALGRIND_MAKE_MEM_NOACCESS (style, sizeof (cairo_stroke_style_t))); -} - -/* - * For a stroke in the given style, compute the maximum distance - * from the path that vertices could be generated. In the case - * of rotation in the ctm, the distance will not be exact. - */ -void -_cairo_stroke_style_max_distance_from_path (const cairo_stroke_style_t *style, - const cairo_path_fixed_t *path, - const cairo_matrix_t *ctm, - double *dx, double *dy) -{ - double style_expansion = 0.5; - - if (style->line_cap == CAIRO_LINE_CAP_SQUARE) - style_expansion = M_SQRT1_2; - - if (style->line_join == CAIRO_LINE_JOIN_MITER && - ! path->stroke_is_rectilinear && - style_expansion < M_SQRT2 * style->miter_limit) - { - style_expansion = M_SQRT2 * style->miter_limit; - } - - style_expansion *= style->line_width; - - if (_cairo_matrix_has_unity_scale (ctm)) { - *dx = *dy = style_expansion; - } else { - *dx = style_expansion * hypot (ctm->xx, ctm->xy); - *dy = style_expansion * hypot (ctm->yy, ctm->yx); - } -} - -void -_cairo_stroke_style_max_line_distance_from_path (const cairo_stroke_style_t *style, - const cairo_path_fixed_t *path, - const cairo_matrix_t *ctm, - double *dx, double *dy) -{ - double style_expansion = 0.5 * style->line_width; - if (_cairo_matrix_has_unity_scale (ctm)) { - *dx = *dy = style_expansion; - } else { - *dx = style_expansion * hypot (ctm->xx, ctm->xy); - *dy = style_expansion * hypot (ctm->yy, ctm->yx); - } -} - -void -_cairo_stroke_style_max_join_distance_from_path (const cairo_stroke_style_t *style, - const cairo_path_fixed_t *path, - const cairo_matrix_t *ctm, - double *dx, double *dy) -{ - double style_expansion = 0.5; - - if (style->line_join == CAIRO_LINE_JOIN_MITER && - ! path->stroke_is_rectilinear && - style_expansion < M_SQRT2 * style->miter_limit) - { - style_expansion = M_SQRT2 * style->miter_limit; - } - - style_expansion *= style->line_width; - - if (_cairo_matrix_has_unity_scale (ctm)) { - *dx = *dy = style_expansion; - } else { - *dx = style_expansion * hypot (ctm->xx, ctm->xy); - *dy = style_expansion * hypot (ctm->yy, ctm->yx); - } -} -/* - * Computes the period of a dashed stroke style. - * Returns 0 for non-dashed styles. - */ -double -_cairo_stroke_style_dash_period (const cairo_stroke_style_t *style) -{ - double period; - unsigned int i; - - period = 0.0; - for (i = 0; i < style->num_dashes; i++) - period += style->dash[i]; - - if (style->num_dashes & 1) - period *= 2.0; - - return period; -} - -/* - * Coefficient of the linear approximation (minimizing square difference) - * of the surface covered by round caps - * - * This can be computed in the following way: - * the area inside the circle with radius w/2 and the region -d/2 <= x <= d/2 is: - * f(w,d) = 2 * integrate (sqrt (w*w/4 - x*x), x, -d/2, d/2) - * The square difference to a generic linear approximation (c*d) in the range (0,w) would be: - * integrate ((f(w,d) - c*d)^2, d, 0, w) - * To minimize this difference it is sufficient to find a solution of the differential with - * respect to c: - * solve ( diff (integrate ((f(w,d) - c*d)^2, d, 0, w), c), c) - * Which leads to c = 9/32*pi*w - * Since we're not interested in the true area, but just in a coverage extimate, - * we always divide the real area by the line width (w). - * The same computation for square caps would be - * f(w,d) = 2 * integrate(w/2, x, -d/2, d/2) - * c = 1*w - * but in this case it would not be an approximation, since f is already linear in d. - */ -#define ROUND_MINSQ_APPROXIMATION (9*M_PI/32) - -/* - * Computes the length of the "on" part of a dashed stroke style, - * taking into account also line caps. - * Returns 0 for non-dashed styles. - */ -double -_cairo_stroke_style_dash_stroked (const cairo_stroke_style_t *style) -{ - double stroked, cap_scale; - unsigned int i; - - switch (style->line_cap) { - default: ASSERT_NOT_REACHED; - case CAIRO_LINE_CAP_BUTT: cap_scale = 0.0; break; - case CAIRO_LINE_CAP_ROUND: cap_scale = ROUND_MINSQ_APPROXIMATION; break; - case CAIRO_LINE_CAP_SQUARE: cap_scale = 1.0; break; - } - - stroked = 0.0; - if (style->num_dashes & 1) { - /* Each dash element is used both as on and as off. The order in which they are summed is - * irrelevant, so sum the coverage of one dash element, taken both on and off at each iteration */ - for (i = 0; i < style->num_dashes; i++) - stroked += style->dash[i] + cap_scale * MIN (style->dash[i], style->line_width); - } else { - /* Even (0, 2, ...) dashes are on and simply counted for the coverage, odd dashes are off, thus - * their coverage is approximated based on the area covered by the caps of adjacent on dases. */ - for (i = 0; i + 1 < style->num_dashes; i += 2) - stroked += style->dash[i] + cap_scale * MIN (style->dash[i+1], style->line_width); - } - - return stroked; -} - -/* - * Verifies if _cairo_stroke_style_dash_approximate should be used to generate - * an approximation of the dash pattern in the specified style, when used for - * stroking a path with the given CTM and tolerance. - * Always %FALSE for non-dashed styles. - */ -cairo_bool_t -_cairo_stroke_style_dash_can_approximate (const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - double tolerance) -{ - double period; - - if (! style->num_dashes) - return FALSE; - - period = _cairo_stroke_style_dash_period (style); - return _cairo_matrix_transformed_circle_major_axis (ctm, period) < tolerance; -} - -/* - * Create a 2-dashes approximation of a dashed style, by making the "on" and "off" - * parts respect the original ratio. - */ -void -_cairo_stroke_style_dash_approximate (const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - double tolerance, - double *dash_offset, - double *dashes, - unsigned int *num_dashes) -{ - double coverage, scale, offset; - cairo_bool_t on = TRUE; - unsigned int i = 0; - - coverage = _cairo_stroke_style_dash_stroked (style) / _cairo_stroke_style_dash_period (style); - coverage = MIN (coverage, 1.0); - scale = tolerance / _cairo_matrix_transformed_circle_major_axis (ctm, 1.0); - - /* We stop searching for a starting point as soon as the - * offset reaches zero. Otherwise when an initial dash - * segment shrinks to zero it will be skipped over. */ - offset = style->dash_offset; - while (offset > 0.0 && offset >= style->dash[i]) { - offset -= style->dash[i]; - on = !on; - if (++i == style->num_dashes) - i = 0; - } - - *num_dashes = 2; - - /* - * We want to create a new dash pattern with the same relative coverage, - * but composed of just 2 elements with total length equal to scale. - * Based on the formula in _cairo_stroke_style_dash_stroked: - * scale * coverage = dashes[0] + cap_scale * MIN (dashes[1], line_width) - * = MIN (dashes[0] + cap_scale * (scale - dashes[0]), - * dashes[0] + cap_scale * line_width) = - * = MIN (dashes[0] * (1 - cap_scale) + cap_scale * scale, - * dashes[0] + cap_scale * line_width) - * - * Solving both cases we get: - * dashes[0] = scale * (coverage - cap_scale) / (1 - cap_scale) - * when scale - dashes[0] <= line_width - * dashes[0] = scale * coverage - cap_scale * line_width - * when scale - dashes[0] > line_width. - * - * Comparing the two cases we get: - * second > first - * second > scale * (coverage - cap_scale) / (1 - cap_scale) - * second - cap_scale * second - scale * coverage + scale * cap_scale > 0 - * (scale * coverage - cap_scale * line_width) - cap_scale * second - scale * coverage + scale * cap_scale > 0 - * - line_width - second + scale > 0 - * scale - second > line_width - * which is the condition for the second solution to be the valid one. - * So when second > first, the second solution is the correct one (i.e. - * the solution is always MAX (first, second). - */ - switch (style->line_cap) { - default: - ASSERT_NOT_REACHED; - dashes[0] = 0.0; - break; - - case CAIRO_LINE_CAP_BUTT: - /* Simplified formula (substituting 0 for cap_scale): */ - dashes[0] = scale * coverage; - break; - - case CAIRO_LINE_CAP_ROUND: - dashes[0] = MAX(scale * (coverage - ROUND_MINSQ_APPROXIMATION) / (1.0 - ROUND_MINSQ_APPROXIMATION), - scale * coverage - ROUND_MINSQ_APPROXIMATION * style->line_width); - break; - - case CAIRO_LINE_CAP_SQUARE: - /* - * Special attention is needed to handle the case cap_scale == 1 (since the first solution - * is either indeterminate or -inf in this case). Since dash lengths are always >=0, using - * 0 as first solution always leads to the correct solution. - */ - dashes[0] = MAX(0.0, scale * coverage - style->line_width); - break; - } - - dashes[1] = scale - dashes[0]; - - *dash_offset = on ? 0.0 : dashes[0]; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-surface-backend-private.h b/source/libs/cairo/cairo-src/src/cairo-surface-backend-private.h deleted file mode 100644 index 955a79ff5c3ddff6455fc6b89f726bda15baa39e..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-surface-backend-private.h +++ /dev/null @@ -1,221 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - */ - -#ifndef CAIRO_SURFACE_BACKEND_PRIVATE_H -#define CAIRO_SURFACE_BACKEND_PRIVATE_H - -#include "cairo-compiler-private.h" -#include "cairo-error-private.h" - -CAIRO_BEGIN_DECLS - -struct _cairo_surface_backend { - cairo_surface_type_t type; - - cairo_warn cairo_status_t - (*finish) (void *surface); - - cairo_t * - (*create_context) (void *surface); - - cairo_surface_t * - (*create_similar) (void *surface, - cairo_content_t content, - int width, - int height); - cairo_surface_t * - (*create_similar_image) (void *surface, - cairo_format_t format, - int width, - int height); - - cairo_image_surface_t * - (*map_to_image) (void *surface, - const cairo_rectangle_int_t *extents); - cairo_int_status_t - (*unmap_image) (void *surface, - cairo_image_surface_t *image); - - cairo_surface_t * - (*source) (void *abstract_surface, - cairo_rectangle_int_t *extents); - - cairo_warn cairo_status_t - (*acquire_source_image) (void *abstract_surface, - cairo_image_surface_t **image_out, - void **image_extra); - - cairo_warn void - (*release_source_image) (void *abstract_surface, - cairo_image_surface_t *image_out, - void *image_extra); - - cairo_surface_t * - (*snapshot) (void *surface); - - cairo_warn cairo_int_status_t - (*copy_page) (void *surface); - - cairo_warn cairo_int_status_t - (*show_page) (void *surface); - - /* Get the extents of the current surface. For many surface types - * this will be as simple as { x=0, y=0, width=surface->width, - * height=surface->height}. - * - * If this function is not implemented, or if it returns - * FALSE the surface is considered to be - * boundless and infinite bounds are used for it. - */ - cairo_bool_t - (*get_extents) (void *surface, - cairo_rectangle_int_t *extents); - - void - (*get_font_options) (void *surface, - cairo_font_options_t *options); - - cairo_warn cairo_status_t - (*flush) (void *surface, - unsigned flags); - - cairo_warn cairo_status_t - (*mark_dirty_rectangle) (void *surface, - int x, - int y, - int width, - int height); - - cairo_warn cairo_int_status_t - (*paint) (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip); - - cairo_warn cairo_int_status_t - (*mask) (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip); - - cairo_warn cairo_int_status_t - (*stroke) (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip); - - cairo_warn cairo_int_status_t - (*fill) (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip); - - cairo_warn cairo_int_status_t - (*fill_stroke) (void *surface, - cairo_operator_t fill_op, - const cairo_pattern_t *fill_source, - cairo_fill_rule_t fill_rule, - double fill_tolerance, - cairo_antialias_t fill_antialias, - const cairo_path_fixed_t*path, - cairo_operator_t stroke_op, - const cairo_pattern_t *stroke_source, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *stroke_ctm, - const cairo_matrix_t *stroke_ctm_inverse, - double stroke_tolerance, - cairo_antialias_t stroke_antialias, - const cairo_clip_t *clip); - - cairo_warn cairo_int_status_t - (*show_glyphs) (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip); - - cairo_bool_t - (*has_show_text_glyphs) (void *surface); - - cairo_warn cairo_int_status_t - (*show_text_glyphs) (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const char *utf8, - int utf8_len, - cairo_glyph_t *glyphs, - int num_glyphs, - const cairo_text_cluster_t *clusters, - int num_clusters, - cairo_text_cluster_flags_t cluster_flags, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip); - - const char ** - (*get_supported_mime_types) (void *surface); -}; - -cairo_private cairo_status_t -_cairo_surface_default_acquire_source_image (void *surface, - cairo_image_surface_t **image_out, - void **image_extra); - -cairo_private void -_cairo_surface_default_release_source_image (void *surface, - cairo_image_surface_t *image, - void *image_extra); - -cairo_private cairo_surface_t * -_cairo_surface_default_source (void *surface, - cairo_rectangle_int_t *extents); - -CAIRO_END_DECLS - -#endif /* CAIRO_SURFACE_BACKEND_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-surface-clipper-private.h b/source/libs/cairo/cairo-src/src/cairo-surface-clipper-private.h deleted file mode 100644 index e5b00af7c66afd129142b6f63981554282500567..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-surface-clipper-private.h +++ /dev/null @@ -1,71 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.u> - */ - -#ifndef CAIRO_SURFACE_CLIPPER_PRIVATE_H -#define CAIRO_SURFACE_CLIPPER_PRIVATE_H - -#include "cairo-types-private.h" -#include "cairo-clip-private.h" - -CAIRO_BEGIN_DECLS - -typedef struct _cairo_surface_clipper cairo_surface_clipper_t; - -typedef cairo_status_t -(*cairo_surface_clipper_intersect_clip_path_func_t) (cairo_surface_clipper_t *, - cairo_path_fixed_t *, - cairo_fill_rule_t, - double, - cairo_antialias_t); -struct _cairo_surface_clipper { - cairo_clip_t *clip; - cairo_surface_clipper_intersect_clip_path_func_t intersect_clip_path; -}; - -cairo_private cairo_status_t -_cairo_surface_clipper_set_clip (cairo_surface_clipper_t *clipper, - const cairo_clip_t *clip); - -cairo_private void -_cairo_surface_clipper_init (cairo_surface_clipper_t *clipper, - cairo_surface_clipper_intersect_clip_path_func_t intersect); - -cairo_private void -_cairo_surface_clipper_reset (cairo_surface_clipper_t *clipper); - -CAIRO_END_DECLS - -#endif /* CAIRO_SURFACE_CLIPPER_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-surface-clipper.c b/source/libs/cairo/cairo-src/src/cairo-surface-clipper.c deleted file mode 100644 index 5309362c68f3940d4960b7e8337b78720bf2a715..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-surface-clipper.c +++ /dev/null @@ -1,196 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-clip-inline.h" -#include "cairo-surface-clipper-private.h" - -/* A collection of routines to facilitate vector surface clipping */ - -/* XXX Eliminate repeated paths and nested clips */ - -static cairo_status_t -_cairo_path_fixed_add_box (cairo_path_fixed_t *path, - const cairo_box_t *box) -{ - cairo_status_t status; - - status = _cairo_path_fixed_move_to (path, box->p1.x, box->p1.y); - if (unlikely (status)) - return status; - - status = _cairo_path_fixed_line_to (path, box->p2.x, box->p1.y); - if (unlikely (status)) - return status; - - status = _cairo_path_fixed_line_to (path, box->p2.x, box->p2.y); - if (unlikely (status)) - return status; - - status = _cairo_path_fixed_line_to (path, box->p1.x, box->p2.y); - if (unlikely (status)) - return status; - - return _cairo_path_fixed_close_path (path); -} - -static cairo_status_t -_cairo_surface_clipper_intersect_clip_boxes (cairo_surface_clipper_t *clipper, - const cairo_clip_t *clip) -{ - cairo_path_fixed_t path; - cairo_status_t status; - int i; - - if (clip->num_boxes == 0) - return CAIRO_STATUS_SUCCESS; - - /* Reconstruct the path for the clip boxes. - * XXX maybe a new clipper callback? - */ - - _cairo_path_fixed_init (&path); - for (i = 0; i < clip->num_boxes; i++) { - status = _cairo_path_fixed_add_box (&path, &clip->boxes[i]); - if (unlikely (status)) { - _cairo_path_fixed_fini (&path); - return status; - } - } - - status = clipper->intersect_clip_path (clipper, &path, - CAIRO_FILL_RULE_WINDING, - 0., - CAIRO_ANTIALIAS_DEFAULT); - _cairo_path_fixed_fini (&path); - - return status; -} - -static cairo_status_t -_cairo_surface_clipper_intersect_clip_path_recursive (cairo_surface_clipper_t *clipper, - cairo_clip_path_t *clip_path, - cairo_clip_path_t *end) -{ - cairo_status_t status; - - if (clip_path->prev != end) { - status = - _cairo_surface_clipper_intersect_clip_path_recursive (clipper, - clip_path->prev, - end); - if (unlikely (status)) - return status; - } - - return clipper->intersect_clip_path (clipper, - &clip_path->path, - clip_path->fill_rule, - clip_path->tolerance, - clip_path->antialias); -} - -cairo_status_t -_cairo_surface_clipper_set_clip (cairo_surface_clipper_t *clipper, - const cairo_clip_t *clip) -{ - cairo_status_t status; - cairo_bool_t incremental = FALSE; - - if (_cairo_clip_equal (clip, clipper->clip)) - return CAIRO_STATUS_SUCCESS; - - /* all clipped out state should never propagate this far */ - assert (!_cairo_clip_is_all_clipped (clip)); - - /* XXX Is this an incremental clip? */ - if (clipper->clip && clip && - clip->num_boxes == clipper->clip->num_boxes && - memcmp (clip->boxes, clipper->clip->boxes, - sizeof (cairo_box_t) * clip->num_boxes) == 0) - { - cairo_clip_path_t *clip_path = clip->path; - while (clip_path != NULL && clip_path != clipper->clip->path) - clip_path = clip_path->prev; - - if (clip_path) { - incremental = TRUE; - status = _cairo_surface_clipper_intersect_clip_path_recursive (clipper, - clip->path, - clipper->clip->path); - } - } - - _cairo_clip_destroy (clipper->clip); - clipper->clip = _cairo_clip_copy (clip); - - if (incremental) - return status; - - status = clipper->intersect_clip_path (clipper, NULL, 0, 0, 0); - if (unlikely (status)) - return status; - - if (clip == NULL) - return CAIRO_STATUS_SUCCESS; - - status = _cairo_surface_clipper_intersect_clip_boxes (clipper, clip); - if (unlikely (status)) - return status; - - if (clip->path != NULL) { - status = _cairo_surface_clipper_intersect_clip_path_recursive (clipper, - clip->path, - NULL); - } - - return status; -} - -void -_cairo_surface_clipper_init (cairo_surface_clipper_t *clipper, - cairo_surface_clipper_intersect_clip_path_func_t func) -{ - clipper->clip = NULL; - clipper->intersect_clip_path = func; -} - -void -_cairo_surface_clipper_reset (cairo_surface_clipper_t *clipper) -{ - _cairo_clip_destroy (clipper->clip); - clipper->clip = NULL; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-surface-fallback-private.h b/source/libs/cairo/cairo-src/src/cairo-surface-fallback-private.h deleted file mode 100644 index ecf7b0edf2bf2dec8f67c2264384d392c45ab91c..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-surface-fallback-private.h +++ /dev/null @@ -1,95 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Joonas Pihlaja <jpihlaja@cc.helsinki.fi> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_SURFACE_FALLBACK_PRIVATE_H -#define CAIRO_SURFACE_FALLBACK_PRIVATE_H - -#include "cairoint.h" - -CAIRO_BEGIN_DECLS - -cairo_private cairo_int_status_t -_cairo_surface_fallback_paint (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip); - -cairo_private cairo_int_status_t -_cairo_surface_fallback_mask (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip); - -cairo_private cairo_int_status_t -_cairo_surface_fallback_stroke (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t*style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip); - -cairo_private cairo_int_status_t -_cairo_surface_fallback_fill (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip); - -cairo_private cairo_int_status_t -_cairo_surface_fallback_glyphs (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip); - -CAIRO_END_DECLS - -#endif /* CAIRO_SURFACE_FALLBACK_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-surface-fallback.c b/source/libs/cairo/cairo-src/src/cairo-surface-fallback.c deleted file mode 100644 index a0af1596921e23887622b2ba100d86ebb3150aa4..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-surface-fallback.c +++ /dev/null @@ -1,115 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Joonas Pihlaja <jpihlaja@cc.helsinki.fi> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-compositor-private.h" -#include "cairo-surface-fallback-private.h" - -cairo_int_status_t -_cairo_surface_fallback_paint (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - return _cairo_compositor_paint (&_cairo_fallback_compositor, - surface, op, source, clip); -} - -cairo_int_status_t -_cairo_surface_fallback_mask (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - return _cairo_compositor_mask (&_cairo_fallback_compositor, - surface, op, source, mask, clip); -} - -cairo_int_status_t -_cairo_surface_fallback_stroke (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t*path, - const cairo_stroke_style_t*style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - return _cairo_compositor_stroke (&_cairo_fallback_compositor, - surface, op, source, path, - style, ctm,ctm_inverse, - tolerance, antialias, clip); -} - -cairo_int_status_t -_cairo_surface_fallback_fill (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - return _cairo_compositor_fill (&_cairo_fallback_compositor, - surface, op, source, path, - fill_rule, tolerance, antialias, - clip); -} - -cairo_int_status_t -_cairo_surface_fallback_glyphs (void *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - return _cairo_compositor_glyphs (&_cairo_fallback_compositor, - surface, op, source, - glyphs, num_glyphs, scaled_font, - clip); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-surface-inline.h b/source/libs/cairo/cairo-src/src/cairo-surface-inline.h deleted file mode 100644 index 85fbc9192bd9b33fd6e6520c117efee176c0aced..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-surface-inline.h +++ /dev/null @@ -1,60 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - */ - -#ifndef CAIRO_SURFACE_INLINE_H -#define CAIRO_SURFACE_INLINE_H - -#include "cairo-surface-private.h" - -static inline cairo_status_t -__cairo_surface_flush (cairo_surface_t *surface, unsigned flags) -{ - cairo_status_t status = CAIRO_STATUS_SUCCESS; - if (surface->backend->flush) - status = surface->backend->flush (surface, flags); - return status; -} - -static inline cairo_surface_t * -_cairo_surface_reference (cairo_surface_t *surface) -{ - if (!CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count)) - _cairo_reference_count_inc (&surface->ref_count); - return surface; -} - -#endif /* CAIRO_SURFACE_INLINE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-surface-observer-inline.h b/source/libs/cairo/cairo-src/src/cairo-surface-observer-inline.h deleted file mode 100644 index 07b94770d4be6e89455d5fac86c4a72220b82be9..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-surface-observer-inline.h +++ /dev/null @@ -1,59 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Intel Corporation. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_SURFACE_OBSERVER_INLINE_H -#define CAIRO_SURFACE_OBSERVER_INLINE_H - -#include "cairo-surface-observer-private.h" - -static inline cairo_surface_t * -_cairo_surface_observer_get_target (cairo_surface_t *surface) -{ - return ((cairo_surface_observer_t *) surface)->target; -} - -static inline cairo_bool_t -_cairo_surface_is_observer (cairo_surface_t *surface) -{ - return surface->backend->type == (cairo_surface_type_t)CAIRO_INTERNAL_SURFACE_TYPE_OBSERVER; -} - -static inline cairo_bool_t -_cairo_device_is_observer (cairo_device_t *device) -{ - return device->backend->type == (cairo_device_type_t)CAIRO_INTERNAL_DEVICE_TYPE_OBSERVER; -} - -#endif /* CAIRO_SURFACE_OBSERVER_INLINE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-surface-observer-private.h b/source/libs/cairo/cairo-src/src/cairo-surface-observer-private.h deleted file mode 100644 index 6ed0c18d17c27aa817d3bed81aeaab8b84c62f4c..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-surface-observer-private.h +++ /dev/null @@ -1,208 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Intel Corporation. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_SURFACE_OBSERVER_PRIVATE_H -#define CAIRO_SURFACE_OBSERVER_PRIVATE_H - -#include "cairoint.h" - -#include "cairo-device-private.h" -#include "cairo-list-private.h" -#include "cairo-recording-surface-private.h" -#include "cairo-surface-private.h" -#include "cairo-surface-backend-private.h" -#include "cairo-time-private.h" - -struct stat { - double min, max, sum, sum_sq; - unsigned count; -}; - -#define NUM_OPERATORS (CAIRO_OPERATOR_HSL_LUMINOSITY+1) -#define NUM_CAPS (CAIRO_LINE_CAP_SQUARE+1) -#define NUM_JOINS (CAIRO_LINE_JOIN_BEVEL+1) -#define NUM_ANTIALIAS (CAIRO_ANTIALIAS_BEST+1) -#define NUM_FILL_RULE (CAIRO_FILL_RULE_EVEN_ODD+1) - -struct extents { - struct stat area; - unsigned int bounded, unbounded; -}; - -struct pattern { - unsigned int type[8]; /* native/record/other surface/gradients */ -}; - -struct path { - unsigned int type[5]; /* empty/pixel/rectilinear/straight/curved */ -}; - -struct clip { - unsigned int type[6]; /* none, region, boxes, single path, polygon, general */ -}; - -typedef struct _cairo_observation cairo_observation_t; -typedef struct _cairo_observation_record cairo_observation_record_t; -typedef struct _cairo_device_observer cairo_device_observer_t; - -struct _cairo_observation_record { - cairo_content_t target_content; - int target_width; - int target_height; - - int index; - cairo_operator_t op; - int source; - int mask; - int num_glyphs; - int path; - int fill_rule; - double tolerance; - int antialias; - int clip; - cairo_time_t elapsed; -}; - -struct _cairo_observation { - int num_surfaces; - int num_contexts; - int num_sources_acquired; - - /* XXX put interesting stats here! */ - - struct paint { - cairo_time_t elapsed; - unsigned int count; - struct extents extents; - unsigned int operators[NUM_OPERATORS]; - struct pattern source; - struct clip clip; - unsigned int noop; - - cairo_observation_record_t slowest; - } paint; - - struct mask { - cairo_time_t elapsed; - unsigned int count; - struct extents extents; - unsigned int operators[NUM_OPERATORS]; - struct pattern source; - struct pattern mask; - struct clip clip; - unsigned int noop; - - cairo_observation_record_t slowest; - } mask; - - struct fill { - cairo_time_t elapsed; - unsigned int count; - struct extents extents; - unsigned int operators[NUM_OPERATORS]; - struct pattern source; - struct path path; - unsigned int antialias[NUM_ANTIALIAS]; - unsigned int fill_rule[NUM_FILL_RULE]; - struct clip clip; - unsigned int noop; - - cairo_observation_record_t slowest; - } fill; - - struct stroke { - cairo_time_t elapsed; - unsigned int count; - struct extents extents; - unsigned int operators[NUM_OPERATORS]; - unsigned int caps[NUM_CAPS]; - unsigned int joins[NUM_CAPS]; - unsigned int antialias[NUM_ANTIALIAS]; - struct pattern source; - struct path path; - struct stat line_width; - struct clip clip; - unsigned int noop; - - cairo_observation_record_t slowest; - } stroke; - - struct glyphs { - cairo_time_t elapsed; - unsigned int count; - struct extents extents; - unsigned int operators[NUM_OPERATORS]; - struct pattern source; - struct clip clip; - unsigned int noop; - - cairo_observation_record_t slowest; - } glyphs; - - cairo_array_t timings; - cairo_recording_surface_t *record; -}; - -struct _cairo_device_observer { - cairo_device_t base; - cairo_device_t *target; - - cairo_observation_t log; -}; - -struct callback_list { - cairo_list_t link; - - cairo_surface_observer_callback_t func; - void *data; -}; - -struct _cairo_surface_observer { - cairo_surface_t base; - cairo_surface_t *target; - - cairo_observation_t log; - - cairo_list_t paint_callbacks; - cairo_list_t mask_callbacks; - cairo_list_t fill_callbacks; - cairo_list_t stroke_callbacks; - cairo_list_t glyphs_callbacks; - - cairo_list_t flush_callbacks; - cairo_list_t finish_callbacks; -}; - -#endif /* CAIRO_SURFACE_OBSERVER_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-surface-observer.c b/source/libs/cairo/cairo-src/src/cairo-surface-observer.c deleted file mode 100644 index e6f78e6da6f04b62157d8abbe80f697873f694cf..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-surface-observer.c +++ /dev/null @@ -1,2104 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Intel Corporation. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-surface-observer-private.h" -#include "cairo-surface-observer-inline.h" - -#include "cairo-array-private.h" -#include "cairo-combsort-inline.h" -#include "cairo-composite-rectangles-private.h" -#include "cairo-error-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-list-inline.h" -#include "cairo-pattern-private.h" -#include "cairo-output-stream-private.h" -#include "cairo-recording-surface-private.h" -#include "cairo-surface-subsurface-inline.h" -#include "cairo-reference-count-private.h" - -#if CAIRO_HAS_SCRIPT_SURFACE -#include "cairo-script-private.h" -#endif - -static const cairo_surface_backend_t _cairo_surface_observer_backend; - -/* observation/stats */ - -static void init_stats (struct stat *s) -{ - s->min = HUGE_VAL; - s->max = -HUGE_VAL; -} - -static void init_extents (struct extents *e) -{ - init_stats (&e->area); -} - -static void init_pattern (struct pattern *p) -{ -} - -static void init_path (struct path *p) -{ -} - -static void init_clip (struct clip *c) -{ -} - -static void init_paint (struct paint *p) -{ - init_extents (&p->extents); - init_pattern (&p->source); - init_clip (&p->clip); -} - -static void init_mask (struct mask *m) -{ - init_extents (&m->extents); - init_pattern (&m->source); - init_pattern (&m->mask); - init_clip (&m->clip); -} - -static void init_fill (struct fill *f) -{ - init_extents (&f->extents); - init_pattern (&f->source); - init_path (&f->path); - init_clip (&f->clip); -} - -static void init_stroke (struct stroke *s) -{ - init_extents (&s->extents); - init_pattern (&s->source); - init_path (&s->path); - init_clip (&s->clip); -} - -static void init_glyphs (struct glyphs *g) -{ - init_extents (&g->extents); - init_pattern (&g->source); - init_clip (&g->clip); -} - -static cairo_status_t -log_init (cairo_observation_t *log, - cairo_bool_t record) -{ - memset (log, 0, sizeof(*log)); - - init_paint (&log->paint); - init_mask (&log->mask); - init_fill (&log->fill); - init_stroke (&log->stroke); - init_glyphs (&log->glyphs); - - _cairo_array_init (&log->timings, sizeof (cairo_observation_record_t)); - - if (record) { - log->record = (cairo_recording_surface_t *) - cairo_recording_surface_create (CAIRO_CONTENT_COLOR_ALPHA, NULL); - if (unlikely (log->record->base.status)) - return log->record->base.status; - - log->record->optimize_clears = FALSE; - } - - return CAIRO_STATUS_SUCCESS; -} - -static void -log_fini (cairo_observation_t *log) -{ - _cairo_array_fini (&log->timings); - cairo_surface_destroy (&log->record->base); -} - -static cairo_surface_t* -get_pattern_surface (const cairo_pattern_t *pattern) -{ - return ((cairo_surface_pattern_t *)pattern)->surface; -} - -static int -classify_pattern (const cairo_pattern_t *pattern, - const cairo_surface_t *target) -{ - int classify; - - switch (pattern->type) { - case CAIRO_PATTERN_TYPE_SURFACE: - if (get_pattern_surface (pattern)->type == target->type) - classify = 0; - else if (get_pattern_surface (pattern)->type == CAIRO_SURFACE_TYPE_RECORDING) - classify = 1; - else - classify = 2; - break; - default: - case CAIRO_PATTERN_TYPE_SOLID: - classify = 3; - break; - case CAIRO_PATTERN_TYPE_LINEAR: - classify = 4; - break; - case CAIRO_PATTERN_TYPE_RADIAL: - classify = 5; - break; - case CAIRO_PATTERN_TYPE_MESH: - classify = 6; - break; - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - classify = 7; - break; - } - return classify; -} - -static void -add_pattern (struct pattern *stats, - const cairo_pattern_t *pattern, - const cairo_surface_t *target) -{ - stats->type[classify_pattern(pattern, target)]++; -} - -static int -classify_path (const cairo_path_fixed_t *path, - cairo_bool_t is_fill) -{ - int classify; - - /* XXX improve for stroke */ - classify = -1; - if (is_fill) { - if (path->fill_is_empty) - classify = 0; - else if (_cairo_path_fixed_fill_is_rectilinear (path)) - classify = path->fill_maybe_region ? 1 : 2; - } else { - if (_cairo_path_fixed_stroke_is_rectilinear (path)) - classify = 2; - } - if (classify == -1) - classify = 3 + (path->has_curve_to != 0); - - return classify; -} - -static void -add_path (struct path *stats, - const cairo_path_fixed_t *path, - cairo_bool_t is_fill) -{ - stats->type[classify_path(path, is_fill)]++; -} - -static int -classify_clip (const cairo_clip_t *clip) -{ - int classify; - - if (clip == NULL) - classify = 0; - else if (_cairo_clip_is_region (clip)) - classify = 1; - else if (clip->path == NULL) - classify = 2; - else if (clip->path->prev == NULL) - classify = 3; - else if (_cairo_clip_is_polygon (clip)) - classify = 4; - else - classify = 5; - - return classify; -} - -static void -add_clip (struct clip *stats, - const cairo_clip_t *clip) -{ - stats->type[classify_clip (clip)]++; -} - -static void -stats_add (struct stat *s, double v) -{ - if (v < s->min) - s->min = v; - if (v > s->max) - s->max = v; - s->sum += v; - s->sum_sq += v*v; - s->count++; -} - -static void -add_extents (struct extents *stats, - const cairo_composite_rectangles_t *extents) -{ - const cairo_rectangle_int_t *r = extents->is_bounded ? &extents->bounded :&extents->unbounded; - stats_add (&stats->area, r->width * r->height); - stats->bounded += extents->is_bounded != 0; - stats->unbounded += extents->is_bounded == 0; -} - -/* device interface */ - -static void -_cairo_device_observer_lock (void *_device) -{ - cairo_device_observer_t *device = (cairo_device_observer_t *) _device; - cairo_status_t ignored; - - /* cairo_device_acquire() can fail for nil and finished - * devices. We don't care about observing them. */ - ignored = cairo_device_acquire (device->target); -} - -static void -_cairo_device_observer_unlock (void *_device) -{ - cairo_device_observer_t *device = (cairo_device_observer_t *) _device; - cairo_device_release (device->target); -} - -static cairo_status_t -_cairo_device_observer_flush (void *_device) -{ - cairo_device_observer_t *device = (cairo_device_observer_t *) _device; - - if (device->target == NULL) - return CAIRO_STATUS_SUCCESS; - - cairo_device_flush (device->target); - return device->target->status; -} - -static void -_cairo_device_observer_finish (void *_device) -{ - cairo_device_observer_t *device = (cairo_device_observer_t *) _device; - log_fini (&device->log); - cairo_device_finish (device->target); -} - -static void -_cairo_device_observer_destroy (void *_device) -{ - cairo_device_observer_t *device = (cairo_device_observer_t *) _device; - cairo_device_destroy (device->target); - free (device); -} - -static const cairo_device_backend_t _cairo_device_observer_backend = { - CAIRO_INTERNAL_DEVICE_TYPE_OBSERVER, - - _cairo_device_observer_lock, - _cairo_device_observer_unlock, - - _cairo_device_observer_flush, - _cairo_device_observer_finish, - _cairo_device_observer_destroy, -}; - -static cairo_device_t * -_cairo_device_create_observer_internal (cairo_device_t *target, - cairo_bool_t record) -{ - cairo_device_observer_t *device; - cairo_status_t status; - - device = malloc (sizeof (cairo_device_observer_t)); - if (unlikely (device == NULL)) - return _cairo_device_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - _cairo_device_init (&device->base, &_cairo_device_observer_backend); - status = log_init (&device->log, record); - if (unlikely (status)) { - free (device); - return _cairo_device_create_in_error (status); - } - - device->target = cairo_device_reference (target); - - return &device->base; -} - -/* surface interface */ - -static cairo_device_observer_t * -to_device (cairo_surface_observer_t *suface) -{ - return (cairo_device_observer_t *)suface->base.device; -} - -static cairo_surface_t * -_cairo_surface_create_observer_internal (cairo_device_t *device, - cairo_surface_t *target) -{ - cairo_surface_observer_t *surface; - cairo_status_t status; - - surface = malloc (sizeof (cairo_surface_observer_t)); - if (unlikely (surface == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - _cairo_surface_init (&surface->base, - &_cairo_surface_observer_backend, device, - target->content); - - status = log_init (&surface->log, - ((cairo_device_observer_t *)device)->log.record != NULL); - if (unlikely (status)) { - free (surface); - return _cairo_surface_create_in_error (status); - } - - surface->target = cairo_surface_reference (target); - surface->base.type = surface->target->type; - surface->base.is_clear = surface->target->is_clear; - - cairo_list_init (&surface->paint_callbacks); - cairo_list_init (&surface->mask_callbacks); - cairo_list_init (&surface->fill_callbacks); - cairo_list_init (&surface->stroke_callbacks); - cairo_list_init (&surface->glyphs_callbacks); - - cairo_list_init (&surface->flush_callbacks); - cairo_list_init (&surface->finish_callbacks); - - surface->log.num_surfaces++; - to_device (surface)->log.num_surfaces++; - - return &surface->base; -} - -static inline void -do_callbacks (cairo_surface_observer_t *surface, cairo_list_t *head) -{ - struct callback_list *cb; - - cairo_list_foreach_entry (cb, struct callback_list, head, link) - cb->func (&surface->base, surface->target, cb->data); -} - - -static cairo_status_t -_cairo_surface_observer_finish (void *abstract_surface) -{ - cairo_surface_observer_t *surface = abstract_surface; - - do_callbacks (surface, &surface->finish_callbacks); - - cairo_surface_destroy (surface->target); - log_fini (&surface->log); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_surface_t * -_cairo_surface_observer_create_similar (void *abstract_other, - cairo_content_t content, - int width, int height) -{ - cairo_surface_observer_t *other = abstract_other; - cairo_surface_t *target, *surface; - - target = NULL; - if (other->target->backend->create_similar) - target = other->target->backend->create_similar (other->target, content, - width, height); - if (target == NULL) - target = _cairo_image_surface_create_with_content (content, - width, height); - - surface = _cairo_surface_create_observer_internal (other->base.device, - target); - cairo_surface_destroy (target); - - return surface; -} - -static cairo_surface_t * -_cairo_surface_observer_create_similar_image (void *other, - cairo_format_t format, - int width, int height) -{ - cairo_surface_observer_t *surface = other; - - if (surface->target->backend->create_similar_image) - return surface->target->backend->create_similar_image (surface->target, - format, - width, height); - - return NULL; -} - -static cairo_image_surface_t * -_cairo_surface_observer_map_to_image (void *abstract_surface, - const cairo_rectangle_int_t *extents) -{ - cairo_surface_observer_t *surface = abstract_surface; - return _cairo_surface_map_to_image (surface->target, extents); -} - -static cairo_int_status_t -_cairo_surface_observer_unmap_image (void *abstract_surface, - cairo_image_surface_t *image) -{ - cairo_surface_observer_t *surface = abstract_surface; - return _cairo_surface_unmap_image (surface->target, image); -} - -static void -record_target (cairo_observation_record_t *r, - cairo_surface_t *target) -{ - cairo_rectangle_int_t extents; - - r->target_content = target->content; - if (_cairo_surface_get_extents (target, &extents)) { - r->target_width = extents.width; - r->target_height = extents.height; - } else { - r->target_width = -1; - r->target_height = -1; - } -} - -static cairo_observation_record_t * -record_paint (cairo_observation_record_t *r, - cairo_surface_t *target, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip, - cairo_time_t elapsed) -{ - record_target (r, target); - - r->op = op; - r->source = classify_pattern (source, target); - r->mask = -1; - r->num_glyphs = -1; - r->path = -1; - r->fill_rule = -1; - r->tolerance = -1; - r->antialias = -1; - r->clip = classify_clip (clip); - r->elapsed = elapsed; - - return r; -} - -static cairo_observation_record_t * -record_mask (cairo_observation_record_t *r, - cairo_surface_t *target, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip, - cairo_time_t elapsed) -{ - record_target (r, target); - - r->op = op; - r->source = classify_pattern (source, target); - r->mask = classify_pattern (mask, target); - r->num_glyphs = -1; - r->path = -1; - r->fill_rule = -1; - r->tolerance = -1; - r->antialias = -1; - r->clip = classify_clip (clip); - r->elapsed = elapsed; - - return r; -} - -static cairo_observation_record_t * -record_fill (cairo_observation_record_t *r, - cairo_surface_t *target, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip, - cairo_time_t elapsed) -{ - record_target (r, target); - - r->op = op; - r->source = classify_pattern (source, target); - r->mask = -1; - r->num_glyphs = -1; - r->path = classify_path (path, TRUE); - r->fill_rule = fill_rule; - r->tolerance = tolerance; - r->antialias = antialias; - r->clip = classify_clip (clip); - r->elapsed = elapsed; - - return r; -} - -static cairo_observation_record_t * -record_stroke (cairo_observation_record_t *r, - cairo_surface_t *target, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip, - cairo_time_t elapsed) -{ - record_target (r, target); - - r->op = op; - r->source = classify_pattern (source, target); - r->mask = -1; - r->num_glyphs = -1; - r->path = classify_path (path, FALSE); - r->fill_rule = -1; - r->tolerance = tolerance; - r->antialias = antialias; - r->clip = classify_clip (clip); - r->elapsed = elapsed; - - return r; -} - -static cairo_observation_record_t * -record_glyphs (cairo_observation_record_t *r, - cairo_surface_t *target, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip, - cairo_time_t elapsed) -{ - record_target (r, target); - - r->op = op; - r->source = classify_pattern (source, target); - r->mask = -1; - r->path = -1; - r->num_glyphs = num_glyphs; - r->fill_rule = -1; - r->tolerance = -1; - r->antialias = -1; - r->clip = classify_clip (clip); - r->elapsed = elapsed; - - return r; -} - -static void -add_record (cairo_observation_t *log, - cairo_observation_record_t *r) -{ - cairo_int_status_t status; - - r->index = log->record ? log->record->commands.num_elements : 0; - - status = _cairo_array_append (&log->timings, r); - assert (status == CAIRO_INT_STATUS_SUCCESS); -} - -static void -_cairo_surface_sync (cairo_surface_t *target, int x, int y) -{ - cairo_rectangle_int_t extents; - - extents.x = x; - extents.y = y; - extents.width = 1; - extents.height = 1; - - _cairo_surface_unmap_image (target, - _cairo_surface_map_to_image (target, - &extents)); -} - -static void -midpt (const cairo_composite_rectangles_t *extents, int *x, int *y) -{ - *x = extents->bounded.x + extents->bounded.width / 2; - *y = extents->bounded.y + extents->bounded.height / 2; -} - -static void -add_record_paint (cairo_observation_t *log, - cairo_surface_t *target, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip, - cairo_time_t elapsed) -{ - cairo_observation_record_t record; - cairo_int_status_t status; - - add_record (log, - record_paint (&record, target, op, source, clip, elapsed)); - - /* We have to bypass the high-level surface layer in case it tries to be - * too smart and discard operations; we need to record exactly what just - * happened on the target. - */ - if (log->record) { - status = log->record->base.backend->paint (&log->record->base, - op, source, clip); - assert (status == CAIRO_INT_STATUS_SUCCESS); - } - - if (_cairo_time_gt (elapsed, log->paint.slowest.elapsed)) - log->paint.slowest = record; - log->paint.elapsed = _cairo_time_add (log->paint.elapsed, elapsed); -} - -static cairo_int_status_t -_cairo_surface_observer_paint (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - cairo_surface_observer_t *surface = abstract_surface; - cairo_device_observer_t *device = to_device (surface); - cairo_composite_rectangles_t composite; - cairo_int_status_t status; - cairo_time_t t; - int x, y; - - /* XXX device locking */ - - surface->log.paint.count++; - surface->log.paint.operators[op]++; - add_pattern (&surface->log.paint.source, source, surface->target); - add_clip (&surface->log.paint.clip, clip); - - device->log.paint.count++; - device->log.paint.operators[op]++; - add_pattern (&device->log.paint.source, source, surface->target); - add_clip (&device->log.paint.clip, clip); - - status = _cairo_composite_rectangles_init_for_paint (&composite, - surface->target, - op, source, - clip); - if (unlikely (status)) { - surface->log.paint.noop++; - device->log.paint.noop++; - return status; - } - - midpt (&composite, &x, &y); - - add_extents (&surface->log.paint.extents, &composite); - add_extents (&device->log.paint.extents, &composite); - _cairo_composite_rectangles_fini (&composite); - - t = _cairo_time_get (); - status = _cairo_surface_paint (surface->target, - op, source, - clip); - if (unlikely (status)) - return status; - - _cairo_surface_sync (surface->target, x, y); - t = _cairo_time_get_delta (t); - - add_record_paint (&surface->log, surface->target, op, source, clip, t); - add_record_paint (&device->log, surface->target, op, source, clip, t); - - do_callbacks (surface, &surface->paint_callbacks); - - return CAIRO_STATUS_SUCCESS; -} - -static void -add_record_mask (cairo_observation_t *log, - cairo_surface_t *target, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip, - cairo_time_t elapsed) -{ - cairo_observation_record_t record; - cairo_int_status_t status; - - add_record (log, - record_mask (&record, target, op, source, mask, clip, elapsed)); - - if (log->record) { - status = log->record->base.backend->mask (&log->record->base, - op, source, mask, clip); - assert (status == CAIRO_INT_STATUS_SUCCESS); - } - - if (_cairo_time_gt (elapsed, log->mask.slowest.elapsed)) - log->mask.slowest = record; - log->mask.elapsed = _cairo_time_add (log->mask.elapsed, elapsed); -} - -static cairo_int_status_t -_cairo_surface_observer_mask (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - cairo_surface_observer_t *surface = abstract_surface; - cairo_device_observer_t *device = to_device (surface); - cairo_composite_rectangles_t composite; - cairo_int_status_t status; - cairo_time_t t; - int x, y; - - surface->log.mask.count++; - surface->log.mask.operators[op]++; - add_pattern (&surface->log.mask.source, source, surface->target); - add_pattern (&surface->log.mask.mask, mask, surface->target); - add_clip (&surface->log.mask.clip, clip); - - device->log.mask.count++; - device->log.mask.operators[op]++; - add_pattern (&device->log.mask.source, source, surface->target); - add_pattern (&device->log.mask.mask, mask, surface->target); - add_clip (&device->log.mask.clip, clip); - - status = _cairo_composite_rectangles_init_for_mask (&composite, - surface->target, - op, source, mask, - clip); - if (unlikely (status)) { - surface->log.mask.noop++; - device->log.mask.noop++; - return status; - } - - midpt (&composite, &x, &y); - - add_extents (&surface->log.mask.extents, &composite); - add_extents (&device->log.mask.extents, &composite); - _cairo_composite_rectangles_fini (&composite); - - t = _cairo_time_get (); - status = _cairo_surface_mask (surface->target, - op, source, mask, - clip); - if (unlikely (status)) - return status; - - _cairo_surface_sync (surface->target, x, y); - t = _cairo_time_get_delta (t); - - add_record_mask (&surface->log, - surface->target, op, source, mask, clip, - t); - add_record_mask (&device->log, - surface->target, op, source, mask, clip, - t); - - do_callbacks (surface, &surface->mask_callbacks); - - return CAIRO_STATUS_SUCCESS; -} - -static void -add_record_fill (cairo_observation_t *log, - cairo_surface_t *target, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip, - cairo_time_t elapsed) -{ - cairo_observation_record_t record; - cairo_int_status_t status; - - add_record (log, - record_fill (&record, - target, op, source, - path, fill_rule, tolerance, antialias, - clip, elapsed)); - - if (log->record) { - status = log->record->base.backend->fill (&log->record->base, - op, source, - path, fill_rule, - tolerance, antialias, - clip); - assert (status == CAIRO_INT_STATUS_SUCCESS); - } - - if (_cairo_time_gt (elapsed, log->fill.slowest.elapsed)) - log->fill.slowest = record; - log->fill.elapsed = _cairo_time_add (log->fill.elapsed, elapsed); -} - -static cairo_int_status_t -_cairo_surface_observer_fill (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_surface_observer_t *surface = abstract_surface; - cairo_device_observer_t *device = to_device (surface); - cairo_composite_rectangles_t composite; - cairo_int_status_t status; - cairo_time_t t; - int x, y; - - surface->log.fill.count++; - surface->log.fill.operators[op]++; - surface->log.fill.fill_rule[fill_rule]++; - surface->log.fill.antialias[antialias]++; - add_pattern (&surface->log.fill.source, source, surface->target); - add_path (&surface->log.fill.path, path, TRUE); - add_clip (&surface->log.fill.clip, clip); - - device->log.fill.count++; - device->log.fill.operators[op]++; - device->log.fill.fill_rule[fill_rule]++; - device->log.fill.antialias[antialias]++; - add_pattern (&device->log.fill.source, source, surface->target); - add_path (&device->log.fill.path, path, TRUE); - add_clip (&device->log.fill.clip, clip); - - status = _cairo_composite_rectangles_init_for_fill (&composite, - surface->target, - op, source, path, - clip); - if (unlikely (status)) { - surface->log.fill.noop++; - device->log.fill.noop++; - return status; - } - - midpt (&composite, &x, &y); - - add_extents (&surface->log.fill.extents, &composite); - add_extents (&device->log.fill.extents, &composite); - _cairo_composite_rectangles_fini (&composite); - - t = _cairo_time_get (); - status = _cairo_surface_fill (surface->target, - op, source, path, - fill_rule, tolerance, antialias, - clip); - if (unlikely (status)) - return status; - - _cairo_surface_sync (surface->target, x, y); - t = _cairo_time_get_delta (t); - - add_record_fill (&surface->log, - surface->target, op, source, path, - fill_rule, tolerance, antialias, - clip, t); - - add_record_fill (&device->log, - surface->target, op, source, path, - fill_rule, tolerance, antialias, - clip, t); - - do_callbacks (surface, &surface->fill_callbacks); - - return CAIRO_STATUS_SUCCESS; -} - -static void -add_record_stroke (cairo_observation_t *log, - cairo_surface_t *target, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip, - cairo_time_t elapsed) -{ - cairo_observation_record_t record; - cairo_int_status_t status; - - add_record (log, - record_stroke (&record, - target, op, source, - path, style, ctm,ctm_inverse, - tolerance, antialias, - clip, elapsed)); - - if (log->record) { - status = log->record->base.backend->stroke (&log->record->base, - op, source, - path, style, ctm,ctm_inverse, - tolerance, antialias, - clip); - assert (status == CAIRO_INT_STATUS_SUCCESS); - } - - if (_cairo_time_gt (elapsed, log->stroke.slowest.elapsed)) - log->stroke.slowest = record; - log->stroke.elapsed = _cairo_time_add (log->stroke.elapsed, elapsed); -} - -static cairo_int_status_t -_cairo_surface_observer_stroke (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_surface_observer_t *surface = abstract_surface; - cairo_device_observer_t *device = to_device (surface); - cairo_composite_rectangles_t composite; - cairo_int_status_t status; - cairo_time_t t; - int x, y; - - surface->log.stroke.count++; - surface->log.stroke.operators[op]++; - surface->log.stroke.antialias[antialias]++; - surface->log.stroke.caps[style->line_cap]++; - surface->log.stroke.joins[style->line_join]++; - add_pattern (&surface->log.stroke.source, source, surface->target); - add_path (&surface->log.stroke.path, path, FALSE); - add_clip (&surface->log.stroke.clip, clip); - - device->log.stroke.count++; - device->log.stroke.operators[op]++; - device->log.stroke.antialias[antialias]++; - device->log.stroke.caps[style->line_cap]++; - device->log.stroke.joins[style->line_join]++; - add_pattern (&device->log.stroke.source, source, surface->target); - add_path (&device->log.stroke.path, path, FALSE); - add_clip (&device->log.stroke.clip, clip); - - status = _cairo_composite_rectangles_init_for_stroke (&composite, - surface->target, - op, source, - path, style, ctm, - clip); - if (unlikely (status)) { - surface->log.stroke.noop++; - device->log.stroke.noop++; - return status; - } - - midpt (&composite, &x, &y); - - add_extents (&surface->log.stroke.extents, &composite); - add_extents (&device->log.stroke.extents, &composite); - _cairo_composite_rectangles_fini (&composite); - - t = _cairo_time_get (); - status = _cairo_surface_stroke (surface->target, - op, source, path, - style, ctm, ctm_inverse, - tolerance, antialias, - clip); - if (unlikely (status)) - return status; - - _cairo_surface_sync (surface->target, x, y); - t = _cairo_time_get_delta (t); - - add_record_stroke (&surface->log, - surface->target, op, source, path, - style, ctm,ctm_inverse, - tolerance, antialias, - clip, t); - - add_record_stroke (&device->log, - surface->target, op, source, path, - style, ctm,ctm_inverse, - tolerance, antialias, - clip, t); - - do_callbacks (surface, &surface->stroke_callbacks); - - return CAIRO_STATUS_SUCCESS; -} - -static void -add_record_glyphs (cairo_observation_t *log, - cairo_surface_t *target, - cairo_operator_t op, - const cairo_pattern_t*source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip, - cairo_time_t elapsed) -{ - cairo_observation_record_t record; - cairo_int_status_t status; - - add_record (log, - record_glyphs (&record, - target, op, source, - glyphs, num_glyphs, scaled_font, - clip, elapsed)); - - if (log->record) { - status = log->record->base.backend->show_text_glyphs (&log->record->base, - op, source, - NULL, 0, - glyphs, num_glyphs, - NULL, 0, 0, - scaled_font, - clip); - assert (status == CAIRO_INT_STATUS_SUCCESS); - } - - if (_cairo_time_gt (elapsed, log->glyphs.slowest.elapsed)) - log->glyphs.slowest = record; - log->glyphs.elapsed = _cairo_time_add (log->glyphs.elapsed, elapsed); -} - -static cairo_int_status_t -_cairo_surface_observer_glyphs (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - cairo_surface_observer_t *surface = abstract_surface; - cairo_device_observer_t *device = to_device (surface); - cairo_composite_rectangles_t composite; - cairo_int_status_t status; - cairo_glyph_t *dev_glyphs; - cairo_time_t t; - int x, y; - - surface->log.glyphs.count++; - surface->log.glyphs.operators[op]++; - add_pattern (&surface->log.glyphs.source, source, surface->target); - add_clip (&surface->log.glyphs.clip, clip); - - device->log.glyphs.count++; - device->log.glyphs.operators[op]++; - add_pattern (&device->log.glyphs.source, source, surface->target); - add_clip (&device->log.glyphs.clip, clip); - - status = _cairo_composite_rectangles_init_for_glyphs (&composite, - surface->target, - op, source, - scaled_font, - glyphs, num_glyphs, - clip, - NULL); - if (unlikely (status)) { - surface->log.glyphs.noop++; - device->log.glyphs.noop++; - return status; - } - - midpt (&composite, &x, &y); - - add_extents (&surface->log.glyphs.extents, &composite); - add_extents (&device->log.glyphs.extents, &composite); - _cairo_composite_rectangles_fini (&composite); - - /* XXX We have to copy the glyphs, because the backend is allowed to - * modify! */ - dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); - if (unlikely (dev_glyphs == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - memcpy (dev_glyphs, glyphs, num_glyphs * sizeof (cairo_glyph_t)); - - t = _cairo_time_get (); - status = _cairo_surface_show_text_glyphs (surface->target, op, source, - NULL, 0, - dev_glyphs, num_glyphs, - NULL, 0, 0, - scaled_font, - clip); - free (dev_glyphs); - if (unlikely (status)) - return status; - - _cairo_surface_sync (surface->target, x, y); - t = _cairo_time_get_delta (t); - - add_record_glyphs (&surface->log, - surface->target, op, source, - glyphs, num_glyphs, scaled_font, - clip, t); - - add_record_glyphs (&device->log, - surface->target, op, source, - glyphs, num_glyphs, scaled_font, - clip, t); - - do_callbacks (surface, &surface->glyphs_callbacks); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_surface_observer_flush (void *abstract_surface, unsigned flags) -{ - cairo_surface_observer_t *surface = abstract_surface; - - do_callbacks (surface, &surface->flush_callbacks); - return _cairo_surface_flush (surface->target, flags); -} - -static cairo_status_t -_cairo_surface_observer_mark_dirty (void *abstract_surface, - int x, int y, - int width, int height) -{ - cairo_surface_observer_t *surface = abstract_surface; - cairo_status_t status; - - status = CAIRO_STATUS_SUCCESS; - if (surface->target->backend->mark_dirty_rectangle) - status = surface->target->backend->mark_dirty_rectangle (surface->target, - x,y, width,height); - - return status; -} - -static cairo_int_status_t -_cairo_surface_observer_copy_page (void *abstract_surface) -{ - cairo_surface_observer_t *surface = abstract_surface; - cairo_status_t status; - - status = CAIRO_STATUS_SUCCESS; - if (surface->target->backend->copy_page) - status = surface->target->backend->copy_page (surface->target); - - return status; -} - -static cairo_int_status_t -_cairo_surface_observer_show_page (void *abstract_surface) -{ - cairo_surface_observer_t *surface = abstract_surface; - cairo_status_t status; - - status = CAIRO_STATUS_SUCCESS; - if (surface->target->backend->show_page) - status = surface->target->backend->show_page (surface->target); - - return status; -} - -static cairo_bool_t -_cairo_surface_observer_get_extents (void *abstract_surface, - cairo_rectangle_int_t *extents) -{ - cairo_surface_observer_t *surface = abstract_surface; - return _cairo_surface_get_extents (surface->target, extents); -} - -static void -_cairo_surface_observer_get_font_options (void *abstract_surface, - cairo_font_options_t *options) -{ - cairo_surface_observer_t *surface = abstract_surface; - - if (surface->target->backend->get_font_options != NULL) - surface->target->backend->get_font_options (surface->target, options); -} - -static cairo_surface_t * -_cairo_surface_observer_source (void *abstract_surface, - cairo_rectangle_int_t *extents) -{ - cairo_surface_observer_t *surface = abstract_surface; - return _cairo_surface_get_source (surface->target, extents); -} - -static cairo_status_t -_cairo_surface_observer_acquire_source_image (void *abstract_surface, - cairo_image_surface_t **image_out, - void **image_extra) -{ - cairo_surface_observer_t *surface = abstract_surface; - - surface->log.num_sources_acquired++; - to_device (surface)->log.num_sources_acquired++; - - return _cairo_surface_acquire_source_image (surface->target, - image_out, image_extra); -} - -static void -_cairo_surface_observer_release_source_image (void *abstract_surface, - cairo_image_surface_t *image, - void *image_extra) -{ - cairo_surface_observer_t *surface = abstract_surface; - - _cairo_surface_release_source_image (surface->target, image, image_extra); -} - -static cairo_surface_t * -_cairo_surface_observer_snapshot (void *abstract_surface) -{ - cairo_surface_observer_t *surface = abstract_surface; - - /* XXX hook onto the snapshot so that we measure number of reads */ - - if (surface->target->backend->snapshot) - return surface->target->backend->snapshot (surface->target); - - return NULL; -} - -static cairo_t * -_cairo_surface_observer_create_context(void *target) -{ - cairo_surface_observer_t *surface = target; - - if (_cairo_surface_is_subsurface (&surface->base)) - surface = (cairo_surface_observer_t *) - _cairo_surface_subsurface_get_target (&surface->base); - - surface->log.num_contexts++; - to_device (surface)->log.num_contexts++; - - return surface->target->backend->create_context (target); -} - -static const cairo_surface_backend_t _cairo_surface_observer_backend = { - CAIRO_INTERNAL_SURFACE_TYPE_OBSERVER, - _cairo_surface_observer_finish, - - _cairo_surface_observer_create_context, - - _cairo_surface_observer_create_similar, - _cairo_surface_observer_create_similar_image, - _cairo_surface_observer_map_to_image, - _cairo_surface_observer_unmap_image, - - _cairo_surface_observer_source, - _cairo_surface_observer_acquire_source_image, - _cairo_surface_observer_release_source_image, - _cairo_surface_observer_snapshot, - - _cairo_surface_observer_copy_page, - _cairo_surface_observer_show_page, - - _cairo_surface_observer_get_extents, - _cairo_surface_observer_get_font_options, - - _cairo_surface_observer_flush, - _cairo_surface_observer_mark_dirty, - - _cairo_surface_observer_paint, - _cairo_surface_observer_mask, - _cairo_surface_observer_stroke, - _cairo_surface_observer_fill, - NULL, /* fill-stroke */ - _cairo_surface_observer_glyphs, -}; - -/** - * cairo_surface_create_observer: - * @target: an existing surface for which the observer will watch - * @mode: sets the mode of operation (normal vs. record) - * - * Create a new surface that exists solely to watch another is doing. In - * the process it will log operations and times, which are fast, which are - * slow, which are frequent, etc. - * - * The @mode parameter can be set to either CAIRO_SURFACE_OBSERVER_NORMAL - * or CAIRO_SURFACE_OBSERVER_RECORD_OPERATIONS, to control whether or not - * the internal observer should record operations. - * - * Return value: a pointer to the newly allocated surface. The caller - * owns the surface and should call cairo_surface_destroy() when done - * with it. - * - * This function always returns a valid pointer, but it will return a - * pointer to a "nil" surface if @other is already in an error state - * or any other error occurs. - * - * Since: 1.12 - **/ -cairo_surface_t * -cairo_surface_create_observer (cairo_surface_t *target, - cairo_surface_observer_mode_t mode) -{ - cairo_device_t *device; - cairo_surface_t *surface; - cairo_bool_t record; - - if (unlikely (target->status)) - return _cairo_surface_create_in_error (target->status); - if (unlikely (target->finished)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - - record = mode & CAIRO_SURFACE_OBSERVER_RECORD_OPERATIONS; - device = _cairo_device_create_observer_internal (target->device, record); - if (unlikely (device->status)) - return _cairo_surface_create_in_error (device->status); - - surface = _cairo_surface_create_observer_internal (device, target); - cairo_device_destroy (device); - - return surface; -} - -static cairo_status_t -_cairo_surface_observer_add_callback (cairo_list_t *head, - cairo_surface_observer_callback_t func, - void *data) -{ - struct callback_list *cb; - - cb = malloc (sizeof (*cb)); - if (unlikely (cb == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - cairo_list_add (&cb->link, head); - cb->func = func; - cb->data = data; - - return CAIRO_STATUS_SUCCESS; -} - -cairo_status_t -cairo_surface_observer_add_paint_callback (cairo_surface_t *abstract_surface, - cairo_surface_observer_callback_t func, - void *data) -{ - cairo_surface_observer_t *surface; - - if (unlikely (CAIRO_REFERENCE_COUNT_IS_INVALID (&abstract_surface->ref_count))) - return abstract_surface->status; - - if (! _cairo_surface_is_observer (abstract_surface)) - return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - - surface = (cairo_surface_observer_t *)abstract_surface; - return _cairo_surface_observer_add_callback (&surface->paint_callbacks, - func, data); -} - -cairo_status_t -cairo_surface_observer_add_mask_callback (cairo_surface_t *abstract_surface, - cairo_surface_observer_callback_t func, - void *data) -{ - cairo_surface_observer_t *surface; - - if (unlikely (CAIRO_REFERENCE_COUNT_IS_INVALID (&abstract_surface->ref_count))) - return abstract_surface->status; - - if (! _cairo_surface_is_observer (abstract_surface)) - return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - - surface = (cairo_surface_observer_t *)abstract_surface; - return _cairo_surface_observer_add_callback (&surface->mask_callbacks, - func, data); -} - -cairo_status_t -cairo_surface_observer_add_fill_callback (cairo_surface_t *abstract_surface, - cairo_surface_observer_callback_t func, - void *data) -{ - cairo_surface_observer_t *surface; - - if (unlikely (CAIRO_REFERENCE_COUNT_IS_INVALID (&abstract_surface->ref_count))) - return abstract_surface->status; - - if (! _cairo_surface_is_observer (abstract_surface)) - return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - - surface = (cairo_surface_observer_t *)abstract_surface; - return _cairo_surface_observer_add_callback (&surface->fill_callbacks, - func, data); -} - -cairo_status_t -cairo_surface_observer_add_stroke_callback (cairo_surface_t *abstract_surface, - cairo_surface_observer_callback_t func, - void *data) -{ - cairo_surface_observer_t *surface; - - if (unlikely (CAIRO_REFERENCE_COUNT_IS_INVALID (&abstract_surface->ref_count))) - return abstract_surface->status; - - if (! _cairo_surface_is_observer (abstract_surface)) - return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - - surface = (cairo_surface_observer_t *)abstract_surface; - return _cairo_surface_observer_add_callback (&surface->stroke_callbacks, - func, data); -} - -cairo_status_t -cairo_surface_observer_add_glyphs_callback (cairo_surface_t *abstract_surface, - cairo_surface_observer_callback_t func, - void *data) -{ - cairo_surface_observer_t *surface; - - if (unlikely (CAIRO_REFERENCE_COUNT_IS_INVALID (&abstract_surface->ref_count))) - return abstract_surface->status; - - if (! _cairo_surface_is_observer (abstract_surface)) - return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - - surface = (cairo_surface_observer_t *)abstract_surface; - return _cairo_surface_observer_add_callback (&surface->glyphs_callbacks, - func, data); -} - -cairo_status_t -cairo_surface_observer_add_flush_callback (cairo_surface_t *abstract_surface, - cairo_surface_observer_callback_t func, - void *data) -{ - cairo_surface_observer_t *surface; - - if (unlikely (CAIRO_REFERENCE_COUNT_IS_INVALID (&abstract_surface->ref_count))) - return abstract_surface->status; - - if (! _cairo_surface_is_observer (abstract_surface)) - return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - - surface = (cairo_surface_observer_t *)abstract_surface; - return _cairo_surface_observer_add_callback (&surface->flush_callbacks, - func, data); -} - -cairo_status_t -cairo_surface_observer_add_finish_callback (cairo_surface_t *abstract_surface, - cairo_surface_observer_callback_t func, - void *data) -{ - cairo_surface_observer_t *surface; - - if (unlikely (CAIRO_REFERENCE_COUNT_IS_INVALID (&abstract_surface->ref_count))) - return abstract_surface->status; - - if (! _cairo_surface_is_observer (abstract_surface)) - return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - - surface = (cairo_surface_observer_t *)abstract_surface; - return _cairo_surface_observer_add_callback (&surface->finish_callbacks, - func, data); -} - -static void -print_extents (cairo_output_stream_t *stream, const struct extents *e) -{ - _cairo_output_stream_printf (stream, - " extents: total %g, avg %g [unbounded %d]\n", - e->area.sum, - e->area.sum / e->area.count, - e->unbounded); -} - -static inline int ordercmp (int a, int b, const unsigned int *array) -{ - /* high to low */ - return array[b] - array[a]; -} -CAIRO_COMBSORT_DECLARE_WITH_DATA (sort_order, int, ordercmp) - -static void -print_array (cairo_output_stream_t *stream, - const unsigned int *array, - const char **names, - int count) -{ - int order[64]; - int i, j; - - assert (count < ARRAY_LENGTH (order)); - for (i = j = 0; i < count; i++) { - if (array[i] != 0) - order[j++] = i; - } - - sort_order (order, j, (void *)array); - for (i = 0; i < j; i++) - _cairo_output_stream_printf (stream, " %d %s%s", - array[order[i]], names[order[i]], - i < j -1 ? "," : ""); -} - -static const char *operator_names[] = { - "CLEAR", /* CAIRO_OPERATOR_CLEAR */ - - "SOURCE", /* CAIRO_OPERATOR_SOURCE */ - "OVER", /* CAIRO_OPERATOR_OVER */ - "IN", /* CAIRO_OPERATOR_IN */ - "OUT", /* CAIRO_OPERATOR_OUT */ - "ATOP", /* CAIRO_OPERATOR_ATOP */ - - "DEST", /* CAIRO_OPERATOR_DEST */ - "DEST_OVER", /* CAIRO_OPERATOR_DEST_OVER */ - "DEST_IN", /* CAIRO_OPERATOR_DEST_IN */ - "DEST_OUT", /* CAIRO_OPERATOR_DEST_OUT */ - "DEST_ATOP", /* CAIRO_OPERATOR_DEST_ATOP */ - - "XOR", /* CAIRO_OPERATOR_XOR */ - "ADD", /* CAIRO_OPERATOR_ADD */ - "SATURATE", /* CAIRO_OPERATOR_SATURATE */ - - "MULTIPLY", /* CAIRO_OPERATOR_MULTIPLY */ - "SCREEN", /* CAIRO_OPERATOR_SCREEN */ - "OVERLAY", /* CAIRO_OPERATOR_OVERLAY */ - "DARKEN", /* CAIRO_OPERATOR_DARKEN */ - "LIGHTEN", /* CAIRO_OPERATOR_LIGHTEN */ - "DODGE", /* CAIRO_OPERATOR_COLOR_DODGE */ - "BURN", /* CAIRO_OPERATOR_COLOR_BURN */ - "HARD_LIGHT", /* CAIRO_OPERATOR_HARD_LIGHT */ - "SOFT_LIGHT", /* CAIRO_OPERATOR_SOFT_LIGHT */ - "DIFFERENCE", /* CAIRO_OPERATOR_DIFFERENCE */ - "EXCLUSION", /* CAIRO_OPERATOR_EXCLUSION */ - "HSL_HUE", /* CAIRO_OPERATOR_HSL_HUE */ - "HSL_SATURATION", /* CAIRO_OPERATOR_HSL_SATURATION */ - "HSL_COLOR", /* CAIRO_OPERATOR_HSL_COLOR */ - "HSL_LUMINOSITY" /* CAIRO_OPERATOR_HSL_LUMINOSITY */ -}; -static void -print_operators (cairo_output_stream_t *stream, unsigned int *array) -{ - _cairo_output_stream_printf (stream, " op:"); - print_array (stream, array, operator_names, NUM_OPERATORS); - _cairo_output_stream_printf (stream, "\n"); -} - -static const char *fill_rule_names[] = { - "non-zero", - "even-odd", -}; -static void -print_fill_rule (cairo_output_stream_t *stream, unsigned int *array) -{ - _cairo_output_stream_printf (stream, " fill rule:"); - print_array (stream, array, fill_rule_names, ARRAY_LENGTH(fill_rule_names)); - _cairo_output_stream_printf (stream, "\n"); -} - -static const char *cap_names[] = { - "butt", /* CAIRO_LINE_CAP_BUTT */ - "round", /* CAIRO_LINE_CAP_ROUND */ - "square" /* CAIRO_LINE_CAP_SQUARE */ -}; -static void -print_line_caps (cairo_output_stream_t *stream, unsigned int *array) -{ - _cairo_output_stream_printf (stream, " caps:"); - print_array (stream, array, cap_names, NUM_CAPS); - _cairo_output_stream_printf (stream, "\n"); -} - -static const char *join_names[] = { - "miter", /* CAIRO_LINE_JOIN_MITER */ - "round", /* CAIRO_LINE_JOIN_ROUND */ - "bevel", /* CAIRO_LINE_JOIN_BEVEL */ -}; -static void -print_line_joins (cairo_output_stream_t *stream, unsigned int *array) -{ - _cairo_output_stream_printf (stream, " joins:"); - print_array (stream, array, join_names, NUM_JOINS); - _cairo_output_stream_printf (stream, "\n"); -} - -static const char *antialias_names[] = { - "default", - "none", - "gray", - "subpixel", - "fast", - "good", - "best" -}; -static void -print_antialias (cairo_output_stream_t *stream, unsigned int *array) -{ - _cairo_output_stream_printf (stream, " antialias:"); - print_array (stream, array, antialias_names, NUM_ANTIALIAS); - _cairo_output_stream_printf (stream, "\n"); -} - -static const char *pattern_names[] = { - "native", - "record", - "other surface", - "solid", - "linear", - "radial", - "mesh", - "raster" -}; -static void -print_pattern (cairo_output_stream_t *stream, - const char *name, - const struct pattern *p) -{ - _cairo_output_stream_printf (stream, " %s:", name); - print_array (stream, p->type, pattern_names, ARRAY_LENGTH (pattern_names)); - _cairo_output_stream_printf (stream, "\n"); -} - -static const char *path_names[] = { - "empty", - "pixel-aligned", - "rectliinear", - "straight", - "curved", -}; -static void -print_path (cairo_output_stream_t *stream, - const struct path *p) -{ - _cairo_output_stream_printf (stream, " path:"); - print_array (stream, p->type, path_names, ARRAY_LENGTH (path_names)); - _cairo_output_stream_printf (stream, "\n"); -} - -static const char *clip_names[] = { - "none", - "region", - "boxes", - "single path", - "polygon", - "general", -}; -static void -print_clip (cairo_output_stream_t *stream, const struct clip *c) -{ - _cairo_output_stream_printf (stream, " clip:"); - print_array (stream, c->type, clip_names, ARRAY_LENGTH (clip_names)); - _cairo_output_stream_printf (stream, "\n"); -} - -static void -print_record (cairo_output_stream_t *stream, - cairo_observation_record_t *r) -{ - _cairo_output_stream_printf (stream, " op: %s\n", operator_names[r->op]); - _cairo_output_stream_printf (stream, " source: %s\n", - pattern_names[r->source]); - if (r->mask != -1) - _cairo_output_stream_printf (stream, " mask: %s\n", - pattern_names[r->mask]); - if (r->num_glyphs != -1) - _cairo_output_stream_printf (stream, " num_glyphs: %d\n", - r->num_glyphs); - if (r->path != -1) - _cairo_output_stream_printf (stream, " path: %s\n", - path_names[r->path]); - if (r->fill_rule != -1) - _cairo_output_stream_printf (stream, " fill rule: %s\n", - fill_rule_names[r->fill_rule]); - if (r->antialias != -1) - _cairo_output_stream_printf (stream, " antialias: %s\n", - antialias_names[r->antialias]); - _cairo_output_stream_printf (stream, " clip: %s\n", clip_names[r->clip]); - _cairo_output_stream_printf (stream, " elapsed: %f ns\n", - _cairo_time_to_ns (r->elapsed)); -} - -static double percent (cairo_time_t a, cairo_time_t b) -{ - /* Fake %.1f */ - return _cairo_round (_cairo_time_to_s (a) * 1000 / - _cairo_time_to_s (b)) / 10; -} - -static cairo_bool_t -replay_record (cairo_observation_t *log, - cairo_observation_record_t *r, - cairo_device_t *script) -{ -#if CAIRO_HAS_SCRIPT_SURFACE - cairo_surface_t *surface; - cairo_int_status_t status; - - if (log->record == NULL || script == NULL) - return FALSE; - - surface = cairo_script_surface_create (script, - r->target_content, - r->target_width, - r->target_height); - status = - _cairo_recording_surface_replay_one (log->record, r->index, surface); - cairo_surface_destroy (surface); - - assert (status == CAIRO_INT_STATUS_SUCCESS); - - return TRUE; -#else - return FALSE; -#endif -} - -static cairo_time_t -_cairo_observation_total_elapsed (cairo_observation_t *log) -{ - cairo_time_t total; - - total = log->paint.elapsed; - total = _cairo_time_add (total, log->mask.elapsed); - total = _cairo_time_add (total, log->fill.elapsed); - total = _cairo_time_add (total, log->stroke.elapsed); - total = _cairo_time_add (total, log->glyphs.elapsed); - - return total; -} - -static void -_cairo_observation_print (cairo_output_stream_t *stream, - cairo_observation_t *log) -{ - cairo_device_t *script; - cairo_time_t total; - -#if CAIRO_HAS_SCRIPT_SURFACE - script = _cairo_script_context_create_internal (stream); - _cairo_script_context_attach_snapshots (script, FALSE); -#else - script = NULL; -#endif - - total = _cairo_observation_total_elapsed (log); - - _cairo_output_stream_printf (stream, "elapsed: %f\n", - _cairo_time_to_ns (total)); - _cairo_output_stream_printf (stream, "surfaces: %d\n", - log->num_surfaces); - _cairo_output_stream_printf (stream, "contexts: %d\n", - log->num_contexts); - _cairo_output_stream_printf (stream, "sources acquired: %d\n", - log->num_sources_acquired); - - - _cairo_output_stream_printf (stream, "paint: count %d [no-op %d], elapsed %f [%f%%]\n", - log->paint.count, log->paint.noop, - _cairo_time_to_ns (log->paint.elapsed), - percent (log->paint.elapsed, total)); - if (log->paint.count) { - print_extents (stream, &log->paint.extents); - print_operators (stream, log->paint.operators); - print_pattern (stream, "source", &log->paint.source); - print_clip (stream, &log->paint.clip); - - _cairo_output_stream_printf (stream, "slowest paint: %f%%\n", - percent (log->paint.slowest.elapsed, - log->paint.elapsed)); - print_record (stream, &log->paint.slowest); - - _cairo_output_stream_printf (stream, "\n"); - if (replay_record (log, &log->paint.slowest, script)) - _cairo_output_stream_printf (stream, "\n\n"); - } - - _cairo_output_stream_printf (stream, "mask: count %d [no-op %d], elapsed %f [%f%%]\n", - log->mask.count, log->mask.noop, - _cairo_time_to_ns (log->mask.elapsed), - percent (log->mask.elapsed, total)); - if (log->mask.count) { - print_extents (stream, &log->mask.extents); - print_operators (stream, log->mask.operators); - print_pattern (stream, "source", &log->mask.source); - print_pattern (stream, "mask", &log->mask.mask); - print_clip (stream, &log->mask.clip); - - _cairo_output_stream_printf (stream, "slowest mask: %f%%\n", - percent (log->mask.slowest.elapsed, - log->mask.elapsed)); - print_record (stream, &log->mask.slowest); - - _cairo_output_stream_printf (stream, "\n"); - if (replay_record (log, &log->mask.slowest, script)) - _cairo_output_stream_printf (stream, "\n\n"); - } - - _cairo_output_stream_printf (stream, "fill: count %d [no-op %d], elaspsed %f [%f%%]\n", - log->fill.count, log->fill.noop, - _cairo_time_to_ns (log->fill.elapsed), - percent (log->fill.elapsed, total)); - if (log->fill.count) { - print_extents (stream, &log->fill.extents); - print_operators (stream, log->fill.operators); - print_pattern (stream, "source", &log->fill.source); - print_path (stream, &log->fill.path); - print_fill_rule (stream, log->fill.fill_rule); - print_antialias (stream, log->fill.antialias); - print_clip (stream, &log->fill.clip); - - _cairo_output_stream_printf (stream, "slowest fill: %f%%\n", - percent (log->fill.slowest.elapsed, - log->fill.elapsed)); - print_record (stream, &log->fill.slowest); - - _cairo_output_stream_printf (stream, "\n"); - if (replay_record (log, &log->fill.slowest, script)) - _cairo_output_stream_printf (stream, "\n\n"); - } - - _cairo_output_stream_printf (stream, "stroke: count %d [no-op %d], elapsed %f [%f%%]\n", - log->stroke.count, log->stroke.noop, - _cairo_time_to_ns (log->stroke.elapsed), - percent (log->stroke.elapsed, total)); - if (log->stroke.count) { - print_extents (stream, &log->stroke.extents); - print_operators (stream, log->stroke.operators); - print_pattern (stream, "source", &log->stroke.source); - print_path (stream, &log->stroke.path); - print_antialias (stream, log->stroke.antialias); - print_line_caps (stream, log->stroke.caps); - print_line_joins (stream, log->stroke.joins); - print_clip (stream, &log->stroke.clip); - - _cairo_output_stream_printf (stream, "slowest stroke: %f%%\n", - percent (log->stroke.slowest.elapsed, - log->stroke.elapsed)); - print_record (stream, &log->stroke.slowest); - - _cairo_output_stream_printf (stream, "\n"); - if (replay_record (log, &log->stroke.slowest, script)) - _cairo_output_stream_printf (stream, "\n\n"); - } - - _cairo_output_stream_printf (stream, "glyphs: count %d [no-op %d], elasped %f [%f%%]\n", - log->glyphs.count, log->glyphs.noop, - _cairo_time_to_ns (log->glyphs.elapsed), - percent (log->glyphs.elapsed, total)); - if (log->glyphs.count) { - print_extents (stream, &log->glyphs.extents); - print_operators (stream, log->glyphs.operators); - print_pattern (stream, "source", &log->glyphs.source); - print_clip (stream, &log->glyphs.clip); - - _cairo_output_stream_printf (stream, "slowest glyphs: %f%%\n", - percent (log->glyphs.slowest.elapsed, - log->glyphs.elapsed)); - print_record (stream, &log->glyphs.slowest); - - _cairo_output_stream_printf (stream, "\n"); - if (replay_record (log, &log->glyphs.slowest, script)) - _cairo_output_stream_printf (stream, "\n\n"); - } - - cairo_device_destroy (script); -} - -cairo_status_t -cairo_surface_observer_print (cairo_surface_t *abstract_surface, - cairo_write_func_t write_func, - void *closure) -{ - cairo_output_stream_t *stream; - cairo_surface_observer_t *surface; - - if (unlikely (abstract_surface->status)) - return abstract_surface->status; - - if (unlikely (! _cairo_surface_is_observer (abstract_surface))) - return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - - surface = (cairo_surface_observer_t *) abstract_surface; - - stream = _cairo_output_stream_create (write_func, NULL, closure); - _cairo_observation_print (stream, &surface->log); - return _cairo_output_stream_destroy (stream); -} - -double -cairo_surface_observer_elapsed (cairo_surface_t *abstract_surface) -{ - cairo_surface_observer_t *surface; - - if (unlikely (CAIRO_REFERENCE_COUNT_IS_INVALID (&abstract_surface->ref_count))) - return -1; - - if (! _cairo_surface_is_observer (abstract_surface)) - return -1; - - surface = (cairo_surface_observer_t *) abstract_surface; - return _cairo_time_to_ns (_cairo_observation_total_elapsed (&surface->log)); -} - -cairo_status_t -cairo_device_observer_print (cairo_device_t *abstract_device, - cairo_write_func_t write_func, - void *closure) -{ - cairo_output_stream_t *stream; - cairo_device_observer_t *device; - - if (unlikely (abstract_device->status)) - return abstract_device->status; - - if (unlikely (! _cairo_device_is_observer (abstract_device))) - return _cairo_error (CAIRO_STATUS_DEVICE_TYPE_MISMATCH); - - device = (cairo_device_observer_t *) abstract_device; - - stream = _cairo_output_stream_create (write_func, NULL, closure); - _cairo_observation_print (stream, &device->log); - return _cairo_output_stream_destroy (stream); -} - -double -cairo_device_observer_elapsed (cairo_device_t *abstract_device) -{ - cairo_device_observer_t *device; - - if (unlikely (CAIRO_REFERENCE_COUNT_IS_INVALID (&abstract_device->ref_count))) - return -1; - - if (! _cairo_device_is_observer (abstract_device)) - return -1; - - device = (cairo_device_observer_t *) abstract_device; - return _cairo_time_to_ns (_cairo_observation_total_elapsed (&device->log)); -} - -double -cairo_device_observer_paint_elapsed (cairo_device_t *abstract_device) -{ - cairo_device_observer_t *device; - - if (unlikely (CAIRO_REFERENCE_COUNT_IS_INVALID (&abstract_device->ref_count))) - return -1; - - if (! _cairo_device_is_observer (abstract_device)) - return -1; - - device = (cairo_device_observer_t *) abstract_device; - return _cairo_time_to_ns (device->log.paint.elapsed); -} - -double -cairo_device_observer_mask_elapsed (cairo_device_t *abstract_device) -{ - cairo_device_observer_t *device; - - if (unlikely (CAIRO_REFERENCE_COUNT_IS_INVALID (&abstract_device->ref_count))) - return -1; - - if (! _cairo_device_is_observer (abstract_device)) - return -1; - - device = (cairo_device_observer_t *) abstract_device; - return _cairo_time_to_ns (device->log.mask.elapsed); -} - -double -cairo_device_observer_fill_elapsed (cairo_device_t *abstract_device) -{ - cairo_device_observer_t *device; - - if (unlikely (CAIRO_REFERENCE_COUNT_IS_INVALID (&abstract_device->ref_count))) - return -1; - - if (! _cairo_device_is_observer (abstract_device)) - return -1; - - device = (cairo_device_observer_t *) abstract_device; - return _cairo_time_to_ns (device->log.fill.elapsed); -} - -double -cairo_device_observer_stroke_elapsed (cairo_device_t *abstract_device) -{ - cairo_device_observer_t *device; - - if (unlikely (CAIRO_REFERENCE_COUNT_IS_INVALID (&abstract_device->ref_count))) - return -1; - - if (! _cairo_device_is_observer (abstract_device)) - return -1; - - device = (cairo_device_observer_t *) abstract_device; - return _cairo_time_to_ns (device->log.stroke.elapsed); -} - -double -cairo_device_observer_glyphs_elapsed (cairo_device_t *abstract_device) -{ - cairo_device_observer_t *device; - - if (unlikely (CAIRO_REFERENCE_COUNT_IS_INVALID (&abstract_device->ref_count))) - return -1; - - if (! _cairo_device_is_observer (abstract_device)) - return -1; - - device = (cairo_device_observer_t *) abstract_device; - return _cairo_time_to_ns (device->log.glyphs.elapsed); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-surface-offset-private.h b/source/libs/cairo/cairo-src/src/cairo-surface-offset-private.h deleted file mode 100644 index 310ba5691cdc6a11c70e5e0ed807ee0e53178209..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-surface-offset-private.h +++ /dev/null @@ -1,95 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.u> - */ - -#ifndef CAIRO_SURFACE_OFFSET_PRIVATE_H -#define CAIRO_SURFACE_OFFSET_PRIVATE_H - -#include "cairo-types-private.h" - -CAIRO_BEGIN_DECLS - -cairo_private cairo_status_t -_cairo_surface_offset_paint (cairo_surface_t *target, - int x, int y, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip); - -cairo_private cairo_status_t -_cairo_surface_offset_mask (cairo_surface_t *target, - int x, int y, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip); - -cairo_private cairo_status_t -_cairo_surface_offset_stroke (cairo_surface_t *surface, - int x, int y, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip); - -cairo_private cairo_status_t -_cairo_surface_offset_fill (cairo_surface_t *surface, - int x, int y, - cairo_operator_t op, - const cairo_pattern_t*source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip); - -cairo_private cairo_status_t -_cairo_surface_offset_glyphs (cairo_surface_t *surface, - int x, int y, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int num_glyphs, - const cairo_clip_t *clip); - -#endif /* CAIRO_SURFACE_OFFSET_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-surface-offset.c b/source/libs/cairo/cairo-src/src/cairo-surface-offset.c deleted file mode 100644 index 98f57f298041a7ef00cd2fe44f84dabe4bffafbe..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-surface-offset.c +++ /dev/null @@ -1,308 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2005 Red Hat, Inc - * Copyright © 2007 Adrian Johnson - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-clip-inline.h" -#include "cairo-error-private.h" -#include "cairo-pattern-private.h" -#include "cairo-surface-offset-private.h" - -/* A collection of routines to facilitate drawing to an alternate surface. */ - -static void -_copy_transformed_pattern (cairo_pattern_t *pattern, - const cairo_pattern_t *original, - const cairo_matrix_t *ctm_inverse) -{ - _cairo_pattern_init_static_copy (pattern, original); - - if (! _cairo_matrix_is_identity (ctm_inverse)) - _cairo_pattern_transform (pattern, ctm_inverse); -} - -cairo_status_t -_cairo_surface_offset_paint (cairo_surface_t *target, - int x, int y, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - cairo_status_t status; - cairo_clip_t *dev_clip = (cairo_clip_t *) clip; - cairo_pattern_union_t source_copy; - - if (unlikely (target->status)) - return target->status; - - if (_cairo_clip_is_all_clipped (clip)) - return CAIRO_STATUS_SUCCESS; - - if (x | y) { - cairo_matrix_t m; - - dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y); - - cairo_matrix_init_translate (&m, x, y); - _copy_transformed_pattern (&source_copy.base, source, &m); - source = &source_copy.base; - } - - status = _cairo_surface_paint (target, op, source, dev_clip); - - if (dev_clip != clip) - _cairo_clip_destroy (dev_clip); - - return status; -} - -cairo_status_t -_cairo_surface_offset_mask (cairo_surface_t *target, - int x, int y, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - cairo_status_t status; - cairo_clip_t *dev_clip = (cairo_clip_t *) clip; - cairo_pattern_union_t source_copy; - cairo_pattern_union_t mask_copy; - - if (unlikely (target->status)) - return target->status; - - if (_cairo_clip_is_all_clipped (clip)) - return CAIRO_STATUS_SUCCESS; - - if (x | y) { - cairo_matrix_t m; - - dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y); - - cairo_matrix_init_translate (&m, x, y); - _copy_transformed_pattern (&source_copy.base, source, &m); - _copy_transformed_pattern (&mask_copy.base, mask, &m); - source = &source_copy.base; - mask = &mask_copy.base; - } - - status = _cairo_surface_mask (target, op, - source, mask, - dev_clip); - - if (dev_clip != clip) - _cairo_clip_destroy (dev_clip); - - return status; -} - -cairo_status_t -_cairo_surface_offset_stroke (cairo_surface_t *surface, - int x, int y, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t*stroke_style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *) path; - cairo_clip_t *dev_clip = (cairo_clip_t *) clip; - cairo_matrix_t dev_ctm = *ctm; - cairo_matrix_t dev_ctm_inverse = *ctm_inverse; - cairo_pattern_union_t source_copy; - cairo_status_t status; - - if (unlikely (surface->status)) - return surface->status; - - if (_cairo_clip_is_all_clipped (clip)) - return CAIRO_STATUS_SUCCESS; - - if (x | y) { - cairo_matrix_t m; - - dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y); - - status = _cairo_path_fixed_init_copy (&path_copy, dev_path); - if (unlikely (status)) - goto FINISH; - - _cairo_path_fixed_translate (&path_copy, - _cairo_fixed_from_int (-x), - _cairo_fixed_from_int (-y)); - dev_path = &path_copy; - - cairo_matrix_init_translate (&m, -x, -y); - cairo_matrix_multiply (&dev_ctm, &dev_ctm, &m); - - cairo_matrix_init_translate (&m, x, y); - _copy_transformed_pattern (&source_copy.base, source, &m); - source = &source_copy.base; - cairo_matrix_multiply (&dev_ctm_inverse, &m, &dev_ctm_inverse); - } - - status = _cairo_surface_stroke (surface, op, source, - dev_path, stroke_style, - &dev_ctm, &dev_ctm_inverse, - tolerance, antialias, - dev_clip); - -FINISH: - if (dev_path != path) - _cairo_path_fixed_fini (dev_path); - if (dev_clip != clip) - _cairo_clip_destroy (dev_clip); - - return status; -} - -cairo_status_t -_cairo_surface_offset_fill (cairo_surface_t *surface, - int x, int y, - cairo_operator_t op, - const cairo_pattern_t*source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_status_t status; - cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *) path; - cairo_clip_t *dev_clip = (cairo_clip_t *) clip; - cairo_pattern_union_t source_copy; - - if (unlikely (surface->status)) - return surface->status; - - if (_cairo_clip_is_all_clipped (clip)) - return CAIRO_STATUS_SUCCESS; - - if (x | y) { - cairo_matrix_t m; - - dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y); - - status = _cairo_path_fixed_init_copy (&path_copy, dev_path); - if (unlikely (status)) - goto FINISH; - - _cairo_path_fixed_translate (&path_copy, - _cairo_fixed_from_int (-x), - _cairo_fixed_from_int (-y)); - dev_path = &path_copy; - - cairo_matrix_init_translate (&m, x, y); - _copy_transformed_pattern (&source_copy.base, source, &m); - source = &source_copy.base; - } - - status = _cairo_surface_fill (surface, op, source, - dev_path, fill_rule, - tolerance, antialias, - dev_clip); - -FINISH: - if (dev_path != path) - _cairo_path_fixed_fini (dev_path); - if (dev_clip != clip) - _cairo_clip_destroy (dev_clip); - - return status; -} - -cairo_status_t -_cairo_surface_offset_glyphs (cairo_surface_t *surface, - int x, int y, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int num_glyphs, - const cairo_clip_t *clip) -{ - cairo_status_t status; - cairo_clip_t *dev_clip = (cairo_clip_t *) clip; - cairo_pattern_union_t source_copy; - cairo_glyph_t *dev_glyphs; - int i; - - if (unlikely (surface->status)) - return surface->status; - - if (_cairo_clip_is_all_clipped (clip)) - return CAIRO_STATUS_SUCCESS; - - dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); - if (dev_glyphs == NULL) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - memcpy (dev_glyphs, glyphs, sizeof (cairo_glyph_t) * num_glyphs); - - if (x | y) { - cairo_matrix_t m; - - dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y); - - cairo_matrix_init_translate (&m, x, y); - _copy_transformed_pattern (&source_copy.base, source, &m); - source = &source_copy.base; - - for (i = 0; i < num_glyphs; i++) { - dev_glyphs[i].x -= x; - dev_glyphs[i].y -= y; - } - } - - status = _cairo_surface_show_text_glyphs (surface, op, source, - NULL, 0, - dev_glyphs, num_glyphs, - NULL, 0, 0, - scaled_font, - dev_clip); - - if (dev_clip != clip) - _cairo_clip_destroy (dev_clip); - free (dev_glyphs); - - return status; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-surface-private.h b/source/libs/cairo/cairo-src/src/cairo-surface-private.h deleted file mode 100644 index f20ab073932da68a7f407c355ac1b1166d26f5be..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-surface-private.h +++ /dev/null @@ -1,121 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - */ - -#ifndef CAIRO_SURFACE_PRIVATE_H -#define CAIRO_SURFACE_PRIVATE_H - -#include "cairo.h" - -#include "cairo-types-private.h" -#include "cairo-list-private.h" -#include "cairo-reference-count-private.h" -#include "cairo-clip-private.h" -#include "cairo-surface-backend-private.h" - -typedef void (*cairo_surface_func_t) (cairo_surface_t *); - -struct _cairo_surface { - const cairo_surface_backend_t *backend; - cairo_device_t *device; - - /* 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; - - cairo_content_t content; - - cairo_reference_count_t ref_count; - cairo_status_t status; - unsigned int unique_id; - unsigned int serial; - cairo_damage_t *damage; - - unsigned _finishing : 1; - unsigned finished : 1; - unsigned is_clear : 1; - unsigned has_font_options : 1; - unsigned owns_device : 1; - - cairo_user_data_array_t user_data; - cairo_user_data_array_t mime_data; - - cairo_matrix_t device_transform; - cairo_matrix_t device_transform_inverse; - cairo_list_t device_transform_observers; - - /* The actual resolution of the device, in dots per inch. */ - double x_resolution; - double y_resolution; - - /* The resolution that should be used when generating image-based - * fallback; generally only used by the analysis/paginated - * surfaces - */ - double x_fallback_resolution; - double y_fallback_resolution; - - /* A "snapshot" surface is immutable. See _cairo_surface_snapshot. */ - cairo_surface_t *snapshot_of; - cairo_surface_func_t snapshot_detach; - /* current snapshots of this surface*/ - cairo_list_t snapshots; - /* place upon snapshot list */ - cairo_list_t snapshot; - - /* - * Surface font options, falling back to backend's default options, - * and set using _cairo_surface_set_font_options(), and propagated by - * cairo_surface_create_similar(). - */ - cairo_font_options_t font_options; -}; - -cairo_private cairo_surface_t * -_cairo_surface_create_in_error (cairo_status_t status); - -cairo_private cairo_surface_t * -_cairo_int_surface_create_in_error (cairo_int_status_t status); - -cairo_private cairo_surface_t * -_cairo_surface_get_source (cairo_surface_t *surface, - cairo_rectangle_int_t *extents); - -cairo_private cairo_status_t -_cairo_surface_flush (cairo_surface_t *surface, unsigned flags); - -#endif /* CAIRO_SURFACE_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-surface-snapshot-inline.h b/source/libs/cairo/cairo-src/src/cairo-surface-snapshot-inline.h deleted file mode 100644 index bf89c772b429e247eddf87eda79f143e66dd2efd..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-surface-snapshot-inline.h +++ /dev/null @@ -1,67 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Intel Corporation. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_SURFACE_SNAPSHOT_INLINE_H -#define CAIRO_SURFACE_SNAPSHOT_INLINE_H - -#include "cairo-surface-snapshot-private.h" -#include "cairo-surface-inline.h" - -static inline cairo_bool_t -_cairo_surface_snapshot_is_reused (cairo_surface_t *surface) -{ - return CAIRO_REFERENCE_COUNT_GET_VALUE (&surface->ref_count) > 2; -} - -static inline cairo_surface_t * -_cairo_surface_snapshot_get_target (cairo_surface_t *surface) -{ - cairo_surface_snapshot_t *snapshot = (cairo_surface_snapshot_t *) surface; - cairo_surface_t *target; - - CAIRO_MUTEX_LOCK (snapshot->mutex); - target = _cairo_surface_reference (snapshot->target); - CAIRO_MUTEX_UNLOCK (snapshot->mutex); - - return target; -} - -static inline cairo_bool_t -_cairo_surface_is_snapshot (cairo_surface_t *surface) -{ - return surface->backend->type == (cairo_surface_type_t)CAIRO_INTERNAL_SURFACE_TYPE_SNAPSHOT; -} - -#endif /* CAIRO_SURFACE_SNAPSHOT_INLINE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-surface-snapshot-private.h b/source/libs/cairo/cairo-src/src/cairo-surface-snapshot-private.h deleted file mode 100644 index 58bee7b49dd198d245b73e7500e7a8a1d7908a4e..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-surface-snapshot-private.h +++ /dev/null @@ -1,51 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Intel Corporation. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_SURFACE_SNAPSHOT_PRIVATE_H -#define CAIRO_SURFACE_SNAPSHOT_PRIVATE_H - -#include "cairo-mutex-private.h" -#include "cairo-surface-private.h" -#include "cairo-surface-backend-private.h" - -struct _cairo_surface_snapshot { - cairo_surface_t base; - - cairo_mutex_t mutex; - cairo_surface_t *target; - cairo_surface_t *clone; -}; - -#endif /* CAIRO_SURFACE_SNAPSHOT_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-surface-snapshot.c b/source/libs/cairo/cairo-src/src/cairo-surface-snapshot.c deleted file mode 100644 index 68bf9054ecdcf6068143af6af0d2b71377840fee..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-surface-snapshot.c +++ /dev/null @@ -1,289 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-error-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-surface-snapshot-inline.h" - -static cairo_status_t -_cairo_surface_snapshot_finish (void *abstract_surface) -{ - cairo_surface_snapshot_t *surface = abstract_surface; - cairo_status_t status = CAIRO_STATUS_SUCCESS; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - if (surface->clone != NULL) { - cairo_surface_finish (surface->clone); - status = surface->clone->status; - - cairo_surface_destroy (surface->clone); - } - - CAIRO_MUTEX_FINI (surface->mutex); - - return status; -} - -static cairo_status_t -_cairo_surface_snapshot_flush (void *abstract_surface, unsigned flags) -{ - cairo_surface_snapshot_t *surface = abstract_surface; - cairo_surface_t *target; - cairo_status_t status; - - target = _cairo_surface_snapshot_get_target (&surface->base); - status = _cairo_surface_flush (target, flags); - cairo_surface_destroy (target); - - return status; -} - -static cairo_surface_t * -_cairo_surface_snapshot_source (void *abstract_surface, - cairo_rectangle_int_t *extents) -{ - cairo_surface_snapshot_t *surface = abstract_surface; - return _cairo_surface_get_source (surface->target, extents); /* XXX racy */ -} - -struct snapshot_extra { - cairo_surface_t *target; - void *extra; -}; - -static cairo_status_t -_cairo_surface_snapshot_acquire_source_image (void *abstract_surface, - cairo_image_surface_t **image_out, - void **extra_out) -{ - cairo_surface_snapshot_t *surface = abstract_surface; - struct snapshot_extra *extra; - cairo_status_t status; - - extra = malloc (sizeof (*extra)); - if (unlikely (extra == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - extra->target = _cairo_surface_snapshot_get_target (&surface->base); - status = _cairo_surface_acquire_source_image (extra->target, image_out, &extra->extra); - if (unlikely (status)) { - cairo_surface_destroy (extra->target); - free (extra); - } - - *extra_out = extra; - return status; -} - -static void -_cairo_surface_snapshot_release_source_image (void *abstract_surface, - cairo_image_surface_t *image, - void *_extra) -{ - struct snapshot_extra *extra = _extra; - - _cairo_surface_release_source_image (extra->target, image, extra->extra); - cairo_surface_destroy (extra->target); - free (extra); -} - -static cairo_bool_t -_cairo_surface_snapshot_get_extents (void *abstract_surface, - cairo_rectangle_int_t *extents) -{ - cairo_surface_snapshot_t *surface = abstract_surface; - cairo_surface_t *target; - cairo_bool_t bounded; - - target = _cairo_surface_snapshot_get_target (&surface->base); - bounded = _cairo_surface_get_extents (target, extents); - cairo_surface_destroy (target); - - return bounded; -} - -static const cairo_surface_backend_t _cairo_surface_snapshot_backend = { - CAIRO_INTERNAL_SURFACE_TYPE_SNAPSHOT, - _cairo_surface_snapshot_finish, - NULL, - - NULL, /* create similar */ - NULL, /* create similar image */ - NULL, /* map to image */ - NULL, /* unmap image */ - - _cairo_surface_snapshot_source, - _cairo_surface_snapshot_acquire_source_image, - _cairo_surface_snapshot_release_source_image, - NULL, /* snapshot */ - - NULL, /* copy_page */ - NULL, /* show_page */ - - _cairo_surface_snapshot_get_extents, - NULL, /* get-font-options */ - - _cairo_surface_snapshot_flush, -}; - -static void -_cairo_surface_snapshot_copy_on_write (cairo_surface_t *surface) -{ - cairo_surface_snapshot_t *snapshot = (cairo_surface_snapshot_t *) surface; - cairo_image_surface_t *image; - cairo_surface_t *clone; - void *extra; - cairo_status_t status; - - TRACE ((stderr, "%s: target=%d\n", - __FUNCTION__, snapshot->target->unique_id)); - - /* We need to make an image copy of the original surface since the - * snapshot may exceed the lifetime of the original device, i.e. - * when we later need to use the snapshot the data may have already - * been lost. - */ - - CAIRO_MUTEX_LOCK (snapshot->mutex); - - if (snapshot->target->backend->snapshot != NULL) { - clone = snapshot->target->backend->snapshot (snapshot->target); - if (clone != NULL) { - assert (clone->status || ! _cairo_surface_is_snapshot (clone)); - goto done; - } - } - - /* XXX copy to a similar surface, leave acquisition till later? - * We should probably leave such decisions to the backend in case we - * rely upon devices/connections like Xlib. - */ - status = _cairo_surface_acquire_source_image (snapshot->target, &image, &extra); - if (unlikely (status)) { - snapshot->target = _cairo_surface_create_in_error (status); - status = _cairo_surface_set_error (surface, status); - goto unlock; - } - clone = image->base.backend->snapshot (&image->base); - _cairo_surface_release_source_image (snapshot->target, image, extra); - -done: - status = _cairo_surface_set_error (surface, clone->status); - snapshot->target = snapshot->clone = clone; - snapshot->base.type = clone->type; -unlock: - CAIRO_MUTEX_UNLOCK (snapshot->mutex); -} - -/** - * _cairo_surface_snapshot: - * @surface: a #cairo_surface_t - * - * Make an immutable reference to @surface. It is an error to call a - * surface-modifying function on the result of this function. The - * resulting 'snapshot' is a lazily copied-on-write surface i.e. it - * remains a reference to the original surface until that surface is - * written to again, at which time a copy is made of the original surface - * and the snapshot then points to that instead. Multiple snapshots of the - * same unmodified surface point to the same copy. - * - * The caller owns the return value and should call - * cairo_surface_destroy() when finished with it. This function will not - * return %NULL, but will return a nil surface instead. - * - * Return value: The snapshot surface. Note that the return surface - * may not necessarily be of the same type as @surface. - **/ -cairo_surface_t * -_cairo_surface_snapshot (cairo_surface_t *surface) -{ - cairo_surface_snapshot_t *snapshot; - cairo_status_t status; - - TRACE ((stderr, "%s: target=%d\n", __FUNCTION__, surface->unique_id)); - - if (unlikely (surface->status)) - return _cairo_surface_create_in_error (surface->status); - - if (unlikely (surface->finished)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - - if (surface->snapshot_of != NULL) - return cairo_surface_reference (surface); - - if (_cairo_surface_is_snapshot (surface)) - return cairo_surface_reference (surface); - - snapshot = (cairo_surface_snapshot_t *) - _cairo_surface_has_snapshot (surface, &_cairo_surface_snapshot_backend); - if (snapshot != NULL) - return cairo_surface_reference (&snapshot->base); - - snapshot = malloc (sizeof (cairo_surface_snapshot_t)); - if (unlikely (snapshot == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - - _cairo_surface_init (&snapshot->base, - &_cairo_surface_snapshot_backend, - NULL, /* device */ - surface->content); - snapshot->base.type = surface->type; - - CAIRO_MUTEX_INIT (snapshot->mutex); - snapshot->target = surface; - snapshot->clone = NULL; - - status = _cairo_surface_copy_mime_data (&snapshot->base, surface); - if (unlikely (status)) { - cairo_surface_destroy (&snapshot->base); - return _cairo_surface_create_in_error (status); - } - - snapshot->base.device_transform = surface->device_transform; - snapshot->base.device_transform_inverse = surface->device_transform_inverse; - - _cairo_surface_attach_snapshot (surface, - &snapshot->base, - _cairo_surface_snapshot_copy_on_write); - - return &snapshot->base; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-surface-subsurface-inline.h b/source/libs/cairo/cairo-src/src/cairo-surface-subsurface-inline.h deleted file mode 100644 index 0cd09e63e7038b68fda61b18e3f4d9820d1dc9a8..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-surface-subsurface-inline.h +++ /dev/null @@ -1,72 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Intel Corporation. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_SURFACE_SUBSURFACE_INLINE_H -#define CAIRO_SURFACE_SUBSURFACE_INLINE_H - -#include "cairo-surface-subsurface-private.h" - -static inline cairo_surface_t * -_cairo_surface_subsurface_get_target (cairo_surface_t *surface) -{ - return ((cairo_surface_subsurface_t *) surface)->target; -} - -static inline void -_cairo_surface_subsurface_offset (cairo_surface_t *surface, - int *x, int *y) -{ - cairo_surface_subsurface_t *ss = (cairo_surface_subsurface_t *) surface; - *x += ss->extents.x; - *y += ss->extents.y; -} - -static inline cairo_surface_t * -_cairo_surface_subsurface_get_target_with_offset (cairo_surface_t *surface, - int *x, int *y) -{ - cairo_surface_subsurface_t *ss = (cairo_surface_subsurface_t *) surface; - *x += ss->extents.x; - *y += ss->extents.y; - return ss->target; -} - -static inline cairo_bool_t -_cairo_surface_is_subsurface (cairo_surface_t *surface) -{ - return surface->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE; -} - -#endif /* CAIRO_SURFACE_SUBSURFACE_INLINE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-surface-subsurface-private.h b/source/libs/cairo/cairo-src/src/cairo-surface-subsurface-private.h deleted file mode 100644 index 89c5cc01b9d367f45da5720ab8bdea386f63b600..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-surface-subsurface-private.h +++ /dev/null @@ -1,55 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Intel Corporation. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_SURFACE_SUBSURFACE_PRIVATE_H -#define CAIRO_SURFACE_SUBSURFACE_PRIVATE_H - -#include "cairo-surface-private.h" -#include "cairo-surface-backend-private.h" - -struct _cairo_surface_subsurface { - cairo_surface_t base; - - cairo_rectangle_int_t extents; - - cairo_surface_t *target; - cairo_surface_t *snapshot; -}; - -cairo_private void -_cairo_surface_subsurface_set_snapshot (cairo_surface_t *surface, - cairo_surface_t *snapshot); - -#endif /* CAIRO_SURFACE_SUBSURFACE_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-surface-subsurface.c b/source/libs/cairo/cairo-src/src/cairo-surface-subsurface.c deleted file mode 100644 index b7dfd9d9e0cff30b445c9e0e60b5011048e52b45..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-surface-subsurface.c +++ /dev/null @@ -1,587 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Intel Corporation. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-clip-inline.h" -#include "cairo-error-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-recording-surface-private.h" -#include "cairo-surface-offset-private.h" -#include "cairo-surface-snapshot-private.h" -#include "cairo-surface-subsurface-private.h" - -static const cairo_surface_backend_t _cairo_surface_subsurface_backend; - -static cairo_status_t -_cairo_surface_subsurface_finish (void *abstract_surface) -{ - cairo_surface_subsurface_t *surface = abstract_surface; - - cairo_surface_destroy (surface->target); - cairo_surface_destroy (surface->snapshot); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_surface_t * -_cairo_surface_subsurface_create_similar (void *other, - cairo_content_t content, - int width, int height) -{ - cairo_surface_subsurface_t *surface = other; - - if (surface->target->backend->create_similar == NULL) - return NULL; - - return surface->target->backend->create_similar (surface->target, content, width, height); -} - -static cairo_surface_t * -_cairo_surface_subsurface_create_similar_image (void *other, - cairo_format_t format, - int width, int height) -{ - cairo_surface_subsurface_t *surface = other; - - if (surface->target->backend->create_similar_image == NULL) - return NULL; - - return surface->target->backend->create_similar_image (surface->target, - format, - width, height); -} - -static cairo_image_surface_t * -_cairo_surface_subsurface_map_to_image (void *abstract_surface, - const cairo_rectangle_int_t *extents) -{ - cairo_surface_subsurface_t *surface = abstract_surface; - cairo_rectangle_int_t target_extents; - - target_extents.x = extents->x + surface->extents.x; - target_extents.y = extents->y + surface->extents.y; - target_extents.width = extents->width; - target_extents.height = extents->height; - - return _cairo_surface_map_to_image (surface->target, &target_extents); -} - -static cairo_int_status_t -_cairo_surface_subsurface_unmap_image (void *abstract_surface, - cairo_image_surface_t *image) -{ - cairo_surface_subsurface_t *surface = abstract_surface; - return _cairo_surface_unmap_image (surface->target, image); -} - -static cairo_int_status_t -_cairo_surface_subsurface_paint (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - cairo_surface_subsurface_t *surface = abstract_surface; - cairo_rectangle_int_t rect = { 0, 0, surface->extents.width, surface->extents.height }; - cairo_status_t status; - cairo_clip_t *target_clip; - - target_clip = _cairo_clip_copy_intersect_rectangle (clip, &rect); - status = _cairo_surface_offset_paint (surface->target, - -surface->extents.x, -surface->extents.y, - op, source, target_clip); - _cairo_clip_destroy (target_clip); - return status; -} - -static cairo_int_status_t -_cairo_surface_subsurface_mask (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - cairo_surface_subsurface_t *surface = abstract_surface; - cairo_rectangle_int_t rect = { 0, 0, surface->extents.width, surface->extents.height }; - cairo_status_t status; - cairo_clip_t *target_clip; - - target_clip = _cairo_clip_copy_intersect_rectangle (clip, &rect); - status = _cairo_surface_offset_mask (surface->target, - -surface->extents.x, -surface->extents.y, - op, source, mask, target_clip); - _cairo_clip_destroy (target_clip); - return status; -} - -static cairo_int_status_t -_cairo_surface_subsurface_fill (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_surface_subsurface_t *surface = abstract_surface; - cairo_rectangle_int_t rect = { 0, 0, surface->extents.width, surface->extents.height }; - cairo_status_t status; - cairo_clip_t *target_clip; - - target_clip = _cairo_clip_copy_intersect_rectangle (clip, &rect); - status = _cairo_surface_offset_fill (surface->target, - -surface->extents.x, -surface->extents.y, - op, source, path, fill_rule, tolerance, antialias, - target_clip); - _cairo_clip_destroy (target_clip); - return status; -} - -static cairo_int_status_t -_cairo_surface_subsurface_stroke (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_surface_subsurface_t *surface = abstract_surface; - cairo_rectangle_int_t rect = { 0, 0, surface->extents.width, surface->extents.height }; - cairo_status_t status; - cairo_clip_t *target_clip; - - target_clip = _cairo_clip_copy_intersect_rectangle (clip, &rect); - status = _cairo_surface_offset_stroke (surface->target, - -surface->extents.x, -surface->extents.y, - op, source, path, stroke_style, ctm, ctm_inverse, - tolerance, antialias, - target_clip); - _cairo_clip_destroy (target_clip); - return status; -} - -static cairo_int_status_t -_cairo_surface_subsurface_glyphs (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - cairo_surface_subsurface_t *surface = abstract_surface; - cairo_rectangle_int_t rect = { 0, 0, surface->extents.width, surface->extents.height }; - cairo_status_t status; - cairo_clip_t *target_clip; - - target_clip = _cairo_clip_copy_intersect_rectangle (clip, &rect); - status = _cairo_surface_offset_glyphs (surface->target, - -surface->extents.x, -surface->extents.y, - op, source, - scaled_font, glyphs, num_glyphs, - target_clip); - _cairo_clip_destroy (target_clip); - return status; -} - -static cairo_status_t -_cairo_surface_subsurface_flush (void *abstract_surface, unsigned flags) -{ - cairo_surface_subsurface_t *surface = abstract_surface; - return _cairo_surface_flush (surface->target, flags); -} - -static cairo_status_t -_cairo_surface_subsurface_mark_dirty (void *abstract_surface, - int x, int y, - int width, int height) -{ - cairo_surface_subsurface_t *surface = abstract_surface; - cairo_status_t status; - - status = CAIRO_STATUS_SUCCESS; - if (surface->target->backend->mark_dirty_rectangle != NULL) { - cairo_rectangle_int_t rect, extents; - - rect.x = x; - rect.y = y; - rect.width = width; - rect.height = height; - - extents.x = extents.y = 0; - extents.width = surface->extents.width; - extents.height = surface->extents.height; - - if (_cairo_rectangle_intersect (&rect, &extents)) { - status = surface->target->backend->mark_dirty_rectangle (surface->target, - rect.x + surface->extents.x, - rect.y + surface->extents.y, - rect.width, rect.height); - } - } - - return status; -} - -static cairo_bool_t -_cairo_surface_subsurface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *extents) -{ - cairo_surface_subsurface_t *surface = abstract_surface; - - extents->x = 0; - extents->y = 0; - extents->width = surface->extents.width; - extents->height = surface->extents.height; - - return TRUE; -} - -static void -_cairo_surface_subsurface_get_font_options (void *abstract_surface, - cairo_font_options_t *options) -{ - cairo_surface_subsurface_t *surface = abstract_surface; - - if (surface->target->backend->get_font_options != NULL) - surface->target->backend->get_font_options (surface->target, options); -} - -static cairo_surface_t * -_cairo_surface_subsurface_source (void *abstract_surface, - cairo_rectangle_int_t *extents) -{ - cairo_surface_subsurface_t *surface = abstract_surface; - cairo_surface_t *source; - - source = _cairo_surface_get_source (surface->target, extents); - if (extents) - *extents = surface->extents; - - return source; -} - -static cairo_status_t -_cairo_surface_subsurface_acquire_source_image (void *abstract_surface, - cairo_image_surface_t **image_out, - void **extra_out) -{ - cairo_surface_subsurface_t *surface = abstract_surface; - cairo_surface_pattern_t pattern; - cairo_surface_t *image; - cairo_status_t status; - - image = _cairo_image_surface_create_with_content (surface->base.content, - surface->extents.width, - surface->extents.height); - if (unlikely (image->status)) - return image->status; - - _cairo_pattern_init_for_surface (&pattern, surface->target); - cairo_matrix_init_translate (&pattern.base.matrix, - surface->extents.x, - surface->extents.y); - pattern.base.filter = CAIRO_FILTER_NEAREST; - status = _cairo_surface_paint (image, - CAIRO_OPERATOR_SOURCE, - &pattern.base, NULL); - _cairo_pattern_fini (&pattern.base); - if (unlikely (status)) { - cairo_surface_destroy (image); - return status; - } - - *image_out = (cairo_image_surface_t *)image; - *extra_out = NULL; - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_surface_subsurface_release_source_image (void *abstract_surface, - cairo_image_surface_t *image, - void *abstract_extra) -{ - cairo_surface_destroy (&image->base); -} - -static cairo_surface_t * -_cairo_surface_subsurface_snapshot (void *abstract_surface) -{ - cairo_surface_subsurface_t *surface = abstract_surface; - cairo_surface_pattern_t pattern; - cairo_surface_t *clone; - cairo_status_t status; - - TRACE ((stderr, "%s: target=%d\n", __FUNCTION__, surface->target->unique_id)); - - clone = _cairo_surface_create_scratch (surface->target, - surface->target->content, - surface->extents.width, - surface->extents.height, - NULL); - if (unlikely (clone->status)) - return clone; - - _cairo_pattern_init_for_surface (&pattern, surface->target); - cairo_matrix_init_translate (&pattern.base.matrix, - surface->extents.x, surface->extents.y); - pattern.base.filter = CAIRO_FILTER_NEAREST; - status = _cairo_surface_paint (clone, - CAIRO_OPERATOR_SOURCE, - &pattern.base, NULL); - _cairo_pattern_fini (&pattern.base); - - if (unlikely (status)) { - cairo_surface_destroy (clone); - clone = _cairo_surface_create_in_error (status); - } - - return clone; -} - -static cairo_t * -_cairo_surface_subsurface_create_context(void *target) -{ - cairo_surface_subsurface_t *surface = target; - return surface->target->backend->create_context (&surface->base); -} - -static const cairo_surface_backend_t _cairo_surface_subsurface_backend = { - CAIRO_SURFACE_TYPE_SUBSURFACE, - _cairo_surface_subsurface_finish, - - _cairo_surface_subsurface_create_context, - - _cairo_surface_subsurface_create_similar, - _cairo_surface_subsurface_create_similar_image, - _cairo_surface_subsurface_map_to_image, - _cairo_surface_subsurface_unmap_image, - - _cairo_surface_subsurface_source, - _cairo_surface_subsurface_acquire_source_image, - _cairo_surface_subsurface_release_source_image, - _cairo_surface_subsurface_snapshot, - - NULL, /* copy_page */ - NULL, /* show_page */ - - _cairo_surface_subsurface_get_extents, - _cairo_surface_subsurface_get_font_options, - - _cairo_surface_subsurface_flush, - _cairo_surface_subsurface_mark_dirty, - - _cairo_surface_subsurface_paint, - _cairo_surface_subsurface_mask, - _cairo_surface_subsurface_stroke, - _cairo_surface_subsurface_fill, - NULL, /* fill/stroke */ - _cairo_surface_subsurface_glyphs, -}; - -/** - * cairo_surface_create_for_rectangle: - * @target: an existing surface for which the sub-surface will point to - * @x: the x-origin of the sub-surface from the top-left of the target surface (in device-space units) - * @y: the y-origin of the sub-surface from the top-left of the target surface (in device-space units) - * @width: width of the sub-surface (in device-space units) - * @height: height of the sub-surface (in device-space units) - * - * Create a new surface that is a rectangle within the target surface. - * All operations drawn to this surface are then clipped and translated - * onto the target surface. Nothing drawn via this sub-surface outside of - * its bounds is drawn onto the target surface, making this a useful method - * for passing constrained child surfaces to library routines that draw - * directly onto the parent surface, i.e. with no further backend allocations, - * double buffering or copies. - * - * <note><para>The semantics of subsurfaces have not been finalized yet - * unless the rectangle is in full device units, is contained within - * the extents of the target surface, and the target or subsurface's - * device transforms are not changed.</para></note> - * - * Return value: a pointer to the newly allocated surface. The caller - * owns the surface and should call cairo_surface_destroy() when done - * with it. - * - * This function always returns a valid pointer, but it will return a - * pointer to a "nil" surface if @other is already in an error state - * or any other error occurs. - * - * Since: 1.10 - **/ -cairo_surface_t * -cairo_surface_create_for_rectangle (cairo_surface_t *target, - double x, double y, - double width, double height) -{ - cairo_surface_subsurface_t *surface; - - if (unlikely (width < 0 || height < 0)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE)); - - if (unlikely (target->status)) - return _cairo_surface_create_in_error (target->status); - if (unlikely (target->finished)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - - surface = malloc (sizeof (cairo_surface_subsurface_t)); - if (unlikely (surface == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - x *= target->device_transform.xx; - y *= target->device_transform.yy; - - width *= target->device_transform.xx; - height *= target->device_transform.yy; - - x += target->device_transform.x0; - y += target->device_transform.y0; - - _cairo_surface_init (&surface->base, - &_cairo_surface_subsurface_backend, - NULL, /* device */ - target->content); - - /* XXX forced integer alignment */ - surface->extents.x = ceil (x); - surface->extents.y = ceil (y); - surface->extents.width = floor (x + width) - surface->extents.x; - surface->extents.height = floor (y + height) - surface->extents.y; - if ((surface->extents.width | surface->extents.height) < 0) - surface->extents.width = surface->extents.height = 0; - - if (target->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) { - /* Maintain subsurfaces as 1-depth */ - cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) target; - surface->extents.x += sub->extents.x; - surface->extents.y += sub->extents.y; - target = sub->target; - } - - surface->target = cairo_surface_reference (target); - surface->base.type = surface->target->type; - - surface->snapshot = NULL; - - cairo_surface_set_device_scale (&surface->base, - target->device_transform.xx, - target->device_transform.yy); - - return &surface->base; -} - -cairo_surface_t * -_cairo_surface_create_for_rectangle_int (cairo_surface_t *target, - const cairo_rectangle_int_t *extents) -{ - cairo_surface_subsurface_t *surface; - - if (unlikely (target->status)) - return _cairo_surface_create_in_error (target->status); - if (unlikely (target->finished)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - - assert (target->backend->type != CAIRO_SURFACE_TYPE_SUBSURFACE); - - surface = malloc (sizeof (cairo_surface_subsurface_t)); - if (unlikely (surface == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - _cairo_surface_init (&surface->base, - &_cairo_surface_subsurface_backend, - NULL, /* device */ - target->content); - - surface->extents = *extents; - surface->extents.x *= target->device_transform.xx; - surface->extents.y *= target->device_transform.yy; - surface->extents.width *= target->device_transform.xx; - surface->extents.height *= target->device_transform.yy; - surface->extents.x += target->device_transform.x0; - surface->extents.y += target->device_transform.y0; - - surface->target = cairo_surface_reference (target); - surface->base.type = surface->target->type; - - surface->snapshot = NULL; - - cairo_surface_set_device_scale (&surface->base, - target->device_transform.xx, - target->device_transform.yy); - - return &surface->base; -} -/* XXX observe mark-dirty */ - -static void -_cairo_surface_subsurface_detach_snapshot (cairo_surface_t *surface) -{ - cairo_surface_subsurface_t *ss = (cairo_surface_subsurface_t *) surface; - - TRACE ((stderr, "%s: target=%d\n", __FUNCTION__, ss->target->unique_id)); - - cairo_surface_destroy (ss->snapshot); - ss->snapshot = NULL; -} - -void -_cairo_surface_subsurface_set_snapshot (cairo_surface_t *surface, - cairo_surface_t *snapshot) -{ - cairo_surface_subsurface_t *ss = (cairo_surface_subsurface_t *) surface; - - TRACE ((stderr, "%s: target=%d, snapshot=%d\n", __FUNCTION__, - ss->target->unique_id, snapshot->unique_id)); - - /* FIXME: attaching the subsurface as a snapshot to its target creates - * a reference cycle. Let's make this call as a no-op until that bug - * is fixed. - */ - return; - - if (ss->snapshot) - _cairo_surface_detach_snapshot (ss->snapshot); - - ss->snapshot = cairo_surface_reference (snapshot); - - _cairo_surface_attach_snapshot (ss->target, &ss->base, - _cairo_surface_subsurface_detach_snapshot); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-surface-wrapper-private.h b/source/libs/cairo/cairo-src/src/cairo-surface-wrapper-private.h deleted file mode 100644 index 6529ebc111550c2b5c22fcb5aad909a797d891e3..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-surface-wrapper-private.h +++ /dev/null @@ -1,193 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.u> - */ - -#ifndef CAIRO_SURFACE_WRAPPER_PRIVATE_H -#define CAIRO_SURFACE_WRAPPER_PRIVATE_H - -#include "cairoint.h" -#include "cairo-types-private.h" -#include "cairo-surface-backend-private.h" - -CAIRO_BEGIN_DECLS - -struct _cairo_surface_wrapper { - cairo_surface_t *target; - - cairo_matrix_t transform; - - cairo_bool_t has_extents; - cairo_rectangle_int_t extents; - const cairo_clip_t *clip; - - cairo_bool_t needs_transform; -}; - -cairo_private void -_cairo_surface_wrapper_init (cairo_surface_wrapper_t *wrapper, - cairo_surface_t *target); - -cairo_private void -_cairo_surface_wrapper_intersect_extents (cairo_surface_wrapper_t *wrapper, - const cairo_rectangle_int_t *extents); - -cairo_private void -_cairo_surface_wrapper_set_inverse_transform (cairo_surface_wrapper_t *wrapper, - const cairo_matrix_t *transform); - -cairo_private void -_cairo_surface_wrapper_set_clip (cairo_surface_wrapper_t *wrapper, - const cairo_clip_t *clip); - -cairo_private void -_cairo_surface_wrapper_fini (cairo_surface_wrapper_t *wrapper); - -static inline cairo_bool_t -_cairo_surface_wrapper_has_fill_stroke (cairo_surface_wrapper_t *wrapper) -{ - return wrapper->target->backend->fill_stroke != NULL; -} - -cairo_private cairo_status_t -_cairo_surface_wrapper_acquire_source_image (cairo_surface_wrapper_t *wrapper, - cairo_image_surface_t **image_out, - void **image_extra); - -cairo_private void -_cairo_surface_wrapper_release_source_image (cairo_surface_wrapper_t *wrapper, - cairo_image_surface_t *image, - void *image_extra); - - -cairo_private cairo_status_t -_cairo_surface_wrapper_paint (cairo_surface_wrapper_t *wrapper, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip); - -cairo_private cairo_status_t -_cairo_surface_wrapper_mask (cairo_surface_wrapper_t *wrapper, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip); - -cairo_private cairo_status_t -_cairo_surface_wrapper_stroke (cairo_surface_wrapper_t *wrapper, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip); - -cairo_private cairo_status_t -_cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper, - cairo_operator_t fill_op, - const cairo_pattern_t *fill_source, - cairo_fill_rule_t fill_rule, - double fill_tolerance, - cairo_antialias_t fill_antialias, - const cairo_path_fixed_t*path, - cairo_operator_t stroke_op, - const cairo_pattern_t *stroke_source, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *stroke_ctm, - const cairo_matrix_t *stroke_ctm_inverse, - double stroke_tolerance, - cairo_antialias_t stroke_antialias, - const cairo_clip_t *clip); - -cairo_private cairo_status_t -_cairo_surface_wrapper_fill (cairo_surface_wrapper_t *wrapper, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip); - -cairo_private cairo_status_t -_cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper, - cairo_operator_t op, - const cairo_pattern_t *source, - const char *utf8, - int utf8_len, - const cairo_glyph_t *glyphs, - int num_glyphs, - const cairo_text_cluster_t *clusters, - int num_clusters, - cairo_text_cluster_flags_t cluster_flags, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip); - -cairo_private cairo_surface_t * -_cairo_surface_wrapper_create_similar (cairo_surface_wrapper_t *wrapper, - cairo_content_t content, - int width, - int height); -cairo_private cairo_bool_t -_cairo_surface_wrapper_get_extents (cairo_surface_wrapper_t *wrapper, - cairo_rectangle_int_t *extents); - -cairo_private void -_cairo_surface_wrapper_get_font_options (cairo_surface_wrapper_t *wrapper, - cairo_font_options_t *options); - -cairo_private cairo_surface_t * -_cairo_surface_wrapper_snapshot (cairo_surface_wrapper_t *wrapper); - -cairo_private cairo_bool_t -_cairo_surface_wrapper_has_show_text_glyphs (cairo_surface_wrapper_t *wrapper); - -static inline cairo_bool_t -_cairo_surface_wrapper_is_active (cairo_surface_wrapper_t *wrapper) -{ - return wrapper->target != (cairo_surface_t *) 0; -} - -cairo_private cairo_bool_t -_cairo_surface_wrapper_get_target_extents (cairo_surface_wrapper_t *wrapper, - cairo_rectangle_int_t *extents); - -CAIRO_END_DECLS - -#endif /* CAIRO_SURFACE_WRAPPER_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-surface-wrapper.c b/source/libs/cairo/cairo-src/src/cairo-surface-wrapper.c deleted file mode 100644 index 9236c8bf42e546325dbfbf99d834962aa08f6e64..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-surface-wrapper.c +++ /dev/null @@ -1,685 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2005 Red Hat, Inc - * Copyright © 2007 Adrian Johnson - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-clip-inline.h" -#include "cairo-error-private.h" -#include "cairo-pattern-private.h" -#include "cairo-surface-wrapper-private.h" - -/* A collection of routines to facilitate surface wrapping */ - -static void -_copy_transformed_pattern (cairo_pattern_t *pattern, - const cairo_pattern_t *original, - const cairo_matrix_t *ctm_inverse) -{ - _cairo_pattern_init_static_copy (pattern, original); - - if (! _cairo_matrix_is_identity (ctm_inverse)) - _cairo_pattern_transform (pattern, ctm_inverse); -} - -cairo_status_t -_cairo_surface_wrapper_acquire_source_image (cairo_surface_wrapper_t *wrapper, - cairo_image_surface_t **image_out, - void **image_extra) -{ - if (unlikely (wrapper->target->status)) - return wrapper->target->status; - - return _cairo_surface_acquire_source_image (wrapper->target, - image_out, image_extra); -} - -void -_cairo_surface_wrapper_release_source_image (cairo_surface_wrapper_t *wrapper, - cairo_image_surface_t *image, - void *image_extra) -{ - _cairo_surface_release_source_image (wrapper->target, image, image_extra); -} - -static void -_cairo_surface_wrapper_get_transform (cairo_surface_wrapper_t *wrapper, - cairo_matrix_t *m) -{ - cairo_matrix_init_identity (m); - - if (wrapper->has_extents && (wrapper->extents.x || wrapper->extents.y)) - cairo_matrix_translate (m, -wrapper->extents.x, -wrapper->extents.y); - - if (! _cairo_matrix_is_identity (&wrapper->transform)) - cairo_matrix_multiply (m, &wrapper->transform, m); - - if (! _cairo_matrix_is_identity (&wrapper->target->device_transform)) - cairo_matrix_multiply (m, &wrapper->target->device_transform, m); -} - -static void -_cairo_surface_wrapper_get_inverse_transform (cairo_surface_wrapper_t *wrapper, - cairo_matrix_t *m) -{ - cairo_matrix_init_identity (m); - - if (! _cairo_matrix_is_identity (&wrapper->target->device_transform_inverse)) - cairo_matrix_multiply (m, &wrapper->target->device_transform_inverse, m); - - if (! _cairo_matrix_is_identity (&wrapper->transform)) { - cairo_matrix_t inv; - cairo_status_t status; - - inv = wrapper->transform; - status = cairo_matrix_invert (&inv); - assert (status == CAIRO_STATUS_SUCCESS); - cairo_matrix_multiply (m, &inv, m); - } - - if (wrapper->has_extents && (wrapper->extents.x || wrapper->extents.y)) - cairo_matrix_translate (m, wrapper->extents.x, wrapper->extents.y); -} - -static cairo_clip_t * -_cairo_surface_wrapper_get_clip (cairo_surface_wrapper_t *wrapper, - const cairo_clip_t *clip) -{ - cairo_clip_t *copy; - - copy = _cairo_clip_copy (clip); - if (wrapper->has_extents) { - copy = _cairo_clip_intersect_rectangle (copy, &wrapper->extents); - } - copy = _cairo_clip_transform (copy, &wrapper->transform); - if (! _cairo_matrix_is_identity (&wrapper->target->device_transform)) - copy = _cairo_clip_transform (copy, &wrapper->target->device_transform); - if (wrapper->clip) - copy = _cairo_clip_intersect_clip (copy, wrapper->clip); - - return copy; -} - -cairo_status_t -_cairo_surface_wrapper_paint (cairo_surface_wrapper_t *wrapper, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - cairo_status_t status; - cairo_clip_t *dev_clip; - cairo_pattern_union_t source_copy; - - if (unlikely (wrapper->target->status)) - return wrapper->target->status; - - dev_clip = _cairo_surface_wrapper_get_clip (wrapper, clip); - if (_cairo_clip_is_all_clipped (dev_clip)) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - if (wrapper->needs_transform) { - cairo_matrix_t m; - - _cairo_surface_wrapper_get_transform (wrapper, &m); - - status = cairo_matrix_invert (&m); - assert (status == CAIRO_STATUS_SUCCESS); - - _copy_transformed_pattern (&source_copy.base, source, &m); - source = &source_copy.base; - } - - status = _cairo_surface_paint (wrapper->target, op, source, dev_clip); - - _cairo_clip_destroy (dev_clip); - return status; -} - - -cairo_status_t -_cairo_surface_wrapper_mask (cairo_surface_wrapper_t *wrapper, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - cairo_status_t status; - cairo_clip_t *dev_clip; - cairo_pattern_union_t source_copy; - cairo_pattern_union_t mask_copy; - - if (unlikely (wrapper->target->status)) - return wrapper->target->status; - - dev_clip = _cairo_surface_wrapper_get_clip (wrapper, clip); - if (_cairo_clip_is_all_clipped (dev_clip)) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - if (wrapper->needs_transform) { - cairo_matrix_t m; - - _cairo_surface_wrapper_get_transform (wrapper, &m); - - status = cairo_matrix_invert (&m); - assert (status == CAIRO_STATUS_SUCCESS); - - _copy_transformed_pattern (&source_copy.base, source, &m); - source = &source_copy.base; - - _copy_transformed_pattern (&mask_copy.base, mask, &m); - mask = &mask_copy.base; - } - - status = _cairo_surface_mask (wrapper->target, op, source, mask, dev_clip); - - _cairo_clip_destroy (dev_clip); - return status; -} - -cairo_status_t -_cairo_surface_wrapper_stroke (cairo_surface_wrapper_t *wrapper, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_status_t status; - cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *) path; - cairo_clip_t *dev_clip; - cairo_matrix_t dev_ctm = *ctm; - cairo_matrix_t dev_ctm_inverse = *ctm_inverse; - cairo_pattern_union_t source_copy; - - if (unlikely (wrapper->target->status)) - return wrapper->target->status; - - dev_clip = _cairo_surface_wrapper_get_clip (wrapper, clip); - if (_cairo_clip_is_all_clipped (dev_clip)) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - if (wrapper->needs_transform) { - cairo_matrix_t m; - - _cairo_surface_wrapper_get_transform (wrapper, &m); - - status = _cairo_path_fixed_init_copy (&path_copy, dev_path); - if (unlikely (status)) - goto FINISH; - - _cairo_path_fixed_transform (&path_copy, &m); - dev_path = &path_copy; - - cairo_matrix_multiply (&dev_ctm, &dev_ctm, &m); - - status = cairo_matrix_invert (&m); - assert (status == CAIRO_STATUS_SUCCESS); - - cairo_matrix_multiply (&dev_ctm_inverse, &m, &dev_ctm_inverse); - - _copy_transformed_pattern (&source_copy.base, source, &m); - source = &source_copy.base; - } - - status = _cairo_surface_stroke (wrapper->target, op, source, - dev_path, stroke_style, - &dev_ctm, &dev_ctm_inverse, - tolerance, antialias, - dev_clip); - - FINISH: - if (dev_path != path) - _cairo_path_fixed_fini (dev_path); - _cairo_clip_destroy (dev_clip); - return status; -} - -cairo_status_t -_cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper, - cairo_operator_t fill_op, - const cairo_pattern_t *fill_source, - cairo_fill_rule_t fill_rule, - double fill_tolerance, - cairo_antialias_t fill_antialias, - const cairo_path_fixed_t*path, - cairo_operator_t stroke_op, - const cairo_pattern_t *stroke_source, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *stroke_ctm, - const cairo_matrix_t *stroke_ctm_inverse, - double stroke_tolerance, - cairo_antialias_t stroke_antialias, - const cairo_clip_t *clip) -{ - cairo_status_t status; - cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *)path; - cairo_matrix_t dev_ctm = *stroke_ctm; - cairo_matrix_t dev_ctm_inverse = *stroke_ctm_inverse; - cairo_clip_t *dev_clip; - cairo_pattern_union_t stroke_source_copy; - cairo_pattern_union_t fill_source_copy; - - if (unlikely (wrapper->target->status)) - return wrapper->target->status; - - dev_clip = _cairo_surface_wrapper_get_clip (wrapper, clip); - if (_cairo_clip_is_all_clipped (dev_clip)) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - if (wrapper->needs_transform) { - cairo_matrix_t m; - - _cairo_surface_wrapper_get_transform (wrapper, &m); - - status = _cairo_path_fixed_init_copy (&path_copy, dev_path); - if (unlikely (status)) - goto FINISH; - - _cairo_path_fixed_transform (&path_copy, &m); - dev_path = &path_copy; - - cairo_matrix_multiply (&dev_ctm, &dev_ctm, &m); - - status = cairo_matrix_invert (&m); - assert (status == CAIRO_STATUS_SUCCESS); - - cairo_matrix_multiply (&dev_ctm_inverse, &m, &dev_ctm_inverse); - - _copy_transformed_pattern (&stroke_source_copy.base, stroke_source, &m); - stroke_source = &stroke_source_copy.base; - - _copy_transformed_pattern (&fill_source_copy.base, fill_source, &m); - fill_source = &fill_source_copy.base; - } - - status = _cairo_surface_fill_stroke (wrapper->target, - fill_op, fill_source, fill_rule, - fill_tolerance, fill_antialias, - dev_path, - stroke_op, stroke_source, - stroke_style, - &dev_ctm, &dev_ctm_inverse, - stroke_tolerance, stroke_antialias, - dev_clip); - - FINISH: - if (dev_path != path) - _cairo_path_fixed_fini (dev_path); - _cairo_clip_destroy (dev_clip); - return status; -} - -cairo_status_t -_cairo_surface_wrapper_fill (cairo_surface_wrapper_t *wrapper, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_status_t status; - cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *) path; - cairo_pattern_union_t source_copy; - cairo_clip_t *dev_clip; - - if (unlikely (wrapper->target->status)) - return wrapper->target->status; - - dev_clip = _cairo_surface_wrapper_get_clip (wrapper, clip); - if (_cairo_clip_is_all_clipped (dev_clip)) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - if (wrapper->needs_transform) { - cairo_matrix_t m; - - _cairo_surface_wrapper_get_transform (wrapper, &m); - - status = _cairo_path_fixed_init_copy (&path_copy, dev_path); - if (unlikely (status)) - goto FINISH; - - _cairo_path_fixed_transform (&path_copy, &m); - dev_path = &path_copy; - - status = cairo_matrix_invert (&m); - assert (status == CAIRO_STATUS_SUCCESS); - - _copy_transformed_pattern (&source_copy.base, source, &m); - source = &source_copy.base; - } - - status = _cairo_surface_fill (wrapper->target, op, source, - dev_path, fill_rule, - tolerance, antialias, - dev_clip); - - FINISH: - if (dev_path != path) - _cairo_path_fixed_fini (dev_path); - _cairo_clip_destroy (dev_clip); - return status; -} - -cairo_status_t -_cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper, - cairo_operator_t op, - const cairo_pattern_t *source, - const char *utf8, - int utf8_len, - const cairo_glyph_t *glyphs, - int num_glyphs, - const cairo_text_cluster_t *clusters, - int num_clusters, - cairo_text_cluster_flags_t cluster_flags, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - cairo_status_t status; - cairo_clip_t *dev_clip; - cairo_glyph_t stack_glyphs [CAIRO_STACK_ARRAY_LENGTH(cairo_glyph_t)]; - cairo_glyph_t *dev_glyphs = stack_glyphs; - cairo_scaled_font_t *dev_scaled_font = scaled_font; - cairo_pattern_union_t source_copy; - cairo_font_options_t options; - - if (unlikely (wrapper->target->status)) - return wrapper->target->status; - - dev_clip = _cairo_surface_wrapper_get_clip (wrapper, clip); - if (_cairo_clip_is_all_clipped (dev_clip)) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - cairo_surface_get_font_options (wrapper->target, &options); - cairo_font_options_merge (&options, &scaled_font->options); - - if (wrapper->needs_transform) { - cairo_matrix_t m; - int i; - - _cairo_surface_wrapper_get_transform (wrapper, &m); - - if (! _cairo_matrix_is_translation (&m)) { - cairo_matrix_t ctm; - - _cairo_matrix_multiply (&ctm, - &m, - &scaled_font->ctm); - dev_scaled_font = cairo_scaled_font_create (scaled_font->font_face, - &scaled_font->font_matrix, - &ctm, &options); - } - - if (num_glyphs > ARRAY_LENGTH (stack_glyphs)) { - dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); - if (unlikely (dev_glyphs == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto FINISH; - } - } - - for (i = 0; i < num_glyphs; i++) { - dev_glyphs[i] = glyphs[i]; - cairo_matrix_transform_point (&m, - &dev_glyphs[i].x, - &dev_glyphs[i].y); - } - - status = cairo_matrix_invert (&m); - assert (status == CAIRO_STATUS_SUCCESS); - - _copy_transformed_pattern (&source_copy.base, source, &m); - source = &source_copy.base; - } else { - if (! cairo_font_options_equal (&options, &scaled_font->options)) { - dev_scaled_font = cairo_scaled_font_create (scaled_font->font_face, - &scaled_font->font_matrix, - &scaled_font->ctm, - &options); - } - - /* show_text_glyphs is special because _cairo_surface_show_text_glyphs is allowed - * to modify the glyph array that's passed in. We must always - * copy the array before handing it to the backend. - */ - if (num_glyphs > ARRAY_LENGTH (stack_glyphs)) { - dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); - if (unlikely (dev_glyphs == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto FINISH; - } - } - - memcpy (dev_glyphs, glyphs, sizeof (cairo_glyph_t) * num_glyphs); - } - - status = _cairo_surface_show_text_glyphs (wrapper->target, op, source, - utf8, utf8_len, - dev_glyphs, num_glyphs, - clusters, num_clusters, - cluster_flags, - dev_scaled_font, - dev_clip); - FINISH: - _cairo_clip_destroy (dev_clip); - if (dev_glyphs != stack_glyphs) - free (dev_glyphs); - if (dev_scaled_font != scaled_font) - cairo_scaled_font_destroy (dev_scaled_font); - return status; -} - -cairo_surface_t * -_cairo_surface_wrapper_create_similar (cairo_surface_wrapper_t *wrapper, - cairo_content_t content, - int width, - int height) -{ - return _cairo_surface_create_scratch (wrapper->target, - content, width, height, NULL); -} - -cairo_bool_t -_cairo_surface_wrapper_get_extents (cairo_surface_wrapper_t *wrapper, - cairo_rectangle_int_t *extents) -{ - if (wrapper->has_extents) { - if (_cairo_surface_get_extents (wrapper->target, extents)) - _cairo_rectangle_intersect (extents, &wrapper->extents); - else - *extents = wrapper->extents; - - return TRUE; - } else { - return _cairo_surface_get_extents (wrapper->target, extents); - } -} - -static cairo_bool_t -_cairo_surface_wrapper_needs_device_transform (cairo_surface_wrapper_t *wrapper) -{ - return - (wrapper->has_extents && (wrapper->extents.x | wrapper->extents.y)) || - ! _cairo_matrix_is_identity (&wrapper->transform) || - ! _cairo_matrix_is_identity (&wrapper->target->device_transform); -} - -void -_cairo_surface_wrapper_intersect_extents (cairo_surface_wrapper_t *wrapper, - const cairo_rectangle_int_t *extents) -{ - if (! wrapper->has_extents) { - wrapper->extents = *extents; - wrapper->has_extents = TRUE; - } else - _cairo_rectangle_intersect (&wrapper->extents, extents); - - wrapper->needs_transform = - _cairo_surface_wrapper_needs_device_transform (wrapper); -} - -void -_cairo_surface_wrapper_set_inverse_transform (cairo_surface_wrapper_t *wrapper, - const cairo_matrix_t *transform) -{ - cairo_status_t status; - - if (transform == NULL || _cairo_matrix_is_identity (transform)) { - cairo_matrix_init_identity (&wrapper->transform); - - wrapper->needs_transform = - _cairo_surface_wrapper_needs_device_transform (wrapper); - } else { - wrapper->transform = *transform; - status = cairo_matrix_invert (&wrapper->transform); - /* should always be invertible unless given pathological input */ - assert (status == CAIRO_STATUS_SUCCESS); - - wrapper->needs_transform = TRUE; - } -} - -void -_cairo_surface_wrapper_set_clip (cairo_surface_wrapper_t *wrapper, - const cairo_clip_t *clip) -{ - wrapper->clip = clip; -} - -void -_cairo_surface_wrapper_get_font_options (cairo_surface_wrapper_t *wrapper, - cairo_font_options_t *options) -{ - cairo_surface_get_font_options (wrapper->target, options); -} - -cairo_surface_t * -_cairo_surface_wrapper_snapshot (cairo_surface_wrapper_t *wrapper) -{ - if (wrapper->target->backend->snapshot) - return wrapper->target->backend->snapshot (wrapper->target); - - return NULL; -} - -cairo_bool_t -_cairo_surface_wrapper_has_show_text_glyphs (cairo_surface_wrapper_t *wrapper) -{ - return cairo_surface_has_show_text_glyphs (wrapper->target); -} - -void -_cairo_surface_wrapper_init (cairo_surface_wrapper_t *wrapper, - cairo_surface_t *target) -{ - wrapper->target = cairo_surface_reference (target); - cairo_matrix_init_identity (&wrapper->transform); - wrapper->has_extents = FALSE; - wrapper->extents.x = wrapper->extents.y = 0; - wrapper->clip = NULL; - - wrapper->needs_transform = FALSE; - if (target) { - wrapper->needs_transform = - ! _cairo_matrix_is_identity (&target->device_transform); - } -} - -void -_cairo_surface_wrapper_fini (cairo_surface_wrapper_t *wrapper) -{ - cairo_surface_destroy (wrapper->target); -} - -cairo_bool_t -_cairo_surface_wrapper_get_target_extents (cairo_surface_wrapper_t *wrapper, - cairo_rectangle_int_t *extents) -{ - cairo_rectangle_int_t clip; - cairo_bool_t has_clip; - - has_clip = _cairo_surface_get_extents (wrapper->target, &clip); - if (wrapper->clip) { - if (has_clip) { - if (! _cairo_rectangle_intersect (&clip, - _cairo_clip_get_extents (wrapper->clip))) - return FALSE; - } else { - has_clip = TRUE; - clip = *_cairo_clip_get_extents (wrapper->clip); - } - } - - if (has_clip && wrapper->needs_transform) { - cairo_matrix_t m; - double x1, y1, x2, y2; - - _cairo_surface_wrapper_get_inverse_transform (wrapper, &m); - - x1 = clip.x; - y1 = clip.y; - x2 = clip.x + clip.width; - y2 = clip.y + clip.height; - - _cairo_matrix_transform_bounding_box (&m, &x1, &y1, &x2, &y2, NULL); - - clip.x = floor (x1); - clip.y = floor (y1); - clip.width = ceil (x2) - clip.x; - clip.height = ceil (y2) - clip.y; - } - - if (has_clip) { - if (wrapper->has_extents) { - *extents = wrapper->extents; - return _cairo_rectangle_intersect (extents, &clip); - } else { - *extents = clip; - return TRUE; - } - } else if (wrapper->has_extents) { - *extents = wrapper->extents; - return TRUE; - } else { - _cairo_unbounded_rectangle_init (extents); - return TRUE; - } -} diff --git a/source/libs/cairo/cairo-src/src/cairo-surface.c b/source/libs/cairo/cairo-src/src/cairo-surface.c deleted file mode 100644 index bfe3fa1064c4068227de6f9ea168f0b126ae205a..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-surface.c +++ /dev/null @@ -1,2749 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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" - -#include "cairo-array-private.h" -#include "cairo-clip-inline.h" -#include "cairo-clip-private.h" -#include "cairo-damage-private.h" -#include "cairo-device-private.h" -#include "cairo-error-private.h" -#include "cairo-list-inline.h" -#include "cairo-image-surface-inline.h" -#include "cairo-recording-surface-private.h" -#include "cairo-region-private.h" -#include "cairo-surface-inline.h" -#include "cairo-tee-surface-private.h" - -/** - * SECTION:cairo-surface - * @Title: cairo_surface_t - * @Short_Description: Base class for surfaces - * @See_Also: #cairo_t, #cairo_pattern_t - * - * #cairo_surface_t is the abstract type representing all different drawing - * targets that cairo can render to. The actual drawings are - * performed using a cairo <firstterm>context</firstterm>. - * - * A cairo surface is created by using <firstterm>backend</firstterm>-specific - * constructors, typically of the form - * <function>cairo_<emphasis>backend</emphasis>_surface_create(<!-- -->)</function>. - * - * Most surface types allow accessing the surface without using Cairo - * functions. If you do this, keep in mind that it is mandatory that you call - * cairo_surface_flush() before reading from or writing to the surface and that - * you must use cairo_surface_mark_dirty() after modifying it. - * <example> - * <title>Directly modifying an image surface</title> - * <programlisting> - * void - * modify_image_surface (cairo_surface_t *surface) - * { - * unsigned char *data; - * int width, height, stride; - * - * // flush to ensure all writing to the image was done - * cairo_surface_flush (surface); - * - * // modify the image - * data = cairo_image_surface_get_data (surface); - * width = cairo_image_surface_get_width (surface); - * height = cairo_image_surface_get_height (surface); - * stride = cairo_image_surface_get_stride (surface); - * modify_image_data (data, width, height, stride); - * - * // mark the image dirty so Cairo clears its caches. - * cairo_surface_mark_dirty (surface); - * } - * </programlisting> - * </example> - * Note that for other surface types it might be necessary to acquire the - * surface's device first. See cairo_device_acquire() for a discussion of - * devices. - **/ - -#define DEFINE_NIL_SURFACE(status, name) \ -const cairo_surface_t name = { \ - NULL, /* backend */ \ - NULL, /* device */ \ - CAIRO_SURFACE_TYPE_IMAGE, /* type */ \ - CAIRO_CONTENT_COLOR, /* content */ \ - CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ \ - status, /* status */ \ - 0, /* unique id */ \ - 0, /* serial */ \ - NULL, /* damage */ \ - FALSE, /* _finishing */ \ - FALSE, /* finished */ \ - TRUE, /* is_clear */ \ - FALSE, /* has_font_options */ \ - FALSE, /* owns_device */ \ - { 0, 0, 0, NULL, }, /* user_data */ \ - { 0, 0, 0, NULL, }, /* mime_data */ \ - { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, /* device_transform */ \ - { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, /* device_transform_inverse */ \ - { NULL, NULL }, /* device_transform_observers */ \ - 0.0, /* x_resolution */ \ - 0.0, /* y_resolution */ \ - 0.0, /* x_fallback_resolution */ \ - 0.0, /* y_fallback_resolution */ \ - NULL, /* snapshot_of */ \ - NULL, /* snapshot_detach */ \ - { NULL, NULL }, /* snapshots */ \ - { NULL, NULL }, /* snapshot */ \ - { CAIRO_ANTIALIAS_DEFAULT, /* antialias */ \ - CAIRO_SUBPIXEL_ORDER_DEFAULT, /* subpixel_order */ \ - CAIRO_LCD_FILTER_DEFAULT, /* lcd_filter */ \ - CAIRO_HINT_STYLE_DEFAULT, /* hint_style */ \ - CAIRO_HINT_METRICS_DEFAULT, /* hint_metrics */ \ - CAIRO_ROUND_GLYPH_POS_DEFAULT /* round_glyph_positions */ \ - } /* font_options */ \ -} - -/* XXX error object! */ - -static DEFINE_NIL_SURFACE(CAIRO_STATUS_NO_MEMORY, _cairo_surface_nil); -static DEFINE_NIL_SURFACE(CAIRO_STATUS_SURFACE_TYPE_MISMATCH, _cairo_surface_nil_surface_type_mismatch); -static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_STATUS, _cairo_surface_nil_invalid_status); -static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_CONTENT, _cairo_surface_nil_invalid_content); -static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_FORMAT, _cairo_surface_nil_invalid_format); -static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_VISUAL, _cairo_surface_nil_invalid_visual); -static DEFINE_NIL_SURFACE(CAIRO_STATUS_FILE_NOT_FOUND, _cairo_surface_nil_file_not_found); -static DEFINE_NIL_SURFACE(CAIRO_STATUS_TEMP_FILE_ERROR, _cairo_surface_nil_temp_file_error); -static DEFINE_NIL_SURFACE(CAIRO_STATUS_READ_ERROR, _cairo_surface_nil_read_error); -static DEFINE_NIL_SURFACE(CAIRO_STATUS_WRITE_ERROR, _cairo_surface_nil_write_error); -static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_STRIDE, _cairo_surface_nil_invalid_stride); -static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_SIZE, _cairo_surface_nil_invalid_size); -static DEFINE_NIL_SURFACE(CAIRO_STATUS_DEVICE_TYPE_MISMATCH, _cairo_surface_nil_device_type_mismatch); -static DEFINE_NIL_SURFACE(CAIRO_STATUS_DEVICE_ERROR, _cairo_surface_nil_device_error); - -static DEFINE_NIL_SURFACE(CAIRO_INT_STATUS_UNSUPPORTED, _cairo_surface_nil_unsupported); -static DEFINE_NIL_SURFACE(CAIRO_INT_STATUS_NOTHING_TO_DO, _cairo_surface_nil_nothing_to_do); - -static void _cairo_surface_finish_snapshots (cairo_surface_t *surface); -static void _cairo_surface_finish (cairo_surface_t *surface); - -/** - * _cairo_surface_set_error: - * @surface: a surface - * @status: a status value indicating an error - * - * Atomically sets surface->status to @status and calls _cairo_error; - * Does nothing if status is %CAIRO_STATUS_SUCCESS or any of the internal - * status values. - * - * All assignments of an error status to surface->status should happen - * through _cairo_surface_set_error(). Note that due to the nature of - * the atomic operation, it is not safe to call this function on the - * nil objects. - * - * The purpose of this function is to allow the user to set a - * breakpoint in _cairo_error() to generate a stack trace for when the - * user causes cairo to detect an error. - * - * Return value: the error status. - **/ -cairo_int_status_t -_cairo_surface_set_error (cairo_surface_t *surface, - cairo_int_status_t status) -{ - /* NOTHING_TO_DO is magic. We use it to break out of the inner-most - * surface function, but anything higher just sees "success". - */ - if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) - status = CAIRO_INT_STATUS_SUCCESS; - - if (status == CAIRO_INT_STATUS_SUCCESS || - status >= (int)CAIRO_INT_STATUS_LAST_STATUS) - return status; - - /* Don't overwrite an existing error. This preserves the first - * error, which is the most significant. */ - _cairo_status_set_error (&surface->status, (cairo_status_t)status); - - return _cairo_error (status); -} - -/** - * cairo_surface_get_type: - * @surface: a #cairo_surface_t - * - * This function returns the type of the backend used to create - * a surface. See #cairo_surface_type_t for available types. - * - * Return value: The type of @surface. - * - * Since: 1.2 - **/ -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_get_content: - * @surface: a #cairo_surface_t - * - * This function returns the content type of @surface which indicates - * whether the surface contains color and/or alpha information. See - * #cairo_content_t. - * - * Return value: The content type of @surface. - * - * Since: 1.2 - **/ -cairo_content_t -cairo_surface_get_content (cairo_surface_t *surface) -{ - return surface->content; -} - -/** - * cairo_surface_status: - * @surface: a #cairo_surface_t - * - * Checks whether an error has previously occurred for this - * surface. - * - * Return value: %CAIRO_STATUS_SUCCESS, %CAIRO_STATUS_NULL_POINTER, - * %CAIRO_STATUS_NO_MEMORY, %CAIRO_STATUS_READ_ERROR, - * %CAIRO_STATUS_INVALID_CONTENT, %CAIRO_STATUS_INVALID_FORMAT, or - * %CAIRO_STATUS_INVALID_VISUAL. - * - * Since: 1.0 - **/ -cairo_status_t -cairo_surface_status (cairo_surface_t *surface) -{ - return surface->status; -} -slim_hidden_def (cairo_surface_status); - -static unsigned int -_cairo_surface_allocate_unique_id (void) -{ - static cairo_atomic_int_t unique_id; - -#if CAIRO_NO_MUTEX - if (++unique_id == 0) - unique_id = 1; - return unique_id; -#else - cairo_atomic_int_t old, id; - - do { - old = _cairo_atomic_uint_get (&unique_id); - id = old + 1; - if (id == 0) - id = 1; - } while (! _cairo_atomic_uint_cmpxchg (&unique_id, old, id)); - - return id; -#endif -} - -/** - * cairo_surface_get_device: - * @surface: a #cairo_surface_t - * - * This function returns the device for a @surface. - * See #cairo_device_t. - * - * Return value: The device for @surface or %NULL if the surface does - * not have an associated device. - * - * Since: 1.10 - **/ -cairo_device_t * -cairo_surface_get_device (cairo_surface_t *surface) -{ - if (unlikely (surface->status)) - return _cairo_device_create_in_error (surface->status); - - return surface->device; -} - -static cairo_bool_t -_cairo_surface_has_snapshots (cairo_surface_t *surface) -{ - return ! cairo_list_is_empty (&surface->snapshots); -} - -static cairo_bool_t -_cairo_surface_has_mime_data (cairo_surface_t *surface) -{ - return surface->mime_data.num_elements != 0; -} - -static void -_cairo_surface_detach_mime_data (cairo_surface_t *surface) -{ - if (! _cairo_surface_has_mime_data (surface)) - return; - - _cairo_user_data_array_fini (&surface->mime_data); - _cairo_user_data_array_init (&surface->mime_data); -} - -static void -_cairo_surface_detach_snapshots (cairo_surface_t *surface) -{ - while (_cairo_surface_has_snapshots (surface)) { - _cairo_surface_detach_snapshot (cairo_list_first_entry (&surface->snapshots, - cairo_surface_t, - snapshot)); - } -} - -void -_cairo_surface_detach_snapshot (cairo_surface_t *snapshot) -{ - assert (snapshot->snapshot_of != NULL); - - snapshot->snapshot_of = NULL; - cairo_list_del (&snapshot->snapshot); - - if (snapshot->snapshot_detach != NULL) - snapshot->snapshot_detach (snapshot); - - cairo_surface_destroy (snapshot); -} - -void -_cairo_surface_attach_snapshot (cairo_surface_t *surface, - cairo_surface_t *snapshot, - cairo_surface_func_t detach_func) -{ - assert (surface != snapshot); - assert (snapshot->snapshot_of != surface); - - cairo_surface_reference (snapshot); - - if (snapshot->snapshot_of != NULL) - _cairo_surface_detach_snapshot (snapshot); - - snapshot->snapshot_of = surface; - snapshot->snapshot_detach = detach_func; - - cairo_list_add (&snapshot->snapshot, &surface->snapshots); - - assert (_cairo_surface_has_snapshot (surface, snapshot->backend) == snapshot); -} - -cairo_surface_t * -_cairo_surface_has_snapshot (cairo_surface_t *surface, - const cairo_surface_backend_t *backend) -{ - cairo_surface_t *snapshot; - - cairo_list_foreach_entry (snapshot, cairo_surface_t, - &surface->snapshots, snapshot) - { - if (snapshot->backend == backend) - return snapshot; - } - - return NULL; -} - -cairo_status_t -_cairo_surface_begin_modification (cairo_surface_t *surface) -{ - assert (surface->status == CAIRO_STATUS_SUCCESS); - assert (! surface->finished); - - return _cairo_surface_flush (surface, 1); -} - -void -_cairo_surface_init (cairo_surface_t *surface, - const cairo_surface_backend_t *backend, - cairo_device_t *device, - cairo_content_t content) -{ - CAIRO_MUTEX_INITIALIZE (); - - surface->backend = backend; - surface->device = cairo_device_reference (device); - surface->content = content; - surface->type = backend->type; - - CAIRO_REFERENCE_COUNT_INIT (&surface->ref_count, 1); - surface->status = CAIRO_STATUS_SUCCESS; - surface->unique_id = _cairo_surface_allocate_unique_id (); - surface->finished = FALSE; - surface->_finishing = FALSE; - surface->is_clear = FALSE; - surface->serial = 0; - surface->damage = NULL; - surface->owns_device = (device != NULL); - - _cairo_user_data_array_init (&surface->user_data); - _cairo_user_data_array_init (&surface->mime_data); - - cairo_matrix_init_identity (&surface->device_transform); - cairo_matrix_init_identity (&surface->device_transform_inverse); - cairo_list_init (&surface->device_transform_observers); - - surface->x_resolution = CAIRO_SURFACE_RESOLUTION_DEFAULT; - surface->y_resolution = CAIRO_SURFACE_RESOLUTION_DEFAULT; - - surface->x_fallback_resolution = CAIRO_SURFACE_FALLBACK_RESOLUTION_DEFAULT; - surface->y_fallback_resolution = CAIRO_SURFACE_FALLBACK_RESOLUTION_DEFAULT; - - cairo_list_init (&surface->snapshots); - surface->snapshot_of = NULL; - - surface->has_font_options = FALSE; -} - -static void -_cairo_surface_copy_similar_properties (cairo_surface_t *surface, - cairo_surface_t *other) -{ - if (other->has_font_options || other->backend != surface->backend) { - cairo_font_options_t options; - - cairo_surface_get_font_options (other, &options); - _cairo_surface_set_font_options (surface, &options); - } - - cairo_surface_set_fallback_resolution (surface, - other->x_fallback_resolution, - other->y_fallback_resolution); -} - -/** - * cairo_surface_create_similar: - * @other: an existing surface used to select the backend of the new surface - * @content: the content for the new surface - * @width: width of the new surface, (in device-space units) - * @height: height of the new surface (in device-space units) - * - * Create a new surface that is as compatible as possible with an - * existing surface. For example the new surface will have the same - * fallback resolution and font options as @other. Generally, the new - * surface will also use the same backend as @other, unless that is - * not possible for some reason. The type of the returned surface may - * be examined with cairo_surface_get_type(). - * - * Initially the surface contents are all 0 (transparent if contents - * have transparency, black otherwise.) - * - * Use cairo_surface_create_similar_image() if you need an image surface - * which can be painted quickly to the target surface. - * - * Return value: a pointer to the newly allocated surface. The caller - * owns the surface and should call cairo_surface_destroy() when done - * with it. - * - * This function always returns a valid pointer, but it will return a - * pointer to a "nil" surface if @other is already in an error state - * or any other error occurs. - * - * Since: 1.0 - **/ -cairo_surface_t * -cairo_surface_create_similar (cairo_surface_t *other, - cairo_content_t content, - int width, - int height) -{ - cairo_surface_t *surface; - cairo_status_t status; - cairo_solid_pattern_t pattern; - - if (unlikely (other->status)) - return _cairo_surface_create_in_error (other->status); - if (unlikely (other->finished)) - return _cairo_surface_create_in_error (CAIRO_STATUS_SURFACE_FINISHED); - if (unlikely (width < 0 || height < 0)) - return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_SIZE); - - if (unlikely (! CAIRO_CONTENT_VALID (content))) - return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_CONTENT); - - if (unlikely (other->status)) - return _cairo_surface_create_in_error (other->status); - - /* We inherit the device scale, so create a larger surface */ - width = width * other->device_transform.xx; - height = height * other->device_transform.yy; - - surface = NULL; - if (other->backend->create_similar) - surface = other->backend->create_similar (other, content, width, height); - if (surface == NULL) - surface = cairo_surface_create_similar_image (other, - _cairo_format_from_content (content), - width, height); - - if (unlikely (surface->status)) - return surface; - - _cairo_surface_copy_similar_properties (surface, other); - cairo_surface_set_device_scale (surface, - other->device_transform.xx, - other->device_transform.yy); - - if (unlikely (surface->status)) - return surface; - - _cairo_pattern_init_solid (&pattern, CAIRO_COLOR_TRANSPARENT); - status = _cairo_surface_paint (surface, - CAIRO_OPERATOR_CLEAR, - &pattern.base, NULL); - if (unlikely (status)) { - cairo_surface_destroy (surface); - surface = _cairo_surface_create_in_error (status); - } - - assert (surface->is_clear); - - return surface; -} - -/** - * cairo_surface_create_similar_image: - * @other: an existing surface used to select the preference of the new surface - * @format: the format for the new surface - * @width: width of the new surface, (in device-space units) - * @height: height of the new surface (in device-space units) - * - * Create a new image surface that is as compatible as possible for uploading - * to and the use in conjunction with an existing surface. However, this surface - * can still be used like any normal image surface. - * - * Initially the surface contents are all 0 (transparent if contents - * have transparency, black otherwise.) - * - * Use cairo_surface_create_similar() if you don't need an image surface. - * - * Return value: a pointer to the newly allocated image surface. The caller - * owns the surface and should call cairo_surface_destroy() when done - * with it. - * - * This function always returns a valid pointer, but it will return a - * pointer to a "nil" surface if @other is already in an error state - * or any other error occurs. - * - * Since: 1.12 - **/ -cairo_surface_t * -cairo_surface_create_similar_image (cairo_surface_t *other, - cairo_format_t format, - int width, - int height) -{ - cairo_surface_t *image; - - if (unlikely (other->status)) - return _cairo_surface_create_in_error (other->status); - if (unlikely (other->finished)) - return _cairo_surface_create_in_error (CAIRO_STATUS_SURFACE_FINISHED); - - if (unlikely (width < 0 || height < 0)) - return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_SIZE); - if (unlikely (! CAIRO_FORMAT_VALID (format))) - return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_FORMAT); - - image = NULL; - if (other->backend->create_similar_image) - image = other->backend->create_similar_image (other, - format, width, height); - if (image == NULL) - image = cairo_image_surface_create (format, width, height); - - assert (image->is_clear); - - return image; -} -slim_hidden_def (cairo_surface_create_similar_image); - -/** - * _cairo_surface_map_to_image: - * @surface: an existing surface used to extract the image from - * @extents: limit the extraction to an rectangular region - * - * Returns an image surface that is the most efficient mechanism for - * modifying the backing store of the target surface. The region - * retrieved is limited to @extents. - * - * Note, the use of the original surface as a target or source whilst - * it is mapped is undefined. The result of mapping the surface - * multiple times is undefined. Calling cairo_surface_destroy() or - * cairo_surface_finish() on the resulting image surface results in - * undefined behavior. Changing the device transform of the image - * surface or of @surface before the image surface is unmapped results - * in undefined behavior. - * - * Assumes that @surface is valid (CAIRO_STATUS_SUCCESS, - * non-finished). - * - * Return value: a pointer to the newly allocated image surface. The - * caller must use _cairo_surface_unmap_image() to destroy this image - * surface. - * - * This function always returns a valid pointer, but it will return a - * pointer to a "nil" surface if @other is already in an error state - * or any other error occurs. - * - * The returned image might have a %CAIRO_FORMAT_INVALID format. - **/ -cairo_image_surface_t * -_cairo_surface_map_to_image (cairo_surface_t *surface, - const cairo_rectangle_int_t *extents) -{ - cairo_image_surface_t *image = NULL; - - assert (extents != NULL); - - /* TODO: require map_to_image != NULL */ - if (surface->backend->map_to_image) - image = surface->backend->map_to_image (surface, extents); - - if (image == NULL) - image = _cairo_image_surface_clone_subimage (surface, extents); - - return image; -} - -/** - * _cairo_surface_unmap_image: - * @surface: the surface passed to _cairo_surface_map_to_image(). - * @image: the currently mapped image - * - * Unmaps the image surface as returned from - * _cairo_surface_map_to_image(). - * - * The content of the image will be uploaded to the target surface. - * Afterwards, the image is destroyed. - * - * Using an image surface which wasn't returned by - * _cairo_surface_map_to_image() results in undefined behavior. - * - * An image surface in error status can be passed to - * _cairo_surface_unmap_image(). - * - * Return value: the unmap status. - * - * Even if the unmap status is not successful, @image is destroyed. - **/ -cairo_int_status_t -_cairo_surface_unmap_image (cairo_surface_t *surface, - cairo_image_surface_t *image) -{ - cairo_surface_pattern_t pattern; - cairo_rectangle_int_t extents; - cairo_clip_t *clip; - cairo_int_status_t status; - - /* map_to_image can return error surfaces */ - if (unlikely (image->base.status)) { - status = image->base.status; - goto destroy; - } - - /* If the image is untouched just skip the update */ - if (image->base.serial == 0) { - status = CAIRO_STATUS_SUCCESS; - goto destroy; - } - - /* TODO: require unmap_image != NULL */ - if (surface->backend->unmap_image && - ! _cairo_image_surface_is_clone (image)) - { - status = surface->backend->unmap_image (surface, image); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - } - - _cairo_pattern_init_for_surface (&pattern, &image->base); - pattern.base.filter = CAIRO_FILTER_NEAREST; - - /* We have to apply the translate from map_to_image's extents.x and .y */ - cairo_matrix_init_translate (&pattern.base.matrix, - image->base.device_transform.x0, - image->base.device_transform.y0); - - /* And we also have to clip the operation to the image's extents */ - extents.x = image->base.device_transform_inverse.x0; - extents.y = image->base.device_transform_inverse.y0; - extents.width = image->width; - extents.height = image->height; - clip = _cairo_clip_intersect_rectangle (NULL, &extents); - - status = _cairo_surface_paint (surface, - CAIRO_OPERATOR_SOURCE, - &pattern.base, - clip); - - _cairo_pattern_fini (&pattern.base); - _cairo_clip_destroy (clip); - -destroy: - cairo_surface_finish (&image->base); - cairo_surface_destroy (&image->base); - - return status; -} - -/** - * cairo_surface_map_to_image: - * @surface: an existing surface used to extract the image from - * @extents: limit the extraction to an rectangular region - * - * Returns an image surface that is the most efficient mechanism for - * modifying the backing store of the target surface. The region retrieved - * may be limited to the @extents or %NULL for the whole surface - * - * Note, the use of the original surface as a target or source whilst - * it is mapped is undefined. The result of mapping the surface - * multiple times is undefined. Calling cairo_surface_destroy() or - * cairo_surface_finish() on the resulting image surface results in - * undefined behavior. Changing the device transform of the image - * surface or of @surface before the image surface is unmapped results - * in undefined behavior. - * - * Return value: a pointer to the newly allocated image surface. The caller - * must use cairo_surface_unmap_image() to destroy this image surface. - * - * This function always returns a valid pointer, but it will return a - * pointer to a "nil" surface if @other is already in an error state - * or any other error occurs. If the returned pointer does not have an - * error status, it is guaranteed to be an image surface whose format - * is not %CAIRO_FORMAT_INVALID. - * - * Since: 1.12 - **/ -cairo_surface_t * -cairo_surface_map_to_image (cairo_surface_t *surface, - const cairo_rectangle_int_t *extents) -{ - cairo_rectangle_int_t rect; - cairo_image_surface_t *image; - cairo_status_t status; - - if (unlikely (surface->status)) - return _cairo_surface_create_in_error (surface->status); - if (unlikely (surface->finished)) - return _cairo_surface_create_in_error (CAIRO_STATUS_SURFACE_FINISHED); - - if (extents == NULL) { - if (unlikely (! surface->backend->get_extents (surface, &rect))) - return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_SIZE); - - extents = ▭ - } else { - cairo_rectangle_int_t surface_extents; - - /* If this surface is bounded, we can't map parts - * that are outside of it. */ - if (likely (surface->backend->get_extents (surface, &surface_extents))) { - if (unlikely (! _cairo_rectangle_contains_rectangle (&surface_extents, extents))) - return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_SIZE); - } - } - - image = _cairo_surface_map_to_image (surface, extents); - - status = image->base.status; - if (unlikely (status)) { - cairo_surface_destroy (&image->base); - return _cairo_surface_create_in_error (status); - } - - if (image->format == CAIRO_FORMAT_INVALID) { - cairo_surface_destroy (&image->base); - image = _cairo_image_surface_clone_subimage (surface, extents); - } - - return &image->base; -} - -/** - * cairo_surface_unmap_image: - * @surface: the surface passed to cairo_surface_map_to_image(). - * @image: the currently mapped image - * - * Unmaps the image surface as returned from #cairo_surface_map_to_image(). - * - * The content of the image will be uploaded to the target surface. - * Afterwards, the image is destroyed. - * - * Using an image surface which wasn't returned by cairo_surface_map_to_image() - * results in undefined behavior. - * - * Since: 1.12 - **/ -void -cairo_surface_unmap_image (cairo_surface_t *surface, - cairo_surface_t *image) -{ - cairo_int_status_t status = CAIRO_STATUS_SUCCESS; - - if (unlikely (surface->status)) { - status = surface->status; - goto error; - } - if (unlikely (surface->finished)) { - status = _cairo_error (CAIRO_STATUS_SURFACE_FINISHED); - goto error; - } - if (unlikely (image->status)) { - status = image->status; - goto error; - } - if (unlikely (image->finished)) { - status = _cairo_error (CAIRO_STATUS_SURFACE_FINISHED); - goto error; - } - if (unlikely (! _cairo_surface_is_image (image))) { - status = _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - goto error; - } - - status = _cairo_surface_unmap_image (surface, - (cairo_image_surface_t *) image); - if (unlikely (status)) - _cairo_surface_set_error (surface, status); - - return; - -error: - _cairo_surface_set_error (surface, status); - cairo_surface_finish (image); - cairo_surface_destroy (image); -} - -cairo_surface_t * -_cairo_surface_create_scratch (cairo_surface_t *other, - cairo_content_t content, - int width, - int height, - const cairo_color_t *color) -{ - cairo_surface_t *surface; - cairo_status_t status; - cairo_solid_pattern_t pattern; - - if (unlikely (other->status)) - return _cairo_surface_create_in_error (other->status); - - surface = NULL; - if (other->backend->create_similar) - surface = other->backend->create_similar (other, content, width, height); - if (surface == NULL) - surface = cairo_surface_create_similar_image (other, - _cairo_format_from_content (content), - width, height); - - if (unlikely (surface->status)) - return surface; - - _cairo_surface_copy_similar_properties (surface, other); - - if (unlikely (surface->status)) - return surface; - - if (color) { - _cairo_pattern_init_solid (&pattern, color); - status = _cairo_surface_paint (surface, - color == CAIRO_COLOR_TRANSPARENT ? - CAIRO_OPERATOR_CLEAR : CAIRO_OPERATOR_SOURCE, - &pattern.base, NULL); - if (unlikely (status)) { - cairo_surface_destroy (surface); - surface = _cairo_surface_create_in_error (status); - } - } - - return surface; -} - -/** - * cairo_surface_reference: - * @surface: a #cairo_surface_t - * - * Increases the reference count on @surface by one. This prevents - * @surface from being destroyed until a matching call to - * cairo_surface_destroy() is made. - * - * The number of references to a #cairo_surface_t can be get using - * cairo_surface_get_reference_count(). - * - * Return value: the referenced #cairo_surface_t. - * - * Since: 1.0 - **/ -cairo_surface_t * -cairo_surface_reference (cairo_surface_t *surface) -{ - if (surface == NULL || - CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count)) - return surface; - - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count)); - - _cairo_reference_count_inc (&surface->ref_count); - - return surface; -} -slim_hidden_def (cairo_surface_reference); - -/** - * cairo_surface_destroy: - * @surface: a #cairo_surface_t - * - * Decreases the reference count on @surface by one. If the result is - * zero, then @surface and all associated resources are freed. See - * cairo_surface_reference(). - * - * Since: 1.0 - **/ -void -cairo_surface_destroy (cairo_surface_t *surface) -{ - if (surface == NULL || - CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count)) - return; - - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count)); - - if (! _cairo_reference_count_dec_and_test (&surface->ref_count)) - return; - - assert (surface->snapshot_of == NULL); - - if (! surface->finished) { - _cairo_surface_finish_snapshots (surface); - /* We may have been referenced by a snapshot prior to have - * detaching it with the copy-on-write. - */ - if (CAIRO_REFERENCE_COUNT_GET_VALUE (&surface->ref_count)) - return; - - _cairo_surface_finish (surface); - } - - if (surface->damage) - _cairo_damage_destroy (surface->damage); - - _cairo_user_data_array_fini (&surface->user_data); - _cairo_user_data_array_fini (&surface->mime_data); - - if (surface->owns_device) - cairo_device_destroy (surface->device); - - assert (surface->snapshot_of == NULL); - assert (! _cairo_surface_has_snapshots (surface)); - /* paranoid check that nobody took a reference whilst finishing */ - assert (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count)); - - free (surface); -} -slim_hidden_def(cairo_surface_destroy); - -/** - * cairo_surface_get_reference_count: - * @surface: a #cairo_surface_t - * - * Returns the current reference count of @surface. - * - * Return value: the current reference count of @surface. If the - * object is a nil object, 0 will be returned. - * - * Since: 1.4 - **/ -unsigned int -cairo_surface_get_reference_count (cairo_surface_t *surface) -{ - if (surface == NULL || - CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count)) - return 0; - - return CAIRO_REFERENCE_COUNT_GET_VALUE (&surface->ref_count); -} - -static void -_cairo_surface_finish_snapshots (cairo_surface_t *surface) -{ - cairo_status_t status; - - /* update the snapshots *before* we declare the surface as finished */ - surface->_finishing = TRUE; - status = _cairo_surface_flush (surface, 0); - (void) status; -} - -static void -_cairo_surface_finish (cairo_surface_t *surface) -{ - cairo_status_t status; - - surface->finished = TRUE; - - /* call finish even if in error mode */ - if (surface->backend->finish) { - status = surface->backend->finish (surface); - if (unlikely (status)) - _cairo_surface_set_error (surface, status); - } - - assert (surface->snapshot_of == NULL); - assert (!_cairo_surface_has_snapshots (surface)); -} - -/** - * cairo_surface_finish: - * @surface: the #cairo_surface_t to finish - * - * This function finishes the surface and drops all references to - * external resources. For example, for the Xlib backend it means - * that cairo will no longer access the drawable, which can be freed. - * After calling cairo_surface_finish() the only valid operations on a - * surface are getting and setting user, referencing and - * destroying, and flushing and finishing it. - * Further drawing to the surface will not affect the - * surface but will instead trigger a %CAIRO_STATUS_SURFACE_FINISHED - * error. - * - * When the last call to cairo_surface_destroy() decreases the - * reference count to zero, cairo will call cairo_surface_finish() if - * it hasn't been called already, before freeing the resources - * associated with the surface. - * - * Since: 1.0 - **/ -void -cairo_surface_finish (cairo_surface_t *surface) -{ - if (surface == NULL) - return; - - if (CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count)) - return; - - if (surface->finished) - return; - - /* We have to be careful when decoupling potential reference cycles */ - cairo_surface_reference (surface); - - _cairo_surface_finish_snapshots (surface); - /* XXX need to block and wait for snapshot references */ - _cairo_surface_finish (surface); - - cairo_surface_destroy (surface); -} -slim_hidden_def (cairo_surface_finish); - -/** - * _cairo_surface_release_device_reference: - * @surface: a #cairo_surface_t - * - * This function makes @surface release the reference to its device. The - * function is intended to be used for avoiding cycling references for - * surfaces that are owned by their device, for example cache surfaces. - * Note that the @surface will still assume that the device is available. - * So it is the caller's responsibility to ensure the device stays around - * until the @surface is destroyed. Just calling cairo_surface_finish() is - * not enough. - **/ -void -_cairo_surface_release_device_reference (cairo_surface_t *surface) -{ - assert (surface->owns_device); - - cairo_device_destroy (surface->device); - surface->owns_device = FALSE; -} - -/** - * cairo_surface_get_user_data: - * @surface: a #cairo_surface_t - * @key: the address of the #cairo_user_data_key_t the user data was - * attached to - * - * Return user data previously attached to @surface using the specified - * key. If no user data has been attached with the given key this - * function returns %NULL. - * - * Return value: the user data previously attached or %NULL. - * - * Since: 1.0 - **/ -void * -cairo_surface_get_user_data (cairo_surface_t *surface, - const cairo_user_data_key_t *key) -{ - /* Prevent reads of the array during teardown */ - if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count)) - return NULL; - - return _cairo_user_data_array_get_data (&surface->user_data, key); -} - -/** - * cairo_surface_set_user_data: - * @surface: a #cairo_surface_t - * @key: the address of a #cairo_user_data_key_t to attach the user data to - * @user_data: the user data to attach to the surface - * @destroy: a #cairo_destroy_func_t which will be called when the - * surface is destroyed or when new user data is attached using the - * same key. - * - * Attach user data to @surface. To remove user data from a surface, - * call this function with the key that was used to set it and %NULL - * for @data. - * - * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a - * slot could not be allocated for the user data. - * - * Since: 1.0 - **/ -cairo_status_t -cairo_surface_set_user_data (cairo_surface_t *surface, - const cairo_user_data_key_t *key, - void *user_data, - cairo_destroy_func_t destroy) -{ - if (CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count)) - return surface->status; - - if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count)) - return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED); - - return _cairo_user_data_array_set_data (&surface->user_data, - key, user_data, destroy); -} - -/** - * cairo_surface_get_mime_data: - * @surface: a #cairo_surface_t - * @mime_type: the mime type of the image data - * @data: the image data to attached to the surface - * @length: the length of the image data - * - * Return mime data previously attached to @surface using the - * specified mime type. If no data has been attached with the given - * mime type, @data is set %NULL. - * - * Since: 1.10 - **/ -void -cairo_surface_get_mime_data (cairo_surface_t *surface, - const char *mime_type, - const unsigned char **data, - unsigned long *length) -{ - cairo_user_data_slot_t *slots; - int i, num_slots; - - *data = NULL; - *length = 0; - - /* Prevent reads of the array during teardown */ - if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count)) - return; - - /* The number of mime-types attached to a surface is usually small, - * typically zero. Therefore it is quicker to do a strcmp() against - * each key than it is to intern the string (i.e. compute a hash, - * search the hash table, and do a final strcmp). - */ - num_slots = surface->mime_data.num_elements; - slots = _cairo_array_index (&surface->mime_data, 0); - for (i = 0; i < num_slots; i++) { - if (slots[i].key != NULL && strcmp ((char *) slots[i].key, mime_type) == 0) { - cairo_mime_data_t *mime_data = slots[i].user_data; - - *data = mime_data->data; - *length = mime_data->length; - return; - } - } -} -slim_hidden_def (cairo_surface_get_mime_data); - -static void -_cairo_mime_data_destroy (void *ptr) -{ - cairo_mime_data_t *mime_data = ptr; - - if (! _cairo_reference_count_dec_and_test (&mime_data->ref_count)) - return; - - if (mime_data->destroy && mime_data->closure) - mime_data->destroy (mime_data->closure); - - free (mime_data); -} - -/** - * CAIRO_MIME_TYPE_JBIG2: - * - * Joint Bi-level Image Experts Group image coding standard (ISO/IEC 11544). - * - * Since: 1.14 - **/ - -/** - * CAIRO_MIME_TYPE_JBIG2_GLOBAL: - * - * Joint Bi-level Image Experts Group image coding standard (ISO/IEC 11544) global segment. - * - * Since: 1.14 - **/ - -/** - * CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID: - * - * An unique identifier shared by a JBIG2 global segment and all JBIG2 images - * that depend on the global segment. - * - * Since: 1.14 - **/ - -/** - * CAIRO_MIME_TYPE_JP2: - * - * The Joint Photographic Experts Group (JPEG) 2000 image coding standard (ISO/IEC 15444-1). - * - * Since: 1.10 - **/ - -/** - * CAIRO_MIME_TYPE_JPEG: - * - * The Joint Photographic Experts Group (JPEG) image coding standard (ISO/IEC 10918-1). - * - * Since: 1.10 - **/ - -/** - * CAIRO_MIME_TYPE_PNG: - * - * The Portable Network Graphics image file format (ISO/IEC 15948). - * - * Since: 1.10 - **/ - -/** - * CAIRO_MIME_TYPE_URI: - * - * URI for an image file (unofficial MIME type). - * - * Since: 1.10 - **/ - -/** - * CAIRO_MIME_TYPE_UNIQUE_ID: - * - * Unique identifier for a surface (cairo specific MIME type). All surfaces with - * the same unique identifier will only be embedded once. - * - * Since: 1.12 - **/ - -/** - * cairo_surface_set_mime_data: - * @surface: a #cairo_surface_t - * @mime_type: the MIME type of the image data - * @data: the image data to attach to the surface - * @length: the length of the image data - * @destroy: a #cairo_destroy_func_t which will be called when the - * surface is destroyed or when new image data is attached using the - * same mime type. - * @closure: the data to be passed to the @destroy notifier - * - * Attach an image in the format @mime_type to @surface. To remove - * the data from a surface, call this function with same mime type - * and %NULL for @data. - * - * The attached image (or filename) data can later be used by backends - * which support it (currently: PDF, PS, SVG and Win32 Printing - * surfaces) to emit this data instead of making a snapshot of the - * @surface. This approach tends to be faster and requires less - * memory and disk space. - * - * The recognized MIME types are the following: %CAIRO_MIME_TYPE_JPEG, - * %CAIRO_MIME_TYPE_PNG, %CAIRO_MIME_TYPE_JP2, %CAIRO_MIME_TYPE_URI, - * %CAIRO_MIME_TYPE_UNIQUE_ID, %CAIRO_MIME_TYPE_JBIG2, - * %CAIRO_MIME_TYPE_JBIG2_GLOBAL, %CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID. - * - * See corresponding backend surface docs for details about which MIME - * types it can handle. Caution: the associated MIME data will be - * discarded if you draw on the surface afterwards. Use this function - * with care. - * - * Even if a backend supports a MIME type, that does not mean cairo - * will always be able to use the attached MIME data. For example, if - * the backend does not natively support the compositing operation used - * to apply the MIME data to the backend. In that case, the MIME data - * will be ignored. Therefore, to apply an image in all cases, it is best - * to create an image surface which contains the decoded image data and - * then attach the MIME data to that. This ensures the image will always - * be used while still allowing the MIME data to be used whenever - * possible. - * - * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a - * slot could not be allocated for the user data. - * - * Since: 1.10 - **/ -cairo_status_t -cairo_surface_set_mime_data (cairo_surface_t *surface, - const char *mime_type, - const unsigned char *data, - unsigned long length, - cairo_destroy_func_t destroy, - void *closure) -{ - cairo_status_t status; - cairo_mime_data_t *mime_data; - - if (CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count)) - return surface->status; - - if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count)) - return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED); - - if (unlikely (surface->status)) - return surface->status; - if (unlikely (surface->finished)) - return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - - status = _cairo_intern_string (&mime_type, -1); - if (unlikely (status)) - return _cairo_surface_set_error (surface, status); - - if (data != NULL) { - mime_data = malloc (sizeof (cairo_mime_data_t)); - if (unlikely (mime_data == NULL)) - return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_NO_MEMORY)); - - CAIRO_REFERENCE_COUNT_INIT (&mime_data->ref_count, 1); - - mime_data->data = (unsigned char *) data; - mime_data->length = length; - mime_data->destroy = destroy; - mime_data->closure = closure; - } else - mime_data = NULL; - - status = _cairo_user_data_array_set_data (&surface->mime_data, - (cairo_user_data_key_t *) mime_type, - mime_data, - _cairo_mime_data_destroy); - if (unlikely (status)) { - free (mime_data); - - return _cairo_surface_set_error (surface, status); - } - - return CAIRO_STATUS_SUCCESS; -} -slim_hidden_def (cairo_surface_set_mime_data); - -/** - * cairo_surface_supports_mime_type: - * @surface: a #cairo_surface_t - * @mime_type: the mime type - * - * Return whether @surface supports @mime_type. - * - * Return value: %TRUE if @surface supports - * @mime_type, %FALSE otherwise - * - * Since: 1.12 - **/ -cairo_bool_t -cairo_surface_supports_mime_type (cairo_surface_t *surface, - const char *mime_type) -{ - const char **types; - - if (unlikely (surface->status)) - return FALSE; - if (unlikely (surface->finished)) { - _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - return FALSE; - } - - if (surface->backend->get_supported_mime_types) { - types = surface->backend->get_supported_mime_types (surface); - if (types) { - while (*types) { - if (strcmp (*types, mime_type) == 0) - return TRUE; - types++; - } - } - } - - return FALSE; -} -slim_hidden_def (cairo_surface_supports_mime_type); - -static void -_cairo_mime_data_reference (const void *key, void *elt, void *closure) -{ - cairo_mime_data_t *mime_data = elt; - - _cairo_reference_count_inc (&mime_data->ref_count); -} - -cairo_status_t -_cairo_surface_copy_mime_data (cairo_surface_t *dst, - cairo_surface_t *src) -{ - cairo_status_t status; - - if (dst->status) - return dst->status; - - if (src->status) - return _cairo_surface_set_error (dst, src->status); - - /* first copy the mime-data, discarding any already set on dst */ - status = _cairo_user_data_array_copy (&dst->mime_data, &src->mime_data); - if (unlikely (status)) - return _cairo_surface_set_error (dst, status); - - /* now increment the reference counters for the copies */ - _cairo_user_data_array_foreach (&dst->mime_data, - _cairo_mime_data_reference, - NULL); - - return CAIRO_STATUS_SUCCESS; -} - -/** - * _cairo_surface_set_font_options: - * @surface: a #cairo_surface_t - * @options: a #cairo_font_options_t object that contains the - * options to use for this surface instead of backend's default - * font options. - * - * Sets the default font rendering options for the surface. - * This is useful to correctly propagate default font options when - * falling back to an image surface in a backend implementation. - * This affects the options returned in cairo_surface_get_font_options(). - * - * If @options is %NULL the surface options are reset to those of - * the backend default. - **/ -void -_cairo_surface_set_font_options (cairo_surface_t *surface, - cairo_font_options_t *options) -{ - if (surface->status) - return; - - assert (surface->snapshot_of == NULL); - - if (surface->finished) { - _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - return; - } - - if (options) { - surface->has_font_options = TRUE; - _cairo_font_options_init_copy (&surface->font_options, options); - } else { - surface->has_font_options = FALSE; - } -} - -/** - * cairo_surface_get_font_options: - * @surface: a #cairo_surface_t - * @options: a #cairo_font_options_t object into which to store - * the retrieved options. All existing values are overwritten - * - * Retrieves the default font rendering options for the surface. - * This allows display surfaces to report the correct subpixel order - * for rendering on them, print surfaces to disable hinting of - * metrics and so forth. The result can then be used with - * cairo_scaled_font_create(). - * - * Since: 1.0 - **/ -void -cairo_surface_get_font_options (cairo_surface_t *surface, - cairo_font_options_t *options) -{ - if (cairo_font_options_status (options)) - return; - - if (surface->status) { - _cairo_font_options_init_default (options); - return; - } - - if (! surface->has_font_options) { - surface->has_font_options = TRUE; - - _cairo_font_options_init_default (&surface->font_options); - - if (!surface->finished && surface->backend->get_font_options) { - surface->backend->get_font_options (surface, &surface->font_options); - } - } - - _cairo_font_options_init_copy (options, &surface->font_options); -} -slim_hidden_def (cairo_surface_get_font_options); - -cairo_status_t -_cairo_surface_flush (cairo_surface_t *surface, unsigned flags) -{ - /* update the current snapshots *before* the user updates the surface */ - _cairo_surface_detach_snapshots (surface); - if (surface->snapshot_of != NULL) - _cairo_surface_detach_snapshot (surface); - _cairo_surface_detach_mime_data (surface); - - return __cairo_surface_flush (surface, flags); -} - -/** - * cairo_surface_flush: - * @surface: a #cairo_surface_t - * - * Do any pending drawing for the surface and also restore any temporary - * modifications cairo has made to the surface's state. This function - * must be called before switching from drawing on the surface with - * cairo to drawing on it directly with native APIs, or accessing its - * memory outside of Cairo. If the surface doesn't support direct - * access, then this function does nothing. - * - * Since: 1.0 - **/ -void -cairo_surface_flush (cairo_surface_t *surface) -{ - cairo_status_t status; - - if (surface->status) - return; - - if (surface->finished) - return; - - status = _cairo_surface_flush (surface, 0); - if (unlikely (status)) - _cairo_surface_set_error (surface, status); -} -slim_hidden_def (cairo_surface_flush); - -/** - * cairo_surface_mark_dirty: - * @surface: a #cairo_surface_t - * - * Tells cairo that drawing has been done to surface using means other - * than cairo, and that cairo should reread any cached areas. Note - * that you must call cairo_surface_flush() before doing such drawing. - * - * Since: 1.0 - **/ -void -cairo_surface_mark_dirty (cairo_surface_t *surface) -{ - cairo_rectangle_int_t extents; - - if (unlikely (surface->status)) - return; - if (unlikely (surface->finished)) { - _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - return; - } - - _cairo_surface_get_extents (surface, &extents); - cairo_surface_mark_dirty_rectangle (surface, - extents.x, extents.y, - extents.width, extents.height); -} -slim_hidden_def (cairo_surface_mark_dirty); - -/** - * cairo_surface_mark_dirty_rectangle: - * @surface: a #cairo_surface_t - * @x: X coordinate of dirty rectangle - * @y: Y coordinate of dirty rectangle - * @width: width of dirty rectangle - * @height: height of dirty rectangle - * - * 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. - * - * Since: 1.0 - **/ -void -cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface, - int x, - int y, - int width, - int height) -{ - cairo_status_t status; - - if (unlikely (surface->status)) - return; - - assert (surface->snapshot_of == NULL); - - if (unlikely (surface->finished)) { - _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - return; - } - - /* The application *should* have called cairo_surface_flush() before - * modifying the surface independently of cairo (and thus having to - * call mark_dirty()). */ - assert (! _cairo_surface_has_snapshots (surface)); - assert (! _cairo_surface_has_mime_data (surface)); - - surface->is_clear = FALSE; - surface->serial++; - - if (surface->damage) { - cairo_box_t box; - - box.p1.x = x; - box.p1.y = y; - box.p2.x = x + width; - box.p2.y = y + height; - - surface->damage = _cairo_damage_add_box (surface->damage, &box); - } - - if (surface->backend->mark_dirty_rectangle != NULL) { - /* XXX: FRAGILE: We're ignoring the scaling component of - * device_transform here. I don't know what the right thing to - * do would actually be if there were some scaling here, but - * we avoid this since device_transfom scaling is not exported - * publicly and mark_dirty is not used internally. */ - status = surface->backend->mark_dirty_rectangle (surface, - x + surface->device_transform.x0, - y + surface->device_transform.y0, - width, height); - - if (unlikely (status)) - _cairo_surface_set_error (surface, status); - } -} -slim_hidden_def (cairo_surface_mark_dirty_rectangle); - -/** - * cairo_surface_set_device_scale: - * @surface: a #cairo_surface_t - * @x_scale: a scale factor in the X direction - * @y_scale: a scale factor in the Y direction - * - * Sets a scale that is multiplied to the device coordinates determined - * by the CTM when drawing to @surface. One common use for this is to - * render to very high resolution display devices at a scale factor, so - * that code that assumes 1 pixel will be a certain size will still work. - * Setting a transformation via cairo_translate() isn't - * sufficient to do this, since functions like - * cairo_device_to_user() will expose the hidden scale. - * - * Note that the scale affects drawing to the surface as well as - * using the surface in a source pattern. - * - * Since: 1.14 - **/ -void -cairo_surface_set_device_scale (cairo_surface_t *surface, - double x_scale, - double y_scale) -{ - cairo_status_t status; - - if (unlikely (surface->status)) - return; - - assert (surface->snapshot_of == NULL); - - if (unlikely (surface->finished)) { - _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - return; - } - - status = _cairo_surface_begin_modification (surface); - if (unlikely (status)) { - _cairo_surface_set_error (surface, status); - return; - } - - surface->device_transform.xx = x_scale; - surface->device_transform.yy = y_scale; - surface->device_transform.xy = 0.0; - surface->device_transform.yx = 0.0; - - surface->device_transform_inverse = surface->device_transform; - status = cairo_matrix_invert (&surface->device_transform_inverse); - /* should always be invertible unless given pathological input */ - assert (status == CAIRO_STATUS_SUCCESS); - - _cairo_observers_notify (&surface->device_transform_observers, surface); -} -slim_hidden_def (cairo_surface_set_device_scale); - -/** - * cairo_surface_get_device_scale: - * @surface: a #cairo_surface_t - * @x_scale: the scale in the X direction, in device units - * @y_scale: the scale in the Y direction, in device units - * - * This function returns the previous device offset set by - * cairo_surface_set_device_scale(). - * - * Since: 1.14 - **/ -void -cairo_surface_get_device_scale (cairo_surface_t *surface, - double *x_scale, - double *y_scale) -{ - if (x_scale) - *x_scale = surface->device_transform.xx; - if (y_scale) - *y_scale = surface->device_transform.yy; -} -slim_hidden_def (cairo_surface_get_device_scale); - -/** - * cairo_surface_set_device_offset: - * @surface: a #cairo_surface_t - * @x_offset: the offset in the X direction, in device units - * @y_offset: the offset in the Y direction, in device units - * - * Sets an offset that is added to the device coordinates determined - * by the CTM when drawing to @surface. One use case for this function - * is when we want to create a #cairo_surface_t that redirects drawing - * for a portion of an onscreen surface to an offscreen surface in a - * way that is completely invisible to the user of the cairo - * API. Setting a transformation via cairo_translate() isn't - * sufficient to do this, since functions like - * cairo_device_to_user() will expose the hidden offset. - * - * Note that the offset affects drawing to the surface as well as - * using the surface in a source pattern. - * - * Since: 1.0 - **/ -void -cairo_surface_set_device_offset (cairo_surface_t *surface, - double x_offset, - double y_offset) -{ - cairo_status_t status; - - if (unlikely (surface->status)) - return; - - assert (surface->snapshot_of == NULL); - - if (unlikely (surface->finished)) { - _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - return; - } - - status = _cairo_surface_begin_modification (surface); - if (unlikely (status)) { - _cairo_surface_set_error (surface, status); - return; - } - - surface->device_transform.x0 = x_offset; - surface->device_transform.y0 = y_offset; - - surface->device_transform_inverse = surface->device_transform; - status = cairo_matrix_invert (&surface->device_transform_inverse); - /* should always be invertible unless given pathological input */ - assert (status == CAIRO_STATUS_SUCCESS); - - _cairo_observers_notify (&surface->device_transform_observers, surface); -} -slim_hidden_def (cairo_surface_set_device_offset); - -/** - * cairo_surface_get_device_offset: - * @surface: a #cairo_surface_t - * @x_offset: the offset in the X direction, in device units - * @y_offset: the offset in the Y direction, in device units - * - * This function returns the previous device offset set by - * cairo_surface_set_device_offset(). - * - * Since: 1.2 - **/ -void -cairo_surface_get_device_offset (cairo_surface_t *surface, - double *x_offset, - double *y_offset) -{ - if (x_offset) - *x_offset = surface->device_transform.x0; - if (y_offset) - *y_offset = surface->device_transform.y0; -} -slim_hidden_def (cairo_surface_get_device_offset); - -/** - * cairo_surface_set_fallback_resolution: - * @surface: a #cairo_surface_t - * @x_pixels_per_inch: horizontal setting for pixels per inch - * @y_pixels_per_inch: vertical setting for pixels per inch - * - * Set the horizontal and vertical resolution for image fallbacks. - * - * When certain operations aren't supported natively by a backend, - * cairo will fallback by rendering operations to an image and then - * overlaying that image onto the output. For backends that are - * natively vector-oriented, this function can be used to set the - * resolution used for these image fallbacks, (larger values will - * result in more detailed images, but also larger file sizes). - * - * Some examples of natively vector-oriented backends are the ps, pdf, - * and svg backends. - * - * For backends that are natively raster-oriented, image fallbacks are - * still possible, but they are always performed at the native - * device resolution. So this function has no effect on those - * backends. - * - * Note: The fallback resolution only takes effect at the time of - * completing a page (with cairo_show_page() or cairo_copy_page()) so - * there is currently no way to have more than one fallback resolution - * in effect on a single page. - * - * The default fallback resoultion is 300 pixels per inch in both - * dimensions. - * - * Since: 1.2 - **/ -void -cairo_surface_set_fallback_resolution (cairo_surface_t *surface, - double x_pixels_per_inch, - double y_pixels_per_inch) -{ - cairo_status_t status; - - if (unlikely (surface->status)) - return; - - assert (surface->snapshot_of == NULL); - - if (unlikely (surface->finished)) { - _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - return; - } - - if (x_pixels_per_inch <= 0 || y_pixels_per_inch <= 0) { - /* XXX Could delay raising the error until we fallback, but throwing - * the error here means that we can catch the real culprit. - */ - _cairo_surface_set_error (surface, CAIRO_STATUS_INVALID_MATRIX); - return; - } - - status = _cairo_surface_begin_modification (surface); - if (unlikely (status)) { - _cairo_surface_set_error (surface, status); - return; - } - - surface->x_fallback_resolution = x_pixels_per_inch; - surface->y_fallback_resolution = y_pixels_per_inch; -} -slim_hidden_def (cairo_surface_set_fallback_resolution); - -/** - * cairo_surface_get_fallback_resolution: - * @surface: a #cairo_surface_t - * @x_pixels_per_inch: horizontal pixels per inch - * @y_pixels_per_inch: vertical pixels per inch - * - * This function returns the previous fallback resolution set by - * cairo_surface_set_fallback_resolution(), or default fallback - * resolution if never set. - * - * Since: 1.8 - **/ -void -cairo_surface_get_fallback_resolution (cairo_surface_t *surface, - double *x_pixels_per_inch, - double *y_pixels_per_inch) -{ - if (x_pixels_per_inch) - *x_pixels_per_inch = surface->x_fallback_resolution; - if (y_pixels_per_inch) - *y_pixels_per_inch = surface->y_fallback_resolution; -} - -cairo_bool_t -_cairo_surface_has_device_transform (cairo_surface_t *surface) -{ - return ! _cairo_matrix_is_identity (&surface->device_transform); -} - -/** - * _cairo_surface_acquire_source_image: - * @surface: a #cairo_surface_t - * @image_out: location to store a pointer to an image surface that - * has identical contents to @surface. This surface could be @surface - * itself, a surface held internal to @surface, or it could be a new - * surface with a copy of the relevant portion of @surface. - * @image_extra: location to store image specific backend data - * - * Gets an image surface to use when drawing as a fallback when drawing with - * @surface as a source. _cairo_surface_release_source_image() must be called - * when finished. - * - * Return value: %CAIRO_STATUS_SUCCESS if an image was stored in @image_out. - * %CAIRO_INT_STATUS_UNSUPPORTED if an image cannot be retrieved for the specified - * surface. Or %CAIRO_STATUS_NO_MEMORY. - **/ -cairo_status_t -_cairo_surface_acquire_source_image (cairo_surface_t *surface, - cairo_image_surface_t **image_out, - void **image_extra) -{ - cairo_status_t status; - - if (unlikely (surface->status)) - return surface->status; - - assert (!surface->finished); - - if (surface->backend->acquire_source_image == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = surface->backend->acquire_source_image (surface, - image_out, image_extra); - if (unlikely (status)) - return _cairo_surface_set_error (surface, status); - - _cairo_debug_check_image_surface_is_defined (&(*image_out)->base); - - return CAIRO_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_surface_default_acquire_source_image (void *_surface, - cairo_image_surface_t **image_out, - void **image_extra) -{ - cairo_surface_t *surface = _surface; - cairo_rectangle_int_t extents; - - if (unlikely (! surface->backend->get_extents (surface, &extents))) - return _cairo_error (CAIRO_STATUS_INVALID_SIZE); - - *image_out = _cairo_surface_map_to_image (surface, &extents); - *image_extra = NULL; - return (*image_out)->base.status; -} - -/** - * _cairo_surface_release_source_image: - * @surface: a #cairo_surface_t - * @image_extra: same as return from the matching _cairo_surface_acquire_source_image() - * - * Releases any resources obtained with _cairo_surface_acquire_source_image() - **/ -void -_cairo_surface_release_source_image (cairo_surface_t *surface, - cairo_image_surface_t *image, - void *image_extra) -{ - assert (!surface->finished); - - if (surface->backend->release_source_image) - surface->backend->release_source_image (surface, image, image_extra); -} - -void -_cairo_surface_default_release_source_image (void *surface, - cairo_image_surface_t *image, - void *image_extra) -{ - cairo_status_t ignored; - - ignored = _cairo_surface_unmap_image (surface, image); - (void)ignored; -} - - -cairo_surface_t * -_cairo_surface_get_source (cairo_surface_t *surface, - cairo_rectangle_int_t *extents) -{ - assert (surface->backend->source); - return surface->backend->source (surface, extents); -} - -cairo_surface_t * -_cairo_surface_default_source (void *surface, - cairo_rectangle_int_t *extents) -{ - if (extents) - _cairo_surface_get_extents(surface, extents); - return surface; -} - -static cairo_status_t -_pattern_has_error (const cairo_pattern_t *pattern) -{ - const cairo_surface_pattern_t *spattern; - - if (unlikely (pattern->status)) - return pattern->status; - - if (pattern->type != CAIRO_PATTERN_TYPE_SURFACE) - return CAIRO_STATUS_SUCCESS; - - spattern = (const cairo_surface_pattern_t *) pattern; - if (unlikely (spattern->surface->status)) - return spattern->surface->status; - - if (unlikely (spattern->surface->finished)) - return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_bool_t -nothing_to_do (cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source) -{ - if (_cairo_pattern_is_clear (source)) { - if (op == CAIRO_OPERATOR_OVER || op == CAIRO_OPERATOR_ADD) - return TRUE; - - if (op == CAIRO_OPERATOR_SOURCE) - op = CAIRO_OPERATOR_CLEAR; - } - - if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear) - return TRUE; - - if (op == CAIRO_OPERATOR_ATOP && (surface->content & CAIRO_CONTENT_COLOR) ==0) - return TRUE; - - return FALSE; -} - -cairo_status_t -_cairo_surface_paint (cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - if (unlikely (surface->status)) - return surface->status; - if (unlikely (surface->finished)) - return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - - if (_cairo_clip_is_all_clipped (clip)) - return CAIRO_STATUS_SUCCESS; - - status = _pattern_has_error (source); - if (unlikely (status)) - return status; - - if (nothing_to_do (surface, op, source)) - return CAIRO_STATUS_SUCCESS; - - status = _cairo_surface_begin_modification (surface); - if (unlikely (status)) - return status; - - status = surface->backend->paint (surface, op, source, clip); - if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) { - surface->is_clear = op == CAIRO_OPERATOR_CLEAR && clip == NULL; - surface->serial++; - } - - return _cairo_surface_set_error (surface, status); -} - -cairo_status_t -_cairo_surface_mask (cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - if (unlikely (surface->status)) - return surface->status; - if (unlikely (surface->finished)) - return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - - if (_cairo_clip_is_all_clipped (clip)) - return CAIRO_STATUS_SUCCESS; - - /* If the mask is blank, this is just an expensive no-op */ - if (_cairo_pattern_is_clear (mask) && - _cairo_operator_bounded_by_mask (op)) - { - return CAIRO_STATUS_SUCCESS; - } - - status = _pattern_has_error (source); - if (unlikely (status)) - return status; - - status = _pattern_has_error (mask); - if (unlikely (status)) - return status; - - if (nothing_to_do (surface, op, source)) - return CAIRO_STATUS_SUCCESS; - - status = _cairo_surface_begin_modification (surface); - if (unlikely (status)) - return status; - - status = surface->backend->mask (surface, op, source, mask, clip); - if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) { - surface->is_clear = FALSE; - surface->serial++; - } - - return _cairo_surface_set_error (surface, status); -} - -cairo_status_t -_cairo_surface_fill_stroke (cairo_surface_t *surface, - cairo_operator_t fill_op, - const cairo_pattern_t *fill_source, - cairo_fill_rule_t fill_rule, - double fill_tolerance, - cairo_antialias_t fill_antialias, - cairo_path_fixed_t *path, - cairo_operator_t stroke_op, - const cairo_pattern_t *stroke_source, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *stroke_ctm, - const cairo_matrix_t *stroke_ctm_inverse, - double stroke_tolerance, - cairo_antialias_t stroke_antialias, - const cairo_clip_t *clip) -{ - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - if (unlikely (surface->status)) - return surface->status; - if (unlikely (surface->finished)) - return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - - if (_cairo_clip_is_all_clipped (clip)) - return CAIRO_STATUS_SUCCESS; - - if (surface->is_clear && - fill_op == CAIRO_OPERATOR_CLEAR && - stroke_op == CAIRO_OPERATOR_CLEAR) - { - return CAIRO_STATUS_SUCCESS; - } - - status = _pattern_has_error (fill_source); - if (unlikely (status)) - return status; - - status = _pattern_has_error (stroke_source); - if (unlikely (status)) - return status; - - status = _cairo_surface_begin_modification (surface); - if (unlikely (status)) - return status; - - if (surface->backend->fill_stroke) { - cairo_matrix_t dev_ctm = *stroke_ctm; - cairo_matrix_t dev_ctm_inverse = *stroke_ctm_inverse; - - status = surface->backend->fill_stroke (surface, - fill_op, fill_source, fill_rule, - fill_tolerance, fill_antialias, - path, - stroke_op, stroke_source, - stroke_style, - &dev_ctm, &dev_ctm_inverse, - stroke_tolerance, stroke_antialias, - clip); - - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - goto FINISH; - } - - status = _cairo_surface_fill (surface, fill_op, fill_source, path, - fill_rule, fill_tolerance, fill_antialias, - clip); - if (unlikely (status)) - goto FINISH; - - status = _cairo_surface_stroke (surface, stroke_op, stroke_source, path, - stroke_style, stroke_ctm, stroke_ctm_inverse, - stroke_tolerance, stroke_antialias, - clip); - if (unlikely (status)) - goto FINISH; - - FINISH: - if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) { - surface->is_clear = FALSE; - surface->serial++; - } - - return _cairo_surface_set_error (surface, status); -} - -cairo_status_t -_cairo_surface_stroke (cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - if (unlikely (surface->status)) - return surface->status; - if (unlikely (surface->finished)) - return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - - if (_cairo_clip_is_all_clipped (clip)) - return CAIRO_STATUS_SUCCESS; - - status = _pattern_has_error (source); - if (unlikely (status)) - return status; - - if (nothing_to_do (surface, op, source)) - return CAIRO_STATUS_SUCCESS; - - status = _cairo_surface_begin_modification (surface); - if (unlikely (status)) - return status; - - status = surface->backend->stroke (surface, op, source, - path, stroke_style, - ctm, ctm_inverse, - tolerance, antialias, - clip); - if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) { - surface->is_clear = FALSE; - surface->serial++; - } - - return _cairo_surface_set_error (surface, status); -} - -cairo_status_t -_cairo_surface_fill (cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - if (unlikely (surface->status)) - return surface->status; - if (unlikely (surface->finished)) - return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - - if (_cairo_clip_is_all_clipped (clip)) - return CAIRO_STATUS_SUCCESS; - - status = _pattern_has_error (source); - if (unlikely (status)) - return status; - - if (nothing_to_do (surface, op, source)) - return CAIRO_STATUS_SUCCESS; - - status = _cairo_surface_begin_modification (surface); - if (unlikely (status)) - return status; - - status = surface->backend->fill (surface, op, source, - path, fill_rule, - tolerance, antialias, - clip); - if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) { - surface->is_clear = FALSE; - surface->serial++; - } - - return _cairo_surface_set_error (surface, status); -} - -/** - * cairo_surface_copy_page: - * @surface: a #cairo_surface_t - * - * Emits the current page for backends that support multiple pages, - * but doesn't clear it, so that the contents of the current page will - * be retained for the next page. Use cairo_surface_show_page() if you - * want to get an empty page after the emission. - * - * There is a convenience function for this that takes a #cairo_t, - * namely cairo_copy_page(). - * - * Since: 1.6 - **/ -void -cairo_surface_copy_page (cairo_surface_t *surface) -{ - if (unlikely (surface->status)) - return; - - assert (surface->snapshot_of == NULL); - - if (unlikely (surface->finished)) { - _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED); - return; - } - - /* It's fine if some backends don't implement copy_page */ - if (surface->backend->copy_page == NULL) - return; - - _cairo_surface_set_error (surface, surface->backend->copy_page (surface)); -} -slim_hidden_def (cairo_surface_copy_page); - -/** - * cairo_surface_show_page: - * @surface: a #cairo_Surface_t - * - * Emits and clears the current page for backends that support multiple - * pages. Use cairo_surface_copy_page() if you don't want to clear the page. - * - * There is a convenience function for this that takes a #cairo_t, - * namely cairo_show_page(). - * - * Since: 1.6 - **/ -void -cairo_surface_show_page (cairo_surface_t *surface) -{ - cairo_status_t status; - - if (unlikely (surface->status)) - return; - - if (unlikely (surface->finished)) { - _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED); - return; - } - - status = _cairo_surface_begin_modification (surface); - if (unlikely (status)) { - _cairo_surface_set_error (surface, status); - return; - } - - /* It's fine if some backends don't implement show_page */ - if (surface->backend->show_page == NULL) - return; - - _cairo_surface_set_error (surface, surface->backend->show_page (surface)); -} -slim_hidden_def (cairo_surface_show_page); - -/** - * _cairo_surface_get_extents: - * @surface: the #cairo_surface_t to fetch extents for - * - * This function returns a bounding box for the surface. The surface - * bounds are defined as a region beyond which no rendering will - * possibly be recorded, in other words, it is the maximum extent of - * potentially usable coordinates. - * - * For vector surfaces, (PDF, PS, SVG and recording-surfaces), the surface - * might be conceived as unbounded, but we force the user to provide a - * maximum size at the time of surface_create. So get_extents uses - * that size. - * - * Note: The coordinates returned are in "backend" space rather than - * "surface" space. That is, they are relative to the true (0,0) - * origin rather than the device_transform origin. This might seem a - * bit inconsistent with other #cairo_surface_t interfaces, but all - * current callers are within the surface layer where backend space is - * desired. - * - * This behavior would have to be changed is we ever exported a public - * variant of this function. - **/ -cairo_bool_t -_cairo_surface_get_extents (cairo_surface_t *surface, - cairo_rectangle_int_t *extents) -{ - cairo_bool_t bounded; - - if (unlikely (surface->status)) - goto zero_extents; - if (unlikely (surface->finished)) { - _cairo_surface_set_error(surface, CAIRO_STATUS_SURFACE_FINISHED); - goto zero_extents; - } - - bounded = FALSE; - if (surface->backend->get_extents != NULL) - bounded = surface->backend->get_extents (surface, extents); - - if (! bounded) - _cairo_unbounded_rectangle_init (extents); - - return bounded; - -zero_extents: - extents->x = extents->y = 0; - extents->width = extents->height = 0; - return TRUE; -} - -/** - * cairo_surface_has_show_text_glyphs: - * @surface: a #cairo_surface_t - * - * Returns whether the surface supports - * sophisticated cairo_show_text_glyphs() operations. That is, - * whether it actually uses the provided text and cluster data - * to a cairo_show_text_glyphs() call. - * - * Note: Even if this function returns %FALSE, a - * cairo_show_text_glyphs() operation targeted at @surface will - * still succeed. It just will - * act like a cairo_show_glyphs() operation. Users can use this - * function to avoid computing UTF-8 text and cluster mapping if the - * target surface does not use it. - * - * Return value: %TRUE if @surface supports - * cairo_show_text_glyphs(), %FALSE otherwise - * - * Since: 1.8 - **/ -cairo_bool_t -cairo_surface_has_show_text_glyphs (cairo_surface_t *surface) -{ - if (unlikely (surface->status)) - return FALSE; - - if (unlikely (surface->finished)) { - _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED); - return FALSE; - } - - if (surface->backend->has_show_text_glyphs) - return surface->backend->has_show_text_glyphs (surface); - else - return surface->backend->show_text_glyphs != NULL; -} -slim_hidden_def (cairo_surface_has_show_text_glyphs); - -/* Note: the backends may modify the contents of the glyph array as long as - * they do not return %CAIRO_INT_STATUS_UNSUPPORTED. This makes it possible to - * avoid copying the array again and again, and edit it in-place. - * Backends are in fact free to use the array as a generic buffer as they - * see fit. - * - * For show_glyphs backend method, and NOT for show_text_glyphs method, - * when they do return UNSUPPORTED, they may adjust remaining_glyphs to notify - * that they have successfully rendered some of the glyphs (from the beginning - * of the array), but not all. If they don't touch remaining_glyphs, it - * defaults to all glyphs. - * - * See commits 5a9642c5746fd677aed35ce620ce90b1029b1a0c and - * 1781e6018c17909311295a9cc74b70500c6b4d0a for the rationale. - */ -cairo_status_t -_cairo_surface_show_text_glyphs (cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const char *utf8, - int utf8_len, - cairo_glyph_t *glyphs, - int num_glyphs, - const cairo_text_cluster_t *clusters, - int num_clusters, - cairo_text_cluster_flags_t cluster_flags, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - if (unlikely (surface->status)) - return surface->status; - if (unlikely (surface->finished)) - return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - - if (num_glyphs == 0 && utf8_len == 0) - return CAIRO_STATUS_SUCCESS; - - if (_cairo_clip_is_all_clipped (clip)) - return CAIRO_STATUS_SUCCESS; - - status = _pattern_has_error (source); - if (unlikely (status)) - return status; - - if (nothing_to_do (surface, op, source)) - return CAIRO_STATUS_SUCCESS; - - status = _cairo_surface_begin_modification (surface); - if (unlikely (status)) - return status; - - status = CAIRO_INT_STATUS_UNSUPPORTED; - - /* The logic here is duplicated in _cairo_analysis_surface show_glyphs and - * show_text_glyphs. Keep in synch. */ - if (clusters) { - /* A real show_text_glyphs call. Try show_text_glyphs backend - * method first */ - if (surface->backend->show_text_glyphs != NULL) { - status = surface->backend->show_text_glyphs (surface, op, - source, - utf8, utf8_len, - glyphs, num_glyphs, - clusters, num_clusters, cluster_flags, - scaled_font, - clip); - } - if (status == CAIRO_INT_STATUS_UNSUPPORTED && - surface->backend->show_glyphs) - { - status = surface->backend->show_glyphs (surface, op, - source, - glyphs, num_glyphs, - scaled_font, - clip); - } - } else { - /* A mere show_glyphs call. Try show_glyphs backend method first */ - if (surface->backend->show_glyphs != NULL) { - status = surface->backend->show_glyphs (surface, op, - source, - glyphs, num_glyphs, - scaled_font, - clip); - } else if (surface->backend->show_text_glyphs != NULL) { - /* Intentionally only try show_text_glyphs method for show_glyphs - * calls if backend does not have show_glyphs. If backend has - * both methods implemented, we don't fallback from show_glyphs to - * show_text_glyphs, and hence the backend can assume in its - * show_text_glyphs call that clusters is not NULL (which also - * implies that UTF-8 is not NULL, unless the text is - * zero-length). - */ - status = surface->backend->show_text_glyphs (surface, op, - source, - utf8, utf8_len, - glyphs, num_glyphs, - clusters, num_clusters, cluster_flags, - scaled_font, - clip); - } - } - - if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) { - surface->is_clear = FALSE; - surface->serial++; - } - - return _cairo_surface_set_error (surface, status); -} - -/** - * _cairo_surface_set_resolution: - * @surface: the surface - * @x_res: x resolution, in dpi - * @y_res: y resolution, in dpi - * - * Set the actual surface resolution of @surface to the given x and y DPI. - * Mainly used for correctly computing the scale factor when fallback - * rendering needs to take place in the paginated surface. - **/ -void -_cairo_surface_set_resolution (cairo_surface_t *surface, - double x_res, - double y_res) -{ - if (surface->status) - return; - - surface->x_resolution = x_res; - surface->y_resolution = y_res; -} - -/** - * _cairo_surface_create_in_error: - * @status: the error status - * - * Return an appropriate static error surface for the error status. - * On error, surface creation functions should always return a surface - * created with _cairo_surface_create_in_error() instead of a new surface - * in an error state. This simplifies internal code as no refcounting has - * to be done. - **/ -cairo_surface_t * -_cairo_surface_create_in_error (cairo_status_t status) -{ - assert (status < CAIRO_STATUS_LAST_STATUS); - switch (status) { - case CAIRO_STATUS_NO_MEMORY: - return (cairo_surface_t *) &_cairo_surface_nil; - case CAIRO_STATUS_SURFACE_TYPE_MISMATCH: - return (cairo_surface_t *) &_cairo_surface_nil_surface_type_mismatch; - case CAIRO_STATUS_INVALID_STATUS: - return (cairo_surface_t *) &_cairo_surface_nil_invalid_status; - case CAIRO_STATUS_INVALID_CONTENT: - return (cairo_surface_t *) &_cairo_surface_nil_invalid_content; - case CAIRO_STATUS_INVALID_FORMAT: - return (cairo_surface_t *) &_cairo_surface_nil_invalid_format; - case CAIRO_STATUS_INVALID_VISUAL: - return (cairo_surface_t *) &_cairo_surface_nil_invalid_visual; - case CAIRO_STATUS_READ_ERROR: - return (cairo_surface_t *) &_cairo_surface_nil_read_error; - case CAIRO_STATUS_WRITE_ERROR: - return (cairo_surface_t *) &_cairo_surface_nil_write_error; - case CAIRO_STATUS_FILE_NOT_FOUND: - return (cairo_surface_t *) &_cairo_surface_nil_file_not_found; - case CAIRO_STATUS_TEMP_FILE_ERROR: - return (cairo_surface_t *) &_cairo_surface_nil_temp_file_error; - case CAIRO_STATUS_INVALID_STRIDE: - return (cairo_surface_t *) &_cairo_surface_nil_invalid_stride; - case CAIRO_STATUS_INVALID_SIZE: - return (cairo_surface_t *) &_cairo_surface_nil_invalid_size; - case CAIRO_STATUS_DEVICE_TYPE_MISMATCH: - return (cairo_surface_t *) &_cairo_surface_nil_device_type_mismatch; - case CAIRO_STATUS_DEVICE_ERROR: - return (cairo_surface_t *) &_cairo_surface_nil_device_error; - case CAIRO_STATUS_SUCCESS: - case CAIRO_STATUS_LAST_STATUS: - ASSERT_NOT_REACHED; - /* fall-through */ - case CAIRO_STATUS_INVALID_RESTORE: - case CAIRO_STATUS_INVALID_POP_GROUP: - case CAIRO_STATUS_NO_CURRENT_POINT: - case CAIRO_STATUS_INVALID_MATRIX: - case CAIRO_STATUS_NULL_POINTER: - case CAIRO_STATUS_INVALID_STRING: - case CAIRO_STATUS_INVALID_PATH_DATA: - case CAIRO_STATUS_SURFACE_FINISHED: - case CAIRO_STATUS_PATTERN_TYPE_MISMATCH: - case CAIRO_STATUS_INVALID_DASH: - case CAIRO_STATUS_INVALID_DSC_COMMENT: - case CAIRO_STATUS_INVALID_INDEX: - case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE: - case CAIRO_STATUS_FONT_TYPE_MISMATCH: - case CAIRO_STATUS_USER_FONT_IMMUTABLE: - case CAIRO_STATUS_USER_FONT_ERROR: - case CAIRO_STATUS_NEGATIVE_COUNT: - case CAIRO_STATUS_INVALID_CLUSTERS: - case CAIRO_STATUS_INVALID_SLANT: - case CAIRO_STATUS_INVALID_WEIGHT: - case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: - case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION: - case CAIRO_STATUS_DEVICE_FINISHED: - case CAIRO_STATUS_JBIG2_GLOBAL_MISSING: - default: - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_surface_t *) &_cairo_surface_nil; - } -} - -cairo_surface_t * -_cairo_int_surface_create_in_error (cairo_int_status_t status) -{ - if (status < CAIRO_INT_STATUS_LAST_STATUS) - return _cairo_surface_create_in_error (status); - - switch ((int)status) { - case CAIRO_INT_STATUS_UNSUPPORTED: - return (cairo_surface_t *) &_cairo_surface_nil_unsupported; - case CAIRO_INT_STATUS_NOTHING_TO_DO: - return (cairo_surface_t *) &_cairo_surface_nil_nothing_to_do; - default: - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_surface_t *) &_cairo_surface_nil; - } -} - -/* LocalWords: rasterized - */ diff --git a/source/libs/cairo/cairo-src/src/cairo-svg-surface-private.h b/source/libs/cairo/cairo-src/src/cairo-svg-surface-private.h deleted file mode 100644 index ddbf464b1d29e8e058c3c21f2a11460cb190e757..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-svg-surface-private.h +++ /dev/null @@ -1,74 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2004 Red Hat, Inc - * Copyright © 2005-2006 Emmanuel Pacaud <emmanuel.pacaud@free.fr> - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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): - * Kristian Høgsberg <krh@redhat.com> - * Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.fr> - * Carl Worth <cworth@cworth.org> - */ - -#ifndef CAIRO_SVG_SURFACE_PRIVATE_H -#define CAIRO_SVG_SURFACE_PRIVATE_H - -#include "cairo-svg.h" - -#include "cairo-surface-private.h" -#include "cairo-surface-clipper-private.h" - -typedef struct cairo_svg_document cairo_svg_document_t; - -typedef struct cairo_svg_surface { - cairo_surface_t base; - - cairo_content_t content; - - double width; - double height; - - cairo_svg_document_t *document; - - cairo_output_stream_t *xml_node; - cairo_array_t page_set; - - cairo_surface_clipper_t clipper; - unsigned int clip_level; - unsigned int base_clip; - cairo_bool_t is_base_clip_emitted; - - cairo_paginated_mode_t paginated_mode; - - cairo_bool_t force_fallbacks; -} cairo_svg_surface_t; - -#endif /* CAIRO_SVG_SURFACE_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-svg-surface.c b/source/libs/cairo/cairo-src/src/cairo-svg-surface.c deleted file mode 100644 index 372ef45b86e5fe1135599fec0861de71d9f1e8d2..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-svg-surface.c +++ /dev/null @@ -1,2884 +0,0 @@ -/* vim: set sw=4 sts=4: -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2004 Red Hat, Inc - * Copyright © 2005-2007 Emmanuel Pacaud <emmanuel.pacaud@free.fr> - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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): - * Kristian Høgsberg <krh@redhat.com> - * Emmanuel Pacaud <emmanuel.pacaud@free.fr> - * Carl Worth <cworth@cworth.org> - */ - -#define _BSD_SOURCE /* for snprintf() */ -#include "cairoint.h" - -#include "cairo-svg.h" - -#include "cairo-array-private.h" -#include "cairo-analysis-surface-private.h" -#include "cairo-default-context-private.h" -#include "cairo-error-private.h" -#include "cairo-image-info-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-recording-surface-inline.h" -#include "cairo-output-stream-private.h" -#include "cairo-path-fixed-private.h" -#include "cairo-paginated-private.h" -#include "cairo-scaled-font-subsets-private.h" -#include "cairo-surface-clipper-private.h" -#include "cairo-surface-snapshot-inline.h" -#include "cairo-svg-surface-private.h" - -/** - * SECTION:cairo-svg - * @Title: SVG Surfaces - * @Short_Description: Rendering SVG documents - * @See_Also: #cairo_surface_t - * - * The SVG surface is used to render cairo graphics to - * SVG files and is a multi-page vector surface backend. - **/ - -/** - * CAIRO_HAS_SVG_SURFACE: - * - * Defined if the SVG surface backend is available. - * This macro can be used to conditionally compile backend-specific code. - * - * Since: 1.2 - **/ - -typedef struct cairo_svg_page cairo_svg_page_t; - -static const int invalid_pattern_id = -1; - -static const cairo_svg_version_t _cairo_svg_versions[] = -{ - CAIRO_SVG_VERSION_1_1, - CAIRO_SVG_VERSION_1_2 -}; - -#define CAIRO_SVG_VERSION_LAST ARRAY_LENGTH (_cairo_svg_versions) - -static const char *_cairo_svg_supported_mime_types[] = -{ - CAIRO_MIME_TYPE_JPEG, - CAIRO_MIME_TYPE_PNG, - CAIRO_MIME_TYPE_URI, - NULL -}; - -static void -_cairo_svg_surface_emit_path (cairo_output_stream_t *output, - const cairo_path_fixed_t *path, - const cairo_matrix_t *ctm_inverse); - -static cairo_bool_t -_cairo_svg_version_has_page_set_support (cairo_svg_version_t version) -{ - return version > CAIRO_SVG_VERSION_1_1; -} - -static const char * _cairo_svg_version_strings[CAIRO_SVG_VERSION_LAST] = -{ - "SVG 1.1", - "SVG 1.2" -}; - -static const char * _cairo_svg_internal_version_strings[CAIRO_SVG_VERSION_LAST] = -{ - "1.1", - "1.2" -}; - -struct cairo_svg_page { - unsigned int surface_id; - unsigned int clip_level; - cairo_output_stream_t *xml_node; -}; - -struct cairo_svg_document { - cairo_output_stream_t *output_stream; - unsigned long refcount; - cairo_surface_t *owner; - cairo_bool_t finished; - - double width; - double height; - - cairo_output_stream_t *xml_node_defs; - cairo_output_stream_t *xml_node_glyphs; - - unsigned int linear_pattern_id; - unsigned int radial_pattern_id; - unsigned int pattern_id; - unsigned int filter_id; - unsigned int clip_id; - unsigned int mask_id; - - cairo_bool_t alpha_filter; - - cairo_svg_version_t svg_version; - - cairo_scaled_font_subsets_t *font_subsets; -}; - -static cairo_status_t -_cairo_svg_document_create (cairo_output_stream_t *stream, - double width, - double height, - cairo_svg_version_t version, - cairo_svg_document_t **document_out); - -static cairo_status_t -_cairo_svg_document_destroy (cairo_svg_document_t *document); - -static cairo_status_t -_cairo_svg_document_finish (cairo_svg_document_t *document); - -static cairo_svg_document_t * -_cairo_svg_document_reference (cairo_svg_document_t *document); - -static unsigned int -_cairo_svg_document_allocate_mask_id (cairo_svg_document_t *document); - -static cairo_surface_t * -_cairo_svg_surface_create_for_document (cairo_svg_document_t *document, - cairo_content_t content, - double width, - double height); -static cairo_surface_t * -_cairo_svg_surface_create_for_stream_internal (cairo_output_stream_t *stream, - double width, - double height, - cairo_svg_version_t version); - -static const cairo_surface_backend_t cairo_svg_surface_backend; -static const cairo_paginated_surface_backend_t cairo_svg_surface_paginated_backend; - -/** - * cairo_svg_surface_create_for_stream: - * @write_func: a #cairo_write_func_t to accept the output data, may be %NULL - * to indicate a no-op @write_func. With a no-op @write_func, - * the surface may be queried or used as a source without - * generating any temporary files. - * @closure: the closure argument for @write_func - * @width_in_points: width of the surface, in points (1 point == 1/72.0 inch) - * @height_in_points: height of the surface, in points (1 point == 1/72.0 inch) - * - * Creates a SVG surface of the specified size in points to be written - * incrementally to the stream represented by @write_func and @closure. - * - * Return value: a pointer to the newly created surface. The caller - * owns the surface and should call cairo_surface_destroy() when done - * with it. - * - * This function always returns a valid pointer, but it will return a - * pointer to a "nil" surface if an error such as out of memory - * occurs. You can use cairo_surface_status() to check for this. - * - * Since: 1.2 - **/ -cairo_surface_t * -cairo_svg_surface_create_for_stream (cairo_write_func_t write_func, - void *closure, - double width, - double height) -{ - cairo_output_stream_t *stream; - - stream = _cairo_output_stream_create (write_func, NULL, closure); - if (_cairo_output_stream_get_status (stream)) - return _cairo_surface_create_in_error (_cairo_output_stream_destroy (stream)); - - return _cairo_svg_surface_create_for_stream_internal (stream, width, height, CAIRO_SVG_VERSION_1_1); -} - -/** - * cairo_svg_surface_create: - * @filename: a filename for the SVG output (must be writable), %NULL may be - * used to specify no output. This will generate a SVG surface that - * may be queried and used as a source, without generating a - * temporary file. - * @width_in_points: width of the surface, in points (1 point == 1/72.0 inch) - * @height_in_points: height of the surface, in points (1 point == 1/72.0 inch) - * - * Creates a SVG surface of the specified size in points to be written - * to @filename. - * - * The SVG surface backend recognizes the following MIME types for the - * data attached to a surface (see cairo_surface_set_mime_data()) when - * it is used as a source pattern for drawing on this surface: - * %CAIRO_MIME_TYPE_JPEG, %CAIRO_MIME_TYPE_PNG, - * %CAIRO_MIME_TYPE_URI. If any of them is specified, the SVG backend - * emits a href with the content of MIME data instead of a surface - * snapshot (PNG, Base64-encoded) in the corresponding image tag. - * - * The unofficial MIME type %CAIRO_MIME_TYPE_URI is examined - * first. If present, the URI is emitted as is: assuring the - * correctness of URI is left to the client code. - * - * If %CAIRO_MIME_TYPE_URI is not present, but %CAIRO_MIME_TYPE_JPEG - * or %CAIRO_MIME_TYPE_PNG is specified, the corresponding data is - * Base64-encoded and emitted. - * - * Return value: a pointer to the newly created surface. The caller - * owns the surface and should call cairo_surface_destroy() when done - * with it. - * - * This function always returns a valid pointer, but it will return a - * pointer to a "nil" surface if an error such as out of memory - * occurs. You can use cairo_surface_status() to check for this. - * - * Since: 1.2 - **/ -cairo_surface_t * -cairo_svg_surface_create (const char *filename, - double width, - double height) -{ - cairo_output_stream_t *stream; - - stream = _cairo_output_stream_create_for_filename (filename); - if (_cairo_output_stream_get_status (stream)) - return _cairo_surface_create_in_error (_cairo_output_stream_destroy (stream)); - - return _cairo_svg_surface_create_for_stream_internal (stream, width, height, CAIRO_SVG_VERSION_1_1); -} - -static cairo_bool_t -_cairo_surface_is_svg (cairo_surface_t *surface) -{ - return surface->backend == &cairo_svg_surface_backend; -} - -/* If the abstract_surface is a paginated surface, and that paginated - * surface's target is a svg_surface, then set svg_surface to that - * target. Otherwise return FALSE. - */ -static cairo_bool_t -_extract_svg_surface (cairo_surface_t *surface, - cairo_svg_surface_t **svg_surface) -{ - cairo_surface_t *target; - cairo_status_t status_ignored; - - if (surface->status) - return FALSE; - if (surface->finished) { - status_ignored = _cairo_surface_set_error (surface, - _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - return FALSE; - } - - if (! _cairo_surface_is_paginated (surface)) { - status_ignored = _cairo_surface_set_error (surface, - _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH)); - return FALSE; - } - - target = _cairo_paginated_surface_get_target (surface); - if (target->status) { - status_ignored = _cairo_surface_set_error (surface, - target->status); - return FALSE; - } - if (target->finished) { - status_ignored = _cairo_surface_set_error (surface, - _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - return FALSE; - } - - if (! _cairo_surface_is_svg (target)) { - status_ignored = _cairo_surface_set_error (surface, - _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH)); - return FALSE; - } - - *svg_surface = (cairo_svg_surface_t *) target; - return TRUE; -} - -/** - * cairo_svg_surface_restrict_to_version: - * @surface: a SVG #cairo_surface_t - * @version: SVG version - * - * Restricts the generated SVG file to @version. See cairo_svg_get_versions() - * for a list of available version values that can be used here. - * - * This function should only be called before any drawing operations - * have been performed on the given surface. The simplest way to do - * this is to call this function immediately after creating the - * surface. - * - * Since: 1.2 - **/ -void -cairo_svg_surface_restrict_to_version (cairo_surface_t *abstract_surface, - cairo_svg_version_t version) -{ - cairo_svg_surface_t *surface = NULL; /* hide compiler warning */ - - if (! _extract_svg_surface (abstract_surface, &surface)) - return; - - if (version < CAIRO_SVG_VERSION_LAST) - surface->document->svg_version = version; -} - -/** - * cairo_svg_get_versions: - * @versions: supported version list - * @num_versions: list length - * - * Used to retrieve the list of supported versions. See - * cairo_svg_surface_restrict_to_version(). - * - * Since: 1.2 - **/ -void -cairo_svg_get_versions (cairo_svg_version_t const **versions, - int *num_versions) -{ - if (versions != NULL) - *versions = _cairo_svg_versions; - - if (num_versions != NULL) - *num_versions = CAIRO_SVG_VERSION_LAST; -} - -/** - * cairo_svg_version_to_string: - * @version: a version id - * - * Get the string representation of the given @version id. This function - * will return %NULL if @version isn't valid. See cairo_svg_get_versions() - * for a way to get the list of valid version ids. - * - * Return value: the string associated to given version. - * - * Since: 1.2 - **/ -const char * -cairo_svg_version_to_string (cairo_svg_version_t version) -{ - if (version >= CAIRO_SVG_VERSION_LAST) - return NULL; - - return _cairo_svg_version_strings[version]; -} - -static cairo_bool_t -_cliprect_covers_surface (cairo_svg_surface_t *surface, - cairo_path_fixed_t *path) -{ - cairo_box_t box; - - if (_cairo_path_fixed_is_box (path, &box)) { - if (box.p1.x <= 0 && - box.p1.y <= 0 && - _cairo_fixed_to_double (box.p2.x) >= surface->width && - _cairo_fixed_to_double (box.p2.y) >= surface->height) - { - return TRUE; - } - } - - return FALSE; -} - -static cairo_status_t -_cairo_svg_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper, - cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_svg_surface_t *surface = cairo_container_of (clipper, - cairo_svg_surface_t, - clipper); - cairo_svg_document_t *document = surface->document; - unsigned int i; - - if (path == NULL) { - for (i = 0; i < surface->clip_level; i++) - _cairo_output_stream_printf (surface->xml_node, "</g>\n"); - - surface->clip_level = 0; - return CAIRO_STATUS_SUCCESS; - } - - /* skip trivial whole-page clips */ - if (_cliprect_covers_surface (surface, path)) - return CAIRO_STATUS_SUCCESS; - - _cairo_output_stream_printf (document->xml_node_defs, - "<clipPath id=\"clip%d\">\n" - " <path ", - document->clip_id); - _cairo_svg_surface_emit_path (document->xml_node_defs, path, NULL); - - _cairo_output_stream_printf (document->xml_node_defs, - "/>\n" - "</clipPath>\n"); - - _cairo_output_stream_printf (surface->xml_node, - "<g clip-path=\"url(#clip%d)\" " - "clip-rule=\"%s\">\n", - document->clip_id, - fill_rule == CAIRO_FILL_RULE_EVEN_ODD ? - "evenodd" : "nonzero"); - - document->clip_id++; - surface->clip_level++; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_surface_t * -_cairo_svg_surface_create_for_document (cairo_svg_document_t *document, - cairo_content_t content, - double width, - double height) -{ - cairo_svg_surface_t *surface; - cairo_surface_t *paginated; - cairo_status_t status, status_ignored; - - surface = malloc (sizeof (cairo_svg_surface_t)); - if (unlikely (surface == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - _cairo_surface_init (&surface->base, - &cairo_svg_surface_backend, - NULL, /* device */ - content); - - surface->width = width; - surface->height = height; - - surface->document = _cairo_svg_document_reference (document); - - surface->clip_level = 0; - _cairo_surface_clipper_init (&surface->clipper, - _cairo_svg_surface_clipper_intersect_clip_path); - - surface->base_clip = document->clip_id++; - surface->is_base_clip_emitted = FALSE; - - surface->xml_node = _cairo_memory_stream_create (); - status = _cairo_output_stream_get_status (surface->xml_node); - if (unlikely (status)) - goto CLEANUP; - - _cairo_array_init (&surface->page_set, sizeof (cairo_svg_page_t)); - - if (content == CAIRO_CONTENT_COLOR) { - _cairo_output_stream_printf (surface->xml_node, - "<rect width=\"%f\" height=\"%f\" " - "style=\"opacity:1;stroke:none;" - "fill:rgb(0,0,0);\"/>\n", - width, height); - status = _cairo_output_stream_get_status (surface->xml_node); - if (unlikely (status)) - goto CLEANUP; - } - - surface->paginated_mode = CAIRO_PAGINATED_MODE_ANALYZE; - surface->force_fallbacks = FALSE; - surface->content = content; - - paginated = _cairo_paginated_surface_create (&surface->base, - surface->content, - &cairo_svg_surface_paginated_backend); - status = paginated->status; - if (status == CAIRO_STATUS_SUCCESS) { - /* paginated keeps the only reference to surface now, drop ours */ - cairo_surface_destroy (&surface->base); - return paginated; - } - - /* ignore status as we are on the error path */ -CLEANUP: - status_ignored = _cairo_output_stream_destroy (surface->xml_node); - status_ignored = _cairo_svg_document_destroy (document); - - free (surface); - - return _cairo_surface_create_in_error (status); -} - -static cairo_surface_t * -_cairo_svg_surface_create_for_stream_internal (cairo_output_stream_t *stream, - double width, - double height, - cairo_svg_version_t version) -{ - cairo_svg_document_t *document = NULL; /* silence compiler */ - cairo_surface_t *surface; - cairo_status_t status; - - status = _cairo_svg_document_create (stream, - width, height, version, - &document); - if (unlikely (status)) { - surface = _cairo_surface_create_in_error (status); - /* consume the output stream on behalf of caller */ - status = _cairo_output_stream_destroy (stream); - return surface; - } - - surface = _cairo_svg_surface_create_for_document (document, CAIRO_CONTENT_COLOR_ALPHA, - width, height); - if (surface->status) { - status = _cairo_svg_document_destroy (document); - return surface; - } - - document->owner = surface; - status = _cairo_svg_document_destroy (document); - /* the ref count should be 2 at this point */ - assert (status == CAIRO_STATUS_SUCCESS); - - return surface; -} - -static cairo_svg_page_t * -_cairo_svg_surface_store_page (cairo_svg_surface_t *surface) -{ - cairo_svg_page_t page; - cairo_output_stream_t *stream; - cairo_int_status_t status; - unsigned int i; - - stream = _cairo_memory_stream_create (); - if (_cairo_output_stream_get_status (stream)) { - status = _cairo_output_stream_destroy (stream); - return NULL; - } - - page.surface_id = surface->base.unique_id; - page.clip_level = surface->clip_level; - page.xml_node = surface->xml_node; - - if (_cairo_array_append (&surface->page_set, &page)) { - status = _cairo_output_stream_destroy (stream); - return NULL; - } - - surface->xml_node = stream; - surface->clip_level = 0; - for (i = 0; i < page.clip_level; i++) - _cairo_output_stream_printf (page.xml_node, "</g>\n"); - - _cairo_surface_clipper_reset (&surface->clipper); - - return _cairo_array_index (&surface->page_set, - surface->page_set.num_elements - 1); -} - -static cairo_int_status_t -_cairo_svg_surface_copy_page (void *abstract_surface) -{ - cairo_svg_surface_t *surface = abstract_surface; - cairo_svg_page_t *page; - - page = _cairo_svg_surface_store_page (surface); - if (unlikely (page == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_memory_stream_copy (page->xml_node, surface->xml_node); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_svg_surface_show_page (void *abstract_surface) -{ - cairo_svg_surface_t *surface = abstract_surface; - - if (unlikely (_cairo_svg_surface_store_page (surface) == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_svg_surface_emit_transform (cairo_output_stream_t *output, - char const *attribute_str, - const cairo_matrix_t *object_matrix, - const cairo_matrix_t *parent_matrix) -{ - cairo_matrix_t matrix = *object_matrix; - - if (parent_matrix != NULL) - cairo_matrix_multiply (&matrix, &matrix, parent_matrix); - - if (!_cairo_matrix_is_identity (&matrix)) - _cairo_output_stream_printf (output, - "%s=\"matrix(%f,%f,%f,%f,%f,%f)\"", - attribute_str, - matrix.xx, matrix.yx, - matrix.xy, matrix.yy, - matrix.x0, matrix.y0); -} - -typedef struct { - cairo_output_stream_t *output; - const cairo_matrix_t *ctm_inverse; -} svg_path_info_t; - -static cairo_status_t -_cairo_svg_path_move_to (void *closure, - const cairo_point_t *point) -{ - svg_path_info_t *info = closure; - double x = _cairo_fixed_to_double (point->x); - double y = _cairo_fixed_to_double (point->y); - - if (info->ctm_inverse) - cairo_matrix_transform_point (info->ctm_inverse, &x, &y); - - _cairo_output_stream_printf (info->output, "M %f %f ", x, y); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_svg_path_line_to (void *closure, - const cairo_point_t *point) -{ - svg_path_info_t *info = closure; - double x = _cairo_fixed_to_double (point->x); - double y = _cairo_fixed_to_double (point->y); - - if (info->ctm_inverse) - cairo_matrix_transform_point (info->ctm_inverse, &x, &y); - - _cairo_output_stream_printf (info->output, "L %f %f ", x, y); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_svg_path_curve_to (void *closure, - const cairo_point_t *b, - const cairo_point_t *c, - const cairo_point_t *d) -{ - svg_path_info_t *info = closure; - double bx = _cairo_fixed_to_double (b->x); - double by = _cairo_fixed_to_double (b->y); - double cx = _cairo_fixed_to_double (c->x); - double cy = _cairo_fixed_to_double (c->y); - double dx = _cairo_fixed_to_double (d->x); - double dy = _cairo_fixed_to_double (d->y); - - if (info->ctm_inverse) { - cairo_matrix_transform_point (info->ctm_inverse, &bx, &by); - cairo_matrix_transform_point (info->ctm_inverse, &cx, &cy); - cairo_matrix_transform_point (info->ctm_inverse, &dx, &dy); - } - - _cairo_output_stream_printf (info->output, - "C %f %f %f %f %f %f ", - bx, by, cx, cy, dx, dy); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_svg_path_close_path (void *closure) -{ - svg_path_info_t *info = closure; - - _cairo_output_stream_printf (info->output, "Z "); - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_svg_surface_emit_path (cairo_output_stream_t *output, - const cairo_path_fixed_t *path, - const cairo_matrix_t *ctm_inverse) -{ - cairo_status_t status; - svg_path_info_t info; - - _cairo_output_stream_printf (output, "d=\""); - - info.output = output; - info.ctm_inverse = ctm_inverse; - status = _cairo_path_fixed_interpret (path, - _cairo_svg_path_move_to, - _cairo_svg_path_line_to, - _cairo_svg_path_curve_to, - _cairo_svg_path_close_path, - &info); - assert (status == CAIRO_STATUS_SUCCESS); - - _cairo_output_stream_printf (output, "\""); -} - -static cairo_int_status_t -_cairo_svg_document_emit_outline_glyph_data (cairo_svg_document_t *document, - cairo_scaled_font_t *scaled_font, - unsigned long glyph_index) -{ - cairo_scaled_glyph_t *scaled_glyph; - cairo_int_status_t status; - - status = _cairo_scaled_glyph_lookup (scaled_font, - glyph_index, - CAIRO_SCALED_GLYPH_INFO_METRICS| - CAIRO_SCALED_GLYPH_INFO_PATH, - &scaled_glyph); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (document->xml_node_glyphs, - "<path style=\"stroke:none;\" "); - - _cairo_svg_surface_emit_path (document->xml_node_glyphs, - scaled_glyph->path, NULL); - - _cairo_output_stream_printf (document->xml_node_glyphs, - "/>\n"); - - return status; -} - -static cairo_int_status_t -_cairo_svg_document_emit_bitmap_glyph_data (cairo_svg_document_t *document, - cairo_scaled_font_t *scaled_font, - unsigned long glyph_index) -{ - cairo_scaled_glyph_t *scaled_glyph; - cairo_image_surface_t *image; - cairo_status_t status; - uint8_t *row, *byte; - int rows, cols; - int x, y, bit; - - status = _cairo_scaled_glyph_lookup (scaled_font, - glyph_index, - CAIRO_SCALED_GLYPH_INFO_METRICS | - CAIRO_SCALED_GLYPH_INFO_SURFACE, - &scaled_glyph); - if (unlikely (status)) - return status; - - image = _cairo_image_surface_coerce_to_format (scaled_glyph->surface, - CAIRO_FORMAT_A1); - status = image->base.status; - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (document->xml_node_glyphs, "<g"); - _cairo_svg_surface_emit_transform (document->xml_node_glyphs, " transform", - &image->base.device_transform_inverse, NULL); - _cairo_output_stream_printf (document->xml_node_glyphs, ">\n"); - - for (y = 0, row = image->data, rows = image->height; rows; row += image->stride, rows--, y++) { - for (x = 0, byte = row, cols = (image->width + 7) / 8; cols; byte++, cols--) { - uint8_t output_byte = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (*byte); - for (bit = 7; bit >= 0 && x < image->width; bit--, x++) { - if (output_byte & (1 << bit)) { - _cairo_output_stream_printf (document->xml_node_glyphs, - "<rect x=\"%d\" y=\"%d\" width=\"1\" height=\"1\"/>\n", - x, y); - } - } - } - } - _cairo_output_stream_printf (document->xml_node_glyphs, "</g>\n"); - - cairo_surface_destroy (&image->base); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_svg_document_emit_glyph (cairo_svg_document_t *document, - cairo_scaled_font_t *scaled_font, - unsigned long scaled_font_glyph_index, - unsigned int font_id, - unsigned int subset_glyph_index) -{ - cairo_int_status_t status; - - _cairo_output_stream_printf (document->xml_node_glyphs, - "<symbol overflow=\"visible\" id=\"glyph%d-%d\">\n", - font_id, - subset_glyph_index); - - status = _cairo_svg_document_emit_outline_glyph_data (document, - scaled_font, - scaled_font_glyph_index); - if (status == CAIRO_INT_STATUS_UNSUPPORTED) - status = _cairo_svg_document_emit_bitmap_glyph_data (document, - scaled_font, - scaled_font_glyph_index); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (document->xml_node_glyphs, "</symbol>\n"); - - return CAIRO_INT_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_svg_document_emit_font_subset (cairo_scaled_font_subset_t *font_subset, - void *closure) -{ - cairo_svg_document_t *document = closure; - cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS; - unsigned int i; - - _cairo_scaled_font_freeze_cache (font_subset->scaled_font); - for (i = 0; i < font_subset->num_glyphs; i++) { - status = _cairo_svg_document_emit_glyph (document, - font_subset->scaled_font, - font_subset->glyphs[i], - font_subset->font_id, i); - if (unlikely (status)) - break; - } - _cairo_scaled_font_thaw_cache (font_subset->scaled_font); - - return status; -} - -static cairo_status_t -_cairo_svg_document_emit_font_subsets (cairo_svg_document_t *document) -{ - cairo_status_t status; - - status = _cairo_scaled_font_subsets_foreach_scaled (document->font_subsets, - _cairo_svg_document_emit_font_subset, - document); - if (unlikely (status)) - goto FAIL; - - status = _cairo_scaled_font_subsets_foreach_user (document->font_subsets, - _cairo_svg_document_emit_font_subset, - document); - - FAIL: - _cairo_scaled_font_subsets_destroy (document->font_subsets); - document->font_subsets = NULL; - - return status; -} - -static char const * -_cairo_svg_surface_operators[] = { - "clear", - - "src", "src-over", "src-in", - "src-out", "src-atop", - - "dst", "dst-over", "dst-in", - "dst-out", "dst-atop", - - "xor", "plus", - "color-dodge", /* FIXME: saturate ? */ - - "multiply", "screen", "overlay", - "darken", "lighten", - "color-dodge", "color-burn", - "hard-light", "soft-light", - "difference", "exclusion" -}; - -static cairo_bool_t -_cairo_svg_surface_analyze_operator (cairo_svg_surface_t *surface, - cairo_operator_t op) -{ - /* guard against newly added operators */ - if (op >= ARRAY_LENGTH (_cairo_svg_surface_operators)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* allow operators being NULL if they are unsupported */ - if (_cairo_svg_surface_operators[op] == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_svg_surface_analyze_operation (cairo_svg_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *pattern) -{ - cairo_svg_document_t *document = surface->document; - - if (surface->force_fallbacks && - surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) - { - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - if (pattern->type == CAIRO_PATTERN_TYPE_MESH) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* SVG doesn't support extend reflect for image pattern */ - if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE && - pattern->extend == CAIRO_EXTEND_REFLECT) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (document->svg_version >= CAIRO_SVG_VERSION_1_2) - return _cairo_svg_surface_analyze_operator (surface, op); - - if (op == CAIRO_OPERATOR_OVER) - return CAIRO_STATUS_SUCCESS; - - /* The SOURCE operator is only supported if there is nothing - * painted underneath. */ - if (op == CAIRO_OPERATOR_SOURCE) - return CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY; - - return CAIRO_INT_STATUS_UNSUPPORTED; -} - -static cairo_int_status_t -_cairo_svg_surface_operation_supported (cairo_svg_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *pattern) -{ - return _cairo_svg_surface_analyze_operation (surface, op, pattern) != CAIRO_INT_STATUS_UNSUPPORTED; -} - -static cairo_status_t -_cairo_svg_surface_finish (void *abstract_surface) -{ - cairo_status_t status, status2; - cairo_svg_surface_t *surface = abstract_surface; - cairo_svg_document_t *document = surface->document; - cairo_svg_page_t *page; - unsigned int i; - - if (_cairo_paginated_surface_get_target (document->owner) == &surface->base) - status = _cairo_svg_document_finish (document); - else - status = CAIRO_STATUS_SUCCESS; - - if (surface->xml_node != NULL) { - status2 = _cairo_output_stream_destroy (surface->xml_node); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - } - - for (i = 0; i < surface->page_set.num_elements; i++) { - page = _cairo_array_index (&surface->page_set, i); - status2 = _cairo_output_stream_destroy (page->xml_node); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - } - _cairo_array_fini (&surface->page_set); - - _cairo_surface_clipper_reset (&surface->clipper); - - status2 = _cairo_svg_document_destroy (document); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - - return status; -} - - -static void -_cairo_svg_surface_emit_alpha_filter (cairo_svg_document_t *document) -{ - if (document->alpha_filter) - return; - - _cairo_output_stream_printf (document->xml_node_defs, - "<filter id=\"alpha\" " - "filterUnits=\"objectBoundingBox\" " - "x=\"0%%\" y=\"0%%\" " - "width=\"100%%\" height=\"100%%\">\n" - " <feColorMatrix type=\"matrix\" " - "in=\"SourceGraphic\" " - "values=\"0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0\"/>\n" - "</filter>\n"); - - document->alpha_filter = TRUE; -} - -typedef struct { - cairo_output_stream_t *output; - unsigned int in_mem; - unsigned int trailing; - unsigned char src[3]; -} base64_write_closure_t; - -static char const base64_table[64] = -"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -static cairo_status_t -base64_write_func (void *closure, - const unsigned char *data, - unsigned int length) -{ - base64_write_closure_t *info = (base64_write_closure_t *) closure; - unsigned int i; - unsigned char *src; - - src = info->src; - - if (info->in_mem + length < 3) { - for (i = 0; i < length; i++) { - src[i + info->in_mem] = *data++; - } - info->in_mem += length; - return CAIRO_STATUS_SUCCESS; - } - - do { - unsigned char dst[4]; - - for (i = info->in_mem; i < 3; i++) { - src[i] = *data++; - length--; - } - info->in_mem = 0; - - dst[0] = base64_table[src[0] >> 2]; - dst[1] = base64_table[(src[0] & 0x03) << 4 | src[1] >> 4]; - dst[2] = base64_table[(src[1] & 0x0f) << 2 | src[2] >> 6]; - dst[3] = base64_table[src[2] & 0xfc >> 2]; - /* Special case for the last missing bits */ - switch (info->trailing) { - case 2: - dst[2] = '='; - case 1: - dst[3] = '='; - default: - break; - } - _cairo_output_stream_write (info->output, dst, 4); - } while (length >= 3); - - for (i = 0; i < length; i++) { - src[i] = *data++; - } - info->in_mem = length; - - return _cairo_output_stream_get_status (info->output); -} - -static cairo_int_status_t -_cairo_surface_base64_encode_jpeg (cairo_surface_t *surface, - cairo_output_stream_t *output) -{ - const unsigned char *mime_data; - unsigned long mime_data_length; - cairo_image_info_t image_info; - base64_write_closure_t info; - cairo_status_t status; - - cairo_surface_get_mime_data (surface, CAIRO_MIME_TYPE_JPEG, - &mime_data, &mime_data_length); - if (mime_data == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_image_info_get_jpeg_info (&image_info, mime_data, mime_data_length); - if (unlikely (status)) - return status; - - if (image_info.num_components == 4) - return CAIRO_INT_STATUS_UNSUPPORTED; - - _cairo_output_stream_printf (output, "data:image/jpeg;base64,"); - - info.output = output; - info.in_mem = 0; - info.trailing = 0; - - status = base64_write_func (&info, mime_data, mime_data_length); - if (unlikely (status)) - return status; - - if (info.in_mem > 0) { - memset (info.src + info.in_mem, 0, 3 - info.in_mem); - info.trailing = 3 - info.in_mem; - info.in_mem = 3; - status = base64_write_func (&info, NULL, 0); - } - - return status; -} - -static cairo_int_status_t -_cairo_surface_base64_encode_png (cairo_surface_t *surface, - cairo_output_stream_t *output) -{ - const unsigned char *mime_data; - unsigned long mime_data_length; - base64_write_closure_t info; - cairo_status_t status; - - cairo_surface_get_mime_data (surface, CAIRO_MIME_TYPE_PNG, - &mime_data, &mime_data_length); - if (unlikely (surface->status)) - return surface->status; - if (mime_data == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - _cairo_output_stream_printf (output, "data:image/png;base64,"); - - info.output = output; - info.in_mem = 0; - info.trailing = 0; - - status = base64_write_func (&info, mime_data, mime_data_length); - if (unlikely (status)) - return status; - - if (info.in_mem > 0) { - memset (info.src + info.in_mem, 0, 3 - info.in_mem); - info.trailing = 3 - info.in_mem; - info.in_mem = 3; - status = base64_write_func (&info, NULL, 0); - } - - return status; -} - -static cairo_int_status_t -_cairo_surface_base64_encode (cairo_surface_t *surface, - cairo_output_stream_t *output) -{ - cairo_int_status_t status; - base64_write_closure_t info; - - status = _cairo_surface_base64_encode_jpeg (surface, output); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - - status = _cairo_surface_base64_encode_png (surface, output); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - - info.output = output; - info.in_mem = 0; - info.trailing = 0; - - _cairo_output_stream_printf (info.output, "data:image/png;base64,"); - - status = cairo_surface_write_to_png_stream (surface, base64_write_func, - (void *) &info); - - if (unlikely (status)) - return status; - - if (info.in_mem > 0) { - memset (info.src + info.in_mem, 0, 3 - info.in_mem); - info.trailing = 3 - info.in_mem; - info.in_mem = 3; - status = base64_write_func (&info, NULL, 0); - } - - return status; -} - -static void -_cairo_svg_surface_emit_operator (cairo_output_stream_t *output, - cairo_svg_surface_t *surface, - cairo_operator_t op) -{ - if (surface->document->svg_version >= CAIRO_SVG_VERSION_1_2 && - op != CAIRO_OPERATOR_OVER) { - _cairo_output_stream_printf (output, " comp-op=\"%s\"", _cairo_svg_surface_operators[op]); - if (!_cairo_operator_bounded_by_source (op)) - _cairo_output_stream_printf (output, " clip-to-self=\"true\""); - } -} - -static void -_cairo_svg_surface_emit_operator_for_style (cairo_output_stream_t *output, - cairo_svg_surface_t *surface, - cairo_operator_t op) -{ - if (surface->document->svg_version >= CAIRO_SVG_VERSION_1_2 && - op != CAIRO_OPERATOR_OVER) { - _cairo_output_stream_printf (output, "comp-op:%s;", _cairo_svg_surface_operators[op]); - if (!_cairo_operator_bounded_by_source (op)) - _cairo_output_stream_printf (output, "clip-to-self:true;"); - } -} - -/** - * _cairo_svg_surface_emit_attr_value: - * - * Write the value to output the stream as a sequence of characters, - * while escaping those which have special meaning in the XML - * attribute's value context: & and ". - **/ -static void -_cairo_svg_surface_emit_attr_value (cairo_output_stream_t *stream, - const unsigned char *value, - unsigned int length) -{ - const unsigned char *p; - const unsigned char *q; - unsigned int i; - - /* we'll accumulate non-special chars in [q, p) range */ - p = value; - q = p; - for (i = 0; i < length; i++, p++) { - if (*p == '&' || *p == '"') { - /* flush what's left before special char */ - if (p != q) { - _cairo_output_stream_write (stream, q, p - q); - q = p + 1; - } - - if (*p == '&') - _cairo_output_stream_printf (stream, "&"); - else // p == '"' - _cairo_output_stream_printf (stream, """); - } - } - - /* flush the trailing chars if any */ - if (p != q) - _cairo_output_stream_write (stream, q, p - q); -} - -static cairo_status_t -_cairo_svg_surface_emit_surface (cairo_svg_document_t *document, - cairo_surface_t *surface) -{ - cairo_rectangle_int_t extents; - cairo_bool_t is_bounded; - cairo_status_t status; - const unsigned char *uri; - unsigned long uri_len; - - if (_cairo_user_data_array_get_data (&surface->user_data, - (cairo_user_data_key_t *) document)) - { - return CAIRO_STATUS_SUCCESS; - } - - is_bounded = _cairo_surface_get_extents (surface, &extents); - assert (is_bounded); - - _cairo_output_stream_printf (document->xml_node_defs, - "<image id=\"image%d\" width=\"%d\" height=\"%d\"", - surface->unique_id, - extents.width, extents.height); - - _cairo_output_stream_printf (document->xml_node_defs, " xlink:href=\""); - - cairo_surface_get_mime_data (surface, CAIRO_MIME_TYPE_URI, - &uri, &uri_len); - if (uri != NULL) { - _cairo_svg_surface_emit_attr_value (document->xml_node_defs, - uri, uri_len); - } else { - status = _cairo_surface_base64_encode (surface, - document->xml_node_defs); - if (unlikely (status)) - return status; - } - - _cairo_output_stream_printf (document->xml_node_defs, "\"/>\n"); - - /* and tag it */ - return _cairo_user_data_array_set_data (&surface->user_data, - (cairo_user_data_key_t *) document, - document, NULL); -} - -static cairo_status_t -_cairo_svg_surface_emit_composite_surface_pattern (cairo_output_stream_t *output, - cairo_svg_surface_t *svg_surface, - cairo_operator_t op, - cairo_surface_pattern_t *pattern, - int pattern_id, - const cairo_matrix_t *parent_matrix, - const char *extra_attributes) -{ - cairo_status_t status; - cairo_matrix_t p2u; - - p2u = pattern->base.matrix; - status = cairo_matrix_invert (&p2u); - /* cairo_pattern_set_matrix ensures the matrix is invertible */ - assert (status == CAIRO_STATUS_SUCCESS); - - status = _cairo_svg_surface_emit_surface (svg_surface->document, - pattern->surface); - if (unlikely (status)) - return status; - - if (pattern_id != invalid_pattern_id) { - cairo_rectangle_int_t extents; - cairo_bool_t is_bounded; - - is_bounded = _cairo_surface_get_extents (pattern->surface, &extents); - assert (is_bounded); - - _cairo_output_stream_printf (output, - "<pattern id=\"pattern%d\" " - "patternUnits=\"userSpaceOnUse\" " - "width=\"%d\" height=\"%d\" ", - pattern_id, - extents.width, extents.height); - _cairo_svg_surface_emit_transform (output, - " patternTransform", - &p2u, parent_matrix); - _cairo_output_stream_printf (output, ">\n "); - } - - _cairo_output_stream_printf (output, - "<use xlink:href=\"#image%d\"", - pattern->surface->unique_id); - if (extra_attributes) - _cairo_output_stream_printf (output, " %s", extra_attributes); - - if (pattern_id == invalid_pattern_id) { - _cairo_svg_surface_emit_operator (output, svg_surface, op); - _cairo_svg_surface_emit_transform (output, - " transform", - &p2u, parent_matrix); - } - _cairo_output_stream_printf (output, "/>\n"); - - - if (pattern_id != invalid_pattern_id) - _cairo_output_stream_printf (output, "</pattern>\n"); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_svg_surface_emit_recording_surface (cairo_svg_document_t *document, - cairo_recording_surface_t *source) -{ - cairo_status_t status; - cairo_surface_t *paginated_surface; - cairo_svg_surface_t *svg_surface; - cairo_array_t *page_set; - - cairo_output_stream_t *contents; - - if (_cairo_user_data_array_get_data (&source->base.user_data, - (cairo_user_data_key_t *) document)) - { - return CAIRO_STATUS_SUCCESS; - } - - paginated_surface = _cairo_svg_surface_create_for_document (document, - source->base.content, - source->extents_pixels.width, - source->extents_pixels.height); - if (unlikely (paginated_surface->status)) - return paginated_surface->status; - - svg_surface = (cairo_svg_surface_t *) - _cairo_paginated_surface_get_target (paginated_surface); - cairo_surface_set_fallback_resolution (paginated_surface, - document->owner->x_fallback_resolution, - document->owner->y_fallback_resolution); - cairo_surface_set_device_offset (&svg_surface->base, - -source->extents_pixels.x, - -source->extents_pixels.y); - - status = _cairo_recording_surface_replay (&source->base, paginated_surface); - if (unlikely (status)) { - cairo_surface_destroy (paginated_surface); - return status; - } - - cairo_surface_show_page (paginated_surface); - status = cairo_surface_status (paginated_surface); - if (unlikely (status)) { - cairo_surface_destroy (paginated_surface); - return status; - } - - if (! svg_surface->is_base_clip_emitted) { - svg_surface->is_base_clip_emitted = TRUE; - _cairo_output_stream_printf (document->xml_node_defs, - "<clipPath id=\"clip%d\">\n" - " <rect width=\"%f\" height=\"%f\"/>\n" - "</clipPath>\n", - svg_surface->base_clip, - svg_surface->width, - svg_surface->height); - } - - if (source->base.content == CAIRO_CONTENT_ALPHA) { - _cairo_svg_surface_emit_alpha_filter (document); - _cairo_output_stream_printf (document->xml_node_defs, - "<g id=\"surface%d\" " - "clip-path=\"url(#clip%d)\" " - "filter=\"url(#alpha)\">\n", - source->base.unique_id, - svg_surface->base_clip); - } else { - _cairo_output_stream_printf (document->xml_node_defs, - "<g id=\"surface%d\" " - "clip-path=\"url(#clip%d)\">\n", - source->base.unique_id, - svg_surface->base_clip); - } - - contents = svg_surface->xml_node; - page_set = &svg_surface->page_set; - - if (_cairo_memory_stream_length (contents) > 0) { - if (unlikely (_cairo_svg_surface_store_page (svg_surface) == NULL)) { - cairo_surface_destroy (paginated_surface); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - } - - if (page_set->num_elements > 0) { - cairo_svg_page_t *page; - - page = _cairo_array_index (page_set, page_set->num_elements - 1); - _cairo_memory_stream_copy (page->xml_node, document->xml_node_defs); - } - - _cairo_output_stream_printf (document->xml_node_defs, "</g>\n"); - - status = cairo_surface_status (paginated_surface); - cairo_surface_destroy (paginated_surface); - - if (unlikely (status)) - return status; - - /* and tag it */ - return _cairo_user_data_array_set_data (&source->base.user_data, - (cairo_user_data_key_t *) document, - document, NULL); -} - -static cairo_recording_surface_t * -to_recording_surface (const cairo_surface_pattern_t *pattern) -{ - cairo_surface_t *surface = pattern->surface; - if (_cairo_surface_is_paginated (surface)) - surface = _cairo_paginated_surface_get_recording (surface); - if (_cairo_surface_is_snapshot (surface)) - surface = _cairo_surface_snapshot_get_target (surface); - return (cairo_recording_surface_t *) surface; -} - -static cairo_status_t -_cairo_svg_surface_emit_composite_recording_pattern (cairo_output_stream_t *output, - cairo_svg_surface_t *surface, - cairo_operator_t op, - cairo_surface_pattern_t *pattern, - int pattern_id, - const cairo_matrix_t *parent_matrix, - const char *extra_attributes) -{ - cairo_svg_document_t *document = surface->document; - cairo_recording_surface_t *recording_surface; - cairo_matrix_t p2u; - cairo_status_t status; - - p2u = pattern->base.matrix; - status = cairo_matrix_invert (&p2u); - /* cairo_pattern_set_matrix ensures the matrix is invertible */ - assert (status == CAIRO_STATUS_SUCCESS); - - recording_surface = to_recording_surface (pattern); - status = _cairo_svg_surface_emit_recording_surface (document, recording_surface); - if (unlikely (status)) - return status; - - if (pattern_id != invalid_pattern_id) { - _cairo_output_stream_printf (output, - "<pattern id=\"pattern%d\" " - "patternUnits=\"userSpaceOnUse\" " - "width=\"%d\" height=\"%d\"", - pattern_id, - recording_surface->extents.width, - recording_surface->extents.height); - _cairo_svg_surface_emit_transform (output, " patternTransform", &p2u, parent_matrix); - _cairo_output_stream_printf (output, ">\n"); - } - - _cairo_output_stream_printf (output, - "<use xlink:href=\"#surface%d\"", - recording_surface->base.unique_id); - - if (pattern_id == invalid_pattern_id) { - _cairo_svg_surface_emit_operator (output, surface, op); - _cairo_svg_surface_emit_transform (output, " transform", &p2u, parent_matrix); - } - - if (extra_attributes) - _cairo_output_stream_printf (output, " %s", extra_attributes); - - _cairo_output_stream_printf (output, "/>\n"); - - if (pattern_id != invalid_pattern_id) - _cairo_output_stream_printf (output, "</pattern>\n"); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_svg_surface_emit_composite_pattern (cairo_output_stream_t *output, - cairo_svg_surface_t *surface, - cairo_operator_t op, - cairo_surface_pattern_t *pattern, - int pattern_id, - const cairo_matrix_t *parent_matrix, - const char *extra_attributes) -{ - - if (pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING) { - return _cairo_svg_surface_emit_composite_recording_pattern (output, surface, - op, pattern, - pattern_id, - parent_matrix, - extra_attributes); - } - - return _cairo_svg_surface_emit_composite_surface_pattern (output, surface, - op, pattern, - pattern_id, - parent_matrix, - extra_attributes); -} - -static cairo_status_t -_cairo_svg_surface_emit_solid_pattern (cairo_svg_surface_t *surface, - cairo_solid_pattern_t *pattern, - cairo_output_stream_t *style, - cairo_bool_t is_stroke) -{ - _cairo_output_stream_printf (style, is_stroke ? - "stroke:rgb(%f%%,%f%%,%f%%);stroke-opacity:%f;": - "fill:rgb(%f%%,%f%%,%f%%);fill-opacity:%f;", - pattern->color.red * 100.0, - pattern->color.green * 100.0, - pattern->color.blue * 100.0, - pattern->color.alpha); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_svg_surface_emit_surface_pattern (cairo_svg_surface_t *surface, - cairo_surface_pattern_t *pattern, - cairo_output_stream_t *style, - cairo_bool_t is_stroke, - const cairo_matrix_t *parent_matrix) -{ - cairo_svg_document_t *document = surface->document; - cairo_status_t status; - int pattern_id; - - pattern_id = document->pattern_id++; - status = _cairo_svg_surface_emit_composite_pattern (document->xml_node_defs, - surface, CAIRO_OPERATOR_SOURCE, pattern, - pattern_id, parent_matrix, NULL); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (style, - "%s:url(#pattern%d);", - is_stroke ? "stroke" : "fill", - pattern_id); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_svg_surface_emit_pattern_stops (cairo_output_stream_t *output, - cairo_gradient_pattern_t const *pattern, - double start_offset, - cairo_bool_t reverse_stops, - cairo_bool_t emulate_reflect) -{ - cairo_gradient_stop_t *stops; - double offset; - unsigned int n_stops; - unsigned int i; - - if (pattern->n_stops < 1) - return CAIRO_STATUS_SUCCESS; - - if (pattern->n_stops == 1) { - _cairo_output_stream_printf (output, - "<stop offset=\"%f\" style=\"" - "stop-color:rgb(%f%%,%f%%,%f%%);" - "stop-opacity:%f;\"/>\n", - pattern->stops[0].offset, - pattern->stops[0].color.red * 100.0, - pattern->stops[0].color.green * 100.0, - pattern->stops[0].color.blue * 100.0, - pattern->stops[0].color.alpha); - return CAIRO_STATUS_SUCCESS; - } - - if (emulate_reflect || reverse_stops) { - n_stops = emulate_reflect ? pattern->n_stops * 2 - 2: pattern->n_stops; - stops = _cairo_malloc_ab (n_stops, sizeof (cairo_gradient_stop_t)); - if (unlikely (stops == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - for (i = 0; i < pattern->n_stops; i++) { - if (reverse_stops) { - stops[i] = pattern->stops[pattern->n_stops - i - 1]; - stops[i].offset = 1.0 - stops[i].offset; - } else - stops[i] = pattern->stops[i]; - if (emulate_reflect) { - stops[i].offset /= 2; - if (i > 0 && i < (pattern->n_stops - 1)) { - if (reverse_stops) { - stops[i + pattern->n_stops - 1] = pattern->stops[i]; - stops[i + pattern->n_stops - 1].offset = - 0.5 + 0.5 * stops[i + pattern->n_stops - 1].offset; - } else { - stops[i + pattern->n_stops - 1] = pattern->stops[pattern->n_stops - i - 1]; - stops[i + pattern->n_stops - 1].offset = - 1 - 0.5 * stops[i + pattern->n_stops - 1].offset; - } - } - } - } - } else { - n_stops = pattern->n_stops; - stops = pattern->stops; - } - - if (start_offset >= 0.0) - for (i = 0; i < n_stops; i++) { - offset = start_offset + (1 - start_offset ) * stops[i].offset; - _cairo_output_stream_printf (output, - "<stop offset=\"%f\" style=\"" - "stop-color:rgb(%f%%,%f%%,%f%%);" - "stop-opacity:%f;\"/>\n", - offset, - stops[i].color.red * 100.0, - stops[i].color.green * 100.0, - stops[i].color.blue * 100.0, - stops[i].color.alpha); - } - else { - cairo_bool_t found = FALSE; - unsigned int offset_index; - cairo_color_stop_t offset_color_start, offset_color_stop; - - for (i = 0; i < n_stops; i++) { - if (stops[i].offset >= -start_offset) { - if (i > 0) { - if (stops[i].offset != stops[i-1].offset) { - double x0, x1; - cairo_color_stop_t *color0, *color1; - - x0 = stops[i-1].offset; - x1 = stops[i].offset; - color0 = &stops[i-1].color; - color1 = &stops[i].color; - offset_color_start.red = color0->red + (color1->red - color0->red) - * (-start_offset - x0) / (x1 - x0); - offset_color_start.green = color0->green + (color1->green - color0->green) - * (-start_offset - x0) / (x1 - x0); - offset_color_start.blue = color0->blue + (color1->blue - color0->blue) - * (-start_offset - x0) / (x1 - x0); - offset_color_start.alpha = color0->alpha + (color1->alpha - color0->alpha) - * (-start_offset - x0) / (x1 - x0); - offset_color_stop = offset_color_start; - } else { - offset_color_stop = stops[i-1].color; - offset_color_start = stops[i].color; - } - } else - offset_color_stop = offset_color_start = stops[i].color; - offset_index = i; - found = TRUE; - break; - } - } - - if (!found) { - offset_index = n_stops - 1; - offset_color_stop = offset_color_start = stops[offset_index].color; - } - - _cairo_output_stream_printf (output, - "<stop offset=\"0\" style=\"" - "stop-color:rgb(%f%%,%f%%,%f%%);" - "stop-opacity:%f;\"/>\n", - offset_color_start.red * 100.0, - offset_color_start.green * 100.0, - offset_color_start.blue * 100.0, - offset_color_start.alpha); - for (i = offset_index; i < n_stops; i++) { - _cairo_output_stream_printf (output, - "<stop offset=\"%f\" style=\"" - "stop-color:rgb(%f%%,%f%%,%f%%);" - "stop-opacity:%f;\"/>\n", - stops[i].offset + start_offset, - stops[i].color.red * 100.0, - stops[i].color.green * 100.0, - stops[i].color.blue * 100.0, - stops[i].color.alpha); - } - for (i = 0; i < offset_index; i++) { - _cairo_output_stream_printf (output, - "<stop offset=\"%f\" style=\"" - "stop-color:rgb(%f%%,%f%%,%f%%);" - "stop-opacity:%f;\"/>\n", - 1.0 + stops[i].offset + start_offset, - stops[i].color.red * 100.0, - stops[i].color.green * 100.0, - stops[i].color.blue * 100.0, - stops[i].color.alpha); - } - - _cairo_output_stream_printf (output, - "<stop offset=\"1\" style=\"" - "stop-color:rgb(%f%%,%f%%,%f%%);" - "stop-opacity:%f;\"/>\n", - offset_color_stop.red * 100.0, - offset_color_stop.green * 100.0, - offset_color_stop.blue * 100.0, - offset_color_stop.alpha); - - } - - if (reverse_stops || emulate_reflect) - free (stops); - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_svg_surface_emit_pattern_extend (cairo_output_stream_t *output, - cairo_pattern_t *pattern) -{ - switch (pattern->extend) { - case CAIRO_EXTEND_REPEAT: - _cairo_output_stream_printf (output, "spreadMethod=\"repeat\" "); - break; - case CAIRO_EXTEND_REFLECT: - _cairo_output_stream_printf (output, "spreadMethod=\"reflect\" "); - break; - case CAIRO_EXTEND_NONE: - case CAIRO_EXTEND_PAD: - break; - } -} - -static cairo_status_t -_cairo_svg_surface_emit_linear_pattern (cairo_svg_surface_t *surface, - cairo_linear_pattern_t *pattern, - cairo_output_stream_t *style, - cairo_bool_t is_stroke, - const cairo_matrix_t *parent_matrix) -{ - cairo_svg_document_t *document = surface->document; - cairo_matrix_t p2u; - cairo_status_t status; - - p2u = pattern->base.base.matrix; - status = cairo_matrix_invert (&p2u); - /* cairo_pattern_set_matrix ensures the matrix is invertible */ - assert (status == CAIRO_STATUS_SUCCESS); - - _cairo_output_stream_printf (document->xml_node_defs, - "<linearGradient id=\"linear%d\" " - "gradientUnits=\"userSpaceOnUse\" " - "x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" ", - document->linear_pattern_id, - pattern->pd1.x, pattern->pd1.y, - pattern->pd2.x, pattern->pd2.y); - - _cairo_svg_surface_emit_pattern_extend (document->xml_node_defs, &pattern->base.base), - _cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", &p2u, parent_matrix); - _cairo_output_stream_printf (document->xml_node_defs, ">\n"); - - status = _cairo_svg_surface_emit_pattern_stops (document->xml_node_defs, - &pattern->base, 0.0, - FALSE, FALSE); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (document->xml_node_defs, - "</linearGradient>\n"); - - _cairo_output_stream_printf (style, - "%s:url(#linear%d);", - is_stroke ? "stroke" : "fill", - document->linear_pattern_id); - - document->linear_pattern_id++; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_svg_surface_emit_radial_pattern (cairo_svg_surface_t *surface, - cairo_radial_pattern_t *pattern, - cairo_output_stream_t *style, - cairo_bool_t is_stroke, - const cairo_matrix_t *parent_matrix) -{ - cairo_svg_document_t *document = surface->document; - cairo_matrix_t p2u; - cairo_extend_t extend; - double x0, y0, x1, y1, r0, r1; - double fx, fy; - cairo_bool_t reverse_stops; - cairo_status_t status; - cairo_circle_double_t *c0, *c1; - - extend = pattern->base.base.extend; - - if (pattern->cd1.radius < pattern->cd2.radius) { - c0 = &pattern->cd1; - c1 = &pattern->cd2; - reverse_stops = FALSE; - } else { - c0 = &pattern->cd2; - c1 = &pattern->cd1; - reverse_stops = TRUE; - } - - x0 = c0->center.x; - y0 = c0->center.y; - r0 = c0->radius; - x1 = c1->center.x; - y1 = c1->center.y; - r1 = c1->radius; - - p2u = pattern->base.base.matrix; - status = cairo_matrix_invert (&p2u); - /* cairo_pattern_set_matrix ensures the matrix is invertible */ - assert (status == CAIRO_STATUS_SUCCESS); - - if (r0 == r1) { - unsigned int n_stops = pattern->base.n_stops; - - _cairo_output_stream_printf (document->xml_node_defs, - "<radialGradient id=\"radial%d\" " - "gradientUnits=\"userSpaceOnUse\" " - "cx=\"%f\" cy=\"%f\" " - "fx=\"%f\" fy=\"%f\" r=\"%f\" ", - document->radial_pattern_id, - x1, y1, - x1, y1, r1); - _cairo_svg_surface_emit_transform (document->xml_node_defs, - "gradientTransform", - &p2u, parent_matrix); - _cairo_output_stream_printf (document->xml_node_defs, ">\n"); - - if (extend == CAIRO_EXTEND_NONE || n_stops < 1) - _cairo_output_stream_printf (document->xml_node_defs, - "<stop offset=\"0\" style=\"" - "stop-color:rgb(0%%,0%%,0%%);" - "stop-opacity:0;\"/>\n"); - else { - _cairo_output_stream_printf (document->xml_node_defs, - "<stop offset=\"0\" style=\"" - "stop-color:rgb(%f%%,%f%%,%f%%);" - "stop-opacity %f;\"/>\n", - pattern->base.stops[0].color.red * 100.0, - pattern->base.stops[0].color.green * 100.0, - pattern->base.stops[0].color.blue * 100.0, - pattern->base.stops[0].color.alpha); - if (n_stops > 1) - _cairo_output_stream_printf (document->xml_node_defs, - "<stop offset=\"0\" style=\"" - "stop-color:rgb(%f%%,%f%%,%f%%);" - "stop-opacity:%f;\"/>\n", - pattern->base.stops[n_stops - 1].color.red * 100.0, - pattern->base.stops[n_stops - 1].color.green * 100.0, - pattern->base.stops[n_stops - 1].color.blue * 100.0, - pattern->base.stops[n_stops - 1].color.alpha); - } - - } else { - double offset, r, x, y; - cairo_bool_t emulate_reflect = FALSE; - - fx = (r1 * x0 - r0 * x1) / (r1 - r0); - fy = (r1 * y0 - r0 * y1) / (r1 - r0); - - /* SVG doesn't support the inner circle and use instead a gradient focal. - * That means we need to emulate the cairo behaviour by processing the - * cairo gradient stops. - * The CAIRO_EXTENT_NONE and CAIRO_EXTENT_PAD modes are quite easy to handle, - * it's just a matter of stop position translation and calculation of - * the corresponding SVG radial gradient focal. - * The CAIRO_EXTENT_REFLECT and CAIRO_EXTEND_REPEAT modes require to compute a new - * radial gradient, with an new outer circle, equal to r1 - r0 in the CAIRO_EXTEND_REPEAT - * case, and 2 * (r1 - r0) in the CAIRO_EXTENT_REFLECT case, and a new gradient stop - * list that maps to the original cairo stop list. - */ - if ((extend == CAIRO_EXTEND_REFLECT - || extend == CAIRO_EXTEND_REPEAT) - && r0 > 0.0) { - double r_org = r1; - - if (extend == CAIRO_EXTEND_REFLECT) { - r1 = 2 * r1 - r0; - emulate_reflect = TRUE; - } - - offset = fmod (r1, r1 - r0) / (r1 - r0) - 1.0; - r = r1 - r0; - - /* New position of outer circle. */ - x = r * (x1 - fx) / r_org + fx; - y = r * (y1 - fy) / r_org + fy; - - x1 = x; - y1 = y; - r1 = r; - r0 = 0.0; - } else { - offset = r0 / r1; - } - - _cairo_output_stream_printf (document->xml_node_defs, - "<radialGradient id=\"radial%d\" " - "gradientUnits=\"userSpaceOnUse\" " - "cx=\"%f\" cy=\"%f\" " - "fx=\"%f\" fy=\"%f\" r=\"%f\" ", - document->radial_pattern_id, - x1, y1, - fx, fy, r1); - - if (emulate_reflect) - _cairo_output_stream_printf (document->xml_node_defs, "spreadMethod=\"repeat\" "); - else - _cairo_svg_surface_emit_pattern_extend (document->xml_node_defs, &pattern->base.base); - _cairo_svg_surface_emit_transform (document->xml_node_defs, "gradientTransform", &p2u, parent_matrix); - _cairo_output_stream_printf (document->xml_node_defs, ">\n"); - - /* To support cairo's EXTEND_NONE, (for which SVG has no similar - * notion), we add transparent color stops on either end of the - * user-provided stops. */ - if (extend == CAIRO_EXTEND_NONE) { - _cairo_output_stream_printf (document->xml_node_defs, - "<stop offset=\"0\" style=\"" - "stop-color:rgb(0%%,0%%,0%%);" - "stop-opacity:0;\"/>\n"); - if (r0 != 0.0) - _cairo_output_stream_printf (document->xml_node_defs, - "<stop offset=\"%f\" style=\"" - "stop-color:rgb(0%%,0%%,0%%);" - "stop-opacity:0;\"/>\n", - r0 / r1); - } - status = _cairo_svg_surface_emit_pattern_stops (document->xml_node_defs, - &pattern->base, offset, - reverse_stops, - emulate_reflect); - if (unlikely (status)) - return status; - - if (pattern->base.base.extend == CAIRO_EXTEND_NONE) - _cairo_output_stream_printf (document->xml_node_defs, - "<stop offset=\"1.0\" style=\"" - "stop-color:rgb(0%%,0%%,0%%);" - "stop-opacity:0;\"/>\n"); - } - - _cairo_output_stream_printf (document->xml_node_defs, - "</radialGradient>\n"); - - _cairo_output_stream_printf (style, - "%s:url(#radial%d);", - is_stroke ? "stroke" : "fill", - document->radial_pattern_id); - - document->radial_pattern_id++; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_svg_surface_emit_pattern (cairo_svg_surface_t *surface, - const cairo_pattern_t *pattern, - cairo_output_stream_t *output, - cairo_bool_t is_stroke, - const cairo_matrix_t *parent_matrix) -{ - switch (pattern->type) { - case CAIRO_PATTERN_TYPE_SOLID: - return _cairo_svg_surface_emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern, - output, is_stroke); - - case CAIRO_PATTERN_TYPE_SURFACE: - return _cairo_svg_surface_emit_surface_pattern (surface, (cairo_surface_pattern_t *) pattern, - output, is_stroke, parent_matrix); - - case CAIRO_PATTERN_TYPE_LINEAR: - return _cairo_svg_surface_emit_linear_pattern (surface, (cairo_linear_pattern_t *) pattern, - output, is_stroke, parent_matrix); - - case CAIRO_PATTERN_TYPE_RADIAL: - return _cairo_svg_surface_emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern, - output, is_stroke, parent_matrix); - - case CAIRO_PATTERN_TYPE_MESH: - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - ASSERT_NOT_REACHED; - } - return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH); -} - -static cairo_status_t -_cairo_svg_surface_emit_fill_style (cairo_output_stream_t *output, - cairo_svg_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_fill_rule_t fill_rule, - const cairo_matrix_t *parent_matrix) -{ - _cairo_output_stream_printf (output, - "fill-rule:%s;", - fill_rule == CAIRO_FILL_RULE_EVEN_ODD ? - "evenodd" : "nonzero"); - _cairo_svg_surface_emit_operator_for_style (output, surface, op); - return _cairo_svg_surface_emit_pattern (surface, source, output, FALSE, parent_matrix); -} - -static cairo_status_t -_cairo_svg_surface_emit_stroke_style (cairo_output_stream_t *output, - cairo_svg_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *parent_matrix) -{ - cairo_status_t status; - const char *line_cap, *line_join; - unsigned int i; - - switch (stroke_style->line_cap) { - case CAIRO_LINE_CAP_BUTT: - line_cap = "butt"; - break; - case CAIRO_LINE_CAP_ROUND: - line_cap = "round"; - break; - case CAIRO_LINE_CAP_SQUARE: - line_cap = "square"; - break; - default: - ASSERT_NOT_REACHED; - } - - switch (stroke_style->line_join) { - case CAIRO_LINE_JOIN_MITER: - line_join = "miter"; - break; - case CAIRO_LINE_JOIN_ROUND: - line_join = "round"; - break; - case CAIRO_LINE_JOIN_BEVEL: - line_join = "bevel"; - break; - default: - ASSERT_NOT_REACHED; - } - - _cairo_output_stream_printf (output, - "stroke-width:%f;" - "stroke-linecap:%s;" - "stroke-linejoin:%s;", - stroke_style->line_width, - line_cap, - line_join); - - status = _cairo_svg_surface_emit_pattern (surface, source, output, TRUE, parent_matrix); - if (unlikely (status)) - return status; - - _cairo_svg_surface_emit_operator_for_style (output, surface, op); - - if (stroke_style->num_dashes > 0) { - _cairo_output_stream_printf (output, "stroke-dasharray:"); - for (i = 0; i < stroke_style->num_dashes; i++) { - _cairo_output_stream_printf (output, "%f", - stroke_style->dash[i]); - if (i + 1 < stroke_style->num_dashes) - _cairo_output_stream_printf (output, ","); - else - _cairo_output_stream_printf (output, ";"); - } - if (stroke_style->dash_offset != 0.0) { - _cairo_output_stream_printf (output, - "stroke-dashoffset:%f;", - stroke_style->dash_offset); - } - } - - _cairo_output_stream_printf (output, - "stroke-miterlimit:%f;", - stroke_style->miter_limit); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_svg_surface_fill_stroke (void *abstract_surface, - cairo_operator_t fill_op, - const cairo_pattern_t *fill_source, - cairo_fill_rule_t fill_rule, - double fill_tolerance, - cairo_antialias_t fill_antialias, - const cairo_path_fixed_t*path, - cairo_operator_t stroke_op, - const cairo_pattern_t *stroke_source, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *stroke_ctm, - const cairo_matrix_t *stroke_ctm_inverse, - double stroke_tolerance, - cairo_antialias_t stroke_antialias, - const cairo_clip_t *clip) -{ - cairo_svg_surface_t *surface = abstract_surface; - cairo_status_t status; - - status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->xml_node, "<path style=\""); - status = _cairo_svg_surface_emit_fill_style (surface->xml_node, surface, fill_op, - fill_source, fill_rule, stroke_ctm_inverse); - if (unlikely (status)) - return status; - - status = _cairo_svg_surface_emit_stroke_style (surface->xml_node, surface, stroke_op, - stroke_source, stroke_style, stroke_ctm_inverse); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->xml_node, "\" "); - - _cairo_svg_surface_emit_path (surface->xml_node, path, stroke_ctm_inverse); - - _cairo_svg_surface_emit_transform (surface->xml_node, " transform", stroke_ctm, NULL); - _cairo_output_stream_printf (surface->xml_node, "/>\n"); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_svg_surface_fill (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t*path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_svg_surface_t *surface = abstract_surface; - cairo_status_t status; - - if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) - return _cairo_svg_surface_analyze_operation (surface, op, source); - - assert (_cairo_svg_surface_operation_supported (surface, op, source)); - - status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->xml_node, "<path style=\" stroke:none;"); - status = _cairo_svg_surface_emit_fill_style (surface->xml_node, surface, op, source, fill_rule, NULL); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->xml_node, "\" "); - - _cairo_svg_surface_emit_path (surface->xml_node, path, NULL); - - _cairo_output_stream_printf (surface->xml_node, "/>\n"); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_bool_t -_cairo_svg_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *rectangle) -{ - cairo_svg_surface_t *surface = abstract_surface; - - rectangle->x = 0; - rectangle->y = 0; - - /* XXX: The conversion to integers here is pretty bogus, (not to - * mention the arbitrary limitation of width to a short(!). We - * may need to come up with a better interface for get_size. - */ - rectangle->width = ceil (surface->width); - rectangle->height = ceil (surface->height); - - return TRUE; -} - -static cairo_status_t -_cairo_svg_surface_emit_paint (cairo_output_stream_t *output, - cairo_svg_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask_source, - const char *extra_attributes) -{ - cairo_status_t status; - - if (source->type == CAIRO_PATTERN_TYPE_SURFACE && - source->extend == CAIRO_EXTEND_NONE) - return _cairo_svg_surface_emit_composite_pattern (output, - surface, - op, - (cairo_surface_pattern_t *) source, - invalid_pattern_id, - mask_source ? &mask_source->matrix :NULL, - extra_attributes); - - _cairo_output_stream_printf (output, - "<rect x=\"0\" y=\"0\" " - "width=\"%f\" height=\"%f\" " - "style=\"", - surface->width, surface->height); - _cairo_svg_surface_emit_operator_for_style (output, surface, op); - status = _cairo_svg_surface_emit_pattern (surface, source, output, FALSE, NULL); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (output, "stroke:none;\""); - - if (extra_attributes) - _cairo_output_stream_printf (output, " %s", extra_attributes); - - _cairo_output_stream_printf (output, "/>\n"); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_svg_surface_paint (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - cairo_status_t status; - cairo_svg_surface_t *surface = abstract_surface; - - /* Emulation of clear and source operators, when no clipping region - * is defined. We just delete existing content of surface root node, - * and exit early if operator is clear. - */ - if ((op == CAIRO_OPERATOR_CLEAR || op == CAIRO_OPERATOR_SOURCE) && - clip == NULL) - { - switch (surface->paginated_mode) { - case CAIRO_PAGINATED_MODE_FALLBACK: - ASSERT_NOT_REACHED; - case CAIRO_PAGINATED_MODE_ANALYZE: - return CAIRO_STATUS_SUCCESS; - - case CAIRO_PAGINATED_MODE_RENDER: - status = _cairo_output_stream_destroy (surface->xml_node); - if (unlikely (status)) { - surface->xml_node = NULL; - return status; - } - - surface->xml_node = _cairo_memory_stream_create (); - if (_cairo_output_stream_get_status (surface->xml_node)) { - status = _cairo_output_stream_destroy (surface->xml_node); - surface->xml_node = NULL; - return status; - } - - if (op == CAIRO_OPERATOR_CLEAR) { - if (surface->content == CAIRO_CONTENT_COLOR) { - _cairo_output_stream_printf (surface->xml_node, - "<rect " - "width=\"%f\" height=\"%f\" " - "style=\"opacity:1;" - "stroke:none;" - "fill:rgb(0,0,0);\"/>\n", - surface->width, surface->height); - } - return CAIRO_STATUS_SUCCESS; - } - break; - } - } else { - if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) - return _cairo_svg_surface_analyze_operation (surface, op, source); - - assert (_cairo_svg_surface_operation_supported (surface, op, source)); - } - - status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); - if (unlikely (status)) - return status; - - return _cairo_svg_surface_emit_paint (surface->xml_node, - surface, op, source, 0, NULL); -} - -static cairo_int_status_t -_cairo_svg_surface_mask (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - cairo_status_t status; - cairo_svg_surface_t *surface = abstract_surface; - cairo_svg_document_t *document = surface->document; - cairo_output_stream_t *mask_stream; - char buffer[64]; - cairo_bool_t discard_filter = FALSE; - unsigned int mask_id; - - if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) { - cairo_status_t source_status, mask_status; - - source_status = _cairo_svg_surface_analyze_operation (surface, op, source); - if (_cairo_status_is_error (source_status)) - return source_status; - - if (mask->has_component_alpha) { - mask_status = CAIRO_INT_STATUS_UNSUPPORTED; - } else { - mask_status = _cairo_svg_surface_analyze_operation (surface, op, mask); - if (_cairo_status_is_error (mask_status)) - return mask_status; - } - - return _cairo_analysis_surface_merge_status (source_status, - mask_status); - } - - assert (_cairo_svg_surface_operation_supported (surface, op, source)); - assert (_cairo_svg_surface_operation_supported (surface, CAIRO_OPERATOR_OVER, mask)); - - status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); - if (unlikely (status)) - return status; - - if (mask->type == CAIRO_PATTERN_TYPE_SURFACE) { - const cairo_surface_pattern_t *surface_pattern = (const cairo_surface_pattern_t*) mask; - cairo_content_t content = surface_pattern->surface->content; - if (content == CAIRO_CONTENT_ALPHA) - discard_filter = TRUE; - } - - if (!discard_filter) - _cairo_svg_surface_emit_alpha_filter (document); - - /* _cairo_svg_surface_emit_paint() will output a pattern definition to - * document->xml_node_defs so we need to write the mask element to - * a temporary stream and then copy that to xml_node_defs. */ - mask_stream = _cairo_memory_stream_create (); - if (_cairo_output_stream_get_status (mask_stream)) - return _cairo_output_stream_destroy (mask_stream); - - mask_id = _cairo_svg_document_allocate_mask_id (document); - - _cairo_output_stream_printf (mask_stream, - "<mask id=\"mask%d\">\n" - "%s", - mask_id, - discard_filter ? "" : " <g filter=\"url(#alpha)\">\n"); - status = _cairo_svg_surface_emit_paint (mask_stream, surface, CAIRO_OPERATOR_OVER, mask, source, NULL); - if (unlikely (status)) { - cairo_status_t ignore = _cairo_output_stream_destroy (mask_stream); - return status; - (void) ignore; - } - - _cairo_output_stream_printf (mask_stream, - "%s" - "</mask>\n", - discard_filter ? "" : " </g>\n"); - _cairo_memory_stream_copy (mask_stream, document->xml_node_defs); - - status = _cairo_output_stream_destroy (mask_stream); - if (unlikely (status)) - return status; - - snprintf (buffer, sizeof buffer, "mask=\"url(#mask%d)\"", - mask_id); - status = _cairo_svg_surface_emit_paint (surface->xml_node, surface, op, source, 0, buffer); - if (unlikely (status)) - return status; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_svg_surface_stroke (void *abstract_dst, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t*path, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_svg_surface_t *surface = abstract_dst; - cairo_status_t status; - - if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) - return _cairo_svg_surface_analyze_operation (surface, op, source); - - assert (_cairo_svg_surface_operation_supported (surface, op, source)); - - status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->xml_node, "<path style=\"fill:none;"); - status = _cairo_svg_surface_emit_stroke_style (surface->xml_node, surface, op, - source, stroke_style, ctm_inverse); - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->xml_node, "\" "); - - _cairo_svg_surface_emit_path (surface->xml_node, path, ctm_inverse); - - _cairo_svg_surface_emit_transform (surface->xml_node, " transform", ctm, NULL); - _cairo_output_stream_printf (surface->xml_node, "/>\n"); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_svg_surface_show_glyphs (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *pattern, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - cairo_svg_surface_t *surface = abstract_surface; - cairo_svg_document_t *document = surface->document; - cairo_path_fixed_t path; - cairo_int_status_t status; - cairo_scaled_font_subsets_glyph_t subset_glyph; - int i; - - if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) - return _cairo_svg_surface_analyze_operation (surface, op, pattern); - - assert (_cairo_svg_surface_operation_supported (surface, op, pattern)); - - if (num_glyphs <= 0) - return CAIRO_STATUS_SUCCESS; - - status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); - if (unlikely (status)) - return status; - - /* FIXME it's probably possible to apply a pattern of a gradient to - * a group of symbols, but I don't know how yet. Gradients or patterns - * are translated by x and y properties of use element. */ - if (pattern->type != CAIRO_PATTERN_TYPE_SOLID) - goto FALLBACK; - - _cairo_output_stream_printf (surface->xml_node, "<g style=\""); - status = _cairo_svg_surface_emit_pattern (surface, pattern, - surface->xml_node, FALSE, NULL); - if (unlikely (status)) - return status; - - _cairo_svg_surface_emit_operator_for_style (surface->xml_node, surface, op); - - _cairo_output_stream_printf (surface->xml_node, "\">\n"); - - for (i = 0; i < num_glyphs; i++) { - status = _cairo_scaled_font_subsets_map_glyph (document->font_subsets, - scaled_font, glyphs[i].index, - NULL, 0, - &subset_glyph); - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - _cairo_output_stream_printf (surface->xml_node, "</g>\n"); - - glyphs += i; - num_glyphs -= i; - goto FALLBACK; - } - - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->xml_node, - " <use xlink:href=\"#glyph%d-%d\" " - "x=\"%f\" y=\"%f\"/>\n", - subset_glyph.font_id, - subset_glyph.subset_glyph_index, - glyphs[i].x, glyphs[i].y); - } - - _cairo_output_stream_printf (surface->xml_node, "</g>\n"); - - return CAIRO_STATUS_SUCCESS; - -FALLBACK: - _cairo_path_fixed_init (&path); - - status = _cairo_scaled_font_glyph_path (scaled_font, - (cairo_glyph_t *) glyphs, - num_glyphs, &path); - - if (unlikely (status)) { - _cairo_path_fixed_fini (&path); - return status; - } - - status = _cairo_svg_surface_fill (abstract_surface, op, pattern, - &path, CAIRO_FILL_RULE_WINDING, - 0.0, CAIRO_ANTIALIAS_SUBPIXEL, - clip); - - _cairo_path_fixed_fini (&path); - - return status; -} - -static void -_cairo_svg_surface_get_font_options (void *abstract_surface, - cairo_font_options_t *options) -{ - _cairo_font_options_init_default (options); - - cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_NONE); - cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF); - cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_GRAY); - _cairo_font_options_set_round_glyph_positions (options, CAIRO_ROUND_GLYPH_POS_OFF); -} - - -static const char ** -_cairo_svg_surface_get_supported_mime_types (void *abstract_surface) -{ - return _cairo_svg_supported_mime_types; -} - -static const cairo_surface_backend_t cairo_svg_surface_backend = { - CAIRO_SURFACE_TYPE_SVG, - _cairo_svg_surface_finish, - - _cairo_default_context_create, - - NULL, /* create_similar: handled by wrapper */ - NULL, /* create_similar_image */ - NULL, /* map to image */ - NULL, /* unmap image */ - - _cairo_surface_default_source, - NULL, /* acquire_source_image */ - NULL, /* release_source_image */ - NULL, /* snapshot */ - - _cairo_svg_surface_copy_page, - _cairo_svg_surface_show_page, - - _cairo_svg_surface_get_extents, - _cairo_svg_surface_get_font_options, - - NULL, /* flush */ - NULL, /* mark dirty rectangle */ - - _cairo_svg_surface_paint, - _cairo_svg_surface_mask, - _cairo_svg_surface_stroke, - _cairo_svg_surface_fill, - _cairo_svg_surface_fill_stroke, - _cairo_svg_surface_show_glyphs, - NULL, /* has_show_text_glyphs */ - NULL, /* show_text_glyphs */ - _cairo_svg_surface_get_supported_mime_types, -}; - -static cairo_status_t -_cairo_svg_document_create (cairo_output_stream_t *output_stream, - double width, - double height, - cairo_svg_version_t version, - cairo_svg_document_t **document_out) -{ - cairo_svg_document_t *document; - cairo_status_t status, status_ignored; - - if (output_stream->status) - return output_stream->status; - - document = malloc (sizeof (cairo_svg_document_t)); - if (unlikely (document == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - /* The use of defs for font glyphs imposes no per-subset limit. */ - document->font_subsets = _cairo_scaled_font_subsets_create_scaled (); - if (unlikely (document->font_subsets == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto CLEANUP_DOCUMENT; - } - - document->output_stream = output_stream; - document->refcount = 1; - document->owner = NULL; - document->finished = FALSE; - document->width = width; - document->height = height; - - document->linear_pattern_id = 0; - document->radial_pattern_id = 0; - document->pattern_id = 0; - document->filter_id = 0; - document->clip_id = 0; - document->mask_id = 0; - - document->xml_node_defs = _cairo_memory_stream_create (); - status = _cairo_output_stream_get_status (document->xml_node_defs); - if (unlikely (status)) - goto CLEANUP_NODE_DEFS; - - document->xml_node_glyphs = _cairo_memory_stream_create (); - status = _cairo_output_stream_get_status (document->xml_node_glyphs); - if (unlikely (status)) - goto CLEANUP_NODE_GLYPHS; - - document->alpha_filter = FALSE; - - document->svg_version = version; - - *document_out = document; - return CAIRO_STATUS_SUCCESS; - - CLEANUP_NODE_GLYPHS: - status_ignored = _cairo_output_stream_destroy (document->xml_node_glyphs); - CLEANUP_NODE_DEFS: - status_ignored = _cairo_output_stream_destroy (document->xml_node_defs); - _cairo_scaled_font_subsets_destroy (document->font_subsets); - CLEANUP_DOCUMENT: - free (document); - return status; -} - -static cairo_svg_document_t * -_cairo_svg_document_reference (cairo_svg_document_t *document) -{ - document->refcount++; - - return document; -} - -static unsigned int -_cairo_svg_document_allocate_mask_id (cairo_svg_document_t *document) -{ - return document->mask_id++; -} - -static cairo_status_t -_cairo_svg_document_destroy (cairo_svg_document_t *document) -{ - cairo_status_t status; - - document->refcount--; - if (document->refcount > 0) - return CAIRO_STATUS_SUCCESS; - - status = _cairo_svg_document_finish (document); - - free (document); - - return status; -} - -static cairo_status_t -_cairo_svg_document_finish (cairo_svg_document_t *document) -{ - cairo_status_t status, status2; - cairo_output_stream_t *output = document->output_stream; - cairo_svg_page_t *page; - unsigned int i; - - if (document->finished) - return CAIRO_STATUS_SUCCESS; - - /* - * Should we add DOCTYPE? - * - * Google says no. - * - * http://tech.groups.yahoo.com/group/svg-developers/message/48562: - * There's a bunch of issues, but just to pick a few: - * - they'll give false positives. - * - they'll give false negatives. - * - they're namespace-unaware. - * - they don't wildcard. - * So when they say OK they really haven't checked anything, when - * they say NOT OK they might be on crack, and like all - * namespace-unaware things they're a dead branch of the XML tree. - * - * http://jwatt.org/svg/authoring/: - * Unfortunately the SVG DTDs are a source of so many issues that the - * SVG WG has decided not to write one for the upcoming SVG 1.2 - * standard. In fact SVG WG members are even telling people not to use - * a DOCTYPE declaration in SVG 1.0 and 1.1 documents. - */ - - _cairo_output_stream_printf (output, - "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - "<svg xmlns=\"http://www.w3.org/2000/svg\" " - "xmlns:xlink=\"http://www.w3.org/1999/xlink\" " - "width=\"%fpt\" height=\"%fpt\" " - "viewBox=\"0 0 %f %f\" version=\"%s\">\n", - document->width, document->height, - document->width, document->height, - _cairo_svg_internal_version_strings [document->svg_version]); - - status = _cairo_svg_document_emit_font_subsets (document); - - if (_cairo_memory_stream_length (document->xml_node_glyphs) > 0 || - _cairo_memory_stream_length (document->xml_node_defs) > 0) { - _cairo_output_stream_printf (output, "<defs>\n"); - if (_cairo_memory_stream_length (document->xml_node_glyphs) > 0) { - _cairo_output_stream_printf (output, "<g>\n"); - _cairo_memory_stream_copy (document->xml_node_glyphs, output); - _cairo_output_stream_printf (output, "</g>\n"); - } - _cairo_memory_stream_copy (document->xml_node_defs, output); - _cairo_output_stream_printf (output, "</defs>\n"); - } - - if (document->owner != NULL) { - cairo_svg_surface_t *surface; - - surface = (cairo_svg_surface_t *) _cairo_paginated_surface_get_target (document->owner); - if (surface->xml_node != NULL && - _cairo_memory_stream_length (surface->xml_node) > 0) { - if (unlikely (_cairo_svg_surface_store_page (surface) == NULL)) { - if (status == CAIRO_STATUS_SUCCESS) - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - } - - if (surface->page_set.num_elements > 1 && - _cairo_svg_version_has_page_set_support (document->svg_version)) { - _cairo_output_stream_printf (output, "<pageSet>\n"); - for (i = 0; i < surface->page_set.num_elements; i++) { - page = _cairo_array_index (&surface->page_set, i); - _cairo_output_stream_printf (output, "<page>\n"); - _cairo_output_stream_printf (output, - "<g id=\"surface%d\">\n", - page->surface_id); - _cairo_memory_stream_copy (page->xml_node, output); - _cairo_output_stream_printf (output, "</g>\n</page>\n"); - } - _cairo_output_stream_printf (output, "</pageSet>\n"); - } else if (surface->page_set.num_elements > 0) { - page = _cairo_array_index (&surface->page_set, surface->page_set.num_elements - 1); - _cairo_output_stream_printf (output, - "<g id=\"surface%d\">\n", - page->surface_id); - _cairo_memory_stream_copy (page->xml_node, output); - _cairo_output_stream_printf (output, "</g>\n"); - } - } - - _cairo_output_stream_printf (output, "</svg>\n"); - - status2 = _cairo_output_stream_destroy (document->xml_node_glyphs); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - - status2 = _cairo_output_stream_destroy (document->xml_node_defs); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - - status2 = _cairo_output_stream_destroy (output); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - - document->finished = TRUE; - - return status; -} - -static void -_cairo_svg_surface_set_paginated_mode (void *abstract_surface, - cairo_paginated_mode_t paginated_mode) -{ - cairo_svg_surface_t *surface = abstract_surface; - - surface->paginated_mode = paginated_mode; -} - -static cairo_bool_t -_cairo_svg_surface_supports_fine_grained_fallbacks (void *abstract_surface) -{ - cairo_svg_surface_t *surface = abstract_surface; - cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED; - - if (surface->document->svg_version >= CAIRO_SVG_VERSION_1_2) { - status = _cairo_svg_surface_analyze_operator (surface, - CAIRO_OPERATOR_SOURCE); - } - - return status == CAIRO_INT_STATUS_SUCCESS; -} - -static const cairo_paginated_surface_backend_t cairo_svg_surface_paginated_backend = { - NULL /*_cairo_svg_surface_start_page*/, - _cairo_svg_surface_set_paginated_mode, - NULL, /* _cairo_svg_surface_set_bounding_box */ - NULL, /* _cairo_svg_surface_set_fallback_images_required */ - _cairo_svg_surface_supports_fine_grained_fallbacks, - -}; diff --git a/source/libs/cairo/cairo-src/src/cairo-svg.h b/source/libs/cairo/cairo-src/src/cairo-svg.h deleted file mode 100644 index 592c645f6270c689b467acfb1a44ed528baf73ba..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-svg.h +++ /dev/null @@ -1,84 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * cairo-svg.h - * - * Copyright © 2005 Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.fr> - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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. - * - */ - -#ifndef CAIRO_SVG_H -#define CAIRO_SVG_H - -#include "cairo.h" - -#if CAIRO_HAS_SVG_SURFACE - -CAIRO_BEGIN_DECLS - -/** - * cairo_svg_version_t: - * @CAIRO_SVG_VERSION_1_1: The version 1.1 of the SVG specification. (Since 1.2) - * @CAIRO_SVG_VERSION_1_2: The version 1.2 of the SVG specification. (Since 1.2) - * - * #cairo_svg_version_t is used to describe the version number of the SVG - * specification that a generated SVG file will conform to. - * - * Since: 1.2 - **/ -typedef enum _cairo_svg_version { - CAIRO_SVG_VERSION_1_1, - CAIRO_SVG_VERSION_1_2 -} cairo_svg_version_t; - -cairo_public cairo_surface_t * -cairo_svg_surface_create (const char *filename, - double width_in_points, - double height_in_points); - -cairo_public cairo_surface_t * -cairo_svg_surface_create_for_stream (cairo_write_func_t write_func, - void *closure, - double width_in_points, - double height_in_points); - -cairo_public void -cairo_svg_surface_restrict_to_version (cairo_surface_t *surface, - cairo_svg_version_t version); - -cairo_public void -cairo_svg_get_versions (cairo_svg_version_t const **versions, - int *num_versions); - -cairo_public const char * -cairo_svg_version_to_string (cairo_svg_version_t version); - -CAIRO_END_DECLS - -#else /* CAIRO_HAS_SVG_SURFACE */ -# error Cairo was not compiled with support for the svg backend -#endif /* CAIRO_HAS_SVG_SURFACE */ - -#endif /* CAIRO_SVG_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-tee-surface-private.h b/source/libs/cairo/cairo-src/src/cairo-tee-surface-private.h deleted file mode 100644 index a83cfc959db44b2c1b4c4e05f4d2e40123a024eb..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-tee-surface-private.h +++ /dev/null @@ -1,47 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_TEE_SURFACE_PRIVATE_H -#define CAIRO_TEE_SURFACE_PRIVATE_H - -#include "cairoint.h" - -cairo_private cairo_surface_t * -_cairo_tee_surface_find_match (void *abstract_surface, - const cairo_surface_backend_t *backend, - cairo_content_t content); - -#endif /* CAIRO_TEE_SURFACE_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-tee-surface.c b/source/libs/cairo/cairo-src/src/cairo-tee-surface.c deleted file mode 100644 index 294e5f162e22b18af59bc89da93adda13ddd8d00..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-tee-surface.c +++ /dev/null @@ -1,602 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2005 Red Hat, Inc - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Carl Worth <cworth@cworth.org> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -/* This surface supports redirecting all its input to multiple surfaces. - */ - -#include "cairoint.h" - -#include "cairo-tee.h" - -#include "cairo-default-context-private.h" -#include "cairo-error-private.h" -#include "cairo-tee-surface-private.h" -#include "cairo-recording-surface-inline.h" -#include "cairo-surface-wrapper-private.h" -#include "cairo-array-private.h" -#include "cairo-image-surface-inline.h" - -typedef struct _cairo_tee_surface { - cairo_surface_t base; - - cairo_surface_wrapper_t master; - cairo_array_t slaves; -} cairo_tee_surface_t; - -slim_hidden_proto (cairo_tee_surface_create); -slim_hidden_proto (cairo_tee_surface_add); - -static cairo_surface_t * -_cairo_tee_surface_create_similar (void *abstract_surface, - cairo_content_t content, - int width, - int height) -{ - - cairo_tee_surface_t *other = abstract_surface; - cairo_surface_t *similar; - cairo_surface_t *surface; - cairo_surface_wrapper_t *slaves; - int n, num_slaves; - - similar = _cairo_surface_wrapper_create_similar (&other->master, - content, width, height); - surface = cairo_tee_surface_create (similar); - cairo_surface_destroy (similar); - if (unlikely (surface->status)) - return surface; - - num_slaves = _cairo_array_num_elements (&other->slaves); - slaves = _cairo_array_index (&other->slaves, 0); - for (n = 0; n < num_slaves; n++) { - - similar = _cairo_surface_wrapper_create_similar (&slaves[n], - content, - width, height); - cairo_tee_surface_add (surface, similar); - cairo_surface_destroy (similar); - } - - if (unlikely (surface->status)) { - cairo_status_t status = surface->status; - cairo_surface_destroy (surface); - surface = _cairo_surface_create_in_error (status); - } - - return surface; -} - -static cairo_status_t -_cairo_tee_surface_finish (void *abstract_surface) -{ - cairo_tee_surface_t *surface = abstract_surface; - cairo_surface_wrapper_t *slaves; - int n, num_slaves; - - _cairo_surface_wrapper_fini (&surface->master); - - num_slaves = _cairo_array_num_elements (&surface->slaves); - slaves = _cairo_array_index (&surface->slaves, 0); - for (n = 0; n < num_slaves; n++) - _cairo_surface_wrapper_fini (&slaves[n]); - - _cairo_array_fini (&surface->slaves); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_surface_t * -_cairo_tee_surface_source (void *abstract_surface, - cairo_rectangle_int_t *extents) -{ - cairo_tee_surface_t *surface = abstract_surface; - return _cairo_surface_get_source (surface->master.target, extents); -} - -static cairo_status_t -_cairo_tee_surface_acquire_source_image (void *abstract_surface, - cairo_image_surface_t **image_out, - void **image_extra) -{ - cairo_tee_surface_t *surface = abstract_surface; - cairo_surface_wrapper_t *slaves; - int num_slaves, n; - - /* we prefer to use a real image surface if available */ - if (_cairo_surface_is_image (surface->master.target)) { - return _cairo_surface_wrapper_acquire_source_image (&surface->master, - image_out, image_extra); - } - - num_slaves = _cairo_array_num_elements (&surface->slaves); - slaves = _cairo_array_index (&surface->slaves, 0); - for (n = 0; n < num_slaves; n++) { - if (_cairo_surface_is_image (slaves[n].target)) { - return _cairo_surface_wrapper_acquire_source_image (&slaves[n], - image_out, - image_extra); - } - } - - return _cairo_surface_wrapper_acquire_source_image (&surface->master, - image_out, image_extra); -} - -static void -_cairo_tee_surface_release_source_image (void *abstract_surface, - cairo_image_surface_t *image, - void *image_extra) -{ - cairo_tee_surface_t *surface = abstract_surface; - - _cairo_surface_wrapper_release_source_image (&surface->master, - image, image_extra); -} - -static cairo_surface_t * -_cairo_tee_surface_snapshot (void *abstract_surface) -{ - cairo_tee_surface_t *surface = abstract_surface; - cairo_surface_wrapper_t *slaves; - int num_slaves, n; - - /* we prefer to use a recording surface for our snapshots */ - if (_cairo_surface_is_recording (surface->master.target)) - return _cairo_surface_wrapper_snapshot (&surface->master); - - num_slaves = _cairo_array_num_elements (&surface->slaves); - slaves = _cairo_array_index (&surface->slaves, 0); - for (n = 0; n < num_slaves; n++) { - if (_cairo_surface_is_recording (slaves[n].target)) - return _cairo_surface_wrapper_snapshot (&slaves[n]); - } - - return _cairo_surface_wrapper_snapshot (&surface->master); -} - -static cairo_bool_t -_cairo_tee_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *rectangle) -{ - cairo_tee_surface_t *surface = abstract_surface; - - return _cairo_surface_wrapper_get_extents (&surface->master, rectangle); -} - -static void -_cairo_tee_surface_get_font_options (void *abstract_surface, - cairo_font_options_t *options) -{ - cairo_tee_surface_t *surface = abstract_surface; - - _cairo_surface_wrapper_get_font_options (&surface->master, options); -} - -static cairo_int_status_t -_cairo_tee_surface_paint (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - cairo_tee_surface_t *surface = abstract_surface; - cairo_surface_wrapper_t *slaves; - int n, num_slaves; - cairo_int_status_t status; - - num_slaves = _cairo_array_num_elements (&surface->slaves); - slaves = _cairo_array_index (&surface->slaves, 0); - for (n = 0; n < num_slaves; n++) { - status = _cairo_surface_wrapper_paint (&slaves[n], op, source, clip); - if (unlikely (status)) - return status; - } - - return _cairo_surface_wrapper_paint (&surface->master, op, source, clip); -} - -static cairo_int_status_t -_cairo_tee_surface_mask (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - cairo_tee_surface_t *surface = abstract_surface; - cairo_surface_wrapper_t *slaves; - cairo_int_status_t status; - int n, num_slaves; - - num_slaves = _cairo_array_num_elements (&surface->slaves); - slaves = _cairo_array_index (&surface->slaves, 0); - for (n = 0; n < num_slaves; n++) { - status = _cairo_surface_wrapper_mask (&slaves[n], - op, source, mask, clip); - if (unlikely (status)) - return status; - } - - return _cairo_surface_wrapper_mask (&surface->master, - op, source, mask, clip); -} - -static cairo_int_status_t -_cairo_tee_surface_stroke (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_tee_surface_t *surface = abstract_surface; - cairo_surface_wrapper_t *slaves; - cairo_int_status_t status; - int n, num_slaves; - - num_slaves = _cairo_array_num_elements (&surface->slaves); - slaves = _cairo_array_index (&surface->slaves, 0); - for (n = 0; n < num_slaves; n++) { - status = _cairo_surface_wrapper_stroke (&slaves[n], - op, source, - path, style, - ctm, ctm_inverse, - tolerance, antialias, - clip); - if (unlikely (status)) - return status; - } - - return _cairo_surface_wrapper_stroke (&surface->master, - op, source, - path, style, - ctm, ctm_inverse, - tolerance, antialias, - clip); -} - -static cairo_int_status_t -_cairo_tee_surface_fill (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_tee_surface_t *surface = abstract_surface; - cairo_surface_wrapper_t *slaves; - cairo_int_status_t status; - int n, num_slaves; - - num_slaves = _cairo_array_num_elements (&surface->slaves); - slaves = _cairo_array_index (&surface->slaves, 0); - for (n = 0; n < num_slaves; n++) { - status = _cairo_surface_wrapper_fill (&slaves[n], - op, source, - path, fill_rule, - tolerance, antialias, - clip); - if (unlikely (status)) - return status; - } - - return _cairo_surface_wrapper_fill (&surface->master, - op, source, - path, fill_rule, - tolerance, antialias, - clip); -} - -static cairo_bool_t -_cairo_tee_surface_has_show_text_glyphs (void *abstract_surface) -{ - return TRUE; -} - -static cairo_int_status_t -_cairo_tee_surface_show_text_glyphs (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const char *utf8, - int utf8_len, - cairo_glyph_t *glyphs, - int num_glyphs, - const cairo_text_cluster_t *clusters, - int num_clusters, - cairo_text_cluster_flags_t cluster_flags, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - cairo_tee_surface_t *surface = abstract_surface; - cairo_surface_wrapper_t *slaves; - cairo_int_status_t status; - int n, num_slaves; - cairo_glyph_t *glyphs_copy; - - /* XXX: This copying is ugly. */ - glyphs_copy = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); - if (unlikely (glyphs_copy == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - num_slaves = _cairo_array_num_elements (&surface->slaves); - slaves = _cairo_array_index (&surface->slaves, 0); - for (n = 0; n < num_slaves; n++) { - memcpy (glyphs_copy, glyphs, sizeof (cairo_glyph_t) * num_glyphs); - status = _cairo_surface_wrapper_show_text_glyphs (&slaves[n], op, - source, - utf8, utf8_len, - glyphs_copy, num_glyphs, - clusters, num_clusters, - cluster_flags, - scaled_font, - clip); - if (unlikely (status)) - goto CLEANUP; - } - - memcpy (glyphs_copy, glyphs, sizeof (cairo_glyph_t) * num_glyphs); - status = _cairo_surface_wrapper_show_text_glyphs (&surface->master, op, - source, - utf8, utf8_len, - glyphs_copy, num_glyphs, - clusters, num_clusters, - cluster_flags, - scaled_font, - clip); -CLEANUP: - free (glyphs_copy); - return status; -} - -static const cairo_surface_backend_t cairo_tee_surface_backend = { - CAIRO_SURFACE_TYPE_TEE, - _cairo_tee_surface_finish, - - _cairo_default_context_create, /* XXX */ - - _cairo_tee_surface_create_similar, - NULL, /* create similar image */ - NULL, /* map to image */ - NULL, /* unmap image */ - - _cairo_tee_surface_source, - _cairo_tee_surface_acquire_source_image, - _cairo_tee_surface_release_source_image, - _cairo_tee_surface_snapshot, - NULL, /* copy_page */ - NULL, /* show_page */ - _cairo_tee_surface_get_extents, - _cairo_tee_surface_get_font_options, - NULL, /* flush */ - NULL, /* mark_dirty_rectangle */ - - _cairo_tee_surface_paint, - _cairo_tee_surface_mask, - _cairo_tee_surface_stroke, - _cairo_tee_surface_fill, - NULL, /* fill_stroke */ - - NULL, /* show_glyphs */ - - _cairo_tee_surface_has_show_text_glyphs, - _cairo_tee_surface_show_text_glyphs -}; - -cairo_surface_t * -cairo_tee_surface_create (cairo_surface_t *master) -{ - cairo_tee_surface_t *surface; - - if (unlikely (master->status)) - return _cairo_surface_create_in_error (master->status); - - surface = malloc (sizeof (cairo_tee_surface_t)); - if (unlikely (surface == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - _cairo_surface_init (&surface->base, - &cairo_tee_surface_backend, - master->device, - master->content); - - _cairo_surface_wrapper_init (&surface->master, master); - - _cairo_array_init (&surface->slaves, sizeof (cairo_surface_wrapper_t)); - - return &surface->base; -} -slim_hidden_def (cairo_tee_surface_create); - -void -cairo_tee_surface_add (cairo_surface_t *abstract_surface, - cairo_surface_t *target) -{ - cairo_tee_surface_t *surface; - cairo_surface_wrapper_t slave; - cairo_status_t status; - - if (unlikely (abstract_surface->status)) - return; - if (unlikely (abstract_surface->finished)) { - status = _cairo_surface_set_error (abstract_surface, - _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - return; - } - - if (abstract_surface->backend != &cairo_tee_surface_backend) { - status = _cairo_surface_set_error (abstract_surface, - _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH)); - return; - } - - if (unlikely (target->status)) { - status = _cairo_surface_set_error (abstract_surface, target->status); - return; - } - - surface = (cairo_tee_surface_t *) abstract_surface; - - _cairo_surface_wrapper_init (&slave, target); - status = _cairo_array_append (&surface->slaves, &slave); - if (unlikely (status)) { - _cairo_surface_wrapper_fini (&slave); - status = _cairo_surface_set_error (&surface->base, status); - } -} -slim_hidden_def (cairo_tee_surface_add); - -void -cairo_tee_surface_remove (cairo_surface_t *abstract_surface, - cairo_surface_t *target) -{ - cairo_tee_surface_t *surface; - cairo_surface_wrapper_t *slaves; - int n, num_slaves; - - if (unlikely (abstract_surface->status)) - return; - if (unlikely (abstract_surface->finished)) { - _cairo_surface_set_error (abstract_surface, - _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - return; - } - - if (abstract_surface->backend != &cairo_tee_surface_backend) { - _cairo_surface_set_error (abstract_surface, - _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH)); - return; - } - - surface = (cairo_tee_surface_t *) abstract_surface; - if (target == surface->master.target) { - _cairo_surface_set_error (abstract_surface, - _cairo_error (CAIRO_STATUS_INVALID_INDEX)); - return; - } - - num_slaves = _cairo_array_num_elements (&surface->slaves); - slaves = _cairo_array_index (&surface->slaves, 0); - for (n = 0; n < num_slaves; n++) { - if (slaves[n].target == target) - break; - } - - if (n == num_slaves) { - _cairo_surface_set_error (abstract_surface, - _cairo_error (CAIRO_STATUS_INVALID_INDEX)); - return; - } - - _cairo_surface_wrapper_fini (&slaves[n]); - for (n++; n < num_slaves; n++) - slaves[n-1] = slaves[n]; - surface->slaves.num_elements--; /* XXX: cairo_array_remove()? */ -} - -cairo_surface_t * -cairo_tee_surface_index (cairo_surface_t *abstract_surface, - unsigned int index) -{ - cairo_tee_surface_t *surface; - - if (unlikely (abstract_surface->status)) - return _cairo_surface_create_in_error (abstract_surface->status); - if (unlikely (abstract_surface->finished)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - - if (abstract_surface->backend != &cairo_tee_surface_backend) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH)); - - surface = (cairo_tee_surface_t *) abstract_surface; - if (index == 0) { - return surface->master.target; - } else { - cairo_surface_wrapper_t *slave; - - index--; - - if (index >= _cairo_array_num_elements (&surface->slaves)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_INDEX)); - - slave = _cairo_array_index (&surface->slaves, index); - return slave->target; - } -} - -cairo_surface_t * -_cairo_tee_surface_find_match (void *abstract_surface, - const cairo_surface_backend_t *backend, - cairo_content_t content) -{ - cairo_tee_surface_t *surface = abstract_surface; - cairo_surface_wrapper_t *slaves; - int num_slaves, n; - - /* exact match first */ - if (surface->master.target->backend == backend && - surface->master.target->content == content) - { - return surface->master.target; - } - - num_slaves = _cairo_array_num_elements (&surface->slaves); - slaves = _cairo_array_index (&surface->slaves, 0); - for (n = 0; n < num_slaves; n++) { - if (slaves[n].target->backend == backend && - slaves[n].target->content == content) - { - return slaves[n].target; - } - } - - /* matching backend? */ - if (surface->master.target->backend == backend) - return surface->master.target; - - num_slaves = _cairo_array_num_elements (&surface->slaves); - slaves = _cairo_array_index (&surface->slaves, 0); - for (n = 0; n < num_slaves; n++) { - if (slaves[n].target->backend == backend) - return slaves[n].target; - } - - return NULL; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-tee.h b/source/libs/cairo/cairo-src/src/cairo-tee.h deleted file mode 100644 index 9125a3a4a2b0ba211a2fd6ba709bae0976e9307a..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-tee.h +++ /dev/null @@ -1,66 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Chris Wilson - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_TEE_H -#define CAIRO_TEE_H - -#include "cairo.h" - -#if CAIRO_HAS_TEE_SURFACE - -CAIRO_BEGIN_DECLS - -cairo_public cairo_surface_t * -cairo_tee_surface_create (cairo_surface_t *master); - -cairo_public void -cairo_tee_surface_add (cairo_surface_t *surface, - cairo_surface_t *target); - -cairo_public void -cairo_tee_surface_remove (cairo_surface_t *surface, - cairo_surface_t *target); - -cairo_public cairo_surface_t * -cairo_tee_surface_index (cairo_surface_t *surface, - unsigned int index); - -CAIRO_END_DECLS - -#else /*CAIRO_HAS_TEE_SURFACE*/ -# error Cairo was not compiled with support for the TEE backend -#endif /*CAIRO_HAS_TEE_SURFACE*/ - -#endif /*CAIRO_TEE_H*/ diff --git a/source/libs/cairo/cairo-src/src/cairo-time-private.h b/source/libs/cairo/cairo-src/src/cairo-time-private.h deleted file mode 100644 index 06dc912b4314071de953641bb53e367010d39b00..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-time-private.h +++ /dev/null @@ -1,94 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright (C) 2011 Andrea Canciani - * - * 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 the - * copyright holders not be used in advertising or publicity - * pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied - * warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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. - * - * Authors: Andrea Canciani <ranma42@gmail.com> - * - */ - -#ifndef CAIRO_TIME_PRIVATE_H -#define CAIRO_TIME_PRIVATE_H - -#include "cairo-compiler-private.h" -#include "cairo-wideint-private.h" - -/* Make the base type signed for easier arithmetic */ -typedef cairo_int64_t cairo_time_t; - -#define _cairo_time_add _cairo_int64_add -#define _cairo_time_sub _cairo_int64_sub -#define _cairo_time_gt _cairo_int64_gt -#define _cairo_time_lt _cairo_int64_lt - -#define _cairo_time_to_double _cairo_int64_to_double -#define _cairo_time_from_double _cairo_double_to_int64 - -cairo_private int -_cairo_time_cmp (const void *a, - const void *b); - -cairo_private double -_cairo_time_to_s (cairo_time_t t); - -cairo_private cairo_time_t -_cairo_time_from_s (double t); - -cairo_private cairo_time_t -_cairo_time_get (void); - -static cairo_always_inline cairo_time_t -_cairo_time_get_delta (cairo_time_t t) -{ - cairo_time_t now; - - now = _cairo_time_get (); - - return _cairo_time_sub (now, t); -} - -static cairo_always_inline double -_cairo_time_to_ns (cairo_time_t t) -{ - return 1.e9 * _cairo_time_to_s (t); -} - -static cairo_always_inline cairo_time_t -_cairo_time_max (cairo_time_t a, cairo_time_t b) -{ - if (_cairo_int64_gt (a, b)) - return a; - else - return b; -} - -static cairo_always_inline cairo_time_t -_cairo_time_min (cairo_time_t a, cairo_time_t b) -{ - if (_cairo_int64_lt (a, b)) - return a; - else - return b; -} - -#endif diff --git a/source/libs/cairo/cairo-src/src/cairo-time.c b/source/libs/cairo/cairo-src/src/cairo-time.c deleted file mode 100644 index a0003fbfc2c5023b8a441f1d12e232e42d73aa3b..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-time.c +++ /dev/null @@ -1,225 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright (c) 2007 Netlabs - * Copyright (c) 2006 Mozilla Corporation - * Copyright (c) 2006 Red Hat, Inc. - * Copyright (c) 2011 Andrea Canciani - * - * 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 - * the authors not be used in advertising or publicity pertaining to - * distribution of the software without specific, written prior - * permission. The authors make no representations about the - * suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE AUTHORS 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. - * - * Authors: Peter Weilbacher <mozilla@weilbacher.org> - * Vladimir Vukicevic <vladimir@pobox.com> - * Carl Worth <cworth@cworth.org> - * Andrea Canciani <ranma42@gmail.com> - */ - -#include "cairoint.h" - -#include "cairo-time-private.h" - -#if HAVE_CLOCK_GETTIME -#if defined(CLOCK_MONOTONIC_RAW) -#define CAIRO_CLOCK CLOCK_MONOTONIC_RAW -#elif defined(CLOCK_MONOTONIC) -#define CAIRO_CLOCK CLOCK_MONOTONIC -#endif -#endif - -#if defined(__APPLE__) -#include <mach/mach_time.h> - -static cairo_always_inline double -_cairo_time_1s (void) -{ - mach_timebase_info_data_t freq; - - mach_timebase_info (&freq); - - return 1000000000. * freq.denom / freq.numer; -} - -cairo_time_t -_cairo_time_get (void) -{ - return mach_absolute_time (); -} - -#elif defined(__OS2__) -#define INCL_BASE -#include <os2.h> - -static cairo_always_inline double -_cairo_time_1s (void) -{ - ULONG freq; - - DosTmrQueryFreq (&freq); - - return freq; -} - -cairo_time_t -_cairo_time_get (void) -{ - QWORD t; - cairo_int64_t r; - - DosTmrQueryTime (&t); - - r = _cairo_int64_lsl (_cairo_int32_to_int64 (t.ulHi), 32); - r = _cairo_int64_add (r, _cairo_int32_to_int64 (t.ulLo)); - - return r; -} - -#elif _WIN32 -#define WIN32_LEAN_AND_MEAN -#include <windows.h> - -static cairo_always_inline double -_cairo_time_1s (void) -{ - LARGE_INTEGER freq; - - QueryPerformanceFrequency (&freq); - - return freq.QuadPart; -} - -#ifndef HAVE_UINT64_T -static cairo_always_inline cairo_time_t -_cairo_time_from_large_integer (LARGE_INTEGER t) -{ - cairo_int64_t r; - - r = _cairo_int64_lsl (_cairo_int32_to_int64 (t.HighPart), 32); - r = _cairo_int64_add (r, _cairo_int32_to_int64 (t.LowPart)); - - return r; -} -#else -static cairo_always_inline cairo_time_t -_cairo_time_from_large_integer (LARGE_INTEGER t) -{ - return t.QuadPart; -} -#endif - -cairo_time_t -_cairo_time_get (void) -{ - LARGE_INTEGER t; - - QueryPerformanceCounter (&t); - - return _cairo_time_from_large_integer(t); -} - -#elif defined(CAIRO_CLOCK) -#include <time.h> - -static cairo_always_inline double -_cairo_time_1s (void) -{ - return 1000000000; -} - -cairo_time_t -_cairo_time_get (void) -{ - struct timespec t; - cairo_time_t r; - - clock_gettime (CAIRO_CLOCK, &t); - - r = _cairo_double_to_int64 (_cairo_time_1s ()); - r = _cairo_int64_mul (r, _cairo_int32_to_int64 (t.tv_sec)); - r = _cairo_int64_add (r, _cairo_int32_to_int64 (t.tv_nsec)); - - return r; -} - -#else -#include <sys/time.h> - -static cairo_always_inline double -_cairo_time_1s (void) -{ - return 1000000; -} - -cairo_time_t -_cairo_time_get (void) -{ - struct timeval t; - cairo_time_t r; - - gettimeofday (&t, NULL); - - r = _cairo_double_to_int64 (_cairo_time_1s ()); - r = _cairo_int64_mul (r, _cairo_int32_to_int64 (t.tv_sec)); - r = _cairo_int64_add (r, _cairo_int32_to_int64 (t.tv_usec)); - - return r; -} - -#endif - -int -_cairo_time_cmp (const void *a, - const void *b) -{ - const cairo_time_t *ta = a, *tb = b; - return _cairo_int64_cmp (*ta, *tb); -} - -static double -_cairo_time_ticks_per_sec (void) -{ - static double ticks = 0; - - if (unlikely (ticks == 0)) - ticks = _cairo_time_1s (); - - return ticks; -} - -static double -_cairo_time_s_per_tick (void) -{ - static double s = 0; - - if (unlikely (s == 0)) - s = 1. / _cairo_time_ticks_per_sec (); - - return s; -} - -double -_cairo_time_to_s (cairo_time_t t) -{ - return _cairo_int64_to_double (t) * _cairo_time_s_per_tick (); -} - -cairo_time_t -_cairo_time_from_s (double t) -{ - return _cairo_double_to_int64 (t * _cairo_time_ticks_per_sec ()); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-tor-scan-converter.c b/source/libs/cairo/cairo-src/src/cairo-tor-scan-converter.c deleted file mode 100644 index b1b51872b19467d94a2fb0e431f0f1434697f747..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-tor-scan-converter.c +++ /dev/null @@ -1,1899 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* glitter-paths - polygon scan converter - * - * Copyright (c) 2008 M Joonas Pihlaja - * Copyright (c) 2007 David Turner - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -/* This is the Glitter paths scan converter incorporated into cairo. - * The source is from commit 734c53237a867a773640bd5b64816249fa1730f8 - * of - * - * http://gitweb.freedesktop.org/?p=users/joonas/glitter-paths - */ -/* Glitter-paths is a stand alone polygon rasteriser derived from - * David Turner's reimplementation of Tor Anderssons's 15x17 - * supersampling rasteriser from the Apparition graphics library. The - * main new feature here is cheaply choosing per-scan line between - * doing fully analytical coverage computation for an entire row at a - * time vs. using a supersampling approach. - * - * David Turner's code can be found at - * - * http://david.freetype.org/rasterizer-shootout/raster-comparison-20070813.tar.bz2 - * - * In particular this file incorporates large parts of ftgrays_tor10.h - * from raster-comparison-20070813.tar.bz2 - */ -/* Overview - * - * A scan converter's basic purpose to take polygon edges and convert - * them into an RLE compressed A8 mask. This one works in two phases: - * gathering edges and generating spans. - * - * 1) As the user feeds the scan converter edges they are vertically - * clipped and bucketted into a _polygon_ data structure. The edges - * are also snapped from the user's coordinates to the subpixel grid - * coordinates used during scan conversion. - * - * user - * | - * | edges - * V - * polygon buckets - * - * 2) Generating spans works by performing a vertical sweep of pixel - * rows from top to bottom and maintaining an _active_list_ of edges - * that intersect the row. From the active list the fill rule - * determines which edges are the left and right edges of the start of - * each span, and their contribution is then accumulated into a pixel - * coverage list (_cell_list_) as coverage deltas. Once the coverage - * deltas of all edges are known we can form spans of constant pixel - * coverage by summing the deltas during a traversal of the cell list. - * At the end of a pixel row the cell list is sent to a coverage - * blitter for rendering to some target surface. - * - * The pixel coverages are computed by either supersampling the row - * and box filtering a mono rasterisation, or by computing the exact - * coverages of edges in the active list. The supersampling method is - * used whenever some edge starts or stops within the row or there are - * edge intersections in the row. - * - * polygon bucket for \ - * current pixel row | - * | | - * | activate new edges | Repeat GRID_Y times if we - * V \ are supersampling this row, - * active list / or just once if we're computing - * | | analytical coverage. - * | coverage deltas | - * V | - * pixel coverage list / - * | - * V - * coverage blitter - */ -#include "cairoint.h" -#include "cairo-spans-private.h" -#include "cairo-error-private.h" - -#include <stdlib.h> -#include <string.h> -#include <limits.h> -#include <setjmp.h> - -/*------------------------------------------------------------------------- - * cairo specific config - */ -#define I static - -/* Prefer cairo's status type. */ -#define GLITTER_HAVE_STATUS_T 1 -#define GLITTER_STATUS_SUCCESS CAIRO_STATUS_SUCCESS -#define GLITTER_STATUS_NO_MEMORY CAIRO_STATUS_NO_MEMORY -typedef cairo_status_t glitter_status_t; - -/* The input coordinate scale and the rasterisation grid scales. */ -#define GLITTER_INPUT_BITS CAIRO_FIXED_FRAC_BITS -#define GRID_X_BITS CAIRO_FIXED_FRAC_BITS -#define GRID_Y 15 - -/* Set glitter up to use a cairo span renderer to do the coverage - * blitting. */ -struct pool; -struct cell_list; - -/*------------------------------------------------------------------------- - * glitter-paths.h - */ - -/* "Input scaled" numbers are fixed precision reals with multiplier - * 2**GLITTER_INPUT_BITS. Input coordinates are given to glitter as - * pixel scaled numbers. These get converted to the internal grid - * scaled numbers as soon as possible. Internal overflow is possible - * if GRID_X/Y inside glitter-paths.c is larger than - * 1<<GLITTER_INPUT_BITS. */ -#ifndef GLITTER_INPUT_BITS -# define GLITTER_INPUT_BITS 8 -#endif -#define GLITTER_INPUT_SCALE (1<<GLITTER_INPUT_BITS) -typedef int glitter_input_scaled_t; - -#if !GLITTER_HAVE_STATUS_T -typedef enum { - GLITTER_STATUS_SUCCESS = 0, - GLITTER_STATUS_NO_MEMORY -} glitter_status_t; -#endif - -#ifndef I -# define I /*static*/ -#endif - -/* Opaque type for scan converting. */ -typedef struct glitter_scan_converter glitter_scan_converter_t; - -/* Reset a scan converter to accept polygon edges and set the clip box - * in pixels. Allocates O(ymax-ymin) bytes of memory. The clip box - * is set to integer pixel coordinates xmin <= x < xmax, ymin <= y < - * ymax. */ -I glitter_status_t -glitter_scan_converter_reset( - glitter_scan_converter_t *converter, - int xmin, int ymin, - int xmax, int ymax); - -/* Render the polygon in the scan converter to the given A8 format - * image raster. Only the pixels accessible as pixels[y*stride+x] for - * x,y inside the clip box are written to, where xmin <= x < xmax, - * ymin <= y < ymax. The image is assumed to be clear on input. - * - * If nonzero_fill is true then the interior of the polygon is - * computed with the non-zero fill rule. Otherwise the even-odd fill - * rule is used. - * - * The scan converter must be reset or destroyed after this call. */ - -/*------------------------------------------------------------------------- - * glitter-paths.c: Implementation internal types - */ -#include <stdlib.h> -#include <string.h> -#include <limits.h> - -/* All polygon coordinates are snapped onto a subsample grid. "Grid - * scaled" numbers are fixed precision reals with multiplier GRID_X or - * GRID_Y. */ -typedef int grid_scaled_t; -typedef int grid_scaled_x_t; -typedef int grid_scaled_y_t; - -/* Default x/y scale factors. - * You can either define GRID_X/Y_BITS to get a power-of-two scale - * or define GRID_X/Y separately. */ -#if !defined(GRID_X) && !defined(GRID_X_BITS) -# define GRID_X_BITS 8 -#endif -#if !defined(GRID_Y) && !defined(GRID_Y_BITS) -# define GRID_Y 15 -#endif - -/* Use GRID_X/Y_BITS to define GRID_X/Y if they're available. */ -#ifdef GRID_X_BITS -# define GRID_X (1 << GRID_X_BITS) -#endif -#ifdef GRID_Y_BITS -# define GRID_Y (1 << GRID_Y_BITS) -#endif - -/* The GRID_X_TO_INT_FRAC macro splits a grid scaled coordinate into - * integer and fractional parts. The integer part is floored. */ -#if defined(GRID_X_TO_INT_FRAC) - /* do nothing */ -#elif defined(GRID_X_BITS) -# define GRID_X_TO_INT_FRAC(x, i, f) \ - _GRID_TO_INT_FRAC_shift(x, i, f, GRID_X_BITS) -#else -# define GRID_X_TO_INT_FRAC(x, i, f) \ - _GRID_TO_INT_FRAC_general(x, i, f, GRID_X) -#endif - -#define _GRID_TO_INT_FRAC_general(t, i, f, m) do { \ - (i) = (t) / (m); \ - (f) = (t) % (m); \ - if ((f) < 0) { \ - --(i); \ - (f) += (m); \ - } \ -} while (0) - -#define _GRID_TO_INT_FRAC_shift(t, i, f, b) do { \ - (f) = (t) & ((1 << (b)) - 1); \ - (i) = (t) >> (b); \ -} while (0) - -/* A grid area is a real in [0,1] scaled by 2*GRID_X*GRID_Y. We want - * to be able to represent exactly areas of subpixel trapezoids whose - * vertices are given in grid scaled coordinates. The scale factor - * comes from needing to accurately represent the area 0.5*dx*dy of a - * triangle with base dx and height dy in grid scaled numbers. */ -#define GRID_XY (2*GRID_X*GRID_Y) /* Unit area on the grid. */ - -/* GRID_AREA_TO_ALPHA(area): map [0,GRID_XY] to [0,255]. */ -#if GRID_XY == 510 -# define GRID_AREA_TO_ALPHA(c) (((c)+1) >> 1) -#elif GRID_XY == 255 -# define GRID_AREA_TO_ALPHA(c) (c) -#elif GRID_XY == 64 -# define GRID_AREA_TO_ALPHA(c) (((c) << 2) | -(((c) & 0x40) >> 6)) -#elif GRID_XY == 128 -# define GRID_AREA_TO_ALPHA(c) ((((c) << 1) | -((c) >> 7)) & 255) -#elif GRID_XY == 256 -# define GRID_AREA_TO_ALPHA(c) (((c) | -((c) >> 8)) & 255) -#elif GRID_XY == 15 -# define GRID_AREA_TO_ALPHA(c) (((c) << 4) + (c)) -#elif GRID_XY == 2*256*15 -# define GRID_AREA_TO_ALPHA(c) (((c) + ((c)<<4) + 256) >> 9) -#else -# define GRID_AREA_TO_ALPHA(c) (((c)*255 + GRID_XY/2) / GRID_XY) -#endif - -#define UNROLL3(x) x x x - -struct quorem { - int32_t quo; - int64_t rem; -}; - -/* Header for a chunk of memory in a memory pool. */ -struct _pool_chunk { - /* # bytes used in this chunk. */ - size_t size; - - /* # bytes total in this chunk */ - size_t capacity; - - /* Pointer to the previous chunk or %NULL if this is the sentinel - * chunk in the pool header. */ - struct _pool_chunk *prev_chunk; - - /* Actual data starts here. Well aligned even for 64 bit types. */ - int64_t data; -}; - -/* The int64_t data member of _pool_chunk just exists to enforce alignment, - * it shouldn't be included in the allocated size for the struct. */ -#define SIZEOF_POOL_CHUNK (sizeof(struct _pool_chunk) - sizeof(int64_t)) - -/* A memory pool. This is supposed to be embedded on the stack or - * within some other structure. It may optionally be followed by an - * embedded array from which requests are fulfilled until - * malloc needs to be called to allocate a first real chunk. */ -struct pool { - /* Chunk we're allocating from. */ - struct _pool_chunk *current; - - jmp_buf *jmp; - - /* Free list of previously allocated chunks. All have >= default - * capacity. */ - struct _pool_chunk *first_free; - - /* The default capacity of a chunk. */ - size_t default_capacity; - - /* Header for the sentinel chunk. Directly following the pool - * struct should be some space for embedded elements from which - * the sentinel chunk allocates from. This is expressed as a char - * array so that the 'int64_t data' member of _pool_chunk isn't - * included. This way embedding struct pool in other structs works - * without wasting space. */ - char sentinel[SIZEOF_POOL_CHUNK]; -}; - -/* A polygon edge. */ -struct edge { - /* Next in y-bucket or active list. */ - struct edge *next, *prev; - - /* The clipped y of the top of the edge. */ - grid_scaled_y_t ytop; - - /* Number of subsample rows remaining to scan convert of this - * edge. */ - grid_scaled_y_t height_left; - - /* Original sign of the edge: +1 for downwards, -1 for upwards - * edges. */ - int dir; - int cell; - - /* Current x coordinate while the edge is on the active - * list. Initialised to the x coordinate of the top of the - * edge. The quotient is in grid_scaled_x_t units and the - * remainder is mod dy in grid_scaled_y_t units.*/ - struct quorem x; - - /* Advance of the current x when moving down a subsample line. */ - struct quorem dxdy; - - /* Advance of the current x when moving down a full pixel - * row. Only initialised when the height of the edge is large - * enough that there's a chance the edge could be stepped by a - * full row's worth of subsample rows at a time. */ - struct quorem dxdy_full; - - /* y2-y1 after orienting the edge downwards. */ - int64_t dy; -}; - -#define EDGE_Y_BUCKET_INDEX(y, ymin) (((y) - (ymin))/GRID_Y) - -/* A collection of sorted and vertically clipped edges of the polygon. - * Edges are moved from the polygon to an active list while scan - * converting. */ -struct polygon { - /* The vertical clip extents. */ - grid_scaled_y_t ymin, ymax; - - /* Array of edges all starting in the same bucket. An edge is put - * into bucket EDGE_BUCKET_INDEX(edge->ytop, polygon->ymin) when - * it is added to the polygon. */ - struct edge **y_buckets; - struct edge *y_buckets_embedded[64]; - - struct { - struct pool base[1]; - struct edge embedded[32]; - } edge_pool; -}; - -/* A cell records the effect on pixel coverage of polygon edges - * passing through a pixel. It contains two accumulators of pixel - * coverage. - * - * Consider the effects of a polygon edge on the coverage of a pixel - * it intersects and that of the following one. The coverage of the - * following pixel is the height of the edge multiplied by the width - * of the pixel, and the coverage of the pixel itself is the area of - * the trapezoid formed by the edge and the right side of the pixel. - * - * +-----------------------+-----------------------+ - * | | | - * | | | - * |_______________________|_______________________| - * | \...................|.......................|\ - * | \..................|.......................| | - * | \.................|.......................| | - * | \....covered.....|.......................| | - * | \....area.......|.......................| } covered height - * | \..............|.......................| | - * |uncovered\.............|.......................| | - * | area \............|.......................| | - * |___________\...........|.......................|/ - * | | | - * | | | - * | | | - * +-----------------------+-----------------------+ - * - * Since the coverage of the following pixel will always be a multiple - * of the width of the pixel, we can store the height of the covered - * area instead. The coverage of the pixel itself is the total - * coverage minus the area of the uncovered area to the left of the - * edge. As it's faster to compute the uncovered area we only store - * that and subtract it from the total coverage later when forming - * spans to blit. - * - * The heights and areas are signed, with left edges of the polygon - * having positive sign and right edges having negative sign. When - * two edges intersect they swap their left/rightness so their - * contribution above and below the intersection point must be - * computed separately. */ -struct cell { - struct cell *next; - int x; - int16_t uncovered_area; - int16_t covered_height; -}; - -/* A cell list represents the scan line sparsely as cells ordered by - * ascending x. It is geared towards scanning the cells in order - * using an internal cursor. */ -struct cell_list { - /* Sentinel nodes */ - struct cell head, tail; - - /* Cursor state for iterating through the cell list. */ - struct cell *cursor, *rewind; - - /* Cells in the cell list are owned by the cell list and are - * allocated from this pool. */ - struct { - struct pool base[1]; - struct cell embedded[32]; - } cell_pool; -}; - -struct cell_pair { - struct cell *cell1; - struct cell *cell2; -}; - -/* The active list contains edges in the current scan line ordered by - * the x-coordinate of the intercept of the edge and the scan line. */ -struct active_list { - /* Leftmost edge on the current scan line. */ - struct edge head, tail; - - /* A lower bound on the height of the active edges is used to - * estimate how soon some active edge ends. We can't advance the - * scan conversion by a full pixel row if an edge ends somewhere - * within it. */ - grid_scaled_y_t min_height; - int is_vertical; -}; - -struct glitter_scan_converter { - struct polygon polygon[1]; - struct active_list active[1]; - struct cell_list coverages[1]; - - cairo_half_open_span_t *spans; - cairo_half_open_span_t spans_embedded[64]; - - /* Clip box. */ - grid_scaled_x_t xmin, xmax; - grid_scaled_y_t ymin, ymax; -}; - -static struct _pool_chunk * -_pool_chunk_init( - struct _pool_chunk *p, - struct _pool_chunk *prev_chunk, - size_t capacity) -{ - p->prev_chunk = prev_chunk; - p->size = 0; - p->capacity = capacity; - return p; -} - -static struct _pool_chunk * -_pool_chunk_create(struct pool *pool, size_t size) -{ - struct _pool_chunk *p; - - p = malloc(SIZEOF_POOL_CHUNK + size); - if (unlikely (NULL == p)) - longjmp (*pool->jmp, _cairo_error (CAIRO_STATUS_NO_MEMORY)); - - return _pool_chunk_init(p, pool->current, size); -} - -static void -pool_init(struct pool *pool, - jmp_buf *jmp, - size_t default_capacity, - size_t embedded_capacity) -{ - pool->jmp = jmp; - pool->current = (void*) pool->sentinel; - pool->first_free = NULL; - pool->default_capacity = default_capacity; - _pool_chunk_init(pool->current, NULL, embedded_capacity); -} - -static void -pool_fini(struct pool *pool) -{ - struct _pool_chunk *p = pool->current; - do { - while (NULL != p) { - struct _pool_chunk *prev = p->prev_chunk; - if (p != (void *) pool->sentinel) - free(p); - p = prev; - } - p = pool->first_free; - pool->first_free = NULL; - } while (NULL != p); -} - -/* Satisfy an allocation by first allocating a new large enough chunk - * and adding it to the head of the pool's chunk list. This function - * is called as a fallback if pool_alloc() couldn't do a quick - * allocation from the current chunk in the pool. */ -static void * -_pool_alloc_from_new_chunk( - struct pool *pool, - size_t size) -{ - struct _pool_chunk *chunk; - void *obj; - size_t capacity; - - /* If the allocation is smaller than the default chunk size then - * try getting a chunk off the free list. Force alloc of a new - * chunk for large requests. */ - capacity = size; - chunk = NULL; - if (size < pool->default_capacity) { - capacity = pool->default_capacity; - chunk = pool->first_free; - if (chunk) { - pool->first_free = chunk->prev_chunk; - _pool_chunk_init(chunk, pool->current, chunk->capacity); - } - } - - if (NULL == chunk) - chunk = _pool_chunk_create (pool, capacity); - pool->current = chunk; - - obj = ((unsigned char*)&chunk->data + chunk->size); - chunk->size += size; - return obj; -} - -/* Allocate size bytes from the pool. The first allocated address - * returned from a pool is aligned to 8 bytes. Subsequent - * addresses will maintain alignment as long as multiples of 8 are - * allocated. Returns the address of a new memory area or %NULL on - * allocation failures. The pool retains ownership of the returned - * memory. */ -inline static void * -pool_alloc (struct pool *pool, size_t size) -{ - struct _pool_chunk *chunk = pool->current; - - if (size <= chunk->capacity - chunk->size) { - void *obj = ((unsigned char*)&chunk->data + chunk->size); - chunk->size += size; - return obj; - } else { - return _pool_alloc_from_new_chunk(pool, size); - } -} - -/* Relinquish all pool_alloced memory back to the pool. */ -static void -pool_reset (struct pool *pool) -{ - /* Transfer all used chunks to the chunk free list. */ - struct _pool_chunk *chunk = pool->current; - if (chunk != (void *) pool->sentinel) { - while (chunk->prev_chunk != (void *) pool->sentinel) { - chunk = chunk->prev_chunk; - } - chunk->prev_chunk = pool->first_free; - pool->first_free = pool->current; - } - /* Reset the sentinel as the current chunk. */ - pool->current = (void *) pool->sentinel; - pool->current->size = 0; -} - -/* Rewinds the cell list's cursor to the beginning. After rewinding - * we're good to cell_list_find() the cell any x coordinate. */ -inline static void -cell_list_rewind (struct cell_list *cells) -{ - cells->cursor = &cells->head; -} - -inline static void -cell_list_maybe_rewind (struct cell_list *cells, int x) -{ - if (x < cells->cursor->x) { - cells->cursor = cells->rewind; - if (x < cells->cursor->x) - cells->cursor = &cells->head; - } -} - -inline static void -cell_list_set_rewind (struct cell_list *cells) -{ - cells->rewind = cells->cursor; -} - -static void -cell_list_init(struct cell_list *cells, jmp_buf *jmp) -{ - pool_init(cells->cell_pool.base, jmp, - 256*sizeof(struct cell), - sizeof(cells->cell_pool.embedded)); - cells->tail.next = NULL; - cells->tail.x = INT_MAX; - cells->head.x = INT_MIN; - cells->head.next = &cells->tail; - cell_list_rewind (cells); -} - -static void -cell_list_fini(struct cell_list *cells) -{ - pool_fini (cells->cell_pool.base); -} - -/* Empty the cell list. This is called at the start of every pixel - * row. */ -inline static void -cell_list_reset (struct cell_list *cells) -{ - cell_list_rewind (cells); - cells->head.next = &cells->tail; - pool_reset (cells->cell_pool.base); -} - -inline static struct cell * -cell_list_alloc (struct cell_list *cells, - struct cell *tail, - int x) -{ - struct cell *cell; - - cell = pool_alloc (cells->cell_pool.base, sizeof (struct cell)); - cell->next = tail->next; - tail->next = cell; - cell->x = x; - *(uint32_t *)&cell->uncovered_area = 0; - - return cell; -} - -/* Find a cell at the given x-coordinate. Returns %NULL if a new cell - * needed to be allocated but couldn't be. Cells must be found with - * non-decreasing x-coordinate until the cell list is rewound using - * cell_list_rewind(). Ownership of the returned cell is retained by - * the cell list. */ -inline static struct cell * -cell_list_find (struct cell_list *cells, int x) -{ - struct cell *tail = cells->cursor; - - if (tail->x == x) - return tail; - - while (1) { - UNROLL3({ - if (tail->next->x > x) - break; - tail = tail->next; - }); - } - - if (tail->x != x) - tail = cell_list_alloc (cells, tail, x); - return cells->cursor = tail; - -} - -/* Find two cells at x1 and x2. This is exactly equivalent - * to - * - * pair.cell1 = cell_list_find(cells, x1); - * pair.cell2 = cell_list_find(cells, x2); - * - * except with less function call overhead. */ -inline static struct cell_pair -cell_list_find_pair(struct cell_list *cells, int x1, int x2) -{ - struct cell_pair pair; - - pair.cell1 = cells->cursor; - while (1) { - UNROLL3({ - if (pair.cell1->next->x > x1) - break; - pair.cell1 = pair.cell1->next; - }); - } - if (pair.cell1->x != x1) - pair.cell1 = cell_list_alloc (cells, pair.cell1, x1); - - pair.cell2 = pair.cell1; - while (1) { - UNROLL3({ - if (pair.cell2->next->x > x2) - break; - pair.cell2 = pair.cell2->next; - }); - } - if (pair.cell2->x != x2) - pair.cell2 = cell_list_alloc (cells, pair.cell2, x2); - - cells->cursor = pair.cell2; - return pair; -} - -/* Add a subpixel span covering [x1, x2) to the coverage cells. */ -inline static void -cell_list_add_subspan(struct cell_list *cells, - grid_scaled_x_t x1, - grid_scaled_x_t x2) -{ - int ix1, fx1; - int ix2, fx2; - - if (x1 == x2) - return; - - GRID_X_TO_INT_FRAC(x1, ix1, fx1); - GRID_X_TO_INT_FRAC(x2, ix2, fx2); - - if (ix1 != ix2) { - struct cell_pair p; - p = cell_list_find_pair(cells, ix1, ix2); - p.cell1->uncovered_area += 2*fx1; - ++p.cell1->covered_height; - p.cell2->uncovered_area -= 2*fx2; - --p.cell2->covered_height; - } else { - struct cell *cell = cell_list_find(cells, ix1); - cell->uncovered_area += 2*(fx1-fx2); - } -} - -inline static void full_step (struct edge *e) -{ - if (e->dy == 0) - return; - - e->x.quo += e->dxdy_full.quo; - e->x.rem += e->dxdy_full.rem; - if (e->x.rem < 0) { - e->x.quo--; - e->x.rem += e->dy; - } else if (e->x.rem >= e->dy) { - ++e->x.quo; - e->x.rem -= e->dy; - } - - e->cell = e->x.quo + (e->x.rem >= e->dy/2); -} - - -/* Adds the analytical coverage of an edge crossing the current pixel - * row to the coverage cells and advances the edge's x position to the - * following row. - * - * This function is only called when we know that during this pixel row: - * - * 1) The relative order of all edges on the active list doesn't - * change. In particular, no edges intersect within this row to pixel - * precision. - * - * 2) No new edges start in this row. - * - * 3) No existing edges end mid-row. - * - * This function depends on being called with all edges from the - * active list in the order they appear on the list (i.e. with - * non-decreasing x-coordinate.) */ -static void -cell_list_render_edge(struct cell_list *cells, - struct edge *edge, - int sign) -{ - struct quorem x1, x2; - grid_scaled_x_t fx1, fx2; - int ix1, ix2; - - x1 = edge->x; - full_step (edge); - x2 = edge->x; - - /* Step back from the sample location (half-subrow) to the pixel origin */ - if (edge->dy) { - x1.quo -= edge->dxdy.quo / 2; - x1.rem -= edge->dxdy.rem / 2; - if (x1.rem < 0) { - --x1.quo; - x1.rem += edge->dy; - } else if (x1.rem >= edge->dy) { - ++x1.quo; - x1.rem -= edge->dy; - } - - x2.quo -= edge->dxdy.quo / 2; - x2.rem -= edge->dxdy.rem / 2; - if (x2.rem < 0) { - --x2.quo; - x2.rem += edge->dy; - } else if (x2.rem >= edge->dy) { - ++x2.quo; - x2.rem -= edge->dy; - } - } - - GRID_X_TO_INT_FRAC(x1.quo, ix1, fx1); - GRID_X_TO_INT_FRAC(x2.quo, ix2, fx2); - - cell_list_maybe_rewind(cells, MIN(ix1, ix2)); - - /* Edge is entirely within a column? */ - if (ix1 == ix2) { - /* We always know that ix1 is >= the cell list cursor in this - * case due to the no-intersections precondition. */ - struct cell *cell = cell_list_find(cells, ix1); - cell->covered_height += sign*GRID_Y; - cell->uncovered_area += sign*(fx1 + fx2)*GRID_Y; - return; - } - - /* Orient the edge left-to-right. */ - if (ix2 < ix1) { - struct quorem tx; - int t; - - t = ix1; - ix1 = ix2; - ix2 = t; - - t = fx1; - fx1 = fx2; - fx2 = t; - - tx = x1; - x1 = x2; - x2 = tx; - } - - /* Add coverage for all pixels [ix1,ix2] on this row crossed - * by the edge. */ - { - struct cell_pair pair; - struct quorem y; - int64_t tmp, dx; - int y_last; - - dx = (x2.quo - x1.quo) * edge->dy + (x2.rem - x1.rem); - - tmp = (ix1 + 1) * GRID_X * edge->dy; - tmp -= x1.quo * edge->dy + x1.rem; - tmp *= GRID_Y; - - y.quo = tmp / dx; - y.rem = tmp % dx; - - /* When rendering a previous edge on the active list we may - * advance the cell list cursor past the leftmost pixel of the - * current edge even though the two edges don't intersect. - * e.g. consider two edges going down and rightwards: - * - * --\_+---\_+-----+-----+---- - * \_ \_ | | - * | \_ | \_ | | - * | \_| \_| | - * | \_ \_ | - * ----+-----+-\---+-\---+---- - * - * The left edge touches cells past the starting cell of the - * right edge. Fortunately such cases are rare. - */ - - pair = cell_list_find_pair(cells, ix1, ix1+1); - pair.cell1->uncovered_area += sign*y.quo*(GRID_X + fx1); - pair.cell1->covered_height += sign*y.quo; - y_last = y.quo; - - if (ix1+1 < ix2) { - struct cell *cell = pair.cell2; - struct quorem dydx_full; - - dydx_full.quo = GRID_Y * GRID_X * edge->dy / dx; - dydx_full.rem = GRID_Y * GRID_X * edge->dy % dx; - - ++ix1; - do { - y.quo += dydx_full.quo; - y.rem += dydx_full.rem; - if (y.rem >= dx) { - y.quo++; - y.rem -= dx; - } - - cell->uncovered_area += sign*(y.quo - y_last)*GRID_X; - cell->covered_height += sign*(y.quo - y_last); - y_last = y.quo; - - ++ix1; - cell = cell_list_find(cells, ix1); - } while (ix1 != ix2); - - pair.cell2 = cell; - } - pair.cell2->uncovered_area += sign*(GRID_Y - y_last)*fx2; - pair.cell2->covered_height += sign*(GRID_Y - y_last); - } -} - -static void -polygon_init (struct polygon *polygon, jmp_buf *jmp) -{ - polygon->ymin = polygon->ymax = 0; - polygon->y_buckets = polygon->y_buckets_embedded; - pool_init (polygon->edge_pool.base, jmp, - 8192 - sizeof (struct _pool_chunk), - sizeof (polygon->edge_pool.embedded)); -} - -static void -polygon_fini (struct polygon *polygon) -{ - if (polygon->y_buckets != polygon->y_buckets_embedded) - free (polygon->y_buckets); - - pool_fini (polygon->edge_pool.base); -} - -/* Empties the polygon of all edges. The polygon is then prepared to - * receive new edges and clip them to the vertical range - * [ymin,ymax). */ -static glitter_status_t -polygon_reset (struct polygon *polygon, - grid_scaled_y_t ymin, - grid_scaled_y_t ymax) -{ - unsigned h = ymax - ymin; - unsigned num_buckets = EDGE_Y_BUCKET_INDEX(ymax + GRID_Y-1, ymin); - - pool_reset(polygon->edge_pool.base); - - if (unlikely (h > 0x7FFFFFFFU - GRID_Y)) - goto bail_no_mem; /* even if you could, you wouldn't want to. */ - - if (polygon->y_buckets != polygon->y_buckets_embedded) - free (polygon->y_buckets); - - polygon->y_buckets = polygon->y_buckets_embedded; - if (num_buckets > ARRAY_LENGTH (polygon->y_buckets_embedded)) { - polygon->y_buckets = _cairo_malloc_ab (num_buckets, - sizeof (struct edge *)); - if (unlikely (NULL == polygon->y_buckets)) - goto bail_no_mem; - } - memset (polygon->y_buckets, 0, num_buckets * sizeof (struct edge *)); - - polygon->ymin = ymin; - polygon->ymax = ymax; - return GLITTER_STATUS_SUCCESS; - -bail_no_mem: - polygon->ymin = 0; - polygon->ymax = 0; - return GLITTER_STATUS_NO_MEMORY; -} - -static void -_polygon_insert_edge_into_its_y_bucket(struct polygon *polygon, - struct edge *e) -{ - unsigned ix = EDGE_Y_BUCKET_INDEX(e->ytop, polygon->ymin); - struct edge **ptail = &polygon->y_buckets[ix]; - e->next = *ptail; - *ptail = e; -} - -static void -active_list_reset (struct active_list *active) -{ - active->head.height_left = INT_MAX; - active->head.dy = 0; - active->head.cell = INT_MIN; - active->head.prev = NULL; - active->head.next = &active->tail; - active->tail.prev = &active->head; - active->tail.next = NULL; - active->tail.cell = INT_MAX; - active->tail.height_left = INT_MAX; - active->tail.dy = 0; - active->min_height = 0; - active->is_vertical = 1; -} - -static void -active_list_init(struct active_list *active) -{ - active_list_reset(active); -} - -/* - * Merge two sorted edge lists. - * Input: - * - head_a: The head of the first list. - * - head_b: The head of the second list; head_b cannot be NULL. - * Output: - * Returns the head of the merged list. - * - * Implementation notes: - * To make it fast (in particular, to reduce to an insertion sort whenever - * one of the two input lists only has a single element) we iterate through - * a list until its head becomes greater than the head of the other list, - * then we switch their roles. As soon as one of the two lists is empty, we - * just attach the other one to the current list and exit. - * Writes to memory are only needed to "switch" lists (as it also requires - * attaching to the output list the list which we will be iterating next) and - * to attach the last non-empty list. - */ -static struct edge * -merge_sorted_edges (struct edge *head_a, struct edge *head_b) -{ - struct edge *head, **next, *prev; - int32_t x; - - prev = head_a->prev; - next = &head; - if (head_a->cell <= head_b->cell) { - head = head_a; - } else { - head = head_b; - head_b->prev = prev; - goto start_with_b; - } - - do { - x = head_b->cell; - while (head_a != NULL && head_a->cell <= x) { - prev = head_a; - next = &head_a->next; - head_a = head_a->next; - } - - head_b->prev = prev; - *next = head_b; - if (head_a == NULL) - return head; - -start_with_b: - x = head_a->cell; - while (head_b != NULL && head_b->cell <= x) { - prev = head_b; - next = &head_b->next; - head_b = head_b->next; - } - - head_a->prev = prev; - *next = head_a; - if (head_b == NULL) - return head; - } while (1); -} - -/* - * Sort (part of) a list. - * Input: - * - list: The list to be sorted; list cannot be NULL. - * - limit: Recursion limit. - * Output: - * - head_out: The head of the sorted list containing the first 2^(level+1) elements of the - * input list; if the input list has fewer elements, head_out be a sorted list - * containing all the elements of the input list. - * Returns the head of the list of unprocessed elements (NULL if the sorted list contains - * all the elements of the input list). - * - * Implementation notes: - * Special case single element list, unroll/inline the sorting of the first two elements. - * Some tail recursion is used since we iterate on the bottom-up solution of the problem - * (we start with a small sorted list and keep merging other lists of the same size to it). - */ -static struct edge * -sort_edges (struct edge *list, - unsigned int level, - struct edge **head_out) -{ - struct edge *head_other, *remaining; - unsigned int i; - - head_other = list->next; - - if (head_other == NULL) { - *head_out = list; - return NULL; - } - - remaining = head_other->next; - if (list->cell <= head_other->cell) { - *head_out = list; - head_other->next = NULL; - } else { - *head_out = head_other; - head_other->prev = list->prev; - head_other->next = list; - list->prev = head_other; - list->next = NULL; - } - - for (i = 0; i < level && remaining; i++) { - remaining = sort_edges (remaining, i, &head_other); - *head_out = merge_sorted_edges (*head_out, head_other); - } - - return remaining; -} - - static struct edge * -merge_unsorted_edges (struct edge *head, struct edge *unsorted) -{ - sort_edges (unsorted, UINT_MAX, &unsorted); - return merge_sorted_edges (head, unsorted); -} - -/* Test if the edges on the active list can be safely advanced by a - * full row without intersections or any edges ending. */ -inline static int -can_do_full_row (struct active_list *active) -{ - const struct edge *e; - int prev_x = INT_MIN; - - /* Recomputes the minimum height of all edges on the active - * list if we have been dropping edges. */ - if (active->min_height <= 0) { - int min_height = INT_MAX; - int is_vertical = 1; - - e = active->head.next; - while (NULL != e) { - if (e->height_left < min_height) - min_height = e->height_left; - is_vertical &= e->dy == 0; - e = e->next; - } - - active->is_vertical = is_vertical; - active->min_height = min_height; - } - - if (active->min_height < GRID_Y) - return 0; - - /* Check for intersections as no edges end during the next row. */ - for (e = active->head.next; e != &active->tail; e = e->next) { - int cell; - - if (e->dy) { - struct quorem x = e->x; - x.quo += e->dxdy_full.quo; - x.rem += e->dxdy_full.rem; - if (x.rem < 0) { - x.quo--; - x.rem += e->dy; - } else if (x.rem >= e->dy) { - x.quo++; - x.rem -= e->dy; - } - cell = x.quo + (x.rem >= e->dy/2); - } else - cell = e->cell; - - if (cell < prev_x) - return 0; - - prev_x = cell; - } - - return 1; -} - -/* Merges edges on the given subpixel row from the polygon to the - * active_list. */ -inline static void -active_list_merge_edges_from_bucket(struct active_list *active, - struct edge *edges) -{ - active->head.next = merge_unsorted_edges (active->head.next, edges); -} - -inline static int -polygon_fill_buckets (struct active_list *active, - struct edge *edge, - int y, - struct edge **buckets) -{ - grid_scaled_y_t min_height = active->min_height; - int is_vertical = active->is_vertical; - int max_suby = 0; - - while (edge) { - struct edge *next = edge->next; - int suby = edge->ytop - y; - if (buckets[suby]) - buckets[suby]->prev = edge; - edge->next = buckets[suby]; - edge->prev = NULL; - buckets[suby] = edge; - if (edge->height_left < min_height) - min_height = edge->height_left; - is_vertical &= edge->dy == 0; - edge = next; - if (suby > max_suby) - max_suby = suby; - } - - active->is_vertical = is_vertical; - active->min_height = min_height; - - return max_suby; -} - -static void step (struct edge *edge) -{ - if (edge->dy == 0) - return; - - edge->x.quo += edge->dxdy.quo; - edge->x.rem += edge->dxdy.rem; - if (edge->x.rem < 0) { - --edge->x.quo; - edge->x.rem += edge->dy; - } else if (edge->x.rem >= edge->dy) { - ++edge->x.quo; - edge->x.rem -= edge->dy; - } - - edge->cell = edge->x.quo + (edge->x.rem >= edge->dy/2); -} - -inline static void -sub_row (struct active_list *active, - struct cell_list *coverages, - unsigned int mask) -{ - struct edge *edge = active->head.next; - int xstart = INT_MIN, prev_x = INT_MIN; - int winding = 0; - - cell_list_rewind (coverages); - - while (&active->tail != edge) { - struct edge *next = edge->next; - int xend = edge->cell; - - if (--edge->height_left) { - step (edge); - - if (edge->cell < prev_x) { - struct edge *pos = edge->prev; - pos->next = next; - next->prev = pos; - do { - pos = pos->prev; - } while (edge->cell < pos->cell); - pos->next->prev = edge; - edge->next = pos->next; - edge->prev = pos; - pos->next = edge; - } else - prev_x = edge->cell; - active->min_height = -1; - } else { - edge->prev->next = next; - next->prev = edge->prev; - } - - winding += edge->dir; - if ((winding & mask) == 0) { - if (next->cell != xend) { - cell_list_add_subspan (coverages, xstart, xend); - xstart = INT_MIN; - } - } else if (xstart == INT_MIN) - xstart = xend; - - edge = next; - } -} - -inline static void dec (struct active_list *a, struct edge *e, int h) -{ - e->height_left -= h; - if (e->height_left == 0) { - e->prev->next = e->next; - e->next->prev = e->prev; - a->min_height = -1; - } -} - -static void -full_row (struct active_list *active, - struct cell_list *coverages, - unsigned int mask) -{ - struct edge *left = active->head.next; - - while (&active->tail != left) { - struct edge *right; - int winding; - - dec (active, left, GRID_Y); - - winding = left->dir; - right = left->next; - do { - dec (active, right, GRID_Y); - - winding += right->dir; - if ((winding & mask) == 0 && right->next->cell != right->cell) - break; - - full_step (right); - - right = right->next; - } while (1); - - cell_list_set_rewind (coverages); - cell_list_render_edge (coverages, left, +1); - cell_list_render_edge (coverages, right, -1); - - left = right->next; - } -} - -static void -_glitter_scan_converter_init(glitter_scan_converter_t *converter, jmp_buf *jmp) -{ - polygon_init(converter->polygon, jmp); - active_list_init(converter->active); - cell_list_init(converter->coverages, jmp); - converter->xmin=0; - converter->ymin=0; - converter->xmax=0; - converter->ymax=0; -} - -static void -_glitter_scan_converter_fini(glitter_scan_converter_t *self) -{ - if (self->spans != self->spans_embedded) - free (self->spans); - - polygon_fini(self->polygon); - cell_list_fini(self->coverages); - - self->xmin=0; - self->ymin=0; - self->xmax=0; - self->ymax=0; -} - -static grid_scaled_t -int_to_grid_scaled(int i, int scale) -{ - /* Clamp to max/min representable scaled number. */ - if (i >= 0) { - if (i >= INT_MAX/scale) - i = INT_MAX/scale; - } - else { - if (i <= INT_MIN/scale) - i = INT_MIN/scale; - } - return i*scale; -} - -#define int_to_grid_scaled_x(x) int_to_grid_scaled((x), GRID_X) -#define int_to_grid_scaled_y(x) int_to_grid_scaled((x), GRID_Y) - -I glitter_status_t -glitter_scan_converter_reset( - glitter_scan_converter_t *converter, - int xmin, int ymin, - int xmax, int ymax) -{ - glitter_status_t status; - int max_num_spans; - - converter->xmin = 0; converter->xmax = 0; - converter->ymin = 0; converter->ymax = 0; - - max_num_spans = xmax - xmin + 1; - - if (max_num_spans > ARRAY_LENGTH(converter->spans_embedded)) { - converter->spans = _cairo_malloc_ab (max_num_spans, - sizeof (cairo_half_open_span_t)); - if (unlikely (converter->spans == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } else - converter->spans = converter->spans_embedded; - - xmin = int_to_grid_scaled_x(xmin); - ymin = int_to_grid_scaled_y(ymin); - xmax = int_to_grid_scaled_x(xmax); - ymax = int_to_grid_scaled_y(ymax); - - active_list_reset(converter->active); - cell_list_reset(converter->coverages); - status = polygon_reset(converter->polygon, ymin, ymax); - if (status) - return status; - - converter->xmin = xmin; - converter->xmax = xmax; - converter->ymin = ymin; - converter->ymax = ymax; - return GLITTER_STATUS_SUCCESS; -} - -/* INPUT_TO_GRID_X/Y (in_coord, out_grid_scaled, grid_scale) - * These macros convert an input coordinate in the client's - * device space to the rasterisation grid. - */ -/* Gah.. this bit of ugly defines INPUT_TO_GRID_X/Y so as to use - * shifts if possible, and something saneish if not. - */ -#if !defined(INPUT_TO_GRID_Y) && defined(GRID_Y_BITS) && GRID_Y_BITS <= GLITTER_INPUT_BITS -# define INPUT_TO_GRID_Y(in, out) (out) = (in) >> (GLITTER_INPUT_BITS - GRID_Y_BITS) -#else -# define INPUT_TO_GRID_Y(in, out) INPUT_TO_GRID_general(in, out, GRID_Y) -#endif - -#if !defined(INPUT_TO_GRID_X) && defined(GRID_X_BITS) && GRID_X_BITS <= GLITTER_INPUT_BITS -# define INPUT_TO_GRID_X(in, out) (out) = (in) >> (GLITTER_INPUT_BITS - GRID_X_BITS) -#else -# define INPUT_TO_GRID_X(in, out) INPUT_TO_GRID_general(in, out, GRID_X) -#endif - -#define INPUT_TO_GRID_general(in, out, grid_scale) do { \ - long long tmp__ = (long long)(grid_scale) * (in); \ - tmp__ += 1 << (GLITTER_INPUT_BITS-1); \ - tmp__ >>= GLITTER_INPUT_BITS; \ - (out) = tmp__; \ -} while (0) - -inline static void -polygon_add_edge (struct polygon *polygon, - const cairo_edge_t *edge) -{ - struct edge *e; - grid_scaled_y_t ytop, ybot; - const cairo_point_t *p1, *p2; - - INPUT_TO_GRID_Y (edge->top, ytop); - if (ytop < polygon->ymin) - ytop = polygon->ymin; - - INPUT_TO_GRID_Y (edge->bottom, ybot); - if (ybot > polygon->ymax) - ybot = polygon->ymax; - - if (ybot <= ytop) - return; - - e = pool_alloc (polygon->edge_pool.base, sizeof (struct edge)); - - e->ytop = ytop; - e->height_left = ybot - ytop; - if (edge->line.p2.y > edge->line.p1.y) { - e->dir = edge->dir; - p1 = &edge->line.p1; - p2 = &edge->line.p2; - } else { - e->dir = -edge->dir; - p1 = &edge->line.p2; - p2 = &edge->line.p1; - } - - if (p2->x == p1->x) { - e->cell = p1->x; - e->x.quo = p1->x; - e->x.rem = 0; - e->dxdy.quo = e->dxdy.rem = 0; - e->dxdy_full.quo = e->dxdy_full.rem = 0; - e->dy = 0; - } else { - int64_t Ex, Ey, tmp; - - Ex = (int64_t)(p2->x - p1->x) * GRID_X; - Ey = (int64_t)(p2->y - p1->y) * GRID_Y * (2 << GLITTER_INPUT_BITS); - - e->dxdy.quo = Ex * (2 << GLITTER_INPUT_BITS) / Ey; - e->dxdy.rem = Ex * (2 << GLITTER_INPUT_BITS) % Ey; - - tmp = (int64_t)(2*ytop + 1) << GLITTER_INPUT_BITS; - tmp -= (int64_t)p1->y * GRID_Y * 2; - tmp *= Ex; - e->x.quo = tmp / Ey; - e->x.rem = tmp % Ey; - -#if GRID_X_BITS == GLITTER_INPUT_BITS - e->x.quo += p1->x; -#else - tmp = (int64_t)p1->x * GRID_X; - e->x.quo += tmp >> GLITTER_INPUT_BITS; - e->x.rem += ((tmp & ((1 << GLITTER_INPUT_BITS) - 1)) * Ey) / (1 << GLITTER_INPUT_BITS); -#endif - - if (e->x.rem < 0) { - e->x.quo--; - e->x.rem += Ey; - } else if (e->x.rem >= Ey) { - e->x.quo++; - e->x.rem -= Ey; - } - - if (e->height_left >= GRID_Y) { - tmp = Ex * (2 * GRID_Y << GLITTER_INPUT_BITS); - e->dxdy_full.quo = tmp / Ey; - e->dxdy_full.rem = tmp % Ey; - } else - e->dxdy_full.quo = e->dxdy_full.rem = 0; - - e->cell = e->x.quo + (e->x.rem >= Ey/2); - e->dy = Ey; - } - - _polygon_insert_edge_into_its_y_bucket (polygon, e); -} - -/* Add a new polygon edge from pixel (x1,y1) to (x2,y2) to the scan - * converter. The coordinates represent pixel positions scaled by - * 2**GLITTER_PIXEL_BITS. If this function fails then the scan - * converter should be reset or destroyed. Dir must be +1 or -1, - * with the latter reversing the orientation of the edge. */ -I void -glitter_scan_converter_add_edge (glitter_scan_converter_t *converter, - const cairo_edge_t *edge) -{ - polygon_add_edge (converter->polygon, edge); -} - -static void -step_edges (struct active_list *active, int count) -{ - struct edge *edge; - - count *= GRID_Y; - for (edge = active->head.next; edge != &active->tail; edge = edge->next) { - edge->height_left -= count; - if (! edge->height_left) { - edge->prev->next = edge->next; - edge->next->prev = edge->prev; - active->min_height = -1; - } - } -} - -static glitter_status_t -blit_a8 (struct cell_list *cells, - cairo_span_renderer_t *renderer, - cairo_half_open_span_t *spans, - int y, int height, - int xmin, int xmax) -{ - struct cell *cell = cells->head.next; - int prev_x = xmin, last_x = -1; - int16_t cover = 0, last_cover = 0; - unsigned num_spans; - - if (cell == &cells->tail) - return CAIRO_STATUS_SUCCESS; - - /* Skip cells to the left of the clip region. */ - while (cell->x < xmin) { - cover += cell->covered_height; - cell = cell->next; - } - cover *= GRID_X*2; - - /* Form the spans from the coverages and areas. */ - num_spans = 0; - for (; cell->x < xmax; cell = cell->next) { - int x = cell->x; - int16_t area; - - if (x > prev_x && cover != last_cover) { - spans[num_spans].x = prev_x; - spans[num_spans].coverage = GRID_AREA_TO_ALPHA (cover); - last_cover = cover; - last_x = prev_x; - ++num_spans; - } - - cover += cell->covered_height*GRID_X*2; - area = cover - cell->uncovered_area; - - if (area != last_cover) { - spans[num_spans].x = x; - spans[num_spans].coverage = GRID_AREA_TO_ALPHA (area); - last_cover = area; - last_x = x; - ++num_spans; - } - - prev_x = x+1; - } - - if (prev_x <= xmax && cover != last_cover) { - spans[num_spans].x = prev_x; - spans[num_spans].coverage = GRID_AREA_TO_ALPHA (cover); - last_cover = cover; - last_x = prev_x; - ++num_spans; - } - - if (last_x < xmax && last_cover) { - spans[num_spans].x = xmax; - spans[num_spans].coverage = 0; - ++num_spans; - } - - /* Dump them into the renderer. */ - return renderer->render_rows (renderer, y, height, spans, num_spans); -} - -#define GRID_AREA_TO_A1(A) ((GRID_AREA_TO_ALPHA (A) > 127) ? 255 : 0) -static glitter_status_t -blit_a1 (struct cell_list *cells, - cairo_span_renderer_t *renderer, - cairo_half_open_span_t *spans, - int y, int height, - int xmin, int xmax) -{ - struct cell *cell = cells->head.next; - int prev_x = xmin, last_x = -1; - int16_t cover = 0; - uint8_t coverage, last_cover = 0; - unsigned num_spans; - - if (cell == &cells->tail) - return CAIRO_STATUS_SUCCESS; - - /* Skip cells to the left of the clip region. */ - while (cell->x < xmin) { - cover += cell->covered_height; - cell = cell->next; - } - cover *= GRID_X*2; - - /* Form the spans from the coverages and areas. */ - num_spans = 0; - for (; cell->x < xmax; cell = cell->next) { - int x = cell->x; - int16_t area; - - coverage = GRID_AREA_TO_A1 (cover); - if (x > prev_x && coverage != last_cover) { - last_x = spans[num_spans].x = prev_x; - last_cover = spans[num_spans].coverage = coverage; - ++num_spans; - } - - cover += cell->covered_height*GRID_X*2; - area = cover - cell->uncovered_area; - - coverage = GRID_AREA_TO_A1 (area); - if (coverage != last_cover) { - last_x = spans[num_spans].x = x; - last_cover = spans[num_spans].coverage = coverage; - ++num_spans; - } - - prev_x = x+1; - } - - coverage = GRID_AREA_TO_A1 (cover); - if (prev_x <= xmax && coverage != last_cover) { - last_x = spans[num_spans].x = prev_x; - last_cover = spans[num_spans].coverage = coverage; - ++num_spans; - } - - if (last_x < xmax && last_cover) { - spans[num_spans].x = xmax; - spans[num_spans].coverage = 0; - ++num_spans; - } - if (num_spans == 1) - return CAIRO_STATUS_SUCCESS; - - /* Dump them into the renderer. */ - return renderer->render_rows (renderer, y, height, spans, num_spans); -} - - -I void -glitter_scan_converter_render(glitter_scan_converter_t *converter, - unsigned int winding_mask, - int antialias, - cairo_span_renderer_t *renderer) -{ - int i, j; - int ymax_i = converter->ymax / GRID_Y; - int ymin_i = converter->ymin / GRID_Y; - int xmin_i, xmax_i; - int h = ymax_i - ymin_i; - struct polygon *polygon = converter->polygon; - struct cell_list *coverages = converter->coverages; - struct active_list *active = converter->active; - struct edge *buckets[GRID_Y] = { 0 }; - - xmin_i = converter->xmin / GRID_X; - xmax_i = converter->xmax / GRID_X; - if (xmin_i >= xmax_i) - return; - - /* Render each pixel row. */ - for (i = 0; i < h; i = j) { - int do_full_row = 0; - - j = i + 1; - - /* Determine if we can ignore this row or use the full pixel - * stepper. */ - if (polygon_fill_buckets (active, - polygon->y_buckets[i], - (i+ymin_i)*GRID_Y, - buckets) == 0) { - if (buckets[0]) { - active_list_merge_edges_from_bucket (active, buckets[0]); - buckets[0] = NULL; - } - - if (active->head.next == &active->tail) { - active->min_height = INT_MAX; - active->is_vertical = 1; - for (; j < h && ! polygon->y_buckets[j]; j++) - ; - continue; - } - - do_full_row = can_do_full_row (active); - } - - if (do_full_row) { - /* Step by a full pixel row's worth. */ - full_row (active, coverages, winding_mask); - - if (active->is_vertical) { - while (j < h && - polygon->y_buckets[j] == NULL && - active->min_height >= 2*GRID_Y) - { - active->min_height -= GRID_Y; - j++; - } - if (j != i + 1) - step_edges (active, j - (i + 1)); - } - } else { - int sub; - - /* Subsample this row. */ - for (sub = 0; sub < GRID_Y; sub++) { - if (buckets[sub]) { - active_list_merge_edges_from_bucket (active, buckets[sub]); - buckets[sub] = NULL; - } - sub_row (active, coverages, winding_mask); - } - } - - if (antialias) - blit_a8 (coverages, renderer, converter->spans, - i+ymin_i, j-i, xmin_i, xmax_i); - else - blit_a1 (coverages, renderer, converter->spans, - i+ymin_i, j-i, xmin_i, xmax_i); - cell_list_reset (coverages); - - active->min_height -= GRID_Y; - } -} - -struct _cairo_tor_scan_converter { - cairo_scan_converter_t base; - - glitter_scan_converter_t converter[1]; - cairo_fill_rule_t fill_rule; - cairo_antialias_t antialias; - - jmp_buf jmp; -}; - -typedef struct _cairo_tor_scan_converter cairo_tor_scan_converter_t; - -static void -_cairo_tor_scan_converter_destroy (void *converter) -{ - cairo_tor_scan_converter_t *self = converter; - if (self == NULL) { - return; - } - _glitter_scan_converter_fini (self->converter); - free(self); -} - -cairo_status_t -_cairo_tor_scan_converter_add_polygon (void *converter, - const cairo_polygon_t *polygon) -{ - cairo_tor_scan_converter_t *self = converter; - int i; - -#if 0 - FILE *file = fopen ("polygon.txt", "w"); - _cairo_debug_print_polygon (file, polygon); - fclose (file); -#endif - - for (i = 0; i < polygon->num_edges; i++) - glitter_scan_converter_add_edge (self->converter, &polygon->edges[i]); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_tor_scan_converter_generate (void *converter, - cairo_span_renderer_t *renderer) -{ - cairo_tor_scan_converter_t *self = converter; - cairo_status_t status; - - if ((status = setjmp (self->jmp))) - return _cairo_scan_converter_set_error (self, _cairo_error (status)); - - glitter_scan_converter_render (self->converter, - self->fill_rule == CAIRO_FILL_RULE_WINDING ? ~0 : 1, - self->antialias != CAIRO_ANTIALIAS_NONE, - renderer); - return CAIRO_STATUS_SUCCESS; -} - -cairo_scan_converter_t * -_cairo_tor_scan_converter_create (int xmin, - int ymin, - int xmax, - int ymax, - cairo_fill_rule_t fill_rule, - cairo_antialias_t antialias) -{ - cairo_tor_scan_converter_t *self; - cairo_status_t status; - - self = malloc (sizeof(struct _cairo_tor_scan_converter)); - if (unlikely (self == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto bail_nomem; - } - - self->base.destroy = _cairo_tor_scan_converter_destroy; - self->base.generate = _cairo_tor_scan_converter_generate; - - _glitter_scan_converter_init (self->converter, &self->jmp); - status = glitter_scan_converter_reset (self->converter, - xmin, ymin, xmax, ymax); - if (unlikely (status)) - goto bail; - - self->fill_rule = fill_rule; - self->antialias = antialias; - - return &self->base; - - bail: - self->base.destroy(&self->base); - bail_nomem: - return _cairo_scan_converter_create_in_error (status); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-tor22-scan-converter.c b/source/libs/cairo/cairo-src/src/cairo-tor22-scan-converter.c deleted file mode 100644 index 4cec5ee4f379ba286ba9d9d577862f8cc54e2ec5..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-tor22-scan-converter.c +++ /dev/null @@ -1,1709 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* glitter-paths - polygon scan converter - * - * Copyright (c) 2008 M Joonas Pihlaja - * Copyright (c) 2007 David Turner - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -/* This is the Glitter paths scan converter incorporated into cairo. - * The source is from commit 734c53237a867a773640bd5b64816249fa1730f8 - * of - * - * http://gitweb.freedesktop.org/?p=users/joonas/glitter-paths - */ -/* Glitter-paths is a stand alone polygon rasteriser derived from - * David Turner's reimplementation of Tor Anderssons's 15x17 - * supersampling rasteriser from the Apparition graphics library. The - * main new feature here is cheaply choosing per-scan line between - * doing fully analytical coverage computation for an entire row at a - * time vs. using a supersampling approach. - * - * David Turner's code can be found at - * - * http://david.freetype.org/rasterizer-shootout/raster-comparison-20070813.tar.bz2 - * - * In particular this file incorporates large parts of ftgrays_tor10.h - * from raster-comparison-20070813.tar.bz2 - */ -/* Overview - * - * A scan converter's basic purpose to take polygon edges and convert - * them into an RLE compressed A8 mask. This one works in two phases: - * gathering edges and generating spans. - * - * 1) As the user feeds the scan converter edges they are vertically - * clipped and bucketted into a _polygon_ data structure. The edges - * are also snapped from the user's coordinates to the subpixel grid - * coordinates used during scan conversion. - * - * user - * | - * | edges - * V - * polygon buckets - * - * 2) Generating spans works by performing a vertical sweep of pixel - * rows from top to bottom and maintaining an _active_list_ of edges - * that intersect the row. From the active list the fill rule - * determines which edges are the left and right edges of the start of - * each span, and their contribution is then accumulated into a pixel - * coverage list (_cell_list_) as coverage deltas. Once the coverage - * deltas of all edges are known we can form spans of constant pixel - * coverage by summing the deltas during a traversal of the cell list. - * At the end of a pixel row the cell list is sent to a coverage - * blitter for rendering to some target surface. - * - * The pixel coverages are computed by either supersampling the row - * and box filtering a mono rasterisation, or by computing the exact - * coverages of edges in the active list. The supersampling method is - * used whenever some edge starts or stops within the row or there are - * edge intersections in the row. - * - * polygon bucket for \ - * current pixel row | - * | | - * | activate new edges | Repeat GRID_Y times if we - * V \ are supersampling this row, - * active list / or just once if we're computing - * | | analytical coverage. - * | coverage deltas | - * V | - * pixel coverage list / - * | - * V - * coverage blitter - */ -#include "cairoint.h" -#include "cairo-spans-private.h" -#include "cairo-error-private.h" - -#include <stdlib.h> -#include <string.h> -#include <limits.h> -#include <setjmp.h> - -/*------------------------------------------------------------------------- - * cairo specific config - */ -#define I static - -/* Prefer cairo's status type. */ -#define GLITTER_HAVE_STATUS_T 1 -#define GLITTER_STATUS_SUCCESS CAIRO_STATUS_SUCCESS -#define GLITTER_STATUS_NO_MEMORY CAIRO_STATUS_NO_MEMORY -typedef cairo_status_t glitter_status_t; - -/* The input coordinate scale and the rasterisation grid scales. */ -#define GLITTER_INPUT_BITS CAIRO_FIXED_FRAC_BITS -//#define GRID_X_BITS CAIRO_FIXED_FRAC_BITS -//#define GRID_Y 15 -#define GRID_X_BITS 2 -#define GRID_Y_BITS 2 - -/* Set glitter up to use a cairo span renderer to do the coverage - * blitting. */ -struct pool; -struct cell_list; - -/*------------------------------------------------------------------------- - * glitter-paths.h - */ - -/* "Input scaled" numbers are fixed precision reals with multiplier - * 2**GLITTER_INPUT_BITS. Input coordinates are given to glitter as - * pixel scaled numbers. These get converted to the internal grid - * scaled numbers as soon as possible. Internal overflow is possible - * if GRID_X/Y inside glitter-paths.c is larger than - * 1<<GLITTER_INPUT_BITS. */ -#ifndef GLITTER_INPUT_BITS -# define GLITTER_INPUT_BITS 8 -#endif -#define GLITTER_INPUT_SCALE (1<<GLITTER_INPUT_BITS) -typedef int glitter_input_scaled_t; - -#if !GLITTER_HAVE_STATUS_T -typedef enum { - GLITTER_STATUS_SUCCESS = 0, - GLITTER_STATUS_NO_MEMORY -} glitter_status_t; -#endif - -#ifndef I -# define I /*static*/ -#endif - -/* Opaque type for scan converting. */ -typedef struct glitter_scan_converter glitter_scan_converter_t; - -/* Reset a scan converter to accept polygon edges and set the clip box - * in pixels. Allocates O(ymax-ymin) bytes of memory. The clip box - * is set to integer pixel coordinates xmin <= x < xmax, ymin <= y < - * ymax. */ -I glitter_status_t -glitter_scan_converter_reset( - glitter_scan_converter_t *converter, - int xmin, int ymin, - int xmax, int ymax); - -/* Render the polygon in the scan converter to the given A8 format - * image raster. Only the pixels accessible as pixels[y*stride+x] for - * x,y inside the clip box are written to, where xmin <= x < xmax, - * ymin <= y < ymax. The image is assumed to be clear on input. - * - * If nonzero_fill is true then the interior of the polygon is - * computed with the non-zero fill rule. Otherwise the even-odd fill - * rule is used. - * - * The scan converter must be reset or destroyed after this call. */ - -/*------------------------------------------------------------------------- - * glitter-paths.c: Implementation internal types - */ -#include <stdlib.h> -#include <string.h> -#include <limits.h> - -/* All polygon coordinates are snapped onto a subsample grid. "Grid - * scaled" numbers are fixed precision reals with multiplier GRID_X or - * GRID_Y. */ -typedef int grid_scaled_t; -typedef int grid_scaled_x_t; -typedef int grid_scaled_y_t; - -/* Default x/y scale factors. - * You can either define GRID_X/Y_BITS to get a power-of-two scale - * or define GRID_X/Y separately. */ -#if !defined(GRID_X) && !defined(GRID_X_BITS) -# define GRID_X_BITS 8 -#endif -#if !defined(GRID_Y) && !defined(GRID_Y_BITS) -# define GRID_Y 15 -#endif - -/* Use GRID_X/Y_BITS to define GRID_X/Y if they're available. */ -#ifdef GRID_X_BITS -# define GRID_X (1 << GRID_X_BITS) -#endif -#ifdef GRID_Y_BITS -# define GRID_Y (1 << GRID_Y_BITS) -#endif - -/* The GRID_X_TO_INT_FRAC macro splits a grid scaled coordinate into - * integer and fractional parts. The integer part is floored. */ -#if defined(GRID_X_TO_INT_FRAC) - /* do nothing */ -#elif defined(GRID_X_BITS) -# define GRID_X_TO_INT_FRAC(x, i, f) \ - _GRID_TO_INT_FRAC_shift(x, i, f, GRID_X_BITS) -#else -# define GRID_X_TO_INT_FRAC(x, i, f) \ - _GRID_TO_INT_FRAC_general(x, i, f, GRID_X) -#endif - -#define _GRID_TO_INT_FRAC_general(t, i, f, m) do { \ - (i) = (t) / (m); \ - (f) = (t) % (m); \ - if ((f) < 0) { \ - --(i); \ - (f) += (m); \ - } \ -} while (0) - -#define _GRID_TO_INT_FRAC_shift(t, i, f, b) do { \ - (f) = (t) & ((1 << (b)) - 1); \ - (i) = (t) >> (b); \ -} while (0) - -/* A grid area is a real in [0,1] scaled by 2*GRID_X*GRID_Y. We want - * to be able to represent exactly areas of subpixel trapezoids whose - * vertices are given in grid scaled coordinates. The scale factor - * comes from needing to accurately represent the area 0.5*dx*dy of a - * triangle with base dx and height dy in grid scaled numbers. */ -#define GRID_XY (2*GRID_X*GRID_Y) /* Unit area on the grid. */ - -/* GRID_AREA_TO_ALPHA(area): map [0,GRID_XY] to [0,255]. */ -#if GRID_XY == 510 -# define GRID_AREA_TO_ALPHA(c) (((c)+1) >> 1) -#elif GRID_XY == 255 -# define GRID_AREA_TO_ALPHA(c) (c) -#elif GRID_XY == 64 -# define GRID_AREA_TO_ALPHA(c) (((c) << 2) | -(((c) & 0x40) >> 6)) -#elif GRID_XY == 32 -# define GRID_AREA_TO_ALPHA(c) (((c) << 3) | -(((c) & 0x20) >> 5)) -#elif GRID_XY == 128 -# define GRID_AREA_TO_ALPHA(c) ((((c) << 1) | -((c) >> 7)) & 255) -#elif GRID_XY == 256 -# define GRID_AREA_TO_ALPHA(c) (((c) | -((c) >> 8)) & 255) -#elif GRID_XY == 15 -# define GRID_AREA_TO_ALPHA(c) (((c) << 4) + (c)) -#elif GRID_XY == 2*256*15 -# define GRID_AREA_TO_ALPHA(c) (((c) + ((c)<<4) + 256) >> 9) -#else -# define GRID_AREA_TO_ALPHA(c) (((c)*255 + GRID_XY/2) / GRID_XY) -#endif - -#define UNROLL3(x) x x x - -struct quorem { - int32_t quo; - int32_t rem; -}; - -/* Header for a chunk of memory in a memory pool. */ -struct _pool_chunk { - /* # bytes used in this chunk. */ - size_t size; - - /* # bytes total in this chunk */ - size_t capacity; - - /* Pointer to the previous chunk or %NULL if this is the sentinel - * chunk in the pool header. */ - struct _pool_chunk *prev_chunk; - - /* Actual data starts here. Well aligned for pointers. */ -}; - -/* A memory pool. This is supposed to be embedded on the stack or - * within some other structure. It may optionally be followed by an - * embedded array from which requests are fulfilled until - * malloc needs to be called to allocate a first real chunk. */ -struct pool { - /* Chunk we're allocating from. */ - struct _pool_chunk *current; - - jmp_buf *jmp; - - /* Free list of previously allocated chunks. All have >= default - * capacity. */ - struct _pool_chunk *first_free; - - /* The default capacity of a chunk. */ - size_t default_capacity; - - /* Header for the sentinel chunk. Directly following the pool - * struct should be some space for embedded elements from which - * the sentinel chunk allocates from. */ - struct _pool_chunk sentinel[1]; -}; - -/* A polygon edge. */ -struct edge { - /* Next in y-bucket or active list. */ - struct edge *next, *prev; - - /* Number of subsample rows remaining to scan convert of this - * edge. */ - grid_scaled_y_t height_left; - - /* Original sign of the edge: +1 for downwards, -1 for upwards - * edges. */ - int dir; - int vertical; - - /* Current x coordinate while the edge is on the active - * list. Initialised to the x coordinate of the top of the - * edge. The quotient is in grid_scaled_x_t units and the - * remainder is mod dy in grid_scaled_y_t units.*/ - struct quorem x; - - /* Advance of the current x when moving down a subsample line. */ - struct quorem dxdy; - - /* The clipped y of the top of the edge. */ - grid_scaled_y_t ytop; - - /* y2-y1 after orienting the edge downwards. */ - grid_scaled_y_t dy; -}; - -#define EDGE_Y_BUCKET_INDEX(y, ymin) (((y) - (ymin))/GRID_Y) - -/* A collection of sorted and vertically clipped edges of the polygon. - * Edges are moved from the polygon to an active list while scan - * converting. */ -struct polygon { - /* The vertical clip extents. */ - grid_scaled_y_t ymin, ymax; - - /* Array of edges all starting in the same bucket. An edge is put - * into bucket EDGE_BUCKET_INDEX(edge->ytop, polygon->ymin) when - * it is added to the polygon. */ - struct edge **y_buckets; - struct edge *y_buckets_embedded[64]; - - struct { - struct pool base[1]; - struct edge embedded[32]; - } edge_pool; -}; - -/* A cell records the effect on pixel coverage of polygon edges - * passing through a pixel. It contains two accumulators of pixel - * coverage. - * - * Consider the effects of a polygon edge on the coverage of a pixel - * it intersects and that of the following one. The coverage of the - * following pixel is the height of the edge multiplied by the width - * of the pixel, and the coverage of the pixel itself is the area of - * the trapezoid formed by the edge and the right side of the pixel. - * - * +-----------------------+-----------------------+ - * | | | - * | | | - * |_______________________|_______________________| - * | \...................|.......................|\ - * | \..................|.......................| | - * | \.................|.......................| | - * | \....covered.....|.......................| | - * | \....area.......|.......................| } covered height - * | \..............|.......................| | - * |uncovered\.............|.......................| | - * | area \............|.......................| | - * |___________\...........|.......................|/ - * | | | - * | | | - * | | | - * +-----------------------+-----------------------+ - * - * Since the coverage of the following pixel will always be a multiple - * of the width of the pixel, we can store the height of the covered - * area instead. The coverage of the pixel itself is the total - * coverage minus the area of the uncovered area to the left of the - * edge. As it's faster to compute the uncovered area we only store - * that and subtract it from the total coverage later when forming - * spans to blit. - * - * The heights and areas are signed, with left edges of the polygon - * having positive sign and right edges having negative sign. When - * two edges intersect they swap their left/rightness so their - * contribution above and below the intersection point must be - * computed separately. */ -struct cell { - struct cell *next; - int x; - int16_t uncovered_area; - int16_t covered_height; -}; - -/* A cell list represents the scan line sparsely as cells ordered by - * ascending x. It is geared towards scanning the cells in order - * using an internal cursor. */ -struct cell_list { - /* Sentinel nodes */ - struct cell head, tail; - - /* Cursor state for iterating through the cell list. */ - struct cell *cursor, *rewind; - - /* Cells in the cell list are owned by the cell list and are - * allocated from this pool. */ - struct { - struct pool base[1]; - struct cell embedded[32]; - } cell_pool; -}; - -struct cell_pair { - struct cell *cell1; - struct cell *cell2; -}; - -/* The active list contains edges in the current scan line ordered by - * the x-coordinate of the intercept of the edge and the scan line. */ -struct active_list { - /* Leftmost edge on the current scan line. */ - struct edge head, tail; - - /* A lower bound on the height of the active edges is used to - * estimate how soon some active edge ends. We can't advance the - * scan conversion by a full pixel row if an edge ends somewhere - * within it. */ - grid_scaled_y_t min_height; - int is_vertical; -}; - -struct glitter_scan_converter { - struct polygon polygon[1]; - struct active_list active[1]; - struct cell_list coverages[1]; - - cairo_half_open_span_t *spans; - cairo_half_open_span_t spans_embedded[64]; - - /* Clip box. */ - grid_scaled_x_t xmin, xmax; - grid_scaled_y_t ymin, ymax; -}; - -/* Compute the floored division a/b. Assumes / and % perform symmetric - * division. */ -inline static struct quorem -floored_divrem(int a, int b) -{ - struct quorem qr; - qr.quo = a/b; - qr.rem = a%b; - if ((a^b)<0 && qr.rem) { - qr.quo -= 1; - qr.rem += b; - } - return qr; -} - -/* Compute the floored division (x*a)/b. Assumes / and % perform symmetric - * division. */ -static struct quorem -floored_muldivrem(int x, int a, int b) -{ - struct quorem qr; - long long xa = (long long)x*a; - qr.quo = xa/b; - qr.rem = xa%b; - if ((xa>=0) != (b>=0) && qr.rem) { - qr.quo -= 1; - qr.rem += b; - } - return qr; -} - -static struct _pool_chunk * -_pool_chunk_init( - struct _pool_chunk *p, - struct _pool_chunk *prev_chunk, - size_t capacity) -{ - p->prev_chunk = prev_chunk; - p->size = 0; - p->capacity = capacity; - return p; -} - -static struct _pool_chunk * -_pool_chunk_create(struct pool *pool, size_t size) -{ - struct _pool_chunk *p; - - p = malloc(size + sizeof(struct _pool_chunk)); - if (unlikely (NULL == p)) - longjmp (*pool->jmp, _cairo_error (CAIRO_STATUS_NO_MEMORY)); - - return _pool_chunk_init(p, pool->current, size); -} - -static void -pool_init(struct pool *pool, - jmp_buf *jmp, - size_t default_capacity, - size_t embedded_capacity) -{ - pool->jmp = jmp; - pool->current = pool->sentinel; - pool->first_free = NULL; - pool->default_capacity = default_capacity; - _pool_chunk_init(pool->sentinel, NULL, embedded_capacity); -} - -static void -pool_fini(struct pool *pool) -{ - struct _pool_chunk *p = pool->current; - do { - while (NULL != p) { - struct _pool_chunk *prev = p->prev_chunk; - if (p != pool->sentinel) - free(p); - p = prev; - } - p = pool->first_free; - pool->first_free = NULL; - } while (NULL != p); -} - -/* Satisfy an allocation by first allocating a new large enough chunk - * and adding it to the head of the pool's chunk list. This function - * is called as a fallback if pool_alloc() couldn't do a quick - * allocation from the current chunk in the pool. */ -static void * -_pool_alloc_from_new_chunk( - struct pool *pool, - size_t size) -{ - struct _pool_chunk *chunk; - void *obj; - size_t capacity; - - /* If the allocation is smaller than the default chunk size then - * try getting a chunk off the free list. Force alloc of a new - * chunk for large requests. */ - capacity = size; - chunk = NULL; - if (size < pool->default_capacity) { - capacity = pool->default_capacity; - chunk = pool->first_free; - if (chunk) { - pool->first_free = chunk->prev_chunk; - _pool_chunk_init(chunk, pool->current, chunk->capacity); - } - } - - if (NULL == chunk) - chunk = _pool_chunk_create (pool, capacity); - pool->current = chunk; - - obj = ((unsigned char*)chunk + sizeof(*chunk) + chunk->size); - chunk->size += size; - return obj; -} - -/* Allocate size bytes from the pool. The first allocated address - * returned from a pool is aligned to sizeof(void*). Subsequent - * addresses will maintain alignment as long as multiples of void* are - * allocated. Returns the address of a new memory area or %NULL on - * allocation failures. The pool retains ownership of the returned - * memory. */ -inline static void * -pool_alloc (struct pool *pool, size_t size) -{ - struct _pool_chunk *chunk = pool->current; - - if (size <= chunk->capacity - chunk->size) { - void *obj = ((unsigned char*)chunk + sizeof(*chunk) + chunk->size); - chunk->size += size; - return obj; - } else { - return _pool_alloc_from_new_chunk(pool, size); - } -} - -/* Relinquish all pool_alloced memory back to the pool. */ -static void -pool_reset (struct pool *pool) -{ - /* Transfer all used chunks to the chunk free list. */ - struct _pool_chunk *chunk = pool->current; - if (chunk != pool->sentinel) { - while (chunk->prev_chunk != pool->sentinel) { - chunk = chunk->prev_chunk; - } - chunk->prev_chunk = pool->first_free; - pool->first_free = pool->current; - } - /* Reset the sentinel as the current chunk. */ - pool->current = pool->sentinel; - pool->sentinel->size = 0; -} - -/* Rewinds the cell list's cursor to the beginning. After rewinding - * we're good to cell_list_find() the cell any x coordinate. */ -inline static void -cell_list_rewind (struct cell_list *cells) -{ - cells->cursor = &cells->head; -} - -inline static void -cell_list_maybe_rewind (struct cell_list *cells, int x) -{ - if (x < cells->cursor->x) { - cells->cursor = cells->rewind; - if (x < cells->cursor->x) - cells->cursor = &cells->head; - } -} - -inline static void -cell_list_set_rewind (struct cell_list *cells) -{ - cells->rewind = cells->cursor; -} - -static void -cell_list_init(struct cell_list *cells, jmp_buf *jmp) -{ - pool_init(cells->cell_pool.base, jmp, - 256*sizeof(struct cell), - sizeof(cells->cell_pool.embedded)); - cells->tail.next = NULL; - cells->tail.x = INT_MAX; - cells->head.x = INT_MIN; - cells->head.next = &cells->tail; - cell_list_rewind (cells); -} - -static void -cell_list_fini(struct cell_list *cells) -{ - pool_fini (cells->cell_pool.base); -} - -/* Empty the cell list. This is called at the start of every pixel - * row. */ -inline static void -cell_list_reset (struct cell_list *cells) -{ - cell_list_rewind (cells); - cells->head.next = &cells->tail; - pool_reset (cells->cell_pool.base); -} - -inline static struct cell * -cell_list_alloc (struct cell_list *cells, - struct cell *tail, - int x) -{ - struct cell *cell; - - cell = pool_alloc (cells->cell_pool.base, sizeof (struct cell)); - cell->next = tail->next; - tail->next = cell; - cell->x = x; - *(uint32_t *)&cell->uncovered_area = 0; - - return cell; -} - -/* Find a cell at the given x-coordinate. Returns %NULL if a new cell - * needed to be allocated but couldn't be. Cells must be found with - * non-decreasing x-coordinate until the cell list is rewound using - * cell_list_rewind(). Ownership of the returned cell is retained by - * the cell list. */ -inline static struct cell * -cell_list_find (struct cell_list *cells, int x) -{ - struct cell *tail = cells->cursor; - - if (tail->x == x) - return tail; - - while (1) { - UNROLL3({ - if (tail->next->x > x) - break; - tail = tail->next; - }); - } - - if (tail->x != x) - tail = cell_list_alloc (cells, tail, x); - return cells->cursor = tail; - -} - -/* Find two cells at x1 and x2. This is exactly equivalent - * to - * - * pair.cell1 = cell_list_find(cells, x1); - * pair.cell2 = cell_list_find(cells, x2); - * - * except with less function call overhead. */ -inline static struct cell_pair -cell_list_find_pair(struct cell_list *cells, int x1, int x2) -{ - struct cell_pair pair; - - pair.cell1 = cells->cursor; - while (1) { - UNROLL3({ - if (pair.cell1->next->x > x1) - break; - pair.cell1 = pair.cell1->next; - }); - } - if (pair.cell1->x != x1) - pair.cell1 = cell_list_alloc (cells, pair.cell1, x1); - - pair.cell2 = pair.cell1; - while (1) { - UNROLL3({ - if (pair.cell2->next->x > x2) - break; - pair.cell2 = pair.cell2->next; - }); - } - if (pair.cell2->x != x2) - pair.cell2 = cell_list_alloc (cells, pair.cell2, x2); - - cells->cursor = pair.cell2; - return pair; -} - -/* Add a subpixel span covering [x1, x2) to the coverage cells. */ -inline static void -cell_list_add_subspan(struct cell_list *cells, - grid_scaled_x_t x1, - grid_scaled_x_t x2) -{ - int ix1, fx1; - int ix2, fx2; - - if (x1 == x2) - return; - - GRID_X_TO_INT_FRAC(x1, ix1, fx1); - GRID_X_TO_INT_FRAC(x2, ix2, fx2); - - if (ix1 != ix2) { - struct cell_pair p; - p = cell_list_find_pair(cells, ix1, ix2); - p.cell1->uncovered_area += 2*fx1; - ++p.cell1->covered_height; - p.cell2->uncovered_area -= 2*fx2; - --p.cell2->covered_height; - } else { - struct cell *cell = cell_list_find(cells, ix1); - cell->uncovered_area += 2*(fx1-fx2); - } -} - -/* Adds the analytical coverage of an edge crossing the current pixel - * row to the coverage cells and advances the edge's x position to the - * following row. - * - * This function is only called when we know that during this pixel row: - * - * 1) The relative order of all edges on the active list doesn't - * change. In particular, no edges intersect within this row to pixel - * precision. - * - * 2) No new edges start in this row. - * - * 3) No existing edges end mid-row. - * - * This function depends on being called with all edges from the - * active list in the order they appear on the list (i.e. with - * non-decreasing x-coordinate.) */ -static void -cell_list_render_edge(struct cell_list *cells, - struct edge *edge, - int sign) -{ - grid_scaled_x_t fx; - struct cell *cell; - int ix; - - GRID_X_TO_INT_FRAC(edge->x.quo, ix, fx); - - /* We always know that ix1 is >= the cell list cursor in this - * case due to the no-intersections precondition. */ - cell = cell_list_find(cells, ix); - cell->covered_height += sign*GRID_Y; - cell->uncovered_area += sign*2*fx*GRID_Y; -} - -static void -polygon_init (struct polygon *polygon, jmp_buf *jmp) -{ - polygon->ymin = polygon->ymax = 0; - polygon->y_buckets = polygon->y_buckets_embedded; - pool_init (polygon->edge_pool.base, jmp, - 8192 - sizeof (struct _pool_chunk), - sizeof (polygon->edge_pool.embedded)); -} - -static void -polygon_fini (struct polygon *polygon) -{ - if (polygon->y_buckets != polygon->y_buckets_embedded) - free (polygon->y_buckets); - - pool_fini (polygon->edge_pool.base); -} - -/* Empties the polygon of all edges. The polygon is then prepared to - * receive new edges and clip them to the vertical range - * [ymin,ymax). */ -static glitter_status_t -polygon_reset (struct polygon *polygon, - grid_scaled_y_t ymin, - grid_scaled_y_t ymax) -{ - unsigned h = ymax - ymin; - unsigned num_buckets = EDGE_Y_BUCKET_INDEX(ymax + GRID_Y-1, ymin); - - pool_reset(polygon->edge_pool.base); - - if (unlikely (h > 0x7FFFFFFFU - GRID_Y)) - goto bail_no_mem; /* even if you could, you wouldn't want to. */ - - if (polygon->y_buckets != polygon->y_buckets_embedded) - free (polygon->y_buckets); - - polygon->y_buckets = polygon->y_buckets_embedded; - if (num_buckets > ARRAY_LENGTH (polygon->y_buckets_embedded)) { - polygon->y_buckets = _cairo_malloc_ab (num_buckets, - sizeof (struct edge *)); - if (unlikely (NULL == polygon->y_buckets)) - goto bail_no_mem; - } - memset (polygon->y_buckets, 0, num_buckets * sizeof (struct edge *)); - - polygon->ymin = ymin; - polygon->ymax = ymax; - return GLITTER_STATUS_SUCCESS; - -bail_no_mem: - polygon->ymin = 0; - polygon->ymax = 0; - return GLITTER_STATUS_NO_MEMORY; -} - -static void -_polygon_insert_edge_into_its_y_bucket(struct polygon *polygon, - struct edge *e) -{ - unsigned ix = EDGE_Y_BUCKET_INDEX(e->ytop, polygon->ymin); - struct edge **ptail = &polygon->y_buckets[ix]; - e->next = *ptail; - *ptail = e; -} - -inline static void -polygon_add_edge (struct polygon *polygon, - const cairo_edge_t *edge) -{ - struct edge *e; - grid_scaled_x_t dx; - grid_scaled_y_t dy; - grid_scaled_y_t ytop, ybot; - grid_scaled_y_t ymin = polygon->ymin; - grid_scaled_y_t ymax = polygon->ymax; - - if (unlikely (edge->top >= ymax || edge->bottom <= ymin)) - return; - - e = pool_alloc (polygon->edge_pool.base, sizeof (struct edge)); - - dx = edge->line.p2.x - edge->line.p1.x; - dy = edge->line.p2.y - edge->line.p1.y; - e->dy = dy; - e->dir = edge->dir; - - ytop = edge->top >= ymin ? edge->top : ymin; - ybot = edge->bottom <= ymax ? edge->bottom : ymax; - e->ytop = ytop; - e->height_left = ybot - ytop; - - if (dx == 0) { - e->vertical = TRUE; - e->x.quo = edge->line.p1.x; - e->x.rem = 0; - e->dxdy.quo = 0; - e->dxdy.rem = 0; - } else { - e->vertical = FALSE; - e->dxdy = floored_divrem (dx, dy); - if (ytop == edge->line.p1.y) { - e->x.quo = edge->line.p1.x; - e->x.rem = 0; - } else { - e->x = floored_muldivrem (ytop - edge->line.p1.y, dx, dy); - e->x.quo += edge->line.p1.x; - } - } - - _polygon_insert_edge_into_its_y_bucket (polygon, e); - - e->x.rem -= dy; /* Bias the remainder for faster - * edge advancement. */ -} - -static void -active_list_reset (struct active_list *active) -{ - active->head.vertical = 1; - active->head.height_left = INT_MAX; - active->head.x.quo = INT_MIN; - active->head.prev = NULL; - active->head.next = &active->tail; - active->tail.prev = &active->head; - active->tail.next = NULL; - active->tail.x.quo = INT_MAX; - active->tail.height_left = INT_MAX; - active->tail.vertical = 1; - active->min_height = 0; - active->is_vertical = 1; -} - -static void -active_list_init(struct active_list *active) -{ - active_list_reset(active); -} - -/* - * Merge two sorted edge lists. - * Input: - * - head_a: The head of the first list. - * - head_b: The head of the second list; head_b cannot be NULL. - * Output: - * Returns the head of the merged list. - * - * Implementation notes: - * To make it fast (in particular, to reduce to an insertion sort whenever - * one of the two input lists only has a single element) we iterate through - * a list until its head becomes greater than the head of the other list, - * then we switch their roles. As soon as one of the two lists is empty, we - * just attach the other one to the current list and exit. - * Writes to memory are only needed to "switch" lists (as it also requires - * attaching to the output list the list which we will be iterating next) and - * to attach the last non-empty list. - */ -static struct edge * -merge_sorted_edges (struct edge *head_a, struct edge *head_b) -{ - struct edge *head, **next, *prev; - int32_t x; - - prev = head_a->prev; - next = &head; - if (head_a->x.quo <= head_b->x.quo) { - head = head_a; - } else { - head = head_b; - head_b->prev = prev; - goto start_with_b; - } - - do { - x = head_b->x.quo; - while (head_a != NULL && head_a->x.quo <= x) { - prev = head_a; - next = &head_a->next; - head_a = head_a->next; - } - - head_b->prev = prev; - *next = head_b; - if (head_a == NULL) - return head; - -start_with_b: - x = head_a->x.quo; - while (head_b != NULL && head_b->x.quo <= x) { - prev = head_b; - next = &head_b->next; - head_b = head_b->next; - } - - head_a->prev = prev; - *next = head_a; - if (head_b == NULL) - return head; - } while (1); -} - -/* - * Sort (part of) a list. - * Input: - * - list: The list to be sorted; list cannot be NULL. - * - limit: Recursion limit. - * Output: - * - head_out: The head of the sorted list containing the first 2^(level+1) elements of the - * input list; if the input list has fewer elements, head_out be a sorted list - * containing all the elements of the input list. - * Returns the head of the list of unprocessed elements (NULL if the sorted list contains - * all the elements of the input list). - * - * Implementation notes: - * Special case single element list, unroll/inline the sorting of the first two elements. - * Some tail recursion is used since we iterate on the bottom-up solution of the problem - * (we start with a small sorted list and keep merging other lists of the same size to it). - */ -static struct edge * -sort_edges (struct edge *list, - unsigned int level, - struct edge **head_out) -{ - struct edge *head_other, *remaining; - unsigned int i; - - head_other = list->next; - - if (head_other == NULL) { - *head_out = list; - return NULL; - } - - remaining = head_other->next; - if (list->x.quo <= head_other->x.quo) { - *head_out = list; - head_other->next = NULL; - } else { - *head_out = head_other; - head_other->prev = list->prev; - head_other->next = list; - list->prev = head_other; - list->next = NULL; - } - - for (i = 0; i < level && remaining; i++) { - remaining = sort_edges (remaining, i, &head_other); - *head_out = merge_sorted_edges (*head_out, head_other); - } - - return remaining; -} - -static struct edge * -merge_unsorted_edges (struct edge *head, struct edge *unsorted) -{ - sort_edges (unsorted, UINT_MAX, &unsorted); - return merge_sorted_edges (head, unsorted); -} - -/* Test if the edges on the active list can be safely advanced by a - * full row without intersections or any edges ending. */ -inline static int -can_do_full_row (struct active_list *active) -{ - const struct edge *e; - - /* Recomputes the minimum height of all edges on the active - * list if we have been dropping edges. */ - if (active->min_height <= 0) { - int min_height = INT_MAX; - int is_vertical = 1; - - e = active->head.next; - while (NULL != e) { - if (e->height_left < min_height) - min_height = e->height_left; - is_vertical &= e->vertical; - e = e->next; - } - - active->is_vertical = is_vertical; - active->min_height = min_height; - } - - if (active->min_height < GRID_Y) - return 0; - - return active->is_vertical; -} - -/* Merges edges on the given subpixel row from the polygon to the - * active_list. */ -inline static void -active_list_merge_edges_from_bucket(struct active_list *active, - struct edge *edges) -{ - active->head.next = merge_unsorted_edges (active->head.next, edges); -} - -inline static void -polygon_fill_buckets (struct active_list *active, - struct edge *edge, - int y, - struct edge **buckets) -{ - grid_scaled_y_t min_height = active->min_height; - int is_vertical = active->is_vertical; - - while (edge) { - struct edge *next = edge->next; - int suby = edge->ytop - y; - if (buckets[suby]) - buckets[suby]->prev = edge; - edge->next = buckets[suby]; - edge->prev = NULL; - buckets[suby] = edge; - if (edge->height_left < min_height) - min_height = edge->height_left; - is_vertical &= edge->vertical; - edge = next; - } - - active->is_vertical = is_vertical; - active->min_height = min_height; -} - -inline static void -sub_row (struct active_list *active, - struct cell_list *coverages, - unsigned int mask) -{ - struct edge *edge = active->head.next; - int xstart = INT_MIN, prev_x = INT_MIN; - int winding = 0; - - cell_list_rewind (coverages); - - while (&active->tail != edge) { - struct edge *next = edge->next; - int xend = edge->x.quo; - - if (--edge->height_left) { - edge->x.quo += edge->dxdy.quo; - edge->x.rem += edge->dxdy.rem; - if (edge->x.rem >= 0) { - ++edge->x.quo; - edge->x.rem -= edge->dy; - } - - if (edge->x.quo < prev_x) { - struct edge *pos = edge->prev; - pos->next = next; - next->prev = pos; - do { - pos = pos->prev; - } while (edge->x.quo < pos->x.quo); - pos->next->prev = edge; - edge->next = pos->next; - edge->prev = pos; - pos->next = edge; - } else - prev_x = edge->x.quo; - } else { - edge->prev->next = next; - next->prev = edge->prev; - } - - winding += edge->dir; - if ((winding & mask) == 0) { - if (next->x.quo != xend) { - cell_list_add_subspan (coverages, xstart, xend); - xstart = INT_MIN; - } - } else if (xstart == INT_MIN) - xstart = xend; - - edge = next; - } -} - -inline static void dec (struct edge *e, int h) -{ - e->height_left -= h; - if (e->height_left == 0) { - e->prev->next = e->next; - e->next->prev = e->prev; - } -} - -static void -full_row (struct active_list *active, - struct cell_list *coverages, - unsigned int mask) -{ - struct edge *left = active->head.next; - - while (&active->tail != left) { - struct edge *right; - int winding; - - dec (left, GRID_Y); - - winding = left->dir; - right = left->next; - do { - dec (right, GRID_Y); - - winding += right->dir; - if ((winding & mask) == 0 && right->next->x.quo != right->x.quo) - break; - - right = right->next; - } while (1); - - cell_list_set_rewind (coverages); - cell_list_render_edge (coverages, left, +1); - cell_list_render_edge (coverages, right, -1); - - left = right->next; - } -} - -static void -_glitter_scan_converter_init(glitter_scan_converter_t *converter, jmp_buf *jmp) -{ - polygon_init(converter->polygon, jmp); - active_list_init(converter->active); - cell_list_init(converter->coverages, jmp); - converter->xmin=0; - converter->ymin=0; - converter->xmax=0; - converter->ymax=0; -} - -static void -_glitter_scan_converter_fini(glitter_scan_converter_t *self) -{ - if (self->spans != self->spans_embedded) - free (self->spans); - - polygon_fini(self->polygon); - cell_list_fini(self->coverages); - - self->xmin=0; - self->ymin=0; - self->xmax=0; - self->ymax=0; -} - -static grid_scaled_t -int_to_grid_scaled(int i, int scale) -{ - /* Clamp to max/min representable scaled number. */ - if (i >= 0) { - if (i >= INT_MAX/scale) - i = INT_MAX/scale; - } - else { - if (i <= INT_MIN/scale) - i = INT_MIN/scale; - } - return i*scale; -} - -#define int_to_grid_scaled_x(x) int_to_grid_scaled((x), GRID_X) -#define int_to_grid_scaled_y(x) int_to_grid_scaled((x), GRID_Y) - -I glitter_status_t -glitter_scan_converter_reset( - glitter_scan_converter_t *converter, - int xmin, int ymin, - int xmax, int ymax) -{ - glitter_status_t status; - - converter->xmin = 0; converter->xmax = 0; - converter->ymin = 0; converter->ymax = 0; - - if (xmax - xmin > ARRAY_LENGTH(converter->spans_embedded)) { - converter->spans = _cairo_malloc_ab (xmax - xmin, - sizeof (cairo_half_open_span_t)); - if (unlikely (converter->spans == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } else - converter->spans = converter->spans_embedded; - - xmin = int_to_grid_scaled_x(xmin); - ymin = int_to_grid_scaled_y(ymin); - xmax = int_to_grid_scaled_x(xmax); - ymax = int_to_grid_scaled_y(ymax); - - active_list_reset(converter->active); - cell_list_reset(converter->coverages); - status = polygon_reset(converter->polygon, ymin, ymax); - if (status) - return status; - - converter->xmin = xmin; - converter->xmax = xmax; - converter->ymin = ymin; - converter->ymax = ymax; - return GLITTER_STATUS_SUCCESS; -} - -/* INPUT_TO_GRID_X/Y (in_coord, out_grid_scaled, grid_scale) - * These macros convert an input coordinate in the client's - * device space to the rasterisation grid. - */ -/* Gah.. this bit of ugly defines INPUT_TO_GRID_X/Y so as to use - * shifts if possible, and something saneish if not. - */ -#if !defined(INPUT_TO_GRID_Y) && defined(GRID_Y_BITS) && GRID_Y_BITS <= GLITTER_INPUT_BITS -# define INPUT_TO_GRID_Y(in, out) (out) = (in) >> (GLITTER_INPUT_BITS - GRID_Y_BITS) -#else -# define INPUT_TO_GRID_Y(in, out) INPUT_TO_GRID_general(in, out, GRID_Y) -#endif - -#if !defined(INPUT_TO_GRID_X) && defined(GRID_X_BITS) && GRID_X_BITS <= GLITTER_INPUT_BITS -# define INPUT_TO_GRID_X(in, out) (out) = (in) >> (GLITTER_INPUT_BITS - GRID_X_BITS) -#else -# define INPUT_TO_GRID_X(in, out) INPUT_TO_GRID_general(in, out, GRID_X) -#endif - -#define INPUT_TO_GRID_general(in, out, grid_scale) do { \ - long long tmp__ = (long long)(grid_scale) * (in); \ - tmp__ >>= GLITTER_INPUT_BITS; \ - (out) = tmp__; \ -} while (0) - -/* Add a new polygon edge from pixel (x1,y1) to (x2,y2) to the scan - * converter. The coordinates represent pixel positions scaled by - * 2**GLITTER_PIXEL_BITS. If this function fails then the scan - * converter should be reset or destroyed. Dir must be +1 or -1, - * with the latter reversing the orientation of the edge. */ -I void -glitter_scan_converter_add_edge (glitter_scan_converter_t *converter, - const cairo_edge_t *edge) -{ - cairo_edge_t e; - - INPUT_TO_GRID_Y (edge->top, e.top); - INPUT_TO_GRID_Y (edge->bottom, e.bottom); - if (e.top >= e.bottom) - return; - - /* XXX: possible overflows if GRID_X/Y > 2**GLITTER_INPUT_BITS */ - INPUT_TO_GRID_Y (edge->line.p1.y, e.line.p1.y); - INPUT_TO_GRID_Y (edge->line.p2.y, e.line.p2.y); - if (e.line.p1.y == e.line.p2.y) - e.line.p2.y++; /* Fudge to prevent div-by-zero */ - - INPUT_TO_GRID_X (edge->line.p1.x, e.line.p1.x); - INPUT_TO_GRID_X (edge->line.p2.x, e.line.p2.x); - - e.dir = edge->dir; - - polygon_add_edge (converter->polygon, &e); -} - -static void -step_edges (struct active_list *active, int count) -{ - struct edge *edge; - - count *= GRID_Y; - for (edge = active->head.next; edge != &active->tail; edge = edge->next) { - edge->height_left -= count; - if (! edge->height_left) { - edge->prev->next = edge->next; - edge->next->prev = edge->prev; - } - } -} - -static glitter_status_t -blit_a8 (struct cell_list *cells, - cairo_span_renderer_t *renderer, - cairo_half_open_span_t *spans, - int y, int height, - int xmin, int xmax) -{ - struct cell *cell = cells->head.next; - int prev_x = xmin, last_x = -1; - int16_t cover = 0, last_cover = 0; - unsigned num_spans; - - if (cell == &cells->tail) - return CAIRO_STATUS_SUCCESS; - - /* Skip cells to the left of the clip region. */ - while (cell->x < xmin) { - cover += cell->covered_height; - cell = cell->next; - } - cover *= GRID_X*2; - - /* Form the spans from the coverages and areas. */ - num_spans = 0; - for (; cell->x < xmax; cell = cell->next) { - int x = cell->x; - int16_t area; - - if (x > prev_x && cover != last_cover) { - spans[num_spans].x = prev_x; - spans[num_spans].coverage = GRID_AREA_TO_ALPHA (cover); - last_cover = cover; - last_x = prev_x; - ++num_spans; - } - - cover += cell->covered_height*GRID_X*2; - area = cover - cell->uncovered_area; - - if (area != last_cover) { - spans[num_spans].x = x; - spans[num_spans].coverage = GRID_AREA_TO_ALPHA (area); - last_cover = area; - last_x = x; - ++num_spans; - } - - prev_x = x+1; - } - - if (prev_x <= xmax && cover != last_cover) { - spans[num_spans].x = prev_x; - spans[num_spans].coverage = GRID_AREA_TO_ALPHA (cover); - last_cover = cover; - last_x = prev_x; - ++num_spans; - } - - if (last_x < xmax && last_cover) { - spans[num_spans].x = xmax; - spans[num_spans].coverage = 0; - ++num_spans; - } - - /* Dump them into the renderer. */ - return renderer->render_rows (renderer, y, height, spans, num_spans); -} - -#define GRID_AREA_TO_A1(A) ((GRID_AREA_TO_ALPHA (A) > 127) ? 255 : 0) -static glitter_status_t -blit_a1 (struct cell_list *cells, - cairo_span_renderer_t *renderer, - cairo_half_open_span_t *spans, - int y, int height, - int xmin, int xmax) -{ - struct cell *cell = cells->head.next; - int prev_x = xmin, last_x = -1; - int16_t cover = 0; - uint8_t coverage, last_cover = 0; - unsigned num_spans; - - if (cell == &cells->tail) - return CAIRO_STATUS_SUCCESS; - - /* Skip cells to the left of the clip region. */ - while (cell->x < xmin) { - cover += cell->covered_height; - cell = cell->next; - } - cover *= GRID_X*2; - - /* Form the spans from the coverages and areas. */ - num_spans = 0; - for (; cell->x < xmax; cell = cell->next) { - int x = cell->x; - int16_t area; - - coverage = GRID_AREA_TO_A1 (cover); - if (x > prev_x && coverage != last_cover) { - last_x = spans[num_spans].x = prev_x; - last_cover = spans[num_spans].coverage = coverage; - ++num_spans; - } - - cover += cell->covered_height*GRID_X*2; - area = cover - cell->uncovered_area; - - coverage = GRID_AREA_TO_A1 (area); - if (coverage != last_cover) { - last_x = spans[num_spans].x = x; - last_cover = spans[num_spans].coverage = coverage; - ++num_spans; - } - - prev_x = x+1; - } - - coverage = GRID_AREA_TO_A1 (cover); - if (prev_x <= xmax && coverage != last_cover) { - last_x = spans[num_spans].x = prev_x; - last_cover = spans[num_spans].coverage = coverage; - ++num_spans; - } - - if (last_x < xmax && last_cover) { - spans[num_spans].x = xmax; - spans[num_spans].coverage = 0; - ++num_spans; - } - if (num_spans == 1) - return CAIRO_STATUS_SUCCESS; - - /* Dump them into the renderer. */ - return renderer->render_rows (renderer, y, height, spans, num_spans); -} - - -I void -glitter_scan_converter_render(glitter_scan_converter_t *converter, - unsigned int winding_mask, - int antialias, - cairo_span_renderer_t *renderer) -{ - int i, j; - int ymax_i = converter->ymax / GRID_Y; - int ymin_i = converter->ymin / GRID_Y; - int xmin_i, xmax_i; - int h = ymax_i - ymin_i; - struct polygon *polygon = converter->polygon; - struct cell_list *coverages = converter->coverages; - struct active_list *active = converter->active; - struct edge *buckets[GRID_Y] = { 0 }; - - xmin_i = converter->xmin / GRID_X; - xmax_i = converter->xmax / GRID_X; - if (xmin_i >= xmax_i) - return; - - /* Render each pixel row. */ - for (i = 0; i < h; i = j) { - int do_full_row = 0; - - j = i + 1; - - /* Determine if we can ignore this row or use the full pixel - * stepper. */ - if (! polygon->y_buckets[i]) { - if (active->head.next == &active->tail) { - active->min_height = INT_MAX; - active->is_vertical = 1; - for (; j < h && ! polygon->y_buckets[j]; j++) - ; - continue; - } - - do_full_row = can_do_full_row (active); - } - - if (do_full_row) { - /* Step by a full pixel row's worth. */ - full_row (active, coverages, winding_mask); - - if (active->is_vertical) { - while (j < h && - polygon->y_buckets[j] == NULL && - active->min_height >= 2*GRID_Y) - { - active->min_height -= GRID_Y; - j++; - } - if (j != i + 1) - step_edges (active, j - (i + 1)); - } - } else { - int sub; - - polygon_fill_buckets (active, - polygon->y_buckets[i], - (i+ymin_i)*GRID_Y, - buckets); - - /* Subsample this row. */ - for (sub = 0; sub < GRID_Y; sub++) { - if (buckets[sub]) { - active_list_merge_edges_from_bucket (active, buckets[sub]); - buckets[sub] = NULL; - } - - sub_row (active, coverages, winding_mask); - } - } - - if (antialias) - blit_a8 (coverages, renderer, converter->spans, - i+ymin_i, j-i, xmin_i, xmax_i); - else - blit_a1 (coverages, renderer, converter->spans, - i+ymin_i, j-i, xmin_i, xmax_i); - cell_list_reset (coverages); - - active->min_height -= GRID_Y; - } -} - -struct _cairo_tor22_scan_converter { - cairo_scan_converter_t base; - - glitter_scan_converter_t converter[1]; - cairo_fill_rule_t fill_rule; - cairo_antialias_t antialias; - - jmp_buf jmp; -}; - -typedef struct _cairo_tor22_scan_converter cairo_tor22_scan_converter_t; - -static void -_cairo_tor22_scan_converter_destroy (void *converter) -{ - cairo_tor22_scan_converter_t *self = converter; - if (self == NULL) { - return; - } - _glitter_scan_converter_fini (self->converter); - free(self); -} - -cairo_status_t -_cairo_tor22_scan_converter_add_polygon (void *converter, - const cairo_polygon_t *polygon) -{ - cairo_tor22_scan_converter_t *self = converter; - int i; - -#if 0 - FILE *file = fopen ("polygon.txt", "w"); - _cairo_debug_print_polygon (file, polygon); - fclose (file); -#endif - - for (i = 0; i < polygon->num_edges; i++) - glitter_scan_converter_add_edge (self->converter, &polygon->edges[i]); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_tor22_scan_converter_generate (void *converter, - cairo_span_renderer_t *renderer) -{ - cairo_tor22_scan_converter_t *self = converter; - cairo_status_t status; - - if ((status = setjmp (self->jmp))) - return _cairo_scan_converter_set_error (self, _cairo_error (status)); - - glitter_scan_converter_render (self->converter, - self->fill_rule == CAIRO_FILL_RULE_WINDING ? ~0 : 1, - self->antialias != CAIRO_ANTIALIAS_NONE, - renderer); - return CAIRO_STATUS_SUCCESS; -} - -cairo_scan_converter_t * -_cairo_tor22_scan_converter_create (int xmin, - int ymin, - int xmax, - int ymax, - cairo_fill_rule_t fill_rule, - cairo_antialias_t antialias) -{ - cairo_tor22_scan_converter_t *self; - cairo_status_t status; - - self = malloc (sizeof(struct _cairo_tor22_scan_converter)); - if (unlikely (self == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto bail_nomem; - } - - self->base.destroy = _cairo_tor22_scan_converter_destroy; - self->base.generate = _cairo_tor22_scan_converter_generate; - - _glitter_scan_converter_init (self->converter, &self->jmp); - status = glitter_scan_converter_reset (self->converter, - xmin, ymin, xmax, ymax); - if (unlikely (status)) - goto bail; - - self->fill_rule = fill_rule; - self->antialias = antialias; - - return &self->base; - - bail: - self->base.destroy(&self->base); - bail_nomem: - return _cairo_scan_converter_create_in_error (status); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-toy-font-face.c b/source/libs/cairo/cairo-src/src/cairo-toy-font-face.c deleted file mode 100644 index 4fe94ab091939ae9f184ae91f3a45733caa3cb95..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-toy-font-face.c +++ /dev/null @@ -1,524 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005,2008 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Graydon Hoare <graydon@redhat.com> - * Owen Taylor <otaylor@redhat.com> - * Behdad Esfahbod <behdad@behdad.org> - */ - -#define _BSD_SOURCE /* for strdup() */ -#include "cairoint.h" -#include "cairo-error-private.h" - - -static const cairo_font_face_t _cairo_font_face_null_pointer = { - { 0 }, /* hash_entry */ - CAIRO_STATUS_NULL_POINTER, /* status */ - CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ - { 0, 0, 0, NULL }, /* user_data */ - NULL -}; - -static const cairo_font_face_t _cairo_font_face_invalid_string = { - { 0 }, /* hash_entry */ - CAIRO_STATUS_INVALID_STRING, /* status */ - CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ - { 0, 0, 0, NULL }, /* user_data */ - NULL -}; - -static const cairo_font_face_t _cairo_font_face_invalid_slant = { - { 0 }, /* hash_entry */ - CAIRO_STATUS_INVALID_SLANT, /* status */ - CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ - { 0, 0, 0, NULL }, /* user_data */ - NULL -}; - -static const cairo_font_face_t _cairo_font_face_invalid_weight = { - { 0 }, /* hash_entry */ - CAIRO_STATUS_INVALID_WEIGHT, /* status */ - CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ - { 0, 0, 0, NULL }, /* user_data */ - NULL -}; - - -static const cairo_font_face_backend_t _cairo_toy_font_face_backend; - -static int -_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 - * this mapping is to provide unique #cairo_font_face_t values so that - * our cache and mapping from #cairo_font_face_t => #cairo_scaled_font_t - * works. Once the corresponding #cairo_font_face_t objects fall out of - * downstream caches, we don't need them in this hash table anymore. - * - * Modifications to this hash table are protected by - * _cairo_toy_font_face_mutex. - */ -static cairo_hash_table_t *cairo_toy_font_face_hash_table = NULL; - -static cairo_hash_table_t * -_cairo_toy_font_face_hash_table_lock (void) -{ - CAIRO_MUTEX_LOCK (_cairo_toy_font_face_mutex); - - if (cairo_toy_font_face_hash_table == NULL) - { - cairo_toy_font_face_hash_table = - _cairo_hash_table_create (_cairo_toy_font_face_keys_equal); - - if (cairo_toy_font_face_hash_table == NULL) { - CAIRO_MUTEX_UNLOCK (_cairo_toy_font_face_mutex); - return NULL; - } - } - - return cairo_toy_font_face_hash_table; -} - -static void -_cairo_toy_font_face_hash_table_unlock (void) -{ - CAIRO_MUTEX_UNLOCK (_cairo_toy_font_face_mutex); -} - -/** - * _cairo_toy_font_face_init_key: - * - * Initialize those portions of #cairo_toy_font_face_t needed to use - * it as a hash table key, including the hash code buried away in - * font_face->base.hash_entry. No memory allocation is performed here - * so that no fini call is needed. We do this to make it easier to use - * an automatic #cairo_toy_font_face_t variable as a key. - **/ -static void -_cairo_toy_font_face_init_key (cairo_toy_font_face_t *key, - const char *family, - cairo_font_slant_t slant, - cairo_font_weight_t weight) -{ - unsigned long hash; - - key->family = family; - key->owns_family = FALSE; - - key->slant = slant; - key->weight = weight; - - /* 1607 and 1451 are just a couple of arbitrary primes. */ - hash = _cairo_hash_string (family); - hash += ((unsigned long) slant) * 1607; - hash += ((unsigned long) weight) * 1451; - - key->base.hash_entry.hash = hash; -} - -static cairo_status_t -_cairo_toy_font_face_create_impl_face (cairo_toy_font_face_t *font_face, - cairo_font_face_t **impl_font_face) -{ - const cairo_font_face_backend_t * backend = CAIRO_FONT_FACE_BACKEND_DEFAULT; - cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED; - - if (unlikely (font_face->base.status)) - return font_face->base.status; - - if (backend->create_for_toy != NULL && - 0 != strncmp (font_face->family, CAIRO_USER_FONT_FAMILY_DEFAULT, - strlen (CAIRO_USER_FONT_FAMILY_DEFAULT))) - { - status = backend->create_for_toy (font_face, impl_font_face); - } - - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - backend = &_cairo_user_font_face_backend; - status = backend->create_for_toy (font_face, impl_font_face); - } - - return status; -} - -static cairo_status_t -_cairo_toy_font_face_init (cairo_toy_font_face_t *font_face, - const char *family, - cairo_font_slant_t slant, - cairo_font_weight_t weight) -{ - char *family_copy; - cairo_status_t status; - - family_copy = strdup (family); - if (unlikely (family_copy == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_toy_font_face_init_key (font_face, family_copy, slant, weight); - font_face->owns_family = TRUE; - - _cairo_font_face_init (&font_face->base, &_cairo_toy_font_face_backend); - - status = _cairo_toy_font_face_create_impl_face (font_face, - &font_face->impl_face); - if (unlikely (status)) { - free (family_copy); - return status; - } - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_toy_font_face_fini (cairo_toy_font_face_t *font_face) -{ - /* We assert here that we own font_face->family before casting - * away the const qualifer. */ - assert (font_face->owns_family); - free ((char*) font_face->family); - - if (font_face->impl_face) - cairo_font_face_destroy (font_face->impl_face); -} - -static int -_cairo_toy_font_face_keys_equal (const void *key_a, - const void *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 && - face_a->weight == face_b->weight); -} - -/** - * cairo_toy_font_face_create: - * @family: a font family name, encoded in UTF-8 - * @slant: the slant for the font - * @weight: the weight for the font - * - * Creates a font face from a triplet of family, slant, and weight. - * These font faces are used in implementation of the the #cairo_t "toy" - * font API. - * - * If @family is the zero-length string "", the platform-specific default - * family is assumed. The default family then can be queried using - * cairo_toy_font_face_get_family(). - * - * The cairo_select_font_face() function uses this to create font faces. - * See that function for limitations and other details of toy font faces. - * - * Return value: a newly created #cairo_font_face_t. Free with - * cairo_font_face_destroy() when you are done using it. - * - * Since: 1.8 - **/ -cairo_font_face_t * -cairo_toy_font_face_create (const char *family, - cairo_font_slant_t slant, - cairo_font_weight_t weight) -{ - cairo_status_t status; - cairo_toy_font_face_t key, *font_face; - cairo_hash_table_t *hash_table; - - if (family == NULL) - return (cairo_font_face_t*) &_cairo_font_face_null_pointer; - - /* Make sure we've got valid UTF-8 for the family */ - status = _cairo_utf8_to_ucs4 (family, -1, NULL, NULL); - if (unlikely (status)) { - if (status == CAIRO_STATUS_INVALID_STRING) - return (cairo_font_face_t*) &_cairo_font_face_invalid_string; - - return (cairo_font_face_t*) &_cairo_font_face_nil; - } - - switch (slant) { - case CAIRO_FONT_SLANT_NORMAL: - case CAIRO_FONT_SLANT_ITALIC: - case CAIRO_FONT_SLANT_OBLIQUE: - break; - default: - return (cairo_font_face_t*) &_cairo_font_face_invalid_slant; - } - - switch (weight) { - case CAIRO_FONT_WEIGHT_NORMAL: - case CAIRO_FONT_WEIGHT_BOLD: - break; - default: - return (cairo_font_face_t*) &_cairo_font_face_invalid_weight; - } - - if (*family == '\0') - family = CAIRO_FONT_FAMILY_DEFAULT; - - hash_table = _cairo_toy_font_face_hash_table_lock (); - if (unlikely (hash_table == NULL)) - goto UNWIND; - - _cairo_toy_font_face_init_key (&key, family, slant, weight); - - /* Return existing font_face if it exists in the hash table. */ - font_face = _cairo_hash_table_lookup (hash_table, - &key.base.hash_entry); - if (font_face != NULL) { - if (font_face->base.status == CAIRO_STATUS_SUCCESS) { - cairo_font_face_reference (&font_face->base); - _cairo_toy_font_face_hash_table_unlock (); - return &font_face->base; - } - - /* remove the bad font from the hash table */ - _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry); - } - - /* Otherwise create it and insert into hash table. */ - font_face = malloc (sizeof (cairo_toy_font_face_t)); - if (unlikely (font_face == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto UNWIND_HASH_TABLE_LOCK; - } - - status = _cairo_toy_font_face_init (font_face, family, slant, weight); - if (unlikely (status)) - goto UNWIND_FONT_FACE_MALLOC; - - assert (font_face->base.hash_entry.hash == key.base.hash_entry.hash); - status = _cairo_hash_table_insert (hash_table, &font_face->base.hash_entry); - if (unlikely (status)) - goto UNWIND_FONT_FACE_INIT; - - _cairo_toy_font_face_hash_table_unlock (); - - return &font_face->base; - - UNWIND_FONT_FACE_INIT: - _cairo_toy_font_face_fini (font_face); - UNWIND_FONT_FACE_MALLOC: - free (font_face); - UNWIND_HASH_TABLE_LOCK: - _cairo_toy_font_face_hash_table_unlock (); - UNWIND: - return (cairo_font_face_t*) &_cairo_font_face_nil; -} -slim_hidden_def (cairo_toy_font_face_create); - -static cairo_bool_t -_cairo_toy_font_face_destroy (void *abstract_face) -{ - cairo_toy_font_face_t *font_face = abstract_face; - cairo_hash_table_t *hash_table; - - hash_table = _cairo_toy_font_face_hash_table_lock (); - /* All created objects must have been mapped in the hash table. */ - assert (hash_table != NULL); - - if (! _cairo_reference_count_dec_and_test (&font_face->base.ref_count)) { - /* somebody recreated the font whilst we waited for the lock */ - _cairo_toy_font_face_hash_table_unlock (); - return FALSE; - } - - /* Font faces in SUCCESS status are guaranteed to be in the - * hashtable. Font faces in an error status are removed from the - * hashtable if they are found during a lookup, thus they should - * only be removed if they are in the hashtable. */ - if (likely (font_face->base.status == CAIRO_STATUS_SUCCESS) || - _cairo_hash_table_lookup (hash_table, &font_face->base.hash_entry) == font_face) - _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry); - - _cairo_toy_font_face_hash_table_unlock (); - - _cairo_toy_font_face_fini (font_face); - return TRUE; -} - -static cairo_status_t -_cairo_toy_font_face_scaled_font_create (void *abstract_font_face, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options, - cairo_scaled_font_t **scaled_font) -{ - cairo_toy_font_face_t *font_face = (cairo_toy_font_face_t *) abstract_font_face; - - ASSERT_NOT_REACHED; - - return _cairo_font_face_set_error (&font_face->base, CAIRO_STATUS_FONT_TYPE_MISMATCH); -} - -static cairo_font_face_t * -_cairo_toy_font_face_get_implementation (void *abstract_font_face, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options) -{ - cairo_toy_font_face_t *font_face = abstract_font_face; - - if (font_face->impl_face) { - cairo_font_face_t *impl = font_face->impl_face; - - if (impl->backend->get_implementation != NULL) { - return impl->backend->get_implementation (impl, - font_matrix, - ctm, - options); - } - - return cairo_font_face_reference (impl); - } - - return abstract_font_face; -} - -static cairo_bool_t -_cairo_font_face_is_toy (cairo_font_face_t *font_face) -{ - return font_face->backend == &_cairo_toy_font_face_backend; -} - -/** - * cairo_toy_font_face_get_family: - * @font_face: A toy font face - * - * Gets the familly name of a toy font. - * - * Return value: The family name. This string is owned by the font face - * and remains valid as long as the font face is alive (referenced). - * - * Since: 1.8 - **/ -const char * -cairo_toy_font_face_get_family (cairo_font_face_t *font_face) -{ - cairo_toy_font_face_t *toy_font_face; - - if (font_face->status) - return CAIRO_FONT_FAMILY_DEFAULT; - - toy_font_face = (cairo_toy_font_face_t *) font_face; - if (! _cairo_font_face_is_toy (font_face)) { - if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH)) - return CAIRO_FONT_FAMILY_DEFAULT; - } - assert (toy_font_face->owns_family); - return toy_font_face->family; -} - -/** - * cairo_toy_font_face_get_slant: - * @font_face: A toy font face - * - * Gets the slant a toy font. - * - * Return value: The slant value - * - * Since: 1.8 - **/ -cairo_font_slant_t -cairo_toy_font_face_get_slant (cairo_font_face_t *font_face) -{ - cairo_toy_font_face_t *toy_font_face; - - if (font_face->status) - return CAIRO_FONT_SLANT_DEFAULT; - - toy_font_face = (cairo_toy_font_face_t *) font_face; - if (! _cairo_font_face_is_toy (font_face)) { - if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH)) - return CAIRO_FONT_SLANT_DEFAULT; - } - return toy_font_face->slant; -} -slim_hidden_def (cairo_toy_font_face_get_slant); - -/** - * cairo_toy_font_face_get_weight: - * @font_face: A toy font face - * - * Gets the weight a toy font. - * - * Return value: The weight value - * - * Since: 1.8 - **/ -cairo_font_weight_t -cairo_toy_font_face_get_weight (cairo_font_face_t *font_face) -{ - cairo_toy_font_face_t *toy_font_face; - - if (font_face->status) - return CAIRO_FONT_WEIGHT_DEFAULT; - - toy_font_face = (cairo_toy_font_face_t *) font_face; - if (! _cairo_font_face_is_toy (font_face)) { - if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH)) - return CAIRO_FONT_WEIGHT_DEFAULT; - } - return toy_font_face->weight; -} -slim_hidden_def (cairo_toy_font_face_get_weight); - -static const cairo_font_face_backend_t _cairo_toy_font_face_backend = { - CAIRO_FONT_TYPE_TOY, - NULL, /* create_for_toy */ - _cairo_toy_font_face_destroy, - _cairo_toy_font_face_scaled_font_create, - _cairo_toy_font_face_get_implementation -}; - -void -_cairo_toy_font_face_reset_static_data (void) -{ - cairo_hash_table_t *hash_table; - - /* We manually acquire the lock rather than calling - * cairo_toy_font_face_hash_table_lock simply to avoid - * creating the table only to destroy it again. */ - CAIRO_MUTEX_LOCK (_cairo_toy_font_face_mutex); - hash_table = cairo_toy_font_face_hash_table; - cairo_toy_font_face_hash_table = NULL; - CAIRO_MUTEX_UNLOCK (_cairo_toy_font_face_mutex); - - if (hash_table != NULL) - _cairo_hash_table_destroy (hash_table); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-traps-compositor.c b/source/libs/cairo/cairo-src/src/cairo-traps-compositor.c deleted file mode 100644 index 3414fc2684a157aef75e5e5fd71b4eb5da548922..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-traps-compositor.c +++ /dev/null @@ -1,2351 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Joonas Pihlaja <jpihlaja@cc.helsinki.fi> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-box-inline.h" -#include "cairo-boxes-private.h" -#include "cairo-clip-inline.h" -#include "cairo-clip-private.h" -#include "cairo-composite-rectangles-private.h" -#include "cairo-compositor-private.h" -#include "cairo-error-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-pattern-inline.h" -#include "cairo-paginated-private.h" -#include "cairo-recording-surface-inline.h" -#include "cairo-surface-subsurface-private.h" -#include "cairo-surface-snapshot-inline.h" -#include "cairo-surface-observer-private.h" -#include "cairo-region-private.h" -#include "cairo-spans-private.h" -#include "cairo-traps-private.h" -#include "cairo-tristrip-private.h" - -typedef cairo_int_status_t -(*draw_func_t) (const cairo_traps_compositor_t *compositor, - cairo_surface_t *dst, - void *closure, - cairo_operator_t op, - cairo_surface_t *src, - int src_x, - int src_y, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents, - cairo_clip_t *clip); - -static void do_unaligned_row(void (*blt)(void *closure, - int16_t x, int16_t y, - int16_t w, int16_t h, - uint16_t coverage), - void *closure, - const cairo_box_t *b, - int tx, int y, int h, - uint16_t coverage) -{ - int x1 = _cairo_fixed_integer_part (b->p1.x) - tx; - int x2 = _cairo_fixed_integer_part (b->p2.x) - tx; - if (x2 > x1) { - if (! _cairo_fixed_is_integer (b->p1.x)) { - blt(closure, x1, y, 1, h, - coverage * (256 - _cairo_fixed_fractional_part (b->p1.x))); - x1++; - } - - if (x2 > x1) - blt(closure, x1, y, x2-x1, h, (coverage << 8) - (coverage >> 8)); - - if (! _cairo_fixed_is_integer (b->p2.x)) - blt(closure, x2, y, 1, h, - coverage * _cairo_fixed_fractional_part (b->p2.x)); - } else - blt(closure, x1, y, 1, h, - coverage * (b->p2.x - b->p1.x)); -} - -static void do_unaligned_box(void (*blt)(void *closure, - int16_t x, int16_t y, - int16_t w, int16_t h, - uint16_t coverage), - void *closure, - const cairo_box_t *b, int tx, int ty) -{ - int y1 = _cairo_fixed_integer_part (b->p1.y) - ty; - int y2 = _cairo_fixed_integer_part (b->p2.y) - ty; - if (y2 > y1) { - if (! _cairo_fixed_is_integer (b->p1.y)) { - do_unaligned_row(blt, closure, b, tx, y1, 1, - 256 - _cairo_fixed_fractional_part (b->p1.y)); - y1++; - } - - if (y2 > y1) - do_unaligned_row(blt, closure, b, tx, y1, y2-y1, 256); - - if (! _cairo_fixed_is_integer (b->p2.y)) - do_unaligned_row(blt, closure, b, tx, y2, 1, - _cairo_fixed_fractional_part (b->p2.y)); - } else - do_unaligned_row(blt, closure, b, tx, y1, 1, - b->p2.y - b->p1.y); -} - -struct blt_in { - const cairo_traps_compositor_t *compositor; - cairo_surface_t *dst; - cairo_boxes_t boxes; -}; - -static void blt_in(void *closure, - int16_t x, int16_t y, - int16_t w, int16_t h, - uint16_t coverage) -{ - struct blt_in *info = closure; - cairo_color_t color; - - if (CAIRO_ALPHA_SHORT_IS_OPAQUE (coverage)) - return; - - _cairo_box_from_integers (&info->boxes.chunks.base[0], x, y, w, h); - - _cairo_color_init_rgba (&color, 0, 0, 0, coverage / (double) 0xffff); - info->compositor->fill_boxes (info->dst, - CAIRO_OPERATOR_IN, &color, - &info->boxes); -} - -static void -add_rect_with_offset (cairo_boxes_t *boxes, int x1, int y1, int x2, int y2, int dx, int dy) -{ - cairo_box_t box; - cairo_int_status_t status; - - box.p1.x = _cairo_fixed_from_int (x1 - dx); - box.p1.y = _cairo_fixed_from_int (y1 - dy); - box.p2.x = _cairo_fixed_from_int (x2 - dx); - box.p2.y = _cairo_fixed_from_int (y2 - dy); - - status = _cairo_boxes_add (boxes, CAIRO_ANTIALIAS_DEFAULT, &box); - assert (status == CAIRO_INT_STATUS_SUCCESS); -} - -static cairo_int_status_t -combine_clip_as_traps (const cairo_traps_compositor_t *compositor, - cairo_surface_t *mask, - const cairo_clip_t *clip, - const cairo_rectangle_int_t *extents) -{ - cairo_polygon_t polygon; - cairo_fill_rule_t fill_rule; - cairo_antialias_t antialias; - cairo_traps_t traps; - cairo_surface_t *src; - cairo_box_t box; - cairo_rectangle_int_t fixup; - int src_x, src_y; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - status = _cairo_clip_get_polygon (clip, &polygon, - &fill_rule, &antialias); - if (status) - return status; - - _cairo_traps_init (&traps); - status = _cairo_bentley_ottmann_tessellate_polygon (&traps, - &polygon, - fill_rule); - _cairo_polygon_fini (&polygon); - if (unlikely (status)) - return status; - - src = compositor->pattern_to_surface (mask, NULL, FALSE, - extents, NULL, - &src_x, &src_y); - if (unlikely (src->status)) { - _cairo_traps_fini (&traps); - return src->status; - } - - status = compositor->composite_traps (mask, CAIRO_OPERATOR_IN, src, - src_x, src_y, - extents->x, extents->y, - extents, - antialias, &traps); - - _cairo_traps_extents (&traps, &box); - _cairo_box_round_to_rectangle (&box, &fixup); - _cairo_traps_fini (&traps); - cairo_surface_destroy (src); - - if (unlikely (status)) - return status; - - if (! _cairo_rectangle_intersect (&fixup, extents)) - return CAIRO_STATUS_SUCCESS; - - if (fixup.width < extents->width || fixup.height < extents->height) { - cairo_boxes_t clear; - - _cairo_boxes_init (&clear); - - /* top */ - if (fixup.y != extents->y) { - add_rect_with_offset (&clear, - extents->x, extents->y, - extents->x + extents->width, - fixup.y, - extents->x, extents->y); - } - /* left */ - if (fixup.x != extents->x) { - add_rect_with_offset (&clear, - extents->x, fixup.y, - fixup.x, - fixup.y + fixup.height, - extents->x, extents->y); - } - /* right */ - if (fixup.x + fixup.width != extents->x + extents->width) { - add_rect_with_offset (&clear, - fixup.x + fixup.width, - fixup.y, - extents->x + extents->width, - fixup.y + fixup.height, - extents->x, extents->y); - } - /* bottom */ - if (fixup.y + fixup.height != extents->y + extents->height) { - add_rect_with_offset (&clear, - extents->x, - fixup.y + fixup.height, - extents->x + extents->width, - extents->y + extents->height, - extents->x, extents->y); - } - - status = compositor->fill_boxes (mask, - CAIRO_OPERATOR_CLEAR, - CAIRO_COLOR_TRANSPARENT, - &clear); - - _cairo_boxes_fini (&clear); - } - - return status; -} - -static cairo_status_t -__clip_to_surface (const cairo_traps_compositor_t *compositor, - const cairo_composite_rectangles_t *composite, - const cairo_rectangle_int_t *extents, - cairo_surface_t **surface) -{ - cairo_surface_t *mask; - cairo_polygon_t polygon; - cairo_fill_rule_t fill_rule; - cairo_antialias_t antialias; - cairo_traps_t traps; - cairo_boxes_t clear; - cairo_surface_t *src; - int src_x, src_y; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - status = _cairo_clip_get_polygon (composite->clip, &polygon, - &fill_rule, &antialias); - if (status) - return status; - - _cairo_traps_init (&traps); - status = _cairo_bentley_ottmann_tessellate_polygon (&traps, - &polygon, - fill_rule); - _cairo_polygon_fini (&polygon); - if (unlikely (status)) - return status; - - mask = _cairo_surface_create_scratch (composite->surface, - CAIRO_CONTENT_ALPHA, - extents->width, - extents->height, - NULL); - if (unlikely (mask->status)) { - _cairo_traps_fini (&traps); - return status; - } - - src = compositor->pattern_to_surface (mask, NULL, FALSE, - extents, NULL, - &src_x, &src_y); - if (unlikely (status = src->status)) - goto error; - - status = compositor->acquire (mask); - if (unlikely (status)) - goto error; - - _cairo_boxes_init_from_rectangle (&clear, - 0, 0, - extents->width, - extents->height); - status = compositor->fill_boxes (mask, - CAIRO_OPERATOR_CLEAR, - CAIRO_COLOR_TRANSPARENT, - &clear); - if (unlikely (status)) - goto error_release; - - status = compositor->composite_traps (mask, CAIRO_OPERATOR_ADD, src, - src_x, src_y, - extents->x, extents->y, - extents, - antialias, &traps); - if (unlikely (status)) - goto error_release; - - compositor->release (mask); - *surface = mask; -out: - cairo_surface_destroy (src); - _cairo_traps_fini (&traps); - return status; - -error_release: - compositor->release (mask); -error: - cairo_surface_destroy (mask); - goto out; -} - -static cairo_surface_t * -traps_get_clip_surface (const cairo_traps_compositor_t *compositor, - const cairo_composite_rectangles_t *composite, - const cairo_rectangle_int_t *extents) -{ - cairo_surface_t *surface = NULL; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - status = __clip_to_surface (compositor, composite, extents, &surface); - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - surface = _cairo_surface_create_scratch (composite->surface, - CAIRO_CONTENT_ALPHA, - extents->width, - extents->height, - CAIRO_COLOR_WHITE); - if (unlikely (surface->status)) - return surface; - - status = _cairo_clip_combine_with_surface (composite->clip, surface, - extents->x, extents->y); - } - if (unlikely (status)) { - cairo_surface_destroy (surface); - surface = _cairo_surface_create_in_error (status); - } - - return surface; -} - -static void blt_unaligned_boxes(const cairo_traps_compositor_t *compositor, - cairo_surface_t *surface, - int dx, int dy, - cairo_box_t *boxes, - int num_boxes) -{ - struct blt_in info; - int i; - - info.compositor = compositor; - info.dst = surface; - _cairo_boxes_init (&info.boxes); - info.boxes.num_boxes = 1; - for (i = 0; i < num_boxes; i++) { - cairo_box_t *b = &boxes[i]; - - if (! _cairo_fixed_is_integer (b->p1.x) || - ! _cairo_fixed_is_integer (b->p1.y) || - ! _cairo_fixed_is_integer (b->p2.x) || - ! _cairo_fixed_is_integer (b->p2.y)) - { - do_unaligned_box(blt_in, &info, b, dx, dy); - } - } -} - -static cairo_surface_t * -create_composite_mask (const cairo_traps_compositor_t *compositor, - cairo_surface_t *dst, - void *draw_closure, - draw_func_t draw_func, - draw_func_t mask_func, - const cairo_composite_rectangles_t *extents) -{ - cairo_surface_t *surface, *src; - cairo_int_status_t status; - int src_x, src_y; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - surface = _cairo_surface_create_scratch (dst, CAIRO_CONTENT_ALPHA, - extents->bounded.width, - extents->bounded.height, - NULL); - if (unlikely (surface->status)) - return surface; - - src = compositor->pattern_to_surface (surface, - &_cairo_pattern_white.base, - FALSE, - &extents->bounded, - &extents->bounded, - &src_x, &src_y); - if (unlikely (src->status)) { - cairo_surface_destroy (surface); - return src; - } - - status = compositor->acquire (surface); - if (unlikely (status)) { - cairo_surface_destroy (src); - cairo_surface_destroy (surface); - return _cairo_surface_create_in_error (status); - } - - if (!surface->is_clear) { - cairo_boxes_t clear; - - _cairo_boxes_init_from_rectangle (&clear, - 0, 0, - extents->bounded.width, - extents->bounded.height); - status = compositor->fill_boxes (surface, - CAIRO_OPERATOR_CLEAR, - CAIRO_COLOR_TRANSPARENT, - &clear); - if (unlikely (status)) - goto error; - - surface->is_clear = TRUE; - } - - if (mask_func) { - status = mask_func (compositor, surface, draw_closure, - CAIRO_OPERATOR_SOURCE, src, src_x, src_y, - extents->bounded.x, extents->bounded.y, - &extents->bounded, extents->clip); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) { - surface->is_clear = FALSE; - goto out; - } - if (unlikely (status != CAIRO_INT_STATUS_UNSUPPORTED)) - goto error; - } - - /* Is it worth setting the clip region here? */ - status = draw_func (compositor, surface, draw_closure, - CAIRO_OPERATOR_ADD, src, src_x, src_y, - extents->bounded.x, extents->bounded.y, - &extents->bounded, NULL); - if (unlikely (status)) - goto error; - - surface->is_clear = FALSE; - if (extents->clip->path != NULL) { - status = combine_clip_as_traps (compositor, surface, - extents->clip, &extents->bounded); - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - status = _cairo_clip_combine_with_surface (extents->clip, surface, - extents->bounded.x, - extents->bounded.y); - } - if (unlikely (status)) - goto error; - } else if (extents->clip->boxes) { - blt_unaligned_boxes(compositor, surface, - extents->bounded.x, extents->bounded.y, - extents->clip->boxes, extents->clip->num_boxes); - - } - -out: - compositor->release (surface); - cairo_surface_destroy (src); - return surface; - -error: - compositor->release (surface); - if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) { - cairo_surface_destroy (surface); - surface = _cairo_surface_create_in_error (status); - } - cairo_surface_destroy (src); - return surface; -} - -/* Handles compositing with a clip surface when the operator allows - * us to combine the clip with the mask - */ -static cairo_status_t -clip_and_composite_with_mask (const cairo_traps_compositor_t *compositor, - const cairo_composite_rectangles_t*extents, - draw_func_t draw_func, - draw_func_t mask_func, - void *draw_closure, - cairo_operator_t op, - cairo_surface_t *src, - int src_x, int src_y) -{ - cairo_surface_t *dst = extents->surface; - cairo_surface_t *mask; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - mask = create_composite_mask (compositor, dst, draw_closure, - draw_func, mask_func, - extents); - if (unlikely (mask->status)) - return mask->status; - - if (mask->is_clear) - goto skip; - - if (src != NULL || dst->content != CAIRO_CONTENT_ALPHA) { - compositor->composite (dst, op, src, mask, - extents->bounded.x + src_x, - extents->bounded.y + src_y, - 0, 0, - extents->bounded.x, extents->bounded.y, - extents->bounded.width, extents->bounded.height); - } else { - compositor->composite (dst, op, mask, NULL, - 0, 0, - 0, 0, - extents->bounded.x, extents->bounded.y, - extents->bounded.width, extents->bounded.height); - } - -skip: - cairo_surface_destroy (mask); - return CAIRO_STATUS_SUCCESS; -} - -/* Handles compositing with a clip surface when we have to do the operation - * in two pieces and combine them together. - */ -static cairo_status_t -clip_and_composite_combine (const cairo_traps_compositor_t *compositor, - const cairo_composite_rectangles_t*extents, - draw_func_t draw_func, - void *draw_closure, - cairo_operator_t op, - cairo_surface_t *src, - int src_x, int src_y) -{ - cairo_surface_t *dst = extents->surface; - cairo_surface_t *tmp, *clip; - cairo_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - tmp = _cairo_surface_create_scratch (dst, dst->content, - extents->bounded.width, - extents->bounded.height, - NULL); - if (unlikely (tmp->status)) - return tmp->status; - - status = compositor->acquire (tmp); - if (unlikely (status)) { - cairo_surface_destroy (tmp); - return status; - } - - compositor->composite (tmp, - dst->is_clear ? CAIRO_OPERATOR_CLEAR : CAIRO_OPERATOR_SOURCE, - dst, NULL, - extents->bounded.x, extents->bounded.y, - 0, 0, - 0, 0, - extents->bounded.width, extents->bounded.height); - - status = draw_func (compositor, tmp, draw_closure, op, - src, src_x, src_y, - extents->bounded.x, extents->bounded.y, - &extents->bounded, NULL); - - if (unlikely (status)) - goto cleanup; - - clip = traps_get_clip_surface (compositor, extents, &extents->bounded); - if (unlikely ((status = clip->status))) - goto cleanup; - - if (dst->is_clear) { - compositor->composite (dst, CAIRO_OPERATOR_SOURCE, tmp, clip, - 0, 0, - 0, 0, - extents->bounded.x, extents->bounded.y, - extents->bounded.width, extents->bounded.height); - } else { - compositor->lerp (dst, tmp, clip, - 0, 0, - 0,0, - extents->bounded.x, extents->bounded.y, - extents->bounded.width, extents->bounded.height); - } - cairo_surface_destroy (clip); - -cleanup: - compositor->release (tmp); - cairo_surface_destroy (tmp); - - return status; -} - -/* Handles compositing for %CAIRO_OPERATOR_SOURCE, which is special; it's - * defined as (src IN mask IN clip) ADD (dst OUT (mask IN clip)) - */ -static cairo_status_t -clip_and_composite_source (const cairo_traps_compositor_t *compositor, - cairo_surface_t *dst, - draw_func_t draw_func, - draw_func_t mask_func, - void *draw_closure, - cairo_surface_t *src, - int src_x, - int src_y, - const cairo_composite_rectangles_t *extents) -{ - cairo_surface_t *mask; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - /* Create a surface that is mask IN clip */ - mask = create_composite_mask (compositor, dst, draw_closure, - draw_func, mask_func, - extents); - if (unlikely (mask->status)) - return mask->status; - - if (mask->is_clear) - goto skip; - - if (dst->is_clear) { - compositor->composite (dst, CAIRO_OPERATOR_SOURCE, src, mask, - extents->bounded.x + src_x, extents->bounded.y + src_y, - 0, 0, - extents->bounded.x, extents->bounded.y, - extents->bounded.width, extents->bounded.height); - } else { - compositor->lerp (dst, src, mask, - extents->bounded.x + src_x, extents->bounded.y + src_y, - 0, 0, - extents->bounded.x, extents->bounded.y, - extents->bounded.width, extents->bounded.height); - } - -skip: - cairo_surface_destroy (mask); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_bool_t -can_reduce_alpha_op (cairo_operator_t op) -{ - int iop = op; - switch (iop) { - case CAIRO_OPERATOR_OVER: - case CAIRO_OPERATOR_SOURCE: - case CAIRO_OPERATOR_ADD: - return TRUE; - default: - return FALSE; - } -} - -static cairo_bool_t -reduce_alpha_op (cairo_composite_rectangles_t *extents) -{ - cairo_surface_t *dst = extents->surface; - cairo_operator_t op = extents->op; - const cairo_pattern_t *pattern = &extents->source_pattern.base; - return dst->is_clear && - dst->content == CAIRO_CONTENT_ALPHA && - _cairo_pattern_is_opaque_solid (pattern) && - can_reduce_alpha_op (op); -} - -static cairo_status_t -fixup_unbounded_with_mask (const cairo_traps_compositor_t *compositor, - const cairo_composite_rectangles_t *extents) -{ - cairo_surface_t *dst = extents->surface; - cairo_surface_t *mask; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - /* XXX can we avoid querying the clip surface again? */ - mask = traps_get_clip_surface (compositor, extents, &extents->unbounded); - if (unlikely (mask->status)) - return mask->status; - - /* top */ - if (extents->bounded.y != extents->unbounded.y) { - int x = extents->unbounded.x; - int y = extents->unbounded.y; - int width = extents->unbounded.width; - int height = extents->bounded.y - y; - - compositor->composite (dst, CAIRO_OPERATOR_DEST_OUT, mask, NULL, - 0, 0, - 0, 0, - x, y, - width, height); - } - - /* left */ - if (extents->bounded.x != extents->unbounded.x) { - int x = extents->unbounded.x; - int y = extents->bounded.y; - int width = extents->bounded.x - x; - int height = extents->bounded.height; - - compositor->composite (dst, CAIRO_OPERATOR_DEST_OUT, mask, NULL, - 0, y - extents->unbounded.y, - 0, 0, - x, y, - width, height); - } - - /* right */ - if (extents->bounded.x + extents->bounded.width != extents->unbounded.x + extents->unbounded.width) { - int x = extents->bounded.x + extents->bounded.width; - int y = extents->bounded.y; - int width = extents->unbounded.x + extents->unbounded.width - x; - int height = extents->bounded.height; - - compositor->composite (dst, CAIRO_OPERATOR_DEST_OUT, mask, NULL, - x - extents->unbounded.x, y - extents->unbounded.y, - 0, 0, - x, y, - width, height); - } - - /* bottom */ - if (extents->bounded.y + extents->bounded.height != extents->unbounded.y + extents->unbounded.height) { - int x = extents->unbounded.x; - int y = extents->bounded.y + extents->bounded.height; - int width = extents->unbounded.width; - int height = extents->unbounded.y + extents->unbounded.height - y; - - compositor->composite (dst, CAIRO_OPERATOR_DEST_OUT, mask, NULL, - 0, y - extents->unbounded.y, - 0, 0, - x, y, - width, height); - } - - cairo_surface_destroy (mask); - - return CAIRO_STATUS_SUCCESS; -} - -static void -add_rect (cairo_boxes_t *boxes, int x1, int y1, int x2, int y2) -{ - cairo_box_t box; - cairo_int_status_t status; - - box.p1.x = _cairo_fixed_from_int (x1); - box.p1.y = _cairo_fixed_from_int (y1); - box.p2.x = _cairo_fixed_from_int (x2); - box.p2.y = _cairo_fixed_from_int (y2); - - status = _cairo_boxes_add (boxes, CAIRO_ANTIALIAS_DEFAULT, &box); - assert (status == CAIRO_INT_STATUS_SUCCESS); -} - -static cairo_status_t -fixup_unbounded (const cairo_traps_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - cairo_boxes_t *boxes) -{ - cairo_surface_t *dst = extents->surface; - cairo_boxes_t clear, tmp; - cairo_box_t box; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - if (extents->bounded.width == extents->unbounded.width && - extents->bounded.height == extents->unbounded.height) - { - return CAIRO_STATUS_SUCCESS; - } - - assert (extents->clip->path == NULL); - - /* subtract the drawn boxes from the unbounded area */ - _cairo_boxes_init (&clear); - - box.p1.x = _cairo_fixed_from_int (extents->unbounded.x + extents->unbounded.width); - box.p1.y = _cairo_fixed_from_int (extents->unbounded.y); - box.p2.x = _cairo_fixed_from_int (extents->unbounded.x); - box.p2.y = _cairo_fixed_from_int (extents->unbounded.y + extents->unbounded.height); - - if (boxes == NULL) { - if (extents->bounded.width == 0 || extents->bounded.height == 0) { - goto empty; - } else { - /* top */ - if (extents->bounded.y != extents->unbounded.y) { - add_rect (&clear, - extents->unbounded.x, extents->unbounded.y, - extents->unbounded.x + extents->unbounded.width, - extents->bounded.y); - } - /* left */ - if (extents->bounded.x != extents->unbounded.x) { - add_rect (&clear, - extents->unbounded.x, extents->bounded.y, - extents->bounded.x, - extents->bounded.y + extents->bounded.height); - } - /* right */ - if (extents->bounded.x + extents->bounded.width != extents->unbounded.x + extents->unbounded.width) { - add_rect (&clear, - extents->bounded.x + extents->bounded.width, - extents->bounded.y, - extents->unbounded.x + extents->unbounded.width, - extents->bounded.y + extents->bounded.height); - } - /* bottom */ - if (extents->bounded.y + extents->bounded.height != extents->unbounded.y + extents->unbounded.height) { - add_rect (&clear, - extents->unbounded.x, - extents->bounded.y + extents->bounded.height, - extents->unbounded.x + extents->unbounded.width, - extents->unbounded.y + extents->unbounded.height); - } - } - } else if (boxes->num_boxes) { - _cairo_boxes_init (&tmp); - - assert (boxes->is_pixel_aligned); - - status = _cairo_boxes_add (&tmp, CAIRO_ANTIALIAS_DEFAULT, &box); - assert (status == CAIRO_INT_STATUS_SUCCESS); - - tmp.chunks.next = &boxes->chunks; - tmp.num_boxes += boxes->num_boxes; - - status = _cairo_bentley_ottmann_tessellate_boxes (&tmp, - CAIRO_FILL_RULE_WINDING, - &clear); - tmp.chunks.next = NULL; - if (unlikely (status)) - goto error; - } else { -empty: - box.p1.x = _cairo_fixed_from_int (extents->unbounded.x); - box.p2.x = _cairo_fixed_from_int (extents->unbounded.x + extents->unbounded.width); - - status = _cairo_boxes_add (&clear, CAIRO_ANTIALIAS_DEFAULT, &box); - assert (status == CAIRO_INT_STATUS_SUCCESS); - } - - /* Now intersect with the clip boxes */ - if (extents->clip->num_boxes) { - _cairo_boxes_init_for_array (&tmp, - extents->clip->boxes, - extents->clip->num_boxes); - status = _cairo_boxes_intersect (&clear, &tmp, &clear); - if (unlikely (status)) - goto error; - } - - status = compositor->fill_boxes (dst, - CAIRO_OPERATOR_CLEAR, - CAIRO_COLOR_TRANSPARENT, - &clear); - -error: - _cairo_boxes_fini (&clear); - return status; -} - -enum { - NEED_CLIP_REGION = 0x1, - NEED_CLIP_SURFACE = 0x2, - FORCE_CLIP_REGION = 0x4, -}; - -static cairo_bool_t -need_bounded_clip (cairo_composite_rectangles_t *extents) -{ - unsigned int flags = 0; - - if (extents->clip->num_boxes > 1 || - extents->mask.width > extents->unbounded.width || - extents->mask.height > extents->unbounded.height) - { - flags |= NEED_CLIP_REGION; - } - - if (extents->clip->num_boxes > 1 || - extents->mask.width > extents->bounded.width || - extents->mask.height > extents->bounded.height) - { - flags |= FORCE_CLIP_REGION; - } - - if (! _cairo_clip_is_region (extents->clip)) - flags |= NEED_CLIP_SURFACE; - - return flags; -} - -static cairo_bool_t -need_unbounded_clip (cairo_composite_rectangles_t *extents) -{ - unsigned int flags = 0; - if (! extents->is_bounded) { - flags |= NEED_CLIP_REGION; - if (! _cairo_clip_is_region (extents->clip)) - flags |= NEED_CLIP_SURFACE; - } - if (extents->clip->path != NULL) - flags |= NEED_CLIP_SURFACE; - return flags; -} - -static cairo_status_t -clip_and_composite (const cairo_traps_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - draw_func_t draw_func, - draw_func_t mask_func, - void *draw_closure, - unsigned int need_clip) -{ - cairo_surface_t *dst = extents->surface; - cairo_operator_t op = extents->op; - cairo_pattern_t *source = &extents->source_pattern.base; - cairo_surface_t *src; - int src_x, src_y; - cairo_region_t *clip_region = NULL; - cairo_status_t status = CAIRO_STATUS_SUCCESS; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - if (reduce_alpha_op (extents)) { - op = CAIRO_OPERATOR_ADD; - source = NULL; - } - - if (op == CAIRO_OPERATOR_CLEAR) { - op = CAIRO_OPERATOR_DEST_OUT; - source = NULL; - } - - compositor->acquire (dst); - - if (need_clip & NEED_CLIP_REGION) { - const cairo_rectangle_int_t *limit; - - if ((need_clip & FORCE_CLIP_REGION) == 0) - limit = &extents->unbounded; - else - limit = &extents->destination; - - clip_region = _cairo_clip_get_region (extents->clip); - if (clip_region != NULL && - cairo_region_contains_rectangle (clip_region, - limit) == CAIRO_REGION_OVERLAP_IN) - clip_region = NULL; - - if (clip_region != NULL) { - status = compositor->set_clip_region (dst, clip_region); - if (unlikely (status)) { - compositor->release (dst); - return status; - } - } - } - - if (extents->bounded.width == 0 || extents->bounded.height == 0) - goto skip; - - src = compositor->pattern_to_surface (dst, source, FALSE, - &extents->bounded, - &extents->source_sample_area, - &src_x, &src_y); - if (unlikely (status = src->status)) - goto error; - - if (op == CAIRO_OPERATOR_SOURCE) { - status = clip_and_composite_source (compositor, dst, - draw_func, mask_func, draw_closure, - src, src_x, src_y, - extents); - } else { - if (need_clip & NEED_CLIP_SURFACE) { - if (extents->is_bounded) { - status = clip_and_composite_with_mask (compositor, extents, - draw_func, mask_func, - draw_closure, - op, src, src_x, src_y); - } else { - status = clip_and_composite_combine (compositor, extents, - draw_func, draw_closure, - op, src, src_x, src_y); - } - } else { - status = draw_func (compositor, - dst, draw_closure, - op, src, src_x, src_y, - 0, 0, - &extents->bounded, - extents->clip); - } - } - cairo_surface_destroy (src); - -skip: - if (status == CAIRO_STATUS_SUCCESS && ! extents->is_bounded) { - if (need_clip & NEED_CLIP_SURFACE) - status = fixup_unbounded_with_mask (compositor, extents); - else - status = fixup_unbounded (compositor, extents, NULL); - } - -error: - if (clip_region) - compositor->set_clip_region (dst, NULL); - - compositor->release (dst); - - return status; -} - -/* meta-ops */ - -typedef struct { - cairo_traps_t traps; - cairo_antialias_t antialias; -} composite_traps_info_t; - -static cairo_int_status_t -composite_traps (const cairo_traps_compositor_t *compositor, - cairo_surface_t *dst, - void *closure, - cairo_operator_t op, - cairo_surface_t *src, - int src_x, int src_y, - int dst_x, int dst_y, - const cairo_rectangle_int_t *extents, - cairo_clip_t *clip) -{ - composite_traps_info_t *info = closure; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - return compositor->composite_traps (dst, op, src, - src_x - dst_x, src_y - dst_y, - dst_x, dst_y, - extents, - info->antialias, &info->traps); -} - -typedef struct { - cairo_tristrip_t strip; - cairo_antialias_t antialias; -} composite_tristrip_info_t; - -static cairo_int_status_t -composite_tristrip (const cairo_traps_compositor_t *compositor, - cairo_surface_t *dst, - void *closure, - cairo_operator_t op, - cairo_surface_t *src, - int src_x, int src_y, - int dst_x, int dst_y, - const cairo_rectangle_int_t *extents, - cairo_clip_t *clip) -{ - composite_tristrip_info_t *info = closure; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - return compositor->composite_tristrip (dst, op, src, - src_x - dst_x, src_y - dst_y, - dst_x, dst_y, - extents, - info->antialias, &info->strip); -} - -static cairo_bool_t -is_recording_pattern (const cairo_pattern_t *pattern) -{ - cairo_surface_t *surface; - - if (pattern->type != CAIRO_PATTERN_TYPE_SURFACE) - return FALSE; - - surface = ((const cairo_surface_pattern_t *) pattern)->surface; - surface = _cairo_surface_get_source (surface, NULL); - return _cairo_surface_is_recording (surface); -} - -static cairo_surface_t * -recording_pattern_get_surface (const cairo_pattern_t *pattern) -{ - cairo_surface_t *surface; - - surface = ((const cairo_surface_pattern_t *) pattern)->surface; - return _cairo_surface_get_source (surface, NULL); -} - -static cairo_bool_t -recording_pattern_contains_sample (const cairo_pattern_t *pattern, - const cairo_rectangle_int_t *sample) -{ - cairo_recording_surface_t *surface; - - if (! is_recording_pattern (pattern)) - return FALSE; - - if (pattern->extend == CAIRO_EXTEND_NONE) - return TRUE; - - surface = (cairo_recording_surface_t *) recording_pattern_get_surface (pattern); - if (surface->unbounded) - return TRUE; - - return _cairo_rectangle_contains_rectangle (&surface->extents, sample); -} - -static cairo_bool_t -op_reduces_to_source (cairo_composite_rectangles_t *extents) -{ - if (extents->op == CAIRO_OPERATOR_SOURCE) - return TRUE; - - if (extents->surface->is_clear) - return extents->op == CAIRO_OPERATOR_OVER || extents->op == CAIRO_OPERATOR_ADD; - - return FALSE; -} - -static cairo_status_t -composite_aligned_boxes (const cairo_traps_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - cairo_boxes_t *boxes) -{ - cairo_surface_t *dst = extents->surface; - cairo_operator_t op = extents->op; - cairo_bool_t need_clip_mask = ! _cairo_clip_is_region (extents->clip); - cairo_bool_t op_is_source; - cairo_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - if (need_clip_mask && - (! extents->is_bounded || extents->op == CAIRO_OPERATOR_SOURCE)) - { - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - op_is_source = op_reduces_to_source (extents); - - /* Are we just copying a recording surface? */ - if (! need_clip_mask && op_is_source && - recording_pattern_contains_sample (&extents->source_pattern.base, - &extents->source_sample_area)) - { - cairo_clip_t *recording_clip; - const cairo_pattern_t *source = &extents->source_pattern.base; - const cairo_matrix_t *m; - cairo_matrix_t matrix; - - /* XXX could also do tiling repeat modes... */ - - /* first clear the area about to be overwritten */ - if (! dst->is_clear) { - status = compositor->acquire (dst); - if (unlikely (status)) - return status; - - status = compositor->fill_boxes (dst, - CAIRO_OPERATOR_CLEAR, - CAIRO_COLOR_TRANSPARENT, - boxes); - compositor->release (dst); - if (unlikely (status)) - return status; - } - - m = &source->matrix; - if (_cairo_surface_has_device_transform (dst)) { - cairo_matrix_multiply (&matrix, - &source->matrix, - &dst->device_transform); - m = &matrix; - } - - recording_clip = _cairo_clip_from_boxes (boxes); - status = _cairo_recording_surface_replay_with_clip (recording_pattern_get_surface (source), - m, dst, recording_clip); - _cairo_clip_destroy (recording_clip); - - return status; - } - - status = compositor->acquire (dst); - if (unlikely (status)) - return status; - - if (! need_clip_mask && - (op == CAIRO_OPERATOR_CLEAR || - extents->source_pattern.base.type == CAIRO_PATTERN_TYPE_SOLID)) - { - const cairo_color_t *color; - - if (op == CAIRO_OPERATOR_CLEAR) { - color = CAIRO_COLOR_TRANSPARENT; - } else { - color = &((cairo_solid_pattern_t *) &extents->source_pattern)->color; - if (op_is_source) - op = CAIRO_OPERATOR_SOURCE; - } - - status = compositor->fill_boxes (dst, op, color, boxes); - } - else - { - cairo_surface_t *src, *mask = NULL; - cairo_pattern_t *source = &extents->source_pattern.base; - int src_x, src_y; - int mask_x = 0, mask_y = 0; - - if (need_clip_mask) { - mask = traps_get_clip_surface (compositor, - extents, &extents->bounded); - if (unlikely (mask->status)) - return mask->status; - - mask_x = -extents->bounded.x; - mask_y = -extents->bounded.y; - - if (op == CAIRO_OPERATOR_CLEAR) { - source = NULL; - op = CAIRO_OPERATOR_DEST_OUT; - } - } else if (op_is_source) - op = CAIRO_OPERATOR_SOURCE; - - src = compositor->pattern_to_surface (dst, source, FALSE, - &extents->bounded, - &extents->source_sample_area, - &src_x, &src_y); - if (likely (src->status == CAIRO_STATUS_SUCCESS)) { - status = compositor->composite_boxes (dst, op, src, mask, - src_x, src_y, - mask_x, mask_y, - 0, 0, - boxes, &extents->bounded); - cairo_surface_destroy (src); - } else - status = src->status; - - cairo_surface_destroy (mask); - } - - if (status == CAIRO_STATUS_SUCCESS && ! extents->is_bounded) - status = fixup_unbounded (compositor, extents, boxes); - - compositor->release (dst); - - return status; -} - -static cairo_status_t -upload_boxes (const cairo_traps_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - cairo_boxes_t *boxes) -{ - cairo_surface_t *dst = extents->surface; - const cairo_pattern_t *source = &extents->source_pattern.base; - cairo_surface_t *src; - cairo_rectangle_int_t limit; - cairo_int_status_t status; - int tx, ty; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - src = _cairo_pattern_get_source((cairo_surface_pattern_t *)source, - &limit); - if (!(src->type == CAIRO_SURFACE_TYPE_IMAGE || src->type == dst->type)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (! _cairo_matrix_is_integer_translation (&source->matrix, &tx, &ty)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* Check that the data is entirely within the image */ - if (extents->bounded.x + tx < limit.x || extents->bounded.y + ty < limit.y) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (extents->bounded.x + extents->bounded.width + tx > limit.x + limit.width || - extents->bounded.y + extents->bounded.height + ty > limit.y + limit.height) - return CAIRO_INT_STATUS_UNSUPPORTED; - - tx += limit.x; - ty += limit.y; - - if (src->type == CAIRO_SURFACE_TYPE_IMAGE) - status = compositor->draw_image_boxes (dst, - (cairo_image_surface_t *)src, - boxes, tx, ty); - else - status = compositor->copy_boxes (dst, src, boxes, &extents->bounded, - tx, ty); - - return status; -} - -static cairo_int_status_t -trim_extents_to_traps (cairo_composite_rectangles_t *extents, - cairo_traps_t *traps) -{ - cairo_box_t box; - - _cairo_traps_extents (traps, &box); - return _cairo_composite_rectangles_intersect_mask_extents (extents, &box); -} - -static cairo_int_status_t -trim_extents_to_tristrip (cairo_composite_rectangles_t *extents, - cairo_tristrip_t *strip) -{ - cairo_box_t box; - - _cairo_tristrip_extents (strip, &box); - return _cairo_composite_rectangles_intersect_mask_extents (extents, &box); -} - -static cairo_int_status_t -trim_extents_to_boxes (cairo_composite_rectangles_t *extents, - cairo_boxes_t *boxes) -{ - cairo_box_t box; - - _cairo_boxes_extents (boxes, &box); - return _cairo_composite_rectangles_intersect_mask_extents (extents, &box); -} - -static cairo_int_status_t -boxes_for_traps (cairo_boxes_t *boxes, - cairo_traps_t *traps, - cairo_antialias_t antialias) -{ - int i, j; - - /* first check that the traps are rectilinear */ - if (antialias == CAIRO_ANTIALIAS_NONE) { - for (i = 0; i < traps->num_traps; i++) { - const cairo_trapezoid_t *t = &traps->traps[i]; - if (_cairo_fixed_integer_round_down (t->left.p1.x) != - _cairo_fixed_integer_round_down (t->left.p2.x) || - _cairo_fixed_integer_round_down (t->right.p1.x) != - _cairo_fixed_integer_round_down (t->right.p2.x)) - { - return CAIRO_INT_STATUS_UNSUPPORTED; - } - } - } else { - for (i = 0; i < traps->num_traps; i++) { - const cairo_trapezoid_t *t = &traps->traps[i]; - if (t->left.p1.x != t->left.p2.x || t->right.p1.x != t->right.p2.x) - return CAIRO_INT_STATUS_UNSUPPORTED; - } - } - - _cairo_boxes_init (boxes); - - boxes->chunks.base = (cairo_box_t *) traps->traps; - boxes->chunks.size = traps->num_traps; - - if (antialias != CAIRO_ANTIALIAS_NONE) { - for (i = j = 0; i < traps->num_traps; i++) { - /* Note the traps and boxes alias so we need to take the local copies first. */ - cairo_fixed_t x1 = traps->traps[i].left.p1.x; - cairo_fixed_t x2 = traps->traps[i].right.p1.x; - cairo_fixed_t y1 = traps->traps[i].top; - cairo_fixed_t y2 = traps->traps[i].bottom; - - if (x1 == x2 || y1 == y2) - continue; - - boxes->chunks.base[j].p1.x = x1; - boxes->chunks.base[j].p1.y = y1; - boxes->chunks.base[j].p2.x = x2; - boxes->chunks.base[j].p2.y = y2; - j++; - - if (boxes->is_pixel_aligned) { - boxes->is_pixel_aligned = - _cairo_fixed_is_integer (x1) && _cairo_fixed_is_integer (y1) && - _cairo_fixed_is_integer (x2) && _cairo_fixed_is_integer (y2); - } - } - } else { - boxes->is_pixel_aligned = TRUE; - - for (i = j = 0; i < traps->num_traps; i++) { - /* Note the traps and boxes alias so we need to take the local copies first. */ - cairo_fixed_t x1 = traps->traps[i].left.p1.x; - cairo_fixed_t x2 = traps->traps[i].right.p1.x; - cairo_fixed_t y1 = traps->traps[i].top; - cairo_fixed_t y2 = traps->traps[i].bottom; - - /* round down here to match Pixman's behavior when using traps. */ - boxes->chunks.base[j].p1.x = _cairo_fixed_round_down (x1); - boxes->chunks.base[j].p1.y = _cairo_fixed_round_down (y1); - boxes->chunks.base[j].p2.x = _cairo_fixed_round_down (x2); - boxes->chunks.base[j].p2.y = _cairo_fixed_round_down (y2); - j += (boxes->chunks.base[j].p1.x != boxes->chunks.base[j].p2.x && - boxes->chunks.base[j].p1.y != boxes->chunks.base[j].p2.y); - } - } - boxes->chunks.count = j; - boxes->num_boxes = j; - - return CAIRO_INT_STATUS_SUCCESS; -} - -static cairo_status_t -clip_and_composite_boxes (const cairo_traps_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - cairo_boxes_t *boxes); - -static cairo_status_t -clip_and_composite_polygon (const cairo_traps_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - cairo_polygon_t *polygon, - cairo_antialias_t antialias, - cairo_fill_rule_t fill_rule, - cairo_bool_t curvy) -{ - composite_traps_info_t traps; - cairo_surface_t *dst = extents->surface; - cairo_bool_t clip_surface = ! _cairo_clip_is_region (extents->clip); - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - if (polygon->num_edges == 0) { - status = CAIRO_INT_STATUS_SUCCESS; - - if (! extents->is_bounded) { - cairo_region_t *clip_region = _cairo_clip_get_region (extents->clip); - - if (clip_region && - cairo_region_contains_rectangle (clip_region, - &extents->unbounded) == CAIRO_REGION_OVERLAP_IN) - clip_region = NULL; - - if (clip_region != NULL) { - status = compositor->set_clip_region (dst, clip_region); - if (unlikely (status)) - return status; - } - - if (clip_surface) - status = fixup_unbounded_with_mask (compositor, extents); - else - status = fixup_unbounded (compositor, extents, NULL); - - if (clip_region != NULL) - compositor->set_clip_region (dst, NULL); - } - - return status; - } - - if (extents->clip->path != NULL && extents->is_bounded) { - cairo_polygon_t clipper; - cairo_fill_rule_t clipper_fill_rule; - cairo_antialias_t clipper_antialias; - - status = _cairo_clip_get_polygon (extents->clip, - &clipper, - &clipper_fill_rule, - &clipper_antialias); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) { - if (clipper_antialias == antialias) { - status = _cairo_polygon_intersect (polygon, fill_rule, - &clipper, clipper_fill_rule); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) { - cairo_clip_t * clip = _cairo_clip_copy_region (extents->clip); - _cairo_clip_destroy (extents->clip); - extents->clip = clip; - - fill_rule = CAIRO_FILL_RULE_WINDING; - } - _cairo_polygon_fini (&clipper); - } - } - } - - if (antialias == CAIRO_ANTIALIAS_NONE && curvy) { - cairo_boxes_t boxes; - - _cairo_boxes_init (&boxes); - status = _cairo_rasterise_polygon_to_boxes (polygon, fill_rule, &boxes); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) { - assert (boxes.is_pixel_aligned); - status = clip_and_composite_boxes (compositor, extents, &boxes); - } - _cairo_boxes_fini (&boxes); - if ((status != CAIRO_INT_STATUS_UNSUPPORTED)) - return status; - } - - _cairo_traps_init (&traps.traps); - - if (antialias == CAIRO_ANTIALIAS_NONE && curvy) { - status = _cairo_rasterise_polygon_to_traps (polygon, fill_rule, antialias, &traps.traps); - } else { - status = _cairo_bentley_ottmann_tessellate_polygon (&traps.traps, polygon, fill_rule); - } - if (unlikely (status)) - goto CLEANUP_TRAPS; - - status = trim_extents_to_traps (extents, &traps.traps); - if (unlikely (status)) - goto CLEANUP_TRAPS; - - /* Use a fast path if the trapezoids consist of a set of boxes. */ - status = CAIRO_INT_STATUS_UNSUPPORTED; - if (1) { - cairo_boxes_t boxes; - - status = boxes_for_traps (&boxes, &traps.traps, antialias); - if (status == CAIRO_INT_STATUS_SUCCESS) { - status = clip_and_composite_boxes (compositor, extents, &boxes); - /* XXX need to reconstruct the traps! */ - assert (status != CAIRO_INT_STATUS_UNSUPPORTED); - } - } - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - /* Otherwise render the trapezoids to a mask and composite in the usual - * fashion. - */ - unsigned int flags = 0; - - /* For unbounded operations, the X11 server will estimate the - * affected rectangle and apply the operation to that. However, - * there are cases where this is an overestimate (e.g. the - * clip-fill-{eo,nz}-unbounded test). - * - * The clip will trim that overestimate to our expectations. - */ - if (! extents->is_bounded) - flags |= FORCE_CLIP_REGION; - - traps.antialias = antialias; - status = clip_and_composite (compositor, extents, - composite_traps, NULL, &traps, - need_unbounded_clip (extents) | flags); - } - -CLEANUP_TRAPS: - _cairo_traps_fini (&traps.traps); - - return status; -} - -struct composite_opacity_info { - const cairo_traps_compositor_t *compositor; - uint8_t op; - cairo_surface_t *dst; - cairo_surface_t *src; - int src_x, src_y; - double opacity; -}; - -static void composite_opacity(void *closure, - int16_t x, int16_t y, - int16_t w, int16_t h, - uint16_t coverage) -{ - struct composite_opacity_info *info = closure; - const cairo_traps_compositor_t *compositor = info->compositor; - cairo_surface_t *mask; - int mask_x, mask_y; - cairo_color_t color; - cairo_solid_pattern_t solid; - - _cairo_color_init_rgba (&color, 0, 0, 0, info->opacity * coverage); - _cairo_pattern_init_solid (&solid, &color); - mask = compositor->pattern_to_surface (info->dst, &solid.base, TRUE, - &_cairo_unbounded_rectangle, - &_cairo_unbounded_rectangle, - &mask_x, &mask_y); - if (likely (mask->status == CAIRO_STATUS_SUCCESS)) { - if (info->src) { - compositor->composite (info->dst, info->op, info->src, mask, - x + info->src_x, y + info->src_y, - mask_x, mask_y, - x, y, - w, h); - } else { - compositor->composite (info->dst, info->op, mask, NULL, - mask_x, mask_y, - 0, 0, - x, y, - w, h); - } - } - - cairo_surface_destroy (mask); -} - - -static cairo_int_status_t -composite_opacity_boxes (const cairo_traps_compositor_t *compositor, - cairo_surface_t *dst, - void *closure, - cairo_operator_t op, - cairo_surface_t *src, - int src_x, - int src_y, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents, - cairo_clip_t *clip) -{ - const cairo_solid_pattern_t *mask = closure; - struct composite_opacity_info info; - int i; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - info.compositor = compositor; - info.op = op; - info.dst = dst; - - info.src = src; - info.src_x = src_x; - info.src_y = src_y; - - info.opacity = mask->color.alpha / (double) 0xffff; - - /* XXX for lots of boxes create a clip region for the fully opaque areas */ - for (i = 0; i < clip->num_boxes; i++) - do_unaligned_box(composite_opacity, &info, - &clip->boxes[i], dst_x, dst_y); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -composite_boxes (const cairo_traps_compositor_t *compositor, - cairo_surface_t *dst, - void *closure, - cairo_operator_t op, - cairo_surface_t *src, - int src_x, - int src_y, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents, - cairo_clip_t *clip) -{ - cairo_traps_t traps; - cairo_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - status = _cairo_traps_init_boxes (&traps, closure); - if (unlikely (status)) - return status; - - status = compositor->composite_traps (dst, op, src, - src_x - dst_x, src_y - dst_y, - dst_x, dst_y, - extents, - CAIRO_ANTIALIAS_DEFAULT, &traps); - _cairo_traps_fini (&traps); - - return status; -} - -static cairo_status_t -clip_and_composite_boxes (const cairo_traps_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - cairo_boxes_t *boxes) -{ - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - if (boxes->num_boxes == 0 && extents->is_bounded) - return CAIRO_STATUS_SUCCESS; - - status = trim_extents_to_boxes (extents, boxes); - if (unlikely (status)) - return status; - - if (boxes->is_pixel_aligned && extents->clip->path == NULL && - extents->source_pattern.base.type == CAIRO_PATTERN_TYPE_SURFACE && - (op_reduces_to_source (extents) || - (extents->op == CAIRO_OPERATOR_OVER && - (extents->source_pattern.surface.surface->content & CAIRO_CONTENT_ALPHA) == 0))) - { - status = upload_boxes (compositor, extents, boxes); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - } - - /* Can we reduce drawing through a clip-mask to simply drawing the clip? */ - if (extents->clip->path != NULL && extents->is_bounded) { - cairo_polygon_t polygon; - cairo_fill_rule_t fill_rule; - cairo_antialias_t antialias; - cairo_clip_t *clip; - - clip = _cairo_clip_copy (extents->clip); - clip = _cairo_clip_intersect_boxes (clip, boxes); - if (_cairo_clip_is_all_clipped (clip)) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - status = _cairo_clip_get_polygon (clip, &polygon, - &fill_rule, &antialias); - _cairo_clip_path_destroy (clip->path); - clip->path = NULL; - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) { - cairo_clip_t *saved_clip = extents->clip; - extents->clip = clip; - - status = clip_and_composite_polygon (compositor, extents, &polygon, - antialias, fill_rule, FALSE); - - clip = extents->clip; - extents->clip = saved_clip; - - _cairo_polygon_fini (&polygon); - } - _cairo_clip_destroy (clip); - - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - } - - /* Use a fast path if the boxes are pixel aligned (or nearly aligned!) */ - if (boxes->is_pixel_aligned) { - status = composite_aligned_boxes (compositor, extents, boxes); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - } - - return clip_and_composite (compositor, extents, - composite_boxes, NULL, boxes, - need_unbounded_clip (extents)); -} - -static cairo_int_status_t -composite_traps_as_boxes (const cairo_traps_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - composite_traps_info_t *info) -{ - cairo_boxes_t boxes; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - if (! _cairo_traps_to_boxes (&info->traps, info->antialias, &boxes)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - return clip_and_composite_boxes (compositor, extents, &boxes); -} - -static cairo_int_status_t -clip_and_composite_traps (const cairo_traps_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - composite_traps_info_t *info, - unsigned flags) -{ - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - status = trim_extents_to_traps (extents, &info->traps); - if (unlikely (status != CAIRO_INT_STATUS_SUCCESS)) - return status; - - status = CAIRO_INT_STATUS_UNSUPPORTED; - if ((flags & FORCE_CLIP_REGION) == 0) - status = composite_traps_as_boxes (compositor, extents, info); - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - /* For unbounded operations, the X11 server will estimate the - * affected rectangle and apply the operation to that. However, - * there are cases where this is an overestimate (e.g. the - * clip-fill-{eo,nz}-unbounded test). - * - * The clip will trim that overestimate to our expectations. - */ - if (! extents->is_bounded) - flags |= FORCE_CLIP_REGION; - - status = clip_and_composite (compositor, extents, - composite_traps, NULL, info, - need_unbounded_clip (extents) | flags); - } - - return status; -} - -static cairo_int_status_t -clip_and_composite_tristrip (const cairo_traps_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - composite_tristrip_info_t *info) -{ - cairo_int_status_t status; - unsigned int flags = 0; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - status = trim_extents_to_tristrip (extents, &info->strip); - if (unlikely (status != CAIRO_INT_STATUS_SUCCESS)) - return status; - - if (! extents->is_bounded) - flags |= FORCE_CLIP_REGION; - - status = clip_and_composite (compositor, extents, - composite_tristrip, NULL, info, - need_unbounded_clip (extents) | flags); - - return status; -} - -struct composite_mask { - cairo_surface_t *mask; - int mask_x, mask_y; -}; - -static cairo_int_status_t -composite_mask (const cairo_traps_compositor_t *compositor, - cairo_surface_t *dst, - void *closure, - cairo_operator_t op, - cairo_surface_t *src, - int src_x, - int src_y, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents, - cairo_clip_t *clip) -{ - struct composite_mask *data = closure; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - if (src != NULL) { - compositor->composite (dst, op, src, data->mask, - extents->x + src_x, extents->y + src_y, - extents->x + data->mask_x, extents->y + data->mask_y, - extents->x - dst_x, extents->y - dst_y, - extents->width, extents->height); - } else { - compositor->composite (dst, op, data->mask, NULL, - extents->x + data->mask_x, extents->y + data->mask_y, - 0, 0, - extents->x - dst_x, extents->y - dst_y, - extents->width, extents->height); - } - - return CAIRO_STATUS_SUCCESS; -} - -struct composite_box_info { - const cairo_traps_compositor_t *compositor; - cairo_surface_t *dst; - cairo_surface_t *src; - int src_x, src_y; - uint8_t op; -}; - -static void composite_box(void *closure, - int16_t x, int16_t y, - int16_t w, int16_t h, - uint16_t coverage) -{ - struct composite_box_info *info = closure; - const cairo_traps_compositor_t *compositor = info->compositor; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - if (! CAIRO_ALPHA_SHORT_IS_OPAQUE (coverage)) { - cairo_surface_t *mask; - cairo_color_t color; - cairo_solid_pattern_t solid; - int mask_x, mask_y; - - _cairo_color_init_rgba (&color, 0, 0, 0, coverage / (double)0xffff); - _cairo_pattern_init_solid (&solid, &color); - - mask = compositor->pattern_to_surface (info->dst, &solid.base, FALSE, - &_cairo_unbounded_rectangle, - &_cairo_unbounded_rectangle, - &mask_x, &mask_y); - - if (likely (mask->status == CAIRO_STATUS_SUCCESS)) { - compositor->composite (info->dst, info->op, info->src, mask, - x + info->src_x, y + info->src_y, - mask_x, mask_y, - x, y, - w, h); - } - - cairo_surface_destroy (mask); - } else { - compositor->composite (info->dst, info->op, info->src, NULL, - x + info->src_x, y + info->src_y, - 0, 0, - x, y, - w, h); - } -} - -static cairo_int_status_t -composite_mask_clip_boxes (const cairo_traps_compositor_t *compositor, - cairo_surface_t *dst, - void *closure, - cairo_operator_t op, - cairo_surface_t *src, - int src_x, - int src_y, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents, - cairo_clip_t *clip) -{ - struct composite_mask *data = closure; - struct composite_box_info info; - int i; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - info.compositor = compositor; - info.op = CAIRO_OPERATOR_SOURCE; - info.dst = dst; - info.src = data->mask; - info.src_x = data->mask_x; - info.src_y = data->mask_y; - - info.src_x += dst_x; - info.src_y += dst_y; - - for (i = 0; i < clip->num_boxes; i++) - do_unaligned_box(composite_box, &info, &clip->boxes[i], dst_x, dst_y); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -composite_mask_clip (const cairo_traps_compositor_t *compositor, - cairo_surface_t *dst, - void *closure, - cairo_operator_t op, - cairo_surface_t *src, - int src_x, - int src_y, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents, - cairo_clip_t *clip) -{ - struct composite_mask *data = closure; - cairo_polygon_t polygon; - cairo_fill_rule_t fill_rule; - composite_traps_info_t info; - cairo_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - status = _cairo_clip_get_polygon (clip, &polygon, - &fill_rule, &info.antialias); - if (unlikely (status)) - return status; - - _cairo_traps_init (&info.traps); - status = _cairo_bentley_ottmann_tessellate_polygon (&info.traps, - &polygon, - fill_rule); - _cairo_polygon_fini (&polygon); - if (unlikely (status)) - return status; - - status = composite_traps (compositor, dst, &info, - CAIRO_OPERATOR_SOURCE, - data->mask, - data->mask_x + dst_x, data->mask_y + dst_y, - dst_x, dst_y, - extents, NULL); - _cairo_traps_fini (&info.traps); - - return status; -} - -/* high-level compositor interface */ - -static cairo_int_status_t -_cairo_traps_compositor_paint (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents) -{ - cairo_traps_compositor_t *compositor = (cairo_traps_compositor_t*)_compositor; - cairo_boxes_t boxes; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - status = compositor->check_composite (extents); - if (unlikely (status)) - return status; - - _cairo_clip_steal_boxes (extents->clip, &boxes); - status = clip_and_composite_boxes (compositor, extents, &boxes); - _cairo_clip_unsteal_boxes (extents->clip, &boxes); - - return status; -} - -static cairo_int_status_t -_cairo_traps_compositor_mask (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents) -{ - const cairo_traps_compositor_t *compositor = (cairo_traps_compositor_t*)_compositor; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - status = compositor->check_composite (extents); - if (unlikely (status)) - return status; - - if (extents->mask_pattern.base.type == CAIRO_PATTERN_TYPE_SOLID && - extents->clip->path == NULL) { - status = clip_and_composite (compositor, extents, - composite_opacity_boxes, - composite_opacity_boxes, - &extents->mask_pattern, - need_unbounded_clip (extents)); - } else { - struct composite_mask data; - - data.mask = compositor->pattern_to_surface (extents->surface, - &extents->mask_pattern.base, - TRUE, - &extents->bounded, - &extents->mask_sample_area, - &data.mask_x, - &data.mask_y); - if (unlikely (data.mask->status)) - return data.mask->status; - - status = clip_and_composite (compositor, extents, - composite_mask, - extents->clip->path ? composite_mask_clip : composite_mask_clip_boxes, - &data, need_bounded_clip (extents)); - - cairo_surface_destroy (data.mask); - } - - return status; -} - -static cairo_int_status_t -_cairo_traps_compositor_stroke (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias) -{ - const cairo_traps_compositor_t *compositor = (cairo_traps_compositor_t *)_compositor; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - status = compositor->check_composite (extents); - if (unlikely (status)) - return status; - - status = CAIRO_INT_STATUS_UNSUPPORTED; - if (_cairo_path_fixed_stroke_is_rectilinear (path)) { - cairo_boxes_t boxes; - - _cairo_boxes_init_with_clip (&boxes, extents->clip); - status = _cairo_path_fixed_stroke_rectilinear_to_boxes (path, - style, - ctm, - antialias, - &boxes); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) - status = clip_and_composite_boxes (compositor, extents, &boxes); - _cairo_boxes_fini (&boxes); - } - - if (status == CAIRO_INT_STATUS_UNSUPPORTED && 0 && - _cairo_clip_is_region (extents->clip)) /* XXX */ - { - composite_tristrip_info_t info; - - info.antialias = antialias; - _cairo_tristrip_init_with_clip (&info.strip, extents->clip); - status = _cairo_path_fixed_stroke_to_tristrip (path, style, - ctm, ctm_inverse, - tolerance, - &info.strip); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) - status = clip_and_composite_tristrip (compositor, extents, &info); - _cairo_tristrip_fini (&info.strip); - } - - if (status == CAIRO_INT_STATUS_UNSUPPORTED && - path->has_curve_to && antialias == CAIRO_ANTIALIAS_NONE) { - cairo_polygon_t polygon; - - _cairo_polygon_init_with_clip (&polygon, extents->clip); - status = _cairo_path_fixed_stroke_to_polygon (path, style, - ctm, ctm_inverse, - tolerance, - &polygon); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) - status = clip_and_composite_polygon (compositor, - extents, &polygon, - CAIRO_ANTIALIAS_NONE, - CAIRO_FILL_RULE_WINDING, - TRUE); - _cairo_polygon_fini (&polygon); - } - - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - cairo_int_status_t (*func) (const cairo_path_fixed_t *path, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_traps_t *traps); - composite_traps_info_t info; - unsigned flags; - - if (antialias == CAIRO_ANTIALIAS_BEST || antialias == CAIRO_ANTIALIAS_GOOD) { - func = _cairo_path_fixed_stroke_polygon_to_traps; - flags = 0; - } else { - func = _cairo_path_fixed_stroke_to_traps; - flags = need_bounded_clip (extents) & ~NEED_CLIP_SURFACE; - } - - info.antialias = antialias; - _cairo_traps_init_with_clip (&info.traps, extents->clip); - status = func (path, style, ctm, ctm_inverse, tolerance, &info.traps); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) - status = clip_and_composite_traps (compositor, extents, &info, flags); - _cairo_traps_fini (&info.traps); - } - - return status; -} - -static cairo_int_status_t -_cairo_traps_compositor_fill (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - const cairo_traps_compositor_t *compositor = (cairo_traps_compositor_t *)_compositor; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - status = compositor->check_composite (extents); - if (unlikely (status)) - return status; - - status = CAIRO_INT_STATUS_UNSUPPORTED; - if (_cairo_path_fixed_fill_is_rectilinear (path)) { - cairo_boxes_t boxes; - - _cairo_boxes_init_with_clip (&boxes, extents->clip); - status = _cairo_path_fixed_fill_rectilinear_to_boxes (path, - fill_rule, - antialias, - &boxes); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) - status = clip_and_composite_boxes (compositor, extents, &boxes); - _cairo_boxes_fini (&boxes); - } - - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - cairo_polygon_t polygon; - -#if 0 - if (extents->mask.width > extents->unbounded.width || - extents->mask.height > extents->unbounded.height) - { - cairo_box_t limits; - _cairo_box_from_rectangle (&limits, &extents->unbounded); - _cairo_polygon_init (&polygon, &limits, 1); - } - else - { - _cairo_polygon_init (&polygon, NULL, 0); - } - - status = _cairo_path_fixed_fill_to_polygon (path, tolerance, &polygon); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) { - status = _cairo_polygon_intersect_with_boxes (&polygon, &fill_rule, - extents->clip->boxes, - extents->clip->num_boxes); - } -#else - _cairo_polygon_init_with_clip (&polygon, extents->clip); - status = _cairo_path_fixed_fill_to_polygon (path, tolerance, &polygon); -#endif - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) { - status = clip_and_composite_polygon (compositor, extents, &polygon, - antialias, fill_rule, path->has_curve_to); - } - _cairo_polygon_fini (&polygon); - } - - return status; -} - -static cairo_int_status_t -composite_glyphs (const cairo_traps_compositor_t *compositor, - cairo_surface_t *dst, - void *closure, - cairo_operator_t op, - cairo_surface_t *src, - int src_x, int src_y, - int dst_x, int dst_y, - const cairo_rectangle_int_t *extents, - cairo_clip_t *clip) -{ - cairo_composite_glyphs_info_t *info = closure; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - if (op == CAIRO_OPERATOR_ADD && (dst->content & CAIRO_CONTENT_COLOR) == 0) - info->use_mask = 0; - - return compositor->composite_glyphs (dst, op, src, - src_x, src_y, - dst_x, dst_y, - info); -} - -static cairo_int_status_t -_cairo_traps_compositor_glyphs (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_bool_t overlap) -{ - const cairo_traps_compositor_t *compositor = (cairo_traps_compositor_t *)_compositor; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - status = compositor->check_composite (extents); - if (unlikely (status)) - return status; - - _cairo_scaled_font_freeze_cache (scaled_font); - status = compositor->check_composite_glyphs (extents, - scaled_font, glyphs, - &num_glyphs); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) { - cairo_composite_glyphs_info_t info; - - info.font = scaled_font; - info.glyphs = glyphs; - info.num_glyphs = num_glyphs; - info.use_mask = overlap || ! extents->is_bounded; - info.extents = extents->bounded; - - status = clip_and_composite (compositor, extents, - composite_glyphs, NULL, &info, - need_bounded_clip (extents) | FORCE_CLIP_REGION); - } - _cairo_scaled_font_thaw_cache (scaled_font); - - return status; -} - -void -_cairo_traps_compositor_init (cairo_traps_compositor_t *compositor, - const cairo_compositor_t *delegate) -{ - compositor->base.delegate = delegate; - - compositor->base.paint = _cairo_traps_compositor_paint; - compositor->base.mask = _cairo_traps_compositor_mask; - compositor->base.fill = _cairo_traps_compositor_fill; - compositor->base.stroke = _cairo_traps_compositor_stroke; - compositor->base.glyphs = _cairo_traps_compositor_glyphs; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-traps-private.h b/source/libs/cairo/cairo-src/src/cairo-traps-private.h deleted file mode 100644 index dcaf40d18638649bcad26d1f78ebbca14b08a33a..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-traps-private.h +++ /dev/null @@ -1,143 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - */ - -#ifndef CAIRO_TRAPS_PRIVATE_H -#define CAIRO_TRAPS_PRIVATE_H - -#include "cairo-compiler-private.h" -#include "cairo-error-private.h" -#include "cairo-types-private.h" - -CAIRO_BEGIN_DECLS - -struct _cairo_traps { - cairo_status_t status; - - cairo_box_t bounds; - const cairo_box_t *limits; - int num_limits; - - unsigned int maybe_region : 1; /* hint: 0 implies that it cannot be */ - unsigned int has_intersections : 1; - unsigned int is_rectilinear : 1; - unsigned int is_rectangular : 1; - - int num_traps; - int traps_size; - cairo_trapezoid_t *traps; - cairo_trapezoid_t traps_embedded[16]; -}; - -/* cairo-traps.c */ -cairo_private void -_cairo_traps_init (cairo_traps_t *traps); - -cairo_private void -_cairo_traps_init_with_clip (cairo_traps_t *traps, - const cairo_clip_t *clip); - -cairo_private void -_cairo_traps_limit (cairo_traps_t *traps, - const cairo_box_t *boxes, - int num_boxes); - -cairo_private cairo_status_t -_cairo_traps_init_boxes (cairo_traps_t *traps, - const cairo_boxes_t *boxes); - -cairo_private void -_cairo_traps_clear (cairo_traps_t *traps); - -cairo_private void -_cairo_traps_fini (cairo_traps_t *traps); - -#define _cairo_traps_status(T) (T)->status - -cairo_private void -_cairo_traps_translate (cairo_traps_t *traps, int x, int y); - -cairo_private void -_cairo_traps_tessellate_triangle_with_edges (cairo_traps_t *traps, - const cairo_point_t t[3], - const cairo_point_t edges[4]); - -cairo_private void -_cairo_traps_tessellate_convex_quad (cairo_traps_t *traps, - const cairo_point_t q[4]); - -cairo_private cairo_status_t -_cairo_traps_tessellate_rectangle (cairo_traps_t *traps, - const cairo_point_t *top_left, - const cairo_point_t *bottom_right); - -cairo_private void -_cairo_traps_add_trap (cairo_traps_t *traps, - cairo_fixed_t top, cairo_fixed_t bottom, - const cairo_line_t *left, - const cairo_line_t *right); - -cairo_private int -_cairo_traps_contain (const cairo_traps_t *traps, - double x, double y); - -cairo_private void -_cairo_traps_extents (const cairo_traps_t *traps, - cairo_box_t *extents); - -cairo_private cairo_int_status_t -_cairo_traps_extract_region (cairo_traps_t *traps, - cairo_antialias_t antialias, - cairo_region_t **region); - -cairo_private cairo_bool_t -_cairo_traps_to_boxes (cairo_traps_t *traps, - cairo_antialias_t antialias, - cairo_boxes_t *boxes); - -cairo_private cairo_status_t -_cairo_traps_path (const cairo_traps_t *traps, - cairo_path_fixed_t *path); - -cairo_private cairo_int_status_t -_cairo_rasterise_polygon_to_traps (cairo_polygon_t *polygon, - cairo_fill_rule_t fill_rule, - cairo_antialias_t antialias, - cairo_traps_t *traps); - -CAIRO_END_DECLS - -#endif /* CAIRO_TRAPS_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-traps.c b/source/libs/cairo/cairo-src/src/cairo-traps.c deleted file mode 100644 index 3aa0052f91f1d1bae4adb30eca1cdc113de63009..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-traps.c +++ /dev/null @@ -1,1123 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* - * Copyright © 2002 Keith Packard - * Copyright © 2007 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Keith Packard - * - * Contributor(s): - * Keith R. Packard <keithp@keithp.com> - * Carl D. Worth <cworth@cworth.org> - * - * 2002-07-15: Converted from XRenderCompositeDoublePoly to #cairo_trap_t. Carl D. Worth - */ - -#include "cairoint.h" - -#include "cairo-box-inline.h" -#include "cairo-boxes-private.h" -#include "cairo-error-private.h" -#include "cairo-line-private.h" -#include "cairo-region-private.h" -#include "cairo-slope-private.h" -#include "cairo-traps-private.h" -#include "cairo-spans-private.h" - -/* private functions */ - -void -_cairo_traps_init (cairo_traps_t *traps) -{ - VG (VALGRIND_MAKE_MEM_UNDEFINED (traps, sizeof (cairo_traps_t))); - - traps->status = CAIRO_STATUS_SUCCESS; - - traps->maybe_region = 1; - traps->is_rectilinear = 0; - traps->is_rectangular = 0; - - traps->num_traps = 0; - - traps->traps_size = ARRAY_LENGTH (traps->traps_embedded); - traps->traps = traps->traps_embedded; - - traps->num_limits = 0; - traps->has_intersections = FALSE; -} - -void -_cairo_traps_limit (cairo_traps_t *traps, - const cairo_box_t *limits, - int num_limits) -{ - int i; - - traps->limits = limits; - traps->num_limits = num_limits; - - traps->bounds = limits[0]; - for (i = 1; i < num_limits; i++) - _cairo_box_add_box (&traps->bounds, &limits[i]); -} - -void -_cairo_traps_init_with_clip (cairo_traps_t *traps, - const cairo_clip_t *clip) -{ - _cairo_traps_init (traps); - if (clip) - _cairo_traps_limit (traps, clip->boxes, clip->num_boxes); -} - -void -_cairo_traps_clear (cairo_traps_t *traps) -{ - traps->status = CAIRO_STATUS_SUCCESS; - - traps->maybe_region = 1; - traps->is_rectilinear = 0; - traps->is_rectangular = 0; - - traps->num_traps = 0; - traps->has_intersections = FALSE; -} - -void -_cairo_traps_fini (cairo_traps_t *traps) -{ - if (traps->traps != traps->traps_embedded) - free (traps->traps); - - VG (VALGRIND_MAKE_MEM_NOACCESS (traps, sizeof (cairo_traps_t))); -} - -/* make room for at least one more trap */ -static cairo_bool_t -_cairo_traps_grow (cairo_traps_t *traps) -{ - cairo_trapezoid_t *new_traps; - int new_size = 4 * traps->traps_size; - - if (CAIRO_INJECT_FAULT ()) { - traps->status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - return FALSE; - } - - if (traps->traps == traps->traps_embedded) { - new_traps = _cairo_malloc_ab (new_size, sizeof (cairo_trapezoid_t)); - if (new_traps != NULL) - memcpy (new_traps, traps->traps, sizeof (traps->traps_embedded)); - } else { - new_traps = _cairo_realloc_ab (traps->traps, - new_size, sizeof (cairo_trapezoid_t)); - } - - if (unlikely (new_traps == NULL)) { - traps->status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - return FALSE; - } - - traps->traps = new_traps; - traps->traps_size = new_size; - return TRUE; -} - -void -_cairo_traps_add_trap (cairo_traps_t *traps, - cairo_fixed_t top, cairo_fixed_t bottom, - const cairo_line_t *left, - const cairo_line_t *right) -{ - cairo_trapezoid_t *trap; - - assert (left->p1.y != left->p2.y); - assert (right->p1.y != right->p2.y); - assert (bottom > top); - - if (unlikely (traps->num_traps == traps->traps_size)) { - if (unlikely (! _cairo_traps_grow (traps))) - return; - } - - trap = &traps->traps[traps->num_traps++]; - trap->top = top; - trap->bottom = bottom; - trap->left = *left; - trap->right = *right; -} - -static void -_cairo_traps_add_clipped_trap (cairo_traps_t *traps, - cairo_fixed_t _top, cairo_fixed_t _bottom, - const cairo_line_t *_left, - const cairo_line_t *_right) -{ - /* Note: With the goofy trapezoid specification, (where an - * arbitrary two points on the lines can specified for the left - * and right edges), these limit checks would not work in - * general. For example, one can imagine a trapezoid entirely - * within the limits, but with two points used to specify the left - * edge entirely to the right of the limits. Fortunately, for our - * purposes, cairo will never generate such a crazy - * trapezoid. Instead, cairo always uses for its points the - * extreme positions of the edge that are visible on at least some - * trapezoid. With this constraint, it's impossible for both - * points to be outside the limits while the relevant edge is - * entirely inside the limits. - */ - if (traps->num_limits) { - const cairo_box_t *b = &traps->bounds; - cairo_fixed_t top = _top, bottom = _bottom; - cairo_line_t left = *_left, right = *_right; - - /* Trivially reject if trapezoid is entirely to the right or - * to the left of the limits. */ - if (left.p1.x >= b->p2.x && left.p2.x >= b->p2.x) - return; - - if (right.p1.x <= b->p1.x && right.p2.x <= b->p1.x) - return; - - /* And reject if the trapezoid is entirely above or below */ - if (top >= b->p2.y || bottom <= b->p1.y) - return; - - /* Otherwise, clip the trapezoid to the limits. We only clip - * where an edge is entirely outside the limits. If we wanted - * to be more clever, we could handle cases where a trapezoid - * edge intersects the edge of the limits, but that would - * require slicing this trapezoid into multiple trapezoids, - * and I'm not sure the effort would be worth it. */ - if (top < b->p1.y) - top = b->p1.y; - - if (bottom > b->p2.y) - bottom = b->p2.y; - - if (left.p1.x <= b->p1.x && left.p2.x <= b->p1.x) - left.p1.x = left.p2.x = b->p1.x; - - if (right.p1.x >= b->p2.x && right.p2.x >= b->p2.x) - right.p1.x = right.p2.x = b->p2.x; - - /* Trivial discards for empty trapezoids that are likely to - * be produced by our tessellators (most notably convex_quad - * when given a simple rectangle). - */ - if (top >= bottom) - return; - - /* cheap colinearity check */ - if (right.p1.x <= left.p1.x && right.p1.y == left.p1.y && - right.p2.x <= left.p2.x && right.p2.y == left.p2.y) - return; - - _cairo_traps_add_trap (traps, top, bottom, &left, &right); - } else - _cairo_traps_add_trap (traps, _top, _bottom, _left, _right); -} - -static int -_compare_point_fixed_by_y (const void *av, const void *bv) -{ - const cairo_point_t *a = av, *b = bv; - int ret = a->y - b->y; - if (ret == 0) - ret = a->x - b->x; - return ret; -} - -void -_cairo_traps_tessellate_convex_quad (cairo_traps_t *traps, - const cairo_point_t q[4]) -{ - int a, b, c, d; - int i; - cairo_slope_t ab, ad; - cairo_bool_t b_left_of_d; - cairo_line_t left; - cairo_line_t right; - - /* Choose a as a point with minimal y */ - a = 0; - for (i = 1; i < 4; i++) - if (_compare_point_fixed_by_y (&q[i], &q[a]) < 0) - a = i; - - /* b and d are adjacent to a, while c is opposite */ - b = (a + 1) % 4; - c = (a + 2) % 4; - d = (a + 3) % 4; - - /* Choose between b and d so that b.y is less than d.y */ - if (_compare_point_fixed_by_y (&q[d], &q[b]) < 0) { - b = (a + 3) % 4; - d = (a + 1) % 4; - } - - /* Without freedom left to choose anything else, we have four - * cases to tessellate. - * - * First, we have to determine the Y-axis sort of the four - * vertices, (either abcd or abdc). After that we need to detemine - * which edges will be "left" and which will be "right" in the - * resulting trapezoids. This can be determined by computing a - * slope comparison of ab and ad to determine if b is left of d or - * not. - * - * Note that "left of" here is in the sense of which edges should - * be the left vs. right edges of the trapezoid. In particular, b - * left of d does *not* mean that b.x is less than d.x. - * - * This should hopefully be made clear in the lame ASCII art - * below. Since the same slope comparison is used in all cases, we - * compute it before testing for the Y-value sort. */ - - /* Note: If a == b then the ab slope doesn't give us any - * information. In that case, we can replace it with the ac (or - * equivalenly the bc) slope which gives us exactly the same - * information we need. At worst the names of the identifiers ab - * and b_left_of_d are inaccurate in this case, (would be ac, and - * c_left_of_d). */ - if (q[a].x == q[b].x && q[a].y == q[b].y) - _cairo_slope_init (&ab, &q[a], &q[c]); - else - _cairo_slope_init (&ab, &q[a], &q[b]); - - _cairo_slope_init (&ad, &q[a], &q[d]); - - b_left_of_d = _cairo_slope_compare (&ab, &ad) > 0; - - if (q[c].y <= q[d].y) { - if (b_left_of_d) { - /* Y-sort is abcd and b is left of d, (slope(ab) > slope (ad)) - * - * top bot left right - * _a a a - * / / /| |\ a.y b.y ab ad - * b / b | b \ - * / / | | \ \ b.y c.y bc ad - * c / c | c \ - * | / \| \ \ c.y d.y cd ad - * d d d - */ - left.p1 = q[a]; left.p2 = q[b]; - right.p1 = q[a]; right.p2 = q[d]; - _cairo_traps_add_clipped_trap (traps, q[a].y, q[b].y, &left, &right); - left.p1 = q[b]; left.p2 = q[c]; - _cairo_traps_add_clipped_trap (traps, q[b].y, q[c].y, &left, &right); - left.p1 = q[c]; left.p2 = q[d]; - _cairo_traps_add_clipped_trap (traps, q[c].y, q[d].y, &left, &right); - } else { - /* Y-sort is abcd and b is right of d, (slope(ab) <= slope (ad)) - * - * a a a_ - * /| |\ \ \ a.y b.y ad ab - * / b | b \ b - * / / | | \ \ b.y c.y ad bc - * / c | c \ c - * / / |/ \ | c.y d.y ad cd - * d d d - */ - left.p1 = q[a]; left.p2 = q[d]; - right.p1 = q[a]; right.p2 = q[b]; - _cairo_traps_add_clipped_trap (traps, q[a].y, q[b].y, &left, &right); - right.p1 = q[b]; right.p2 = q[c]; - _cairo_traps_add_clipped_trap (traps, q[b].y, q[c].y, &left, &right); - right.p1 = q[c]; right.p2 = q[d]; - _cairo_traps_add_clipped_trap (traps, q[c].y, q[d].y, &left, &right); - } - } else { - if (b_left_of_d) { - /* Y-sort is abdc and b is left of d, (slope (ab) > slope (ad)) - * - * a a a - * // / \ |\ a.y b.y ab ad - * /b/ b \ b \ - * / / \ \ \ \ b.y d.y bc ad - * /d/ \ d \ d - * // \ / \| d.y c.y bc dc - * c c c - */ - left.p1 = q[a]; left.p2 = q[b]; - right.p1 = q[a]; right.p2 = q[d]; - _cairo_traps_add_clipped_trap (traps, q[a].y, q[b].y, &left, &right); - left.p1 = q[b]; left.p2 = q[c]; - _cairo_traps_add_clipped_trap (traps, q[b].y, q[d].y, &left, &right); - right.p1 = q[d]; right.p2 = q[c]; - _cairo_traps_add_clipped_trap (traps, q[d].y, q[c].y, &left, &right); - } else { - /* Y-sort is abdc and b is right of d, (slope (ab) <= slope (ad)) - * - * a a a - * /| / \ \\ a.y b.y ad ab - * / b / b \b\ - * / / / / \ \ b.y d.y ad bc - * d / d / \d\ - * |/ \ / \\ d.y c.y dc bc - * c c c - */ - left.p1 = q[a]; left.p2 = q[d]; - right.p1 = q[a]; right.p2 = q[b]; - _cairo_traps_add_clipped_trap (traps, q[a].y, q[b].y, &left, &right); - right.p1 = q[b]; right.p2 = q[c]; - _cairo_traps_add_clipped_trap (traps, q[b].y, q[d].y, &left, &right); - left.p1 = q[d]; left.p2 = q[c]; - _cairo_traps_add_clipped_trap (traps, q[d].y, q[c].y, &left, &right); - } - } -} - -static void add_tri (cairo_traps_t *traps, - int y1, int y2, - const cairo_line_t *left, - const cairo_line_t *right) -{ - if (y2 < y1) { - int tmp = y1; - y1 = y2; - y2 = tmp; - } - - if (cairo_lines_compare_at_y (left, right, y1) > 0) { - const cairo_line_t *tmp = left; - left = right; - right = tmp; - } - - _cairo_traps_add_clipped_trap (traps, y1, y2, left, right); -} - -void -_cairo_traps_tessellate_triangle_with_edges (cairo_traps_t *traps, - const cairo_point_t t[3], - const cairo_point_t edges[4]) -{ - cairo_line_t lines[3]; - - if (edges[0].y <= edges[1].y) { - lines[0].p1 = edges[0]; - lines[0].p2 = edges[1]; - } else { - lines[0].p1 = edges[1]; - lines[0].p2 = edges[0]; - } - - if (edges[2].y <= edges[3].y) { - lines[1].p1 = edges[2]; - lines[1].p2 = edges[3]; - } else { - lines[1].p1 = edges[3]; - lines[1].p2 = edges[2]; - } - - if (t[1].y == t[2].y) { - add_tri (traps, t[0].y, t[1].y, &lines[0], &lines[1]); - return; - } - - if (t[1].y <= t[2].y) { - lines[2].p1 = t[1]; - lines[2].p2 = t[2]; - } else { - lines[2].p1 = t[2]; - lines[2].p2 = t[1]; - } - - if (((t[1].y - t[0].y) < 0) ^ ((t[2].y - t[0].y) < 0)) { - add_tri (traps, t[0].y, t[1].y, &lines[0], &lines[2]); - add_tri (traps, t[0].y, t[2].y, &lines[1], &lines[2]); - } else if (abs(t[1].y - t[0].y) < abs(t[2].y - t[0].y)) { - add_tri (traps, t[0].y, t[1].y, &lines[0], &lines[1]); - add_tri (traps, t[1].y, t[2].y, &lines[2], &lines[1]); - } else { - add_tri (traps, t[0].y, t[2].y, &lines[1], &lines[0]); - add_tri (traps, t[1].y, t[2].y, &lines[2], &lines[0]); - } -} - -/** - * _cairo_traps_init_boxes: - * @traps: a #cairo_traps_t - * @box: an array box that will each be converted to a single trapezoid - * to store in @traps. - * - * Initializes a #cairo_traps_t to contain an array of rectangular - * trapezoids. - **/ -cairo_status_t -_cairo_traps_init_boxes (cairo_traps_t *traps, - const cairo_boxes_t *boxes) -{ - cairo_trapezoid_t *trap; - const struct _cairo_boxes_chunk *chunk; - - _cairo_traps_init (traps); - - while (traps->traps_size < boxes->num_boxes) { - if (unlikely (! _cairo_traps_grow (traps))) { - _cairo_traps_fini (traps); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - } - - traps->num_traps = boxes->num_boxes; - traps->is_rectilinear = TRUE; - traps->is_rectangular = TRUE; - traps->maybe_region = boxes->is_pixel_aligned; - - trap = &traps->traps[0]; - for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) { - const cairo_box_t *box; - int i; - - box = chunk->base; - for (i = 0; i < chunk->count; i++) { - trap->top = box->p1.y; - trap->bottom = box->p2.y; - - trap->left.p1 = box->p1; - trap->left.p2.x = box->p1.x; - trap->left.p2.y = box->p2.y; - - trap->right.p1.x = box->p2.x; - trap->right.p1.y = box->p1.y; - trap->right.p2 = box->p2; - - box++, trap++; - } - } - - return CAIRO_STATUS_SUCCESS; -} - -cairo_status_t -_cairo_traps_tessellate_rectangle (cairo_traps_t *traps, - const cairo_point_t *top_left, - const cairo_point_t *bottom_right) -{ - cairo_line_t left; - cairo_line_t right; - cairo_fixed_t top, bottom; - - if (top_left->y == bottom_right->y) - return CAIRO_STATUS_SUCCESS; - - if (top_left->x == bottom_right->x) - return CAIRO_STATUS_SUCCESS; - - left.p1.x = left.p2.x = top_left->x; - left.p1.y = right.p1.y = top_left->y; - right.p1.x = right.p2.x = bottom_right->x; - left.p2.y = right.p2.y = bottom_right->y; - - top = top_left->y; - bottom = bottom_right->y; - - if (traps->num_limits) { - cairo_bool_t reversed; - int n; - - if (top >= traps->bounds.p2.y || bottom <= traps->bounds.p1.y) - return CAIRO_STATUS_SUCCESS; - - /* support counter-clockwise winding for rectangular tessellation */ - reversed = top_left->x > bottom_right->x; - if (reversed) { - right.p1.x = right.p2.x = top_left->x; - left.p1.x = left.p2.x = bottom_right->x; - } - - if (left.p1.x >= traps->bounds.p2.x || right.p1.x <= traps->bounds.p1.x) - return CAIRO_STATUS_SUCCESS; - - for (n = 0; n < traps->num_limits; n++) { - const cairo_box_t *limits = &traps->limits[n]; - cairo_line_t _left, _right; - cairo_fixed_t _top, _bottom; - - if (top >= limits->p2.y) - continue; - if (bottom <= limits->p1.y) - continue; - - /* Trivially reject if trapezoid is entirely to the right or - * to the left of the limits. */ - if (left.p1.x >= limits->p2.x) - continue; - if (right.p1.x <= limits->p1.x) - continue; - - /* Otherwise, clip the trapezoid to the limits. */ - _top = top; - if (_top < limits->p1.y) - _top = limits->p1.y; - - _bottom = bottom; - if (_bottom > limits->p2.y) - _bottom = limits->p2.y; - - if (_bottom <= _top) - continue; - - _left = left; - if (_left.p1.x < limits->p1.x) { - _left.p1.x = limits->p1.x; - _left.p1.y = limits->p1.y; - _left.p2.x = limits->p1.x; - _left.p2.y = limits->p2.y; - } - - _right = right; - if (_right.p1.x > limits->p2.x) { - _right.p1.x = limits->p2.x; - _right.p1.y = limits->p1.y; - _right.p2.x = limits->p2.x; - _right.p2.y = limits->p2.y; - } - - if (left.p1.x >= right.p1.x) - continue; - - if (reversed) - _cairo_traps_add_trap (traps, _top, _bottom, &_right, &_left); - else - _cairo_traps_add_trap (traps, _top, _bottom, &_left, &_right); - } - } else { - _cairo_traps_add_trap (traps, top, bottom, &left, &right); - } - - return traps->status; -} - -void -_cairo_traps_translate (cairo_traps_t *traps, int x, int y) -{ - cairo_fixed_t xoff, yoff; - cairo_trapezoid_t *t; - int i; - - /* Ugh. The cairo_composite/(Render) interface doesn't allow - an offset for the trapezoids. Need to manually shift all - the coordinates to align with the offset origin of the - intermediate surface. */ - - xoff = _cairo_fixed_from_int (x); - yoff = _cairo_fixed_from_int (y); - - for (i = 0, t = traps->traps; i < traps->num_traps; i++, t++) { - t->top += yoff; - t->bottom += yoff; - t->left.p1.x += xoff; - t->left.p1.y += yoff; - t->left.p2.x += xoff; - t->left.p2.y += yoff; - t->right.p1.x += xoff; - t->right.p1.y += yoff; - t->right.p2.x += xoff; - t->right.p2.y += yoff; - } -} - -void -_cairo_trapezoid_array_translate_and_scale (cairo_trapezoid_t *offset_traps, - cairo_trapezoid_t *src_traps, - int num_traps, - double tx, double ty, - double sx, double sy) -{ - int i; - cairo_fixed_t xoff = _cairo_fixed_from_double (tx); - cairo_fixed_t yoff = _cairo_fixed_from_double (ty); - - if (sx == 1.0 && sy == 1.0) { - for (i = 0; i < num_traps; i++) { - offset_traps[i].top = src_traps[i].top + yoff; - offset_traps[i].bottom = src_traps[i].bottom + yoff; - offset_traps[i].left.p1.x = src_traps[i].left.p1.x + xoff; - offset_traps[i].left.p1.y = src_traps[i].left.p1.y + yoff; - offset_traps[i].left.p2.x = src_traps[i].left.p2.x + xoff; - offset_traps[i].left.p2.y = src_traps[i].left.p2.y + yoff; - offset_traps[i].right.p1.x = src_traps[i].right.p1.x + xoff; - offset_traps[i].right.p1.y = src_traps[i].right.p1.y + yoff; - offset_traps[i].right.p2.x = src_traps[i].right.p2.x + xoff; - offset_traps[i].right.p2.y = src_traps[i].right.p2.y + yoff; - } - } else { - cairo_fixed_t xsc = _cairo_fixed_from_double (sx); - cairo_fixed_t ysc = _cairo_fixed_from_double (sy); - - for (i = 0; i < num_traps; i++) { - offset_traps[i].top = _cairo_fixed_mul (src_traps[i].top + yoff, ysc); - offset_traps[i].bottom = _cairo_fixed_mul (src_traps[i].bottom + yoff, ysc); - offset_traps[i].left.p1.x = _cairo_fixed_mul (src_traps[i].left.p1.x + xoff, xsc); - offset_traps[i].left.p1.y = _cairo_fixed_mul (src_traps[i].left.p1.y + yoff, ysc); - offset_traps[i].left.p2.x = _cairo_fixed_mul (src_traps[i].left.p2.x + xoff, xsc); - offset_traps[i].left.p2.y = _cairo_fixed_mul (src_traps[i].left.p2.y + yoff, ysc); - offset_traps[i].right.p1.x = _cairo_fixed_mul (src_traps[i].right.p1.x + xoff, xsc); - offset_traps[i].right.p1.y = _cairo_fixed_mul (src_traps[i].right.p1.y + yoff, ysc); - offset_traps[i].right.p2.x = _cairo_fixed_mul (src_traps[i].right.p2.x + xoff, xsc); - offset_traps[i].right.p2.y = _cairo_fixed_mul (src_traps[i].right.p2.y + yoff, ysc); - } - } -} - -static cairo_bool_t -_cairo_trap_contains (cairo_trapezoid_t *t, cairo_point_t *pt) -{ - cairo_slope_t slope_left, slope_pt, slope_right; - - if (t->top > pt->y) - return FALSE; - if (t->bottom < pt->y) - return FALSE; - - _cairo_slope_init (&slope_left, &t->left.p1, &t->left.p2); - _cairo_slope_init (&slope_pt, &t->left.p1, pt); - - if (_cairo_slope_compare (&slope_left, &slope_pt) < 0) - return FALSE; - - _cairo_slope_init (&slope_right, &t->right.p1, &t->right.p2); - _cairo_slope_init (&slope_pt, &t->right.p1, pt); - - if (_cairo_slope_compare (&slope_pt, &slope_right) < 0) - return FALSE; - - return TRUE; -} - -cairo_bool_t -_cairo_traps_contain (const cairo_traps_t *traps, - double x, double y) -{ - int i; - cairo_point_t point; - - point.x = _cairo_fixed_from_double (x); - point.y = _cairo_fixed_from_double (y); - - for (i = 0; i < traps->num_traps; i++) { - if (_cairo_trap_contains (&traps->traps[i], &point)) - return TRUE; - } - - return FALSE; -} - -static cairo_fixed_t -_line_compute_intersection_x_for_y (const cairo_line_t *line, - cairo_fixed_t y) -{ - return _cairo_edge_compute_intersection_x_for_y (&line->p1, &line->p2, y); -} - -void -_cairo_traps_extents (const cairo_traps_t *traps, - cairo_box_t *extents) -{ - int i; - - if (traps->num_traps == 0) { - extents->p1.x = extents->p1.y = 0; - extents->p2.x = extents->p2.y = 0; - return; - } - - extents->p1.x = extents->p1.y = INT32_MAX; - extents->p2.x = extents->p2.y = INT32_MIN; - - for (i = 0; i < traps->num_traps; i++) { - const cairo_trapezoid_t *trap = &traps->traps[i]; - - if (trap->top < extents->p1.y) - extents->p1.y = trap->top; - if (trap->bottom > extents->p2.y) - extents->p2.y = trap->bottom; - - if (trap->left.p1.x < extents->p1.x) { - cairo_fixed_t x = trap->left.p1.x; - if (trap->top != trap->left.p1.y) { - x = _line_compute_intersection_x_for_y (&trap->left, - trap->top); - if (x < extents->p1.x) - extents->p1.x = x; - } else - extents->p1.x = x; - } - if (trap->left.p2.x < extents->p1.x) { - cairo_fixed_t x = trap->left.p2.x; - if (trap->bottom != trap->left.p2.y) { - x = _line_compute_intersection_x_for_y (&trap->left, - trap->bottom); - if (x < extents->p1.x) - extents->p1.x = x; - } else - extents->p1.x = x; - } - - if (trap->right.p1.x > extents->p2.x) { - cairo_fixed_t x = trap->right.p1.x; - if (trap->top != trap->right.p1.y) { - x = _line_compute_intersection_x_for_y (&trap->right, - trap->top); - if (x > extents->p2.x) - extents->p2.x = x; - } else - extents->p2.x = x; - } - if (trap->right.p2.x > extents->p2.x) { - cairo_fixed_t x = trap->right.p2.x; - if (trap->bottom != trap->right.p2.y) { - x = _line_compute_intersection_x_for_y (&trap->right, - trap->bottom); - if (x > extents->p2.x) - extents->p2.x = x; - } else - extents->p2.x = x; - } - } -} - -static cairo_bool_t -_mono_edge_is_vertical (const cairo_line_t *line) -{ - return _cairo_fixed_integer_round_down (line->p1.x) == _cairo_fixed_integer_round_down (line->p2.x); -} - -static cairo_bool_t -_traps_are_pixel_aligned (cairo_traps_t *traps, - cairo_antialias_t antialias) -{ - int i; - - if (antialias == CAIRO_ANTIALIAS_NONE) { - for (i = 0; i < traps->num_traps; i++) { - if (! _mono_edge_is_vertical (&traps->traps[i].left) || - ! _mono_edge_is_vertical (&traps->traps[i].right)) - { - traps->maybe_region = FALSE; - return FALSE; - } - } - } else { - for (i = 0; i < traps->num_traps; i++) { - if (traps->traps[i].left.p1.x != traps->traps[i].left.p2.x || - traps->traps[i].right.p1.x != traps->traps[i].right.p2.x || - ! _cairo_fixed_is_integer (traps->traps[i].top) || - ! _cairo_fixed_is_integer (traps->traps[i].bottom) || - ! _cairo_fixed_is_integer (traps->traps[i].left.p1.x) || - ! _cairo_fixed_is_integer (traps->traps[i].right.p1.x)) - { - traps->maybe_region = FALSE; - return FALSE; - } - } - } - - return TRUE; -} - -/** - * _cairo_traps_extract_region: - * @traps: a #cairo_traps_t - * @region: a #cairo_region_t - * - * Determines if a set of trapezoids are exactly representable as a - * cairo region. If so, the passed-in region is initialized to - * the area representing the given traps. It should be finalized - * with cairo_region_fini(). If not, %CAIRO_INT_STATUS_UNSUPPORTED - * is returned. - * - * Return value: %CAIRO_STATUS_SUCCESS, %CAIRO_INT_STATUS_UNSUPPORTED - * or %CAIRO_STATUS_NO_MEMORY - **/ -cairo_int_status_t -_cairo_traps_extract_region (cairo_traps_t *traps, - cairo_antialias_t antialias, - cairo_region_t **region) -{ - cairo_rectangle_int_t stack_rects[CAIRO_STACK_ARRAY_LENGTH (cairo_rectangle_int_t)]; - cairo_rectangle_int_t *rects = stack_rects; - cairo_int_status_t status; - int i, rect_count; - - /* we only treat this a hint... */ - if (antialias != CAIRO_ANTIALIAS_NONE && ! traps->maybe_region) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (! _traps_are_pixel_aligned (traps, antialias)) { - traps->maybe_region = FALSE; - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - if (traps->num_traps > ARRAY_LENGTH (stack_rects)) { - rects = _cairo_malloc_ab (traps->num_traps, sizeof (cairo_rectangle_int_t)); - - if (unlikely (rects == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - rect_count = 0; - for (i = 0; i < traps->num_traps; i++) { - int x1, y1, x2, y2; - - if (antialias == CAIRO_ANTIALIAS_NONE) { - x1 = _cairo_fixed_integer_round_down (traps->traps[i].left.p1.x); - y1 = _cairo_fixed_integer_round_down (traps->traps[i].top); - x2 = _cairo_fixed_integer_round_down (traps->traps[i].right.p1.x); - y2 = _cairo_fixed_integer_round_down (traps->traps[i].bottom); - } else { - x1 = _cairo_fixed_integer_part (traps->traps[i].left.p1.x); - y1 = _cairo_fixed_integer_part (traps->traps[i].top); - x2 = _cairo_fixed_integer_part (traps->traps[i].right.p1.x); - y2 = _cairo_fixed_integer_part (traps->traps[i].bottom); - } - - if (x2 > x1 && y2 > y1) { - rects[rect_count].x = x1; - rects[rect_count].y = y1; - rects[rect_count].width = x2 - x1; - rects[rect_count].height = y2 - y1; - rect_count++; - } - } - - - *region = cairo_region_create_rectangles (rects, rect_count); - status = (*region)->status; - - if (rects != stack_rects) - free (rects); - - return status; -} - -cairo_bool_t -_cairo_traps_to_boxes (cairo_traps_t *traps, - cairo_antialias_t antialias, - cairo_boxes_t *boxes) -{ - int i; - - for (i = 0; i < traps->num_traps; i++) { - if (traps->traps[i].left.p1.x != traps->traps[i].left.p2.x || - traps->traps[i].right.p1.x != traps->traps[i].right.p2.x) - return FALSE; - } - - _cairo_boxes_init (boxes); - - boxes->num_boxes = traps->num_traps; - boxes->chunks.base = (cairo_box_t *) traps->traps; - boxes->chunks.count = traps->num_traps; - boxes->chunks.size = traps->num_traps; - - if (antialias != CAIRO_ANTIALIAS_NONE) { - for (i = 0; i < traps->num_traps; i++) { - /* Note the traps and boxes alias so we need to take the local copies first. */ - cairo_fixed_t x1 = traps->traps[i].left.p1.x; - cairo_fixed_t x2 = traps->traps[i].right.p1.x; - cairo_fixed_t y1 = traps->traps[i].top; - cairo_fixed_t y2 = traps->traps[i].bottom; - - boxes->chunks.base[i].p1.x = x1; - boxes->chunks.base[i].p1.y = y1; - boxes->chunks.base[i].p2.x = x2; - boxes->chunks.base[i].p2.y = y2; - - if (boxes->is_pixel_aligned) { - boxes->is_pixel_aligned = - _cairo_fixed_is_integer (x1) && _cairo_fixed_is_integer (y1) && - _cairo_fixed_is_integer (x2) && _cairo_fixed_is_integer (y2); - } - } - } else { - boxes->is_pixel_aligned = TRUE; - - for (i = 0; i < traps->num_traps; i++) { - /* Note the traps and boxes alias so we need to take the local copies first. */ - cairo_fixed_t x1 = traps->traps[i].left.p1.x; - cairo_fixed_t x2 = traps->traps[i].right.p1.x; - cairo_fixed_t y1 = traps->traps[i].top; - cairo_fixed_t y2 = traps->traps[i].bottom; - - /* round down here to match Pixman's behavior when using traps. */ - boxes->chunks.base[i].p1.x = _cairo_fixed_round_down (x1); - boxes->chunks.base[i].p1.y = _cairo_fixed_round_down (y1); - boxes->chunks.base[i].p2.x = _cairo_fixed_round_down (x2); - boxes->chunks.base[i].p2.y = _cairo_fixed_round_down (y2); - } - } - - return TRUE; -} - -/* moves trap points such that they become the actual corners of the trapezoid */ -static void -_sanitize_trap (cairo_trapezoid_t *t) -{ - cairo_trapezoid_t s = *t; - -#define FIX(lr, tb, p) \ - if (t->lr.p.y != t->tb) { \ - t->lr.p.x = s.lr.p2.x + _cairo_fixed_mul_div_floor (s.lr.p1.x - s.lr.p2.x, s.tb - s.lr.p2.y, s.lr.p1.y - s.lr.p2.y); \ - t->lr.p.y = s.tb; \ - } - FIX (left, top, p1); - FIX (left, bottom, p2); - FIX (right, top, p1); - FIX (right, bottom, p2); -} - -cairo_private cairo_status_t -_cairo_traps_path (const cairo_traps_t *traps, - cairo_path_fixed_t *path) -{ - int i; - - for (i = 0; i < traps->num_traps; i++) { - cairo_status_t status; - cairo_trapezoid_t trap = traps->traps[i]; - - if (trap.top == trap.bottom) - continue; - - _sanitize_trap (&trap); - - status = _cairo_path_fixed_move_to (path, trap.left.p1.x, trap.top); - if (unlikely (status)) return status; - status = _cairo_path_fixed_line_to (path, trap.right.p1.x, trap.top); - if (unlikely (status)) return status; - status = _cairo_path_fixed_line_to (path, trap.right.p2.x, trap.bottom); - if (unlikely (status)) return status; - status = _cairo_path_fixed_line_to (path, trap.left.p2.x, trap.bottom); - if (unlikely (status)) return status; - status = _cairo_path_fixed_close_path (path); - if (unlikely (status)) return status; - } - - return CAIRO_STATUS_SUCCESS; -} - -void -_cairo_debug_print_traps (FILE *file, const cairo_traps_t *traps) -{ - cairo_box_t extents; - int n; - -#if 0 - if (traps->has_limits) { - printf ("%s: limits=(%d, %d, %d, %d)\n", - filename, - traps->limits.p1.x, traps->limits.p1.y, - traps->limits.p2.x, traps->limits.p2.y); - } -#endif - - _cairo_traps_extents (traps, &extents); - fprintf (file, "extents=(%d, %d, %d, %d)\n", - extents.p1.x, extents.p1.y, - extents.p2.x, extents.p2.y); - - for (n = 0; n < traps->num_traps; n++) { - fprintf (file, "%d %d L:(%d, %d), (%d, %d) R:(%d, %d), (%d, %d)\n", - traps->traps[n].top, - traps->traps[n].bottom, - traps->traps[n].left.p1.x, - traps->traps[n].left.p1.y, - traps->traps[n].left.p2.x, - traps->traps[n].left.p2.y, - traps->traps[n].right.p1.x, - traps->traps[n].right.p1.y, - traps->traps[n].right.p2.x, - traps->traps[n].right.p2.y); - } -} - -struct cairo_trap_renderer { - cairo_span_renderer_t base; - cairo_traps_t *traps; -}; - -static cairo_status_t -span_to_traps (void *abstract_renderer, int y, int h, - const cairo_half_open_span_t *spans, unsigned num_spans) -{ - struct cairo_trap_renderer *r = abstract_renderer; - cairo_fixed_t top, bot; - - if (num_spans == 0) - return CAIRO_STATUS_SUCCESS; - - top = _cairo_fixed_from_int (y); - bot = _cairo_fixed_from_int (y + h); - do { - if (spans[0].coverage) { - cairo_fixed_t x0 = _cairo_fixed_from_int(spans[0].x); - cairo_fixed_t x1 = _cairo_fixed_from_int(spans[1].x); - cairo_line_t left = { { x0, top }, { x0, bot } }, - right = { { x1, top }, { x1, bot } }; - _cairo_traps_add_trap (r->traps, top, bot, &left, &right); - } - spans++; - } while (--num_spans > 1); - - return CAIRO_STATUS_SUCCESS; -} - -cairo_int_status_t -_cairo_rasterise_polygon_to_traps (cairo_polygon_t *polygon, - cairo_fill_rule_t fill_rule, - cairo_antialias_t antialias, - cairo_traps_t *traps) -{ - struct cairo_trap_renderer renderer; - cairo_scan_converter_t *converter; - cairo_int_status_t status; - cairo_rectangle_int_t r; - - TRACE ((stderr, "%s: fill_rule=%d, antialias=%d\n", - __FUNCTION__, fill_rule, antialias)); - assert(antialias == CAIRO_ANTIALIAS_NONE); - - renderer.traps = traps; - renderer.base.render_rows = span_to_traps; - - _cairo_box_round_to_rectangle (&polygon->extents, &r); - converter = _cairo_mono_scan_converter_create (r.x, r.y, - r.x + r.width, - r.y + r.height, - fill_rule); - status = _cairo_mono_scan_converter_add_polygon (converter, polygon); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) - status = converter->generate (converter, &renderer.base); - converter->destroy (converter); - return status; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-tristrip-private.h b/source/libs/cairo/cairo-src/src/cairo-tristrip-private.h deleted file mode 100644 index ccd28799e826fb43c45544e8f07979c1f8018a3a..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-tristrip-private.h +++ /dev/null @@ -1,94 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_TRISTRIP_PRIVATE_H -#define CAIRO_TRISTRIP_PRIVATE_H - -#include "cairo-compiler-private.h" -#include "cairo-error-private.h" -#include "cairo-types-private.h" - -CAIRO_BEGIN_DECLS - -struct _cairo_tristrip { - cairo_status_t status; - - /* XXX clipping */ - - const cairo_box_t *limits; - int num_limits; - - int num_points; - int size_points; - cairo_point_t *points; - cairo_point_t points_embedded[64]; -}; - -cairo_private void -_cairo_tristrip_init (cairo_tristrip_t *strip); - -cairo_private void -_cairo_tristrip_limit (cairo_tristrip_t *strip, - const cairo_box_t *limits, - int num_limits); - -cairo_private void -_cairo_tristrip_init_with_clip (cairo_tristrip_t *strip, - const cairo_clip_t *clip); - -cairo_private void -_cairo_tristrip_translate (cairo_tristrip_t *strip, int x, int y); - -cairo_private void -_cairo_tristrip_move_to (cairo_tristrip_t *strip, - const cairo_point_t *point); - -cairo_private void -_cairo_tristrip_add_point (cairo_tristrip_t *strip, - const cairo_point_t *point); - -cairo_private void -_cairo_tristrip_extents (const cairo_tristrip_t *strip, - cairo_box_t *extents); - -cairo_private void -_cairo_tristrip_fini (cairo_tristrip_t *strip); - -#define _cairo_tristrip_status(T) ((T)->status) - -CAIRO_END_DECLS - -#endif /* CAIRO_TRISTRIP_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-tristrip.c b/source/libs/cairo/cairo-src/src/cairo-tristrip.c deleted file mode 100644 index bb4972f5003403cb5ae708248790910b78f9f8f7..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-tristrip.c +++ /dev/null @@ -1,185 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Chris Wilson - * - * Contributor(s): - * Chris Wilson <chris@chris-wilsonc.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-error-private.h" -#include "cairo-tristrip-private.h" - -void -_cairo_tristrip_init (cairo_tristrip_t *strip) -{ - VG (VALGRIND_MAKE_MEM_UNDEFINED (strip, sizeof (cairo_tristrip_t))); - - strip->status = CAIRO_STATUS_SUCCESS; - - strip->num_limits = 0; - strip->num_points = 0; - - strip->size_points = ARRAY_LENGTH (strip->points_embedded); - strip->points = strip->points_embedded; -} - -void -_cairo_tristrip_fini (cairo_tristrip_t *strip) -{ - if (strip->points != strip->points_embedded) - free (strip->points); - - VG (VALGRIND_MAKE_MEM_NOACCESS (strip, sizeof (cairo_tristrip_t))); -} - - -void -_cairo_tristrip_limit (cairo_tristrip_t *strip, - const cairo_box_t *limits, - int num_limits) -{ - strip->limits = limits; - strip->num_limits = num_limits; -} - -void -_cairo_tristrip_init_with_clip (cairo_tristrip_t *strip, - const cairo_clip_t *clip) -{ - _cairo_tristrip_init (strip); - if (clip) - _cairo_tristrip_limit (strip, clip->boxes, clip->num_boxes); -} - -/* make room for at least one more trap */ -static cairo_bool_t -_cairo_tristrip_grow (cairo_tristrip_t *strip) -{ - cairo_point_t *points; - int new_size = 4 * strip->size_points; - - if (CAIRO_INJECT_FAULT ()) { - strip->status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - return FALSE; - } - - if (strip->points == strip->points_embedded) { - points = _cairo_malloc_ab (new_size, sizeof (cairo_point_t)); - if (points != NULL) - memcpy (points, strip->points, sizeof (strip->points_embedded)); - } else { - points = _cairo_realloc_ab (strip->points, - new_size, sizeof (cairo_trapezoid_t)); - } - - if (unlikely (points == NULL)) { - strip->status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - return FALSE; - } - - strip->points = points; - strip->size_points = new_size; - return TRUE; -} - -void -_cairo_tristrip_add_point (cairo_tristrip_t *strip, - const cairo_point_t *p) -{ - if (unlikely (strip->num_points == strip->size_points)) { - if (unlikely (! _cairo_tristrip_grow (strip))) - return; - } - - strip->points[strip->num_points++] = *p; -} - -/* Insert degenerate triangles to advance to the given point. The - * next point inserted must also be @p. */ -void -_cairo_tristrip_move_to (cairo_tristrip_t *strip, - const cairo_point_t *p) -{ - if (strip->num_points == 0) - return; - - _cairo_tristrip_add_point (strip, &strip->points[strip->num_points-1]); - _cairo_tristrip_add_point (strip, p); -#if 0 - /* and one more for luck! (to preserve cw/ccw ordering) */ - _cairo_tristrip_add_point (strip, p); -#endif -} - -void -_cairo_tristrip_translate (cairo_tristrip_t *strip, int x, int y) -{ - cairo_fixed_t xoff, yoff; - cairo_point_t *p; - int i; - - xoff = _cairo_fixed_from_int (x); - yoff = _cairo_fixed_from_int (y); - - for (i = 0, p = strip->points; i < strip->num_points; i++, p++) { - p->x += xoff; - p->y += yoff; - } -} - -void -_cairo_tristrip_extents (const cairo_tristrip_t *strip, - cairo_box_t *extents) -{ - int i; - - if (strip->num_points == 0) { - extents->p1.x = extents->p1.y = 0; - extents->p2.x = extents->p2.y = 0; - return; - } - - extents->p2 = extents->p1 = strip->points[0]; - for (i = 1; i < strip->num_points; i++) { - const cairo_point_t *p = &strip->points[i]; - - if (p->x < extents->p1.x) - extents->p1.x = p->x; - else if (p->x > extents->p2.x) - extents->p2.x = p->x; - - if (p->y < extents->p1.y) - extents->p1.y = p->y; - else if (p->y > extents->p2.y) - extents->p2.y = p->y; - } -} diff --git a/source/libs/cairo/cairo-src/src/cairo-truetype-subset-private.h b/source/libs/cairo/cairo-src/src/cairo-truetype-subset-private.h deleted file mode 100644 index dc9573216f3eee53f852f88ab65c75926662bc2c..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-truetype-subset-private.h +++ /dev/null @@ -1,212 +0,0 @@ -/* 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Kristian Høgsberg <krh@redhat.com> - * Adrian Johnson <ajohnson@redneon.com> - */ - -#ifndef CAIRO_TRUETYPE_SUBSET_PRIVATE_H -#define CAIRO_TRUETYPE_SUBSET_PRIVATE_H - -#include "cairoint.h" - -#if CAIRO_HAS_FONT_SUBSET - -/* The structs defined here should strictly follow the TrueType - * specification and not be padded. We use only 16-bit integer - * in their definition to guarantee that. The fields of type - * "FIXED" in the TT spec are broken into two *_1 and *_2 16-bit - * parts, and 64-bit members are broken into four. - * - * The test truetype-tables in the test suite makes sure that - * these tables have the right size. Please update that test - * if you add new tables/structs that should be packed. - */ - -#define MAKE_TT_TAG(a, b, c, d) (a<<24 | b<<16 | c<<8 | d) -#define TT_TAG_CFF MAKE_TT_TAG('C','F','F',' ') -#define TT_TAG_cmap MAKE_TT_TAG('c','m','a','p') -#define TT_TAG_cvt MAKE_TT_TAG('c','v','t',' ') -#define TT_TAG_fpgm MAKE_TT_TAG('f','p','g','m') -#define TT_TAG_glyf MAKE_TT_TAG('g','l','y','f') -#define TT_TAG_head MAKE_TT_TAG('h','e','a','d') -#define TT_TAG_hhea MAKE_TT_TAG('h','h','e','a') -#define TT_TAG_hmtx MAKE_TT_TAG('h','m','t','x') -#define TT_TAG_loca MAKE_TT_TAG('l','o','c','a') -#define TT_TAG_maxp MAKE_TT_TAG('m','a','x','p') -#define TT_TAG_name MAKE_TT_TAG('n','a','m','e') -#define TT_TAG_OS2 MAKE_TT_TAG('O','S','/','2') -#define TT_TAG_post MAKE_TT_TAG('p','o','s','t') -#define TT_TAG_prep MAKE_TT_TAG('p','r','e','p') - -/* All tt_* structs are big-endian */ -typedef struct _tt_cmap_index { - uint16_t platform; - uint16_t encoding; - uint32_t offset; -} tt_cmap_index_t; - -typedef struct _tt_cmap { - uint16_t version; - uint16_t num_tables; - tt_cmap_index_t index[1]; -} tt_cmap_t; - -typedef struct _segment_map { - uint16_t format; - uint16_t length; - uint16_t version; - uint16_t segCountX2; - uint16_t searchRange; - uint16_t entrySelector; - uint16_t rangeShift; - uint16_t endCount[1]; -} tt_segment_map_t; - -typedef struct _tt_head { - int16_t version_1; - int16_t version_2; - int16_t revision_1; - int16_t revision_2; - uint16_t checksum_1; - uint16_t checksum_2; - uint16_t magic_1; - uint16_t magic_2; - uint16_t flags; - uint16_t units_per_em; - int16_t created_1; - int16_t created_2; - int16_t created_3; - int16_t created_4; - int16_t modified_1; - int16_t modified_2; - int16_t modified_3; - int16_t modified_4; - int16_t x_min; /* FWORD */ - int16_t y_min; /* FWORD */ - int16_t x_max; /* FWORD */ - int16_t y_max; /* FWORD */ - uint16_t mac_style; - uint16_t lowest_rec_pppem; - int16_t font_direction_hint; - int16_t index_to_loc_format; - int16_t glyph_data_format; -} tt_head_t; - -typedef struct _tt_hhea { - int16_t version_1; - int16_t version_2; - int16_t ascender; /* FWORD */ - int16_t descender; /* FWORD */ - int16_t line_gap; /* FWORD */ - uint16_t advance_max_width; /* UFWORD */ - int16_t min_left_side_bearing; /* FWORD */ - int16_t min_right_side_bearing; /* FWORD */ - int16_t x_max_extent; /* FWORD */ - int16_t caret_slope_rise; - int16_t caret_slope_run; - int16_t reserved[5]; - int16_t metric_data_format; - uint16_t num_hmetrics; -} tt_hhea_t; - -typedef struct _tt_maxp { - int16_t version_1; - int16_t version_2; - uint16_t num_glyphs; - uint16_t max_points; - uint16_t max_contours; - uint16_t max_composite_points; - uint16_t max_composite_contours; - uint16_t max_zones; - uint16_t max_twilight_points; - uint16_t max_storage; - uint16_t max_function_defs; - uint16_t max_instruction_defs; - uint16_t max_stack_elements; - uint16_t max_size_of_instructions; - uint16_t max_component_elements; - uint16_t max_component_depth; -} tt_maxp_t; - -typedef struct _tt_name_record { - uint16_t platform; - uint16_t encoding; - uint16_t language; - uint16_t name; - uint16_t length; - uint16_t offset; -} tt_name_record_t; - -typedef struct _tt_name { - uint16_t format; - uint16_t num_records; - uint16_t strings_offset; - tt_name_record_t records[1]; -} tt_name_t; - - -/* bitmask for fsSelection field */ -#define TT_FS_SELECTION_ITALIC 1 -#define TT_FS_SELECTION_BOLD 32 - -/* _unused fields are defined in TT spec but not used by cairo */ -typedef struct _tt_os2 { - uint16_t _unused1[2]; - uint16_t usWeightClass; - uint16_t _unused2[28]; - uint16_t fsSelection; - uint16_t _unused3[11]; -} tt_os2_t; - -/* composite_glyph_t flags */ -#define TT_ARG_1_AND_2_ARE_WORDS 0x0001 -#define TT_WE_HAVE_A_SCALE 0x0008 -#define TT_MORE_COMPONENTS 0x0020 -#define TT_WE_HAVE_AN_X_AND_Y_SCALE 0x0040 -#define TT_WE_HAVE_A_TWO_BY_TWO 0x0080 - -typedef struct _tt_composite_glyph { - uint16_t flags; - uint16_t index; - uint16_t args[6]; /* 1 to 6 arguments depending on value of flags */ -} tt_composite_glyph_t; - -typedef struct _tt_glyph_data { - int16_t num_contours; - int8_t data[8]; - tt_composite_glyph_t glyph; -} tt_glyph_data_t; - -#endif /* CAIRO_HAS_FONT_SUBSET */ - -#endif /* CAIRO_TRUETYPE_SUBSET_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-truetype-subset.c b/source/libs/cairo/cairo-src/src/cairo-truetype-subset.c deleted file mode 100644 index 9137ef3aa38ae5e82b9e8362d63f8a3c3eb105f9..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-truetype-subset.c +++ /dev/null @@ -1,1649 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2004 Red Hat, Inc - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Kristian Høgsberg <krh@redhat.com> - * Adrian Johnson <ajohnson@redneon.com> - */ - -/* - * Useful links: - * http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6.html - * http://www.microsoft.com/typography/specs/default.htm - */ - -#define _BSD_SOURCE /* for snprintf(), strdup() */ -#include "cairoint.h" - -#include "cairo-array-private.h" -#include "cairo-error-private.h" - -#if CAIRO_HAS_FONT_SUBSET - -#include "cairo-scaled-font-subsets-private.h" -#include "cairo-truetype-subset-private.h" - - -typedef struct subset_glyph subset_glyph_t; -struct subset_glyph { - int parent_index; - unsigned long location; -}; - -typedef struct _cairo_truetype_font cairo_truetype_font_t; - -typedef struct table table_t; -struct table { - unsigned long tag; - cairo_status_t (*write) (cairo_truetype_font_t *font, unsigned long tag); - int pos; /* position in the font directory */ -}; - -struct _cairo_truetype_font { - - cairo_scaled_font_subset_t *scaled_font_subset; - - table_t truetype_tables[10]; - int num_tables; - - struct { - char *font_name; - char *ps_name; - unsigned int num_glyphs; - int *widths; - long x_min, y_min, x_max, y_max; - long ascent, descent; - int units_per_em; - } base; - - subset_glyph_t *glyphs; - const cairo_scaled_font_backend_t *backend; - int num_glyphs_in_face; - int checksum_index; - cairo_array_t output; - cairo_array_t string_offsets; - unsigned long last_offset; - unsigned long last_boundary; - int *parent_to_subset; - cairo_status_t status; - cairo_bool_t is_pdf; -}; - -/* - * Test that the structs we define for TrueType tables have the - * correct size, ie. they are not padded. - */ -#define check(T, S) COMPILE_TIME_ASSERT (sizeof (T) == (S)) -check (tt_head_t, 54); -check (tt_hhea_t, 36); -check (tt_maxp_t, 32); -check (tt_name_record_t, 12); -check (tt_name_t, 18); -check (tt_name_t, 18); -check (tt_composite_glyph_t, 16); -check (tt_glyph_data_t, 26); -#undef check - -static cairo_status_t -cairo_truetype_font_use_glyph (cairo_truetype_font_t *font, - unsigned short glyph, - unsigned short *out); - -#define SFNT_VERSION 0x00010000 -#define SFNT_STRING_MAX_LENGTH 65535 - -static cairo_status_t -_cairo_truetype_font_set_error (cairo_truetype_font_t *font, - cairo_status_t status) -{ - if (status == CAIRO_STATUS_SUCCESS || - status == (int)CAIRO_INT_STATUS_UNSUPPORTED) - return status; - - _cairo_status_set_error (&font->status, status); - - return _cairo_error (status); -} - -static cairo_status_t -_cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset, - cairo_bool_t is_pdf, - cairo_truetype_font_t **font_return) -{ - cairo_status_t status; - cairo_truetype_font_t *font; - const cairo_scaled_font_backend_t *backend; - tt_head_t head; - tt_hhea_t hhea; - tt_maxp_t maxp; - unsigned long size; - - backend = scaled_font_subset->scaled_font->backend; - if (!backend->load_truetype_table) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* FIXME: We should either support subsetting vertical fonts, or fail on - * vertical. Currently font_options_t doesn't have vertical flag, but - * it should be added in the future. For now, the freetype backend - * returns UNSUPPORTED in load_truetype_table if the font is vertical. - * - * if (cairo_font_options_get_vertical_layout (scaled_font_subset->scaled_font)) - * return CAIRO_INT_STATUS_UNSUPPORTED; - */ - - /* We need to use a fallback font generated from the synthesized outlines. */ - if (backend->is_synthetic && backend->is_synthetic (scaled_font_subset->scaled_font)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - size = sizeof (tt_head_t); - status = backend->load_truetype_table (scaled_font_subset->scaled_font, - TT_TAG_head, 0, - (unsigned char *) &head, - &size); - if (unlikely (status)) - return status; - - size = sizeof (tt_maxp_t); - status = backend->load_truetype_table (scaled_font_subset->scaled_font, - TT_TAG_maxp, 0, - (unsigned char *) &maxp, - &size); - if (unlikely (status)) - return status; - - size = sizeof (tt_hhea_t); - status = backend->load_truetype_table (scaled_font_subset->scaled_font, - TT_TAG_hhea, 0, - (unsigned char *) &hhea, - &size); - if (unlikely (status)) - return status; - - font = malloc (sizeof (cairo_truetype_font_t)); - if (unlikely (font == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - font->backend = backend; - font->num_glyphs_in_face = be16_to_cpu (maxp.num_glyphs); - font->scaled_font_subset = scaled_font_subset; - - font->last_offset = 0; - font->last_boundary = 0; - _cairo_array_init (&font->output, sizeof (char)); - status = _cairo_array_grow_by (&font->output, 4096); - if (unlikely (status)) - goto fail1; - - font->glyphs = calloc (font->num_glyphs_in_face + 1, sizeof (subset_glyph_t)); - if (unlikely (font->glyphs == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail1; - } - - font->parent_to_subset = calloc (font->num_glyphs_in_face, sizeof (int)); - if (unlikely (font->parent_to_subset == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail2; - } - - font->is_pdf = is_pdf; - font->base.num_glyphs = 0; - font->base.x_min = (int16_t) be16_to_cpu (head.x_min); - font->base.y_min = (int16_t) be16_to_cpu (head.y_min); - font->base.x_max = (int16_t) be16_to_cpu (head.x_max); - font->base.y_max = (int16_t) be16_to_cpu (head.y_max); - font->base.ascent = (int16_t) be16_to_cpu (hhea.ascender); - font->base.descent = (int16_t) be16_to_cpu (hhea.descender); - font->base.units_per_em = (int16_t) be16_to_cpu (head.units_per_em); - if (font->base.units_per_em == 0) - font->base.units_per_em = 2048; - - font->base.ps_name = NULL; - font->base.font_name = NULL; - status = _cairo_truetype_read_font_name (scaled_font_subset->scaled_font, - &font->base.ps_name, - &font->base.font_name); - if (_cairo_status_is_error (status)) - goto fail3; - - /* If the PS name is not found, create a CairoFont-x-y name. */ - if (font->base.ps_name == NULL) { - font->base.ps_name = malloc (30); - if (unlikely (font->base.ps_name == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail3; - } - - snprintf(font->base.ps_name, 30, "CairoFont-%u-%u", - scaled_font_subset->font_id, - scaled_font_subset->subset_id); - } - - font->base.widths = calloc (font->num_glyphs_in_face, sizeof (int)); - if (unlikely (font->base.widths == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail4; - } - - _cairo_array_init (&font->string_offsets, sizeof (unsigned long)); - status = _cairo_array_grow_by (&font->string_offsets, 10); - if (unlikely (status)) - goto fail5; - - font->status = CAIRO_STATUS_SUCCESS; - - *font_return = font; - - return CAIRO_STATUS_SUCCESS; - - fail5: - _cairo_array_fini (&font->string_offsets); - free (font->base.widths); - fail4: - free (font->base.ps_name); - fail3: - free (font->parent_to_subset); - free (font->base.font_name); - fail2: - free (font->glyphs); - fail1: - _cairo_array_fini (&font->output); - free (font); - - return status; -} - -static void -cairo_truetype_font_destroy (cairo_truetype_font_t *font) -{ - _cairo_array_fini (&font->string_offsets); - free (font->base.widths); - free (font->base.ps_name); - free (font->base.font_name); - free (font->parent_to_subset); - free (font->glyphs); - _cairo_array_fini (&font->output); - free (font); -} - -static cairo_status_t -cairo_truetype_font_allocate_write_buffer (cairo_truetype_font_t *font, - size_t length, - unsigned char **buffer) -{ - cairo_status_t status; - - if (font->status) - return font->status; - - status = _cairo_array_allocate (&font->output, length, (void **) buffer); - if (unlikely (status)) - return _cairo_truetype_font_set_error (font, status); - - return CAIRO_STATUS_SUCCESS; -} - -static void -cairo_truetype_font_write (cairo_truetype_font_t *font, - const void *data, - size_t length) -{ - cairo_status_t status; - - if (font->status) - return; - - status = _cairo_array_append_multiple (&font->output, data, length); - if (unlikely (status)) - status = _cairo_truetype_font_set_error (font, status); -} - -static void -cairo_truetype_font_write_be16 (cairo_truetype_font_t *font, - uint16_t value) -{ - uint16_t be16_value; - - if (font->status) - return; - - be16_value = cpu_to_be16 (value); - cairo_truetype_font_write (font, &be16_value, sizeof be16_value); -} - -static void -cairo_truetype_font_write_be32 (cairo_truetype_font_t *font, - uint32_t value) -{ - uint32_t be32_value; - - if (font->status) - return; - - be32_value = cpu_to_be32 (value); - cairo_truetype_font_write (font, &be32_value, sizeof be32_value); -} - -static cairo_status_t -cairo_truetype_font_align_output (cairo_truetype_font_t *font, - unsigned long *aligned) -{ - int length, pad; - unsigned char *padding; - - length = _cairo_array_num_elements (&font->output); - *aligned = (length + 3) & ~3; - pad = *aligned - length; - - if (pad) { - cairo_status_t status; - - status = cairo_truetype_font_allocate_write_buffer (font, pad, - &padding); - if (unlikely (status)) - return status; - - memset (padding, 0, pad); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_truetype_font_check_boundary (cairo_truetype_font_t *font, - unsigned long boundary) -{ - cairo_status_t status; - - if (font->status) - return font->status; - - if (boundary - font->last_offset > SFNT_STRING_MAX_LENGTH) - { - status = _cairo_array_append (&font->string_offsets, - &font->last_boundary); - if (unlikely (status)) - return _cairo_truetype_font_set_error (font, status); - - font->last_offset = font->last_boundary; - } - font->last_boundary = boundary; - - return CAIRO_STATUS_SUCCESS; -} - -typedef struct _cmap_unicode_range { - unsigned int start; - unsigned int end; -} cmap_unicode_range_t; - -static cmap_unicode_range_t winansi_unicode_ranges[] = { - { 0x0020, 0x007f }, - { 0x00a0, 0x00ff }, - { 0x0152, 0x0153 }, - { 0x0160, 0x0161 }, - { 0x0178, 0x0178 }, - { 0x017d, 0x017e }, - { 0x0192, 0x0192 }, - { 0x02c6, 0x02c6 }, - { 0x02dc, 0x02dc }, - { 0x2013, 0x2026 }, - { 0x2030, 0x2030 }, - { 0x2039, 0x203a }, - { 0x20ac, 0x20ac }, - { 0x2122, 0x2122 }, -}; - -static cairo_status_t -cairo_truetype_font_write_cmap_table (cairo_truetype_font_t *font, - unsigned long tag) -{ - int i; - unsigned int j; - int range_offset; - int num_ranges; - int entry_selector; - int length; - - num_ranges = ARRAY_LENGTH (winansi_unicode_ranges); - - length = 16 + (num_ranges + 1)*8; - for (i = 0; i < num_ranges; i++) - length += (winansi_unicode_ranges[i].end - winansi_unicode_ranges[i].start + 1)*2; - - entry_selector = 0; - while ((1 << entry_selector) <= (num_ranges + 1)) - entry_selector++; - - entry_selector--; - - cairo_truetype_font_write_be16 (font, 0); /* Table version */ - cairo_truetype_font_write_be16 (font, 1); /* Num tables */ - - cairo_truetype_font_write_be16 (font, 3); /* Platform */ - cairo_truetype_font_write_be16 (font, 1); /* Encoding */ - cairo_truetype_font_write_be32 (font, 12); /* Offset to start of table */ - - /* Output a format 4 encoding table for the winansi encoding */ - - cairo_truetype_font_write_be16 (font, 4); /* Format */ - cairo_truetype_font_write_be16 (font, length); /* Length */ - cairo_truetype_font_write_be16 (font, 0); /* Version */ - cairo_truetype_font_write_be16 (font, num_ranges*2 + 2); /* 2*segcount */ - cairo_truetype_font_write_be16 (font, (1 << (entry_selector + 1))); /* searchrange */ - cairo_truetype_font_write_be16 (font, entry_selector); /* entry selector */ - cairo_truetype_font_write_be16 (font, num_ranges*2 + 2 - (1 << (entry_selector + 1))); /* rangeshift */ - for (i = 0; i < num_ranges; i++) - cairo_truetype_font_write_be16 (font, winansi_unicode_ranges[i].end); /* end count[] */ - cairo_truetype_font_write_be16 (font, 0xffff); /* end count[] */ - - cairo_truetype_font_write_be16 (font, 0); /* reserved */ - - for (i = 0; i < num_ranges; i++) - cairo_truetype_font_write_be16 (font, winansi_unicode_ranges[i].start); /* startCode[] */ - cairo_truetype_font_write_be16 (font, 0xffff); /* startCode[] */ - - for (i = 0; i < num_ranges; i++) - cairo_truetype_font_write_be16 (font, 0x0000); /* delta[] */ - cairo_truetype_font_write_be16 (font, 1); /* delta[] */ - - range_offset = num_ranges*2 + 2; - for (i = 0; i < num_ranges; i++) { - cairo_truetype_font_write_be16 (font, range_offset); /* rangeOffset[] */ - range_offset += (winansi_unicode_ranges[i].end - winansi_unicode_ranges[i].start + 1)*2 - 2; - } - cairo_truetype_font_write_be16 (font, 0); /* rangeOffset[] */ - - for (i = 0; i < num_ranges; i++) { - for (j = winansi_unicode_ranges[i].start; j < winansi_unicode_ranges[i].end + 1; j++) { - int ch = _cairo_unicode_to_winansi (j); - int glyph; - - if (ch > 0) - glyph = font->scaled_font_subset->latin_to_subset_glyph_index[ch]; - else - glyph = 0; - cairo_truetype_font_write_be16 (font, glyph); - } - } - - return font->status; -} - -static cairo_status_t -cairo_truetype_font_write_generic_table (cairo_truetype_font_t *font, - unsigned long tag) -{ - cairo_status_t status; - unsigned char *buffer; - unsigned long size; - - if (font->status) - return font->status; - - size = 0; - status = font->backend->load_truetype_table(font->scaled_font_subset->scaled_font, - tag, 0, NULL, &size); - if (unlikely (status)) - return _cairo_truetype_font_set_error (font, status); - - status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer); - if (unlikely (status)) - return _cairo_truetype_font_set_error (font, status); - - status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - tag, 0, buffer, &size); - if (unlikely (status)) - return _cairo_truetype_font_set_error (font, status); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t *font, - unsigned char *buffer, - unsigned long size) -{ - tt_glyph_data_t *glyph_data; - tt_composite_glyph_t *composite_glyph; - int num_args; - int has_more_components; - unsigned short flags; - unsigned short index; - cairo_status_t status; - unsigned char *end = buffer + size; - - if (font->status) - return font->status; - - glyph_data = (tt_glyph_data_t *) buffer; - if ((unsigned char *)(&glyph_data->data) >= end) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if ((int16_t)be16_to_cpu (glyph_data->num_contours) >= 0) - return CAIRO_STATUS_SUCCESS; - - composite_glyph = &glyph_data->glyph; - do { - if ((unsigned char *)(&composite_glyph->args[1]) > end) - return CAIRO_INT_STATUS_UNSUPPORTED; - - flags = be16_to_cpu (composite_glyph->flags); - has_more_components = flags & TT_MORE_COMPONENTS; - status = cairo_truetype_font_use_glyph (font, be16_to_cpu (composite_glyph->index), &index); - if (unlikely (status)) - return status; - - composite_glyph->index = cpu_to_be16 (index); - num_args = 1; - if (flags & TT_ARG_1_AND_2_ARE_WORDS) - num_args += 1; - - if (flags & TT_WE_HAVE_A_SCALE) - num_args += 1; - else if (flags & TT_WE_HAVE_AN_X_AND_Y_SCALE) - num_args += 2; - else if (flags & TT_WE_HAVE_A_TWO_BY_TWO) - num_args += 4; - - composite_glyph = (tt_composite_glyph_t *) &(composite_glyph->args[num_args]); - } while (has_more_components); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_truetype_font_write_glyf_table (cairo_truetype_font_t *font, - unsigned long tag) -{ - unsigned long start_offset, index, size, next; - tt_head_t header; - unsigned long begin, end; - unsigned char *buffer; - unsigned int i; - union { - unsigned char *bytes; - uint16_t *short_offsets; - uint32_t *long_offsets; - } u; - cairo_status_t status; - - if (font->status) - return font->status; - - size = sizeof (tt_head_t); - status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - TT_TAG_head, 0, - (unsigned char*) &header, &size); - if (unlikely (status)) - return _cairo_truetype_font_set_error (font, status); - - if (be16_to_cpu (header.index_to_loc_format) == 0) - size = sizeof (int16_t) * (font->num_glyphs_in_face + 1); - else - size = sizeof (int32_t) * (font->num_glyphs_in_face + 1); - - u.bytes = malloc (size); - if (unlikely (u.bytes == NULL)) - return _cairo_truetype_font_set_error (font, CAIRO_STATUS_NO_MEMORY); - - status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - TT_TAG_loca, 0, u.bytes, &size); - if (unlikely (status)) - return _cairo_truetype_font_set_error (font, status); - - start_offset = _cairo_array_num_elements (&font->output); - for (i = 0; i < font->base.num_glyphs; i++) { - index = font->glyphs[i].parent_index; - if (be16_to_cpu (header.index_to_loc_format) == 0) { - begin = be16_to_cpu (u.short_offsets[index]) * 2; - end = be16_to_cpu (u.short_offsets[index + 1]) * 2; - } - else { - begin = be32_to_cpu (u.long_offsets[index]); - end = be32_to_cpu (u.long_offsets[index + 1]); - } - - /* quick sanity check... */ - if (end < begin) { - status = CAIRO_INT_STATUS_UNSUPPORTED; - goto FAIL; - } - - size = end - begin; - status = cairo_truetype_font_align_output (font, &next); - if (unlikely (status)) - goto FAIL; - - status = cairo_truetype_font_check_boundary (font, next); - if (unlikely (status)) - goto FAIL; - - font->glyphs[i].location = next - start_offset; - - status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer); - if (unlikely (status)) - goto FAIL; - - if (size > 1) { - tt_glyph_data_t *glyph_data; - int num_contours; - - status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - TT_TAG_glyf, begin, buffer, &size); - if (unlikely (status)) - goto FAIL; - - glyph_data = (tt_glyph_data_t *) buffer; - num_contours = (int16_t)be16_to_cpu (glyph_data->num_contours); - if (num_contours < 0) { - status = cairo_truetype_font_remap_composite_glyph (font, buffer, size); - if (unlikely (status)) - goto FAIL; - } else if (num_contours == 0) { - /* num_contours == 0 is undefined in the Opentype - * spec. There are some embedded fonts that have a - * space glyph with num_contours = 0 that fails on - * some printers. The spec requires glyphs without - * contours to have a 0 size glyph entry in the loca - * table. - * - * If num_contours == 0, truncate the glyph to 0 size. - */ - _cairo_array_truncate (&font->output, _cairo_array_num_elements (&font->output) - size); - } - } - } - - status = cairo_truetype_font_align_output (font, &next); - if (unlikely (status)) - goto FAIL; - - font->glyphs[i].location = next - start_offset; - - status = font->status; -FAIL: - free (u.bytes); - - return _cairo_truetype_font_set_error (font, status); -} - -static cairo_status_t -cairo_truetype_font_write_head_table (cairo_truetype_font_t *font, - unsigned long tag) -{ - unsigned char *buffer; - unsigned long size; - cairo_status_t status; - - if (font->status) - return font->status; - - size = 0; - status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - tag, 0, NULL, &size); - if (unlikely (status)) - return _cairo_truetype_font_set_error (font, status); - - font->checksum_index = _cairo_array_num_elements (&font->output) + 8; - status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer); - if (unlikely (status)) - return _cairo_truetype_font_set_error (font, status); - - status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - tag, 0, buffer, &size); - if (unlikely (status)) - return _cairo_truetype_font_set_error (font, status); - - /* set checkSumAdjustment to 0 for table checksum calculation */ - *(uint32_t *)(buffer + 8) = 0; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_truetype_font_write_hhea_table (cairo_truetype_font_t *font, unsigned long tag) -{ - tt_hhea_t *hhea; - unsigned long size; - cairo_status_t status; - - if (font->status) - return font->status; - - size = sizeof (tt_hhea_t); - status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &hhea); - if (unlikely (status)) - return _cairo_truetype_font_set_error (font, status); - - status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - tag, 0, (unsigned char *) hhea, &size); - if (unlikely (status)) - return _cairo_truetype_font_set_error (font, status); - - hhea->num_hmetrics = cpu_to_be16 ((uint16_t)(font->base.num_glyphs)); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_truetype_font_write_hmtx_table (cairo_truetype_font_t *font, - unsigned long tag) -{ - unsigned long size; - unsigned long long_entry_size; - unsigned long short_entry_size; - short *p; - unsigned int i; - tt_hhea_t hhea; - int num_hmetrics; - cairo_status_t status; - - if (font->status) - return font->status; - - size = sizeof (tt_hhea_t); - status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - TT_TAG_hhea, 0, - (unsigned char*) &hhea, &size); - if (unlikely (status)) - return _cairo_truetype_font_set_error (font, status); - - num_hmetrics = be16_to_cpu(hhea.num_hmetrics); - - for (i = 0; i < font->base.num_glyphs; i++) { - long_entry_size = 2 * sizeof (int16_t); - short_entry_size = sizeof (int16_t); - status = cairo_truetype_font_allocate_write_buffer (font, - long_entry_size, - (unsigned char **) &p); - if (unlikely (status)) - return _cairo_truetype_font_set_error (font, status); - - if (font->glyphs[i].parent_index < num_hmetrics) { - status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - TT_TAG_hmtx, - font->glyphs[i].parent_index * long_entry_size, - (unsigned char *) p, &long_entry_size); - if (unlikely (status)) - return _cairo_truetype_font_set_error (font, status); - } - else - { - status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - TT_TAG_hmtx, - (num_hmetrics - 1) * long_entry_size, - (unsigned char *) p, &short_entry_size); - if (unlikely (status)) - return _cairo_truetype_font_set_error (font, status); - - status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - TT_TAG_hmtx, - num_hmetrics * long_entry_size + - (font->glyphs[i].parent_index - num_hmetrics) * short_entry_size, - (unsigned char *) (p + 1), &short_entry_size); - if (unlikely (status)) - return _cairo_truetype_font_set_error (font, status); - } - font->base.widths[i] = be16_to_cpu (p[0]); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_truetype_font_write_loca_table (cairo_truetype_font_t *font, - unsigned long tag) -{ - unsigned int i; - tt_head_t header; - unsigned long size; - cairo_status_t status; - - if (font->status) - return font->status; - - size = sizeof(tt_head_t); - status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - TT_TAG_head, 0, - (unsigned char*) &header, &size); - if (unlikely (status)) - return _cairo_truetype_font_set_error (font, status); - - if (be16_to_cpu (header.index_to_loc_format) == 0) - { - for (i = 0; i < font->base.num_glyphs + 1; i++) - cairo_truetype_font_write_be16 (font, font->glyphs[i].location / 2); - } else { - for (i = 0; i < font->base.num_glyphs + 1; i++) - cairo_truetype_font_write_be32 (font, font->glyphs[i].location); - } - - return font->status; -} - -static cairo_status_t -cairo_truetype_font_write_maxp_table (cairo_truetype_font_t *font, - unsigned long tag) -{ - tt_maxp_t *maxp; - unsigned long size; - cairo_status_t status; - - if (font->status) - return font->status; - - size = sizeof (tt_maxp_t); - status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &maxp); - if (unlikely (status)) - return _cairo_truetype_font_set_error (font, status); - - status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - tag, 0, (unsigned char *) maxp, &size); - if (unlikely (status)) - return _cairo_truetype_font_set_error (font, status); - - maxp->num_glyphs = cpu_to_be16 (font->base.num_glyphs); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_truetype_font_write_offset_table (cairo_truetype_font_t *font) -{ - cairo_status_t status; - unsigned char *table_buffer; - size_t table_buffer_length; - unsigned short search_range, entry_selector, range_shift; - - if (font->status) - return font->status; - - search_range = 1; - entry_selector = 0; - while (search_range * 2 <= font->num_tables) { - search_range *= 2; - entry_selector++; - } - search_range *= 16; - range_shift = font->num_tables * 16 - search_range; - - cairo_truetype_font_write_be32 (font, SFNT_VERSION); - cairo_truetype_font_write_be16 (font, font->num_tables); - cairo_truetype_font_write_be16 (font, search_range); - cairo_truetype_font_write_be16 (font, entry_selector); - cairo_truetype_font_write_be16 (font, range_shift); - - /* Allocate space for the table directory. Each directory entry - * will be filled in by cairo_truetype_font_update_entry() after - * the table is written. */ - table_buffer_length = font->num_tables * 16; - status = cairo_truetype_font_allocate_write_buffer (font, table_buffer_length, - &table_buffer); - if (unlikely (status)) - return _cairo_truetype_font_set_error (font, status); - - return CAIRO_STATUS_SUCCESS; -} - -static uint32_t -cairo_truetype_font_calculate_checksum (cairo_truetype_font_t *font, - unsigned long start, - unsigned long end) -{ - uint32_t *padded_end; - uint32_t *p; - uint32_t checksum; - char *data; - - checksum = 0; - data = _cairo_array_index (&font->output, 0); - p = (uint32_t *) (data + start); - padded_end = (uint32_t *) (data + ((end + 3) & ~3)); - while (p < padded_end) - checksum += be32_to_cpu(*p++); - - return checksum; -} - -static void -cairo_truetype_font_update_entry (cairo_truetype_font_t *font, - int index, - unsigned long tag, - unsigned long start, - unsigned long end) -{ - uint32_t *entry; - - entry = _cairo_array_index (&font->output, 12 + 16 * index); - entry[0] = cpu_to_be32 ((uint32_t)tag); - entry[1] = cpu_to_be32 (cairo_truetype_font_calculate_checksum (font, start, end)); - entry[2] = cpu_to_be32 ((uint32_t)start); - entry[3] = cpu_to_be32 ((uint32_t)(end - start)); -} - -static cairo_status_t -cairo_truetype_font_generate (cairo_truetype_font_t *font, - const char **data, - unsigned long *length, - const unsigned long **string_offsets, - unsigned long *num_strings) -{ - cairo_status_t status; - unsigned long start, end, next; - uint32_t checksum, *checksum_location; - int i; - - if (font->status) - return font->status; - - status = cairo_truetype_font_write_offset_table (font); - if (unlikely (status)) - goto FAIL; - - status = cairo_truetype_font_align_output (font, &start); - if (unlikely (status)) - goto FAIL; - - end = 0; - for (i = 0; i < font->num_tables; i++) { - status = font->truetype_tables[i].write (font, font->truetype_tables[i].tag); - if (unlikely (status)) - goto FAIL; - - end = _cairo_array_num_elements (&font->output); - status = cairo_truetype_font_align_output (font, &next); - if (unlikely (status)) - goto FAIL; - - cairo_truetype_font_update_entry (font, font->truetype_tables[i].pos, - font->truetype_tables[i].tag, start, end); - status = cairo_truetype_font_check_boundary (font, next); - if (unlikely (status)) - goto FAIL; - - start = next; - } - - checksum = - 0xb1b0afba - cairo_truetype_font_calculate_checksum (font, 0, end); - checksum_location = _cairo_array_index (&font->output, font->checksum_index); - *checksum_location = cpu_to_be32 (checksum); - - *data = _cairo_array_index (&font->output, 0); - *length = _cairo_array_num_elements (&font->output); - *num_strings = _cairo_array_num_elements (&font->string_offsets); - if (*num_strings != 0) - *string_offsets = _cairo_array_index (&font->string_offsets, 0); - else - *string_offsets = NULL; - - FAIL: - return _cairo_truetype_font_set_error (font, status); -} - -static cairo_status_t -cairo_truetype_font_use_glyph (cairo_truetype_font_t *font, - unsigned short glyph, - unsigned short *out) -{ - if (glyph >= font->num_glyphs_in_face) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (font->parent_to_subset[glyph] == 0) { - font->parent_to_subset[glyph] = font->base.num_glyphs; - font->glyphs[font->base.num_glyphs].parent_index = glyph; - font->base.num_glyphs++; - } - - *out = font->parent_to_subset[glyph]; - return CAIRO_STATUS_SUCCESS; -} - -static void -cairo_truetype_font_add_truetype_table (cairo_truetype_font_t *font, - unsigned long tag, - cairo_status_t (*write) (cairo_truetype_font_t *font, unsigned long tag), - int pos) -{ - font->truetype_tables[font->num_tables].tag = tag; - font->truetype_tables[font->num_tables].write = write; - font->truetype_tables[font->num_tables].pos = pos; - font->num_tables++; -} - -/* cairo_truetype_font_create_truetype_table_list() builds the list of - * truetype tables to be embedded in the subsetted font. Each call to - * cairo_truetype_font_add_truetype_table() adds a table, the callback - * for generating the table, and the position in the table directory - * to the truetype_tables array. - * - * As we write out the glyf table we remap composite glyphs. - * Remapping composite glyphs will reference the sub glyphs the - * composite glyph is made up of. The "glyf" table callback needs to - * be called first so we have all the glyphs in the subset before - * going further. - * - * The order in which tables are added to the truetype_table array - * using cairo_truetype_font_add_truetype_table() specifies the order - * in which the callback functions will be called. - * - * The tables in the table directory must be listed in alphabetical - * order. The "cvt", "fpgm", and "prep" are optional tables. They - * will only be embedded in the subset if they exist in the source - * font. "cmap" is only embedded for latin fonts. The pos parameter of - * cairo_truetype_font_add_truetype_table() specifies the position of - * the table in the table directory. - */ -static void -cairo_truetype_font_create_truetype_table_list (cairo_truetype_font_t *font) -{ - cairo_bool_t has_cvt = FALSE; - cairo_bool_t has_fpgm = FALSE; - cairo_bool_t has_prep = FALSE; - unsigned long size; - int pos; - - size = 0; - if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - TT_TAG_cvt, 0, NULL, - &size) == CAIRO_INT_STATUS_SUCCESS) - has_cvt = TRUE; - - size = 0; - if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - TT_TAG_fpgm, 0, NULL, - &size) == CAIRO_INT_STATUS_SUCCESS) - has_fpgm = TRUE; - - size = 0; - if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, - TT_TAG_prep, 0, NULL, - &size) == CAIRO_INT_STATUS_SUCCESS) - has_prep = TRUE; - - font->num_tables = 0; - pos = 0; - if (font->is_pdf && font->scaled_font_subset->is_latin) - pos++; - if (has_cvt) - pos++; - if (has_fpgm) - pos++; - cairo_truetype_font_add_truetype_table (font, TT_TAG_glyf, cairo_truetype_font_write_glyf_table, pos); - - pos = 0; - if (font->is_pdf && font->scaled_font_subset->is_latin) - cairo_truetype_font_add_truetype_table (font, TT_TAG_cmap, cairo_truetype_font_write_cmap_table, pos++); - if (has_cvt) - cairo_truetype_font_add_truetype_table (font, TT_TAG_cvt, cairo_truetype_font_write_generic_table, pos++); - if (has_fpgm) - cairo_truetype_font_add_truetype_table (font, TT_TAG_fpgm, cairo_truetype_font_write_generic_table, pos++); - pos++; - cairo_truetype_font_add_truetype_table (font, TT_TAG_head, cairo_truetype_font_write_head_table, pos++); - cairo_truetype_font_add_truetype_table (font, TT_TAG_hhea, cairo_truetype_font_write_hhea_table, pos++); - cairo_truetype_font_add_truetype_table (font, TT_TAG_hmtx, cairo_truetype_font_write_hmtx_table, pos++); - cairo_truetype_font_add_truetype_table (font, TT_TAG_loca, cairo_truetype_font_write_loca_table, pos++); - cairo_truetype_font_add_truetype_table (font, TT_TAG_maxp, cairo_truetype_font_write_maxp_table, pos++); - if (has_prep) - cairo_truetype_font_add_truetype_table (font, TT_TAG_prep, cairo_truetype_font_write_generic_table, pos); -} - -static cairo_status_t -cairo_truetype_subset_init_internal (cairo_truetype_subset_t *truetype_subset, - cairo_scaled_font_subset_t *font_subset, - cairo_bool_t is_pdf) -{ - cairo_truetype_font_t *font = NULL; - cairo_status_t status; - const char *data = NULL; /* squelch bogus compiler warning */ - unsigned long length = 0; /* squelch bogus compiler warning */ - unsigned long offsets_length; - unsigned int i; - const unsigned long *string_offsets = NULL; - unsigned long num_strings = 0; - - status = _cairo_truetype_font_create (font_subset, is_pdf, &font); - if (unlikely (status)) - return status; - - for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) { - unsigned short parent_glyph = font->scaled_font_subset->glyphs[i]; - status = cairo_truetype_font_use_glyph (font, parent_glyph, &parent_glyph); - if (unlikely (status)) - goto fail1; - } - - cairo_truetype_font_create_truetype_table_list (font); - status = cairo_truetype_font_generate (font, &data, &length, - &string_offsets, &num_strings); - if (unlikely (status)) - goto fail1; - - truetype_subset->ps_name = strdup (font->base.ps_name); - if (unlikely (truetype_subset->ps_name == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail1; - } - - if (font->base.font_name != NULL) { - truetype_subset->family_name_utf8 = strdup (font->base.font_name); - if (unlikely (truetype_subset->family_name_utf8 == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail2; - } - } else { - truetype_subset->family_name_utf8 = NULL; - } - - /* The widths array returned must contain only widths for the - * glyphs in font_subset. Any subglyphs appended after - * font_subset->num_glyphs are omitted. */ - truetype_subset->widths = calloc (sizeof (double), - font->scaled_font_subset->num_glyphs); - if (unlikely (truetype_subset->widths == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail3; - } - for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) - truetype_subset->widths[i] = (double)font->base.widths[i]/font->base.units_per_em; - - truetype_subset->x_min = (double)font->base.x_min/font->base.units_per_em; - truetype_subset->y_min = (double)font->base.y_min/font->base.units_per_em; - truetype_subset->x_max = (double)font->base.x_max/font->base.units_per_em; - truetype_subset->y_max = (double)font->base.y_max/font->base.units_per_em; - truetype_subset->ascent = (double)font->base.ascent/font->base.units_per_em; - truetype_subset->descent = (double)font->base.descent/font->base.units_per_em; - - if (length) { - truetype_subset->data = malloc (length); - if (unlikely (truetype_subset->data == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail4; - } - - memcpy (truetype_subset->data, data, length); - } else - truetype_subset->data = NULL; - truetype_subset->data_length = length; - - if (num_strings) { - offsets_length = num_strings * sizeof (unsigned long); - truetype_subset->string_offsets = malloc (offsets_length); - if (unlikely (truetype_subset->string_offsets == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail5; - } - - memcpy (truetype_subset->string_offsets, string_offsets, offsets_length); - truetype_subset->num_string_offsets = num_strings; - } else { - truetype_subset->string_offsets = NULL; - truetype_subset->num_string_offsets = 0; - } - - cairo_truetype_font_destroy (font); - - return CAIRO_STATUS_SUCCESS; - - fail5: - free (truetype_subset->data); - fail4: - free (truetype_subset->widths); - fail3: - free (truetype_subset->family_name_utf8); - fail2: - free (truetype_subset->ps_name); - fail1: - cairo_truetype_font_destroy (font); - - return status; -} - -cairo_status_t -_cairo_truetype_subset_init_ps (cairo_truetype_subset_t *truetype_subset, - cairo_scaled_font_subset_t *font_subset) -{ - return cairo_truetype_subset_init_internal (truetype_subset, font_subset, FALSE); -} - -cairo_status_t -_cairo_truetype_subset_init_pdf (cairo_truetype_subset_t *truetype_subset, - cairo_scaled_font_subset_t *font_subset) -{ - return cairo_truetype_subset_init_internal (truetype_subset, font_subset, TRUE); -} - -void -_cairo_truetype_subset_fini (cairo_truetype_subset_t *subset) -{ - free (subset->ps_name); - free (subset->family_name_utf8); - free (subset->widths); - free (subset->data); - free (subset->string_offsets); -} - -static cairo_int_status_t -_cairo_truetype_reverse_cmap (cairo_scaled_font_t *scaled_font, - unsigned long table_offset, - unsigned long index, - uint32_t *ucs4) -{ - cairo_status_t status; - const cairo_scaled_font_backend_t *backend; - tt_segment_map_t *map; - char buf[4]; - unsigned int num_segments, i; - unsigned long size; - uint16_t *start_code; - uint16_t *end_code; - uint16_t *delta; - uint16_t *range_offset; - uint16_t c; - - backend = scaled_font->backend; - size = 4; - status = backend->load_truetype_table (scaled_font, - TT_TAG_cmap, table_offset, - (unsigned char *) &buf, - &size); - if (unlikely (status)) - return status; - - /* All table formats have the same first two words */ - map = (tt_segment_map_t *) buf; - if (be16_to_cpu (map->format) != 4) - return CAIRO_INT_STATUS_UNSUPPORTED; - - size = be16_to_cpu (map->length); - map = malloc (size); - if (unlikely (map == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - status = backend->load_truetype_table (scaled_font, - TT_TAG_cmap, table_offset, - (unsigned char *) map, - &size); - if (unlikely (status)) - goto fail; - - num_segments = be16_to_cpu (map->segCountX2)/2; - - /* A Format 4 cmap contains 8 uint16_t numbers and 4 arrays of - * uint16_t each num_segments long. */ - if (size < (8 + 4*num_segments)*sizeof(uint16_t)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - end_code = map->endCount; - start_code = &(end_code[num_segments + 1]); - delta = &(start_code[num_segments]); - range_offset = &(delta[num_segments]); - - /* search for glyph in segments with rangeOffset=0 */ - for (i = 0; i < num_segments; i++) { - c = index - be16_to_cpu (delta[i]); - if (range_offset[i] == 0 && - c >= be16_to_cpu (start_code[i]) && - c <= be16_to_cpu (end_code[i])) - { - *ucs4 = c; - goto found; - } - } - - /* search for glyph in segments with rangeOffset=1 */ - for (i = 0; i < num_segments; i++) { - if (range_offset[i] != 0) { - uint16_t *glyph_ids = &range_offset[i] + be16_to_cpu (range_offset[i])/2; - int range_size = be16_to_cpu (end_code[i]) - be16_to_cpu (start_code[i]) + 1; - uint16_t g_id_be = cpu_to_be16 (index); - int j; - - if (range_size > 0) { - if ((char*)glyph_ids + 2*range_size > (char*)map + size) - return CAIRO_INT_STATUS_UNSUPPORTED; - - for (j = 0; j < range_size; j++) { - if (glyph_ids[j] == g_id_be) { - *ucs4 = be16_to_cpu (start_code[i]) + j; - goto found; - } - } - } - } - } - - /* glyph not found */ - *ucs4 = -1; - -found: - status = CAIRO_STATUS_SUCCESS; - -fail: - free (map); - - return status; -} - -cairo_int_status_t -_cairo_truetype_index_to_ucs4 (cairo_scaled_font_t *scaled_font, - unsigned long index, - uint32_t *ucs4) -{ - cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED; - const cairo_scaled_font_backend_t *backend; - tt_cmap_t *cmap; - char buf[4]; - int num_tables, i; - unsigned long size; - - backend = scaled_font->backend; - if (!backend->load_truetype_table) - return CAIRO_INT_STATUS_UNSUPPORTED; - - size = 4; - status = backend->load_truetype_table (scaled_font, - TT_TAG_cmap, 0, - (unsigned char *) &buf, - &size); - if (unlikely (status)) - return status; - - cmap = (tt_cmap_t *) buf; - num_tables = be16_to_cpu (cmap->num_tables); - size = 4 + num_tables*sizeof(tt_cmap_index_t); - cmap = _cairo_malloc_ab_plus_c (num_tables, sizeof (tt_cmap_index_t), 4); - if (unlikely (cmap == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - status = backend->load_truetype_table (scaled_font, - TT_TAG_cmap, 0, - (unsigned char *) cmap, - &size); - if (unlikely (status)) - goto cleanup; - - /* Find a table with Unicode mapping */ - for (i = 0; i < num_tables; i++) { - if (be16_to_cpu (cmap->index[i].platform) == 3 && - be16_to_cpu (cmap->index[i].encoding) == 1) { - status = _cairo_truetype_reverse_cmap (scaled_font, - be32_to_cpu (cmap->index[i].offset), - index, - ucs4); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - break; - } - } - -cleanup: - free (cmap); - - return status; -} - -static cairo_status_t -find_name (tt_name_t *name, int name_id, int platform, int encoding, int language, char **str_out) -{ - tt_name_record_t *record; - int i, len; - char *str; - char *p; - cairo_bool_t has_tag; - cairo_status_t status; - - str = NULL; - for (i = 0; i < be16_to_cpu (name->num_records); i++) { - record = &(name->records[i]); - if (be16_to_cpu (record->name) == name_id && - be16_to_cpu (record->platform) == platform && - be16_to_cpu (record->encoding) == encoding && - (language == -1 || be16_to_cpu (record->language) == language)) { - - str = malloc (be16_to_cpu (record->length) + 1); - if (str == NULL) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - len = be16_to_cpu (record->length); - memcpy (str, - ((char*)name) + be16_to_cpu (name->strings_offset) + be16_to_cpu (record->offset), - len); - str[be16_to_cpu (record->length)] = 0; - break; - } - } - if (str == NULL) { - *str_out = NULL; - return CAIRO_STATUS_SUCCESS; - } - - if (platform == 3) { /* Win platform, unicode encoding */ - /* convert to utf8 */ - int size = 0; - char *utf8; - uint16_t *u = (uint16_t *) str; - int u_len = len/2; - - for (i = 0; i < u_len; i++) - size += _cairo_ucs4_to_utf8 (be16_to_cpu(u[i]), NULL); - - utf8 = malloc (size + 1); - if (utf8 == NULL) { - status =_cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail; - } - p = utf8; - for (i = 0; i < u_len; i++) - p += _cairo_ucs4_to_utf8 (be16_to_cpu(u[i]), p); - *p = 0; - free (str); - str = utf8; - } else if (platform == 1) { /* Mac platform, Mac Roman encoding */ - /* Replace characters above 127 with underscores. We could use - * a lookup table to convert to unicode but since most fonts - * include a unicode name this is just a rarely used fallback. */ - for (i = 0; i < len; i++) { - if ((unsigned char)str[i] > 127) - str[i] = '_'; - } - } - - /* If font name is prefixed with a PDF subset tag, strip it off. */ - p = str; - len = strlen (str); - has_tag = FALSE; - if (len > 7 && p[6] == '+') { - has_tag = TRUE; - for (i = 0; i < 6; i++) { - if (p[i] < 'A' || p[i] > 'Z') { - has_tag = FALSE; - break; - } - } - } - if (has_tag) { - p = malloc (len - 6); - if (unlikely (p == NULL)) { - status =_cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail; - } - memcpy (p, str + 7, len - 7); - p[len-7] = 0; - free (str); - str = p; - } - - *str_out = str; - - return CAIRO_STATUS_SUCCESS; - - fail: - free (str); - - return status; -} - -cairo_int_status_t -_cairo_truetype_read_font_name (cairo_scaled_font_t *scaled_font, - char **ps_name_out, - char **font_name_out) -{ - cairo_status_t status; - const cairo_scaled_font_backend_t *backend; - tt_name_t *name; - unsigned long size; - char *ps_name = NULL; - char *family_name = NULL; - - backend = scaled_font->backend; - if (!backend->load_truetype_table) - return CAIRO_INT_STATUS_UNSUPPORTED; - - size = 0; - status = backend->load_truetype_table (scaled_font, - TT_TAG_name, 0, - NULL, - &size); - if (status) - return status; - - name = malloc (size); - if (name == NULL) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - status = backend->load_truetype_table (scaled_font, - TT_TAG_name, 0, - (unsigned char *) name, - &size); - if (status) - goto fail; - - /* Find PS Name (name_id = 6). OT spec says PS name must be one of - * the following two encodings */ - status = find_name (name, 6, 3, 1, 0x409, &ps_name); /* win, unicode, english-us */ - if (unlikely(status)) - goto fail; - - if (!ps_name) { - status = find_name (name, 6, 1, 0, 0, &ps_name); /* mac, roman, english */ - if (unlikely(status)) - goto fail; - } - - /* Find Family name (name_id = 1) */ - status = find_name (name, 1, 3, 1, 0x409, &family_name); /* win, unicode, english-us */ - if (unlikely(status)) - goto fail; - - if (!family_name) { - status = find_name (name, 1, 3, 0, 0x409, &family_name); /* win, symbol, english-us */ - if (unlikely(status)) - goto fail; - } - - if (!family_name) { - status = find_name (name, 1, 1, 0, 0, &family_name); /* mac, roman, english */ - if (unlikely(status)) - goto fail; - } - - if (!family_name) { - status = find_name (name, 1, 3, 1, -1, &family_name); /* win, unicode, any language */ - if (unlikely(status)) - goto fail; - } - - status = _cairo_escape_ps_name (&ps_name); - if (unlikely(status)) - goto fail; - - free (name); - - *ps_name_out = ps_name; - *font_name_out = family_name; - - return CAIRO_STATUS_SUCCESS; - -fail: - free (name); - free (ps_name); - free (family_name); - *ps_name_out = NULL; - *font_name_out = NULL; - - return status; -} - -cairo_int_status_t -_cairo_truetype_get_style (cairo_scaled_font_t *scaled_font, - int *weight, - cairo_bool_t *bold, - cairo_bool_t *italic) -{ - cairo_status_t status; - const cairo_scaled_font_backend_t *backend; - tt_os2_t os2; - unsigned long size; - uint16_t selection; - - backend = scaled_font->backend; - if (!backend->load_truetype_table) - return CAIRO_INT_STATUS_UNSUPPORTED; - - size = 0; - status = backend->load_truetype_table (scaled_font, - TT_TAG_OS2, 0, - NULL, - &size); - if (status) - return status; - - if (size < sizeof(os2)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - size = sizeof (os2); - status = backend->load_truetype_table (scaled_font, - TT_TAG_OS2, 0, - (unsigned char *) &os2, - &size); - if (status) - return status; - - *weight = be16_to_cpu (os2.usWeightClass); - selection = be16_to_cpu (os2.fsSelection); - *bold = (selection & TT_FS_SELECTION_BOLD) ? TRUE : FALSE; - *italic = (selection & TT_FS_SELECTION_ITALIC) ? TRUE : FALSE; - - return CAIRO_STATUS_SUCCESS; -} - -#endif /* CAIRO_HAS_FONT_SUBSET */ diff --git a/source/libs/cairo/cairo-src/src/cairo-type1-fallback.c b/source/libs/cairo/cairo-src/src/cairo-type1-fallback.c deleted file mode 100644 index 4a657413e48dba6100b43a20c5af5d377d3de4d1..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-type1-fallback.c +++ /dev/null @@ -1,903 +0,0 @@ -/* 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Adrian Johnson <ajohnson@redneon.com> - */ - -#define _BSD_SOURCE /* for snprintf(), strdup() */ -#include "cairoint.h" - -#include "cairo-array-private.h" -#include "cairo-error-private.h" - -#if CAIRO_HAS_FONT_SUBSET - -#include "cairo-type1-private.h" -#include "cairo-scaled-font-subsets-private.h" -#include "cairo-path-fixed-private.h" -#include "cairo-output-stream-private.h" - -typedef enum { - CAIRO_CHARSTRING_TYPE1, - CAIRO_CHARSTRING_TYPE2 -} cairo_charstring_type_t; - -typedef struct _cairo_type1_font { - int *widths; - - cairo_scaled_font_subset_t *scaled_font_subset; - cairo_scaled_font_t *type1_scaled_font; - - cairo_array_t contents; - - double x_min, y_min, x_max, y_max; - - const char *data; - unsigned long header_size; - unsigned long data_size; - unsigned long trailer_size; - int bbox_position; - int bbox_max_chars; - - cairo_output_stream_t *output; - - unsigned short eexec_key; - cairo_bool_t hex_encode; - int hex_column; -} cairo_type1_font_t; - -static cairo_status_t -cairo_type1_font_create (cairo_scaled_font_subset_t *scaled_font_subset, - cairo_type1_font_t **subset_return, - cairo_bool_t hex_encode) -{ - cairo_type1_font_t *font; - cairo_font_face_t *font_face; - cairo_matrix_t font_matrix; - cairo_matrix_t ctm; - cairo_font_options_t font_options; - cairo_status_t status; - - font = calloc (1, sizeof (cairo_type1_font_t)); - if (unlikely (font == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - font->widths = calloc (scaled_font_subset->num_glyphs, sizeof (int)); - if (unlikely (font->widths == NULL)) { - free (font); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - font->scaled_font_subset = scaled_font_subset; - font->hex_encode = hex_encode; - - font_face = cairo_scaled_font_get_font_face (scaled_font_subset->scaled_font); - - cairo_matrix_init_scale (&font_matrix, 1000, -1000); - cairo_matrix_init_identity (&ctm); - - _cairo_font_options_init_default (&font_options); - cairo_font_options_set_hint_style (&font_options, CAIRO_HINT_STYLE_NONE); - cairo_font_options_set_hint_metrics (&font_options, CAIRO_HINT_METRICS_OFF); - - font->type1_scaled_font = cairo_scaled_font_create (font_face, - &font_matrix, - &ctm, - &font_options); - status = font->type1_scaled_font->status; - if (unlikely (status)) - goto fail; - - _cairo_array_init (&font->contents, sizeof (unsigned char)); - font->output = NULL; - - *subset_return = font; - - return CAIRO_STATUS_SUCCESS; - -fail: - free (font->widths); - free (font); - - return status; -} - -/* Charstring commands. If the high byte is 0 the command is encoded - * with a single byte. */ -#define CHARSTRING_sbw 0x0c07 -#define CHARSTRING_rmoveto 0x0015 -#define CHARSTRING_rlineto 0x0005 -#define CHARSTRING_rcurveto 0x0008 -#define CHARSTRING_closepath 0x0009 -#define CHARSTRING_endchar 0x000e - -/* Before calling this function, the caller must allocate sufficient - * space in data (see _cairo_array_grow_by). The maximum number of - * bytes that will be used is 2. - */ -static void -charstring_encode_command (cairo_array_t *data, int command) -{ - cairo_status_t status; - unsigned int orig_size; - unsigned char buf[5]; - unsigned char *p = buf; - - if (command & 0xff00) - *p++ = command >> 8; - *p++ = command & 0x00ff; - - /* Ensure the array doesn't grow, which allows this function to - * have no possibility of failure. */ - orig_size = _cairo_array_size (data); - status = _cairo_array_append_multiple (data, buf, p - buf); - - assert (status == CAIRO_STATUS_SUCCESS); - assert (_cairo_array_size (data) == orig_size); -} - -/* Before calling this function, the caller must allocate sufficient - * space in data (see _cairo_array_grow_by). The maximum number of - * bytes that will be used is 5. - */ -static void -charstring_encode_integer (cairo_array_t *data, - int i, - cairo_charstring_type_t type) -{ - cairo_status_t status; - unsigned int orig_size; - unsigned char buf[10]; - unsigned char *p = buf; - - if (i >= -107 && i <= 107) { - *p++ = i + 139; - } else if (i >= 108 && i <= 1131) { - i -= 108; - *p++ = (i >> 8)+ 247; - *p++ = i & 0xff; - } else if (i >= -1131 && i <= -108) { - i = -i - 108; - *p++ = (i >> 8)+ 251; - *p++ = i & 0xff; - } else { - if (type == CAIRO_CHARSTRING_TYPE1) { - *p++ = 0xff; - *p++ = i >> 24; - *p++ = (i >> 16) & 0xff; - *p++ = (i >> 8) & 0xff; - *p++ = i & 0xff; - } else { - *p++ = 0xff; - *p++ = (i >> 8) & 0xff; - *p++ = i & 0xff; - *p++ = 0; - *p++ = 0; - } - } - - /* Ensure the array doesn't grow, which allows this function to - * have no possibility of failure. */ - orig_size = _cairo_array_size (data); - status = _cairo_array_append_multiple (data, buf, p - buf); - - assert (status == CAIRO_STATUS_SUCCESS); - assert (_cairo_array_size (data) == orig_size); -} - -typedef struct _ps_path_info { - cairo_array_t *data; - int current_x, current_y; - cairo_charstring_type_t type; -} t1_path_info_t; - -static cairo_status_t -_charstring_move_to (void *closure, - const cairo_point_t *point) -{ - t1_path_info_t *path_info = (t1_path_info_t *) closure; - int dx, dy; - cairo_status_t status; - - status = _cairo_array_grow_by (path_info->data, 12); - if (unlikely (status)) - return status; - - dx = _cairo_fixed_integer_part (point->x) - path_info->current_x; - dy = _cairo_fixed_integer_part (point->y) - path_info->current_y; - charstring_encode_integer (path_info->data, dx, path_info->type); - charstring_encode_integer (path_info->data, dy, path_info->type); - path_info->current_x += dx; - path_info->current_y += dy; - - charstring_encode_command (path_info->data, CHARSTRING_rmoveto); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_charstring_line_to (void *closure, - const cairo_point_t *point) -{ - t1_path_info_t *path_info = (t1_path_info_t *) closure; - int dx, dy; - cairo_status_t status; - - status = _cairo_array_grow_by (path_info->data, 12); - if (unlikely (status)) - return status; - - dx = _cairo_fixed_integer_part (point->x) - path_info->current_x; - dy = _cairo_fixed_integer_part (point->y) - path_info->current_y; - charstring_encode_integer (path_info->data, dx, path_info->type); - charstring_encode_integer (path_info->data, dy, path_info->type); - path_info->current_x += dx; - path_info->current_y += dy; - - charstring_encode_command (path_info->data, CHARSTRING_rlineto); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_charstring_curve_to (void *closure, - const cairo_point_t *point1, - const cairo_point_t *point2, - const cairo_point_t *point3) -{ - t1_path_info_t *path_info = (t1_path_info_t *) closure; - int dx1, dy1, dx2, dy2, dx3, dy3; - cairo_status_t status; - - status = _cairo_array_grow_by (path_info->data, 32); - if (unlikely (status)) - return status; - - dx1 = _cairo_fixed_integer_part (point1->x) - path_info->current_x; - dy1 = _cairo_fixed_integer_part (point1->y) - path_info->current_y; - dx2 = _cairo_fixed_integer_part (point2->x) - path_info->current_x - dx1; - dy2 = _cairo_fixed_integer_part (point2->y) - path_info->current_y - dy1; - dx3 = _cairo_fixed_integer_part (point3->x) - path_info->current_x - dx1 - dx2; - dy3 = _cairo_fixed_integer_part (point3->y) - path_info->current_y - dy1 - dy2; - charstring_encode_integer (path_info->data, dx1, path_info->type); - charstring_encode_integer (path_info->data, dy1, path_info->type); - charstring_encode_integer (path_info->data, dx2, path_info->type); - charstring_encode_integer (path_info->data, dy2, path_info->type); - charstring_encode_integer (path_info->data, dx3, path_info->type); - charstring_encode_integer (path_info->data, dy3, path_info->type); - path_info->current_x += dx1 + dx2 + dx3; - path_info->current_y += dy1 + dy2 + dy3; - charstring_encode_command (path_info->data, CHARSTRING_rcurveto); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_charstring_close_path (void *closure) -{ - cairo_status_t status; - t1_path_info_t *path_info = (t1_path_info_t *) closure; - - if (path_info->type == CAIRO_CHARSTRING_TYPE2) - return CAIRO_STATUS_SUCCESS; - - status = _cairo_array_grow_by (path_info->data, 2); - if (unlikely (status)) - return status; - - charstring_encode_command (path_info->data, CHARSTRING_closepath); - - return CAIRO_STATUS_SUCCESS; -} - -static void -charstring_encrypt (cairo_array_t *data) -{ - unsigned char *d, *end; - uint16_t c, p, r; - - r = CAIRO_TYPE1_CHARSTRING_KEY; - d = (unsigned char *) _cairo_array_index (data, 0); - end = d + _cairo_array_num_elements (data); - while (d < end) { - p = *d; - c = p ^ (r >> 8); - r = (c + r) * CAIRO_TYPE1_ENCRYPT_C1 + CAIRO_TYPE1_ENCRYPT_C2; - *d++ = c; - } -} - -static cairo_int_status_t -cairo_type1_font_create_charstring (cairo_type1_font_t *font, - int subset_index, - int glyph_index, - cairo_charstring_type_t type, - cairo_array_t *data) -{ - cairo_int_status_t status; - cairo_scaled_glyph_t *scaled_glyph; - t1_path_info_t path_info; - cairo_text_extents_t *metrics; - cairo_bool_t emit_path = TRUE; - - /* This call may return CAIRO_INT_STATUS_UNSUPPORTED for bitmap fonts. */ - status = _cairo_scaled_glyph_lookup (font->type1_scaled_font, - glyph_index, - CAIRO_SCALED_GLYPH_INFO_METRICS| - CAIRO_SCALED_GLYPH_INFO_PATH, - &scaled_glyph); - - /* It is ok for the .notdef glyph to not have a path available. We - * just need the metrics to emit an empty glyph. */ - if (glyph_index == 0 && status == CAIRO_INT_STATUS_UNSUPPORTED) { - emit_path = FALSE; - status = _cairo_scaled_glyph_lookup (font->type1_scaled_font, - glyph_index, - CAIRO_SCALED_GLYPH_INFO_METRICS, - &scaled_glyph); - } - if (unlikely (status)) - return status; - - metrics = &scaled_glyph->metrics; - if (subset_index == 0) { - font->x_min = metrics->x_bearing; - font->y_min = metrics->y_bearing; - font->x_max = metrics->x_bearing + metrics->width; - font->y_max = metrics->y_bearing + metrics->height; - } else { - if (metrics->x_bearing < font->x_min) - font->x_min = metrics->x_bearing; - if (metrics->y_bearing < font->y_min) - font->y_min = metrics->y_bearing; - if (metrics->x_bearing + metrics->width > font->x_max) - font->x_max = metrics->x_bearing + metrics->width; - if (metrics->y_bearing + metrics->height > font->y_max) - font->y_max = metrics->y_bearing + metrics->height; - } - font->widths[subset_index] = metrics->x_advance; - - status = _cairo_array_grow_by (data, 30); - if (unlikely (status)) - return status; - - if (type == CAIRO_CHARSTRING_TYPE1) { - charstring_encode_integer (data, (int) scaled_glyph->metrics.x_bearing, type); - charstring_encode_integer (data, (int) scaled_glyph->metrics.y_bearing, type); - charstring_encode_integer (data, (int) scaled_glyph->metrics.x_advance, type); - charstring_encode_integer (data, (int) scaled_glyph->metrics.y_advance, type); - charstring_encode_command (data, CHARSTRING_sbw); - - path_info.current_x = (int) scaled_glyph->metrics.x_bearing; - path_info.current_y = (int) scaled_glyph->metrics.y_bearing; - } else { - charstring_encode_integer (data, (int) scaled_glyph->metrics.x_advance, type); - - path_info.current_x = 0; - path_info.current_y = 0; - } - path_info.data = data; - path_info.type = type; - if (emit_path) { - status = _cairo_path_fixed_interpret (scaled_glyph->path, - _charstring_move_to, - _charstring_line_to, - _charstring_curve_to, - _charstring_close_path, - &path_info); - if (unlikely (status)) - return status; - } - - status = _cairo_array_grow_by (data, 1); - if (unlikely (status)) - return status; - charstring_encode_command (path_info.data, CHARSTRING_endchar); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -cairo_type1_font_write_charstrings (cairo_type1_font_t *font, - cairo_output_stream_t *encrypted_output) -{ - cairo_status_t status; - unsigned char zeros[] = { 0, 0, 0, 0 }; - cairo_array_t data; - unsigned int i; - int length; - - _cairo_array_init (&data, sizeof (unsigned char)); - status = _cairo_array_grow_by (&data, 1024); - if (unlikely (status)) - goto fail; - - _cairo_output_stream_printf (encrypted_output, - "2 index /CharStrings %d dict dup begin\n", - font->scaled_font_subset->num_glyphs + 1); - - _cairo_scaled_font_freeze_cache (font->type1_scaled_font); - for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) { - _cairo_array_truncate (&data, 0); - /* four "random" bytes required by encryption algorithm */ - status = _cairo_array_append_multiple (&data, zeros, 4); - if (unlikely (status)) - break; - - status = cairo_type1_font_create_charstring (font, i, - font->scaled_font_subset->glyphs[i], - CAIRO_CHARSTRING_TYPE1, - &data); - if (unlikely (status)) - break; - - charstring_encrypt (&data); - length = _cairo_array_num_elements (&data); - if (font->scaled_font_subset->glyph_names != NULL) { - _cairo_output_stream_printf (encrypted_output, "/%s %d RD ", - font->scaled_font_subset->glyph_names[i], - length); - } else if (i == 0) { - _cairo_output_stream_printf (encrypted_output, "/.notdef %d RD ", length); - } else { - _cairo_output_stream_printf (encrypted_output, "/g%d %d RD ", i, length); - } - _cairo_output_stream_write (encrypted_output, - _cairo_array_index (&data, 0), - length); - _cairo_output_stream_printf (encrypted_output, " ND\n"); - } - _cairo_scaled_font_thaw_cache (font->type1_scaled_font); - -fail: - _cairo_array_fini (&data); - return status; -} - -static void -cairo_type1_font_write_header (cairo_type1_font_t *font, - const char *name) -{ - unsigned int i; - const char spaces[50] = " "; - - _cairo_output_stream_printf (font->output, - "%%!FontType1-1.1 %s 1.0\n" - "11 dict begin\n" - "/FontName /%s def\n" - "/PaintType 0 def\n" - "/FontType 1 def\n" - "/FontMatrix [0.001 0 0 0.001 0 0] readonly def\n", - name, - name); - - /* We don't know the bbox values until after the charstrings have - * been generated. Reserve some space and fill in the bbox - * later. */ - - /* Worst case for four signed ints with spaces between each number */ - font->bbox_max_chars = 50; - - _cairo_output_stream_printf (font->output, "/FontBBox {"); - font->bbox_position = _cairo_output_stream_get_position (font->output); - _cairo_output_stream_write (font->output, spaces, font->bbox_max_chars); - - _cairo_output_stream_printf (font->output, - "} readonly def\n" - "/Encoding 256 array\n" - "0 1 255 {1 index exch /.notdef put} for\n"); - if (font->scaled_font_subset->is_latin) { - for (i = 1; i < 256; i++) { - int subset_glyph = font->scaled_font_subset->latin_to_subset_glyph_index[i]; - - if (subset_glyph > 0) { - if (font->scaled_font_subset->glyph_names != NULL) { - _cairo_output_stream_printf (font->output, "dup %d /%s put\n", - i, font->scaled_font_subset->glyph_names[subset_glyph]); - } else { - _cairo_output_stream_printf (font->output, "dup %d /g%d put\n", i, subset_glyph); - } - } - } - } else { - for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) { - if (font->scaled_font_subset->glyph_names != NULL) { - _cairo_output_stream_printf (font->output, "dup %d /%s put\n", - i, font->scaled_font_subset->glyph_names[i]); - } else { - _cairo_output_stream_printf (font->output, "dup %d /g%d put\n", i, i); - } - } - } - _cairo_output_stream_printf (font->output, - "readonly def\n" - "currentdict end\n" - "currentfile eexec\n"); -} - -static cairo_status_t -cairo_type1_write_stream_encrypted (void *closure, - const unsigned char *data, - unsigned int length) -{ - const unsigned char *in, *end; - uint16_t c, p; - static const char hex_digits[16] = "0123456789abcdef"; - char digits[3]; - cairo_type1_font_t *font = closure; - - in = (const unsigned char *) data; - end = (const unsigned char *) data + length; - while (in < end) { - p = *in++; - c = p ^ (font->eexec_key >> 8); - font->eexec_key = (c + font->eexec_key) * CAIRO_TYPE1_ENCRYPT_C1 + CAIRO_TYPE1_ENCRYPT_C2; - - if (font->hex_encode) { - digits[0] = hex_digits[c >> 4]; - digits[1] = hex_digits[c & 0x0f]; - digits[2] = '\n'; - font->hex_column += 2; - - if (font->hex_column == 78) { - _cairo_output_stream_write (font->output, digits, 3); - font->hex_column = 0; - } else { - _cairo_output_stream_write (font->output, digits, 2); - } - } else { - digits[0] = c; - _cairo_output_stream_write (font->output, digits, 1); - } - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -cairo_type1_font_write_private_dict (cairo_type1_font_t *font, - const char *name) -{ - cairo_int_status_t status; - cairo_status_t status2; - cairo_output_stream_t *encrypted_output; - - font->eexec_key = CAIRO_TYPE1_PRIVATE_DICT_KEY; - font->hex_column = 0; - encrypted_output = _cairo_output_stream_create ( - cairo_type1_write_stream_encrypted, - NULL, - font); - if (_cairo_output_stream_get_status (encrypted_output)) - return _cairo_output_stream_destroy (encrypted_output); - - /* Note: the first four spaces at the start of this private dict - * are the four "random" bytes of plaintext required by the - * encryption algorithm */ - _cairo_output_stream_printf (encrypted_output, - " dup /Private 9 dict dup begin\n" - "/RD {string currentfile exch readstring pop}" - " bind executeonly def\n" - "/ND {noaccess def} executeonly def\n" - "/NP {noaccess put} executeonly def\n" - "/BlueValues [] def\n" - "/MinFeature {16 16} def\n" - "/lenIV 4 def\n" - "/password 5839 def\n"); - - status = cairo_type1_font_write_charstrings (font, encrypted_output); - if (unlikely (status)) - goto fail; - - _cairo_output_stream_printf (encrypted_output, - "end\n" - "end\n" - "readonly put\n" - "noaccess put\n" - "dup /FontName get exch definefont pop\n" - "mark currentfile closefile\n"); - - fail: - status2 = _cairo_output_stream_destroy (encrypted_output); - if (status == CAIRO_INT_STATUS_SUCCESS) - status = status2; - - return status; -} - -static void -cairo_type1_font_write_trailer(cairo_type1_font_t *font) -{ - int i; - static const char zeros[65] = - "0000000000000000000000000000000000000000000000000000000000000000\n"; - - for (i = 0; i < 8; i++) - _cairo_output_stream_write (font->output, zeros, sizeof zeros); - - _cairo_output_stream_printf (font->output, "cleartomark\n"); -} - -static cairo_status_t -cairo_type1_write_stream (void *closure, - const unsigned char *data, - unsigned int length) -{ - cairo_type1_font_t *font = closure; - - return _cairo_array_append_multiple (&font->contents, data, length); -} - -static cairo_int_status_t -cairo_type1_font_write (cairo_type1_font_t *font, - const char *name) -{ - cairo_int_status_t status; - - cairo_type1_font_write_header (font, name); - font->header_size = _cairo_output_stream_get_position (font->output); - - status = cairo_type1_font_write_private_dict (font, name); - if (unlikely (status)) - return status; - - font->data_size = _cairo_output_stream_get_position (font->output) - - font->header_size; - - cairo_type1_font_write_trailer (font); - font->trailer_size = - _cairo_output_stream_get_position (font->output) - - font->header_size - font->data_size; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -cairo_type1_font_generate (cairo_type1_font_t *font, const char *name) -{ - cairo_int_status_t status; - - status = _cairo_array_grow_by (&font->contents, 4096); - if (unlikely (status)) - return status; - - font->output = _cairo_output_stream_create (cairo_type1_write_stream, NULL, font); - if (_cairo_output_stream_get_status (font->output)) - return _cairo_output_stream_destroy (font->output); - - status = cairo_type1_font_write (font, name); - if (unlikely (status)) - return status; - - font->data = _cairo_array_index (&font->contents, 0); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_type1_font_destroy (cairo_type1_font_t *font) -{ - cairo_status_t status = CAIRO_STATUS_SUCCESS; - - free (font->widths); - cairo_scaled_font_destroy (font->type1_scaled_font); - _cairo_array_fini (&font->contents); - if (font->output) - status = _cairo_output_stream_destroy (font->output); - free (font); - - return status; -} - -static cairo_status_t -_cairo_type1_fallback_init_internal (cairo_type1_subset_t *type1_subset, - const char *name, - cairo_scaled_font_subset_t *scaled_font_subset, - cairo_bool_t hex_encode) -{ - cairo_type1_font_t *font; - cairo_status_t status; - unsigned long length; - unsigned int i, len; - - status = cairo_type1_font_create (scaled_font_subset, &font, hex_encode); - if (unlikely (status)) - return status; - - status = cairo_type1_font_generate (font, name); - if (unlikely (status)) - goto fail1; - - type1_subset->base_font = strdup (name); - if (unlikely (type1_subset->base_font == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail1; - } - - type1_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs); - if (unlikely (type1_subset->widths == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail2; - } - for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) - type1_subset->widths[i] = (double)font->widths[i]/1000; - - type1_subset->x_min = (double)font->x_min/1000; - type1_subset->y_min = (double)font->y_min/1000; - type1_subset->x_max = (double)font->x_max/1000; - type1_subset->y_max = (double)font->y_max/1000; - type1_subset->ascent = (double)font->y_max/1000; - type1_subset->descent = (double)font->y_min/1000; - - length = font->header_size + font->data_size + - font->trailer_size; - type1_subset->data = malloc (length); - if (unlikely (type1_subset->data == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail3; - } - memcpy (type1_subset->data, - _cairo_array_index (&font->contents, 0), length); - - len = snprintf(type1_subset->data + font->bbox_position, - font->bbox_max_chars, - "%d %d %d %d", - (int)font->x_min, - (int)font->y_min, - (int)font->x_max, - (int)font->y_max); - type1_subset->data[font->bbox_position + len] = ' '; - - type1_subset->header_length = font->header_size; - type1_subset->data_length = font->data_size; - type1_subset->trailer_length = font->trailer_size; - - return cairo_type1_font_destroy (font); - - fail3: - free (type1_subset->widths); - fail2: - free (type1_subset->base_font); - fail1: - /* status is already set, ignore further errors */ - cairo_type1_font_destroy (font); - - return status; -} - -cairo_status_t -_cairo_type1_fallback_init_binary (cairo_type1_subset_t *type1_subset, - const char *name, - cairo_scaled_font_subset_t *scaled_font_subset) -{ - return _cairo_type1_fallback_init_internal (type1_subset, - name, - scaled_font_subset, FALSE); -} - -cairo_status_t -_cairo_type1_fallback_init_hex (cairo_type1_subset_t *type1_subset, - const char *name, - cairo_scaled_font_subset_t *scaled_font_subset) -{ - return _cairo_type1_fallback_init_internal (type1_subset, - name, - scaled_font_subset, TRUE); -} - -void -_cairo_type1_fallback_fini (cairo_type1_subset_t *subset) -{ - free (subset->base_font); - free (subset->widths); - free (subset->data); -} - -cairo_status_t -_cairo_type2_charstrings_init (cairo_type2_charstrings_t *type2_subset, - cairo_scaled_font_subset_t *scaled_font_subset) -{ - cairo_type1_font_t *font; - cairo_status_t status; - unsigned int i; - cairo_array_t charstring; - - status = cairo_type1_font_create (scaled_font_subset, &font, FALSE); - if (unlikely (status)) - return status; - - _cairo_array_init (&type2_subset->charstrings, sizeof (cairo_array_t)); - - type2_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs); - if (unlikely (type2_subset->widths == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto fail1; - } - - _cairo_scaled_font_freeze_cache (font->type1_scaled_font); - for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) { - _cairo_array_init (&charstring, sizeof (unsigned char)); - status = _cairo_array_grow_by (&charstring, 32); - if (unlikely (status)) - goto fail2; - - status = cairo_type1_font_create_charstring (font, i, - font->scaled_font_subset->glyphs[i], - CAIRO_CHARSTRING_TYPE2, - &charstring); - if (unlikely (status)) - goto fail2; - - status = _cairo_array_append (&type2_subset->charstrings, &charstring); - if (unlikely (status)) - goto fail2; - } - _cairo_scaled_font_thaw_cache (font->type1_scaled_font); - - for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) - type2_subset->widths[i] = font->widths[i]; - - type2_subset->x_min = (int) font->x_min; - type2_subset->y_min = (int) font->y_min; - type2_subset->x_max = (int) font->x_max; - type2_subset->y_max = (int) font->y_max; - type2_subset->ascent = (int) font->y_max; - type2_subset->descent = (int) font->y_min; - - return cairo_type1_font_destroy (font); - -fail2: - _cairo_scaled_font_thaw_cache (font->type1_scaled_font); - _cairo_array_fini (&charstring); - _cairo_type2_charstrings_fini (type2_subset); -fail1: - cairo_type1_font_destroy (font); - return status; -} - -void -_cairo_type2_charstrings_fini (cairo_type2_charstrings_t *type2_subset) -{ - unsigned int i, num_charstrings; - cairo_array_t *charstring; - - num_charstrings = _cairo_array_num_elements (&type2_subset->charstrings); - for (i = 0; i < num_charstrings; i++) { - charstring = _cairo_array_index (&type2_subset->charstrings, i); - _cairo_array_fini (charstring); - } - _cairo_array_fini (&type2_subset->charstrings); - - free (type2_subset->widths); -} - -#endif /* CAIRO_HAS_FONT_SUBSET */ diff --git a/source/libs/cairo/cairo-src/src/cairo-type1-glyph-names.c b/source/libs/cairo/cairo-src/src/cairo-type1-glyph-names.c deleted file mode 100644 index 80ccb96269ea40a6f1f2e450196fa20750ff8362..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-type1-glyph-names.c +++ /dev/null @@ -1,410 +0,0 @@ -/* 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Kristian Høgsberg <krh@redhat.com> - */ - -#include "cairoint.h" - -#if CAIRO_HAS_FONT_SUBSET - -#include "cairo-type1-private.h" -#include "cairo-scaled-font-subsets-private.h" - -#if 0 -/* - * The three tables that follow are generated using this perl code: - */ - -@ps_standard_encoding = ( - # 0 - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - # 16 - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - # 32 - "space", "exclam", "quotedbl", "numbersign", - "dollar", "percent", "ampersand", "quoteright", - "parenleft", "parenright", "asterisk", "plus", - "comma", "hyphen", "period", "slash", - # 48 - "zero", "one", "two", "three", - "four", "five", "six", "seven", - "eight", "nine", "colon", "semicolon", - "less", "equal", "greater", "question", - # 64 - "at", "A", "B", "C", - "D", "E", "F", "G", - "H", "I", "J", "K", - "L", "M", "N", "O", - # 80 - "P", "Q", "R", "S", - "T", "U", "V", "W", - "X", "Y", "Z", "bracketleft", - "backslash", "bracketright", "asciicircum", "underscore", - # 96 - "quoteleft", "a", "b", "c", - "d", "e", "f", "g", - "h", "i", "j", "k", - "l", "m", "n", "o", - # 112 - "p", "q", "r", "s", - "t", "u", "v", "w", - "x", "y", "z", "braceleft", - "bar", "braceright", "asciitilde", NULL, - # 128 - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - # 144 - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - # 160 - NULL, "exclamdown", "cent", "sterling", - "fraction", "yen", "florin", "section", - "currency", "quotesingle", "quotedblleft", "guillemotleft", - "guilsinglleft","guilsinglright","fi", "fl", - # 176 - NULL, "endash", "dagger", "daggerdbl", - "periodcentered",NULL, "paragraph", "bullet", - "quotesinglbase","quotedblbase","quotedblright","guillemotright", - "ellipsis", "perthousand", NULL, "questiondown", - # 192 - NULL, "grave", "acute", "circumflex", - "tilde", "macron", "breve", "dotaccent", - "dieresis", NULL, "ring", "cedilla", - NULL, "hungarumlaut", "ogonek", "caron", - # 208 - "emdash", NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - # 224 - NULL, "AE", NULL, "ordfeminine", - NULL, NULL, NULL, NULL, - "Lslash", "Oslash", "OE", "ordmasculine", - NULL, NULL, NULL, NULL, - # 240 - NULL, "ae", NULL, NULL, - NULL, "dotlessi", NULL, NULL, - "lslash", "oslash", "oe", "germandbls", - NULL, NULL, NULL, NULL - ); - -@winansi_encoding = ( - # 0 - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - # 16 - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, - # 32 - "space", "exclam", "quotedbl", "numbersign", - "dollar", "percent", "ampersand", "quotesingle", - "parenleft", "parenright", "asterisk", "plus", - "comma", "hyphen", "period", "slash", - # 48 - "zero", "one", "two", "three", - "four", "five", "six", "seven", - "eight", "nine", "colon", "semicolon", - "less", "equal", "greater", "question", - # 64 - "at", "A", "B", "C", - "D", "E", "F", "G", - "H", "I", "J", "K", - "L", "M", "N", "O", - # 80 - "P", "Q", "R", "S", - "T", "U", "V", "W", - "X", "Y", "Z", "bracketleft", - "backslash", "bracketright", "asciicircum", "underscore", - # 96 - "grave", "a", "b", "c", - "d", "e", "f", "g", - "h", "i", "j", "k", - "l", "m", "n", "o", - # 112 - "p", "q", "r", "s", - "t", "u", "v", "w", - "x", "y", "z", "braceleft", - "bar", "braceright", "asciitilde", NULL, - # 128 - "Euro", NULL, "quotesinglbase","florin", - "quotedblbase", "ellipsis", "dagger", "daggerdbl", - "circumflex", "perthousand", "Scaron", "guilsinglleft", - "OE", NULL, "Zcaron", NULL, - # 144 - NULL, "quoteleft", "quoteright", "quotedblleft", - "quotedblright","bullet", "endash", "emdash", - "tilde", "trademark", "scaron", "guilsinglright", - "oe", NULL, "zcaron", "Ydieresis", - # 160 - NULL, "exclamdown", "cent", "sterling", - "currency", "yen", "brokenbar", "section", - "dieresis", "copyright", "ordfeminine", "guillemotleft", - # 173 is also "hyphen" but we leave this NULL to avoid duplicate names - "logicalnot", NULL, "registered", "macron", - # 176 - "degree", "plusminus", "twosuperior", "threesuperior", - "acute", "mu", "paragraph", "periodcentered", - "cedilla", "onesuperior", "ordmasculine", "guillemotright", - "onequarter", "onehalf", "threequarters","questiondown", - # 192 - "Agrave", "Aacute", "Acircumflex", "Atilde", - "Adieresis", "Aring", "AE", "Ccedilla", - "Egrave", "Eacute", "Ecircumflex", "Edieresis", - "Igrave", "Iacute", "Icircumflex", "Idieresis", - # 208 - "Eth", "Ntilde", "Ograve", "Oacute", - "Ocircumflex", "Otilde", "Odieresis", "multiply", - "Oslash", "Ugrave", "Uacute", "Ucircumflex", - "Udieresis", "Yacute", "Thorn", "germandbls", - # 224 - "agrave", "aacute", "acircumflex", "atilde", - "adieresis", "aring", "ae", "ccedilla", - "egrave", "eacute", "ecircumflex", "edieresis", - "igrave", "iacute", "icircumflex", "idieresis", - # 240 - "eth", "ntilde", "ograve", "oacute", - "ocircumflex", "otilde", "odieresis", "divide", - "oslash", "ugrave", "uacute", "ucircumflex", - "udieresis", "yacute", "thorn", "ydieresis" -); - -sub print_offsets { - $s = qq(); - for $sym (@_) { - if (! ($sym eq NULL)) { - $ss = qq( $hash{$sym}/*$sym*/,); - } else { - $ss = qq( 0,); - } - if (length($s) + length($ss) > 78) { - print qq( $s\n); - $s = ""; - } - $s .= $ss; - } - print qq( $s\n); -} - -@combined = (@ps_standard_encoding, @winansi_encoding); -print "static const char glyph_name_symbol[] = {\n"; -%hash = (); -$s = qq( "\\0"); -$offset = 1; -for $sym (@combined) { - if (! ($sym eq NULL)) { - if (! exists $hash{$sym}) { - $hash{$sym} = $offset; - $offset += length($sym) + 1; - $ss = qq( "$sym\\0"); - if (length($s) + length($ss) > 78) { - print qq( $s\n); - $s = ""; - } - $s .= $ss; - } - } -} -print qq( $s\n); -print "};\n\n"; - -print "static const int16_t ps_standard_encoding_offset[256] = {\n"; -print_offsets(@ps_standard_encoding); -print "};\n"; - -print "static const int16_t winansi_encoding_offset[256] = {\n"; -print_offsets(@winansi_encoding); -print "};\n"; - -exit; -#endif - -static const char glyph_name_symbol[] = { - "\0" "space\0" "exclam\0" "quotedbl\0" "numbersign\0" "dollar\0" "percent\0" - "ampersand\0" "quoteright\0" "parenleft\0" "parenright\0" "asterisk\0" - "plus\0" "comma\0" "hyphen\0" "period\0" "slash\0" "zero\0" "one\0" "two\0" - "three\0" "four\0" "five\0" "six\0" "seven\0" "eight\0" "nine\0" "colon\0" - "semicolon\0" "less\0" "equal\0" "greater\0" "question\0" "at\0" "A\0" "B\0" - "C\0" "D\0" "E\0" "F\0" "G\0" "H\0" "I\0" "J\0" "K\0" "L\0" "M\0" "N\0" "O\0" - "P\0" "Q\0" "R\0" "S\0" "T\0" "U\0" "V\0" "W\0" "X\0" "Y\0" "Z\0" - "bracketleft\0" "backslash\0" "bracketright\0" "asciicircum\0" "underscore\0" - "quoteleft\0" "a\0" "b\0" "c\0" "d\0" "e\0" "f\0" "g\0" "h\0" "i\0" "j\0" - "k\0" "l\0" "m\0" "n\0" "o\0" "p\0" "q\0" "r\0" "s\0" "t\0" "u\0" "v\0" "w\0" - "x\0" "y\0" "z\0" "braceleft\0" "bar\0" "braceright\0" "asciitilde\0" - "exclamdown\0" "cent\0" "sterling\0" "fraction\0" "yen\0" "florin\0" - "section\0" "currency\0" "quotesingle\0" "quotedblleft\0" "guillemotleft\0" - "guilsinglleft\0" "guilsinglright\0" "fi\0" "fl\0" "endash\0" "dagger\0" - "daggerdbl\0" "periodcentered\0" "paragraph\0" "bullet\0" "quotesinglbase\0" - "quotedblbase\0" "quotedblright\0" "guillemotright\0" "ellipsis\0" - "perthousand\0" "questiondown\0" "grave\0" "acute\0" "circumflex\0" "tilde\0" - "macron\0" "breve\0" "dotaccent\0" "dieresis\0" "ring\0" "cedilla\0" - "hungarumlaut\0" "ogonek\0" "caron\0" "emdash\0" "AE\0" "ordfeminine\0" - "Lslash\0" "Oslash\0" "OE\0" "ordmasculine\0" "ae\0" "dotlessi\0" "lslash\0" - "oslash\0" "oe\0" "germandbls\0" "Euro\0" "Scaron\0" "Zcaron\0" "trademark\0" - "scaron\0" "zcaron\0" "Ydieresis\0" "brokenbar\0" "copyright\0" - "logicalnot\0" "registered\0" "degree\0" "plusminus\0" "twosuperior\0" - "threesuperior\0" "mu\0" "onesuperior\0" "onequarter\0" "onehalf\0" - "threequarters\0" "Agrave\0" "Aacute\0" "Acircumflex\0" "Atilde\0" - "Adieresis\0" "Aring\0" "Ccedilla\0" "Egrave\0" "Eacute\0" "Ecircumflex\0" - "Edieresis\0" "Igrave\0" "Iacute\0" "Icircumflex\0" "Idieresis\0" "Eth\0" - "Ntilde\0" "Ograve\0" "Oacute\0" "Ocircumflex\0" "Otilde\0" "Odieresis\0" - "multiply\0" "Ugrave\0" "Uacute\0" "Ucircumflex\0" "Udieresis\0" "Yacute\0" - "Thorn\0" "agrave\0" "aacute\0" "acircumflex\0" "atilde\0" "adieresis\0" - "aring\0" "ccedilla\0" "egrave\0" "eacute\0" "ecircumflex\0" "edieresis\0" - "igrave\0" "iacute\0" "icircumflex\0" "idieresis\0" "eth\0" "ntilde\0" - "ograve\0" "oacute\0" "ocircumflex\0" "otilde\0" "odieresis\0" "divide\0" - "ugrave\0" "uacute\0" "ucircumflex\0" "udieresis\0" "yacute\0" "thorn\0" - "ydieresis\0" -}; - -static const int16_t ps_standard_encoding_offset[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1/*space*/, 7/*exclam*/, 14/*quotedbl*/, 23/*numbersign*/, - 34/*dollar*/, 41/*percent*/, 49/*ampersand*/, 59/*quoteright*/, - 70/*parenleft*/, 80/*parenright*/, 91/*asterisk*/, 100/*plus*/, 105/*comma*/, - 111/*hyphen*/, 118/*period*/, 125/*slash*/, 131/*zero*/, 136/*one*/, - 140/*two*/, 144/*three*/, 150/*four*/, 155/*five*/, 160/*six*/, 164/*seven*/, - 170/*eight*/, 176/*nine*/, 181/*colon*/, 187/*semicolon*/, 197/*less*/, - 202/*equal*/, 208/*greater*/, 216/*question*/, 225/*at*/, 228/*A*/, 230/*B*/, - 232/*C*/, 234/*D*/, 236/*E*/, 238/*F*/, 240/*G*/, 242/*H*/, 244/*I*/, - 246/*J*/, 248/*K*/, 250/*L*/, 252/*M*/, 254/*N*/, 256/*O*/, 258/*P*/, - 260/*Q*/, 262/*R*/, 264/*S*/, 266/*T*/, 268/*U*/, 270/*V*/, 272/*W*/, - 274/*X*/, 276/*Y*/, 278/*Z*/, 280/*bracketleft*/, 292/*backslash*/, - 302/*bracketright*/, 315/*asciicircum*/, 327/*underscore*/, 338/*quoteleft*/, - 348/*a*/, 350/*b*/, 352/*c*/, 354/*d*/, 356/*e*/, 358/*f*/, 360/*g*/, - 362/*h*/, 364/*i*/, 366/*j*/, 368/*k*/, 370/*l*/, 372/*m*/, 374/*n*/, - 376/*o*/, 378/*p*/, 380/*q*/, 382/*r*/, 384/*s*/, 386/*t*/, 388/*u*/, - 390/*v*/, 392/*w*/, 394/*x*/, 396/*y*/, 398/*z*/, 400/*braceleft*/, - 410/*bar*/, 414/*braceright*/, 425/*asciitilde*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 436/*exclamdown*/, 447/*cent*/, 452/*sterling*/, 461/*fraction*/, 470/*yen*/, - 474/*florin*/, 481/*section*/, 489/*currency*/, 498/*quotesingle*/, - 510/*quotedblleft*/, 523/*guillemotleft*/, 537/*guilsinglleft*/, - 551/*guilsinglright*/, 566/*fi*/, 569/*fl*/, 0, 572/*endash*/, 579/*dagger*/, - 586/*daggerdbl*/, 596/*periodcentered*/, 0, 611/*paragraph*/, 621/*bullet*/, - 628/*quotesinglbase*/, 643/*quotedblbase*/, 656/*quotedblright*/, - 670/*guillemotright*/, 685/*ellipsis*/, 694/*perthousand*/, 0, - 706/*questiondown*/, 0, 719/*grave*/, 725/*acute*/, 731/*circumflex*/, - 742/*tilde*/, 748/*macron*/, 755/*breve*/, 761/*dotaccent*/, 771/*dieresis*/, - 0, 780/*ring*/, 785/*cedilla*/, 0, 793/*hungarumlaut*/, 806/*ogonek*/, - 813/*caron*/, 819/*emdash*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 826/*AE*/, 0, 829/*ordfeminine*/, 0, 0, 0, 0, 841/*Lslash*/, 848/*Oslash*/, - 855/*OE*/, 858/*ordmasculine*/, 0, 0, 0, 0, 0, 871/*ae*/, 0, 0, 0, - 874/*dotlessi*/, 0, 0, 883/*lslash*/, 890/*oslash*/, 897/*oe*/, - 900/*germandbls*/, 0, 0, 0, 0, -}; - -static const int16_t winansi_encoding_offset[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1/*space*/, 7/*exclam*/, 14/*quotedbl*/, 23/*numbersign*/, - 34/*dollar*/, 41/*percent*/, 49/*ampersand*/, 498/*quotesingle*/, - 70/*parenleft*/, 80/*parenright*/, 91/*asterisk*/, 100/*plus*/, 105/*comma*/, - 111/*hyphen*/, 118/*period*/, 125/*slash*/, 131/*zero*/, 136/*one*/, - 140/*two*/, 144/*three*/, 150/*four*/, 155/*five*/, 160/*six*/, 164/*seven*/, - 170/*eight*/, 176/*nine*/, 181/*colon*/, 187/*semicolon*/, 197/*less*/, - 202/*equal*/, 208/*greater*/, 216/*question*/, 225/*at*/, 228/*A*/, 230/*B*/, - 232/*C*/, 234/*D*/, 236/*E*/, 238/*F*/, 240/*G*/, 242/*H*/, 244/*I*/, - 246/*J*/, 248/*K*/, 250/*L*/, 252/*M*/, 254/*N*/, 256/*O*/, 258/*P*/, - 260/*Q*/, 262/*R*/, 264/*S*/, 266/*T*/, 268/*U*/, 270/*V*/, 272/*W*/, - 274/*X*/, 276/*Y*/, 278/*Z*/, 280/*bracketleft*/, 292/*backslash*/, - 302/*bracketright*/, 315/*asciicircum*/, 327/*underscore*/, 719/*grave*/, - 348/*a*/, 350/*b*/, 352/*c*/, 354/*d*/, 356/*e*/, 358/*f*/, 360/*g*/, - 362/*h*/, 364/*i*/, 366/*j*/, 368/*k*/, 370/*l*/, 372/*m*/, 374/*n*/, - 376/*o*/, 378/*p*/, 380/*q*/, 382/*r*/, 384/*s*/, 386/*t*/, 388/*u*/, - 390/*v*/, 392/*w*/, 394/*x*/, 396/*y*/, 398/*z*/, 400/*braceleft*/, - 410/*bar*/, 414/*braceright*/, 425/*asciitilde*/, 0, 911/*Euro*/, 0, - 628/*quotesinglbase*/, 474/*florin*/, 643/*quotedblbase*/, 685/*ellipsis*/, - 579/*dagger*/, 586/*daggerdbl*/, 731/*circumflex*/, 694/*perthousand*/, - 916/*Scaron*/, 537/*guilsinglleft*/, 855/*OE*/, 0, 923/*Zcaron*/, 0, 0, - 338/*quoteleft*/, 59/*quoteright*/, 510/*quotedblleft*/, - 656/*quotedblright*/, 621/*bullet*/, 572/*endash*/, 819/*emdash*/, - 742/*tilde*/, 930/*trademark*/, 940/*scaron*/, 551/*guilsinglright*/, - 897/*oe*/, 0, 947/*zcaron*/, 954/*Ydieresis*/, 0, 436/*exclamdown*/, - 447/*cent*/, 452/*sterling*/, 489/*currency*/, 470/*yen*/, 964/*brokenbar*/, - 481/*section*/, 771/*dieresis*/, 974/*copyright*/, 829/*ordfeminine*/, - 523/*guillemotleft*/, 984/*logicalnot*/, 0, 995/*registered*/, 748/*macron*/, - 1006/*degree*/, 1013/*plusminus*/, 1023/*twosuperior*/, - 1035/*threesuperior*/, 725/*acute*/, 1049/*mu*/, 611/*paragraph*/, - 596/*periodcentered*/, 785/*cedilla*/, 1052/*onesuperior*/, - 858/*ordmasculine*/, 670/*guillemotright*/, 1064/*onequarter*/, - 1075/*onehalf*/, 1083/*threequarters*/, 706/*questiondown*/, 1097/*Agrave*/, - 1104/*Aacute*/, 1111/*Acircumflex*/, 1123/*Atilde*/, 1130/*Adieresis*/, - 1140/*Aring*/, 826/*AE*/, 1146/*Ccedilla*/, 1155/*Egrave*/, 1162/*Eacute*/, - 1169/*Ecircumflex*/, 1181/*Edieresis*/, 1191/*Igrave*/, 1198/*Iacute*/, - 1205/*Icircumflex*/, 1217/*Idieresis*/, 1227/*Eth*/, 1231/*Ntilde*/, - 1238/*Ograve*/, 1245/*Oacute*/, 1252/*Ocircumflex*/, 1264/*Otilde*/, - 1271/*Odieresis*/, 1281/*multiply*/, 848/*Oslash*/, 1290/*Ugrave*/, - 1297/*Uacute*/, 1304/*Ucircumflex*/, 1316/*Udieresis*/, 1326/*Yacute*/, - 1333/*Thorn*/, 900/*germandbls*/, 1339/*agrave*/, 1346/*aacute*/, - 1353/*acircumflex*/, 1365/*atilde*/, 1372/*adieresis*/, 1382/*aring*/, - 871/*ae*/, 1388/*ccedilla*/, 1397/*egrave*/, 1404/*eacute*/, - 1411/*ecircumflex*/, 1423/*edieresis*/, 1433/*igrave*/, 1440/*iacute*/, - 1447/*icircumflex*/, 1459/*idieresis*/, 1469/*eth*/, 1473/*ntilde*/, - 1480/*ograve*/, 1487/*oacute*/, 1494/*ocircumflex*/, 1506/*otilde*/, - 1513/*odieresis*/, 1523/*divide*/, 890/*oslash*/, 1530/*ugrave*/, - 1537/*uacute*/, 1544/*ucircumflex*/, 1556/*udieresis*/, 1566/*yacute*/, - 1573/*thorn*/, 1579/*ydieresis*/, -}; - -const char * -_cairo_ps_standard_encoding_to_glyphname (int glyph) -{ - if (ps_standard_encoding_offset[glyph]) - return glyph_name_symbol + ps_standard_encoding_offset[glyph]; - else - return NULL; -} - -const char * -_cairo_winansi_to_glyphname (int glyph) -{ - if (winansi_encoding_offset[glyph]) - return glyph_name_symbol + winansi_encoding_offset[glyph]; - else - return NULL; -} - -#endif /* CAIRO_HAS_FONT_SUBSET */ diff --git a/source/libs/cairo/cairo-src/src/cairo-type1-private.h b/source/libs/cairo/cairo-src/src/cairo-type1-private.h deleted file mode 100644 index 1630397bca6b65ee93a27f19d31bcd7b2951a4cf..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-type1-private.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Cairo - a vector graphics library with display and print output - * - * Copyright © 2007 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Adrian Johnson <ajohnson@redneon.com> - */ - -#ifndef CAIRO_TYPE1_PRIVATE_H -#define CAIRO_TYPE1_PRIVATE_H - -#include "cairoint.h" - -#if CAIRO_HAS_FONT_SUBSET - -/* Magic constants for the type1 eexec encryption */ -#define CAIRO_TYPE1_ENCRYPT_C1 ((unsigned short) 52845) -#define CAIRO_TYPE1_ENCRYPT_C2 ((unsigned short) 22719) -#define CAIRO_TYPE1_PRIVATE_DICT_KEY ((unsigned short) 55665) -#define CAIRO_TYPE1_CHARSTRING_KEY ((unsigned short) 4330) - -#endif /* CAIRO_HAS_FONT_SUBSET */ - -#endif /* CAIRO_TYPE1_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-type1-subset.c b/source/libs/cairo/cairo-src/src/cairo-type1-subset.c deleted file mode 100644 index b15663509d3812b1299d105c47b7b592ecf83008..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-type1-subset.c +++ /dev/null @@ -1,1821 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Kristian Høgsberg <krh@redhat.com> - */ - -/* - * Useful links: - * http://partners.adobe.com/public/developer/en/font/T1_SPEC.PDF - */ - - -#define _BSD_SOURCE /* for snprintf(), strdup() */ -#include "cairoint.h" - -#include "cairo-array-private.h" -#include "cairo-error-private.h" - -#if CAIRO_HAS_FONT_SUBSET - -#include "cairo-type1-private.h" -#include "cairo-scaled-font-subsets-private.h" -#include "cairo-output-stream-private.h" - -#include <ctype.h> - -#define TYPE1_STACKSIZE 24 /* Defined in Type 1 Font Format */ - - -typedef struct { - int subset_index; - double width; - const char *encrypted_charstring; - int encrypted_charstring_length; -} glyph_data_t; - -typedef struct _cairo_type1_font_subset { - cairo_scaled_font_subset_t *scaled_font_subset; - - struct { - unsigned int font_id; - char *base_font; - unsigned int num_glyphs; - double x_min, y_min, x_max, y_max; - double ascent, descent; - double units_per_em; - - const char *data; - unsigned long header_size; - unsigned long data_size; - unsigned long trailer_size; - } base; - - int num_glyphs; - - /* The glyphs and glyph_names arrays are indexed by the order of - * the Charstrings in the font. This is not necessarily the same - * order as the glyph index. The index_to_glyph_name() font backend - * function is used to map the glyph index to the glyph order in - * the Charstrings. */ - - glyph_data_t *glyphs; - char **glyph_names; - cairo_array_t glyphs_array; - cairo_array_t glyph_names_array; - - int num_subrs; - cairo_bool_t subset_subrs; - struct { - const char *subr_string; - int subr_length; - const char *np; - int np_length; - cairo_bool_t used; - } *subrs; - - /* Indexed by subset_index this maps to the glyph order in the - * glyph_names and glyphs arrays. Has font->num_golyphs - * elements. */ - int *subset_index_to_glyphs; - - cairo_output_stream_t *output; - cairo_array_t contents; - - const char *rd, *nd, *np; - - int lenIV; - - char *type1_data; - unsigned int type1_length; - char *type1_end; - - char *header_segment; - int header_segment_size; - char *eexec_segment; - int eexec_segment_size; - cairo_bool_t eexec_segment_is_ascii; - - char *cleartext; - char *cleartext_end; - - int header_size; - - unsigned short eexec_key; - cairo_bool_t hex_encode; - int hex_column; - - struct { - double stack[TYPE1_STACKSIZE]; - int sp; - } build_stack; - - struct { - int stack[TYPE1_STACKSIZE]; - int sp; - } ps_stack; - - -} cairo_type1_font_subset_t; - - -static cairo_status_t -_cairo_type1_font_subset_init (cairo_type1_font_subset_t *font, - cairo_scaled_font_subset_t *scaled_font_subset, - cairo_bool_t hex_encode) -{ - memset (font, 0, sizeof (*font)); - font->scaled_font_subset = scaled_font_subset; - - _cairo_array_init (&font->glyphs_array, sizeof (glyph_data_t)); - _cairo_array_init (&font->glyph_names_array, sizeof (char *)); - font->subset_index_to_glyphs = NULL; - font->base.num_glyphs = 0; - font->num_subrs = 0; - font->subset_subrs = TRUE; - font->subrs = NULL; - - font->hex_encode = hex_encode; - font->num_glyphs = 0; - - _cairo_array_init (&font->contents, sizeof (char)); - - return CAIRO_STATUS_SUCCESS; -} - -static void -cairo_type1_font_subset_use_glyph (cairo_type1_font_subset_t *font, int glyph) -{ - if (font->glyphs[glyph].subset_index >= 0) - return; - - font->glyphs[glyph].subset_index = font->num_glyphs; - font->subset_index_to_glyphs[font->num_glyphs] = glyph; - font->num_glyphs++; -} - -static cairo_bool_t -is_ps_delimiter(int c) -{ - static const char delimiters[] = "()[]{}<>/% \t\r\n"; - - return strchr (delimiters, c) != NULL; -} - -static const char * -find_token (const char *buffer, const char *end, const char *token) -{ - int i, length; - /* FIXME: find substring really must be find_token */ - - if (buffer == NULL) - return NULL; - - length = strlen (token); - for (i = 0; buffer + i < end - length + 1; i++) - if (memcmp (buffer + i, token, length) == 0) - if ((i == 0 || token[0] == '/' || is_ps_delimiter(buffer[i - 1])) && - (buffer + i == end - length || is_ps_delimiter(buffer[i + length]))) - return buffer + i; - - return NULL; -} - -static cairo_status_t -cairo_type1_font_subset_find_segments (cairo_type1_font_subset_t *font) -{ - unsigned char *p; - const char *eexec_token; - int size, i; - - p = (unsigned char *) font->type1_data; - font->type1_end = font->type1_data + font->type1_length; - if (p[0] == 0x80 && p[1] == 0x01) { - font->header_segment_size = - p[2] | (p[3] << 8) | (p[4] << 16) | (p[5] << 24); - font->header_segment = (char *) p + 6; - - p += 6 + font->header_segment_size; - font->eexec_segment_size = - p[2] | (p[3] << 8) | (p[4] << 16) | (p[5] << 24); - font->eexec_segment = (char *) p + 6; - font->eexec_segment_is_ascii = (p[1] == 1); - - p += 6 + font->eexec_segment_size; - while (p < (unsigned char *) (font->type1_end) && p[1] != 0x03) { - size = p[2] | (p[3] << 8) | (p[4] << 16) | (p[5] << 24); - p += 6 + size; - } - font->type1_end = (char *) p; - } else { - eexec_token = find_token ((char *) p, font->type1_end, "eexec"); - if (eexec_token == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - font->header_segment_size = eexec_token - (char *) p + strlen ("eexec\n"); - font->header_segment = (char *) p; - font->eexec_segment_size = font->type1_length - font->header_segment_size; - font->eexec_segment = (char *) p + font->header_segment_size; - font->eexec_segment_is_ascii = TRUE; - for (i = 0; i < 4; i++) { - if (!isxdigit(font->eexec_segment[i])) - font->eexec_segment_is_ascii = FALSE; - } - } - - return CAIRO_STATUS_SUCCESS; -} - -/* Search for the definition of key and erase it by overwriting with spaces. - * This function is looks for definitions of the form: - * - * /key1 1234 def - * /key2 [12 34 56] def - * - * ie a key defined as an integer or array of integers. - * - */ -static void -cairo_type1_font_erase_dict_key (cairo_type1_font_subset_t *font, - const char *key) -{ - const char *start, *p, *segment_end; - - segment_end = font->header_segment + font->header_segment_size; - - start = font->header_segment; - do { - start = find_token (start, segment_end, key); - if (start) { - p = start + strlen(key); - /* skip integers or array of integers */ - while (p < segment_end && - (_cairo_isspace(*p) || - _cairo_isdigit(*p) || - *p == '[' || - *p == ']')) - { - p++; - } - - if (p + 3 < segment_end && memcmp(p, "def", 3) == 0) { - /* erase definition of the key */ - memset((char *) start, ' ', p + 3 - start); - } - start += strlen(key); - } - } while (start); -} - -static cairo_status_t -cairo_type1_font_subset_get_matrix (cairo_type1_font_subset_t *font, - const char *name, - double *a, - double *b, - double *c, - double *d) -{ - const char *start, *end, *segment_end; - int ret, s_max, i, j; - char *s; - const char *decimal_point; - int decimal_point_len; - - decimal_point = cairo_get_locale_decimal_point (); - decimal_point_len = strlen (decimal_point); - - assert (decimal_point_len != 0); - - segment_end = font->header_segment + font->header_segment_size; - start = find_token (font->header_segment, segment_end, name); - if (start == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - end = find_token (start, segment_end, "def"); - if (end == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - s_max = end - start + 5*decimal_point_len + 1; - s = malloc (s_max); - if (unlikely (s == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - i = 0; - j = 0; - while (i < end - start && j < s_max - decimal_point_len) { - if (start[i] == '.') { - strncpy(s + j, decimal_point, decimal_point_len); - i++; - j += decimal_point_len; - } else { - s[j++] = start[i++]; - } - } - s[j] = 0; - - start = strpbrk (s, "{["); - if (!start) { - free (s); - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - start++; - ret = 0; - if (*start) - ret = sscanf(start, "%lf %lf %lf %lf", a, b, c, d); - - free (s); - - if (ret != 4) - return CAIRO_INT_STATUS_UNSUPPORTED; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_type1_font_subset_get_bbox (cairo_type1_font_subset_t *font) -{ - cairo_status_t status; - double x_min, y_min, x_max, y_max; - double xx, yx, xy, yy; - - status = cairo_type1_font_subset_get_matrix (font, "/FontBBox", - &x_min, - &y_min, - &x_max, - &y_max); - if (unlikely (status)) - return status; - - status = cairo_type1_font_subset_get_matrix (font, "/FontMatrix", - &xx, &yx, &xy, &yy); - if (unlikely (status)) - return status; - - if (yy == 0.0) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* Freetype uses 1/yy to get units per EM */ - font->base.units_per_em = 1.0/yy; - - font->base.x_min = x_min / font->base.units_per_em; - font->base.y_min = y_min / font->base.units_per_em; - font->base.x_max = x_max / font->base.units_per_em; - font->base.y_max = y_max / font->base.units_per_em; - font->base.ascent = font->base.y_max; - font->base.descent = font->base.y_min; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_type1_font_subset_get_fontname (cairo_type1_font_subset_t *font) -{ - const char *start, *end, *segment_end; - char *s; - int i; - cairo_status_t status; - - segment_end = font->header_segment + font->header_segment_size; - start = find_token (font->header_segment, segment_end, "/FontName"); - if (start == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - start += strlen ("/FontName"); - - end = find_token (start, segment_end, "def"); - if (end == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - while (end > start && _cairo_isspace(end[-1])) - end--; - - s = malloc (end - start + 1); - if (unlikely (s == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - strncpy (s, start, end - start); - s[end - start] = 0; - - start = strchr (s, '/'); - if (!start++ || !start) { - free (s); - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - /* If font name is prefixed with a subset tag, strip it off. */ - if (strlen(start) > 7 && start[6] == '+') { - for (i = 0; i < 6; i++) { - if (start[i] < 'A' || start[i] > 'Z') - break; - } - if (i == 6) - start += 7; - } - - font->base.base_font = strdup (start); - free (s); - if (unlikely (font->base.base_font == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - status = _cairo_escape_ps_name (&font->base.base_font); - - return status; -} - -static cairo_status_t -cairo_type1_font_subset_write_header (cairo_type1_font_subset_t *font, - const char *name) -{ - const char *start, *end, *segment_end; - unsigned int i; - - /* FIXME: - * This function assumes that /FontName always appears - * before /Encoding. This appears to always be the case with Type1 - * fonts. - * - * The more recently added code for removing the UniqueID and XUID - * keys can not make any assumptions about the position of the - * keys in the dictionary so it is implemented by overwriting the - * key definition with spaces before we start copying the font to - * the output. - * - * This code should be rewritten to not make any assumptions about - * the order of dictionary keys. This will allow UniqueID to be - * stripped out instead of leaving a bunch of spaces in the - * output. - */ - cairo_type1_font_erase_dict_key (font, "/UniqueID"); - cairo_type1_font_erase_dict_key (font, "/XUID"); - - segment_end = font->header_segment + font->header_segment_size; - - /* Type 1 fonts created by Fontforge have some PostScript code at - * the start of the font that skips the font if the printer has a - * cached copy of the font with the same unique id. This breaks - * our subsetted font so we disable it by searching for the - * PostScript operator "known" when used to check for the - * "/UniqueID" dictionary key. We append " pop false " after it to - * pop the result of this check off the stack and replace it with - * "false" to make the PostScript code think "/UniqueID" does not - * exist. - */ - end = font->header_segment; - start = find_token (font->header_segment, segment_end, "/UniqueID"); - if (start) { - start += 9; - while (start < segment_end && _cairo_isspace (*start)) - start++; - if (start + 5 < segment_end && memcmp(start, "known", 5) == 0) { - _cairo_output_stream_write (font->output, font->header_segment, - start + 5 - font->header_segment); - _cairo_output_stream_printf (font->output, " pop false "); - end = start + 5; - } - } - - start = find_token (end, segment_end, "/FontName"); - if (start == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - _cairo_output_stream_write (font->output, end, - start - end); - - _cairo_output_stream_printf (font->output, "/FontName /%s def", name); - - end = find_token (start, segment_end, "def"); - if (end == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - end += 3; - - start = find_token (end, segment_end, "/Encoding"); - if (start == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - _cairo_output_stream_write (font->output, end, start - end); - - _cairo_output_stream_printf (font->output, - "/Encoding 256 array\n" - "0 1 255 {1 index exch /.notdef put} for\n"); - if (font->scaled_font_subset->is_latin) { - for (i = 1; i < 256; i++) { - int subset_glyph = font->scaled_font_subset->latin_to_subset_glyph_index[i]; - - if (subset_glyph > 0) { - _cairo_output_stream_printf (font->output, - "dup %d /%s put\n", - i, - _cairo_winansi_to_glyphname (i)); - } - } - } else { - for (i = 0; i < font->base.num_glyphs; i++) { - if (font->glyphs[i].subset_index <= 0) - continue; - _cairo_output_stream_printf (font->output, - "dup %d /%s put\n", - font->glyphs[i].subset_index, - font->glyph_names[i]); - } - } - _cairo_output_stream_printf (font->output, "readonly def"); - - end = find_token (start, segment_end, "def"); - if (end == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - end += 3; - - /* There are some buggy fonts that contain more than one /Encoding */ - if (find_token (end, segment_end, "/Encoding")) - return CAIRO_INT_STATUS_UNSUPPORTED; - - _cairo_output_stream_write (font->output, end, segment_end - end); - - return font->output->status; -} - -static int -hex_to_int (int ch) -{ - if (ch <= '9') - return ch - '0'; - else if (ch <= 'F') - return ch - 'A' + 10; - else - return ch - 'a' + 10; -} - -static cairo_status_t -cairo_type1_font_subset_write_encrypted (cairo_type1_font_subset_t *font, - const char *data, unsigned int length) -{ - const unsigned char *in, *end; - int c, p; - static const char hex_digits[16] = "0123456789abcdef"; - char digits[3]; - - in = (const unsigned char *) data; - end = (const unsigned char *) data + length; - while (in < end) { - p = *in++; - c = p ^ (font->eexec_key >> 8); - font->eexec_key = (c + font->eexec_key) * CAIRO_TYPE1_ENCRYPT_C1 + CAIRO_TYPE1_ENCRYPT_C2; - - if (font->hex_encode) { - digits[0] = hex_digits[c >> 4]; - digits[1] = hex_digits[c & 0x0f]; - digits[2] = '\n'; - font->hex_column += 2; - - if (font->hex_column == 78) { - _cairo_output_stream_write (font->output, digits, 3); - font->hex_column = 0; - } else { - _cairo_output_stream_write (font->output, digits, 2); - } - } else { - digits[0] = c; - _cairo_output_stream_write (font->output, digits, 1); - } - } - - return font->output->status; -} - -static cairo_status_t -cairo_type1_font_subset_decrypt_eexec_segment (cairo_type1_font_subset_t *font) -{ - unsigned short r = CAIRO_TYPE1_PRIVATE_DICT_KEY; - unsigned char *in, *end; - char *out; - int c, p; - int i; - - in = (unsigned char *) font->eexec_segment; - end = (unsigned char *) in + font->eexec_segment_size; - - font->cleartext = malloc (font->eexec_segment_size + 1); - if (unlikely (font->cleartext == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - out = font->cleartext; - while (in < end) { - if (font->eexec_segment_is_ascii) { - c = *in++; - if (_cairo_isspace (c)) - continue; - c = (hex_to_int (c) << 4) | hex_to_int (*in++); - } else { - c = *in++; - } - p = c ^ (r >> 8); - r = (c + r) * CAIRO_TYPE1_ENCRYPT_C1 + CAIRO_TYPE1_ENCRYPT_C2; - - *out++ = p; - } - font->cleartext_end = out; - - /* Overwrite random bytes with spaces. - * - * The first 4 bytes of the cleartext are the random bytes - * required by the encryption algorithm. When encrypting the - * cleartext, the first ciphertext byte must not be a white space - * character and the first 4 bytes must not be an ASCII Hex - * character. Some fonts do not check that their randomly chosen - * bytes results in ciphertext that complies with this - * restriction. This may cause problems for some PDF consumers. By - * replacing the random bytes with spaces, the first four bytes of - * ciphertext will always be 0xf9, 0x83, 0xef, 0x00 which complies - * with this restriction. Using spaces also means we don't have to - * skip over the random bytes when parsing the cleartext. - */ - for (i = 0; i < 4 && i < font->eexec_segment_size; i++) - font->cleartext[i] = ' '; - - /* Ensure strtol() can not scan past the end of the cleartext */ - font->cleartext[font->eexec_segment_size] = 0; - - return CAIRO_STATUS_SUCCESS; -} - -static const char * -skip_token (const char *p, const char *end) -{ - while (p < end && _cairo_isspace(*p)) - p++; - - while (p < end && !_cairo_isspace(*p)) - p++; - - if (p == end) - return NULL; - - return p; -} - -static void -cairo_type1_font_subset_decrypt_charstring (const unsigned char *in, int size, unsigned char *out) -{ - unsigned short r = CAIRO_TYPE1_CHARSTRING_KEY; - int c, p, i; - - for (i = 0; i < size; i++) { - c = *in++; - p = c ^ (r >> 8); - r = (c + r) * CAIRO_TYPE1_ENCRYPT_C1 + CAIRO_TYPE1_ENCRYPT_C2; - *out++ = p; - } -} - -static const unsigned char * -cairo_type1_font_subset_decode_integer (const unsigned char *p, int *integer) -{ - if (*p <= 246) { - *integer = *p++ - 139; - } else if (*p <= 250) { - *integer = (p[0] - 247) * 256 + p[1] + 108; - p += 2; - } else if (*p <= 254) { - *integer = -(p[0] - 251) * 256 - p[1] - 108; - p += 2; - } else { - *integer = (p[1] << 24) | (p[2] << 16) | (p[3] << 8) | p[4]; - p += 5; - } - - return p; -} - -static cairo_status_t -use_standard_encoding_glyph (cairo_type1_font_subset_t *font, int index) -{ - const char *glyph_name; - unsigned int i; - - if (index < 0 || index > 255) - return CAIRO_STATUS_SUCCESS; - - glyph_name = _cairo_ps_standard_encoding_to_glyphname (index); - if (glyph_name == NULL) - return CAIRO_STATUS_SUCCESS; - - for (i = 0; i < font->base.num_glyphs; i++) { - if (font->glyph_names[i] && strcmp (font->glyph_names[i], glyph_name) == 0) { - cairo_type1_font_subset_use_glyph (font, i); - - return CAIRO_STATUS_SUCCESS; - } - } - - return CAIRO_INT_STATUS_UNSUPPORTED; -} - - -#define TYPE1_CHARSTRING_COMMAND_HSTEM 0x01 -#define TYPE1_CHARSTRING_COMMAND_VSTEM 0x03 -#define TYPE1_CHARSTRING_COMMAND_VMOVETO 0x04 -#define TYPE1_CHARSTRING_COMMAND_RLINETO 0x05 -#define TYPE1_CHARSTRING_COMMAND_HLINETO 0x06 -#define TYPE1_CHARSTRING_COMMAND_VLINETO 0x07 -#define TYPE1_CHARSTRING_COMMAND_RRCURVETO 0x08 -#define TYPE1_CHARSTRING_COMMAND_CLOSEPATH 0x09 -#define TYPE1_CHARSTRING_COMMAND_CALLSUBR 0x0a -#define TYPE1_CHARSTRING_COMMAND_RETURN 0x0b -#define TYPE1_CHARSTRING_COMMAND_ESCAPE 0x0c -#define TYPE1_CHARSTRING_COMMAND_HSBW 0x0d -#define TYPE1_CHARSTRING_COMMAND_ENDCHAR 0x0e -#define TYPE1_CHARSTRING_COMMAND_RMOVETO 0x15 -#define TYPE1_CHARSTRING_COMMAND_HMOVETO 0x16 -#define TYPE1_CHARSTRING_COMMAND_VHCURVETO 0x1e -#define TYPE1_CHARSTRING_COMMAND_HVCURVETO 0x1f -#define TYPE1_CHARSTRING_COMMAND_DOTSECTION 0x0c00 -#define TYPE1_CHARSTRING_COMMAND_VSTEM3 0x0c01 -#define TYPE1_CHARSTRING_COMMAND_HSTEM3 0x0c02 -#define TYPE1_CHARSTRING_COMMAND_SEAC 0x0c06 -#define TYPE1_CHARSTRING_COMMAND_SBW 0x0c07 -#define TYPE1_CHARSTRING_COMMAND_DIV 0x0c0c -#define TYPE1_CHARSTRING_COMMAND_CALLOTHERSUBR 0x0c10 -#define TYPE1_CHARSTRING_COMMAND_POP 0x0c11 -#define TYPE1_CHARSTRING_COMMAND_SETCURRENTPOINT 0x0c21 - -/* Parse the charstring, including recursing into subroutines. Find - * the glyph width, subroutines called, and glyphs required by the - * SEAC operator. */ -static cairo_status_t -cairo_type1_font_subset_parse_charstring (cairo_type1_font_subset_t *font, - int glyph, - const char *encrypted_charstring, - int encrypted_charstring_length) -{ - cairo_status_t status; - unsigned char *charstring; - const unsigned char *end; - const unsigned char *p; - int command; - - charstring = malloc (encrypted_charstring_length); - if (unlikely (charstring == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - cairo_type1_font_subset_decrypt_charstring ((const unsigned char *) - encrypted_charstring, - encrypted_charstring_length, - charstring); - end = charstring + encrypted_charstring_length; - p = charstring + font->lenIV; - status = CAIRO_STATUS_SUCCESS; - while (p < end) { - if (*p < 32) { - command = *p++; - switch (command) { - case TYPE1_CHARSTRING_COMMAND_HSTEM: - case TYPE1_CHARSTRING_COMMAND_VSTEM: - case TYPE1_CHARSTRING_COMMAND_VMOVETO: - case TYPE1_CHARSTRING_COMMAND_RLINETO: - case TYPE1_CHARSTRING_COMMAND_HLINETO: - case TYPE1_CHARSTRING_COMMAND_VLINETO: - case TYPE1_CHARSTRING_COMMAND_RRCURVETO: - case TYPE1_CHARSTRING_COMMAND_CLOSEPATH: - case TYPE1_CHARSTRING_COMMAND_RMOVETO: - case TYPE1_CHARSTRING_COMMAND_HMOVETO: - case TYPE1_CHARSTRING_COMMAND_VHCURVETO: - case TYPE1_CHARSTRING_COMMAND_HVCURVETO: - case TYPE1_CHARSTRING_COMMAND_RETURN: - case TYPE1_CHARSTRING_COMMAND_ENDCHAR: - default: - /* stack clearing operator */ - font->build_stack.sp = 0; - break; - - case TYPE1_CHARSTRING_COMMAND_CALLSUBR: - if (font->subset_subrs && font->build_stack.sp > 0) { - double int_val; - if (modf(font->build_stack.stack[--font->build_stack.sp], &int_val) == 0.0) { - int subr_num = int_val; - if (subr_num >= 0 && subr_num < font->num_subrs) { - font->subrs[subr_num].used = TRUE; - status = cairo_type1_font_subset_parse_charstring ( - font, - glyph, - font->subrs[subr_num].subr_string, - font->subrs[subr_num].subr_length); - break; - } - } - } - font->subset_subrs = FALSE; - break; - - case TYPE1_CHARSTRING_COMMAND_HSBW: - if (font->build_stack.sp < 2) { - status = CAIRO_INT_STATUS_UNSUPPORTED; - goto cleanup; - } - - font->glyphs[glyph].width = font->build_stack.stack[1]/font->base.units_per_em; - font->build_stack.sp = 0; - break; - - case TYPE1_CHARSTRING_COMMAND_ESCAPE: - command = command << 8 | *p++; - switch (command) { - case TYPE1_CHARSTRING_COMMAND_DOTSECTION: - case TYPE1_CHARSTRING_COMMAND_VSTEM3: - case TYPE1_CHARSTRING_COMMAND_HSTEM3: - case TYPE1_CHARSTRING_COMMAND_SETCURRENTPOINT: - default: - /* stack clearing operator */ - font->build_stack.sp = 0; - break; - - case TYPE1_CHARSTRING_COMMAND_SEAC: - /* The seac command takes five integer arguments. The - * last two are glyph indices into the PS standard - * encoding give the names of the glyphs that this - * glyph is composed from. All we need to do is to - * make sure those glyphs are present in the subset - * under their standard names. */ - if (font->build_stack.sp < 5) { - status = CAIRO_INT_STATUS_UNSUPPORTED; - goto cleanup; - } - - status = use_standard_encoding_glyph (font, font->build_stack.stack[3]); - if (unlikely (status)) - goto cleanup; - - status = use_standard_encoding_glyph (font, font->build_stack.stack[4]); - if (unlikely (status)) - goto cleanup; - - font->build_stack.sp = 0; - break; - - case TYPE1_CHARSTRING_COMMAND_SBW: - if (font->build_stack.sp < 4) { - status = CAIRO_INT_STATUS_UNSUPPORTED; - goto cleanup; - } - - font->glyphs[glyph].width = font->build_stack.stack[2]/font->base.units_per_em; - font->build_stack.sp = 0; - break; - - case TYPE1_CHARSTRING_COMMAND_DIV: - if (font->build_stack.sp < 2) { - status = CAIRO_INT_STATUS_UNSUPPORTED; - goto cleanup; - } else { - double num1 = font->build_stack.stack[font->build_stack.sp - 2]; - double num2 = font->build_stack.stack[font->build_stack.sp - 1]; - font->build_stack.sp--; - if (num2 == 0.0) { - status = CAIRO_INT_STATUS_UNSUPPORTED; - goto cleanup; - } - font->build_stack.stack[font->build_stack.sp - 1] = num1/num2; - } - break; - - case TYPE1_CHARSTRING_COMMAND_CALLOTHERSUBR: - if (font->build_stack.sp < 1) { - status = CAIRO_INT_STATUS_UNSUPPORTED; - goto cleanup; - } - - font->build_stack.sp--; - font->ps_stack.sp = 0; - while (font->build_stack.sp) - font->ps_stack.stack[font->ps_stack.sp++] = font->build_stack.stack[--font->build_stack.sp]; - - break; - - case TYPE1_CHARSTRING_COMMAND_POP: - if (font->ps_stack.sp < 1) { - status = CAIRO_INT_STATUS_UNSUPPORTED; - goto cleanup; - } - - /* T1 spec states that if the interpreter does not - * support executing the callothersub, the results - * must be taken from the callothersub arguments. */ - font->build_stack.stack[font->build_stack.sp++] = font->ps_stack.stack[--font->ps_stack.sp]; - break; - } - break; - } - } else { - /* integer argument */ - if (font->build_stack.sp < TYPE1_STACKSIZE) { - int val; - p = cairo_type1_font_subset_decode_integer (p, &val); - font->build_stack.stack[font->build_stack.sp++] = val; - } else { - status = CAIRO_INT_STATUS_UNSUPPORTED; - goto cleanup; - } - } - } - -cleanup: - free (charstring); - - return status; -} - -static cairo_status_t -cairo_type1_font_subset_build_subr_list (cairo_type1_font_subset_t *font, - int subr_number, - const char *encrypted_charstring, int encrypted_charstring_length, - const char *np, int np_length) -{ - - font->subrs[subr_number].subr_string = encrypted_charstring; - font->subrs[subr_number].subr_length = encrypted_charstring_length; - font->subrs[subr_number].np = np; - font->subrs[subr_number].np_length = np_length; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -write_used_subrs (cairo_type1_font_subset_t *font, - int subr_number, - const char *subr_string, int subr_string_length, - const char *np, int np_length) -{ - cairo_status_t status; - char buffer[256]; - int length; - - if (!font->subrs[subr_number].used) - return CAIRO_STATUS_SUCCESS; - - length = snprintf (buffer, sizeof buffer, - "dup %d %d %s ", - subr_number, subr_string_length, font->rd); - status = cairo_type1_font_subset_write_encrypted (font, buffer, length); - if (unlikely (status)) - return status; - - status = cairo_type1_font_subset_write_encrypted (font, - subr_string, - subr_string_length); - if (unlikely (status)) - return status; - - if (np) { - status = cairo_type1_font_subset_write_encrypted (font, np, np_length); - } else { - length = snprintf (buffer, sizeof buffer, "%s\n", font->np); - status = cairo_type1_font_subset_write_encrypted (font, buffer, length); - } - if (unlikely (status)) - return status; - - return CAIRO_STATUS_SUCCESS; -} - -typedef cairo_status_t (*subr_func_t) (cairo_type1_font_subset_t *font, - int subr_number, - const char *subr_string, int subr_string_length, - const char *np, int np_length); - -static cairo_status_t -cairo_type1_font_for_each_subr (cairo_type1_font_subset_t *font, - const char *array_start, - const char *cleartext_end, - subr_func_t func, - const char **array_end) -{ - const char *p, *subr_string; - char *end; - int subr_num, subr_length; - const char *np; - int np_length; - cairo_status_t status; - - /* We're looking at "dup" at the start of the first subroutine. The subroutines - * definitions are on the form: - * - * dup 5 23 RD <23 binary bytes> NP - * - * or alternatively using -| and |- instead of RD and ND. - * The first number is the subroutine number. - */ - - p = array_start; - while (p + 3 < cleartext_end && strncmp (p, "dup", 3) == 0) { - p = skip_token (p, cleartext_end); - - /* get subr number */ - subr_num = strtol (p, &end, 10); - if (p == end) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (subr_num < 0 || subr_num >= font->num_subrs) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* get subr length */ - p = end; - subr_length = strtol (p, &end, 10); - if (p == end) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* Skip past -| or RD to binary data. There is exactly one space - * between the -| or RD token and the encrypted data, thus '+ 1'. */ - subr_string = skip_token (end, cleartext_end) + 1; - - np = NULL; - np_length = 0; - - /* Skip binary data and | or NP token. */ - p = skip_token (subr_string + subr_length, cleartext_end); - while (p < cleartext_end && _cairo_isspace(*p)) - p++; - - /* Some fonts have "noaccess put" instead of "NP" */ - if (p + 3 < cleartext_end && strncmp (p, "put", 3) == 0) { - p = skip_token (p, cleartext_end); - while (p < cleartext_end && _cairo_isspace(*p)) - p++; - - np = subr_string + subr_length; - np_length = p - np; - } - - status = func (font, subr_num, - subr_string, subr_length, np, np_length); - if (unlikely (status)) - return status; - - } - - *array_end = (char *) p; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_type1_font_subset_build_glyph_list (cairo_type1_font_subset_t *font, - int glyph_number, - const char *name, int name_length, - const char *encrypted_charstring, int encrypted_charstring_length) -{ - char *s; - glyph_data_t glyph; - cairo_status_t status; - - s = malloc (name_length + 1); - if (unlikely (s == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - strncpy (s, name, name_length); - s[name_length] = 0; - - status = _cairo_array_append (&font->glyph_names_array, &s); - if (unlikely (status)) - return status; - - glyph.subset_index = -1; - glyph.width = 0; - glyph.encrypted_charstring = encrypted_charstring; - glyph.encrypted_charstring_length = encrypted_charstring_length; - status = _cairo_array_append (&font->glyphs_array, &glyph); - - return status; -} - -static cairo_status_t -write_used_glyphs (cairo_type1_font_subset_t *font, - int glyph_number, - const char *name, int name_length, - const char *charstring, int charstring_length) -{ - cairo_status_t status; - char buffer[256]; - int length; - unsigned int subset_id; - int ch; - const char *wa_name; - - if (font->glyphs[glyph_number].subset_index < 0) - return CAIRO_STATUS_SUCCESS; - - if (font->scaled_font_subset->is_latin) { - /* When using the WinAnsi encoding in PDF, the /Encoding array - * is ignored and instead glyphs are keyed by glyph names. To - * ensure correct rendering we replace the glyph name in the - * font with the standard name. - **/ - subset_id = font->glyphs[glyph_number].subset_index; - /* Any additional glyph included for use by the seac operator - * will either have subset_id >= font->scaled_font_subset->num_glyphs - * or will not map to a winansi name (wa_name = NULL). In this - * case the original name is used. - */ - if (subset_id > 0 && subset_id < font->scaled_font_subset->num_glyphs) { - ch = font->scaled_font_subset->to_latin_char[subset_id]; - wa_name = _cairo_winansi_to_glyphname (ch); - if (wa_name) { - name = wa_name; - name_length = strlen(name); - } - } - } - - length = snprintf (buffer, sizeof buffer, - "/%.*s %d %s ", - name_length, name, charstring_length, font->rd); - status = cairo_type1_font_subset_write_encrypted (font, buffer, length); - if (unlikely (status)) - return status; - - status = cairo_type1_font_subset_write_encrypted (font, - charstring, - charstring_length); - if (unlikely (status)) - return status; - - length = snprintf (buffer, sizeof buffer, "%s\n", font->nd); - status = cairo_type1_font_subset_write_encrypted (font, buffer, length); - if (unlikely (status)) - return status; - - return CAIRO_STATUS_SUCCESS; -} - -typedef cairo_status_t (*glyph_func_t) (cairo_type1_font_subset_t *font, - int glyph_number, - const char *name, int name_length, - const char *charstring, int charstring_length); - -static cairo_status_t -cairo_type1_font_subset_for_each_glyph (cairo_type1_font_subset_t *font, - const char *dict_start, - const char *dict_end, - glyph_func_t func, - const char **dict_out) -{ - int charstring_length, name_length; - const char *p, *charstring, *name; - char *end; - cairo_status_t status; - int glyph_count; - - /* We're looking at '/' in the name of the first glyph. The glyph - * definitions are on the form: - * - * /name 23 RD <23 binary bytes> ND - * - * or alternatively using -| and |- instead of RD and ND. - * - * We parse the glyph name and see if it is in the subset. If it - * is, we call the specified callback with the glyph name and - * glyph data, otherwise we just skip it. We need to parse - * through a glyph definition; we can't just find the next '/', - * since the binary data could contain a '/'. - */ - - p = dict_start; - glyph_count = 0; - while (*p == '/') { - name = p + 1; - p = skip_token (p, dict_end); - name_length = p - name; - - charstring_length = strtol (p, &end, 10); - if (p == end) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* Skip past -| or RD to binary data. There is exactly one space - * between the -| or RD token and the encrypted data, thus '+ 1'. */ - charstring = skip_token (end, dict_end) + 1; - - /* Skip binary data and |- or ND token. */ - p = skip_token (charstring + charstring_length, dict_end); - while (p < dict_end && _cairo_isspace(*p)) - p++; - - /* In case any of the skip_token() calls above reached EOF, p will - * be equal to dict_end. */ - if (p == dict_end) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = func (font, glyph_count++, - name, name_length, - charstring, charstring_length); - if (unlikely (status)) - return status; - } - - *dict_out = p; - - return CAIRO_STATUS_SUCCESS; -} - - -static cairo_status_t -cairo_type1_font_subset_write_private_dict (cairo_type1_font_subset_t *font, - const char *name) -{ - cairo_status_t status; - const char *p, *subrs, *charstrings, *array_start, *array_end, *dict_start, *dict_end; - const char *lenIV_start, *lenIV_end, *closefile_token; - char buffer[32], *lenIV_str, *subr_count_end, *glyph_count_end; - int ret, lenIV, length; - const cairo_scaled_font_backend_t *backend; - unsigned int i; - int glyph, j; - - /* The private dict holds hint information, common subroutines and - * the actual glyph definitions (charstrings). - * - * What we do here is scan directly to the /Subrs token, which - * marks the beginning of the subroutines. We read in all the - * subroutines, then move on to the /CharString token, which marks - * the beginning of the glyph definitions, and read in the charstrings. - * - * The charstrings are parsed to extract glyph widths, work out - * which subroutines are called, and to see if any extra glyphs - * need to be included due to the use of the seac glyph combining - * operator. - * - * Finally, the private dict is copied to the subset font minus the - * subroutines and charstrings not required. - */ - - /* Determine lenIV, the number of random characters at the start of - each encrypted charstring. The default is 4, but this can be - overridden in the private dict. */ - font->lenIV = 4; - if ((lenIV_start = find_token (font->cleartext, font->cleartext_end, "/lenIV")) != NULL) { - lenIV_start += 6; - lenIV_end = find_token (lenIV_start, font->cleartext_end, "def"); - if (lenIV_end == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - lenIV_str = malloc (lenIV_end - lenIV_start + 1); - if (unlikely (lenIV_str == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - strncpy (lenIV_str, lenIV_start, lenIV_end - lenIV_start); - lenIV_str[lenIV_end - lenIV_start] = 0; - - ret = sscanf(lenIV_str, "%d", &lenIV); - free(lenIV_str); - - if (unlikely (ret <= 0)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* Apparently some fonts signal unencrypted charstrings with a negative lenIV, - though this is not part of the Type 1 Font Format specification. See, e.g. - http://lists.gnu.org/archive/html/freetype-devel/2000-06/msg00064.html. */ - if (unlikely (lenIV < 0)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - font->lenIV = lenIV; - } - - /* Find start of Subrs */ - subrs = find_token (font->cleartext, font->cleartext_end, "/Subrs"); - if (subrs == NULL) { - font->subset_subrs = FALSE; - p = font->cleartext; - array_start = NULL; - goto skip_subrs; - } - - /* Scan past /Subrs and get the array size. */ - p = subrs + strlen ("/Subrs"); - font->num_subrs = strtol (p, &subr_count_end, 10); - if (subr_count_end == p) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (font->num_subrs <= 0) - return CAIRO_INT_STATUS_UNSUPPORTED; - - font->subrs = calloc (font->num_subrs, sizeof (font->subrs[0])); - if (unlikely (font->subrs == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - /* look for "dup" which marks the beginning of the first subr */ - array_start = find_token (subr_count_end, font->cleartext_end, "dup"); - if (subrs == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* Read in the subroutines */ - status = cairo_type1_font_for_each_subr (font, - array_start, - font->cleartext_end, - cairo_type1_font_subset_build_subr_list, - &array_end); - if (unlikely(status)) - return status; - - p = array_end; -skip_subrs: - - /* Find start of CharStrings */ - charstrings = find_token (p, font->cleartext_end, "/CharStrings"); - if (charstrings == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* Scan past /CharStrings and the integer following it. */ - p = charstrings + strlen ("/CharStrings"); - strtol (p, &glyph_count_end, 10); - if (p == glyph_count_end) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* Look for a '/' which marks the beginning of the first glyph - * definition. */ - for (p = glyph_count_end; p < font->cleartext_end; p++) - if (*p == '/') - break; - if (p == font->cleartext_end) - return CAIRO_INT_STATUS_UNSUPPORTED; - dict_start = p; - - /* Now that we have the private dictionary broken down in - * sections, do the first pass through the glyph definitions to - * build a list of glyph names and charstrings. */ - status = cairo_type1_font_subset_for_each_glyph (font, - dict_start, - font->cleartext_end, - cairo_type1_font_subset_build_glyph_list, - &dict_end); - if (unlikely(status)) - return status; - - font->glyphs = _cairo_array_index (&font->glyphs_array, 0); - font->glyph_names = _cairo_array_index (&font->glyph_names_array, 0); - font->base.num_glyphs = _cairo_array_num_elements (&font->glyphs_array); - font->subset_index_to_glyphs = calloc (font->base.num_glyphs, sizeof font->subset_index_to_glyphs[0]); - if (unlikely (font->subset_index_to_glyphs == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - backend = font->scaled_font_subset->scaled_font->backend; - if (!backend->index_to_glyph_name) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* Find the glyph number corresponding to each glyph in the subset - * and mark it as in use */ - - for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) { - unsigned long index; - - status = backend->index_to_glyph_name (font->scaled_font_subset->scaled_font, - font->glyph_names, - font->base.num_glyphs, - font->scaled_font_subset->glyphs[i], - &index); - if (unlikely(status)) - return status; - - cairo_type1_font_subset_use_glyph (font, index); - } - - /* Go through the charstring of each glyph in use, get the glyph - * width and figure out which extra glyphs may be required by the - * seac operator (which may cause font->num_glyphs to increase - * while this loop is executing). Also subset the Subrs. */ - for (j = 0; j < font->num_glyphs; j++) { - glyph = font->subset_index_to_glyphs[j]; - font->build_stack.sp = 0; - font->ps_stack.sp = 0; - status = cairo_type1_font_subset_parse_charstring (font, - glyph, - font->glyphs[glyph].encrypted_charstring, - font->glyphs[glyph].encrypted_charstring_length); - if (unlikely (status)) - return status; - } - - /* Always include the first five subroutines in case the Flex/hint mechanism is - * being used. */ - for (j = 0; j < MIN (font->num_subrs, 5); j++) { - font->subrs[j].used = TRUE; - } - - closefile_token = find_token (dict_end, font->cleartext_end, "closefile"); - if (closefile_token == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* We're ready to start outputting. First write the header, - * i.e. the public part of the font dict.*/ - status = cairo_type1_font_subset_write_header (font, name); - if (unlikely (status)) - return status; - - font->base.header_size = _cairo_output_stream_get_position (font->output); - - /* Start outputting the private dict */ - if (font->subset_subrs) { - /* First output everything up to the start of the Subrs array. */ - status = cairo_type1_font_subset_write_encrypted (font, font->cleartext, - array_start - font->cleartext); - if (unlikely (status)) - return status; - - /* Write out the subr definitions for each of the glyphs in - * the subset. */ - status = cairo_type1_font_for_each_subr (font, - array_start, - font->cleartext_end, - write_used_subrs, - &p); - if (unlikely (status)) - return status; - } else { - p = font->cleartext; - } - - /* If subr subsetting, output everything from end of subrs to - * start of /CharStrings token. If not subr subsetting, output - * everything start of private dict to start of /CharStrings - * token. */ - status = cairo_type1_font_subset_write_encrypted (font, p, charstrings - p); - if (unlikely (status)) - return status; - - /* Write out new charstring count */ - length = snprintf (buffer, sizeof buffer, - "/CharStrings %d", font->num_glyphs); - status = cairo_type1_font_subset_write_encrypted (font, buffer, length); - if (unlikely (status)) - return status; - - /* Write out text between the charstring count and the first - * charstring definition */ - status = cairo_type1_font_subset_write_encrypted (font, glyph_count_end, - dict_start - glyph_count_end); - if (unlikely (status)) - return status; - - /* Write out the charstring definitions for each of the glyphs in - * the subset. */ - status = cairo_type1_font_subset_for_each_glyph (font, - dict_start, - font->cleartext_end, - write_used_glyphs, - &p); - if (unlikely (status)) - return status; - - /* Output what's left between the end of the glyph definitions and - * the end of the private dict to the output. */ - status = cairo_type1_font_subset_write_encrypted (font, p, - closefile_token - p + strlen ("closefile") + 1); - if (unlikely (status)) - return status; - - if (font->hex_encode) - _cairo_output_stream_write (font->output, "\n", 1); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -cairo_type1_font_subset_write_trailer(cairo_type1_font_subset_t *font) -{ - const char *cleartomark_token; - int i; - static const char zeros[65] = - "0000000000000000000000000000000000000000000000000000000000000000\n"; - - - for (i = 0; i < 8; i++) - _cairo_output_stream_write (font->output, zeros, sizeof zeros); - - cleartomark_token = find_token (font->type1_data, font->type1_end, "cleartomark"); - if (cleartomark_token) { - /* Some fonts have conditional save/restore around the entire - * font dict, so we need to retain whatever postscript code - * that may come after 'cleartomark'. */ - - _cairo_output_stream_write (font->output, cleartomark_token, - font->type1_end - cleartomark_token); - if (*(font->type1_end - 1) != '\n') - _cairo_output_stream_printf (font->output, "\n"); - - } else if (!font->eexec_segment_is_ascii) { - /* Fonts embedded in PDF may omit the fixed-content portion - * that includes the 'cleartomark' operator. Type 1 in PDF is - * always binary. */ - - _cairo_output_stream_printf (font->output, "cleartomark\n"); - } else { - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - /* some fonts do not have a newline at the end of the last line */ - _cairo_output_stream_printf (font->output, "\n"); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -type1_font_write (void *closure, const unsigned char *data, unsigned int length) -{ - cairo_type1_font_subset_t *font = closure; - - return _cairo_array_append_multiple (&font->contents, data, length); -} - -static cairo_status_t -cairo_type1_font_subset_write (cairo_type1_font_subset_t *font, - const char *name) -{ - cairo_status_t status; - - status = cairo_type1_font_subset_find_segments (font); - if (unlikely (status)) - return status; - - status = cairo_type1_font_subset_decrypt_eexec_segment (font); - if (unlikely (status)) - return status; - - /* Determine which glyph definition delimiters to use. */ - if (find_token (font->cleartext, font->cleartext_end, "/-|") != NULL) { - font->rd = "-|"; - font->nd = "|-"; - font->np = "|"; - } else if (find_token (font->cleartext, font->cleartext_end, "/RD") != NULL) { - font->rd = "RD"; - font->nd = "ND"; - font->np = "NP"; - } else { - /* Don't know *what* kind of font this is... */ - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - font->eexec_key = CAIRO_TYPE1_PRIVATE_DICT_KEY; - font->hex_column = 0; - - status = cairo_type1_font_subset_get_bbox (font); - if (unlikely (status)) - return status; - - status = cairo_type1_font_subset_get_fontname (font); - if (unlikely (status)) - return status; - - status = cairo_type1_font_subset_write_private_dict (font, name); - if (unlikely (status)) - return status; - - font->base.data_size = _cairo_output_stream_get_position (font->output) - - font->base.header_size; - - status = cairo_type1_font_subset_write_trailer (font); - if (unlikely (status)) - return status; - - font->base.trailer_size = - _cairo_output_stream_get_position (font->output) - - font->base.header_size - font->base.data_size; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_bool_t -check_fontdata_is_type1 (const unsigned char *data, long length) -{ - /* Test for Type 1 Binary (PFB) */ - if (length > 2 && data[0] == 0x80 && data[1] == 0x01) - return TRUE; - - /* Test for Type 1 1 ASCII (PFA) */ - if (length > 2 && data[0] == '%' && data[1] == '!') - return TRUE; - - return FALSE; -} - -static cairo_status_t -cairo_type1_font_subset_generate (void *abstract_font, - const char *name) - -{ - cairo_type1_font_subset_t *font = abstract_font; - cairo_scaled_font_t *scaled_font; - cairo_status_t status; - unsigned long data_length; - - scaled_font = font->scaled_font_subset->scaled_font; - if (!scaled_font->backend->load_type1_data) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = scaled_font->backend->load_type1_data (scaled_font, 0, NULL, &data_length); - if (status) - return CAIRO_INT_STATUS_UNSUPPORTED; - - font->type1_length = data_length; - font->type1_data = malloc (font->type1_length); - if (unlikely (font->type1_data == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - status = scaled_font->backend->load_type1_data (scaled_font, 0, - (unsigned char *) font->type1_data, - &data_length); - if (unlikely (status)) - return status; - - if (!check_fontdata_is_type1 ((unsigned char *)font->type1_data, data_length)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_array_grow_by (&font->contents, 4096); - if (unlikely (status)) - return status; - - font->output = _cairo_output_stream_create (type1_font_write, NULL, font); - if (unlikely ((status = font->output->status))) - return status; - - status = cairo_type1_font_subset_write (font, name); - if (unlikely (status)) - return status; - - font->base.data = _cairo_array_index (&font->contents, 0); - - return status; -} - -static cairo_status_t -_cairo_type1_font_subset_fini (cairo_type1_font_subset_t *font) -{ - cairo_status_t status = CAIRO_STATUS_SUCCESS; - unsigned int i; - - /* If the subset generation failed, some of the pointers below may - * be NULL depending on at which point the error occurred. */ - - _cairo_array_fini (&font->contents); - - free (font->type1_data); - for (i = 0; i < _cairo_array_num_elements (&font->glyph_names_array); i++) { - char **s; - - s = _cairo_array_index (&font->glyph_names_array, i); - free (*s); - } - _cairo_array_fini (&font->glyph_names_array); - _cairo_array_fini (&font->glyphs_array); - - free (font->subrs); - - if (font->output != NULL) - status = _cairo_output_stream_destroy (font->output); - - free (font->base.base_font); - - free (font->subset_index_to_glyphs); - - free (font->cleartext); - - return status; -} - -cairo_status_t -_cairo_type1_subset_init (cairo_type1_subset_t *type1_subset, - const char *name, - cairo_scaled_font_subset_t *scaled_font_subset, - cairo_bool_t hex_encode) -{ - cairo_type1_font_subset_t font; - cairo_status_t status; - unsigned long length; - unsigned int i; - char buf[30]; - - /* We need to use a fallback font generated from the synthesized outlines. */ - if (scaled_font_subset->scaled_font->backend->is_synthetic && - scaled_font_subset->scaled_font->backend->is_synthetic (scaled_font_subset->scaled_font)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_type1_font_subset_init (&font, scaled_font_subset, hex_encode); - if (unlikely (status)) - return status; - - status = cairo_type1_font_subset_generate (&font, name); - if (unlikely (status)) - goto fail1; - - if (font.base.base_font) { - type1_subset->base_font = strdup (font.base.base_font); - } else { - snprintf(buf, sizeof (buf), "CairoFont-%u-%u", - scaled_font_subset->font_id, scaled_font_subset->subset_id); - type1_subset->base_font = strdup (buf); - } - if (unlikely (type1_subset->base_font == NULL)) - goto fail1; - - type1_subset->widths = calloc (sizeof (double), font.num_glyphs); - if (unlikely (type1_subset->widths == NULL)) - goto fail2; - for (i = 0; i < font.base.num_glyphs; i++) { - if (font.glyphs[i].subset_index < 0) - continue; - type1_subset->widths[font.glyphs[i].subset_index] = - font.glyphs[i].width; - } - - type1_subset->x_min = font.base.x_min; - type1_subset->y_min = font.base.y_min; - type1_subset->x_max = font.base.x_max; - type1_subset->y_max = font.base.y_max; - type1_subset->ascent = font.base.ascent; - type1_subset->descent = font.base.descent; - - length = font.base.header_size + - font.base.data_size + - font.base.trailer_size; - type1_subset->data = malloc (length); - if (unlikely (type1_subset->data == NULL)) - goto fail3; - - memcpy (type1_subset->data, - _cairo_array_index (&font.contents, 0), length); - - type1_subset->header_length = font.base.header_size; - type1_subset->data_length = font.base.data_size; - type1_subset->trailer_length = font.base.trailer_size; - - return _cairo_type1_font_subset_fini (&font); - - fail3: - free (type1_subset->widths); - fail2: - free (type1_subset->base_font); - fail1: - _cairo_type1_font_subset_fini (&font); - - return status; -} - -void -_cairo_type1_subset_fini (cairo_type1_subset_t *subset) -{ - free (subset->base_font); - free (subset->widths); - free (subset->data); -} - -cairo_bool_t -_cairo_type1_scaled_font_is_type1 (cairo_scaled_font_t *scaled_font) -{ - cairo_status_t status; - unsigned long length; - unsigned char buf[64]; - - if (!scaled_font->backend->load_type1_data) - return FALSE; - - status = scaled_font->backend->load_type1_data (scaled_font, 0, NULL, &length); - if (status) - return FALSE; - - /* We only need a few bytes to test for Type 1 */ - if (length > sizeof (buf)) - length = sizeof (buf); - - status = scaled_font->backend->load_type1_data (scaled_font, 0, buf, &length); - if (status) - return FALSE; - - return check_fontdata_is_type1 (buf, length); -} - -#endif /* CAIRO_HAS_FONT_SUBSET */ diff --git a/source/libs/cairo/cairo-src/src/cairo-type3-glyph-surface-private.h b/source/libs/cairo/cairo-src/src/cairo-type3-glyph-surface-private.h deleted file mode 100644 index 6f40f1c25b4d882a6ce94cf9e5aaa517510e3415..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-type3-glyph-surface-private.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2008 Adrian Johnson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Adrian Johnson. - * - * Contributor(s): - * Adrian Johnson <ajohnson@redneon.com> - */ - -#ifndef CAIRO_TYPE3_GLYPH_SURFACE_PRIVATE_H -#define CAIRO_TYPE3_GLYPH_SURFACE_PRIVATE_H - -#include "cairoint.h" - -#if CAIRO_HAS_FONT_SUBSET - -#include "cairo-surface-private.h" -#include "cairo-surface-clipper-private.h" -#include "cairo-pdf-operators-private.h" - -typedef cairo_int_status_t -(*cairo_type3_glyph_surface_emit_image_t) (cairo_image_surface_t *image, - cairo_output_stream_t *stream); - -typedef struct cairo_type3_glyph_surface { - cairo_surface_t base; - - cairo_scaled_font_t *scaled_font; - cairo_output_stream_t *stream; - cairo_pdf_operators_t pdf_operators; - cairo_matrix_t cairo_to_pdf; - cairo_type3_glyph_surface_emit_image_t emit_image; - - cairo_surface_clipper_t clipper; -} cairo_type3_glyph_surface_t; - -cairo_private cairo_surface_t * -_cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font, - cairo_output_stream_t *stream, - cairo_type3_glyph_surface_emit_image_t emit_image, - cairo_scaled_font_subsets_t *font_subsets, - cairo_bool_t ps_output); - -cairo_private void -_cairo_type3_glyph_surface_set_font_subsets_callback (void *abstract_surface, - cairo_pdf_operators_use_font_subset_t use_font_subset, - void *closure); - -cairo_private cairo_status_t -_cairo_type3_glyph_surface_analyze_glyph (void *abstract_surface, - unsigned long glyph_index); - -cairo_private cairo_status_t -_cairo_type3_glyph_surface_emit_glyph (void *abstract_surface, - cairo_output_stream_t *stream, - unsigned long glyph_index, - cairo_box_t *bbox, - double *width); - -#endif /* CAIRO_HAS_FONT_SUBSET */ - -#endif /* CAIRO_TYPE3_GLYPH_SURFACE_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-type3-glyph-surface.c b/source/libs/cairo/cairo-src/src/cairo-type3-glyph-surface.c deleted file mode 100644 index c99d461066c15619b30e66ffb463c36d0a1ba560..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-type3-glyph-surface.c +++ /dev/null @@ -1,568 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2008 Adrian Johnson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Adrian Johnson. - * - * Contributor(s): - * Adrian Johnson <ajohnson@redneon.com> - */ - -#include "cairoint.h" - -#if CAIRO_HAS_FONT_SUBSET - -#include "cairo-type3-glyph-surface-private.h" -#include "cairo-output-stream-private.h" -#include "cairo-recording-surface-private.h" -#include "cairo-analysis-surface-private.h" -#include "cairo-default-context-private.h" -#include "cairo-error-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-surface-clipper-private.h" - -static const cairo_surface_backend_t cairo_type3_glyph_surface_backend; - -static cairo_status_t -_cairo_type3_glyph_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper, - cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_type3_glyph_surface_t *surface = cairo_container_of (clipper, - cairo_type3_glyph_surface_t, - clipper); - - if (path == NULL) { - _cairo_output_stream_printf (surface->stream, "Q q\n"); - return CAIRO_STATUS_SUCCESS; - } - - return _cairo_pdf_operators_clip (&surface->pdf_operators, - path, - fill_rule); -} - -cairo_surface_t * -_cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font, - cairo_output_stream_t *stream, - cairo_type3_glyph_surface_emit_image_t emit_image, - cairo_scaled_font_subsets_t *font_subsets, - cairo_bool_t ps) -{ - cairo_type3_glyph_surface_t *surface; - cairo_matrix_t invert_y_axis; - - if (unlikely (stream != NULL && stream->status)) - return _cairo_surface_create_in_error (stream->status); - - surface = malloc (sizeof (cairo_type3_glyph_surface_t)); - if (unlikely (surface == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - _cairo_surface_init (&surface->base, - &cairo_type3_glyph_surface_backend, - NULL, /* device */ - CAIRO_CONTENT_COLOR_ALPHA); - - surface->scaled_font = scaled_font; - surface->stream = stream; - surface->emit_image = emit_image; - - /* Setup the transform from the user-font device space to Type 3 - * font space. The Type 3 font space is defined by the FontMatrix - * entry in the Type 3 dictionary. In the PDF backend this is an - * identity matrix. */ - surface->cairo_to_pdf = scaled_font->scale_inverse; - cairo_matrix_init_scale (&invert_y_axis, 1, -1); - cairo_matrix_multiply (&surface->cairo_to_pdf, &surface->cairo_to_pdf, &invert_y_axis); - - _cairo_pdf_operators_init (&surface->pdf_operators, - surface->stream, - &surface->cairo_to_pdf, - font_subsets, - ps); - - _cairo_surface_clipper_init (&surface->clipper, - _cairo_type3_glyph_surface_clipper_intersect_clip_path); - - return &surface->base; -} - -static cairo_status_t -_cairo_type3_glyph_surface_emit_image (cairo_type3_glyph_surface_t *surface, - cairo_image_surface_t *image, - cairo_matrix_t *image_matrix) -{ - cairo_status_t status; - - /* The only image type supported by Type 3 fonts are 1-bit masks */ - image = _cairo_image_surface_coerce_to_format (image, CAIRO_FORMAT_A1); - status = image->base.status; - if (unlikely (status)) - return status; - - _cairo_output_stream_printf (surface->stream, - "q %f %f %f %f %f %f cm\n", - image_matrix->xx, - image_matrix->xy, - image_matrix->yx, - image_matrix->yy, - image_matrix->x0, - image_matrix->y0); - - status = surface->emit_image (image, surface->stream); - cairo_surface_destroy (&image->base); - - _cairo_output_stream_printf (surface->stream, - "Q\n"); - - return status; -} - -static cairo_status_t -_cairo_type3_glyph_surface_emit_image_pattern (cairo_type3_glyph_surface_t *surface, - cairo_image_surface_t *image, - const cairo_matrix_t *pattern_matrix) -{ - cairo_matrix_t mat, upside_down; - cairo_status_t status; - - if (image->width == 0 || image->height == 0) - return CAIRO_STATUS_SUCCESS; - - mat = *pattern_matrix; - - /* Get the pattern space to user space matrix */ - status = cairo_matrix_invert (&mat); - - /* cairo_pattern_set_matrix ensures the matrix is invertible */ - assert (status == CAIRO_STATUS_SUCCESS); - - /* Make this a pattern space to Type 3 font space matrix */ - cairo_matrix_multiply (&mat, &mat, &surface->cairo_to_pdf); - - /* PDF images are in a 1 unit by 1 unit image space. Turn the 1 by - * 1 image upside down to convert to flip the Y-axis going from - * cairo to PDF. Then scale the image up to the required size. */ - cairo_matrix_scale (&mat, image->width, image->height); - cairo_matrix_init (&upside_down, 1, 0, 0, -1, 0, 1); - cairo_matrix_multiply (&mat, &upside_down, &mat); - - return _cairo_type3_glyph_surface_emit_image (surface, image, &mat); -} - -static cairo_status_t -_cairo_type3_glyph_surface_finish (void *abstract_surface) -{ - cairo_type3_glyph_surface_t *surface = abstract_surface; - - return _cairo_pdf_operators_fini (&surface->pdf_operators); -} - -static cairo_int_status_t -_cairo_type3_glyph_surface_paint (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - cairo_type3_glyph_surface_t *surface = abstract_surface; - const cairo_surface_pattern_t *pattern; - cairo_image_surface_t *image; - void *image_extra; - cairo_status_t status; - - if (source->type != CAIRO_PATTERN_TYPE_SURFACE) - return CAIRO_INT_STATUS_IMAGE_FALLBACK; - - status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); - if (unlikely (status)) - return status; - - pattern = (const cairo_surface_pattern_t *) source; - status = _cairo_surface_acquire_source_image (pattern->surface, - &image, &image_extra); - if (unlikely (status)) - goto fail; - - status = _cairo_type3_glyph_surface_emit_image_pattern (surface, - image, - &pattern->base.matrix); - -fail: - _cairo_surface_release_source_image (pattern->surface, image, image_extra); - - return status; -} - -static cairo_int_status_t -_cairo_type3_glyph_surface_mask (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - return _cairo_type3_glyph_surface_paint (abstract_surface, - op, mask, - clip); -} - -static cairo_int_status_t -_cairo_type3_glyph_surface_stroke (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_type3_glyph_surface_t *surface = abstract_surface; - cairo_int_status_t status; - - status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); - if (unlikely (status)) - return status; - - return _cairo_pdf_operators_stroke (&surface->pdf_operators, - path, - style, - ctm, - ctm_inverse); -} - -static cairo_int_status_t -_cairo_type3_glyph_surface_fill (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_type3_glyph_surface_t *surface = abstract_surface; - cairo_int_status_t status; - - status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); - if (unlikely (status)) - return status; - - return _cairo_pdf_operators_fill (&surface->pdf_operators, - path, - fill_rule); -} - -static cairo_int_status_t -_cairo_type3_glyph_surface_show_glyphs (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - cairo_type3_glyph_surface_t *surface = abstract_surface; - cairo_int_status_t status; - cairo_scaled_font_t *font; - cairo_matrix_t new_ctm, invert_y_axis; - - status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); - if (unlikely (status)) - return status; - - cairo_matrix_init_scale (&invert_y_axis, 1, -1); - cairo_matrix_multiply (&new_ctm, &invert_y_axis, &scaled_font->ctm); - cairo_matrix_multiply (&new_ctm, &surface->cairo_to_pdf, &new_ctm); - font = cairo_scaled_font_create (scaled_font->font_face, - &scaled_font->font_matrix, - &new_ctm, - &scaled_font->options); - if (unlikely (font->status)) - return font->status; - - status = _cairo_pdf_operators_show_text_glyphs (&surface->pdf_operators, - NULL, 0, - glyphs, num_glyphs, - NULL, 0, - FALSE, - font); - - cairo_scaled_font_destroy (font); - - return status; -} - -static const cairo_surface_backend_t cairo_type3_glyph_surface_backend = { - CAIRO_INTERNAL_SURFACE_TYPE_TYPE3_GLYPH, - _cairo_type3_glyph_surface_finish, - - _cairo_default_context_create, /* XXX usable through a context? */ - - NULL, /* create similar */ - NULL, /* create similar image */ - NULL, /* map to image */ - NULL, /* unmap image */ - - NULL, /* source */ - NULL, /* acquire_source_image */ - NULL, /* release_source_image */ - NULL, /* snapshot */ - - NULL, /* copy page */ - NULL, /* show page */ - - NULL, /* _cairo_type3_glyph_surface_get_extents */ - NULL, /* _cairo_type3_glyph_surface_get_font_options */ - - NULL, /* flush */ - NULL, /* mark_dirty_rectangle */ - - _cairo_type3_glyph_surface_paint, - _cairo_type3_glyph_surface_mask, - _cairo_type3_glyph_surface_stroke, - _cairo_type3_glyph_surface_fill, - NULL, /* fill-stroke */ - _cairo_type3_glyph_surface_show_glyphs, -}; - -static void -_cairo_type3_glyph_surface_set_stream (cairo_type3_glyph_surface_t *surface, - cairo_output_stream_t *stream) -{ - surface->stream = stream; - _cairo_pdf_operators_set_stream (&surface->pdf_operators, stream); -} - -static cairo_status_t -_cairo_type3_glyph_surface_emit_fallback_image (cairo_type3_glyph_surface_t *surface, - unsigned long glyph_index) -{ - cairo_scaled_glyph_t *scaled_glyph; - cairo_status_t status; - cairo_image_surface_t *image; - cairo_matrix_t mat; - double x, y; - - status = _cairo_scaled_glyph_lookup (surface->scaled_font, - glyph_index, - CAIRO_SCALED_GLYPH_INFO_METRICS | - CAIRO_SCALED_GLYPH_INFO_SURFACE, - &scaled_glyph); - if (unlikely (status)) - return status; - - image = scaled_glyph->surface; - if (image->width == 0 || image->height == 0) - return CAIRO_STATUS_SUCCESS; - - x = _cairo_fixed_to_double (scaled_glyph->bbox.p1.x); - y = _cairo_fixed_to_double (scaled_glyph->bbox.p2.y); - mat.xx = image->width; - mat.xy = 0; - mat.yx = 0; - mat.yy = image->height; - mat.x0 = x; - mat.y0 = y; - cairo_matrix_multiply (&mat, &mat, &surface->scaled_font->scale_inverse); - mat.y0 *= -1; - - return _cairo_type3_glyph_surface_emit_image (surface, image, &mat); -} - -void -_cairo_type3_glyph_surface_set_font_subsets_callback (void *abstract_surface, - cairo_pdf_operators_use_font_subset_t use_font_subset, - void *closure) -{ - cairo_type3_glyph_surface_t *surface = abstract_surface; - - if (unlikely (surface->base.status)) - return; - - _cairo_pdf_operators_set_font_subsets_callback (&surface->pdf_operators, - use_font_subset, - closure); -} - -cairo_status_t -_cairo_type3_glyph_surface_analyze_glyph (void *abstract_surface, - unsigned long glyph_index) -{ - cairo_type3_glyph_surface_t *surface = abstract_surface; - cairo_scaled_glyph_t *scaled_glyph; - cairo_int_status_t status, status2; - cairo_output_stream_t *null_stream; - - if (unlikely (surface->base.status)) - return surface->base.status; - - null_stream = _cairo_null_stream_create (); - if (unlikely (null_stream->status)) - return null_stream->status; - - _cairo_type3_glyph_surface_set_stream (surface, null_stream); - - _cairo_scaled_font_freeze_cache (surface->scaled_font); - status = _cairo_scaled_glyph_lookup (surface->scaled_font, - glyph_index, - CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE, - &scaled_glyph); - - if (_cairo_int_status_is_error (status)) - goto cleanup; - - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - status = CAIRO_INT_STATUS_SUCCESS; - goto cleanup; - } - - status = _cairo_recording_surface_replay (scaled_glyph->recording_surface, - &surface->base); - if (unlikely (status)) - goto cleanup; - - status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK) - status = CAIRO_INT_STATUS_SUCCESS; - -cleanup: - _cairo_scaled_font_thaw_cache (surface->scaled_font); - - status2 = _cairo_output_stream_destroy (null_stream); - if (status == CAIRO_INT_STATUS_SUCCESS) - status = status2; - - return status; -} - -cairo_status_t -_cairo_type3_glyph_surface_emit_glyph (void *abstract_surface, - cairo_output_stream_t *stream, - unsigned long glyph_index, - cairo_box_t *bbox, - double *width) -{ - cairo_type3_glyph_surface_t *surface = abstract_surface; - cairo_scaled_glyph_t *scaled_glyph; - cairo_int_status_t status, status2; - double x_advance, y_advance; - cairo_matrix_t font_matrix_inverse; - - if (unlikely (surface->base.status)) - return surface->base.status; - - _cairo_type3_glyph_surface_set_stream (surface, stream); - - _cairo_scaled_font_freeze_cache (surface->scaled_font); - status = _cairo_scaled_glyph_lookup (surface->scaled_font, - glyph_index, - CAIRO_SCALED_GLYPH_INFO_METRICS | - CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE, - &scaled_glyph); - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - status = _cairo_scaled_glyph_lookup (surface->scaled_font, - glyph_index, - CAIRO_SCALED_GLYPH_INFO_METRICS, - &scaled_glyph); - if (status == CAIRO_INT_STATUS_SUCCESS) - status = CAIRO_INT_STATUS_IMAGE_FALLBACK; - } - if (_cairo_int_status_is_error (status)) { - _cairo_scaled_font_thaw_cache (surface->scaled_font); - return status; - } - - x_advance = scaled_glyph->metrics.x_advance; - y_advance = scaled_glyph->metrics.y_advance; - font_matrix_inverse = surface->scaled_font->font_matrix; - status2 = cairo_matrix_invert (&font_matrix_inverse); - - /* The invertability of font_matrix is tested in - * pdf_operators_show_glyphs before any glyphs are mapped to the - * subset. */ - assert (status2 == CAIRO_INT_STATUS_SUCCESS); - - cairo_matrix_transform_distance (&font_matrix_inverse, &x_advance, &y_advance); - *width = x_advance; - - *bbox = scaled_glyph->bbox; - _cairo_matrix_transform_bounding_box_fixed (&surface->scaled_font->scale_inverse, - bbox, NULL); - - _cairo_output_stream_printf (surface->stream, - "%f 0 %f %f %f %f d1\n", - x_advance, - _cairo_fixed_to_double (bbox->p1.x), - - _cairo_fixed_to_double (bbox->p2.y), - _cairo_fixed_to_double (bbox->p2.x), - - _cairo_fixed_to_double (bbox->p1.y)); - - if (status == CAIRO_INT_STATUS_SUCCESS) { - cairo_output_stream_t *mem_stream; - - mem_stream = _cairo_memory_stream_create (); - status = mem_stream->status; - if (unlikely (status)) - goto FAIL; - - _cairo_type3_glyph_surface_set_stream (surface, mem_stream); - - _cairo_output_stream_printf (surface->stream, "q\n"); - status = _cairo_recording_surface_replay (scaled_glyph->recording_surface, - &surface->base); - - status2 = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (status == CAIRO_INT_STATUS_SUCCESS) - status = status2; - - _cairo_output_stream_printf (surface->stream, "Q\n"); - - _cairo_type3_glyph_surface_set_stream (surface, stream); - if (status == CAIRO_INT_STATUS_SUCCESS) - _cairo_memory_stream_copy (mem_stream, stream); - - status2 = _cairo_output_stream_destroy (mem_stream); - if (status == CAIRO_INT_STATUS_SUCCESS) - status = status2; - } - - if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK) - status = _cairo_type3_glyph_surface_emit_fallback_image (surface, glyph_index); - - FAIL: - _cairo_scaled_font_thaw_cache (surface->scaled_font); - - return status; -} - -#endif /* CAIRO_HAS_FONT_SUBSET */ diff --git a/source/libs/cairo/cairo-src/src/cairo-types-private.h b/source/libs/cairo/cairo-src/src/cairo-types-private.h deleted file mode 100644 index 3d15d968e4bca357c632b0afa89068d9f8f7f330..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-types-private.h +++ /dev/null @@ -1,429 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - */ - -#ifndef CAIRO_TYPES_PRIVATE_H -#define CAIRO_TYPES_PRIVATE_H - -#include "cairo.h" -#include "cairo-fixed-type-private.h" -#include "cairo-list-private.h" -#include "cairo-reference-count-private.h" - -CAIRO_BEGIN_DECLS - -/** - * SECTION:cairo-types - * @Title: Types - * @Short_Description: Generic data types - * - * This section lists generic data types used in the cairo API. - **/ - -typedef struct _cairo_array cairo_array_t; -typedef struct _cairo_backend cairo_backend_t; -typedef struct _cairo_boxes_t cairo_boxes_t; -typedef struct _cairo_cache cairo_cache_t; -typedef struct _cairo_composite_rectangles cairo_composite_rectangles_t; -typedef struct _cairo_clip cairo_clip_t; -typedef struct _cairo_clip_path cairo_clip_path_t; -typedef struct _cairo_color cairo_color_t; -typedef struct _cairo_color_stop cairo_color_stop_t; -typedef struct _cairo_contour cairo_contour_t; -typedef struct _cairo_contour_chain cairo_contour_chain_t; -typedef struct _cairo_contour_iter cairo_contour_iter_t; -typedef struct _cairo_damage cairo_damage_t; -typedef struct _cairo_device_backend cairo_device_backend_t; -typedef struct _cairo_font_face_backend cairo_font_face_backend_t; -typedef struct _cairo_gstate cairo_gstate_t; -typedef struct _cairo_gstate_backend cairo_gstate_backend_t; -typedef struct _cairo_glyph_text_info cairo_glyph_text_info_t; -typedef struct _cairo_hash_entry cairo_hash_entry_t; -typedef struct _cairo_hash_table cairo_hash_table_t; -typedef struct _cairo_image_surface cairo_image_surface_t; -typedef struct _cairo_mime_data cairo_mime_data_t; -typedef struct _cairo_observer cairo_observer_t; -typedef struct _cairo_output_stream cairo_output_stream_t; -typedef struct _cairo_paginated_surface_backend cairo_paginated_surface_backend_t; -typedef struct _cairo_path_fixed cairo_path_fixed_t; -typedef struct _cairo_rectangle_int16 cairo_glyph_size_t; -typedef struct _cairo_scaled_font_subsets cairo_scaled_font_subsets_t; -typedef struct _cairo_solid_pattern cairo_solid_pattern_t; -typedef struct _cairo_surface_attributes cairo_surface_attributes_t; -typedef struct _cairo_surface_backend cairo_surface_backend_t; -typedef struct _cairo_surface_observer cairo_surface_observer_t; -typedef struct _cairo_surface_snapshot cairo_surface_snapshot_t; -typedef struct _cairo_surface_subsurface cairo_surface_subsurface_t; -typedef struct _cairo_surface_wrapper cairo_surface_wrapper_t; -typedef struct _cairo_traps cairo_traps_t; -typedef struct _cairo_tristrip cairo_tristrip_t; -typedef struct _cairo_unscaled_font_backend cairo_unscaled_font_backend_t; -typedef struct _cairo_xlib_screen_info cairo_xlib_screen_info_t; - -typedef cairo_array_t cairo_user_data_array_t; - -typedef struct _cairo_scaled_font_private cairo_scaled_font_private_t; -typedef struct _cairo_scaled_font_backend cairo_scaled_font_backend_t; -typedef struct _cairo_scaled_glyph cairo_scaled_glyph_t; -typedef struct _cairo_scaled_glyph_private cairo_scaled_glyph_private_t; - -typedef struct cairo_compositor cairo_compositor_t; -typedef struct cairo_fallback_compositor cairo_fallback_compositor_t; -typedef struct cairo_mask_compositor cairo_mask_compositor_t; -typedef struct cairo_traps_compositor cairo_traps_compositor_t; -typedef struct cairo_spans_compositor cairo_spans_compositor_t; - -struct _cairo_observer { - cairo_list_t link; - void (*callback) (cairo_observer_t *self, void *arg); -}; - -/** - * _cairo_hash_entry: - * - * A #cairo_hash_entry_t contains both a key and a value for - * #cairo_hash_table_t. User-derived types for #cairo_hash_entry_t must - * be type-compatible with this structure (eg. they must have an - * unsigned long as the first parameter. The easiest way to get this - * is to use: - * - * typedef _my_entry { - * cairo_hash_entry_t base; - * ... Remainder of key and value fields here .. - * } my_entry_t; - * - * which then allows a pointer to my_entry_t to be passed to any of - * the #cairo_hash_table_t functions as follows without requiring a cast: - * - * _cairo_hash_table_insert (hash_table, &my_entry->base); - * - * IMPORTANT: The caller is responsible for initializing - * my_entry->base.hash with a hash code derived from the key. The - * essential property of the hash code is that keys_equal must never - * return %TRUE for two keys that have different hashes. The best hash - * code will reduce the frequency of two keys with the same code for - * which keys_equal returns %FALSE. - * - * Which parts of the entry make up the "key" and which part make up - * the value are entirely up to the caller, (as determined by the - * computation going into base.hash as well as the keys_equal - * function). A few of the #cairo_hash_table_t functions accept an entry - * which will be used exclusively as a "key", (indicated by a - * parameter name of key). In these cases, the value-related fields of - * the entry need not be initialized if so desired. - **/ -struct _cairo_hash_entry { - unsigned long hash; -}; - -struct _cairo_array { - unsigned int size; - unsigned int num_elements; - unsigned int element_size; - char *elements; -}; - -/** - * _cairo_lcd_filter: - * @CAIRO_LCD_FILTER_DEFAULT: Use the default LCD filter for - * font backend and target device - * @CAIRO_LCD_FILTER_NONE: Do not perform LCD filtering - * @CAIRO_LCD_FILTER_INTRA_PIXEL: Intra-pixel filter - * @CAIRO_LCD_FILTER_FIR3: FIR filter with a 3x3 kernel - * @CAIRO_LCD_FILTER_FIR5: FIR filter with a 5x5 kernel - * - * The LCD filter specifies the low-pass filter applied to LCD-optimized - * bitmaps generated with an antialiasing mode of %CAIRO_ANTIALIAS_SUBPIXEL. - * - * Note: This API was temporarily made available in the public - * interface during the 1.7.x development series, but was made private - * before 1.8. - **/ -typedef enum _cairo_lcd_filter { - CAIRO_LCD_FILTER_DEFAULT, - CAIRO_LCD_FILTER_NONE, - CAIRO_LCD_FILTER_INTRA_PIXEL, - CAIRO_LCD_FILTER_FIR3, - CAIRO_LCD_FILTER_FIR5 -} cairo_lcd_filter_t; - -typedef enum _cairo_round_glyph_positions { - CAIRO_ROUND_GLYPH_POS_DEFAULT, - CAIRO_ROUND_GLYPH_POS_ON, - CAIRO_ROUND_GLYPH_POS_OFF -} cairo_round_glyph_positions_t; - -struct _cairo_font_options { - cairo_antialias_t antialias; - cairo_subpixel_order_t subpixel_order; - cairo_lcd_filter_t lcd_filter; - cairo_hint_style_t hint_style; - cairo_hint_metrics_t hint_metrics; - cairo_round_glyph_positions_t round_glyph_positions; -}; - -struct _cairo_glyph_text_info { - const char *utf8; - int utf8_len; - - const cairo_text_cluster_t *clusters; - int num_clusters; - cairo_text_cluster_flags_t cluster_flags; -}; - - -/* XXX: Right now, the _cairo_color structure puts unpremultiplied - color in the doubles and premultiplied color in the shorts. Yes, - this is crazy insane, (but at least we don't export this - madness). I'm still working on a cleaner API, but in the meantime, - at least this does prevent precision loss in color when changing - alpha. */ -struct _cairo_color { - double red; - double green; - double blue; - double alpha; - - unsigned short red_short; - unsigned short green_short; - unsigned short blue_short; - unsigned short alpha_short; -}; - -struct _cairo_color_stop { - /* unpremultiplied */ - double red; - double green; - double blue; - double alpha; - - /* unpremultipled, for convenience */ - uint16_t red_short; - uint16_t green_short; - uint16_t blue_short; - uint16_t alpha_short; -}; - -typedef enum _cairo_paginated_mode { - CAIRO_PAGINATED_MODE_ANALYZE, /* analyze page regions */ - CAIRO_PAGINATED_MODE_RENDER, /* render page contents */ - CAIRO_PAGINATED_MODE_FALLBACK /* paint fallback images */ -} cairo_paginated_mode_t; - -typedef enum _cairo_internal_surface_type { - CAIRO_INTERNAL_SURFACE_TYPE_SNAPSHOT = 0x1000, - CAIRO_INTERNAL_SURFACE_TYPE_PAGINATED, - CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS, - CAIRO_INTERNAL_SURFACE_TYPE_OBSERVER, - CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK, - CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED, - CAIRO_INTERNAL_SURFACE_TYPE_TEST_WRAPPING, - CAIRO_INTERNAL_SURFACE_TYPE_NULL, - CAIRO_INTERNAL_SURFACE_TYPE_TYPE3_GLYPH -} cairo_internal_surface_type_t; - -typedef enum _cairo_internal_device_type { - CAIRO_INTERNAL_DEVICE_TYPE_OBSERVER = 0x1000, -} cairo_device_surface_type_t; - -#define CAIRO_HAS_TEST_PAGINATED_SURFACE 1 - -typedef struct _cairo_slope { - cairo_fixed_t dx; - cairo_fixed_t dy; -} cairo_slope_t, cairo_distance_t; - -typedef struct _cairo_point_double { - double x; - double y; -} cairo_point_double_t; - -typedef struct _cairo_circle_double { - cairo_point_double_t center; - double radius; -} cairo_circle_double_t; - -typedef struct _cairo_distance_double { - double dx; - double dy; -} cairo_distance_double_t; - -typedef struct _cairo_box_double { - cairo_point_double_t p1; - cairo_point_double_t p2; -} cairo_box_double_t; - -typedef struct _cairo_line { - cairo_point_t p1; - cairo_point_t p2; -} cairo_line_t, cairo_box_t; - -typedef struct _cairo_trapezoid { - cairo_fixed_t top, bottom; - cairo_line_t left, right; -} cairo_trapezoid_t; - -typedef struct _cairo_point_int { - int x, y; -} cairo_point_int_t; - -#define CAIRO_RECT_INT_MIN (INT_MIN >> CAIRO_FIXED_FRAC_BITS) -#define CAIRO_RECT_INT_MAX (INT_MAX >> CAIRO_FIXED_FRAC_BITS) - -typedef enum _cairo_direction { - CAIRO_DIRECTION_FORWARD, - CAIRO_DIRECTION_REVERSE -} cairo_direction_t; - -typedef struct _cairo_edge { - cairo_line_t line; - int top, bottom; - int dir; -} cairo_edge_t; - -typedef struct _cairo_polygon { - cairo_status_t status; - - cairo_box_t extents; - cairo_box_t limit; - const cairo_box_t *limits; - int num_limits; - - int num_edges; - int edges_size; - cairo_edge_t *edges; - cairo_edge_t edges_embedded[32]; -} cairo_polygon_t; - -typedef cairo_warn cairo_status_t -(*cairo_spline_add_point_func_t) (void *closure, - const cairo_point_t *point, - const cairo_slope_t *tangent); - -typedef struct _cairo_spline_knots { - cairo_point_t a, b, c, d; -} cairo_spline_knots_t; - -typedef struct _cairo_spline { - cairo_spline_add_point_func_t add_point_func; - void *closure; - - cairo_spline_knots_t knots; - - cairo_slope_t initial_slope; - cairo_slope_t final_slope; - - cairo_bool_t has_point; - cairo_point_t last_point; -} cairo_spline_t; - -typedef struct _cairo_pen_vertex { - cairo_point_t point; - - cairo_slope_t slope_ccw; - cairo_slope_t slope_cw; -} cairo_pen_vertex_t; - -typedef struct _cairo_pen { - double radius; - double tolerance; - - int num_vertices; - cairo_pen_vertex_t *vertices; - cairo_pen_vertex_t vertices_embedded[32]; -} cairo_pen_t; - -typedef struct _cairo_stroke_style { - double line_width; - cairo_line_cap_t line_cap; - cairo_line_join_t line_join; - double miter_limit; - double *dash; - unsigned int num_dashes; - double dash_offset; -} cairo_stroke_style_t; - -typedef struct _cairo_format_masks { - int bpp; - unsigned long alpha_mask; - unsigned long red_mask; - unsigned long green_mask; - unsigned long blue_mask; -} cairo_format_masks_t; - -typedef enum { - CAIRO_STOCK_WHITE, - CAIRO_STOCK_BLACK, - CAIRO_STOCK_TRANSPARENT, - CAIRO_STOCK_NUM_COLORS, -} cairo_stock_t; - -typedef enum _cairo_image_transparency { - CAIRO_IMAGE_IS_OPAQUE, - CAIRO_IMAGE_HAS_BILEVEL_ALPHA, - CAIRO_IMAGE_HAS_ALPHA, - CAIRO_IMAGE_UNKNOWN -} cairo_image_transparency_t; - -typedef enum _cairo_image_color { - CAIRO_IMAGE_IS_COLOR, - CAIRO_IMAGE_IS_GRAYSCALE, - CAIRO_IMAGE_IS_MONOCHROME, - CAIRO_IMAGE_UNKNOWN_COLOR -} cairo_image_color_t; - - -struct _cairo_mime_data { - cairo_reference_count_t ref_count; - unsigned char *data; - unsigned long length; - cairo_destroy_func_t destroy; - void *closure; -}; - -/* - * A #cairo_unscaled_font_t is just an opaque handle we use in the - * glyph cache. - */ -typedef struct _cairo_unscaled_font { - cairo_hash_entry_t hash_entry; - cairo_reference_count_t ref_count; - const cairo_unscaled_font_backend_t *backend; -} cairo_unscaled_font_t; -CAIRO_END_DECLS - -#endif /* CAIRO_TYPES_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-unicode.c b/source/libs/cairo/cairo-src/src/cairo-unicode.c deleted file mode 100644 index 88de39516b6cbafe113b2bd46d4897dee01defcd..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-unicode.c +++ /dev/null @@ -1,422 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * The code in this file is derived from GLib's gutf8.c and - * ultimately from libunicode. It is relicensed under the - * dual LGPL/MPL with permission of the original authors. - * - * Copyright © 1999 Tom Tromey - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Tom Tromey. - * and Red Hat, Inc. - * - * Contributor(s): - * Owen Taylor <otaylor@redhat.com> - */ - -#include "cairoint.h" -#include "cairo-error-private.h" - -#define UTF8_COMPUTE(Char, Mask, Len) \ - if (Char < 128) \ - { \ - Len = 1; \ - Mask = 0x7f; \ - } \ - else if ((Char & 0xe0) == 0xc0) \ - { \ - Len = 2; \ - Mask = 0x1f; \ - } \ - else if ((Char & 0xf0) == 0xe0) \ - { \ - Len = 3; \ - Mask = 0x0f; \ - } \ - else if ((Char & 0xf8) == 0xf0) \ - { \ - Len = 4; \ - Mask = 0x07; \ - } \ - else if ((Char & 0xfc) == 0xf8) \ - { \ - Len = 5; \ - Mask = 0x03; \ - } \ - else if ((Char & 0xfe) == 0xfc) \ - { \ - Len = 6; \ - Mask = 0x01; \ - } \ - else \ - Len = -1; - -#define UTF8_LENGTH(Char) \ - ((Char) < 0x80 ? 1 : \ - ((Char) < 0x800 ? 2 : \ - ((Char) < 0x10000 ? 3 : \ - ((Char) < 0x200000 ? 4 : \ - ((Char) < 0x4000000 ? 5 : 6))))) - -#define UTF8_GET(Result, Chars, Count, Mask, Len) \ - (Result) = (Chars)[0] & (Mask); \ - for ((Count) = 1; (Count) < (Len); ++(Count)) \ - { \ - if (((Chars)[(Count)] & 0xc0) != 0x80) \ - { \ - (Result) = -1; \ - break; \ - } \ - (Result) <<= 6; \ - (Result) |= ((Chars)[(Count)] & 0x3f); \ - } - -#define UNICODE_VALID(Char) \ - ((Char) < 0x110000 && \ - (((Char) & 0xFFFFF800) != 0xD800) && \ - ((Char) < 0xFDD0 || (Char) > 0xFDEF) && \ - ((Char) & 0xFFFE) != 0xFFFE) - -static const char utf8_skip_data[256] = { - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1 -}; - -#define UTF8_NEXT_CHAR(p) ((p) + utf8_skip_data[*(unsigned char *)(p)]) - -/* Converts a sequence of bytes encoded as UTF-8 to a Unicode character. - * If @p does not point to a valid UTF-8 encoded character, results are - * undefined. - **/ -static uint32_t -_utf8_get_char (const unsigned char *p) -{ - int i, mask = 0, len; - uint32_t result; - unsigned char c = (unsigned char) *p; - - UTF8_COMPUTE (c, mask, len); - if (len == -1) - return (uint32_t)-1; - UTF8_GET (result, p, i, mask, len); - - return result; -} - -/* Like _utf8_get_char, but take a maximum length - * and return (uint32_t)-2 on incomplete trailing character - */ -static uint32_t -_utf8_get_char_extended (const unsigned char *p, - long max_len) -{ - int i, len; - uint32_t wc = (unsigned char) *p; - - if (wc < 0x80) { - return wc; - } else if (wc < 0xc0) { - return (uint32_t)-1; - } else if (wc < 0xe0) { - len = 2; - wc &= 0x1f; - } else if (wc < 0xf0) { - len = 3; - wc &= 0x0f; - } else if (wc < 0xf8) { - len = 4; - wc &= 0x07; - } else if (wc < 0xfc) { - len = 5; - wc &= 0x03; - } else if (wc < 0xfe) { - len = 6; - wc &= 0x01; - } else { - return (uint32_t)-1; - } - - if (max_len >= 0 && len > max_len) { - for (i = 1; i < max_len; i++) { - if ((((unsigned char *)p)[i] & 0xc0) != 0x80) - return (uint32_t)-1; - } - return (uint32_t)-2; - } - - for (i = 1; i < len; ++i) { - uint32_t ch = ((unsigned char *)p)[i]; - - if ((ch & 0xc0) != 0x80) { - if (ch) - return (uint32_t)-1; - else - return (uint32_t)-2; - } - - wc <<= 6; - wc |= (ch & 0x3f); - } - - if (UTF8_LENGTH(wc) != len) - return (uint32_t)-1; - - return wc; -} - -/** - * _cairo_utf8_get_char_validated: - * @p: a UTF-8 string - * @unicode: location to store one Unicode character - * - * Decodes the first character of a valid UTF-8 string, and returns - * the number of bytes consumed. - * - * Note that the string should be valid. Do not use this without - * validating the string first. - * - * Returns: the number of bytes forming the character returned. - **/ -int -_cairo_utf8_get_char_validated (const char *p, - uint32_t *unicode) -{ - int i, mask = 0, len; - uint32_t result; - unsigned char c = (unsigned char) *p; - - UTF8_COMPUTE (c, mask, len); - if (len == -1) { - if (unicode) - *unicode = (uint32_t)-1; - return 1; - } - UTF8_GET (result, p, i, mask, len); - - if (unicode) - *unicode = result; - return len; -} - -/** - * _cairo_utf8_to_ucs4: - * @str: an UTF-8 string - * @len: length of @str in bytes, or -1 if it is nul-terminated. - * If @len is supplied and the string has an embedded nul - * byte, only the portion before the nul byte is converted. - * @result: location to store a pointer to a newly allocated UTF-32 - * string (always native endian), or %NULL. Free with free(). A 0 - * word will be written after the last character. - * @items_written: location to store number of 32-bit words - * written. (Not including the trailing 0) - * - * Converts a UTF-8 string to UCS-4. UCS-4 is an encoding of Unicode - * with 1 32-bit word per character. The string is validated to - * consist entirely of valid Unicode characters. - * - * Return value: %CAIRO_STATUS_SUCCESS if the entire string was - * successfully converted. %CAIRO_STATUS_INVALID_STRING if an - * invalid sequence was found. - **/ -cairo_status_t -_cairo_utf8_to_ucs4 (const char *str, - int len, - uint32_t **result, - int *items_written) -{ - uint32_t *str32 = NULL; - int n_chars, i; - const unsigned char *in; - const unsigned char * const ustr = (const unsigned char *) str; - - in = ustr; - n_chars = 0; - while ((len < 0 || ustr + len - in > 0) && *in) - { - uint32_t wc = _utf8_get_char_extended (in, ustr + len - in); - if (wc & 0x80000000 || !UNICODE_VALID (wc)) - return _cairo_error (CAIRO_STATUS_INVALID_STRING); - - n_chars++; - if (n_chars == INT_MAX) - return _cairo_error (CAIRO_STATUS_INVALID_STRING); - - in = UTF8_NEXT_CHAR (in); - } - - if (result) { - str32 = _cairo_malloc_ab (n_chars + 1, sizeof (uint32_t)); - if (!str32) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - in = ustr; - for (i=0; i < n_chars; i++) { - str32[i] = _utf8_get_char (in); - in = UTF8_NEXT_CHAR (in); - } - str32[i] = 0; - - *result = str32; - } - - if (items_written) - *items_written = n_chars; - - return CAIRO_STATUS_SUCCESS; -} - -/** - * _cairo_ucs4_to_utf8: - * @unicode: a UCS-4 character - * @utf8: buffer to write utf8 string into. Must have at least 4 bytes - * space available. Or %NULL. - * - * This space left intentionally blank. - * - * Return value: Number of bytes in the utf8 string or 0 if an invalid - * unicode character - **/ -int -_cairo_ucs4_to_utf8 (uint32_t unicode, - char *utf8) -{ - int bytes; - char *p; - - if (unicode < 0x80) { - if (utf8) - *utf8 = unicode; - return 1; - } else if (unicode < 0x800) { - bytes = 2; - } else if (unicode < 0x10000) { - bytes = 3; - } else if (unicode < 0x200000) { - bytes = 4; - } else { - return 0; - } - - if (!utf8) - return bytes; - - p = utf8 + bytes; - while (p > utf8) { - *--p = 0x80 | (unicode & 0x3f); - unicode >>= 6; - } - *p |= 0xf0 << (4 - bytes); - - return bytes; -} - -#if CAIRO_HAS_UTF8_TO_UTF16 -/** - * _cairo_utf8_to_utf16: - * @str: an UTF-8 string - * @len: length of @str in bytes, or -1 if it is nul-terminated. - * If @len is supplied and the string has an embedded nul - * byte, only the portion before the nul byte is converted. - * @result: location to store a pointer to a newly allocated UTF-16 - * string (always native endian). Free with free(). A 0 - * word will be written after the last character. - * @items_written: location to store number of 16-bit words - * written. (Not including the trailing 0) - * - * Converts a UTF-8 string to UTF-16. UTF-16 is an encoding of Unicode - * where characters are represented either as a single 16-bit word, or - * as a pair of 16-bit "surrogates". The string is validated to - * consist entirely of valid Unicode characters. - * - * Return value: %CAIRO_STATUS_SUCCESS if the entire string was - * successfully converted. %CAIRO_STATUS_INVALID_STRING if an - * an invalid sequence was found. - **/ -cairo_status_t -_cairo_utf8_to_utf16 (const char *str, - int len, - uint16_t **result, - int *items_written) -{ - uint16_t *str16 = NULL; - int n16, i; - const unsigned char *in; - const unsigned char * const ustr = (const unsigned char *) str; - - in = ustr; - n16 = 0; - while ((len < 0 || ustr + len - in > 0) && *in) { - uint32_t wc = _utf8_get_char_extended (in, ustr + len - in); - if (wc & 0x80000000 || !UNICODE_VALID (wc)) - return _cairo_error (CAIRO_STATUS_INVALID_STRING); - - if (wc < 0x10000) - n16 += 1; - else - n16 += 2; - - if (n16 == INT_MAX - 1 || n16 == INT_MAX) - return _cairo_error (CAIRO_STATUS_INVALID_STRING); - - in = UTF8_NEXT_CHAR (in); - } - - str16 = _cairo_malloc_ab (n16 + 1, sizeof (uint16_t)); - if (!str16) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - in = ustr; - for (i = 0; i < n16;) { - uint32_t wc = _utf8_get_char (in); - - if (wc < 0x10000) { - str16[i++] = wc; - } else { - str16[i++] = (wc - 0x10000) / 0x400 + 0xd800; - str16[i++] = (wc - 0x10000) % 0x400 + 0xdc00; - } - - in = UTF8_NEXT_CHAR (in); - } - - str16[i] = 0; - - *result = str16; - if (items_written) - *items_written = n16; - - return CAIRO_STATUS_SUCCESS; -} -#endif diff --git a/source/libs/cairo/cairo-src/src/cairo-uninstalled.pc.in b/source/libs/cairo/cairo-src/src/cairo-uninstalled.pc.in deleted file mode 100644 index 9dc3231ae45fabbe91add945785c4fd0a9e705a5..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-uninstalled.pc.in +++ /dev/null @@ -1,8 +0,0 @@ -Name: cairo -Description: Multi-platform 2D graphics library -Version: @VERSION@ - -@PKGCONFIG_REQUIRES@: @CAIRO_REQUIRES@ -Libs: ${pc_top_builddir}/${pcfiledir}/src/libcairo.la -Libs.private: @CAIRO_NONPKGCONFIG_LIBS@ -Cflags: -I${pc_top_builddir}/${pcfiledir}/@srcdir@/src diff --git a/source/libs/cairo/cairo-src/src/cairo-user-font-private.h b/source/libs/cairo/cairo-src/src/cairo-user-font-private.h deleted file mode 100644 index d54ef78b44e045d2ac23fce2c4bebee72de951fd..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-user-font-private.h +++ /dev/null @@ -1,46 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2006, 2008 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Kristian Høgsberg <krh@redhat.com> - * Behdad Esfahbod <behdad@behdad.org> - */ - -#ifndef CAIRO_USER_FONT_PRIVATE_H -#define CAIRO_USER_FONT_PRIVATE_H - -#include "cairo.h" -#include "cairo-compiler-private.h" - -cairo_private cairo_bool_t -_cairo_font_face_is_user (cairo_font_face_t *font_face); - -#endif /* CAIRO_USER_FONT_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-user-font.c b/source/libs/cairo/cairo-src/src/cairo-user-font.c deleted file mode 100644 index 6d2de2097d5039b69b27273d378ed2847b69d785..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-user-font.c +++ /dev/null @@ -1,831 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2006, 2008 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Kristian Høgsberg <krh@redhat.com> - * Behdad Esfahbod <behdad@behdad.org> - */ - -#include "cairoint.h" -#include "cairo-user-font-private.h" -#include "cairo-recording-surface-private.h" -#include "cairo-analysis-surface-private.h" -#include "cairo-error-private.h" - -/** - * SECTION:cairo-user-fonts - * @Title:User Fonts - * @Short_Description: Font support with font data provided by the user - * - * The user-font feature allows the cairo user to provide drawings for glyphs - * in a font. This is most useful in implementing fonts in non-standard - * formats, like SVG fonts and Flash fonts, but can also be used by games and - * other application to draw "funky" fonts. - **/ - -/** - * CAIRO_HAS_USER_FONT: - * - * Defined if the user font backend is available. - * This macro can be used to conditionally compile backend-specific code. - * The user font backend is always built in versions of cairo that support - * this feature (1.8 and later). - * - * Since: 1.8 - **/ - -typedef struct _cairo_user_scaled_font_methods { - cairo_user_scaled_font_init_func_t init; - cairo_user_scaled_font_render_glyph_func_t render_glyph; - cairo_user_scaled_font_unicode_to_glyph_func_t unicode_to_glyph; - cairo_user_scaled_font_text_to_glyphs_func_t text_to_glyphs; -} cairo_user_scaled_font_methods_t; - -typedef struct _cairo_user_font_face { - cairo_font_face_t base; - - /* Set to true after first scaled font is created. At that point, - * the scaled_font_methods cannot change anymore. */ - cairo_bool_t immutable; - - cairo_user_scaled_font_methods_t scaled_font_methods; -} cairo_user_font_face_t; - -typedef struct _cairo_user_scaled_font { - cairo_scaled_font_t base; - - cairo_text_extents_t default_glyph_extents; - - /* space to compute extents in, and factors to convert back to user space */ - cairo_matrix_t extent_scale; - double extent_x_scale; - double extent_y_scale; - - /* multiplier for metrics hinting */ - double snap_x_scale; - double snap_y_scale; - -} cairo_user_scaled_font_t; - -/* #cairo_user_scaled_font_t */ - -static cairo_surface_t * -_cairo_user_scaled_font_create_recording_surface (const cairo_user_scaled_font_t *scaled_font) -{ - cairo_content_t content; - - content = scaled_font->base.options.antialias == CAIRO_ANTIALIAS_SUBPIXEL ? - CAIRO_CONTENT_COLOR_ALPHA : - CAIRO_CONTENT_ALPHA; - - return cairo_recording_surface_create (content, NULL); -} - - -static cairo_t * -_cairo_user_scaled_font_create_recording_context (const cairo_user_scaled_font_t *scaled_font, - cairo_surface_t *recording_surface) -{ - cairo_t *cr; - - cr = cairo_create (recording_surface); - - if (!_cairo_matrix_is_scale_0 (&scaled_font->base.scale)) { - cairo_matrix_t scale; - scale = scaled_font->base.scale; - scale.x0 = scale.y0 = 0.; - cairo_set_matrix (cr, &scale); - } - - cairo_set_font_size (cr, 1.0); - cairo_set_font_options (cr, &scaled_font->base.options); - cairo_set_source_rgb (cr, 1., 1., 1.); - - return cr; -} - -static cairo_int_status_t -_cairo_user_scaled_glyph_init (void *abstract_font, - cairo_scaled_glyph_t *scaled_glyph, - cairo_scaled_glyph_info_t info) -{ - cairo_int_status_t status = CAIRO_STATUS_SUCCESS; - cairo_user_scaled_font_t *scaled_font = abstract_font; - cairo_surface_t *recording_surface = scaled_glyph->recording_surface; - - if (!scaled_glyph->recording_surface) { - cairo_user_font_face_t *face = - (cairo_user_font_face_t *) scaled_font->base.font_face; - cairo_text_extents_t extents = scaled_font->default_glyph_extents; - cairo_t *cr; - - if (!face->scaled_font_methods.render_glyph) - return CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED; - - recording_surface = _cairo_user_scaled_font_create_recording_surface (scaled_font); - - /* special case for 0 rank matrix (as in _cairo_scaled_font_init): empty surface */ - if (!_cairo_matrix_is_scale_0 (&scaled_font->base.scale)) { - cr = _cairo_user_scaled_font_create_recording_context (scaled_font, recording_surface); - status = face->scaled_font_methods.render_glyph ((cairo_scaled_font_t *)scaled_font, - _cairo_scaled_glyph_index(scaled_glyph), - cr, &extents); - if (status == CAIRO_INT_STATUS_SUCCESS) - status = cairo_status (cr); - - cairo_destroy (cr); - - if (unlikely (status)) { - cairo_surface_destroy (recording_surface); - return status; - } - } - - _cairo_scaled_glyph_set_recording_surface (scaled_glyph, - &scaled_font->base, - recording_surface); - - - /* set metrics */ - - if (extents.width == 0.) { - cairo_box_t bbox; - double x1, y1, x2, y2; - double x_scale, y_scale; - - /* Compute extents.x/y/width/height from recording_surface, - * in font space. - */ - status = _cairo_recording_surface_get_bbox ((cairo_recording_surface_t *) recording_surface, - &bbox, - &scaled_font->extent_scale); - if (unlikely (status)) - return status; - - _cairo_box_to_doubles (&bbox, &x1, &y1, &x2, &y2); - - x_scale = scaled_font->extent_x_scale; - y_scale = scaled_font->extent_y_scale; - extents.x_bearing = x1 * x_scale; - extents.y_bearing = y1 * y_scale; - extents.width = (x2 - x1) * x_scale; - extents.height = (y2 - y1) * y_scale; - } - - if (scaled_font->base.options.hint_metrics != CAIRO_HINT_METRICS_OFF) { - extents.x_advance = _cairo_lround (extents.x_advance / scaled_font->snap_x_scale) * scaled_font->snap_x_scale; - extents.y_advance = _cairo_lround (extents.y_advance / scaled_font->snap_y_scale) * scaled_font->snap_y_scale; - } - - _cairo_scaled_glyph_set_metrics (scaled_glyph, - &scaled_font->base, - &extents); - } - - if (info & CAIRO_SCALED_GLYPH_INFO_SURFACE) { - cairo_surface_t *surface; - cairo_format_t format; - int width, height; - - /* TODO - * extend the glyph cache to support argb glyphs. - * need to figure out the semantics and interaction with subpixel - * rendering first. - */ - - width = _cairo_fixed_integer_ceil (scaled_glyph->bbox.p2.x) - - _cairo_fixed_integer_floor (scaled_glyph->bbox.p1.x); - height = _cairo_fixed_integer_ceil (scaled_glyph->bbox.p2.y) - - _cairo_fixed_integer_floor (scaled_glyph->bbox.p1.y); - - switch (scaled_font->base.options.antialias) { - default: - case CAIRO_ANTIALIAS_DEFAULT: - case CAIRO_ANTIALIAS_FAST: - case CAIRO_ANTIALIAS_GOOD: - case CAIRO_ANTIALIAS_GRAY: format = CAIRO_FORMAT_A8; break; - case CAIRO_ANTIALIAS_NONE: format = CAIRO_FORMAT_A1; break; - case CAIRO_ANTIALIAS_BEST: - case CAIRO_ANTIALIAS_SUBPIXEL: format = CAIRO_FORMAT_ARGB32; break; - } - surface = cairo_image_surface_create (format, width, height); - - cairo_surface_set_device_offset (surface, - - _cairo_fixed_integer_floor (scaled_glyph->bbox.p1.x), - - _cairo_fixed_integer_floor (scaled_glyph->bbox.p1.y)); - status = _cairo_recording_surface_replay (recording_surface, surface); - - if (unlikely (status)) { - cairo_surface_destroy(surface); - return status; - } - - _cairo_scaled_glyph_set_surface (scaled_glyph, - &scaled_font->base, - (cairo_image_surface_t *) surface); - } - - if (info & CAIRO_SCALED_GLYPH_INFO_PATH) { - cairo_path_fixed_t *path = _cairo_path_fixed_create (); - if (!path) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - status = _cairo_recording_surface_get_path (recording_surface, path); - if (unlikely (status)) { - _cairo_path_fixed_destroy (path); - return status; - } - - _cairo_scaled_glyph_set_path (scaled_glyph, - &scaled_font->base, - path); - } - - return status; -} - -static unsigned long -_cairo_user_ucs4_to_index (void *abstract_font, - uint32_t ucs4) -{ - cairo_user_scaled_font_t *scaled_font = abstract_font; - cairo_user_font_face_t *face = - (cairo_user_font_face_t *) scaled_font->base.font_face; - unsigned long glyph = 0; - - if (face->scaled_font_methods.unicode_to_glyph) { - cairo_status_t status; - - status = face->scaled_font_methods.unicode_to_glyph (&scaled_font->base, - ucs4, &glyph); - - if (status == CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED) - goto not_implemented; - - if (status != CAIRO_STATUS_SUCCESS) { - status = _cairo_scaled_font_set_error (&scaled_font->base, status); - glyph = 0; - } - - } else { -not_implemented: - glyph = ucs4; - } - - return glyph; -} - -static cairo_int_status_t -_cairo_user_text_to_glyphs (void *abstract_font, - double x, - double y, - const char *utf8, - int utf8_len, - cairo_glyph_t **glyphs, - int *num_glyphs, - cairo_text_cluster_t **clusters, - int *num_clusters, - cairo_text_cluster_flags_t *cluster_flags) -{ - cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED; - - cairo_user_scaled_font_t *scaled_font = abstract_font; - cairo_user_font_face_t *face = - (cairo_user_font_face_t *) scaled_font->base.font_face; - - if (face->scaled_font_methods.text_to_glyphs) { - int i; - cairo_glyph_t *orig_glyphs = *glyphs; - int orig_num_glyphs = *num_glyphs; - - status = face->scaled_font_methods.text_to_glyphs (&scaled_font->base, - utf8, utf8_len, - glyphs, num_glyphs, - clusters, num_clusters, cluster_flags); - - if (status != CAIRO_INT_STATUS_SUCCESS && - status != CAIRO_INT_STATUS_USER_FONT_NOT_IMPLEMENTED) - return status; - - if (status == CAIRO_INT_STATUS_USER_FONT_NOT_IMPLEMENTED || - *num_glyphs < 0) { - if (orig_glyphs != *glyphs) { - cairo_glyph_free (*glyphs); - *glyphs = orig_glyphs; - } - *num_glyphs = orig_num_glyphs; - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - /* Convert from font space to user space and add x,y */ - for (i = 0; i < *num_glyphs; i++) { - double gx = (*glyphs)[i].x; - double gy = (*glyphs)[i].y; - - cairo_matrix_transform_point (&scaled_font->base.font_matrix, - &gx, &gy); - - (*glyphs)[i].x = gx + x; - (*glyphs)[i].y = gy + y; - } - } - - return status; -} - -static cairo_status_t -_cairo_user_font_face_scaled_font_create (void *abstract_face, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options, - cairo_scaled_font_t **scaled_font); - -static cairo_status_t -_cairo_user_font_face_create_for_toy (cairo_toy_font_face_t *toy_face, - cairo_font_face_t **font_face) -{ - return _cairo_font_face_twin_create_for_toy (toy_face, font_face); -} - -static const cairo_scaled_font_backend_t _cairo_user_scaled_font_backend = { - CAIRO_FONT_TYPE_USER, - NULL, /* scaled_font_fini */ - _cairo_user_scaled_glyph_init, - _cairo_user_text_to_glyphs, - _cairo_user_ucs4_to_index, - NULL, /* show_glyphs */ - NULL, /* load_truetype_table */ - NULL /* index_to_ucs4 */ -}; - -/* #cairo_user_font_face_t */ - -static cairo_status_t -_cairo_user_font_face_scaled_font_create (void *abstract_face, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options, - cairo_scaled_font_t **scaled_font) -{ - cairo_status_t status = CAIRO_STATUS_SUCCESS; - cairo_user_font_face_t *font_face = abstract_face; - cairo_user_scaled_font_t *user_scaled_font = NULL; - cairo_font_extents_t font_extents = {1., 0., 1., 1., 0.}; - - font_face->immutable = TRUE; - - user_scaled_font = malloc (sizeof (cairo_user_scaled_font_t)); - if (unlikely (user_scaled_font == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - status = _cairo_scaled_font_init (&user_scaled_font->base, - &font_face->base, - font_matrix, ctm, options, - &_cairo_user_scaled_font_backend); - - if (unlikely (status)) { - free (user_scaled_font); - return status; - } - - /* XXX metrics hinting? */ - - /* compute a normalized version of font scale matrix to compute - * extents in. This is to minimize error caused by the cairo_fixed_t - * representation. */ - { - double fixed_scale, x_scale, y_scale; - - user_scaled_font->extent_scale = user_scaled_font->base.scale_inverse; - status = _cairo_matrix_compute_basis_scale_factors (&user_scaled_font->extent_scale, - &x_scale, &y_scale, - 1); - if (status == CAIRO_STATUS_SUCCESS) { - - if (x_scale == 0) x_scale = 1.; - if (y_scale == 0) y_scale = 1.; - - user_scaled_font->snap_x_scale = x_scale; - user_scaled_font->snap_y_scale = y_scale; - - /* since glyphs are pretty much 1.0x1.0, we can reduce error by - * scaling to a larger square. say, 1024.x1024. */ - fixed_scale = 1024.; - x_scale /= fixed_scale; - y_scale /= fixed_scale; - - cairo_matrix_scale (&user_scaled_font->extent_scale, 1. / x_scale, 1. / y_scale); - - user_scaled_font->extent_x_scale = x_scale; - user_scaled_font->extent_y_scale = y_scale; - } - } - - if (status == CAIRO_STATUS_SUCCESS && - font_face->scaled_font_methods.init != NULL) - { - /* Lock the scaled_font mutex such that user doesn't accidentally try - * to use it just yet. */ - CAIRO_MUTEX_LOCK (user_scaled_font->base.mutex); - - /* Give away fontmap lock such that user-font can use other fonts */ - status = _cairo_scaled_font_register_placeholder_and_unlock_font_map (&user_scaled_font->base); - if (status == CAIRO_STATUS_SUCCESS) { - cairo_surface_t *recording_surface; - cairo_t *cr; - - recording_surface = _cairo_user_scaled_font_create_recording_surface (user_scaled_font); - cr = _cairo_user_scaled_font_create_recording_context (user_scaled_font, recording_surface); - cairo_surface_destroy (recording_surface); - - status = font_face->scaled_font_methods.init (&user_scaled_font->base, - cr, - &font_extents); - - if (status == CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED) - status = CAIRO_STATUS_SUCCESS; - - if (status == CAIRO_STATUS_SUCCESS) - status = cairo_status (cr); - - cairo_destroy (cr); - - _cairo_scaled_font_unregister_placeholder_and_lock_font_map (&user_scaled_font->base); - } - - CAIRO_MUTEX_UNLOCK (user_scaled_font->base.mutex); - } - - if (status == CAIRO_STATUS_SUCCESS) - status = _cairo_scaled_font_set_metrics (&user_scaled_font->base, &font_extents); - - if (status != CAIRO_STATUS_SUCCESS) { - _cairo_scaled_font_fini (&user_scaled_font->base); - free (user_scaled_font); - } else { - user_scaled_font->default_glyph_extents.x_bearing = 0.; - user_scaled_font->default_glyph_extents.y_bearing = -font_extents.ascent; - user_scaled_font->default_glyph_extents.width = 0.; - user_scaled_font->default_glyph_extents.height = font_extents.ascent + font_extents.descent; - user_scaled_font->default_glyph_extents.x_advance = font_extents.max_x_advance; - user_scaled_font->default_glyph_extents.y_advance = 0.; - - *scaled_font = &user_scaled_font->base; - } - - return status; -} - -const cairo_font_face_backend_t _cairo_user_font_face_backend = { - CAIRO_FONT_TYPE_USER, - _cairo_user_font_face_create_for_toy, - _cairo_font_face_destroy, - _cairo_user_font_face_scaled_font_create -}; - - -cairo_bool_t -_cairo_font_face_is_user (cairo_font_face_t *font_face) -{ - return font_face->backend == &_cairo_user_font_face_backend; -} - -/* Implement the public interface */ - -/** - * cairo_user_font_face_create: - * - * Creates a new user font-face. - * - * Use the setter functions to associate callbacks with the returned - * user font. The only mandatory callback is render_glyph. - * - * After the font-face is created, the user can attach arbitrary data - * (the actual font data) to it using cairo_font_face_set_user_data() - * and access it from the user-font callbacks by using - * cairo_scaled_font_get_font_face() followed by - * cairo_font_face_get_user_data(). - * - * Return value: a newly created #cairo_font_face_t. Free with - * cairo_font_face_destroy() when you are done using it. - * - * Since: 1.8 - **/ -cairo_font_face_t * -cairo_user_font_face_create (void) -{ - cairo_user_font_face_t *font_face; - - font_face = malloc (sizeof (cairo_user_font_face_t)); - if (!font_face) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return (cairo_font_face_t *)&_cairo_font_face_nil; - } - - _cairo_font_face_init (&font_face->base, &_cairo_user_font_face_backend); - - font_face->immutable = FALSE; - memset (&font_face->scaled_font_methods, 0, sizeof (font_face->scaled_font_methods)); - - return &font_face->base; -} -slim_hidden_def(cairo_user_font_face_create); - -/* User-font method setters */ - - -/** - * cairo_user_font_face_set_init_func: - * @font_face: A user font face - * @init_func: The init callback, or %NULL - * - * Sets the scaled-font initialization function of a user-font. - * See #cairo_user_scaled_font_init_func_t for details of how the callback - * works. - * - * The font-face should not be immutable or a %CAIRO_STATUS_USER_FONT_IMMUTABLE - * error will occur. A user font-face is immutable as soon as a scaled-font - * is created from it. - * - * Since: 1.8 - **/ -void -cairo_user_font_face_set_init_func (cairo_font_face_t *font_face, - cairo_user_scaled_font_init_func_t init_func) -{ - cairo_user_font_face_t *user_font_face; - - if (font_face->status) - return; - - if (! _cairo_font_face_is_user (font_face)) { - if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH)) - return; - } - - user_font_face = (cairo_user_font_face_t *) font_face; - if (user_font_face->immutable) { - if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_USER_FONT_IMMUTABLE)) - return; - } - user_font_face->scaled_font_methods.init = init_func; -} -slim_hidden_def(cairo_user_font_face_set_init_func); - -/** - * cairo_user_font_face_set_render_glyph_func: - * @font_face: A user font face - * @render_glyph_func: The render_glyph callback, or %NULL - * - * Sets the glyph rendering function of a user-font. - * See #cairo_user_scaled_font_render_glyph_func_t for details of how the callback - * works. - * - * The font-face should not be immutable or a %CAIRO_STATUS_USER_FONT_IMMUTABLE - * error will occur. A user font-face is immutable as soon as a scaled-font - * is created from it. - * - * The render_glyph callback is the only mandatory callback of a user-font. - * If the callback is %NULL and a glyph is tried to be rendered using - * @font_face, a %CAIRO_STATUS_USER_FONT_ERROR will occur. - * - * Since: 1.8 - **/ -void -cairo_user_font_face_set_render_glyph_func (cairo_font_face_t *font_face, - cairo_user_scaled_font_render_glyph_func_t render_glyph_func) -{ - cairo_user_font_face_t *user_font_face; - - if (font_face->status) - return; - - if (! _cairo_font_face_is_user (font_face)) { - if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH)) - return; - } - - user_font_face = (cairo_user_font_face_t *) font_face; - if (user_font_face->immutable) { - if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_USER_FONT_IMMUTABLE)) - return; - } - user_font_face->scaled_font_methods.render_glyph = render_glyph_func; -} -slim_hidden_def(cairo_user_font_face_set_render_glyph_func); - -/** - * cairo_user_font_face_set_text_to_glyphs_func: - * @font_face: A user font face - * @text_to_glyphs_func: The text_to_glyphs callback, or %NULL - * - * Sets th text-to-glyphs conversion function of a user-font. - * See #cairo_user_scaled_font_text_to_glyphs_func_t for details of how the callback - * works. - * - * The font-face should not be immutable or a %CAIRO_STATUS_USER_FONT_IMMUTABLE - * error will occur. A user font-face is immutable as soon as a scaled-font - * is created from it. - * - * Since: 1.8 - **/ -void -cairo_user_font_face_set_text_to_glyphs_func (cairo_font_face_t *font_face, - cairo_user_scaled_font_text_to_glyphs_func_t text_to_glyphs_func) -{ - cairo_user_font_face_t *user_font_face; - - if (font_face->status) - return; - - if (! _cairo_font_face_is_user (font_face)) { - if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH)) - return; - } - - user_font_face = (cairo_user_font_face_t *) font_face; - if (user_font_face->immutable) { - if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_USER_FONT_IMMUTABLE)) - return; - } - user_font_face->scaled_font_methods.text_to_glyphs = text_to_glyphs_func; -} - -/** - * cairo_user_font_face_set_unicode_to_glyph_func: - * @font_face: A user font face - * @unicode_to_glyph_func: The unicode_to_glyph callback, or %NULL - * - * Sets the unicode-to-glyph conversion function of a user-font. - * See #cairo_user_scaled_font_unicode_to_glyph_func_t for details of how the callback - * works. - * - * The font-face should not be immutable or a %CAIRO_STATUS_USER_FONT_IMMUTABLE - * error will occur. A user font-face is immutable as soon as a scaled-font - * is created from it. - * - * Since: 1.8 - **/ -void -cairo_user_font_face_set_unicode_to_glyph_func (cairo_font_face_t *font_face, - cairo_user_scaled_font_unicode_to_glyph_func_t unicode_to_glyph_func) -{ - cairo_user_font_face_t *user_font_face; - if (font_face->status) - return; - - if (! _cairo_font_face_is_user (font_face)) { - if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH)) - return; - } - - user_font_face = (cairo_user_font_face_t *) font_face; - if (user_font_face->immutable) { - if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_USER_FONT_IMMUTABLE)) - return; - } - user_font_face->scaled_font_methods.unicode_to_glyph = unicode_to_glyph_func; -} -slim_hidden_def(cairo_user_font_face_set_unicode_to_glyph_func); - -/* User-font method getters */ - -/** - * cairo_user_font_face_get_init_func: - * @font_face: A user font face - * - * Gets the scaled-font initialization function of a user-font. - * - * Return value: The init callback of @font_face - * or %NULL if none set or an error has occurred. - * - * Since: 1.8 - **/ -cairo_user_scaled_font_init_func_t -cairo_user_font_face_get_init_func (cairo_font_face_t *font_face) -{ - cairo_user_font_face_t *user_font_face; - - if (font_face->status) - return NULL; - - if (! _cairo_font_face_is_user (font_face)) { - if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH)) - return NULL; - } - - user_font_face = (cairo_user_font_face_t *) font_face; - return user_font_face->scaled_font_methods.init; -} - -/** - * cairo_user_font_face_get_render_glyph_func: - * @font_face: A user font face - * - * Gets the glyph rendering function of a user-font. - * - * Return value: The render_glyph callback of @font_face - * or %NULL if none set or an error has occurred. - * - * Since: 1.8 - **/ -cairo_user_scaled_font_render_glyph_func_t -cairo_user_font_face_get_render_glyph_func (cairo_font_face_t *font_face) -{ - cairo_user_font_face_t *user_font_face; - - if (font_face->status) - return NULL; - - if (! _cairo_font_face_is_user (font_face)) { - if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH)) - return NULL; - } - - user_font_face = (cairo_user_font_face_t *) font_face; - return user_font_face->scaled_font_methods.render_glyph; -} - -/** - * cairo_user_font_face_get_text_to_glyphs_func: - * @font_face: A user font face - * - * Gets the text-to-glyphs conversion function of a user-font. - * - * Return value: The text_to_glyphs callback of @font_face - * or %NULL if none set or an error occurred. - * - * Since: 1.8 - **/ -cairo_user_scaled_font_text_to_glyphs_func_t -cairo_user_font_face_get_text_to_glyphs_func (cairo_font_face_t *font_face) -{ - cairo_user_font_face_t *user_font_face; - - if (font_face->status) - return NULL; - - if (! _cairo_font_face_is_user (font_face)) { - if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH)) - return NULL; - } - - user_font_face = (cairo_user_font_face_t *) font_face; - return user_font_face->scaled_font_methods.text_to_glyphs; -} - -/** - * cairo_user_font_face_get_unicode_to_glyph_func: - * @font_face: A user font face - * - * Gets the unicode-to-glyph conversion function of a user-font. - * - * Return value: The unicode_to_glyph callback of @font_face - * or %NULL if none set or an error occurred. - * - * Since: 1.8 - **/ -cairo_user_scaled_font_unicode_to_glyph_func_t -cairo_user_font_face_get_unicode_to_glyph_func (cairo_font_face_t *font_face) -{ - cairo_user_font_face_t *user_font_face; - - if (font_face->status) - return NULL; - - if (! _cairo_font_face_is_user (font_face)) { - if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH)) - return NULL; - } - - user_font_face = (cairo_user_font_face_t *) font_face; - return user_font_face->scaled_font_methods.unicode_to_glyph; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-version.c b/source/libs/cairo/cairo-src/src/cairo-version.c deleted file mode 100644 index a94cef6819d4784b178a80cc66db9a1f9ef08236..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-version.c +++ /dev/null @@ -1,261 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - */ - -#define CAIRO_VERSION_H 1 - -#include "cairoint.h" - -/* get the "real" version info instead of dummy cairo-version.h */ -#undef CAIRO_VERSION_H -#include "../cairo-version.h" - -/** - * SECTION:cairo-version - * @Title: Version Information - * @Short_Description: Compile-time and run-time version checks. - * - * Cairo has a three-part version number scheme. In this scheme, we use - * even vs. odd numbers to distinguish fixed points in the software - * vs. in-progress development, (such as from git instead of a tar file, - * or as a "snapshot" tar file as opposed to a "release" tar file). - * - * <informalexample><screen> - * _____ Major. Always 1, until we invent a new scheme. - * / ___ Minor. Even/Odd = Release/Snapshot (tar files) or Branch/Head (git) - * | / _ Micro. Even/Odd = Tar-file/git - * | | / - * 1.0.0 - * </screen></informalexample> - * - * Here are a few examples of versions that one might see. - * <informalexample><screen> - * Releases - * -------- - * 1.0.0 - A major release - * 1.0.2 - A subsequent maintenance release - * 1.2.0 - Another major release - * - * Snapshots - * --------- - * 1.1.2 - A snapshot (working toward the 1.2.0 release) - * - * In-progress development (eg. from git) - * -------------------------------------- - * 1.0.1 - Development on a maintenance branch (toward 1.0.2 release) - * 1.1.1 - Development on head (toward 1.1.2 snapshot and 1.2.0 release) - * </screen></informalexample> - * - * <refsect2> - * <title>Compatibility</title> - * - * The API/ABI compatibility guarantees for various versions are as - * follows. First, let's assume some cairo-using application code that is - * successfully using the API/ABI "from" one version of cairo. Then let's - * ask the question whether this same code can be moved "to" the API/ABI - * of another version of cairo. - * - * Moving from a release to any later version (release, snapshot, - * development) is always guaranteed to provide compatibility. - * - * Moving from a snapshot to any later version is not guaranteed to - * provide compatibility, since snapshots may introduce new API that ends - * up being removed before the next release. - * - * Moving from an in-development version (odd micro component) to any - * later version is not guaranteed to provide compatibility. In fact, - * there's not even a guarantee that the code will even continue to work - * with the same in-development version number. This is because these - * numbers don't correspond to any fixed state of the software, but - * rather the many states between snapshots and releases. - * - * </refsect2> - * <refsect2> - * <title>Examining the version</title> - * - * Cairo provides the ability to examine the version at either - * compile-time or run-time and in both a human-readable form as well as - * an encoded form suitable for direct comparison. Cairo also provides the - * macro CAIRO_VERSION_ENCODE() to perform the encoding. - * - * <informalexample><screen> - * Compile-time - * ------------ - * CAIRO_VERSION_STRING Human-readable - * CAIRO_VERSION Encoded, suitable for comparison - * - * Run-time - * -------- - * cairo_version_string() Human-readable - * cairo_version() Encoded, suitable for comparison - * </screen></informalexample> - * - * For example, checking that the cairo version is greater than or equal - * to 1.0.0 could be achieved at compile-time or run-time as follows: - * - * <informalexample><programlisting> - * ##if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 0, 0) - * printf ("Compiling with suitable cairo version: %s\n", %CAIRO_VERSION_STRING); - * ##endif - * - * if (cairo_version() >= CAIRO_VERSION_ENCODE(1, 0, 0)) - * printf ("Running with suitable cairo version: %s\n", cairo_version_string ()); - * </programlisting></informalexample> - * - * </refsect2> - * - **/ - -/** - * CAIRO_VERSION: - * - * The version of cairo available at compile-time, encoded using - * CAIRO_VERSION_ENCODE(). - * - * Since: 1.0 - **/ - -/** - * CAIRO_VERSION_MAJOR: - * - * The major component of the version of cairo available at compile-time. - * - * Since: 1.0 - **/ - -/** - * CAIRO_VERSION_MINOR: - * - * The minor component of the version of cairo available at compile-time. - * - * Since: 1.0 - **/ - -/** - * CAIRO_VERSION_MICRO: - * - * The micro component of the version of cairo available at compile-time. - * - * Since: 1.0 - **/ - -/** - * CAIRO_VERSION_STRING: - * - * A human-readable string literal containing the version of cairo available - * at compile-time, in the form of "X.Y.Z". - * - * Since: 1.8 - **/ - -/** - * CAIRO_VERSION_ENCODE: - * @major: the major component of the version number - * @minor: the minor component of the version number - * @micro: the micro component of the version number - * - * This macro encodes the given cairo version into an integer. The numbers - * returned by %CAIRO_VERSION and cairo_version() are encoded using this macro. - * Two encoded version numbers can be compared as integers. The encoding ensures - * that later versions compare greater than earlier versions. - * - * Returns: the encoded version. - * - * Since: 1.0 - **/ - -/** - * CAIRO_VERSION_STRINGIZE: - * @major: the major component of the version number - * @minor: the minor component of the version number - * @micro: the micro component of the version number - * - * This macro encodes the given cairo version into an string. The numbers - * returned by %CAIRO_VERSION_STRING and cairo_version_string() are encoded using this macro. - * The parameters to this macro must expand to numerical literals. - * - * Returns: a string literal containing the version. - * - * Since: 1.8 - **/ - -/** - * cairo_version: - * - * Returns the version of the cairo library encoded in a single - * integer as per %CAIRO_VERSION_ENCODE. The encoding ensures that - * later versions compare greater than earlier versions. - * - * A run-time comparison to check that cairo's version is greater than - * or equal to version X.Y.Z could be performed as follows: - * - * <informalexample><programlisting> - * if (cairo_version() >= CAIRO_VERSION_ENCODE(X,Y,Z)) {...} - * </programlisting></informalexample> - * - * See also cairo_version_string() as well as the compile-time - * equivalents %CAIRO_VERSION and %CAIRO_VERSION_STRING. - * - * Return value: the encoded version. - * - * Since: 1.0 - **/ -int -cairo_version (void) -{ - return CAIRO_VERSION; -} - -/** - * cairo_version_string: - * - * Returns the version of the cairo library as a human-readable string - * of the form "X.Y.Z". - * - * See also cairo_version() as well as the compile-time equivalents - * %CAIRO_VERSION_STRING and %CAIRO_VERSION. - * - * Return value: a string containing the version. - * - * Since: 1.0 - **/ -const char* -cairo_version_string (void) -{ - return CAIRO_VERSION_STRING; -} -slim_hidden_def (cairo_version_string); diff --git a/source/libs/cairo/cairo-src/src/cairo-version.h b/source/libs/cairo/cairo-src/src/cairo-version.h deleted file mode 100644 index 51008003f98ff194ef209ca82d600de41d583fb7..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-version.h +++ /dev/null @@ -1,14 +0,0 @@ -/* This is a dummy file. - * The actual version info is in toplevel cairo-version.h. - * The purpose of this file is to make most of the source files NOT depend - * on the real cairo-version.h, and as a result, changing library version - * would not cause a complete rebuild of all object files (just a relink). - * This is useful when bisecting. */ -#ifndef CAIRO_VERSION_H -#define CAIRO_VERSION_H - -#define CAIRO_VERSION_MAJOR USE_cairo_version_OR_cairo_version_string_INSTEAD -#define CAIRO_VERSION_MINOR USE_cairo_version_OR_cairo_version_string_INSTEAD -#define CAIRO_VERSION_MICRO USE_cairo_version_OR_cairo_version_string_INSTEAD - -#endif diff --git a/source/libs/cairo/cairo-src/src/cairo-vg-surface.c b/source/libs/cairo/cairo-src/src/cairo-vg-surface.c deleted file mode 100644 index 6e0d9a0ed69af0c8a4625b4bc7a3adf3c5082b93..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-vg-surface.c +++ /dev/null @@ -1,1853 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2008 Opened Hand Ltd. - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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.og/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. - * - * Contributor(s): - * Pierre Tardy <tardyp@gmail.com> - * Øyvind KolÃ¥s <pippin@gimp.org> - * Vladimi Vukicevic <vladimir@mozilla.com> (stubbed out base backend) - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-vg.h" - -#include "cairo-cache-private.h" -#include "cairo-default-context-private.h" -#include "cairo-error-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-path-fixed-private.h" -#include "cairo-recording-surface-inline.h" -#include "cairo-surface-clipper-private.h" - -#include <pixman.h> -#include <VG/openvg.h> - -//#define OPENVG_DEBUG - -/* - * Work that needs to be done: - * - Glyph cache / proper font support - * - * - First-class paths - * Paths are expensive for OpenVG, reuse paths whenever possible. - * So add a path cache, and first class paths! - */ - -typedef struct _cairo_vg_surface cairo_vg_surface_t; - -/* XXX need GL specific context control. :( */ -struct _cairo_vg_context { - cairo_status_t status; - cairo_reference_count_t ref_count; - - unsigned long target_id; - - VGPaint paint; - cairo_vg_surface_t *source; - double alpha; - - cairo_cache_t snapshot_cache; - - void *display; - void *context; - - cairo_status_t (*create_target) (cairo_vg_context_t *, - cairo_vg_surface_t *); - cairo_status_t (*set_target) (cairo_vg_context_t *, - cairo_vg_surface_t *); - void (*destroy_target) (cairo_vg_context_t *, cairo_vg_surface_t *); -}; - -struct _cairo_vg_surface { - cairo_surface_t base; - - cairo_vg_context_t *context; - - VGImage image; - VGImageFormat format; - int width; - int height; - cairo_bool_t own_image; - - cairo_cache_entry_t snapshot_cache_entry; - - cairo_surface_clipper_t clipper; - - unsigned long target_id; -}; - -static const cairo_surface_backend_t cairo_vg_surface_backend; - -slim_hidden_proto (cairo_vg_surface_create); - -static cairo_surface_t * -_vg_surface_create_internal (cairo_vg_context_t *context, - VGImage image, - VGImageFormat format, - int width, int height); - -static cairo_vg_context_t * -_vg_context_reference (cairo_vg_context_t *context) -{ - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&context->ref_count)); - - _cairo_reference_count_inc (&context->ref_count); - - return context; -} - -static cairo_vg_context_t * -_vg_context_lock (cairo_vg_context_t *context) -{ - /* XXX if we need to add locking, then it has to be recursive */ - return context; -} - -static cairo_int_status_t -_vg_context_set_target (cairo_vg_context_t *context, - cairo_vg_surface_t *surface) -{ - cairo_status_t status; - - if (surface->target_id == 0) { - status = context->create_target (context, surface); - if (unlikely (status)) - return status; - } - - if (context->target_id == surface->target_id) - return CAIRO_STATUS_SUCCESS; - - context->target_id = surface->target_id; - - return context->set_target (context, surface); -} - -static void -_vg_context_destroy_target (cairo_vg_context_t *context, - cairo_vg_surface_t *surface) -{ - if (surface->target_id == 0) - return; - - if (context->target_id == surface->target_id) - context->set_target (context, NULL); - - context->destroy_target (context, surface); -} - -static cairo_bool_t -_vg_snapshot_cache_can_remove (const void *entry) -{ - return TRUE; -} - -static void -_vg_snapshot_cache_remove (void *cache_entry) -{ - cairo_vg_surface_t *surface = cairo_container_of (cache_entry, - cairo_vg_surface_t, - snapshot_cache_entry); - surface->snapshot_cache_entry.hash = 0; - cairo_surface_destroy (&surface->base); -} - -static cairo_status_t -_vg_context_init (cairo_vg_context_t *context) -{ - cairo_status_t status; - - context->status = CAIRO_STATUS_SUCCESS; - CAIRO_REFERENCE_COUNT_INIT (&context->ref_count, 1); - - status = _cairo_cache_init (&context->snapshot_cache, - NULL, - _vg_snapshot_cache_can_remove, - _vg_snapshot_cache_remove, - 16*1024*1024); - if (unlikely (status)) - return status; - - context->target_id = 0; - context->source = NULL; - context->alpha = 1.0; - - context->paint = vgCreatePaint (); - vgLoadIdentity (); - - return CAIRO_STATUS_SUCCESS; -} - -static void -_vg_context_destroy (cairo_vg_context_t *context) -{ - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&context->ref_count)); - - if (! _cairo_reference_count_dec_and_test (&context->ref_count)) - return; - - if (context->paint != VG_INVALID_HANDLE) - vgDestroyPaint (context->paint); - - _cairo_cache_fini (&context->snapshot_cache); - free (context); -} - -static void -_vg_context_unlock (cairo_vg_context_t *context) -{ -} - -#ifdef OPENVG_DEBUG -static void check_vg_errors(const char*function,int line) -{ - int err = vgGetError(); - if (err != VG_NO_ERROR){ - printf("%s+%d:vgError detected: 0x%08x.\n",function, line,err); - assert(err == VG_NO_ERROR); - } - -} -#define CHECK_VG_ERRORS() check_vg_errors(__FILE__,__LINE__) -#else -#define CHECK_VG_ERRORS() do{}while(0) -#endif //OPENVG_DEBUG - -static pixman_format_code_t -_vg_format_to_pixman (VGImageFormat format, - cairo_bool_t *needs_premult_fixup) -{ - *needs_premult_fixup = FALSE; - switch (format) { - /* RGB{A,X} channel ordering */ - case VG_sRGBX_8888: return PIXMAN_r8g8b8x8; - case VG_sRGBA_8888: *needs_premult_fixup = TRUE; return PIXMAN_r8g8b8a8; - case VG_sRGBA_8888_PRE: return PIXMAN_r8g8b8a8; - case VG_sRGB_565: return PIXMAN_r5g6b5; - case VG_sRGBA_5551: return 0; - case VG_sRGBA_4444: return 0; - case VG_sL_8: return PIXMAN_g8; - case VG_lRGBX_8888: return 0; - case VG_lRGBA_8888: return 0; - case VG_lRGBA_8888_PRE: return 0; - case VG_lL_8: return 0; - case VG_A_8: return PIXMAN_a8; - case VG_BW_1: return PIXMAN_a1; - case VG_A_1: return PIXMAN_a1; - case VG_A_4: return PIXMAN_a4; - - /* {A,X}RGB channel ordering */ - case VG_sXRGB_8888: return PIXMAN_x8r8g8b8; - case VG_sARGB_8888: *needs_premult_fixup = TRUE; return PIXMAN_a8r8g8b8; - case VG_sARGB_8888_PRE: return PIXMAN_a8r8g8b8; - case VG_sARGB_1555: return 0; - case VG_sARGB_4444: return 0; - case VG_lXRGB_8888: return 0; - case VG_lARGB_8888: return 0; - case VG_lARGB_8888_PRE: return 0; - - /* BGR{A,X} channel ordering */ - case VG_sBGRX_8888: return PIXMAN_b8g8r8x8; - case VG_sBGRA_8888: *needs_premult_fixup = TRUE; return PIXMAN_b8g8r8a8; - case VG_sBGRA_8888_PRE: return PIXMAN_b8g8r8a8; - case VG_sBGR_565: return PIXMAN_b5g6r5; - case VG_sBGRA_5551: return 0; - case VG_sBGRA_4444: return 0; - case VG_lBGRX_8888: return 0; - case VG_lBGRA_8888: return 0; - case VG_lBGRA_8888_PRE: return 0; - - /* {A,X}BGR channel ordering */ - case VG_sXBGR_8888: return PIXMAN_x8b8g8r8; - case VG_sABGR_8888: *needs_premult_fixup = TRUE; return PIXMAN_a8b8g8r8; - case VG_sABGR_8888_PRE: return PIXMAN_a8b8g8r8; - case VG_sABGR_1555: return 0; - case VG_sABGR_4444: return 0; - case VG_lXBGR_8888: return 0; - case VG_lABGR_8888: return 0; - case VG_lABGR_8888_PRE: return 0; - default: return 0; - } -} - -static pixman_format_code_t -_vg_format_to_content (VGImageFormat format) -{ - /* XXX could use more simple bit tests */ - switch (format) { - /* RGB{A,X} channel ordering */ - case VG_sRGBX_8888: return CAIRO_CONTENT_COLOR; - case VG_sRGBA_8888: return CAIRO_CONTENT_COLOR_ALPHA; - case VG_sRGBA_8888_PRE: return CAIRO_CONTENT_COLOR_ALPHA; - case VG_sRGB_565: return CAIRO_CONTENT_COLOR; - case VG_sRGBA_5551: return CAIRO_CONTENT_COLOR_ALPHA; - case VG_sRGBA_4444: return CAIRO_CONTENT_COLOR_ALPHA; - case VG_sL_8: return CAIRO_CONTENT_ALPHA; - case VG_lRGBX_8888: return CAIRO_CONTENT_COLOR; - case VG_lRGBA_8888: return CAIRO_CONTENT_COLOR_ALPHA; - case VG_lRGBA_8888_PRE: return CAIRO_CONTENT_COLOR_ALPHA; - case VG_lL_8: return CAIRO_CONTENT_ALPHA; - case VG_A_8: return CAIRO_CONTENT_ALPHA; - case VG_A_4: return CAIRO_CONTENT_ALPHA; - case VG_A_1: return CAIRO_CONTENT_ALPHA; - case VG_BW_1: return CAIRO_CONTENT_ALPHA; - - /* {A,X}RGB channel ordering */ - case VG_sXRGB_8888: return CAIRO_CONTENT_COLOR; - case VG_sARGB_8888: return CAIRO_CONTENT_COLOR_ALPHA; - case VG_sARGB_8888_PRE: return CAIRO_CONTENT_COLOR_ALPHA; - case VG_sARGB_1555: return CAIRO_CONTENT_COLOR_ALPHA; - case VG_sARGB_4444: return CAIRO_CONTENT_COLOR_ALPHA; - case VG_lXRGB_8888: return CAIRO_CONTENT_COLOR; - case VG_lARGB_8888: return CAIRO_CONTENT_COLOR_ALPHA; - case VG_lARGB_8888_PRE: return CAIRO_CONTENT_COLOR_ALPHA; - - /* BGR{A,X} channel ordering */ - case VG_sBGRX_8888: return CAIRO_CONTENT_COLOR; - case VG_sBGRA_8888: return CAIRO_CONTENT_COLOR_ALPHA; - case VG_sBGRA_8888_PRE: return CAIRO_CONTENT_COLOR_ALPHA; - case VG_sBGR_565: return CAIRO_CONTENT_COLOR; - case VG_sBGRA_5551: return CAIRO_CONTENT_COLOR_ALPHA; - case VG_sBGRA_4444: return CAIRO_CONTENT_COLOR_ALPHA; - case VG_lBGRX_8888: return CAIRO_CONTENT_COLOR; - case VG_lBGRA_8888: return CAIRO_CONTENT_COLOR_ALPHA; - case VG_lBGRA_8888_PRE: return CAIRO_CONTENT_COLOR_ALPHA; - - /* {A,X}BGR channel ordering */ - case VG_sXBGR_8888: return CAIRO_CONTENT_COLOR; - case VG_sABGR_8888: return CAIRO_CONTENT_COLOR_ALPHA; - case VG_sABGR_8888_PRE: return CAIRO_CONTENT_COLOR_ALPHA; - case VG_sABGR_1555: return CAIRO_CONTENT_COLOR_ALPHA; - case VG_sABGR_4444: return CAIRO_CONTENT_COLOR_ALPHA; - case VG_lXBGR_8888: return CAIRO_CONTENT_COLOR; - case VG_lABGR_8888: return CAIRO_CONTENT_COLOR_ALPHA; - case VG_lABGR_8888_PRE: return CAIRO_CONTENT_COLOR_ALPHA; - default: return 0; - } -} - -static VGImageFormat -_vg_format_from_pixman (pixman_format_code_t format) -{ - /* XXX _PRE needs fixup */ - switch ((int) format) { - case PIXMAN_r5g6b5: return VG_sRGB_565; - case PIXMAN_g8: return VG_sL_8; - case PIXMAN_a8: return VG_A_8; - case PIXMAN_a1: return VG_BW_1; - case PIXMAN_x8r8g8b8: return VG_sXRGB_8888; - case PIXMAN_a8r8g8b8: return VG_sARGB_8888; // _PRE - case PIXMAN_b8g8r8x8: return VG_sBGRX_8888; - case PIXMAN_b8g8r8a8: return VG_sBGRA_8888; // _PRE - case PIXMAN_b5g6r5: return VG_sBGR_565; - case PIXMAN_x8b8g8r8: return VG_sXBGR_8888; - case PIXMAN_a8b8g8r8: return VG_sABGR_8888; // _PRE - default: return 0; - } -} - -static VGImageFormat -_vg_format_for_content (cairo_content_t content) -{ - switch (content) { - case CAIRO_CONTENT_ALPHA: return VG_A_8; - case CAIRO_CONTENT_COLOR: return VG_sXRGB_8888; - default: ASSERT_NOT_REACHED; - case CAIRO_CONTENT_COLOR_ALPHA: return VG_sARGB_8888; // _PRE - } -} - -static cairo_surface_t * -_vg_surface_create_similar (void *abstract_surface, - cairo_content_t content, - int width, - int height) -{ - cairo_vg_surface_t *surface = abstract_surface; - - if (width > vgGeti (VG_MAX_IMAGE_WIDTH) || - height > vgGeti (VG_MAX_IMAGE_HEIGHT)) - { - return NULL; - } - - return cairo_vg_surface_create (surface->context, content, width, height); -} - -static cairo_status_t -_vg_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper, - cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_vg_surface_t *surface = cairo_container_of (clipper, - cairo_vg_surface_t, - clipper); - cairo_vg_surface_t *mask; - cairo_status_t status; - - if (path == NULL) { - vgMask (VG_INVALID_HANDLE, - VG_FILL_MASK, 0, 0, surface->width, surface->height); - vgSeti (VG_MASKING, VG_FALSE); - CHECK_VG_ERRORS(); - return CAIRO_STATUS_SUCCESS; - } - - mask = (cairo_vg_surface_t *) - _vg_surface_create_similar (surface, CAIRO_CONTENT_ALPHA, - surface->width, surface->height); - if (unlikely (mask == NULL)) - return CAIRO_INT_STATUS_UNSUPPORTED; - if (unlikely (mask->base.status)) - return mask->base.status; - - status = _cairo_surface_fill (&mask->base, - CAIRO_OPERATOR_SOURCE, - &_cairo_pattern_white.base, - path, fill_rule, tolerance, antialias, - NULL); - if (status) { - cairo_surface_destroy (&mask->base); - return status; - } - - vgSeti (VG_MASKING, VG_TRUE); - vgMask (mask->image, VG_INTERSECT_MASK, 0, 0, mask->width, mask->height); - - cairo_surface_destroy (&mask->base); - - CHECK_VG_ERRORS(); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_bool_t -_vg_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *extents) -{ - cairo_vg_surface_t *surface = abstract_surface; - - extents->x = 0; - extents->y = 0; - extents->width = surface->width; - extents->height = surface->height; - - return TRUE; -} - -#define MAX_SEG 16 /* max number of knots to upload in a batch */ - -typedef struct _vg_path { - VGPath path; - const cairo_matrix_t *ctm_inverse; - - VGubyte gseg[MAX_SEG]; - VGfloat gdata[MAX_SEG*3*2]; - int dcount; - int scount; -} vg_path_t; - -static cairo_status_t -_vg_move_to (void *closure, - const cairo_point_t *point) -{ - vg_path_t *path = closure; - double x = _cairo_fixed_to_double (point->x); - double y = _cairo_fixed_to_double (point->y); - - if (path->ctm_inverse) - cairo_matrix_transform_point (path->ctm_inverse, &x, &y); - - path->gseg[path->scount++] = VG_MOVE_TO; - path->gdata[path->dcount++] = x; - path->gdata[path->dcount++] = y; - - if (path->scount >= MAX_SEG-1) { - vgAppendPathData (path->path, path->scount, path->gseg, path->gdata); - path->scount = 0; - path->dcount = 0; - } - - CHECK_VG_ERRORS(); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_vg_line_to (void *closure, - const cairo_point_t *point) -{ - vg_path_t *path = closure; - double x = _cairo_fixed_to_double (point->x); - double y = _cairo_fixed_to_double (point->y); - - if (path->ctm_inverse) - cairo_matrix_transform_point (path->ctm_inverse, &x, &y); - - path->gseg[path->scount++] = VG_LINE_TO; - path->gdata[path->dcount++] = x; - path->gdata[path->dcount++] = y; - - if (path->scount >= MAX_SEG-1) { - vgAppendPathData (path->path, path->scount, path->gseg, path->gdata); - path->scount = 0; - path->dcount = 0; - } - - CHECK_VG_ERRORS(); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_vg_curve_to (void *closure, - const cairo_point_t *p0, - const cairo_point_t *p1, - const cairo_point_t *p2) -{ - vg_path_t *path = closure; - double x0 = _cairo_fixed_to_double (p0->x); - double y0 = _cairo_fixed_to_double (p0->y); - double x1 = _cairo_fixed_to_double (p1->x); - double y1 = _cairo_fixed_to_double (p1->y); - double x2 = _cairo_fixed_to_double (p2->x); - double y2 = _cairo_fixed_to_double (p2->y); - - if (path->ctm_inverse) { - cairo_matrix_transform_point (path->ctm_inverse, &x0, &y0); - cairo_matrix_transform_point (path->ctm_inverse, &x1, &y1); - cairo_matrix_transform_point (path->ctm_inverse, &x2, &y2); - } - - path->gseg[path->scount++] = VG_CUBIC_TO; - path->gdata[path->dcount++] = x0; - path->gdata[path->dcount++] = y0; - path->gdata[path->dcount++] = x1; - path->gdata[path->dcount++] = y1; - path->gdata[path->dcount++] = x2; - path->gdata[path->dcount++] = y2; - - if (path->scount >= MAX_SEG-1) { - vgAppendPathData(path->path, path->scount, path->gseg, path->gdata); - path->scount = 0; - path->dcount = 0; - } - - CHECK_VG_ERRORS(); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_vg_close_path (void *closure) -{ - vg_path_t *path = closure; - - path->gseg[path->scount++] = VG_CLOSE_PATH; - - if (path->scount >= MAX_SEG-1) { - vgAppendPathData (path->path, path->scount, path->gseg, path->gdata); - path->scount = 0; - path->dcount = 0; - } - - CHECK_VG_ERRORS(); - return CAIRO_STATUS_SUCCESS; -} - -static void -_vg_path_from_cairo (vg_path_t *vg_path, - const cairo_path_fixed_t *path) -{ - cairo_status_t status; - - vg_path->scount = 0; - vg_path->dcount = 0; - - status = _cairo_path_fixed_interpret (path, - _vg_move_to, - _vg_line_to, - _vg_curve_to, - _vg_close_path, - vg_path); - assert (status == CAIRO_STATUS_SUCCESS); - - vgAppendPathData (vg_path->path, - vg_path->scount, vg_path->gseg, vg_path->gdata); - CHECK_VG_ERRORS(); -} - -static cairo_bool_t -_vg_is_supported_operator (cairo_operator_t op) -{ - switch ((int) op) { - case CAIRO_OPERATOR_SOURCE: - case CAIRO_OPERATOR_OVER: - case CAIRO_OPERATOR_IN: - case CAIRO_OPERATOR_DEST_OVER: - case CAIRO_OPERATOR_DEST_IN: - case CAIRO_OPERATOR_ADD: - return TRUE; - - default: - return FALSE; - } -} - -static VGBlendMode -_vg_operator (cairo_operator_t op) -{ - switch ((int) op) { - case CAIRO_OPERATOR_SOURCE: - return VG_BLEND_SRC; - case CAIRO_OPERATOR_OVER: - return VG_BLEND_SRC_OVER; - case CAIRO_OPERATOR_IN: - return VG_BLEND_SRC_IN; - case CAIRO_OPERATOR_DEST_OVER: - return VG_BLEND_DST_OVER; - case CAIRO_OPERATOR_DEST_IN: - return VG_BLEND_DST_IN; - case CAIRO_OPERATOR_ADD: - return VG_BLEND_ADDITIVE; - default: - ASSERT_NOT_REACHED; - return VG_BLEND_SRC_OVER; - } -} - -static VGFillRule -_vg_fill_rule_from_cairo (cairo_fill_rule_t rule) -{ - switch (rule) { - case CAIRO_FILL_RULE_EVEN_ODD: return VG_EVEN_ODD; - case CAIRO_FILL_RULE_WINDING: return VG_NON_ZERO; - } - - ASSERT_NOT_REACHED; - return VG_NON_ZERO; -} - -static VGRenderingQuality -_vg_rendering_quality_from_cairo (cairo_antialias_t aa) -{ - switch (aa) { - case CAIRO_ANTIALIAS_DEFAULT: - case CAIRO_ANTIALIAS_SUBPIXEL: - case CAIRO_ANTIALIAS_GOOD: - case CAIRO_ANTIALIAS_BEST: - return VG_RENDERING_QUALITY_BETTER; - - case CAIRO_ANTIALIAS_GRAY: - case CAIRO_ANTIALIAS_FAST: - return VG_RENDERING_QUALITY_FASTER; - - case CAIRO_ANTIALIAS_NONE: - return VG_RENDERING_QUALITY_NONANTIALIASED; - } - - ASSERT_NOT_REACHED; - return VG_RENDERING_QUALITY_BETTER; -} - -static VGCapStyle -_vg_line_cap_from_cairo (cairo_line_cap_t cap) -{ - switch (cap) { - case CAIRO_LINE_CAP_BUTT: return VG_CAP_BUTT; - case CAIRO_LINE_CAP_ROUND: return VG_CAP_ROUND; - case CAIRO_LINE_CAP_SQUARE: return VG_CAP_SQUARE; - } - - ASSERT_NOT_REACHED; - return VG_CAP_BUTT; -} - -static VGJoinStyle -_vg_line_join_from_cairo (cairo_line_join_t join) -{ - switch (join) { - case CAIRO_LINE_JOIN_MITER: return VG_JOIN_MITER; - case CAIRO_LINE_JOIN_ROUND: return VG_JOIN_ROUND; - case CAIRO_LINE_JOIN_BEVEL: return VG_JOIN_BEVEL; - } - - ASSERT_NOT_REACHED; - return VG_JOIN_MITER; -} - -static void -_vg_matrix_from_cairo (VGfloat *dst, const cairo_matrix_t *src) -{ - dst[0] = /* sx */ src->xx; - dst[1] = /* shy */ src->yx; - dst[2] = /* w0 */ 0; - dst[3] = /* shx */ src->xy; - dst[4] = /* sy */ src->yy; - dst[5] = /* w1 */ 0; - dst[6] = /* tx */ src->x0; - dst[7] = /* ty */ src->y0; - dst[8] = /* w2 */ 0; -} - -static cairo_status_t -_vg_setup_gradient_stops (cairo_vg_context_t *context, - const cairo_gradient_pattern_t *pattern) -{ - VGint numstops = pattern->n_stops; - VGfloat *stops, stack_stops[CAIRO_STACK_ARRAY_LENGTH (VGfloat)]; - int i; - - if (numstops*5 < ARRAY_LENGTH (stack_stops)) { - stops = stack_stops; - } else { - stops = _cairo_malloc_ab (numstops, 5*sizeof (VGfloat)); - if (unlikely (stops == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - for (i = 0; i < numstops; i++) { - stops[i*5 + 0] = pattern->stops[i].offset; - stops[i*5 + 1] = pattern->stops[i].color.red; - stops[i*5 + 2] = pattern->stops[i].color.green; - stops[i*5 + 3] = pattern->stops[i].color.blue; - stops[i*5 + 4] = pattern->stops[i].color.alpha * context->alpha; - } - - vgSetParameterfv (context->paint, - VG_PAINT_COLOR_RAMP_STOPS, numstops * 5, stops); - - if (stops != stack_stops) - free (stops); - - CHECK_VG_ERRORS(); - return CAIRO_STATUS_SUCCESS; -} - -static void -_vg_set_source_matrix (const cairo_pattern_t *pat) -{ - cairo_matrix_t mat; - cairo_status_t status; - VGfloat vmat[9]; - - mat = pat->matrix; - status = cairo_matrix_invert (&mat); - assert (status == CAIRO_STATUS_SUCCESS); - - _vg_matrix_from_cairo (vmat, &mat); - - vgSeti (VG_MATRIX_MODE, VG_MATRIX_FILL_PAINT_TO_USER); - vgLoadMatrix (vmat); - vgSeti (VG_MATRIX_MODE, VG_MATRIX_STROKE_PAINT_TO_USER); - vgLoadMatrix (vmat); - vgSeti (VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); - - CHECK_VG_ERRORS(); -} - -static cairo_status_t -_vg_setup_linear_source (cairo_vg_context_t *context, - const cairo_linear_pattern_t *lpat) -{ - VGfloat linear[4]; - - linear[0] = lpat->pd1.x; - linear[1] = lpat->pd1.y; - linear[2] = lpat->pd2.x; - linear[3] = lpat->pd2.y; - - vgSetParameteri (context->paint, - VG_PAINT_COLOR_RAMP_SPREAD_MODE, - VG_COLOR_RAMP_SPREAD_PAD); - vgSetParameteri (context->paint, - VG_PAINT_TYPE, - VG_PAINT_TYPE_LINEAR_GRADIENT); - vgSetParameterfv (context->paint, - VG_PAINT_LINEAR_GRADIENT, 4, linear); - - _vg_set_source_matrix (&lpat->base.base); - - CHECK_VG_ERRORS(); - return _vg_setup_gradient_stops (context, &lpat->base); - -} - -static cairo_status_t -_vg_setup_radial_source (cairo_vg_context_t *context, - const cairo_radial_pattern_t *rpat) -{ - VGfloat radial[5]; - - radial[0] = rpat->cd1.center.x; - radial[1] = rpat->cd1.center.y; - radial[2] = rpat->cd2.center.x; - radial[3] = rpat->cd2.center.y; - radial[4] = rpat->cd2.radius; - - vgSetParameteri (context->paint, - VG_PAINT_COLOR_RAMP_SPREAD_MODE, VG_COLOR_RAMP_SPREAD_PAD); - vgSetParameteri (context->paint, - VG_PAINT_TYPE, VG_PAINT_TYPE_RADIAL_GRADIENT); - vgSetParameterfv (context->paint, - VG_PAINT_RADIAL_GRADIENT, 5, radial); - - _vg_set_source_matrix (&rpat->base.base); - - /* FIXME: copy/adapt fixes from SVG backend to add inner radius */ - - CHECK_VG_ERRORS(); - return _vg_setup_gradient_stops (context, &rpat->base); -} - -static cairo_status_t -_vg_setup_solid_source (cairo_vg_context_t *context, - const cairo_solid_pattern_t *spat) -{ - VGfloat color[] = { - spat->color.red, - spat->color.green, - spat->color.blue, - spat->color.alpha * context->alpha - }; - - vgSetParameteri (context->paint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR); - vgSetParameterfv (context->paint, VG_PAINT_COLOR, 4, color); - - CHECK_VG_ERRORS(); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_vg_surface_t * -_vg_clone_recording_surface (cairo_vg_context_t *context, - cairo_surface_t *surface) -{ - VGImage vg_image; - VGImageFormat format; - cairo_status_t status; - cairo_rectangle_int_t extents; - cairo_vg_surface_t *clone; - - status = _cairo_surface_get_extents (surface, &extents); - if (status) - return NULL; - - if (extents.width > vgGeti (VG_MAX_IMAGE_WIDTH) || - extents.height > vgGeti (VG_MAX_IMAGE_HEIGHT)) - { - return NULL; - } - - format = _vg_format_for_content (surface->content); - - /* NONALIASED, FASTER, BETTER */ - vg_image = vgCreateImage (format, - extents.width, extents.height, - VG_IMAGE_QUALITY_FASTER); - clone = (cairo_vg_surface_t *) - _vg_surface_create_internal (context, vg_image, format, - extents.width, extents.height); - cairo_surface_set_device_offset (&clone->base, -extents.x, -extents.y); - - status = _cairo_recording_surface_replay (surface, &clone->base); - if (unlikely (status)) { - cairo_surface_destroy (&clone->base); - return (cairo_vg_surface_t *) _cairo_surface_create_in_error (status); - } - - return clone; -} - -static cairo_vg_surface_t * -_vg_clone_image_surface (cairo_vg_context_t *context, - cairo_surface_t *surface) -{ - cairo_image_surface_t *image; - void *image_extra; - cairo_status_t status; - VGImage vg_image; - VGImageFormat format; - cairo_rectangle_int_t extents; - cairo_vg_surface_t *clone; - - if (surface->backend->acquire_source_image == NULL) - return NULL; - - status = _cairo_surface_get_extents (surface, &extents); - if (status) - return NULL; - - if (extents.width > vgGeti (VG_MAX_IMAGE_WIDTH) || - extents.height > vgGeti (VG_MAX_IMAGE_HEIGHT)) - { - return NULL; - } - - status = _cairo_surface_acquire_source_image (surface, - &image, &image_extra); - if (unlikely (status)) - return (cairo_vg_surface_t *) _cairo_surface_create_in_error (status); - - format = _vg_format_from_pixman (image->pixman_format); - if (format == 0) - format = _vg_format_for_content (image->base.content); - - /* NONALIASED, FASTER, BETTER */ - vg_image = vgCreateImage (format, - image->width, image->height, - VG_IMAGE_QUALITY_FASTER); - clone = (cairo_vg_surface_t *) - _vg_surface_create_internal (context, vg_image, format, - image->width, image->height); - if (unlikely (clone->base.status)) - return clone; - - vgImageSubData (clone->image, - image->data, image->stride, - format, 0, 0, image->width, image->height); - - _cairo_surface_release_source_image (surface, image, image_extra); - - return clone; -} - -static void -_vg_surface_remove_from_cache (cairo_surface_t *abstract_surface) -{ - cairo_vg_surface_t *surface = (cairo_vg_surface_t *) abstract_surface; - - if (surface->snapshot_cache_entry.hash) { - cairo_vg_context_t *context; - - context = _vg_context_lock (surface->context); - _cairo_cache_remove (&context->snapshot_cache, - &surface->snapshot_cache_entry); - _vg_context_unlock (context); - - surface->snapshot_cache_entry.hash = 0; - } -} - -static cairo_status_t -_vg_setup_surface_source (cairo_vg_context_t *context, - const cairo_surface_pattern_t *spat) -{ - cairo_surface_t *snapshot; - cairo_vg_surface_t *clone; - cairo_status_t status; - - snapshot = _cairo_surface_has_snapshot (spat->surface, - &cairo_vg_surface_backend); - if (snapshot != NULL) { - clone = (cairo_vg_surface_t *) cairo_surface_reference (snapshot); - goto DONE; - } - - if (_cairo_surface_is_recording (spat->surface)) - clone = _vg_clone_recording_surface (context, spat->surface); - else - clone = _vg_clone_image_surface (context, spat->surface); - if (clone == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - if (unlikely (clone->base.status)) - return clone->base.status; - - clone->snapshot_cache_entry.hash = clone->base.unique_id; - status = _cairo_cache_insert (&context->snapshot_cache, - &clone->snapshot_cache_entry); - if (unlikely (status)) { - clone->snapshot_cache_entry.hash = 0; - cairo_surface_destroy (&clone->base); - return status; - } - - _cairo_surface_attach_snapshot (spat->surface, &clone->base, - _vg_surface_remove_from_cache); - -DONE: - cairo_surface_destroy (&context->source->base); - context->source = clone; - - vgSetParameteri (context->paint, VG_PAINT_TYPE, VG_PAINT_TYPE_PATTERN); - - switch (spat->base.extend) { - case CAIRO_EXTEND_PAD: - vgSetParameteri (context->paint, - VG_PAINT_PATTERN_TILING_MODE, - VG_TILE_PAD); - break; - - case CAIRO_EXTEND_NONE: - vgSetParameteri (context->paint, - VG_PAINT_PATTERN_TILING_MODE, - VG_TILE_FILL); - { - VGfloat color[] = {0,0,0,0}; - vgSetfv (VG_TILE_FILL_COLOR, 4, color); - } - break; - - case CAIRO_EXTEND_REPEAT: - vgSetParameteri (context->paint, - VG_PAINT_PATTERN_TILING_MODE, - VG_TILE_REPEAT); - break; - - default: - ASSERT_NOT_REACHED; - case CAIRO_EXTEND_REFLECT: - vgSetParameteri (context->paint, - VG_PAINT_PATTERN_TILING_MODE, - VG_TILE_REFLECT); - break; - } - vgPaintPattern (context->paint, context->source->image); - - _vg_set_source_matrix (&spat->base); - - CHECK_VG_ERRORS(); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -setup_source (cairo_vg_context_t *context, - const cairo_pattern_t *source) -{ - switch (source->type) { - case CAIRO_PATTERN_TYPE_SOLID: - return _vg_setup_solid_source (context, - (cairo_solid_pattern_t *) source); - case CAIRO_PATTERN_TYPE_LINEAR: - return _vg_setup_linear_source (context, - (cairo_linear_pattern_t *) source); - case CAIRO_PATTERN_TYPE_RADIAL: - return _vg_setup_radial_source (context, - (cairo_radial_pattern_t *) source); - case CAIRO_PATTERN_TYPE_SURFACE: - return _vg_setup_surface_source (context, - (cairo_surface_pattern_t *) source); - default: - ASSERT_NOT_REACHED; - return CAIRO_INT_STATUS_UNSUPPORTED; - } -} - -static cairo_int_status_t -_vg_surface_stroke (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_vg_surface_t *surface = abstract_surface; - cairo_vg_context_t *context; - cairo_status_t status; - VGfloat state[9]; - VGfloat strokeTransform[9]; - vg_path_t vg_path; - - if (! _vg_is_supported_operator (op)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - context = _vg_context_lock (surface->context); - status = _vg_context_set_target (context, surface); - if (status) { - _vg_context_unlock (context); - return status; - } - - status = setup_source (context, source); - if (status) { - _vg_context_unlock (context); - return status; - } - - status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); - if (unlikely (status)) { - _vg_context_unlock (context); - return status; - } - - vg_path.path = vgCreatePath (VG_PATH_FORMAT_STANDARD, - VG_PATH_DATATYPE_F, - 1, 0, 0, 0, - VG_PATH_CAPABILITY_ALL); - - vgGetMatrix (state); - _vg_matrix_from_cairo (strokeTransform, ctm); - vgMultMatrix (strokeTransform); - - vg_path.ctm_inverse = ctm_inverse; - - _vg_path_from_cairo (&vg_path, path); - - /* XXX DASH_PATTERN, DASH_PHASE */ - vgSetf (VG_STROKE_LINE_WIDTH, style->line_width); - vgSetf (VG_STROKE_MITER_LIMIT, style->miter_limit); - vgSetf (VG_STROKE_JOIN_STYLE, _vg_line_join_from_cairo (style->line_join)); - vgSetf (VG_STROKE_CAP_STYLE, _vg_line_cap_from_cairo (style->line_cap)); - - vgSeti (VG_BLEND_MODE, _vg_operator (op)); - - vgSetPaint (context->paint, VG_STROKE_PATH); - - vgDrawPath (vg_path.path, VG_STROKE_PATH); - - vgDestroyPath (vg_path.path); - - vgLoadMatrix (state); - - CHECK_VG_ERRORS(); - _vg_context_unlock (context); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_vg_surface_fill (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_vg_surface_t *surface = abstract_surface; - cairo_vg_context_t *context; - cairo_status_t status; - vg_path_t vg_path; - - if (op == CAIRO_OPERATOR_DEST) - return CAIRO_STATUS_SUCCESS; - - if (! _vg_is_supported_operator (op)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - context = _vg_context_lock (surface->context); - status = _vg_context_set_target (context, surface); - if (status) { - _vg_context_unlock (context); - return status; - } - - status = setup_source (context, source); - if (status) { - _vg_context_unlock (context); - return status; - } - - status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); - if (unlikely (status)) { - _vg_context_unlock (context); - return status; - } - - vg_path.path = vgCreatePath (VG_PATH_FORMAT_STANDARD, - VG_PATH_DATATYPE_F, - 1, 0, - 0, 0, - VG_PATH_CAPABILITY_ALL); - vg_path.ctm_inverse = NULL; - - _vg_path_from_cairo (&vg_path, path); - - /* XXX tolerance */ - - vgSeti (VG_BLEND_MODE, _vg_operator (op)); - vgSetf (VG_FILL_RULE, _vg_fill_rule_from_cairo (fill_rule)); - vgSetf (VG_RENDERING_QUALITY, _vg_rendering_quality_from_cairo (antialias)); - - vgSetPaint (context->paint, VG_FILL_PATH); - - vgDrawPath (vg_path.path, VG_FILL_PATH); - - vgDestroyPath (vg_path.path); - - _vg_context_unlock (context); - - CHECK_VG_ERRORS(); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_vg_surface_paint (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - cairo_vg_surface_t *surface = abstract_surface; - cairo_vg_context_t *context; - cairo_status_t status; - - if (op == CAIRO_OPERATOR_DEST) - return CAIRO_STATUS_SUCCESS; - - if (! _vg_is_supported_operator (op)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - context = _vg_context_lock (surface->context); - status = _vg_context_set_target (context, surface); - if (status) { - _vg_context_unlock (context); - return status; - } - - status = setup_source (context, source); - if (status) { - _vg_context_unlock (context); - return status; - } - - status = _cairo_surface_clipper_set_clip (&surface->clipper, clip); - if (unlikely (status)) { - _vg_context_unlock (context); - return status; - } - - vgSeti (VG_BLEND_MODE, _vg_operator (op)); - vgSetPaint (context->paint, VG_FILL_PATH); - - { /* creating a rectangular path that should cover the extent */ - VGubyte segs[] = { - VG_MOVE_TO_ABS, VG_LINE_TO_ABS, - VG_LINE_TO_ABS, VG_LINE_TO_ABS, - VG_CLOSE_PATH - }; - VGfloat data[] = { - 0, 0, - surface->width, 0, - surface->width, surface->height, - 0, surface->height - }; - VGPath fullext; - - fullext = vgCreatePath (VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, - 1,0,0,0, VG_PATH_CAPABILITY_ALL); - vgAppendPathData (fullext, sizeof(segs), segs, data); - - vgDrawPath (fullext, VG_FILL_PATH); - - vgDestroyPath (fullext); - } - - _vg_context_unlock (context); - - CHECK_VG_ERRORS(); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_vg_surface_mask (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - cairo_vg_surface_t *surface = abstract_surface; - cairo_status_t status; - - if (! _vg_is_supported_operator (op)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* Handle paint-with-alpha to do fades cheaply */ - if (mask->type == CAIRO_PATTERN_TYPE_SOLID) { - cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) mask; - cairo_vg_context_t *context = _vg_context_lock (surface->context); - double alpha = context->alpha; - - context->alpha = solid->color.alpha; - status = _vg_surface_paint (abstract_surface, op, source, clip); - context->alpha = alpha; - - _vg_context_unlock (context); - - return status; - } - - return CAIRO_INT_STATUS_UNSUPPORTED; -} - -static void -_vg_surface_get_font_options (void *abstract_surface, - cairo_font_options_t *options) -{ - _cairo_font_options_init_default (options); - - cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_ON); - _cairo_font_options_set_round_glyph_positions (options, CAIRO_ROUND_GLYPH_POS_OFF); -} - -static cairo_int_status_t -_vg_surface_show_glyphs (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - cairo_status_t status = CAIRO_STATUS_SUCCESS; - cairo_path_fixed_t path; - - if (num_glyphs <= 0) - return CAIRO_STATUS_SUCCESS; - - _cairo_path_fixed_init (&path); - - /* XXX Glyph cache! OpenVG font support in 1.1? */ - - status = _cairo_scaled_font_glyph_path (scaled_font, - glyphs, num_glyphs, - &path); - if (unlikely (status)) - goto BAIL; - - status = _vg_surface_fill (abstract_surface, - op, source, &path, - CAIRO_FILL_RULE_WINDING, - CAIRO_GSTATE_TOLERANCE_DEFAULT, - CAIRO_ANTIALIAS_DEFAULT, - clip); -BAIL: - _cairo_path_fixed_fini (&path); - return status; -} - -static inline int -multiply_alpha (int alpha, int color) -{ - int temp = alpha * color + 0x80; - return (temp + (temp >> 8)) >> 8; -} - -static void -premultiply_argb (uint8_t *data, - int width, - int height, - int stride) -{ - int i; - - while (height --) { - uint32_t *row = (uint32_t *) data; - - for (i = 0; i < width; i++) { - uint32_t p = row[i]; - uint8_t alpha; - - alpha = p >> 24; - if (alpha == 0) { - row[i] = 0; - } else if (alpha != 0xff) { - uint8_t r = multiply_alpha (alpha, (p >> 16) & 0xff); - uint8_t g = multiply_alpha (alpha, (p >> 8) & 0xff); - uint8_t b = multiply_alpha (alpha, (p >> 0) & 0xff); - row[i] = (alpha << 24) | (r << 16) | (g << 8) | (b << 0); - } - } - - data += stride; - } -} - -static cairo_int_status_t -_vg_get_image (cairo_vg_surface_t *surface, - int x, int y, - int width, int height, - cairo_image_surface_t **image_out) -{ - cairo_image_surface_t *image; - pixman_image_t *pixman_image; - pixman_format_code_t pixman_format; - cairo_bool_t needs_premultiply; - - pixman_format = _vg_format_to_pixman (surface->format, - &needs_premultiply); - if (pixman_format == 0) - return CAIRO_INT_STATUS_UNSUPPORTED; - - pixman_image = pixman_image_create_bits (pixman_format, - width, height, - NULL, 0); - if (unlikely (pixman_image == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - vgFinish (); - CHECK_VG_ERRORS(); - - vgGetImageSubData (surface->image, - pixman_image_get_data (pixman_image), - pixman_image_get_stride (pixman_image), - surface->format, - x, y, width, height); - - image = (cairo_image_surface_t *) - _cairo_image_surface_create_for_pixman_image (pixman_image, - pixman_format); - if (unlikely (image->base.status)) { - pixman_image_unref (pixman_image); - return image->base.status; - } - - if (needs_premultiply) - premultiply_argb (image->data, width, height, image->stride); - - *image_out = image; - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_vg_surface_acquire_source_image (void *abstract_surface, - cairo_image_surface_t **image_out, - void **image_extra) -{ - cairo_vg_surface_t *surface = abstract_surface; - - CHECK_VG_ERRORS(); - *image_extra = NULL; - return _vg_get_image (surface, - 0, 0, surface->width, surface->height, - image_out); -} - -static void -_vg_surface_release_source_image (void *abstract_surface, - cairo_image_surface_t *image, - void *image_extra) -{ - cairo_surface_destroy (&image->base); -} - -static cairo_status_t -_vg_surface_finish (void *abstract_surface) -{ - cairo_vg_surface_t *surface = abstract_surface; - cairo_vg_context_t *context = _vg_context_lock (surface->context); - - if (surface->snapshot_cache_entry.hash) { - _cairo_cache_remove (&context->snapshot_cache, - &surface->snapshot_cache_entry); - - surface->snapshot_cache_entry.hash = 0; - } - - _cairo_surface_clipper_reset (&surface->clipper); - - if (surface->own_image) - vgDestroyImage (surface->image); - - _vg_context_destroy_target (context, surface); - - _vg_context_unlock (context); - _vg_context_destroy (context); - - CHECK_VG_ERRORS(); - return CAIRO_STATUS_SUCCESS; -} - -static const cairo_surface_backend_t cairo_vg_surface_backend = { - CAIRO_SURFACE_TYPE_VG, - _vg_surface_finish, - - _cairo_default_context_create, /* XXX */ - - _vg_surface_create_similar, - NULL, /* create similar image */ - NULL, /* map to image */ - NULL, /* unmap image */ - - _cairo_surface_default_source, - _vg_surface_acquire_source_image, - _vg_surface_release_source_image, - NULL, /* snapshot */ - - NULL, /* copy_page */ - NULL, /* show_page */ - - _vg_surface_get_extents, - _vg_surface_get_font_options, /* get_font_options */ - - NULL, /* flush */ - NULL, /* mark dirty */ - - _vg_surface_paint, - _vg_surface_mask, - _vg_surface_stroke, - _vg_surface_fill, - NULL, /* fill-stroke */ - _vg_surface_show_glyphs, -}; - -static cairo_surface_t * -_vg_surface_create_internal (cairo_vg_context_t *context, - VGImage image, - VGImageFormat format, - int width, int height) -{ - cairo_vg_surface_t *surface; - - surface = malloc (sizeof (cairo_vg_surface_t)); - if (unlikely (surface == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - surface->context = _vg_context_reference (context); - - surface->image = image; - surface->format = format; - - _cairo_surface_init (&surface->base, - &cairo_vg_surface_backend, - NULL, /* device */ - _vg_format_to_content (format)); - - surface->width = width; - surface->height = height; - - _cairo_surface_clipper_init (&surface->clipper, - _vg_surface_clipper_intersect_clip_path); - - surface->snapshot_cache_entry.hash = 0; - - surface->target_id = 0; - - CHECK_VG_ERRORS(); - return &surface->base; -} - -cairo_surface_t * -cairo_vg_surface_create_for_image (cairo_vg_context_t *context, - VGImage image, - VGImageFormat format, - int width, int height) -{ - cairo_bool_t premult; - - if (context->status) - return _cairo_surface_create_in_error (context->status); - - if (image == VG_INVALID_HANDLE) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - if (_vg_format_to_pixman (format, &premult) == 0) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT)); - - return _vg_surface_create_internal (context, image, format, width, height); -} - -cairo_surface_t * -cairo_vg_surface_create (cairo_vg_context_t *context, - cairo_content_t content, - int width, - int height) -{ - VGImage image; - VGImageFormat format; - cairo_surface_t *surface; - - if (context->status) - return _cairo_surface_create_in_error (context->status); - - if (! CAIRO_CONTENT_VALID (content)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT)); - - if (width > vgGeti (VG_MAX_IMAGE_WIDTH) || - height > vgGeti (VG_MAX_IMAGE_HEIGHT)) - { - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE)); - } - - - format = _vg_format_for_content (content); - image = vgCreateImage (format, width, height, VG_IMAGE_QUALITY_BETTER); - if (image == VG_INVALID_HANDLE) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - surface = _vg_surface_create_internal (context, - image, format, width, height); - if (unlikely (surface->status)) - return surface; - - ((cairo_vg_surface_t *) surface)->own_image = TRUE; - return surface; -} -slim_hidden_def (cairo_vg_surface_create); - -VGImage -cairo_vg_surface_get_image (cairo_surface_t *abstract_surface) -{ - cairo_vg_surface_t *surface; - - if (abstract_surface->backend != &cairo_vg_surface_backend) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return VG_INVALID_HANDLE; - } - - surface = (cairo_vg_surface_t *) abstract_surface; - return surface->image; -} - -int -cairo_vg_surface_get_width (cairo_surface_t *abstract_surface) -{ - cairo_vg_surface_t *surface; - - if (abstract_surface->backend != &cairo_vg_surface_backend) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return 0; - } - - surface = (cairo_vg_surface_t *) abstract_surface; - return surface->width; -} - -int -cairo_vg_surface_get_height (cairo_surface_t *abstract_surface) -{ - cairo_vg_surface_t *surface; - - if (abstract_surface->backend != &cairo_vg_surface_backend) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return 0; - } - - surface = (cairo_vg_surface_t *) abstract_surface; - return surface->height; -} - -VGImageFormat -cairo_vg_surface_get_format (cairo_surface_t *abstract_surface) -{ - cairo_vg_surface_t *surface; - - if (abstract_surface->backend != &cairo_vg_surface_backend) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return 0; - } - - surface = (cairo_vg_surface_t *) abstract_surface; - return surface->format; -} - -/* GL specific context support :-( - * - * OpenVG like cairo defers creation of surface (and the necessary - * paraphernalia to the application. - */ - -static const cairo_vg_context_t _vg_context_nil = { - CAIRO_STATUS_NO_MEMORY, - CAIRO_REFERENCE_COUNT_INVALID -}; - -static const cairo_vg_context_t _vg_context_nil_invalid_visual = { - CAIRO_STATUS_INVALID_VISUAL, - CAIRO_REFERENCE_COUNT_INVALID -}; - -#if CAIRO_HAS_GLX_FUNCTIONS -#include <GL/glx.h> - -static cairo_status_t -glx_create_target (cairo_vg_context_t *context, - cairo_vg_surface_t *surface) -{ - /* XXX hmm, magic required for creating an FBO points to VGImage! */ - return CAIRO_INT_STATUS_UNSUPPORTED; -} - -static cairo_status_t -glx_set_target (cairo_vg_context_t *context, - cairo_vg_surface_t *surface) -{ -#if 0 - glXMakeContextCurrent (context->display, - (GLXDrawable) surface->target_id, - (GLXDrawable) surface->target_id, - context->context); -#else - return CAIRO_INT_STATUS_UNSUPPORTED; -#endif -} - -static void -glx_destroy_target (cairo_vg_context_t *context, - cairo_vg_surface_t *surface) -{ -} - -cairo_vg_context_t * -cairo_vg_context_create_for_glx (Display *dpy, GLXContext ctx) -{ - cairo_vg_context_t *context; - cairo_status_t status; - - context = malloc (sizeof (*context)); - if (unlikely (context == NULL)) - return (cairo_vg_context_t *) &_vg_context_nil; - - context->display = dpy; - context->context = ctx; - - context->create_target = glx_create_target; - context->set_target = glx_set_target; - context->destroy_target = glx_destroy_target; - - status = _vg_context_init (context); - if (unlikely (status)) { - free (context); - return (cairo_vg_context_t *) &_vg_context_nil; - } - - return context; -} -#endif - -#if CAIRO_HAS_EGL_FUNCTIONS -static cairo_status_t -egl_create_target (cairo_vg_context_t *context, - cairo_vg_surface_t *surface) -{ - EGLSurface *egl_surface; -#define RED 1 -#define GREEN 3 -#define BLUE 5 -#define ALPHA 7 - int attribs[] = { - EGL_RED_SIZE, 0, - EGL_GREEN_SIZE, 0, - EGL_BLUE_SIZE, 0, - EGL_ALPHA_SIZE, 0, - EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, - EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT, - EGL_NONE - }; - pixman_format_code_t pixman_format; - EGLConfig config; - int num_configs = 0; - cairo_bool_t needs_premultiply; - - pixman_format = _vg_format_to_pixman (surface->format, &needs_premultiply); - if (pixman_format == 0) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* XXX no control over pixel ordering! */ - attribs[RED] = PIXMAN_FORMAT_R (pixman_format); - attribs[GREEN] = PIXMAN_FORMAT_G (pixman_format); - attribs[BLUE] = PIXMAN_FORMAT_B (pixman_format); - attribs[ALPHA] = PIXMAN_FORMAT_A (pixman_format); - - if (! eglChooseConfig (context->display, - attribs, - &config, 1, &num_configs) || - num_configs != 1) - { - fprintf(stderr, "Error: eglChooseConfig() failed.\n"); - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - egl_surface = - eglCreatePbufferFromClientBuffer (context->display, - EGL_OPENVG_IMAGE, - (EGLClientBuffer) surface->image, - config, - NULL); - surface->target_id = (unsigned long) egl_surface; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -egl_set_target (cairo_vg_context_t *context, - cairo_vg_surface_t *surface) -{ - if (! eglMakeCurrent (context->display, - (EGLSurface *) surface->target_id, - (EGLSurface *) surface->target_id, - context->context)) - { - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - return CAIRO_STATUS_SUCCESS; -} - -static void -egl_destroy_target (cairo_vg_context_t *context, - cairo_vg_surface_t *surface) -{ - eglDestroySurface (context->display, - (EGLSurface *) surface->target_id); -} - -cairo_vg_context_t * -cairo_vg_context_create_for_egl (EGLDisplay egl_display, - EGLContext egl_context) -{ - cairo_vg_context_t *context; - cairo_status_t status; - - context = malloc (sizeof (*context)); - if (unlikely (context == NULL)) - return (cairo_vg_context_t *) &_vg_context_nil; - - status = _vg_context_init (context); - if (unlikely (status)) { - free (context); - return (cairo_vg_context_t *) &_vg_context_nil; - } - - context->display = egl_display; - context->context = egl_context; - - context->create_target = egl_create_target; - context->set_target = egl_set_target; - context->destroy_target = egl_destroy_target; - - return context; -} -#endif - -cairo_status_t -cairo_vg_context_status (cairo_vg_context_t *context) -{ - return context->status; -} - -void -cairo_vg_context_destroy (cairo_vg_context_t *context) -{ - if (context == NULL || CAIRO_REFERENCE_COUNT_IS_INVALID (&context->ref_count)) - return; - - _vg_context_destroy (context); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-vg.h b/source/libs/cairo/cairo-src/src/cairo-vg.h deleted file mode 100644 index f9a62e51c6986551c0669fb65ec756e21d19db37..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-vg.h +++ /dev/null @@ -1,103 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2007 * Mozilla Corporation - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Mozilla Corporation. - * - * Contributor(s): - * Vladimir Vukicevic <vladimir@mozilla.com> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_VG_H -#define CAIRO_VG_H - -#include "cairo.h" - -#if CAIRO_HAS_VG_SURFACE - -#include <VG/openvg.h> - -CAIRO_BEGIN_DECLS - -typedef struct _cairo_vg_context cairo_vg_context_t; - -#if CAIRO_HAS_GLX_FUNCTIONS -typedef struct __GLXcontextRec *GLXContext; -typedef struct _XDisplay Display; - -cairo_public cairo_vg_context_t * -cairo_vg_context_create_for_glx (Display *dpy, - GLXContext ctx); -#endif - -#if CAIRO_HAS_EGL_FUNCTIONS -#include <EGL/egl.h> - -cairo_public cairo_vg_context_t * -cairo_vg_context_create_for_egl (EGLDisplay egl_display, - EGLContext egl_context); -#endif - -cairo_public cairo_status_t -cairo_vg_context_status (cairo_vg_context_t *context); - -cairo_public void -cairo_vg_context_destroy (cairo_vg_context_t *context); - -cairo_public cairo_surface_t * -cairo_vg_surface_create (cairo_vg_context_t *context, - cairo_content_t content, int width, int height); - -cairo_public cairo_surface_t * -cairo_vg_surface_create_for_image (cairo_vg_context_t *context, - VGImage image, - VGImageFormat format, - int width, int height); - -cairo_public VGImage -cairo_vg_surface_get_image (cairo_surface_t *abstract_surface); - -cairo_public VGImageFormat -cairo_vg_surface_get_format (cairo_surface_t *abstract_surface); - -cairo_public int -cairo_vg_surface_get_height (cairo_surface_t *abstract_surface); - -cairo_public int -cairo_vg_surface_get_width (cairo_surface_t *abstract_surface); - -CAIRO_END_DECLS - -#else /* CAIRO_HAS_VG_SURFACE*/ -# error Cairo was not compiled with support for the OpenVG backend -#endif /* CAIRO_HAS_VG_SURFACE*/ - -#endif /* CAIRO_VG_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-wgl-context.c b/source/libs/cairo/cairo-src/src/cairo-wgl-context.c deleted file mode 100644 index 4872374464827f705ccd851c7958aafc2a0661fe..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-wgl-context.c +++ /dev/null @@ -1,261 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Eric Anholt - * Copyright © 2009 Chris Wilson - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Carl Worth <cworth@cworth.org> - * Chris Wilson <chris@chris-wilson.co.uk> - * Zoxc <zoxc32@gmail.com> - */ - -#include "cairoint.h" - -#include "cairo-gl-private.h" - -#include "cairo-error-private.h" - -#define WIN32_LEAN_AND_MEAN -#include <windows.h> - -typedef struct _cairo_wgl_context { - cairo_gl_context_t base; - - HDC dummy_dc; - HWND dummy_wnd; - HGLRC rc; - - HDC prev_dc; - HGLRC prev_rc; -} cairo_wgl_context_t; - -typedef struct _cairo_wgl_surface { - cairo_gl_surface_t base; - - HDC dc; -} cairo_wgl_surface_t; - -static void -_wgl_acquire (void *abstract_ctx) -{ - cairo_wgl_context_t *ctx = abstract_ctx; - - HDC current_dc; - - ctx->prev_dc = wglGetCurrentDC (); - ctx->prev_rc = wglGetCurrentContext (); - - if (ctx->base.current_target == NULL || - _cairo_gl_surface_is_texture (ctx->base.current_target)) - { - current_dc = ctx->dummy_dc; - } - else - { - cairo_wgl_surface_t *surface = (cairo_wgl_surface_t *) ctx->base.current_target; - current_dc = surface->dc; - } - - if (ctx->prev_dc != current_dc || - (ctx->prev_rc != ctx->rc && - current_dc != ctx->dummy_dc)) - { - wglMakeCurrent (current_dc, ctx->rc); - } -} - -static void -_wgl_make_current (void *abstract_ctx, cairo_gl_surface_t *abstract_surface) -{ - cairo_wgl_context_t *ctx = abstract_ctx; - cairo_wgl_surface_t *surface = (cairo_wgl_surface_t *) abstract_surface; - - /* Set the window as the target of our context. */ - wglMakeCurrent (surface->dc, ctx->rc); -} - -static void -_wgl_release (void *abstract_ctx) -{ - cairo_wgl_context_t *ctx = abstract_ctx; - - if (ctx->prev_dc != wglGetCurrentDC () || - ctx->prev_rc != wglGetCurrentContext ()) - { - wglMakeCurrent (ctx->prev_dc, - ctx->prev_rc); - } -} - -static void -_wgl_swap_buffers (void *abstract_ctx, - cairo_gl_surface_t *abstract_surface) -{ - cairo_wgl_surface_t *surface = (cairo_wgl_surface_t *) abstract_surface; - - SwapBuffers (surface->dc); -} - -static void -_wgl_destroy (void *abstract_ctx) -{ - cairo_wgl_context_t *ctx = abstract_ctx; - - if (ctx->dummy_dc != 0) { - wglMakeCurrent (ctx->dummy_dc, 0); - ReleaseDC (ctx->dummy_wnd, ctx->dummy_dc); - DestroyWindow (ctx->dummy_wnd); - } -} - -static cairo_status_t -_wgl_dummy_ctx (cairo_wgl_context_t *ctx) -{ - WNDCLASSEXA wincl; - PIXELFORMATDESCRIPTOR pfd; - int format; - HDC dc; - - ZeroMemory (&wincl, sizeof (WNDCLASSEXA)); - wincl.cbSize = sizeof (WNDCLASSEXA); - wincl.hInstance = GetModuleHandle (0); - wincl.lpszClassName = "cairo_wgl_context_dummy"; - wincl.lpfnWndProc = DefWindowProcA; - wincl.style = CS_OWNDC; - - RegisterClassExA (&wincl); - - ctx->dummy_wnd = CreateWindowA ("cairo_wgl_context_dummy", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - ctx->dummy_dc = GetDC (ctx->dummy_wnd); - - ZeroMemory (&pfd, sizeof (PIXELFORMATDESCRIPTOR)); - pfd.nSize = sizeof (PIXELFORMATDESCRIPTOR); - pfd.nVersion = 1; - pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - pfd.iPixelType = PFD_TYPE_RGBA; - pfd.cColorBits = 24; - pfd.cDepthBits = 16; - pfd.iLayerType = PFD_MAIN_PLANE; - - format = ChoosePixelFormat (ctx->dummy_dc, &pfd); - SetPixelFormat (ctx->dummy_dc, format, &pfd); - - wglMakeCurrent(ctx->dummy_dc, ctx->rc); - - return CAIRO_STATUS_SUCCESS; -} - -cairo_device_t * -cairo_wgl_device_create (HGLRC rc) -{ - cairo_wgl_context_t *ctx; - cairo_status_t status; - - ctx = calloc (1, sizeof (cairo_wgl_context_t)); - if (unlikely (ctx == NULL)) - return _cairo_gl_context_create_in_error (CAIRO_STATUS_NO_MEMORY); - - ctx->rc = rc; - ctx->prev_dc = 0; - ctx->prev_rc = 0; - - status = _wgl_dummy_ctx (ctx); - if (unlikely (status)) { - free (ctx); - return _cairo_gl_context_create_in_error (status); - } - - ctx->base.acquire = _wgl_acquire; - ctx->base.release = _wgl_release; - ctx->base.make_current = _wgl_make_current; - ctx->base.swap_buffers = _wgl_swap_buffers; - ctx->base.destroy = _wgl_destroy; - - status = _cairo_gl_dispatch_init (&ctx->base.dispatch, - (cairo_gl_get_proc_addr_func_t) wglGetProcAddress); - if (unlikely (status)) { - free (ctx); - return _cairo_gl_context_create_in_error (status); - } - - status = _cairo_gl_context_init (&ctx->base); - if (unlikely (status)) { - free (ctx); - return _cairo_gl_context_create_in_error (status); - } - - ctx->base.release (ctx); - - return &ctx->base.base; -} - -HGLRC -cairo_wgl_device_get_context (cairo_device_t *device) -{ - cairo_wgl_context_t *ctx; - - if (device->backend->type != CAIRO_DEVICE_TYPE_GL) { - _cairo_error_throw (CAIRO_STATUS_DEVICE_TYPE_MISMATCH); - return NULL; - } - - ctx = (cairo_wgl_context_t *) device; - - return ctx->rc; -} - -cairo_surface_t * -cairo_gl_surface_create_for_dc (cairo_device_t *device, - HDC dc, - int width, - int height) -{ - cairo_wgl_surface_t *surface; - - if (unlikely (device->status)) - return _cairo_surface_create_in_error (device->status); - - if (device->backend->type != CAIRO_DEVICE_TYPE_GL) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH)); - - if (width <= 0 || height <= 0) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE)); - - surface = calloc (1, sizeof (cairo_wgl_surface_t)); - if (unlikely (surface == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - _cairo_gl_surface_init (device, &surface->base, - CAIRO_CONTENT_COLOR_ALPHA, width, height); - surface->dc = dc; - - return &surface->base.base; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-wideint-private.h b/source/libs/cairo/cairo-src/src/cairo-wideint-private.h deleted file mode 100644 index 3f5491bb1c026d0dd24768bb8d2f583993c2f169..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-wideint-private.h +++ /dev/null @@ -1,338 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2004 Keith Packard - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Keith Packard - * - * Contributor(s): - * Keith R. Packard <keithp@keithp.com> - * - */ - -#ifndef CAIRO_WIDEINT_H -#define CAIRO_WIDEINT_H - -#include "cairo-wideint-type-private.h" - -#include "cairo-compiler-private.h" - -/* - * 64-bit datatypes. Two separate implementations, one using - * built-in 64-bit signed/unsigned types another implemented - * as a pair of 32-bit ints - */ - -#define I cairo_private cairo_const - -#if !HAVE_UINT64_T - -cairo_uquorem64_t I -_cairo_uint64_divrem (cairo_uint64_t num, cairo_uint64_t den); - -cairo_uint64_t I _cairo_double_to_uint64 (double i); -double I _cairo_uint64_to_double (cairo_uint64_t i); -cairo_int64_t I _cairo_double_to_int64 (double i); -double I _cairo_int64_to_double (cairo_uint64_t i); - -cairo_uint64_t I _cairo_uint32_to_uint64 (uint32_t i); -#define _cairo_uint64_to_uint32(a) ((a).lo) -cairo_uint64_t I _cairo_uint64_add (cairo_uint64_t a, cairo_uint64_t b); -cairo_uint64_t I _cairo_uint64_sub (cairo_uint64_t a, cairo_uint64_t b); -cairo_uint64_t I _cairo_uint64_mul (cairo_uint64_t a, cairo_uint64_t b); -cairo_uint64_t I _cairo_uint32x32_64_mul (uint32_t a, uint32_t b); -cairo_uint64_t I _cairo_uint64_lsl (cairo_uint64_t a, int shift); -cairo_uint64_t I _cairo_uint64_rsl (cairo_uint64_t a, int shift); -cairo_uint64_t I _cairo_uint64_rsa (cairo_uint64_t a, int shift); -int I _cairo_uint64_lt (cairo_uint64_t a, cairo_uint64_t b); -int I _cairo_uint64_cmp (cairo_uint64_t a, cairo_uint64_t b); -int I _cairo_uint64_eq (cairo_uint64_t a, cairo_uint64_t b); -cairo_uint64_t I _cairo_uint64_negate (cairo_uint64_t a); -#define _cairo_uint64_is_zero(a) ((a).hi == 0 && (a).lo == 0) -#define _cairo_uint64_negative(a) (((int32_t) ((a).hi)) < 0) -cairo_uint64_t I _cairo_uint64_not (cairo_uint64_t a); - -#define _cairo_uint64_to_int64(i) (i) -#define _cairo_int64_to_uint64(i) (i) - -cairo_int64_t I _cairo_int32_to_int64(int32_t i); -#define _cairo_int64_to_int32(a) ((int32_t) _cairo_uint64_to_uint32(a)) -#define _cairo_int64_add(a,b) _cairo_uint64_add (a,b) -#define _cairo_int64_sub(a,b) _cairo_uint64_sub (a,b) -#define _cairo_int64_mul(a,b) _cairo_uint64_mul (a,b) -cairo_int64_t I _cairo_int32x32_64_mul (int32_t a, int32_t b); -int I _cairo_int64_lt (cairo_int64_t a, cairo_int64_t b); -int I _cairo_int64_cmp (cairo_int64_t a, cairo_int64_t b); -#define _cairo_int64_is_zero(a) _cairo_uint64_is_zero (a) -#define _cairo_int64_eq(a,b) _cairo_uint64_eq (a,b) -#define _cairo_int64_lsl(a,b) _cairo_uint64_lsl (a,b) -#define _cairo_int64_rsl(a,b) _cairo_uint64_rsl (a,b) -#define _cairo_int64_rsa(a,b) _cairo_uint64_rsa (a,b) -#define _cairo_int64_negate(a) _cairo_uint64_negate(a) -#define _cairo_int64_negative(a) (((int32_t) ((a).hi)) < 0) -#define _cairo_int64_not(a) _cairo_uint64_not(a) - -#else - -static inline cairo_uquorem64_t -_cairo_uint64_divrem (cairo_uint64_t num, cairo_uint64_t den) -{ - cairo_uquorem64_t qr; - - qr.quo = num / den; - qr.rem = num % den; - return qr; -} - -/* - * These need to be functions or gcc will complain when used on the - * result of a function: - * - * warning: cast from function call of type ‘#cairo_uint64_t’ to - * non-matching type ‘double’ - */ -static cairo_always_inline cairo_const cairo_uint64_t _cairo_double_to_uint64 (double i) { return i; } -static cairo_always_inline cairo_const double _cairo_uint64_to_double (cairo_uint64_t i) { return i; } - -static cairo_always_inline cairo_int64_t I _cairo_double_to_int64 (double i) { return i; } -static cairo_always_inline double I _cairo_int64_to_double (cairo_int64_t i) { return i; } - -#define _cairo_uint32_to_uint64(i) ((uint64_t) (i)) -#define _cairo_uint64_to_uint32(i) ((uint32_t) (i)) -#define _cairo_uint64_add(a,b) ((a) + (b)) -#define _cairo_uint64_sub(a,b) ((a) - (b)) -#define _cairo_uint64_mul(a,b) ((a) * (b)) -#define _cairo_uint32x32_64_mul(a,b) ((uint64_t) (a) * (b)) -#define _cairo_uint64_lsl(a,b) ((a) << (b)) -#define _cairo_uint64_rsl(a,b) ((uint64_t) (a) >> (b)) -#define _cairo_uint64_rsa(a,b) ((uint64_t) ((int64_t) (a) >> (b))) -#define _cairo_uint64_lt(a,b) ((a) < (b)) -#define _cairo_uint64_cmp(a,b) ((a) == (b) ? 0 : (a) < (b) ? -1 : 1) -#define _cairo_uint64_is_zero(a) ((a) == 0) -#define _cairo_uint64_eq(a,b) ((a) == (b)) -#define _cairo_uint64_negate(a) ((uint64_t) -((int64_t) (a))) -#define _cairo_uint64_negative(a) ((int64_t) (a) < 0) -#define _cairo_uint64_not(a) (~(a)) - -#define _cairo_uint64_to_int64(i) ((int64_t) (i)) -#define _cairo_int64_to_uint64(i) ((uint64_t) (i)) - -#define _cairo_int32_to_int64(i) ((int64_t) (i)) -#define _cairo_int64_to_int32(i) ((int32_t) (i)) -#define _cairo_int64_add(a,b) ((a) + (b)) -#define _cairo_int64_sub(a,b) ((a) - (b)) -#define _cairo_int64_mul(a,b) ((a) * (b)) -#define _cairo_int32x32_64_mul(a,b) ((int64_t) (a) * (b)) -#define _cairo_int64_lt(a,b) ((a) < (b)) -#define _cairo_int64_cmp(a,b) ((a) == (b) ? 0 : (a) < (b) ? -1 : 1) -#define _cairo_int64_is_zero(a) ((a) == 0) -#define _cairo_int64_eq(a,b) ((a) == (b)) -#define _cairo_int64_lsl(a,b) ((a) << (b)) -#define _cairo_int64_rsl(a,b) ((int64_t) ((uint64_t) (a) >> (b))) -#define _cairo_int64_rsa(a,b) ((int64_t) (a) >> (b)) -#define _cairo_int64_negate(a) (-(a)) -#define _cairo_int64_negative(a) ((a) < 0) -#define _cairo_int64_not(a) (~(a)) - -#endif - -/* - * 64-bit comparisons derived from lt or eq - */ -#define _cairo_uint64_le(a,b) (!_cairo_uint64_gt(a,b)) -#define _cairo_uint64_ne(a,b) (!_cairo_uint64_eq(a,b)) -#define _cairo_uint64_ge(a,b) (!_cairo_uint64_lt(a,b)) -#define _cairo_uint64_gt(a,b) _cairo_uint64_lt(b,a) - -#define _cairo_int64_le(a,b) (!_cairo_int64_gt(a,b)) -#define _cairo_int64_ne(a,b) (!_cairo_int64_eq(a,b)) -#define _cairo_int64_ge(a,b) (!_cairo_int64_lt(a,b)) -#define _cairo_int64_gt(a,b) _cairo_int64_lt(b,a) - -/* - * As the C implementation always computes both, create - * a function which returns both for the 'native' type as well - */ - -static inline cairo_quorem64_t -_cairo_int64_divrem (cairo_int64_t num, cairo_int64_t den) -{ - int num_neg = _cairo_int64_negative (num); - int den_neg = _cairo_int64_negative (den); - cairo_uquorem64_t uqr; - cairo_quorem64_t qr; - - if (num_neg) - num = _cairo_int64_negate (num); - if (den_neg) - den = _cairo_int64_negate (den); - uqr = _cairo_uint64_divrem (num, den); - if (num_neg) - qr.rem = _cairo_int64_negate (uqr.rem); - else - qr.rem = uqr.rem; - if (num_neg != den_neg) - qr.quo = (cairo_int64_t) _cairo_int64_negate (uqr.quo); - else - qr.quo = (cairo_int64_t) uqr.quo; - return qr; -} - -static inline int32_t -_cairo_int64_32_div (cairo_int64_t num, int32_t den) -{ -#if !HAVE_UINT64_T - return _cairo_int64_to_int32 - (_cairo_int64_divrem (num, _cairo_int32_to_int64 (den)).quo); -#else - return num / den; -#endif -} - -/* - * 128-bit datatypes. Again, provide two implementations in - * case the machine has a native 128-bit datatype. GCC supports int128_t - * on ia64 - */ - -#if !HAVE_UINT128_T - -cairo_uint128_t I _cairo_uint32_to_uint128 (uint32_t i); -cairo_uint128_t I _cairo_uint64_to_uint128 (cairo_uint64_t i); -#define _cairo_uint128_to_uint64(a) ((a).lo) -#define _cairo_uint128_to_uint32(a) _cairo_uint64_to_uint32(_cairo_uint128_to_uint64(a)) -cairo_uint128_t I _cairo_uint128_add (cairo_uint128_t a, cairo_uint128_t b); -cairo_uint128_t I _cairo_uint128_sub (cairo_uint128_t a, cairo_uint128_t b); -cairo_uint128_t I _cairo_uint128_mul (cairo_uint128_t a, cairo_uint128_t b); -cairo_uint128_t I _cairo_uint64x64_128_mul (cairo_uint64_t a, cairo_uint64_t b); -cairo_uint128_t I _cairo_uint128_lsl (cairo_uint128_t a, int shift); -cairo_uint128_t I _cairo_uint128_rsl (cairo_uint128_t a, int shift); -cairo_uint128_t I _cairo_uint128_rsa (cairo_uint128_t a, int shift); -int I _cairo_uint128_lt (cairo_uint128_t a, cairo_uint128_t b); -int I _cairo_uint128_cmp (cairo_uint128_t a, cairo_uint128_t b); -int I _cairo_uint128_eq (cairo_uint128_t a, cairo_uint128_t b); -#define _cairo_uint128_is_zero(a) (_cairo_uint64_is_zero ((a).hi) && _cairo_uint64_is_zero ((a).lo)) -cairo_uint128_t I _cairo_uint128_negate (cairo_uint128_t a); -#define _cairo_uint128_negative(a) (_cairo_uint64_negative(a.hi)) -cairo_uint128_t I _cairo_uint128_not (cairo_uint128_t a); - -#define _cairo_uint128_to_int128(i) (i) -#define _cairo_int128_to_uint128(i) (i) - -cairo_int128_t I _cairo_int32_to_int128 (int32_t i); -cairo_int128_t I _cairo_int64_to_int128 (cairo_int64_t i); -#define _cairo_int128_to_int64(a) ((cairo_int64_t) (a).lo) -#define _cairo_int128_to_int32(a) _cairo_int64_to_int32(_cairo_int128_to_int64(a)) -#define _cairo_int128_add(a,b) _cairo_uint128_add(a,b) -#define _cairo_int128_sub(a,b) _cairo_uint128_sub(a,b) -#define _cairo_int128_mul(a,b) _cairo_uint128_mul(a,b) -cairo_int128_t I _cairo_int64x64_128_mul (cairo_int64_t a, cairo_int64_t b); -#define _cairo_int64x32_128_mul(a, b) _cairo_int64x64_128_mul(a, _cairo_int32_to_int64(b)) -#define _cairo_int128_lsl(a,b) _cairo_uint128_lsl(a,b) -#define _cairo_int128_rsl(a,b) _cairo_uint128_rsl(a,b) -#define _cairo_int128_rsa(a,b) _cairo_uint128_rsa(a,b) -int I _cairo_int128_lt (cairo_int128_t a, cairo_int128_t b); -int I _cairo_int128_cmp (cairo_int128_t a, cairo_int128_t b); -#define _cairo_int128_is_zero(a) _cairo_uint128_is_zero (a) -#define _cairo_int128_eq(a,b) _cairo_uint128_eq (a,b) -#define _cairo_int128_negate(a) _cairo_uint128_negate(a) -#define _cairo_int128_negative(a) (_cairo_uint128_negative(a)) -#define _cairo_int128_not(a) _cairo_uint128_not(a) - -#else /* !HAVE_UINT128_T */ - -#define _cairo_uint32_to_uint128(i) ((uint128_t) (i)) -#define _cairo_uint64_to_uint128(i) ((uint128_t) (i)) -#define _cairo_uint128_to_uint64(i) ((uint64_t) (i)) -#define _cairo_uint128_to_uint32(i) ((uint32_t) (i)) -#define _cairo_uint128_add(a,b) ((a) + (b)) -#define _cairo_uint128_sub(a,b) ((a) - (b)) -#define _cairo_uint128_mul(a,b) ((a) * (b)) -#define _cairo_uint64x64_128_mul(a,b) ((uint128_t) (a) * (b)) -#define _cairo_uint128_lsl(a,b) ((a) << (b)) -#define _cairo_uint128_rsl(a,b) ((uint128_t) (a) >> (b)) -#define _cairo_uint128_rsa(a,b) ((uint128_t) ((int128_t) (a) >> (b))) -#define _cairo_uint128_lt(a,b) ((a) < (b)) -#define _cairo_uint128_cmp(a,b) ((a) == (b) ? 0 : (a) < (b) ? -1 : 1) -#define _cairo_uint128_is_zero(a) ((a) == 0) -#define _cairo_uint128_eq(a,b) ((a) == (b)) -#define _cairo_uint128_negate(a) ((uint128_t) -((int128_t) (a))) -#define _cairo_uint128_negative(a) ((int128_t) (a) < 0) -#define _cairo_uint128_not(a) (~(a)) - -#define _cairo_uint128_to_int128(i) ((int128_t) (i)) -#define _cairo_int128_to_uint128(i) ((uint128_t) (i)) - -#define _cairo_int32_to_int128(i) ((int128_t) (i)) -#define _cairo_int64_to_int128(i) ((int128_t) (i)) -#define _cairo_int128_to_int64(i) ((int64_t) (i)) -#define _cairo_int128_to_int32(i) ((int32_t) (i)) -#define _cairo_int128_add(a,b) ((a) + (b)) -#define _cairo_int128_sub(a,b) ((a) - (b)) -#define _cairo_int128_mul(a,b) ((a) * (b)) -#define _cairo_int64x64_128_mul(a,b) ((int128_t) (a) * (b)) -#define _cairo_int64x32_128_mul(a, b) _cairo_int64x64_128_mul(a, _cairo_int32_to_int64(b)) -#define _cairo_int128_lt(a,b) ((a) < (b)) -#define _cairo_int128_cmp(a,b) ((a) == (b) ? 0 : (a) < (b) ? -1 : 1) -#define _cairo_int128_is_zero(a) ((a) == 0) -#define _cairo_int128_eq(a,b) ((a) == (b)) -#define _cairo_int128_lsl(a,b) ((a) << (b)) -#define _cairo_int128_rsl(a,b) ((int128_t) ((uint128_t) (a) >> (b))) -#define _cairo_int128_rsa(a,b) ((int128_t) (a) >> (b)) -#define _cairo_int128_negate(a) (-(a)) -#define _cairo_int128_negative(a) ((a) < 0) -#define _cairo_int128_not(a) (~(a)) - -#endif /* HAVE_UINT128_T */ - -cairo_uquorem128_t I -_cairo_uint128_divrem (cairo_uint128_t num, cairo_uint128_t den); - -cairo_quorem128_t I -_cairo_int128_divrem (cairo_int128_t num, cairo_int128_t den); - -cairo_uquorem64_t I -_cairo_uint_96by64_32x64_divrem (cairo_uint128_t num, - cairo_uint64_t den); - -cairo_quorem64_t I -_cairo_int_96by64_32x64_divrem (cairo_int128_t num, - cairo_int64_t den); - -#define _cairo_uint128_le(a,b) (!_cairo_uint128_gt(a,b)) -#define _cairo_uint128_ne(a,b) (!_cairo_uint128_eq(a,b)) -#define _cairo_uint128_ge(a,b) (!_cairo_uint128_lt(a,b)) -#define _cairo_uint128_gt(a,b) _cairo_uint128_lt(b,a) - -#define _cairo_int128_le(a,b) (!_cairo_int128_gt(a,b)) -#define _cairo_int128_ne(a,b) (!_cairo_int128_eq(a,b)) -#define _cairo_int128_ge(a,b) (!_cairo_int128_lt(a,b)) -#define _cairo_int128_gt(a,b) _cairo_int128_lt(b,a) - -#undef I - -#endif /* CAIRO_WIDEINT_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-wideint-type-private.h b/source/libs/cairo/cairo-src/src/cairo-wideint-type-private.h deleted file mode 100644 index 84a3cbab0d204dedb63701e5f2822e74e3633461..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-wideint-type-private.h +++ /dev/null @@ -1,158 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2004 Keith Packard - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Keith Packard - * - * Contributor(s): - * Keith R. Packard <keithp@keithp.com> - * - */ - -#ifndef CAIRO_WIDEINT_TYPE_H -#define CAIRO_WIDEINT_TYPE_H - -#include "cairo.h" - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#if HAVE_STDINT_H -# include <stdint.h> -#elif HAVE_INTTYPES_H -# include <inttypes.h> -#elif HAVE_SYS_INT_TYPES_H -# include <sys/int_types.h> -#elif defined(_MSC_VER) - typedef __int8 int8_t; - typedef unsigned __int8 uint8_t; - typedef __int16 int16_t; - typedef unsigned __int16 uint16_t; - typedef __int32 int32_t; - typedef unsigned __int32 uint32_t; - typedef __int64 int64_t; - typedef unsigned __int64 uint64_t; -# ifndef HAVE_UINT64_T -# define HAVE_UINT64_T 1 -# endif -#else -#error Cannot find definitions for fixed-width integral types (uint8_t, uint32_t, etc.) -#endif - -#ifndef INT16_MIN -# define INT16_MIN (-32767-1) -#endif -#ifndef INT16_MAX -# define INT16_MAX (32767) -#endif -#ifndef UINT16_MAX -# define UINT16_MAX (65535) -#endif -#ifndef INT32_MIN -# define INT32_MIN (-2147483647-1) -#endif -#ifndef INT32_MAX -# define INT32_MAX (2147483647) -#endif -#ifndef UINT32_MAX -# define UINT32_MAX (4294967295U) -#endif - -#if HAVE_BYTESWAP_H -# include <byteswap.h> -#endif -#ifndef bswap_16 -# define bswap_16(p) \ - (((((uint16_t)(p)) & 0x00ff) << 8) | \ - (((uint16_t)(p)) >> 8)); -#endif -#ifndef bswap_32 -# define bswap_32(p) \ - (((((uint32_t)(p)) & 0x000000ff) << 24) | \ - ((((uint32_t)(p)) & 0x0000ff00) << 8) | \ - ((((uint32_t)(p)) & 0x00ff0000) >> 8) | \ - ((((uint32_t)(p))) >> 24)); -#endif - - -#if !HAVE_UINT64_T - -typedef struct _cairo_uint64 { - uint32_t lo, hi; -} cairo_uint64_t, cairo_int64_t; - -#else - -typedef uint64_t cairo_uint64_t; -typedef int64_t cairo_int64_t; - -#endif - -typedef struct _cairo_uquorem64 { - cairo_uint64_t quo; - cairo_uint64_t rem; -} cairo_uquorem64_t; - -typedef struct _cairo_quorem64 { - cairo_int64_t quo; - cairo_int64_t rem; -} cairo_quorem64_t; - -/* gcc has a non-standard name. */ -#if HAVE___UINT128_T && !HAVE_UINT128_T -typedef __uint128_t uint128_t; -typedef __int128_t int128_t; -#define HAVE_UINT128_T 1 -#endif - -#if !HAVE_UINT128_T - -typedef struct cairo_uint128 { - cairo_uint64_t lo, hi; -} cairo_uint128_t, cairo_int128_t; - -#else - -typedef uint128_t cairo_uint128_t; -typedef int128_t cairo_int128_t; - -#endif - -typedef struct _cairo_uquorem128 { - cairo_uint128_t quo; - cairo_uint128_t rem; -} cairo_uquorem128_t; - -typedef struct _cairo_quorem128 { - cairo_int128_t quo; - cairo_int128_t rem; -} cairo_quorem128_t; - - -#endif /* CAIRO_WIDEINT_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-wideint.c b/source/libs/cairo/cairo-src/src/cairo-wideint.c deleted file mode 100644 index 2e056fa36a2b3662f6262612b7e5f5f91245d8a0..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-wideint.c +++ /dev/null @@ -1,852 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2004 Keith Packard - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Keith Packard - * - * Contributor(s): - * Keith R. Packard <keithp@keithp.com> - */ - -#include "cairoint.h" - -#if HAVE_UINT64_T - -#define uint64_lo32(i) ((i) & 0xffffffff) -#define uint64_hi32(i) ((i) >> 32) -#define uint64_lo(i) ((i) & 0xffffffff) -#define uint64_hi(i) ((i) >> 32) -#define uint64_shift32(i) ((i) << 32) -#define uint64_carry32 (((uint64_t) 1) << 32) - -#define _cairo_uint32s_to_uint64(h,l) ((uint64_t) (h) << 32 | (l)) - -#else - -#define uint64_lo32(i) ((i).lo) -#define uint64_hi32(i) ((i).hi) - -static cairo_uint64_t -uint64_lo (cairo_uint64_t i) -{ - cairo_uint64_t s; - - s.lo = i.lo; - s.hi = 0; - return s; -} - -static cairo_uint64_t -uint64_hi (cairo_uint64_t i) -{ - cairo_uint64_t s; - - s.lo = i.hi; - s.hi = 0; - return s; -} - -static cairo_uint64_t -uint64_shift32 (cairo_uint64_t i) -{ - cairo_uint64_t s; - - s.lo = 0; - s.hi = i.lo; - return s; -} - -static const cairo_uint64_t uint64_carry32 = { 0, 1 }; - -cairo_uint64_t -_cairo_double_to_uint64 (double i) -{ - cairo_uint64_t q; - - q.hi = i * (1. / 4294967296.); - q.lo = i - q.hi * 4294967296.; - return q; -} - -double -_cairo_uint64_to_double (cairo_uint64_t i) -{ - return i.hi * 4294967296. + i.lo; -} - -cairo_int64_t -_cairo_double_to_int64 (double i) -{ - cairo_uint64_t q; - - q.hi = i * (1. / INT32_MAX); - q.lo = i - q.hi * (double)INT32_MAX; - return q; -} - -double -_cairo_int64_to_double (cairo_int64_t i) -{ - return i.hi * INT32_MAX + i.lo; -} - -cairo_uint64_t -_cairo_uint32_to_uint64 (uint32_t i) -{ - cairo_uint64_t q; - - q.lo = i; - q.hi = 0; - return q; -} - -cairo_int64_t -_cairo_int32_to_int64 (int32_t i) -{ - cairo_uint64_t q; - - q.lo = i; - q.hi = i < 0 ? -1 : 0; - return q; -} - -static cairo_uint64_t -_cairo_uint32s_to_uint64 (uint32_t h, uint32_t l) -{ - cairo_uint64_t q; - - q.lo = l; - q.hi = h; - return q; -} - -cairo_uint64_t -_cairo_uint64_add (cairo_uint64_t a, cairo_uint64_t b) -{ - cairo_uint64_t s; - - s.hi = a.hi + b.hi; - s.lo = a.lo + b.lo; - if (s.lo < a.lo) - s.hi++; - return s; -} - -cairo_uint64_t -_cairo_uint64_sub (cairo_uint64_t a, cairo_uint64_t b) -{ - cairo_uint64_t s; - - s.hi = a.hi - b.hi; - s.lo = a.lo - b.lo; - if (s.lo > a.lo) - s.hi--; - return s; -} - -#define uint32_lo(i) ((i) & 0xffff) -#define uint32_hi(i) ((i) >> 16) -#define uint32_carry16 ((1) << 16) - -cairo_uint64_t -_cairo_uint32x32_64_mul (uint32_t a, uint32_t b) -{ - cairo_uint64_t s; - - uint16_t ah, al, bh, bl; - uint32_t r0, r1, r2, r3; - - al = uint32_lo (a); - ah = uint32_hi (a); - bl = uint32_lo (b); - bh = uint32_hi (b); - - r0 = (uint32_t) al * bl; - r1 = (uint32_t) al * bh; - r2 = (uint32_t) ah * bl; - r3 = (uint32_t) ah * bh; - - r1 += uint32_hi(r0); /* no carry possible */ - r1 += r2; /* but this can carry */ - if (r1 < r2) /* check */ - r3 += uint32_carry16; - - s.hi = r3 + uint32_hi(r1); - s.lo = (uint32_lo (r1) << 16) + uint32_lo (r0); - return s; -} - -cairo_int64_t -_cairo_int32x32_64_mul (int32_t a, int32_t b) -{ - cairo_int64_t s; - s = _cairo_uint32x32_64_mul ((uint32_t) a, (uint32_t) b); - if (a < 0) - s.hi -= b; - if (b < 0) - s.hi -= a; - return s; -} - -cairo_uint64_t -_cairo_uint64_mul (cairo_uint64_t a, cairo_uint64_t b) -{ - cairo_uint64_t s; - - s = _cairo_uint32x32_64_mul (a.lo, b.lo); - s.hi += a.lo * b.hi + a.hi * b.lo; - return s; -} - -cairo_uint64_t -_cairo_uint64_lsl (cairo_uint64_t a, int shift) -{ - if (shift >= 32) - { - a.hi = a.lo; - a.lo = 0; - shift -= 32; - } - if (shift) - { - a.hi = a.hi << shift | a.lo >> (32 - shift); - a.lo = a.lo << shift; - } - return a; -} - -cairo_uint64_t -_cairo_uint64_rsl (cairo_uint64_t a, int shift) -{ - if (shift >= 32) - { - a.lo = a.hi; - a.hi = 0; - shift -= 32; - } - if (shift) - { - a.lo = a.lo >> shift | a.hi << (32 - shift); - a.hi = a.hi >> shift; - } - return a; -} - -#define _cairo_uint32_rsa(a,n) ((uint32_t) (((int32_t) (a)) >> (n))) - -cairo_int64_t -_cairo_uint64_rsa (cairo_int64_t a, int shift) -{ - if (shift >= 32) - { - a.lo = a.hi; - a.hi = _cairo_uint32_rsa (a.hi, 31); - shift -= 32; - } - if (shift) - { - a.lo = a.lo >> shift | a.hi << (32 - shift); - a.hi = _cairo_uint32_rsa (a.hi, shift); - } - return a; -} - -int -_cairo_uint64_lt (cairo_uint64_t a, cairo_uint64_t b) -{ - return (a.hi < b.hi || - (a.hi == b.hi && a.lo < b.lo)); -} - -int -_cairo_uint64_eq (cairo_uint64_t a, cairo_uint64_t b) -{ - return a.hi == b.hi && a.lo == b.lo; -} - -int -_cairo_int64_lt (cairo_int64_t a, cairo_int64_t b) -{ - if (_cairo_int64_negative (a) && !_cairo_int64_negative (b)) - return 1; - if (!_cairo_int64_negative (a) && _cairo_int64_negative (b)) - return 0; - return _cairo_uint64_lt (a, b); -} - -int -_cairo_uint64_cmp (cairo_uint64_t a, cairo_uint64_t b) -{ - if (a.hi < b.hi) - return -1; - else if (a.hi > b.hi) - return 1; - else if (a.lo < b.lo) - return -1; - else if (a.lo > b.lo) - return 1; - else - return 0; -} - -int -_cairo_int64_cmp (cairo_int64_t a, cairo_int64_t b) -{ - if (_cairo_int64_negative (a) && !_cairo_int64_negative (b)) - return -1; - if (!_cairo_int64_negative (a) && _cairo_int64_negative (b)) - return 1; - - return _cairo_uint64_cmp (a, b); -} - -cairo_uint64_t -_cairo_uint64_not (cairo_uint64_t a) -{ - a.lo = ~a.lo; - a.hi = ~a.hi; - return a; -} - -cairo_uint64_t -_cairo_uint64_negate (cairo_uint64_t a) -{ - a.lo = ~a.lo; - a.hi = ~a.hi; - if (++a.lo == 0) - ++a.hi; - return a; -} - -/* - * Simple bit-at-a-time divide. - */ -cairo_uquorem64_t -_cairo_uint64_divrem (cairo_uint64_t num, cairo_uint64_t den) -{ - cairo_uquorem64_t qr; - cairo_uint64_t bit; - cairo_uint64_t quo; - - bit = _cairo_uint32_to_uint64 (1); - - /* normalize to make den >= num, but not overflow */ - while (_cairo_uint64_lt (den, num) && (den.hi & 0x80000000) == 0) - { - bit = _cairo_uint64_lsl (bit, 1); - den = _cairo_uint64_lsl (den, 1); - } - quo = _cairo_uint32_to_uint64 (0); - - /* generate quotient, one bit at a time */ - while (bit.hi | bit.lo) - { - if (_cairo_uint64_le (den, num)) - { - num = _cairo_uint64_sub (num, den); - quo = _cairo_uint64_add (quo, bit); - } - bit = _cairo_uint64_rsl (bit, 1); - den = _cairo_uint64_rsl (den, 1); - } - qr.quo = quo; - qr.rem = num; - return qr; -} - -#endif /* !HAVE_UINT64_T */ - -#if HAVE_UINT128_T -cairo_uquorem128_t -_cairo_uint128_divrem (cairo_uint128_t num, cairo_uint128_t den) -{ - cairo_uquorem128_t qr; - - qr.quo = num / den; - qr.rem = num % den; - return qr; -} - -#else - -cairo_uint128_t -_cairo_uint32_to_uint128 (uint32_t i) -{ - cairo_uint128_t q; - - q.lo = _cairo_uint32_to_uint64 (i); - q.hi = _cairo_uint32_to_uint64 (0); - return q; -} - -cairo_int128_t -_cairo_int32_to_int128 (int32_t i) -{ - cairo_int128_t q; - - q.lo = _cairo_int32_to_int64 (i); - q.hi = _cairo_int32_to_int64 (i < 0 ? -1 : 0); - return q; -} - -cairo_uint128_t -_cairo_uint64_to_uint128 (cairo_uint64_t i) -{ - cairo_uint128_t q; - - q.lo = i; - q.hi = _cairo_uint32_to_uint64 (0); - return q; -} - -cairo_int128_t -_cairo_int64_to_int128 (cairo_int64_t i) -{ - cairo_int128_t q; - - q.lo = i; - q.hi = _cairo_int32_to_int64 (_cairo_int64_negative(i) ? -1 : 0); - return q; -} - -cairo_uint128_t -_cairo_uint128_add (cairo_uint128_t a, cairo_uint128_t b) -{ - cairo_uint128_t s; - - s.hi = _cairo_uint64_add (a.hi, b.hi); - s.lo = _cairo_uint64_add (a.lo, b.lo); - if (_cairo_uint64_lt (s.lo, a.lo)) - s.hi = _cairo_uint64_add (s.hi, _cairo_uint32_to_uint64 (1)); - return s; -} - -cairo_uint128_t -_cairo_uint128_sub (cairo_uint128_t a, cairo_uint128_t b) -{ - cairo_uint128_t s; - - s.hi = _cairo_uint64_sub (a.hi, b.hi); - s.lo = _cairo_uint64_sub (a.lo, b.lo); - if (_cairo_uint64_gt (s.lo, a.lo)) - s.hi = _cairo_uint64_sub (s.hi, _cairo_uint32_to_uint64(1)); - return s; -} - -cairo_uint128_t -_cairo_uint64x64_128_mul (cairo_uint64_t a, cairo_uint64_t b) -{ - cairo_uint128_t s; - uint32_t ah, al, bh, bl; - cairo_uint64_t r0, r1, r2, r3; - - al = uint64_lo32 (a); - ah = uint64_hi32 (a); - bl = uint64_lo32 (b); - bh = uint64_hi32 (b); - - r0 = _cairo_uint32x32_64_mul (al, bl); - r1 = _cairo_uint32x32_64_mul (al, bh); - r2 = _cairo_uint32x32_64_mul (ah, bl); - r3 = _cairo_uint32x32_64_mul (ah, bh); - - r1 = _cairo_uint64_add (r1, uint64_hi (r0)); /* no carry possible */ - r1 = _cairo_uint64_add (r1, r2); /* but this can carry */ - if (_cairo_uint64_lt (r1, r2)) /* check */ - r3 = _cairo_uint64_add (r3, uint64_carry32); - - s.hi = _cairo_uint64_add (r3, uint64_hi(r1)); - s.lo = _cairo_uint64_add (uint64_shift32 (r1), - uint64_lo (r0)); - return s; -} - -cairo_int128_t -_cairo_int64x64_128_mul (cairo_int64_t a, cairo_int64_t b) -{ - cairo_int128_t s; - s = _cairo_uint64x64_128_mul (_cairo_int64_to_uint64(a), - _cairo_int64_to_uint64(b)); - if (_cairo_int64_negative (a)) - s.hi = _cairo_uint64_sub (s.hi, - _cairo_int64_to_uint64 (b)); - if (_cairo_int64_negative (b)) - s.hi = _cairo_uint64_sub (s.hi, - _cairo_int64_to_uint64 (a)); - return s; -} - -cairo_uint128_t -_cairo_uint128_mul (cairo_uint128_t a, cairo_uint128_t b) -{ - cairo_uint128_t s; - - s = _cairo_uint64x64_128_mul (a.lo, b.lo); - s.hi = _cairo_uint64_add (s.hi, - _cairo_uint64_mul (a.lo, b.hi)); - s.hi = _cairo_uint64_add (s.hi, - _cairo_uint64_mul (a.hi, b.lo)); - return s; -} - -cairo_uint128_t -_cairo_uint128_lsl (cairo_uint128_t a, int shift) -{ - if (shift >= 64) - { - a.hi = a.lo; - a.lo = _cairo_uint32_to_uint64 (0); - shift -= 64; - } - if (shift) - { - a.hi = _cairo_uint64_add (_cairo_uint64_lsl (a.hi, shift), - _cairo_uint64_rsl (a.lo, (64 - shift))); - a.lo = _cairo_uint64_lsl (a.lo, shift); - } - return a; -} - -cairo_uint128_t -_cairo_uint128_rsl (cairo_uint128_t a, int shift) -{ - if (shift >= 64) - { - a.lo = a.hi; - a.hi = _cairo_uint32_to_uint64 (0); - shift -= 64; - } - if (shift) - { - a.lo = _cairo_uint64_add (_cairo_uint64_rsl (a.lo, shift), - _cairo_uint64_lsl (a.hi, (64 - shift))); - a.hi = _cairo_uint64_rsl (a.hi, shift); - } - return a; -} - -cairo_uint128_t -_cairo_uint128_rsa (cairo_int128_t a, int shift) -{ - if (shift >= 64) - { - a.lo = a.hi; - a.hi = _cairo_uint64_rsa (a.hi, 64-1); - shift -= 64; - } - if (shift) - { - a.lo = _cairo_uint64_add (_cairo_uint64_rsl (a.lo, shift), - _cairo_uint64_lsl (a.hi, (64 - shift))); - a.hi = _cairo_uint64_rsa (a.hi, shift); - } - return a; -} - -int -_cairo_uint128_lt (cairo_uint128_t a, cairo_uint128_t b) -{ - return (_cairo_uint64_lt (a.hi, b.hi) || - (_cairo_uint64_eq (a.hi, b.hi) && - _cairo_uint64_lt (a.lo, b.lo))); -} - -int -_cairo_int128_lt (cairo_int128_t a, cairo_int128_t b) -{ - if (_cairo_int128_negative (a) && !_cairo_int128_negative (b)) - return 1; - if (!_cairo_int128_negative (a) && _cairo_int128_negative (b)) - return 0; - return _cairo_uint128_lt (a, b); -} - -int -_cairo_uint128_cmp (cairo_uint128_t a, cairo_uint128_t b) -{ - int cmp; - - cmp = _cairo_uint64_cmp (a.hi, b.hi); - if (cmp) - return cmp; - return _cairo_uint64_cmp (a.lo, b.lo); -} - -int -_cairo_int128_cmp (cairo_int128_t a, cairo_int128_t b) -{ - if (_cairo_int128_negative (a) && !_cairo_int128_negative (b)) - return -1; - if (!_cairo_int128_negative (a) && _cairo_int128_negative (b)) - return 1; - - return _cairo_uint128_cmp (a, b); -} - -int -_cairo_uint128_eq (cairo_uint128_t a, cairo_uint128_t b) -{ - return (_cairo_uint64_eq (a.hi, b.hi) && - _cairo_uint64_eq (a.lo, b.lo)); -} - -#if HAVE_UINT64_T -#define _cairo_msbset64(q) (q & ((uint64_t) 1 << 63)) -#else -#define _cairo_msbset64(q) (q.hi & ((uint32_t) 1 << 31)) -#endif - -cairo_uquorem128_t -_cairo_uint128_divrem (cairo_uint128_t num, cairo_uint128_t den) -{ - cairo_uquorem128_t qr; - cairo_uint128_t bit; - cairo_uint128_t quo; - - bit = _cairo_uint32_to_uint128 (1); - - /* normalize to make den >= num, but not overflow */ - while (_cairo_uint128_lt (den, num) && !_cairo_msbset64(den.hi)) - { - bit = _cairo_uint128_lsl (bit, 1); - den = _cairo_uint128_lsl (den, 1); - } - quo = _cairo_uint32_to_uint128 (0); - - /* generate quotient, one bit at a time */ - while (_cairo_uint128_ne (bit, _cairo_uint32_to_uint128(0))) - { - if (_cairo_uint128_le (den, num)) - { - num = _cairo_uint128_sub (num, den); - quo = _cairo_uint128_add (quo, bit); - } - bit = _cairo_uint128_rsl (bit, 1); - den = _cairo_uint128_rsl (den, 1); - } - qr.quo = quo; - qr.rem = num; - return qr; -} - -cairo_uint128_t -_cairo_uint128_negate (cairo_uint128_t a) -{ - a.lo = _cairo_uint64_not (a.lo); - a.hi = _cairo_uint64_not (a.hi); - return _cairo_uint128_add (a, _cairo_uint32_to_uint128 (1)); -} - -cairo_uint128_t -_cairo_uint128_not (cairo_uint128_t a) -{ - a.lo = _cairo_uint64_not (a.lo); - a.hi = _cairo_uint64_not (a.hi); - return a; -} - -#endif /* !HAVE_UINT128_T */ - -cairo_quorem128_t -_cairo_int128_divrem (cairo_int128_t num, cairo_int128_t den) -{ - int num_neg = _cairo_int128_negative (num); - int den_neg = _cairo_int128_negative (den); - cairo_uquorem128_t uqr; - cairo_quorem128_t qr; - - if (num_neg) - num = _cairo_int128_negate (num); - if (den_neg) - den = _cairo_int128_negate (den); - uqr = _cairo_uint128_divrem (num, den); - if (num_neg) - qr.rem = _cairo_int128_negate (uqr.rem); - else - qr.rem = uqr.rem; - if (num_neg != den_neg) - qr.quo = _cairo_int128_negate (uqr.quo); - else - qr.quo = uqr.quo; - return qr; -} - -/** - * _cairo_uint_96by64_32x64_divrem: - * - * Compute a 32 bit quotient and 64 bit remainder of a 96 bit unsigned - * dividend and 64 bit divisor. If the quotient doesn't fit into 32 - * bits then the returned remainder is equal to the divisor, and the - * quotient is the largest representable 64 bit integer. It is an - * error to call this function with the high 32 bits of @num being - * non-zero. - **/ -cairo_uquorem64_t -_cairo_uint_96by64_32x64_divrem (cairo_uint128_t num, - cairo_uint64_t den) -{ - cairo_uquorem64_t result; - cairo_uint64_t B = _cairo_uint32s_to_uint64 (1, 0); - - /* These are the high 64 bits of the *96* bit numerator. We're - * going to represent the numerator as xB + y, where x is a 64, - * and y is a 32 bit number. */ - cairo_uint64_t x = _cairo_uint128_to_uint64 (_cairo_uint128_rsl(num, 32)); - - /* Initialise the result to indicate overflow. */ - result.quo = _cairo_uint32s_to_uint64 (-1U, -1U); - result.rem = den; - - /* Don't bother if the quotient is going to overflow. */ - if (_cairo_uint64_ge (x, den)) { - return /* overflow */ result; - } - - if (_cairo_uint64_lt (x, B)) { - /* When the final quotient is known to fit in 32 bits, then - * num < 2^64 if and only if den < 2^32. */ - return _cairo_uint64_divrem (_cairo_uint128_to_uint64 (num), den); - } - else { - /* Denominator is >= 2^32. the numerator is >= 2^64, and the - * division won't overflow: need two divrems. Write the - * numerator and denominator as - * - * num = xB + y x : 64 bits, y : 32 bits - * den = uB + v u, v : 32 bits - */ - uint32_t y = _cairo_uint128_to_uint32 (num); - uint32_t u = uint64_hi32 (den); - uint32_t v = _cairo_uint64_to_uint32 (den); - - /* Compute a lower bound approximate quotient of num/den - * from x/(u+1). Then we have - * - * x = q(u+1) + r ; q : 32 bits, r <= u : 32 bits. - * - * xB + y = q(u+1)B + (rB+y) - * = q(uB + B + v - v) + (rB+y) - * = q(uB + v) + qB - qv + (rB+y) - * = q(uB + v) + q(B-v) + (rB+y) - * - * The true quotient of num/den then is q plus the - * contribution of q(B-v) + (rB+y). The main contribution - * comes from the term q(B-v), with the term (rB+y) only - * contributing at most one part. - * - * The term q(B-v) must fit into 64 bits, since q fits into 32 - * bits on account of being a lower bound to the true - * quotient, and as B-v <= 2^32, we may safely use a single - * 64/64 bit division to find its contribution. */ - - cairo_uquorem64_t quorem; - cairo_uint64_t remainder; /* will contain final remainder */ - uint32_t quotient; /* will contain final quotient. */ - uint32_t q; - uint32_t r; - - /* Approximate quotient by dividing the high 64 bits of num by - * u+1. Watch out for overflow of u+1. */ - if (u+1) { - quorem = _cairo_uint64_divrem (x, _cairo_uint32_to_uint64 (u+1)); - q = _cairo_uint64_to_uint32 (quorem.quo); - r = _cairo_uint64_to_uint32 (quorem.rem); - } - else { - q = uint64_hi32 (x); - r = _cairo_uint64_to_uint32 (x); - } - quotient = q; - - /* Add the main term's contribution to quotient. Note B-v = - * -v as an uint32 (unless v = 0) */ - if (v) - quorem = _cairo_uint64_divrem (_cairo_uint32x32_64_mul (q, -v), den); - else - quorem = _cairo_uint64_divrem (_cairo_uint32s_to_uint64 (q, 0), den); - quotient += _cairo_uint64_to_uint32 (quorem.quo); - - /* Add the contribution of the subterm and start computing the - * true remainder. */ - remainder = _cairo_uint32s_to_uint64 (r, y); - if (_cairo_uint64_ge (remainder, den)) { - remainder = _cairo_uint64_sub (remainder, den); - quotient++; - } - - /* Add the contribution of the main term's remainder. The - * funky test here checks that remainder + main_rem >= den, - * taking into account overflow of the addition. */ - remainder = _cairo_uint64_add (remainder, quorem.rem); - if (_cairo_uint64_ge (remainder, den) || - _cairo_uint64_lt (remainder, quorem.rem)) - { - remainder = _cairo_uint64_sub (remainder, den); - quotient++; - } - - result.quo = _cairo_uint32_to_uint64 (quotient); - result.rem = remainder; - } - return result; -} - -cairo_quorem64_t -_cairo_int_96by64_32x64_divrem (cairo_int128_t num, cairo_int64_t den) -{ - int num_neg = _cairo_int128_negative (num); - int den_neg = _cairo_int64_negative (den); - cairo_uint64_t nonneg_den; - cairo_uquorem64_t uqr; - cairo_quorem64_t qr; - - if (num_neg) - num = _cairo_int128_negate (num); - if (den_neg) - nonneg_den = _cairo_int64_negate (den); - else - nonneg_den = den; - - uqr = _cairo_uint_96by64_32x64_divrem (num, nonneg_den); - if (_cairo_uint64_eq (uqr.rem, nonneg_den)) { - /* bail on overflow. */ - qr.quo = _cairo_uint32s_to_uint64 (0x7FFFFFFF, -1U); - qr.rem = den; - return qr; - } - - if (num_neg) - qr.rem = _cairo_int64_negate (uqr.rem); - else - qr.rem = uqr.rem; - if (num_neg != den_neg) - qr.quo = _cairo_int64_negate (uqr.quo); - else - qr.quo = uqr.quo; - return qr; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-win32.h b/source/libs/cairo/cairo-src/src/cairo-win32.h deleted file mode 100644 index 3d2e1c60169559aef079f82780c47bb4e92eda19..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-win32.h +++ /dev/null @@ -1,112 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2005 Red Hat, Inc - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Owen Taylor <otaylor@redhat.com> - */ - -#ifndef _CAIRO_WIN32_H_ -#define _CAIRO_WIN32_H_ - -#include "cairo.h" - -#if CAIRO_HAS_WIN32_SURFACE - -#include <windows.h> - -CAIRO_BEGIN_DECLS - -cairo_public cairo_surface_t * -cairo_win32_surface_create (HDC hdc); - -cairo_public cairo_surface_t * -cairo_win32_printing_surface_create (HDC hdc); - -cairo_public cairo_surface_t * -cairo_win32_surface_create_with_ddb (HDC hdc, - cairo_format_t format, - int width, - int height); - -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_surface_t * -cairo_win32_surface_get_image (cairo_surface_t *surface); - -#if CAIRO_HAS_WIN32_FONT - -/* - * Win32 font support - */ - -cairo_public cairo_font_face_t * -cairo_win32_font_face_create_for_logfontw (LOGFONTW *logfont); - -cairo_public cairo_font_face_t * -cairo_win32_font_face_create_for_hfont (HFONT font); - -cairo_public cairo_font_face_t * -cairo_win32_font_face_create_for_logfontw_hfont (LOGFONTW *logfont, HFONT font); - -cairo_public cairo_status_t -cairo_win32_scaled_font_select_font (cairo_scaled_font_t *scaled_font, - HDC hdc); - -cairo_public void -cairo_win32_scaled_font_done_font (cairo_scaled_font_t *scaled_font); - -cairo_public double -cairo_win32_scaled_font_get_metrics_factor (cairo_scaled_font_t *scaled_font); - -cairo_public void -cairo_win32_scaled_font_get_logical_to_device (cairo_scaled_font_t *scaled_font, - cairo_matrix_t *logical_to_device); - -cairo_public void -cairo_win32_scaled_font_get_device_to_logical (cairo_scaled_font_t *scaled_font, - cairo_matrix_t *device_to_logical); - -#endif /* CAIRO_HAS_WIN32_FONT */ - -CAIRO_END_DECLS - -#else /* CAIRO_HAS_WIN32_SURFACE */ -# error Cairo was not compiled with support for the win32 backend -#endif /* CAIRO_HAS_WIN32_SURFACE */ - -#endif /* _CAIRO_WIN32_H_ */ diff --git a/source/libs/cairo/cairo-src/src/cairo-xcb-connection-core.c b/source/libs/cairo/cairo-src/src/cairo-xcb-connection-core.c deleted file mode 100644 index e01dc1a8361940bd39a29cc30c704f7752466384..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xcb-connection-core.c +++ /dev/null @@ -1,300 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-xcb-private.h" - -#include <xcb/xcbext.h> - -xcb_pixmap_t -_cairo_xcb_connection_create_pixmap (cairo_xcb_connection_t *connection, - uint8_t depth, - xcb_drawable_t drawable, - uint16_t width, - uint16_t height) -{ - xcb_pixmap_t pixmap = _cairo_xcb_connection_get_xid (connection); - - assert (width > 0); - assert (height > 0); - xcb_create_pixmap (connection->xcb_connection, - depth, pixmap, drawable, - width, height); - return pixmap; -} - -void -_cairo_xcb_connection_free_pixmap (cairo_xcb_connection_t *connection, - xcb_pixmap_t pixmap) -{ - xcb_free_pixmap (connection->xcb_connection, pixmap); - _cairo_xcb_connection_put_xid (connection, pixmap); -} - -xcb_gcontext_t -_cairo_xcb_connection_create_gc (cairo_xcb_connection_t *connection, - xcb_drawable_t drawable, - uint32_t value_mask, - uint32_t *values) -{ - xcb_gcontext_t gc = _cairo_xcb_connection_get_xid (connection); - xcb_create_gc (connection->xcb_connection, gc, drawable, - value_mask, values); - return gc; -} - -void -_cairo_xcb_connection_free_gc (cairo_xcb_connection_t *connection, - xcb_gcontext_t gc) -{ - xcb_free_gc (connection->xcb_connection, gc); - _cairo_xcb_connection_put_xid (connection, gc); -} - -void -_cairo_xcb_connection_change_gc (cairo_xcb_connection_t *connection, - xcb_gcontext_t gc, - uint32_t value_mask, - uint32_t *values) -{ - xcb_change_gc (connection->xcb_connection, gc, - value_mask, values); -} - -void -_cairo_xcb_connection_copy_area (cairo_xcb_connection_t *connection, - xcb_drawable_t src, - xcb_drawable_t dst, - xcb_gcontext_t gc, - int16_t src_x, - int16_t src_y, - int16_t dst_x, - int16_t dst_y, - uint16_t width, - uint16_t height) -{ - xcb_copy_area (connection->xcb_connection, src, dst, gc, - src_x, src_y, dst_x, dst_y, width, height); -} - -void -_cairo_xcb_connection_poly_fill_rectangle (cairo_xcb_connection_t *connection, - xcb_drawable_t dst, - xcb_gcontext_t gc, - uint32_t num_rectangles, - xcb_rectangle_t *rectangles) -{ - xcb_poly_fill_rectangle (connection->xcb_connection, dst, gc, - num_rectangles, rectangles); -} - -void -_cairo_xcb_connection_put_image (cairo_xcb_connection_t *connection, - xcb_drawable_t dst, - xcb_gcontext_t gc, - uint16_t width, - uint16_t height, - int16_t dst_x, - int16_t dst_y, - uint8_t depth, - uint32_t stride, - void *data) -{ - const uint32_t req_size = 18; - uint32_t length = height * stride; - uint32_t len = (req_size + length) >> 2; - - if (len < connection->maximum_request_length) { - xcb_put_image (connection->xcb_connection, XCB_IMAGE_FORMAT_Z_PIXMAP, - dst, gc, width, height, dst_x, dst_y, 0, depth, - length, data); - } else { - int rows = (connection->maximum_request_length - req_size - 4) / stride; - if (rows > 0) { - do { - if (rows > height) - rows = height; - - length = rows * stride; - - xcb_put_image (connection->xcb_connection, XCB_IMAGE_FORMAT_Z_PIXMAP, - dst, gc, width, rows, dst_x, dst_y, 0, depth, length, data); - - height -= rows; - dst_y += rows; - data = (char *) data + length; - } while (height); - } else { - ASSERT_NOT_REACHED; - } - } -} - -static void -_cairo_xcb_connection_do_put_subimage (cairo_xcb_connection_t *connection, - xcb_drawable_t dst, - xcb_gcontext_t gc, - int16_t src_x, - int16_t src_y, - uint16_t width, - uint16_t height, - uint16_t cpp, - int stride, - int16_t dst_x, - int16_t dst_y, - uint8_t depth, - void *_data) -{ - xcb_protocol_request_t xcb_req = { - 0 /* count */, - 0 /* ext */, - XCB_PUT_IMAGE /* opcode */, - 1 /* isvoid (doesn't cause a reply) */ - }; - xcb_put_image_request_t req; - struct iovec vec_stack[CAIRO_STACK_ARRAY_LENGTH (struct iovec)]; - struct iovec *vec = vec_stack; - uint32_t len = 0; - uint8_t *data = _data; - int n = 3; - /* Two extra entries are needed for xcb, two for us */ - int entries_needed = height + 2 + 2; - - req.format = XCB_IMAGE_FORMAT_Z_PIXMAP; - req.drawable = dst; - req.gc = gc; - req.width = width; - req.height = height; - req.dst_x = dst_x; - req.dst_y = dst_y; - req.left_pad = 0; - req.depth = depth; - req.pad0[0] = 0; - req.pad0[1] = 0; - - if (entries_needed > ARRAY_LENGTH (vec_stack)) { - vec = _cairo_malloc_ab (entries_needed, sizeof (struct iovec)); - if (unlikely (vec == NULL)) { - /* XXX loop over ARRAY_LENGTH (vec_stack) */ - return; - } - } - - data += src_y * stride + src_x * cpp; - /* vec[1] will be used in XCB if it has to use BigRequests or insert a sync, - * vec[0] is used if the internal queue needs to be flushed. */ - vec[2].iov_base = (char *) &req; - vec[2].iov_len = sizeof (req); - - /* Now comes the actual data */ - while (height--) { - vec[n].iov_base = data; - vec[n].iov_len = cpp * width; - len += cpp * width; - data += stride; - n++; - } - - /* And again some padding */ - vec[n].iov_base = 0; - vec[n].iov_len = -len & 3; - n++; - - /* For efficiency reasons, this functions writes the request "directly" to - * the xcb connection to avoid having to copy the data around. */ - assert (n == entries_needed); - xcb_req.count = n - 2; - xcb_send_request (connection->xcb_connection, 0, &vec[2], &xcb_req); - - if (vec != vec_stack) - free (vec); -} - -void -_cairo_xcb_connection_put_subimage (cairo_xcb_connection_t *connection, - xcb_drawable_t dst, - xcb_gcontext_t gc, - int16_t src_x, - int16_t src_y, - uint16_t width, - uint16_t height, - uint16_t cpp, - int stride, - int16_t dst_x, - int16_t dst_y, - uint8_t depth, - void *_data) -{ - const uint32_t req_size = sizeof(xcb_put_image_request_t); - uint32_t length = height * cpp * width; - uint32_t len = (req_size + length) >> 2; - - if (len < connection->maximum_request_length) { - _cairo_xcb_connection_do_put_subimage (connection, dst, gc, src_x, src_y, - width, height, cpp, stride, dst_x, dst_y, depth, _data); - } else { - int rows = (connection->maximum_request_length - req_size - 4) / (cpp * width); - if (rows > 0) { - do { - if (rows > height) - rows = height; - - _cairo_xcb_connection_do_put_subimage (connection, dst, gc, src_x, src_y, - width, rows, cpp, stride, dst_x, dst_y, depth, _data); - - height -= rows; - dst_y += rows; - _data = (char *) _data + stride * rows; - } while (height); - } else { - ASSERT_NOT_REACHED; - } - } -} - -xcb_get_image_reply_t * -_cairo_xcb_connection_get_image (cairo_xcb_connection_t *connection, - xcb_drawable_t src, - int16_t src_x, - int16_t src_y, - uint16_t width, - uint16_t height) -{ - return xcb_get_image_reply (connection->xcb_connection, - xcb_get_image (connection->xcb_connection, - XCB_IMAGE_FORMAT_Z_PIXMAP, - src, - src_x, src_y, - width, height, - (uint32_t) -1), - NULL); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-xcb-connection-render.c b/source/libs/cairo/cairo-src/src/cairo-xcb-connection-render.c deleted file mode 100644 index 61119653e9a4385acb4c2193e91074fab3bd42a8..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xcb-connection-render.c +++ /dev/null @@ -1,299 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-xcb-private.h" - -#include <xcb/xcbext.h> - -void -_cairo_xcb_connection_render_create_picture (cairo_xcb_connection_t *connection, - xcb_render_picture_t picture, - xcb_drawable_t drawable, - xcb_render_pictformat_t format, - uint32_t value_mask, - uint32_t *value_list) -{ - assert (connection->flags & CAIRO_XCB_HAS_RENDER); - xcb_render_create_picture (connection->xcb_connection, picture, drawable, - format, value_mask, value_list); -} - -void -_cairo_xcb_connection_render_change_picture (cairo_xcb_connection_t *connection, - xcb_render_picture_t picture, - uint32_t value_mask, - uint32_t *value_list) -{ - assert (connection->flags & CAIRO_XCB_HAS_RENDER); - xcb_render_change_picture (connection->xcb_connection, picture, - value_mask, value_list); -} - -void -_cairo_xcb_connection_render_set_picture_clip_rectangles (cairo_xcb_connection_t *connection, - xcb_render_picture_t picture, - int16_t clip_x_origin, - int16_t clip_y_origin, - uint32_t rectangles_len, - xcb_rectangle_t *rectangles) -{ - assert (connection->flags & CAIRO_XCB_HAS_RENDER); - xcb_render_set_picture_clip_rectangles (connection->xcb_connection, picture, - clip_x_origin, clip_y_origin, - rectangles_len, rectangles); -} - -void -_cairo_xcb_connection_render_free_picture (cairo_xcb_connection_t *connection, - xcb_render_picture_t picture) -{ - assert (connection->flags & CAIRO_XCB_HAS_RENDER); - xcb_render_free_picture (connection->xcb_connection, picture); - _cairo_xcb_connection_put_xid (connection, picture); -} - -void -_cairo_xcb_connection_render_composite (cairo_xcb_connection_t *connection, - uint8_t op, - xcb_render_picture_t src, - xcb_render_picture_t mask, - xcb_render_picture_t dst, - int16_t src_x, - int16_t src_y, - int16_t mask_x, - int16_t mask_y, - int16_t dst_x, - int16_t dst_y, - uint16_t width, - uint16_t height) -{ - assert (connection->flags & CAIRO_XCB_RENDER_HAS_COMPOSITE); - xcb_render_composite (connection->xcb_connection, op, src, mask, dst, - src_x, src_y, mask_x, mask_y, dst_x, dst_y, width, height); -} - -void -_cairo_xcb_connection_render_trapezoids (cairo_xcb_connection_t *connection, - uint8_t op, - xcb_render_picture_t src, - xcb_render_picture_t dst, - xcb_render_pictformat_t mask_format, - int16_t src_x, - int16_t src_y, - uint32_t traps_len, - xcb_render_trapezoid_t *traps) -{ - assert (connection->flags & CAIRO_XCB_RENDER_HAS_COMPOSITE_TRAPEZOIDS); - xcb_render_trapezoids (connection->xcb_connection, op, src, dst, - mask_format, src_x, src_y, traps_len, traps); -} - -void -_cairo_xcb_connection_render_create_glyph_set (cairo_xcb_connection_t *connection, - xcb_render_glyphset_t id, - xcb_render_pictformat_t format) -{ - assert (connection->flags & CAIRO_XCB_HAS_RENDER); - xcb_render_create_glyph_set (connection->xcb_connection, id, format); -} - -void -_cairo_xcb_connection_render_free_glyph_set (cairo_xcb_connection_t *connection, - xcb_render_glyphset_t glyphset) -{ - assert (connection->flags & CAIRO_XCB_HAS_RENDER); - xcb_render_free_glyph_set (connection->xcb_connection, glyphset); - _cairo_xcb_connection_put_xid (connection, glyphset); -} - -void -_cairo_xcb_connection_render_add_glyphs (cairo_xcb_connection_t *connection, - xcb_render_glyphset_t glyphset, - uint32_t num_glyphs, - uint32_t *glyphs_id, - xcb_render_glyphinfo_t *glyphs, - uint32_t data_len, - uint8_t *data) -{ - assert (connection->flags & CAIRO_XCB_HAS_RENDER); - xcb_render_add_glyphs (connection->xcb_connection, glyphset, num_glyphs, - glyphs_id, glyphs, data_len, data); -} - -void -_cairo_xcb_connection_render_free_glyphs (cairo_xcb_connection_t *connection, - xcb_render_glyphset_t glyphset, - uint32_t num_glyphs, - xcb_render_glyph_t *glyphs) -{ - assert (connection->flags & CAIRO_XCB_HAS_RENDER); - xcb_render_free_glyphs (connection->xcb_connection, glyphset, num_glyphs, glyphs); -} - -void -_cairo_xcb_connection_render_composite_glyphs_8 (cairo_xcb_connection_t *connection, - uint8_t op, - xcb_render_picture_t src, - xcb_render_picture_t dst, - xcb_render_pictformat_t mask_format, - xcb_render_glyphset_t glyphset, - int16_t src_x, - int16_t src_y, - uint32_t glyphcmds_len, - uint8_t *glyphcmds) -{ - assert (connection->flags & CAIRO_XCB_HAS_RENDER); - xcb_render_composite_glyphs_8 (connection->xcb_connection, op, src, dst, mask_format, - glyphset, src_x, src_y, glyphcmds_len, glyphcmds); -} - -void -_cairo_xcb_connection_render_composite_glyphs_16 (cairo_xcb_connection_t *connection, - uint8_t op, - xcb_render_picture_t src, - xcb_render_picture_t dst, - xcb_render_pictformat_t mask_format, - xcb_render_glyphset_t glyphset, - int16_t src_x, - int16_t src_y, - uint32_t glyphcmds_len, - uint8_t *glyphcmds) -{ - assert (connection->flags & CAIRO_XCB_HAS_RENDER); - xcb_render_composite_glyphs_16 (connection->xcb_connection, op, src, dst, mask_format, - glyphset, src_x, src_y, glyphcmds_len, glyphcmds); -} - -void -_cairo_xcb_connection_render_composite_glyphs_32 (cairo_xcb_connection_t *connection, - uint8_t op, - xcb_render_picture_t src, - xcb_render_picture_t dst, - xcb_render_pictformat_t mask_format, - xcb_render_glyphset_t glyphset, - int16_t src_x, - int16_t src_y, - uint32_t glyphcmds_len, - uint8_t *glyphcmds) -{ - assert (connection->flags & CAIRO_XCB_HAS_RENDER); - xcb_render_composite_glyphs_32 (connection->xcb_connection, op, src, dst, mask_format, - glyphset, src_x, src_y, glyphcmds_len, glyphcmds); -} - -void -_cairo_xcb_connection_render_fill_rectangles (cairo_xcb_connection_t *connection, - uint8_t op, - xcb_render_picture_t dst, - xcb_render_color_t color, - uint32_t num_rects, - xcb_rectangle_t *rects) -{ - assert (connection->flags & CAIRO_XCB_RENDER_HAS_FILL_RECTANGLES); - xcb_render_fill_rectangles (connection->xcb_connection, op, dst, color, - num_rects, rects); -} - -void -_cairo_xcb_connection_render_set_picture_transform (cairo_xcb_connection_t *connection, - xcb_render_picture_t picture, - xcb_render_transform_t *transform) -{ - assert (connection->flags & CAIRO_XCB_RENDER_HAS_PICTURE_TRANSFORM); - xcb_render_set_picture_transform (connection->xcb_connection, picture, *transform); -} - -void -_cairo_xcb_connection_render_set_picture_filter (cairo_xcb_connection_t *connection, - xcb_render_picture_t picture, - uint16_t filter_len, - char *filter) -{ - assert (connection->flags & CAIRO_XCB_RENDER_HAS_FILTERS); - xcb_render_set_picture_filter (connection->xcb_connection, picture, - filter_len, filter, 0, NULL); -} - -void -_cairo_xcb_connection_render_create_solid_fill (cairo_xcb_connection_t *connection, - xcb_render_picture_t picture, - xcb_render_color_t color) -{ - assert (connection->flags & CAIRO_XCB_RENDER_HAS_GRADIENTS); - xcb_render_create_solid_fill (connection->xcb_connection, picture, color); -} - -void -_cairo_xcb_connection_render_create_linear_gradient (cairo_xcb_connection_t *connection, - xcb_render_picture_t picture, - xcb_render_pointfix_t p1, - xcb_render_pointfix_t p2, - uint32_t num_stops, - xcb_render_fixed_t *stops, - xcb_render_color_t *colors) -{ - assert (connection->flags & CAIRO_XCB_RENDER_HAS_GRADIENTS); - xcb_render_create_linear_gradient (connection->xcb_connection, picture, - p1, p2, num_stops, stops, colors); -} - -void -_cairo_xcb_connection_render_create_radial_gradient (cairo_xcb_connection_t *connection, - xcb_render_picture_t picture, - xcb_render_pointfix_t inner, - xcb_render_pointfix_t outer, - xcb_render_fixed_t inner_radius, - xcb_render_fixed_t outer_radius, - uint32_t num_stops, - xcb_render_fixed_t *stops, - xcb_render_color_t *colors) -{ - assert (connection->flags & CAIRO_XCB_RENDER_HAS_GRADIENTS); - xcb_render_create_radial_gradient (connection->xcb_connection, picture, - inner, outer, inner_radius, outer_radius, - num_stops, stops, colors); -} - -void -_cairo_xcb_connection_render_create_conical_gradient (cairo_xcb_connection_t *connection, - xcb_render_picture_t picture, - xcb_render_pointfix_t center, - xcb_render_fixed_t angle, - uint32_t num_stops, - xcb_render_fixed_t *stops, - xcb_render_color_t *colors) -{ - assert (connection->flags & CAIRO_XCB_RENDER_HAS_GRADIENTS); - xcb_render_create_conical_gradient (connection->xcb_connection, picture, - center, angle, num_stops, stops, colors); -} diff --git a/source/libs/cairo/cairo-src/src/cairo-xcb-connection-shm.c b/source/libs/cairo/cairo-src/src/cairo-xcb-connection-shm.c deleted file mode 100644 index 7720bbbd25b6def262267592c6ef70521a0377f1..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xcb-connection-shm.c +++ /dev/null @@ -1,115 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#if CAIRO_HAS_XCB_SHM_FUNCTIONS - -#include "cairo-xcb-private.h" - -#include <xcb/xcbext.h> -#include <xcb/shm.h> - -uint32_t -_cairo_xcb_connection_shm_attach (cairo_xcb_connection_t *connection, - uint32_t id, - cairo_bool_t readonly) -{ - uint32_t segment = _cairo_xcb_connection_get_xid (connection); - assert (connection->flags & CAIRO_XCB_HAS_SHM); - xcb_shm_attach (connection->xcb_connection, segment, id, readonly); - return segment; -} - -void -_cairo_xcb_connection_shm_put_image (cairo_xcb_connection_t *connection, - xcb_drawable_t dst, - xcb_gcontext_t gc, - uint16_t total_width, - uint16_t total_height, - int16_t src_x, - int16_t src_y, - uint16_t width, - uint16_t height, - int16_t dst_x, - int16_t dst_y, - uint8_t depth, - uint32_t shm, - uint32_t offset) -{ - assert (connection->flags & CAIRO_XCB_HAS_SHM); - xcb_shm_put_image (connection->xcb_connection, dst, gc, total_width, total_height, - src_x, src_y, width, height, dst_x, dst_y, depth, - XCB_IMAGE_FORMAT_Z_PIXMAP, 0, shm, offset); -} - -cairo_status_t -_cairo_xcb_connection_shm_get_image (cairo_xcb_connection_t *connection, - xcb_drawable_t src, - int16_t src_x, - int16_t src_y, - uint16_t width, - uint16_t height, - uint32_t shmseg, - uint32_t offset) -{ - xcb_shm_get_image_reply_t *reply; - - assert (connection->flags & CAIRO_XCB_HAS_SHM); - reply = xcb_shm_get_image_reply (connection->xcb_connection, - xcb_shm_get_image (connection->xcb_connection, - src, - src_x, src_y, - width, height, - (uint32_t) -1, - XCB_IMAGE_FORMAT_Z_PIXMAP, - shmseg, offset), - NULL); - free (reply); - - if (!reply) { - /* an error here should be impossible */ - return _cairo_error (CAIRO_STATUS_READ_ERROR); - } - - return CAIRO_STATUS_SUCCESS; -} - -void -_cairo_xcb_connection_shm_detach (cairo_xcb_connection_t *connection, - uint32_t segment) -{ - assert (connection->flags & CAIRO_XCB_HAS_SHM); - xcb_shm_detach (connection->xcb_connection, segment); - _cairo_xcb_connection_put_xid (connection, segment); -} - -#endif /* CAIRO_HAS_XCB_SHM_FUNCTIONS */ diff --git a/source/libs/cairo/cairo-src/src/cairo-xcb-connection.c b/source/libs/cairo/cairo-src/src/cairo-xcb-connection.c deleted file mode 100644 index 67897fa4eccda197b8126a4ffe7ef427351eb289..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xcb-connection.c +++ /dev/null @@ -1,1006 +0,0 @@ -/* Cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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. - * - * Authors: - * Chris Wilson <chris@chris-wilson.co.uk> - */ - - -#include "cairoint.h" - -#include "cairo-xcb-private.h" -#include "cairo-hash-private.h" -#include "cairo-freelist-private.h" -#include "cairo-list-inline.h" - -#include <xcb/xcbext.h> -#include <xcb/bigreq.h> -#include <errno.h> - -#if CAIRO_HAS_XCB_SHM_FUNCTIONS -#include <sys/ipc.h> -#include <sys/shm.h> -#include <xcb/shm.h> -#endif - -typedef struct _cairo_xcb_xrender_format { - cairo_hash_entry_t key; - xcb_render_pictformat_t xrender_format; -} cairo_xcb_xrender_format_t; - -typedef struct _cairo_xcb_xid { - cairo_list_t link; - uint32_t xid; -} cairo_xcb_xid_t; - -#define XCB_RENDER_AT_LEAST(V, major, minor) \ - (((V)->major_version > major) || \ - (((V)->major_version == major) && ((V)->minor_version >= minor))) - -#define XCB_RENDER_HAS_CREATE_PICTURE(surface) XCB_RENDER_AT_LEAST((surface), 0, 0) -#define XCB_RENDER_HAS_COMPOSITE(surface) XCB_RENDER_AT_LEAST((surface), 0, 0) -#define XCB_RENDER_HAS_COMPOSITE_TEXT(surface) XCB_RENDER_AT_LEAST((surface), 0, 0) - -#define XCB_RENDER_HAS_FILL_RECTANGLES(surface) XCB_RENDER_AT_LEAST((surface), 0, 1) - -#define XCB_RENDER_HAS_DISJOINT(surface) XCB_RENDER_AT_LEAST((surface), 0, 2) -#define XCB_RENDER_HAS_CONJOINT(surface) XCB_RENDER_AT_LEAST((surface), 0, 2) - -#define XCB_RENDER_HAS_TRAPEZOIDS(surface) XCB_RENDER_AT_LEAST((surface), 0, 4) -#define XCB_RENDER_HAS_TRIANGLES(surface) XCB_RENDER_AT_LEAST((surface), 0, 4) -#define XCB_RENDER_HAS_TRISTRIP(surface) XCB_RENDER_AT_LEAST((surface), 0, 4) -#define XCB_RENDER_HAS_TRIFAN(surface) XCB_RENDER_AT_LEAST((surface), 0, 4) - -#define XCB_RENDER_HAS_PICTURE_TRANSFORM(surface) XCB_RENDER_AT_LEAST((surface), 0, 6) -#define XCB_RENDER_HAS_FILTERS(surface) XCB_RENDER_AT_LEAST((surface), 0, 6) -#define XCB_RENDER_HAS_FILTER_GOOD(surface) FALSE -#define XCB_RENDER_HAS_FILTER_BEST(surface) FALSE -#define XCB_RENDER_HAS_SUBPIXEL_ORDER(surface) XCB_RENDER_AT_LEAST((surface), 0, 6) - -#define XCB_RENDER_HAS_EXTENDED_REPEAT(surface) XCB_RENDER_AT_LEAST((surface), 0, 10) -#define XCB_RENDER_HAS_GRADIENTS(surface) XCB_RENDER_AT_LEAST((surface), 0, 10) - -#define XCB_RENDER_HAS_PDF_OPERATORS(surface) XCB_RENDER_AT_LEAST((surface), 0, 11) - -static cairo_list_t connections; - -static cairo_status_t -_cairo_xcb_connection_find_visual_formats (cairo_xcb_connection_t *connection, - const xcb_render_query_pict_formats_reply_t *formats) -{ - xcb_render_pictscreen_iterator_t screens; - xcb_render_pictdepth_iterator_t depths; - xcb_render_pictvisual_iterator_t visuals; - - for (screens = xcb_render_query_pict_formats_screens_iterator (formats); - screens.rem; - xcb_render_pictscreen_next (&screens)) - { - for (depths = xcb_render_pictscreen_depths_iterator (screens.data); - depths.rem; - xcb_render_pictdepth_next (&depths)) - { - for (visuals = xcb_render_pictdepth_visuals_iterator (depths.data); - visuals.rem; - xcb_render_pictvisual_next (&visuals)) - { - cairo_xcb_xrender_format_t *f; - cairo_status_t status; - - f = malloc (sizeof (cairo_xcb_xrender_format_t)); - if (unlikely (f == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - f->key.hash = visuals.data->visual; - f->xrender_format = visuals.data->format; - status = _cairo_hash_table_insert (connection->visual_to_xrender_format, - &f->key); - if (unlikely (status)) - return status; - } - } - } - - return CAIRO_STATUS_SUCCESS; -} - -#if 0 -static xcb_format_t * -find_format_for_depth (const xcb_setup_t *setup, uint8_t depth) -{ - xcb_format_t *fmt = xcb_setup_pixmap_formats (setup); - xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length (setup); - - for (; fmt != fmtend; ++fmt) - if (fmt->depth == depth) - return fmt; - - return 0; -} -#endif - -static cairo_status_t -_cairo_xcb_connection_parse_xrender_formats (cairo_xcb_connection_t *connection, - const xcb_render_query_pict_formats_reply_t *formats) -{ - xcb_render_pictforminfo_iterator_t i; - cairo_status_t status; - - for (i = xcb_render_query_pict_formats_formats_iterator (formats); - i.rem; - xcb_render_pictforminfo_next (&i)) - { - cairo_format_masks_t masks; - pixman_format_code_t pixman_format; - - if (i.data->type != XCB_RENDER_PICT_TYPE_DIRECT) - continue; - - masks.alpha_mask = - (unsigned long) i.data->direct.alpha_mask << i.data->direct.alpha_shift; - masks.red_mask = - (unsigned long) i.data->direct.red_mask << i.data->direct.red_shift; - masks.green_mask = - (unsigned long) i.data->direct.green_mask << i.data->direct.green_shift; - masks.blue_mask = - (unsigned long) i.data->direct.blue_mask << i.data->direct.blue_shift; - masks.bpp = i.data->depth; - - if (_pixman_format_from_masks (&masks, &pixman_format)) { - cairo_hash_entry_t key; - - key.hash = pixman_format; - if (! _cairo_hash_table_lookup (connection->xrender_formats, &key)) { - cairo_xcb_xrender_format_t *f; - - f = malloc (sizeof (cairo_xcb_xrender_format_t)); - if (unlikely (f == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - f->key.hash = pixman_format; - f->xrender_format = i.data->id; - status = _cairo_hash_table_insert (connection->xrender_formats, - &f->key); - if (unlikely (status)) - return status; - -#if 0 - printf ("xrender %x -> (%lx, %lx, %lx, %lx, %d) %x [%d, %d]\n", - i.data->id, - masks.alpha_mask, - masks.red_mask, - masks.green_mask, - masks.blue_mask, - masks.bpp, - pixman_format, - PIXMAN_FORMAT_DEPTH(pixman_format), - PIXMAN_FORMAT_BPP(pixman_format)); -#endif - } - } - } - - status = _cairo_xcb_connection_find_visual_formats (connection, formats); - if (unlikely (status)) - return status; - - connection->standard_formats[CAIRO_FORMAT_A1] = - _cairo_xcb_connection_get_xrender_format (connection, PIXMAN_a1); - - connection->standard_formats[CAIRO_FORMAT_A8] = - _cairo_xcb_connection_get_xrender_format (connection, PIXMAN_a8); - - connection->standard_formats[CAIRO_FORMAT_RGB24] = - _cairo_xcb_connection_get_xrender_format (connection, - PIXMAN_FORMAT (24, - PIXMAN_TYPE_ARGB, - 0, 8, 8, 8)); - if (connection->standard_formats[CAIRO_FORMAT_RGB24] == XCB_NONE) { - connection->standard_formats[CAIRO_FORMAT_RGB24] = - _cairo_xcb_connection_get_xrender_format (connection, - PIXMAN_FORMAT (24, PIXMAN_TYPE_ABGR, - 0, 8, 8, 8)); - } - - connection->standard_formats[CAIRO_FORMAT_ARGB32] = - _cairo_xcb_connection_get_xrender_format (connection, PIXMAN_a8r8g8b8); - if (connection->standard_formats[CAIRO_FORMAT_ARGB32] == XCB_NONE) { - connection->standard_formats[CAIRO_FORMAT_ARGB32] = - _cairo_xcb_connection_get_xrender_format (connection, PIXMAN_a8b8g8r8); - } - - return CAIRO_STATUS_SUCCESS; -} - -/* - * We require support for depth 1, 8, 24 and 32 pixmaps - */ -#define DEPTH_MASK(d) (1 << ((d) - 1)) -#define REQUIRED_DEPTHS (DEPTH_MASK(1) | \ - DEPTH_MASK(8) | \ - DEPTH_MASK(24) | \ - DEPTH_MASK(32)) -static cairo_bool_t -pixmap_depths_usable (cairo_xcb_connection_t *connection, - uint32_t missing, - xcb_drawable_t root) -{ - xcb_connection_t *c = connection->xcb_connection; - xcb_void_cookie_t create_cookie[32]; - xcb_pixmap_t pixmap; - cairo_bool_t success = TRUE; - int depth, i, j; - - pixmap = _cairo_xcb_connection_get_xid (connection); - - for (depth = 1, i = 0; depth <= 32; depth++) { - if (missing & DEPTH_MASK(depth)) { - create_cookie[i] = xcb_create_pixmap_checked (c, depth, pixmap, root, 1, 1); - xcb_free_pixmap (c, pixmap); - if (!create_cookie[i].sequence) { - success = FALSE; - break; - } - i++; - } - } - - for (j = 0; j < i; j++) { - xcb_generic_error_t *create_error = xcb_request_check (c, create_cookie[j]); - success &= create_error == NULL; - free (create_error); - } - - _cairo_xcb_connection_put_xid (connection, pixmap); - - return success; -} - -static cairo_bool_t -has_required_depths (cairo_xcb_connection_t *connection) -{ - xcb_screen_iterator_t screens; - - for (screens = xcb_setup_roots_iterator (connection->root); - screens.rem; - xcb_screen_next (&screens)) - { - xcb_depth_iterator_t depths; - uint32_t missing = REQUIRED_DEPTHS; - - for (depths = xcb_screen_allowed_depths_iterator (screens.data); - depths.rem; - xcb_depth_next (&depths)) - { - missing &= ~DEPTH_MASK (depths.data->depth); - } - if (missing == 0) - continue; - - /* - * Ok, this is ugly. It should be sufficient at this - * point to just return false, but Xinerama is broken at - * this point and only advertises depths which have an - * associated visual. Of course, the other depths still - * work, but the only way to find out is to try them. - */ - if (! pixmap_depths_usable (connection, missing, screens.data->root)) - return FALSE; - } - - return TRUE; -} - -static xcb_render_query_version_reply_t * -_render_restrict_env(xcb_render_query_version_reply_t *version) -{ - const char *env; - - if (version == NULL) - return NULL; - - env = getenv ("CAIRO_DEBUG"); - if (env != NULL) - env = strstr (env, "xrender-version="); - if (env != NULL) { - int max_render_major, max_render_minor; - - env += sizeof ("xrender-version=") - 1; - if (sscanf (env, "%d.%d", &max_render_major, &max_render_minor) != 2) - max_render_major = max_render_minor = -1; - - if (max_render_major < 0 || max_render_minor < 0) { - free (version); - return NULL; - } - - if (max_render_major < (int) version->major_version || - (max_render_major == (int) version->major_version && - max_render_minor < (int) version->minor_version)) - { - version->major_version = max_render_major; - version->minor_version = max_render_minor; - } - } - - return version; -} - -static cairo_status_t -_cairo_xcb_connection_query_render (cairo_xcb_connection_t *connection) -{ - xcb_connection_t *c = connection->xcb_connection; - xcb_render_query_version_cookie_t version_cookie; - xcb_render_query_pict_formats_cookie_t formats_cookie; - xcb_render_query_version_reply_t *version; - xcb_render_query_pict_formats_reply_t *formats; - cairo_status_t status; - cairo_bool_t present; - - version_cookie = xcb_render_query_version (c, XCB_RENDER_MAJOR_VERSION, XCB_RENDER_MINOR_VERSION); - formats_cookie = xcb_render_query_pict_formats (c); - - present = has_required_depths (connection); - version = xcb_render_query_version_reply (c, version_cookie, 0); - formats = xcb_render_query_pict_formats_reply (c, formats_cookie, 0); - - version = _render_restrict_env (version); - - if (! present || version == NULL || formats == NULL) { - free (version); - free (formats); - return CAIRO_STATUS_SUCCESS; - } - - /* always true if the extension is present (i.e. >= 0.0) */ - connection->flags |= CAIRO_XCB_HAS_RENDER; - connection->flags |= CAIRO_XCB_RENDER_HAS_COMPOSITE; - connection->flags |= CAIRO_XCB_RENDER_HAS_COMPOSITE_GLYPHS; - - if (XCB_RENDER_HAS_FILL_RECTANGLES (version)) - connection->flags |= CAIRO_XCB_RENDER_HAS_FILL_RECTANGLES; - - if (XCB_RENDER_HAS_TRAPEZOIDS (version)) - connection->flags |= CAIRO_XCB_RENDER_HAS_COMPOSITE_TRAPEZOIDS; - - if (XCB_RENDER_HAS_PICTURE_TRANSFORM (version)) - connection->flags |= CAIRO_XCB_RENDER_HAS_PICTURE_TRANSFORM; - - if (XCB_RENDER_HAS_FILTERS (version)) - connection->flags |= CAIRO_XCB_RENDER_HAS_FILTERS; - - if (XCB_RENDER_HAS_FILTER_GOOD (version)) - connection->flags |= CAIRO_XCB_RENDER_HAS_FILTER_GOOD; - - if (XCB_RENDER_HAS_FILTER_BEST (version)) - connection->flags |= CAIRO_XCB_RENDER_HAS_FILTER_BEST; - - if (XCB_RENDER_HAS_PDF_OPERATORS (version)) - connection->flags |= CAIRO_XCB_RENDER_HAS_PDF_OPERATORS; - - if (XCB_RENDER_HAS_EXTENDED_REPEAT (version)) - connection->flags |= CAIRO_XCB_RENDER_HAS_EXTENDED_REPEAT; - - if (XCB_RENDER_HAS_GRADIENTS (version)) - connection->flags |= CAIRO_XCB_RENDER_HAS_GRADIENTS; - - if (XCB_RENDER_HAS_SUBPIXEL_ORDER (version)) { - uint32_t screen; - uint32_t *subpixel = xcb_render_query_pict_formats_subpixels(formats); - - /* The spec explicitly allows to have too few entries in the reply... */ - for (screen = 0; screen < formats->num_subpixel && screen < connection->root->roots_len; screen++) - connection->subpixel_orders[screen] = subpixel[screen]; - } - - free (version); - - status = _cairo_xcb_connection_parse_xrender_formats (connection, formats); - free (formats); - - return status; -} - -#if 0 -static void -_cairo_xcb_connection_query_cairo (cairo_xcb_connection_t *connection) -{ - xcb_connection_t *c = connection->xcb_connection; - xcb_cairo_query_version_reply_t *version; - - version = xcb_cairo_query_version_reply (c, - xcb_cairo_query_version (c, 0, 0), - 0); - - free (version); -} -#endif - -#if CAIRO_HAS_XCB_SHM_FUNCTIONS -static cairo_bool_t -can_use_shm (cairo_xcb_connection_t *connection) -{ - cairo_bool_t success = TRUE; - xcb_connection_t *c = connection->xcb_connection; - xcb_void_cookie_t cookie[2]; - xcb_generic_error_t *error; - int shmid; - uint32_t shmseg; - void *ptr; - - shmid = shmget (IPC_PRIVATE, 0x1000, IPC_CREAT | 0600); - if (shmid == -1) - return FALSE; - - ptr = shmat (shmid, NULL, 0); - if (ptr == (char *) -1) { - shmctl (shmid, IPC_RMID, NULL); - return FALSE; - } - - shmseg = _cairo_xcb_connection_get_xid (connection); - cookie[0] = xcb_shm_attach_checked (c, shmseg, shmid, FALSE); - cookie[1] = xcb_shm_detach_checked (c, shmseg); - _cairo_xcb_connection_put_xid (connection, shmseg); - - error = xcb_request_check (c, cookie[0]); - if (error != NULL) - success = FALSE; - - error = xcb_request_check (c, cookie[1]); - if (error != NULL) - success = FALSE; - - shmctl (shmid, IPC_RMID, NULL); - shmdt (ptr); - - return success; -} - -static void -_cairo_xcb_connection_query_shm (cairo_xcb_connection_t *connection) -{ - xcb_connection_t *c = connection->xcb_connection; - xcb_shm_query_version_reply_t *version; - - version = xcb_shm_query_version_reply (c, xcb_shm_query_version (c), 0); - if (version == NULL) - return; - - free (version); - - if (can_use_shm (connection)) - connection->flags |= CAIRO_XCB_HAS_SHM; -} -#endif - -static cairo_status_t -_device_flush (void *device) -{ - cairo_xcb_connection_t *connection = device; - cairo_status_t status; - - status = cairo_device_acquire (&connection->device); - if (unlikely (status)) - return status; - -#if CAIRO_HAS_XCB_SHM_FUNCTIONS - _cairo_xcb_connection_shm_mem_pools_flush (connection); -#endif - - xcb_flush (connection->xcb_connection); - - cairo_device_release (&connection->device); - return CAIRO_STATUS_SUCCESS; -} - -static void -_pluck_xrender_format (void *entry, - void *closure) -{ - _cairo_hash_table_remove (closure, entry); - free (entry); -} - -static void -_device_finish (void *device) -{ - cairo_xcb_connection_t *connection = device; - cairo_bool_t was_cached = FALSE; - - if (! cairo_list_is_empty (&connection->link)) { - CAIRO_MUTEX_LOCK (_cairo_xcb_connections_mutex); - cairo_list_del (&connection->link); - CAIRO_MUTEX_UNLOCK (_cairo_xcb_connections_mutex); - was_cached = TRUE; - } - - while (! cairo_list_is_empty (&connection->fonts)) { - cairo_xcb_font_t *font; - - font = cairo_list_first_entry (&connection->fonts, - cairo_xcb_font_t, - link); - _cairo_xcb_font_close (font); - } - - while (! cairo_list_is_empty (&connection->screens)) { - cairo_xcb_screen_t *screen; - - screen = cairo_list_first_entry (&connection->screens, - cairo_xcb_screen_t, - link); - _cairo_xcb_screen_finish (screen); - } - -#if CAIRO_HAS_XCB_SHM_FUNCTIONS - /* _cairo_xcb_screen_finish finishes surfaces. If any of those surfaces had - * a fallback image, we might have done a SHM PutImage. */ - _cairo_xcb_connection_shm_mem_pools_flush (connection); -#endif - - if (was_cached) - cairo_device_destroy (device); -} - -static void -_device_destroy (void *device) -{ - cairo_xcb_connection_t *connection = device; - - _cairo_hash_table_foreach (connection->xrender_formats, - _pluck_xrender_format, connection->xrender_formats); - _cairo_hash_table_destroy (connection->xrender_formats); - - _cairo_hash_table_foreach (connection->visual_to_xrender_format, - _pluck_xrender_format, - connection->visual_to_xrender_format); - _cairo_hash_table_destroy (connection->visual_to_xrender_format); - -#if CAIRO_HAS_XCB_SHM_FUNCTIONS - _cairo_xcb_connection_shm_mem_pools_fini (connection); -#endif - _cairo_freepool_fini (&connection->shm_info_freelist); - - _cairo_freepool_fini (&connection->xid_pool); - - CAIRO_MUTEX_FINI (connection->shm_mutex); - CAIRO_MUTEX_FINI (connection->screens_mutex); - - free (connection->subpixel_orders); - free (connection); -} - -static const cairo_device_backend_t _cairo_xcb_device_backend = { - CAIRO_DEVICE_TYPE_XCB, - - NULL, NULL, /* lock, unlock */ - - _device_flush, - _device_finish, - _device_destroy, -}; - -cairo_xcb_connection_t * -_cairo_xcb_connection_get (xcb_connection_t *xcb_connection) -{ - cairo_xcb_connection_t *connection; - const xcb_query_extension_reply_t *ext; - cairo_status_t status; - - CAIRO_MUTEX_INITIALIZE (); - - CAIRO_MUTEX_LOCK (_cairo_xcb_connections_mutex); - if (connections.next == NULL) { - /* XXX _cairo_init () */ - cairo_list_init (&connections); - } - - cairo_list_foreach_entry (connection, - cairo_xcb_connection_t, - &connections, - link) - { - if (connection->xcb_connection == xcb_connection) { - /* Maintain MRU order. */ - if (connections.next != &connection->link) - cairo_list_move (&connection->link, &connections); - - goto unlock; - } - } - - connection = malloc (sizeof (cairo_xcb_connection_t)); - if (unlikely (connection == NULL)) - goto unlock; - - _cairo_device_init (&connection->device, &_cairo_xcb_device_backend); - - connection->xcb_connection = xcb_connection; - - cairo_list_init (&connection->fonts); - cairo_list_init (&connection->screens); - cairo_list_init (&connection->link); - connection->xrender_formats = _cairo_hash_table_create (NULL); - if (connection->xrender_formats == NULL) { - CAIRO_MUTEX_FINI (connection->device.mutex); - free (connection); - connection = NULL; - goto unlock; - } - - connection->visual_to_xrender_format = _cairo_hash_table_create (NULL); - if (connection->visual_to_xrender_format == NULL) { - _cairo_hash_table_destroy (connection->xrender_formats); - CAIRO_MUTEX_FINI (connection->device.mutex); - free (connection); - connection = NULL; - goto unlock; - } - - cairo_list_init (&connection->free_xids); - _cairo_freepool_init (&connection->xid_pool, - sizeof (cairo_xcb_xid_t)); - - cairo_list_init (&connection->shm_pools); - cairo_list_init (&connection->shm_pending); - _cairo_freepool_init (&connection->shm_info_freelist, - sizeof (cairo_xcb_shm_info_t)); - - connection->maximum_request_length = - xcb_get_maximum_request_length (xcb_connection); - - CAIRO_MUTEX_INIT (connection->shm_mutex); - CAIRO_MUTEX_INIT (connection->screens_mutex); - - CAIRO_MUTEX_LOCK (connection->device.mutex); - - connection->flags = 0; - connection->force_precision = -1; - - xcb_prefetch_extension_data (xcb_connection, &xcb_big_requests_id); - xcb_prefetch_extension_data (xcb_connection, &xcb_render_id); -#if CAIRO_HAS_XCB_SHM_FUNCTIONS - xcb_prefetch_extension_data (xcb_connection, &xcb_shm_id); -#endif -#if 0 - xcb_prefetch_extension_data (xcb_connection, &xcb_cairo_id); -#endif - - xcb_prefetch_maximum_request_length (xcb_connection); - - connection->root = xcb_get_setup (xcb_connection); - connection->render = NULL; - connection->subpixel_orders = calloc (connection->root->roots_len, sizeof(*connection->subpixel_orders)); - if (unlikely (connection->subpixel_orders == NULL)) { - CAIRO_MUTEX_UNLOCK (connection->device.mutex); - _cairo_xcb_connection_destroy (connection); - connection = NULL; - goto unlock; - } - - ext = xcb_get_extension_data (xcb_connection, &xcb_render_id); - if (ext != NULL && ext->present) { - status = _cairo_xcb_connection_query_render (connection); - if (unlikely (status)) { - CAIRO_MUTEX_UNLOCK (connection->device.mutex); - _cairo_xcb_connection_destroy (connection); - connection = NULL; - goto unlock; - } - - connection->render = ext; - } - -#if 0 - ext = xcb_get_extension_data (connection, &xcb_cairo_id); - if (ext != NULL && ext->present) - _cairo_xcb_connection_query_cairo (connection); -#endif - - connection->shm = NULL; -#if CAIRO_HAS_XCB_SHM_FUNCTIONS - ext = xcb_get_extension_data (xcb_connection, &xcb_shm_id); - if (ext != NULL && ext->present) { - _cairo_xcb_connection_query_shm (connection); - connection->shm = ext; - } -#endif - - connection->original_flags = connection->flags; - - CAIRO_MUTEX_UNLOCK (connection->device.mutex); - - cairo_list_add (&connection->link, &connections); -unlock: - CAIRO_MUTEX_UNLOCK (_cairo_xcb_connections_mutex); - - return connection; -} - -xcb_render_pictformat_t -_cairo_xcb_connection_get_xrender_format (cairo_xcb_connection_t *connection, - pixman_format_code_t pixman_format) -{ - cairo_hash_entry_t key; - cairo_xcb_xrender_format_t *format; - - key.hash = pixman_format; - format = _cairo_hash_table_lookup (connection->xrender_formats, &key); - return format ? format->xrender_format : XCB_NONE; -} - -xcb_render_pictformat_t -_cairo_xcb_connection_get_xrender_format_for_visual (cairo_xcb_connection_t *connection, - const xcb_visualid_t visual) -{ - cairo_hash_entry_t key; - cairo_xcb_xrender_format_t *format; - - key.hash = visual; - format = _cairo_hash_table_lookup (connection->visual_to_xrender_format, &key); - return format ? format->xrender_format : XCB_NONE; -} - -void -_cairo_xcb_connection_put_xid (cairo_xcb_connection_t *connection, - uint32_t xid) -{ - cairo_xcb_xid_t *cache; - - assert (CAIRO_MUTEX_IS_LOCKED (connection->device.mutex)); - cache = _cairo_freepool_alloc (&connection->xid_pool); - if (likely (cache != NULL)) { - cache->xid = xid; - cairo_list_add (&cache->link, &connection->free_xids); - } -} - -uint32_t -_cairo_xcb_connection_get_xid (cairo_xcb_connection_t *connection) -{ - uint32_t xid; - - assert (CAIRO_MUTEX_IS_LOCKED (connection->device.mutex)); - if (! cairo_list_is_empty (&connection->free_xids)) { - cairo_xcb_xid_t *cache; - - cache = cairo_list_first_entry (&connection->free_xids, - cairo_xcb_xid_t, - link); - xid = cache->xid; - - cairo_list_del (&cache->link); - _cairo_freepool_free (&connection->xid_pool, cache); - } else { - xid = xcb_generate_id (connection->xcb_connection); - } - - return xid; -} - -/** - * cairo_xcb_device_get_connection: - * @device: a #cairo_device_t for the XCB backend - * - * Get the connection for the XCB device. - * - * Returns: the #xcb_connection_t for the connection - * - * Since: 1.12 - **/ -xcb_connection_t * -cairo_xcb_device_get_connection (cairo_device_t *device) -{ - if (device->backend->type != CAIRO_DEVICE_TYPE_XCB) - return NULL; - - return ((cairo_xcb_connection_t *)device)->xcb_connection; -} - -/* public (debug) interface */ - -/** - * cairo_xcb_device_debug_cap_xshm_version: - * @device: a #cairo_device_t for the XCB backend - * @major_version: major version to restrict to - * @minor_version: minor version to restrict to - * - * Restricts all future XCB surfaces for this devices to the specified version - * of the SHM extension. This function exists solely for debugging purpose. - * It let's you find out how cairo would behave with an older version of - * the SHM extension. - * - * Use the special values -1 and -1 for disabling the SHM extension. - * - * Since: 1.12 - **/ -void -cairo_xcb_device_debug_cap_xshm_version (cairo_device_t *device, - int major_version, - int minor_version) -{ - cairo_xcb_connection_t *connection = (cairo_xcb_connection_t *) device; - - if (device->backend->type != CAIRO_DEVICE_TYPE_XCB) { - cairo_status_t status; - - status = _cairo_device_set_error (device, CAIRO_STATUS_DEVICE_TYPE_MISMATCH); - (void) status; - return; - } - - /* First reset all the SHM flags to their original value. This works - * because we only ever clear bits after the connection was created. - */ - connection->flags |= (connection->original_flags & CAIRO_XCB_SHM_MASK); - - /* clear any flags that are inappropriate for the desired version */ - if (major_version < 0 && minor_version < 0) { - connection->flags &= ~(CAIRO_XCB_HAS_SHM); - } -} - -/** - * cairo_xcb_device_debug_cap_xrender_version: - * @device: a #cairo_device_t for the XCB backend - * @major_version: major version to restrict to - * @minor_version: minor version to restrict to - * - * Restricts all future XCB surfaces for this devices to the specified version - * of the RENDER extension. This function exists solely for debugging purpose. - * It let's you find out how cairo would behave with an older version of - * the RENDER extension. - * - * Use the special values -1 and -1 for disabling the RENDER extension. - * - * Since: 1.12 - **/ -void -cairo_xcb_device_debug_cap_xrender_version (cairo_device_t *device, - int major_version, - int minor_version) -{ - cairo_xcb_connection_t *connection = (cairo_xcb_connection_t *) device; - - if (device->backend->type != CAIRO_DEVICE_TYPE_XCB) { - cairo_status_t status; - - status = _cairo_device_set_error (device, CAIRO_STATUS_DEVICE_TYPE_MISMATCH); - (void) status; - return; - } - - /* First reset all the RENDER flags to their original value. This works - * because we only ever clear bits after the connection was created. - */ - connection->flags |= (connection->original_flags & CAIRO_XCB_RENDER_MASK); - - /* clear any flags that are inappropriate for the desired version */ - if (major_version < 0 && minor_version < 0) { - connection->flags &= ~(CAIRO_XCB_HAS_RENDER | - CAIRO_XCB_RENDER_HAS_COMPOSITE | - CAIRO_XCB_RENDER_HAS_COMPOSITE_GLYPHS | - CAIRO_XCB_RENDER_HAS_FILL_RECTANGLES | - CAIRO_XCB_RENDER_HAS_COMPOSITE_TRAPEZOIDS | - CAIRO_XCB_RENDER_HAS_PICTURE_TRANSFORM | - CAIRO_XCB_RENDER_HAS_FILTERS | - CAIRO_XCB_RENDER_HAS_FILTER_GOOD | - CAIRO_XCB_RENDER_HAS_FILTER_BEST | - CAIRO_XCB_RENDER_HAS_PDF_OPERATORS | - CAIRO_XCB_RENDER_HAS_EXTENDED_REPEAT | - CAIRO_XCB_RENDER_HAS_GRADIENTS); - } else { - xcb_render_query_version_reply_t version; - - version.major_version = major_version; - version.minor_version = minor_version; - - if (! XCB_RENDER_HAS_FILL_RECTANGLES (&version)) - connection->flags &= ~CAIRO_XCB_RENDER_HAS_FILL_RECTANGLES; - - if (! XCB_RENDER_HAS_TRAPEZOIDS (&version)) - connection->flags &= ~CAIRO_XCB_RENDER_HAS_COMPOSITE_TRAPEZOIDS; - - if (! XCB_RENDER_HAS_PICTURE_TRANSFORM (&version)) - connection->flags &= ~CAIRO_XCB_RENDER_HAS_PICTURE_TRANSFORM; - - if (! XCB_RENDER_HAS_FILTERS (&version)) - connection->flags &= ~CAIRO_XCB_RENDER_HAS_FILTERS; - - if (! XCB_RENDER_HAS_PDF_OPERATORS (&version)) - connection->flags &= ~CAIRO_XCB_RENDER_HAS_PDF_OPERATORS; - - if (! XCB_RENDER_HAS_EXTENDED_REPEAT (&version)) - connection->flags &= ~CAIRO_XCB_RENDER_HAS_EXTENDED_REPEAT; - - if (! XCB_RENDER_HAS_GRADIENTS (&version)) - connection->flags &= ~CAIRO_XCB_RENDER_HAS_GRADIENTS; - } -} -#if CAIRO_HAS_XLIB_XCB_FUNCTIONS -slim_hidden_def (cairo_xcb_device_debug_cap_xrender_version); -#endif - -/** - * cairo_xcb_device_debug_set_precision: - * @device: a #cairo_device_t for the XCB backend - * @precision: the precision to use - * - * Render supports two modes of precision when rendering trapezoids. Set - * the precision to the desired mode. - * - * Since: 1.12 - **/ -void -cairo_xcb_device_debug_set_precision (cairo_device_t *device, - int precision) -{ - if (device == NULL || device->status) - return; - if (device->backend->type != CAIRO_DEVICE_TYPE_XCB) { - cairo_status_t status; - - status = _cairo_device_set_error (device, CAIRO_STATUS_DEVICE_TYPE_MISMATCH); - (void) status; - return; - } - - ((cairo_xcb_connection_t *) device)->force_precision = precision; -} -#if CAIRO_HAS_XLIB_XCB_FUNCTIONS -slim_hidden_def (cairo_xcb_device_debug_set_precision); -#endif - -/** - * cairo_xcb_device_debug_get_precision: - * @device: a #cairo_device_t for the XCB backend - * - * Get the Xrender precision mode. - * - * Returns: the render precision mode - * - * Since: 1.12 - **/ -int -cairo_xcb_device_debug_get_precision (cairo_device_t *device) -{ - if (device == NULL || device->status) - return -1; - if (device->backend->type != CAIRO_DEVICE_TYPE_XCB) { - cairo_status_t status; - - status = _cairo_device_set_error (device, CAIRO_STATUS_DEVICE_TYPE_MISMATCH); - (void) status; - return -1; - } - - return ((cairo_xcb_connection_t *) device)->force_precision; -} -#if CAIRO_HAS_XLIB_XCB_FUNCTIONS -slim_hidden_def (cairo_xcb_device_debug_get_precision); -#endif diff --git a/source/libs/cairo/cairo-src/src/cairo-xcb-private.h b/source/libs/cairo/cairo-src/src/cairo-xcb-private.h deleted file mode 100644 index f5d5a4c81c788231ae65a721fa3caf3d578cc717..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xcb-private.h +++ /dev/null @@ -1,801 +0,0 @@ -/* Cairo - a vector graphics library with display and print output - * - * Copyright © 2005 Red Hat, Inc. - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributors(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_XCB_PRIVATE_H -#define CAIRO_XCB_PRIVATE_H - -#include "cairoint.h" - -#include "cairo-xcb.h" - -#include "cairo-cache-private.h" -#include "cairo-compiler-private.h" -#include "cairo-device-private.h" -#include "cairo-error-private.h" -#include "cairo-freelist-private.h" -#include "cairo-list-private.h" -#include "cairo-mutex-private.h" -#include "cairo-pattern-private.h" -#include "cairo-reference-count-private.h" -#include "cairo-scaled-font-private.h" -#include "cairo-spans-private.h" -#include "cairo-surface-private.h" - -#include <xcb/xcb.h> -#include <xcb/render.h> -#include <xcb/xcbext.h> -#include <pixman.h> - -#define XLIB_COORD_MAX 32767 - -/* maximum number of cached GC's */ -#define GC_CACHE_SIZE 4 - -#define CAIRO_XCB_RENDER_AT_LEAST(major, minor) \ - ((XCB_RENDER_MAJOR_VERSION > major) || \ - ((XCB_RENDER_MAJOR_VERSION == major) && (XCB_RENDER_MINOR_VERSION >= minor))) - -typedef struct _cairo_xcb_connection cairo_xcb_connection_t; -typedef struct _cairo_xcb_font cairo_xcb_font_t; -typedef struct _cairo_xcb_screen cairo_xcb_screen_t; -typedef struct _cairo_xcb_surface cairo_xcb_surface_t; -typedef struct _cairo_xcb_picture cairo_xcb_picture_t; -typedef struct _cairo_xcb_shm_mem_pool cairo_xcb_shm_mem_pool_t; -typedef struct _cairo_xcb_shm_info cairo_xcb_shm_info_t; -typedef struct _cairo_xcb_resources cairo_xcb_resources_t; - -struct _cairo_xcb_shm_info { - cairo_xcb_connection_t *connection; - uint32_t shm; - uint32_t offset; - size_t size; - void *mem; - cairo_xcb_shm_mem_pool_t *pool; - xcb_get_input_focus_cookie_t sync; - cairo_list_t pending; -}; - -struct _cairo_xcb_surface { - cairo_surface_t base; - cairo_image_surface_t *fallback; - cairo_boxes_t fallback_damage; - - cairo_xcb_connection_t *connection; - cairo_xcb_screen_t *screen; - - xcb_drawable_t drawable; - cairo_bool_t owns_pixmap; - - cairo_bool_t deferred_clear; - cairo_color_t deferred_clear_color; - - int width; - int height; - int depth; - - xcb_render_picture_t picture; - xcb_render_pictformat_t xrender_format; - pixman_format_code_t pixman_format; - uint32_t precision; - - cairo_list_t link; -}; - -struct _cairo_xcb_picture { - cairo_surface_t base; - - cairo_xcb_screen_t *screen; - xcb_render_picture_t picture; - xcb_render_pictformat_t xrender_format; - pixman_format_code_t pixman_format; - - int width, height; - - cairo_extend_t extend; - cairo_filter_t filter; - cairo_bool_t has_component_alpha; - xcb_render_transform_t transform; - - int x0, y0; - int x, y; - - cairo_list_t link; -}; - -#if CAIRO_HAS_XLIB_XCB_FUNCTIONS -typedef struct _cairo_xlib_xcb_surface { - cairo_surface_t base; - - cairo_xcb_surface_t *xcb; - - /* original settings for query */ - void *display; - void *screen; - void *visual; - void *format; -} cairo_xlib_xcb_surface_t; -#endif - - -enum { - GLYPHSET_INDEX_ARGB32, - GLYPHSET_INDEX_A8, - GLYPHSET_INDEX_A1, - NUM_GLYPHSETS -}; - -typedef struct _cairo_xcb_font_glyphset_free_glyphs { - xcb_render_glyphset_t glyphset; - int glyph_count; - xcb_render_glyph_t glyph_indices[128]; -} cairo_xcb_font_glyphset_free_glyphs_t; - -typedef struct _cairo_xcb_font_glyphset_info { - xcb_render_glyphset_t glyphset; - cairo_format_t format; - xcb_render_pictformat_t xrender_format; - cairo_xcb_font_glyphset_free_glyphs_t *pending_free_glyphs; -} cairo_xcb_font_glyphset_info_t; - -struct _cairo_xcb_font { - cairo_scaled_font_private_t base; - cairo_scaled_font_t *scaled_font; - cairo_xcb_connection_t *connection; - cairo_xcb_font_glyphset_info_t glyphset_info[NUM_GLYPHSETS]; - cairo_list_t link; -}; - -struct _cairo_xcb_screen { - cairo_xcb_connection_t *connection; - - xcb_screen_t *xcb_screen; - xcb_render_sub_pixel_t subpixel_order; - - xcb_gcontext_t gc[GC_CACHE_SIZE]; - uint8_t gc_depths[GC_CACHE_SIZE]; - - cairo_surface_t *stock_colors[CAIRO_STOCK_NUM_COLORS]; - struct { - cairo_surface_t *picture; - cairo_color_t color; - } solid_cache[16]; - int solid_cache_size; - - cairo_cache_t linear_pattern_cache; - cairo_cache_t radial_pattern_cache; - cairo_freelist_t pattern_cache_entry_freelist; - - cairo_list_t link; - cairo_list_t surfaces; - cairo_list_t pictures; - - cairo_bool_t has_font_options; - cairo_font_options_t font_options; -}; - -struct _cairo_xcb_connection { - cairo_device_t device; - - xcb_connection_t *xcb_connection; - - xcb_render_pictformat_t standard_formats[5]; - cairo_hash_table_t *xrender_formats; - cairo_hash_table_t *visual_to_xrender_format; - - unsigned int maximum_request_length; - unsigned int flags; - unsigned int original_flags; - - int force_precision; - - const xcb_setup_t *root; - const xcb_query_extension_reply_t *render; - const xcb_query_extension_reply_t *shm; - xcb_render_sub_pixel_t *subpixel_orders; - - cairo_list_t free_xids; - cairo_freepool_t xid_pool; - - cairo_mutex_t shm_mutex; - cairo_list_t shm_pools; - cairo_list_t shm_pending; - cairo_freepool_t shm_info_freelist; - - cairo_mutex_t screens_mutex; - cairo_list_t screens; - - cairo_list_t fonts; - - cairo_list_t link; -}; - -struct _cairo_xcb_resources { - cairo_bool_t xft_antialias; - int xft_lcdfilter; - cairo_bool_t xft_hinting; - int xft_hintstyle; - int xft_rgba; -}; - -enum { - CAIRO_XCB_HAS_RENDER = 0x0001, - CAIRO_XCB_RENDER_HAS_FILL_RECTANGLES = 0x0002, - CAIRO_XCB_RENDER_HAS_COMPOSITE = 0x0004, - CAIRO_XCB_RENDER_HAS_COMPOSITE_TRAPEZOIDS = 0x0008, - CAIRO_XCB_RENDER_HAS_COMPOSITE_GLYPHS = 0x0010, - CAIRO_XCB_RENDER_HAS_PICTURE_TRANSFORM = 0x0020, - CAIRO_XCB_RENDER_HAS_FILTERS = 0x0040, - CAIRO_XCB_RENDER_HAS_PDF_OPERATORS = 0x0080, - CAIRO_XCB_RENDER_HAS_EXTENDED_REPEAT = 0x0100, - CAIRO_XCB_RENDER_HAS_GRADIENTS = 0x0200, - CAIRO_XCB_RENDER_HAS_FILTER_GOOD = 0x0400, - CAIRO_XCB_RENDER_HAS_FILTER_BEST = 0x0800, - - CAIRO_XCB_HAS_SHM = 0x80000000, - - CAIRO_XCB_RENDER_MASK = CAIRO_XCB_HAS_RENDER | - CAIRO_XCB_RENDER_HAS_FILL_RECTANGLES | - CAIRO_XCB_RENDER_HAS_COMPOSITE | - CAIRO_XCB_RENDER_HAS_COMPOSITE_TRAPEZOIDS | - CAIRO_XCB_RENDER_HAS_COMPOSITE_GLYPHS | - CAIRO_XCB_RENDER_HAS_PICTURE_TRANSFORM | - CAIRO_XCB_RENDER_HAS_FILTERS | - CAIRO_XCB_RENDER_HAS_PDF_OPERATORS | - CAIRO_XCB_RENDER_HAS_EXTENDED_REPEAT | - CAIRO_XCB_RENDER_HAS_GRADIENTS | - CAIRO_XCB_RENDER_HAS_FILTER_GOOD | - CAIRO_XCB_RENDER_HAS_FILTER_BEST, - CAIRO_XCB_SHM_MASK = CAIRO_XCB_HAS_SHM -}; - -#define CAIRO_XCB_SHM_SMALL_IMAGE 8192 - -cairo_private extern const cairo_surface_backend_t _cairo_xcb_surface_backend; - -/** - * _cairo_surface_is_xcb: - * @surface: a #cairo_surface_t - * - * Checks if a surface is an #cairo_xcb_surface_t - * - * Return value: %TRUE if the surface is an xcb surface - **/ -static inline cairo_bool_t -_cairo_surface_is_xcb (const cairo_surface_t *surface) -{ - /* _cairo_surface_nil sets a NULL backend so be safe */ - return surface->backend && surface->backend->type == CAIRO_SURFACE_TYPE_XCB; -} - -cairo_private cairo_xcb_connection_t * -_cairo_xcb_connection_get (xcb_connection_t *connection); - -static inline cairo_xcb_connection_t * -_cairo_xcb_connection_reference (cairo_xcb_connection_t *connection) -{ - return (cairo_xcb_connection_t *) cairo_device_reference (&connection->device); -} - -cairo_private xcb_render_pictformat_t -_cairo_xcb_connection_get_xrender_format (cairo_xcb_connection_t *connection, - pixman_format_code_t pixman_format); - -cairo_private xcb_render_pictformat_t -_cairo_xcb_connection_get_xrender_format_for_visual (cairo_xcb_connection_t *connection, - const xcb_visualid_t visual); - -static inline cairo_status_t cairo_warn -_cairo_xcb_connection_acquire (cairo_xcb_connection_t *connection) -{ - return cairo_device_acquire (&connection->device); -} - -cairo_private uint32_t -_cairo_xcb_connection_get_xid (cairo_xcb_connection_t *connection); - -cairo_private void -_cairo_xcb_connection_put_xid (cairo_xcb_connection_t *connection, - uint32_t xid); - -static inline void -_cairo_xcb_connection_release (cairo_xcb_connection_t *connection) -{ - cairo_device_release (&connection->device); -} - -static inline void -_cairo_xcb_connection_destroy (cairo_xcb_connection_t *connection) -{ - cairo_device_destroy (&connection->device); -} - -cairo_private cairo_int_status_t -_cairo_xcb_connection_allocate_shm_info (cairo_xcb_connection_t *display, - size_t size, - cairo_bool_t might_reuse, - cairo_xcb_shm_info_t **shm_info_out); - -cairo_private void -_cairo_xcb_shm_info_destroy (cairo_xcb_shm_info_t *shm_info); - -cairo_private void -_cairo_xcb_connection_shm_mem_pools_flush (cairo_xcb_connection_t *connection); - -cairo_private void -_cairo_xcb_connection_shm_mem_pools_fini (cairo_xcb_connection_t *connection); - -cairo_private void -_cairo_xcb_font_close (cairo_xcb_font_t *font); - -cairo_private cairo_xcb_screen_t * -_cairo_xcb_screen_get (xcb_connection_t *connection, - xcb_screen_t *screen); - -cairo_private void -_cairo_xcb_screen_finish (cairo_xcb_screen_t *screen); - -cairo_private xcb_gcontext_t -_cairo_xcb_screen_get_gc (cairo_xcb_screen_t *screen, - xcb_drawable_t drawable, - int depth); - -cairo_private void -_cairo_xcb_screen_put_gc (cairo_xcb_screen_t *screen, int depth, xcb_gcontext_t gc); - -cairo_private cairo_font_options_t * -_cairo_xcb_screen_get_font_options (cairo_xcb_screen_t *screen); - -cairo_private cairo_status_t -_cairo_xcb_screen_store_linear_picture (cairo_xcb_screen_t *screen, - const cairo_linear_pattern_t *linear, - cairo_surface_t *picture); - -cairo_private cairo_surface_t * -_cairo_xcb_screen_lookup_linear_picture (cairo_xcb_screen_t *screen, - const cairo_linear_pattern_t *linear); - -cairo_private cairo_status_t -_cairo_xcb_screen_store_radial_picture (cairo_xcb_screen_t *screen, - const cairo_radial_pattern_t *radial, - cairo_surface_t *picture); - -cairo_private cairo_surface_t * -_cairo_xcb_screen_lookup_radial_picture (cairo_xcb_screen_t *screen, - const cairo_radial_pattern_t *radial); - -cairo_private cairo_surface_t * -_cairo_xcb_surface_create_similar_image (void *abstrct_other, - cairo_format_t format, - int width, - int height); - -cairo_private cairo_surface_t * -_cairo_xcb_surface_create_similar (void *abstract_other, - cairo_content_t content, - int width, - int height); - -cairo_private cairo_surface_t * -_cairo_xcb_surface_create_internal (cairo_xcb_screen_t *screen, - xcb_drawable_t drawable, - cairo_bool_t owns_pixmap, - pixman_format_code_t pixman_format, - xcb_render_pictformat_t xrender_format, - int width, - int height); - -cairo_private_no_warn cairo_bool_t -_cairo_xcb_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *extents); - -cairo_private cairo_int_status_t -_cairo_xcb_render_compositor_paint (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *extents); - -cairo_private cairo_int_status_t -_cairo_xcb_render_compositor_mask (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *extents); - -cairo_private cairo_int_status_t -_cairo_xcb_render_compositor_stroke (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias); - -cairo_private cairo_int_status_t -_cairo_xcb_render_compositor_fill (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias); - -cairo_private cairo_int_status_t -_cairo_xcb_render_compositor_glyphs (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_bool_t overlap); -cairo_private void -_cairo_xcb_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font); - -cairo_private void -_cairo_xcb_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph, - cairo_scaled_font_t *scaled_font); - -cairo_private cairo_status_t -_cairo_xcb_surface_clear (cairo_xcb_surface_t *dst); - -cairo_private cairo_status_t -_cairo_xcb_surface_core_copy_boxes (cairo_xcb_surface_t *dst, - const cairo_pattern_t *src_pattern, - const cairo_rectangle_int_t *extents, - const cairo_boxes_t *boxes); - -cairo_private cairo_status_t -_cairo_xcb_surface_core_fill_boxes (cairo_xcb_surface_t *dst, - const cairo_color_t *color, - cairo_boxes_t *boxes); - -cairo_private xcb_pixmap_t -_cairo_xcb_connection_create_pixmap (cairo_xcb_connection_t *connection, - uint8_t depth, - xcb_drawable_t drawable, - uint16_t width, - uint16_t height); - -cairo_private void -_cairo_xcb_connection_free_pixmap (cairo_xcb_connection_t *connection, - xcb_pixmap_t pixmap); - -cairo_private xcb_gcontext_t -_cairo_xcb_connection_create_gc (cairo_xcb_connection_t *connection, - xcb_drawable_t drawable, - uint32_t value_mask, - uint32_t *values); - -cairo_private void -_cairo_xcb_connection_free_gc (cairo_xcb_connection_t *connection, - xcb_gcontext_t gc); - -cairo_private void -_cairo_xcb_connection_change_gc (cairo_xcb_connection_t *connection, - xcb_gcontext_t gc, - uint32_t value_mask, - uint32_t *values); - -cairo_private void -_cairo_xcb_connection_copy_area (cairo_xcb_connection_t *connection, - xcb_drawable_t src, - xcb_drawable_t dst, - xcb_gcontext_t gc, - int16_t src_x, - int16_t src_y, - int16_t dst_x, - int16_t dst_y, - uint16_t width, - uint16_t height); - -cairo_private void -_cairo_xcb_connection_put_image (cairo_xcb_connection_t *connection, - xcb_drawable_t dst, - xcb_gcontext_t gc, - uint16_t width, - uint16_t height, - int16_t dst_x, - int16_t dst_y, - uint8_t depth, - uint32_t length, - void *data); - -cairo_private void -_cairo_xcb_connection_put_subimage (cairo_xcb_connection_t *connection, - xcb_drawable_t dst, - xcb_gcontext_t gc, - int16_t src_x, - int16_t src_y, - uint16_t width, - uint16_t height, - uint16_t cpp, - int stride, - int16_t dst_x, - int16_t dst_y, - uint8_t depth, - void *data); - -cairo_private xcb_get_image_reply_t * -_cairo_xcb_connection_get_image (cairo_xcb_connection_t *connection, - xcb_drawable_t src, - int16_t src_x, - int16_t src_y, - uint16_t width, - uint16_t height); - -cairo_private void -_cairo_xcb_connection_poly_fill_rectangle (cairo_xcb_connection_t *connection, - xcb_drawable_t dst, - xcb_gcontext_t gc, - uint32_t num_rectangles, - xcb_rectangle_t *rectangles); - -cairo_private cairo_status_t -_cairo_xcb_shm_image_create (cairo_xcb_connection_t *connection, - pixman_format_code_t pixman_format, - int width, int height, - cairo_image_surface_t **image_out, - cairo_xcb_shm_info_t **shm_info_out); - -#if CAIRO_HAS_XCB_SHM_FUNCTIONS -cairo_private uint32_t -_cairo_xcb_connection_shm_attach (cairo_xcb_connection_t *connection, - uint32_t id, - cairo_bool_t readonly); - -cairo_private void -_cairo_xcb_connection_shm_put_image (cairo_xcb_connection_t *connection, - xcb_drawable_t dst, - xcb_gcontext_t gc, - uint16_t total_width, - uint16_t total_height, - int16_t src_x, - int16_t src_y, - uint16_t width, - uint16_t height, - int16_t dst_x, - int16_t dst_y, - uint8_t depth, - uint32_t shm, - uint32_t offset); - -cairo_private cairo_status_t -_cairo_xcb_connection_shm_get_image (cairo_xcb_connection_t *connection, - xcb_drawable_t src, - int16_t src_x, - int16_t src_y, - uint16_t width, - uint16_t height, - uint32_t shmseg, - uint32_t offset); - -cairo_private void -_cairo_xcb_connection_shm_detach (cairo_xcb_connection_t *connection, - uint32_t segment); -#else -static inline void -_cairo_xcb_connection_shm_put_image (cairo_xcb_connection_t *connection, - xcb_drawable_t dst, - xcb_gcontext_t gc, - uint16_t total_width, - uint16_t total_height, - int16_t src_x, - int16_t src_y, - uint16_t width, - uint16_t height, - int16_t dst_x, - int16_t dst_y, - uint8_t depth, - uint32_t shm, - uint32_t offset) -{ - ASSERT_NOT_REACHED; -} -#endif - -cairo_private void -_cairo_xcb_connection_render_create_picture (cairo_xcb_connection_t *connection, - xcb_render_picture_t picture, - xcb_drawable_t drawable, - xcb_render_pictformat_t format, - uint32_t value_mask, - uint32_t *value_list); - -cairo_private void -_cairo_xcb_connection_render_change_picture (cairo_xcb_connection_t *connection, - xcb_render_picture_t picture, - uint32_t value_mask, - uint32_t *value_list); - -cairo_private void -_cairo_xcb_connection_render_set_picture_clip_rectangles (cairo_xcb_connection_t *connection, - xcb_render_picture_t picture, - int16_t clip_x_origin, - int16_t clip_y_origin, - uint32_t rectangles_len, - xcb_rectangle_t *rectangles); - -cairo_private void -_cairo_xcb_connection_render_free_picture (cairo_xcb_connection_t *connection, - xcb_render_picture_t picture); - -cairo_private void -_cairo_xcb_connection_render_composite (cairo_xcb_connection_t *connection, - uint8_t op, - xcb_render_picture_t src, - xcb_render_picture_t mask, - xcb_render_picture_t dst, - int16_t src_x, - int16_t src_y, - int16_t mask_x, - int16_t mask_y, - int16_t dst_x, - int16_t dst_y, - uint16_t width, - uint16_t height); - -cairo_private void -_cairo_xcb_connection_render_trapezoids (cairo_xcb_connection_t *connection, - uint8_t op, - xcb_render_picture_t src, - xcb_render_picture_t dst, - xcb_render_pictformat_t mask_format, - int16_t src_x, - int16_t src_y, - uint32_t traps_len, - xcb_render_trapezoid_t *traps); - -cairo_private void -_cairo_xcb_connection_render_create_glyph_set (cairo_xcb_connection_t *connection, - xcb_render_glyphset_t id, - xcb_render_pictformat_t format); - -cairo_private void -_cairo_xcb_connection_render_free_glyph_set (cairo_xcb_connection_t *connection, - xcb_render_glyphset_t glyphset); - -cairo_private void -_cairo_xcb_connection_render_add_glyphs (cairo_xcb_connection_t *connection, - xcb_render_glyphset_t glyphset, - uint32_t num_glyphs, - uint32_t *glyphs_id, - xcb_render_glyphinfo_t *glyphs, - uint32_t data_len, - uint8_t *data); - -cairo_private void -_cairo_xcb_connection_render_free_glyphs (cairo_xcb_connection_t *connection, - xcb_render_glyphset_t glyphset, - uint32_t num_glyphs, - xcb_render_glyph_t *glyphs); - -cairo_private void -_cairo_xcb_connection_render_composite_glyphs_8 (cairo_xcb_connection_t *connection, - uint8_t op, - xcb_render_picture_t src, - xcb_render_picture_t dst, - xcb_render_pictformat_t mask_format, - xcb_render_glyphset_t glyphset, - int16_t src_x, - int16_t src_y, - uint32_t glyphcmds_len, - uint8_t *glyphcmds); - -cairo_private void -_cairo_xcb_connection_render_composite_glyphs_16 (cairo_xcb_connection_t *connection, - uint8_t op, - xcb_render_picture_t src, - xcb_render_picture_t dst, - xcb_render_pictformat_t mask_format, - xcb_render_glyphset_t glyphset, - int16_t src_x, - int16_t src_y, - uint32_t glyphcmds_len, - uint8_t *glyphcmds); - -cairo_private void -_cairo_xcb_connection_render_composite_glyphs_32 (cairo_xcb_connection_t *connection, - uint8_t op, - xcb_render_picture_t src, - xcb_render_picture_t dst, - xcb_render_pictformat_t mask_format, - xcb_render_glyphset_t glyphset, - int16_t src_x, - int16_t src_y, - uint32_t glyphcmds_len, - uint8_t *glyphcmds); - -cairo_private void -_cairo_xcb_connection_render_fill_rectangles (cairo_xcb_connection_t *connection, - uint8_t op, - xcb_render_picture_t dst, - xcb_render_color_t color, - uint32_t num_rects, - xcb_rectangle_t *rects); - -cairo_private void -_cairo_xcb_connection_render_set_picture_transform (cairo_xcb_connection_t *connection, - xcb_render_picture_t picture, - xcb_render_transform_t *transform); - -cairo_private void -_cairo_xcb_connection_render_set_picture_filter (cairo_xcb_connection_t *connection, - xcb_render_picture_t picture, - uint16_t filter_len, - char *filter); - -cairo_private void -_cairo_xcb_connection_render_create_solid_fill (cairo_xcb_connection_t *connection, - xcb_render_picture_t picture, - xcb_render_color_t color); - -cairo_private void -_cairo_xcb_connection_render_create_linear_gradient (cairo_xcb_connection_t *connection, - xcb_render_picture_t picture, - xcb_render_pointfix_t p1, - xcb_render_pointfix_t p2, - uint32_t num_stops, - xcb_render_fixed_t *stops, - xcb_render_color_t *colors); - -cairo_private void -_cairo_xcb_connection_render_create_radial_gradient (cairo_xcb_connection_t *connection, - xcb_render_picture_t picture, - xcb_render_pointfix_t inner, - xcb_render_pointfix_t outer, - xcb_render_fixed_t inner_radius, - xcb_render_fixed_t outer_radius, - uint32_t num_stops, - xcb_render_fixed_t *stops, - xcb_render_color_t *colors); - -cairo_private void -_cairo_xcb_connection_render_create_conical_gradient (cairo_xcb_connection_t *c, - xcb_render_picture_t picture, - xcb_render_pointfix_t center, - xcb_render_fixed_t angle, - uint32_t num_stops, - xcb_render_fixed_t *stops, - xcb_render_color_t *colors); -#if CAIRO_HAS_XLIB_XCB_FUNCTIONS -slim_hidden_proto (cairo_xcb_surface_create); -slim_hidden_proto (cairo_xcb_surface_create_for_bitmap); -slim_hidden_proto (cairo_xcb_surface_create_with_xrender_format); -slim_hidden_proto (cairo_xcb_surface_set_size); -slim_hidden_proto (cairo_xcb_surface_set_drawable); -slim_hidden_proto (cairo_xcb_device_debug_get_precision); -slim_hidden_proto_no_warn (cairo_xcb_device_debug_set_precision); -slim_hidden_proto_no_warn (cairo_xcb_device_debug_cap_xrender_version); -#endif - -cairo_private void -_cairo_xcb_resources_get (cairo_xcb_screen_t *screen, - cairo_xcb_resources_t *resources); - -#endif /* CAIRO_XCB_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-xcb-resources.c b/source/libs/cairo/cairo-src/src/cairo-xcb-resources.c deleted file mode 100644 index 1877758c25a126711194ad0f6d441b9ce645222b..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xcb-resources.c +++ /dev/null @@ -1,281 +0,0 @@ -/* Cairo - a vector graphics library with display and print output - * - * Copyright © 2014 Lukas Lalinsky - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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. - * - * Authors: - * Lukas Lalinsky <lukas@oxygene.sk> - * - * Partially on code from xftdpy.c - * - * Copyright © 2000 Keith Packard - * - * 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 Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD 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. - */ - -#include "cairoint.h" - -#include "cairo-xcb-private.h" - -#include "cairo-fontconfig-private.h" - -static void -parse_boolean (const char *v, cairo_bool_t *out) -{ - char c0, c1; - - c0 = *v; - if (c0 == 't' || c0 == 'T' || c0 == 'y' || c0 == 'Y' || c0 == '1') - *out = TRUE; - if (c0 == 'f' || c0 == 'F' || c0 == 'n' || c0 == 'N' || c0 == '0') - *out = FALSE; - if (c0 == 'o') { - c1 = v[1]; - if (c1 == 'n' || c1 == 'N') - *out = TRUE; - if (c1 == 'f' || c1 == 'F') - *out = FALSE; - } -} - -static void -parse_integer (const char *v, int *out) -{ - char *e; - int value; - -#if CAIRO_HAS_FC_FONT - if (FcNameConstant ((FcChar8 *) v, out)) - return; -#endif - - value = strtol (v, &e, 0); - if (e != v) - *out = value; -} - -static char * -skip_spaces(char *str) -{ - while (*str == ' ' || *str == '\t' || *str == '\n') - str++; - return str; -} - -struct resource_parser { - int buffer_size; - int bytes_in_buffer; - char* buffer; - cairo_xcb_resources_t *resources; -}; - -static cairo_bool_t -resource_parse_line (char *name, cairo_xcb_resources_t *resources) -{ - char *value; - - value = strchr (name, ':'); - if (value == NULL) - return FALSE; - - *value++ = 0; - - name = skip_spaces (name); - value = skip_spaces (value); - - if (strcmp (name, "Xft.antialias") == 0) - parse_boolean (value, &(resources->xft_antialias)); - else if (strcmp (name, "Xft.lcdfilter") == 0) - parse_integer (value, &(resources->xft_lcdfilter)); - else if (strcmp (name, "Xft.rgba") == 0) - parse_integer (value, &(resources->xft_rgba)); - else if (strcmp (name, "Xft.hinting") == 0) - parse_boolean (value, &(resources->xft_hinting)); - else if (strcmp (name, "Xft.hintstyle") == 0) - parse_integer (value, &(resources->xft_hintstyle)); - - return TRUE; -} - -static int -resource_parse_lines (struct resource_parser *parser) -{ - char *line, *newline; - - line = parser->buffer; - while (1) { - newline = strchr (line, '\n'); - if (newline == NULL) - break; - - *newline++ = 0; - - if (! resource_parse_line (line, parser->resources)) - break; - - line = newline; - } - - return line - parser->buffer; -} - -static void -resource_parser_init (struct resource_parser *parser, cairo_xcb_resources_t *resources) -{ - parser->buffer_size = 0; - parser->bytes_in_buffer = 0; - parser->buffer = NULL; - parser->resources = resources; -} - -static cairo_bool_t -resource_parser_update (struct resource_parser *parser, const char *data, int length) -{ - int bytes_parsed; - - if (parser->bytes_in_buffer + length + 1 > parser->buffer_size) { - parser->buffer_size = parser->bytes_in_buffer + length + 1; - parser->buffer = realloc(parser->buffer, parser->buffer_size); - if (! parser->buffer) { - parser->buffer_size = 0; - parser->bytes_in_buffer = 0; - return FALSE; - } - } - - memmove (parser->buffer + parser->bytes_in_buffer, data, length); - parser->bytes_in_buffer += length; - parser->buffer[parser->bytes_in_buffer] = 0; - - bytes_parsed = resource_parse_lines (parser); - - if (parser->bytes_in_buffer > bytes_parsed) { - memmove (parser->buffer, parser->buffer + bytes_parsed, parser->bytes_in_buffer - bytes_parsed); - parser->bytes_in_buffer -= bytes_parsed; - } else { - parser->bytes_in_buffer = 0; - } - - return TRUE; -} - -static void -resource_parser_done (struct resource_parser *parser) -{ - if (parser->bytes_in_buffer > 0) { - parser->buffer[parser->bytes_in_buffer] = 0; - resource_parse_line (parser->buffer, parser->resources); - } - - free (parser->buffer); -} - -static void -get_resources(xcb_connection_t *connection, xcb_screen_t *screen, cairo_xcb_resources_t *resources) -{ - xcb_get_property_cookie_t cookie; - xcb_get_property_reply_t *reply; - struct resource_parser parser; - int offset; - cairo_bool_t has_more_data; - - resources->xft_antialias = TRUE; - resources->xft_lcdfilter = -1; - resources->xft_hinting = TRUE; - resources->xft_hintstyle = FC_HINT_FULL; - resources->xft_rgba = FC_RGBA_UNKNOWN; - - resource_parser_init (&parser, resources); - - offset = 0; - has_more_data = FALSE; - do { - cookie = xcb_get_property (connection, 0, screen->root, XCB_ATOM_RESOURCE_MANAGER, XCB_ATOM_STRING, offset, 1024); - reply = xcb_get_property_reply (connection, cookie, NULL); - - if (reply) { - if (reply->format == 8 && reply->type == XCB_ATOM_STRING) { - char *value = (char *) xcb_get_property_value (reply); - int length = xcb_get_property_value_length (reply); - - offset += length / 4; /* X needs the offset in 'long' units */ - has_more_data = reply->bytes_after > 0; - - if (! resource_parser_update (&parser, value, length)) - has_more_data = FALSE; /* early exit on error */ - } - - free (reply); - } - } while (has_more_data); - - resource_parser_done (&parser); -} - -void -_cairo_xcb_resources_get (cairo_xcb_screen_t *screen, cairo_xcb_resources_t *resources) -{ - get_resources (screen->connection->xcb_connection, screen->xcb_screen, resources); - - if (resources->xft_rgba == FC_RGBA_UNKNOWN) { - switch (screen->subpixel_order) { - case XCB_RENDER_SUB_PIXEL_UNKNOWN: - resources->xft_rgba = FC_RGBA_UNKNOWN; - break; - case XCB_RENDER_SUB_PIXEL_HORIZONTAL_RGB: - resources->xft_rgba = FC_RGBA_RGB; - break; - case XCB_RENDER_SUB_PIXEL_HORIZONTAL_BGR: - resources->xft_rgba = FC_RGBA_BGR; - break; - case XCB_RENDER_SUB_PIXEL_VERTICAL_RGB: - resources->xft_rgba = FC_RGBA_VRGB; - break; - case XCB_RENDER_SUB_PIXEL_VERTICAL_BGR: - resources->xft_rgba = FC_RGBA_VBGR; - break; - case XCB_RENDER_SUB_PIXEL_NONE: - resources->xft_rgba = FC_RGBA_NONE; - break; - } - } -} diff --git a/source/libs/cairo/cairo-src/src/cairo-xcb-screen.c b/source/libs/cairo/cairo-src/src/cairo-xcb-screen.c deleted file mode 100644 index d0019f9cdffb1728f75e82f40bd739e9b246c7af..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xcb-screen.c +++ /dev/null @@ -1,494 +0,0 @@ -/* Cairo - a vector graphics library with display and print output - * - * Copyright © 2008 Chris Wilson - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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. - * - * Authors: - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-xcb-private.h" -#include "cairo-list-inline.h" - -#include "cairo-fontconfig-private.h" - -static void -_cairo_xcb_init_screen_font_options (cairo_xcb_screen_t *screen) -{ - cairo_xcb_resources_t res; - cairo_antialias_t antialias; - cairo_subpixel_order_t subpixel_order; - cairo_lcd_filter_t lcd_filter; - cairo_hint_style_t hint_style; - - _cairo_xcb_resources_get (screen, &res); - - /* the rest of the code in this function is copied from - _cairo_xlib_init_screen_font_options in cairo-xlib-screen.c */ - - if (res.xft_hinting) { - switch (res.xft_hintstyle) { - case FC_HINT_NONE: - hint_style = CAIRO_HINT_STYLE_NONE; - break; - case FC_HINT_SLIGHT: - hint_style = CAIRO_HINT_STYLE_SLIGHT; - break; - case FC_HINT_MEDIUM: - hint_style = CAIRO_HINT_STYLE_MEDIUM; - break; - case FC_HINT_FULL: - hint_style = CAIRO_HINT_STYLE_FULL; - break; - default: - hint_style = CAIRO_HINT_STYLE_DEFAULT; - } - } else { - hint_style = CAIRO_HINT_STYLE_NONE; - } - - switch (res.xft_rgba) { - case FC_RGBA_RGB: - subpixel_order = CAIRO_SUBPIXEL_ORDER_RGB; - break; - case FC_RGBA_BGR: - subpixel_order = CAIRO_SUBPIXEL_ORDER_BGR; - break; - case FC_RGBA_VRGB: - subpixel_order = CAIRO_SUBPIXEL_ORDER_VRGB; - break; - case FC_RGBA_VBGR: - subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR; - break; - case FC_RGBA_UNKNOWN: - case FC_RGBA_NONE: - default: - subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT; - } - - switch (res.xft_lcdfilter) { - case FC_LCD_NONE: - lcd_filter = CAIRO_LCD_FILTER_NONE; - break; - case FC_LCD_DEFAULT: - lcd_filter = CAIRO_LCD_FILTER_FIR5; - break; - case FC_LCD_LIGHT: - lcd_filter = CAIRO_LCD_FILTER_FIR3; - break; - case FC_LCD_LEGACY: - lcd_filter = CAIRO_LCD_FILTER_INTRA_PIXEL; - break; - default: - lcd_filter = CAIRO_LCD_FILTER_DEFAULT; - break; - } - - if (res.xft_antialias) { - if (subpixel_order == CAIRO_SUBPIXEL_ORDER_DEFAULT) - antialias = CAIRO_ANTIALIAS_GRAY; - else - antialias = CAIRO_ANTIALIAS_SUBPIXEL; - } else { - antialias = CAIRO_ANTIALIAS_NONE; - } - - cairo_font_options_set_hint_style (&screen->font_options, hint_style); - cairo_font_options_set_antialias (&screen->font_options, antialias); - cairo_font_options_set_subpixel_order (&screen->font_options, subpixel_order); - _cairo_font_options_set_lcd_filter (&screen->font_options, lcd_filter); - cairo_font_options_set_hint_metrics (&screen->font_options, CAIRO_HINT_METRICS_ON); -} - -struct pattern_cache_entry { - cairo_cache_entry_t key; - cairo_xcb_screen_t *screen; - cairo_pattern_union_t pattern; - cairo_surface_t *picture; -}; - -void -_cairo_xcb_screen_finish (cairo_xcb_screen_t *screen) -{ - int i; - - CAIRO_MUTEX_LOCK (screen->connection->screens_mutex); - cairo_list_del (&screen->link); - CAIRO_MUTEX_UNLOCK (screen->connection->screens_mutex); - - while (! cairo_list_is_empty (&screen->surfaces)) { - cairo_surface_t *surface; - - surface = &cairo_list_first_entry (&screen->surfaces, - cairo_xcb_surface_t, - link)->base; - - cairo_surface_finish (surface); - } - - while (! cairo_list_is_empty (&screen->pictures)) { - cairo_surface_t *surface; - - surface = &cairo_list_first_entry (&screen->pictures, - cairo_xcb_picture_t, - link)->base; - - cairo_surface_finish (surface); - } - - for (i = 0; i < screen->solid_cache_size; i++) - cairo_surface_destroy (screen->solid_cache[i].picture); - - for (i = 0; i < ARRAY_LENGTH (screen->stock_colors); i++) - cairo_surface_destroy (screen->stock_colors[i]); - - for (i = 0; i < ARRAY_LENGTH (screen->gc); i++) { - if (screen->gc_depths[i] != 0) - _cairo_xcb_connection_free_gc (screen->connection, screen->gc[i]); - } - - _cairo_cache_fini (&screen->linear_pattern_cache); - _cairo_cache_fini (&screen->radial_pattern_cache); - _cairo_freelist_fini (&screen->pattern_cache_entry_freelist); - - free (screen); -} - -static cairo_bool_t -_linear_pattern_cache_entry_equal (const void *A, const void *B) -{ - const struct pattern_cache_entry *a = A, *b = B; - - return _cairo_linear_pattern_equal (&a->pattern.gradient.linear, - &b->pattern.gradient.linear); -} - -static cairo_bool_t -_radial_pattern_cache_entry_equal (const void *A, const void *B) -{ - const struct pattern_cache_entry *a = A, *b = B; - - return _cairo_radial_pattern_equal (&a->pattern.gradient.radial, - &b->pattern.gradient.radial); -} - -static void -_pattern_cache_entry_destroy (void *closure) -{ - struct pattern_cache_entry *entry = closure; - - _cairo_pattern_fini (&entry->pattern.base); - cairo_surface_destroy (entry->picture); - _cairo_freelist_free (&entry->screen->pattern_cache_entry_freelist, entry); -} - -static int _get_screen_index(cairo_xcb_connection_t *xcb_connection, - xcb_screen_t *xcb_screen) -{ - int idx = 0; - xcb_screen_iterator_t iter = xcb_setup_roots_iterator(xcb_connection->root); - for (; iter.rem; xcb_screen_next(&iter), idx++) - if (iter.data->root == xcb_screen->root) - return idx; - - ASSERT_NOT_REACHED; -} - -cairo_xcb_screen_t * -_cairo_xcb_screen_get (xcb_connection_t *xcb_connection, - xcb_screen_t *xcb_screen) -{ - cairo_xcb_connection_t *connection; - cairo_xcb_screen_t *screen; - cairo_status_t status; - int screen_idx; - int i; - - connection = _cairo_xcb_connection_get (xcb_connection); - if (unlikely (connection == NULL)) - return NULL; - - CAIRO_MUTEX_LOCK (connection->screens_mutex); - - cairo_list_foreach_entry (screen, - cairo_xcb_screen_t, - &connection->screens, - link) - { - if (screen->xcb_screen == xcb_screen) { - /* Maintain list in MRU order */ - if (&screen->link != connection->screens.next) - cairo_list_move (&screen->link, &connection->screens); - - goto unlock; - } - } - - screen = malloc (sizeof (cairo_xcb_screen_t)); - if (unlikely (screen == NULL)) - goto unlock; - - screen_idx = _get_screen_index(connection, xcb_screen); - - screen->connection = connection; - screen->xcb_screen = xcb_screen; - screen->has_font_options = FALSE; - screen->subpixel_order = connection->subpixel_orders[screen_idx]; - - _cairo_freelist_init (&screen->pattern_cache_entry_freelist, - sizeof (struct pattern_cache_entry)); - cairo_list_init (&screen->link); - cairo_list_init (&screen->surfaces); - cairo_list_init (&screen->pictures); - - memset (screen->gc_depths, 0, sizeof (screen->gc_depths)); - memset (screen->gc, 0, sizeof (screen->gc)); - - screen->solid_cache_size = 0; - for (i = 0; i < ARRAY_LENGTH (screen->stock_colors); i++) - screen->stock_colors[i] = NULL; - - status = _cairo_cache_init (&screen->linear_pattern_cache, - _linear_pattern_cache_entry_equal, - NULL, - _pattern_cache_entry_destroy, - 16); - if (unlikely (status)) - goto error_screen; - - status = _cairo_cache_init (&screen->radial_pattern_cache, - _radial_pattern_cache_entry_equal, - NULL, - _pattern_cache_entry_destroy, - 4); - if (unlikely (status)) - goto error_linear; - - cairo_list_add (&screen->link, &connection->screens); - -unlock: - CAIRO_MUTEX_UNLOCK (connection->screens_mutex); - - return screen; - -error_linear: - _cairo_cache_fini (&screen->linear_pattern_cache); -error_screen: - CAIRO_MUTEX_UNLOCK (connection->screens_mutex); - free (screen); - - return NULL; -} - -static xcb_gcontext_t -_create_gc (cairo_xcb_screen_t *screen, - xcb_drawable_t drawable) -{ - uint32_t values[] = { 0 }; - - return _cairo_xcb_connection_create_gc (screen->connection, drawable, - XCB_GC_GRAPHICS_EXPOSURES, - values); -} - -xcb_gcontext_t -_cairo_xcb_screen_get_gc (cairo_xcb_screen_t *screen, - xcb_drawable_t drawable, - int depth) -{ - int i; - - assert (CAIRO_MUTEX_IS_LOCKED (screen->connection->device.mutex)); - - for (i = 0; i < ARRAY_LENGTH (screen->gc); i++) { - if (screen->gc_depths[i] == depth) { - screen->gc_depths[i] = 0; - return screen->gc[i]; - } - } - - return _create_gc (screen, drawable); -} - -void -_cairo_xcb_screen_put_gc (cairo_xcb_screen_t *screen, int depth, xcb_gcontext_t gc) -{ - int i; - - assert (CAIRO_MUTEX_IS_LOCKED (screen->connection->device.mutex)); - - for (i = 0; i < ARRAY_LENGTH (screen->gc); i++) { - if (screen->gc_depths[i] == 0) - break; - } - - if (i == ARRAY_LENGTH (screen->gc)) { - /* perform random substitution to ensure fair caching over depths */ - i = rand () % ARRAY_LENGTH (screen->gc); - _cairo_xcb_connection_free_gc (screen->connection, screen->gc[i]); - } - - screen->gc[i] = gc; - screen->gc_depths[i] = depth; -} - -cairo_status_t -_cairo_xcb_screen_store_linear_picture (cairo_xcb_screen_t *screen, - const cairo_linear_pattern_t *linear, - cairo_surface_t *picture) -{ - struct pattern_cache_entry *entry; - cairo_status_t status; - - assert (CAIRO_MUTEX_IS_LOCKED (screen->connection->device.mutex)); - - entry = _cairo_freelist_alloc (&screen->pattern_cache_entry_freelist); - if (unlikely (entry == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - entry->key.hash = _cairo_linear_pattern_hash (_CAIRO_HASH_INIT_VALUE, linear); - entry->key.size = 1; - - status = _cairo_pattern_init_copy (&entry->pattern.base, &linear->base.base); - if (unlikely (status)) { - _cairo_freelist_free (&screen->pattern_cache_entry_freelist, entry); - return status; - } - - entry->picture = cairo_surface_reference (picture); - entry->screen = screen; - - status = _cairo_cache_insert (&screen->linear_pattern_cache, - &entry->key); - if (unlikely (status)) { - cairo_surface_destroy (picture); - _cairo_freelist_free (&screen->pattern_cache_entry_freelist, entry); - return status; - } - - return CAIRO_STATUS_SUCCESS; -} - -cairo_surface_t * -_cairo_xcb_screen_lookup_linear_picture (cairo_xcb_screen_t *screen, - const cairo_linear_pattern_t *linear) -{ - cairo_surface_t *picture = NULL; - struct pattern_cache_entry tmpl; - struct pattern_cache_entry *entry; - - assert (CAIRO_MUTEX_IS_LOCKED (screen->connection->device.mutex)); - - tmpl.key.hash = _cairo_linear_pattern_hash (_CAIRO_HASH_INIT_VALUE, linear); - _cairo_pattern_init_static_copy (&tmpl.pattern.base, &linear->base.base); - - entry = _cairo_cache_lookup (&screen->linear_pattern_cache, &tmpl.key); - if (entry != NULL) - picture = cairo_surface_reference (entry->picture); - - return picture; -} - -cairo_status_t -_cairo_xcb_screen_store_radial_picture (cairo_xcb_screen_t *screen, - const cairo_radial_pattern_t *radial, - cairo_surface_t *picture) -{ - struct pattern_cache_entry *entry; - cairo_status_t status; - - assert (CAIRO_MUTEX_IS_LOCKED (screen->connection->device.mutex)); - - entry = _cairo_freelist_alloc (&screen->pattern_cache_entry_freelist); - if (unlikely (entry == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - entry->key.hash = _cairo_radial_pattern_hash (_CAIRO_HASH_INIT_VALUE, radial); - entry->key.size = 1; - - status = _cairo_pattern_init_copy (&entry->pattern.base, &radial->base.base); - if (unlikely (status)) { - _cairo_freelist_free (&screen->pattern_cache_entry_freelist, entry); - return status; - } - - entry->picture = cairo_surface_reference (picture); - entry->screen = screen; - - status = _cairo_cache_insert (&screen->radial_pattern_cache, &entry->key); - if (unlikely (status)) { - cairo_surface_destroy (picture); - _cairo_freelist_free (&screen->pattern_cache_entry_freelist, entry); - return status; - } - - return CAIRO_STATUS_SUCCESS; -} - -cairo_surface_t * -_cairo_xcb_screen_lookup_radial_picture (cairo_xcb_screen_t *screen, - const cairo_radial_pattern_t *radial) -{ - cairo_surface_t *picture = NULL; - struct pattern_cache_entry tmpl; - struct pattern_cache_entry *entry; - - assert (CAIRO_MUTEX_IS_LOCKED (screen->connection->device.mutex)); - - tmpl.key.hash = _cairo_radial_pattern_hash (_CAIRO_HASH_INIT_VALUE, radial); - _cairo_pattern_init_static_copy (&tmpl.pattern.base, &radial->base.base); - - entry = _cairo_cache_lookup (&screen->radial_pattern_cache, &tmpl.key); - if (entry != NULL) - picture = cairo_surface_reference (entry->picture); - - return picture; -} - -cairo_font_options_t * -_cairo_xcb_screen_get_font_options (cairo_xcb_screen_t *screen) -{ - if (! screen->has_font_options) { - _cairo_font_options_init_default (&screen->font_options); - _cairo_font_options_set_round_glyph_positions (&screen->font_options, CAIRO_ROUND_GLYPH_POS_ON); - - /* XXX: This is disabled because something seems to be merging - font options incorrectly for xcb. This effectively reverts - the changes brought in git e691d242, and restores ~150 tests - to resume passing. See mailing list archives for Sep 17, - 2014 for more discussion. */ - if (0 && ! _cairo_xcb_connection_acquire (screen->connection)) { - _cairo_xcb_init_screen_font_options (screen); - _cairo_xcb_connection_release (screen->connection); - } - - screen->has_font_options = TRUE; - } - - return &screen->font_options; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-xcb-shm.c b/source/libs/cairo/cairo-src/src/cairo-xcb-shm.c deleted file mode 100644 index 2be2dac5bf924a430fab3edeacaa98a7bb2e2c70..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xcb-shm.c +++ /dev/null @@ -1,337 +0,0 @@ -/* Cairo - a vector graphics library with display and print output - * - * Copyright © 2007 Chris Wilson - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributors(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#if CAIRO_HAS_XCB_SHM_FUNCTIONS - -#include "cairo-xcb-private.h" -#include "cairo-list-inline.h" -#include "cairo-mempool-private.h" - -#include <xcb/shm.h> -#include <sys/ipc.h> -#include <sys/shm.h> -#include <errno.h> - -#define CAIRO_MAX_SHM_MEMORY (16*1024*1024) - -/* a simple buddy allocator for memory pools - * XXX fragmentation? use Doug Lea's malloc? - */ - -typedef struct _cairo_xcb_shm_mem_block cairo_xcb_shm_mem_block_t; - -typedef enum { - PENDING_WAIT, - PENDING_POLL -} shm_wait_type_t; - -struct _cairo_xcb_shm_mem_pool { - int shmid; - uint32_t shmseg; - void *shm; - - cairo_mempool_t mem; - - cairo_list_t link; -}; - -static void -_cairo_xcb_shm_mem_pool_destroy (cairo_xcb_shm_mem_pool_t *pool) -{ - cairo_list_del (&pool->link); - - shmdt (pool->shm); - _cairo_mempool_fini (&pool->mem); - - free (pool); -} - -static void -_cairo_xcb_shm_info_finalize (cairo_xcb_shm_info_t *shm_info) -{ - cairo_xcb_connection_t *connection = shm_info->connection; - - assert (CAIRO_MUTEX_IS_LOCKED (connection->shm_mutex)); - - _cairo_mempool_free (&shm_info->pool->mem, shm_info->mem); - _cairo_freepool_free (&connection->shm_info_freelist, shm_info); - - /* scan for old, unused pools - hold at least one in reserve */ - if (! cairo_list_is_singular (&connection->shm_pools)) - { - cairo_xcb_shm_mem_pool_t *pool, *next; - cairo_list_t head; - - cairo_list_init (&head); - cairo_list_move (connection->shm_pools.next, &head); - - cairo_list_foreach_entry_safe (pool, next, cairo_xcb_shm_mem_pool_t, - &connection->shm_pools, link) - { - if (pool->mem.free_bytes == pool->mem.max_bytes) { - _cairo_xcb_connection_shm_detach (connection, pool->shmseg); - _cairo_xcb_shm_mem_pool_destroy (pool); - } - } - - cairo_list_move (head.next, &connection->shm_pools); - } -} - -static void -_cairo_xcb_shm_process_pending (cairo_xcb_connection_t *connection, shm_wait_type_t wait) -{ - cairo_xcb_shm_info_t *info, *next; - xcb_get_input_focus_reply_t *reply; - - assert (CAIRO_MUTEX_IS_LOCKED (connection->shm_mutex)); - cairo_list_foreach_entry_safe (info, next, cairo_xcb_shm_info_t, - &connection->shm_pending, pending) - { - switch (wait) { - case PENDING_WAIT: - reply = xcb_wait_for_reply (connection->xcb_connection, - info->sync.sequence, NULL); - break; - case PENDING_POLL: - if (! xcb_poll_for_reply (connection->xcb_connection, - info->sync.sequence, - (void **) &reply, NULL)) - /* We cannot be sure the server finished with this image yet, so - * try again later. All other shm info are guaranteed to have a - * larger sequence number and thus don't have to be checked. */ - return; - break; - default: - /* silence Clang static analyzer warning */ - ASSERT_NOT_REACHED; - reply = NULL; - } - - free (reply); - cairo_list_del (&info->pending); - _cairo_xcb_shm_info_finalize (info); - } -} - -cairo_int_status_t -_cairo_xcb_connection_allocate_shm_info (cairo_xcb_connection_t *connection, - size_t size, - cairo_bool_t might_reuse, - cairo_xcb_shm_info_t **shm_info_out) -{ - cairo_xcb_shm_info_t *shm_info; - cairo_xcb_shm_mem_pool_t *pool, *next; - size_t bytes, maxbits = 16, minbits = 8; - size_t shm_allocated = 0; - void *mem = NULL; - cairo_status_t status; - - assert (connection->flags & CAIRO_XCB_HAS_SHM); - - CAIRO_MUTEX_LOCK (connection->shm_mutex); - _cairo_xcb_shm_process_pending (connection, PENDING_POLL); - - if (might_reuse) { - cairo_list_foreach_entry (shm_info, cairo_xcb_shm_info_t, - &connection->shm_pending, pending) { - if (shm_info->size >= size) { - cairo_list_del (&shm_info->pending); - CAIRO_MUTEX_UNLOCK (connection->shm_mutex); - - xcb_discard_reply (connection->xcb_connection, shm_info->sync.sequence); - shm_info->sync.sequence = XCB_NONE; - - *shm_info_out = shm_info; - return CAIRO_STATUS_SUCCESS; - } - } - } - - cairo_list_foreach_entry_safe (pool, next, cairo_xcb_shm_mem_pool_t, - &connection->shm_pools, link) - { - if (pool->mem.free_bytes > size) { - mem = _cairo_mempool_alloc (&pool->mem, size); - if (mem != NULL) { - /* keep the active pools towards the front */ - cairo_list_move (&pool->link, &connection->shm_pools); - goto allocate_shm_info; - } - } - /* scan for old, unused pools */ - if (pool->mem.free_bytes == pool->mem.max_bytes) { - _cairo_xcb_connection_shm_detach (connection, - pool->shmseg); - _cairo_xcb_shm_mem_pool_destroy (pool); - } else { - shm_allocated += pool->mem.max_bytes; - } - } - - if (unlikely (shm_allocated >= CAIRO_MAX_SHM_MEMORY)) { - CAIRO_MUTEX_UNLOCK (connection->shm_mutex); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - pool = malloc (sizeof (cairo_xcb_shm_mem_pool_t)); - if (unlikely (pool == NULL)) { - CAIRO_MUTEX_UNLOCK (connection->shm_mutex); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - bytes = 1 << maxbits; - while (bytes <= size) - bytes <<= 1, maxbits++; - bytes <<= 3; - - do { - pool->shmid = shmget (IPC_PRIVATE, bytes, IPC_CREAT | 0600); - if (pool->shmid != -1) - break; - - /* If the allocation failed because we asked for too much memory, we try - * again with a smaller request, as long as our allocation still fits. */ - bytes >>= 1; - if (errno != EINVAL || bytes < size) - break; - } while (TRUE); - if (pool->shmid == -1) { - int err = errno; - if (! (err == EINVAL || err == ENOMEM)) - connection->flags &= ~CAIRO_XCB_HAS_SHM; - free (pool); - CAIRO_MUTEX_UNLOCK (connection->shm_mutex); - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - pool->shm = shmat (pool->shmid, NULL, 0); - if (unlikely (pool->shm == (char *) -1)) { - shmctl (pool->shmid, IPC_RMID, NULL); - free (pool); - CAIRO_MUTEX_UNLOCK (connection->shm_mutex); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - status = _cairo_mempool_init (&pool->mem, pool->shm, bytes, - minbits, maxbits - minbits + 1); - if (unlikely (status)) { - shmdt (pool->shm); - free (pool); - CAIRO_MUTEX_UNLOCK (connection->shm_mutex); - return status; - } - - pool->shmseg = _cairo_xcb_connection_shm_attach (connection, pool->shmid, FALSE); - shmctl (pool->shmid, IPC_RMID, NULL); - - cairo_list_add (&pool->link, &connection->shm_pools); - mem = _cairo_mempool_alloc (&pool->mem, size); - - allocate_shm_info: - shm_info = _cairo_freepool_alloc (&connection->shm_info_freelist); - if (unlikely (shm_info == NULL)) { - _cairo_mempool_free (&pool->mem, mem); - CAIRO_MUTEX_UNLOCK (connection->shm_mutex); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - shm_info->connection = connection; - shm_info->pool = pool; - shm_info->shm = pool->shmseg; - shm_info->size = size; - shm_info->offset = (char *) mem - (char *) pool->shm; - shm_info->mem = mem; - shm_info->sync.sequence = XCB_NONE; - - /* scan for old, unused pools */ - cairo_list_foreach_entry_safe (pool, next, cairo_xcb_shm_mem_pool_t, - &connection->shm_pools, link) - { - if (pool->mem.free_bytes == pool->mem.max_bytes) { - _cairo_xcb_connection_shm_detach (connection, - pool->shmseg); - _cairo_xcb_shm_mem_pool_destroy (pool); - } - } - CAIRO_MUTEX_UNLOCK (connection->shm_mutex); - - *shm_info_out = shm_info; - return CAIRO_STATUS_SUCCESS; -} - -void -_cairo_xcb_shm_info_destroy (cairo_xcb_shm_info_t *shm_info) -{ - cairo_xcb_connection_t *connection = shm_info->connection; - - /* We can only return shm_info->mem to the allocator when we can be sure - * that the X server no longer reads from it. Since the X server processes - * requests in order, we send a GetInputFocus here. - * _cairo_xcb_shm_process_pending () will later check if the reply for that - * request was received and then actually mark this memory area as free. */ - - CAIRO_MUTEX_LOCK (connection->shm_mutex); - assert (shm_info->sync.sequence == XCB_NONE); - shm_info->sync = xcb_get_input_focus (connection->xcb_connection); - - cairo_list_init (&shm_info->pending); - cairo_list_add_tail (&shm_info->pending, &connection->shm_pending); - CAIRO_MUTEX_UNLOCK (connection->shm_mutex); -} - -void -_cairo_xcb_connection_shm_mem_pools_flush (cairo_xcb_connection_t *connection) -{ - CAIRO_MUTEX_LOCK (connection->shm_mutex); - _cairo_xcb_shm_process_pending (connection, PENDING_WAIT); - CAIRO_MUTEX_UNLOCK (connection->shm_mutex); -} - -void -_cairo_xcb_connection_shm_mem_pools_fini (cairo_xcb_connection_t *connection) -{ - assert (cairo_list_is_empty (&connection->shm_pending)); - while (! cairo_list_is_empty (&connection->shm_pools)) { - _cairo_xcb_shm_mem_pool_destroy (cairo_list_first_entry (&connection->shm_pools, - cairo_xcb_shm_mem_pool_t, - link)); - } -} - -#endif /* CAIRO_HAS_XCB_SHM_FUNCTIONS */ diff --git a/source/libs/cairo/cairo-src/src/cairo-xcb-surface-core.c b/source/libs/cairo/cairo-src/src/cairo-xcb-surface-core.c deleted file mode 100644 index 9c0c0a0957d46325d50465e388843ecfc6e0a65d..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xcb-surface-core.c +++ /dev/null @@ -1,639 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-boxes-private.h" -#include "cairo-xcb-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-surface-backend-private.h" - -/* XXX dithering */ - -typedef struct _cairo_xcb_pixmap { - cairo_surface_t base; - - cairo_xcb_connection_t *connection; - cairo_xcb_screen_t *screen; - - cairo_surface_t *owner; - xcb_pixmap_t pixmap; - int width; - int height; - int depth; - int x0, y0; - cairo_bool_t repeat; -} cairo_xcb_pixmap_t; - -static cairo_status_t -_cairo_xcb_pixmap_finish (void *abstract_surface) -{ - cairo_xcb_pixmap_t *surface = abstract_surface; - cairo_status_t status; - - if (surface->owner != NULL) { - cairo_surface_destroy (surface->owner); - } else { - status = _cairo_xcb_connection_acquire (surface->connection); - if (unlikely (status)) - return status; - - _cairo_xcb_connection_free_pixmap (surface->connection, - surface->pixmap); - _cairo_xcb_connection_release (surface->connection); - } - - return CAIRO_STATUS_SUCCESS; -} - -static const cairo_surface_backend_t _cairo_xcb_pixmap_backend = { - CAIRO_SURFACE_TYPE_XCB, - _cairo_xcb_pixmap_finish, -}; - -static cairo_xcb_pixmap_t * -_cairo_xcb_pixmap_create (cairo_xcb_surface_t *target, - int width, int height) -{ - cairo_xcb_pixmap_t *surface; - - surface = malloc (sizeof (cairo_xcb_pixmap_t)); - if (unlikely (surface == NULL)) - return (cairo_xcb_pixmap_t *) - _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - _cairo_surface_init (&surface->base, - &_cairo_xcb_pixmap_backend, - NULL, - target->base.content); - - surface->connection = target->connection; - surface->screen = target->screen; - surface->owner = NULL; - surface->width = width; - surface->height = height; - surface->depth = target->depth; - surface->x0 = surface->y0 = 0; - surface->repeat = FALSE; - - surface->pixmap = - _cairo_xcb_connection_create_pixmap (surface->connection, - surface->depth, - target->drawable, - width, height); - - return surface; -} - -static cairo_xcb_pixmap_t * -_cairo_xcb_pixmap_copy (cairo_xcb_surface_t *target) -{ - cairo_xcb_pixmap_t *surface; - - surface = malloc (sizeof (cairo_xcb_pixmap_t)); - if (unlikely (surface == NULL)) - return (cairo_xcb_pixmap_t *) - _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - _cairo_surface_init (&surface->base, - &_cairo_xcb_pixmap_backend, - NULL, - target->base.content); - - surface->connection = target->connection; - surface->screen = target->screen; - surface->pixmap = target->drawable; - surface->owner = cairo_surface_reference (&target->base); - surface->width = target->width; - surface->height = target->height; - surface->depth = target->depth; - surface->x0 = surface->y0 = 0; - surface->repeat = FALSE; - - return surface; -} - -#if CAIRO_HAS_XCB_SHM_FUNCTIONS -static cairo_status_t -_cairo_xcb_shm_image_create_shm (cairo_xcb_connection_t *connection, - pixman_format_code_t pixman_format, - int width, int height, - cairo_image_surface_t **image_out, - cairo_xcb_shm_info_t **shm_info_out) -{ - cairo_surface_t *image = NULL; - cairo_xcb_shm_info_t *shm_info = NULL; - cairo_status_t status; - size_t size, stride; - - if (! (connection->flags & CAIRO_XCB_HAS_SHM)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (unlikely (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - stride = CAIRO_STRIDE_FOR_WIDTH_BPP (width, PIXMAN_FORMAT_BPP (pixman_format)); - size = stride * height; - if (size <= CAIRO_XCB_SHM_SMALL_IMAGE) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_xcb_connection_allocate_shm_info (connection, size, - FALSE, &shm_info); - if (unlikely (status)) - return status; - - image = _cairo_image_surface_create_with_pixman_format (shm_info->mem, - pixman_format, - width, height, - stride); - status = image->status; - if (unlikely (status)) { - _cairo_xcb_shm_info_destroy (shm_info); - return status; - } - - status = _cairo_user_data_array_set_data (&image->user_data, - (const cairo_user_data_key_t *) connection, - shm_info, - (cairo_destroy_func_t) _cairo_xcb_shm_info_destroy); - - if (unlikely (status)) { - cairo_surface_destroy (image); - _cairo_xcb_shm_info_destroy (shm_info); - return status; - } - - *image_out = (cairo_image_surface_t *) image; - *shm_info_out = shm_info; - return CAIRO_STATUS_SUCCESS; -} -#else -static cairo_status_t -_cairo_xcb_shm_image_create_shm (cairo_xcb_connection_t *connection, - pixman_format_code_t pixman_format, - int width, int height, - cairo_image_surface_t **image_out, - cairo_xcb_shm_info_t **shm_info_out) -{ - return CAIRO_INT_STATUS_UNSUPPORTED; -} -#endif - -cairo_status_t -_cairo_xcb_shm_image_create (cairo_xcb_connection_t *connection, - pixman_format_code_t pixman_format, - int width, int height, - cairo_image_surface_t **image_out, - cairo_xcb_shm_info_t **shm_info_out) -{ - cairo_surface_t *image = NULL; - cairo_xcb_shm_info_t *shm_info = NULL; - cairo_status_t status; - - status = _cairo_xcb_shm_image_create_shm (connection, - pixman_format, - width, - height, - image_out, - shm_info_out); - - if (status != CAIRO_STATUS_SUCCESS) { - image = _cairo_image_surface_create_with_pixman_format (NULL, - pixman_format, - width, height, - 0); - status = image->status; - if (unlikely (status)) - return status; - - *image_out = (cairo_image_surface_t *) image; - *shm_info_out = shm_info; - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_xcb_pixmap_t * -_pixmap_from_image (cairo_xcb_surface_t *target, - xcb_render_pictformat_t format, - cairo_image_surface_t *image, - cairo_xcb_shm_info_t *shm_info) -{ - xcb_gcontext_t gc; - cairo_xcb_pixmap_t *pixmap; - - pixmap = _cairo_xcb_pixmap_create (target, - image->width, - image->height); - if (unlikely (pixmap->base.status)) - return pixmap; - - gc = _cairo_xcb_screen_get_gc (target->screen, pixmap->pixmap, image->depth); - - if (shm_info != NULL) { - _cairo_xcb_connection_shm_put_image (target->connection, - pixmap->pixmap, gc, - image->width, image->height, - 0, 0, - image->width, image->height, - 0, 0, - image->depth, - shm_info->shm, - shm_info->offset); - } else { - int len; - - /* Do we need to trim the image? */ - len = CAIRO_STRIDE_FOR_WIDTH_BPP (image->width, - PIXMAN_FORMAT_BPP (image->pixman_format)); - if (len == image->stride) { - _cairo_xcb_connection_put_image (target->connection, - pixmap->pixmap, gc, - image->width, image->height, - 0, 0, - image->depth, - image->stride, - image->data); - } else { - _cairo_xcb_connection_put_subimage (target->connection, - pixmap->pixmap, gc, - 0, 0, - image->width, image->height, - PIXMAN_FORMAT_BPP (image->pixman_format) / 8, - image->stride, - 0, 0, - image->depth, - image->data); - - } - } - - _cairo_xcb_screen_put_gc (target->screen, image->depth, gc); - - return pixmap; -} - -static cairo_xcb_pixmap_t * -_render_to_pixmap (cairo_xcb_surface_t *target, - const cairo_pattern_t *pattern, - const cairo_rectangle_int_t *extents) -{ - cairo_image_surface_t *image; - cairo_xcb_shm_info_t *shm_info; - cairo_pattern_union_t copy; - cairo_status_t status; - cairo_xcb_pixmap_t *pixmap; - - status = _cairo_xcb_shm_image_create (target->screen->connection, - target->pixman_format, - extents->width, extents->height, - &image, &shm_info); - if (unlikely (status)) - return (cairo_xcb_pixmap_t *) _cairo_surface_create_in_error (status); - - _cairo_pattern_init_static_copy (©.base, pattern); - cairo_matrix_translate (©.base.matrix, -extents->x, -extents->y); - status = _cairo_surface_paint (&image->base, - CAIRO_OPERATOR_SOURCE, - ©.base, - NULL); - if (unlikely (status)) { - cairo_surface_destroy (&image->base); - return (cairo_xcb_pixmap_t *) _cairo_surface_create_in_error (status); - } - - pixmap = _pixmap_from_image (target, target->xrender_format, image, shm_info); - cairo_surface_destroy (&image->base); - - if (unlikely (pixmap->base.status)) - return pixmap; - - pixmap->x0 = -extents->x; - pixmap->y0 = -extents->y; - return pixmap; -} - -static cairo_xcb_pixmap_t * -_copy_to_pixmap (cairo_xcb_surface_t *source) -{ - cairo_xcb_pixmap_t *pixmap; - - /* If the source may be a window, we need to copy it and its children - * via a temporary pixmap so that we can IncludeInferiors on the source - * and use ClipByChildren on the destination. - */ - if (source->owns_pixmap) { - pixmap = _cairo_xcb_pixmap_copy (source); - if (unlikely (pixmap->base.status)) - return pixmap; - } else { - uint32_t values[1]; - xcb_gcontext_t gc; - - pixmap = _cairo_xcb_pixmap_create (source, - source->width, - source->height); - if (unlikely (pixmap->base.status)) - return pixmap; - - gc = _cairo_xcb_screen_get_gc (source->screen, - pixmap->pixmap, - pixmap->depth); - - values[0] = TRUE; - _cairo_xcb_connection_change_gc (pixmap->connection, gc, - XCB_GC_SUBWINDOW_MODE, values); - - _cairo_xcb_connection_copy_area (pixmap->connection, - source->drawable, - pixmap->pixmap, gc, - 0, 0, - 0, 0, - source->width, - source->height); - - values[0] = FALSE; - _cairo_xcb_connection_change_gc (pixmap->connection, gc, - XCB_GC_SUBWINDOW_MODE, values); - - _cairo_xcb_screen_put_gc (source->screen, - pixmap->depth, - gc); - } - - return pixmap; -} -static cairo_xcb_pixmap_t * -_cairo_xcb_surface_pixmap (cairo_xcb_surface_t *target, - const cairo_surface_pattern_t *pattern, - const cairo_rectangle_int_t *extents, - int tx, int ty) -{ - cairo_surface_t *source; - cairo_xcb_pixmap_t *pixmap; - - source = pattern->surface; - pixmap = (cairo_xcb_pixmap_t *) - _cairo_surface_has_snapshot (source, &_cairo_xcb_pixmap_backend); - if (pixmap != NULL && pixmap->screen == target->screen) - return (cairo_xcb_pixmap_t *) cairo_surface_reference (&pixmap->base); - - if (_cairo_surface_is_xcb(source) && - ((cairo_xcb_surface_t *) source)->screen == target->screen) - { - cairo_xcb_surface_t *xcb_source = (cairo_xcb_surface_t *) source; - - if (xcb_source->depth == target->depth) - pixmap = _copy_to_pixmap (xcb_source); - } -#if CAIRO_HAS_XLIB_XCB_FUNCTIONS - else if (source->type == CAIRO_SURFACE_TYPE_XLIB && - ((cairo_xlib_xcb_surface_t *) source)->xcb->screen == target->screen) - { - cairo_xcb_surface_t *xcb_source = ((cairo_xlib_xcb_surface_t *) source)->xcb; - - if (xcb_source->depth == target->depth) - pixmap = _copy_to_pixmap (xcb_source); - } -#endif - - if (pixmap == NULL) { - cairo_rectangle_int_t rect; - - if (! _cairo_surface_get_extents (source, &rect)) { - rect.x = rect.y = 0; - rect.width = target->width; - rect.height = target->height; - } - - pixmap = _render_to_pixmap (target, &pattern->base, &rect); - } - - if (unlikely (pixmap->base.status)) - return pixmap; - - _cairo_surface_attach_snapshot (source, &pixmap->base, NULL); - - if (pattern->base.extend != CAIRO_EXTEND_NONE) { - if (extents->x < 0 || extents->y < 0 || - extents->x + extents->width > pixmap->width || - extents->y + extents->height > pixmap->height) - { - pixmap->repeat = TRUE; - } - } - - pixmap->x0 += tx; - pixmap->y0 += ty; - - return pixmap; -} - -static cairo_xcb_pixmap_t * -_cairo_xcb_pixmap_for_pattern (cairo_xcb_surface_t *target, - const cairo_pattern_t *pattern, - const cairo_rectangle_int_t *extents) -{ - int tx, ty; - - switch (pattern->type) { - case CAIRO_PATTERN_TYPE_SURFACE: - /* Core can only perform a native, unscaled blit, but can handle tiles */ - if (_cairo_matrix_is_integer_translation (&pattern->matrix, &tx, &ty)) { - switch (pattern->extend) { - case CAIRO_EXTEND_NONE: - case CAIRO_EXTEND_REPEAT: - return _cairo_xcb_surface_pixmap (target, - (cairo_surface_pattern_t *) pattern, - extents, tx, ty); - - default: - case CAIRO_EXTEND_PAD: - case CAIRO_EXTEND_REFLECT: - break; - } - } - /* fallthrough */ - case CAIRO_PATTERN_TYPE_LINEAR: - case CAIRO_PATTERN_TYPE_RADIAL: - case CAIRO_PATTERN_TYPE_MESH: - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - return _render_to_pixmap (target, pattern, extents); - - default: - case CAIRO_PATTERN_TYPE_SOLID: - ASSERT_NOT_REACHED; - return NULL; - } -} - -cairo_status_t -_cairo_xcb_surface_core_copy_boxes (cairo_xcb_surface_t *dst, - const cairo_pattern_t *src_pattern, - const cairo_rectangle_int_t *extents, - const cairo_boxes_t *boxes) -{ - cairo_xcb_pixmap_t *src; - const struct _cairo_boxes_chunk *chunk; - xcb_gcontext_t gc; - cairo_status_t status; - - status = _cairo_xcb_connection_acquire (dst->connection); - if (unlikely (status)) - return status; - - src = _cairo_xcb_pixmap_for_pattern (dst, src_pattern, extents); - status = src->base.status; - if (unlikely (status)) - goto CLEANUP_CONNECTION; - - assert (src->depth == dst->depth); - - gc = _cairo_xcb_screen_get_gc (dst->screen, src->pixmap, src->depth); - - if (src->repeat) { - uint32_t mask = - XCB_GC_FILL_STYLE | - XCB_GC_TILE | - XCB_GC_TILE_STIPPLE_ORIGIN_X | - XCB_GC_TILE_STIPPLE_ORIGIN_Y; - uint32_t values[] = { - XCB_FILL_STYLE_TILED, - src->pixmap, - - src->x0, - src->y0, - }; - xcb_rectangle_t *xcb_rects; - - _cairo_xcb_connection_change_gc (dst->connection, gc, mask, values); - - for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) { - int i; - - xcb_rects = (xcb_rectangle_t *) chunk->base; - - for (i = 0; i < chunk->count; i++) { - int x1 = _cairo_fixed_integer_round (chunk->base[i].p1.x); - int x2 = _cairo_fixed_integer_round (chunk->base[i].p2.x); - int y1 = _cairo_fixed_integer_round (chunk->base[i].p1.y); - int y2 = _cairo_fixed_integer_round (chunk->base[i].p2.y); - - xcb_rects[i].x = x1; - xcb_rects[i].y = y1; - xcb_rects[i].width = x2 - x1; - xcb_rects[i].height = y2 - y1; - } - _cairo_xcb_connection_poly_fill_rectangle (dst->connection, - dst->drawable, - gc, chunk->count, xcb_rects); - } - - values[0] = 0; - _cairo_xcb_connection_change_gc (dst->connection, gc, XCB_GC_FILL_STYLE, values); - } else { - for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) { - int i; - - for (i = 0; i < chunk->count; i++) { - int x1 = _cairo_fixed_integer_round (chunk->base[i].p1.x); - int x2 = _cairo_fixed_integer_round (chunk->base[i].p2.x); - int y1 = _cairo_fixed_integer_round (chunk->base[i].p1.y); - int y2 = _cairo_fixed_integer_round (chunk->base[i].p2.y); - - _cairo_xcb_connection_copy_area (dst->connection, - src->pixmap, - dst->drawable, gc, - src->x0 + x1, - src->y0 + y1, - x1, y1, - x2 - x1, y2 - y1); - } - } - } - - _cairo_xcb_screen_put_gc (dst->screen, src->depth, gc); - cairo_surface_destroy (&src->base); - - CLEANUP_CONNECTION: - _cairo_xcb_connection_release (dst->connection); - - return status; -} - -cairo_status_t -_cairo_xcb_surface_core_fill_boxes (cairo_xcb_surface_t *dst, - const cairo_color_t *color, - cairo_boxes_t *boxes) -{ - struct _cairo_boxes_chunk *chunk; - xcb_gcontext_t gc; - cairo_status_t status; - - status = _cairo_xcb_connection_acquire (dst->connection); - if (unlikely (status)) - return status; - - gc = _cairo_xcb_screen_get_gc (dst->screen, dst->drawable, dst->depth); - -#if 0 - xcb_pixmap_t source; - - source = _dither_source (dst, color); - XSetTSOrigin (surface->dpy, gc, 0, 0); - XSetTile (surface->dpy, gc, source); -#endif - - for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) { - xcb_rectangle_t *xcb_rects; - int i; - - xcb_rects = (xcb_rectangle_t *) chunk->base; - for (i = 0; i < chunk->count; i++) { - int x1 = _cairo_fixed_integer_round (chunk->base[i].p1.x); - int x2 = _cairo_fixed_integer_round (chunk->base[i].p2.x); - int y1 = _cairo_fixed_integer_round (chunk->base[i].p1.y); - int y2 = _cairo_fixed_integer_round (chunk->base[i].p2.y); - - xcb_rects[i].x = x1; - xcb_rects[i].y = y1; - xcb_rects[i].width = x2 - x1; - xcb_rects[i].height = y2 - y1; - } - - _cairo_xcb_connection_poly_fill_rectangle (dst->connection, - dst->drawable, gc, - chunk->count, xcb_rects); - } - - _cairo_xcb_screen_put_gc (dst->screen, dst->depth, gc); - _cairo_xcb_connection_release (dst->connection); - - return CAIRO_STATUS_SUCCESS; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-xcb-surface-render.c b/source/libs/cairo/cairo-src/src/cairo-xcb-surface-render.c deleted file mode 100644 index 139dcda827a39db08c8a0386a4949591245af817..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xcb-surface-render.c +++ /dev/null @@ -1,4879 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "cairo-xcb-private.h" - -#include "cairo-boxes-private.h" -#include "cairo-clip-inline.h" -#include "cairo-clip-private.h" -#include "cairo-composite-rectangles-private.h" -#include "cairo-image-surface-inline.h" -#include "cairo-image-surface-private.h" -#include "cairo-list-inline.h" -#include "cairo-region-private.h" -#include "cairo-surface-offset-private.h" -#include "cairo-surface-snapshot-inline.h" -#include "cairo-surface-subsurface-private.h" -#include "cairo-traps-private.h" -#include "cairo-recording-surface-inline.h" -#include "cairo-paginated-private.h" -#include "cairo-pattern-inline.h" - -#define PIXMAN_MAX_INT ((pixman_fixed_1 >> 1) - pixman_fixed_e) /* need to ensure deltas also fit */ - -static cairo_status_t -_clip_and_composite_boxes (cairo_xcb_surface_t *dst, - cairo_operator_t op, - const cairo_pattern_t *src, - cairo_boxes_t *boxes, - cairo_composite_rectangles_t *extents); - -static inline cairo_xcb_connection_t * -_picture_to_connection (cairo_xcb_picture_t *picture) -{ - return (cairo_xcb_connection_t *) picture->base.device; -} - -static void -_cairo_xcb_surface_ensure_picture (cairo_xcb_surface_t *surface); - -static uint32_t -hars_petruska_f54_1_random (void) -{ -#define rol(x,k) ((x << k) | (x >> (32-k))) - static uint32_t x; - return x = (x ^ rol (x, 5) ^ rol (x, 24)) + 0x37798849; -#undef rol -} - -static cairo_status_t -_cairo_xcb_picture_finish (void *abstract_surface) -{ - cairo_xcb_picture_t *surface = abstract_surface; - cairo_xcb_connection_t *connection = _picture_to_connection (surface); - cairo_status_t status; - - status = _cairo_xcb_connection_acquire (connection); - cairo_list_del (&surface->link); - if (unlikely (status)) - return status; - - _cairo_xcb_connection_render_free_picture (connection, surface->picture); - - _cairo_xcb_connection_release (connection); - - return CAIRO_STATUS_SUCCESS; -} - -static const cairo_surface_backend_t _cairo_xcb_picture_backend = { - CAIRO_SURFACE_TYPE_XCB, - _cairo_xcb_picture_finish, -}; - -static const struct xcb_render_transform_t identity_transform = { - 1 << 16, 0, 0, - 0, 1 << 16, 0, - 0, 0, 1 << 16, -}; - -static cairo_xcb_picture_t * -_cairo_xcb_picture_create (cairo_xcb_screen_t *screen, - pixman_format_code_t pixman_format, - xcb_render_pictformat_t xrender_format, - int width, int height) -{ - cairo_xcb_picture_t *surface; - - surface = malloc (sizeof (cairo_xcb_picture_t)); - if (unlikely (surface == NULL)) - return (cairo_xcb_picture_t *) - _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - _cairo_surface_init (&surface->base, - &_cairo_xcb_picture_backend, - &screen->connection->device, - _cairo_content_from_pixman_format (pixman_format)); - - cairo_list_add (&surface->link, &screen->pictures); - - surface->screen = screen; - surface->picture = _cairo_xcb_connection_get_xid (screen->connection); - surface->pixman_format = pixman_format; - surface->xrender_format = xrender_format; - - surface->x0 = surface->y0 = 0; - surface->x = surface->y = 0; - surface->width = width; - surface->height = height; - - surface->transform = identity_transform; - surface->extend = CAIRO_EXTEND_NONE; - surface->filter = CAIRO_FILTER_NEAREST; - surface->has_component_alpha = FALSE; - - return surface; -} - -static inline cairo_bool_t -_operator_is_supported (uint32_t flags, cairo_operator_t op) -{ - if (op <= CAIRO_OPERATOR_SATURATE) - return TRUE; - - /* Can we use PDF operators? */ -#if CAIRO_XCB_RENDER_AT_LEAST(0, 11) - if (op <= CAIRO_OPERATOR_HSL_LUMINOSITY) - return flags & CAIRO_XCB_RENDER_HAS_PDF_OPERATORS; -#endif - - return FALSE; -} - -static int -_render_operator (cairo_operator_t op) -{ -#define C(x,y) case CAIRO_OPERATOR_##x: return XCB_RENDER_PICT_OP_##y - switch (op) { - C(CLEAR, CLEAR); - C(SOURCE, SRC); - - C(OVER, OVER); - C(IN, IN); - C(OUT, OUT); - C(ATOP, ATOP); - - C(DEST, DST); - C(DEST_OVER, OVER_REVERSE); - C(DEST_IN, IN_REVERSE); - C(DEST_OUT, OUT_REVERSE); - C(DEST_ATOP, ATOP_REVERSE); - - C(XOR, XOR); - C(ADD, ADD); - C(SATURATE, SATURATE); - - /* PDF operators were added in RENDER 0.11, check if the xcb headers have - * the defines, else fall through to the default case. */ -#if CAIRO_XCB_RENDER_AT_LEAST(0, 11) -#define BLEND(x,y) C(x,y) -#else -#define BLEND(x,y) case CAIRO_OPERATOR_##x: -#endif - BLEND(MULTIPLY, MULTIPLY); - BLEND(SCREEN, SCREEN); - BLEND(OVERLAY, OVERLAY); - BLEND(DARKEN, DARKEN); - BLEND(LIGHTEN, LIGHTEN); - BLEND(COLOR_DODGE, COLOR_DODGE); - BLEND(COLOR_BURN, COLOR_BURN); - BLEND(HARD_LIGHT, HARD_LIGHT); - BLEND(SOFT_LIGHT, SOFT_LIGHT); - BLEND(DIFFERENCE, DIFFERENCE); - BLEND(EXCLUSION, EXCLUSION); - BLEND(HSL_HUE, HSL_HUE); - BLEND(HSL_SATURATION, HSL_SATURATION); - BLEND(HSL_COLOR, HSL_COLOR); - BLEND(HSL_LUMINOSITY, HSL_LUMINOSITY); - - default: - ASSERT_NOT_REACHED; - return XCB_RENDER_PICT_OP_OVER; - } -} - -static cairo_status_t -_cairo_xcb_surface_set_clip_region (cairo_xcb_surface_t *surface, - cairo_region_t *region) -{ - xcb_rectangle_t stack_rects[CAIRO_STACK_ARRAY_LENGTH (xcb_rectangle_t)]; - xcb_rectangle_t *rects = stack_rects; - int i, num_rects; - - num_rects = cairo_region_num_rectangles (region); - - if (num_rects > ARRAY_LENGTH (stack_rects)) { - rects = _cairo_malloc_ab (num_rects, sizeof (xcb_rectangle_t)); - if (unlikely (rects == NULL)) { - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - } - - for (i = 0; i < num_rects; i++) { - cairo_rectangle_int_t rect; - - cairo_region_get_rectangle (region, i, &rect); - - rects[i].x = rect.x; - rects[i].y = rect.y; - rects[i].width = rect.width; - rects[i].height = rect.height; - } - - _cairo_xcb_connection_render_set_picture_clip_rectangles (surface->connection, - surface->picture, - 0, 0, - num_rects, rects); - - if (rects != stack_rects) - free (rects); - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_xcb_surface_clear_clip_region (cairo_xcb_surface_t *surface) -{ - uint32_t values[] = { XCB_NONE }; - _cairo_xcb_connection_render_change_picture (surface->connection, - surface->picture, - XCB_RENDER_CP_CLIP_MASK, - values); -} - -static void -_cairo_xcb_surface_set_precision (cairo_xcb_surface_t *surface, - cairo_antialias_t antialias) -{ - cairo_xcb_connection_t *connection = surface->connection; - uint32_t precision; - - if (connection->force_precision != -1) - precision = connection->force_precision; - else switch (antialias) { - default: - case CAIRO_ANTIALIAS_DEFAULT: - case CAIRO_ANTIALIAS_GRAY: - case CAIRO_ANTIALIAS_NONE: - case CAIRO_ANTIALIAS_FAST: - case CAIRO_ANTIALIAS_GOOD: - precision = XCB_RENDER_POLY_MODE_IMPRECISE; - break; - case CAIRO_ANTIALIAS_SUBPIXEL: - case CAIRO_ANTIALIAS_BEST: - precision = XCB_RENDER_POLY_MODE_PRECISE; - break; - } - - if (surface->precision != precision) { - _cairo_xcb_connection_render_change_picture (connection, - surface->picture, - XCB_RENDER_CP_POLY_MODE, - &precision); - surface->precision = precision; - } -} - - -static void -_cairo_xcb_surface_ensure_picture (cairo_xcb_surface_t *surface) -{ - assert (surface->fallback == NULL); - if (surface->picture == XCB_NONE) { - uint32_t values[1]; - uint32_t flags = 0; - - if (surface->precision != XCB_RENDER_POLY_MODE_PRECISE) { - flags |= XCB_RENDER_CP_POLY_MODE; - values[0] = surface->precision; - } - - surface->picture = _cairo_xcb_connection_get_xid (surface->connection); - _cairo_xcb_connection_render_create_picture (surface->connection, - surface->picture, - surface->drawable, - surface->xrender_format, - flags, values); - } -} - -static cairo_xcb_picture_t * -_picture_from_image (cairo_xcb_surface_t *target, - xcb_render_pictformat_t format, - cairo_image_surface_t *image, - cairo_xcb_shm_info_t *shm_info) -{ - xcb_pixmap_t pixmap; - xcb_gcontext_t gc; - cairo_xcb_picture_t *picture; - - pixmap = _cairo_xcb_connection_create_pixmap (target->connection, - image->depth, - target->drawable, - image->width, image->height); - - gc = _cairo_xcb_screen_get_gc (target->screen, pixmap, image->depth); - - if (shm_info != NULL) { - _cairo_xcb_connection_shm_put_image (target->connection, - pixmap, gc, - image->width, image->height, - 0, 0, - image->width, image->height, - 0, 0, - image->depth, - shm_info->shm, - shm_info->offset); - } else { - int len; - - /* Do we need to trim the image? */ - len = CAIRO_STRIDE_FOR_WIDTH_BPP (image->width, PIXMAN_FORMAT_BPP (image->pixman_format)); - if (len == image->stride) { - _cairo_xcb_connection_put_image (target->connection, - pixmap, gc, - image->width, image->height, - 0, 0, - image->depth, - image->stride, - image->data); - } else { - _cairo_xcb_connection_put_subimage (target->connection, - pixmap, gc, - 0, 0, - image->width, image->height, - PIXMAN_FORMAT_BPP (image->pixman_format) / 8, - image->stride, - 0, 0, - image->depth, - image->data); - - } - } - - _cairo_xcb_screen_put_gc (target->screen, image->depth, gc); - - picture = _cairo_xcb_picture_create (target->screen, - image->pixman_format, format, - image->width, image->height); - if (likely (picture->base.status == CAIRO_STATUS_SUCCESS)) { - _cairo_xcb_connection_render_create_picture (target->connection, - picture->picture, pixmap, format, - 0, 0); - } - - _cairo_xcb_connection_free_pixmap (target->connection, pixmap); - - return picture; -} - -static cairo_bool_t -_pattern_is_supported (uint32_t flags, - const cairo_pattern_t *pattern) - -{ - if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) - return TRUE; - - switch (pattern->extend) { - default: - ASSERT_NOT_REACHED; - case CAIRO_EXTEND_NONE: - case CAIRO_EXTEND_REPEAT: - break; - case CAIRO_EXTEND_PAD: - case CAIRO_EXTEND_REFLECT: - if ((flags & CAIRO_XCB_RENDER_HAS_EXTENDED_REPEAT) == 0) - return FALSE; - } - - if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) { - switch (pattern->filter) { - case CAIRO_FILTER_FAST: - case CAIRO_FILTER_NEAREST: - return (flags & CAIRO_XCB_RENDER_HAS_PICTURE_TRANSFORM) || - _cairo_matrix_is_integer_translation (&pattern->matrix, NULL, NULL); - case CAIRO_FILTER_GOOD: - return flags & CAIRO_XCB_RENDER_HAS_FILTER_GOOD; - case CAIRO_FILTER_BEST: - return flags & CAIRO_XCB_RENDER_HAS_FILTER_BEST; - case CAIRO_FILTER_BILINEAR: - case CAIRO_FILTER_GAUSSIAN: - default: - return flags & CAIRO_XCB_RENDER_HAS_FILTERS; - } - } else if (pattern->type == CAIRO_PATTERN_TYPE_MESH) { - return FALSE; - } else { /* gradient */ - if ((flags & CAIRO_XCB_RENDER_HAS_GRADIENTS) == 0) - return FALSE; - - /* The RENDER specification says that the inner circle has to be - * completely contained inside the outer one. */ - if (pattern->type == CAIRO_PATTERN_TYPE_RADIAL && - ! _cairo_radial_pattern_focus_is_inside ((cairo_radial_pattern_t *) pattern)) - { - return FALSE; - } - return TRUE; - } -} - -static void -_cairo_xcb_picture_set_matrix (cairo_xcb_picture_t *picture, - const cairo_matrix_t *matrix, - cairo_filter_t filter, - double xc, double yc) -{ - xcb_render_transform_t transform; - pixman_transform_t *pixman_transform; - cairo_int_status_t ignored; - - /* Casting between pixman_transform_t and xcb_render_transform_t is safe - * because they happen to be the exact same type. - */ - pixman_transform = (pixman_transform_t *) &transform; - - picture->x = picture->x0; - picture->y = picture->y0; - ignored = _cairo_matrix_to_pixman_matrix_offset (matrix, filter, xc, yc, - pixman_transform, - &picture->x, &picture->y); - (void) ignored; - - if (memcmp (&picture->transform, &transform, sizeof (xcb_render_transform_t))) { - _cairo_xcb_connection_render_set_picture_transform (_picture_to_connection (picture), - picture->picture, - &transform); - - picture->transform = transform; - } -} - -static void -_cairo_xcb_picture_set_filter (cairo_xcb_picture_t *picture, - cairo_filter_t filter) -{ - const char *render_filter; - int len; - - if (picture->filter == filter) - return; - - switch (filter) { - case CAIRO_FILTER_FAST: - render_filter = "fast"; - len = strlen ("fast"); - break; - - case CAIRO_FILTER_GOOD: - render_filter = "good"; - len = strlen ("good"); - break; - - case CAIRO_FILTER_BEST: - render_filter = "best"; - len = strlen ("best"); - break; - - case CAIRO_FILTER_NEAREST: - render_filter = "nearest"; - len = strlen ("nearest"); - break; - - case CAIRO_FILTER_BILINEAR: - render_filter = "bilinear"; - len = strlen ("bilinear"); - break; - - default: - ASSERT_NOT_REACHED; - case CAIRO_FILTER_GAUSSIAN: - render_filter = "best"; - len = strlen ("best"); - break; - } - - _cairo_xcb_connection_render_set_picture_filter (_picture_to_connection (picture), - picture->picture, - len, (char *) render_filter); - picture->filter = filter; -} - -static void -_cairo_xcb_picture_set_extend (cairo_xcb_picture_t *picture, - cairo_extend_t extend) -{ - uint32_t pa[1]; - - if (picture->extend == extend) - return; - - switch (extend) { - default: - ASSERT_NOT_REACHED; - case CAIRO_EXTEND_NONE: - pa[0] = XCB_RENDER_REPEAT_NONE; - break; - - case CAIRO_EXTEND_REPEAT: - pa[0] = XCB_RENDER_REPEAT_NORMAL; - break; - - case CAIRO_EXTEND_REFLECT: - pa[0] = XCB_RENDER_REPEAT_REFLECT; - break; - - case CAIRO_EXTEND_PAD: - pa[0] = XCB_RENDER_REPEAT_PAD; - break; - } - - _cairo_xcb_connection_render_change_picture (_picture_to_connection (picture), - picture->picture, - XCB_RENDER_CP_REPEAT, pa); - picture->extend = extend; -} - -static void -_cairo_xcb_picture_set_component_alpha (cairo_xcb_picture_t *picture, - cairo_bool_t ca) -{ - uint32_t pa[1]; - - if (picture->has_component_alpha == ca) - return; - - pa[0] = ca; - - _cairo_xcb_connection_render_change_picture (_picture_to_connection (picture), - picture->picture, - XCB_RENDER_CP_COMPONENT_ALPHA, - pa); - picture->has_component_alpha = ca; -} - -static cairo_xcb_picture_t * -_solid_picture (cairo_xcb_surface_t *target, - const cairo_color_t *color) -{ - xcb_render_color_t xcb_color; - xcb_render_pictformat_t xrender_format; - cairo_xcb_picture_t *picture; - - xcb_color.red = color->red_short; - xcb_color.green = color->green_short; - xcb_color.blue = color->blue_short; - xcb_color.alpha = color->alpha_short; - - xrender_format = target->screen->connection->standard_formats[CAIRO_FORMAT_ARGB32]; - picture = _cairo_xcb_picture_create (target->screen, - PIXMAN_a8r8g8b8, - xrender_format, - -1, -1); - if (unlikely (picture->base.status)) - return picture; - - if (target->connection->flags & CAIRO_XCB_RENDER_HAS_GRADIENTS) { - _cairo_xcb_connection_render_create_solid_fill (target->connection, - picture->picture, - xcb_color); - } else { - xcb_pixmap_t pixmap; - uint32_t values[] = { XCB_RENDER_REPEAT_NORMAL }; - - pixmap = _cairo_xcb_connection_create_pixmap (target->connection, - 32, target->drawable, 1, 1); - _cairo_xcb_connection_render_create_picture (target->connection, - picture->picture, - pixmap, - xrender_format, - XCB_RENDER_CP_REPEAT, - values); - if (target->connection->flags & CAIRO_XCB_RENDER_HAS_FILL_RECTANGLES) { - xcb_rectangle_t rect; - - rect.x = rect.y = 0; - rect.width = rect.height = 1; - - _cairo_xcb_connection_render_fill_rectangles (_picture_to_connection (picture), - XCB_RENDER_PICT_OP_SRC, - picture->picture, - xcb_color, 1, &rect); - } else { - xcb_gcontext_t gc; - uint32_t pixel; - - gc = _cairo_xcb_screen_get_gc (target->screen, pixmap, 32); - - /* XXX byte ordering? */ - pixel = ((color->alpha_short >> 8) << 24) | - ((color->red_short >> 8) << 16) | - ((color->green_short >> 8) << 8) | - ((color->blue_short >> 8) << 0); - - _cairo_xcb_connection_put_image (target->connection, - pixmap, gc, - 1, 1, 0, 0, - 32, 4, &pixel); - - _cairo_xcb_screen_put_gc (target->screen, 32, gc); - } - - _cairo_xcb_connection_free_pixmap (target->connection, pixmap); - } - - return picture; -} - -static cairo_xcb_picture_t * -_cairo_xcb_transparent_picture (cairo_xcb_surface_t *target) -{ - cairo_xcb_picture_t *picture; - - picture = (cairo_xcb_picture_t *) target->screen->stock_colors[CAIRO_STOCK_TRANSPARENT]; - if (picture == NULL) { - picture = _solid_picture (target, CAIRO_COLOR_TRANSPARENT); - target->screen->stock_colors[CAIRO_STOCK_TRANSPARENT] = &picture->base; - } - - return (cairo_xcb_picture_t *) cairo_surface_reference (&picture->base); -} - -static cairo_xcb_picture_t * -_cairo_xcb_black_picture (cairo_xcb_surface_t *target) -{ - cairo_xcb_picture_t *picture; - - picture = (cairo_xcb_picture_t *) target->screen->stock_colors[CAIRO_STOCK_BLACK]; - if (picture == NULL) { - picture = _solid_picture (target, CAIRO_COLOR_BLACK); - target->screen->stock_colors[CAIRO_STOCK_BLACK] = &picture->base; - } - - return (cairo_xcb_picture_t *) cairo_surface_reference (&picture->base); -} - -static cairo_xcb_picture_t * -_cairo_xcb_white_picture (cairo_xcb_surface_t *target) -{ - cairo_xcb_picture_t *picture; - - picture = (cairo_xcb_picture_t *) target->screen->stock_colors[CAIRO_STOCK_WHITE]; - if (picture == NULL) { - picture = _solid_picture (target, CAIRO_COLOR_WHITE); - target->screen->stock_colors[CAIRO_STOCK_WHITE] = &picture->base; - } - - return (cairo_xcb_picture_t *) cairo_surface_reference (&picture->base); -} - -static cairo_xcb_picture_t * -_cairo_xcb_solid_picture (cairo_xcb_surface_t *target, - const cairo_solid_pattern_t *pattern) -{ - cairo_xcb_picture_t *picture; - cairo_xcb_screen_t *screen; - int i, n_cached; - - if (pattern->color.alpha_short <= 0x00ff) - return _cairo_xcb_transparent_picture (target); - - if (pattern->color.alpha_short >= 0xff00) { - if (pattern->color.red_short <= 0x00ff && - pattern->color.green_short <= 0x00ff && - pattern->color.blue_short <= 0x00ff) - { - return _cairo_xcb_black_picture (target); - } - - if (pattern->color.red_short >= 0xff00 && - pattern->color.green_short >= 0xff00 && - pattern->color.blue_short >= 0xff00) - { - return _cairo_xcb_white_picture (target); - } - } - - screen = target->screen; - n_cached = screen->solid_cache_size; - for (i = 0; i < n_cached; i++) { - if (_cairo_color_equal (&screen->solid_cache[i].color, &pattern->color)) { - return (cairo_xcb_picture_t *) cairo_surface_reference (screen->solid_cache[i].picture); - } - } - - picture = _solid_picture (target, &pattern->color); - if (unlikely (picture->base.status)) - return picture; - - if (screen->solid_cache_size < ARRAY_LENGTH (screen->solid_cache)) { - i = screen->solid_cache_size++; - } else { - i = hars_petruska_f54_1_random () % ARRAY_LENGTH (screen->solid_cache); - cairo_surface_destroy (screen->solid_cache[i].picture); - } - screen->solid_cache[i].picture = cairo_surface_reference (&picture->base); - screen->solid_cache[i].color = pattern->color; - - return picture; -} - -static cairo_xcb_picture_t * -_render_to_picture (cairo_xcb_surface_t *target, - const cairo_pattern_t *pattern, - const cairo_rectangle_int_t *extents) -{ - cairo_image_surface_t *image; - cairo_xcb_shm_info_t *shm_info; - cairo_pattern_union_t copy; - cairo_status_t status; - cairo_xcb_picture_t *picture; - pixman_format_code_t pixman_format; - xcb_render_pictformat_t xrender_format; - - /* XXX handle extend modes via tiling? */ - /* XXX alpha-only masks? */ - - pixman_format = PIXMAN_a8r8g8b8; - xrender_format = target->screen->connection->standard_formats[CAIRO_FORMAT_ARGB32]; - - status = _cairo_xcb_shm_image_create (target->screen->connection, - pixman_format, - extents->width, extents->height, - &image, &shm_info); - if (unlikely (status)) - return (cairo_xcb_picture_t *) _cairo_surface_create_in_error (status); - - _cairo_pattern_init_static_copy (©.base, pattern); - cairo_matrix_translate (©.base.matrix, extents->x, extents->y); - status = _cairo_surface_paint (&image->base, - CAIRO_OPERATOR_SOURCE, - ©.base, - NULL); - if (unlikely (status)) { - cairo_surface_destroy (&image->base); - return (cairo_xcb_picture_t *) _cairo_surface_create_in_error (status); - } - - picture = _picture_from_image (target, xrender_format, image, shm_info); - cairo_surface_destroy (&image->base); - - if (unlikely (picture->base.status)) - return picture; - - _cairo_xcb_picture_set_component_alpha (picture, pattern->has_component_alpha); - picture->x = -extents->x; - picture->y = -extents->y; - - return picture; -} - -static xcb_render_fixed_t * -_gradient_to_xcb (const cairo_gradient_pattern_t *gradient, - unsigned int *n_stops, - char *buf, unsigned int buflen) -{ - xcb_render_fixed_t *stops; - xcb_render_color_t *colors; - unsigned int i; - - assert (gradient->n_stops > 0); - *n_stops = MAX (gradient->n_stops, 2); - - if (*n_stops * (sizeof (xcb_render_fixed_t) + sizeof (xcb_render_color_t)) < buflen) - { - stops = (xcb_render_fixed_t *) buf; - } - else - { - stops = - _cairo_malloc_ab (*n_stops, - sizeof (xcb_render_fixed_t) + sizeof (xcb_render_color_t)); - if (unlikely (stops == NULL)) - return NULL; - } - - colors = (xcb_render_color_t *) (stops + *n_stops); - for (i = 0; i < gradient->n_stops; i++) { - stops[i] = - _cairo_fixed_16_16_from_double (gradient->stops[i].offset); - - colors[i].red = gradient->stops[i].color.red_short; - colors[i].green = gradient->stops[i].color.green_short; - colors[i].blue = gradient->stops[i].color.blue_short; - colors[i].alpha = gradient->stops[i].color.alpha_short; - } - - /* RENDER does not support gradients with less than 2 stops. If a - * gradient has only a single stop, duplicate it to make RENDER - * happy. */ - if (gradient->n_stops == 1) { - stops[1] = _cairo_fixed_16_16_from_double (gradient->stops[0].offset); - - colors[1].red = gradient->stops[0].color.red_short; - colors[1].green = gradient->stops[0].color.green_short; - colors[1].blue = gradient->stops[0].color.blue_short; - colors[1].alpha = gradient->stops[0].color.alpha_short; - } - - return stops; -} - -static cairo_xcb_picture_t * -_cairo_xcb_linear_picture (cairo_xcb_surface_t *target, - const cairo_linear_pattern_t *pattern, - const cairo_rectangle_int_t *extents) -{ - char buf[CAIRO_STACK_BUFFER_SIZE]; - xcb_render_fixed_t *stops; - xcb_render_color_t *colors; - xcb_render_pointfix_t p1, p2; - cairo_matrix_t matrix; - cairo_circle_double_t extremes[2]; - cairo_xcb_picture_t *picture; - cairo_status_t status; - unsigned int n_stops; - - _cairo_gradient_pattern_fit_to_range (&pattern->base, PIXMAN_MAX_INT >> 1, &matrix, extremes); - - picture = (cairo_xcb_picture_t *) - _cairo_xcb_screen_lookup_linear_picture (target->screen, pattern); - if (picture != NULL) - goto setup_picture; - - stops = _gradient_to_xcb (&pattern->base, &n_stops, buf, sizeof (buf)); - if (unlikely (stops == NULL)) - return (cairo_xcb_picture_t *) _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY); - - picture = _cairo_xcb_picture_create (target->screen, - target->screen->connection->standard_formats[CAIRO_FORMAT_ARGB32], - PIXMAN_a8r8g8b8, - -1, -1); - if (unlikely (picture->base.status)) { - if (stops != (xcb_render_fixed_t *) buf) - free (stops); - return picture; - } - picture->filter = CAIRO_FILTER_DEFAULT; - - colors = (xcb_render_color_t *) (stops + n_stops); - - p1.x = _cairo_fixed_16_16_from_double (extremes[0].center.x); - p1.y = _cairo_fixed_16_16_from_double (extremes[0].center.y); - p2.x = _cairo_fixed_16_16_from_double (extremes[1].center.x); - p2.y = _cairo_fixed_16_16_from_double (extremes[1].center.y); - - _cairo_xcb_connection_render_create_linear_gradient (target->connection, - picture->picture, - p1, p2, - n_stops, - stops, colors); - - if (stops != (xcb_render_fixed_t *) buf) - free (stops); - - status = _cairo_xcb_screen_store_linear_picture (target->screen, - pattern, - &picture->base); - if (unlikely (status)) { - cairo_surface_destroy (&picture->base); - return (cairo_xcb_picture_t *) _cairo_surface_create_in_error (status); - } - -setup_picture: - _cairo_xcb_picture_set_matrix (picture, &matrix, - pattern->base.base.filter, - extents->x + extents->width/2., - extents->y + extents->height/2.); - _cairo_xcb_picture_set_filter (picture, pattern->base.base.filter); - _cairo_xcb_picture_set_extend (picture, pattern->base.base.extend); - _cairo_xcb_picture_set_component_alpha (picture, - pattern->base.base.has_component_alpha); - - return picture; -} - -static cairo_xcb_picture_t * -_cairo_xcb_radial_picture (cairo_xcb_surface_t *target, - const cairo_radial_pattern_t *pattern, - const cairo_rectangle_int_t *extents) -{ - char buf[CAIRO_STACK_BUFFER_SIZE]; - xcb_render_fixed_t *stops; - xcb_render_color_t *colors; - xcb_render_pointfix_t p1, p2; - xcb_render_fixed_t r1, r2; - cairo_matrix_t matrix; - cairo_circle_double_t extremes[2]; - cairo_xcb_picture_t *picture; - cairo_status_t status; - unsigned int n_stops; - - _cairo_gradient_pattern_fit_to_range (&pattern->base, PIXMAN_MAX_INT >> 1, &matrix, extremes); - - picture = (cairo_xcb_picture_t *) - _cairo_xcb_screen_lookup_radial_picture (target->screen, pattern); - if (picture != NULL) - goto setup_picture; - - stops = _gradient_to_xcb (&pattern->base, &n_stops, buf, sizeof (buf)); - if (unlikely (stops == NULL)) - return (cairo_xcb_picture_t *) _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY); - - picture = _cairo_xcb_picture_create (target->screen, - target->screen->connection->standard_formats[CAIRO_FORMAT_ARGB32], - PIXMAN_a8r8g8b8, - -1, -1); - if (unlikely (picture->base.status)) { - if (stops != (xcb_render_fixed_t *) buf) - free (stops); - return picture; - } - picture->filter = CAIRO_FILTER_DEFAULT; - - colors = (xcb_render_color_t *) (stops + n_stops); - - p1.x = _cairo_fixed_16_16_from_double (extremes[0].center.x); - p1.y = _cairo_fixed_16_16_from_double (extremes[0].center.y); - p2.x = _cairo_fixed_16_16_from_double (extremes[1].center.x); - p2.y = _cairo_fixed_16_16_from_double (extremes[1].center.y); - - r1 = _cairo_fixed_16_16_from_double (extremes[0].radius); - r2 = _cairo_fixed_16_16_from_double (extremes[1].radius); - - _cairo_xcb_connection_render_create_radial_gradient (target->connection, - picture->picture, - p1, p2, r1, r2, - n_stops, - stops, colors); - - if (stops != (xcb_render_fixed_t *) buf) - free (stops); - - status = _cairo_xcb_screen_store_radial_picture (target->screen, - pattern, - &picture->base); - if (unlikely (status)) { - cairo_surface_destroy (&picture->base); - return (cairo_xcb_picture_t *) _cairo_surface_create_in_error (status); - } - -setup_picture: - _cairo_xcb_picture_set_matrix (picture, &matrix, - pattern->base.base.filter, - extents->x + extents->width/2., - extents->y + extents->height/2.); - _cairo_xcb_picture_set_filter (picture, pattern->base.base.filter); - _cairo_xcb_picture_set_extend (picture, pattern->base.base.extend); - _cairo_xcb_picture_set_component_alpha (picture, - pattern->base.base.has_component_alpha); - - return picture; -} - -static cairo_xcb_picture_t * -_copy_to_picture (cairo_xcb_surface_t *source) -{ - cairo_xcb_picture_t *picture; - uint32_t values[] = { 0, 1 }; - - if (source->deferred_clear) { - cairo_status_t status = _cairo_xcb_surface_clear (source); - if (unlikely (status)) - return (cairo_xcb_picture_t *) _cairo_surface_create_in_error (status); - } - - picture = _cairo_xcb_picture_create (source->screen, - source->xrender_format, - source->pixman_format, - source->width, - source->height); - if (unlikely (picture->base.status)) - return picture; - - _cairo_xcb_connection_render_create_picture (source->connection, - picture->picture, - source->drawable, - source->xrender_format, - XCB_RENDER_CP_GRAPHICS_EXPOSURE | - XCB_RENDER_CP_SUBWINDOW_MODE, - values); - - return picture; -} - -static void -_cairo_xcb_surface_setup_surface_picture(cairo_xcb_picture_t *picture, - const cairo_surface_pattern_t *pattern, - const cairo_rectangle_int_t *extents) -{ - cairo_filter_t filter; - - filter = pattern->base.filter; - if (filter != CAIRO_FILTER_NEAREST && - _cairo_matrix_is_pixel_exact (&pattern->base.matrix)) - { - filter = CAIRO_FILTER_NEAREST; - } - _cairo_xcb_picture_set_filter (picture, filter); - - _cairo_xcb_picture_set_matrix (picture, - &pattern->base.matrix, filter, - extents->x + extents->width/2., - extents->y + extents->height/2.); - - - _cairo_xcb_picture_set_extend (picture, pattern->base.extend); - _cairo_xcb_picture_set_component_alpha (picture, pattern->base.has_component_alpha); -} - -static cairo_xcb_picture_t * -record_to_picture (cairo_surface_t *target, - const cairo_surface_pattern_t *pattern, - const cairo_rectangle_int_t *extents) -{ - cairo_surface_pattern_t tmp_pattern; - cairo_xcb_picture_t *picture; - cairo_status_t status; - cairo_matrix_t matrix; - cairo_surface_t *tmp; - cairo_surface_t *source; - cairo_rectangle_int_t limit; - cairo_extend_t extend; - - /* XXX: The following was once more or less copied from cairo-xlibs-ource.c, - * record_source() and recording_pattern_get_surface(), can we share a - * single version? - */ - - /* First get the 'real' recording surface and figure out the size for tmp */ - source = _cairo_pattern_get_source (pattern, &limit); - assert (_cairo_surface_is_recording (source)); - - if (! _cairo_matrix_is_identity (&pattern->base.matrix)) { - double x1, y1, x2, y2; - - matrix = pattern->base.matrix; - status = cairo_matrix_invert (&matrix); - assert (status == CAIRO_STATUS_SUCCESS); - - x1 = limit.x; - y1 = limit.y; - x2 = limit.x + limit.width; - y2 = limit.y + limit.height; - - _cairo_matrix_transform_bounding_box (&matrix, - &x1, &y1, &x2, &y2, NULL); - - limit.x = floor (x1); - limit.y = floor (y1); - limit.width = ceil (x2) - limit.x; - limit.height = ceil (y2) - limit.y; - } - extend = pattern->base.extend; - if (_cairo_rectangle_contains_rectangle (&limit, extents)) - extend = CAIRO_EXTEND_NONE; - if (extend == CAIRO_EXTEND_NONE && ! _cairo_rectangle_intersect (&limit, extents)) - return _cairo_xcb_transparent_picture ((cairo_xcb_surface_t *) target); - - /* Now draw the recording surface to an xcb surface */ - tmp = _cairo_surface_create_scratch (target, - source->content, - limit.width, - limit.height, - CAIRO_COLOR_TRANSPARENT); - if (tmp->status != CAIRO_STATUS_SUCCESS) { - return (cairo_xcb_picture_t *) tmp; - } - - cairo_matrix_init_translate (&matrix, limit.x, limit.y); - cairo_matrix_multiply (&matrix, &matrix, &pattern->base.matrix); - - status = _cairo_recording_surface_replay_with_clip (source, - &matrix, tmp, - NULL); - if (unlikely (status)) { - cairo_surface_destroy (tmp); - return (cairo_xcb_picture_t *) _cairo_surface_create_in_error (status); - } - - /* Now that we have drawn this to an xcb surface, try again with that */ - _cairo_pattern_init_static_copy (&tmp_pattern.base, &pattern->base); - tmp_pattern.surface = tmp; - cairo_matrix_init_translate (&tmp_pattern.base.matrix, -limit.x, -limit.y); - - picture = _copy_to_picture ((cairo_xcb_surface_t *) tmp); - if (picture->base.status == CAIRO_STATUS_SUCCESS) - _cairo_xcb_surface_setup_surface_picture (picture, &tmp_pattern, extents); - cairo_surface_destroy (tmp); - return picture; -} - -static cairo_xcb_picture_t * -_cairo_xcb_surface_picture (cairo_xcb_surface_t *target, - const cairo_surface_pattern_t *pattern, - const cairo_rectangle_int_t *extents) -{ - cairo_surface_t *source = pattern->surface; - cairo_xcb_picture_t *picture; - - picture = (cairo_xcb_picture_t *) - _cairo_surface_has_snapshot (source, &_cairo_xcb_picture_backend); - if (picture != NULL) { - if (picture->screen == target->screen) { - picture = (cairo_xcb_picture_t *) cairo_surface_reference (&picture->base); - _cairo_xcb_surface_setup_surface_picture (picture, pattern, extents); - return picture; - } - picture = NULL; - } - - if (source->type == CAIRO_SURFACE_TYPE_XCB) - { - if (_cairo_surface_is_xcb(source)) { - cairo_xcb_surface_t *xcb = (cairo_xcb_surface_t *) source; - if (xcb->screen == target->screen && xcb->fallback == NULL) { - picture = _copy_to_picture ((cairo_xcb_surface_t *) source); - if (unlikely (picture->base.status)) - return picture; - } - } else if (source->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) { - cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) source; - cairo_xcb_surface_t *xcb = (cairo_xcb_surface_t *) sub->target; - - /* XXX repeat interval with source clipping? */ - if (FALSE && xcb->screen == target->screen && xcb->fallback == NULL) { - xcb_rectangle_t rect; - - picture = _copy_to_picture (xcb); - if (unlikely (picture->base.status)) - return picture; - - rect.x = sub->extents.x; - rect.y = sub->extents.y; - rect.width = sub->extents.width; - rect.height = sub->extents.height; - - _cairo_xcb_connection_render_set_picture_clip_rectangles (xcb->connection, - picture->picture, - 0, 0, - 1, &rect); - picture->x0 = rect.x; - picture->y0 = rect.y; - picture->width = rect.width; - picture->height = rect.height; - } - } else if (_cairo_surface_is_snapshot (source)) { - cairo_surface_snapshot_t *snap = (cairo_surface_snapshot_t *) source; - cairo_xcb_surface_t *xcb = (cairo_xcb_surface_t *) snap->target; - - if (xcb->screen == target->screen && xcb->fallback == NULL) { - picture = _copy_to_picture (xcb); - if (unlikely (picture->base.status)) - return picture; - } - } - } -#if CAIRO_HAS_XLIB_XCB_FUNCTIONS - else if (source->type == CAIRO_SURFACE_TYPE_XLIB) - { - if (source->backend->type == CAIRO_SURFACE_TYPE_XLIB) { - cairo_xcb_surface_t *xcb = ((cairo_xlib_xcb_surface_t *) source)->xcb; - if (xcb->screen == target->screen && xcb->fallback == NULL) { - picture = _copy_to_picture (xcb); - if (unlikely (picture->base.status)) - return picture; - } - } else if (source->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) { - cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) source; - cairo_xcb_surface_t *xcb = ((cairo_xlib_xcb_surface_t *) sub->target)->xcb; - - if (FALSE && xcb->screen == target->screen && xcb->fallback == NULL) { - xcb_rectangle_t rect; - - picture = _copy_to_picture (xcb); - if (unlikely (picture->base.status)) - return picture; - - rect.x = sub->extents.x; - rect.y = sub->extents.y; - rect.width = sub->extents.width; - rect.height = sub->extents.height; - - _cairo_xcb_connection_render_set_picture_clip_rectangles (xcb->connection, - picture->picture, - 0, 0, - 1, &rect); - picture->x0 = rect.x; - picture->y0 = rect.y; - picture->width = rect.width; - picture->height = rect.height; - } - } else if (_cairo_surface_is_snapshot (source)) { - cairo_surface_snapshot_t *snap = (cairo_surface_snapshot_t *) source; - cairo_xcb_surface_t *xcb = ((cairo_xlib_xcb_surface_t *) snap->target)->xcb; - - if (xcb->screen == target->screen && xcb->fallback == NULL) { - picture = _copy_to_picture (xcb); - if (unlikely (picture->base.status)) - return picture; - } - } - } -#endif -#if CAIRO_HAS_GL_FUNCTIONS - else if (source->type == CAIRO_SURFACE_TYPE_GL) - { - /* pixmap from texture */ - } -#endif - else if (source->type == CAIRO_SURFACE_TYPE_RECORDING) - { - /* We have to skip the call to attach_snapshot() because we possibly - * only drew part of the recording surface. - * TODO: When can we safely attach a snapshot? - */ - return record_to_picture(&target->base, pattern, extents); - } - - if (picture == NULL) { - cairo_image_surface_t *image; - void *image_extra; - cairo_status_t status; - - status = _cairo_surface_acquire_source_image (source, &image, &image_extra); - if (unlikely (status)) - return (cairo_xcb_picture_t *) _cairo_surface_create_in_error (status); - - if (image->format != CAIRO_FORMAT_INVALID) { - xcb_render_pictformat_t format; - - format = target->screen->connection->standard_formats[image->format]; - - picture = _picture_from_image (target, format, image, NULL); - _cairo_surface_release_source_image (source, image, image_extra); - } else { - cairo_image_surface_t *conv; - xcb_render_pictformat_t render_format; - - /* XXX XRenderPutImage! */ - - conv = _cairo_image_surface_coerce (image); - _cairo_surface_release_source_image (source, image, image_extra); - if (unlikely (conv->base.status)) - return (cairo_xcb_picture_t *) conv; - - render_format = target->screen->connection->standard_formats[conv->format]; - picture = _picture_from_image (target, render_format, conv, NULL); - cairo_surface_destroy (&conv->base); - } - - if (unlikely (picture->base.status)) - return picture; - } - - /* XXX: This causes too many problems and bugs, let's skip it for now. */ -#if 0 - _cairo_surface_attach_snapshot (source, - &picture->base, - NULL); -#endif - - _cairo_xcb_surface_setup_surface_picture (picture, pattern, extents); - return picture; -} - -static cairo_xcb_picture_t * -_cairo_xcb_picture_for_pattern (cairo_xcb_surface_t *target, - const cairo_pattern_t *pattern, - const cairo_rectangle_int_t *extents) -{ - if (pattern == NULL) - return _cairo_xcb_white_picture (target); - - if (! _pattern_is_supported (target->connection->flags, pattern)) - return _render_to_picture (target, pattern, extents); - - switch (pattern->type) { - case CAIRO_PATTERN_TYPE_SOLID: - return _cairo_xcb_solid_picture (target, (cairo_solid_pattern_t *) pattern); - - case CAIRO_PATTERN_TYPE_LINEAR: - return _cairo_xcb_linear_picture (target, - (cairo_linear_pattern_t *) pattern, - extents); - - case CAIRO_PATTERN_TYPE_RADIAL: - return _cairo_xcb_radial_picture (target, - (cairo_radial_pattern_t *) pattern, - extents); - - case CAIRO_PATTERN_TYPE_SURFACE: - return _cairo_xcb_surface_picture (target, - (cairo_surface_pattern_t *) pattern, - extents); - default: - ASSERT_NOT_REACHED; - case CAIRO_PATTERN_TYPE_MESH: - case CAIRO_PATTERN_TYPE_RASTER_SOURCE: - return _render_to_picture (target, pattern, extents); - } -} - -COMPILE_TIME_ASSERT (sizeof (xcb_rectangle_t) <= sizeof (cairo_box_t)); - -static cairo_status_t -_render_fill_boxes (void *abstract_dst, - cairo_operator_t op, - const cairo_color_t *color, - cairo_boxes_t *boxes) -{ - cairo_xcb_surface_t *dst = abstract_dst; - xcb_rectangle_t stack_xrects[CAIRO_STACK_ARRAY_LENGTH (xcb_rectangle_t)]; - xcb_rectangle_t *xrects = stack_xrects; - xcb_render_color_t render_color; - int render_op = _render_operator (op); - struct _cairo_boxes_chunk *chunk; - int max_count; - - render_color.red = color->red_short; - render_color.green = color->green_short; - render_color.blue = color->blue_short; - render_color.alpha = color->alpha_short; - - max_count = 0; - for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) { - if (chunk->count > max_count) - max_count = chunk->count; - } - if (max_count > ARRAY_LENGTH (stack_xrects)) { - xrects = _cairo_malloc_ab (max_count, sizeof (xcb_rectangle_t)); - if (unlikely (xrects == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) { - int i, j; - - for (i = j = 0; i < chunk->count; i++) { - int x1 = _cairo_fixed_integer_round_down (chunk->base[i].p1.x); - int y1 = _cairo_fixed_integer_round_down (chunk->base[i].p1.y); - int x2 = _cairo_fixed_integer_round_down (chunk->base[i].p2.x); - int y2 = _cairo_fixed_integer_round_down (chunk->base[i].p2.y); - - if (x2 > x1 && y2 > y1) { - xrects[j].x = x1; - xrects[j].y = y1; - xrects[j].width = x2 - x1; - xrects[j].height = y2 - y1; - j++; - } - } - - if (j) { - _cairo_xcb_connection_render_fill_rectangles - (dst->connection, - render_op, dst->picture, - render_color, j, xrects); - } - } - - if (xrects != stack_xrects) - free (xrects); - - return CAIRO_STATUS_SUCCESS; -} - -/* pixel aligned, non-overlapping boxes */ -static cairo_int_status_t -_render_composite_boxes (cairo_xcb_surface_t *dst, - cairo_operator_t op, - const cairo_pattern_t *src_pattern, - const cairo_pattern_t *mask_pattern, - const cairo_rectangle_int_t *extents, - const cairo_boxes_t *boxes) -{ - cairo_xcb_picture_t *src, *mask; - const struct _cairo_boxes_chunk *chunk; - xcb_rectangle_t stack_boxes[CAIRO_STACK_ARRAY_LENGTH (xcb_rectangle_t)]; - xcb_rectangle_t *clip_boxes; - cairo_rectangle_int_t stack_extents; - cairo_status_t status; - int num_boxes; - int render_op; - - render_op = _render_operator (op); - - if (src_pattern == NULL) { - src_pattern = mask_pattern; - mask_pattern = NULL; - } - - /* amalgamate into a single Composite call by setting a clip region */ - clip_boxes = stack_boxes; - if (boxes->num_boxes > ARRAY_LENGTH (stack_boxes)) { - clip_boxes = _cairo_malloc_ab (boxes->num_boxes, sizeof (xcb_rectangle_t)); - if (unlikely (clip_boxes == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - src = _cairo_xcb_picture_for_pattern (dst, src_pattern, extents); - status = src->base.status; - if (unlikely (status)) - goto cleanup_boxes; - - num_boxes = 0; - for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) { - const cairo_box_t *box = chunk->base; - int i; - - for (i = 0; i < chunk->count; i++) { - int x = _cairo_fixed_integer_round_down (box[i].p1.x); - int y = _cairo_fixed_integer_round_down (box[i].p1.y); - int width = _cairo_fixed_integer_round_down (box[i].p2.x) - x; - int height = _cairo_fixed_integer_round_down (box[i].p2.y) - y; - - if (width && height) { - clip_boxes[num_boxes].x = x; - clip_boxes[num_boxes].y = y; - clip_boxes[num_boxes].width = width; - clip_boxes[num_boxes].height = height; - num_boxes++; - } - } - } - - if (num_boxes) { - if (num_boxes > 1) { - _cairo_xcb_connection_render_set_picture_clip_rectangles (dst->connection, - dst->picture, - 0, 0, - num_boxes, - clip_boxes); - } else { - stack_extents.x = clip_boxes[0].x; - stack_extents.y = clip_boxes[0].y; - stack_extents.width = clip_boxes[0].width; - stack_extents.height = clip_boxes[0].height; - extents = &stack_extents; - } - - if (mask_pattern != NULL) { - mask = _cairo_xcb_picture_for_pattern (dst, mask_pattern, extents); - status = mask->base.status; - if (unlikely (status)) - goto cleanup_clip; - - _cairo_xcb_connection_render_composite (dst->connection, - render_op, - src->picture, - mask->picture, - dst->picture, - src->x + extents->x, src->y + extents->y, - mask->x + extents->x, mask->y + extents->y, - extents->x, extents->y, - extents->width, extents->height); - - cairo_surface_destroy (&mask->base); - } else { - _cairo_xcb_connection_render_composite (dst->connection, - render_op, - src->picture, - XCB_NONE, - dst->picture, - src->x + extents->x, src->y + extents->y, - 0, 0, - extents->x, extents->y, - extents->width, extents->height); - } - -cleanup_clip: - - if (num_boxes > 1) - _cairo_xcb_surface_clear_clip_region (dst); - } - - cairo_surface_destroy (&src->base); - -cleanup_boxes: - - if (clip_boxes != stack_boxes) - free (clip_boxes); - - return status; -} - - -#define CAIRO_FIXED_16_16_MIN _cairo_fixed_from_int (-32768) -#define CAIRO_FIXED_16_16_MAX _cairo_fixed_from_int (32767) - -static cairo_bool_t -_line_exceeds_16_16 (const cairo_line_t *line) -{ - return - line->p1.x <= CAIRO_FIXED_16_16_MIN || - line->p1.x >= CAIRO_FIXED_16_16_MAX || - - line->p2.x <= CAIRO_FIXED_16_16_MIN || - line->p2.x >= CAIRO_FIXED_16_16_MAX || - - line->p1.y <= CAIRO_FIXED_16_16_MIN || - line->p1.y >= CAIRO_FIXED_16_16_MAX || - - line->p2.y <= CAIRO_FIXED_16_16_MIN || - line->p2.y >= CAIRO_FIXED_16_16_MAX; -} - -static void -_project_line_x_onto_16_16 (const cairo_line_t *line, - cairo_fixed_t top, - cairo_fixed_t bottom, - xcb_render_linefix_t *out) -{ - cairo_point_double_t p1, p2; - double m; - - p1.x = _cairo_fixed_to_double (line->p1.x); - p1.y = _cairo_fixed_to_double (line->p1.y); - - p2.x = _cairo_fixed_to_double (line->p2.x); - p2.y = _cairo_fixed_to_double (line->p2.y); - - m = (p2.x - p1.x) / (p2.y - p1.y); - out->p1.x = _cairo_fixed_16_16_from_double (p1.x + m * _cairo_fixed_to_double (top - line->p1.y)); - out->p2.x = _cairo_fixed_16_16_from_double (p1.x + m * _cairo_fixed_to_double (bottom - line->p1.y)); -} - -typedef struct { - cairo_traps_t traps; - cairo_antialias_t antialias; -} composite_traps_info_t; - -COMPILE_TIME_ASSERT (sizeof (xcb_render_trapezoid_t) <= sizeof (cairo_trapezoid_t)); - -static cairo_int_status_t -_composite_traps (void *closure, - cairo_xcb_surface_t *dst, - cairo_operator_t op, - const cairo_pattern_t *pattern, - int dst_x, int dst_y, - const cairo_rectangle_int_t *extents, - cairo_clip_t *clip) -{ - composite_traps_info_t *info = closure; - const cairo_traps_t *traps = &info->traps; - cairo_xcb_picture_t *src; - cairo_format_t format; - xcb_render_pictformat_t xrender_format; - xcb_render_trapezoid_t *xtraps; - int render_reference_x, render_reference_y; - cairo_status_t status; - int i; - - if (dst->deferred_clear) { - status = _cairo_xcb_surface_clear (dst); - if (unlikely (status)) - return status; - } - - src = _cairo_xcb_picture_for_pattern (dst, pattern, extents); - if (unlikely (src->base.status)) - return src->base.status; - - if (info->antialias == CAIRO_ANTIALIAS_NONE) - format = CAIRO_FORMAT_A1; - else - format = CAIRO_FORMAT_A8; - xrender_format = dst->screen->connection->standard_formats[format]; - - xtraps = (xcb_render_trapezoid_t *) traps->traps; - for (i = 0; i < traps->num_traps; i++) { - cairo_trapezoid_t t = traps->traps[i]; - - /* top/bottom will be clamped to surface bounds */ - xtraps[i].top = _cairo_fixed_to_16_16 (t.top); - xtraps[i].top -= dst_y << 16; - xtraps[i].bottom = _cairo_fixed_to_16_16 (t.bottom); - xtraps[i].bottom -= dst_y << 16; - - /* However, all the other coordinates will have been left untouched so - * as not to introduce numerical error. Recompute them if they - * exceed the 16.16 limits. - */ - if (unlikely (_line_exceeds_16_16 (&t.left))) { - _project_line_x_onto_16_16 (&t.left, - t.top, - t.bottom, - &xtraps[i].left); - xtraps[i].left.p1.y = xtraps[i].top; - xtraps[i].left.p2.y = xtraps[i].bottom; - } else { - xtraps[i].left.p1.x = _cairo_fixed_to_16_16 (t.left.p1.x); - xtraps[i].left.p1.y = _cairo_fixed_to_16_16 (t.left.p1.y); - xtraps[i].left.p2.x = _cairo_fixed_to_16_16 (t.left.p2.x); - xtraps[i].left.p2.y = _cairo_fixed_to_16_16 (t.left.p2.y); - } - xtraps[i].left.p1.x -= dst_x << 16; - xtraps[i].left.p1.y -= dst_y << 16; - xtraps[i].left.p2.x -= dst_x << 16; - xtraps[i].left.p2.y -= dst_y << 16; - - if (unlikely (_line_exceeds_16_16 (&t.right))) { - _project_line_x_onto_16_16 (&t.right, - t.top, - t.bottom, - &xtraps[i].right); - xtraps[i].right.p1.y = xtraps[i].top; - xtraps[i].right.p2.y = xtraps[i].bottom; - } else { - xtraps[i].right.p1.x = _cairo_fixed_to_16_16 (t.right.p1.x); - xtraps[i].right.p1.y = _cairo_fixed_to_16_16 (t.right.p1.y); - xtraps[i].right.p2.x = _cairo_fixed_to_16_16 (t.right.p2.x); - xtraps[i].right.p2.y = _cairo_fixed_to_16_16 (t.right.p2.y); - } - xtraps[i].right.p1.x -= dst_x << 16; - xtraps[i].right.p1.y -= dst_y << 16; - xtraps[i].right.p2.x -= dst_x << 16; - xtraps[i].right.p2.y -= dst_y << 16; - } - - if (xtraps[0].left.p1.y < xtraps[0].left.p2.y) { - render_reference_x = xtraps[0].left.p1.x >> 16; - render_reference_y = xtraps[0].left.p1.y >> 16; - } else { - render_reference_x = xtraps[0].left.p2.x >> 16; - render_reference_y = xtraps[0].left.p2.y >> 16; - } - render_reference_x += src->x + dst_x; - render_reference_y += src->y + dst_y; - - _cairo_xcb_surface_set_precision (dst, info->antialias); - _cairo_xcb_connection_render_trapezoids (dst->connection, - _render_operator (op), - src->picture, - dst->picture, - xrender_format, - render_reference_x, - render_reference_y, - traps->num_traps, xtraps); - - cairo_surface_destroy (&src->base); - - return CAIRO_STATUS_SUCCESS; -} - -/* low-level composite driver */ - -static cairo_xcb_surface_t * -get_clip_surface (const cairo_clip_t *clip, - cairo_xcb_surface_t *target, - int *tx, int *ty) -{ - cairo_surface_t *surface; - cairo_status_t status; - - surface = _cairo_surface_create_scratch (&target->base, - CAIRO_CONTENT_ALPHA, - clip->extents.width, - clip->extents.height, - CAIRO_COLOR_WHITE); - if (unlikely (surface->status)) - return (cairo_xcb_surface_t *) surface; - - assert (surface->backend == &_cairo_xcb_surface_backend); - status = _cairo_clip_combine_with_surface (clip, surface, - clip->extents.x, clip->extents.y); - if (unlikely (status)) { - cairo_surface_destroy (surface); - surface = _cairo_surface_create_in_error (status); - } - - *tx = clip->extents.x; - *ty = clip->extents.y; - - return (cairo_xcb_surface_t *) surface; -} - -typedef cairo_int_status_t -(*xcb_draw_func_t) (void *closure, - cairo_xcb_surface_t *dst, - cairo_operator_t op, - const cairo_pattern_t *src, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents, - cairo_clip_t *clip); - -static void do_unaligned_row(void (*blt)(void *closure, - int16_t x, int16_t y, - int16_t w, int16_t h, - uint16_t coverage), - void *closure, - const cairo_box_t *b, - int tx, int y, int h, - uint16_t coverage) -{ - int x1 = _cairo_fixed_integer_part (b->p1.x) - tx; - int x2 = _cairo_fixed_integer_part (b->p2.x) - tx; - if (x2 > x1) { - if (! _cairo_fixed_is_integer (b->p1.x)) { - blt(closure, x1, y, 1, h, - coverage * (256 - _cairo_fixed_fractional_part (b->p1.x))); - x1++; - } - - if (x2 > x1) - blt(closure, x1, y, x2-x1, h, (coverage << 8) - (coverage >> 8)); - - if (! _cairo_fixed_is_integer (b->p2.x)) - blt(closure, x2, y, 1, h, - coverage * _cairo_fixed_fractional_part (b->p2.x)); - } else - blt(closure, x1, y, 1, h, - coverage * (b->p2.x - b->p1.x)); -} - -static void do_unaligned_box(void (*blt)(void *closure, - int16_t x, int16_t y, - int16_t w, int16_t h, - uint16_t coverage), - void *closure, - const cairo_box_t *b, int tx, int ty) -{ - int y1 = _cairo_fixed_integer_part (b->p1.y) - ty; - int y2 = _cairo_fixed_integer_part (b->p2.y) - ty; - if (y2 > y1) { - if (! _cairo_fixed_is_integer (b->p1.y)) { - do_unaligned_row(blt, closure, b, tx, y1, 1, - 256 - _cairo_fixed_fractional_part (b->p1.y)); - y1++; - } - - if (y2 > y1) - do_unaligned_row(blt, closure, b, tx, y1, y2-y1, 256); - - if (! _cairo_fixed_is_integer (b->p2.y)) - do_unaligned_row(blt, closure, b, tx, y2, 1, - _cairo_fixed_fractional_part (b->p2.y)); - } else - do_unaligned_row(blt, closure, b, tx, y1, 1, - b->p2.y - b->p1.y); -} - - -static void blt_in(void *closure, - int16_t x, int16_t y, - int16_t w, int16_t h, - uint16_t coverage) -{ - cairo_xcb_surface_t *mask = closure; - xcb_render_color_t color; - xcb_rectangle_t rect; - - if (coverage == 0xffff) - return; - - color.red = color.green = color.blue = 0; - color.alpha = coverage; - - rect.x = x; - rect.y = y; - rect.width = w; - rect.height = h; - - _cairo_xcb_connection_render_fill_rectangles (mask->connection, - XCB_RENDER_PICT_OP_IN, - mask->picture, - color, 1, &rect); -} - -static cairo_xcb_surface_t * -_create_composite_mask (cairo_clip_t *clip, - xcb_draw_func_t draw_func, - xcb_draw_func_t mask_func, - void *draw_closure, - cairo_xcb_surface_t *dst, - const cairo_rectangle_int_t*extents) -{ - cairo_xcb_surface_t *surface; - cairo_bool_t need_clip_combine; - cairo_int_status_t status; - - surface = (cairo_xcb_surface_t *) - _cairo_xcb_surface_create_similar (dst, CAIRO_CONTENT_ALPHA, - extents->width, extents->height); - if (unlikely (surface->base.status)) - return surface; - - _cairo_xcb_surface_ensure_picture (surface); - - surface->deferred_clear_color = *CAIRO_COLOR_TRANSPARENT; - surface->deferred_clear = TRUE; - surface->base.is_clear = TRUE; - - if (mask_func) { - status = mask_func (draw_closure, surface, - CAIRO_OPERATOR_ADD, NULL, - extents->x, extents->y, - extents, clip); - if (likely (status != CAIRO_INT_STATUS_UNSUPPORTED)) - return surface; - } - - /* Is it worth setting the clip region here? */ - status = draw_func (draw_closure, surface, - CAIRO_OPERATOR_ADD, NULL, - extents->x, extents->y, - extents, NULL); - if (unlikely (status)) { - cairo_surface_destroy (&surface->base); - return (cairo_xcb_surface_t *) _cairo_surface_create_in_error (status); - } - - if (surface->connection->flags & CAIRO_XCB_RENDER_HAS_FILL_RECTANGLES) { - int i; - - for (i = 0; i < clip->num_boxes; i++) { - cairo_box_t *b = &clip->boxes[i]; - - if (! _cairo_fixed_is_integer (b->p1.x) || - ! _cairo_fixed_is_integer (b->p1.y) || - ! _cairo_fixed_is_integer (b->p2.x) || - ! _cairo_fixed_is_integer (b->p2.y)) - { - do_unaligned_box(blt_in, surface, b, extents->x, extents->y); - } - } - - need_clip_combine = clip->path != NULL; - } else - need_clip_combine = ! _cairo_clip_is_region (clip); - - if (need_clip_combine) { - status = _cairo_clip_combine_with_surface (clip, &surface->base, - extents->x, extents->y); - if (unlikely (status)) { - cairo_surface_destroy (&surface->base); - return (cairo_xcb_surface_t *) _cairo_surface_create_in_error (status); - } - } - - return surface; -} - -/* Handles compositing with a clip surface when the operator allows - * us to combine the clip with the mask - */ -static cairo_status_t -_clip_and_composite_with_mask (cairo_clip_t *clip, - cairo_operator_t op, - const cairo_pattern_t *pattern, - xcb_draw_func_t draw_func, - xcb_draw_func_t mask_func, - void *draw_closure, - cairo_xcb_surface_t *dst, - const cairo_rectangle_int_t*extents) -{ - cairo_xcb_surface_t *mask; - cairo_xcb_picture_t *src; - - mask = _create_composite_mask (clip, - draw_func, mask_func, draw_closure, - dst, extents); - if (unlikely (mask->base.status)) - return mask->base.status; - - if (pattern != NULL || dst->base.content != CAIRO_CONTENT_ALPHA) { - src = _cairo_xcb_picture_for_pattern (dst, pattern, extents); - if (unlikely (src->base.status)) { - cairo_surface_destroy (&mask->base); - return src->base.status; - } - - _cairo_xcb_connection_render_composite (dst->connection, - _render_operator (op), - src->picture, - mask->picture, - dst->picture, - extents->x + src->x, extents->y + src->y, - 0, 0, - extents->x, extents->y, - extents->width, extents->height); - - cairo_surface_destroy (&src->base); - } else { - _cairo_xcb_connection_render_composite (dst->connection, - _render_operator (op), - mask->picture, - XCB_NONE, - dst->picture, - 0, 0, - 0, 0, - extents->x, extents->y, - extents->width, extents->height); - } - cairo_surface_destroy (&mask->base); - - return CAIRO_STATUS_SUCCESS; -} - -/* Handles compositing with a clip surface when we have to do the operation - * in two pieces and combine them together. - */ -static cairo_status_t -_clip_and_composite_combine (cairo_clip_t *clip, - cairo_operator_t op, - const cairo_pattern_t *pattern, - xcb_draw_func_t draw_func, - void *draw_closure, - cairo_xcb_surface_t *dst, - const cairo_rectangle_int_t*extents) -{ - cairo_xcb_surface_t *tmp; - cairo_xcb_surface_t *clip_surface; - int clip_x = 0, clip_y = 0; - xcb_render_picture_t clip_picture; - cairo_status_t status; - - tmp = (cairo_xcb_surface_t *) - _cairo_xcb_surface_create_similar (dst, dst->base.content, - extents->width, extents->height); - if (unlikely (tmp->base.status)) - return tmp->base.status; - - /* create_similar() could have done a fallback to an image surface */ - assert (tmp->base.backend == &_cairo_xcb_surface_backend); - - _cairo_xcb_surface_ensure_picture (tmp); - - if (pattern == NULL) { - status = (*draw_func) (draw_closure, tmp, - CAIRO_OPERATOR_ADD, NULL, - extents->x, extents->y, - extents, NULL); - } else { - /* Initialize the temporary surface from the destination surface */ - if (! dst->base.is_clear || - (dst->connection->flags & CAIRO_XCB_RENDER_HAS_FILL_RECTANGLES) == 0) - { - /* XCopyArea may actually be quicker here. - * A good driver should translate if appropriate. - */ - _cairo_xcb_connection_render_composite (dst->connection, - XCB_RENDER_PICT_OP_SRC, - dst->picture, - XCB_NONE, - tmp->picture, - extents->x, extents->y, - 0, 0, - 0, 0, - extents->width, extents->height); - } - else - { - xcb_render_color_t clear; - xcb_rectangle_t xrect; - - clear.red = clear.green = clear.blue = clear.alpha = 0; - - xrect.x = xrect.y = 0; - xrect.width = extents->width; - xrect.height = extents->height; - - _cairo_xcb_connection_render_fill_rectangles (dst->connection, - XCB_RENDER_PICT_OP_CLEAR, - dst->picture, - clear, 1, &xrect); - } - - status = (*draw_func) (draw_closure, tmp, op, pattern, - extents->x, extents->y, - extents, NULL); - } - if (unlikely (status)) - goto CLEANUP_SURFACE; - - clip_surface = get_clip_surface (clip, dst, &clip_x, &clip_y); - status = clip_surface->base.status; - if (unlikely (status)) - goto CLEANUP_SURFACE; - - assert (clip_surface->base.backend == &_cairo_xcb_surface_backend); - clip_picture = clip_surface->picture; - assert (clip_picture != XCB_NONE); - - if (dst->base.is_clear) { - _cairo_xcb_connection_render_composite (dst->connection, - XCB_RENDER_PICT_OP_SRC, - tmp->picture, clip_picture, dst->picture, - 0, 0, - 0, 0, - extents->x, extents->y, - extents->width, extents->height); - } else { - /* Punch the clip out of the destination */ - _cairo_xcb_connection_render_composite (dst->connection, - XCB_RENDER_PICT_OP_OUT_REVERSE, - clip_picture, XCB_NONE, dst->picture, - extents->x - clip_x, - extents->y - clip_y, - 0, 0, - extents->x, extents->y, - extents->width, extents->height); - - /* Now add the two results together */ - _cairo_xcb_connection_render_composite (dst->connection, - XCB_RENDER_PICT_OP_ADD, - tmp->picture, clip_picture, dst->picture, - 0, 0, - extents->x - clip_x, - extents->y - clip_y, - extents->x, extents->y, - extents->width, extents->height); - } - cairo_surface_destroy (&clip_surface->base); - - CLEANUP_SURFACE: - cairo_surface_destroy (&tmp->base); - - return status; -} - -/* Handles compositing for %CAIRO_OPERATOR_SOURCE, which is special; it's - * defined as (src IN mask IN clip) ADD (dst OUT (mask IN clip)) - */ -static cairo_status_t -_clip_and_composite_source (cairo_clip_t *clip, - const cairo_pattern_t *pattern, - xcb_draw_func_t draw_func, - xcb_draw_func_t mask_func, - void *draw_closure, - cairo_xcb_surface_t *dst, - const cairo_rectangle_int_t *extents) -{ - cairo_xcb_surface_t *mask; - cairo_xcb_picture_t *src; - - /* Create a surface that is mask IN clip */ - mask = _create_composite_mask (clip, - draw_func, mask_func, draw_closure, - dst, extents); - if (unlikely (mask->base.status)) - return mask->base.status; - - src = _cairo_xcb_picture_for_pattern (dst, pattern, extents); - if (unlikely (src->base.status)) { - cairo_surface_destroy (&mask->base); - return src->base.status; - } - - if (dst->base.is_clear) { - _cairo_xcb_connection_render_composite (dst->connection, - XCB_RENDER_PICT_OP_SRC, - src->picture, - mask->picture, - dst->picture, - extents->x + src->x, extents->y + src->y, - 0, 0, - extents->x, extents->y, - extents->width, extents->height); - } else { - /* Compute dest' = dest OUT (mask IN clip) */ - _cairo_xcb_connection_render_composite (dst->connection, - XCB_RENDER_PICT_OP_OUT_REVERSE, - mask->picture, - XCB_NONE, - dst->picture, - 0, 0, 0, 0, - extents->x, extents->y, - extents->width, extents->height); - - /* Now compute (src IN (mask IN clip)) ADD dest' */ - _cairo_xcb_connection_render_composite (dst->connection, - XCB_RENDER_PICT_OP_ADD, - src->picture, - mask->picture, - dst->picture, - extents->x + src->x, extents->y + src->y, - 0, 0, - extents->x, extents->y, - extents->width, extents->height); - } - - cairo_surface_destroy (&src->base); - cairo_surface_destroy (&mask->base); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_bool_t -can_reduce_alpha_op (cairo_operator_t op) -{ - int iop = op; - switch (iop) { - case CAIRO_OPERATOR_OVER: - case CAIRO_OPERATOR_SOURCE: - case CAIRO_OPERATOR_ADD: - return TRUE; - default: - return FALSE; - } -} - -static cairo_bool_t -reduce_alpha_op (cairo_surface_t *dst, - cairo_operator_t op, - const cairo_pattern_t *pattern) -{ - return dst->is_clear && - dst->content == CAIRO_CONTENT_ALPHA && - _cairo_pattern_is_opaque_solid (pattern) && - can_reduce_alpha_op (op); -} - -static cairo_status_t -_cairo_xcb_surface_fixup_unbounded (cairo_xcb_surface_t *dst, - const cairo_composite_rectangles_t *rects) -{ - xcb_rectangle_t xrects[4]; - int n; - - if (rects->bounded.width == rects->unbounded.width && - rects->bounded.height == rects->unbounded.height) - { - return CAIRO_STATUS_SUCCESS; - } - - n = 0; - if (rects->bounded.width == 0 || rects->bounded.height == 0) { - xrects[n].x = rects->unbounded.x; - xrects[n].width = rects->unbounded.width; - xrects[n].y = rects->unbounded.y; - xrects[n].height = rects->unbounded.height; - n++; - } else { - /* top */ - if (rects->bounded.y != rects->unbounded.y) { - xrects[n].x = rects->unbounded.x; - xrects[n].width = rects->unbounded.width; - xrects[n].y = rects->unbounded.y; - xrects[n].height = rects->bounded.y - rects->unbounded.y; - n++; - } - /* left */ - if (rects->bounded.x != rects->unbounded.x) { - xrects[n].x = rects->unbounded.x; - xrects[n].width = rects->bounded.x - rects->unbounded.x; - xrects[n].y = rects->bounded.y; - xrects[n].height = rects->bounded.height; - n++; - } - /* right */ - if (rects->bounded.x + rects->bounded.width != rects->unbounded.x + rects->unbounded.width) { - xrects[n].x = rects->bounded.x + rects->bounded.width; - xrects[n].width = rects->unbounded.x + rects->unbounded.width - xrects[n].x; - xrects[n].y = rects->bounded.y; - xrects[n].height = rects->bounded.height; - n++; - } - /* bottom */ - if (rects->bounded.y + rects->bounded.height != rects->unbounded.y + rects->unbounded.height) { - xrects[n].x = rects->unbounded.x; - xrects[n].width = rects->unbounded.width; - xrects[n].y = rects->bounded.y + rects->bounded.height; - xrects[n].height = rects->unbounded.y + rects->unbounded.height - xrects[n].y; - n++; - } - } - - if (dst->connection->flags & CAIRO_XCB_RENDER_HAS_FILL_RECTANGLES) { - xcb_render_color_t color; - - color.red = 0; - color.green = 0; - color.blue = 0; - color.alpha = 0; - - _cairo_xcb_connection_render_fill_rectangles (dst->connection, - XCB_RENDER_PICT_OP_CLEAR, - dst->picture, - color, n, xrects); - } else { - int i; - cairo_xcb_picture_t *src; - - src = _cairo_xcb_transparent_picture (dst); - if (unlikely (src->base.status)) - return src->base.status; - - for (i = 0; i < n; i++) { - _cairo_xcb_connection_render_composite (dst->connection, - XCB_RENDER_PICT_OP_CLEAR, - src->picture, XCB_NONE, dst->picture, - 0, 0, - 0, 0, - xrects[i].x, xrects[i].y, - xrects[i].width, xrects[i].height); - } - cairo_surface_destroy (&src->base); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_xcb_surface_fixup_unbounded_with_mask (cairo_xcb_surface_t *dst, - const cairo_composite_rectangles_t *rects, - cairo_clip_t *clip) -{ - cairo_xcb_surface_t *mask; - int mask_x = 0, mask_y = 0; - - mask = get_clip_surface (clip, dst, &mask_x, &mask_y); - if (unlikely (mask->base.status)) - return mask->base.status; - - /* top */ - if (rects->bounded.y != rects->unbounded.y) { - int x = rects->unbounded.x; - int y = rects->unbounded.y; - int width = rects->unbounded.width; - int height = rects->bounded.y - y; - - _cairo_xcb_connection_render_composite (dst->connection, - XCB_RENDER_PICT_OP_OUT_REVERSE, - mask->picture, XCB_NONE, dst->picture, - x - mask_x, y - mask_y, - 0, 0, - x, y, - width, height); - } - - /* left */ - if (rects->bounded.x != rects->unbounded.x) { - int x = rects->unbounded.x; - int y = rects->bounded.y; - int width = rects->bounded.x - x; - int height = rects->bounded.height; - - _cairo_xcb_connection_render_composite (dst->connection, - XCB_RENDER_PICT_OP_OUT_REVERSE, - mask->picture, XCB_NONE, dst->picture, - x - mask_x, y - mask_y, - 0, 0, - x, y, - width, height); - } - - /* right */ - if (rects->bounded.x + rects->bounded.width != rects->unbounded.x + rects->unbounded.width) { - int x = rects->bounded.x + rects->bounded.width; - int y = rects->bounded.y; - int width = rects->unbounded.x + rects->unbounded.width - x; - int height = rects->bounded.height; - - _cairo_xcb_connection_render_composite (dst->connection, - XCB_RENDER_PICT_OP_OUT_REVERSE, - mask->picture, XCB_NONE, dst->picture, - x - mask_x, y - mask_y, - 0, 0, - x, y, - width, height); - } - - /* bottom */ - if (rects->bounded.y + rects->bounded.height != rects->unbounded.y + rects->unbounded.height) { - int x = rects->unbounded.x; - int y = rects->bounded.y + rects->bounded.height; - int width = rects->unbounded.width; - int height = rects->unbounded.y + rects->unbounded.height - y; - - _cairo_xcb_connection_render_composite (dst->connection, - XCB_RENDER_PICT_OP_OUT_REVERSE, - mask->picture, XCB_NONE, dst->picture, - x - mask_x, y - mask_y, - 0, 0, - x, y, - width, height); - } - - cairo_surface_destroy (&mask->base); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_xcb_surface_fixup_unbounded_boxes (cairo_xcb_surface_t *dst, - const cairo_composite_rectangles_t *extents, - cairo_clip_t *clip, - cairo_boxes_t *boxes) -{ - cairo_boxes_t clear; - cairo_box_t box; - cairo_status_t status; - struct _cairo_boxes_chunk *chunk; - int i; - - if (boxes->num_boxes <= 1 && clip == NULL) - return _cairo_xcb_surface_fixup_unbounded (dst, extents); - - _cairo_boxes_init (&clear); - - box.p1.x = _cairo_fixed_from_int (extents->unbounded.x + extents->unbounded.width); - box.p1.y = _cairo_fixed_from_int (extents->unbounded.y); - box.p2.x = _cairo_fixed_from_int (extents->unbounded.x); - box.p2.y = _cairo_fixed_from_int (extents->unbounded.y + extents->unbounded.height); - - if (clip == NULL) { - cairo_boxes_t tmp; - - _cairo_boxes_init (&tmp); - - status = _cairo_boxes_add (&tmp, CAIRO_ANTIALIAS_DEFAULT, &box); - assert (status == CAIRO_STATUS_SUCCESS); - - tmp.chunks.next = &boxes->chunks; - tmp.num_boxes += boxes->num_boxes; - - status = _cairo_bentley_ottmann_tessellate_boxes (&tmp, - CAIRO_FILL_RULE_WINDING, - &clear); - - tmp.chunks.next = NULL; - } else { - _cairo_boxes_init_with_clip (&clear, clip); - - status = _cairo_boxes_add (&clear, CAIRO_ANTIALIAS_DEFAULT, &box); - assert (status == CAIRO_STATUS_SUCCESS); - - for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) { - status = _cairo_boxes_add (&clear, - CAIRO_ANTIALIAS_DEFAULT, - &chunk->base[i]); - if (unlikely (status)) { - _cairo_boxes_fini (&clear); - return status; - } - } - } - - status = _cairo_bentley_ottmann_tessellate_boxes (&clear, - CAIRO_FILL_RULE_WINDING, - &clear); - } - - if (likely (status == CAIRO_STATUS_SUCCESS)) { - if (dst->connection->flags & CAIRO_XCB_RENDER_HAS_FILL_RECTANGLES) - status = _render_fill_boxes (dst, - CAIRO_OPERATOR_CLEAR, - CAIRO_COLOR_TRANSPARENT, - &clear); - else - status = _cairo_xcb_surface_core_fill_boxes (dst, - CAIRO_COLOR_TRANSPARENT, - &clear); - } - - _cairo_boxes_fini (&clear); - - return status; -} - -cairo_status_t -_cairo_xcb_surface_clear (cairo_xcb_surface_t *dst) -{ - xcb_gcontext_t gc; - xcb_rectangle_t rect; - cairo_status_t status; - - status = _cairo_xcb_connection_acquire (dst->connection); - if (unlikely (status)) - return status; - - rect.x = rect.y = 0; - rect.width = dst->width; - rect.height = dst->height; - - if (dst->connection->flags & CAIRO_XCB_RENDER_HAS_FILL_RECTANGLES) { - xcb_render_color_t color; - uint8_t op; - - color.red = dst->deferred_clear_color.red_short; - color.green = dst->deferred_clear_color.green_short; - color.blue = dst->deferred_clear_color.blue_short; - color.alpha = dst->deferred_clear_color.alpha_short; - - if (color.alpha == 0) - op = XCB_RENDER_PICT_OP_CLEAR; - else - op = XCB_RENDER_PICT_OP_SRC; - - _cairo_xcb_surface_ensure_picture (dst); - _cairo_xcb_connection_render_fill_rectangles (dst->connection, - op, dst->picture, color, - 1, &rect); - } else { - gc = _cairo_xcb_screen_get_gc (dst->screen, dst->drawable, dst->depth); - - /* XXX color */ - _cairo_xcb_connection_poly_fill_rectangle (dst->connection, - dst->drawable, gc, - 1, &rect); - - _cairo_xcb_screen_put_gc (dst->screen, dst->depth, gc); - } - - _cairo_xcb_connection_release (dst->connection); - - dst->deferred_clear = FALSE; - return CAIRO_STATUS_SUCCESS; -} - -enum { - NEED_CLIP_REGION = 0x1, - NEED_CLIP_SURFACE = 0x2, - FORCE_CLIP_REGION = 0x4, -}; - -static cairo_bool_t -need_bounded_clip (cairo_composite_rectangles_t *extents) -{ - unsigned int flags = NEED_CLIP_REGION; - if (! _cairo_clip_is_region (extents->clip)) - flags |= NEED_CLIP_SURFACE; - return flags; -} - -static cairo_bool_t -need_unbounded_clip (cairo_composite_rectangles_t *extents) -{ - unsigned int flags = 0; - if (! extents->is_bounded) { - flags |= NEED_CLIP_REGION; - if (! _cairo_clip_is_region (extents->clip)) - flags |= NEED_CLIP_SURFACE; - } - if (extents->clip->path != NULL) - flags |= NEED_CLIP_SURFACE; - return flags; -} - -static cairo_status_t -_clip_and_composite (cairo_xcb_surface_t *dst, - cairo_operator_t op, - const cairo_pattern_t *src, - xcb_draw_func_t draw_func, - xcb_draw_func_t mask_func, - void *draw_closure, - cairo_composite_rectangles_t*extents, - unsigned int need_clip) -{ - cairo_region_t *clip_region = NULL; - cairo_status_t status; - - status = _cairo_xcb_connection_acquire (dst->connection); - if (unlikely (status)) - return status; - - if (dst->deferred_clear) { - status = _cairo_xcb_surface_clear (dst); - if (unlikely (status)) { - _cairo_xcb_connection_release (dst->connection); - return status; - } - } - - _cairo_xcb_surface_ensure_picture (dst); - - if (need_clip & NEED_CLIP_REGION) { - clip_region = _cairo_clip_get_region (extents->clip); - if ((need_clip & FORCE_CLIP_REGION) == 0 && clip_region != NULL && - cairo_region_contains_rectangle (clip_region, - &extents->unbounded) == CAIRO_REGION_OVERLAP_IN) - clip_region = NULL; - if (clip_region != NULL) { - status = _cairo_xcb_surface_set_clip_region (dst, clip_region); - if (unlikely (status)) { - _cairo_xcb_connection_release (dst->connection); - return status; - } - } - } - - if (reduce_alpha_op (&dst->base, op, src)) { - op = CAIRO_OPERATOR_ADD; - src = NULL; - } - - if (extents->bounded.width != 0 && extents->bounded.height != 0) { - if (op == CAIRO_OPERATOR_SOURCE) { - status = _clip_and_composite_source (extents->clip, src, - draw_func, mask_func, draw_closure, - dst, &extents->bounded); - } else { - if (op == CAIRO_OPERATOR_CLEAR) { - op = CAIRO_OPERATOR_DEST_OUT; - src = NULL; - } - - if (need_clip & NEED_CLIP_SURFACE) { - if (extents->is_bounded) { - status = _clip_and_composite_with_mask (extents->clip, op, src, - draw_func, - mask_func, - draw_closure, - dst, &extents->bounded); - } else { - status = _clip_and_composite_combine (extents->clip, op, src, - draw_func, draw_closure, - dst, &extents->bounded); - } - } else { - status = draw_func (draw_closure, - dst, op, src, - 0, 0, - &extents->bounded, - extents->clip); - } - } - } - - if (status == CAIRO_STATUS_SUCCESS && ! extents->is_bounded) { - if (need_clip & NEED_CLIP_SURFACE) - status = _cairo_xcb_surface_fixup_unbounded_with_mask (dst, extents, extents->clip); - else - status = _cairo_xcb_surface_fixup_unbounded (dst, extents); - } - - if (clip_region) - _cairo_xcb_surface_clear_clip_region (dst); - - _cairo_xcb_connection_release (dst->connection); - - return status; -} - -static cairo_status_t -_core_boxes (cairo_xcb_surface_t *dst, - cairo_operator_t op, - const cairo_pattern_t *src, - cairo_boxes_t *boxes, - const cairo_composite_rectangles_t *extents) -{ - if (! boxes->is_pixel_aligned) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (! _cairo_clip_is_region (extents->clip)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (op == CAIRO_OPERATOR_CLEAR) - return _cairo_xcb_surface_core_fill_boxes (dst, CAIRO_COLOR_TRANSPARENT, boxes); - - if (op == CAIRO_OPERATOR_OVER) { - if (dst->base.is_clear || _cairo_pattern_is_opaque (src, &extents->bounded)) - op = CAIRO_OPERATOR_SOURCE; - } - if (op != CAIRO_OPERATOR_SOURCE) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (src->type == CAIRO_PATTERN_TYPE_SOLID) { - return _cairo_xcb_surface_core_fill_boxes (dst, - &((cairo_solid_pattern_t *) src)->color, - boxes); - } - - return _cairo_xcb_surface_core_copy_boxes (dst, src, &extents->bounded, boxes); -} - -static cairo_status_t -_composite_boxes (cairo_xcb_surface_t *dst, - cairo_operator_t op, - const cairo_pattern_t *src, - cairo_boxes_t *boxes, - const cairo_composite_rectangles_t *extents) -{ - cairo_clip_t *clip = extents->clip; - cairo_bool_t need_clip_mask = ! _cairo_clip_is_region (clip); - cairo_status_t status; - - /* If the boxes are not pixel-aligned, we will need to compute a real mask */ - if (! boxes->is_pixel_aligned) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (need_clip_mask && - (! extents->is_bounded || op == CAIRO_OPERATOR_SOURCE)) - { - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - status = _cairo_xcb_connection_acquire (dst->connection); - if (unlikely (status)) - return status; - - _cairo_xcb_surface_ensure_picture (dst); - if (dst->connection->flags & CAIRO_XCB_RENDER_HAS_FILL_RECTANGLES && ! need_clip_mask && - (op == CAIRO_OPERATOR_CLEAR || src->type == CAIRO_PATTERN_TYPE_SOLID)) - { - const cairo_color_t *color; - - if (op == CAIRO_OPERATOR_CLEAR) - color = CAIRO_COLOR_TRANSPARENT; - else - color = &((cairo_solid_pattern_t *) src)->color; - - status = _render_fill_boxes (dst, op, color, boxes); - } - else - { - cairo_surface_pattern_t mask; - - if (need_clip_mask) { - cairo_xcb_surface_t *clip_surface; - int clip_x = 0, clip_y = 0; - - clip_surface = get_clip_surface (extents->clip, dst, - &clip_x, &clip_y); - if (unlikely (clip_surface->base.status)) - return clip_surface->base.status; - - _cairo_pattern_init_for_surface (&mask, &clip_surface->base); - mask.base.filter = CAIRO_FILTER_NEAREST; - cairo_matrix_init_translate (&mask.base.matrix, - -clip_x, - -clip_y); - cairo_surface_destroy (&clip_surface->base); - - if (op == CAIRO_OPERATOR_CLEAR) { - src = NULL; - op = CAIRO_OPERATOR_DEST_OUT; - } - } - - status = _render_composite_boxes (dst, op, src, - need_clip_mask ? &mask.base : NULL, - &extents->bounded, boxes); - - if (need_clip_mask) - _cairo_pattern_fini (&mask.base); - } - - if (status == CAIRO_STATUS_SUCCESS && ! extents->is_bounded) { - status = - _cairo_xcb_surface_fixup_unbounded_boxes (dst, extents, - clip, boxes); - } - - _cairo_xcb_connection_release (dst->connection); - - return status; -} - -static cairo_bool_t -cairo_boxes_for_each_box (cairo_boxes_t *boxes, - cairo_bool_t (*func) (cairo_box_t *box, - void *data), - void *data) -{ - struct _cairo_boxes_chunk *chunk; - int i; - - for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) - if (! func (&chunk->base[i], data)) - return FALSE; - } - - return TRUE; -} - -struct _image_contains_box { - int width, height; - int tx, ty; -}; - -static cairo_bool_t image_contains_box (cairo_box_t *box, void *closure) -{ - struct _image_contains_box *data = closure; - - /* The box is pixel-aligned so the truncation is safe. */ - return - _cairo_fixed_integer_part (box->p1.x) + data->tx >= 0 && - _cairo_fixed_integer_part (box->p1.y) + data->ty >= 0 && - _cairo_fixed_integer_part (box->p2.x) + data->tx <= data->width && - _cairo_fixed_integer_part (box->p2.y) + data->ty <= data->height; -} - -struct _image_upload_box { - cairo_xcb_surface_t *surface; - cairo_image_surface_t *image; - xcb_gcontext_t gc; - int tx, ty; -}; - -static cairo_bool_t image_upload_box (cairo_box_t *box, void *closure) -{ - const struct _image_upload_box *iub = closure; - /* The box is pixel-aligned so the truncation is safe. */ - int x = _cairo_fixed_integer_part (box->p1.x); - int y = _cairo_fixed_integer_part (box->p1.y); - int width = _cairo_fixed_integer_part (box->p2.x - box->p1.x); - int height = _cairo_fixed_integer_part (box->p2.y - box->p1.y); - int bpp = PIXMAN_FORMAT_BPP (iub->image->pixman_format); - int len = CAIRO_STRIDE_FOR_WIDTH_BPP (width, bpp); - if (len == iub->image->stride) { - _cairo_xcb_connection_put_image (iub->surface->connection, - iub->surface->drawable, - iub->gc, - width, height, - x, y, - iub->image->depth, - iub->image->stride, - iub->image->data + - (y + iub->ty) * iub->image->stride + - (x + iub->tx) * bpp/8); - } else { - _cairo_xcb_connection_put_subimage (iub->surface->connection, - iub->surface->drawable, - iub->gc, - x + iub->tx, - y + iub->ty, - width, height, - bpp / 8, - iub->image->stride, - x, y, - iub->image->depth, - iub->image->data); - } - - return TRUE; -} - -static cairo_status_t -_upload_image_inplace (cairo_xcb_surface_t *surface, - const cairo_pattern_t *source, - cairo_boxes_t *boxes) -{ - const cairo_surface_pattern_t *pattern; - struct _image_contains_box icb; - struct _image_upload_box iub; - cairo_image_surface_t *image; - cairo_status_t status; - int tx, ty; - - if (! boxes->is_pixel_aligned) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (source->type != CAIRO_PATTERN_TYPE_SURFACE) - return CAIRO_INT_STATUS_UNSUPPORTED; - - pattern = (const cairo_surface_pattern_t *) source; - if (! _cairo_surface_is_image (pattern->surface)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* Have we already upload this image to a pixmap? */ - { - cairo_xcb_picture_t *snapshot; - - snapshot = (cairo_xcb_picture_t *) - _cairo_surface_has_snapshot (pattern->surface, &_cairo_xcb_picture_backend); - if (snapshot != NULL) { - if (snapshot->screen == surface->screen) - return CAIRO_INT_STATUS_UNSUPPORTED; - } - } - - image = (cairo_image_surface_t *) pattern->surface; - if (image->format == CAIRO_FORMAT_INVALID) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (image->depth != surface->depth) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (! _cairo_matrix_is_integer_translation (&source->matrix, &tx, &ty)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* Check that the data is entirely within the image */ - icb.width = image->width; - icb.height = image->height; - icb.tx = tx; - icb.ty = ty; - if (! cairo_boxes_for_each_box (boxes, image_contains_box, &icb)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (surface->deferred_clear) { - status = _cairo_xcb_surface_clear (surface); - if (unlikely (status)) - return status; - } - - status = _cairo_xcb_connection_acquire (surface->connection); - if (unlikely (status)) - return status; - - iub.surface = surface; - iub.image = image; - iub.gc = _cairo_xcb_screen_get_gc (surface->screen, - surface->drawable, - image->depth); - iub.tx = tx; - iub.ty = ty; - cairo_boxes_for_each_box (boxes, image_upload_box, &iub); - - _cairo_xcb_screen_put_gc (surface->screen, image->depth, iub.gc); - _cairo_xcb_connection_release (surface->connection); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -trim_extents_to_traps (cairo_composite_rectangles_t *extents, - cairo_traps_t *traps) -{ - cairo_box_t box; - - /* X trims the affected area to the extents of the trapezoids, so - * we need to compensate when fixing up the unbounded area. - */ - _cairo_traps_extents (traps, &box); - return _cairo_composite_rectangles_intersect_mask_extents (extents, &box); -} - -static cairo_bool_t -_mono_edge_is_vertical (const cairo_line_t *line) -{ - return _cairo_fixed_integer_round_down (line->p1.x) == _cairo_fixed_integer_round_down (line->p2.x); -} - -static cairo_bool_t -_traps_are_pixel_aligned (cairo_traps_t *traps, - cairo_antialias_t antialias) -{ - int i; - - if (antialias == CAIRO_ANTIALIAS_NONE) { - for (i = 0; i < traps->num_traps; i++) { - if (! _mono_edge_is_vertical (&traps->traps[i].left) || - ! _mono_edge_is_vertical (&traps->traps[i].right)) - { - traps->maybe_region = FALSE; - return FALSE; - } - } - } else { - for (i = 0; i < traps->num_traps; i++) { - if (traps->traps[i].left.p1.x != traps->traps[i].left.p2.x || - traps->traps[i].right.p1.x != traps->traps[i].right.p2.x || - ! _cairo_fixed_is_integer (traps->traps[i].top) || - ! _cairo_fixed_is_integer (traps->traps[i].bottom) || - ! _cairo_fixed_is_integer (traps->traps[i].left.p1.x) || - ! _cairo_fixed_is_integer (traps->traps[i].right.p1.x)) - { - traps->maybe_region = FALSE; - return FALSE; - } - } - } - - return TRUE; -} - -static void -_boxes_for_traps (cairo_boxes_t *boxes, - cairo_traps_t *traps, - cairo_antialias_t antialias) -{ - int i, j; - - _cairo_boxes_init (boxes); - - boxes->chunks.base = (cairo_box_t *) traps->traps; - boxes->chunks.size = traps->num_traps; - - if (antialias != CAIRO_ANTIALIAS_NONE) { - for (i = j = 0; i < traps->num_traps; i++) { - /* Note the traps and boxes alias so we need to take the local copies first. */ - cairo_fixed_t x1 = traps->traps[i].left.p1.x; - cairo_fixed_t x2 = traps->traps[i].right.p1.x; - cairo_fixed_t y1 = traps->traps[i].top; - cairo_fixed_t y2 = traps->traps[i].bottom; - - if (x1 == x2 || y1 == y2) - continue; - - boxes->chunks.base[j].p1.x = x1; - boxes->chunks.base[j].p1.y = y1; - boxes->chunks.base[j].p2.x = x2; - boxes->chunks.base[j].p2.y = y2; - j++; - - if (boxes->is_pixel_aligned) { - boxes->is_pixel_aligned = - _cairo_fixed_is_integer (x1) && _cairo_fixed_is_integer (y1) && - _cairo_fixed_is_integer (x2) && _cairo_fixed_is_integer (y2); - } - } - } else { - boxes->is_pixel_aligned = TRUE; - - for (i = j = 0; i < traps->num_traps; i++) { - /* Note the traps and boxes alias so we need to take the local copies first. */ - cairo_fixed_t x1 = traps->traps[i].left.p1.x; - cairo_fixed_t x2 = traps->traps[i].right.p1.x; - cairo_fixed_t y1 = traps->traps[i].top; - cairo_fixed_t y2 = traps->traps[i].bottom; - - /* round down here to match Pixman's behavior when using traps. */ - boxes->chunks.base[j].p1.x = _cairo_fixed_round_down (x1); - boxes->chunks.base[j].p1.y = _cairo_fixed_round_down (y1); - boxes->chunks.base[j].p2.x = _cairo_fixed_round_down (x2); - boxes->chunks.base[j].p2.y = _cairo_fixed_round_down (y2); - - j += (boxes->chunks.base[j].p1.x != boxes->chunks.base[j].p2.x && - boxes->chunks.base[j].p1.y != boxes->chunks.base[j].p2.y); - } - } - - boxes->num_boxes = j; - boxes->chunks.count = j; -} - -static cairo_status_t -_composite_polygon (cairo_xcb_surface_t *dst, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_polygon_t *polygon, - cairo_antialias_t antialias, - cairo_fill_rule_t fill_rule, - cairo_composite_rectangles_t *extents) -{ - composite_traps_info_t traps; - cairo_bool_t clip_surface = ! _cairo_clip_is_region (extents->clip); - cairo_region_t *clip_region = _cairo_clip_get_region (extents->clip); - cairo_status_t status; - - if (polygon->num_edges == 0) { - status = CAIRO_STATUS_SUCCESS; - - if (! extents->is_bounded) { - if (cairo_region_contains_rectangle (clip_region, &extents->unbounded) == CAIRO_REGION_OVERLAP_IN) - clip_region = NULL; - - if (clip_surface == FALSE) { - if (clip_region != NULL) { - status = _cairo_xcb_surface_set_clip_region (dst, clip_region); - if (unlikely (status)) - return status; - } - - status = _cairo_xcb_surface_fixup_unbounded (dst, extents); - - if (clip_region != NULL) - _cairo_xcb_surface_clear_clip_region (dst); - } else { - status = _cairo_xcb_surface_fixup_unbounded_with_mask (dst, - extents, - extents->clip); - } - } - - return status; - } - - if (extents->clip->path != NULL && extents->is_bounded) { - cairo_polygon_t clipper; - cairo_fill_rule_t clipper_fill_rule; - cairo_antialias_t clipper_antialias; - - status = _cairo_clip_get_polygon (extents->clip, - &clipper, - &clipper_fill_rule, - &clipper_antialias); - if (likely (status == CAIRO_STATUS_SUCCESS)) { - if (clipper_antialias == antialias) { - status = _cairo_polygon_intersect (polygon, fill_rule, - &clipper, clipper_fill_rule); - if (likely (status == CAIRO_STATUS_SUCCESS)) { - cairo_clip_t * clip = _cairo_clip_copy_region (extents->clip); - _cairo_clip_destroy (extents->clip); - extents->clip = clip; - - fill_rule = CAIRO_FILL_RULE_WINDING; - } - _cairo_polygon_fini (&clipper); - } - } - } - - _cairo_traps_init (&traps.traps); - - status = _cairo_bentley_ottmann_tessellate_polygon (&traps.traps, polygon, fill_rule); - if (unlikely (status)) - goto CLEANUP_TRAPS; - - if (traps.traps.has_intersections) { - if (traps.traps.is_rectangular) - status = _cairo_bentley_ottmann_tessellate_rectangular_traps (&traps.traps, CAIRO_FILL_RULE_WINDING); - else if (traps.traps.is_rectilinear) - status = _cairo_bentley_ottmann_tessellate_rectilinear_traps (&traps.traps, CAIRO_FILL_RULE_WINDING); - else - status = _cairo_bentley_ottmann_tessellate_traps (&traps.traps, CAIRO_FILL_RULE_WINDING); - if (unlikely (status)) - goto CLEANUP_TRAPS; - } - - /* Use a fast path if the trapezoids consist of a simple region, - * but we can only do this if we do not have a clip surface, or can - * substitute the mask with the clip. - */ - if (traps.traps.maybe_region && - _traps_are_pixel_aligned (&traps.traps, antialias) && - (! clip_surface || - (extents->is_bounded && op != CAIRO_OPERATOR_SOURCE))) - { - cairo_boxes_t boxes; - - _boxes_for_traps (&boxes, &traps.traps, antialias); - status = _clip_and_composite_boxes (dst, op, source, &boxes, extents); - } - else - { - /* Otherwise render the trapezoids to a mask and composite in the usual - * fashion. - */ - traps.antialias = antialias; - status = trim_extents_to_traps (extents, &traps.traps); - if (likely (status == CAIRO_STATUS_SUCCESS)) { - unsigned int flags = 0; - - /* For unbounded operations, the X11 server will estimate the - * affected rectangle and apply the operation to that. However, - * there are cases where this is an overestimate (e.g. the - * clip-fill-{eo,nz}-unbounded test). - * - * The clip will trim that overestimate to our expectations. - */ - if (! extents->is_bounded) - flags |= FORCE_CLIP_REGION; - - status = _clip_and_composite (dst, op, source, _composite_traps, - NULL, &traps, extents, - need_unbounded_clip (extents) | flags); - } - } - -CLEANUP_TRAPS: - _cairo_traps_fini (&traps.traps); - - return status; -} - -static cairo_status_t -_clip_and_composite_boxes (cairo_xcb_surface_t *dst, - cairo_operator_t op, - const cairo_pattern_t *src, - cairo_boxes_t *boxes, - cairo_composite_rectangles_t *extents) -{ - composite_traps_info_t info; - cairo_int_status_t status; - - if (boxes->num_boxes == 0 && extents->is_bounded) - return CAIRO_STATUS_SUCCESS; - - if (boxes->is_pixel_aligned && _cairo_clip_is_region (extents->clip) && - (op == CAIRO_OPERATOR_SOURCE || - (dst->base.is_clear && (op == CAIRO_OPERATOR_OVER || op == CAIRO_OPERATOR_ADD)))) - { - if (boxes->num_boxes == 1 && - extents->bounded.width == dst->width && - extents->bounded.height == dst->height) - { - op = CAIRO_OPERATOR_SOURCE; - dst->deferred_clear = FALSE; - } - - status = _upload_image_inplace (dst, src, boxes); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - } - - /* Can we reduce drawing through a clip-mask to simply drawing the clip? */ - if (dst->connection->flags & CAIRO_XCB_RENDER_HAS_COMPOSITE_TRAPEZOIDS && - extents->clip->path != NULL && extents->is_bounded) { - cairo_polygon_t polygon; - cairo_fill_rule_t fill_rule; - cairo_antialias_t antialias; - cairo_clip_t *clip; - - clip = _cairo_clip_copy (extents->clip); - clip = _cairo_clip_intersect_boxes (clip, boxes); - if (_cairo_clip_is_all_clipped (clip)) - return CAIRO_INT_STATUS_NOTHING_TO_DO; - - status = _cairo_clip_get_polygon (clip, &polygon, - &fill_rule, &antialias); - _cairo_clip_path_destroy (clip->path); - clip->path = NULL; - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) { - cairo_clip_t *saved_clip = extents->clip; - extents->clip = clip; - status = _composite_polygon (dst, op, src, - &polygon, - antialias, - fill_rule, - extents); - if (extents->clip != clip) - clip = NULL; - extents->clip = saved_clip; - _cairo_polygon_fini (&polygon); - } - if (clip) - _cairo_clip_destroy (clip); - - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - } - - if (dst->deferred_clear) { - status = _cairo_xcb_surface_clear (dst); - if (unlikely (status)) - return status; - } - - if (boxes->is_pixel_aligned && - _cairo_clip_is_region (extents->clip) && - op == CAIRO_OPERATOR_SOURCE) { - status = _upload_image_inplace (dst, src, boxes); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - } - - if ((dst->connection->flags & CAIRO_XCB_RENDER_HAS_COMPOSITE) == 0) - return _core_boxes (dst, op, src, boxes, extents); - - /* Use a fast path if the boxes are pixel aligned */ - status = _composite_boxes (dst, op, src, boxes, extents); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - return status; - - if ((dst->connection->flags & CAIRO_XCB_RENDER_HAS_COMPOSITE_TRAPEZOIDS) == 0) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* Otherwise render via a mask and composite in the usual fashion. */ - status = _cairo_traps_init_boxes (&info.traps, boxes); - if (unlikely (status)) - return status; - - info.antialias = CAIRO_ANTIALIAS_DEFAULT; - status = trim_extents_to_traps (extents, &info.traps); - if (status == CAIRO_INT_STATUS_SUCCESS) { - status = _clip_and_composite (dst, op, src, - _composite_traps, NULL, &info, - extents, need_unbounded_clip (extents)); - } - - _cairo_traps_fini (&info.traps); - return status; -} - -static cairo_int_status_t -_composite_mask (void *closure, - cairo_xcb_surface_t *dst, - cairo_operator_t op, - const cairo_pattern_t *src_pattern, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents, - cairo_clip_t *clip) -{ - const cairo_pattern_t *mask_pattern = closure; - cairo_xcb_picture_t *src, *mask = NULL; - cairo_status_t status; - - if (dst->base.is_clear) { - if (op == CAIRO_OPERATOR_OVER || op == CAIRO_OPERATOR_ADD) - op = CAIRO_OPERATOR_SOURCE; - } - - if (op == CAIRO_OPERATOR_SOURCE && clip == NULL) - dst->deferred_clear = FALSE; - - if (dst->deferred_clear) { - status = _cairo_xcb_surface_clear (dst); - if (unlikely (status)) - return status; - } - - if (src_pattern != NULL) { - src = _cairo_xcb_picture_for_pattern (dst, src_pattern, extents); - if (unlikely (src->base.status)) - return src->base.status; - - mask = _cairo_xcb_picture_for_pattern (dst, mask_pattern, extents); - if (unlikely (mask->base.status)) { - cairo_surface_destroy (&src->base); - return mask->base.status; - } - - _cairo_xcb_connection_render_composite (dst->connection, - _render_operator (op), - src->picture, - mask->picture, - dst->picture, - extents->x + src->x, extents->y + src->y, - extents->x + mask->x, extents->y + mask->y, - extents->x - dst_x, extents->y - dst_y, - extents->width, extents->height); - cairo_surface_destroy (&mask->base); - cairo_surface_destroy (&src->base); - } else { - src = _cairo_xcb_picture_for_pattern (dst, mask_pattern, extents); - if (unlikely (src->base.status)) - return src->base.status; - - _cairo_xcb_connection_render_composite (dst->connection, - _render_operator (op), - src->picture, - XCB_NONE, - dst->picture, - extents->x + src->x, extents->y + src->y, - 0, 0, - extents->x - dst_x, extents->y - dst_y, - extents->width, extents->height); - cairo_surface_destroy (&src->base); - } - - return CAIRO_STATUS_SUCCESS; -} - -struct composite_box_info { - cairo_xcb_surface_t *dst; - cairo_xcb_picture_t *src; - uint8_t op; -}; - -static void composite_box(void *closure, - int16_t x, int16_t y, - int16_t w, int16_t h, - uint16_t coverage) -{ - struct composite_box_info *info = closure; - - if (coverage < 0xff00) { - cairo_xcb_picture_t *mask; - cairo_color_t color; - - color.red_short = color.green_short = color.blue_short = 0; - color.alpha_short = coverage; - - mask = _solid_picture (info->dst, &color); - if (likely (mask->base.status == CAIRO_STATUS_SUCCESS)) { - _cairo_xcb_connection_render_composite (info->dst->connection, - info->op, - info->src->picture, - mask->picture, - info->dst->picture, - x + info->src->x, y + info->src->y, - 0, 0, - x, y, - w, h); - } - cairo_surface_destroy (&mask->base); - } else { - _cairo_xcb_connection_render_composite (info->dst->connection, - info->op, - info->src->picture, - XCB_NONE, - info->dst->picture, - x + info->src->x, y + info->src->y, - 0, 0, - x, y, - w, h); - } -} - -static cairo_int_status_t -_composite_mask_clip_boxes (void *closure, - cairo_xcb_surface_t *dst, - cairo_operator_t op, - const cairo_pattern_t *src_pattern, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents, - cairo_clip_t *clip) -{ - struct composite_box_info info; - cairo_status_t status; - int i; - - assert (src_pattern == NULL); - assert (op == CAIRO_OPERATOR_ADD); - assert (dst->base.is_clear); - - if (clip->num_boxes > 1) { - status = _cairo_xcb_surface_clear (dst); - if (unlikely (status)) - return status; - } - - info.op = XCB_RENDER_PICT_OP_SRC; - info.dst = dst; - info.src = _cairo_xcb_picture_for_pattern (dst, closure, extents); - if (unlikely (info.src->base.status)) - return info.src->base.status; - - info.src->x += dst_x; - info.src->y += dst_y; - - for (i = 0; i < clip->num_boxes; i++) - do_unaligned_box(composite_box, &info, &clip->boxes[i], dst_x, dst_y); - cairo_surface_destroy (&info.src->base); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_composite_mask_clip (void *closure, - cairo_xcb_surface_t *dst, - cairo_operator_t op, - const cairo_pattern_t *src_pattern, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents, - cairo_clip_t *clip) -{ - const cairo_pattern_t *mask_pattern = closure; - cairo_polygon_t polygon; - cairo_fill_rule_t fill_rule; - composite_traps_info_t info; - cairo_status_t status; - - assert (src_pattern == NULL); - assert (op == CAIRO_OPERATOR_ADD); - assert (dst->base.is_clear); - - status = _cairo_clip_get_polygon (clip, &polygon, - &fill_rule, &info.antialias); - if (unlikely (status)) - return status; - - _cairo_traps_init (&info.traps); - status = _cairo_bentley_ottmann_tessellate_polygon (&info.traps, - &polygon, - fill_rule); - _cairo_polygon_fini (&polygon); - if (unlikely (status)) - return status; - - if (info.traps.has_intersections) { - if (info.traps.is_rectangular) - status = _cairo_bentley_ottmann_tessellate_rectangular_traps (&info.traps, CAIRO_FILL_RULE_WINDING); - else if (info.traps.is_rectilinear) - status = _cairo_bentley_ottmann_tessellate_rectilinear_traps (&info.traps, CAIRO_FILL_RULE_WINDING); - else - status = _cairo_bentley_ottmann_tessellate_traps (&info.traps, CAIRO_FILL_RULE_WINDING); - if (unlikely (status)) { - _cairo_traps_fini (&info.traps); - return status; - } - } - - status = _composite_traps (&info, - dst, CAIRO_OPERATOR_SOURCE, mask_pattern, - dst_x, dst_y, - extents, NULL); - _cairo_traps_fini (&info.traps); - - return status; -} - -struct composite_opacity_info { - uint8_t op; - cairo_xcb_surface_t *dst; - cairo_xcb_picture_t *src; - double opacity; -}; - -static void composite_opacity(void *closure, - int16_t x, int16_t y, - int16_t w, int16_t h, - uint16_t coverage) -{ - struct composite_opacity_info *info = closure; - cairo_xcb_picture_t *mask; - cairo_color_t color; - - color.red_short = color.green_short = color.blue_short = 0; - color.alpha_short = info->opacity * coverage; - - mask = _solid_picture (info->dst, &color); - if (likely (mask->base.status == CAIRO_STATUS_SUCCESS)) { - if (info->src) { - _cairo_xcb_connection_render_composite (info->dst->connection, - info->op, - info->src->picture, - mask->picture, - info->dst->picture, - x + info->src->x, y + info->src->y, - 0, 0, - x, y, - w, h); - } else { - _cairo_xcb_connection_render_composite (info->dst->connection, - info->op, - mask->picture, - XCB_NONE, - info->dst->picture, - 0, 0, - 0, 0, - x, y, - w, h); - } - } - - cairo_surface_destroy (&mask->base); -} - -static cairo_int_status_t -_composite_opacity_boxes (void *closure, - cairo_xcb_surface_t *dst, - cairo_operator_t op, - const cairo_pattern_t *src_pattern, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents, - cairo_clip_t *clip) -{ - const cairo_solid_pattern_t *mask_pattern = closure; - struct composite_opacity_info info; - cairo_status_t status; - int i; - - if (dst->base.is_clear) { - if (op == CAIRO_OPERATOR_OVER || op == CAIRO_OPERATOR_ADD) - op = CAIRO_OPERATOR_SOURCE; - } - - if (op == CAIRO_OPERATOR_SOURCE && - (clip == NULL || - (clip->extents.width >= extents->width && - clip->extents.height >= extents->height))) - dst->deferred_clear = FALSE; - - if (dst->deferred_clear) { - status = _cairo_xcb_surface_clear (dst); - if (unlikely (status)) - return status; - } - - info.op = _render_operator (op); - info.dst = dst; - - if (src_pattern != NULL) { - info.src = _cairo_xcb_picture_for_pattern (dst, src_pattern, extents); - if (unlikely (info.src->base.status)) - return info.src->base.status; - } else - info.src = NULL; - - info.opacity = mask_pattern->color.alpha; - - /* XXX for lots of boxes create a clip region for the fully opaque areas */ - if (clip) { - for (i = 0; i < clip->num_boxes; i++) - do_unaligned_box(composite_opacity, &info, - &clip->boxes[i], dst_x, dst_y); - } else { - composite_opacity(&info, - extents->x - dst_x, - extents->y - dst_y, - extents->width, - extents->height, - 0xffff); - } - cairo_surface_destroy (&info.src->base); - - return CAIRO_STATUS_SUCCESS; -} - -/* high level rasteriser -> compositor */ - -cairo_int_status_t -_cairo_xcb_render_compositor_paint (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *composite) -{ - cairo_xcb_surface_t *surface = (cairo_xcb_surface_t *) composite->surface; - cairo_operator_t op = composite->op; - cairo_pattern_t *source = &composite->source_pattern.base; - cairo_boxes_t boxes; - cairo_status_t status; - - if (unlikely (! _operator_is_supported (surface->connection->flags, op))) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if ((surface->connection->flags & (CAIRO_XCB_RENDER_HAS_COMPOSITE_TRAPEZOIDS | - CAIRO_XCB_RENDER_HAS_COMPOSITE)) == 0) - { - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - if (composite->clip == NULL && - source->type == CAIRO_PATTERN_TYPE_SOLID && - (op == CAIRO_OPERATOR_SOURCE || - op == CAIRO_OPERATOR_CLEAR || - (surface->base.is_clear && - (op == CAIRO_OPERATOR_ADD || op == CAIRO_OPERATOR_OVER)))) - { - surface->deferred_clear = TRUE; - surface->deferred_clear_color = composite->source_pattern.solid.color; - return CAIRO_STATUS_SUCCESS; - } - - _cairo_clip_steal_boxes(composite->clip, &boxes); - status = _clip_and_composite_boxes (surface, op, source, &boxes, composite); - _cairo_clip_unsteal_boxes (composite->clip, &boxes); - - return status; -} - -cairo_int_status_t -_cairo_xcb_render_compositor_mask (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *composite) -{ - cairo_xcb_surface_t *surface = (cairo_xcb_surface_t *) composite->surface; - cairo_operator_t op = composite->op; - cairo_pattern_t *source = &composite->source_pattern.base; - cairo_pattern_t *mask = &composite->mask_pattern.base; - cairo_status_t status; - - if (unlikely (! _operator_is_supported (surface->connection->flags, op))) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if ((surface->connection->flags & CAIRO_XCB_RENDER_HAS_COMPOSITE) == 0) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (mask->type == CAIRO_PATTERN_TYPE_SOLID && - composite->clip->path == NULL && - ! _cairo_clip_is_region (composite->clip)) { - status = _clip_and_composite (surface, op, source, - _composite_opacity_boxes, - _composite_opacity_boxes, - (void *) mask, - composite, need_unbounded_clip (composite)); - } else { - xcb_draw_func_t mask_func = NULL; - if (surface->connection->flags & CAIRO_XCB_RENDER_HAS_COMPOSITE_TRAPEZOIDS) - mask_func = composite->clip->path ? _composite_mask_clip : _composite_mask_clip_boxes; - status = _clip_and_composite (surface, op, source, - _composite_mask, mask_func, - (void *) mask, - composite, need_bounded_clip (composite)); - } - - return status; -} - -static cairo_int_status_t -_cairo_xcb_surface_render_stroke_as_polygon (cairo_xcb_surface_t *dst, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - cairo_composite_rectangles_t *extents) -{ - cairo_polygon_t polygon; - cairo_status_t status; - - _cairo_polygon_init_with_clip (&polygon, extents->clip); - status = _cairo_path_fixed_stroke_to_polygon (path, - stroke_style, - ctm, ctm_inverse, - tolerance, - &polygon); - if (likely (status == CAIRO_STATUS_SUCCESS)) { - status = _composite_polygon (dst, op, source, - &polygon, antialias, - CAIRO_FILL_RULE_WINDING, - extents); - } - _cairo_polygon_fini (&polygon); - - return status; -} - -static cairo_status_t -_cairo_xcb_surface_render_stroke_via_mask (cairo_xcb_surface_t *dst, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - cairo_composite_rectangles_t *extents) -{ - cairo_surface_t *image; - cairo_status_t status; - cairo_clip_t *clip; - int x, y; - - x = extents->bounded.x; - y = extents->bounded.y; - image = _cairo_xcb_surface_create_similar_image (dst, CAIRO_FORMAT_A8, - extents->bounded.width, - extents->bounded.height); - if (unlikely (image->status)) - return image->status; - - clip = _cairo_clip_copy_region (extents->clip); - status = _cairo_surface_offset_stroke (image, x, y, - CAIRO_OPERATOR_ADD, - &_cairo_pattern_white.base, - path, stroke_style, - ctm, ctm_inverse, - tolerance, antialias, - clip); - _cairo_clip_destroy (clip); - if (likely (status == CAIRO_STATUS_SUCCESS)) { - cairo_surface_pattern_t mask; - - _cairo_pattern_init_for_surface (&mask, image); - mask.base.filter = CAIRO_FILTER_NEAREST; - - cairo_matrix_init_translate (&mask.base.matrix, -x, -y); - status = _clip_and_composite (dst, op, source, - _composite_mask, NULL, &mask.base, - extents, need_bounded_clip (extents)); - _cairo_pattern_fini (&mask.base); - } - - cairo_surface_finish (image); - cairo_surface_destroy (image); - - return status; -} - -cairo_int_status_t -_cairo_xcb_render_compositor_stroke (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *composite, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_xcb_surface_t *surface = (cairo_xcb_surface_t *) composite->surface; - cairo_operator_t op = composite->op; - cairo_pattern_t *source = &composite->source_pattern.base; - cairo_int_status_t status; - - if (unlikely (! _operator_is_supported (surface->connection->flags, op))) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if ((surface->connection->flags & (CAIRO_XCB_RENDER_HAS_COMPOSITE_TRAPEZOIDS | - CAIRO_XCB_RENDER_HAS_COMPOSITE)) == 0) - { - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - status = CAIRO_INT_STATUS_UNSUPPORTED; - if (_cairo_path_fixed_stroke_is_rectilinear (path)) { - cairo_boxes_t boxes; - - _cairo_boxes_init_with_clip (&boxes, composite->clip); - status = _cairo_path_fixed_stroke_rectilinear_to_boxes (path, - style, - ctm, - antialias, - &boxes); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) { - status = _clip_and_composite_boxes (surface, op, source, - &boxes, composite); - } - _cairo_boxes_fini (&boxes); - } - - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - if (surface->connection->flags & CAIRO_XCB_RENDER_HAS_COMPOSITE_TRAPEZOIDS) { - status = _cairo_xcb_surface_render_stroke_as_polygon (surface, op, source, - path, style, - ctm, ctm_inverse, - tolerance, antialias, - composite); - } else if (surface->connection->flags & CAIRO_XCB_RENDER_HAS_COMPOSITE) { - status = _cairo_xcb_surface_render_stroke_via_mask (surface, op, source, - path, style, - ctm, ctm_inverse, - tolerance, antialias, - composite); - } else { - ASSERT_NOT_REACHED; - } - } - - return status; -} - -static cairo_status_t -_cairo_xcb_surface_render_fill_as_polygon (cairo_xcb_surface_t *dst, - cairo_operator_t op, - const cairo_pattern_t*source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - cairo_composite_rectangles_t *extents) -{ - cairo_polygon_t polygon; - cairo_status_t status; - - _cairo_polygon_init_with_clip (&polygon, extents->clip); - status = _cairo_path_fixed_fill_to_polygon (path, tolerance, &polygon); - if (likely (status == CAIRO_STATUS_SUCCESS)) { - status = _composite_polygon (dst, op, source, - &polygon, - antialias, - fill_rule, - extents); - } - _cairo_polygon_fini (&polygon); - - return status; -} - -static cairo_status_t -_cairo_xcb_surface_render_fill_via_mask (cairo_xcb_surface_t *dst, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - cairo_composite_rectangles_t *extents) -{ - cairo_surface_t *image; - cairo_status_t status; - cairo_clip_t *clip; - int x, y; - - x = extents->bounded.x; - y = extents->bounded.y; - image = _cairo_xcb_surface_create_similar_image (dst, CAIRO_FORMAT_A8, - extents->bounded.width, - extents->bounded.height); - if (unlikely (image->status)) - return image->status; - - clip = _cairo_clip_copy_region (extents->clip); - status = _cairo_surface_offset_fill (image, x, y, - CAIRO_OPERATOR_ADD, - &_cairo_pattern_white.base, - path, fill_rule, tolerance, antialias, - clip); - _cairo_clip_destroy (clip); - if (likely (status == CAIRO_STATUS_SUCCESS)) { - cairo_surface_pattern_t mask; - - _cairo_pattern_init_for_surface (&mask, image); - mask.base.filter = CAIRO_FILTER_NEAREST; - - cairo_matrix_init_translate (&mask.base.matrix, -x, -y); - status = _clip_and_composite (dst, op, source, - _composite_mask, NULL, &mask.base, - extents, need_bounded_clip (extents)); - - _cairo_pattern_fini (&mask.base); - } - - cairo_surface_finish (image); - cairo_surface_destroy (image); - - return status; -} - -cairo_int_status_t -_cairo_xcb_render_compositor_fill (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *composite, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_xcb_surface_t *surface = (cairo_xcb_surface_t *) composite->surface; - cairo_operator_t op = composite->op; - cairo_pattern_t *source = &composite->source_pattern.base; - cairo_int_status_t status; - - if (unlikely (! _operator_is_supported (surface->connection->flags, op))) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if ((surface->connection->flags & (CAIRO_XCB_RENDER_HAS_COMPOSITE_TRAPEZOIDS | - CAIRO_XCB_RENDER_HAS_COMPOSITE)) == 0) - { - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - status = CAIRO_INT_STATUS_UNSUPPORTED; - if (_cairo_path_fixed_fill_is_rectilinear (path)) { - cairo_boxes_t boxes; - - _cairo_boxes_init_with_clip (&boxes, composite->clip); - status = _cairo_path_fixed_fill_rectilinear_to_boxes (path, - fill_rule, - antialias, - &boxes); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) { - status = _clip_and_composite_boxes (surface, op, source, - &boxes, composite); - } - _cairo_boxes_fini (&boxes); - } - - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - if (surface->connection->flags & CAIRO_XCB_RENDER_HAS_COMPOSITE_TRAPEZOIDS) { - status = _cairo_xcb_surface_render_fill_as_polygon (surface, op, source, path, - fill_rule, tolerance, antialias, - composite); - } else if (surface->connection->flags & CAIRO_XCB_RENDER_HAS_COMPOSITE) { - status = _cairo_xcb_surface_render_fill_via_mask (surface, op, source, path, - fill_rule, tolerance, antialias, - composite); - } else { - ASSERT_NOT_REACHED; - } - } - - return status; -} - -static cairo_status_t -_cairo_xcb_surface_render_glyphs_via_mask (cairo_xcb_surface_t *dst, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_composite_rectangles_t *extents) -{ - cairo_surface_t *image; - cairo_content_t content; - cairo_status_t status; - cairo_clip_t *clip; - int x, y; - - content = CAIRO_CONTENT_ALPHA; - if (scaled_font->options.antialias == CAIRO_ANTIALIAS_SUBPIXEL) - content = CAIRO_CONTENT_COLOR_ALPHA; - - x = extents->bounded.x; - y = extents->bounded.y; - image = _cairo_xcb_surface_create_similar_image (dst, - _cairo_format_from_content (content), - extents->bounded.width, - extents->bounded.height); - if (unlikely (image->status)) - return image->status; - - clip = _cairo_clip_copy_region (extents->clip); - status = _cairo_surface_offset_glyphs (image, x, y, - CAIRO_OPERATOR_ADD, - &_cairo_pattern_white.base, - scaled_font, glyphs, num_glyphs, - clip); - _cairo_clip_destroy (clip); - if (likely (status == CAIRO_STATUS_SUCCESS)) { - cairo_surface_pattern_t mask; - - _cairo_pattern_init_for_surface (&mask, image); - mask.base.filter = CAIRO_FILTER_NEAREST; - if (content & CAIRO_CONTENT_COLOR) - mask.base.has_component_alpha = TRUE; - - cairo_matrix_init_translate (&mask.base.matrix, -x, -y); - status = _clip_and_composite (dst, op, source, - _composite_mask, NULL, &mask.base, - extents, need_bounded_clip (extents)); - - _cairo_pattern_fini (&mask.base); - } - - cairo_surface_finish (image); - cairo_surface_destroy (image); - - return status; -} - -/* Build a struct of the same size of #cairo_glyph_t that can be used both as - * an input glyph with double coordinates, and as "working" glyph with - * integer from-current-point offsets. */ -typedef union { - cairo_glyph_t d; - unsigned long index; - struct { - unsigned long index; - int x; - int y; - } i; -} cairo_xcb_glyph_t; - -/* compile-time assert that #cairo_xcb_glyph_t is the same size as #cairo_glyph_t */ -COMPILE_TIME_ASSERT (sizeof (cairo_xcb_glyph_t) == sizeof (cairo_glyph_t)); - -typedef struct { - cairo_scaled_font_t *font; - cairo_xcb_glyph_t *glyphs; - int num_glyphs; - cairo_bool_t use_mask; -} composite_glyphs_info_t; - -static cairo_status_t -_can_composite_glyphs (cairo_xcb_surface_t *dst, - cairo_rectangle_int_t *extents, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int *num_glyphs) -{ -#define GLYPH_CACHE_SIZE 64 - cairo_box_t bbox_cache[GLYPH_CACHE_SIZE]; - unsigned long glyph_cache[GLYPH_CACHE_SIZE]; -#undef GLYPH_CACHE_SIZE - cairo_status_t status = CAIRO_STATUS_SUCCESS; - cairo_glyph_t *glyphs_end, *valid_glyphs; - const int max_glyph_size = dst->connection->maximum_request_length - 64; - - /* We must initialize the cache with values that cannot match the - * "hash" to guarantee that when compared for the first time they - * will result in a mismatch. The hash function is simply modulus, - * so we cannot use 0 in glyph_cache[0], but we can use it in all - * other array cells. - */ - memset (glyph_cache, 0, sizeof (glyph_cache)); - glyph_cache[0] = 1; - - /* Scan for oversized glyphs or glyphs outside the representable - * range and fallback in that case, discard glyphs outside of the - * image. - */ - valid_glyphs = glyphs; - for (glyphs_end = glyphs + *num_glyphs; glyphs != glyphs_end; glyphs++) { - double x1, y1, x2, y2; - cairo_scaled_glyph_t *glyph; - cairo_box_t *bbox; - int width, height, len; - int g; - - g = glyphs->index % ARRAY_LENGTH (glyph_cache); - if (glyph_cache[g] != glyphs->index) { - status = _cairo_scaled_glyph_lookup (scaled_font, - glyphs->index, - CAIRO_SCALED_GLYPH_INFO_METRICS, - &glyph); - if (unlikely (status)) - break; - - glyph_cache[g] = glyphs->index; - bbox_cache[g] = glyph->bbox; - } - bbox = &bbox_cache[g]; - - /* Drop glyphs outside the clipping */ - x1 = _cairo_fixed_to_double (bbox->p1.x); - y1 = _cairo_fixed_to_double (bbox->p1.y); - y2 = _cairo_fixed_to_double (bbox->p2.y); - x2 = _cairo_fixed_to_double (bbox->p2.x); - if (unlikely (glyphs->x + x2 <= extents->x || - glyphs->y + y2 <= extents->y || - glyphs->x + x1 >= extents->x + extents->width || - glyphs->y + y1 >= extents->y + extents->height)) - { - (*num_glyphs)--; - continue; - } - - /* XRenderAddGlyph does not handle a glyph surface larger than - * the extended maximum XRequest size. - */ - width = _cairo_fixed_integer_ceil (bbox->p2.x - bbox->p1.x); - height = _cairo_fixed_integer_ceil (bbox->p2.y - bbox->p1.y); - len = CAIRO_STRIDE_FOR_WIDTH_BPP (width, 32) * height; - if (unlikely (len >= max_glyph_size)) { - status = CAIRO_INT_STATUS_UNSUPPORTED; - break; - } - - /* The glyph coordinates must be representable in an int16_t. - * When possible, they will be expressed as an offset from the - * previous glyph, otherwise they will be an offset from the - * operation extents or from the surface origin. If the last - * two options are not valid, fallback. - */ - if (unlikely (glyphs->x > INT16_MAX || - glyphs->y > INT16_MAX || - glyphs->x - extents->x < INT16_MIN || - glyphs->y - extents->y < INT16_MIN)) - { - status = CAIRO_INT_STATUS_UNSUPPORTED; - break; - } - - - if (unlikely (valid_glyphs != glyphs)) - *valid_glyphs = *glyphs; - valid_glyphs++; - } - - if (unlikely (valid_glyphs != glyphs)) { - for (; glyphs != glyphs_end; glyphs++) { - *valid_glyphs = *glyphs; - valid_glyphs++; - } - } - - return status; -} - -/* Start a new element for the first glyph, - * or for any glyph that has unexpected position, - * or if current element has too many glyphs - * (Xrender limits each element to 252 glyphs, we limit them to 128) - * - * These same conditions need to be mirrored between - * _cairo_xcb_surface_emit_glyphs and _emit_glyph_chunks - */ -#define _start_new_glyph_elt(count, glyph) \ - (((count) & 127) == 0 || (glyph)->i.x || (glyph)->i.y) - -/* sz_xGlyphtElt required alignment to a 32-bit boundary, so ensure we have - * enough room for padding */ -typedef struct { - uint8_t len; - uint8_t pad1; - uint16_t pad2; - int16_t deltax; - int16_t deltay; -} x_glyph_elt_t; -#define _cairo_sz_x_glyph_elt_t (sizeof (x_glyph_elt_t) + 4) - -static void -_cairo_xcb_font_destroy (cairo_xcb_font_t *font) -{ - int i; - - for (i = 0; i < NUM_GLYPHSETS; i++) { - cairo_xcb_font_glyphset_info_t *info; - - info = &font->glyphset_info[i]; - free (info->pending_free_glyphs); - } - - cairo_list_del (&font->base.link); - cairo_list_del (&font->link); - - _cairo_xcb_connection_destroy (font->connection); - - free (font); -} - -static void -_cairo_xcb_font_fini (cairo_scaled_font_private_t *abstract_private, - cairo_scaled_font_t *scaled_font) -{ - cairo_xcb_font_t *font_private = (cairo_xcb_font_t *)abstract_private; - cairo_xcb_connection_t *connection; - cairo_bool_t have_connection; - cairo_status_t status; - int i; - - connection = font_private->connection; - - status = _cairo_xcb_connection_acquire (connection); - have_connection = status == CAIRO_STATUS_SUCCESS; - - for (i = 0; i < NUM_GLYPHSETS; i++) { - cairo_xcb_font_glyphset_info_t *info; - - info = &font_private->glyphset_info[i]; - if (info->glyphset && status == CAIRO_STATUS_SUCCESS) { - _cairo_xcb_connection_render_free_glyph_set (connection, - info->glyphset); - } - } - - if (have_connection) - _cairo_xcb_connection_release (connection); - - _cairo_xcb_font_destroy (font_private); -} - - -static cairo_xcb_font_t * -_cairo_xcb_font_create (cairo_xcb_connection_t *connection, - cairo_scaled_font_t *font) -{ - cairo_xcb_font_t *priv; - int i; - - priv = malloc (sizeof (cairo_xcb_font_t)); - if (unlikely (priv == NULL)) - return NULL; - - _cairo_scaled_font_attach_private (font, &priv->base, connection, - _cairo_xcb_font_fini); - - priv->scaled_font = font; - priv->connection = _cairo_xcb_connection_reference (connection); - cairo_list_add (&priv->link, &connection->fonts); - - for (i = 0; i < NUM_GLYPHSETS; i++) { - cairo_xcb_font_glyphset_info_t *info = &priv->glyphset_info[i]; - switch (i) { - case GLYPHSET_INDEX_ARGB32: info->format = CAIRO_FORMAT_ARGB32; break; - case GLYPHSET_INDEX_A8: info->format = CAIRO_FORMAT_A8; break; - case GLYPHSET_INDEX_A1: info->format = CAIRO_FORMAT_A1; break; - default: ASSERT_NOT_REACHED; break; - } - info->xrender_format = 0; - info->glyphset = XCB_NONE; - info->pending_free_glyphs = NULL; - } - - return priv; -} - -void -_cairo_xcb_font_close (cairo_xcb_font_t *font) -{ - cairo_scaled_font_t *scaled_font; - - scaled_font = font->scaled_font; - - //scaled_font->surface_private = NULL; - _cairo_scaled_font_reset_cache (scaled_font); - - _cairo_xcb_font_destroy (font); -} - -static void -_cairo_xcb_render_free_glyphs (cairo_xcb_connection_t *connection, - cairo_xcb_font_glyphset_free_glyphs_t *to_free) -{ - _cairo_xcb_connection_render_free_glyphs (connection, - to_free->glyphset, - to_free->glyph_count, - to_free->glyph_indices); -} - -static int -_cairo_xcb_get_glyphset_index_for_format (cairo_format_t format) -{ - if (format == CAIRO_FORMAT_A8) - return GLYPHSET_INDEX_A8; - if (format == CAIRO_FORMAT_A1) - return GLYPHSET_INDEX_A1; - - assert (format == CAIRO_FORMAT_ARGB32); - return GLYPHSET_INDEX_ARGB32; -} - - - -static inline cairo_xcb_font_t * -_cairo_xcb_font_get (const cairo_xcb_connection_t *c, - cairo_scaled_font_t *font) -{ - return (cairo_xcb_font_t *)_cairo_scaled_font_find_private (font, c); -} - - -static cairo_xcb_font_glyphset_info_t * -_cairo_xcb_scaled_font_get_glyphset_info_for_format (cairo_xcb_connection_t *c, - cairo_scaled_font_t *font, - cairo_format_t format) -{ - cairo_xcb_font_t *priv; - cairo_xcb_font_glyphset_info_t *info; - int glyphset_index; - - glyphset_index = _cairo_xcb_get_glyphset_index_for_format (format); - - priv = _cairo_xcb_font_get (c, font); - if (priv == NULL) { - priv = _cairo_xcb_font_create (c, font); - if (priv == NULL) - return NULL; - } - - info = &priv->glyphset_info[glyphset_index]; - if (info->glyphset == XCB_NONE) { - info->glyphset = _cairo_xcb_connection_get_xid (c); - info->xrender_format = c->standard_formats[info->format]; - - _cairo_xcb_connection_render_create_glyph_set (c, - info->glyphset, - info->xrender_format); - } - - return info; -} - -static cairo_bool_t -_cairo_xcb_glyphset_info_has_pending_free_glyph ( - cairo_xcb_font_glyphset_info_t *info, - unsigned long glyph_index) -{ - if (info->pending_free_glyphs != NULL) { - cairo_xcb_font_glyphset_free_glyphs_t *to_free; - int i; - - to_free = info->pending_free_glyphs; - for (i = 0; i < to_free->glyph_count; i++) { - if (to_free->glyph_indices[i] == glyph_index) { - to_free->glyph_count--; - memmove (&to_free->glyph_indices[i], - &to_free->glyph_indices[i+1], - (to_free->glyph_count - i) * sizeof (to_free->glyph_indices[0])); - return TRUE; - } - } - } - - return FALSE; -} - -typedef struct { - cairo_scaled_glyph_private_t base; - - cairo_xcb_font_glyphset_info_t *glyphset; -} cairo_xcb_glyph_private_t; - -static cairo_xcb_font_glyphset_info_t * -_cairo_xcb_scaled_font_get_glyphset_info_for_pending_free_glyph (cairo_xcb_connection_t *c, - cairo_scaled_font_t *font, - unsigned long glyph_index, - cairo_image_surface_t *surface) -{ - cairo_xcb_font_t *priv; - int i; - - priv = _cairo_xcb_font_get (c, font); - if (priv == NULL) - return NULL; - - if (surface != NULL) { - i = _cairo_xcb_get_glyphset_index_for_format (surface->format); - - if (_cairo_xcb_glyphset_info_has_pending_free_glyph ( - &priv->glyphset_info[i], - glyph_index)) - { - return &priv->glyphset_info[i]; - } - } else { - for (i = 0; i < NUM_GLYPHSETS; i++) { - if (_cairo_xcb_glyphset_info_has_pending_free_glyph ( - &priv->glyphset_info[i], - glyph_index)) - { - return &priv->glyphset_info[i]; - } - } - } - - return NULL; -} - -static void -_cairo_xcb_glyph_fini (cairo_scaled_glyph_private_t *glyph_private, - cairo_scaled_glyph_t *glyph, - cairo_scaled_font_t *font) -{ - cairo_xcb_glyph_private_t *priv = (cairo_xcb_glyph_private_t *)glyph_private; - - if (! font->finished) { - cairo_xcb_font_glyphset_info_t *info = priv->glyphset; - cairo_xcb_font_glyphset_free_glyphs_t *to_free; - cairo_xcb_font_t *font_private; - - font_private = _cairo_xcb_font_get (glyph_private->key, font); - assert (font_private); - - to_free = info->pending_free_glyphs; - if (to_free != NULL && - to_free->glyph_count == ARRAY_LENGTH (to_free->glyph_indices)) - { - _cairo_xcb_render_free_glyphs (font_private->connection, to_free); - to_free = info->pending_free_glyphs = NULL; - } - - if (to_free == NULL) { - to_free = malloc (sizeof (cairo_xcb_font_glyphset_free_glyphs_t)); - if (unlikely (to_free == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - return; /* XXX cannot propagate failure */ - } - - to_free->glyphset = info->glyphset; - to_free->glyph_count = 0; - info->pending_free_glyphs = to_free; - } - - to_free->glyph_indices[to_free->glyph_count++] = - _cairo_scaled_glyph_index (glyph); - } - - cairo_list_del (&glyph_private->link); - free (glyph_private); -} - - -static cairo_status_t -_cairo_xcb_glyph_attach (cairo_xcb_connection_t *c, - cairo_scaled_glyph_t *glyph, - cairo_xcb_font_glyphset_info_t *info) -{ - cairo_xcb_glyph_private_t *priv; - - priv = malloc (sizeof (*priv)); - if (unlikely (priv == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_scaled_glyph_attach_private (glyph, &priv->base, c, - _cairo_xcb_glyph_fini); - priv->glyphset = info; - - glyph->dev_private = info; - glyph->dev_private_key = c; - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_xcb_surface_add_glyph (cairo_xcb_connection_t *connection, - cairo_scaled_font_t *font, - cairo_scaled_glyph_t **scaled_glyph_out) -{ - xcb_render_glyphinfo_t glyph_info; - uint32_t glyph_index; - uint8_t *data; - cairo_status_t status = CAIRO_STATUS_SUCCESS; - cairo_scaled_glyph_t *scaled_glyph = *scaled_glyph_out; - cairo_image_surface_t *glyph_surface = scaled_glyph->surface; - cairo_bool_t already_had_glyph_surface; - cairo_xcb_font_glyphset_info_t *info; - - glyph_index = _cairo_scaled_glyph_index (scaled_glyph); - - /* check to see if we have a pending XRenderFreeGlyph for this glyph */ - info = _cairo_xcb_scaled_font_get_glyphset_info_for_pending_free_glyph (connection, font, glyph_index, glyph_surface); - if (info != NULL) - return _cairo_xcb_glyph_attach (connection, scaled_glyph, info); - - if (glyph_surface == NULL) { - status = _cairo_scaled_glyph_lookup (font, - glyph_index, - CAIRO_SCALED_GLYPH_INFO_METRICS | - CAIRO_SCALED_GLYPH_INFO_SURFACE, - scaled_glyph_out); - if (unlikely (status)) - return status; - - scaled_glyph = *scaled_glyph_out; - glyph_surface = scaled_glyph->surface; - already_had_glyph_surface = FALSE; - } else { - already_had_glyph_surface = TRUE; - } - - info = _cairo_xcb_scaled_font_get_glyphset_info_for_format (connection, - font, - glyph_surface->format); - if (unlikely (info == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto BAIL; - } - -#if 0 - /* If the glyph surface has zero height or width, we create - * a clear 1x1 surface, to avoid various X server bugs. - */ - if (glyph_surface->width == 0 || glyph_surface->height == 0) { - cairo_surface_t *tmp_surface; - - tmp_surface = cairo_image_surface_create (info->format, 1, 1); - status = tmp_surface->status; - if (unlikely (status)) - goto BAIL; - - tmp_surface->device_transform = glyph_surface->base.device_transform; - tmp_surface->device_transform_inverse = glyph_surface->base.device_transform_inverse; - - glyph_surface = (cairo_image_surface_t *) tmp_surface; - } -#endif - - /* If the glyph format does not match the font format, then we - * create a temporary surface for the glyph image with the font's - * format. - */ - if (glyph_surface->format != info->format) { - glyph_surface = _cairo_image_surface_coerce_to_format (glyph_surface, - info->format); - status = glyph_surface->base.status; - if (unlikely (status)) - goto BAIL; - } - - /* XXX: FRAGILE: We're ignore device_transform scaling here. A bug? */ - glyph_info.x = _cairo_lround (glyph_surface->base.device_transform.x0); - glyph_info.y = _cairo_lround (glyph_surface->base.device_transform.y0); - glyph_info.width = glyph_surface->width; - glyph_info.height = glyph_surface->height; - glyph_info.x_off = scaled_glyph->x_advance; - glyph_info.y_off = scaled_glyph->y_advance; - - data = glyph_surface->data; - - /* flip formats around */ - switch (_cairo_xcb_get_glyphset_index_for_format (scaled_glyph->surface->format)) { - case GLYPHSET_INDEX_A1: - /* local bitmaps are always stored with bit == byte */ - if (_cairo_is_little_endian() != (connection->root->bitmap_format_bit_order == XCB_IMAGE_ORDER_LSB_FIRST)) { - int c = glyph_surface->stride * glyph_surface->height; - const uint8_t *d; - uint8_t *new, *n; - - if (c == 0) - break; - - new = malloc (c); - if (unlikely (new == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto BAIL; - } - - n = new; - d = data; - do { - uint8_t b = *d++; - b = ((b << 1) & 0xaa) | ((b >> 1) & 0x55); - b = ((b << 2) & 0xcc) | ((b >> 2) & 0x33); - b = ((b << 4) & 0xf0) | ((b >> 4) & 0x0f); - *n++ = b; - } while (--c); - data = new; - } - break; - - case GLYPHSET_INDEX_A8: - break; - - case GLYPHSET_INDEX_ARGB32: - if (_cairo_is_little_endian() != (connection->root->image_byte_order == XCB_IMAGE_ORDER_LSB_FIRST)) { - unsigned int c = glyph_surface->stride * glyph_surface->height / 4; - const uint32_t *d; - uint32_t *new, *n; - - if (c == 0) - break; - - new = malloc (4 * c); - if (unlikely (new == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto BAIL; - } - - n = new; - d = (uint32_t *) data; - do { - *n++ = bswap_32 (*d); - d++; - } while (--c); - data = (uint8_t *) new; - } - break; - - default: - ASSERT_NOT_REACHED; - break; - } - /* XXX assume X server wants pixman padding. Xft assumes this as well */ - - _cairo_xcb_connection_render_add_glyphs (connection, - info->glyphset, - 1, &glyph_index, &glyph_info, - glyph_surface->stride * glyph_surface->height, - data); - - if (data != glyph_surface->data) - free (data); - - status = _cairo_xcb_glyph_attach (connection, scaled_glyph, info); - - BAIL: - if (glyph_surface != scaled_glyph->surface) - cairo_surface_destroy (&glyph_surface->base); - - /* If the scaled glyph didn't already have a surface attached - * to it, release the created surface now that we have it - * uploaded to the X server. If the surface has already been - * there (e.g. because image backend requested it), leave it in - * the cache - */ - if (! already_had_glyph_surface) - _cairo_scaled_glyph_set_surface (scaled_glyph, font, NULL); - - return status; -} - -typedef void (*cairo_xcb_render_composite_text_func_t) - (cairo_xcb_connection_t *connection, - uint8_t op, - xcb_render_picture_t src, - xcb_render_picture_t dst, - xcb_render_pictformat_t mask_format, - xcb_render_glyphset_t glyphset, - int16_t src_x, - int16_t src_y, - uint32_t len, - uint8_t *cmd); - - -static cairo_status_t -_emit_glyphs_chunk (cairo_xcb_surface_t *dst, - cairo_operator_t op, - cairo_xcb_picture_t *src, - /* info for this chunk */ - cairo_xcb_glyph_t *glyphs, - int num_glyphs, - int width, - int estimated_req_size, - cairo_xcb_font_glyphset_info_t *info, - xcb_render_pictformat_t mask_format) -{ - cairo_xcb_render_composite_text_func_t composite_text_func; - uint8_t stack_buf[CAIRO_STACK_BUFFER_SIZE]; - uint8_t *buf = stack_buf; - x_glyph_elt_t *elt = NULL; /* silence compiler */ - uint32_t len; - int i; - - if (estimated_req_size > ARRAY_LENGTH (stack_buf)) { - buf = malloc (estimated_req_size); - if (unlikely (buf == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - len = 0; - for (i = 0; i < num_glyphs; i++) { - if (_start_new_glyph_elt (i, &glyphs[i])) { - if (len & 3) - len += 4 - (len & 3); - - elt = (x_glyph_elt_t *) (buf + len); - elt->len = 0; - elt->deltax = glyphs[i].i.x; - elt->deltay = glyphs[i].i.y; - len += sizeof (x_glyph_elt_t); - } - - switch (width) { - case 1: *(uint8_t *) (buf + len) = glyphs[i].index; break; - case 2: *(uint16_t *) (buf + len) = glyphs[i].index; break; - default: - case 4: *(uint32_t *) (buf + len) = glyphs[i].index; break; - } - len += width; - elt->len++; - } - if (len & 3) - len += 4 - (len & 3); - - switch (width) { - case 1: - composite_text_func = _cairo_xcb_connection_render_composite_glyphs_8; - break; - case 2: - composite_text_func = _cairo_xcb_connection_render_composite_glyphs_16; - break; - default: - case 4: - composite_text_func = _cairo_xcb_connection_render_composite_glyphs_32; - break; - } - composite_text_func (dst->connection, - _render_operator (op), - src->picture, - dst->picture, - mask_format, - info->glyphset, - src->x + glyphs[0].i.x, - src->y + glyphs[0].i.y, - len, buf); - - if (buf != stack_buf) - free (buf); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_composite_glyphs (void *closure, - cairo_xcb_surface_t *dst, - cairo_operator_t op, - const cairo_pattern_t *pattern, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents, - cairo_clip_t *clip) -{ - composite_glyphs_info_t *info = closure; - cairo_scaled_glyph_t *glyph_cache[64]; - cairo_status_t status = CAIRO_STATUS_SUCCESS; - cairo_fixed_t x = 0, y = 0; - cairo_xcb_font_glyphset_info_t *glyphset_info = NULL, *this_glyphset_info; - const unsigned int max_request_size = dst->connection->maximum_request_length - 64; - cairo_xcb_picture_t *src; - - unsigned long max_index = 0; - int width = 1; - - unsigned int request_size = 0; - int i; - - if (dst->deferred_clear) { - status = _cairo_xcb_surface_clear (dst); - if (unlikely (status)) - return status; - } - - src = _cairo_xcb_picture_for_pattern (dst, pattern, extents); - if (unlikely (src->base.status)) - return src->base.status; - - memset (glyph_cache, 0, sizeof (glyph_cache)); - - for (i = 0; i < info->num_glyphs; i++) { - cairo_scaled_glyph_t *glyph; - unsigned long glyph_index = info->glyphs[i].index; - int cache_index = glyph_index % ARRAY_LENGTH (glyph_cache); - int old_width = width; - int this_x, this_y; - - glyph = glyph_cache[cache_index]; - if (glyph == NULL || - _cairo_scaled_glyph_index (glyph) != glyph_index) - { - status = _cairo_scaled_glyph_lookup (info->font, - glyph_index, - CAIRO_SCALED_GLYPH_INFO_METRICS, - &glyph); - if (unlikely (status)) { - cairo_surface_destroy (&src->base); - return status; - } - - /* Send unseen glyphs to the server */ - if (glyph->dev_private_key != dst->connection) { - status = _cairo_xcb_surface_add_glyph (dst->connection, - info->font, - &glyph); - if (unlikely (status)) { - cairo_surface_destroy (&src->base); - return status; - } - } - - glyph_cache[cache_index] = glyph; - } - - this_x = _cairo_lround (info->glyphs[i].d.x) - dst_x; - this_y = _cairo_lround (info->glyphs[i].d.y) - dst_y; - - this_glyphset_info = glyph->dev_private; - if (glyphset_info == NULL) - glyphset_info = this_glyphset_info; - - /* Update max glyph index */ - if (glyph_index > max_index) { - max_index = glyph_index; - if (max_index >= 65536) - width = 4; - else if (max_index >= 256) - width = 2; - if (width != old_width) - request_size += (width - old_width) * i; - } - - /* If we will pass the max request size by adding this glyph, - * flush current glyphs. Note that we account for a - * possible element being added below. - * - * Also flush if changing glyphsets, as Xrender limits one mask - * format per request, so we can either break up, or use a - * wide-enough mask format. We do the former. One reason to - * prefer the latter is the fact that Xserver ADDs all glyphs - * to the mask first, and then composes that to final surface, - * though it's not a big deal. - * - * If the glyph has a coordinate which cannot be represented - * as a 16-bit offset from the previous glyph, flush the - * current chunk. The current glyph will be the first one in - * the next chunk, thus its coordinates will be an offset from - * the destination origin. This offset is guaranteed to be - * representable as 16-bit offset in _can_composite_glyphs(). - */ - if (request_size + width > max_request_size - _cairo_sz_x_glyph_elt_t || - this_x - x > INT16_MAX || this_x - x < INT16_MIN || - this_y - y > INT16_MAX || this_y - y < INT16_MIN || - this_glyphset_info != glyphset_info) - { - status = _emit_glyphs_chunk (dst, op, src, - info->glyphs, i, - old_width, request_size, - glyphset_info, - info->use_mask ? glyphset_info->xrender_format : 0); - if (unlikely (status)) { - cairo_surface_destroy (&src->base); - return status; - } - - info->glyphs += i; - info->num_glyphs -= i; - i = 0; - - max_index = info->glyphs[0].index; - width = max_index < 256 ? 1 : max_index < 65536 ? 2 : 4; - - request_size = 0; - - x = y = 0; - glyphset_info = this_glyphset_info; - } - - /* Convert absolute glyph position to relative-to-current-point - * position */ - info->glyphs[i].i.x = this_x - x; - info->glyphs[i].i.y = this_y - y; - - /* Start a new element for the first glyph, - * or for any glyph that has unexpected position, - * or if current element has too many glyphs. - * - * These same conditions are mirrored in _emit_glyphs_chunk(). - */ - if (_start_new_glyph_elt (i, &info->glyphs[i])) - request_size += _cairo_sz_x_glyph_elt_t; - - /* adjust current-position */ - x = this_x + glyph->x_advance; - y = this_y + glyph->y_advance; - - request_size += width; - } - - if (i) { - status = _emit_glyphs_chunk (dst, op, src, - info->glyphs, i, - width, request_size, - glyphset_info, - info->use_mask ? glyphset_info->xrender_format : 0); - } - - cairo_surface_destroy (&src->base); - - return status; -} - -cairo_int_status_t -_cairo_xcb_render_compositor_glyphs (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *composite, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_bool_t overlap) -{ - cairo_xcb_surface_t *surface = (cairo_xcb_surface_t *) composite->surface; - cairo_operator_t op = composite->op; - cairo_pattern_t *source = &composite->source_pattern.base; - cairo_int_status_t status; - - if (unlikely (! _operator_is_supported (surface->connection->flags, op))) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if ((surface->connection->flags & (CAIRO_XCB_RENDER_HAS_COMPOSITE_GLYPHS | CAIRO_XCB_RENDER_HAS_COMPOSITE)) == 0) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = CAIRO_INT_STATUS_UNSUPPORTED; - if (surface->connection->flags & CAIRO_XCB_RENDER_HAS_COMPOSITE_GLYPHS) { - _cairo_scaled_font_freeze_cache (scaled_font); - - status = _can_composite_glyphs (surface, &composite->bounded, - scaled_font, glyphs, &num_glyphs); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) { - composite_glyphs_info_t info; - unsigned flags = 0; - - info.font = scaled_font; - info.glyphs = (cairo_xcb_glyph_t *) glyphs; - info.num_glyphs = num_glyphs; - info.use_mask = - overlap || - ! composite->is_bounded || - ! _cairo_clip_is_region(composite->clip); - - if (composite->mask.width > composite->unbounded.width || - composite->mask.height > composite->unbounded.height) - { - /* Glyphs are tricky since we do not directly control the - * geometry and their inked extents depend on the - * individual glyph-surface size. We must set a clip region - * so that the X server can trim the glyphs appropriately. - */ - flags |= FORCE_CLIP_REGION; - } - status = _clip_and_composite (surface, op, source, - _composite_glyphs, NULL, - &info, composite, - need_bounded_clip (composite) | - flags); - } - - _cairo_scaled_font_thaw_cache (scaled_font); - } - - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - assert (surface->connection->flags & CAIRO_XCB_RENDER_HAS_COMPOSITE); - status = - _cairo_xcb_surface_render_glyphs_via_mask (surface, op, source, - scaled_font, glyphs, num_glyphs, - composite); - } - - return status; -} diff --git a/source/libs/cairo/cairo-src/src/cairo-xcb-surface.c b/source/libs/cairo/cairo-src/src/cairo-xcb-surface.c deleted file mode 100644 index d4d60ad72856c8585b2f36b3b87c2c0f68594b45..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xcb-surface.c +++ /dev/null @@ -1,1529 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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): - * Behdad Esfahbod <behdad@behdad.org> - * Carl D. Worth <cworth@cworth.org> - * Chris Wilson <chris@chris-wilson.co.uk> - * Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation - */ - -#include "cairoint.h" - -#include "cairo-xcb.h" -#include "cairo-xcb-private.h" - -#include "cairo-composite-rectangles-private.h" -#include "cairo-default-context-private.h" -#include "cairo-image-surface-inline.h" -#include "cairo-list-inline.h" -#include "cairo-surface-backend-private.h" -#include "cairo-compositor-private.h" - -#if CAIRO_HAS_XLIB_XCB_FUNCTIONS -slim_hidden_proto (cairo_xcb_surface_create); -slim_hidden_proto (cairo_xcb_surface_create_for_bitmap); -slim_hidden_proto (cairo_xcb_surface_create_with_xrender_format); -#endif - -/** - * SECTION:cairo-xcb - * @Title: XCB Surfaces - * @Short_Description: X Window System rendering using the XCB library - * @See_Also: #cairo_surface_t - * - * The XCB surface is used to render cairo graphics to X Window System - * windows and pixmaps using the XCB library. - * - * Note that the XCB surface automatically takes advantage of the X render - * extension if it is available. - **/ - -/** - * CAIRO_HAS_XCB_SURFACE: - * - * Defined if the xcb surface backend is available. - * This macro can be used to conditionally compile backend-specific code. - * - * Since: 1.12 - **/ - -cairo_surface_t * -_cairo_xcb_surface_create_similar (void *abstract_other, - cairo_content_t content, - int width, - int height) -{ - cairo_xcb_surface_t *other = abstract_other; - cairo_xcb_surface_t *surface; - cairo_xcb_connection_t *connection; - xcb_pixmap_t pixmap; - cairo_status_t status; - - if (unlikely(width > XLIB_COORD_MAX || - height > XLIB_COORD_MAX || - width <= 0 || - height <= 0)) - return cairo_image_surface_create (_cairo_format_from_content (content), - width, height); - - if ((other->connection->flags & CAIRO_XCB_HAS_RENDER) == 0) - return _cairo_xcb_surface_create_similar_image (other, - _cairo_format_from_content (content), - width, height); - - connection = other->connection; - status = _cairo_xcb_connection_acquire (connection); - if (unlikely (status)) - return _cairo_surface_create_in_error (status); - - if (content == other->base.content) { - pixmap = _cairo_xcb_connection_create_pixmap (connection, - other->depth, - other->drawable, - width, height); - - surface = (cairo_xcb_surface_t *) - _cairo_xcb_surface_create_internal (other->screen, - pixmap, TRUE, - other->pixman_format, - other->xrender_format, - width, height); - } else { - cairo_format_t format; - pixman_format_code_t pixman_format; - - /* XXX find a compatible xrender format */ - switch (content) { - case CAIRO_CONTENT_ALPHA: - pixman_format = PIXMAN_a8; - format = CAIRO_FORMAT_A8; - break; - case CAIRO_CONTENT_COLOR: - pixman_format = PIXMAN_x8r8g8b8; - format = CAIRO_FORMAT_RGB24; - break; - default: - ASSERT_NOT_REACHED; - case CAIRO_CONTENT_COLOR_ALPHA: - pixman_format = PIXMAN_a8r8g8b8; - format = CAIRO_FORMAT_ARGB32; - break; - } - - pixmap = _cairo_xcb_connection_create_pixmap (connection, - PIXMAN_FORMAT_DEPTH (pixman_format), - other->drawable, - width, height); - - surface = (cairo_xcb_surface_t *) - _cairo_xcb_surface_create_internal (other->screen, - pixmap, TRUE, - pixman_format, - connection->standard_formats[format], - width, height); - } - - if (unlikely (surface->base.status)) - _cairo_xcb_connection_free_pixmap (connection, pixmap); - - _cairo_xcb_connection_release (connection); - - return &surface->base; -} - -cairo_surface_t * -_cairo_xcb_surface_create_similar_image (void *abstract_other, - cairo_format_t format, - int width, - int height) -{ - cairo_xcb_surface_t *other = abstract_other; - cairo_xcb_connection_t *connection = other->connection; - - cairo_xcb_shm_info_t *shm_info; - cairo_image_surface_t *image; - cairo_status_t status; - pixman_format_code_t pixman_format; - - if (unlikely(width > XLIB_COORD_MAX || - height > XLIB_COORD_MAX || - width <= 0 || - height <= 0)) - return NULL; - - pixman_format = _cairo_format_to_pixman_format_code (format); - - status = _cairo_xcb_shm_image_create (connection, pixman_format, - width, height, &image, - &shm_info); - if (unlikely (status)) - return _cairo_surface_create_in_error (status); - - if (! image->base.is_clear) { - memset (image->data, 0, image->stride * image->height); - image->base.is_clear = TRUE; - } - - return &image->base; -} - -static cairo_status_t -_cairo_xcb_surface_finish (void *abstract_surface) -{ - cairo_xcb_surface_t *surface = abstract_surface; - cairo_status_t status; - - if (surface->fallback != NULL) { - cairo_surface_finish (&surface->fallback->base); - cairo_surface_destroy (&surface->fallback->base); - } - _cairo_boxes_fini (&surface->fallback_damage); - - cairo_list_del (&surface->link); - - status = _cairo_xcb_connection_acquire (surface->connection); - if (status == CAIRO_STATUS_SUCCESS) { - if (surface->picture != XCB_NONE) { - _cairo_xcb_connection_render_free_picture (surface->connection, - surface->picture); - } - - if (surface->owns_pixmap) - _cairo_xcb_connection_free_pixmap (surface->connection, surface->drawable); - _cairo_xcb_connection_release (surface->connection); - } - - _cairo_xcb_connection_destroy (surface->connection); - - return status; -} - -static void -_destroy_image (pixman_image_t *image, void *data) -{ - free (data); -} - -#if CAIRO_HAS_XCB_SHM_FUNCTIONS -static cairo_surface_t * -_cairo_xcb_surface_create_shm_image (cairo_xcb_connection_t *connection, - pixman_format_code_t pixman_format, - int width, int height, - cairo_bool_t might_reuse, - cairo_xcb_shm_info_t **shm_info_out) -{ - cairo_surface_t *image; - cairo_xcb_shm_info_t *shm_info; - cairo_int_status_t status; - size_t stride; - - *shm_info_out = NULL; - - stride = CAIRO_STRIDE_FOR_WIDTH_BPP (width, - PIXMAN_FORMAT_BPP (pixman_format)); - status = _cairo_xcb_connection_allocate_shm_info (connection, - stride * height, - might_reuse, - &shm_info); - if (unlikely (status)) { - if (status == CAIRO_INT_STATUS_UNSUPPORTED) - return NULL; - - return _cairo_surface_create_in_error (status); - } - - image = _cairo_image_surface_create_with_pixman_format (shm_info->mem, - pixman_format, - width, height, - stride); - if (unlikely (image->status)) { - _cairo_xcb_shm_info_destroy (shm_info); - return image; - } - - status = _cairo_user_data_array_set_data (&image->user_data, - (const cairo_user_data_key_t *) connection, - shm_info, - (cairo_destroy_func_t) _cairo_xcb_shm_info_destroy); - if (unlikely (status)) { - cairo_surface_destroy (image); - _cairo_xcb_shm_info_destroy (shm_info); - return _cairo_surface_create_in_error (status); - } - - *shm_info_out = shm_info; - return image; -} -#endif - -static cairo_surface_t * -_get_shm_image (cairo_xcb_surface_t *surface, - int x, int y, - int width, int height) -{ -#if CAIRO_HAS_XCB_SHM_FUNCTIONS - cairo_xcb_shm_info_t *shm_info; - cairo_surface_t *image; - cairo_status_t status; - - if ((surface->connection->flags & CAIRO_XCB_HAS_SHM) == 0) - return NULL; - - image = _cairo_xcb_surface_create_shm_image (surface->connection, - surface->pixman_format, - width, height, - TRUE, - &shm_info); - if (unlikely (image == NULL || image->status)) - goto done; - - status = _cairo_xcb_connection_shm_get_image (surface->connection, - surface->drawable, - x, y, - width, height, - shm_info->shm, - shm_info->offset); - if (unlikely (status)) { - cairo_surface_destroy (image); - image = _cairo_surface_create_in_error (status); - } - -done: - return image; -#else - return NULL; -#endif -} - -static cairo_surface_t * -_get_image (cairo_xcb_surface_t *surface, - cairo_bool_t use_shm, - int x, int y, - int width, int height) -{ - cairo_surface_t *image; - cairo_xcb_connection_t *connection; - xcb_get_image_reply_t *reply; - cairo_int_status_t status; - - assert (surface->fallback == NULL); - assert (x >= 0); - assert (y >= 0); - assert (x + width <= surface->width); - assert (y + height <= surface->height); - - if (surface->deferred_clear) { - image = - _cairo_image_surface_create_with_pixman_format (NULL, - surface->pixman_format, - width, height, - 0); - if (surface->deferred_clear_color.alpha_short > 0x00ff) { - cairo_solid_pattern_t solid; - - _cairo_pattern_init_solid (&solid, &surface->deferred_clear_color); - status = _cairo_surface_paint (image, - CAIRO_OPERATOR_SOURCE, - &solid.base, - NULL); - if (unlikely (status)) { - cairo_surface_destroy (image); - image = _cairo_surface_create_in_error (status); - } - } - return image; - } - - connection = surface->connection; - - status = _cairo_xcb_connection_acquire (connection); - if (unlikely (status)) - return _cairo_surface_create_in_error (status); - - if (use_shm) { - image = _get_shm_image (surface, x, y, width, height); - if (image) { - if (image->status == CAIRO_STATUS_SUCCESS) { - _cairo_xcb_connection_release (connection); - return image; - } - cairo_surface_destroy (image); - } - } - - reply =_cairo_xcb_connection_get_image (connection, - surface->drawable, - x, y, - width, height); - - if (reply == NULL && ! surface->owns_pixmap) { - /* xcb_get_image_t from a window is dangerous because it can - * produce errors if the window is unmapped or partially - * outside the screen. We could check for errors and - * retry, but to keep things simple, we just create a - * temporary pixmap - * - * If we hit this fallback too often, we should remember so and - * skip the round-trip from the above GetImage request, - * similar to what cairo-xlib does. - */ - xcb_pixmap_t pixmap; - xcb_gcontext_t gc; - - gc = _cairo_xcb_screen_get_gc (surface->screen, - surface->drawable, - surface->depth); - pixmap = _cairo_xcb_connection_create_pixmap (connection, - surface->depth, - surface->drawable, - width, height); - - /* XXX IncludeInferiors? */ - _cairo_xcb_connection_copy_area (connection, - surface->drawable, - pixmap, gc, - x, y, - 0, 0, - width, height); - - _cairo_xcb_screen_put_gc (surface->screen, surface->depth, gc); - - reply = _cairo_xcb_connection_get_image (connection, - pixmap, - 0, 0, - width, height); - _cairo_xcb_connection_free_pixmap (connection, pixmap); - } - - if (unlikely (reply == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto FAIL; - } - - /* XXX byte swap */ - /* XXX format conversion */ - assert (reply->depth == surface->depth); - - image = _cairo_image_surface_create_with_pixman_format - (xcb_get_image_data (reply), - surface->pixman_format, - width, height, - CAIRO_STRIDE_FOR_WIDTH_BPP (width, - PIXMAN_FORMAT_BPP (surface->pixman_format))); - status = image->status; - if (unlikely (status)) { - free (reply); - goto FAIL; - } - - /* XXX */ - pixman_image_set_destroy_function (((cairo_image_surface_t *)image)->pixman_image, _destroy_image, reply); - - _cairo_xcb_connection_release (connection); - - return image; - -FAIL: - _cairo_xcb_connection_release (connection); - return _cairo_surface_create_in_error (status); -} - -static cairo_surface_t * -_cairo_xcb_surface_source (void *abstract_surface, - cairo_rectangle_int_t *extents) -{ - cairo_xcb_surface_t *surface = abstract_surface; - - if (extents) { - extents->x = extents->y = 0; - extents->width = surface->width; - extents->height = surface->height; - } - - return &surface->base; -} - -static cairo_status_t -_cairo_xcb_surface_acquire_source_image (void *abstract_surface, - cairo_image_surface_t **image_out, - void **image_extra) -{ - cairo_xcb_surface_t *surface = abstract_surface; - cairo_surface_t *image; - - if (surface->fallback != NULL) { - image = cairo_surface_reference (&surface->fallback->base); - goto DONE; - } - - image = _cairo_surface_has_snapshot (&surface->base, - &_cairo_image_surface_backend); - if (image != NULL) { - image = cairo_surface_reference (image); - goto DONE; - } - - image = _get_image (surface, FALSE, 0, 0, surface->width, surface->height); - if (unlikely (image->status)) - return image->status; - - _cairo_surface_attach_snapshot (&surface->base, image, NULL); - -DONE: - *image_out = (cairo_image_surface_t *) image; - *image_extra = NULL; - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_xcb_surface_release_source_image (void *abstract_surface, - cairo_image_surface_t *image, - void *image_extra) -{ - cairo_surface_destroy (&image->base); -} - -cairo_bool_t -_cairo_xcb_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *extents) -{ - cairo_xcb_surface_t *surface = abstract_surface; - - extents->x = extents->y = 0; - extents->width = surface->width; - extents->height = surface->height; - return TRUE; -} - -static void -_cairo_xcb_surface_get_font_options (void *abstract_surface, - cairo_font_options_t *options) -{ - cairo_xcb_surface_t *surface = abstract_surface; - - *options = *_cairo_xcb_screen_get_font_options (surface->screen); -} - -static cairo_status_t -_put_shm_image (cairo_xcb_surface_t *surface, - xcb_gcontext_t gc, - cairo_image_surface_t *image) -{ -#if CAIRO_HAS_XCB_SHM_FUNCTIONS - cairo_xcb_shm_info_t *shm_info; - - shm_info = _cairo_user_data_array_get_data (&image->base.user_data, - (const cairo_user_data_key_t *) surface->connection); - if (shm_info == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - _cairo_xcb_connection_shm_put_image (surface->connection, - surface->drawable, - gc, - surface->width, surface->height, - 0, 0, - image->width, image->height, - image->base.device_transform_inverse.x0, - image->base.device_transform_inverse.y0, - image->depth, - shm_info->shm, - shm_info->offset); - - return CAIRO_STATUS_SUCCESS; -#else - return CAIRO_INT_STATUS_UNSUPPORTED; -#endif -} - -static cairo_status_t -_put_image (cairo_xcb_surface_t *surface, - cairo_image_surface_t *image) -{ - cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS; - - /* XXX track damaged region? */ - - status = _cairo_xcb_connection_acquire (surface->connection); - if (unlikely (status)) - return status; - - if (image->pixman_format == surface->pixman_format) { - xcb_gcontext_t gc; - - assert (image->depth == surface->depth); - assert (image->stride == (int) CAIRO_STRIDE_FOR_WIDTH_BPP (image->width, PIXMAN_FORMAT_BPP (image->pixman_format))); - - gc = _cairo_xcb_screen_get_gc (surface->screen, - surface->drawable, - surface->depth); - - status = _put_shm_image (surface, gc, image); - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - _cairo_xcb_connection_put_image (surface->connection, - surface->drawable, gc, - image->width, image->height, - image->base.device_transform_inverse.x0, - image->base.device_transform_inverse.y0, - image->depth, - image->stride, - image->data); - status = CAIRO_STATUS_SUCCESS; - } - - _cairo_xcb_screen_put_gc (surface->screen, surface->depth, gc); - } else { - ASSERT_NOT_REACHED; - } - - _cairo_xcb_connection_release (surface->connection); - return status; -} - -static cairo_int_status_t -_put_shm_image_boxes (cairo_xcb_surface_t *surface, - cairo_image_surface_t *image, - xcb_gcontext_t gc, - cairo_boxes_t *boxes) -{ -#if CAIRO_HAS_XCB_SHM_FUNCTIONS - cairo_xcb_shm_info_t *shm_info; - - shm_info = _cairo_user_data_array_get_data (&image->base.user_data, - (const cairo_user_data_key_t *) surface->connection); - if (shm_info != NULL) { - struct _cairo_boxes_chunk *chunk; - - for (chunk = &boxes->chunks; chunk; chunk = chunk->next) { - int i; - - for (i = 0; i < chunk->count; i++) { - cairo_box_t *b = &chunk->base[i]; - int x = _cairo_fixed_integer_part (b->p1.x); - int y = _cairo_fixed_integer_part (b->p1.y); - int width = _cairo_fixed_integer_part (b->p2.x - b->p1.x); - int height = _cairo_fixed_integer_part (b->p2.y - b->p1.y); - - _cairo_xcb_connection_shm_put_image (surface->connection, - surface->drawable, - gc, - surface->width, surface->height, - x, y, - width, height, - x, y, - image->depth, - shm_info->shm, - shm_info->offset); - } - } - return CAIRO_INT_STATUS_SUCCESS; - } -#endif - - return CAIRO_INT_STATUS_UNSUPPORTED; -} - -static cairo_status_t -_put_image_boxes (cairo_xcb_surface_t *surface, - cairo_image_surface_t *image, - cairo_boxes_t *boxes) -{ - cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS; - xcb_gcontext_t gc; - - if (boxes->num_boxes == 0) - return CAIRO_STATUS_SUCCESS; - - /* XXX track damaged region? */ - - status = _cairo_xcb_connection_acquire (surface->connection); - if (unlikely (status)) - return status; - - assert (image->pixman_format == surface->pixman_format); - assert (image->depth == surface->depth); - assert (image->stride == (int) CAIRO_STRIDE_FOR_WIDTH_BPP (image->width, PIXMAN_FORMAT_BPP (image->pixman_format))); - - gc = _cairo_xcb_screen_get_gc (surface->screen, - surface->drawable, - surface->depth); - - status = _put_shm_image_boxes (surface, image, gc, boxes); - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - struct _cairo_boxes_chunk *chunk; - - for (chunk = &boxes->chunks; chunk; chunk = chunk->next) { - int i; - - for (i = 0; i < chunk->count; i++) { - cairo_box_t *b = &chunk->base[i]; - int x = _cairo_fixed_integer_part (b->p1.x); - int y = _cairo_fixed_integer_part (b->p1.y); - int width = _cairo_fixed_integer_part (b->p2.x - b->p1.x); - int height = _cairo_fixed_integer_part (b->p2.y - b->p1.y); - _cairo_xcb_connection_put_subimage (surface->connection, - surface->drawable, gc, - x, y, - width, height, - PIXMAN_FORMAT_BPP (image->pixman_format) / 8, - image->stride, - x, y, - image->depth, - image->data); - - } - } - status = CAIRO_STATUS_SUCCESS; - } - - _cairo_xcb_screen_put_gc (surface->screen, surface->depth, gc); - _cairo_xcb_connection_release (surface->connection); - return status; -} - -static cairo_status_t -_cairo_xcb_surface_flush (void *abstract_surface, - unsigned flags) -{ - cairo_xcb_surface_t *surface = abstract_surface; - cairo_status_t status; - - if (flags) - return CAIRO_STATUS_SUCCESS; - - if (likely (surface->fallback == NULL)) { - status = CAIRO_STATUS_SUCCESS; - if (! surface->base.finished && surface->deferred_clear) - status = _cairo_xcb_surface_clear (surface); - - return status; - } - - status = surface->base.status; - if (status == CAIRO_STATUS_SUCCESS && - (! surface->base._finishing || ! surface->owns_pixmap)) { - status = cairo_surface_status (&surface->fallback->base); - - if (status == CAIRO_STATUS_SUCCESS) - status = _cairo_bentley_ottmann_tessellate_boxes (&surface->fallback_damage, - CAIRO_FILL_RULE_WINDING, - &surface->fallback_damage); - - if (status == CAIRO_STATUS_SUCCESS) - status = _put_image_boxes (surface, - surface->fallback, - &surface->fallback_damage); - - if (status == CAIRO_STATUS_SUCCESS && ! surface->base._finishing) { - _cairo_surface_attach_snapshot (&surface->base, - &surface->fallback->base, - cairo_surface_finish); - } - } - - _cairo_boxes_clear (&surface->fallback_damage); - cairo_surface_destroy (&surface->fallback->base); - surface->fallback = NULL; - - return status; -} - -static cairo_image_surface_t * -_cairo_xcb_surface_map_to_image (void *abstract_surface, - const cairo_rectangle_int_t *extents) -{ - cairo_xcb_surface_t *surface = abstract_surface; - cairo_surface_t *image; - cairo_status_t status; - - if (surface->fallback) - return _cairo_surface_map_to_image (&surface->fallback->base, extents); - - image = _get_image (surface, TRUE, - extents->x, extents->y, - extents->width, extents->height); - status = cairo_surface_status (image); - if (unlikely (status)) { - cairo_surface_destroy(image); - return _cairo_image_surface_create_in_error (status); - } - - /* Do we have a deferred clear and this image surface does NOT cover the - * whole xcb surface? Have to apply the clear in that case, else - * uploading the image will handle the problem for us. - */ - if (surface->deferred_clear && - ! (extents->width == surface->width && - extents->height == surface->height)) { - status = _cairo_xcb_surface_clear (surface); - if (unlikely (status)) { - cairo_surface_destroy(image); - return _cairo_image_surface_create_in_error (status); - } - } - surface->deferred_clear = FALSE; - - cairo_surface_set_device_offset (image, -extents->x, -extents->y); - return (cairo_image_surface_t *) image; -} - -static cairo_int_status_t -_cairo_xcb_surface_unmap (void *abstract_surface, - cairo_image_surface_t *image) -{ - cairo_xcb_surface_t *surface = abstract_surface; - cairo_int_status_t status; - - if (surface->fallback) - return _cairo_surface_unmap_image (&surface->fallback->base, image); - - status = _put_image (abstract_surface, image); - - cairo_surface_finish (&image->base); - cairo_surface_destroy (&image->base); - - return status; -} - -static cairo_surface_t * -_cairo_xcb_surface_fallback (cairo_xcb_surface_t *surface, - cairo_composite_rectangles_t *composite) -{ - cairo_image_surface_t *image; - cairo_status_t status; - - status = _cairo_composite_rectangles_add_to_damage (composite, - &surface->fallback_damage); - if (unlikely (status)) - return _cairo_surface_create_in_error (status); - - if (surface->fallback) - return &surface->fallback->base; - - image = (cairo_image_surface_t *) - _get_image (surface, TRUE, 0, 0, surface->width, surface->height); - - /* If there was a deferred clear, _get_image applied it */ - if (image->base.status == CAIRO_STATUS_SUCCESS) { - surface->deferred_clear = FALSE; - - surface->fallback = image; - } - - return &surface->fallback->base; -} - -static cairo_int_status_t -_cairo_xcb_fallback_compositor_paint (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *extents) -{ - cairo_xcb_surface_t *surface = (cairo_xcb_surface_t *) extents->surface; - cairo_surface_t *fallback = _cairo_xcb_surface_fallback (surface, extents); - - return _cairo_surface_paint (fallback, extents->op, - &extents->source_pattern.base, - extents->clip); -} - -static cairo_int_status_t -_cairo_xcb_fallback_compositor_mask (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *extents) -{ - cairo_xcb_surface_t *surface = (cairo_xcb_surface_t *) extents->surface; - cairo_surface_t *fallback = _cairo_xcb_surface_fallback (surface, extents); - - return _cairo_surface_mask (fallback, extents->op, - &extents->source_pattern.base, - &extents->mask_pattern.base, - extents->clip); -} - -static cairo_int_status_t -_cairo_xcb_fallback_compositor_stroke (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_xcb_surface_t *surface = (cairo_xcb_surface_t *) extents->surface; - cairo_surface_t *fallback = _cairo_xcb_surface_fallback (surface, extents); - - return _cairo_surface_stroke (fallback, extents->op, - &extents->source_pattern.base, - path, style, ctm, ctm_inverse, - tolerance, antialias, - extents->clip); -} - -static cairo_int_status_t -_cairo_xcb_fallback_compositor_fill (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_xcb_surface_t *surface = (cairo_xcb_surface_t *) extents->surface; - cairo_surface_t *fallback = _cairo_xcb_surface_fallback (surface, extents); - - return _cairo_surface_fill (fallback, extents->op, - &extents->source_pattern.base, - path, fill_rule, tolerance, - antialias, extents->clip); -} - -static cairo_int_status_t -_cairo_xcb_fallback_compositor_glyphs (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_bool_t overlap) -{ - cairo_xcb_surface_t *surface = (cairo_xcb_surface_t *) extents->surface; - cairo_surface_t *fallback = _cairo_xcb_surface_fallback (surface, extents); - - return _cairo_surface_show_text_glyphs (fallback, extents->op, - &extents->source_pattern.base, - NULL, 0, glyphs, num_glyphs, - NULL, 0, 0, - scaled_font, extents->clip); -} - -static const cairo_compositor_t _cairo_xcb_fallback_compositor = { - &__cairo_no_compositor, - - _cairo_xcb_fallback_compositor_paint, - _cairo_xcb_fallback_compositor_mask, - _cairo_xcb_fallback_compositor_stroke, - _cairo_xcb_fallback_compositor_fill, - _cairo_xcb_fallback_compositor_glyphs, -}; - -static const cairo_compositor_t _cairo_xcb_render_compositor = { - &_cairo_xcb_fallback_compositor, - - _cairo_xcb_render_compositor_paint, - _cairo_xcb_render_compositor_mask, - _cairo_xcb_render_compositor_stroke, - _cairo_xcb_render_compositor_fill, - _cairo_xcb_render_compositor_glyphs, -}; - -static inline const cairo_compositor_t * -get_compositor (cairo_surface_t **s) -{ - cairo_xcb_surface_t *surface = (cairo_xcb_surface_t * )*s; - if (surface->fallback) { - *s = &surface->fallback->base; - return ((cairo_image_surface_t *) *s)->compositor; - } - - return &_cairo_xcb_render_compositor; -} - -static cairo_int_status_t -_cairo_xcb_surface_paint (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - cairo_surface_t *surface = abstract_surface; - const cairo_compositor_t *compositor = get_compositor (&surface); - return _cairo_compositor_paint (compositor, surface, op, source, clip); -} - -static cairo_int_status_t -_cairo_xcb_surface_mask (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - cairo_surface_t *surface = abstract_surface; - const cairo_compositor_t *compositor = get_compositor (&surface); - return _cairo_compositor_mask (compositor, surface, op, source, mask, clip); -} - -static cairo_int_status_t -_cairo_xcb_surface_stroke (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_surface_t *surface = abstract_surface; - const cairo_compositor_t *compositor = get_compositor (&surface); - return _cairo_compositor_stroke (compositor, surface, op, source, - path, style, ctm, ctm_inverse, - tolerance, antialias, clip); -} - -static cairo_int_status_t -_cairo_xcb_surface_fill (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t*path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_surface_t *surface = abstract_surface; - const cairo_compositor_t *compositor = get_compositor (&surface); - return _cairo_compositor_fill (compositor, surface, op, - source, path, fill_rule, - tolerance, antialias, clip); -} - -static cairo_int_status_t -_cairo_xcb_surface_glyphs (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - cairo_surface_t *surface = abstract_surface; - const cairo_compositor_t *compositor = get_compositor (&surface); - return _cairo_compositor_glyphs (compositor, surface, op, - source, glyphs, num_glyphs, - scaled_font, clip); -} - -const cairo_surface_backend_t _cairo_xcb_surface_backend = { - CAIRO_SURFACE_TYPE_XCB, - _cairo_xcb_surface_finish, - _cairo_default_context_create, - - _cairo_xcb_surface_create_similar, - _cairo_xcb_surface_create_similar_image, - _cairo_xcb_surface_map_to_image, - _cairo_xcb_surface_unmap, - - _cairo_xcb_surface_source, - _cairo_xcb_surface_acquire_source_image, - _cairo_xcb_surface_release_source_image, - NULL, /* snapshot */ - - - NULL, /* copy_page */ - NULL, /* show_page */ - - _cairo_xcb_surface_get_extents, - _cairo_xcb_surface_get_font_options, - - _cairo_xcb_surface_flush, - NULL, - - _cairo_xcb_surface_paint, - _cairo_xcb_surface_mask, - _cairo_xcb_surface_stroke, - _cairo_xcb_surface_fill, - NULL, /* fill-stroke */ - _cairo_xcb_surface_glyphs, -}; - -cairo_surface_t * -_cairo_xcb_surface_create_internal (cairo_xcb_screen_t *screen, - xcb_drawable_t drawable, - cairo_bool_t owns_pixmap, - pixman_format_code_t pixman_format, - xcb_render_pictformat_t xrender_format, - int width, - int height) -{ - cairo_xcb_surface_t *surface; - - surface = malloc (sizeof (cairo_xcb_surface_t)); - if (unlikely (surface == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - _cairo_surface_init (&surface->base, - &_cairo_xcb_surface_backend, - &screen->connection->device, - _cairo_content_from_pixman_format (pixman_format)); - - surface->connection = _cairo_xcb_connection_reference (screen->connection); - surface->screen = screen; - cairo_list_add (&surface->link, &screen->surfaces); - - surface->drawable = drawable; - surface->owns_pixmap = owns_pixmap; - - surface->deferred_clear = FALSE; - surface->deferred_clear_color = *CAIRO_COLOR_TRANSPARENT; - - surface->width = width; - surface->height = height; - surface->depth = PIXMAN_FORMAT_DEPTH (pixman_format); - - surface->picture = XCB_NONE; - if (screen->connection->force_precision != -1) - surface->precision = screen->connection->force_precision; - else - surface->precision = XCB_RENDER_POLY_MODE_IMPRECISE; - - surface->pixman_format = pixman_format; - surface->xrender_format = xrender_format; - - surface->fallback = NULL; - _cairo_boxes_init (&surface->fallback_damage); - - return &surface->base; -} - -static xcb_screen_t * -_cairo_xcb_screen_from_visual (xcb_connection_t *connection, - xcb_visualtype_t *visual, - int *depth) -{ - xcb_depth_iterator_t d; - xcb_screen_iterator_t s; - - s = xcb_setup_roots_iterator (xcb_get_setup (connection)); - for (; s.rem; xcb_screen_next (&s)) { - if (s.data->root_visual == visual->visual_id) { - *depth = s.data->root_depth; - return s.data; - } - - d = xcb_screen_allowed_depths_iterator(s.data); - for (; d.rem; xcb_depth_next (&d)) { - xcb_visualtype_iterator_t v = xcb_depth_visuals_iterator (d.data); - - for (; v.rem; xcb_visualtype_next (&v)) { - if (v.data->visual_id == visual->visual_id) { - *depth = d.data->depth; - return s.data; - } - } - } - } - - return NULL; -} - -/** - * cairo_xcb_surface_create: - * @connection: an XCB connection - * @drawable: an XCB drawable - * @visual: the visual to use for drawing to @drawable. The depth - * of the visual must match the depth of the drawable. - * Currently, only TrueColor visuals are fully supported. - * @width: the current width of @drawable - * @height: the current height of @drawable - * - * Creates an XCB surface that draws to the given drawable. - * The way that colors are represented in the drawable is specified - * by the provided visual. - * - * Note: If @drawable is a Window, then the function - * cairo_xcb_surface_set_size() must be called whenever the size of the - * window changes. - * - * When @drawable is a Window containing child windows then drawing to - * the created surface will be clipped by those child windows. When - * the created surface is used as a source, the contents of the - * children will be included. - * - * Return value: a pointer to the newly created surface. The caller - * owns the surface and should call cairo_surface_destroy() when done - * with it. - * - * This function always returns a valid pointer, but it will return a - * pointer to a "nil" surface if an error such as out of memory - * occurs. You can use cairo_surface_status() to check for this. - * - * Since: 1.12 - **/ -cairo_surface_t * -cairo_xcb_surface_create (xcb_connection_t *connection, - xcb_drawable_t drawable, - xcb_visualtype_t *visual, - int width, - int height) -{ - cairo_xcb_screen_t *screen; - xcb_screen_t *xcb_screen; - cairo_format_masks_t image_masks; - pixman_format_code_t pixman_format; - xcb_render_pictformat_t xrender_format; - int depth; - - if (xcb_connection_has_error (connection)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_WRITE_ERROR)); - - if (unlikely (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE)); - if (unlikely (width <= 0 || height <= 0)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE)); - - xcb_screen = _cairo_xcb_screen_from_visual (connection, visual, &depth); - if (unlikely (xcb_screen == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL)); - - image_masks.alpha_mask = 0; - image_masks.red_mask = visual->red_mask; - image_masks.green_mask = visual->green_mask; - image_masks.blue_mask = visual->blue_mask; - if (depth == 32) /* XXX visuals have no alpha! */ - image_masks.alpha_mask = - 0xffffffff & ~(visual->red_mask | visual->green_mask | visual->blue_mask); - if (depth > 16) - image_masks.bpp = 32; - else if (depth > 8) - image_masks.bpp = 16; - else if (depth > 1) - image_masks.bpp = 8; - else - image_masks.bpp = 1; - - if (! _pixman_format_from_masks (&image_masks, &pixman_format)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT)); - - screen = _cairo_xcb_screen_get (connection, xcb_screen); - if (unlikely (screen == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - xrender_format = - _cairo_xcb_connection_get_xrender_format_for_visual (screen->connection, - visual->visual_id); - - return _cairo_xcb_surface_create_internal (screen, drawable, FALSE, - pixman_format, - xrender_format, - width, height); -} -#if CAIRO_HAS_XLIB_XCB_FUNCTIONS -slim_hidden_def (cairo_xcb_surface_create); -#endif - -/** - * cairo_xcb_surface_create_for_bitmap: - * @connection: an XCB connection - * @screen: the XCB screen associated with @bitmap - * @bitmap: an XCB drawable (a Pixmap with depth 1) - * @width: the current width of @bitmap - * @height: the current height of @bitmap - * - * Creates an XCB surface that draws to the given bitmap. - * This will be drawn to as a %CAIRO_FORMAT_A1 object. - * - * Return value: a pointer to the newly created surface. The caller - * owns the surface and should call cairo_surface_destroy() when done - * with it. - * - * This function always returns a valid pointer, but it will return a - * pointer to a "nil" surface if an error such as out of memory - * occurs. You can use cairo_surface_status() to check for this. - * - * Since: 1.12 - **/ -cairo_surface_t * -cairo_xcb_surface_create_for_bitmap (xcb_connection_t *connection, - xcb_screen_t *screen, - xcb_pixmap_t bitmap, - int width, - int height) -{ - cairo_xcb_screen_t *cairo_xcb_screen; - - if (xcb_connection_has_error (connection)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_WRITE_ERROR)); - - if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE)); - if (unlikely (width <= 0 || height <= 0)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE)); - - cairo_xcb_screen = _cairo_xcb_screen_get (connection, screen); - if (unlikely (cairo_xcb_screen == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - return _cairo_xcb_surface_create_internal (cairo_xcb_screen, bitmap, FALSE, - PIXMAN_a1, - cairo_xcb_screen->connection->standard_formats[CAIRO_FORMAT_A1], - width, height); -} -#if CAIRO_HAS_XLIB_XCB_FUNCTIONS -slim_hidden_def (cairo_xcb_surface_create_for_bitmap); -#endif - -/** - * cairo_xcb_surface_create_with_xrender_format: - * @connection: an XCB connection - * @drawable: an XCB drawable - * @screen: the XCB screen associated with @drawable - * @format: the picture format to use for drawing to @drawable. The - * depth of @format mush match the depth of the drawable. - * @width: the current width of @drawable - * @height: the current height of @drawable - * - * Creates an XCB surface that draws to the given drawable. - * The way that colors are represented in the drawable is specified - * by the provided picture format. - * - * Note: If @drawable is a Window, then the function - * cairo_xcb_surface_set_size() must be called whenever the size of the - * window changes. - * - * When @drawable is a Window containing child windows then drawing to - * the created surface will be clipped by those child windows. When - * the created surface is used as a source, the contents of the - * children will be included. - * - * Return value: a pointer to the newly created surface. The caller - * owns the surface and should call cairo_surface_destroy() when done - * with it. - * - * This function always returns a valid pointer, but it will return a - * pointer to a "nil" surface if an error such as out of memory - * occurs. You can use cairo_surface_status() to check for this. - * - * Since: 1.12 - **/ -cairo_surface_t * -cairo_xcb_surface_create_with_xrender_format (xcb_connection_t *connection, - xcb_screen_t *screen, - xcb_drawable_t drawable, - xcb_render_pictforminfo_t *format, - int width, - int height) -{ - cairo_xcb_screen_t *cairo_xcb_screen; - cairo_format_masks_t image_masks; - pixman_format_code_t pixman_format; - - if (xcb_connection_has_error (connection)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_WRITE_ERROR)); - - if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE)); - if (unlikely (width <= 0 || height <= 0)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE)); - - image_masks.alpha_mask = - (unsigned long) format->direct.alpha_mask << format->direct.alpha_shift; - image_masks.red_mask = - (unsigned long) format->direct.red_mask << format->direct.red_shift; - image_masks.green_mask = - (unsigned long) format->direct.green_mask << format->direct.green_shift; - image_masks.blue_mask = - (unsigned long) format->direct.blue_mask << format->direct.blue_shift; -#if 0 - image_masks.bpp = format->depth; -#else - if (format->depth > 16) - image_masks.bpp = 32; - else if (format->depth > 8) - image_masks.bpp = 16; - else if (format->depth > 1) - image_masks.bpp = 8; - else - image_masks.bpp = 1; -#endif - - if (! _pixman_format_from_masks (&image_masks, &pixman_format)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT)); - - cairo_xcb_screen = _cairo_xcb_screen_get (connection, screen); - if (unlikely (cairo_xcb_screen == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - return _cairo_xcb_surface_create_internal (cairo_xcb_screen, - drawable, - FALSE, - pixman_format, - format->id, - width, height); -} -#if CAIRO_HAS_XLIB_XCB_FUNCTIONS -slim_hidden_def (cairo_xcb_surface_create_with_xrender_format); -#endif - -/* This does the necessary fixup when a surface's drawable or size changed. */ -static void -_drawable_changed (cairo_xcb_surface_t *surface) -{ - _cairo_surface_set_error (&surface->base, - _cairo_surface_begin_modification (&surface->base)); - _cairo_boxes_clear (&surface->fallback_damage); - cairo_surface_destroy (&surface->fallback->base); - - surface->deferred_clear = FALSE; - surface->fallback = NULL; -} - -/** - * cairo_xcb_surface_set_size: - * @surface: a #cairo_surface_t for the XCB backend - * @width: the new width of the surface - * @height: the new height of the surface - * - * Informs cairo of the new size of the XCB drawable underlying the - * surface. For a surface created for a window (rather than a pixmap), - * this function must be called each time the size of the window - * changes. (For a subwindow, you are normally resizing the window - * yourself, but for a toplevel window, it is necessary to listen for - * ConfigureNotify events.) - * - * A pixmap can never change size, so it is never necessary to call - * this function on a surface created for a pixmap. - * - * If cairo_surface_flush() wasn't called, some pending operations - * might be discarded. - * - * Since: 1.12 - **/ -void -cairo_xcb_surface_set_size (cairo_surface_t *abstract_surface, - int width, - int height) -{ - cairo_xcb_surface_t *surface; - - if (unlikely (abstract_surface->status)) - return; - if (unlikely (abstract_surface->finished)) { - _cairo_surface_set_error (abstract_surface, - _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - return; - } - - - if ( !_cairo_surface_is_xcb(abstract_surface)) { - _cairo_surface_set_error (abstract_surface, - _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH)); - return; - } - - if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX || width <= 0 || height <= 0) { - _cairo_surface_set_error (abstract_surface, - _cairo_error (CAIRO_STATUS_INVALID_SIZE)); - return; - } - - surface = (cairo_xcb_surface_t *) abstract_surface; - - _drawable_changed(surface); - surface->width = width; - surface->height = height; -} -#if CAIRO_HAS_XLIB_XCB_FUNCTIONS -slim_hidden_def (cairo_xcb_surface_set_size); -#endif - -/** - * cairo_xcb_surface_set_drawable: - * @surface: a #cairo_surface_t for the XCB backend - * @drawable: the new drawable of the surface - * @width: the new width of the surface - * @height: the new height of the surface - * - * Informs cairo of the new drawable and size of the XCB drawable underlying the - * surface. - * - * If cairo_surface_flush() wasn't called, some pending operations - * might be discarded. - * - * Since: 1.12 - **/ -void -cairo_xcb_surface_set_drawable (cairo_surface_t *abstract_surface, - xcb_drawable_t drawable, - int width, - int height) -{ - cairo_xcb_surface_t *surface; - - if (unlikely (abstract_surface->status)) - return; - if (unlikely (abstract_surface->finished)) { - _cairo_surface_set_error (abstract_surface, - _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - return; - } - - - if ( !_cairo_surface_is_xcb(abstract_surface)) { - _cairo_surface_set_error (abstract_surface, - _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH)); - return; - } - - if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX || width <= 0 || height <= 0) { - _cairo_surface_set_error (abstract_surface, - _cairo_error (CAIRO_STATUS_INVALID_SIZE)); - return; - } - - surface = (cairo_xcb_surface_t *) abstract_surface; - - /* XXX: and what about this case? */ - if (surface->owns_pixmap) - return; - - _drawable_changed (surface); - - if (surface->drawable != drawable) { - cairo_status_t status; - status = _cairo_xcb_connection_acquire (surface->connection); - if (unlikely (status)) - return; - - if (surface->picture != XCB_NONE) { - _cairo_xcb_connection_render_free_picture (surface->connection, - surface->picture); - surface->picture = XCB_NONE; - } - - _cairo_xcb_connection_release (surface->connection); - - surface->drawable = drawable; - } - surface->width = width; - surface->height = height; -} -#if CAIRO_HAS_XLIB_XCB_FUNCTIONS -slim_hidden_def (cairo_xcb_surface_set_drawable); -#endif diff --git a/source/libs/cairo/cairo-src/src/cairo-xcb.h b/source/libs/cairo/cairo-src/src/cairo-xcb.h deleted file mode 100644 index e321d8482c2fd180600cca44c328d3b2651d8f55..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xcb.h +++ /dev/null @@ -1,116 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_XCB_H -#define CAIRO_XCB_H - -#include "cairo.h" - -#if CAIRO_HAS_XCB_SURFACE - -#include <xcb/xcb.h> -#include <xcb/render.h> - -CAIRO_BEGIN_DECLS - -cairo_public cairo_surface_t * -cairo_xcb_surface_create (xcb_connection_t *connection, - xcb_drawable_t drawable, - xcb_visualtype_t *visual, - int width, - int height); - -cairo_public cairo_surface_t * -cairo_xcb_surface_create_for_bitmap (xcb_connection_t *connection, - xcb_screen_t *screen, - xcb_pixmap_t bitmap, - int width, - int height); - -cairo_public cairo_surface_t * -cairo_xcb_surface_create_with_xrender_format (xcb_connection_t *connection, - xcb_screen_t *screen, - xcb_drawable_t drawable, - xcb_render_pictforminfo_t *format, - int width, - int height); - -cairo_public void -cairo_xcb_surface_set_size (cairo_surface_t *surface, - int width, - int height); - -cairo_public void -cairo_xcb_surface_set_drawable (cairo_surface_t *surface, - xcb_drawable_t drawable, - int width, - int height); - -cairo_public xcb_connection_t * -cairo_xcb_device_get_connection (cairo_device_t *device); - -/* debug interface */ - -cairo_public void -cairo_xcb_device_debug_cap_xshm_version (cairo_device_t *device, - int major_version, - int minor_version); - -cairo_public void -cairo_xcb_device_debug_cap_xrender_version (cairo_device_t *device, - int major_version, - int minor_version); - -/* - * @precision: -1 implies automatically choose based on antialiasing mode, - * any other value overrides and sets the corresponding PolyMode. - */ -cairo_public void -cairo_xcb_device_debug_set_precision (cairo_device_t *device, - int precision); - -cairo_public int -cairo_xcb_device_debug_get_precision (cairo_device_t *device); - -CAIRO_END_DECLS - -#else /* CAIRO_HAS_XCB_SURFACE */ -# error Cairo was not compiled with support for the xcb backend -#endif /* CAIRO_HAS_XCB_SURFACE */ - -#endif /* CAIRO_XCB_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-xlib-core-compositor.c b/source/libs/cairo/cairo-src/src/cairo-xlib-core-compositor.c deleted file mode 100644 index 5babcc81bed61fcb16c9e10b3ceda6b635213a66..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xlib-core-compositor.c +++ /dev/null @@ -1,650 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Behdad Esfahbod <behdad@behdad.org> - * Chris Wilson <chris@chris-wilson.co.uk> - * Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation - */ - -/* The original X drawing API was very restrictive in what it could handle, - * pixel-aligned fill/blits are all that map into Cairo's drawing model. - */ - -#include "cairoint.h" - -#if !CAIRO_HAS_XLIB_XCB_FUNCTIONS - -#include "cairo-xlib-private.h" -#include "cairo-xlib-surface-private.h" - -#include "cairo-boxes-private.h" -#include "cairo-clip-inline.h" -#include "cairo-compositor-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-pattern-private.h" -#include "cairo-region-private.h" -#include "cairo-surface-offset-private.h" - -/* the low-level interface */ - -static cairo_int_status_t -acquire (void *abstract_dst) -{ - cairo_xlib_surface_t *dst = abstract_dst; - return _cairo_xlib_display_acquire (dst->base.device, &dst->display); -} - -static cairo_int_status_t -release (void *abstract_dst) -{ - cairo_xlib_surface_t *dst = abstract_dst; - - cairo_device_release (&dst->display->base); - dst->display = NULL; - - return CAIRO_STATUS_SUCCESS; -} - -struct _fill_box { - Display *dpy; - Drawable drawable; - GC gc; - //cairo_surface_t *dither = NULL; -}; - -static cairo_bool_t fill_box (cairo_box_t *box, void *closure) -{ - struct _fill_box *data = closure; - int x = _cairo_fixed_integer_part (box->p1.x); - int y = _cairo_fixed_integer_part (box->p1.y); - int width = _cairo_fixed_integer_part (box->p2.x - box->p1.x); - int height = _cairo_fixed_integer_part (box->p2.y - box->p1.y); - - XFillRectangle (data->dpy, data->drawable, data->gc, x, y, width, height); - return TRUE; -} - -static void -_characterize_field (uint32_t mask, int *width, int *shift) -{ - *width = _cairo_popcount (mask); - /* The final '& 31' is to force a 0 mask to result in 0 shift. */ - *shift = _cairo_popcount ((mask - 1) & ~mask) & 31; -} - -static uint32_t -color_to_pixel (cairo_xlib_surface_t *dst, - const cairo_color_t *color) -{ - uint32_t rgba = 0; - int width, shift; - - _characterize_field (dst->a_mask, &width, &shift); - rgba |= color->alpha_short >> (16 - width) << shift; - - _characterize_field (dst->r_mask, &width, &shift); - rgba |= color->red_short >> (16 - width) << shift; - - _characterize_field (dst->g_mask, &width, &shift); - rgba |= color->green_short >> (16 - width) << shift; - - _characterize_field (dst->b_mask, &width, &shift); - rgba |= color->blue_short >> (16 - width) << shift; - - return rgba; -} - -static cairo_int_status_t -_fill_box_init (struct _fill_box *fb, - cairo_xlib_surface_t *dst, - const cairo_color_t *color) -{ - cairo_int_status_t status; - - status = _cairo_xlib_surface_get_gc (dst->display, dst, &fb->gc); - if (unlikely (status)) - return status; - - fb->dpy = dst->display->display; - fb->drawable = dst->drawable; - - if (dst->visual && dst->visual->class != TrueColor && 0) { -#if 0 - cairo_solid_pattern_t solid; - cairo_surface_attributes_t attrs; - - _cairo_pattern_init_solid (&solid, color); - status = _cairo_pattern_acquire_surface (&solid.base, &dst->base, - 0, 0, - ARRAY_LENGTH (dither_pattern[0]), - ARRAY_LENGTH (dither_pattern), - CAIRO_PATTERN_ACQUIRE_NONE, - &dither, - &attrs); - if (unlikely (status)) { - _cairo_xlib_surface_put_gc (dst->display, dst, fb.gc); - return status; - } - - XSetTSOrigin (fb->dpy, fb->gc, - - (dst->base.device_transform.x0 + attrs.x_offset), - - (dst->base.device_transform.y0 + attrs.y_offset)); - XSetTile (fb->dpy, fb->gc, ((cairo_xlib_surface_t *) dither)->drawable); -#endif - } else { - XGCValues gcv; - - gcv.foreground = color_to_pixel (dst, color); - gcv.fill_style = FillSolid; - - XChangeGC (fb->dpy, fb->gc, GCFillStyle | GCForeground, &gcv); - } - - return CAIRO_INT_STATUS_SUCCESS; -} - -static void -_fill_box_fini (struct _fill_box *fb, - cairo_xlib_surface_t *dst) -{ - _cairo_xlib_surface_put_gc (dst->display, dst, fb->gc); - //cairo_surface_destroy (fb->dither); -} - -cairo_int_status_t -_cairo_xlib_core_fill_boxes (cairo_xlib_surface_t *dst, - const cairo_color_t *color, - cairo_boxes_t *boxes) -{ - cairo_int_status_t status; - struct _fill_box fb; - - status = _fill_box_init (&fb, dst, color); - if (unlikely (status)) - return status; - - _cairo_boxes_for_each_box (boxes, fill_box, &fb); - - _fill_box_fini (&fb, dst); - return CAIRO_STATUS_SUCCESS; -} - -cairo_int_status_t -_cairo_xlib_core_fill_rectangles (cairo_xlib_surface_t *dst, - const cairo_color_t *color, - int num_rects, - cairo_rectangle_int_t *rects) -{ - cairo_int_status_t status; - struct _fill_box fb; - int i; - - status = _fill_box_init (&fb, dst, color); - if (unlikely (status)) - return status; - - for (i = 0; i < num_rects; i++) - XFillRectangle (fb.dpy, fb.drawable, fb.gc, - rects[i].x, rects[i].y, - rects[i].width, rects[i].height); - - _fill_box_fini (&fb, dst); - return CAIRO_STATUS_SUCCESS; -} - -struct _fallback_box { - cairo_xlib_surface_t *dst; - cairo_format_t format; - const cairo_pattern_t *pattern; -}; - -static cairo_bool_t fallback_box (cairo_box_t *box, void *closure) -{ - struct _fallback_box *data = closure; - int x = _cairo_fixed_integer_part (box->p1.x); - int y = _cairo_fixed_integer_part (box->p1.y); - int width = _cairo_fixed_integer_part (box->p2.x - box->p1.x); - int height = _cairo_fixed_integer_part (box->p2.y - box->p1.y); - cairo_surface_t *image; - cairo_status_t status; - - /* XXX for EXTEND_NONE and if the box is wholly outside we can just fill */ - - image = cairo_surface_create_similar_image (&data->dst->base, data->format, - width, height); - status = _cairo_surface_offset_paint (image, x, y, - CAIRO_OPERATOR_SOURCE, - data->pattern, NULL); - if (status == CAIRO_STATUS_SUCCESS) { - status = _cairo_xlib_surface_draw_image (data->dst, - (cairo_image_surface_t *)image, - 0, 0, - width, height, - x, y); - } - cairo_surface_destroy (image); - - return status == CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -fallback_boxes (cairo_xlib_surface_t *dst, - const cairo_pattern_t *pattern, - cairo_boxes_t *boxes) -{ - struct _fallback_box fb; - - /* XXX create_similar_image using pixman_format? */ - switch (dst->depth) { - case 8: fb.format = CAIRO_FORMAT_A8; break; - case 16: fb.format = CAIRO_FORMAT_RGB16_565; break; - case 24: fb.format = CAIRO_FORMAT_RGB24; break; - case 30: fb.format = CAIRO_FORMAT_RGB30; break; - case 32: fb.format = CAIRO_FORMAT_ARGB32; break; - default: return CAIRO_INT_STATUS_UNSUPPORTED; - } - - fb.dst = dst; - fb.pattern = pattern; - - if (! _cairo_boxes_for_each_box (boxes, fallback_box, &fb)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -render_boxes (cairo_xlib_surface_t *dst, - const cairo_pattern_t *pattern, - cairo_boxes_t *boxes) -{ - if (pattern->filter != CAIRO_FILTER_NEAREST) - return fallback_boxes (dst, pattern, boxes); - - switch (pattern->extend) { - default: - case CAIRO_EXTEND_NONE: - case CAIRO_EXTEND_REFLECT: - case CAIRO_EXTEND_PAD: - return fallback_boxes (dst, pattern, boxes); - - case CAIRO_EXTEND_REPEAT: /* XXX Use tiling */ - return fallback_boxes (dst, pattern, boxes); - } -} - -/* the mid-level: converts boxes into drawing operations */ - -struct _box_data { - Display *dpy; - cairo_xlib_surface_t *dst; - cairo_surface_t *src; - GC gc; - int tx, ty; - int width, height; -}; - -static cairo_bool_t source_contains_box (cairo_box_t *box, void *closure) -{ - struct _box_data *data = closure; - - /* The box is pixel-aligned so the truncation is safe. */ - return - _cairo_fixed_integer_part (box->p1.x) + data->tx >= 0 && - _cairo_fixed_integer_part (box->p1.y) + data->ty >= 0 && - _cairo_fixed_integer_part (box->p2.x) + data->tx <= data->width && - _cairo_fixed_integer_part (box->p2.y) + data->ty <= data->height; -} - -static cairo_bool_t image_upload_box (cairo_box_t *box, void *closure) -{ - const struct _box_data *iub = closure; - int x = _cairo_fixed_integer_part (box->p1.x); - int y = _cairo_fixed_integer_part (box->p1.y); - int width = _cairo_fixed_integer_part (box->p2.x - box->p1.x); - int height = _cairo_fixed_integer_part (box->p2.y - box->p1.y); - - return _cairo_xlib_surface_draw_image (iub->dst, - (cairo_image_surface_t *)iub->src, - x + iub->tx, y + iub->ty, - width, height, - x, y) == CAIRO_STATUS_SUCCESS; -} - -static cairo_bool_t -surface_matches_image_format (cairo_xlib_surface_t *surface, - cairo_image_surface_t *image) -{ - cairo_format_masks_t format; - - return (_pixman_format_to_masks (image->pixman_format, &format) && - (format.alpha_mask == surface->a_mask || surface->a_mask == 0) && - (format.red_mask == surface->r_mask || surface->r_mask == 0) && - (format.green_mask == surface->g_mask || surface->g_mask == 0) && - (format.blue_mask == surface->b_mask || surface->b_mask == 0)); -} - -static cairo_status_t -upload_image_inplace (cairo_xlib_surface_t *dst, - const cairo_pattern_t *source, - cairo_boxes_t *boxes) -{ - const cairo_surface_pattern_t *pattern; - struct _box_data iub; - cairo_image_surface_t *image; - - if (source->type != CAIRO_PATTERN_TYPE_SURFACE) - return CAIRO_INT_STATUS_UNSUPPORTED; - - pattern = (const cairo_surface_pattern_t *) source; - if (pattern->surface->type != CAIRO_SURFACE_TYPE_IMAGE) - return CAIRO_INT_STATUS_UNSUPPORTED; - - image = (cairo_image_surface_t *) pattern->surface; - if (image->format == CAIRO_FORMAT_INVALID) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (image->depth != dst->depth) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (! surface_matches_image_format (dst, image)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* XXX subsurface */ - - if (! _cairo_matrix_is_integer_translation (&source->matrix, - &iub.tx, &iub.ty)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - iub.dst = dst; - iub.src = &image->base; - iub.width = image->width; - iub.height = image->height; - - /* First check that the data is entirely within the image */ - if (! _cairo_boxes_for_each_box (boxes, source_contains_box, &iub)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (! _cairo_boxes_for_each_box (boxes, image_upload_box, &iub)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_bool_t copy_box (cairo_box_t *box, void *closure) -{ - const struct _box_data *cb = closure; - int x = _cairo_fixed_integer_part (box->p1.x); - int y = _cairo_fixed_integer_part (box->p1.y); - int width = _cairo_fixed_integer_part (box->p2.x - box->p1.x); - int height = _cairo_fixed_integer_part (box->p2.y - box->p1.y); - - XCopyArea (cb->dpy, - ((cairo_xlib_surface_t *)cb->src)->drawable, - cb->dst->drawable, - cb->gc, - x + cb->tx, y + cb->ty, - width, height, - x, y); - return TRUE; -} - -static cairo_status_t -copy_boxes (cairo_xlib_surface_t *dst, - const cairo_pattern_t *source, - cairo_boxes_t *boxes) -{ - const cairo_surface_pattern_t *pattern; - struct _box_data cb; - cairo_xlib_surface_t *src; - cairo_status_t status; - - if (source->type != CAIRO_PATTERN_TYPE_SURFACE) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* XXX subsurface */ - - pattern = (const cairo_surface_pattern_t *) source; - if (pattern->surface->backend->type != CAIRO_SURFACE_TYPE_XLIB) - return CAIRO_INT_STATUS_UNSUPPORTED; - - src = (cairo_xlib_surface_t *) pattern->surface; - if (src->depth != dst->depth) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* We can only have a single control for subwindow_mode on the - * GC. If we have a Window destination, we need to set ClipByChildren, - * but if we have a Window source, we need IncludeInferiors. If we have - * both a Window destination and source, we must fallback. There is - * no convenient way to detect if a drawable is a Pixmap or Window, - * therefore we can only rely on those surfaces that we created - * ourselves to be Pixmaps, and treat everything else as a potential - * Window. - */ - if (! src->owns_pixmap && ! dst->owns_pixmap) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (! _cairo_xlib_surface_same_screen (dst, src)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (! _cairo_matrix_is_integer_translation (&source->matrix, - &cb.tx, &cb.ty)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - cb.dpy = dst->display->display; - cb.dst = dst; - cb.src = &src->base; - cb.width = src->width; - cb.height = src->height; - - /* First check that the data is entirely within the image */ - if (! _cairo_boxes_for_each_box (boxes, source_contains_box, &cb)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_xlib_surface_get_gc (dst->display, dst, &cb.gc); - if (unlikely (status)) - return status; - - if (! src->owns_pixmap) { - XGCValues gcv; - - gcv.subwindow_mode = IncludeInferiors; - XChangeGC (dst->display->display, cb.gc, GCSubwindowMode, &gcv); - } - - status = CAIRO_STATUS_SUCCESS; - if (! _cairo_boxes_for_each_box (boxes, copy_box, &cb)) - status = CAIRO_INT_STATUS_UNSUPPORTED; - - if (! src->owns_pixmap) { - XGCValues gcv; - - gcv.subwindow_mode = ClipByChildren; - XChangeGC (dst->display->display, cb.gc, GCSubwindowMode, &gcv); - } - - _cairo_xlib_surface_put_gc (dst->display, dst, cb.gc); - - return status; -} - -static cairo_status_t -draw_boxes (cairo_composite_rectangles_t *extents, - cairo_boxes_t *boxes) -{ - cairo_xlib_surface_t *dst = (cairo_xlib_surface_t *)extents->surface; - cairo_operator_t op = extents->op; - const cairo_pattern_t *src = &extents->source_pattern.base; - cairo_int_status_t status; - - if (boxes->num_boxes == 0 && extents->is_bounded) - return CAIRO_STATUS_SUCCESS; - - if (! boxes->is_pixel_aligned) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (op == CAIRO_OPERATOR_CLEAR) - op = CAIRO_OPERATOR_SOURCE; - - if (op == CAIRO_OPERATOR_OVER && - _cairo_pattern_is_opaque (src, &extents->bounded)) - op = CAIRO_OPERATOR_SOURCE; - - if (dst->base.is_clear && op == CAIRO_OPERATOR_OVER) - op = CAIRO_OPERATOR_SOURCE; - - if (op != CAIRO_OPERATOR_SOURCE) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = acquire (dst); - if (unlikely (status)) - return status; - - if (src->type == CAIRO_PATTERN_TYPE_SOLID) { - status = _cairo_xlib_core_fill_boxes - (dst, &((cairo_solid_pattern_t *) src)->color, boxes); - } else { - status = upload_image_inplace (dst, src, boxes); - if (status == CAIRO_INT_STATUS_UNSUPPORTED) - status = copy_boxes (dst, src, boxes); - if (status == CAIRO_INT_STATUS_UNSUPPORTED) - status = render_boxes (dst, src, boxes); - } - - release (dst); - - return status; -} - -/* high-level compositor interface */ - -static cairo_int_status_t -_cairo_xlib_core_compositor_paint (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *extents) -{ - cairo_int_status_t status; - - status = CAIRO_INT_STATUS_UNSUPPORTED; - if (_cairo_clip_is_region (extents->clip)) { - cairo_boxes_t boxes; - - _cairo_clip_steal_boxes (extents->clip, &boxes); - status = draw_boxes (extents, &boxes); - _cairo_clip_unsteal_boxes (extents->clip, &boxes); - } - - return status; -} - -static cairo_int_status_t -_cairo_xlib_core_compositor_stroke (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_int_status_t status; - - status = CAIRO_INT_STATUS_UNSUPPORTED; - if (extents->clip->path == NULL && - _cairo_path_fixed_stroke_is_rectilinear (path)) { - cairo_boxes_t boxes; - - _cairo_boxes_init_with_clip (&boxes, extents->clip); - status = _cairo_path_fixed_stroke_rectilinear_to_boxes (path, - style, - ctm, - antialias, - &boxes); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) - status = draw_boxes (extents, &boxes); - _cairo_boxes_fini (&boxes); - } - - return status; -} - -static cairo_int_status_t -_cairo_xlib_core_compositor_fill (const cairo_compositor_t *compositor, - cairo_composite_rectangles_t *extents, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_int_status_t status; - - status = CAIRO_INT_STATUS_UNSUPPORTED; - if (extents->clip->path == NULL && - _cairo_path_fixed_fill_is_rectilinear (path)) { - cairo_boxes_t boxes; - - _cairo_boxes_init_with_clip (&boxes, extents->clip); - status = _cairo_path_fixed_fill_rectilinear_to_boxes (path, - fill_rule, - antialias, - &boxes); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) - status = draw_boxes (extents, &boxes); - _cairo_boxes_fini (&boxes); - } - - return status; -} - -const cairo_compositor_t * -_cairo_xlib_core_compositor_get (void) -{ - static cairo_compositor_t compositor; - - if (compositor.delegate == NULL) { - compositor.delegate = _cairo_xlib_fallback_compositor_get (); - - compositor.paint = _cairo_xlib_core_compositor_paint; - compositor.mask = NULL; - compositor.fill = _cairo_xlib_core_compositor_fill; - compositor.stroke = _cairo_xlib_core_compositor_stroke; - compositor.glyphs = NULL; /* XXX PolyGlyph? */ - } - - return &compositor; -} - -#endif /* !CAIRO_HAS_XLIB_XCB_FUNCTIONS */ diff --git a/source/libs/cairo/cairo-src/src/cairo-xlib-display.c b/source/libs/cairo/cairo-src/src/cairo-xlib-display.c deleted file mode 100644 index a2a3bc7924b1e3335ab0a3c7a0815c3872029533..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xlib-display.c +++ /dev/null @@ -1,655 +0,0 @@ -/* Cairo - a vector graphics library with display and print output - * - * Copyright © 2007 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Chris Wilson. - * - * Contributor(s): - * Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation - */ - -#include "cairoint.h" - -#if !CAIRO_HAS_XLIB_XCB_FUNCTIONS - -#include "cairo-xlib-private.h" -#include "cairo-xlib-xrender-private.h" -#include "cairo-freelist-private.h" -#include "cairo-error-private.h" -#include "cairo-list-inline.h" - -#include <X11/Xlibint.h> /* For XESetCloseDisplay */ - -typedef int (*cairo_xlib_error_func_t) (Display *display, - XErrorEvent *event); - -static cairo_xlib_display_t *_cairo_xlib_display_list; - -static int -_noop_error_handler (Display *display, - XErrorEvent *event) -{ - return False; /* return value is ignored */ -} - -static void -_cairo_xlib_display_finish (void *abstract_display) -{ - cairo_xlib_display_t *display = abstract_display; - Display *dpy = display->display; - - _cairo_xlib_display_fini_shm (display); - - if (! cairo_device_acquire (&display->base)) { - cairo_xlib_error_func_t old_handler; - - /* protect the notifies from triggering XErrors */ - XSync (dpy, False); - old_handler = XSetErrorHandler (_noop_error_handler); - - while (! cairo_list_is_empty (&display->fonts)) { - _cairo_xlib_font_close (cairo_list_first_entry (&display->fonts, - cairo_xlib_font_t, - link)); - } - - while (! cairo_list_is_empty (&display->screens)) { - _cairo_xlib_screen_destroy (display, - cairo_list_first_entry (&display->screens, - cairo_xlib_screen_t, - link)); - } - - XSync (dpy, False); - XSetErrorHandler (old_handler); - - cairo_device_release (&display->base); - } -} - -static void -_cairo_xlib_display_destroy (void *abstract_display) -{ - cairo_xlib_display_t *display = abstract_display; - - free (display); -} - -static int -_cairo_xlib_close_display (Display *dpy, XExtCodes *codes) -{ - cairo_xlib_display_t *display, **prev, *next; - - CAIRO_MUTEX_LOCK (_cairo_xlib_display_mutex); - for (display = _cairo_xlib_display_list; display; display = display->next) - if (display->display == dpy) - break; - CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex); - if (display == NULL) - return 0; - - cairo_device_finish (&display->base); - - /* - * Unhook from the global list - */ - CAIRO_MUTEX_LOCK (_cairo_xlib_display_mutex); - prev = &_cairo_xlib_display_list; - for (display = _cairo_xlib_display_list; display; display = next) { - next = display->next; - if (display->display == dpy) { - *prev = next; - break; - } else - prev = &display->next; - } - CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex); - - display->display = NULL; /* catch any later invalid access */ - cairo_device_destroy (&display->base); - - /* Return value in accordance with requirements of - * XESetCloseDisplay */ - return 0; -} - -static const cairo_device_backend_t _cairo_xlib_device_backend = { - CAIRO_DEVICE_TYPE_XLIB, - - NULL, - NULL, - - NULL, /* flush */ - _cairo_xlib_display_finish, - _cairo_xlib_display_destroy, -}; - -static void _cairo_xlib_display_select_compositor (cairo_xlib_display_t *display) -{ -#if 1 - if (display->render_major > 0 || display->render_minor >= 4) - display->compositor = _cairo_xlib_traps_compositor_get (); - else if (display->render_major > 0 || display->render_minor >= 0) - display->compositor = _cairo_xlib_mask_compositor_get (); - else - display->compositor = _cairo_xlib_core_compositor_get (); -#else - display->compositor = _cairo_xlib_fallback_compositor_get (); -#endif -} - -/** - * _cairo_xlib_device_create: - * @dpy: the display to create the device for - * - * Gets the device belonging to @dpy, or creates it if it doesn't exist yet. - * - * Returns: the device belonging to @dpy - **/ -cairo_device_t * -_cairo_xlib_device_create (Display *dpy) -{ - cairo_xlib_display_t *display; - cairo_xlib_display_t **prev; - cairo_device_t *device; - XExtCodes *codes; - const char *env; - - CAIRO_MUTEX_INITIALIZE (); - - /* There is an apparent deadlock between this mutex and the - * mutex for the display, but it's actually safe. For the - * app to call XCloseDisplay() while any other thread is - * inside this function would be an error in the logic - * app, and the CloseDisplay hook is the only other place we - * acquire this mutex. - */ - CAIRO_MUTEX_LOCK (_cairo_xlib_display_mutex); - - for (prev = &_cairo_xlib_display_list; (display = *prev); prev = &(*prev)->next) - { - if (display->display == dpy) { - /* - * MRU the list - */ - if (prev != &_cairo_xlib_display_list) { - *prev = display->next; - display->next = _cairo_xlib_display_list; - _cairo_xlib_display_list = display; - } - device = cairo_device_reference (&display->base); - goto UNLOCK; - } - } - - display = malloc (sizeof (cairo_xlib_display_t)); - if (unlikely (display == NULL)) { - device = _cairo_device_create_in_error (CAIRO_STATUS_NO_MEMORY); - goto UNLOCK; - } - - _cairo_device_init (&display->base, &_cairo_xlib_device_backend); - - display->display = dpy; - cairo_list_init (&display->screens); - cairo_list_init (&display->fonts); - display->closed = FALSE; - - /* Xlib calls out to the extension close_display hooks in LIFO - * order. So we have to ensure that all extensions that we depend - * on in our close_display hook are properly initialized before we - * add our hook. For now, that means Render, so we call into its - * QueryVersion function to ensure it gets initialized. - */ - display->render_major = display->render_minor = -1; - XRenderQueryVersion (dpy, &display->render_major, &display->render_minor); - env = getenv ("CAIRO_DEBUG"); - if (env != NULL && (env = strstr (env, "xrender-version=")) != NULL) { - int max_render_major, max_render_minor; - - env += sizeof ("xrender-version=") - 1; - if (sscanf (env, "%d.%d", &max_render_major, &max_render_minor) != 2) - max_render_major = max_render_minor = -1; - - if (max_render_major < display->render_major || - (max_render_major == display->render_major && - max_render_minor < display->render_minor)) - { - display->render_major = max_render_major; - display->render_minor = max_render_minor; - } - } - - _cairo_xlib_display_select_compositor (display); - - display->white = NULL; - memset (display->alpha, 0, sizeof (display->alpha)); - memset (display->solid, 0, sizeof (display->solid)); - memset (display->solid_cache, 0, sizeof (display->solid_cache)); - memset (display->last_solid_cache, 0, sizeof (display->last_solid_cache)); - - memset (display->cached_xrender_formats, 0, - sizeof (display->cached_xrender_formats)); - - display->force_precision = -1; - - _cairo_xlib_display_init_shm (display); - - /* Prior to Render 0.10, there is no protocol support for gradients and - * we call function stubs instead, which would silently consume the drawing. - */ -#if RENDER_MAJOR == 0 && RENDER_MINOR < 10 - display->buggy_gradients = TRUE; -#else - display->buggy_gradients = FALSE; -#endif - display->buggy_pad_reflect = FALSE; - display->buggy_repeat = FALSE; - - /* This buggy_repeat condition is very complicated because there - * are multiple X server code bases (with multiple versioning - * schemes within a code base), and multiple bugs. - * - * The X servers: - * - * 1. The Vendor=="XFree86" code base with release numbers such - * as 4.7.0 (VendorRelease==40700000). - * - * 2. The Vendor=="X.Org" code base (a descendant of the - * XFree86 code base). It originally had things like - * VendorRelease==60700000 for release 6.7.0 but then changed - * its versioning scheme so that, for example, - * VendorRelease==10400000 for the 1.4.0 X server within the - * X.Org 7.3 release. - * - * The bugs: - * - * 1. The original bug that led to the buggy_repeat - * workaround. This was a bug that Owen Taylor investigated, - * understood well, and characterized against various X - * servers. Confirmed X servers with this bug include: - * - * "XFree86" <= 40500000 - * "X.Org" <= 60802000 (only with old numbering >= 60700000) - * - * 2. A separate bug resulting in a crash of the X server when - * using cairo's extend-reflect test case, (which, surprisingly - * enough was not passing RepeatReflect to the X server, but - * instead using RepeatNormal in a workaround). Nobody to date - * has understood the bug well, but it appears to be gone as of - * the X.Org 1.4.0 server. This bug is coincidentally avoided - * by using the same buggy_repeat workaround. Confirmed X - * servers with this bug include: - * - * "X.org" == 60900000 (old versioning scheme) - * "X.org" < 10400000 (new numbering scheme) - * - * For the old-versioning-scheme X servers we don't know - * exactly when second the bug started, but since bug 1 is - * present through 6.8.2 and bug 2 is present in 6.9.0 it seems - * safest to just blacklist all old-versioning-scheme X servers, - * (just using VendorRelease < 70000000), as buggy_repeat=TRUE. - */ - if (_cairo_xlib_vendor_is_xorg (dpy)) { - if (VendorRelease (dpy) >= 60700000) { - if (VendorRelease (dpy) < 70000000) - display->buggy_repeat = TRUE; - - /* We know that gradients simply do not work in early Xorg servers */ - if (VendorRelease (dpy) < 70200000) - display->buggy_gradients = TRUE; - - /* And the extended repeat modes were not fixed until much later */ - display->buggy_pad_reflect = TRUE; - } else { - if (VendorRelease (dpy) < 10400000) - display->buggy_repeat = TRUE; - - /* Too many bugs in the early drivers */ - if (VendorRelease (dpy) < 10699000) - display->buggy_pad_reflect = TRUE; - } - } else if (strstr (ServerVendor (dpy), "XFree86") != NULL) { - if (VendorRelease (dpy) <= 40500000) - display->buggy_repeat = TRUE; - - display->buggy_gradients = TRUE; - display->buggy_pad_reflect = TRUE; - } - - codes = XAddExtension (dpy); - if (unlikely (codes == NULL)) { - device = _cairo_device_create_in_error (CAIRO_STATUS_NO_MEMORY); - free (display); - goto UNLOCK; - } - - XESetCloseDisplay (dpy, codes->extension, _cairo_xlib_close_display); - cairo_device_reference (&display->base); /* add one for the CloseDisplay */ - - display->next = _cairo_xlib_display_list; - _cairo_xlib_display_list = display; - - device = &display->base; - -UNLOCK: - CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex); - return device; -} - -cairo_status_t -_cairo_xlib_display_acquire (cairo_device_t *device, cairo_xlib_display_t **display) -{ - cairo_status_t status; - - status = cairo_device_acquire (device); - if (status) - return status; - - *display = (cairo_xlib_display_t *) device; - return CAIRO_STATUS_SUCCESS; -} - -XRenderPictFormat * -_cairo_xlib_display_get_xrender_format_for_pixman(cairo_xlib_display_t *display, - pixman_format_code_t format) -{ - Display *dpy = display->display; - XRenderPictFormat tmpl; - int mask; - -#define MASK(x) ((1<<(x))-1) - - tmpl.depth = PIXMAN_FORMAT_DEPTH(format); - mask = PictFormatType | PictFormatDepth; - - switch (PIXMAN_FORMAT_TYPE(format)) { - case PIXMAN_TYPE_ARGB: - tmpl.type = PictTypeDirect; - - tmpl.direct.alphaMask = MASK(PIXMAN_FORMAT_A(format)); - if (PIXMAN_FORMAT_A(format)) - tmpl.direct.alpha = (PIXMAN_FORMAT_R(format) + - PIXMAN_FORMAT_G(format) + - PIXMAN_FORMAT_B(format)); - - tmpl.direct.redMask = MASK(PIXMAN_FORMAT_R(format)); - tmpl.direct.red = (PIXMAN_FORMAT_G(format) + - PIXMAN_FORMAT_B(format)); - - tmpl.direct.greenMask = MASK(PIXMAN_FORMAT_G(format)); - tmpl.direct.green = PIXMAN_FORMAT_B(format); - - tmpl.direct.blueMask = MASK(PIXMAN_FORMAT_B(format)); - tmpl.direct.blue = 0; - - mask |= PictFormatRed | PictFormatRedMask; - mask |= PictFormatGreen | PictFormatGreenMask; - mask |= PictFormatBlue | PictFormatBlueMask; - mask |= PictFormatAlpha | PictFormatAlphaMask; - break; - - case PIXMAN_TYPE_ABGR: - tmpl.type = PictTypeDirect; - - tmpl.direct.alphaMask = MASK(PIXMAN_FORMAT_A(format)); - if (tmpl.direct.alphaMask) - tmpl.direct.alpha = (PIXMAN_FORMAT_B(format) + - PIXMAN_FORMAT_G(format) + - PIXMAN_FORMAT_R(format)); - - tmpl.direct.blueMask = MASK(PIXMAN_FORMAT_B(format)); - tmpl.direct.blue = (PIXMAN_FORMAT_G(format) + - PIXMAN_FORMAT_R(format)); - - tmpl.direct.greenMask = MASK(PIXMAN_FORMAT_G(format)); - tmpl.direct.green = PIXMAN_FORMAT_R(format); - - tmpl.direct.redMask = MASK(PIXMAN_FORMAT_R(format)); - tmpl.direct.red = 0; - - mask |= PictFormatRed | PictFormatRedMask; - mask |= PictFormatGreen | PictFormatGreenMask; - mask |= PictFormatBlue | PictFormatBlueMask; - mask |= PictFormatAlpha | PictFormatAlphaMask; - break; - - case PIXMAN_TYPE_BGRA: - tmpl.type = PictTypeDirect; - - tmpl.direct.blueMask = MASK(PIXMAN_FORMAT_B(format)); - tmpl.direct.blue = (PIXMAN_FORMAT_BPP(format) - PIXMAN_FORMAT_B(format)); - - tmpl.direct.greenMask = MASK(PIXMAN_FORMAT_G(format)); - tmpl.direct.green = (PIXMAN_FORMAT_BPP(format) - PIXMAN_FORMAT_B(format) - - PIXMAN_FORMAT_G(format)); - - tmpl.direct.redMask = MASK(PIXMAN_FORMAT_R(format)); - tmpl.direct.red = (PIXMAN_FORMAT_BPP(format) - PIXMAN_FORMAT_B(format) - - PIXMAN_FORMAT_G(format) - PIXMAN_FORMAT_R(format)); - - tmpl.direct.alphaMask = MASK(PIXMAN_FORMAT_A(format)); - tmpl.direct.alpha = 0; - - mask |= PictFormatRed | PictFormatRedMask; - mask |= PictFormatGreen | PictFormatGreenMask; - mask |= PictFormatBlue | PictFormatBlueMask; - mask |= PictFormatAlpha | PictFormatAlphaMask; - break; - - case PIXMAN_TYPE_A: - tmpl.type = PictTypeDirect; - - tmpl.direct.alpha = 0; - tmpl.direct.alphaMask = MASK(PIXMAN_FORMAT_A(format)); - - mask |= PictFormatAlpha | PictFormatAlphaMask; - break; - - case PIXMAN_TYPE_COLOR: - case PIXMAN_TYPE_GRAY: - /* XXX Find matching visual/colormap */ - tmpl.type = PictTypeIndexed; - //tmpl.colormap = screen->visuals[PIXMAN_FORMAT_VIS(format)].vid; - //mask |= PictFormatColormap; - return NULL; - } -#undef MASK - - /* XXX caching? */ - return XRenderFindFormat(dpy, mask, &tmpl, 0); -} - -XRenderPictFormat * -_cairo_xlib_display_get_xrender_format (cairo_xlib_display_t *display, - cairo_format_t format) -{ - XRenderPictFormat *xrender_format; - - xrender_format = display->cached_xrender_formats[format]; - if (xrender_format == NULL) { - int pict_format = PictStandardNUM; - - switch (format) { - case CAIRO_FORMAT_A1: - pict_format = PictStandardA1; break; - case CAIRO_FORMAT_A8: - pict_format = PictStandardA8; break; - case CAIRO_FORMAT_RGB24: - pict_format = PictStandardRGB24; break; - case CAIRO_FORMAT_RGB16_565: - xrender_format = _cairo_xlib_display_get_xrender_format_for_pixman(display, - PIXMAN_r5g6b5); - break; - case CAIRO_FORMAT_RGB30: - xrender_format = _cairo_xlib_display_get_xrender_format_for_pixman(display, - PIXMAN_x2r10g10b10); - break; - case CAIRO_FORMAT_INVALID: - default: - ASSERT_NOT_REACHED; - case CAIRO_FORMAT_ARGB32: - pict_format = PictStandardARGB32; break; - } - if (pict_format != PictStandardNUM) - xrender_format = - XRenderFindStandardFormat (display->display, pict_format); - display->cached_xrender_formats[format] = xrender_format; - } - - return xrender_format; -} - -cairo_xlib_screen_t * -_cairo_xlib_display_get_screen (cairo_xlib_display_t *display, - Screen *screen) -{ - cairo_xlib_screen_t *info; - - cairo_list_foreach_entry (info, cairo_xlib_screen_t, &display->screens, link) { - if (info->screen == screen) { - if (display->screens.next != &info->link) - cairo_list_move (&info->link, &display->screens); - return info; - } - } - - return NULL; -} - -cairo_bool_t -_cairo_xlib_display_has_repeat (cairo_device_t *device) -{ - return ! ((cairo_xlib_display_t *) device)->buggy_repeat; -} - -cairo_bool_t -_cairo_xlib_display_has_reflect (cairo_device_t *device) -{ - return ! ((cairo_xlib_display_t *) device)->buggy_pad_reflect; -} - -cairo_bool_t -_cairo_xlib_display_has_gradients (cairo_device_t *device) -{ - return ! ((cairo_xlib_display_t *) device)->buggy_gradients; -} - -/** - * cairo_xlib_device_debug_cap_xrender_version: - * @device: a #cairo_device_t for the Xlib backend - * @major_version: major version to restrict to - * @minor_version: minor version to restrict to - * - * Restricts all future Xlib surfaces for this devices to the specified version - * of the RENDER extension. This function exists solely for debugging purpose. - * It lets you find out how cairo would behave with an older version of - * the RENDER extension. - * - * Use the special values -1 and -1 for disabling the RENDER extension. - * - * Since: 1.12 - **/ -void -cairo_xlib_device_debug_cap_xrender_version (cairo_device_t *device, - int major_version, - int minor_version) -{ - cairo_xlib_display_t *display = (cairo_xlib_display_t *) device; - - if (device == NULL || device->status) - return; - - if (device->backend->type != CAIRO_DEVICE_TYPE_XLIB) - return; - - if (major_version < display->render_major || - (major_version == display->render_major && - minor_version < display->render_minor)) - { - display->render_major = major_version; - display->render_minor = minor_version; - } - - _cairo_xlib_display_select_compositor (display); -} - -/** - * cairo_xlib_device_debug_set_precision: - * @device: a #cairo_device_t for the Xlib backend - * @precision: the precision to use - * - * Render supports two modes of precision when rendering trapezoids. Set - * the precision to the desired mode. - * - * Since: 1.12 - **/ -void -cairo_xlib_device_debug_set_precision (cairo_device_t *device, - int precision) -{ - if (device == NULL || device->status) - return; - if (device->backend->type != CAIRO_DEVICE_TYPE_XLIB) { - cairo_status_t status; - - status = _cairo_device_set_error (device, CAIRO_STATUS_DEVICE_TYPE_MISMATCH); - (void) status; - return; - } - - ((cairo_xlib_display_t *) device)->force_precision = precision; -} - -/** - * cairo_xlib_device_debug_get_precision: - * @device: a #cairo_device_t for the Xlib backend - * - * Get the Xrender precision mode. - * - * Returns: the render precision mode - * - * Since: 1.12 - **/ -int -cairo_xlib_device_debug_get_precision (cairo_device_t *device) -{ - if (device == NULL || device->status) - return -1; - if (device->backend->type != CAIRO_DEVICE_TYPE_XLIB) { - cairo_status_t status; - - status = _cairo_device_set_error (device, CAIRO_STATUS_DEVICE_TYPE_MISMATCH); - (void) status; - return -1; - } - - return ((cairo_xlib_display_t *) device)->force_precision; -} - -#endif /* !CAIRO_HAS_XLIB_XCB_FUNCTIONS */ diff --git a/source/libs/cairo/cairo-src/src/cairo-xlib-fallback-compositor.c b/source/libs/cairo/cairo-src/src/cairo-xlib-fallback-compositor.c deleted file mode 100644 index ed2845db57db7827ddfb591a2baabd9404d45a5e..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xlib-fallback-compositor.c +++ /dev/null @@ -1,248 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Behdad Esfahbod <behdad@behdad.org> - * Chris Wilson <chris@chris-wilson.co.uk> - * Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation - */ - -#include "cairoint.h" - -#if !CAIRO_HAS_XLIB_XCB_FUNCTIONS - -#include "cairo-xlib-private.h" - -#include "cairo-compositor-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-surface-offset-private.h" - -static const cairo_compositor_t * -_get_compositor (cairo_surface_t *surface) -{ - return ((cairo_image_surface_t *)surface)->compositor; -} - -static cairo_bool_t -unclipped (cairo_xlib_surface_t *xlib, cairo_clip_t *clip) -{ - cairo_rectangle_int_t r; - - r.x = r.y = 0; - r.width = xlib->width; - r.height = xlib->height; - return _cairo_clip_contains_rectangle (clip, &r); -} - -static cairo_int_status_t -_cairo_xlib_shm_compositor_paint (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents) -{ - cairo_xlib_surface_t *xlib = (cairo_xlib_surface_t *)extents->surface; - cairo_int_status_t status; - cairo_surface_t *shm; - cairo_bool_t overwrite; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - overwrite = - extents->op <= CAIRO_OPERATOR_SOURCE && unclipped (xlib, extents->clip); - - shm = _cairo_xlib_surface_get_shm (xlib, overwrite); - if (shm == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_compositor_paint (_get_compositor (shm), shm, - extents->op, - &extents->source_pattern.base, - extents->clip); - if (unlikely (status)) - return status; - - xlib->base.is_clear = - extents->op == CAIRO_OPERATOR_CLEAR && unclipped (xlib, extents->clip); - xlib->base.serial++; - xlib->fallback++; - return CAIRO_INT_STATUS_NOTHING_TO_DO; -} - -static cairo_int_status_t -_cairo_xlib_shm_compositor_mask (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents) -{ - cairo_xlib_surface_t *xlib = (cairo_xlib_surface_t *)extents->surface; - cairo_int_status_t status; - cairo_surface_t *shm; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - shm = _cairo_xlib_surface_get_shm (xlib, FALSE); - if (shm == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_compositor_mask (_get_compositor (shm), shm, - extents->op, - &extents->source_pattern.base, - &extents->mask_pattern.base, - extents->clip); - if (unlikely (status)) - return status; - - xlib->base.is_clear = FALSE; - xlib->base.serial++; - xlib->fallback++; - return CAIRO_INT_STATUS_NOTHING_TO_DO; -} - -static cairo_int_status_t -_cairo_xlib_shm_compositor_stroke (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_xlib_surface_t *xlib = (cairo_xlib_surface_t *)extents->surface; - cairo_int_status_t status; - cairo_surface_t *shm; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - shm = _cairo_xlib_surface_get_shm (xlib, FALSE); - if (shm == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_compositor_stroke (_get_compositor (shm), shm, - extents->op, - &extents->source_pattern.base, - path, style, - ctm, ctm_inverse, - tolerance, - antialias, - extents->clip); - if (unlikely (status)) - return status; - - xlib->base.is_clear = FALSE; - xlib->base.serial++; - xlib->fallback++; - return CAIRO_INT_STATUS_NOTHING_TO_DO; -} - -static cairo_int_status_t -_cairo_xlib_shm_compositor_fill (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - cairo_xlib_surface_t *xlib = (cairo_xlib_surface_t *)extents->surface; - cairo_int_status_t status; - cairo_surface_t *shm; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - shm = _cairo_xlib_surface_get_shm (xlib, FALSE); - if (shm == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_compositor_fill (_get_compositor (shm), shm, - extents->op, - &extents->source_pattern.base, - path, - fill_rule, tolerance, antialias, - extents->clip); - if (unlikely (status)) - return status; - - xlib->base.is_clear = FALSE; - xlib->base.serial++; - xlib->fallback++; - return CAIRO_INT_STATUS_NOTHING_TO_DO; -} - -static cairo_int_status_t -_cairo_xlib_shm_compositor_glyphs (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_bool_t overlap) -{ - cairo_xlib_surface_t *xlib = (cairo_xlib_surface_t *)extents->surface; - cairo_int_status_t status; - cairo_surface_t *shm; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - shm = _cairo_xlib_surface_get_shm (xlib, FALSE); - if (shm == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_compositor_glyphs (_get_compositor (shm), shm, - extents->op, - &extents->source_pattern.base, - glyphs, num_glyphs, scaled_font, - extents->clip); - if (unlikely (status)) - return status; - - xlib->base.is_clear = FALSE; - xlib->base.serial++; - xlib->fallback++; - return CAIRO_INT_STATUS_NOTHING_TO_DO; -} - -static const cairo_compositor_t _cairo_xlib_shm_compositor = { - &_cairo_fallback_compositor, - - _cairo_xlib_shm_compositor_paint, - _cairo_xlib_shm_compositor_mask, - _cairo_xlib_shm_compositor_stroke, - _cairo_xlib_shm_compositor_fill, - _cairo_xlib_shm_compositor_glyphs, -}; - -const cairo_compositor_t * -_cairo_xlib_fallback_compositor_get (void) -{ - return &_cairo_xlib_shm_compositor; -} - -#endif /* !CAIRO_HAS_XLIB_XCB_FUNCTIONS */ diff --git a/source/libs/cairo/cairo-src/src/cairo-xlib-private.h b/source/libs/cairo/cairo-src/src/cairo-xlib-private.h deleted file mode 100644 index 0f2f2e1faa0560c29b1a4064bd8b1a75259944ea..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xlib-private.h +++ /dev/null @@ -1,470 +0,0 @@ -/* Cairo - a vector graphics library with display and print output - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributors(s): - * Chris Wilson <chris@chris-wilson.co.uk> - * Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation - */ - -#ifndef CAIRO_XLIB_PRIVATE_H -#define CAIRO_XLIB_PRIVATE_H - -#include "cairo-xlib-xrender-private.h" -#include "cairo-xlib.h" - -#include "cairo-compiler-private.h" -#include "cairo-device-private.h" -#include "cairo-freelist-type-private.h" -#include "cairo-list-private.h" -#include "cairo-reference-count-private.h" -#include "cairo-types-private.h" -#include "cairo-scaled-font-private.h" -#include "cairo-surface-private.h" - -#include <pixman.h> -#include <string.h> - -typedef struct _cairo_xlib_display cairo_xlib_display_t; -typedef struct _cairo_xlib_shm_display cairo_xlib_shm_display_t; -typedef struct _cairo_xlib_screen cairo_xlib_screen_t; -typedef struct _cairo_xlib_source cairo_xlib_source_t; -typedef struct _cairo_xlib_proxy cairo_xlib_proxy_t; -typedef struct _cairo_xlib_surface cairo_xlib_surface_t; - -/* size of color cube */ -#define CUBE_SIZE 6 -/* size of gray ramp */ -#define RAMP_SIZE 16 -/* maximum number of cached GC's */ -#define GC_CACHE_SIZE 4 - -struct _cairo_xlib_display { - cairo_device_t base; - - cairo_xlib_display_t *next; - - Display *display; - cairo_list_t screens; - cairo_list_t fonts; - - cairo_xlib_shm_display_t *shm; - - const cairo_compositor_t *compositor; - - int render_major; - int render_minor; - XRenderPictFormat *cached_xrender_formats[CAIRO_FORMAT_RGB30 + 1]; - - int force_precision; - - cairo_surface_t *white; - cairo_surface_t *alpha[256]; - cairo_surface_t *solid[32]; - uint32_t solid_cache[32]; /* low 16 are opaque, high 16 transparent */ - struct { - uint32_t color; - int index; - } last_solid_cache[2]; - - /* TRUE if the server has a bug with repeating pictures - * - * https://bugs.freedesktop.org/show_bug.cgi?id=3566 - * - * We can't test for this because it depends on whether the - * picture is in video memory or not. - * - * We also use this variable as a guard against a second - * independent bug with transformed repeating pictures: - * - * http://lists.freedesktop.org/archives/cairo/2004-September/001839.html - * - * Both are fixed in xorg >= 6.9 and hopefully in > 6.8.2, so - * we can reuse the test for now. - */ - unsigned int buggy_gradients : 1; - unsigned int buggy_pad_reflect : 1; - unsigned int buggy_repeat : 1; - unsigned int closed :1; -}; - -typedef struct _cairo_xlib_visual_info { - cairo_list_t link; - VisualID visualid; - struct { uint8_t a, r, g, b; } colors[256]; - uint8_t cube_to_pseudocolor[CUBE_SIZE][CUBE_SIZE][CUBE_SIZE]; - uint8_t field8_to_cube[256]; - int8_t dither8_to_cube[256]; - uint8_t gray8_to_pseudocolor[256]; -} cairo_xlib_visual_info_t; - -struct _cairo_xlib_screen { - cairo_list_t link; - - cairo_device_t *device; - Screen *screen; - - cairo_list_t surfaces; - - cairo_bool_t has_font_options; - cairo_font_options_t font_options; - - GC gc[GC_CACHE_SIZE]; - uint8_t gc_depths[GC_CACHE_SIZE]; - - cairo_list_t visuals; -}; - -enum { - GLYPHSET_INDEX_ARGB32, - GLYPHSET_INDEX_A8, - GLYPHSET_INDEX_A1, - NUM_GLYPHSETS -}; - -typedef struct _cairo_xlib_font_glyphset { - GlyphSet glyphset; - cairo_format_t format; - XRenderPictFormat *xrender_format; - struct _cairo_xlib_font_glyphset_free_glyphs { - int count; - unsigned long indices[128]; - } to_free; -} cairo_xlib_font_glyphset_t; - -typedef struct _cairo_xlib_font { - cairo_scaled_font_private_t base; - cairo_scaled_font_t *font; - cairo_device_t *device; - cairo_list_t link; - cairo_xlib_font_glyphset_t glyphset[NUM_GLYPHSETS]; -} cairo_xlib_font_t; - -struct _cairo_xlib_surface { - cairo_surface_t base; - - Picture picture; - Drawable drawable; - - const cairo_compositor_t *compositor; - cairo_surface_t *shm; - int fallback; - - cairo_xlib_display_t *display; - cairo_xlib_screen_t *screen; - cairo_list_t link; - - Display *dpy; /* only valid between acquire/release */ - cairo_bool_t owns_pixmap; - Visual *visual; - - int use_pixmap; - - int width; - int height; - int depth; - - int precision; - XRenderPictFormat *xrender_format; - /* XXX pixman_format instead of masks? */ - uint32_t a_mask; - uint32_t r_mask; - uint32_t g_mask; - uint32_t b_mask; - - struct _cairo_xlib_source { - cairo_surface_t base; - - Picture picture; - Pixmap pixmap; - Display *dpy; - - unsigned int filter:3; - unsigned int extend:3; - unsigned int has_matrix:1; - unsigned int has_component_alpha:1; - } embedded_source; -}; - -struct _cairo_xlib_proxy { - struct _cairo_xlib_source source; - cairo_surface_t *owner; -}; - -inline static cairo_bool_t -_cairo_xlib_vendor_is_xorg (Display *dpy) -{ - const char *const vendor = ServerVendor (dpy); - return strstr (vendor, "X.Org") || strstr (vendor, "Xorg"); -} - -cairo_private cairo_status_t -_cairo_xlib_surface_get_gc (cairo_xlib_display_t *display, - cairo_xlib_surface_t *surface, - GC *gc); - -cairo_private cairo_device_t * -_cairo_xlib_device_create (Display *display); - -cairo_private void -_cairo_xlib_display_init_shm (cairo_xlib_display_t *display); - -cairo_private void -_cairo_xlib_display_fini_shm (cairo_xlib_display_t *display); - -cairo_private cairo_xlib_screen_t * -_cairo_xlib_display_get_screen (cairo_xlib_display_t *display, - Screen *screen); - -cairo_private cairo_status_t -_cairo_xlib_display_acquire (cairo_device_t *device, - cairo_xlib_display_t **display); - -cairo_private cairo_bool_t -_cairo_xlib_display_has_repeat (cairo_device_t *device); - -cairo_private cairo_bool_t -_cairo_xlib_display_has_reflect (cairo_device_t *device); - -cairo_private cairo_bool_t -_cairo_xlib_display_has_gradients (cairo_device_t *device); - -cairo_private void -_cairo_xlib_display_set_precision(cairo_device_t *device, - int precision); - -cairo_private XRenderPictFormat * -_cairo_xlib_display_get_xrender_format (cairo_xlib_display_t *display, - cairo_format_t format); - -cairo_private XRenderPictFormat * -_cairo_xlib_display_get_xrender_format_for_pixman (cairo_xlib_display_t *display, - pixman_format_code_t format); - -cairo_private cairo_status_t -_cairo_xlib_screen_get (Display *dpy, - Screen *screen, - cairo_xlib_screen_t **out); - -cairo_private void -_cairo_xlib_screen_destroy (cairo_xlib_display_t *display, - cairo_xlib_screen_t *info); - -cairo_private GC -_cairo_xlib_screen_get_gc (cairo_xlib_display_t *display, - cairo_xlib_screen_t *info, - int depth, - Drawable drawable); -cairo_private void -_cairo_xlib_screen_put_gc (cairo_xlib_display_t *display, - cairo_xlib_screen_t *info, - int depth, - GC gc); - -cairo_private cairo_font_options_t * -_cairo_xlib_screen_get_font_options (cairo_xlib_screen_t *info); - -cairo_private cairo_status_t -_cairo_xlib_screen_get_visual_info (cairo_xlib_display_t *display, - cairo_xlib_screen_t *info, - Visual *visual, - cairo_xlib_visual_info_t **out); - -cairo_private cairo_status_t -_cairo_xlib_visual_info_create (Display *dpy, - int screen, - VisualID visualid, - cairo_xlib_visual_info_t **out); - -cairo_private void -_cairo_xlib_visual_info_destroy (cairo_xlib_visual_info_t *info); - -cairo_private const cairo_compositor_t * -_cairo_xlib_core_compositor_get (void); - -cairo_private const cairo_compositor_t * -_cairo_xlib_fallback_compositor_get (void); - -cairo_private const cairo_compositor_t * -_cairo_xlib_mask_compositor_get (void); - -cairo_private const cairo_compositor_t * -_cairo_xlib_traps_compositor_get (void); - -cairo_private void -_cairo_xlib_surface_ensure_picture (cairo_xlib_surface_t *surface); - -cairo_private void -_cairo_xlib_surface_set_precision (cairo_xlib_surface_t *surface, - cairo_antialias_t antialias); - -cairo_private cairo_int_status_t -_cairo_xlib_surface_set_attributes (cairo_xlib_display_t *display, - cairo_xlib_surface_t *surface, - cairo_surface_attributes_t *attributes, - double xc, - double yc); - -cairo_private cairo_status_t -_cairo_xlib_surface_draw_image (cairo_xlib_surface_t *surface, - cairo_image_surface_t *image, - int src_x, - int src_y, - int width, - int height, - int dst_x, - int dst_y); - -cairo_private cairo_surface_t * -_cairo_xlib_source_create_for_pattern (cairo_surface_t *dst, - const cairo_pattern_t *pattern, - cairo_bool_t is_mask, - const cairo_rectangle_int_t *extents, - const cairo_rectangle_int_t *sample, - int *src_x, int *src_y); - -cairo_private void -_cairo_xlib_font_close (cairo_xlib_font_t *font); - -#define CAIRO_RENDER_AT_LEAST(surface, major, minor) \ - (((surface)->render_major > major) || \ - (((surface)->render_major == major) && ((surface)->render_minor >= minor))) - -#define CAIRO_RENDER_HAS_CREATE_PICTURE(surface) CAIRO_RENDER_AT_LEAST((surface), 0, 0) -#define CAIRO_RENDER_HAS_COMPOSITE(surface) CAIRO_RENDER_AT_LEAST((surface), 0, 0) -#define CAIRO_RENDER_HAS_COMPOSITE_TEXT(surface) CAIRO_RENDER_AT_LEAST((surface), 0, 0) - -#define CAIRO_RENDER_HAS_FILL_RECTANGLES(surface) CAIRO_RENDER_AT_LEAST((surface), 0, 1) - -#define CAIRO_RENDER_HAS_DISJOINT(surface) CAIRO_RENDER_AT_LEAST((surface), 0, 2) -#define CAIRO_RENDER_HAS_CONJOINT(surface) CAIRO_RENDER_AT_LEAST((surface), 0, 2) - -#define CAIRO_RENDER_HAS_TRAPEZOIDS(surface) CAIRO_RENDER_AT_LEAST((surface), 0, 4) -#define CAIRO_RENDER_HAS_TRIANGLES(surface) CAIRO_RENDER_AT_LEAST((surface), 0, 4) -#define CAIRO_RENDER_HAS_TRISTRIP(surface) CAIRO_RENDER_AT_LEAST((surface), 0, 4) -#define CAIRO_RENDER_HAS_TRIFAN(surface) CAIRO_RENDER_AT_LEAST((surface), 0, 4) - -#define CAIRO_RENDER_HAS_PICTURE_TRANSFORM(surface) CAIRO_RENDER_AT_LEAST((surface), 0, 6) -#define CAIRO_RENDER_HAS_FILTERS(surface) CAIRO_RENDER_AT_LEAST((surface), 0, 6) -#define CAIRO_RENDER_HAS_FILTER_GOOD(surface) FALSE -#define CAIRO_RENDER_HAS_FILTER_BEST(surface) FALSE - -#define CAIRO_RENDER_HAS_EXTENDED_REPEAT(surface) CAIRO_RENDER_AT_LEAST((surface), 0, 10) -#define CAIRO_RENDER_HAS_GRADIENTS(surface) CAIRO_RENDER_AT_LEAST((surface), 0, 10) - -#define CAIRO_RENDER_HAS_PDF_OPERATORS(surface) CAIRO_RENDER_AT_LEAST((surface), 0, 11) - -#define CAIRO_RENDER_SUPPORTS_OPERATOR(surface, op) \ - ((op) <= CAIRO_OPERATOR_SATURATE || \ - (CAIRO_RENDER_HAS_PDF_OPERATORS(surface) && \ - (op) <= CAIRO_OPERATOR_HSL_LUMINOSITY)) - -/* - * Return whether two xlib surfaces share the same - * screen. Both core and Render drawing require this - * when using multiple drawables in an operation. - */ -static inline cairo_bool_t -_cairo_xlib_surface_same_screen (cairo_xlib_surface_t *dst, - cairo_xlib_surface_t *src) -{ - return dst->screen == src->screen; -} - -cairo_private cairo_int_status_t -_cairo_xlib_core_fill_boxes (cairo_xlib_surface_t *dst, - const cairo_color_t *color, - cairo_boxes_t *boxes); - -cairo_private cairo_int_status_t -_cairo_xlib_core_fill_rectangles (cairo_xlib_surface_t *dst, - const cairo_color_t *color, - int num_rects, - cairo_rectangle_int_t *rects); - -static inline void -_cairo_xlib_surface_put_gc (cairo_xlib_display_t *display, - cairo_xlib_surface_t *surface, - GC gc) -{ - _cairo_xlib_screen_put_gc (display, - surface->screen, - surface->depth, - gc); -} - -cairo_private cairo_surface_t * -_cairo_xlib_surface_create_similar_shm (void *surface, - cairo_format_t format, - int width, int height); - -cairo_private cairo_surface_t * -_cairo_xlib_surface_get_shm (cairo_xlib_surface_t *surface, - cairo_bool_t overwrite); - -cairo_private cairo_int_status_t -_cairo_xlib_surface_put_shm (cairo_xlib_surface_t *surface); - -cairo_private cairo_surface_t * -_cairo_xlib_surface_create_shm (cairo_xlib_surface_t *other, - pixman_format_code_t format, - int width, int height); - -cairo_private cairo_surface_t * -_cairo_xlib_surface_create_shm__image (cairo_xlib_surface_t *surface, - pixman_format_code_t format, - int width, int height); - -cairo_private void -_cairo_xlib_shm_surface_get_ximage (cairo_surface_t *surface, - XImage *ximage); - -cairo_private void * -_cairo_xlib_shm_surface_get_obdata (cairo_surface_t *surface); - -cairo_private void -_cairo_xlib_shm_surface_mark_active (cairo_surface_t *shm); - -cairo_private cairo_bool_t -_cairo_xlib_shm_surface_is_active (cairo_surface_t *surface); - -cairo_private cairo_bool_t -_cairo_xlib_shm_surface_is_idle (cairo_surface_t *surface); - -cairo_private Pixmap -_cairo_xlib_shm_surface_get_pixmap (cairo_surface_t *surface); - -cairo_private XRenderPictFormat * -_cairo_xlib_shm_surface_get_xrender_format (cairo_surface_t *surface); - -cairo_private pixman_format_code_t -_pixman_format_for_xlib_surface (cairo_xlib_surface_t *surface); - -#endif /* CAIRO_XLIB_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-xlib-render-compositor.c b/source/libs/cairo/cairo-src/src/cairo-xlib-render-compositor.c deleted file mode 100644 index 8a1ec7bd731561fbcbfdff9f53823c54be0ca609..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xlib-render-compositor.c +++ /dev/null @@ -1,2005 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Behdad Esfahbod <behdad@behdad.org> - * Chris Wilson <chris@chris-wilson.co.uk> - * Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation - */ - -#include "cairoint.h" - -#if !CAIRO_HAS_XLIB_XCB_FUNCTIONS - -#include "cairo-xlib-private.h" - -#include "cairo-compositor-private.h" -#include "cairo-damage-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-list-inline.h" -#include "cairo-pattern-private.h" -#include "cairo-pixman-private.h" -#include "cairo-traps-private.h" -#include "cairo-tristrip-private.h" - -static cairo_int_status_t -check_composite (const cairo_composite_rectangles_t *extents) -{ - cairo_xlib_display_t *display = ((cairo_xlib_surface_t *)extents->surface)->display; - - if (! CAIRO_RENDER_SUPPORTS_OPERATOR (display, extents->op)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -acquire (void *abstract_dst) -{ - cairo_xlib_surface_t *dst = abstract_dst; - cairo_int_status_t status; - - status = _cairo_xlib_display_acquire (dst->base.device, &dst->display); - if (unlikely (status)) - return status; - - dst->dpy = dst->display->display; - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -release (void *abstract_dst) -{ - cairo_xlib_surface_t *dst = abstract_dst; - - cairo_device_release (&dst->display->base); - dst->dpy = NULL; - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -set_clip_region (void *_surface, - cairo_region_t *region) -{ - cairo_xlib_surface_t *surface = _surface; - - _cairo_xlib_surface_ensure_picture (surface); - - if (region != NULL) { - XRectangle stack_rects[CAIRO_STACK_ARRAY_LENGTH (XRectangle)]; - XRectangle *rects = stack_rects; - int n_rects, i; - - n_rects = cairo_region_num_rectangles (region); - if (n_rects > ARRAY_LENGTH (stack_rects)) { - rects = _cairo_malloc_ab (n_rects, sizeof (XRectangle)); - if (unlikely (rects == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - for (i = 0; i < n_rects; i++) { - cairo_rectangle_int_t rect; - - cairo_region_get_rectangle (region, i, &rect); - - rects[i].x = rect.x; - rects[i].y = rect.y; - rects[i].width = rect.width; - rects[i].height = rect.height; - } - XRenderSetPictureClipRectangles (surface->dpy, - surface->picture, - 0, 0, - rects, n_rects); - if (rects != stack_rects) - free (rects); - } else { - XRenderPictureAttributes pa; - pa.clip_mask = None; - XRenderChangePicture (surface->dpy, - surface->picture, - CPClipMask, &pa); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -copy_image_boxes (void *_dst, - cairo_image_surface_t *image, - cairo_boxes_t *boxes, - int dx, int dy) -{ - cairo_xlib_surface_t *dst = _dst; - struct _cairo_boxes_chunk *chunk; - cairo_int_status_t status; - Pixmap src; - GC gc; - int i, j; - - assert (image->depth == dst->depth); - - status = acquire (dst); - if (unlikely (status)) - return status; - - status = _cairo_xlib_surface_get_gc (dst->display, dst, &gc); - if (unlikely (status)) { - release (dst); - return status; - } - - src = _cairo_xlib_shm_surface_get_pixmap (&image->base); - if (boxes->num_boxes == 1) { - int x1 = _cairo_fixed_integer_part (boxes->chunks.base[0].p1.x); - int y1 = _cairo_fixed_integer_part (boxes->chunks.base[0].p1.y); - int x2 = _cairo_fixed_integer_part (boxes->chunks.base[0].p2.x); - int y2 = _cairo_fixed_integer_part (boxes->chunks.base[0].p2.y); - - _cairo_xlib_shm_surface_mark_active (&image->base); - XCopyArea (dst->dpy, src, dst->drawable, gc, - x1 + dx, y1 + dy, - x2 - x1, y2 - y1, - x1, y1); - } else { - XRectangle stack_rects[CAIRO_STACK_ARRAY_LENGTH (XRectangle)]; - XRectangle *rects = stack_rects; - - if (boxes->num_boxes > ARRAY_LENGTH (stack_rects)) { - rects = _cairo_malloc_ab (boxes->num_boxes, sizeof (XRectangle)); - if (unlikely (rects == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - j = 0; - for (chunk = &boxes->chunks; chunk; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) { - int x1 = _cairo_fixed_integer_part (chunk->base[i].p1.x); - int y1 = _cairo_fixed_integer_part (chunk->base[i].p1.y); - int x2 = _cairo_fixed_integer_part (chunk->base[i].p2.x); - int y2 = _cairo_fixed_integer_part (chunk->base[i].p2.y); - - if (x2 > x1 && y2 > y1) { - rects[j].x = x1; - rects[j].y = y1; - rects[j].width = x2 - x1; - rects[j].height = y2 - y1; - j++; - } - } - } - - XSetClipRectangles (dst->dpy, gc, 0, 0, rects, j, Unsorted); - _cairo_xlib_shm_surface_mark_active (&image->base); - XCopyArea (dst->dpy, src, dst->drawable, gc, - 0, 0, image->width, image->height, -dx, -dy); - XSetClipMask (dst->dpy, gc, None); - - if (rects != stack_rects) - free (rects); - } - - _cairo_xlib_surface_put_gc (dst->display, dst, gc); - release (dst); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_bool_t -boxes_cover_surface (cairo_boxes_t *boxes, - cairo_xlib_surface_t *surface) -{ - cairo_box_t *b; - - if (boxes->num_boxes != 1) - return FALSE; - - b = &boxes->chunks.base[0]; - - if (_cairo_fixed_integer_part (b->p1.x) > 0 || - _cairo_fixed_integer_part (b->p1.y) > 0) - return FALSE; - - if (_cairo_fixed_integer_part (b->p2.x) < surface->width || - _cairo_fixed_integer_part (b->p2.y) < surface->height) - return FALSE; - - return TRUE; -} - -static cairo_int_status_t -draw_image_boxes (void *_dst, - cairo_image_surface_t *image, - cairo_boxes_t *boxes, - int dx, int dy) -{ - cairo_xlib_surface_t *dst = _dst; - struct _cairo_boxes_chunk *chunk; - cairo_image_surface_t *shm = NULL; - cairo_int_status_t status; - int i; - - if (image->base.device == dst->base.device) { - if (image->depth != dst->depth) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (_cairo_xlib_shm_surface_get_pixmap (&image->base)) - return copy_image_boxes (dst, image, boxes, dx, dy); - - goto draw_image_boxes; - } - - if (boxes_cover_surface (boxes, dst)) - shm = (cairo_image_surface_t *) _cairo_xlib_surface_get_shm (dst, TRUE); - if (shm) { - for (chunk = &boxes->chunks; chunk; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) { - cairo_box_t *b = &chunk->base[i]; - cairo_rectangle_int_t r; - - r.x = _cairo_fixed_integer_part (b->p1.x); - r.y = _cairo_fixed_integer_part (b->p1.y); - r.width = _cairo_fixed_integer_part (b->p2.x) - r.x; - r.height = _cairo_fixed_integer_part (b->p2.y) - r.y; - - if (shm->pixman_format != image->pixman_format || - ! pixman_blt ((uint32_t *)image->data, (uint32_t *)shm->data, - image->stride / sizeof (uint32_t), - shm->stride / sizeof (uint32_t), - PIXMAN_FORMAT_BPP (image->pixman_format), - PIXMAN_FORMAT_BPP (shm->pixman_format), - r.x + dx, r.y + dy, - r.x, r.y, - r.width, r.height)) - { - pixman_image_composite32 (PIXMAN_OP_SRC, - image->pixman_image, NULL, shm->pixman_image, - r.x + dx, r.y + dy, - 0, 0, - r.x, r.y, - r.width, r.height); - } - - shm->base.damage = - _cairo_damage_add_rectangle (shm->base.damage, &r); - } - } - dst->base.is_clear = FALSE; - dst->fallback++; - dst->base.serial++; - return CAIRO_INT_STATUS_NOTHING_TO_DO; - } - - if (image->depth == dst->depth && - ((cairo_xlib_display_t *)dst->display)->shm) { - cairo_box_t extents; - cairo_rectangle_int_t r; - - _cairo_boxes_extents (boxes, &extents); - _cairo_box_round_to_rectangle (&extents, &r); - - shm = (cairo_image_surface_t *) - _cairo_xlib_surface_create_shm (dst, image->pixman_format, - r.width, r.height); - if (shm) { - int tx = -r.x, ty = -r.y; - - assert (shm->pixman_format == image->pixman_format); - for (chunk = &boxes->chunks; chunk; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) { - cairo_box_t *b = &chunk->base[i]; - - r.x = _cairo_fixed_integer_part (b->p1.x); - r.y = _cairo_fixed_integer_part (b->p1.y); - r.width = _cairo_fixed_integer_part (b->p2.x) - r.x; - r.height = _cairo_fixed_integer_part (b->p2.y) - r.y; - - if (! pixman_blt ((uint32_t *)image->data, (uint32_t *)shm->data, - image->stride / sizeof (uint32_t), - shm->stride / sizeof (uint32_t), - PIXMAN_FORMAT_BPP (image->pixman_format), - PIXMAN_FORMAT_BPP (shm->pixman_format), - r.x + dx, r.y + dy, - r.x + tx, r.y + ty, - r.width, r.height)) - { - pixman_image_composite32 (PIXMAN_OP_SRC, - image->pixman_image, NULL, shm->pixman_image, - r.x + dx, r.y + dy, - 0, 0, - r.x + tx, r.y + ty, - r.width, r.height); - } - } - } - - dx = tx; - dy = ty; - image = shm; - - if (_cairo_xlib_shm_surface_get_pixmap (&image->base)) { - status = copy_image_boxes (dst, image, boxes, dx, dy); - if (status != CAIRO_INT_STATUS_UNSUPPORTED) - goto out; - } - } - } - -draw_image_boxes: - status = CAIRO_STATUS_SUCCESS; - for (chunk = &boxes->chunks; chunk; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) { - cairo_box_t *b = &chunk->base[i]; - int x1 = _cairo_fixed_integer_part (b->p1.x); - int y1 = _cairo_fixed_integer_part (b->p1.y); - int x2 = _cairo_fixed_integer_part (b->p2.x); - int y2 = _cairo_fixed_integer_part (b->p2.y); - if (_cairo_xlib_surface_draw_image (dst, image, - x1 + dx, y1 + dy, - x2 - x1, y2 - y1, - x1, y1)) { - status = CAIRO_INT_STATUS_UNSUPPORTED; - goto out; - } - } - } - -out: - cairo_surface_destroy (&shm->base); - return status; -} - -static cairo_int_status_t -copy_boxes (void *_dst, - cairo_surface_t *_src, - cairo_boxes_t *boxes, - const cairo_rectangle_int_t *extents, - int dx, int dy) -{ - cairo_xlib_surface_t *dst = _dst; - cairo_xlib_surface_t *src = (cairo_xlib_surface_t *)_src; - struct _cairo_boxes_chunk *chunk; - cairo_int_status_t status; - GC gc; - Drawable d; - int i, j; - - if (! _cairo_xlib_surface_same_screen (dst, src)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - if (dst->depth != src->depth) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = acquire (dst); - if (unlikely (status)) - return status; - - status = _cairo_xlib_surface_get_gc (dst->display, dst, &gc); - if (unlikely (status)) { - release (dst); - return status; - } - - if (src->fallback && src->shm->damage->dirty) { - assert (src != dst); - d = _cairo_xlib_shm_surface_get_pixmap (src->shm); - assert (d != 0); - } else { - if (! src->owns_pixmap) { - XGCValues gcv; - - gcv.subwindow_mode = IncludeInferiors; - XChangeGC (dst->display->display, gc, GCSubwindowMode, &gcv); - } - d = src->drawable; - } - - if (boxes->num_boxes == 1) { - int x1 = _cairo_fixed_integer_part (boxes->chunks.base[0].p1.x); - int y1 = _cairo_fixed_integer_part (boxes->chunks.base[0].p1.y); - int x2 = _cairo_fixed_integer_part (boxes->chunks.base[0].p2.x); - int y2 = _cairo_fixed_integer_part (boxes->chunks.base[0].p2.y); - - XCopyArea (dst->dpy, d, dst->drawable, gc, - x1 + dx, y1 + dy, - x2 - x1, y2 - y1, - x1, y1); - } else { - /* We can only have a single control for subwindow_mode on the - * GC. If we have a Window destination, we need to set ClipByChildren, - * but if we have a Window source, we need IncludeInferiors. If we have - * both a Window destination and source, we must fallback. There is - * no convenient way to detect if a drawable is a Pixmap or Window, - * therefore we can only rely on those surfaces that we created - * ourselves to be Pixmaps, and treat everything else as a potential - * Window. - */ - if (src == dst || (!src->owns_pixmap && !dst->owns_pixmap)) { - for (chunk = &boxes->chunks; chunk; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) { - int x1 = _cairo_fixed_integer_part (chunk->base[i].p1.x); - int y1 = _cairo_fixed_integer_part (chunk->base[i].p1.y); - int x2 = _cairo_fixed_integer_part (chunk->base[i].p2.x); - int y2 = _cairo_fixed_integer_part (chunk->base[i].p2.y); - XCopyArea (dst->dpy, d, dst->drawable, gc, - x1 + dx, y1 + dy, - x2 - x1, y2 - y1, - x1, y1); - } - } - } else { - XRectangle stack_rects[CAIRO_STACK_ARRAY_LENGTH (XRectangle)]; - XRectangle *rects = stack_rects; - - if (boxes->num_boxes > ARRAY_LENGTH (stack_rects)) { - rects = _cairo_malloc_ab (boxes->num_boxes, sizeof (XRectangle)); - if (unlikely (rects == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - j = 0; - for (chunk = &boxes->chunks; chunk; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) { - int x1 = _cairo_fixed_integer_part (chunk->base[i].p1.x); - int y1 = _cairo_fixed_integer_part (chunk->base[i].p1.y); - int x2 = _cairo_fixed_integer_part (chunk->base[i].p2.x); - int y2 = _cairo_fixed_integer_part (chunk->base[i].p2.y); - - rects[j].x = x1; - rects[j].y = y1; - rects[j].width = x2 - x1; - rects[j].height = y2 - y1; - j++; - } - } - assert (j == boxes->num_boxes); - - XSetClipRectangles (dst->dpy, gc, 0, 0, rects, j, Unsorted); - - XCopyArea (dst->dpy, d, dst->drawable, gc, - extents->x + dx, extents->y + dy, - extents->width, extents->height, - extents->x, extents->y); - - XSetClipMask (dst->dpy, gc, None); - - if (rects != stack_rects) - free (rects); - } - } - - if (src->fallback && src->shm->damage->dirty) { - _cairo_xlib_shm_surface_mark_active (src->shm); - } else if (! src->owns_pixmap) { - XGCValues gcv; - - gcv.subwindow_mode = ClipByChildren; - XChangeGC (dst->display->display, gc, GCSubwindowMode, &gcv); - } - - _cairo_xlib_surface_put_gc (dst->display, dst, gc); - release (dst); - return CAIRO_STATUS_SUCCESS; -} - -static int -_render_operator (cairo_operator_t op) -{ - switch (op) { - case CAIRO_OPERATOR_CLEAR: - return PictOpClear; - - case CAIRO_OPERATOR_SOURCE: - return PictOpSrc; - case CAIRO_OPERATOR_OVER: - return PictOpOver; - case CAIRO_OPERATOR_IN: - return PictOpIn; - case CAIRO_OPERATOR_OUT: - return PictOpOut; - case CAIRO_OPERATOR_ATOP: - return PictOpAtop; - - case CAIRO_OPERATOR_DEST: - return PictOpDst; - case CAIRO_OPERATOR_DEST_OVER: - return PictOpOverReverse; - case CAIRO_OPERATOR_DEST_IN: - return PictOpInReverse; - case CAIRO_OPERATOR_DEST_OUT: - return PictOpOutReverse; - case CAIRO_OPERATOR_DEST_ATOP: - return PictOpAtopReverse; - - case CAIRO_OPERATOR_XOR: - return PictOpXor; - case CAIRO_OPERATOR_ADD: - return PictOpAdd; - case CAIRO_OPERATOR_SATURATE: - return PictOpSaturate; - - case CAIRO_OPERATOR_MULTIPLY: - return PictOpMultiply; - case CAIRO_OPERATOR_SCREEN: - return PictOpScreen; - case CAIRO_OPERATOR_OVERLAY: - return PictOpOverlay; - case CAIRO_OPERATOR_DARKEN: - return PictOpDarken; - case CAIRO_OPERATOR_LIGHTEN: - return PictOpLighten; - case CAIRO_OPERATOR_COLOR_DODGE: - return PictOpColorDodge; - case CAIRO_OPERATOR_COLOR_BURN: - return PictOpColorBurn; - case CAIRO_OPERATOR_HARD_LIGHT: - return PictOpHardLight; - case CAIRO_OPERATOR_SOFT_LIGHT: - return PictOpSoftLight; - case CAIRO_OPERATOR_DIFFERENCE: - return PictOpDifference; - case CAIRO_OPERATOR_EXCLUSION: - return PictOpExclusion; - case CAIRO_OPERATOR_HSL_HUE: - return PictOpHSLHue; - case CAIRO_OPERATOR_HSL_SATURATION: - return PictOpHSLSaturation; - case CAIRO_OPERATOR_HSL_COLOR: - return PictOpHSLColor; - case CAIRO_OPERATOR_HSL_LUMINOSITY: - return PictOpHSLLuminosity; - - default: - ASSERT_NOT_REACHED; - return PictOpOver; - } -} - -static cairo_bool_t -fill_reduces_to_source (cairo_operator_t op, - const cairo_color_t *color, - cairo_xlib_surface_t *dst) -{ - if (dst->base.is_clear || CAIRO_COLOR_IS_OPAQUE (color)) { - if (op == CAIRO_OPERATOR_OVER) - return TRUE; - if (op == CAIRO_OPERATOR_ADD) - return (dst->base.content & CAIRO_CONTENT_COLOR) == 0; - } - - return FALSE; -} - -static cairo_int_status_t -fill_rectangles (void *abstract_surface, - cairo_operator_t op, - const cairo_color_t *color, - cairo_rectangle_int_t *rects, - int num_rects) -{ - cairo_xlib_surface_t *dst = abstract_surface; - XRenderColor render_color; - int i; - - //X_DEBUG ((display->display, "fill_rectangles (dst=%x)", (unsigned int) surface->drawable)); - - if (fill_reduces_to_source (op, color, dst)) - op = CAIRO_OPERATOR_SOURCE; - - if (!CAIRO_RENDER_HAS_FILL_RECTANGLES(dst->display)) { - cairo_int_status_t status; - - status = CAIRO_INT_STATUS_UNSUPPORTED; - if (op == CAIRO_OPERATOR_SOURCE) - status = _cairo_xlib_core_fill_rectangles (dst, color, num_rects, rects); - return status; - } - - render_color.red = color->red_short; - render_color.green = color->green_short; - render_color.blue = color->blue_short; - render_color.alpha = color->alpha_short; - - _cairo_xlib_surface_ensure_picture (dst); - if (num_rects == 1) { - /* Take advantage of the protocol compaction that libXrender performs - * to amalgamate sequences of XRenderFillRectangle(). - */ - XRenderFillRectangle (dst->dpy, - _render_operator (op), - dst->picture, - &render_color, - rects->x, rects->y, - rects->width, rects->height); - } else { - XRectangle stack_xrects[CAIRO_STACK_ARRAY_LENGTH (XRectangle)]; - XRectangle *xrects = stack_xrects; - - if (num_rects > ARRAY_LENGTH (stack_xrects)) { - xrects = _cairo_malloc_ab (num_rects, sizeof (XRectangle)); - if (unlikely (xrects == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - for (i = 0; i < num_rects; i++) { - xrects[i].x = rects[i].x; - xrects[i].y = rects[i].y; - xrects[i].width = rects[i].width; - xrects[i].height = rects[i].height; - } - - XRenderFillRectangles (dst->dpy, - _render_operator (op), - dst->picture, - &render_color, xrects, num_rects); - - if (xrects != stack_xrects) - free (xrects); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -fill_boxes (void *abstract_surface, - cairo_operator_t op, - const cairo_color_t *color, - cairo_boxes_t *boxes) -{ - cairo_xlib_surface_t *dst = abstract_surface; - XRenderColor render_color; - - if (fill_reduces_to_source (op, color, dst)) - op = CAIRO_OPERATOR_SOURCE; - - if (!CAIRO_RENDER_HAS_FILL_RECTANGLES(dst->display)) { - cairo_int_status_t status; - - status = CAIRO_INT_STATUS_UNSUPPORTED; - if (op == CAIRO_OPERATOR_SOURCE) - status = _cairo_xlib_core_fill_boxes (dst, color, boxes); - return status; - } - - render_color.red = color->red_short; - render_color.green = color->green_short; - render_color.blue = color->blue_short; - render_color.alpha = color->alpha_short; - - _cairo_xlib_surface_ensure_picture (dst); - if (boxes->num_boxes == 1) { - int x1 = _cairo_fixed_integer_part (boxes->chunks.base[0].p1.x); - int y1 = _cairo_fixed_integer_part (boxes->chunks.base[0].p1.y); - int x2 = _cairo_fixed_integer_part (boxes->chunks.base[0].p2.x); - int y2 = _cairo_fixed_integer_part (boxes->chunks.base[0].p2.y); - - /* Take advantage of the protocol compaction that libXrender performs - * to amalgamate sequences of XRenderFillRectangle(). - */ - XRenderFillRectangle (dst->dpy, - _render_operator (op), - dst->picture, - &render_color, - x1, y1, - x2 - x1, y2 - y1); - } else { - XRectangle stack_xrects[CAIRO_STACK_ARRAY_LENGTH (XRectangle)]; - XRectangle *xrects = stack_xrects; - struct _cairo_boxes_chunk *chunk; - int i, j; - - if (boxes->num_boxes > ARRAY_LENGTH (stack_xrects)) { - xrects = _cairo_malloc_ab (boxes->num_boxes, sizeof (XRectangle)); - if (unlikely (xrects == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - j = 0; - for (chunk = &boxes->chunks; chunk; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) { - int x1 = _cairo_fixed_integer_part (chunk->base[i].p1.x); - int y1 = _cairo_fixed_integer_part (chunk->base[i].p1.y); - int x2 = _cairo_fixed_integer_part (chunk->base[i].p2.x); - int y2 = _cairo_fixed_integer_part (chunk->base[i].p2.y); - - xrects[j].x = x1; - xrects[j].y = y1; - xrects[j].width = x2 - x1; - xrects[j].height = y2 - y1; - j++; - } - } - - XRenderFillRectangles (dst->dpy, - _render_operator (op), - dst->picture, - &render_color, xrects, j); - - if (xrects != stack_xrects) - free (xrects); - } - - return CAIRO_STATUS_SUCCESS; -} - -#if 0 -check_composite () - operation = _categorize_composite_operation (dst, op, src_pattern, - mask_pattern != NULL); - if (operation == DO_UNSUPPORTED) - return UNSUPPORTED ("unsupported operation"); - - //X_DEBUG ((display->display, "composite (dst=%x)", (unsigned int) dst->drawable)); - - operation = _recategorize_composite_operation (dst, op, src, &src_attr, - mask_pattern != NULL); - if (operation == DO_UNSUPPORTED) { - status = UNSUPPORTED ("unsupported operation"); - goto BAIL; - } -#endif - -static cairo_int_status_t -composite (void *abstract_dst, - cairo_operator_t op, - cairo_surface_t *abstract_src, - cairo_surface_t *abstract_mask, - 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_xlib_surface_t *dst = abstract_dst; - cairo_xlib_source_t *src = (cairo_xlib_source_t *)abstract_src; - - op = _render_operator (op); - - _cairo_xlib_surface_ensure_picture (dst); - if (abstract_mask) { - cairo_xlib_source_t *mask = (cairo_xlib_source_t *)abstract_mask; - - XRenderComposite (dst->dpy, op, - src->picture, mask->picture, dst->picture, - src_x, src_y, - mask_x, mask_y, - dst_x, dst_y, - width, height); - } else { - XRenderComposite (dst->dpy, op, - src->picture, 0, dst->picture, - src_x, src_y, - 0, 0, - dst_x, dst_y, - width, height); - } - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -lerp (void *abstract_dst, - cairo_surface_t *abstract_src, - cairo_surface_t *abstract_mask, - 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_xlib_surface_t *dst = abstract_dst; - cairo_xlib_source_t *src = (cairo_xlib_source_t *)abstract_src; - cairo_xlib_source_t *mask = (cairo_xlib_source_t *)abstract_mask; - - _cairo_xlib_surface_ensure_picture (dst); - XRenderComposite (dst->dpy, PictOpOutReverse, - mask->picture, None, dst->picture, - mask_x, mask_y, - 0, 0, - dst_x, dst_y, - width, height); - XRenderComposite (dst->dpy, PictOpAdd, - src->picture, mask->picture, dst->picture, - src_x, src_y, - mask_x, mask_y, - dst_x, dst_y, - width, height); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -composite_boxes (void *abstract_dst, - cairo_operator_t op, - cairo_surface_t *abstract_src, - cairo_surface_t *abstract_mask, - int src_x, - int src_y, - int mask_x, - int mask_y, - int dst_x, - int dst_y, - cairo_boxes_t *boxes, - const cairo_rectangle_int_t *extents) -{ - cairo_xlib_surface_t *dst = abstract_dst; - Picture src = ((cairo_xlib_source_t *)abstract_src)->picture; - Picture mask = abstract_mask ? ((cairo_xlib_source_t *)abstract_mask)->picture : 0; - XRectangle stack_rects[CAIRO_STACK_ARRAY_LENGTH (XRectangle)]; - XRectangle *rects = stack_rects; - struct _cairo_boxes_chunk *chunk; - int i, j; - - op = _render_operator (op); - _cairo_xlib_surface_ensure_picture (dst); - if (boxes->num_boxes == 1) { - int x1 = _cairo_fixed_integer_part (boxes->chunks.base[0].p1.x); - int y1 = _cairo_fixed_integer_part (boxes->chunks.base[0].p1.y); - int x2 = _cairo_fixed_integer_part (boxes->chunks.base[0].p2.x); - int y2 = _cairo_fixed_integer_part (boxes->chunks.base[0].p2.y); - - XRenderComposite (dst->dpy, op, - src, mask, dst->picture, - x1 + src_x, y1 + src_y, - x1 + mask_x, y1 + mask_y, - x1 - dst_x, y1 - dst_y, - x2 - x1, y2 - y1); - return CAIRO_STATUS_SUCCESS; - } - - if (boxes->num_boxes > ARRAY_LENGTH (stack_rects)) { - rects = _cairo_malloc_ab (boxes->num_boxes, sizeof (XRectangle)); - if (unlikely (rects == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - j = 0; - for (chunk = &boxes->chunks; chunk; chunk = chunk->next) { - for (i = 0; i < chunk->count; i++) { - int x1 = _cairo_fixed_integer_part (chunk->base[i].p1.x); - int y1 = _cairo_fixed_integer_part (chunk->base[i].p1.y); - int x2 = _cairo_fixed_integer_part (chunk->base[i].p2.x); - int y2 = _cairo_fixed_integer_part (chunk->base[i].p2.y); - - rects[j].x = x1 - dst_x; - rects[j].y = y1 - dst_y; - rects[j].width = x2 - x1; - rects[j].height = y2 - y1; - j++; - } - } - assert (j == boxes->num_boxes); - - XRenderSetPictureClipRectangles (dst->dpy, - dst->picture, - 0, 0, - rects, j); - if (rects != stack_rects) - free (rects); - - XRenderComposite (dst->dpy, op, - src, mask, dst->picture, - extents->x + src_x, extents->y + src_y, - extents->x + mask_x, extents->y + mask_y, - extents->x - dst_x, extents->y - dst_y, - extents->width, extents->height); - - set_clip_region (dst, NULL); - - return CAIRO_STATUS_SUCCESS; -} - -/* font rendering */ - -void -_cairo_xlib_font_close (cairo_xlib_font_t *priv) -{ - cairo_xlib_display_t *display = (cairo_xlib_display_t *)priv->base.key; - int i; - - /* XXX All I really want is to do is zap my glyphs... */ - _cairo_scaled_font_reset_cache (priv->font); - - for (i = 0; i < NUM_GLYPHSETS; i++) { - cairo_xlib_font_glyphset_t *info; - - info = &priv->glyphset[i]; - if (info->glyphset) - XRenderFreeGlyphSet (display->display, info->glyphset); - } - - /* XXX locking */ - cairo_list_del (&priv->link); - cairo_list_del (&priv->base.link); - free (priv); -} - -static void -_cairo_xlib_font_fini (cairo_scaled_font_private_t *abstract_private, - cairo_scaled_font_t *font) -{ - cairo_xlib_font_t *priv = (cairo_xlib_font_t *) abstract_private; - cairo_status_t status; - cairo_xlib_display_t *display; - int i; - - cairo_list_del (&priv->base.link); - cairo_list_del (&priv->link); - - status = _cairo_xlib_display_acquire (priv->device, &display); - if (status) - goto BAIL; - - for (i = 0; i < NUM_GLYPHSETS; i++) { - cairo_xlib_font_glyphset_t *info; - - info = &priv->glyphset[i]; - if (info->glyphset) - XRenderFreeGlyphSet (display->display, info->glyphset); - } - - cairo_device_release (&display->base); -BAIL: - cairo_device_destroy (&display->base); - free (priv); -} - -static cairo_xlib_font_t * -_cairo_xlib_font_create (cairo_xlib_display_t *display, - cairo_scaled_font_t *font) -{ - cairo_xlib_font_t *priv; - int i; - - priv = malloc (sizeof (cairo_xlib_font_t)); - if (unlikely (priv == NULL)) - return NULL; - - _cairo_scaled_font_attach_private (font, &priv->base, display, - _cairo_xlib_font_fini); - - priv->device = cairo_device_reference (&display->base); - priv->font = font; - cairo_list_add (&priv->link, &display->fonts); - - for (i = 0; i < NUM_GLYPHSETS; i++) { - cairo_xlib_font_glyphset_t *info = &priv->glyphset[i]; - switch (i) { - case GLYPHSET_INDEX_ARGB32: info->format = CAIRO_FORMAT_ARGB32; break; - case GLYPHSET_INDEX_A8: info->format = CAIRO_FORMAT_A8; break; - case GLYPHSET_INDEX_A1: info->format = CAIRO_FORMAT_A1; break; - default: ASSERT_NOT_REACHED; break; - } - info->xrender_format = NULL; - info->glyphset = None; - info->to_free.count = 0; - } - - return priv; -} - -static int -_cairo_xlib_get_glyphset_index_for_format (cairo_format_t format) -{ - if (format == CAIRO_FORMAT_A8) - return GLYPHSET_INDEX_A8; - if (format == CAIRO_FORMAT_A1) - return GLYPHSET_INDEX_A1; - - assert (format == CAIRO_FORMAT_ARGB32); - return GLYPHSET_INDEX_ARGB32; -} - -static inline cairo_xlib_font_t * -_cairo_xlib_font_get (const cairo_xlib_display_t *display, - cairo_scaled_font_t *font) -{ - return (cairo_xlib_font_t *)_cairo_scaled_font_find_private (font, display); -} - -typedef struct { - cairo_scaled_glyph_private_t base; - - - cairo_xlib_font_glyphset_t *glyphset; -} cairo_xlib_glyph_private_t; - -static void -_cairo_xlib_glyph_fini (cairo_scaled_glyph_private_t *glyph_private, - cairo_scaled_glyph_t *glyph, - cairo_scaled_font_t *font) -{ - cairo_xlib_glyph_private_t *priv = (cairo_xlib_glyph_private_t *)glyph_private; - - if (! font->finished) { - cairo_xlib_font_t *font_private; - struct _cairo_xlib_font_glyphset_free_glyphs *to_free; - cairo_xlib_font_glyphset_t *info; - - font_private = _cairo_xlib_font_get (glyph_private->key, font); - assert (font_private); - - info = priv->glyphset; - to_free = &info->to_free; - if (to_free->count == ARRAY_LENGTH (to_free->indices)) { - cairo_xlib_display_t *display; - - if (_cairo_xlib_display_acquire (font_private->device, - &display) == CAIRO_STATUS_SUCCESS) { - XRenderFreeGlyphs (display->display, - info->glyphset, - to_free->indices, - to_free->count); - cairo_device_release (&display->base); - } - - to_free->count = 0; - } - - to_free->indices[to_free->count++] = - _cairo_scaled_glyph_index (glyph); - } - - cairo_list_del (&glyph_private->link); - free (glyph_private); -} - -static cairo_status_t -_cairo_xlib_glyph_attach (cairo_xlib_display_t *display, - cairo_scaled_glyph_t *glyph, - cairo_xlib_font_glyphset_t *info) -{ - cairo_xlib_glyph_private_t *priv; - - priv = malloc (sizeof (*priv)); - if (unlikely (priv == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_scaled_glyph_attach_private (glyph, &priv->base, display, - _cairo_xlib_glyph_fini); - priv->glyphset = info; - - glyph->dev_private = info; - glyph->dev_private_key = display; - return CAIRO_STATUS_SUCCESS; -} - -static cairo_xlib_font_glyphset_t * -_cairo_xlib_font_get_glyphset_info_for_format (cairo_xlib_display_t *display, - cairo_scaled_font_t *font, - cairo_format_t format) -{ - cairo_xlib_font_t *priv; - cairo_xlib_font_glyphset_t *info; - int glyphset_index; - - glyphset_index = _cairo_xlib_get_glyphset_index_for_format (format); - - priv = _cairo_xlib_font_get (display, font); - if (priv == NULL) { - priv = _cairo_xlib_font_create (display, font); - if (priv == NULL) - return NULL; - } - - info = &priv->glyphset[glyphset_index]; - if (info->glyphset == None) { - info->xrender_format = - _cairo_xlib_display_get_xrender_format (display, info->format); - info->glyphset = XRenderCreateGlyphSet (display->display, - info->xrender_format); - } - - return info; -} - -static cairo_bool_t -has_pending_free_glyph (cairo_xlib_font_glyphset_t *info, - unsigned long glyph_index) -{ - struct _cairo_xlib_font_glyphset_free_glyphs *to_free; - int i; - - to_free = &info->to_free; - for (i = 0; i < to_free->count; i++) { - if (to_free->indices[i] == glyph_index) { - to_free->count--; - memmove (&to_free->indices[i], - &to_free->indices[i+1], - (to_free->count - i) * sizeof (to_free->indices[0])); - return TRUE; - } - } - - return FALSE; -} - -static cairo_xlib_font_glyphset_t * -find_pending_free_glyph (cairo_xlib_display_t *display, - cairo_scaled_font_t *font, - unsigned long glyph_index, - cairo_image_surface_t *surface) -{ - cairo_xlib_font_t *priv; - int i; - - priv = _cairo_xlib_font_get (display, font); - if (priv == NULL) - return NULL; - - if (surface != NULL) { - i = _cairo_xlib_get_glyphset_index_for_format (surface->format); - if (has_pending_free_glyph (&priv->glyphset[i], glyph_index)) - return &priv->glyphset[i]; - } else { - for (i = 0; i < NUM_GLYPHSETS; i++) { - if (has_pending_free_glyph (&priv->glyphset[i], glyph_index)) - return &priv->glyphset[i]; - } - } - - return NULL; -} - -static cairo_status_t -_cairo_xlib_surface_add_glyph (cairo_xlib_display_t *display, - cairo_scaled_font_t *font, - cairo_scaled_glyph_t **pscaled_glyph) -{ - XGlyphInfo glyph_info; - unsigned long glyph_index; - unsigned char *data; - cairo_status_t status = CAIRO_STATUS_SUCCESS; - cairo_scaled_glyph_t *glyph = *pscaled_glyph; - cairo_image_surface_t *glyph_surface = glyph->surface; - cairo_bool_t already_had_glyph_surface; - cairo_xlib_font_glyphset_t *info; - - glyph_index = _cairo_scaled_glyph_index (glyph); - - /* check to see if we have a pending XRenderFreeGlyph for this glyph */ - info = find_pending_free_glyph (display, font, glyph_index, glyph_surface); - if (info != NULL) - return _cairo_xlib_glyph_attach (display, glyph, info); - - if (glyph_surface == NULL) { - status = _cairo_scaled_glyph_lookup (font, - glyph_index, - CAIRO_SCALED_GLYPH_INFO_METRICS | - CAIRO_SCALED_GLYPH_INFO_SURFACE, - pscaled_glyph); - if (unlikely (status)) - return status; - - glyph = *pscaled_glyph; - glyph_surface = glyph->surface; - already_had_glyph_surface = FALSE; - } else { - already_had_glyph_surface = TRUE; - } - - info = _cairo_xlib_font_get_glyphset_info_for_format (display, font, - glyph_surface->format); - -#if 0 - /* If the glyph surface has zero height or width, we create - * a clear 1x1 surface, to avoid various X server bugs. - */ - if (glyph_surface->width == 0 || glyph_surface->height == 0) { - cairo_surface_t *tmp_surface; - - tmp_surface = cairo_image_surface_create (info->format, 1, 1); - status = tmp_surface->status; - if (unlikely (status)) - goto BAIL; - - tmp_surface->device_transform = glyph_surface->base.device_transform; - tmp_surface->device_transform_inverse = glyph_surface->base.device_transform_inverse; - - glyph_surface = (cairo_image_surface_t *) tmp_surface; - } -#endif - - /* If the glyph format does not match the font format, then we - * create a temporary surface for the glyph image with the font's - * format. - */ - if (glyph_surface->format != info->format) { - cairo_surface_pattern_t pattern; - cairo_surface_t *tmp_surface; - - tmp_surface = cairo_image_surface_create (info->format, - glyph_surface->width, - glyph_surface->height); - status = tmp_surface->status; - if (unlikely (status)) - goto BAIL; - - tmp_surface->device_transform = glyph_surface->base.device_transform; - tmp_surface->device_transform_inverse = glyph_surface->base.device_transform_inverse; - - _cairo_pattern_init_for_surface (&pattern, &glyph_surface->base); - status = _cairo_surface_paint (tmp_surface, - CAIRO_OPERATOR_SOURCE, &pattern.base, - NULL); - _cairo_pattern_fini (&pattern.base); - - glyph_surface = (cairo_image_surface_t *) tmp_surface; - - if (unlikely (status)) - goto BAIL; - } - - /* XXX: FRAGILE: We're ignore device_transform scaling here. A bug? */ - glyph_info.x = _cairo_lround (glyph_surface->base.device_transform.x0); - glyph_info.y = _cairo_lround (glyph_surface->base.device_transform.y0); - glyph_info.width = glyph_surface->width; - glyph_info.height = glyph_surface->height; - glyph_info.xOff = glyph->x_advance; - glyph_info.yOff = glyph->y_advance; - - data = glyph_surface->data; - - /* flip formats around */ - switch (_cairo_xlib_get_glyphset_index_for_format (glyph->surface->format)) { - case GLYPHSET_INDEX_A1: - /* local bitmaps are always stored with bit == byte */ - if (_cairo_is_little_endian() != (BitmapBitOrder (display->display) == LSBFirst)) { - int c = glyph_surface->stride * glyph_surface->height; - unsigned char *d; - unsigned char *new, *n; - - if (c == 0) - break; - - new = malloc (c); - if (!new) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto BAIL; - } - n = new; - d = data; - do { - char b = *d++; - b = ((b << 1) & 0xaa) | ((b >> 1) & 0x55); - b = ((b << 2) & 0xcc) | ((b >> 2) & 0x33); - b = ((b << 4) & 0xf0) | ((b >> 4) & 0x0f); - *n++ = b; - } while (--c); - data = new; - } - break; - case GLYPHSET_INDEX_A8: - break; - case GLYPHSET_INDEX_ARGB32: - if (_cairo_is_little_endian() != (ImageByteOrder (display->display) == LSBFirst)) { - unsigned int c = glyph_surface->stride * glyph_surface->height / 4; - const uint32_t *d; - uint32_t *new, *n; - - if (c == 0) - break; - - new = malloc (4 * c); - if (unlikely (new == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto BAIL; - } - n = new; - d = (uint32_t *) data; - do { - *n++ = bswap_32 (*d); - d++; - } while (--c); - data = (uint8_t *) new; - } - break; - default: - ASSERT_NOT_REACHED; - break; - } - /* XXX assume X server wants pixman padding. Xft assumes this as well */ - - XRenderAddGlyphs (display->display, info->glyphset, - &glyph_index, &glyph_info, 1, - (char *) data, - glyph_surface->stride * glyph_surface->height); - - if (data != glyph_surface->data) - free (data); - - status = _cairo_xlib_glyph_attach (display, glyph, info); - - BAIL: - if (glyph_surface != glyph->surface) - cairo_surface_destroy (&glyph_surface->base); - - /* if the scaled glyph didn't already have a surface attached - * to it, release the created surface now that we have it - * uploaded to the X server. If the surface has already been - * there (eg. because image backend requested it), leave it in - * the cache - */ - if (!already_had_glyph_surface) - _cairo_scaled_glyph_set_surface (glyph, font, NULL); - - return status; -} - -typedef void (*cairo_xrender_composite_text_func_t) - (Display *dpy, - int op, - Picture src, - Picture dst, - _Xconst XRenderPictFormat *maskFormat, - int xSrc, - int ySrc, - int xDst, - int yDst, - _Xconst XGlyphElt8 *elts, - int nelt); - -/* Build a struct of the same size of #cairo_glyph_t that can be used both as - * an input glyph with double coordinates, and as "working" glyph with - * integer from-current-point offsets. */ -typedef union { - cairo_glyph_t d; - unsigned long index; - struct { - unsigned long index; - int x; - int y; - } i; -} cairo_xlib_glyph_t; - -/* compile-time assert that #cairo_xlib_glyph_t is the same size as #cairo_glyph_t */ -COMPILE_TIME_ASSERT (sizeof (cairo_xlib_glyph_t) == sizeof (cairo_glyph_t)); - -/* Start a new element for the first glyph, - * or for any glyph that has unexpected position, - * or if current element has too many glyphs - * (Xrender limits each element to 252 glyphs, we limit them to 128) - * - * These same conditions need to be mirrored between - * _cairo_xlib_surface_emit_glyphs and _emit_glyph_chunks - */ -#define _start_new_glyph_elt(count, glyph) \ - (((count) & 127) == 0 || (glyph)->i.x || (glyph)->i.y) - -static cairo_status_t -_emit_glyphs_chunk (cairo_xlib_display_t *display, - cairo_xlib_surface_t *dst, - int dst_x, int dst_y, - cairo_xlib_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *font, - cairo_bool_t use_mask, - cairo_operator_t op, - cairo_xlib_source_t *src, - int src_x, int src_y, - /* info for this chunk */ - int num_elts, - int width, - cairo_xlib_font_glyphset_t *info) -{ - /* Which XRenderCompositeText function to use */ - cairo_xrender_composite_text_func_t composite_text_func; - int size; - - /* Element buffer stuff */ - XGlyphElt8 *elts; - XGlyphElt8 stack_elts[CAIRO_STACK_ARRAY_LENGTH (XGlyphElt8)]; - - /* Reuse the input glyph array for output char generation */ - char *char8 = (char *) glyphs; - unsigned short *char16 = (unsigned short *) glyphs; - unsigned int *char32 = (unsigned int *) glyphs; - - int i; - int nelt; /* Element index */ - int n; /* Num output glyphs in current element */ - int j; /* Num output glyphs so far */ - - switch (width) { - case 1: - /* don't cast the 8-variant, to catch possible mismatches */ - composite_text_func = XRenderCompositeText8; - size = sizeof (char); - break; - case 2: - composite_text_func = (cairo_xrender_composite_text_func_t) XRenderCompositeText16; - size = sizeof (unsigned short); - break; - default: - case 4: - composite_text_func = (cairo_xrender_composite_text_func_t) XRenderCompositeText32; - size = sizeof (unsigned int); - } - - /* Allocate element array */ - if (num_elts <= ARRAY_LENGTH (stack_elts)) { - elts = stack_elts; - } else { - elts = _cairo_malloc_ab (num_elts, sizeof (XGlyphElt8)); - if (unlikely (elts == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - /* Fill them in */ - nelt = 0; - n = 0; - j = 0; - for (i = 0; i < num_glyphs; i++) { - /* Start a new element for first output glyph, - * or for any glyph that has unexpected position, - * or if current element has too many glyphs. - * - * These same conditions are mirrored in _cairo_xlib_surface_emit_glyphs() - */ - if (_start_new_glyph_elt (j, &glyphs[i])) { - if (j) { - elts[nelt].nchars = n; - nelt++; - n = 0; - } - elts[nelt].chars = char8 + size * j; - elts[nelt].glyphset = info->glyphset; - elts[nelt].xOff = glyphs[i].i.x; - elts[nelt].yOff = glyphs[i].i.y; - } - - switch (width) { - case 1: char8 [j] = (char) glyphs[i].index; break; - case 2: char16[j] = (unsigned short) glyphs[i].index; break; - default: - case 4: char32[j] = (unsigned int) glyphs[i].index; break; - } - - n++; - j++; - } - - if (n) { - elts[nelt].nchars = n; - nelt++; - } - - /* Check that we agree with _cairo_xlib_surface_emit_glyphs() on the - * expected number of xGlyphElts. */ - assert (nelt == num_elts); - - composite_text_func (display->display, op, - src->picture, - dst->picture, - use_mask ? info->xrender_format : NULL, - src_x + elts[0].xOff + dst_x, - src_y + elts[0].yOff + dst_y, - elts[0].xOff, elts[0].yOff, - (XGlyphElt8 *) elts, nelt); - - if (elts != stack_elts) - free (elts); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -check_composite_glyphs (const cairo_composite_rectangles_t *extents, - cairo_scaled_font_t *font, - cairo_glyph_t *glyphs, - int *num_glyphs) -{ - cairo_xlib_surface_t *dst = (cairo_xlib_surface_t *)extents->surface; - cairo_xlib_display_t *display = dst->display; - int max_request_size, size; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - if (! CAIRO_RENDER_SUPPORTS_OPERATOR (display, extents->op)) - return CAIRO_INT_STATUS_UNSUPPORTED; - - /* The glyph coordinates must be representable in an int16_t. - * When possible, they will be expressed as an offset from the - * previous glyph, otherwise they will be an offset from the - * surface origin. If we can't guarantee this to be possible, - * fallback. - */ - if (extents->bounded.x + extents->bounded.width > INT16_MAX || - extents->bounded.y + extents->bounded.height> INT16_MAX || - extents->bounded.x < INT16_MIN || - extents->bounded.y < INT16_MIN) - { - return CAIRO_INT_STATUS_UNSUPPORTED; - } - - /* Approximate the size of the largest glyph and fallback if we can not - * upload it to the xserver. - */ - size = ceil (font->max_scale); - size = 4 * size * size; - max_request_size = (XExtendedMaxRequestSize (display->display) ? XExtendedMaxRequestSize (display->display) - : XMaxRequestSize (display->display)) * 4 - - sz_xRenderAddGlyphsReq - - sz_xGlyphInfo - - 8; - if (size >= max_request_size) - return CAIRO_INT_STATUS_UNSUPPORTED; - - return CAIRO_STATUS_SUCCESS; -} - -/* sz_xGlyphtElt required alignment to a 32-bit boundary, so ensure we have - * enough room for padding */ -#define _cairo_sz_xGlyphElt (sz_xGlyphElt + 4) - -static cairo_int_status_t -composite_glyphs (void *surface, - cairo_operator_t op, - cairo_surface_t *_src, - int src_x, - int src_y, - int dst_x, - int dst_y, - cairo_composite_glyphs_info_t *info) -{ - cairo_xlib_surface_t *dst = surface; - cairo_xlib_glyph_t *glyphs = (cairo_xlib_glyph_t *)info->glyphs; - cairo_xlib_source_t *src = (cairo_xlib_source_t *)_src; - cairo_xlib_display_t *display = dst->display; - cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS; - cairo_scaled_glyph_t *glyph; - cairo_fixed_t x = dst_x, y = dst_y; - cairo_xlib_font_glyphset_t *glyphset = NULL, *this_glyphset_info; - - unsigned long max_index = 0; - int width = 1; - int num_elts = 0; - int num_out_glyphs = 0; - int num_glyphs = info->num_glyphs; - - int max_request_size = XMaxRequestSize (display->display) * 4 - - MAX (sz_xRenderCompositeGlyphs8Req, - MAX(sz_xRenderCompositeGlyphs16Req, - sz_xRenderCompositeGlyphs32Req)); - int request_size = 0; - int i; - - op = _render_operator (op), - _cairo_xlib_surface_ensure_picture (dst); - for (i = 0; i < num_glyphs; i++) { - int this_x, this_y; - int old_width; - - status = _cairo_scaled_glyph_lookup (info->font, - glyphs[i].index, - CAIRO_SCALED_GLYPH_INFO_METRICS, - &glyph); - if (unlikely (status)) - return status; - - this_x = _cairo_lround (glyphs[i].d.x); - this_y = _cairo_lround (glyphs[i].d.y); - - /* Send unsent glyphs to the server */ - if (glyph->dev_private_key != display) { - status = _cairo_xlib_surface_add_glyph (display, info->font, &glyph); - if (unlikely (status)) - return status; - } - - this_glyphset_info = glyph->dev_private; - if (!glyphset) - glyphset = this_glyphset_info; - - /* The invariant here is that we can always flush the glyphs - * accumulated before this one, using old_width, and they - * would fit in the request. - */ - old_width = width; - - /* Update max glyph index */ - if (glyphs[i].index > max_index) { - max_index = glyphs[i].index; - if (max_index >= 65536) - width = 4; - else if (max_index >= 256) - width = 2; - if (width != old_width) - request_size += (width - old_width) * num_out_glyphs; - } - - /* If we will pass the max request size by adding this glyph, - * flush current glyphs. Note that we account for a - * possible element being added below. - * - * Also flush if changing glyphsets, as Xrender limits one mask - * format per request, so we can either break up, or use a - * wide-enough mask format. We do the former. One reason to - * prefer the latter is the fact that Xserver ADDs all glyphs - * to the mask first, and then composes that to final surface, - * though it's not a big deal. - * - * If the glyph has a coordinate which cannot be represented - * as a 16-bit offset from the previous glyph, flush the - * current chunk. The current glyph will be the first one in - * the next chunk, thus its coordinates will be an offset from - * the destination origin. This offset is guaranteed to be - * representable as 16-bit offset (otherwise we would have - * fallen back). - */ - if (request_size + width > max_request_size - _cairo_sz_xGlyphElt || - this_x - x > INT16_MAX || this_x - x < INT16_MIN || - this_y - y > INT16_MAX || this_y - y < INT16_MIN || - (this_glyphset_info != glyphset)) { - status = _emit_glyphs_chunk (display, dst, dst_x, dst_y, - glyphs, i, info->font, info->use_mask, - op, src, src_x, src_y, - num_elts, old_width, glyphset); - if (unlikely (status)) - return status; - - glyphs += i; - num_glyphs -= i; - i = 0; - max_index = glyphs[i].index; - width = max_index < 256 ? 1 : max_index < 65536 ? 2 : 4; - request_size = 0; - num_elts = 0; - num_out_glyphs = 0; - x = y = 0; - glyphset = this_glyphset_info; - } - - /* Convert absolute glyph position to relative-to-current-point - * position */ - glyphs[i].i.x = this_x - x; - glyphs[i].i.y = this_y - y; - - /* Start a new element for the first glyph, - * or for any glyph that has unexpected position, - * or if current element has too many glyphs. - * - * These same conditions are mirrored in _emit_glyphs_chunk(). - */ - if (_start_new_glyph_elt (num_out_glyphs, &glyphs[i])) { - num_elts++; - request_size += _cairo_sz_xGlyphElt; - } - - /* adjust current-position */ - x = this_x + glyph->x_advance; - y = this_y + glyph->y_advance; - - num_out_glyphs++; - request_size += width; - } - - if (num_elts) { - status = _emit_glyphs_chunk (display, dst, dst_x, dst_y, - glyphs, i, info->font, info->use_mask, - op, src, src_x, src_y, - num_elts, width, glyphset); - } - - return status; -} - -const cairo_compositor_t * -_cairo_xlib_mask_compositor_get (void) -{ - static cairo_mask_compositor_t compositor; - - if (compositor.base.delegate == NULL) { - _cairo_mask_compositor_init (&compositor, - _cairo_xlib_fallback_compositor_get ()); - - compositor.acquire = acquire; - compositor.release = release; - compositor.set_clip_region = set_clip_region; - compositor.pattern_to_surface = _cairo_xlib_source_create_for_pattern; - compositor.draw_image_boxes = draw_image_boxes; - compositor.fill_rectangles = fill_rectangles; - compositor.fill_boxes = fill_boxes; - compositor.copy_boxes = copy_boxes; - compositor.check_composite = check_composite; - compositor.composite = composite; - //compositor.check_composite_boxes = check_composite_boxes; - compositor.composite_boxes = composite_boxes; - compositor.check_composite_glyphs = check_composite_glyphs; - compositor.composite_glyphs = composite_glyphs; - } - - return &compositor.base; -} - -#define CAIRO_FIXED_16_16_MIN -32768 -#define CAIRO_FIXED_16_16_MAX 32767 - -static cairo_bool_t -line_exceeds_16_16 (const cairo_line_t *line) -{ - return - line->p1.x < _cairo_fixed_from_int (CAIRO_FIXED_16_16_MIN) || - line->p1.x > _cairo_fixed_from_int (CAIRO_FIXED_16_16_MAX) || - line->p2.x < _cairo_fixed_from_int (CAIRO_FIXED_16_16_MIN) || - line->p2.x > _cairo_fixed_from_int (CAIRO_FIXED_16_16_MAX) || - line->p1.y < _cairo_fixed_from_int (CAIRO_FIXED_16_16_MIN) || - line->p1.y > _cairo_fixed_from_int (CAIRO_FIXED_16_16_MAX) || - line->p2.y < _cairo_fixed_from_int (CAIRO_FIXED_16_16_MIN) || - line->p2.y > _cairo_fixed_from_int (CAIRO_FIXED_16_16_MAX); -} - -static void -project_line_x_onto_16_16 (const cairo_line_t *line, - cairo_fixed_t top, - cairo_fixed_t bottom, - XLineFixed *out) -{ - cairo_point_double_t p1, p2; - double m; - - p1.x = _cairo_fixed_to_double (line->p1.x); - p1.y = _cairo_fixed_to_double (line->p1.y); - - p2.x = _cairo_fixed_to_double (line->p2.x); - p2.y = _cairo_fixed_to_double (line->p2.y); - - m = (p2.x - p1.x) / (p2.y - p1.y); - out->p1.x = _cairo_fixed_16_16_from_double (p1.x + m * _cairo_fixed_to_double (top - line->p1.y)); - out->p2.x = _cairo_fixed_16_16_from_double (p1.x + m * _cairo_fixed_to_double (bottom - line->p1.y)); -} -#if 0 -static cairo_int_status_T -check_composite_trapezoids () -{ - operation = _categorize_composite_operation (dst, op, pattern, TRUE); - if (operation == DO_UNSUPPORTED) - return UNSUPPORTED ("unsupported operation"); - - operation = _recategorize_composite_operation (dst, op, src, - &attributes, TRUE); - if (operation == DO_UNSUPPORTED) { - status = UNSUPPORTED ("unsupported operation"); - goto BAIL; - } - -} -#endif - -static cairo_int_status_t -composite_traps (void *abstract_dst, - cairo_operator_t op, - cairo_surface_t *abstract_src, - int src_x, - int src_y, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents, - cairo_antialias_t antialias, - cairo_traps_t *traps) -{ - cairo_xlib_surface_t *dst = abstract_dst; - cairo_xlib_display_t *display = dst->display; - cairo_xlib_source_t *src = (cairo_xlib_source_t *)abstract_src; - XRenderPictFormat *pict_format; - XTrapezoid xtraps_stack[CAIRO_STACK_ARRAY_LENGTH (XTrapezoid)]; - XTrapezoid *xtraps = xtraps_stack; - int dx, dy; - int i; - - //X_DEBUG ((display->display, "composite_trapezoids (dst=%x)", (unsigned int) dst->drawable)); - - if (dst->base.is_clear && - (op == CAIRO_OPERATOR_OVER || op == CAIRO_OPERATOR_ADD)) - { - op = CAIRO_OPERATOR_SOURCE; - } - - pict_format = - _cairo_xlib_display_get_xrender_format (display, - antialias == CAIRO_ANTIALIAS_NONE ? CAIRO_FORMAT_A1 : CAIRO_FORMAT_A8); - - if (traps->num_traps > ARRAY_LENGTH (xtraps_stack)) { - xtraps = _cairo_malloc_ab (traps->num_traps, sizeof (XTrapezoid)); - if (unlikely (xtraps == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - dx = -dst_x << 16; - dy = -dst_y << 16; - for (i = 0; i < traps->num_traps; i++) { - cairo_trapezoid_t *t = &traps->traps[i]; - - /* top/bottom will be clamped to surface bounds */ - xtraps[i].top = _cairo_fixed_to_16_16(t->top) + dy; - xtraps[i].bottom = _cairo_fixed_to_16_16(t->bottom) + dy; - - /* However, all the other coordinates will have been left untouched so - * as not to introduce numerical error. Recompute them if they - * exceed the 16.16 limits. - */ - if (unlikely (line_exceeds_16_16 (&t->left))) { - project_line_x_onto_16_16 (&t->left, t->top, t->bottom, - &xtraps[i].left); - xtraps[i].left.p1.x += dx; - xtraps[i].left.p2.x += dx; - xtraps[i].left.p1.y = xtraps[i].top; - xtraps[i].left.p2.y = xtraps[i].bottom; - } else { - xtraps[i].left.p1.x = _cairo_fixed_to_16_16(t->left.p1.x) + dx; - xtraps[i].left.p1.y = _cairo_fixed_to_16_16(t->left.p1.y) + dy; - xtraps[i].left.p2.x = _cairo_fixed_to_16_16(t->left.p2.x) + dx; - xtraps[i].left.p2.y = _cairo_fixed_to_16_16(t->left.p2.y) + dy; - } - - if (unlikely (line_exceeds_16_16 (&t->right))) { - project_line_x_onto_16_16 (&t->right, t->top, t->bottom, - &xtraps[i].right); - xtraps[i].right.p1.x += dx; - xtraps[i].right.p2.x += dx; - xtraps[i].right.p1.y = xtraps[i].top; - xtraps[i].right.p2.y = xtraps[i].bottom; - } else { - xtraps[i].right.p1.x = _cairo_fixed_to_16_16(t->right.p1.x) + dx; - xtraps[i].right.p1.y = _cairo_fixed_to_16_16(t->right.p1.y) + dy; - xtraps[i].right.p2.x = _cairo_fixed_to_16_16(t->right.p2.x) + dx; - xtraps[i].right.p2.y = _cairo_fixed_to_16_16(t->right.p2.y) + dy; - } - } - - if (xtraps[0].left.p1.y < xtraps[0].left.p2.y) { - src_x += _cairo_fixed_16_16_floor (xtraps[0].left.p1.x); - src_y += _cairo_fixed_16_16_floor (xtraps[0].left.p1.y); - } else { - src_x += _cairo_fixed_16_16_floor (xtraps[0].left.p2.x); - src_y += _cairo_fixed_16_16_floor (xtraps[0].left.p2.y); - } - src_x += dst_x; - src_y += dst_y; - - _cairo_xlib_surface_ensure_picture (dst); - _cairo_xlib_surface_set_precision (dst, antialias); - XRenderCompositeTrapezoids (dst->dpy, - _render_operator (op), - src->picture, dst->picture, - pict_format, - src_x, src_y, - xtraps, traps->num_traps); - - if (xtraps != xtraps_stack) - free (xtraps); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -composite_tristrip (void *abstract_dst, - cairo_operator_t op, - cairo_surface_t *abstract_src, - int src_x, - int src_y, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents, - cairo_antialias_t antialias, - cairo_tristrip_t *strip) -{ - cairo_xlib_surface_t *dst = abstract_dst; - cairo_xlib_display_t *display = dst->display; - cairo_xlib_source_t *src = (cairo_xlib_source_t *)abstract_src; - XRenderPictFormat *pict_format; - XPointFixed points_stack[CAIRO_STACK_ARRAY_LENGTH (XPointFixed)]; - XPointFixed *points = points_stack; - int dx, dy; - int i; - - //X_DEBUG ((display->display, "composite_trapezoids (dst=%x)", (unsigned int) dst->drawable)); - - pict_format = - _cairo_xlib_display_get_xrender_format (display, - antialias == CAIRO_ANTIALIAS_NONE ? CAIRO_FORMAT_A1 : CAIRO_FORMAT_A8); - - if (strip->num_points > ARRAY_LENGTH (points_stack)) { - points = _cairo_malloc_ab (strip->num_points, sizeof (XPointFixed)); - if (unlikely (points == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - dx = -dst_x << 16; - dy = -dst_y << 16; - for (i = 0; i < strip->num_points; i++) { - cairo_point_t *p = &strip->points[i]; - - points[i].x = _cairo_fixed_to_16_16(p->x) + dx; - points[i].y = _cairo_fixed_to_16_16(p->y) + dy; - } - - src_x += _cairo_fixed_16_16_floor (points[0].x) + dst_x; - src_y += _cairo_fixed_16_16_floor (points[0].y) + dst_y; - - _cairo_xlib_surface_ensure_picture (dst); - _cairo_xlib_surface_set_precision (dst, antialias); - XRenderCompositeTriStrip (dst->dpy, - _render_operator (op), - src->picture, dst->picture, - pict_format, - src_x, src_y, - points, strip->num_points); - - if (points != points_stack) - free (points); - - return CAIRO_STATUS_SUCCESS; -} - -const cairo_compositor_t * -_cairo_xlib_traps_compositor_get (void) -{ - static cairo_traps_compositor_t compositor; - - if (compositor.base.delegate == NULL) { - _cairo_traps_compositor_init (&compositor, - _cairo_xlib_mask_compositor_get ()); - - compositor.acquire = acquire; - compositor.release = release; - compositor.set_clip_region = set_clip_region; - compositor.pattern_to_surface = _cairo_xlib_source_create_for_pattern; - compositor.draw_image_boxes = draw_image_boxes; - compositor.copy_boxes = copy_boxes; - compositor.fill_boxes = fill_boxes; - compositor.check_composite = check_composite; - compositor.composite = composite; - compositor.lerp = lerp; - //compositor.check_composite_boxes = check_composite_boxes; - compositor.composite_boxes = composite_boxes; - //compositor.check_composite_traps = check_composite_traps; - compositor.composite_traps = composite_traps; - //compositor.check_composite_tristrip = check_composite_tristrip; - compositor.composite_tristrip = composite_tristrip; - compositor.check_composite_glyphs = check_composite_glyphs; - compositor.composite_glyphs = composite_glyphs; - } - - return &compositor.base; -} - -#endif /* !CAIRO_HAS_XLIB_XCB_FUNCTIONS */ diff --git a/source/libs/cairo/cairo-src/src/cairo-xlib-screen.c b/source/libs/cairo/cairo-src/src/cairo-xlib-screen.c deleted file mode 100644 index 57beeaab426f3cc5c77cbaaee36a496f574a69b4..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xlib-screen.c +++ /dev/null @@ -1,467 +0,0 @@ -/* Cairo - a vector graphics library with display and print output - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Partially on code from xftdpy.c - * - * Copyright © 2000 Keith Packard - * - * 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 Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD 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. - */ - -#include "cairoint.h" - -#if !CAIRO_HAS_XLIB_XCB_FUNCTIONS - -#include "cairo-xlib-private.h" -#include "cairo-xlib-xrender-private.h" - -#include "cairo-xlib-surface-private.h" -#include "cairo-error-private.h" -#include "cairo-list-inline.h" - -#include "cairo-fontconfig-private.h" - -static int -parse_boolean (const char *v) -{ - char c0, c1; - - c0 = *v; - if (c0 == 't' || c0 == 'T' || c0 == 'y' || c0 == 'Y' || c0 == '1') - return 1; - if (c0 == 'f' || c0 == 'F' || c0 == 'n' || c0 == 'N' || c0 == '0') - return 0; - if (c0 == 'o') - { - c1 = v[1]; - if (c1 == 'n' || c1 == 'N') - return 1; - if (c1 == 'f' || c1 == 'F') - return 0; - } - - return -1; -} - -static cairo_bool_t -get_boolean_default (Display *dpy, - const char *option, - cairo_bool_t *value) -{ - char *v; - int i; - - v = XGetDefault (dpy, "Xft", option); - if (v) { - i = parse_boolean (v); - if (i >= 0) { - *value = i; - return TRUE; - } - } - - return FALSE; -} - -static cairo_bool_t -get_integer_default (Display *dpy, - const char *option, - int *value) -{ - char *v, *e; - - v = XGetDefault (dpy, "Xft", option); - if (v) { -#if CAIRO_HAS_FC_FONT - if (FcNameConstant ((FcChar8 *) v, value)) - return TRUE; -#endif - - *value = strtol (v, &e, 0); - if (e != v) - return TRUE; - } - - return FALSE; -} - -static void -_cairo_xlib_init_screen_font_options (Display *dpy, - cairo_xlib_screen_t *info) -{ - cairo_bool_t xft_hinting; - cairo_bool_t xft_antialias; - int xft_hintstyle; - int xft_rgba; - int xft_lcdfilter; - cairo_antialias_t antialias; - cairo_subpixel_order_t subpixel_order; - cairo_lcd_filter_t lcd_filter; - cairo_hint_style_t hint_style; - - if (!get_boolean_default (dpy, "antialias", &xft_antialias)) - xft_antialias = TRUE; - - if (!get_integer_default (dpy, "lcdfilter", &xft_lcdfilter)) { - /* -1 is an non-existant Fontconfig constant used to differentiate - * the case when no lcdfilter property is available. - */ - xft_lcdfilter = -1; - } - - if (!get_boolean_default (dpy, "hinting", &xft_hinting)) - xft_hinting = TRUE; - - if (!get_integer_default (dpy, "hintstyle", &xft_hintstyle)) - xft_hintstyle = FC_HINT_FULL; - - if (!get_integer_default (dpy, "rgba", &xft_rgba)) - { - cairo_xlib_display_t *display = (cairo_xlib_display_t *) info->device; - - xft_rgba = FC_RGBA_UNKNOWN; - -#if RENDER_MAJOR > 0 || RENDER_MINOR >= 6 - if (display->render_major > 0 || display->render_minor >= 6) { - int render_order = XRenderQuerySubpixelOrder (dpy, - XScreenNumberOfScreen (info->screen)); - - switch (render_order) { - default: - case SubPixelUnknown: - xft_rgba = FC_RGBA_UNKNOWN; - break; - case SubPixelHorizontalRGB: - xft_rgba = FC_RGBA_RGB; - break; - case SubPixelHorizontalBGR: - xft_rgba = FC_RGBA_BGR; - break; - case SubPixelVerticalRGB: - xft_rgba = FC_RGBA_VRGB; - break; - case SubPixelVerticalBGR: - xft_rgba = FC_RGBA_VBGR; - break; - case SubPixelNone: - xft_rgba = FC_RGBA_NONE; - break; - } - } -#endif - } - - if (xft_hinting) { - switch (xft_hintstyle) { - case FC_HINT_NONE: - hint_style = CAIRO_HINT_STYLE_NONE; - break; - case FC_HINT_SLIGHT: - hint_style = CAIRO_HINT_STYLE_SLIGHT; - break; - case FC_HINT_MEDIUM: - hint_style = CAIRO_HINT_STYLE_MEDIUM; - break; - case FC_HINT_FULL: - hint_style = CAIRO_HINT_STYLE_FULL; - break; - default: - hint_style = CAIRO_HINT_STYLE_DEFAULT; - } - } else { - hint_style = CAIRO_HINT_STYLE_NONE; - } - - switch (xft_rgba) { - case FC_RGBA_RGB: - subpixel_order = CAIRO_SUBPIXEL_ORDER_RGB; - break; - case FC_RGBA_BGR: - subpixel_order = CAIRO_SUBPIXEL_ORDER_BGR; - break; - case FC_RGBA_VRGB: - subpixel_order = CAIRO_SUBPIXEL_ORDER_VRGB; - break; - case FC_RGBA_VBGR: - subpixel_order = CAIRO_SUBPIXEL_ORDER_VBGR; - break; - case FC_RGBA_UNKNOWN: - case FC_RGBA_NONE: - default: - subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT; - } - - switch (xft_lcdfilter) { - case FC_LCD_NONE: - lcd_filter = CAIRO_LCD_FILTER_NONE; - break; - case FC_LCD_DEFAULT: - lcd_filter = CAIRO_LCD_FILTER_FIR5; - break; - case FC_LCD_LIGHT: - lcd_filter = CAIRO_LCD_FILTER_FIR3; - break; - case FC_LCD_LEGACY: - lcd_filter = CAIRO_LCD_FILTER_INTRA_PIXEL; - break; - default: - lcd_filter = CAIRO_LCD_FILTER_DEFAULT; - break; - } - - if (xft_antialias) { - if (subpixel_order == CAIRO_SUBPIXEL_ORDER_DEFAULT) - antialias = CAIRO_ANTIALIAS_GRAY; - else - antialias = CAIRO_ANTIALIAS_SUBPIXEL; - } else { - antialias = CAIRO_ANTIALIAS_NONE; - } - - cairo_font_options_set_hint_style (&info->font_options, hint_style); - cairo_font_options_set_antialias (&info->font_options, antialias); - cairo_font_options_set_subpixel_order (&info->font_options, subpixel_order); - _cairo_font_options_set_lcd_filter (&info->font_options, lcd_filter); - cairo_font_options_set_hint_metrics (&info->font_options, CAIRO_HINT_METRICS_ON); -} - -void -_cairo_xlib_screen_destroy (cairo_xlib_display_t *display, - cairo_xlib_screen_t *info) -{ - Display *dpy; - int i; - - dpy = display->display; - - while (! cairo_list_is_empty (&info->surfaces)) { - cairo_xlib_surface_t *surface; - - surface = cairo_list_first_entry (&info->surfaces, - cairo_xlib_surface_t, - link); - cairo_surface_finish (&surface->base); - } - - for (i = 0; i < ARRAY_LENGTH (info->gc); i++) { - if (info->gc_depths[i] != 0) { - XFreeGC (dpy, info->gc[i]); - info->gc_depths[i] = 0; - } - } - - while (! cairo_list_is_empty (&info->visuals)) { - _cairo_xlib_visual_info_destroy (cairo_list_first_entry (&info->visuals, - cairo_xlib_visual_info_t, - link)); - } - - cairo_list_del (&info->link); - - free (info); -} - -cairo_status_t -_cairo_xlib_screen_get (Display *dpy, - Screen *screen, - cairo_xlib_screen_t **out) -{ - cairo_xlib_display_t *display; - cairo_device_t *device; - cairo_xlib_screen_t *info; - cairo_status_t status; - - device = _cairo_xlib_device_create (dpy); - status = device->status; - if (unlikely (status)) - goto CLEANUP_DEVICE; - - status = _cairo_xlib_display_acquire (device, &display); - if (unlikely (status)) - goto CLEANUP_DEVICE; - - info = _cairo_xlib_display_get_screen (display, screen); - if (info != NULL) { - *out = info; - goto CLEANUP_DISPLAY; - } - - info = malloc (sizeof (cairo_xlib_screen_t)); - if (unlikely (info == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto CLEANUP_DISPLAY; - } - - info->device = device; - info->screen = screen; - info->has_font_options = FALSE; - memset (info->gc_depths, 0, sizeof (info->gc_depths)); - memset (info->gc, 0, sizeof (info->gc)); - - cairo_list_init (&info->surfaces); - cairo_list_init (&info->visuals); - cairo_list_add (&info->link, &display->screens); - - *out = info; - - CLEANUP_DISPLAY: - cairo_device_release (&display->base); - - CLEANUP_DEVICE: - cairo_device_destroy (device); - return status; -} - -GC -_cairo_xlib_screen_get_gc (cairo_xlib_display_t *display, - cairo_xlib_screen_t *info, - int depth, - Drawable drawable) -{ - GC gc = NULL; - int i; - - for (i = 0; i < ARRAY_LENGTH (info->gc); i++) { - if (info->gc_depths[i] == depth) { - info->gc_depths[i] = 0; - gc = info->gc[i]; - break; - } - } - - if (gc == NULL) { - XGCValues gcv; - - gcv.graphics_exposures = False; - gcv.fill_style = FillTiled; - gc = XCreateGC (display->display, - drawable, - GCGraphicsExposures | GCFillStyle, &gcv); - } - - return gc; -} - -void -_cairo_xlib_screen_put_gc (cairo_xlib_display_t *display, - cairo_xlib_screen_t *info, - int depth, - GC gc) -{ - int i; - - for (i = 0; i < ARRAY_LENGTH (info->gc); i++) { - if (info->gc_depths[i] == 0) - break; - } - - if (i == ARRAY_LENGTH (info->gc)) { - /* perform random substitution to ensure fair caching over depths */ - i = rand () % ARRAY_LENGTH (info->gc); - XFreeGC(display->display, info->gc[i]); - } - - info->gc[i] = gc; - info->gc_depths[i] = depth; -} - -cairo_status_t -_cairo_xlib_screen_get_visual_info (cairo_xlib_display_t *display, - cairo_xlib_screen_t *info, - Visual *v, - cairo_xlib_visual_info_t **out) -{ - cairo_xlib_visual_info_t *visual; - cairo_status_t status; - - cairo_list_foreach_entry (visual, - cairo_xlib_visual_info_t, - &info->visuals, - link) - { - if (visual->visualid == v->visualid) { - *out = visual; - return CAIRO_STATUS_SUCCESS; - } - } - - status = _cairo_xlib_visual_info_create (display->display, - XScreenNumberOfScreen (info->screen), - v->visualid, - &visual); - if (unlikely (status)) - return status; - - cairo_list_add (&visual->link, &info->visuals); - *out = visual; - return CAIRO_STATUS_SUCCESS; -} - -cairo_font_options_t * -_cairo_xlib_screen_get_font_options (cairo_xlib_screen_t *info) -{ - if (! info->has_font_options) { - _cairo_font_options_init_default (&info->font_options); - _cairo_font_options_set_round_glyph_positions (&info->font_options, CAIRO_ROUND_GLYPH_POS_ON); - - if (info->screen != NULL) { - cairo_xlib_display_t *display; - - if (! _cairo_xlib_display_acquire (info->device, &display)) { - _cairo_xlib_init_screen_font_options (display->display, - info); - cairo_device_release (&display->base); - } - } - - info->has_font_options = TRUE; - } - - return &info->font_options; -} - -#endif /* !CAIRO_HAS_XLIB_XCB_FUNCTIONS */ diff --git a/source/libs/cairo/cairo-src/src/cairo-xlib-source.c b/source/libs/cairo/cairo-src/src/cairo-xlib-source.c deleted file mode 100644 index 1591f5874f6a1438bdb853a57fdf5c474164b169..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xlib-source.c +++ /dev/null @@ -1,1168 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Behdad Esfahbod <behdad@behdad.org> - * Chris Wilson <chris@chris-wilson.co.uk> - * Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation - */ -#include "cairoint.h" - -#if !CAIRO_HAS_XLIB_XCB_FUNCTIONS - -#include "cairo-xlib-private.h" -#include "cairo-xlib-surface-private.h" - -#include "cairo-error-private.h" -#include "cairo-image-surface-inline.h" -#include "cairo-paginated-private.h" -#include "cairo-pattern-inline.h" -#include "cairo-recording-surface-private.h" -#include "cairo-surface-backend-private.h" -#include "cairo-surface-offset-private.h" -#include "cairo-surface-observer-private.h" -#include "cairo-surface-snapshot-inline.h" -#include "cairo-surface-subsurface-inline.h" - -#define PIXMAN_MAX_INT ((pixman_fixed_1 >> 1) - pixman_fixed_e) /* need to ensure deltas also fit */ - -static cairo_xlib_surface_t * -unwrap_source (const cairo_surface_pattern_t *pattern) -{ - cairo_rectangle_int_t limits; - return (cairo_xlib_surface_t *)_cairo_pattern_get_source (pattern, &limits); -} - -static cairo_status_t -_cairo_xlib_source_finish (void *abstract_surface) -{ - cairo_xlib_source_t *source = abstract_surface; - - XRenderFreePicture (source->dpy, source->picture); - if (source->pixmap) - XFreePixmap (source->dpy, source->pixmap); - return CAIRO_STATUS_SUCCESS; -} - -static const cairo_surface_backend_t cairo_xlib_source_backend = { - CAIRO_SURFACE_TYPE_XLIB, - _cairo_xlib_source_finish, - NULL, /* read-only wrapper */ -}; - -static cairo_status_t -_cairo_xlib_proxy_finish (void *abstract_surface) -{ - cairo_xlib_proxy_t *proxy = abstract_surface; - - _cairo_xlib_shm_surface_mark_active (proxy->owner); - XRenderFreePicture (proxy->source.dpy, proxy->source.picture); - if (proxy->source.pixmap) - XFreePixmap (proxy->source.dpy, proxy->source.pixmap); - cairo_surface_destroy (proxy->owner); - return CAIRO_STATUS_SUCCESS; -} - -static const cairo_surface_backend_t cairo_xlib_proxy_backend = { - CAIRO_SURFACE_TYPE_XLIB, - _cairo_xlib_proxy_finish, - NULL, /* read-only wrapper */ -}; - -static cairo_surface_t * -source (cairo_xlib_surface_t *dst, Picture picture, Pixmap pixmap) -{ - cairo_xlib_source_t *source; - - if (picture == None) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - source = malloc (sizeof (*source)); - if (unlikely (source == NULL)) { - XRenderFreePicture (dst->display->display, picture); - if (pixmap) - XFreePixmap (dst->display->display, pixmap); - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - _cairo_surface_init (&source->base, - &cairo_xlib_source_backend, - NULL, /* device */ - CAIRO_CONTENT_COLOR_ALPHA); - - /* The source exists only within an operation */ - source->picture = picture; - source->pixmap = pixmap; - source->dpy = dst->display->display; - - return &source->base; -} - -static uint32_t -hars_petruska_f54_1_random (void) -{ -#define rol(x,k) ((x << k) | (x >> (32-k))) - static uint32_t x; - return x = (x ^ rol (x, 5) ^ rol (x, 24)) + 0x37798849; -#undef rol -} - -static const XTransform identity = { - { - { 1 << 16, 0x00000, 0x00000 }, - { 0x00000, 1 << 16, 0x00000 }, - { 0x00000, 0x00000, 1 << 16 }, - } -}; - -static cairo_bool_t -picture_set_matrix (cairo_xlib_display_t *display, - Picture picture, - const cairo_matrix_t *matrix, - cairo_filter_t filter, - double xc, - double yc, - int *x_offset, - int *y_offset) -{ - XTransform xtransform; - pixman_transform_t *pixman_transform; - cairo_int_status_t status; - - /* Casting between pixman_transform_t and XTransform is safe because - * they happen to be the exact same type. - */ - pixman_transform = (pixman_transform_t *) &xtransform; - status = _cairo_matrix_to_pixman_matrix_offset (matrix, filter, xc, yc, - pixman_transform, - x_offset, y_offset); - if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) - return TRUE; - if (unlikely (status != CAIRO_INT_STATUS_SUCCESS)) - return FALSE; - - if (memcmp (&xtransform, &identity, sizeof (XTransform)) == 0) - return TRUE; - - /* a late check in case we perturb the matrix too far */ - if (! CAIRO_RENDER_HAS_PICTURE_TRANSFORM (display)) - return FALSE; - - XRenderSetPictureTransform (display->display, picture, &xtransform); - return TRUE; -} - -static cairo_status_t -picture_set_filter (Display *dpy, - Picture picture, - cairo_filter_t filter) -{ - const char *render_filter; - - switch (filter) { - case CAIRO_FILTER_FAST: - render_filter = FilterFast; - break; - case CAIRO_FILTER_GOOD: - render_filter = FilterGood; - break; - case CAIRO_FILTER_BEST: - render_filter = FilterBest; - break; - case CAIRO_FILTER_NEAREST: - render_filter = FilterNearest; - break; - case CAIRO_FILTER_BILINEAR: - render_filter = FilterBilinear; - break; - case CAIRO_FILTER_GAUSSIAN: - /* XXX: The GAUSSIAN value has no implementation in cairo - * whatsoever, so it was really a mistake to have it in the - * API. We could fix this by officially deprecating it, or - * else inventing semantics and providing an actual - * implementation for it. */ - default: - render_filter = FilterBest; - break; - } - - XRenderSetPictureFilter (dpy, picture, (char *) render_filter, NULL, 0); - return CAIRO_STATUS_SUCCESS; -} - -static int -extend_to_repeat (cairo_extend_t extend) -{ - switch (extend) { - default: - ASSERT_NOT_REACHED; - case CAIRO_EXTEND_NONE: - return RepeatNone; - case CAIRO_EXTEND_REPEAT: - return RepeatNormal; - case CAIRO_EXTEND_REFLECT: - return RepeatReflect; - case CAIRO_EXTEND_PAD: - return RepeatPad; - } -} - -static cairo_bool_t -picture_set_properties (cairo_xlib_display_t *display, - Picture picture, - const cairo_pattern_t *pattern, - const cairo_matrix_t *matrix, - const cairo_rectangle_int_t *extents, - int *x_off, int *y_off) -{ - XRenderPictureAttributes pa; - int mask = 0; - - if (! picture_set_matrix (display, picture, matrix, pattern->filter, - extents->x + extents->width / 2, - extents->y + extents->height / 2, - x_off, y_off)) - return FALSE; - - picture_set_filter (display->display, picture, pattern->filter); - - if (pattern->has_component_alpha) { - pa.component_alpha = 1; - mask |= CPComponentAlpha; - } - - if (pattern->extend != CAIRO_EXTEND_NONE) { - pa.repeat = extend_to_repeat (pattern->extend); - mask |= CPRepeat; - } - - if (mask) - XRenderChangePicture (display->display, picture, mask, &pa); - - return TRUE; -} - -static cairo_surface_t * -render_pattern (cairo_xlib_surface_t *dst, - const cairo_pattern_t *pattern, - cairo_bool_t is_mask, - const cairo_rectangle_int_t *extents, - int *src_x, int *src_y) -{ - Display *dpy = dst->display->display; - cairo_xlib_surface_t *src; - cairo_image_surface_t *image; - cairo_status_t status; - cairo_rectangle_int_t map_extents; - - src = (cairo_xlib_surface_t *) - _cairo_surface_create_scratch (&dst->base, - is_mask ? CAIRO_CONTENT_ALPHA : CAIRO_CONTENT_COLOR_ALPHA, - extents->width, - extents->height, - NULL); - if (src->base.type != CAIRO_SURFACE_TYPE_XLIB) { - cairo_surface_destroy (&src->base); - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - map_extents = *extents; - map_extents.x = map_extents.y = 0; - - image = _cairo_surface_map_to_image (&src->base, &map_extents); - status = _cairo_surface_offset_paint (&image->base, extents->x, extents->y, - CAIRO_OPERATOR_SOURCE, pattern, - NULL); - status = _cairo_surface_unmap_image (&src->base, image); - if (unlikely (status)) { - cairo_surface_destroy (&src->base); - return _cairo_surface_create_in_error (status); - } - - status = _cairo_xlib_surface_put_shm (src); - if (unlikely (status)) { - cairo_surface_destroy (&src->base); - return _cairo_surface_create_in_error (status); - } - - src->picture = XRenderCreatePicture (dpy, - src->drawable, src->xrender_format, - 0, NULL); - - *src_x = -extents->x; - *src_y = -extents->y; - return &src->base; -} - -static cairo_surface_t * -gradient_source (cairo_xlib_surface_t *dst, - const cairo_gradient_pattern_t *gradient, - cairo_bool_t is_mask, - const cairo_rectangle_int_t *extents, - int *src_x, int *src_y) -{ - cairo_xlib_display_t *display = dst->display; - cairo_matrix_t matrix = gradient->base.matrix; - char buf[CAIRO_STACK_BUFFER_SIZE]; - cairo_circle_double_t extremes[2]; - XFixed *stops; - XRenderColor *colors; - Picture picture; - unsigned int i, n_stops; - - /* The RENDER specification says that the inner circle has - * to be completely contained inside the outer one. */ - if (gradient->base.type == CAIRO_PATTERN_TYPE_RADIAL && - ! _cairo_radial_pattern_focus_is_inside ((cairo_radial_pattern_t *) gradient)) - return render_pattern (dst, &gradient->base, is_mask, extents, src_x, src_y); - - assert (gradient->n_stops > 0); - n_stops = MAX (gradient->n_stops, 2); - - if (n_stops < sizeof (buf) / (sizeof (XFixed) + sizeof (XRenderColor))) - { - stops = (XFixed *) buf; - } - else - { - stops = - _cairo_malloc_ab (n_stops, - sizeof (XFixed) + sizeof (XRenderColor)); - if (unlikely (stops == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - colors = (XRenderColor *) (stops + n_stops); - for (i = 0; i < gradient->n_stops; i++) { - stops[i] = - _cairo_fixed_16_16_from_double (gradient->stops[i].offset); - - colors[i].red = gradient->stops[i].color.red_short; - colors[i].green = gradient->stops[i].color.green_short; - colors[i].blue = gradient->stops[i].color.blue_short; - colors[i].alpha = gradient->stops[i].color.alpha_short; - } - - /* RENDER does not support gradients with less than 2 - * stops. If a gradient has only a single stop, duplicate - * it to make RENDER happy. */ - if (gradient->n_stops == 1) { - stops[1] = - _cairo_fixed_16_16_from_double (gradient->stops[0].offset); - - colors[1].red = gradient->stops[0].color.red_short; - colors[1].green = gradient->stops[0].color.green_short; - colors[1].blue = gradient->stops[0].color.blue_short; - colors[1].alpha = gradient->stops[0].color.alpha_short; - } - -#if 0 - /* For some weird reason the X server is sometimes getting - * CreateGradient requests with bad length. So far I've only seen - * XRenderCreateLinearGradient request with 4 stops sometime end up - * with length field matching 0 stops at the server side. I've - * looked at the libXrender code and I can't see anything that - * could cause this behavior. However, for some reason having a - * XSync call here seems to avoid the issue so I'll keep it here - * until it's solved. - */ - XSync (display->display, False); -#endif - - _cairo_gradient_pattern_fit_to_range (gradient, PIXMAN_MAX_INT >> 1, &matrix, extremes); - - if (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR) { - XLinearGradient grad; - - grad.p1.x = _cairo_fixed_16_16_from_double (extremes[0].center.x); - grad.p1.y = _cairo_fixed_16_16_from_double (extremes[0].center.y); - grad.p2.x = _cairo_fixed_16_16_from_double (extremes[1].center.x); - grad.p2.y = _cairo_fixed_16_16_from_double (extremes[1].center.y); - - picture = XRenderCreateLinearGradient (display->display, &grad, - stops, colors, - n_stops); - } else { - XRadialGradient grad; - - grad.inner.x = _cairo_fixed_16_16_from_double (extremes[0].center.x); - grad.inner.y = _cairo_fixed_16_16_from_double (extremes[0].center.y); - grad.inner.radius = _cairo_fixed_16_16_from_double (extremes[0].radius); - grad.outer.x = _cairo_fixed_16_16_from_double (extremes[1].center.x); - grad.outer.y = _cairo_fixed_16_16_from_double (extremes[1].center.y); - grad.outer.radius = _cairo_fixed_16_16_from_double (extremes[1].radius); - - picture = XRenderCreateRadialGradient (display->display, &grad, - stops, colors, - n_stops); - } - - if (stops != (XFixed *) buf) - free (stops); - - *src_x = *src_y = 0; - if (! picture_set_properties (display, picture, - &gradient->base, &gradient->base.matrix, - extents, - src_x, src_y)) { - XRenderFreePicture (display->display, picture); - return render_pattern (dst, &gradient->base, is_mask, extents, src_x, src_y); - } - - return source (dst, picture, None); -} - -static cairo_surface_t * -color_source (cairo_xlib_surface_t *dst, const cairo_color_t *color) -{ - Display *dpy = dst->display->display; - XRenderColor xcolor; - Picture picture; - Pixmap pixmap = None; - - xcolor.red = color->red_short; - xcolor.green = color->green_short; - xcolor.blue = color->blue_short; - xcolor.alpha = color->alpha_short; - - if (CAIRO_RENDER_HAS_GRADIENTS(dst->display)) { - picture = XRenderCreateSolidFill (dpy, &xcolor); - } else { - XRenderPictureAttributes pa; - int mask = 0; - - pa.repeat = RepeatNormal; - mask |= CPRepeat; - - pixmap = XCreatePixmap (dpy, dst->drawable, 1, 1, 32); - picture = XRenderCreatePicture (dpy, pixmap, - _cairo_xlib_display_get_xrender_format (dst->display, CAIRO_FORMAT_ARGB32), - mask, &pa); - - if (CAIRO_RENDER_HAS_FILL_RECTANGLES(dst->display)) { - XRectangle r = { 0, 0, 1, 1}; - XRenderFillRectangles (dpy, PictOpSrc, picture, &xcolor, &r, 1); - } else { - XGCValues gcv; - GC gc; - - gc = _cairo_xlib_screen_get_gc (dst->display, dst->screen, - 32, pixmap); - if (unlikely (gc == NULL)) { - XFreePixmap (dpy, pixmap); - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - gcv.foreground = 0; - gcv.foreground |= color->alpha_short >> 8 << 24; - gcv.foreground |= color->red_short >> 8 << 16; - gcv.foreground |= color->green_short >> 8 << 8; - gcv.foreground |= color->blue_short >> 8 << 0; - gcv.fill_style = FillSolid; - - XChangeGC (dpy, gc, GCFillStyle | GCForeground, &gcv); - XFillRectangle (dpy, pixmap, gc, 0, 0, 1, 1); - - _cairo_xlib_screen_put_gc (dst->display, dst->screen, 32, gc); - } - } - - return source (dst, picture, pixmap); -} - -static cairo_surface_t * -alpha_source (cairo_xlib_surface_t *dst, uint8_t alpha) -{ - cairo_xlib_display_t *display = dst->display; - - if (display->alpha[alpha] == NULL) { - cairo_color_t color; - - color.red_short = color.green_short = color.blue_short = 0; - color.alpha_short = alpha << 8 | alpha; - - display->alpha[alpha] = color_source (dst, &color); - } - - return cairo_surface_reference (display->alpha[alpha]); -} - -static cairo_surface_t * -white_source (cairo_xlib_surface_t *dst) -{ - cairo_xlib_display_t *display = dst->display; - - if (display->white == NULL) - display->white = color_source (dst, CAIRO_COLOR_WHITE); - - return cairo_surface_reference (display->white); -} - -static cairo_surface_t * -opaque_source (cairo_xlib_surface_t *dst, const cairo_color_t *color) -{ - cairo_xlib_display_t *display = dst->display; - uint32_t pixel = - 0xff000000 | - color->red_short >> 8 << 16 | - color->green_short >> 8 << 8 | - color->blue_short >> 8 << 0; - int i; - - if (display->last_solid_cache[0].color == pixel) - return cairo_surface_reference (display->solid[display->last_solid_cache[0].index]); - - for (i = 0; i < 16; i++) { - if (display->solid_cache[i] == pixel) - goto done; - } - - i = hars_petruska_f54_1_random () % 16; - cairo_surface_destroy (display->solid[i]); - - display->solid[i] = color_source (dst, color); - display->solid_cache[i] = pixel; - -done: - display->last_solid_cache[0].color = pixel; - display->last_solid_cache[0].index = i; - return cairo_surface_reference (display->solid[i]); -} - -static cairo_surface_t * -transparent_source (cairo_xlib_surface_t *dst, const cairo_color_t *color) -{ - cairo_xlib_display_t *display = dst->display; - uint32_t pixel = - color->alpha_short >> 8 << 24 | - color->red_short >> 8 << 16 | - color->green_short >> 8 << 8 | - color->blue_short >> 8 << 0; - int i; - - if (display->last_solid_cache[1].color == pixel) { - assert (display->solid[display->last_solid_cache[1].index]); - return cairo_surface_reference (display->solid[display->last_solid_cache[1].index]); - } - - for (i = 16; i < 32; i++) { - if (display->solid_cache[i] == pixel) - goto done; - } - - i = 16 + (hars_petruska_f54_1_random () % 16); - cairo_surface_destroy (display->solid[i]); - - display->solid[i] = color_source (dst, color); - display->solid_cache[i] = pixel; - -done: - display->last_solid_cache[1].color = pixel; - display->last_solid_cache[1].index = i; - assert (display->solid[i]); - return cairo_surface_reference (display->solid[i]); -} - -static cairo_surface_t * -solid_source (cairo_xlib_surface_t *dst, - const cairo_color_t *color) -{ - if ((color->red_short | color->green_short | color->blue_short) <= 0xff) - return alpha_source (dst, color->alpha_short >> 8); - - if (CAIRO_ALPHA_SHORT_IS_OPAQUE (color->alpha_short)) { - if (color->red_short >= 0xff00 && color->green_short >= 0xff00 && color->blue_short >= 0xff00) - return white_source (dst); - - return opaque_source (dst, color); - } else - return transparent_source (dst, color); -} - -static cairo_xlib_source_t *init_source (cairo_xlib_surface_t *dst, - cairo_xlib_surface_t *src) -{ - Display *dpy = dst->display->display; - cairo_xlib_source_t *source = &src->embedded_source; - - /* As these are frequent and meant to be fast, we track pictures for - * native surface and minimise update requests. - */ - if (source->picture == None) { - XRenderPictureAttributes pa; - - _cairo_surface_init (&source->base, - &cairo_xlib_source_backend, - NULL, /* device */ - CAIRO_CONTENT_COLOR_ALPHA); - - pa.subwindow_mode = IncludeInferiors; - source->picture = XRenderCreatePicture (dpy, - src->drawable, - src->xrender_format, - CPSubwindowMode, &pa); - - source->has_component_alpha = 0; - source->has_matrix = 0; - source->filter = CAIRO_FILTER_NEAREST; - source->extend = CAIRO_EXTEND_NONE; - } - - return (cairo_xlib_source_t *) cairo_surface_reference (&source->base); -} - -static cairo_surface_t * -embedded_source (cairo_xlib_surface_t *dst, - const cairo_surface_pattern_t *pattern, - const cairo_rectangle_int_t *extents, - int *src_x, int *src_y, - cairo_xlib_source_t *source) -{ - Display *dpy = dst->display->display; - cairo_int_status_t status; - XTransform xtransform; - XRenderPictureAttributes pa; - unsigned mask = 0; - - status = _cairo_matrix_to_pixman_matrix_offset (&pattern->base.matrix, - pattern->base.filter, - extents->x + extents->width / 2, - extents->y + extents->height / 2, - (pixman_transform_t *)&xtransform, - src_x, src_y); - - if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) { - if (source->has_matrix) { - source->has_matrix = 0; - memcpy (&xtransform, &identity, sizeof (identity)); - status = CAIRO_INT_STATUS_SUCCESS; - } - } else - source->has_matrix = 1; - if (status == CAIRO_INT_STATUS_SUCCESS) - XRenderSetPictureTransform (dpy, source->picture, &xtransform); - - if (source->filter != pattern->base.filter) { - picture_set_filter (dpy, source->picture, pattern->base.filter); - source->filter = pattern->base.filter; - } - - if (source->has_component_alpha != pattern->base.has_component_alpha) { - pa.component_alpha = pattern->base.has_component_alpha; - mask |= CPComponentAlpha; - source->has_component_alpha = pattern->base.has_component_alpha; - } - - if (source->extend != pattern->base.extend) { - pa.repeat = extend_to_repeat (pattern->base.extend); - mask |= CPRepeat; - source->extend = pattern->base.extend; - } - - if (mask) - XRenderChangePicture (dpy, source->picture, mask, &pa); - - return &source->base; -} - -static cairo_surface_t * -subsurface_source (cairo_xlib_surface_t *dst, - const cairo_surface_pattern_t *pattern, - cairo_bool_t is_mask, - const cairo_rectangle_int_t *extents, - const cairo_rectangle_int_t *sample, - int *src_x, int *src_y) -{ - cairo_surface_subsurface_t *sub; - cairo_xlib_surface_t *src; - cairo_xlib_source_t *source; - Display *dpy = dst->display->display; - cairo_int_status_t status; - cairo_surface_pattern_t local_pattern; - XTransform xtransform; - XRenderPictureAttributes pa; - unsigned mask = 0; - - sub = (cairo_surface_subsurface_t *) pattern->surface; - - if (sample->x >= 0 && sample->y >= 0 && - sample->x + sample->width <= sub->extents.width && - sample->y + sample->height <= sub->extents.height) - { - src = (cairo_xlib_surface_t *) sub->target; - status = _cairo_surface_flush (&src->base, 0); - if (unlikely (status)) - return _cairo_surface_create_in_error (status); - - if (pattern->base.filter == CAIRO_FILTER_NEAREST && - _cairo_matrix_is_translation (&pattern->base.matrix)) - { - *src_x += pattern->base.matrix.x0 + sub->extents.x; - *src_y += pattern->base.matrix.y0 + sub->extents.y; - - _cairo_xlib_surface_ensure_picture (src); - return cairo_surface_reference (&src->base); - } - else - { - cairo_surface_pattern_t local_pattern = *pattern; - local_pattern.base.matrix.x0 += sub->extents.x; - local_pattern.base.matrix.y0 += sub->extents.y; - local_pattern.base.extend = CAIRO_EXTEND_NONE; - return embedded_source (dst, &local_pattern, extents, - src_x, src_y, init_source (dst, src)); - } - } - - if (sub->snapshot && sub->snapshot->type == CAIRO_SURFACE_TYPE_XLIB) { - src = (cairo_xlib_surface_t *) cairo_surface_reference (sub->snapshot); - source = &src->embedded_source; - } else { - src = (cairo_xlib_surface_t *) - _cairo_surface_create_scratch (&dst->base, - sub->base.content, - sub->extents.width, - sub->extents.height, - NULL); - if (src->base.type != CAIRO_SURFACE_TYPE_XLIB) { - cairo_surface_destroy (&src->base); - return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY); - } - - _cairo_pattern_init_for_surface (&local_pattern, sub->target); - cairo_matrix_init_translate (&local_pattern.base.matrix, - sub->extents.x, sub->extents.y); - local_pattern.base.filter = CAIRO_FILTER_NEAREST; - status = _cairo_surface_paint (&src->base, - CAIRO_OPERATOR_SOURCE, - &local_pattern.base, - NULL); - _cairo_pattern_fini (&local_pattern.base); - - if (unlikely (status)) { - cairo_surface_destroy (&src->base); - return _cairo_surface_create_in_error (status); - } - - _cairo_xlib_surface_ensure_picture (src); - _cairo_surface_subsurface_set_snapshot (&sub->base, &src->base); - - source = &src->embedded_source; - source->has_component_alpha = 0; - source->has_matrix = 0; - source->filter = CAIRO_FILTER_NEAREST; - source->extend = CAIRO_EXTEND_NONE; - } - - status = _cairo_matrix_to_pixman_matrix_offset (&pattern->base.matrix, - pattern->base.filter, - extents->x + extents->width / 2, - extents->y + extents->height / 2, - (pixman_transform_t *)&xtransform, - src_x, src_y); - if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) { - if (source->has_matrix) { - source->has_matrix = 0; - memcpy (&xtransform, &identity, sizeof (identity)); - status = CAIRO_INT_STATUS_SUCCESS; - } - } else - source->has_matrix = 1; - if (status == CAIRO_INT_STATUS_SUCCESS) - XRenderSetPictureTransform (dpy, src->picture, &xtransform); - - if (source->filter != pattern->base.filter) { - picture_set_filter (dpy, src->picture, pattern->base.filter); - source->filter = pattern->base.filter; - } - - if (source->has_component_alpha != pattern->base.has_component_alpha) { - pa.component_alpha = pattern->base.has_component_alpha; - mask |= CPComponentAlpha; - source->has_component_alpha = pattern->base.has_component_alpha; - } - - if (source->extend != pattern->base.extend) { - pa.repeat = extend_to_repeat (pattern->base.extend); - mask |= CPRepeat; - source->extend = pattern->base.extend; - } - - if (mask) - XRenderChangePicture (dpy, src->picture, mask, &pa); - - return &src->base; -} - -static cairo_surface_t * -native_source (cairo_xlib_surface_t *dst, - const cairo_surface_pattern_t *pattern, - cairo_bool_t is_mask, - const cairo_rectangle_int_t *extents, - const cairo_rectangle_int_t *sample, - int *src_x, int *src_y) -{ - cairo_xlib_surface_t *src; - cairo_int_status_t status; - - if (_cairo_surface_is_subsurface (pattern->surface)) - return subsurface_source (dst, pattern, is_mask, - extents, sample, - src_x, src_y); - - src = unwrap_source (pattern); - status = _cairo_surface_flush (&src->base, 0); - if (unlikely (status)) - return _cairo_surface_create_in_error (status); - - if (pattern->base.filter == CAIRO_FILTER_NEAREST && - sample->x >= 0 && sample->y >= 0 && - sample->x + sample->width <= src->width && - sample->y + sample->height <= src->height && - _cairo_matrix_is_translation (&pattern->base.matrix)) - { - *src_x += pattern->base.matrix.x0; - *src_y += pattern->base.matrix.y0; - _cairo_xlib_surface_ensure_picture (src); - return cairo_surface_reference (&src->base); - } - - return embedded_source (dst, pattern, extents, src_x, src_y, - init_source (dst, src)); -} - -static cairo_surface_t * -recording_pattern_get_surface (const cairo_pattern_t *pattern) -{ - cairo_surface_t *surface; - - surface = ((const cairo_surface_pattern_t *) pattern)->surface; - - if (_cairo_surface_is_paginated (surface)) - return cairo_surface_reference (_cairo_paginated_surface_get_recording (surface)); - - if (_cairo_surface_is_snapshot (surface)) - return _cairo_surface_snapshot_get_target (surface); - - return cairo_surface_reference (surface); -} - -static cairo_surface_t * -record_source (cairo_xlib_surface_t *dst, - const cairo_surface_pattern_t *pattern, - cairo_bool_t is_mask, - const cairo_rectangle_int_t *extents, - const cairo_rectangle_int_t *sample, - int *src_x, int *src_y) -{ - cairo_xlib_surface_t *src; - cairo_surface_t *recording; - cairo_matrix_t matrix, m; - cairo_status_t status; - cairo_rectangle_int_t upload, limit; - - upload = *sample; - if (_cairo_surface_get_extents (pattern->surface, &limit) && - ! _cairo_rectangle_intersect (&upload, &limit)) - { - if (pattern->base.extend == CAIRO_EXTEND_NONE) - return alpha_source (dst, 0); - - upload = limit; - } - - src = (cairo_xlib_surface_t *) - _cairo_surface_create_scratch (&dst->base, - pattern->surface->content, - upload.width, - upload.height, - NULL); - if (src->base.type != CAIRO_SURFACE_TYPE_XLIB) { - cairo_surface_destroy (&src->base); - return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY); - } - - cairo_matrix_init_translate (&matrix, upload.x, upload.y); - recording = recording_pattern_get_surface (&pattern->base), - status = _cairo_recording_surface_replay_with_clip (recording, - &matrix, &src->base, - NULL); - cairo_surface_destroy (recording); - if (unlikely (status)) { - cairo_surface_destroy (&src->base); - return _cairo_surface_create_in_error (status); - } - - matrix = pattern->base.matrix; - if (upload.x | upload.y) { - cairo_matrix_init_translate (&m, -upload.x, -upload.y); - cairo_matrix_multiply (&matrix, &matrix, &m); - } - - _cairo_xlib_surface_ensure_picture (src); - if (! picture_set_properties (src->display, src->picture, - &pattern->base, &matrix, extents, - src_x, src_y)) - { - cairo_surface_destroy (&src->base); - return render_pattern (dst, &pattern->base, is_mask, - extents, src_x, src_y); - } - - return &src->base; -} - -static cairo_surface_t * -surface_source (cairo_xlib_surface_t *dst, - const cairo_surface_pattern_t *pattern, - cairo_bool_t is_mask, - const cairo_rectangle_int_t *extents, - const cairo_rectangle_int_t *sample, - int *src_x, int *src_y) -{ - cairo_surface_t *src; - cairo_xlib_surface_t *xsrc; - cairo_surface_pattern_t local_pattern; - cairo_status_t status; - cairo_rectangle_int_t upload, limit; - - src = pattern->surface; - if (src->type == CAIRO_SURFACE_TYPE_IMAGE && - src->device == dst->base.device && - _cairo_xlib_shm_surface_get_pixmap (src)) { - cairo_xlib_proxy_t *proxy; - - proxy = malloc (sizeof(*proxy)); - if (unlikely (proxy == NULL)) - return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_surface_init (&proxy->source.base, - &cairo_xlib_proxy_backend, - dst->base.device, - src->content); - - proxy->source.dpy = dst->display->display; - proxy->source.picture = XRenderCreatePicture (proxy->source.dpy, - _cairo_xlib_shm_surface_get_pixmap (src), - _cairo_xlib_shm_surface_get_xrender_format (src), - 0, NULL); - proxy->source.pixmap = None; - - proxy->source.has_component_alpha = 0; - proxy->source.has_matrix = 0; - proxy->source.filter = CAIRO_FILTER_NEAREST; - proxy->source.extend = CAIRO_EXTEND_NONE; - proxy->owner = cairo_surface_reference (src); - - return embedded_source (dst, pattern, extents, src_x, src_y, - &proxy->source); - } - - upload = *sample; - if (_cairo_surface_get_extents (pattern->surface, &limit)) { - if (pattern->base.extend == CAIRO_EXTEND_NONE) { - if (! _cairo_rectangle_intersect (&upload, &limit)) - return alpha_source (dst, 0); - } else if (pattern->base.extend == CAIRO_EXTEND_PAD) { - if (! _cairo_rectangle_intersect (&upload, &limit)) - upload = limit; - } else { - if (upload.x < limit.x || - upload.x + upload.width > limit.x + limit.width || - upload.y < limit.y || - upload.y + upload.height > limit.y + limit.height) - { - upload = limit; - } - } - } - - xsrc = (cairo_xlib_surface_t *) - _cairo_surface_create_scratch (&dst->base, - src->content, - upload.width, - upload.height, - NULL); - if (xsrc->base.type != CAIRO_SURFACE_TYPE_XLIB) { - cairo_surface_destroy (src); - cairo_surface_destroy (&xsrc->base); - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - if (_cairo_surface_is_image (src)) { - status = _cairo_xlib_surface_draw_image (xsrc, (cairo_image_surface_t *)src, - upload.x, upload.y, - upload.width, upload.height, - 0, 0); - } else { - cairo_image_surface_t *image; - cairo_rectangle_int_t map_extents = { 0,0, upload.width,upload.height }; - - image = _cairo_surface_map_to_image (&xsrc->base, &map_extents); - - _cairo_pattern_init_for_surface (&local_pattern, pattern->surface); - cairo_matrix_init_translate (&local_pattern.base.matrix, - upload.x, upload.y); - - status = _cairo_surface_paint (&image->base, - CAIRO_OPERATOR_SOURCE, - &local_pattern.base, - NULL); - _cairo_pattern_fini (&local_pattern.base); - - status = _cairo_surface_unmap_image (&xsrc->base, image); - if (unlikely (status)) { - cairo_surface_destroy (&xsrc->base); - return _cairo_surface_create_in_error (status); - } - - status = _cairo_xlib_surface_put_shm (xsrc); - if (unlikely (status)) { - cairo_surface_destroy (&xsrc->base); - return _cairo_surface_create_in_error (status); - } - } - - _cairo_pattern_init_static_copy (&local_pattern.base, &pattern->base); - if (upload.x | upload.y) { - cairo_matrix_t m; - cairo_matrix_init_translate (&m, -upload.x, -upload.y); - cairo_matrix_multiply (&local_pattern.base.matrix, - &local_pattern.base.matrix, - &m); - } - - *src_x = *src_y = 0; - _cairo_xlib_surface_ensure_picture (xsrc); - if (! picture_set_properties (xsrc->display, - xsrc->picture, - &local_pattern.base, - &local_pattern.base.matrix, - extents, - src_x, src_y)) - { - cairo_surface_destroy (&xsrc->base); - return render_pattern (dst, &pattern->base, - is_mask, extents, - src_x, src_y); - } - - return &xsrc->base; -} - -static cairo_bool_t -pattern_is_supported (cairo_xlib_display_t *display, - const cairo_pattern_t *pattern) -{ - if (pattern->type == CAIRO_PATTERN_TYPE_MESH) - return FALSE; - - if (display->buggy_pad_reflect) { - if (pattern->extend == CAIRO_EXTEND_REPEAT || pattern->extend == CAIRO_EXTEND_PAD) - return FALSE; - } - - if (display->buggy_gradients) { - if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR || pattern->type == CAIRO_PATTERN_TYPE_RADIAL) - return FALSE; - } - - switch (pattern->filter) { - case CAIRO_FILTER_FAST: - case CAIRO_FILTER_NEAREST: - return CAIRO_RENDER_HAS_PICTURE_TRANSFORM (display) || - _cairo_matrix_is_integer_translation (&pattern->matrix, NULL, NULL); - case CAIRO_FILTER_GOOD: - return CAIRO_RENDER_HAS_FILTER_GOOD (display); - case CAIRO_FILTER_BEST: - return CAIRO_RENDER_HAS_FILTER_BEST (display); - case CAIRO_FILTER_BILINEAR: - case CAIRO_FILTER_GAUSSIAN: - default: - return CAIRO_RENDER_HAS_FILTERS (display); - } -} - -cairo_surface_t * -_cairo_xlib_source_create_for_pattern (cairo_surface_t *_dst, - const cairo_pattern_t *pattern, - cairo_bool_t is_mask, - const cairo_rectangle_int_t *extents, - const cairo_rectangle_int_t *sample, - int *src_x, int *src_y) -{ - cairo_xlib_surface_t *dst = (cairo_xlib_surface_t *)_dst; - - *src_x = *src_y = 0; - - if (pattern == NULL || pattern->type == CAIRO_PATTERN_TYPE_SOLID) { - if (pattern == NULL) - pattern = &_cairo_pattern_white.base; - - return solid_source (dst, &((cairo_solid_pattern_t *)pattern)->color); - } - - if (pattern_is_supported (dst->display, pattern)) { - if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) { - cairo_surface_pattern_t *spattern = (cairo_surface_pattern_t *)pattern; - if (spattern->surface->type == CAIRO_SURFACE_TYPE_XLIB && - _cairo_xlib_surface_same_screen (dst, - unwrap_source (spattern))) - return native_source (dst, spattern, is_mask, - extents, sample, - src_x, src_y); - - if (spattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING) - return record_source (dst, spattern, is_mask, - extents, sample, - src_x, src_y); - - return surface_source (dst, spattern, is_mask, - extents, sample, - src_x, src_y); - } - - if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR || - pattern->type == CAIRO_PATTERN_TYPE_RADIAL) - { - cairo_gradient_pattern_t *gpattern = (cairo_gradient_pattern_t *)pattern; - return gradient_source (dst, gpattern, is_mask, extents, src_x, src_y); - } - } - - return render_pattern (dst, pattern, is_mask, extents, src_x, src_y); -} - -#endif /* !CAIRO_HAS_XLIB_XCB_FUNCTIONS */ diff --git a/source/libs/cairo/cairo-src/src/cairo-xlib-surface-private.h b/source/libs/cairo/cairo-src/src/cairo-xlib-surface-private.h deleted file mode 100644 index 83d9b63cc4c74232061c322421d036b6405b3856..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xlib-surface-private.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Cairo - a vector graphics library with display and print output - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - */ - -#ifndef CAIRO_XLIB_SURFACE_PRIVATE_H -#define CAIRO_XLIB_SURFACE_PRIVATE_H - -#include "cairo-xlib-xrender-private.h" -#include "cairo-xlib.h" -#include "cairo-xlib-private.h" - -#include "cairo-surface-private.h" -#include "cairo-surface-backend-private.h" - - -#endif /* CAIRO_XLIB_SURFACE_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-xlib-surface-shm.c b/source/libs/cairo/cairo-src/src/cairo-xlib-surface-shm.c deleted file mode 100644 index 9824eff823b3643ec56f36b2c92f83beed2a486d..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xlib-surface-shm.c +++ /dev/null @@ -1,1459 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2012 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#if !CAIRO_HAS_XLIB_XCB_FUNCTIONS - -#include "cairo-xlib-private.h" -#include "cairo-xlib-surface-private.h" - -#if !HAVE_X11_EXTENSIONS_XSHM_H || !(HAVE_X11_EXTENSIONS_SHMPROTO_H || HAVE_X11_EXTENSIONS_SHMSTR_H) -void _cairo_xlib_display_init_shm (cairo_xlib_display_t *display) {} - -cairo_surface_t * -_cairo_xlib_surface_get_shm (cairo_xlib_surface_t *surface, - cairo_bool_t overwrite) -{ - return NULL; -} - -cairo_int_status_t -_cairo_xlib_surface_put_shm (cairo_xlib_surface_t *surface) -{ - assert (!surface->fallback); - return CAIRO_INT_STATUS_SUCCESS; -} - -cairo_surface_t * -_cairo_xlib_surface_create_shm (cairo_xlib_surface_t *other, - pixman_format_code_t format, - int width, int height) -{ - return NULL; -} - -cairo_surface_t * -_cairo_xlib_surface_create_shm__image (cairo_xlib_surface_t *surface, - pixman_format_code_t format, - int width, int height) -{ - return NULL; -} - -cairo_surface_t * -_cairo_xlib_surface_create_similar_shm (void *other, - cairo_format_t format, - int width, int height) -{ - return cairo_image_surface_create (format, width, height); -} - -void -_cairo_xlib_shm_surface_mark_active (cairo_surface_t *_shm) -{ - ASSERT_NOT_REACHED; -} - -void -_cairo_xlib_shm_surface_get_ximage (cairo_surface_t *surface, - XImage *ximage) -{ - ASSERT_NOT_REACHED; -} - -void * -_cairo_xlib_shm_surface_get_obdata (cairo_surface_t *surface) -{ - ASSERT_NOT_REACHED; - return NULL; -} - -Pixmap -_cairo_xlib_shm_surface_get_pixmap (cairo_surface_t *surface) -{ - ASSERT_NOT_REACHED; - return 0; -} - -XRenderPictFormat * -_cairo_xlib_shm_surface_get_xrender_format (cairo_surface_t *surface) -{ - ASSERT_NOT_REACHED; - return NULL; -} - -cairo_bool_t -_cairo_xlib_shm_surface_is_active (cairo_surface_t *surface) -{ - ASSERT_NOT_REACHED; - return FALSE; -} - -cairo_bool_t -_cairo_xlib_shm_surface_is_idle (cairo_surface_t *surface) -{ - ASSERT_NOT_REACHED; - return TRUE; -} - -void _cairo_xlib_display_fini_shm (cairo_xlib_display_t *display) {} - -#else - -#include "cairo-damage-private.h" -#include "cairo-default-context-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-list-inline.h" -#include "cairo-mempool-private.h" - -#include <X11/Xlibint.h> -#include <X11/Xproto.h> -#include <X11/extensions/XShm.h> -#if HAVE_X11_EXTENSIONS_SHMPROTO_H -#include <X11/extensions/shmproto.h> -#elif HAVE_X11_EXTENSIONS_SHMSTR_H -#include <X11/extensions/shmstr.h> -#endif -#include <sys/ipc.h> -#include <sys/shm.h> - -#define MIN_PIXMAP_SIZE 4096 - -#define MIN_BITS 8 -#define MIN_SIZE (1<<(MIN_BITS-1)) - -typedef struct _cairo_xlib_shm cairo_xlib_shm_t; -typedef struct _cairo_xlib_shm_info cairo_xlib_shm_info_t; -typedef struct _cairo_xlib_shm_surface cairo_xlib_shm_surface_t; - -struct _cairo_xlib_shm { - cairo_mempool_t mem; - - XShmSegmentInfo shm; - unsigned long attached; - cairo_list_t link; -}; - -struct _cairo_xlib_shm_info { - unsigned long last_request; - void *mem; - size_t size; - cairo_xlib_shm_t *pool; -}; - -struct _cairo_xlib_shm_surface { - cairo_image_surface_t image; - - cairo_list_t link; - cairo_xlib_shm_info_t *info; - Pixmap pixmap; - unsigned long active; - int idle; -}; - -/* the parent is always given by index/2 */ -#define PQ_PARENT_INDEX(i) ((i) >> 1) -#define PQ_FIRST_ENTRY 1 - -/* left and right children are index * 2 and (index * 2) +1 respectively */ -#define PQ_LEFT_CHILD_INDEX(i) ((i) << 1) - -#define PQ_TOP(pq) ((pq)->elements[PQ_FIRST_ENTRY]) - -struct pqueue { - int size, max_size; - cairo_xlib_shm_info_t **elements; -}; - -struct _cairo_xlib_shm_display { - int has_pixmaps; - int opcode; - int event; - - Window window; - unsigned long last_request; - unsigned long last_event; - - cairo_list_t surfaces; - - cairo_list_t pool; - struct pqueue info; -}; - -static inline cairo_bool_t -seqno_passed (unsigned long a, unsigned long b) -{ - return (long)(b - a) >= 0; -} - -static inline cairo_bool_t -seqno_before (unsigned long a, unsigned long b) -{ - return (long)(b - a) > 0; -} - -static inline cairo_bool_t -seqno_after (unsigned long a, unsigned long b) -{ - return (long)(a - b) > 0; -} - -static inline cairo_status_t -_pqueue_init (struct pqueue *pq) -{ - pq->max_size = 32; - pq->size = 0; - - pq->elements = _cairo_malloc_ab (pq->max_size, - sizeof (cairo_xlib_shm_info_t *)); - if (unlikely (pq->elements == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - PQ_TOP(pq) = NULL; - return CAIRO_STATUS_SUCCESS; -} - -static inline void -_pqueue_fini (struct pqueue *pq) -{ - free (pq->elements); -} - -static cairo_status_t -_pqueue_grow (struct pqueue *pq) -{ - cairo_xlib_shm_info_t **new_elements; - - new_elements = _cairo_realloc_ab (pq->elements, - 2 * pq->max_size, - sizeof (cairo_xlib_shm_info_t *)); - if (unlikely (new_elements == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - pq->elements = new_elements; - pq->max_size *= 2; - return CAIRO_STATUS_SUCCESS; -} - -static void -_pqueue_shrink (struct pqueue *pq, int min_size) -{ - cairo_xlib_shm_info_t **new_elements; - - if (min_size > pq->max_size) - return; - - new_elements = _cairo_realloc_ab (pq->elements, - min_size, - sizeof (cairo_xlib_shm_info_t *)); - if (unlikely (new_elements == NULL)) - return; - - pq->elements = new_elements; - pq->max_size = min_size; -} - -static inline cairo_status_t -_pqueue_push (struct pqueue *pq, cairo_xlib_shm_info_t *info) -{ - cairo_xlib_shm_info_t **elements; - int i, parent; - - if (unlikely (pq->size + 1 == pq->max_size)) { - cairo_status_t status; - - status = _pqueue_grow (pq); - if (unlikely (status)) - return status; - } - - elements = pq->elements; - - for (i = ++pq->size; - i != PQ_FIRST_ENTRY && - info->last_request < elements[parent = PQ_PARENT_INDEX (i)]->last_request; - i = parent) - { - elements[i] = elements[parent]; - } - - elements[i] = info; - - return CAIRO_STATUS_SUCCESS; -} - -static inline void -_pqueue_pop (struct pqueue *pq) -{ - cairo_xlib_shm_info_t **elements = pq->elements; - cairo_xlib_shm_info_t *tail; - int child, i; - - tail = elements[pq->size--]; - if (pq->size == 0) { - elements[PQ_FIRST_ENTRY] = NULL; - _pqueue_shrink (pq, 32); - return; - } - - for (i = PQ_FIRST_ENTRY; - (child = PQ_LEFT_CHILD_INDEX (i)) <= pq->size; - i = child) - { - if (child != pq->size && - elements[child+1]->last_request < elements[child]->last_request) - { - child++; - } - - if (elements[child]->last_request >= tail->last_request) - break; - - elements[i] = elements[child]; - } - elements[i] = tail; -} - -static cairo_bool_t _x_error_occurred; - -static int -_check_error_handler (Display *display, - XErrorEvent *event) -{ - _x_error_occurred = TRUE; - return False; /* ignored */ -} - -static cairo_bool_t -can_use_shm (Display *dpy, int *has_pixmap) -{ - XShmSegmentInfo shm; - int (*old_handler) (Display *display, XErrorEvent *event); - Status success; - int major, minor; - - if (! XShmQueryExtension (dpy)) - return FALSE; - - XShmQueryVersion (dpy, &major, &minor, has_pixmap); - - shm.shmid = shmget (IPC_PRIVATE, 0x1000, IPC_CREAT | 0600); - if (shm.shmid == -1) - return FALSE; - - shm.readOnly = FALSE; - shm.shmaddr = shmat (shm.shmid, NULL, 0); - if (shm.shmaddr == (char *) -1) { - shmctl (shm.shmid, IPC_RMID, NULL); - return FALSE; - } - - assert (CAIRO_MUTEX_IS_LOCKED (_cairo_xlib_display_mutex)); - _x_error_occurred = FALSE; - - XLockDisplay (dpy); - XSync (dpy, False); - old_handler = XSetErrorHandler (_check_error_handler); - - success = XShmAttach (dpy, &shm); - if (success) - XShmDetach (dpy, &shm); - - XSync (dpy, False); - XSetErrorHandler (old_handler); - XUnlockDisplay (dpy); - - shmctl (shm.shmid, IPC_RMID, NULL); - shmdt (shm.shmaddr); - - return success && ! _x_error_occurred; -} - -static inline Display * -peek_display (cairo_device_t *device) -{ - return ((cairo_xlib_display_t *)device)->display; -} - -static inline unsigned long -peek_processed (cairo_device_t *device) -{ - return LastKnownRequestProcessed (peek_display(device)); -} - -static void -_cairo_xlib_display_shm_pool_destroy (cairo_xlib_display_t *display, - cairo_xlib_shm_t *pool) -{ - shmdt (pool->shm.shmaddr); - if (display->display) /* may be called after CloseDisplay */ - XShmDetach (display->display, &pool->shm); - - _cairo_mempool_fini (&pool->mem); - - cairo_list_del (&pool->link); - free (pool); -} - -static void send_event(cairo_xlib_display_t *display, - cairo_xlib_shm_info_t *info, - unsigned long seqno) -{ - XShmCompletionEvent ev; - - if (! seqno_after (seqno, display->shm->last_event)) - return; - - ev.type = display->shm->event; - ev.send_event = 1; /* XXX or lie? */ - ev.serial = XNextRequest (display->display); - ev.drawable = display->shm->window; - ev.major_code = display->shm->opcode; - ev.minor_code = X_ShmPutImage; - ev.shmseg = info->pool->shm.shmid; - ev.offset = (char *)info->mem - (char *)info->pool->shm.shmaddr; - - XSendEvent (display->display, ev.drawable, False, 0, (XEvent *)&ev); - - display->shm->last_event = ev.serial; -} - -static void _cairo_xlib_display_sync (cairo_xlib_display_t *display) -{ - cairo_xlib_shm_info_t *info; - struct pqueue *pq = &display->shm->info; - - XSync (display->display, False); - - while ((info = PQ_TOP(pq))) { - _cairo_mempool_free (&info->pool->mem, info->mem); - _pqueue_pop (&display->shm->info); - free (info); - } -} - -static void -_cairo_xlib_shm_info_cleanup (cairo_xlib_display_t *display) -{ - cairo_xlib_shm_info_t *info; - Display *dpy = display->display; - struct pqueue *pq = &display->shm->info; - unsigned long processed; - - if (PQ_TOP(pq) == NULL) - return; - - XEventsQueued (dpy, QueuedAfterReading); - processed = LastKnownRequestProcessed (dpy); - - info = PQ_TOP(pq); - do { - if (! seqno_passed (info->last_request, processed)) { - send_event (display, info, display->shm->last_request); - return; - } - - _cairo_mempool_free (&info->pool->mem, info->mem); - _pqueue_pop (&display->shm->info); - free (info); - } while ((info = PQ_TOP(pq))); -} - -static cairo_xlib_shm_t * -_cairo_xlib_shm_info_find (cairo_xlib_display_t *display, size_t size, - void **ptr, unsigned long *last_request) -{ - cairo_xlib_shm_info_t *info; - struct pqueue *pq = &display->shm->info; - - if (PQ_TOP(pq) == NULL) - return NULL; - - info = PQ_TOP(pq); - do { - cairo_xlib_shm_t *pool = info->pool; - - *last_request = info->last_request; - - _pqueue_pop (&display->shm->info); - _cairo_mempool_free (&pool->mem, info->mem); - free (info); - - if (pool->mem.free_bytes >= size) { - void *mem = _cairo_mempool_alloc (&pool->mem, size); - if (mem != NULL) { - *ptr = mem; - return pool; - } - } - } while ((info = PQ_TOP(pq))); - - return NULL; -} - -static cairo_xlib_shm_t * -_cairo_xlib_shm_pool_find (cairo_xlib_display_t *display, - size_t size, - void **ptr) -{ - cairo_xlib_shm_t *pool; - - cairo_list_foreach_entry (pool, cairo_xlib_shm_t, &display->shm->pool, link) { - if (pool->mem.free_bytes >= size) { - void *mem = _cairo_mempool_alloc (&pool->mem, size); - if (mem != NULL) { - *ptr = mem; - return pool; - } - } - } - - return NULL; -} - -static void -_cairo_xlib_shm_pool_cleanup (cairo_xlib_display_t *display) -{ - cairo_xlib_shm_t *pool, *next; - unsigned long processed; - - processed = LastKnownRequestProcessed (display->display); - - cairo_list_foreach_entry_safe (pool, next, cairo_xlib_shm_t, - &display->shm->pool, link) { - if (! seqno_passed (pool->attached, processed)) - break; - - if (pool->mem.free_bytes == pool->mem.max_bytes) - _cairo_xlib_display_shm_pool_destroy (display, pool); - } -} - -static cairo_xlib_shm_t * -_cairo_xlib_shm_pool_create(cairo_xlib_display_t *display, - size_t size, void **ptr) -{ - Display *dpy = display->display; - cairo_xlib_shm_t *pool; - size_t bytes, maxbits = 16, minbits = MIN_BITS; - Status success; - - pool = malloc (sizeof (cairo_xlib_shm_t)); - if (pool == NULL) - return NULL; - - bytes = 1 << maxbits; - while (bytes <= size) - bytes <<= 1, maxbits++; - bytes <<= 3; - - minbits += (maxbits - 16) / 2; - - pool->shm.shmid = shmget (IPC_PRIVATE, bytes, IPC_CREAT | 0600); - while (pool->shm.shmid == -1 && bytes >= 2*size) { - bytes >>= 1; - pool->shm.shmid = shmget (IPC_PRIVATE, bytes, IPC_CREAT | 0600); - } - if (pool->shm.shmid == -1) - goto cleanup; - - pool->shm.readOnly = FALSE; - pool->shm.shmaddr = shmat (pool->shm.shmid, NULL, 0); - if (pool->shm.shmaddr == (char *) -1) { - shmctl (pool->shm.shmid, IPC_RMID, NULL); - goto cleanup; - } - - pool->attached = XNextRequest (dpy); - success = XShmAttach (dpy, &pool->shm); -#if !IPC_RMID_DEFERRED_RELEASE - XSync (dpy, FALSE); -#endif - shmctl (pool->shm.shmid, IPC_RMID, NULL); - - if (! success) - goto cleanup_shm; - - if (_cairo_mempool_init (&pool->mem, pool->shm.shmaddr, bytes, - minbits, maxbits - minbits + 1)) - goto cleanup_detach; - - cairo_list_add (&pool->link, &display->shm->pool); - - *ptr = _cairo_mempool_alloc (&pool->mem, size); - assert (*ptr != NULL); - return pool; - -cleanup_detach: - XShmDetach (dpy, &pool->shm); -cleanup_shm: - shmdt (pool->shm.shmaddr); -cleanup: - free (pool); - return NULL; -} - -static cairo_xlib_shm_info_t * -_cairo_xlib_shm_info_create (cairo_xlib_display_t *display, - size_t size, cairo_bool_t will_sync) -{ - cairo_xlib_shm_info_t *info; - cairo_xlib_shm_t *pool; - unsigned long last_request = 0; - void *mem = NULL; - - _cairo_xlib_shm_info_cleanup (display); - pool = _cairo_xlib_shm_pool_find (display, size, &mem); - _cairo_xlib_shm_pool_cleanup (display); - - if (pool == NULL && will_sync) - pool = _cairo_xlib_shm_info_find (display, size, &mem, &last_request); - if (pool == NULL) - pool = _cairo_xlib_shm_pool_create (display, size, &mem); - if (pool == NULL) - return NULL; - - assert (mem != NULL); - - info = malloc (sizeof (*info)); - if (info == NULL) { - _cairo_mempool_free (&pool->mem, mem); - return NULL; - } - - info->pool = pool; - info->mem = mem; - info->size = size; - info->last_request = last_request; - - return info; -} - -static cairo_status_t -_cairo_xlib_shm_surface_flush (void *abstract_surface, unsigned flags) -{ - cairo_xlib_shm_surface_t *shm = abstract_surface; - cairo_xlib_display_t *display; - Display *dpy; - cairo_status_t status; - - if (shm->active == 0) - return CAIRO_STATUS_SUCCESS; - - if (shm->image.base._finishing) - return CAIRO_STATUS_SUCCESS; - - if (seqno_passed (shm->active, peek_processed (shm->image.base.device))) { - shm->active = 0; - return CAIRO_STATUS_SUCCESS; - } - - status = _cairo_xlib_display_acquire (shm->image.base.device, &display); - if (unlikely (status)) - return status; - - send_event (display, shm->info, shm->active); - - dpy = display->display; - XEventsQueued (dpy, QueuedAfterReading); - while (! seqno_passed (shm->active, LastKnownRequestProcessed (dpy))) { - LockDisplay(dpy); - _XReadEvents(dpy); - UnlockDisplay(dpy); - } - - cairo_device_release (&display->base); - shm->active = 0; - - return CAIRO_STATUS_SUCCESS; -} - -static inline cairo_bool_t -active (cairo_xlib_shm_surface_t *shm, Display *dpy) -{ - return (shm->active && - ! seqno_passed (shm->active, LastKnownRequestProcessed (dpy))); -} - -static cairo_status_t -_cairo_xlib_shm_surface_finish (void *abstract_surface) -{ - cairo_xlib_shm_surface_t *shm = abstract_surface; - cairo_xlib_display_t *display; - cairo_status_t status; - - if (shm->image.base.damage) { - _cairo_damage_destroy (shm->image.base.damage); - shm->image.base.damage = _cairo_damage_create_in_error (CAIRO_STATUS_SURFACE_FINISHED); - } - - status = _cairo_xlib_display_acquire (shm->image.base.device, &display); - if (unlikely (status)) - return status; - - if (shm->pixmap) - XFreePixmap (display->display, shm->pixmap); - - if (active (shm, display->display)) { - shm->info->last_request = shm->active; - _pqueue_push (&display->shm->info, shm->info); - if (seqno_before (display->shm->last_request, shm->active)) - display->shm->last_request = shm->active; - } else { - _cairo_mempool_free (&shm->info->pool->mem, shm->info->mem); - free (shm->info); - - _cairo_xlib_shm_pool_cleanup (display); - } - - cairo_list_del (&shm->link); - - cairo_device_release (&display->base); - return _cairo_image_surface_finish (abstract_surface); -} - -static const cairo_surface_backend_t cairo_xlib_shm_surface_backend = { - CAIRO_SURFACE_TYPE_IMAGE, - _cairo_xlib_shm_surface_finish, - - _cairo_default_context_create, - - _cairo_image_surface_create_similar, - NULL, /* create similar image */ - _cairo_image_surface_map_to_image, - _cairo_image_surface_unmap_image, - - _cairo_image_surface_source, - _cairo_image_surface_acquire_source_image, - _cairo_image_surface_release_source_image, - _cairo_image_surface_snapshot, - - NULL, /* copy_page */ - NULL, /* show_page */ - - _cairo_image_surface_get_extents, - _cairo_image_surface_get_font_options, - - _cairo_xlib_shm_surface_flush, - NULL, - - _cairo_image_surface_paint, - _cairo_image_surface_mask, - _cairo_image_surface_stroke, - _cairo_image_surface_fill, - NULL, /* fill-stroke */ - _cairo_image_surface_glyphs, -}; - -static cairo_bool_t -has_shm (cairo_xlib_surface_t *surface) -{ - cairo_xlib_display_t *display = (cairo_xlib_display_t *)surface->base.device; - return display->shm != NULL; -} - -static int -has_shm_pixmaps (cairo_xlib_surface_t *surface) -{ - cairo_xlib_display_t *display = (cairo_xlib_display_t *)surface->base.device; - if (!display->shm) - return 0; - - return display->shm->has_pixmaps; -} - -static cairo_xlib_shm_surface_t * -_cairo_xlib_shm_surface_create (cairo_xlib_surface_t *other, - pixman_format_code_t format, - int width, int height, - cairo_bool_t will_sync, - int create_pixmap) -{ - cairo_xlib_shm_surface_t *shm; - cairo_xlib_display_t *display; - pixman_image_t *image; - int stride, size; - - stride = CAIRO_STRIDE_FOR_WIDTH_BPP (width, PIXMAN_FORMAT_BPP(format)); - size = stride * height; - if (size < MIN_SIZE) - return NULL; - - shm = malloc (sizeof (*shm)); - if (unlikely (shm == NULL)) - return (cairo_xlib_shm_surface_t *)_cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_surface_init (&shm->image.base, - &cairo_xlib_shm_surface_backend, - other->base.device, - _cairo_content_from_pixman_format (format)); - - if (_cairo_xlib_display_acquire (other->base.device, &display)) - goto cleanup_shm; - - shm->info = _cairo_xlib_shm_info_create (display, size, will_sync); - if (shm->info == NULL) - goto cleanup_display; - - image = pixman_image_create_bits (format, width, height, - (uint32_t *) shm->info->mem, stride); - if (image == NULL) - goto cleanup_info; - - _cairo_image_surface_init (&shm->image, image, format); - - shm->pixmap = 0; - if (create_pixmap && size >= create_pixmap) { - shm->pixmap = XShmCreatePixmap (display->display, - other->drawable, - shm->info->mem, - &shm->info->pool->shm, - shm->image.width, - shm->image.height, - shm->image.depth); - } - shm->active = shm->info->last_request; - shm->idle = -5; - - assert (shm->active == 0 || will_sync); - - cairo_list_add (&shm->link, &display->shm->surfaces); - - cairo_device_release (&display->base); - - return shm; - -cleanup_info: - _cairo_mempool_free (&shm->info->pool->mem, shm->info->mem); - free(shm->info); -cleanup_display: - cairo_device_release (&display->base); -cleanup_shm: - free (shm); - return NULL; -} - -static void -_cairo_xlib_surface_update_shm (cairo_xlib_surface_t *surface) -{ - cairo_xlib_shm_surface_t *shm = (cairo_xlib_shm_surface_t *)surface->shm; - cairo_xlib_display_t *display; - cairo_damage_t *damage; - GC gc; - - damage = _cairo_damage_reduce (surface->base.damage); - surface->base.damage = _cairo_damage_create(); - - if (_cairo_xlib_display_acquire (surface->base.device, &display)) - goto cleanup_damage; - - if (_cairo_xlib_surface_get_gc (display, surface, &gc)) - goto cleanup_display; - - if (! surface->owns_pixmap) { - XGCValues gcv; - - gcv.subwindow_mode = IncludeInferiors; - XChangeGC (display->display, gc, GCSubwindowMode, &gcv); - } - - if (damage->region) { - XRectangle stack_rects[CAIRO_STACK_ARRAY_LENGTH (XRectangle)]; - XRectangle *rects = stack_rects; - cairo_rectangle_int_t r; - int n_rects, i; - - n_rects = cairo_region_num_rectangles (damage->region); - if (n_rects == 0) { - } else if (n_rects == 1) { - cairo_region_get_rectangle (damage->region, 0, &r); - XCopyArea (display->display, - surface->drawable, shm->pixmap, gc, - r.x, r.y, - r.width, r.height, - r.x, r.y); - } else { - if (n_rects > ARRAY_LENGTH (stack_rects)) { - rects = _cairo_malloc_ab (n_rects, sizeof (XRectangle)); - if (unlikely (rects == NULL)) { - rects = stack_rects; - n_rects = ARRAY_LENGTH (stack_rects); - } - } - for (i = 0; i < n_rects; i++) { - cairo_region_get_rectangle (damage->region, i, &r); - - rects[i].x = r.x; - rects[i].y = r.y; - rects[i].width = r.width; - rects[i].height = r.height; - } - XSetClipRectangles (display->display, gc, 0, 0, rects, i, YXBanded); - - XCopyArea (display->display, - surface->drawable, shm->pixmap, gc, - 0, 0, - shm->image.width, shm->image.height, - 0, 0); - - if (damage->status == CAIRO_STATUS_SUCCESS && damage->region) - XSetClipMask (display->display, gc, None); - } - } else { - XCopyArea (display->display, - surface->drawable, shm->pixmap, gc, - 0, 0, - shm->image.width, shm->image.height, - 0, 0); - } - - if (! surface->owns_pixmap) { - XGCValues gcv; - - gcv.subwindow_mode = ClipByChildren; - XChangeGC (display->display, gc, GCSubwindowMode, &gcv); - } - - _cairo_xlib_display_sync (display); - shm->active = 0; - shm->idle--; - - _cairo_xlib_surface_put_gc (display, surface, gc); -cleanup_display: - cairo_device_release (&display->base); -cleanup_damage: - _cairo_damage_destroy (damage); -} - -static void -_cairo_xlib_surface_clear_shm (cairo_xlib_surface_t *surface) -{ - cairo_xlib_shm_surface_t *shm = (cairo_xlib_shm_surface_t *)surface->shm; - - assert (shm->active == 0); - - _cairo_damage_destroy (surface->base.damage); - surface->base.damage = _cairo_damage_create(); - - memset (shm->image.data, 0, shm->image.stride * shm->image.height); - shm->image.base.is_clear = TRUE; -} - -static void inc_idle (cairo_surface_t *surface) -{ - cairo_xlib_shm_surface_t *shm = (cairo_xlib_shm_surface_t *)surface; - shm->idle++; -} - -static void dec_idle (cairo_surface_t *surface) -{ - cairo_xlib_shm_surface_t *shm = (cairo_xlib_shm_surface_t *)surface; - shm->idle--; -} - -cairo_surface_t * -_cairo_xlib_surface_get_shm (cairo_xlib_surface_t *surface, - cairo_bool_t overwrite) -{ - if (surface->fallback) { - assert (surface->base.damage); - assert (surface->shm); - assert (surface->shm->damage); - goto done; - } - - if (surface->shm == NULL) { - pixman_format_code_t pixman_format; - cairo_bool_t will_sync; - - if (! has_shm_pixmaps (surface)) - return NULL; - - if ((surface->width | surface->height) < 32) - return NULL; - - pixman_format = _pixman_format_for_xlib_surface (surface); - if (pixman_format == 0) - return NULL; - - will_sync = !surface->base.is_clear && !overwrite; - - surface->shm = - &_cairo_xlib_shm_surface_create (surface, pixman_format, - surface->width, surface->height, - will_sync, 1)->image.base; - if (surface->shm == NULL) - return NULL; - - assert (surface->base.damage == NULL); - if (surface->base.serial || !surface->owns_pixmap) { - cairo_rectangle_int_t rect; - - rect.x = rect.y = 0; - rect.width = surface->width; - rect.height = surface->height; - - surface->base.damage = - _cairo_damage_add_rectangle (NULL, &rect); - } else - surface->base.damage = _cairo_damage_create (); - - surface->shm->damage = _cairo_damage_create (); - } - - if (overwrite) { - _cairo_damage_destroy (surface->base.damage); - surface->base.damage = _cairo_damage_create (); - } - - if (!surface->base.is_clear && surface->base.damage->dirty) - _cairo_xlib_surface_update_shm (surface); - - _cairo_xlib_shm_surface_flush (surface->shm, 1); - - if (surface->base.is_clear && surface->base.damage->dirty) - _cairo_xlib_surface_clear_shm (surface); - -done: - dec_idle(surface->shm); - return surface->shm; -} - -cairo_int_status_t -_cairo_xlib_surface_put_shm (cairo_xlib_surface_t *surface) -{ - cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS; - - if (!surface->fallback) { - if (surface->shm) - inc_idle (surface->shm); - return CAIRO_INT_STATUS_SUCCESS; - } - - if (surface->shm->damage->dirty) { - cairo_xlib_shm_surface_t *shm = (cairo_xlib_shm_surface_t *) surface->shm; - cairo_xlib_display_t *display; - cairo_damage_t *damage; - GC gc; - - status = _cairo_xlib_display_acquire (surface->base.device, &display); - if (unlikely (status)) - return status; - - damage = _cairo_damage_reduce (shm->image.base.damage); - shm->image.base.damage = _cairo_damage_create (); - - TRACE ((stderr, "%s: flushing damage x %d\n", __FUNCTION__, - damage->region ? cairo_region_num_rectangles (damage->region) : 0)); - if (damage->status == CAIRO_STATUS_SUCCESS && damage->region) { - XRectangle stack_rects[CAIRO_STACK_ARRAY_LENGTH (XRectangle)]; - XRectangle *rects = stack_rects; - cairo_rectangle_int_t r; - int n_rects, i; - - n_rects = cairo_region_num_rectangles (damage->region); - if (n_rects == 0) - goto out; - - status = _cairo_xlib_surface_get_gc (display, surface, &gc); - if (unlikely (status)) - goto out; - - if (n_rects == 1) { - cairo_region_get_rectangle (damage->region, 0, &r); - _cairo_xlib_shm_surface_mark_active (surface->shm); - XCopyArea (display->display, - shm->pixmap, surface->drawable, gc, - r.x, r.y, - r.width, r.height, - r.x, r.y); - } else { - if (n_rects > ARRAY_LENGTH (stack_rects)) { - rects = _cairo_malloc_ab (n_rects, sizeof (XRectangle)); - if (unlikely (rects == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - _cairo_xlib_surface_put_gc (display, surface, gc); - goto out; - } - } - for (i = 0; i < n_rects; i++) { - cairo_region_get_rectangle (damage->region, i, &r); - - rects[i].x = r.x; - rects[i].y = r.y; - rects[i].width = r.width; - rects[i].height = r.height; - } - XSetClipRectangles (display->display, gc, 0, 0, rects, i, YXBanded); - - _cairo_xlib_shm_surface_mark_active (surface->shm); - XCopyArea (display->display, - shm->pixmap, surface->drawable, gc, - 0, 0, - shm->image.width, shm->image.height, - 0, 0); - - if (damage->status == CAIRO_STATUS_SUCCESS && damage->region) - XSetClipMask (display->display, gc, None); - } - - _cairo_xlib_surface_put_gc (display, surface, gc); - } - -out: - _cairo_damage_destroy (damage); - cairo_device_release (&display->base); - } - - return status; -} - -cairo_surface_t * -_cairo_xlib_surface_create_shm (cairo_xlib_surface_t *other, - pixman_format_code_t format, - int width, int height) -{ - cairo_surface_t *surface; - - surface = NULL; - if (has_shm (other)) - surface = &_cairo_xlib_shm_surface_create (other, format, width, height, - FALSE, has_shm_pixmaps (other))->image.base; - - return surface; -} - -cairo_surface_t * -_cairo_xlib_surface_create_shm__image (cairo_xlib_surface_t *surface, - pixman_format_code_t format, - int width, int height) -{ - if (! has_shm(surface)) - return NULL; - - return &_cairo_xlib_shm_surface_create (surface, format, width, height, - FALSE, 0)->image.base; -} - -cairo_surface_t * -_cairo_xlib_surface_create_similar_shm (void *other, - cairo_format_t format, - int width, int height) -{ - cairo_surface_t *surface; - - surface = _cairo_xlib_surface_create_shm (other, - _cairo_format_to_pixman_format_code (format), - width, height); - if (surface) { - if (! surface->is_clear) { - cairo_xlib_shm_surface_t *shm = (cairo_xlib_shm_surface_t *) surface; - assert (shm->active == 0); - memset (shm->image.data, 0, shm->image.stride * shm->image.height); - shm->image.base.is_clear = TRUE; - } - } else - surface = cairo_image_surface_create (format, width, height); - - return surface; -} - -void -_cairo_xlib_shm_surface_mark_active (cairo_surface_t *_shm) -{ - cairo_xlib_shm_surface_t *shm = (cairo_xlib_shm_surface_t *) _shm; - cairo_xlib_display_t *display = (cairo_xlib_display_t *) _shm->device; - - shm->active = XNextRequest (display->display); -} - -void -_cairo_xlib_shm_surface_get_ximage (cairo_surface_t *surface, - XImage *ximage) -{ - cairo_xlib_shm_surface_t *shm = (cairo_xlib_shm_surface_t *) surface; - int native_byte_order = _cairo_is_little_endian () ? LSBFirst : MSBFirst; - cairo_format_masks_t image_masks; - int ret; - - ret = _pixman_format_to_masks (shm->image.pixman_format, &image_masks); - assert (ret); - - ximage->width = shm->image.width; - ximage->height = shm->image.height; - ximage->format = ZPixmap; - ximage->data = (char *) shm->image.data; - ximage->obdata = (char *)&shm->info->pool->shm; - ximage->byte_order = native_byte_order; - ximage->bitmap_unit = 32; /* always for libpixman */ - ximage->bitmap_bit_order = native_byte_order; - ximage->bitmap_pad = 32; /* always for libpixman */ - ximage->depth = shm->image.depth; - ximage->bytes_per_line = shm->image.stride; - ximage->bits_per_pixel = image_masks.bpp; - ximage->red_mask = image_masks.red_mask; - ximage->green_mask = image_masks.green_mask; - ximage->blue_mask = image_masks.blue_mask; - ximage->xoffset = 0; - - ret = XInitImage (ximage); - assert (ret != 0); -} - -void * -_cairo_xlib_shm_surface_get_obdata (cairo_surface_t *surface) -{ - cairo_xlib_display_t *display = (cairo_xlib_display_t *) surface->device; - cairo_xlib_shm_surface_t *shm = (cairo_xlib_shm_surface_t *) surface; - - display->shm->last_event = shm->active = XNextRequest (display->display); - return &shm->info->pool->shm; -} - -Pixmap -_cairo_xlib_shm_surface_get_pixmap (cairo_surface_t *surface) -{ - cairo_xlib_shm_surface_t *shm; - - shm = (cairo_xlib_shm_surface_t *) surface; - return shm->pixmap; -} - -XRenderPictFormat * -_cairo_xlib_shm_surface_get_xrender_format (cairo_surface_t *surface) -{ - cairo_xlib_shm_surface_t *shm; - - shm = (cairo_xlib_shm_surface_t *) surface; - if (shm->image.format != CAIRO_FORMAT_INVALID) - return _cairo_xlib_display_get_xrender_format ((cairo_xlib_display_t *)surface->device, - shm->image.format); - - return _cairo_xlib_display_get_xrender_format_for_pixman((cairo_xlib_display_t *)surface->device, - shm->image.pixman_format); -} - -cairo_bool_t -_cairo_xlib_shm_surface_is_active (cairo_surface_t *surface) -{ - cairo_xlib_shm_surface_t *shm; - - shm = (cairo_xlib_shm_surface_t *) surface; - if (shm->active == 0) - return FALSE; - - if (seqno_passed (shm->active, peek_processed (shm->image.base.device))) { - shm->active = 0; - return FALSE; - } - - return TRUE; -} - -cairo_bool_t -_cairo_xlib_shm_surface_is_idle (cairo_surface_t *surface) -{ - cairo_xlib_shm_surface_t *shm; - - shm = (cairo_xlib_shm_surface_t *) surface; - return shm->idle > 0; -} - -#define XORG_VERSION_ENCODE(major,minor,patch,snap) \ - (((major) * 10000000) + ((minor) * 100000) + ((patch) * 1000) + snap) - -static cairo_bool_t -has_broken_send_shm_event (cairo_xlib_display_t *display, - cairo_xlib_shm_display_t *shm) -{ - Display *dpy = display->display; - int (*old_handler) (Display *display, XErrorEvent *event); - XShmCompletionEvent ev; - XShmSegmentInfo info; - - info.shmid = shmget (IPC_PRIVATE, 0x1000, IPC_CREAT | 0600); - if (info.shmid == -1) - return TRUE; - - info.readOnly = FALSE; - info.shmaddr = shmat (info.shmid, NULL, 0); - if (info.shmaddr == (char *) -1) { - shmctl (info.shmid, IPC_RMID, NULL); - return TRUE; - } - - ev.type = shm->event; - ev.send_event = 1; - ev.serial = 1; - ev.drawable = shm->window; - ev.major_code = shm->opcode; - ev.minor_code = X_ShmPutImage; - - ev.shmseg = info.shmid; - ev.offset = 0; - - assert (CAIRO_MUTEX_IS_LOCKED (_cairo_xlib_display_mutex)); - _x_error_occurred = FALSE; - - XLockDisplay (dpy); - XSync (dpy, False); - old_handler = XSetErrorHandler (_check_error_handler); - - XShmAttach (dpy, &info); - XSendEvent (dpy, ev.drawable, False, 0, (XEvent *)&ev); - XShmDetach (dpy, &info); - - XSync (dpy, False); - XSetErrorHandler (old_handler); - XUnlockDisplay (dpy); - - shmctl (info.shmid, IPC_RMID, NULL); - shmdt (info.shmaddr); - - return _x_error_occurred; -} - -static cairo_bool_t -xorg_has_buggy_send_shm_completion_event(cairo_xlib_display_t *display, - cairo_xlib_shm_display_t *shm) -{ - Display *dpy = display->display; - - /* As libXext sets the SEND_EVENT bit in the ShmCompletionEvent, - * the Xserver may crash if it does not take care when processing - * the event type. For instance versions of Xorg prior to 1.11.1 - * exhibited this bug, and was fixed by: - * - * commit 2d2dce558d24eeea0eb011ec9ebaa6c5c2273c39 - * Author: Sam Spilsbury <sam.spilsbury@canonical.com> - * Date: Wed Sep 14 09:58:34 2011 +0800 - * - * Remove the SendEvent bit (0x80) before doing range checks on event type. - */ - if (_cairo_xlib_vendor_is_xorg (dpy) && - VendorRelease (dpy) < XORG_VERSION_ENCODE(1,11,0,1)) - return TRUE; - - /* For everyone else check that no error is generated */ - return has_broken_send_shm_event (display, shm); -} - -void -_cairo_xlib_display_init_shm (cairo_xlib_display_t *display) -{ - cairo_xlib_shm_display_t *shm; - XSetWindowAttributes attr; - XExtCodes *codes; - int has_pixmap, scr; - - display->shm = NULL; - - if (!can_use_shm (display->display, &has_pixmap)) - return; - - shm = malloc (sizeof (*shm)); - if (unlikely (shm == NULL)) - return; - - codes = XInitExtension (display->display, SHMNAME); - if (codes == NULL) { - free (shm); - return; - } - - shm->opcode = codes ->major_opcode; - shm->event = codes->first_event; - - if (unlikely (_pqueue_init (&shm->info))) { - free (shm); - return; - } - - scr = DefaultScreen (display->display); - attr.override_redirect = 1; - shm->window = XCreateWindow (display->display, - DefaultRootWindow (display->display), -1, -1, - 1, 1, 0, - DefaultDepth (display->display, scr), - InputOutput, - DefaultVisual (display->display, scr), - CWOverrideRedirect, &attr); - shm->last_event = 0; - shm->last_request = 0; - - if (xorg_has_buggy_send_shm_completion_event(display, shm)) - has_pixmap = 0; - - shm->has_pixmaps = has_pixmap ? MIN_PIXMAP_SIZE : 0; - cairo_list_init (&shm->pool); - - cairo_list_init (&shm->surfaces); - - display->shm = shm; -} - -void -_cairo_xlib_display_fini_shm (cairo_xlib_display_t *display) -{ - cairo_xlib_shm_display_t *shm = display->shm; - - if (shm == NULL) - return; - - while (!cairo_list_is_empty (&shm->surfaces)) - cairo_surface_finish (&cairo_list_first_entry (&shm->surfaces, - cairo_xlib_shm_surface_t, - link)->image.base); - - _pqueue_fini (&shm->info); - - while (!cairo_list_is_empty (&shm->pool)) { - cairo_xlib_shm_t *pool; - - pool = cairo_list_first_entry (&shm->pool, cairo_xlib_shm_t, link); - _cairo_xlib_display_shm_pool_destroy (display, pool); - } - - if (display->display) - XDestroyWindow (display->display, shm->window); - - free (shm); - display->shm = NULL; -} -#endif -#endif diff --git a/source/libs/cairo/cairo-src/src/cairo-xlib-surface.c b/source/libs/cairo/cairo-src/src/cairo-xlib-surface.c deleted file mode 100644 index ffea476f68f116dd3613d491a1183918ec5c3c4a..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xlib-surface.c +++ /dev/null @@ -1,2385 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Behdad Esfahbod <behdad@behdad.org> - * Chris Wilson <chris@chris-wilson.co.uk> - * Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation - */ - -/* Heed well the words of Owen Taylor: - * "Any patch that works around a render bug, or claims to, without a - * specific reference to the bug filed in bugzilla.freedesktop.org will - * never pass approval." - */ - -#include "cairoint.h" - -#if !CAIRO_HAS_XLIB_XCB_FUNCTIONS - -#include "cairo-xlib-private.h" -#include "cairo-xlib-surface-private.h" - -#include "cairo-compositor-private.h" -#include "cairo-clip-private.h" -#include "cairo-damage-private.h" -#include "cairo-default-context-private.h" -#include "cairo-error-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-list-inline.h" -#include "cairo-pattern-private.h" -#include "cairo-pixman-private.h" -#include "cairo-region-private.h" -#include "cairo-scaled-font-private.h" -#include "cairo-surface-snapshot-private.h" -#include "cairo-surface-subsurface-private.h" - -#include <X11/Xutil.h> /* for XDestroyImage */ - -#include <X11/extensions/XShm.h> -#include <sys/ipc.h> -#include <sys/shm.h> - -#define XLIB_COORD_MAX 32767 - -#define DEBUG 0 - -#if DEBUG -#define UNSUPPORTED(reason) \ - fprintf (stderr, \ - "cairo-xlib: hit unsupported operation %s(), line %d: %s\n", \ - __FUNCTION__, __LINE__, reason), \ - CAIRO_INT_STATUS_UNSUPPORTED -#else -#define UNSUPPORTED(reason) CAIRO_INT_STATUS_UNSUPPORTED -#endif - -#if DEBUG -#include <X11/Xlibint.h> -static void CAIRO_PRINTF_FORMAT (2, 3) -_x_bread_crumb (Display *dpy, - const char *fmt, - ...) -{ - xReq *req; - char buf[2048]; - unsigned int len, len_dwords; - va_list ap; - - va_start (ap, fmt); - len = vsnprintf (buf, sizeof (buf), fmt, ap); - va_end (ap); - - buf[len++] = '\0'; - while (len & 3) - buf[len++] = '\0'; - - LockDisplay (dpy); - GetEmptyReq (NoOperation, req); - - len_dwords = len >> 2; - SetReqLen (req, len_dwords, len_dwords); - Data (dpy, buf, len); - - UnlockDisplay (dpy); - SyncHandle (); -} -#define X_DEBUG(x) _x_bread_crumb x -#else -#define X_DEBUG(x) -#endif - -/** - * SECTION:cairo-xlib - * @Title: XLib Surfaces - * @Short_Description: X Window System rendering using XLib - * @See_Also: #cairo_surface_t - * - * The XLib surface is used to render cairo graphics to X Window System - * windows and pixmaps using the XLib library. - * - * Note that the XLib surface automatically takes advantage of X render extension - * if it is available. - **/ - -/** - * CAIRO_HAS_XLIB_SURFACE: - * - * Defined if the Xlib surface backend is available. - * This macro can be used to conditionally compile backend-specific code. - * - * Since: 1.0 - **/ - -/** - * SECTION:cairo-xlib-xrender - * @Title: XLib-XRender Backend - * @Short_Description: X Window System rendering using XLib and the X Render extension - * @See_Also: #cairo_surface_t - * - * The XLib surface is used to render cairo graphics to X Window System - * windows and pixmaps using the XLib and Xrender libraries. - * - * Note that the XLib surface automatically takes advantage of X Render extension - * if it is available. - **/ - -/** - * CAIRO_HAS_XLIB_XRENDER_SURFACE: - * - * Defined if the XLib/XRender surface functions are available. - * This macro can be used to conditionally compile backend-specific code. - * - * Since: 1.6 - **/ - -/* Xlib doesn't define a typedef, so define one ourselves */ -typedef int (*cairo_xlib_error_func_t) (Display *display, - XErrorEvent *event); - -static cairo_surface_t * -_cairo_xlib_surface_create_internal (cairo_xlib_screen_t *screen, - Drawable drawable, - Visual *visual, - XRenderPictFormat *xrender_format, - int width, - int height, - int depth); - -static cairo_bool_t -_cairo_surface_is_xlib (cairo_surface_t *surface); - -/* - * Instead of taking two round trips for each blending request, - * assume that if a particular drawable fails GetImage that it will - * fail for a "while"; use temporary pixmaps to avoid the errors - */ - -#define CAIRO_ASSUME_PIXMAP 20 - -static const XTransform identity = { { - { 1 << 16, 0x00000, 0x00000 }, - { 0x00000, 1 << 16, 0x00000 }, - { 0x00000, 0x00000, 1 << 16 }, -} }; - -static Visual * -_visual_for_xrender_format(Screen *screen, - XRenderPictFormat *xrender_format) -{ - int d, v; - - /* XXX Consider searching through the list of known cairo_visual_t for - * the reverse mapping. - */ - - for (d = 0; d < screen->ndepths; d++) { - Depth *d_info = &screen->depths[d]; - - if (d_info->depth != xrender_format->depth) - continue; - - for (v = 0; v < d_info->nvisuals; v++) { - Visual *visual = &d_info->visuals[v]; - - switch (visual->class) { - case TrueColor: - if (xrender_format->type != PictTypeDirect) - continue; - break; - - case DirectColor: - /* Prefer TrueColor to DirectColor. - * (XRenderFindVisualFormat considers both TrueColor and DirectColor - * Visuals to match the same PictFormat.) - */ - continue; - - case StaticGray: - case GrayScale: - case StaticColor: - case PseudoColor: - if (xrender_format->type != PictTypeIndexed) - continue; - break; - } - - if (xrender_format == - XRenderFindVisualFormat (DisplayOfScreen(screen), visual)) - return visual; - } - } - - return NULL; -} - -static cairo_content_t -_xrender_format_to_content (XRenderPictFormat *xrender_format) -{ - cairo_content_t content; - - /* This only happens when using a non-Render server. Let's punt - * and say there's no alpha here. */ - if (xrender_format == NULL) - return CAIRO_CONTENT_COLOR; - - content = 0; - if (xrender_format->direct.alphaMask) - content |= CAIRO_CONTENT_ALPHA; - if (xrender_format->direct.redMask | - xrender_format->direct.greenMask | - xrender_format->direct.blueMask) - content |= CAIRO_CONTENT_COLOR; - - return content; -} - -static cairo_surface_t * -_cairo_xlib_surface_create_similar (void *abstract_src, - cairo_content_t content, - int width, - int height) -{ - cairo_xlib_surface_t *src = abstract_src; - XRenderPictFormat *xrender_format; - cairo_xlib_surface_t *surface; - cairo_xlib_display_t *display; - Pixmap pix; - - if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX) - return NULL; - - if (width == 0 || height == 0) - return NULL; - - if (_cairo_xlib_display_acquire (src->base.device, &display)) - return NULL; - - /* If we never found an XRenderFormat or if it isn't compatible - * with the content being requested, then we fallback to just - * constructing a cairo_format_t instead, (which will fairly - * arbitrarily pick a visual/depth for the similar surface. - */ - xrender_format = NULL; - if (src->xrender_format && - _xrender_format_to_content (src->xrender_format) == content) - { - xrender_format = src->xrender_format; - } - if (xrender_format == NULL) { - xrender_format = - _cairo_xlib_display_get_xrender_format (display, - _cairo_format_from_content (content)); - } - if (xrender_format) { - Visual *visual; - - /* We've got a compatible XRenderFormat now, which means the - * similar surface will match the existing surface as closely in - * visual/depth etc. as possible. */ - pix = XCreatePixmap (display->display, src->drawable, - width, height, xrender_format->depth); - - if (xrender_format == src->xrender_format) - visual = src->visual; - else - visual = _visual_for_xrender_format(src->screen->screen, - xrender_format); - - surface = (cairo_xlib_surface_t *) - _cairo_xlib_surface_create_internal (src->screen, pix, visual, - xrender_format, - width, height, - xrender_format->depth); - } - else - { - Screen *screen = src->screen->screen; - int depth; - - /* No compatible XRenderFormat, see if we can make an ordinary pixmap, - * so that we can still accelerate blits with XCopyArea(). */ - if (content != CAIRO_CONTENT_COLOR) { - cairo_device_release (&display->base); - return NULL; - } - - depth = DefaultDepthOfScreen (screen); - - pix = XCreatePixmap (display->display, RootWindowOfScreen (screen), - width <= 0 ? 1 : width, height <= 0 ? 1 : height, - depth); - - surface = (cairo_xlib_surface_t *) - _cairo_xlib_surface_create_internal (src->screen, pix, - DefaultVisualOfScreen (screen), - NULL, - width, height, depth); - } - - if (likely (surface->base.status == CAIRO_STATUS_SUCCESS)) - surface->owns_pixmap = TRUE; - else - XFreePixmap (display->display, pix); - - cairo_device_release (&display->base); - - return &surface->base; -} - -static void -_cairo_xlib_surface_discard_shm (cairo_xlib_surface_t *surface) -{ - if (surface->shm == NULL) - return; - - /* Force the flush for an external surface */ - if (!surface->owns_pixmap) - cairo_surface_flush (surface->shm); - - cairo_surface_finish (surface->shm); - cairo_surface_destroy (surface->shm); - surface->shm = NULL; - - _cairo_damage_destroy (surface->base.damage); - surface->base.damage = NULL; - - surface->fallback = 0; -} - -static cairo_status_t -_cairo_xlib_surface_finish (void *abstract_surface) -{ - cairo_xlib_surface_t *surface = abstract_surface; - cairo_status_t status; - cairo_xlib_display_t *display; - - cairo_list_del (&surface->link); - - status = _cairo_xlib_display_acquire (surface->base.device, &display); - if (unlikely (status)) - return status; - - X_DEBUG ((display->display, "finish (drawable=%x)", (unsigned int) surface->drawable)); - - if (surface->embedded_source.picture) - XRenderFreePicture (display->display, surface->embedded_source.picture); - if (surface->picture) - XRenderFreePicture (display->display, surface->picture); - - _cairo_xlib_surface_discard_shm (surface); - - if (surface->owns_pixmap) - XFreePixmap (display->display, surface->drawable); - - cairo_device_release (&display->base); - - return status; -} - -cairo_status_t -_cairo_xlib_surface_get_gc (cairo_xlib_display_t *display, - cairo_xlib_surface_t *surface, - GC *gc) -{ - *gc = _cairo_xlib_screen_get_gc (display, - surface->screen, - surface->depth, - surface->drawable); - if (unlikely (*gc == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - return CAIRO_STATUS_SUCCESS; -} - -static int -_noop_error_handler (Display *display, - XErrorEvent *event) -{ - return False; /* return value is ignored */ -} - -static void -_swap_ximage_2bytes (XImage *ximage) -{ - int i, j; - char *line = ximage->data; - - for (j = ximage->height; j; j--) { - uint16_t *p = (uint16_t *) line; - for (i = ximage->width; i; i--) { - *p = bswap_16 (*p); - p++; - } - - line += ximage->bytes_per_line; - } -} - -static void -_swap_ximage_3bytes (XImage *ximage) -{ - int i, j; - char *line = ximage->data; - - for (j = ximage->height; j; j--) { - uint8_t *p = (uint8_t *) line; - for (i = ximage->width; i; i--) { - uint8_t tmp; - tmp = p[2]; - p[2] = p[0]; - p[0] = tmp; - p += 3; - } - - line += ximage->bytes_per_line; - } -} - -static void -_swap_ximage_4bytes (XImage *ximage) -{ - int i, j; - char *line = ximage->data; - - for (j = ximage->height; j; j--) { - uint32_t *p = (uint32_t *) line; - for (i = ximage->width; i; i--) { - *p = bswap_32 (*p); - p++; - } - - line += ximage->bytes_per_line; - } -} - -static void -_swap_ximage_nibbles (XImage *ximage) -{ - int i, j; - char *line = ximage->data; - - for (j = ximage->height; j; j--) { - uint8_t *p = (uint8_t *) line; - for (i = (ximage->width + 1) / 2; i; i--) { - *p = ((*p >> 4) & 0xf) | ((*p << 4) & ~0xf); - p++; - } - - line += ximage->bytes_per_line; - } -} - -static void -_swap_ximage_bits (XImage *ximage) -{ - int i, j; - char *line = ximage->data; - int unit = ximage->bitmap_unit; - int line_bytes = ((ximage->width + unit - 1) & ~(unit - 1)) / 8; - - for (j = ximage->height; j; j--) { - char *p = line; - - for (i = line_bytes; i; i--) { - char b = *p; - b = ((b << 1) & 0xaa) | ((b >> 1) & 0x55); - b = ((b << 2) & 0xcc) | ((b >> 2) & 0x33); - b = ((b << 4) & 0xf0) | ((b >> 4) & 0x0f); - *p = b; - - p++; - } - - line += ximage->bytes_per_line; - } -} - -static void -_swap_ximage_to_native (XImage *ximage) -{ - int unit_bytes = 0; - int native_byte_order = _cairo_is_little_endian () ? LSBFirst : MSBFirst; - - if (ximage->bits_per_pixel == 1 && - ximage->bitmap_bit_order != native_byte_order) - { - _swap_ximage_bits (ximage); - if (ximage->bitmap_bit_order == ximage->byte_order) - return; - } - - if (ximage->byte_order == native_byte_order) - return; - - switch (ximage->bits_per_pixel) { - case 1: - unit_bytes = ximage->bitmap_unit / 8; - break; - case 4: - _swap_ximage_nibbles (ximage); - /* fall-through */ - case 8: - case 16: - case 20: - case 24: - case 28: - case 30: - case 32: - unit_bytes = (ximage->bits_per_pixel + 7) / 8; - break; - default: - /* This could be hit on some rare but possible cases. */ - ASSERT_NOT_REACHED; - } - - switch (unit_bytes) { - case 1: - break; - case 2: - _swap_ximage_2bytes (ximage); - break; - case 3: - _swap_ximage_3bytes (ximage); - break; - case 4: - _swap_ximage_4bytes (ximage); - break; - default: - ASSERT_NOT_REACHED; - } -} - - -/* Given a mask, (with a single sequence of contiguous 1 bits), return - * the number of 1 bits in 'width' and the number of 0 bits to its - * right in 'shift'. */ -static void -_characterize_field (uint32_t mask, int *width, int *shift) -{ - *width = _cairo_popcount (mask); - /* The final '& 31' is to force a 0 mask to result in 0 shift. */ - *shift = _cairo_popcount ((mask - 1) & ~mask) & 31; -} - -/* Convert a field of 'width' bits to 'new_width' bits with correct - * rounding. */ -static inline uint32_t -_resize_field (uint32_t field, int width, int new_width) -{ - if (width == 0) - return 0; - - if (width >= new_width) { - return field >> (width - new_width); - } else { - uint32_t result = field << (new_width - width); - - while (width < new_width) { - result |= result >> width; - width <<= 1; - } - return result; - } -} - -static inline uint32_t -_adjust_field (uint32_t field, int adjustment) -{ - return MIN (255, MAX(0, (int)field + adjustment)); -} - -/* Given a shifted field value, (described by 'width' and 'shift), - * resize it 8-bits and return that value. - * - * Note that the original field value must not have any non-field bits - * set. - */ -static inline uint32_t -_field_to_8 (uint32_t field, int width, int shift) -{ - return _resize_field (field >> shift, width, 8); -} - -static inline uint32_t -_field_to_8_undither (uint32_t field, int width, int shift, - int dither_adjustment) -{ - return _adjust_field (_field_to_8 (field, width, shift), - dither_adjustment>>width); -} - -/* Given an 8-bit value, convert it to a field of 'width', shift it up - * to 'shift, and return it. */ -static inline uint32_t -_field_from_8 (uint32_t field, int width, int shift) -{ - return _resize_field (field, 8, width) << shift; -} - -static inline uint32_t -_field_from_8_dither (uint32_t field, int width, int shift, - int8_t dither_adjustment) -{ - return _field_from_8 (_adjust_field (field, dither_adjustment>>width), width, shift); -} - -static inline uint32_t -_pseudocolor_from_rgb888_dither (cairo_xlib_visual_info_t *visual_info, - uint32_t r, uint32_t g, uint32_t b, - int8_t dither_adjustment) -{ - if (r == g && g == b) { - dither_adjustment /= RAMP_SIZE; - return visual_info->gray8_to_pseudocolor[_adjust_field (r, dither_adjustment)]; - } else { - dither_adjustment = visual_info->dither8_to_cube[dither_adjustment+128]; - return visual_info->cube_to_pseudocolor[visual_info->field8_to_cube[_adjust_field (r, dither_adjustment)]] - [visual_info->field8_to_cube[_adjust_field (g, dither_adjustment)]] - [visual_info->field8_to_cube[_adjust_field (b, dither_adjustment)]]; - } -} - -static inline uint32_t -_pseudocolor_to_rgb888 (cairo_xlib_visual_info_t *visual_info, - uint32_t pixel) -{ - uint32_t r, g, b; - pixel &= 0xff; - r = visual_info->colors[pixel].r; - g = visual_info->colors[pixel].g; - b = visual_info->colors[pixel].b; - return (r << 16) | - (g << 8) | - (b ); -} - -/* should range from -128 to 127 */ -#define X 16 -static const int8_t dither_pattern[4][4] = { - {-8*X, +0*X, -6*X, +2*X}, - {+4*X, -4*X, +6*X, -2*X}, - {-5*X, +4*X, -7*X, +1*X}, - {+7*X, -1*X, +5*X, -3*X} -}; -#undef X - -static int bits_per_pixel(cairo_xlib_surface_t *surface) -{ - if (surface->depth > 16) - return 32; - else if (surface->depth > 8) - return 16; - else if (surface->depth > 1) - return 8; - else - return 1; -} - -pixman_format_code_t -_pixman_format_for_xlib_surface (cairo_xlib_surface_t *surface) -{ - cairo_format_masks_t masks; - pixman_format_code_t format; - - masks.bpp = bits_per_pixel (surface); - masks.alpha_mask = surface->a_mask; - masks.red_mask = surface->r_mask; - masks.green_mask = surface->g_mask; - masks.blue_mask = surface->b_mask; - if (! _pixman_format_from_masks (&masks, &format)) - return 0; - - return format; -} - -static cairo_surface_t * -_get_image_surface (cairo_xlib_surface_t *surface, - const cairo_rectangle_int_t *extents, - int try_shm) -{ - cairo_int_status_t status; - cairo_image_surface_t *image = NULL; - XImage *ximage; - pixman_format_code_t pixman_format; - cairo_xlib_display_t *display; - - assert (extents->x >= 0); - assert (extents->y >= 0); - assert (extents->x + extents->width <= surface->width); - assert (extents->y + extents->height <= surface->height); - - if (surface->base.is_clear || - (surface->base.serial == 0 && surface->owns_pixmap)) - { - pixman_format = _pixman_format_for_xlib_surface (surface); - if (pixman_format) - { - return _cairo_image_surface_create_with_pixman_format (NULL, - pixman_format, - extents->width, - extents->height, - 0); - } - } - - if (surface->shm) { - cairo_image_surface_t *src = (cairo_image_surface_t *) surface->shm; - cairo_surface_t *dst; - cairo_surface_pattern_t pattern; - - dst = cairo_image_surface_create (src->format, - extents->width, extents->height); - if (unlikely (dst->status)) - return dst; - - _cairo_pattern_init_for_surface (&pattern, &src->base); - cairo_matrix_init_translate (&pattern.base.matrix, - extents->x, extents->y); - status = _cairo_surface_paint (dst, CAIRO_OPERATOR_SOURCE, &pattern.base, NULL); - _cairo_pattern_fini (&pattern.base); - if (unlikely (status)) { - cairo_surface_destroy (dst); - dst = _cairo_surface_create_in_error (status); - } - - return dst; - } - - status = _cairo_xlib_display_acquire (surface->base.device, &display); - if (status) - return _cairo_surface_create_in_error (status); - - pixman_format = _pixman_format_for_xlib_surface (surface); - if (try_shm && pixman_format) { - image = (cairo_image_surface_t *) - _cairo_xlib_surface_create_shm__image (surface, pixman_format, - extents->width, extents->height); - if (image && image->base.status == CAIRO_STATUS_SUCCESS) { - cairo_xlib_error_func_t old_handler; - XImage shm_image; - Bool success; - - _cairo_xlib_shm_surface_get_ximage (&image->base, &shm_image); - - old_handler = XSetErrorHandler (_noop_error_handler); - success = XShmGetImage (display->display, - surface->drawable, - &shm_image, - extents->x, extents->y, - AllPlanes); - XSetErrorHandler (old_handler); - - if (success) { - cairo_device_release (&display->base); - return &image->base; - } - - cairo_surface_destroy (&image->base); - image = NULL; - } - } - - if (surface->use_pixmap == 0) { - cairo_xlib_error_func_t old_handler; - - old_handler = XSetErrorHandler (_noop_error_handler); - - ximage = XGetImage (display->display, - surface->drawable, - extents->x, extents->y, - extents->width, extents->height, - AllPlanes, ZPixmap); - - XSetErrorHandler (old_handler); - - /* If we get an error, the surface must have been a window, - * so retry with the safe code path. - */ - if (!ximage) - surface->use_pixmap = CAIRO_ASSUME_PIXMAP; - } else { - surface->use_pixmap--; - ximage = NULL; - } - - if (ximage == NULL) { - /* XGetImage from a window is dangerous because it can - * produce errors if the window is unmapped or partially - * outside the screen. We could check for errors and - * retry, but to keep things simple, we just create a - * temporary pixmap - */ - Pixmap pixmap; - GC gc; - - status = _cairo_xlib_surface_get_gc (display, surface, &gc); - if (unlikely (status)) - goto BAIL; - - pixmap = XCreatePixmap (display->display, - surface->drawable, - extents->width, extents->height, - surface->depth); - if (pixmap) { - XGCValues gcv; - - gcv.subwindow_mode = IncludeInferiors; - XChangeGC (display->display, gc, GCSubwindowMode, &gcv); - - XCopyArea (display->display, surface->drawable, pixmap, gc, - extents->x, extents->y, - extents->width, extents->height, - 0, 0); - - gcv.subwindow_mode = ClipByChildren; - XChangeGC (display->display, gc, GCSubwindowMode, &gcv); - - ximage = XGetImage (display->display, - pixmap, - 0, 0, - extents->width, extents->height, - AllPlanes, ZPixmap); - - XFreePixmap (display->display, pixmap); - } - - _cairo_xlib_surface_put_gc (display, surface, gc); - - if (ximage == NULL) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto BAIL; - } - } - - _swap_ximage_to_native (ximage); - - /* We can't use pixman to simply write to image if: - * (a) the pixels are not appropriately aligned, - * (b) pixman does not the pixel format, or - * (c) if the image is palettized and we need to convert. - */ - if (pixman_format && - ximage->bitmap_unit == 32 && ximage->bitmap_pad == 32 && - (surface->visual == NULL || surface->visual->class == TrueColor)) - { - image = (cairo_image_surface_t*) - _cairo_image_surface_create_with_pixman_format ((unsigned char *) ximage->data, - pixman_format, - ximage->width, - ximage->height, - ximage->bytes_per_line); - status = image->base.status; - if (unlikely (status)) - goto BAIL; - - /* Let the surface take ownership of the data */ - _cairo_image_surface_assume_ownership_of_data (image); - ximage->data = NULL; - } else { - /* The visual we are dealing with is not supported by the - * standard pixman formats. So we must first convert the data - * to a supported format. */ - - cairo_format_t format; - unsigned char *data; - uint32_t *row; - uint32_t in_pixel, out_pixel; - unsigned int rowstride; - uint32_t a_mask=0, r_mask=0, g_mask=0, b_mask=0; - int a_width=0, r_width=0, g_width=0, b_width=0; - int a_shift=0, r_shift=0, g_shift=0, b_shift=0; - int x, y, x0, y0, x_off, y_off; - cairo_xlib_visual_info_t *visual_info = NULL; - - if (surface->visual == NULL || surface->visual->class == TrueColor) { - cairo_bool_t has_alpha; - cairo_bool_t has_color; - - has_alpha = surface->a_mask; - has_color = (surface->r_mask || - surface->g_mask || - surface->b_mask); - - if (has_color) { - if (has_alpha) { - format = CAIRO_FORMAT_ARGB32; - } else { - format = CAIRO_FORMAT_RGB24; - } - } else { - /* XXX: Using CAIRO_FORMAT_A8 here would be more - * efficient, but would require slightly different code in - * the image conversion to put the alpha channel values - * into the right place. */ - format = CAIRO_FORMAT_ARGB32; - } - - a_mask = surface->a_mask; - r_mask = surface->r_mask; - g_mask = surface->g_mask; - b_mask = surface->b_mask; - - _characterize_field (a_mask, &a_width, &a_shift); - _characterize_field (r_mask, &r_width, &r_shift); - _characterize_field (g_mask, &g_width, &g_shift); - _characterize_field (b_mask, &b_width, &b_shift); - - } else { - format = CAIRO_FORMAT_RGB24; - - status = _cairo_xlib_screen_get_visual_info (display, - surface->screen, - surface->visual, - &visual_info); - if (unlikely (status)) - goto BAIL; - } - - image = (cairo_image_surface_t *) cairo_image_surface_create - (format, ximage->width, ximage->height); - status = image->base.status; - if (unlikely (status)) - goto BAIL; - - data = cairo_image_surface_get_data (&image->base); - rowstride = cairo_image_surface_get_stride (&image->base) >> 2; - row = (uint32_t *) data; - x0 = extents->x + surface->base.device_transform.x0; - y0 = extents->y + surface->base.device_transform.y0; - for (y = 0, y_off = y0 % ARRAY_LENGTH (dither_pattern); - y < ximage->height; - y++, y_off = (y_off+1) % ARRAY_LENGTH (dither_pattern)) { - const int8_t *dither_row = dither_pattern[y_off]; - for (x = 0, x_off = x0 % ARRAY_LENGTH (dither_pattern[0]); - x < ximage->width; - x++, x_off = (x_off+1) % ARRAY_LENGTH (dither_pattern[0])) { - int dither_adjustment = dither_row[x_off]; - - in_pixel = XGetPixel (ximage, x, y); - if (visual_info == NULL) { - out_pixel = ( - _field_to_8 (in_pixel & a_mask, a_width, a_shift) << 24 | - _field_to_8_undither (in_pixel & r_mask, r_width, r_shift, dither_adjustment) << 16 | - _field_to_8_undither (in_pixel & g_mask, g_width, g_shift, dither_adjustment) << 8 | - _field_to_8_undither (in_pixel & b_mask, b_width, b_shift, dither_adjustment)); - } else { - /* Undithering pseudocolor does not look better */ - out_pixel = _pseudocolor_to_rgb888 (visual_info, in_pixel); - } - row[x] = out_pixel; - } - row += rowstride; - } - cairo_surface_mark_dirty (&image->base); - } - - BAIL: - if (ximage) - XDestroyImage (ximage); - - cairo_device_release (&display->base); - - if (unlikely (status)) { - if (image) - cairo_surface_destroy (&image->base); - return _cairo_surface_create_in_error (status); - } - - return &image->base; -} - -void -_cairo_xlib_surface_set_precision (cairo_xlib_surface_t *surface, - cairo_antialias_t antialias) -{ - cairo_xlib_display_t *display = surface->display; - int precision; - - if (display->force_precision != -1) - precision = display->force_precision; - else switch (antialias) { - default: - case CAIRO_ANTIALIAS_DEFAULT: - case CAIRO_ANTIALIAS_GRAY: - case CAIRO_ANTIALIAS_NONE: - case CAIRO_ANTIALIAS_FAST: - case CAIRO_ANTIALIAS_GOOD: - precision = PolyModeImprecise; - break; - case CAIRO_ANTIALIAS_BEST: - case CAIRO_ANTIALIAS_SUBPIXEL: - precision = PolyModePrecise; - break; - } - - if (surface->precision != precision) { - XRenderPictureAttributes pa; - - pa.poly_mode = precision; - XRenderChangePicture (display->display, surface->picture, - CPPolyMode, &pa); - - surface->precision = precision; - } -} - -void -_cairo_xlib_surface_ensure_picture (cairo_xlib_surface_t *surface) -{ - cairo_xlib_display_t *display = surface->display; - XRenderPictureAttributes pa; - int mask = 0; - - if (surface->picture) - return; - - if (display->force_precision != -1) - pa.poly_mode = display->force_precision; - else - pa.poly_mode = PolyModeImprecise; - if (pa.poly_mode) - mask |= CPPolyMode; - - surface->precision = pa.poly_mode; - surface->picture = XRenderCreatePicture (display->display, - surface->drawable, - surface->xrender_format, - mask, &pa); -} - -cairo_status_t -_cairo_xlib_surface_draw_image (cairo_xlib_surface_t *surface, - cairo_image_surface_t *image, - int src_x, - int src_y, - int width, - int height, - int dst_x, - int dst_y) -{ - cairo_xlib_display_t *display; - XImage ximage; - cairo_format_masks_t image_masks; - int native_byte_order = _cairo_is_little_endian () ? LSBFirst : MSBFirst; - cairo_surface_t *shm_image = NULL; - pixman_image_t *pixman_image = NULL; - cairo_status_t status; - cairo_bool_t own_data = FALSE; - cairo_bool_t is_rgb_image; - GC gc; - - ximage.width = image->width; - ximage.height = image->height; - ximage.format = ZPixmap; - ximage.byte_order = native_byte_order; - ximage.bitmap_unit = 32; /* always for libpixman */ - ximage.bitmap_bit_order = native_byte_order; - ximage.bitmap_pad = 32; /* always for libpixman */ - ximage.depth = surface->depth; - ximage.red_mask = surface->r_mask; - ximage.green_mask = surface->g_mask; - ximage.blue_mask = surface->b_mask; - ximage.xoffset = 0; - ximage.obdata = NULL; - - status = _cairo_xlib_display_acquire (surface->base.device, &display); - if (unlikely (status)) - return status; - - is_rgb_image = _pixman_format_to_masks (image->pixman_format, &image_masks); - - if (is_rgb_image && - (image_masks.alpha_mask == surface->a_mask || surface->a_mask == 0) && - (image_masks.red_mask == surface->r_mask || surface->r_mask == 0) && - (image_masks.green_mask == surface->g_mask || surface->g_mask == 0) && - (image_masks.blue_mask == surface->b_mask || surface->b_mask == 0)) - { - int ret; - - ximage.bits_per_pixel = image_masks.bpp; - ximage.bytes_per_line = image->stride; - ximage.data = (char *)image->data; - if (image->base.device != surface->base.device) { - /* If PutImage will break the image up into chunks, prefer to - * send it all in one pass with ShmPutImage. For larger images, - * it is further advantageous to reduce the number of copies, - * albeit at the expense of more SHM bookkeeping. - */ - int max_request_size = XExtendedMaxRequestSize (display->display); - if (max_request_size == 0) - max_request_size = XMaxRequestSize (display->display); - if (max_request_size > 8192) - max_request_size = 8192; - if (width * height * 4 > max_request_size) { - shm_image = _cairo_xlib_surface_create_shm__image (surface, - image->pixman_format, - width, height); - if (shm_image && shm_image->status == CAIRO_STATUS_SUCCESS) { - cairo_image_surface_t *clone = (cairo_image_surface_t *) shm_image; - pixman_image_composite32 (PIXMAN_OP_SRC, - image->pixman_image, NULL, clone->pixman_image, - src_x, src_y, - 0, 0, - 0, 0, - width, height); - ximage.obdata = _cairo_xlib_shm_surface_get_obdata (shm_image); - ximage.data = (char *)clone->data; - ximage.bytes_per_line = clone->stride; - ximage.width = width; - ximage.height = height; - src_x = src_y = 0; - } - } - } else - ximage.obdata = _cairo_xlib_shm_surface_get_obdata (&image->base); - - ret = XInitImage (&ximage); - assert (ret != 0); - } - else if (surface->visual == NULL || surface->visual->class == TrueColor) - { - pixman_format_code_t intermediate_format; - int ret; - - image_masks.alpha_mask = surface->a_mask; - image_masks.red_mask = surface->r_mask; - image_masks.green_mask = surface->g_mask; - image_masks.blue_mask = surface->b_mask; - image_masks.bpp = bits_per_pixel (surface); - ret = _pixman_format_from_masks (&image_masks, &intermediate_format); - assert (ret); - - shm_image = _cairo_xlib_surface_create_shm__image (surface, - intermediate_format, - width, height); - if (shm_image && shm_image->status == CAIRO_STATUS_SUCCESS) { - cairo_image_surface_t *clone = (cairo_image_surface_t *) shm_image; - - pixman_image_composite32 (PIXMAN_OP_SRC, - image->pixman_image, - NULL, - clone->pixman_image, - src_x, src_y, - 0, 0, - 0, 0, - width, height); - - ximage.data = (char *) clone->data; - ximage.obdata = _cairo_xlib_shm_surface_get_obdata (&clone->base); - ximage.bytes_per_line = clone->stride; - } else { - pixman_image = pixman_image_create_bits (intermediate_format, - width, height, NULL, 0); - if (pixman_image == NULL) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto BAIL; - } - - pixman_image_composite32 (PIXMAN_OP_SRC, - image->pixman_image, - NULL, - pixman_image, - src_x, src_y, - 0, 0, - 0, 0, - width, height); - - ximage.data = (char *) pixman_image_get_data (pixman_image); - ximage.bytes_per_line = pixman_image_get_stride (pixman_image); - } - - ximage.width = width; - ximage.height = height; - ximage.bits_per_pixel = image_masks.bpp; - - ret = XInitImage (&ximage); - assert (ret != 0); - - src_x = src_y = 0; - } - else - { - unsigned int stride, rowstride; - int x, y, x0, y0, x_off, y_off; - uint32_t in_pixel, out_pixel, *row; - int i_a_width=0, i_r_width=0, i_g_width=0, i_b_width=0; - int i_a_shift=0, i_r_shift=0, i_g_shift=0, i_b_shift=0; - int o_a_width=0, o_r_width=0, o_g_width=0, o_b_width=0; - int o_a_shift=0, o_r_shift=0, o_g_shift=0, o_b_shift=0; - cairo_xlib_visual_info_t *visual_info = NULL; - cairo_bool_t true_color; - int ret; - - ximage.bits_per_pixel = bits_per_pixel(surface); - stride = CAIRO_STRIDE_FOR_WIDTH_BPP (ximage.width, - ximage.bits_per_pixel); - ximage.bytes_per_line = stride; - ximage.data = _cairo_malloc_ab (stride, ximage.height); - if (unlikely (ximage.data == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto BAIL; - } - - own_data = TRUE; - - ret = XInitImage (&ximage); - assert (ret != 0); - - _characterize_field (image_masks.alpha_mask, &i_a_width, &i_a_shift); - _characterize_field (image_masks.red_mask , &i_r_width, &i_r_shift); - _characterize_field (image_masks.green_mask, &i_g_width, &i_g_shift); - _characterize_field (image_masks.blue_mask , &i_b_width, &i_b_shift); - - true_color = surface->visual == NULL || - surface->visual->class == TrueColor; - if (true_color) { - _characterize_field (surface->a_mask, &o_a_width, &o_a_shift); - _characterize_field (surface->r_mask, &o_r_width, &o_r_shift); - _characterize_field (surface->g_mask, &o_g_width, &o_g_shift); - _characterize_field (surface->b_mask, &o_b_width, &o_b_shift); - } else { - status = _cairo_xlib_screen_get_visual_info (display, - surface->screen, - surface->visual, - &visual_info); - if (unlikely (status)) - goto BAIL; - } - - rowstride = image->stride >> 2; - row = (uint32_t *) image->data; - x0 = dst_x + surface->base.device_transform.x0; - y0 = dst_y + surface->base.device_transform.y0; - for (y = 0, y_off = y0 % ARRAY_LENGTH (dither_pattern); - y < ximage.height; - y++, y_off = (y_off+1) % ARRAY_LENGTH (dither_pattern)) - { - const int8_t *dither_row = dither_pattern[y_off]; - - for (x = 0, x_off = x0 % ARRAY_LENGTH (dither_pattern[0]); - x < ximage.width; - x++, x_off = (x_off+1) % ARRAY_LENGTH (dither_pattern[0])) - { - int dither_adjustment = dither_row[x_off]; - int a, r, g, b; - - if (image_masks.bpp == 1) - in_pixel = !! (((uint8_t*)row)[x/8] & (1 << (x & 7))); - else if (image_masks.bpp <= 8) - in_pixel = ((uint8_t*)row)[x]; - else if (image_masks.bpp <= 16) - in_pixel = ((uint16_t*)row)[x]; - else if (image_masks.bpp <= 24) -#ifdef WORDS_BIGENDIAN - in_pixel = ((uint8_t*)row)[3 * x] << 16 | - ((uint8_t*)row)[3 * x + 1] << 8 | - ((uint8_t*)row)[3 * x + 2]; -#else - in_pixel = ((uint8_t*)row)[3 * x] | - ((uint8_t*)row)[3 * x + 1] << 8 | - ((uint8_t*)row)[3 * x + 2] << 16; -#endif - else - in_pixel = row[x]; - - /* If the incoming image has no alpha channel, then the input - * is opaque and the output should have the maximum alpha value. - * For all other channels, their absence implies 0. - */ - if (image_masks.alpha_mask == 0x0) - a = 0xff; - else - a = _field_to_8 (in_pixel & image_masks.alpha_mask, i_a_width, i_a_shift); - r = _field_to_8 (in_pixel & image_masks.red_mask , i_r_width, i_r_shift); - g = _field_to_8 (in_pixel & image_masks.green_mask, i_g_width, i_g_shift); - b = _field_to_8 (in_pixel & image_masks.blue_mask , i_b_width, i_b_shift); - - if (true_color) { - out_pixel = _field_from_8 (a, o_a_width, o_a_shift) | - _field_from_8_dither (r, o_r_width, o_r_shift, dither_adjustment) | - _field_from_8_dither (g, o_g_width, o_g_shift, dither_adjustment) | - _field_from_8_dither (b, o_b_width, o_b_shift, dither_adjustment); - } else { - out_pixel = _pseudocolor_from_rgb888_dither (visual_info, r, g, b, dither_adjustment); - } - - XPutPixel (&ximage, x, y, out_pixel); - } - - row += rowstride; - } - } - - status = _cairo_xlib_surface_get_gc (display, surface, &gc); - if (unlikely (status)) - goto BAIL; - - if (ximage.obdata) - XShmPutImage (display->display, surface->drawable, gc, &ximage, - src_x, src_y, dst_x, dst_y, width, height, True); - else - XPutImage (display->display, surface->drawable, gc, &ximage, - src_x, src_y, dst_x, dst_y, width, height); - - _cairo_xlib_surface_put_gc (display, surface, gc); - - BAIL: - cairo_device_release (&display->base); - - if (own_data) - free (ximage.data); - if (shm_image) - cairo_surface_destroy (shm_image); - if (pixman_image) - pixman_image_unref (pixman_image); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_surface_t * -_cairo_xlib_surface_source(void *abstract_surface, - cairo_rectangle_int_t *extents) -{ - cairo_xlib_surface_t *surface = abstract_surface; - - if (extents) { - extents->x = extents->y = 0; - extents->width = surface->width; - extents->height = surface->height; - } - - return &surface->base; -} - -static cairo_status_t -_cairo_xlib_surface_acquire_source_image (void *abstract_surface, - cairo_image_surface_t **image_out, - void **image_extra) -{ - cairo_xlib_surface_t *surface = abstract_surface; - cairo_rectangle_int_t extents; - - *image_extra = NULL; - *image_out = (cairo_image_surface_t *) - _cairo_xlib_surface_get_shm (abstract_surface, FALSE); - if (*image_out) - return (*image_out)->base.status; - - extents.x = extents.y = 0; - extents.width = surface->width; - extents.height = surface->height; - - *image_out = (cairo_image_surface_t*) - _get_image_surface (surface, &extents, TRUE); - return (*image_out)->base.status; -} - -static cairo_surface_t * -_cairo_xlib_surface_snapshot (void *abstract_surface) -{ - cairo_xlib_surface_t *surface = abstract_surface; - cairo_rectangle_int_t extents; - - extents.x = extents.y = 0; - extents.width = surface->width; - extents.height = surface->height; - - return _get_image_surface (surface, &extents, FALSE); -} - -static void -_cairo_xlib_surface_release_source_image (void *abstract_surface, - cairo_image_surface_t *image, - void *image_extra) -{ - cairo_xlib_surface_t *surface = abstract_surface; - - if (&image->base == surface->shm) - return; - - cairo_surface_destroy (&image->base); -} - -static cairo_image_surface_t * -_cairo_xlib_surface_map_to_image (void *abstract_surface, - const cairo_rectangle_int_t *extents) -{ - cairo_xlib_surface_t *surface = abstract_surface; - cairo_surface_t *image; - - image = _cairo_xlib_surface_get_shm (abstract_surface, FALSE); - if (image) { - assert (surface->base.damage); - surface->fallback++; - return _cairo_image_surface_map_to_image (image, extents); - } - - image = _get_image_surface (abstract_surface, extents, TRUE); - cairo_surface_set_device_offset (image, -extents->x, -extents->y); - - return (cairo_image_surface_t *) image; -} - -static cairo_int_status_t -_cairo_xlib_surface_unmap_image (void *abstract_surface, - cairo_image_surface_t *image) -{ - cairo_xlib_surface_t *surface = abstract_surface; - cairo_int_status_t status; - - if (surface->shm) { - cairo_rectangle_int_t r; - - assert (surface->fallback); - assert (surface->base.damage); - - r.x = image->base.device_transform_inverse.x0; - r.y = image->base.device_transform_inverse.y0; - r.width = image->width; - r.height = image->height; - - TRACE ((stderr, "%s: adding damage (%d,%d)x(%d,%d)\n", - __FUNCTION__, r.x, r.y, r.width, r.height)); - surface->shm->damage = - _cairo_damage_add_rectangle (surface->shm->damage, &r); - - return _cairo_image_surface_unmap_image (surface->shm, image); - } - - status = _cairo_xlib_surface_draw_image (abstract_surface, image, - 0, 0, - image->width, image->height, - image->base.device_transform_inverse.x0, - image->base.device_transform_inverse.y0); - - cairo_surface_finish (&image->base); - cairo_surface_destroy (&image->base); - - return status; -} - -static cairo_status_t -_cairo_xlib_surface_flush (void *abstract_surface, - unsigned flags) -{ - cairo_xlib_surface_t *surface = abstract_surface; - cairo_int_status_t status; - - if (flags) - return CAIRO_STATUS_SUCCESS; - - status = _cairo_xlib_surface_put_shm (surface); - if (unlikely (status)) - return status; - - surface->fallback >>= 1; - if (surface->shm && _cairo_xlib_shm_surface_is_idle (surface->shm)) - _cairo_xlib_surface_discard_shm (surface); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_bool_t -_cairo_xlib_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *rectangle) -{ - cairo_xlib_surface_t *surface = abstract_surface; - - rectangle->x = 0; - rectangle->y = 0; - - rectangle->width = surface->width; - rectangle->height = surface->height; - - return TRUE; -} - -static void -_cairo_xlib_surface_get_font_options (void *abstract_surface, - cairo_font_options_t *options) -{ - cairo_xlib_surface_t *surface = abstract_surface; - - *options = *_cairo_xlib_screen_get_font_options (surface->screen); -} - -static inline cairo_int_status_t -get_compositor (cairo_xlib_surface_t **surface, - const cairo_compositor_t **compositor) -{ - cairo_xlib_surface_t *s = *surface; - cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;; - - if (s->fallback) { - assert (s->base.damage != NULL); - assert (s->shm != NULL); - assert (s->shm->damage != NULL); - if (! _cairo_xlib_shm_surface_is_active (s->shm)) { - *surface = (cairo_xlib_surface_t *) s->shm; - *compositor = ((cairo_image_surface_t *) s->shm)->compositor; - s->fallback++; - } else { - status = _cairo_xlib_surface_put_shm (s); - s->fallback = 0; - *compositor = s->compositor; - } - } else - *compositor = s->compositor; - - return status; -} - -static cairo_int_status_t -_cairo_xlib_surface_paint (void *_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - cairo_xlib_surface_t *surface = _surface; - const cairo_compositor_t *compositor; - cairo_int_status_t status; - - status = get_compositor (&surface, &compositor); - if (unlikely (status)) - return status; - - return _cairo_compositor_paint (compositor, &surface->base, - op, source, - clip); -} - -static cairo_int_status_t -_cairo_xlib_surface_mask (void *_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - cairo_xlib_surface_t *surface = _surface; - const cairo_compositor_t *compositor; - cairo_int_status_t status; - - status = get_compositor (&surface, &compositor); - if (unlikely (status)) - return status; - - return _cairo_compositor_mask (compositor, &surface->base, - op, source, mask, - clip); -} - -static cairo_int_status_t -_cairo_xlib_surface_stroke (void *_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_xlib_surface_t *surface = _surface; - const cairo_compositor_t *compositor; - cairo_int_status_t status; - - status = get_compositor (&surface, &compositor); - if (unlikely (status)) - return status; - - return _cairo_compositor_stroke (compositor, &surface->base, - op, source, - path, style, ctm, ctm_inverse, - tolerance, antialias, - clip); -} - -static cairo_int_status_t -_cairo_xlib_surface_fill (void *_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_xlib_surface_t *surface = _surface; - const cairo_compositor_t *compositor; - cairo_int_status_t status; - - status = get_compositor (&surface, &compositor); - if (unlikely (status)) - return status; - - return _cairo_compositor_fill (compositor, &surface->base, - op, source, - path, fill_rule, tolerance, antialias, - clip); -} - -static cairo_int_status_t -_cairo_xlib_surface_glyphs (void *_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - cairo_xlib_surface_t *surface = _surface; - const cairo_compositor_t *compositor; - cairo_int_status_t status; - - status = get_compositor (&surface, &compositor); - if (unlikely (status)) - return status; - - return _cairo_compositor_glyphs (compositor, &surface->base, - op, source, - glyphs, num_glyphs, scaled_font, - clip); -} - -static const cairo_surface_backend_t cairo_xlib_surface_backend = { - CAIRO_SURFACE_TYPE_XLIB, - _cairo_xlib_surface_finish, - - _cairo_default_context_create, - - _cairo_xlib_surface_create_similar, - _cairo_xlib_surface_create_similar_shm, - _cairo_xlib_surface_map_to_image, - _cairo_xlib_surface_unmap_image, - - _cairo_xlib_surface_source, - _cairo_xlib_surface_acquire_source_image, - _cairo_xlib_surface_release_source_image, - _cairo_xlib_surface_snapshot, - - NULL, /* copy_page */ - NULL, /* show_page */ - - _cairo_xlib_surface_get_extents, - _cairo_xlib_surface_get_font_options, - - _cairo_xlib_surface_flush, - NULL, /* mark_dirty_rectangle */ - - _cairo_xlib_surface_paint, - _cairo_xlib_surface_mask, - _cairo_xlib_surface_stroke, - _cairo_xlib_surface_fill, - NULL, /* fill-stroke */ - _cairo_xlib_surface_glyphs, -}; - -/** - * _cairo_surface_is_xlib: - * @surface: a #cairo_surface_t - * - * Checks if a surface is a #cairo_xlib_surface_t - * - * Return value: True if the surface is an xlib surface - **/ -static cairo_bool_t -_cairo_surface_is_xlib (cairo_surface_t *surface) -{ - return surface->backend == &cairo_xlib_surface_backend; -} - -static cairo_surface_t * -_cairo_xlib_surface_create_internal (cairo_xlib_screen_t *screen, - Drawable drawable, - Visual *visual, - XRenderPictFormat *xrender_format, - int width, - int height, - int depth) -{ - cairo_xlib_surface_t *surface; - cairo_xlib_display_t *display; - cairo_status_t status; - - if (depth == 0) { - if (xrender_format) { - depth = xrender_format->depth; - - /* XXX find matching visual for core/dithering fallbacks? */ - } else if (visual) { - Screen *scr = screen->screen; - - if (visual == DefaultVisualOfScreen (scr)) { - depth = DefaultDepthOfScreen (scr); - } else { - int j, k; - - /* This is ugly, but we have to walk over all visuals - * for the display to find the correct depth. - */ - depth = 0; - for (j = 0; j < scr->ndepths; j++) { - Depth *d = &scr->depths[j]; - for (k = 0; k < d->nvisuals; k++) { - if (&d->visuals[k] == visual) { - depth = d->depth; - goto found; - } - } - } - } - } - - if (depth == 0) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL)); - -found: - ; - } - - surface = malloc (sizeof (cairo_xlib_surface_t)); - if (unlikely (surface == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - status = _cairo_xlib_display_acquire (screen->device, &display); - if (unlikely (status)) { - free (surface); - return _cairo_surface_create_in_error (_cairo_error (status)); - } - - surface->display = display; - if (CAIRO_RENDER_HAS_CREATE_PICTURE (display)) { - if (!xrender_format) { - if (visual) { - xrender_format = XRenderFindVisualFormat (display->display, visual); - } else if (depth == 1) { - xrender_format = - _cairo_xlib_display_get_xrender_format (display, - CAIRO_FORMAT_A1); - } - } - } - - cairo_device_release (&display->base); - - _cairo_surface_init (&surface->base, - &cairo_xlib_surface_backend, - screen->device, - _xrender_format_to_content (xrender_format)); - - surface->screen = screen; - surface->compositor = display->compositor; - surface->shm = NULL; - surface->fallback = 0; - - surface->drawable = drawable; - surface->owns_pixmap = FALSE; - surface->use_pixmap = 0; - surface->width = width; - surface->height = height; - - surface->picture = None; - surface->precision = PolyModePrecise; - - surface->embedded_source.picture = None; - - surface->visual = visual; - surface->xrender_format = xrender_format; - surface->depth = depth; - - /* - * Compute the pixel format masks from either a XrenderFormat or - * else from a visual; failing that we assume the drawable is an - * alpha-only pixmap as it could only have been created that way - * through the cairo_xlib_surface_create_for_bitmap function. - */ - if (xrender_format) { - surface->a_mask = (unsigned long) - surface->xrender_format->direct.alphaMask - << surface->xrender_format->direct.alpha; - surface->r_mask = (unsigned long) - surface->xrender_format->direct.redMask - << surface->xrender_format->direct.red; - surface->g_mask = (unsigned long) - surface->xrender_format->direct.greenMask - << surface->xrender_format->direct.green; - surface->b_mask = (unsigned long) - surface->xrender_format->direct.blueMask - << surface->xrender_format->direct.blue; - } else if (visual) { - surface->a_mask = 0; - surface->r_mask = visual->red_mask; - surface->g_mask = visual->green_mask; - surface->b_mask = visual->blue_mask; - } else { - if (depth < 32) - surface->a_mask = (1 << depth) - 1; - else - surface->a_mask = 0xffffffff; - surface->r_mask = 0; - surface->g_mask = 0; - surface->b_mask = 0; - } - - cairo_list_add (&surface->link, &screen->surfaces); - - return &surface->base; -} - -static Screen * -_cairo_xlib_screen_from_visual (Display *dpy, Visual *visual) -{ - int s, d, v; - - for (s = 0; s < ScreenCount (dpy); s++) { - Screen *screen; - - screen = ScreenOfDisplay (dpy, s); - if (visual == DefaultVisualOfScreen (screen)) - return screen; - - for (d = 0; d < screen->ndepths; d++) { - Depth *depth; - - depth = &screen->depths[d]; - for (v = 0; v < depth->nvisuals; v++) - if (visual == &depth->visuals[v]) - return screen; - } - } - - return NULL; -} - -static cairo_bool_t valid_size (int width, int height) -{ - /* Note: the minimum surface size allowed in the X protocol is 1x1. - * However, as we historically did not check the minimum size we - * allowed applications to lie and set the correct size later (one hopes). - * To preserve compatability we must allow applications to use - * 0x0 surfaces. - */ - return (width >= 0 && width <= XLIB_COORD_MAX && - height >= 0 && height <= XLIB_COORD_MAX); -} - -/** - * cairo_xlib_surface_create: - * @dpy: an X Display - * @drawable: an X Drawable, (a Pixmap or a Window) - * @visual: the visual to use for drawing to @drawable. The depth - * of the visual must match the depth of the drawable. - * Currently, only TrueColor visuals are fully supported. - * @width: the current width of @drawable. - * @height: the current height of @drawable. - * - * Creates an Xlib surface that draws to the given drawable. - * The way that colors are represented in the drawable is specified - * by the provided visual. - * - * Note: If @drawable is a Window, then the function - * cairo_xlib_surface_set_size() must be called whenever the size of the - * window changes. - * - * When @drawable is a Window containing child windows then drawing to - * the created surface will be clipped by those child windows. When - * the created surface is used as a source, the contents of the - * children will be included. - * - * Return value: the newly created surface - * - * Since: 1.0 - **/ -cairo_surface_t * -cairo_xlib_surface_create (Display *dpy, - Drawable drawable, - Visual *visual, - int width, - int height) -{ - Screen *scr; - cairo_xlib_screen_t *screen; - cairo_status_t status; - - if (! valid_size (width, height)) { - /* you're lying, and you know it! */ - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE)); - } - - scr = _cairo_xlib_screen_from_visual (dpy, visual); - if (scr == NULL) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL)); - - status = _cairo_xlib_screen_get (dpy, scr, &screen); - if (unlikely (status)) - return _cairo_surface_create_in_error (status); - - X_DEBUG ((dpy, "create (drawable=%x)", (unsigned int) drawable)); - - return _cairo_xlib_surface_create_internal (screen, drawable, - visual, NULL, - width, height, 0); -} - -/** - * cairo_xlib_surface_create_for_bitmap: - * @dpy: an X Display - * @bitmap: an X Drawable, (a depth-1 Pixmap) - * @screen: the X Screen associated with @bitmap - * @width: the current width of @bitmap. - * @height: the current height of @bitmap. - * - * Creates an Xlib surface that draws to the given bitmap. - * This will be drawn to as a %CAIRO_FORMAT_A1 object. - * - * Return value: the newly created surface - * - * Since: 1.0 - **/ -cairo_surface_t * -cairo_xlib_surface_create_for_bitmap (Display *dpy, - Pixmap bitmap, - Screen *scr, - int width, - int height) -{ - cairo_xlib_screen_t *screen; - cairo_status_t status; - - if (! valid_size (width, height)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE)); - - status = _cairo_xlib_screen_get (dpy, scr, &screen); - if (unlikely (status)) - return _cairo_surface_create_in_error (status); - - X_DEBUG ((dpy, "create_for_bitmap (drawable=%x)", (unsigned int) bitmap)); - - return _cairo_xlib_surface_create_internal (screen, bitmap, - NULL, NULL, - width, height, 1); -} - -#if CAIRO_HAS_XLIB_XRENDER_SURFACE -/** - * cairo_xlib_surface_create_with_xrender_format: - * @dpy: an X Display - * @drawable: an X Drawable, (a Pixmap or a Window) - * @screen: the X Screen associated with @drawable - * @format: the picture format to use for drawing to @drawable. The depth - * of @format must match the depth of the drawable. - * @width: the current width of @drawable. - * @height: the current height of @drawable. - * - * Creates an Xlib surface that draws to the given drawable. - * The way that colors are represented in the drawable is specified - * by the provided picture format. - * - * Note: If @drawable is a Window, then the function - * cairo_xlib_surface_set_size() must be called whenever the size of the - * window changes. - * - * Return value: the newly created surface - * - * Since: 1.0 - **/ -cairo_surface_t * -cairo_xlib_surface_create_with_xrender_format (Display *dpy, - Drawable drawable, - Screen *scr, - XRenderPictFormat *format, - int width, - int height) -{ - cairo_xlib_screen_t *screen; - cairo_status_t status; - - if (! valid_size (width, height)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE)); - - status = _cairo_xlib_screen_get (dpy, scr, &screen); - if (unlikely (status)) - return _cairo_surface_create_in_error (status); - - X_DEBUG ((dpy, "create_with_xrender_format (drawable=%x)", (unsigned int) drawable)); - - return _cairo_xlib_surface_create_internal (screen, drawable, - _visual_for_xrender_format (scr, format), - format, width, height, 0); -} - -/** - * cairo_xlib_surface_get_xrender_format: - * @surface: an xlib surface - * - * Gets the X Render picture format that @surface uses for rendering with the - * X Render extension. If the surface was created by - * cairo_xlib_surface_create_with_xrender_format() originally, the return - * value is the format passed to that constructor. - * - * Return value: the XRenderPictFormat* associated with @surface, - * or %NULL if the surface is not an xlib surface - * or if the X Render extension is not available. - * - * Since: 1.6 - **/ -XRenderPictFormat * -cairo_xlib_surface_get_xrender_format (cairo_surface_t *surface) -{ - cairo_xlib_surface_t *xlib_surface = (cairo_xlib_surface_t *) surface; - - /* Throw an error for a non-xlib surface */ - if (! _cairo_surface_is_xlib (surface)) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return NULL; - } - - return xlib_surface->xrender_format; -} -#endif - -/** - * cairo_xlib_surface_set_size: - * @surface: a #cairo_surface_t for the XLib backend - * @width: the new width of the surface - * @height: the new height of the surface - * - * Informs cairo of the new size of the X Drawable underlying the - * surface. For a surface created for a Window (rather than a Pixmap), - * this function must be called each time the size of the window - * changes. (For a subwindow, you are normally resizing the window - * yourself, but for a toplevel window, it is necessary to listen for - * ConfigureNotify events.) - * - * A Pixmap can never change size, so it is never necessary to call - * this function on a surface created for a Pixmap. - * - * Since: 1.0 - **/ -void -cairo_xlib_surface_set_size (cairo_surface_t *abstract_surface, - int width, - int height) -{ - cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface; - cairo_status_t status; - - if (unlikely (abstract_surface->status)) - return; - if (unlikely (abstract_surface->finished)) { - _cairo_surface_set_error (abstract_surface, - _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - return; - } - - if (! _cairo_surface_is_xlib (abstract_surface)) { - _cairo_surface_set_error (abstract_surface, - _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH)); - return; - } - - if (surface->width == width && surface->height == height) - return; - - if (! valid_size (width, height)) { - _cairo_surface_set_error (abstract_surface, - _cairo_error (CAIRO_STATUS_INVALID_SIZE)); - return; - } - - status = _cairo_surface_flush (abstract_surface, 0); - if (unlikely (status)) { - _cairo_surface_set_error (abstract_surface, status); - return; - } - - _cairo_xlib_surface_discard_shm (surface); - - surface->width = width; - surface->height = height; -} - -/** - * cairo_xlib_surface_set_drawable: - * @surface: a #cairo_surface_t for the XLib backend - * @drawable: the new drawable for the surface - * @width: the width of the new drawable - * @height: the height of the new drawable - * - * Informs cairo of a new X Drawable underlying the - * surface. The drawable must match the display, screen - * and format of the existing drawable or the application - * will get X protocol errors and will probably terminate. - * No checks are done by this function to ensure this - * compatibility. - * - * Since: 1.0 - **/ -void -cairo_xlib_surface_set_drawable (cairo_surface_t *abstract_surface, - Drawable drawable, - int width, - int height) -{ - cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *)abstract_surface; - cairo_status_t status; - - if (unlikely (abstract_surface->status)) - return; - if (unlikely (abstract_surface->finished)) { - status = _cairo_surface_set_error (abstract_surface, - _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - return; - } - - if (! _cairo_surface_is_xlib (abstract_surface)) { - status = _cairo_surface_set_error (abstract_surface, - _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH)); - return; - } - - if (! valid_size (width, height)) { - status = _cairo_surface_set_error (abstract_surface, - _cairo_error (CAIRO_STATUS_INVALID_SIZE)); - return; - } - - /* XXX: and what about this case? */ - if (surface->owns_pixmap) - return; - - status = _cairo_surface_flush (abstract_surface, 0); - if (unlikely (status)) { - _cairo_surface_set_error (abstract_surface, status); - return; - } - - if (surface->drawable != drawable) { - cairo_xlib_display_t *display; - - status = _cairo_xlib_display_acquire (surface->base.device, &display); - if (unlikely (status)) - return; - - X_DEBUG ((display->display, "set_drawable (drawable=%x)", (unsigned int) drawable)); - - if (surface->picture != None) { - XRenderFreePicture (display->display, surface->picture); - if (unlikely (status)) { - status = _cairo_surface_set_error (&surface->base, status); - return; - } - - surface->picture = None; - } - - cairo_device_release (&display->base); - - surface->drawable = drawable; - } - - if (surface->width != width || surface->height != height) { - _cairo_xlib_surface_discard_shm (surface); - - surface->width = width; - surface->height = height; - } -} - -/** - * cairo_xlib_surface_get_display: - * @surface: a #cairo_xlib_surface_t - * - * Get the X Display for the underlying X Drawable. - * - * Return value: the display. - * - * Since: 1.2 - **/ -Display * -cairo_xlib_surface_get_display (cairo_surface_t *abstract_surface) -{ - if (! _cairo_surface_is_xlib (abstract_surface)) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return NULL; - } - - return ((cairo_xlib_display_t *) abstract_surface->device)->display; -} - -/** - * cairo_xlib_surface_get_drawable: - * @surface: a #cairo_xlib_surface_t - * - * Get the underlying X Drawable used for the surface. - * - * Return value: the drawable. - * - * Since: 1.2 - **/ -Drawable -cairo_xlib_surface_get_drawable (cairo_surface_t *abstract_surface) -{ - cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface; - - if (! _cairo_surface_is_xlib (abstract_surface)) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return 0; - } - - return surface->drawable; -} - -/** - * cairo_xlib_surface_get_screen: - * @surface: a #cairo_xlib_surface_t - * - * Get the X Screen for the underlying X Drawable. - * - * Return value: the screen. - * - * Since: 1.2 - **/ -Screen * -cairo_xlib_surface_get_screen (cairo_surface_t *abstract_surface) -{ - cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface; - - if (! _cairo_surface_is_xlib (abstract_surface)) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return NULL; - } - - return surface->screen->screen; -} - -/** - * cairo_xlib_surface_get_visual: - * @surface: a #cairo_xlib_surface_t - * - * Gets the X Visual associated with @surface, suitable for use with the - * underlying X Drawable. If @surface was created by - * cairo_xlib_surface_create(), the return value is the Visual passed to that - * constructor. - * - * Return value: the Visual or %NULL if there is no appropriate Visual for - * @surface. - * - * Since: 1.2 - **/ -Visual * -cairo_xlib_surface_get_visual (cairo_surface_t *surface) -{ - cairo_xlib_surface_t *xlib_surface = (cairo_xlib_surface_t *) surface; - - if (! _cairo_surface_is_xlib (surface)) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return NULL; - } - - return xlib_surface->visual; -} - -/** - * cairo_xlib_surface_get_depth: - * @surface: a #cairo_xlib_surface_t - * - * Get the number of bits used to represent each pixel value. - * - * Return value: the depth of the surface in bits. - * - * Since: 1.2 - **/ -int -cairo_xlib_surface_get_depth (cairo_surface_t *abstract_surface) -{ - cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface; - - if (! _cairo_surface_is_xlib (abstract_surface)) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return 0; - } - - return surface->depth; -} - -/** - * cairo_xlib_surface_get_width: - * @surface: a #cairo_xlib_surface_t - * - * Get the width of the X Drawable underlying the surface in pixels. - * - * Return value: the width of the surface in pixels. - * - * Since: 1.2 - **/ -int -cairo_xlib_surface_get_width (cairo_surface_t *abstract_surface) -{ - cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface; - - if (! _cairo_surface_is_xlib (abstract_surface)) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return 0; - } - - return surface->width; -} - -/** - * cairo_xlib_surface_get_height: - * @surface: a #cairo_xlib_surface_t - * - * Get the height of the X Drawable underlying the surface in pixels. - * - * Return value: the height of the surface in pixels. - * - * Since: 1.2 - **/ -int -cairo_xlib_surface_get_height (cairo_surface_t *abstract_surface) -{ - cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface; - - if (! _cairo_surface_is_xlib (abstract_surface)) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return 0; - } - - return surface->height; -} - -#endif /* !CAIRO_HAS_XLIB_XCB_FUNCTIONS */ diff --git a/source/libs/cairo/cairo-src/src/cairo-xlib-visual.c b/source/libs/cairo/cairo-src/src/cairo-xlib-visual.c deleted file mode 100644 index 863822eebbded0734fa8c24145bd7a9938781cd8..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xlib-visual.c +++ /dev/null @@ -1,194 +0,0 @@ -/* Cairo - a vector graphics library with display and print output - * - * Copyright © 2008 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - */ - -#include "cairoint.h" - -#if !CAIRO_HAS_XLIB_XCB_FUNCTIONS - -#include "cairo-xlib-private.h" - -#include "cairo-error-private.h" -#include "cairo-list-inline.h" - -/* A perceptual distance metric between two colors. No sqrt needed - * since the square of the distance is still a valid metric. */ - -/* XXX: This is currently using linear distance in RGB space which is - * decidedly not perceptually linear. If someone cared a lot about the - * quality, they might choose something else here. Then again, they - * might also choose not to use a PseudoColor visual... */ -static inline int -_color_distance (unsigned short r1, unsigned short g1, unsigned short b1, - unsigned short r2, unsigned short g2, unsigned short b2) -{ - r1 >>= 8; g1 >>= 8; b1 >>= 8; - r2 >>= 8; g2 >>= 8; b2 >>= 8; - - return ((r2 - r1) * (r2 - r1) + - (g2 - g1) * (g2 - g1) + - (b2 - b1) * (b2 - b1)); -} - -cairo_status_t -_cairo_xlib_visual_info_create (Display *dpy, - int screen, - VisualID visualid, - cairo_xlib_visual_info_t **out) -{ - cairo_xlib_visual_info_t *info; - Colormap colormap = DefaultColormap (dpy, screen); - XColor color; - int gray, red, green, blue; - int i, j, distance, min_distance = 0; - XColor colors[256]; - unsigned short cube_index_to_short[CUBE_SIZE]; - unsigned short ramp_index_to_short[RAMP_SIZE]; - unsigned char gray_to_pseudocolor[RAMP_SIZE]; - - for (i = 0; i < CUBE_SIZE; i++) - cube_index_to_short[i] = (0xffff * i + ((CUBE_SIZE-1)>>1)) / (CUBE_SIZE-1); - for (i = 0; i < RAMP_SIZE; i++) - ramp_index_to_short[i] = (0xffff * i + ((RAMP_SIZE-1)>>1)) / (RAMP_SIZE-1); - - info = malloc (sizeof (cairo_xlib_visual_info_t)); - if (unlikely (info == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - cairo_list_init (&info->link); - info->visualid = visualid; - - /* Allocate a gray ramp and a color cube. - * Give up as soon as failures start. */ - - for (gray = 0; gray < RAMP_SIZE; gray++) { - color.red = color.green = color.blue = ramp_index_to_short[gray]; - if (! XAllocColor (dpy, colormap, &color)) - goto DONE_ALLOCATE; - } - - /* XXX: Could do this in a more clever order to have the best - * possible results from early failure. Could also choose a cube - * uniformly distributed in a better space than RGB. */ - for (red = 0; red < CUBE_SIZE; red++) { - for (green = 0; green < CUBE_SIZE; green++) { - for (blue = 0; blue < CUBE_SIZE; blue++) { - color.red = cube_index_to_short[red]; - color.green = cube_index_to_short[green]; - color.blue = cube_index_to_short[blue]; - color.pixel = 0; - color.flags = 0; - color.pad = 0; - if (! XAllocColor (dpy, colormap, &color)) - goto DONE_ALLOCATE; - } - } - } - DONE_ALLOCATE: - - for (i = 0; i < ARRAY_LENGTH (colors); i++) - colors[i].pixel = i; - XQueryColors (dpy, colormap, colors, ARRAY_LENGTH (colors)); - - /* Search for nearest colors within allocated colormap. */ - for (gray = 0; gray < RAMP_SIZE; gray++) { - for (i = 0; i < 256; i++) { - distance = _color_distance (ramp_index_to_short[gray], - ramp_index_to_short[gray], - ramp_index_to_short[gray], - colors[i].red, - colors[i].green, - colors[i].blue); - if (i == 0 || distance < min_distance) { - gray_to_pseudocolor[gray] = colors[i].pixel; - min_distance = distance; - if (!min_distance) - break; - } - } - } - for (red = 0; red < CUBE_SIZE; red++) { - for (green = 0; green < CUBE_SIZE; green++) { - for (blue = 0; blue < CUBE_SIZE; blue++) { - for (i = 0; i < 256; i++) { - distance = _color_distance (cube_index_to_short[red], - cube_index_to_short[green], - cube_index_to_short[blue], - colors[i].red, - colors[i].green, - colors[i].blue); - if (i == 0 || distance < min_distance) { - info->cube_to_pseudocolor[red][green][blue] = colors[i].pixel; - min_distance = distance; - if (!min_distance) - break; - } - } - } - } - } - - for (i = 0, j = 0; i < 256; i++) { - if (j < CUBE_SIZE - 1 && (((i<<8)+i) - (int)cube_index_to_short[j]) > ((int)cube_index_to_short[j+1] - ((i<<8)+i))) - j++; - info->field8_to_cube[i] = j; - - info->dither8_to_cube[i] = ((int)i - 128) / (CUBE_SIZE - 1); - } - for (i = 0, j = 0; i < 256; i++) { - if (j < RAMP_SIZE - 1 && (((i<<8)+i) - (int)ramp_index_to_short[j]) > ((int)ramp_index_to_short[j+1] - ((i<<8)+i))) - j++; - info->gray8_to_pseudocolor[i] = gray_to_pseudocolor[j]; - } - - for (i = 0; i < 256; i++) { - info->colors[i].a = 0xff; - info->colors[i].r = colors[i].red >> 8; - info->colors[i].g = colors[i].green >> 8; - info->colors[i].b = colors[i].blue >> 8; - } - - *out = info; - return CAIRO_STATUS_SUCCESS; -} - -void -_cairo_xlib_visual_info_destroy (cairo_xlib_visual_info_t *info) -{ - /* No need for XFreeColors() whilst using DefaultColormap */ - _cairo_list_del (&info->link); - free (info); -} - -#endif /* !CAIRO_HAS_XLIB_XCB_FUNCTIONS */ diff --git a/source/libs/cairo/cairo-src/src/cairo-xlib-xcb-surface.c b/source/libs/cairo/cairo-src/src/cairo-xlib-xcb-surface.c deleted file mode 100644 index af3e15578992900f445a1590bb6ae19e6d5a0e98..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xlib-xcb-surface.c +++ /dev/null @@ -1,847 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2009 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#if CAIRO_HAS_XLIB_XCB_FUNCTIONS - -#include "cairo-xlib.h" -#include "cairo-xcb.h" - -#include "cairo-xcb-private.h" -#include "cairo-xlib-xrender-private.h" - -#include "cairo-default-context-private.h" -#include "cairo-list-inline.h" -#include "cairo-image-surface-private.h" -#include "cairo-surface-backend-private.h" - -#include <X11/Xlib-xcb.h> -#include <X11/Xlibint.h> /* For XESetCloseDisplay */ - -struct cairo_xlib_xcb_display_t { - cairo_device_t base; - - Display *dpy; - cairo_device_t *xcb_device; - XExtCodes *codes; - - cairo_list_t link; -}; -typedef struct cairo_xlib_xcb_display_t cairo_xlib_xcb_display_t; - -/* List of all #cairo_xlib_xcb_display_t alive, - * protected by _cairo_xlib_display_mutex */ -static cairo_list_t displays; - -static cairo_surface_t * -_cairo_xlib_xcb_surface_create (void *dpy, - void *scr, - void *visual, - void *format, - cairo_surface_t *xcb); - -static cairo_surface_t * -_cairo_xlib_xcb_surface_create_similar (void *abstract_other, - cairo_content_t content, - int width, - int height) -{ - cairo_xlib_xcb_surface_t *other = abstract_other; - cairo_surface_t *xcb; - - xcb = other->xcb->base.backend->create_similar (other->xcb, content, width, height); - if (unlikely (xcb == NULL || xcb->status)) - return xcb; - - return _cairo_xlib_xcb_surface_create (other->display, other->screen, NULL, NULL, xcb); -} - -static cairo_status_t -_cairo_xlib_xcb_surface_finish (void *abstract_surface) -{ - cairo_xlib_xcb_surface_t *surface = abstract_surface; - cairo_status_t status; - - cairo_surface_finish (&surface->xcb->base); - status = surface->xcb->base.status; - cairo_surface_destroy (&surface->xcb->base); - surface->xcb = NULL; - - return status; -} - -static cairo_surface_t * -_cairo_xlib_xcb_surface_create_similar_image (void *abstract_other, - cairo_format_t format, - int width, - int height) -{ - cairo_xlib_xcb_surface_t *surface = abstract_other; - return cairo_surface_create_similar_image (&surface->xcb->base, format, width, height); -} - -static cairo_image_surface_t * -_cairo_xlib_xcb_surface_map_to_image (void *abstract_surface, - const cairo_rectangle_int_t *extents) -{ - cairo_xlib_xcb_surface_t *surface = abstract_surface; - return _cairo_surface_map_to_image (&surface->xcb->base, extents); -} - -static cairo_int_status_t -_cairo_xlib_xcb_surface_unmap (void *abstract_surface, - cairo_image_surface_t *image) -{ - cairo_xlib_xcb_surface_t *surface = abstract_surface; - return _cairo_surface_unmap_image (&surface->xcb->base, image); -} - -static cairo_surface_t * -_cairo_xlib_xcb_surface_source (void *abstract_surface, - cairo_rectangle_int_t *extents) -{ - cairo_xlib_xcb_surface_t *surface = abstract_surface; - return _cairo_surface_get_source (&surface->xcb->base, extents); -} - -static cairo_status_t -_cairo_xlib_xcb_surface_acquire_source_image (void *abstract_surface, - cairo_image_surface_t **image_out, - void **image_extra) -{ - cairo_xlib_xcb_surface_t *surface = abstract_surface; - return _cairo_surface_acquire_source_image (&surface->xcb->base, - image_out, image_extra); -} - -static void -_cairo_xlib_xcb_surface_release_source_image (void *abstract_surface, - cairo_image_surface_t *image_out, - void *image_extra) -{ - cairo_xlib_xcb_surface_t *surface = abstract_surface; - _cairo_surface_release_source_image (&surface->xcb->base, image_out, image_extra); -} - -static cairo_bool_t -_cairo_xlib_xcb_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *extents) -{ - cairo_xlib_xcb_surface_t *surface = abstract_surface; - return _cairo_surface_get_extents (&surface->xcb->base, extents); -} - -static void -_cairo_xlib_xcb_surface_get_font_options (void *abstract_surface, - cairo_font_options_t *options) -{ - cairo_xlib_xcb_surface_t *surface = abstract_surface; - cairo_surface_get_font_options (&surface->xcb->base, options); -} - -static cairo_int_status_t -_cairo_xlib_xcb_surface_paint (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - cairo_xlib_xcb_surface_t *surface = abstract_surface; - return _cairo_surface_paint (&surface->xcb->base, op, source, clip); -} - -static cairo_int_status_t -_cairo_xlib_xcb_surface_mask (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - cairo_xlib_xcb_surface_t *surface = abstract_surface; - return _cairo_surface_mask (&surface->xcb->base, op, source, mask, clip); -} - -static cairo_int_status_t -_cairo_xlib_xcb_surface_stroke (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_xlib_xcb_surface_t *surface = abstract_surface; - return _cairo_surface_stroke (&surface->xcb->base, - op, source, path, style, ctm, ctm_inverse, - tolerance, antialias, clip); -} - -static cairo_int_status_t -_cairo_xlib_xcb_surface_fill (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_xlib_xcb_surface_t *surface = abstract_surface; - return _cairo_surface_fill (&surface->xcb->base, - op, source, path, - fill_rule, tolerance, - antialias, clip); -} - -static cairo_int_status_t -_cairo_xlib_xcb_surface_glyphs (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - cairo_xlib_xcb_surface_t *surface = abstract_surface; - return _cairo_surface_show_text_glyphs (&surface->xcb->base, op, source, - NULL, 0, - glyphs, num_glyphs, - NULL, 0, 0, - scaled_font, clip); -} - -static cairo_status_t -_cairo_xlib_xcb_surface_flush (void *abstract_surface, unsigned flags) -{ - cairo_xlib_xcb_surface_t *surface = abstract_surface; - /* We have to call cairo_surface_flush() to make sure snapshots are detached */ - return _cairo_surface_flush (&surface->xcb->base, flags); -} - -static cairo_status_t -_cairo_xlib_xcb_surface_mark_dirty (void *abstract_surface, - int x, int y, - int width, int height) -{ - cairo_xlib_xcb_surface_t *surface = abstract_surface; - cairo_surface_mark_dirty_rectangle (&surface->xcb->base, x, y, width, height); - return cairo_surface_status (&surface->xcb->base); -} - -static const cairo_surface_backend_t _cairo_xlib_xcb_surface_backend = { - CAIRO_SURFACE_TYPE_XLIB, - _cairo_xlib_xcb_surface_finish, - - _cairo_default_context_create, /* XXX */ - - _cairo_xlib_xcb_surface_create_similar, - _cairo_xlib_xcb_surface_create_similar_image, - _cairo_xlib_xcb_surface_map_to_image, - _cairo_xlib_xcb_surface_unmap, - - _cairo_xlib_xcb_surface_source, - _cairo_xlib_xcb_surface_acquire_source_image, - _cairo_xlib_xcb_surface_release_source_image, - NULL, /* snapshot */ - - NULL, /* copy_page */ - NULL, /* show_page */ - - _cairo_xlib_xcb_surface_get_extents, - _cairo_xlib_xcb_surface_get_font_options, - - _cairo_xlib_xcb_surface_flush, - _cairo_xlib_xcb_surface_mark_dirty, - - _cairo_xlib_xcb_surface_paint, - _cairo_xlib_xcb_surface_mask, - _cairo_xlib_xcb_surface_stroke, - _cairo_xlib_xcb_surface_fill, - NULL, /* fill_stroke */ - _cairo_xlib_xcb_surface_glyphs, -}; - -static void -_cairo_xlib_xcb_display_finish (void *abstract_display) -{ - cairo_xlib_xcb_display_t *display = (cairo_xlib_xcb_display_t *) abstract_display; - - CAIRO_MUTEX_LOCK (_cairo_xlib_display_mutex); - cairo_list_del (&display->link); - CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex); - - cairo_device_destroy (display->xcb_device); - display->xcb_device = NULL; - - XESetCloseDisplay (display->dpy, display->codes->extension, NULL); - /* Drop the reference from _cairo_xlib_xcb_device_create */ - cairo_device_destroy (&display->base); -} - -static int -_cairo_xlib_xcb_close_display(Display *dpy, XExtCodes *codes) -{ - cairo_xlib_xcb_display_t *display; - - CAIRO_MUTEX_LOCK (_cairo_xlib_display_mutex); - cairo_list_foreach_entry (display, - cairo_xlib_xcb_display_t, - &displays, - link) - { - if (display->dpy == dpy) - { - /* _cairo_xlib_xcb_display_finish will lock the mutex again - * -> deadlock (This mutex isn't recursive) */ - cairo_device_reference (&display->base); - CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex); - - /* Make sure the xcb and xlib-xcb devices are finished */ - cairo_device_finish (display->xcb_device); - cairo_device_finish (&display->base); - - cairo_device_destroy (&display->base); - return 0; - } - } - CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex); - - return 0; -} - -static const cairo_device_backend_t _cairo_xlib_xcb_device_backend = { - CAIRO_DEVICE_TYPE_XLIB, - - NULL, - NULL, - - NULL, /* flush */ - _cairo_xlib_xcb_display_finish, - free, /* destroy */ -}; - -static cairo_device_t * -_cairo_xlib_xcb_device_create (Display *dpy, cairo_device_t *xcb_device) -{ - cairo_xlib_xcb_display_t *display = NULL; - cairo_device_t *device; - - if (xcb_device == NULL) - return NULL; - - CAIRO_MUTEX_INITIALIZE (); - - CAIRO_MUTEX_LOCK (_cairo_xlib_display_mutex); - if (displays.next == NULL) { - cairo_list_init (&displays); - } - - cairo_list_foreach_entry (display, - cairo_xlib_xcb_display_t, - &displays, - link) - { - if (display->dpy == dpy) { - /* Maintain MRU order. */ - if (displays.next != &display->link) - cairo_list_move (&display->link, &displays); - - /* Grab a reference for our caller */ - device = cairo_device_reference (&display->base); - assert (display->xcb_device == xcb_device); - goto unlock; - } - } - - display = malloc (sizeof (cairo_xlib_xcb_display_t)); - if (unlikely (display == NULL)) { - device = _cairo_device_create_in_error (CAIRO_STATUS_NO_MEMORY); - goto unlock; - } - - display->codes = XAddExtension (dpy); - if (unlikely (display->codes == NULL)) { - device = _cairo_device_create_in_error (CAIRO_STATUS_NO_MEMORY); - free (display); - goto unlock; - } - - _cairo_device_init (&display->base, &_cairo_xlib_xcb_device_backend); - - XESetCloseDisplay (dpy, display->codes->extension, _cairo_xlib_xcb_close_display); - /* Add a reference for _cairo_xlib_xcb_display_finish. This basically means - * that the device's reference count never drops to zero - * as long as our Display* is alive. We need this because there is no - * "XDelExtension" to undo XAddExtension and having lots of registered - * extensions slows down libX11. */ - cairo_device_reference (&display->base); - - display->dpy = dpy; - display->xcb_device = cairo_device_reference(xcb_device); - - cairo_list_add (&display->link, &displays); - device = &display->base; - -unlock: - CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex); - - return device; -} - -static cairo_surface_t * -_cairo_xlib_xcb_surface_create (void *dpy, - void *scr, - void *visual, - void *format, - cairo_surface_t *xcb) -{ - cairo_xlib_xcb_surface_t *surface; - - if (unlikely (xcb->status)) - return xcb; - - surface = malloc (sizeof (*surface)); - if (unlikely (surface == NULL)) { - cairo_surface_destroy (xcb); - return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY); - } - - _cairo_surface_init (&surface->base, - &_cairo_xlib_xcb_surface_backend, - _cairo_xlib_xcb_device_create (dpy, xcb->device), - xcb->content); - - /* _cairo_surface_init() got another reference to the device, drop ours */ - cairo_device_destroy (surface->base.device); - - surface->display = dpy; - surface->screen = scr; - surface->visual = visual; - surface->format = format; - surface->xcb = (cairo_xcb_surface_t *) xcb; - - return &surface->base; -} - -static Screen * -_cairo_xlib_screen_from_visual (Display *dpy, Visual *visual) -{ - int s, d, v; - - for (s = 0; s < ScreenCount (dpy); s++) { - Screen *screen; - - screen = ScreenOfDisplay (dpy, s); - if (visual == DefaultVisualOfScreen (screen)) - return screen; - - for (d = 0; d < screen->ndepths; d++) { - Depth *depth; - - depth = &screen->depths[d]; - for (v = 0; v < depth->nvisuals; v++) - if (visual == &depth->visuals[v]) - return screen; - } - } - - return NULL; -} - -cairo_surface_t * -cairo_xlib_surface_create (Display *dpy, - Drawable drawable, - Visual *visual, - int width, - int height) -{ - Screen *scr; - xcb_visualtype_t xcb_visual; - - scr = _cairo_xlib_screen_from_visual (dpy, visual); - if (scr == NULL) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL)); - - xcb_visual.visual_id = visual->visualid; -#if defined(__cplusplus) || defined(c_plusplus) - xcb_visual._class = visual->c_class; -#else - xcb_visual._class = visual->class; -#endif - xcb_visual.bits_per_rgb_value = visual->bits_per_rgb; - xcb_visual.colormap_entries = visual->map_entries; - xcb_visual.red_mask = visual->red_mask; - xcb_visual.green_mask = visual->green_mask; - xcb_visual.blue_mask = visual->blue_mask; - - return _cairo_xlib_xcb_surface_create (dpy, scr, visual, NULL, - cairo_xcb_surface_create (XGetXCBConnection (dpy), - drawable, - &xcb_visual, - width, height)); -} - -static xcb_screen_t * -_cairo_xcb_screen_from_root (xcb_connection_t *connection, - xcb_window_t id) -{ - xcb_screen_iterator_t s; - - s = xcb_setup_roots_iterator (xcb_get_setup (connection)); - for (; s.rem; xcb_screen_next (&s)) { - if (s.data->root == id) - return s.data; - } - - return NULL; -} - -cairo_surface_t * -cairo_xlib_surface_create_for_bitmap (Display *dpy, - Pixmap bitmap, - Screen *scr, - int width, - int height) -{ - xcb_connection_t *connection = XGetXCBConnection (dpy); - xcb_screen_t *screen = _cairo_xcb_screen_from_root (connection, (xcb_window_t) scr->root); - return _cairo_xlib_xcb_surface_create (dpy, scr, NULL, NULL, - cairo_xcb_surface_create_for_bitmap (connection, - screen, - bitmap, - width, height)); -} - -#if CAIRO_HAS_XLIB_XRENDER_SURFACE -cairo_surface_t * -cairo_xlib_surface_create_with_xrender_format (Display *dpy, - Drawable drawable, - Screen *scr, - XRenderPictFormat *format, - int width, - int height) -{ - xcb_render_pictforminfo_t xcb_format; - xcb_connection_t *connection; - xcb_screen_t *screen; - - xcb_format.id = format->id; - xcb_format.type = format->type; - xcb_format.depth = format->depth; - xcb_format.direct.red_shift = format->direct.red; - xcb_format.direct.red_mask = format->direct.redMask; - xcb_format.direct.green_shift = format->direct.green; - xcb_format.direct.green_mask = format->direct.greenMask; - xcb_format.direct.blue_shift = format->direct.blue; - xcb_format.direct.blue_mask = format->direct.blueMask; - xcb_format.direct.alpha_shift = format->direct.alpha; - xcb_format.direct.alpha_mask = format->direct.alphaMask; - xcb_format.colormap = format->colormap; - - connection = XGetXCBConnection (dpy); - screen = _cairo_xcb_screen_from_root (connection, (xcb_window_t) scr->root); - - return _cairo_xlib_xcb_surface_create (dpy, scr, NULL, format, - cairo_xcb_surface_create_with_xrender_format (connection, screen, - drawable, - &xcb_format, - width, height)); -} - -XRenderPictFormat * -cairo_xlib_surface_get_xrender_format (cairo_surface_t *surface) -{ - cairo_xlib_xcb_surface_t *xlib_surface = (cairo_xlib_xcb_surface_t *) surface; - - /* Throw an error for a non-xlib surface */ - if (surface->type != CAIRO_SURFACE_TYPE_XLIB) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return NULL; - } - - return xlib_surface->format; -} -#endif - -void -cairo_xlib_surface_set_size (cairo_surface_t *abstract_surface, - int width, - int height) -{ - cairo_xlib_xcb_surface_t *surface = (cairo_xlib_xcb_surface_t *) abstract_surface; - cairo_status_t status; - - if (unlikely (abstract_surface->status)) - return; - if (unlikely (abstract_surface->finished)) { - status = _cairo_surface_set_error (abstract_surface, - _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - return; - } - - if (surface->base.type != CAIRO_SURFACE_TYPE_XLIB) { - status = _cairo_surface_set_error (abstract_surface, - CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return; - } - - cairo_xcb_surface_set_size (&surface->xcb->base, width, height); - if (unlikely (surface->xcb->base.status)) { - status = _cairo_surface_set_error (abstract_surface, - _cairo_error (surface->xcb->base.status)); - } -} - -void -cairo_xlib_surface_set_drawable (cairo_surface_t *abstract_surface, - Drawable drawable, - int width, - int height) -{ - cairo_xlib_xcb_surface_t *surface = (cairo_xlib_xcb_surface_t *)abstract_surface; - cairo_status_t status; - - if (unlikely (abstract_surface->status)) - return; - if (unlikely (abstract_surface->finished)) { - status = _cairo_surface_set_error (abstract_surface, - _cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - return; - } - - if (surface->base.type != CAIRO_SURFACE_TYPE_XLIB) { - status = _cairo_surface_set_error (abstract_surface, - CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return; - } - - cairo_xcb_surface_set_drawable (&surface->xcb->base, drawable, width, height); - if (unlikely (surface->xcb->base.status)) { - status = _cairo_surface_set_error (abstract_surface, - _cairo_error (surface->xcb->base.status)); - } -} - -Display * -cairo_xlib_surface_get_display (cairo_surface_t *abstract_surface) -{ - cairo_xlib_xcb_surface_t *surface = (cairo_xlib_xcb_surface_t *) abstract_surface; - - if (surface->base.type != CAIRO_SURFACE_TYPE_XLIB) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return NULL; - } - - return surface->display; -} - -Drawable -cairo_xlib_surface_get_drawable (cairo_surface_t *abstract_surface) -{ - cairo_xlib_xcb_surface_t *surface = (cairo_xlib_xcb_surface_t *) abstract_surface; - - if (unlikely (abstract_surface->finished)) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_FINISHED); - return 0; - } - if (surface->base.type != CAIRO_SURFACE_TYPE_XLIB) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return 0; - } - /* This can happen when e.g. create_similar falls back to an image surface - * because we don't have the RENDER extension. */ - if (surface->xcb->base.type != CAIRO_SURFACE_TYPE_XCB) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return 0; - } - - return surface->xcb->drawable; -} - -Screen * -cairo_xlib_surface_get_screen (cairo_surface_t *abstract_surface) -{ - cairo_xlib_xcb_surface_t *surface = (cairo_xlib_xcb_surface_t *) abstract_surface; - - if (surface->base.type != CAIRO_SURFACE_TYPE_XLIB) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return NULL; - } - - return surface->screen; -} - -Visual * -cairo_xlib_surface_get_visual (cairo_surface_t *abstract_surface) -{ - cairo_xlib_xcb_surface_t *surface = (cairo_xlib_xcb_surface_t *) abstract_surface; - - if (surface->base.type != CAIRO_SURFACE_TYPE_XLIB) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return NULL; - } - - return surface->visual; -} - -int -cairo_xlib_surface_get_depth (cairo_surface_t *abstract_surface) -{ - cairo_xlib_xcb_surface_t *surface = (cairo_xlib_xcb_surface_t *) abstract_surface; - - if (unlikely (abstract_surface->finished)) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_FINISHED); - return 0; - } - if (surface->base.type != CAIRO_SURFACE_TYPE_XLIB) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return 0; - } - /* This can happen when e.g. create_similar falls back to an image surface - * because we don't have the RENDER extension. */ - if (surface->xcb->base.type != CAIRO_SURFACE_TYPE_XCB) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return 0; - } - - return surface->xcb->depth; -} - -int -cairo_xlib_surface_get_width (cairo_surface_t *abstract_surface) -{ - cairo_xlib_xcb_surface_t *surface = (cairo_xlib_xcb_surface_t *) abstract_surface; - - if (unlikely (abstract_surface->finished)) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_FINISHED); - return 0; - } - if (surface->base.type != CAIRO_SURFACE_TYPE_XLIB) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return 0; - } - /* This can happen when e.g. create_similar falls back to an image surface - * because we don't have the RENDER extension. */ - if (surface->xcb->base.type != CAIRO_SURFACE_TYPE_XCB) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return 0; - } - - return surface->xcb->width; -} - -int -cairo_xlib_surface_get_height (cairo_surface_t *abstract_surface) -{ - cairo_xlib_xcb_surface_t *surface = (cairo_xlib_xcb_surface_t *) abstract_surface; - - if (unlikely (abstract_surface->finished)) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_FINISHED); - return 0; - } - if (surface->base.type != CAIRO_SURFACE_TYPE_XLIB) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return 0; - } - /* This can happen when e.g. create_similar falls back to an image surface - * because we don't have the RENDER extension. */ - if (surface->xcb->base.type != CAIRO_SURFACE_TYPE_XCB) { - _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return 0; - } - - return surface->xcb->height; -} - -void -cairo_xlib_device_debug_cap_xrender_version (cairo_device_t *device, - int major, int minor) -{ - cairo_xlib_xcb_display_t *display = (cairo_xlib_xcb_display_t *) device; - - if (device == NULL || device->status) - return; - - if (device->backend->type != CAIRO_DEVICE_TYPE_XLIB) - return; - - cairo_xcb_device_debug_cap_xrender_version (display->xcb_device, - major, minor); -} - -void -cairo_xlib_device_debug_set_precision (cairo_device_t *device, - int precision) -{ - cairo_xlib_xcb_display_t *display = (cairo_xlib_xcb_display_t *) device; - - if (device == NULL || device->status) - return; - if (device->backend->type != CAIRO_DEVICE_TYPE_XLIB) { - cairo_status_t status; - - status = _cairo_device_set_error (device, CAIRO_STATUS_DEVICE_TYPE_MISMATCH); - (void) status; - return; - } - - cairo_xcb_device_debug_set_precision (display->xcb_device, precision); -} - -int -cairo_xlib_device_debug_get_precision (cairo_device_t *device) -{ - cairo_xlib_xcb_display_t *display = (cairo_xlib_xcb_display_t *) device; - - if (device == NULL || device->status) - return -1; - if (device->backend->type != CAIRO_DEVICE_TYPE_XLIB) { - cairo_status_t status; - - status = _cairo_device_set_error (device, CAIRO_STATUS_DEVICE_TYPE_MISMATCH); - (void) status; - return -1; - } - - return cairo_xcb_device_debug_get_precision (display->xcb_device); -} - -#endif /* CAIRO_HAS_XLIB_XCB_FUNCTIONS */ diff --git a/source/libs/cairo/cairo-src/src/cairo-xlib-xrender-private.h b/source/libs/cairo/cairo-src/src/cairo-xlib-xrender-private.h deleted file mode 100644 index 90769467b2daabf650777cd2b59bea568fc1c92b..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xlib-xrender-private.h +++ /dev/null @@ -1,1173 +0,0 @@ -/* Cairo - a vector graphics library with display and print output - * - * Copyright © 2007 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - */ - -#ifndef CAIRO_XLIB_XRENDER_PRIVATE_H -#define CAIRO_XLIB_XRENDER_PRIVATE_H - -#include "cairo-features.h" -#include "cairo-compiler-private.h" - -#include <X11/Xlib.h> - -/* These prototypes are used when defining interfaces missing from the - * render headers. As it happens, it is the case that all libxrender - * functions take a pointer as first argument. */ - -__attribute__((__unused__)) static void _void_consume (void *p, ...) { } -__attribute__((__unused__)) static void * _voidp_consume (void *p, ...) { return (void *)0; } -__attribute__((__unused__)) static int _int_consume (void *p, ...) { return 0; } -__attribute__((__unused__)) static void _void_consume_free (Display *p, XID n) { } - - -#if CAIRO_HAS_XLIB_XRENDER_SURFACE - -#include "cairo-xlib-xrender.h" - -#include <X11/extensions/Xrender.h> -#include <X11/extensions/renderproto.h> - -/* We require Render >= 0.6. The following defines were only added in - * 0.10. Make sure they are defined. - */ - -/* Filters included in 0.10 */ -#ifndef FilterConvolution -#define FilterConvolution "convolution" -#endif - -/* Extended repeat attributes included in 0.10 */ -#ifndef RepeatNone -#define RepeatNone 0 -#define RepeatNormal 1 -#define RepeatPad 2 -#define RepeatReflect 3 -#endif - - -#ifndef PictOptBlendMinimum -/* - * Operators only available in version 0.11 - */ -#define PictOpBlendMinimum 0x30 -#define PictOpMultiply 0x30 -#define PictOpScreen 0x31 -#define PictOpOverlay 0x32 -#define PictOpDarken 0x33 -#define PictOpLighten 0x34 -#define PictOpColorDodge 0x35 -#define PictOpColorBurn 0x36 -#define PictOpHardLight 0x37 -#define PictOpSoftLight 0x38 -#define PictOpDifference 0x39 -#define PictOpExclusion 0x3a -#define PictOpHSLHue 0x3b -#define PictOpHSLSaturation 0x3c -#define PictOpHSLColor 0x3d -#define PictOpHSLLuminosity 0x3e -#define PictOpBlendMaximum 0x3e -#endif - -#if !HAVE_XRENDERCREATESOLIDFILL -#define XRenderCreateSolidFill _int_consume -#endif - -#if !HAVE_XRENDERCREATELINEARGRADIENT -#define XRenderCreateLinearGradient _int_consume - -typedef struct _XLinearGradient { - XPointFixed p1; - XPointFixed p2; -} XLinearGradient; -#endif - -#if !HAVE_XRENDERCREATERADIALGRADIENT -#define XRenderCreateRadialGradient _int_consume - -typedef struct _XCircle { - XFixed x; - XFixed y; - XFixed radius; -} XCircle; -typedef struct _XRadialGradient { - XCircle inner; - XCircle outer; -} XRadialGradient; -#endif - -#if !HAVE_XRENDERCREATECONICALGRADIENT -#define XRenderCreateConicalGradient _int_consume - -typedef struct _XConicalGradient { - XPointFixed center; - XFixed angle; /* in degrees */ -} XConicalGradient; -#endif - - -#else /* !CAIRO_HAS_XLIB_XRENDER_SURFACE */ - -/* Provide dummy symbols and macros to get it compile and take the fallback - * route, just like as if Xrender is not available in the server at run-time. */ - - -/* Functions */ - -#define XRenderQueryExtension _int_consume -#define XRenderQueryVersion _int_consume -#define XRenderQueryFormats _int_consume -#define XRenderQuerySubpixelOrder _int_consume -#define XRenderSetSubpixelOrder _int_consume -#define XRenderFindVisualFormat _voidp_consume -#define XRenderFindFormat _voidp_consume -#define XRenderFindStandardFormat _voidp_consume -#define XRenderQueryPictIndexValues _voidp_consume -#define XRenderCreatePicture _int_consume -#define XRenderChangePicture _void_consume -#define XRenderSetPictureClipRectangles _void_consume -#define XRenderSetPictureClipRegion _void_consume -#define XRenderSetPictureTransform _void_consume -#define XRenderFreePicture _void_consume_free -#define XRenderComposite _void_consume -#define XRenderCreateGlyphSet _int_consume -#define XRenderReferenceGlyphSet _int_consume -#define XRenderFreeGlyphSet _void_consume_free -#define XRenderAddGlyphs _void_consume -#define XRenderFreeGlyphs _void_consume -#define XRenderCompositeString8 _void_consume -#define XRenderCompositeString16 _void_consume -#define XRenderCompositeString32 _void_consume -#define XRenderCompositeText8 (cairo_xrender_composite_text_func_t) _void_consume -#define XRenderCompositeText16 _void_consume -#define XRenderCompositeText32 _void_consume -#define XRenderFillRectangle _void_consume -#define XRenderFillRectangles _void_consume -#define XRenderCompositeTrapezoids _void_consume -#define XRenderCompositeTriangles _void_consume -#define XRenderCompositeTriStrip _void_consume -#define XRenderCompositeTriFan _void_consume -#define XRenderCompositeDoublePoly _void_consume -#define XRenderParseColor _int_consume -#define XRenderCreateCursor _int_consume -#define XRenderQueryFilters _voidp_consume -#define XRenderSetPictureFilter _void_consume -#define XRenderCreateAnimCursor _int_consume -#define XRenderAddTraps _void_consume -#define XRenderCreateSolidFill _int_consume -#define XRenderCreateLinearGradient _int_consume -#define XRenderCreateRadialGradient _int_consume -#define XRenderCreateConicalGradient _int_consume - -#define cairo_xlib_surface_create_with_xrender_format _voidp_consume - - - -/* The rest of this file is copied from various Xrender header files, with - * the following copyright/license information: - * - * Copyright © 2000 SuSE, 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 SuSE not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. SuSE makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE - * 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: Keith Packard, SuSE, Inc. - */ - - -/* Copied from X11/extensions/render.h */ - -typedef unsigned long Glyph; -typedef unsigned long GlyphSet; -typedef unsigned long Picture; -typedef unsigned long PictFormat; - -#define BadPictFormat 0 -#define BadPicture 1 -#define BadPictOp 2 -#define BadGlyphSet 3 -#define BadGlyph 4 -#define RenderNumberErrors (BadGlyph+1) - -#define PictTypeIndexed 0 -#define PictTypeDirect 1 - -#define PictOpMinimum 0 -#define PictOpClear 0 -#define PictOpSrc 1 -#define PictOpDst 2 -#define PictOpOver 3 -#define PictOpOverReverse 4 -#define PictOpIn 5 -#define PictOpInReverse 6 -#define PictOpOut 7 -#define PictOpOutReverse 8 -#define PictOpAtop 9 -#define PictOpAtopReverse 10 -#define PictOpXor 11 -#define PictOpAdd 12 -#define PictOpSaturate 13 -#define PictOpMaximum 13 - -/* - * Operators only available in version 0.2 - */ -#define PictOpDisjointMinimum 0x10 -#define PictOpDisjointClear 0x10 -#define PictOpDisjointSrc 0x11 -#define PictOpDisjointDst 0x12 -#define PictOpDisjointOver 0x13 -#define PictOpDisjointOverReverse 0x14 -#define PictOpDisjointIn 0x15 -#define PictOpDisjointInReverse 0x16 -#define PictOpDisjointOut 0x17 -#define PictOpDisjointOutReverse 0x18 -#define PictOpDisjointAtop 0x19 -#define PictOpDisjointAtopReverse 0x1a -#define PictOpDisjointXor 0x1b -#define PictOpDisjointMaximum 0x1b - -#define PictOpConjointMinimum 0x20 -#define PictOpConjointClear 0x20 -#define PictOpConjointSrc 0x21 -#define PictOpConjointDst 0x22 -#define PictOpConjointOver 0x23 -#define PictOpConjointOverReverse 0x24 -#define PictOpConjointIn 0x25 -#define PictOpConjointInReverse 0x26 -#define PictOpConjointOut 0x27 -#define PictOpConjointOutReverse 0x28 -#define PictOpConjointAtop 0x29 -#define PictOpConjointAtopReverse 0x2a -#define PictOpConjointXor 0x2b -#define PictOpConjointMaximum 0x2b - -/* - * Operators only available in version 0.11 - */ -#define PictOpBlendMinimum 0x30 -#define PictOpMultiply 0x30 -#define PictOpScreen 0x31 -#define PictOpOverlay 0x32 -#define PictOpDarken 0x33 -#define PictOpLighten 0x34 -#define PictOpColorDodge 0x35 -#define PictOpColorBurn 0x36 -#define PictOpHardLight 0x37 -#define PictOpSoftLight 0x38 -#define PictOpDifference 0x39 -#define PictOpExclusion 0x3a -#define PictOpHSLHue 0x3b -#define PictOpHSLSaturation 0x3c -#define PictOpHSLColor 0x3d -#define PictOpHSLLuminosity 0x3e -#define PictOpBlendMaximum 0x3e - -#define PolyEdgeSharp 0 -#define PolyEdgeSmooth 1 - -#define PolyModePrecise 0 -#define PolyModeImprecise 1 - -#define CPRepeat (1 << 0) -#define CPAlphaMap (1 << 1) -#define CPAlphaXOrigin (1 << 2) -#define CPAlphaYOrigin (1 << 3) -#define CPClipXOrigin (1 << 4) -#define CPClipYOrigin (1 << 5) -#define CPClipMask (1 << 6) -#define CPGraphicsExposure (1 << 7) -#define CPSubwindowMode (1 << 8) -#define CPPolyEdge (1 << 9) -#define CPPolyMode (1 << 10) -#define CPDither (1 << 11) -#define CPComponentAlpha (1 << 12) -#define CPLastBit 12 - -/* Filters included in 0.6 */ -#define FilterNearest "nearest" -#define FilterBilinear "bilinear" -/* Filters included in 0.10 */ -#define FilterConvolution "convolution" - -#define FilterFast "fast" -#define FilterGood "good" -#define FilterBest "best" - -#define FilterAliasNone -1 - -/* Subpixel orders included in 0.6 */ -#define SubPixelUnknown 0 -#define SubPixelHorizontalRGB 1 -#define SubPixelHorizontalBGR 2 -#define SubPixelVerticalRGB 3 -#define SubPixelVerticalBGR 4 -#define SubPixelNone 5 - -/* Extended repeat attributes included in 0.10 */ -#define RepeatNone 0 -#define RepeatNormal 1 -#define RepeatPad 2 -#define RepeatReflect 3 - - - -/* Copied from X11/extensions/Xrender.h */ - -typedef struct { - short red; - short redMask; - short green; - short greenMask; - short blue; - short blueMask; - short alpha; - short alphaMask; -} XRenderDirectFormat; - -typedef struct { - PictFormat id; - int type; - int depth; - XRenderDirectFormat direct; - Colormap colormap; -} XRenderPictFormat; - -#define PictFormatID (1 << 0) -#define PictFormatType (1 << 1) -#define PictFormatDepth (1 << 2) -#define PictFormatRed (1 << 3) -#define PictFormatRedMask (1 << 4) -#define PictFormatGreen (1 << 5) -#define PictFormatGreenMask (1 << 6) -#define PictFormatBlue (1 << 7) -#define PictFormatBlueMask (1 << 8) -#define PictFormatAlpha (1 << 9) -#define PictFormatAlphaMask (1 << 10) -#define PictFormatColormap (1 << 11) - -typedef struct _XRenderPictureAttributes { - int repeat; - Picture alpha_map; - int alpha_x_origin; - int alpha_y_origin; - int clip_x_origin; - int clip_y_origin; - Pixmap clip_mask; - Bool graphics_exposures; - int subwindow_mode; - int poly_edge; - int poly_mode; - Atom dither; - Bool component_alpha; -} XRenderPictureAttributes; - -typedef struct { - unsigned short red; - unsigned short green; - unsigned short blue; - unsigned short alpha; -} XRenderColor; - -typedef struct _XGlyphInfo { - unsigned short width; - unsigned short height; - short x; - short y; - short xOff; - short yOff; -} XGlyphInfo; - -typedef struct _XGlyphElt8 { - GlyphSet glyphset; - _Xconst char *chars; - int nchars; - int xOff; - int yOff; -} XGlyphElt8; - -typedef struct _XGlyphElt16 { - GlyphSet glyphset; - _Xconst unsigned short *chars; - int nchars; - int xOff; - int yOff; -} XGlyphElt16; - -typedef struct _XGlyphElt32 { - GlyphSet glyphset; - _Xconst unsigned int *chars; - int nchars; - int xOff; - int yOff; -} XGlyphElt32; - -typedef double XDouble; - -typedef struct _XPointDouble { - XDouble x, y; -} XPointDouble; - -#define XDoubleToFixed(f) ((XFixed) ((f) * 65536)) -#define XFixedToDouble(f) (((XDouble) (f)) / 65536) - -typedef int XFixed; - -typedef struct _XPointFixed { - XFixed x, y; -} XPointFixed; - -typedef struct _XLineFixed { - XPointFixed p1, p2; -} XLineFixed; - -typedef struct _XTriangle { - XPointFixed p1, p2, p3; -} XTriangle; - -typedef struct _XCircle { - XFixed x; - XFixed y; - XFixed radius; -} XCircle; - -typedef struct _XTrapezoid { - XFixed top, bottom; - XLineFixed left, right; -} XTrapezoid; - -typedef struct _XTransform { - XFixed matrix[3][3]; -} XTransform; - -typedef struct _XFilters { - int nfilter; - char **filter; - int nalias; - short *alias; -} XFilters; - -typedef struct _XIndexValue { - unsigned long pixel; - unsigned short red, green, blue, alpha; -} XIndexValue; - -typedef struct _XAnimCursor { - Cursor cursor; - unsigned long delay; -} XAnimCursor; - -typedef struct _XSpanFix { - XFixed left, right, y; -} XSpanFix; - -typedef struct _XTrap { - XSpanFix top, bottom; -} XTrap; - -typedef struct _XLinearGradient { - XPointFixed p1; - XPointFixed p2; -} XLinearGradient; - -typedef struct _XRadialGradient { - XCircle inner; - XCircle outer; -} XRadialGradient; - -typedef struct _XConicalGradient { - XPointFixed center; - XFixed angle; /* in degrees */ -} XConicalGradient; - -#define PictStandardARGB32 0 -#define PictStandardRGB24 1 -#define PictStandardA8 2 -#define PictStandardA4 3 -#define PictStandardA1 4 -#define PictStandardNUM 5 - - - -/* Copied from X11/extensions/renderproto.h */ - -#include <X11/Xmd.h> - -#define Window CARD32 -#define Drawable CARD32 -#define Font CARD32 -#define Pixmap CARD32 -#define Cursor CARD32 -#define Colormap CARD32 -#define GContext CARD32 -#define Atom CARD32 -#define VisualID CARD32 -#define Time CARD32 -#define KeyCode CARD8 -#define KeySym CARD32 - -#define Picture CARD32 -#define PictFormat CARD32 -#define Fixed INT32 -#define Glyphset CARD32 -#define Glyph CARD32 - -/* - * data structures - */ - -typedef struct { - CARD16 red B16; - CARD16 redMask B16; - CARD16 green B16; - CARD16 greenMask B16; - CARD16 blue B16; - CARD16 blueMask B16; - CARD16 alpha B16; - CARD16 alphaMask B16; -} xDirectFormat; - -#define sz_xDirectFormat 16 - -typedef struct { - PictFormat id B32; - CARD8 type; - CARD8 depth; - CARD16 pad1 B16; - xDirectFormat direct; - Colormap colormap; -} xPictFormInfo; - -#define sz_xPictFormInfo 28 - -typedef struct { - VisualID visual; - PictFormat format; -} xPictVisual; - -#define sz_xPictVisual 8 - -typedef struct { - CARD8 depth; - CARD8 pad1; - CARD16 nPictVisuals B16; - CARD32 pad2 B32; -} xPictDepth; - -#define sz_xPictDepth 8 - -typedef struct { - CARD32 nDepth B32; - PictFormat fallback B32; -} xPictScreen; - -#define sz_xPictScreen 8 - -typedef struct { - CARD32 pixel B32; - CARD16 red B16; - CARD16 green B16; - CARD16 blue B16; - CARD16 alpha B16; -} xIndexValue; - -#define sz_xIndexValue 12 - -typedef struct { - CARD16 red B16; - CARD16 green B16; - CARD16 blue B16; - CARD16 alpha B16; -} xRenderColor; - -#define sz_xRenderColor 8 - -typedef struct { - Fixed x B32; - Fixed y B32; -} xPointFixed; - -#define sz_xPointFixed 8 - -typedef struct { - xPointFixed p1; - xPointFixed p2; -} xLineFixed; - -#define sz_xLineFixed 16 - -typedef struct { - xPointFixed p1, p2, p3; -} xTriangle; - -#define sz_xTriangle 24 - -typedef struct { - Fixed top B32; - Fixed bottom B32; - xLineFixed left; - xLineFixed right; -} xTrapezoid; - -#define sz_xTrapezoid 40 - -typedef struct { - CARD16 width B16; - CARD16 height B16; - INT16 x B16; - INT16 y B16; - INT16 xOff B16; - INT16 yOff B16; -} xGlyphInfo; - -#define sz_xGlyphInfo 12 - -typedef struct { - CARD8 len; - CARD8 pad1; - CARD16 pad2; - INT16 deltax; - INT16 deltay; -} xGlyphElt; - -#define sz_xGlyphElt 8 - -typedef struct { - Fixed l, r, y; -} xSpanFix; - -#define sz_xSpanFix 12 - -typedef struct { - xSpanFix top, bot; -} xTrap; - -#define sz_xTrap 24 - -/* - * requests and replies - */ -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - CARD32 majorVersion B32; - CARD32 minorVersion B32; -} xRenderQueryVersionReq; - -#define sz_xRenderQueryVersionReq 12 - -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD32 majorVersion B32; - CARD32 minorVersion B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; -} xRenderQueryVersionReply; - -#define sz_xRenderQueryVersionReply 32 - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; -} xRenderQueryPictFormatsReq; - -#define sz_xRenderQueryPictFormatsReq 4 - -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD32 numFormats B32; - CARD32 numScreens B32; - CARD32 numDepths B32; - CARD32 numVisuals B32; - CARD32 numSubpixel B32; /* Version 0.6 */ - CARD32 pad5 B32; -} xRenderQueryPictFormatsReply; - -#define sz_xRenderQueryPictFormatsReply 32 - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - PictFormat format B32; -} xRenderQueryPictIndexValuesReq; - -#define sz_xRenderQueryPictIndexValuesReq 8 - -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD32 numIndexValues; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; -} xRenderQueryPictIndexValuesReply; - -#define sz_xRenderQueryPictIndexValuesReply 32 - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - Picture pid B32; - Drawable drawable B32; - PictFormat format B32; - CARD32 mask B32; -} xRenderCreatePictureReq; - -#define sz_xRenderCreatePictureReq 20 - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - Picture picture B32; - CARD32 mask B32; -} xRenderChangePictureReq; - -#define sz_xRenderChangePictureReq 12 - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - Picture picture B32; - INT16 xOrigin B16; - INT16 yOrigin B16; -} xRenderSetPictureClipRectanglesReq; - -#define sz_xRenderSetPictureClipRectanglesReq 12 - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - Picture picture B32; -} xRenderFreePictureReq; - -#define sz_xRenderFreePictureReq 8 - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - CARD8 op; - CARD8 pad1; - CARD16 pad2 B16; - Picture src B32; - Picture mask B32; - Picture dst B32; - INT16 xSrc B16; - INT16 ySrc B16; - INT16 xMask B16; - INT16 yMask B16; - INT16 xDst B16; - INT16 yDst B16; - CARD16 width B16; - CARD16 height B16; -} xRenderCompositeReq; - -#define sz_xRenderCompositeReq 36 - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - Picture src B32; - Picture dst B32; - CARD32 colorScale B32; - CARD32 alphaScale B32; - INT16 xSrc B16; - INT16 ySrc B16; - INT16 xDst B16; - INT16 yDst B16; - CARD16 width B16; - CARD16 height B16; -} xRenderScaleReq; - -#define sz_xRenderScaleReq 32 - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - CARD8 op; - CARD8 pad1; - CARD16 pad2 B16; - Picture src B32; - Picture dst B32; - PictFormat maskFormat B32; - INT16 xSrc B16; - INT16 ySrc B16; -} xRenderTrapezoidsReq; - -#define sz_xRenderTrapezoidsReq 24 - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - CARD8 op; - CARD8 pad1; - CARD16 pad2 B16; - Picture src B32; - Picture dst B32; - PictFormat maskFormat B32; - INT16 xSrc B16; - INT16 ySrc B16; -} xRenderTrianglesReq; - -#define sz_xRenderTrianglesReq 24 - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - CARD8 op; - CARD8 pad1; - CARD16 pad2 B16; - Picture src B32; - Picture dst B32; - PictFormat maskFormat B32; - INT16 xSrc B16; - INT16 ySrc B16; -} xRenderTriStripReq; - -#define sz_xRenderTriStripReq 24 - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - CARD8 op; - CARD8 pad1; - CARD16 pad2 B16; - Picture src B32; - Picture dst B32; - PictFormat maskFormat B32; - INT16 xSrc B16; - INT16 ySrc B16; -} xRenderTriFanReq; - -#define sz_xRenderTriFanReq 24 - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - Glyphset gsid B32; - PictFormat format B32; -} xRenderCreateGlyphSetReq; - -#define sz_xRenderCreateGlyphSetReq 12 - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - Glyphset gsid B32; - Glyphset existing B32; -} xRenderReferenceGlyphSetReq; - -#define sz_xRenderReferenceGlyphSetReq 24 - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - Glyphset glyphset B32; -} xRenderFreeGlyphSetReq; - -#define sz_xRenderFreeGlyphSetReq 8 - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - Glyphset glyphset B32; - CARD32 nglyphs; -} xRenderAddGlyphsReq; - -#define sz_xRenderAddGlyphsReq 12 - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - Glyphset glyphset B32; -} xRenderFreeGlyphsReq; - -#define sz_xRenderFreeGlyphsReq 8 - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - CARD8 op; - CARD8 pad1; - CARD16 pad2 B16; - Picture src B32; - Picture dst B32; - PictFormat maskFormat B32; - Glyphset glyphset B32; - INT16 xSrc B16; - INT16 ySrc B16; -} xRenderCompositeGlyphsReq, xRenderCompositeGlyphs8Req, -xRenderCompositeGlyphs16Req, xRenderCompositeGlyphs32Req; - -#define sz_xRenderCompositeGlyphs8Req 28 -#define sz_xRenderCompositeGlyphs16Req 28 -#define sz_xRenderCompositeGlyphs32Req 28 - -/* 0.1 and higher */ - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - CARD8 op; - CARD8 pad1; - CARD16 pad2 B16; - Picture dst B32; - xRenderColor color; -} xRenderFillRectanglesReq; - -#define sz_xRenderFillRectanglesReq 20 - -/* 0.5 and higher */ - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - Cursor cid B32; - Picture src B32; - CARD16 x B16; - CARD16 y B16; -} xRenderCreateCursorReq; - -#define sz_xRenderCreateCursorReq 16 - -/* 0.6 and higher */ - -/* - * This can't use an array because 32-bit values may be in bitfields - */ -typedef struct { - Fixed matrix11 B32; - Fixed matrix12 B32; - Fixed matrix13 B32; - Fixed matrix21 B32; - Fixed matrix22 B32; - Fixed matrix23 B32; - Fixed matrix31 B32; - Fixed matrix32 B32; - Fixed matrix33 B32; -} xRenderTransform; - -#define sz_xRenderTransform 36 - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - Picture picture B32; - xRenderTransform transform; -} xRenderSetPictureTransformReq; - -#define sz_xRenderSetPictureTransformReq 44 - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - Drawable drawable B32; -} xRenderQueryFiltersReq; - -#define sz_xRenderQueryFiltersReq 8 - -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD32 numAliases B32; /* LISTofCARD16 */ - CARD32 numFilters B32; /* LISTofSTRING8 */ - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; -} xRenderQueryFiltersReply; - -#define sz_xRenderQueryFiltersReply 32 - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - Picture picture B32; - CARD16 nbytes B16; /* number of bytes in name */ - CARD16 pad B16; -} xRenderSetPictureFilterReq; - -#define sz_xRenderSetPictureFilterReq 12 - -/* 0.8 and higher */ - -typedef struct { - Cursor cursor B32; - CARD32 delay B32; -} xAnimCursorElt; - -#define sz_xAnimCursorElt 8 - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - Cursor cid B32; -} xRenderCreateAnimCursorReq; - -#define sz_xRenderCreateAnimCursorReq 8 - -/* 0.9 and higher */ - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - Picture picture; - INT16 xOff B16; - INT16 yOff B16; -} xRenderAddTrapsReq; - -#define sz_xRenderAddTrapsReq 12 - -/* 0.10 and higher */ - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - Picture pid B32; - xRenderColor color; -} xRenderCreateSolidFillReq; - -#define sz_xRenderCreateSolidFillReq 16 - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - Picture pid B32; - xPointFixed p1; - xPointFixed p2; - CARD32 nStops; -} xRenderCreateLinearGradientReq; - -#define sz_xRenderCreateLinearGradientReq 28 - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - Picture pid B32; - xPointFixed inner; - xPointFixed outer; - Fixed inner_radius; - Fixed outer_radius; - CARD32 nStops; -} xRenderCreateRadialGradientReq; - -#define sz_xRenderCreateRadialGradientReq 36 - -typedef struct { - CARD8 reqType; - CARD8 renderReqType; - CARD16 length B16; - Picture pid B32; - xPointFixed center; - Fixed angle; /* in degrees */ - CARD32 nStops; -} xRenderCreateConicalGradientReq; - -#define sz_xRenderCreateConicalGradientReq 24 - -#undef Window -#undef Drawable -#undef Font -#undef Pixmap -#undef Cursor -#undef Colormap -#undef GContext -#undef Atom -#undef VisualID -#undef Time -#undef KeyCode -#undef KeySym - -#undef Picture -#undef PictFormat -#undef Fixed -#undef Glyphset -#undef Glyph - - -#endif /* CAIRO_HAS_XLIB_XRENDER_SURFACE */ - -#endif /* CAIRO_XLIB_XRENDER_PRIVATE_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-xlib-xrender.h b/source/libs/cairo/cairo-src/src/cairo-xlib-xrender.h deleted file mode 100644 index b34b057de4c82afc466b323182b35c70938807c8..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xlib-xrender.h +++ /dev/null @@ -1,66 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - */ - -#ifndef CAIRO_XLIB_XRENDER_H -#define CAIRO_XLIB_XRENDER_H - -#include "cairo.h" - -#if CAIRO_HAS_XLIB_XRENDER_SURFACE - -#include <X11/Xlib.h> -#include <X11/extensions/Xrender.h> - -CAIRO_BEGIN_DECLS - -cairo_public cairo_surface_t * -cairo_xlib_surface_create_with_xrender_format (Display *dpy, - Drawable drawable, - Screen *screen, - XRenderPictFormat *format, - int width, - int height); - -cairo_public XRenderPictFormat * -cairo_xlib_surface_get_xrender_format (cairo_surface_t *surface); - -CAIRO_END_DECLS - -#else /* CAIRO_HAS_XLIB_XRENDER_SURFACE */ -# error Cairo was not compiled with support for the xlib XRender backend -#endif /* CAIRO_HAS_XLIB_XRENDER_SURFACE */ - -#endif /* CAIRO_XLIB_XRENDER_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-xlib.h b/source/libs/cairo/cairo-src/src/cairo-xlib.h deleted file mode 100644 index ecf8d6c86be2d6490f2e4589c73a24fa608f2aa6..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xlib.h +++ /dev/null @@ -1,118 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - */ - -#ifndef CAIRO_XLIB_H -#define CAIRO_XLIB_H - -#include "cairo.h" - -#if CAIRO_HAS_XLIB_SURFACE - -#include <X11/Xlib.h> - -CAIRO_BEGIN_DECLS - -cairo_public cairo_surface_t * -cairo_xlib_surface_create (Display *dpy, - Drawable drawable, - Visual *visual, - int width, - int height); - -cairo_public cairo_surface_t * -cairo_xlib_surface_create_for_bitmap (Display *dpy, - Pixmap bitmap, - Screen *screen, - int width, - int height); - -cairo_public void -cairo_xlib_surface_set_size (cairo_surface_t *surface, - int width, - int height); - -cairo_public void -cairo_xlib_surface_set_drawable (cairo_surface_t *surface, - Drawable drawable, - int width, - int height); - -cairo_public Display * -cairo_xlib_surface_get_display (cairo_surface_t *surface); - -cairo_public Drawable -cairo_xlib_surface_get_drawable (cairo_surface_t *surface); - -cairo_public Screen * -cairo_xlib_surface_get_screen (cairo_surface_t *surface); - -cairo_public Visual * -cairo_xlib_surface_get_visual (cairo_surface_t *surface); - -cairo_public int -cairo_xlib_surface_get_depth (cairo_surface_t *surface); - -cairo_public int -cairo_xlib_surface_get_width (cairo_surface_t *surface); - -cairo_public int -cairo_xlib_surface_get_height (cairo_surface_t *surface); - -/* debug interface */ - -cairo_public void -cairo_xlib_device_debug_cap_xrender_version (cairo_device_t *device, - int major_version, - int minor_version); - -/* - * @precision: -1 implies automatically choose based on antialiasing mode, - * any other value overrides and sets the corresponding PolyMode. - */ -cairo_public void -cairo_xlib_device_debug_set_precision (cairo_device_t *device, - int precision); - -cairo_public int -cairo_xlib_device_debug_get_precision (cairo_device_t *device); - -CAIRO_END_DECLS - -#else /* CAIRO_HAS_XLIB_SURFACE */ -# error Cairo was not compiled with support for the xlib backend -#endif /* CAIRO_HAS_XLIB_SURFACE */ - -#endif /* CAIRO_XLIB_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo-xml-surface.c b/source/libs/cairo/cairo-src/src/cairo-xml-surface.c deleted file mode 100644 index 6dbafdba2bac50d5d4c9ee705be9f4fa872b3548..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xml-surface.c +++ /dev/null @@ -1,1209 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Chris Wilson. - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -/* This surface is intended to produce a verbose, hierarchical, DAG XML file - * representing a single surface. It is intended to be used by debuggers, - * such as cairo-sphinx, or by application test-suites that what a log of - * operations. - */ - -#include "cairoint.h" - -#include "cairo-xml.h" - -#include "cairo-clip-private.h" -#include "cairo-device-private.h" -#include "cairo-default-context-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-error-private.h" -#include "cairo-output-stream-private.h" -#include "cairo-recording-surface-inline.h" - -#define static cairo_warn static - -typedef struct _cairo_xml_surface cairo_xml_surface_t; - -typedef struct _cairo_xml { - cairo_device_t base; - - cairo_output_stream_t *stream; - int indent; -} cairo_xml_t; - -struct _cairo_xml_surface { - cairo_surface_t base; - - double width, height; -}; - -slim_hidden_proto (cairo_xml_for_recording_surface); - -static const cairo_surface_backend_t _cairo_xml_surface_backend; - -static const char * -_operator_to_string (cairo_operator_t op) -{ - static const char *names[] = { - "CLEAR", /* CAIRO_OPERATOR_CLEAR */ - - "SOURCE", /* CAIRO_OPERATOR_SOURCE */ - "OVER", /* CAIRO_OPERATOR_OVER */ - "IN", /* CAIRO_OPERATOR_IN */ - "OUT", /* CAIRO_OPERATOR_OUT */ - "ATOP", /* CAIRO_OPERATOR_ATOP */ - - "DEST", /* CAIRO_OPERATOR_DEST */ - "DEST_OVER", /* CAIRO_OPERATOR_DEST_OVER */ - "DEST_IN", /* CAIRO_OPERATOR_DEST_IN */ - "DEST_OUT", /* CAIRO_OPERATOR_DEST_OUT */ - "DEST_ATOP", /* CAIRO_OPERATOR_DEST_ATOP */ - - "XOR", /* CAIRO_OPERATOR_XOR */ - "ADD", /* CAIRO_OPERATOR_ADD */ - "SATURATE", /* CAIRO_OPERATOR_SATURATE */ - - "MULTIPLY", /* CAIRO_OPERATOR_MULTIPLY */ - "SCREEN", /* CAIRO_OPERATOR_SCREEN */ - "OVERLAY", /* CAIRO_OPERATOR_OVERLAY */ - "DARKEN", /* CAIRO_OPERATOR_DARKEN */ - "LIGHTEN", /* CAIRO_OPERATOR_LIGHTEN */ - "DODGE", /* CAIRO_OPERATOR_COLOR_DODGE */ - "BURN", /* CAIRO_OPERATOR_COLOR_BURN */ - "HARD_LIGHT", /* CAIRO_OPERATOR_HARD_LIGHT */ - "SOFT_LIGHT", /* CAIRO_OPERATOR_SOFT_LIGHT */ - "DIFFERENCE", /* CAIRO_OPERATOR_DIFFERENCE */ - "EXCLUSION", /* CAIRO_OPERATOR_EXCLUSION */ - "HSL_HUE", /* CAIRO_OPERATOR_HSL_HUE */ - "HSL_SATURATION", /* CAIRO_OPERATOR_HSL_SATURATION */ - "HSL_COLOR", /* CAIRO_OPERATOR_HSL_COLOR */ - "HSL_LUMINOSITY" /* CAIRO_OPERATOR_HSL_LUMINOSITY */ - }; - assert (op < ARRAY_LENGTH (names)); - return names[op]; -} - -static const char * -_extend_to_string (cairo_extend_t extend) -{ - static const char *names[] = { - "EXTEND_NONE", /* CAIRO_EXTEND_NONE */ - "EXTEND_REPEAT", /* CAIRO_EXTEND_REPEAT */ - "EXTEND_REFLECT", /* CAIRO_EXTEND_REFLECT */ - "EXTEND_PAD" /* CAIRO_EXTEND_PAD */ - }; - assert (extend < ARRAY_LENGTH (names)); - return names[extend]; -} - -static const char * -_filter_to_string (cairo_filter_t filter) -{ - static const char *names[] = { - "FILTER_FAST", /* CAIRO_FILTER_FAST */ - "FILTER_GOOD", /* CAIRO_FILTER_GOOD */ - "FILTER_BEST", /* CAIRO_FILTER_BEST */ - "FILTER_NEAREST", /* CAIRO_FILTER_NEAREST */ - "FILTER_BILINEAR", /* CAIRO_FILTER_BILINEAR */ - "FILTER_GAUSSIAN", /* CAIRO_FILTER_GAUSSIAN */ - }; - assert (filter < ARRAY_LENGTH (names)); - return names[filter]; -} - -static const char * -_fill_rule_to_string (cairo_fill_rule_t rule) -{ - static const char *names[] = { - "WINDING", /* CAIRO_FILL_RULE_WINDING */ - "EVEN_ODD" /* CAIRO_FILL_RILE_EVEN_ODD */ - }; - assert (rule < ARRAY_LENGTH (names)); - return names[rule]; -} - -static const char * -_antialias_to_string (cairo_antialias_t antialias) -{ - static const char *names[] = { - "DEFAULT", /* CAIRO_ANTIALIAS_DEFAULT */ - "NONE", /* CAIRO_ANTIALIAS_NONE */ - "GRAY", /* CAIRO_ANTIALIAS_GRAY */ - "SUBPIXEL", /* CAIRO_ANTIALIAS_SUBPIXEL */ - "FAST", /* CAIRO_ANTIALIAS_FAST */ - "GOOD", /* CAIRO_ANTIALIAS_GOOD */ - "BEST", /* CAIRO_ANTIALIAS_BEST */ - }; - assert (antialias < ARRAY_LENGTH (names)); - return names[antialias]; -} - -static const char * -_line_cap_to_string (cairo_line_cap_t line_cap) -{ - static const char *names[] = { - "LINE_CAP_BUTT", /* CAIRO_LINE_CAP_BUTT */ - "LINE_CAP_ROUND", /* CAIRO_LINE_CAP_ROUND */ - "LINE_CAP_SQUARE" /* CAIRO_LINE_CAP_SQUARE */ - }; - assert (line_cap < ARRAY_LENGTH (names)); - return names[line_cap]; -} - -static const char * -_line_join_to_string (cairo_line_join_t line_join) -{ - static const char *names[] = { - "LINE_JOIN_MITER", /* CAIRO_LINE_JOIN_MITER */ - "LINE_JOIN_ROUND", /* CAIRO_LINE_JOIN_ROUND */ - "LINE_JOIN_BEVEL", /* CAIRO_LINE_JOIN_BEVEL */ - }; - assert (line_join < ARRAY_LENGTH (names)); - return names[line_join]; -} - -static const char * -_content_to_string (cairo_content_t content) -{ - switch (content) { - case CAIRO_CONTENT_ALPHA: return "ALPHA"; - case CAIRO_CONTENT_COLOR: return "COLOR"; - default: - case CAIRO_CONTENT_COLOR_ALPHA: return "COLOR_ALPHA"; - } -} - -static const char * -_format_to_string (cairo_format_t format) -{ - switch (format) { - case CAIRO_FORMAT_ARGB32: return "ARGB32"; - case CAIRO_FORMAT_RGB30: return "RGB30"; - case CAIRO_FORMAT_RGB24: return "RGB24"; - case CAIRO_FORMAT_RGB16_565: return "RGB16_565"; - case CAIRO_FORMAT_A8: return "A8"; - case CAIRO_FORMAT_A1: return "A1"; - case CAIRO_FORMAT_INVALID: return "INVALID"; - } - ASSERT_NOT_REACHED; - return "INVALID"; -} - -static cairo_status_t -_device_flush (void *abstract_device) -{ - cairo_xml_t *xml = abstract_device; - cairo_status_t status; - - status = _cairo_output_stream_flush (xml->stream); - - return status; -} - -static void -_device_destroy (void *abstract_device) -{ - cairo_xml_t *xml = abstract_device; - cairo_status_t status; - - status = _cairo_output_stream_destroy (xml->stream); - - free (xml); -} - -static const cairo_device_backend_t _cairo_xml_device_backend = { - CAIRO_DEVICE_TYPE_XML, - - NULL, NULL, /* lock, unlock */ - - _device_flush, - NULL, /* finish */ - _device_destroy -}; - -static cairo_device_t * -_cairo_xml_create_internal (cairo_output_stream_t *stream) -{ - cairo_xml_t *xml; - - xml = malloc (sizeof (cairo_xml_t)); - if (unlikely (xml == NULL)) - return _cairo_device_create_in_error (CAIRO_STATUS_NO_MEMORY); - - memset (xml, 0, sizeof (cairo_xml_t)); - - _cairo_device_init (&xml->base, &_cairo_xml_device_backend); - - xml->indent = 0; - xml->stream = stream; - - return &xml->base; -} - -static void -_cairo_xml_indent (cairo_xml_t *xml, int indent) -{ - xml->indent += indent; - assert (xml->indent >= 0); -} - -static void CAIRO_PRINTF_FORMAT (2, 3) -_cairo_xml_printf (cairo_xml_t *xml, const char *fmt, ...) -{ - va_list ap; - char indent[80]; - int len; - - len = MIN (xml->indent, ARRAY_LENGTH (indent)); - memset (indent, ' ', len); - _cairo_output_stream_write (xml->stream, indent, len); - - va_start (ap, fmt); - _cairo_output_stream_vprintf (xml->stream, fmt, ap); - va_end (ap); - - _cairo_output_stream_write (xml->stream, "\n", 1); -} - -static void CAIRO_PRINTF_FORMAT (2, 3) -_cairo_xml_printf_start (cairo_xml_t *xml, const char *fmt, ...) -{ - char indent[80]; - int len; - - len = MIN (xml->indent, ARRAY_LENGTH (indent)); - memset (indent, ' ', len); - _cairo_output_stream_write (xml->stream, indent, len); - - if (fmt != NULL) { - va_list ap; - - va_start (ap, fmt); - _cairo_output_stream_vprintf (xml->stream, fmt, ap); - va_end (ap); - } -} - -static void CAIRO_PRINTF_FORMAT (2, 3) -_cairo_xml_printf_continue (cairo_xml_t *xml, const char *fmt, ...) -{ - va_list ap; - - va_start (ap, fmt); - _cairo_output_stream_vprintf (xml->stream, fmt, ap); - va_end (ap); -} - -static void CAIRO_PRINTF_FORMAT (2, 3) -_cairo_xml_printf_end (cairo_xml_t *xml, const char *fmt, ...) -{ - if (fmt != NULL) { - va_list ap; - - va_start (ap, fmt); - _cairo_output_stream_vprintf (xml->stream, fmt, ap); - va_end (ap); - } - - _cairo_output_stream_write (xml->stream, "\n", 1); -} - -static cairo_surface_t * -_cairo_xml_surface_create_similar (void *abstract_surface, - cairo_content_t content, - int width, - int height) -{ - cairo_rectangle_t extents; - - extents.x = extents.y = 0; - extents.width = width; - extents.height = height; - - return cairo_recording_surface_create (content, &extents); -} - -static cairo_bool_t -_cairo_xml_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *rectangle) -{ - cairo_xml_surface_t *surface = abstract_surface; - - if (surface->width < 0 || surface->height < 0) - return FALSE; - - rectangle->x = 0; - rectangle->y = 0; - rectangle->width = surface->width; - rectangle->height = surface->height; - - return TRUE; -} - -static cairo_status_t -_cairo_xml_move_to (void *closure, - const cairo_point_t *p1) -{ - _cairo_xml_printf_continue (closure, " %f %f m", - _cairo_fixed_to_double (p1->x), - _cairo_fixed_to_double (p1->y)); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_xml_line_to (void *closure, - const cairo_point_t *p1) -{ - _cairo_xml_printf_continue (closure, " %f %f l", - _cairo_fixed_to_double (p1->x), - _cairo_fixed_to_double (p1->y)); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_xml_curve_to (void *closure, - const cairo_point_t *p1, - const cairo_point_t *p2, - const cairo_point_t *p3) -{ - _cairo_xml_printf_continue (closure, " %f %f %f %f %f %f c", - _cairo_fixed_to_double (p1->x), - _cairo_fixed_to_double (p1->y), - _cairo_fixed_to_double (p2->x), - _cairo_fixed_to_double (p2->y), - _cairo_fixed_to_double (p3->x), - _cairo_fixed_to_double (p3->y)); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_xml_close_path (void *closure) -{ - _cairo_xml_printf_continue (closure, " h"); - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_xml_emit_path (cairo_xml_t *xml, - const cairo_path_fixed_t *path) -{ - cairo_status_t status; - - _cairo_xml_printf_start (xml, "<path>"); - status = _cairo_path_fixed_interpret (path, - _cairo_xml_move_to, - _cairo_xml_line_to, - _cairo_xml_curve_to, - _cairo_xml_close_path, - xml); - assert (status == CAIRO_STATUS_SUCCESS); - _cairo_xml_printf_end (xml, "</path>"); -} - -static void -_cairo_xml_emit_string (cairo_xml_t *xml, - const char *node, - const char *data) -{ - _cairo_xml_printf (xml, "<%s>%s</%s>", node, data, node); -} - -static void -_cairo_xml_emit_double (cairo_xml_t *xml, - const char *node, - double data) -{ - _cairo_xml_printf (xml, "<%s>%f</%s>", node, data, node); -} - -static cairo_xml_t * -to_xml (cairo_xml_surface_t *surface) -{ - return (cairo_xml_t *) surface->base.device; -} - -static cairo_status_t -_cairo_xml_surface_emit_clip_boxes (cairo_xml_surface_t *surface, - const cairo_clip_t *clip) -{ - cairo_box_t *box; - cairo_xml_t *xml; - int n; - - if (clip->num_boxes == 0) - return CAIRO_STATUS_SUCCESS; - - /* skip the trivial clip covering the surface extents */ - if (surface->width >= 0 && surface->height >= 0 && clip->num_boxes == 1) { - box = &clip->boxes[0]; - if (box->p1.x <= 0 && box->p1.y <= 0 && - box->p2.x - box->p1.x >= _cairo_fixed_from_double (surface->width) && - box->p2.y - box->p1.y >= _cairo_fixed_from_double (surface->height)) - { - return CAIRO_STATUS_SUCCESS; - } - } - - xml = to_xml (surface); - - _cairo_xml_printf (xml, "<clip>"); - _cairo_xml_indent (xml, 2); - - _cairo_xml_printf (xml, "<path>"); - _cairo_xml_indent (xml, 2); - for (n = 0; n < clip->num_boxes; n++) { - box = &clip->boxes[n]; - - _cairo_xml_printf_start (xml, "%f %f m", - _cairo_fixed_to_double (box->p1.x), - _cairo_fixed_to_double (box->p1.y)); - _cairo_xml_printf_continue (xml, " %f %f l", - _cairo_fixed_to_double (box->p2.x), - _cairo_fixed_to_double (box->p1.y)); - _cairo_xml_printf_continue (xml, " %f %f l", - _cairo_fixed_to_double (box->p2.x), - _cairo_fixed_to_double (box->p2.y)); - _cairo_xml_printf_continue (xml, " %f %f l", - _cairo_fixed_to_double (box->p1.x), - _cairo_fixed_to_double (box->p2.y)); - _cairo_xml_printf_end (xml, " h"); - } - _cairo_xml_indent (xml, -2); - _cairo_xml_printf (xml, "</path>"); - _cairo_xml_emit_double (xml, "tolerance", 1.0); - _cairo_xml_emit_string (xml, "antialias", - _antialias_to_string (CAIRO_ANTIALIAS_NONE)); - _cairo_xml_emit_string (xml, "fill-rule", - _fill_rule_to_string (CAIRO_FILL_RULE_WINDING)); - - _cairo_xml_indent (xml, -2); - _cairo_xml_printf (xml, "</clip>"); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_xml_surface_emit_clip_path (cairo_xml_surface_t *surface, - const cairo_clip_path_t *clip_path) -{ - cairo_box_t box; - cairo_status_t status; - cairo_xml_t *xml; - - if (clip_path == NULL) - return CAIRO_STATUS_SUCCESS; - - status = _cairo_xml_surface_emit_clip_path (surface, clip_path->prev); - if (unlikely (status)) - return status; - - /* skip the trivial clip covering the surface extents */ - if (surface->width >= 0 && surface->height >= 0 && - _cairo_path_fixed_is_box (&clip_path->path, &box)) - { - if (box.p1.x <= 0 && box.p1.y <= 0 && - box.p2.x - box.p1.x >= _cairo_fixed_from_double (surface->width) && - box.p2.y - box.p1.y >= _cairo_fixed_from_double (surface->height)) - { - return CAIRO_STATUS_SUCCESS; - } - } - - xml = to_xml (surface); - - _cairo_xml_printf_start (xml, "<clip>"); - _cairo_xml_indent (xml, 2); - - _cairo_xml_emit_path (xml, &clip_path->path); - _cairo_xml_emit_double (xml, "tolerance", clip_path->tolerance); - _cairo_xml_emit_string (xml, "antialias", - _antialias_to_string (clip_path->antialias)); - _cairo_xml_emit_string (xml, "fill-rule", - _fill_rule_to_string (clip_path->fill_rule)); - - _cairo_xml_indent (xml, -2); - _cairo_xml_printf_end (xml, "</clip>"); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_xml_surface_emit_clip (cairo_xml_surface_t *surface, - const cairo_clip_t *clip) -{ - cairo_status_t status; - - if (clip == NULL) - return CAIRO_STATUS_SUCCESS; - - status = _cairo_xml_surface_emit_clip_boxes (surface, clip); - if (unlikely (status)) - return status; - - return _cairo_xml_surface_emit_clip_path (surface, clip->path); -} - -static cairo_status_t -_cairo_xml_emit_solid (cairo_xml_t *xml, - const cairo_solid_pattern_t *solid) -{ - _cairo_xml_printf (xml, "<solid>%f %f %f %f</solid>", - solid->color.red, - solid->color.green, - solid->color.blue, - solid->color.alpha); - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_xml_emit_matrix (cairo_xml_t *xml, - const cairo_matrix_t *matrix) -{ - if (! _cairo_matrix_is_identity (matrix)) { - _cairo_xml_printf (xml, "<matrix>%f %f %f %f %f %f</matrix>", - matrix->xx, matrix->yx, - matrix->xy, matrix->yy, - matrix->x0, matrix->y0); - } -} - -static void -_cairo_xml_emit_gradient (cairo_xml_t *xml, - const cairo_gradient_pattern_t *gradient) -{ - unsigned int i; - - for (i = 0; i < gradient->n_stops; i++) { - _cairo_xml_printf (xml, - "<color-stop>%f %f %f %f %f</color-stop>", - gradient->stops[i].offset, - gradient->stops[i].color.red, - gradient->stops[i].color.green, - gradient->stops[i].color.blue, - gradient->stops[i].color.alpha); - } -} - -static cairo_status_t -_cairo_xml_emit_linear (cairo_xml_t *xml, - const cairo_linear_pattern_t *linear) -{ - _cairo_xml_printf (xml, - "<linear x1='%f' y1='%f' x2='%f' y2='%f'>", - linear->pd1.x, linear->pd1.y, - linear->pd2.x, linear->pd2.y); - _cairo_xml_indent (xml, 2); - _cairo_xml_emit_gradient (xml, &linear->base); - _cairo_xml_indent (xml, -2); - _cairo_xml_printf (xml, "</linear>"); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_xml_emit_radial (cairo_xml_t *xml, - const cairo_radial_pattern_t *radial) -{ - _cairo_xml_printf (xml, - "<radial x1='%f' y1='%f' r1='%f' x2='%f' y2='%f' r2='%f'>", - radial->cd1.center.x, radial->cd1.center.y, radial->cd1.radius, - radial->cd2.center.x, radial->cd2.center.y, radial->cd2.radius); - _cairo_xml_indent (xml, 2); - _cairo_xml_emit_gradient (xml, &radial->base); - _cairo_xml_indent (xml, -2); - _cairo_xml_printf (xml, "</radial>"); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_write_func (void *closure, const unsigned char *data, unsigned len) -{ - _cairo_output_stream_write (closure, data, len); - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_xml_emit_image (cairo_xml_t *xml, - cairo_image_surface_t *image) -{ - cairo_output_stream_t *stream; - cairo_status_t status; - - _cairo_xml_printf_start (xml, - "<image width='%d' height='%d' format='%s'>", - image->width, image->height, - _format_to_string (image->format)); - - stream = _cairo_base64_stream_create (xml->stream); - status = cairo_surface_write_to_png_stream (&image->base, - _write_func, stream); - assert (status == CAIRO_STATUS_SUCCESS); - status = _cairo_output_stream_destroy (stream); - if (unlikely (status)) - return status; - - _cairo_xml_printf_end (xml, "</image>"); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_xml_emit_surface (cairo_xml_t *xml, - const cairo_surface_pattern_t *pattern) -{ - cairo_surface_t *source = pattern->surface; - cairo_status_t status; - - if (_cairo_surface_is_recording (source)) { - status = cairo_xml_for_recording_surface (&xml->base, source); - } else { - cairo_image_surface_t *image; - void *image_extra; - - status = _cairo_surface_acquire_source_image (source, - &image, &image_extra); - if (unlikely (status)) - return status; - - status = _cairo_xml_emit_image (xml, image); - - _cairo_surface_release_source_image (source, image, image_extra); - } - - return status; -} - -static cairo_status_t -_cairo_xml_emit_pattern (cairo_xml_t *xml, - const char *source_or_mask, - const cairo_pattern_t *pattern) -{ - cairo_status_t status; - - _cairo_xml_printf (xml, "<%s-pattern>", source_or_mask); - _cairo_xml_indent (xml, 2); - - switch (pattern->type) { - case CAIRO_PATTERN_TYPE_SOLID: - status = _cairo_xml_emit_solid (xml, (cairo_solid_pattern_t *) pattern); - break; - case CAIRO_PATTERN_TYPE_LINEAR: - status = _cairo_xml_emit_linear (xml, (cairo_linear_pattern_t *) pattern); - break; - case CAIRO_PATTERN_TYPE_RADIAL: - status = _cairo_xml_emit_radial (xml, (cairo_radial_pattern_t *) pattern); - break; - case CAIRO_PATTERN_TYPE_SURFACE: - status = _cairo_xml_emit_surface (xml, (cairo_surface_pattern_t *) pattern); - break; - default: - ASSERT_NOT_REACHED; - status = CAIRO_INT_STATUS_UNSUPPORTED; - break; - } - - if (pattern->type != CAIRO_PATTERN_TYPE_SOLID) { - _cairo_xml_emit_matrix (xml, &pattern->matrix); - _cairo_xml_printf (xml, - "<extend>%s</extend>", - _extend_to_string (pattern->extend)); - _cairo_xml_printf (xml, - "<filter>%s</filter>", - _filter_to_string (pattern->filter)); - } - - _cairo_xml_indent (xml, -2); - _cairo_xml_printf (xml, "</%s-pattern>", source_or_mask); - - return status; -} - -static cairo_int_status_t -_cairo_xml_surface_paint (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - cairo_xml_surface_t *surface = abstract_surface; - cairo_xml_t *xml = to_xml (surface); - cairo_status_t status; - - _cairo_xml_printf (xml, "<paint>"); - _cairo_xml_indent (xml, 2); - - _cairo_xml_emit_string (xml, "operator", _operator_to_string (op)); - - status = _cairo_xml_surface_emit_clip (surface, clip); - if (unlikely (status)) - return status; - - status = _cairo_xml_emit_pattern (xml, "source", source); - if (unlikely (status)) - return status; - - _cairo_xml_indent (xml, -2); - _cairo_xml_printf (xml, "</paint>"); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_xml_surface_mask (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - cairo_xml_surface_t *surface = abstract_surface; - cairo_xml_t *xml = to_xml (surface); - cairo_status_t status; - - _cairo_xml_printf (xml, "<mask>"); - _cairo_xml_indent (xml, 2); - - _cairo_xml_emit_string (xml, "operator", _operator_to_string (op)); - - status = _cairo_xml_surface_emit_clip (surface, clip); - if (unlikely (status)) - return status; - - status = _cairo_xml_emit_pattern (xml, "source", source); - if (unlikely (status)) - return status; - - status = _cairo_xml_emit_pattern (xml, "mask", mask); - if (unlikely (status)) - return status; - - _cairo_xml_indent (xml, -2); - _cairo_xml_printf (xml, "</mask>"); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_xml_surface_stroke (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_xml_surface_t *surface = abstract_surface; - cairo_xml_t *xml = to_xml (surface); - cairo_status_t status; - - _cairo_xml_printf (xml, "<stroke>"); - _cairo_xml_indent (xml, 2); - - _cairo_xml_emit_string (xml, "operator", _operator_to_string (op)); - _cairo_xml_emit_double (xml, "line-width", style->line_width); - _cairo_xml_emit_double (xml, "miter-limit", style->miter_limit); - _cairo_xml_emit_string (xml, "line-cap", _line_cap_to_string (style->line_cap)); - _cairo_xml_emit_string (xml, "line-join", _line_join_to_string (style->line_join)); - - status = _cairo_xml_surface_emit_clip (surface, clip); - if (unlikely (status)) - return status; - - status = _cairo_xml_emit_pattern (xml, "source", source); - if (unlikely (status)) - return status; - - if (style->num_dashes) { - unsigned int i; - - _cairo_xml_printf_start (xml, "<dash offset='%f'>", - style->dash_offset); - for (i = 0; i < style->num_dashes; i++) - _cairo_xml_printf_continue (xml, "%f ", style->dash[i]); - - _cairo_xml_printf_end (xml, "</dash>"); - } - - _cairo_xml_emit_path (xml, path); - _cairo_xml_emit_double (xml, "tolerance", tolerance); - _cairo_xml_emit_string (xml, "antialias", _antialias_to_string (antialias)); - - _cairo_xml_emit_matrix (xml, ctm); - - _cairo_xml_indent (xml, -2); - _cairo_xml_printf (xml, "</stroke>"); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -_cairo_xml_surface_fill (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t*path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - cairo_xml_surface_t *surface = abstract_surface; - cairo_xml_t *xml = to_xml (surface); - cairo_status_t status; - - _cairo_xml_printf (xml, "<fill>"); - _cairo_xml_indent (xml, 2); - - _cairo_xml_emit_string (xml, "operator", _operator_to_string (op)); - - status = _cairo_xml_surface_emit_clip (surface, clip); - if (unlikely (status)) - return status; - - status = _cairo_xml_emit_pattern (xml, "source", source); - if (unlikely (status)) - return status; - - _cairo_xml_emit_path (xml, path); - _cairo_xml_emit_double (xml, "tolerance", tolerance); - _cairo_xml_emit_string (xml, "antialias", _antialias_to_string (antialias)); - _cairo_xml_emit_string (xml, "fill-rule", _fill_rule_to_string (fill_rule)); - - _cairo_xml_indent (xml, -2); - _cairo_xml_printf (xml, "</fill>"); - - return CAIRO_STATUS_SUCCESS; -} - -#if CAIRO_HAS_FT_FONT -#include "cairo-ft-private.h" -static cairo_status_t -_cairo_xml_emit_type42_font (cairo_xml_t *xml, - cairo_scaled_font_t *scaled_font) -{ - const cairo_scaled_font_backend_t *backend; - cairo_output_stream_t *base64_stream; - cairo_output_stream_t *zlib_stream; - cairo_status_t status, status2; - unsigned long size; - uint32_t len; - uint8_t *buf; - - backend = scaled_font->backend; - if (backend->load_truetype_table == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - size = 0; - status = backend->load_truetype_table (scaled_font, 0, 0, NULL, &size); - if (unlikely (status)) - return status; - - buf = malloc (size); - if (unlikely (buf == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - status = backend->load_truetype_table (scaled_font, 0, 0, buf, &size); - if (unlikely (status)) { - free (buf); - return status; - } - - _cairo_xml_printf_start (xml, "<font type='42' flags='%d' index='0'>", - _cairo_ft_scaled_font_get_load_flags (scaled_font)); - - - base64_stream = _cairo_base64_stream_create (xml->stream); - len = size; - _cairo_output_stream_write (base64_stream, &len, sizeof (len)); - - zlib_stream = _cairo_deflate_stream_create (base64_stream); - - _cairo_output_stream_write (zlib_stream, buf, size); - free (buf); - - status2 = _cairo_output_stream_destroy (zlib_stream); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - - status2 = _cairo_output_stream_destroy (base64_stream); - if (status == CAIRO_STATUS_SUCCESS) - status = status2; - - _cairo_xml_printf_end (xml, "</font>"); - - return status; -} -#else -static cairo_status_t -_cairo_xml_emit_type42_font (cairo_xml_t *xml, - cairo_scaled_font_t *scaled_font) -{ - return CAIRO_INT_STATUS_UNSUPPORTED; -} -#endif - -static cairo_status_t -_cairo_xml_emit_type3_font (cairo_xml_t *xml, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int num_glyphs) -{ - _cairo_xml_printf_start (xml, "<font type='3'>"); - _cairo_xml_printf_end (xml, "</font>"); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_xml_emit_scaled_font (cairo_xml_t *xml, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int num_glyphs) -{ - cairo_int_status_t status; - - _cairo_xml_printf (xml, "<scaled-font>"); - _cairo_xml_indent (xml, 2); - - status = _cairo_xml_emit_type42_font (xml, scaled_font); - if (status == CAIRO_INT_STATUS_UNSUPPORTED) { - status = _cairo_xml_emit_type3_font (xml, scaled_font, - glyphs, num_glyphs); - } - - _cairo_xml_indent (xml, -2); - _cairo_xml_printf (xml, "<scaled-font>"); - - return status; -} - -static cairo_int_status_t -_cairo_xml_surface_glyphs (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - cairo_xml_surface_t *surface = abstract_surface; - cairo_xml_t *xml = to_xml (surface); - cairo_status_t status; - int i; - - _cairo_xml_printf (xml, "<glyphs>"); - _cairo_xml_indent (xml, 2); - - _cairo_xml_emit_string (xml, "operator", _operator_to_string (op)); - - status = _cairo_xml_surface_emit_clip (surface, clip); - if (unlikely (status)) - return status; - - status = _cairo_xml_emit_pattern (xml, "source", source); - if (unlikely (status)) - return status; - - status = _cairo_xml_emit_scaled_font (xml, scaled_font, glyphs, num_glyphs); - if (unlikely (status)) - return status; - - for (i = 0; i < num_glyphs; i++) { - _cairo_xml_printf (xml, "<glyph index='%lu'>%f %f</glyph>", - glyphs[i].index, - glyphs[i].x, - glyphs[i].y); - } - - _cairo_xml_indent (xml, -2); - _cairo_xml_printf (xml, "</glyphs>"); - - return CAIRO_STATUS_SUCCESS; -} - -static const cairo_surface_backend_t -_cairo_xml_surface_backend = { - CAIRO_SURFACE_TYPE_XML, - NULL, - - _cairo_default_context_create, - - _cairo_xml_surface_create_similar, - NULL, /* create_similar_image */ - NULL, /* map_to_image */ - NULL, /* unmap_image */ - - _cairo_surface_default_source, - NULL, /* acquire source image */ - NULL, /* release source image */ - NULL, /* snapshot */ - - NULL, /* copy page */ - NULL, /* show page */ - - _cairo_xml_surface_get_extents, - NULL, /* get_font_options */ - - NULL, /* flush */ - NULL, /* mark_dirty_rectangle */ - - _cairo_xml_surface_paint, - _cairo_xml_surface_mask, - _cairo_xml_surface_stroke, - _cairo_xml_surface_fill, - NULL, /* fill_stroke */ - _cairo_xml_surface_glyphs, -}; - -static cairo_surface_t * -_cairo_xml_surface_create_internal (cairo_device_t *device, - cairo_content_t content, - double width, - double height) -{ - cairo_xml_surface_t *surface; - - surface = malloc (sizeof (cairo_xml_surface_t)); - if (unlikely (surface == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - _cairo_surface_init (&surface->base, - &_cairo_xml_surface_backend, - device, - content); - - surface->width = width; - surface->height = height; - - return &surface->base; -} - -cairo_device_t * -cairo_xml_create (const char *filename) -{ - cairo_output_stream_t *stream; - cairo_status_t status; - - stream = _cairo_output_stream_create_for_filename (filename); - if ((status = _cairo_output_stream_get_status (stream))) - return _cairo_device_create_in_error (status); - - return _cairo_xml_create_internal (stream); -} - -cairo_device_t * -cairo_xml_create_for_stream (cairo_write_func_t write_func, - void *closure) -{ - cairo_output_stream_t *stream; - cairo_status_t status; - - stream = _cairo_output_stream_create (write_func, NULL, closure); - if ((status = _cairo_output_stream_get_status (stream))) - return _cairo_device_create_in_error (status); - - return _cairo_xml_create_internal (stream); -} - -cairo_surface_t * -cairo_xml_surface_create (cairo_device_t *device, - cairo_content_t content, - double width, double height) -{ - if (unlikely (device->backend->type != CAIRO_DEVICE_TYPE_XML)) - return _cairo_surface_create_in_error (CAIRO_STATUS_DEVICE_TYPE_MISMATCH); - - if (unlikely (device->status)) - return _cairo_surface_create_in_error (device->status); - - return _cairo_xml_surface_create_internal (device, content, width, height); -} - -cairo_status_t -cairo_xml_for_recording_surface (cairo_device_t *device, - cairo_surface_t *recording_surface) -{ - cairo_box_t bbox; - cairo_rectangle_int_t extents; - cairo_surface_t *surface; - cairo_xml_t *xml; - cairo_status_t status; - - if (unlikely (device->status)) - return device->status; - - if (unlikely (recording_surface->status)) - return recording_surface->status; - - if (unlikely (device->backend->type != CAIRO_DEVICE_TYPE_XML)) - return _cairo_error (CAIRO_STATUS_DEVICE_TYPE_MISMATCH); - - if (unlikely (! _cairo_surface_is_recording (recording_surface))) - return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - - status = _cairo_recording_surface_get_bbox ((cairo_recording_surface_t *) recording_surface, - &bbox, NULL); - if (unlikely (status)) - return status; - - _cairo_box_round_to_rectangle (&bbox, &extents); - surface = _cairo_xml_surface_create_internal (device, - recording_surface->content, - extents.width, - extents.height); - if (unlikely (surface->status)) - return surface->status; - - xml = (cairo_xml_t *) device; - - _cairo_xml_printf (xml, - "<surface content='%s' width='%d' height='%d'>", - _content_to_string (recording_surface->content), - extents.width, extents.height); - _cairo_xml_indent (xml, 2); - - cairo_surface_set_device_offset (surface, -extents.x, -extents.y); - status = _cairo_recording_surface_replay (recording_surface, surface); - cairo_surface_destroy (surface); - - _cairo_xml_indent (xml, -2); - _cairo_xml_printf (xml, "</surface>"); - - return status; -} -slim_hidden_def (cairo_xml_for_recording_surface); diff --git a/source/libs/cairo/cairo-src/src/cairo-xml.h b/source/libs/cairo/cairo-src/src/cairo-xml.h deleted file mode 100644 index 9ae76e90aae92cb3ef05c3ce4a7abfdbddd39011..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo-xml.h +++ /dev/null @@ -1,67 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2009 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Chris Wilson - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef CAIRO_XML_H -#define CAIRO_XML_H - -#include "cairo.h" - -#if CAIRO_HAS_XML_SURFACE - -CAIRO_BEGIN_DECLS - -cairo_public cairo_device_t * -cairo_xml_create (const char *filename); - -cairo_public cairo_device_t * -cairo_xml_create_for_stream (cairo_write_func_t write_func, - void *closure); - -cairo_public cairo_surface_t * -cairo_xml_surface_create (cairo_device_t *xml, - cairo_content_t content, - double width, double height); - -cairo_public cairo_status_t -cairo_xml_for_recording_surface (cairo_device_t *xml, - cairo_surface_t *surface); - -CAIRO_END_DECLS - -#else /*CAIRO_HAS_XML_SURFACE*/ -# error Cairo was not compiled with support for the XML backend -#endif /*CAIRO_HAS_XML_SURFACE*/ - -#endif /*CAIRO_XML_H*/ diff --git a/source/libs/cairo/cairo-src/src/cairo.c b/source/libs/cairo/cairo-src/src/cairo.c deleted file mode 100644 index e3acf4d46c7c39a3aa777ed592bdc22d41444d22..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo.c +++ /dev/null @@ -1,4031 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" -#include "cairo-private.h" - -#include "cairo-backend-private.h" -#include "cairo-error-private.h" -#include "cairo-path-private.h" -#include "cairo-pattern-private.h" -#include "cairo-surface-private.h" -#include "cairo-surface-backend-private.h" - -#include <assert.h> - -/** - * SECTION:cairo - * @Title: cairo_t - * @Short_Description: The cairo drawing context - * @See_Also: #cairo_surface_t - * - * #cairo_t is the main object used when drawing with cairo. To - * draw with cairo, you create a #cairo_t, set the target surface, - * and drawing options for the #cairo_t, create shapes with - * functions like cairo_move_to() and cairo_line_to(), and then - * draw shapes with cairo_stroke() or cairo_fill(). - * - * #cairo_t<!-- -->'s can be pushed to a stack via cairo_save(). - * They may then safely be changed, without losing the current state. - * Use cairo_restore() to restore to the saved state. - **/ - -/** - * SECTION:cairo-text - * @Title: text - * @Short_Description: Rendering text and glyphs - * @See_Also: #cairo_font_face_t, #cairo_scaled_font_t, cairo_text_path(), - * cairo_glyph_path() - * - * The functions with <emphasis>text</emphasis> in their name form cairo's - * <firstterm>toy</firstterm> text API. The toy API takes UTF-8 encoded - * text and is limited in its functionality to rendering simple - * left-to-right text with no advanced features. That means for example - * that most complex scripts like Hebrew, Arabic, and Indic scripts are - * out of question. No kerning or correct positioning of diacritical marks - * either. The font selection is pretty limited too and doesn't handle the - * case that the selected font does not cover the characters in the text. - * This set of functions are really that, a toy text API, for testing and - * demonstration purposes. Any serious application should avoid them. - * - * The functions with <emphasis>glyphs</emphasis> in their name form cairo's - * <firstterm>low-level</firstterm> text API. The low-level API relies on - * the user to convert text to a set of glyph indexes and positions. This - * is a very hard problem and is best handled by external libraries, like - * the pangocairo that is part of the Pango text layout and rendering library. - * Pango is available from <ulink - * url="http://www.pango.org/">http://www.pango.org/</ulink>. - **/ - -/** - * SECTION:cairo-transforms - * @Title: Transformations - * @Short_Description: Manipulating the current transformation matrix - * @See_Also: #cairo_matrix_t - * - * The current transformation matrix, <firstterm>ctm</firstterm>, is a - * two-dimensional affine transformation that maps all coordinates and other - * drawing instruments from the <firstterm>user space</firstterm> into the - * surface's canonical coordinate system, also known as the <firstterm>device - * space</firstterm>. - **/ - -#define DEFINE_NIL_CONTEXT(status) \ - { \ - CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ \ - status, /* status */ \ - { 0, 0, 0, NULL }, /* user_data */ \ - NULL \ - } - -static const cairo_t _cairo_nil[] = { - DEFINE_NIL_CONTEXT (CAIRO_STATUS_NO_MEMORY), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_RESTORE), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_POP_GROUP), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_NO_CURRENT_POINT), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_MATRIX), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_STATUS), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_NULL_POINTER), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_STRING), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_PATH_DATA), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_READ_ERROR), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_WRITE_ERROR), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_SURFACE_FINISHED), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_SURFACE_TYPE_MISMATCH), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_PATTERN_TYPE_MISMATCH), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_CONTENT), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_FORMAT), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_VISUAL), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_FILE_NOT_FOUND), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_DASH), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_DSC_COMMENT), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_INDEX), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_TEMP_FILE_ERROR), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_STRIDE), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_FONT_TYPE_MISMATCH), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_USER_FONT_IMMUTABLE), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_USER_FONT_ERROR), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_NEGATIVE_COUNT), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_CLUSTERS), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_SLANT), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_WEIGHT), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_SIZE), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_DEVICE_TYPE_MISMATCH), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_DEVICE_ERROR), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_MESH_CONSTRUCTION), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_DEVICE_FINISHED), - DEFINE_NIL_CONTEXT (CAIRO_STATUS_JBIG2_GLOBAL_MISSING) - -}; -COMPILE_TIME_ASSERT (ARRAY_LENGTH (_cairo_nil) == CAIRO_STATUS_LAST_STATUS - 1); - -/** - * _cairo_set_error: - * @cr: a cairo context - * @status: a status value indicating an error - * - * Atomically sets cr->status to @status and calls _cairo_error; - * Does nothing if status is %CAIRO_STATUS_SUCCESS. - * - * All assignments of an error status to cr->status should happen - * through _cairo_set_error(). Note that due to the nature of the atomic - * operation, it is not safe to call this function on the nil objects. - * - * The purpose of this function is to allow the user to set a - * breakpoint in _cairo_error() to generate a stack trace for when the - * user causes cairo to detect an error. - **/ -static void -_cairo_set_error (cairo_t *cr, cairo_status_t status) -{ - /* Don't overwrite an existing error. This preserves the first - * error, which is the most significant. */ - _cairo_status_set_error (&cr->status, _cairo_error (status)); -} - -cairo_t * -_cairo_create_in_error (cairo_status_t status) -{ - cairo_t *cr; - - assert (status != CAIRO_STATUS_SUCCESS); - - cr = (cairo_t *) &_cairo_nil[status - CAIRO_STATUS_NO_MEMORY]; - assert (status == cr->status); - - return cr; -} - -/** - * cairo_create: - * @target: target surface for the context - * - * Creates a new #cairo_t with all graphics state parameters set to - * default values and with @target as a target surface. The target - * surface should be constructed with a backend-specific function such - * as cairo_image_surface_create() (or any other - * <function>cairo_<emphasis>backend</emphasis>_surface_create(<!-- -->)</function> - * variant). - * - * This function references @target, so you can immediately - * call cairo_surface_destroy() on it if you don't need to - * maintain a separate reference to it. - * - * Return value: a newly allocated #cairo_t with a reference - * count of 1. The initial reference count should be released - * with cairo_destroy() when you are done using the #cairo_t. - * This function never returns %NULL. If memory cannot be - * allocated, a special #cairo_t object will be returned on - * which cairo_status() returns %CAIRO_STATUS_NO_MEMORY. If - * you attempt to target a surface which does not support - * writing (such as #cairo_mime_surface_t) then a - * %CAIRO_STATUS_WRITE_ERROR will be raised. You can use this - * object normally, but no drawing will be done. - * - * Since: 1.0 - **/ -cairo_t * -cairo_create (cairo_surface_t *target) -{ - if (unlikely (target == NULL)) - return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_NULL_POINTER)); - if (unlikely (target->status)) - return _cairo_create_in_error (target->status); - if (unlikely (target->finished)) - return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - - if (target->backend->create_context == NULL) - return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_WRITE_ERROR)); - - return target->backend->create_context (target); - -} -slim_hidden_def (cairo_create); - -void -_cairo_init (cairo_t *cr, - const cairo_backend_t *backend) -{ - CAIRO_REFERENCE_COUNT_INIT (&cr->ref_count, 1); - cr->status = CAIRO_STATUS_SUCCESS; - _cairo_user_data_array_init (&cr->user_data); - - cr->backend = backend; -} - -/** - * cairo_reference: - * @cr: a #cairo_t - * - * Increases the reference count on @cr by one. This prevents - * @cr from being destroyed until a matching call to cairo_destroy() - * is made. - * - * The number of references to a #cairo_t can be get using - * cairo_get_reference_count(). - * - * Return value: the referenced #cairo_t. - * - * Since: 1.0 - **/ -cairo_t * -cairo_reference (cairo_t *cr) -{ - if (cr == NULL || CAIRO_REFERENCE_COUNT_IS_INVALID (&cr->ref_count)) - return cr; - - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&cr->ref_count)); - - _cairo_reference_count_inc (&cr->ref_count); - - return cr; -} - -void -_cairo_fini (cairo_t *cr) -{ - _cairo_user_data_array_fini (&cr->user_data); -} - -/** - * cairo_destroy: - * @cr: a #cairo_t - * - * Decreases the reference count on @cr by one. If the result - * is zero, then @cr and all associated resources are freed. - * See cairo_reference(). - * - * Since: 1.0 - **/ -void -cairo_destroy (cairo_t *cr) -{ - if (cr == NULL || CAIRO_REFERENCE_COUNT_IS_INVALID (&cr->ref_count)) - return; - - assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&cr->ref_count)); - - if (! _cairo_reference_count_dec_and_test (&cr->ref_count)) - return; - - cr->backend->destroy (cr); -} -slim_hidden_def (cairo_destroy); - -/** - * cairo_get_user_data: - * @cr: a #cairo_t - * @key: the address of the #cairo_user_data_key_t the user data was - * attached to - * - * Return user data previously attached to @cr using the specified - * key. If no user data has been attached with the given key this - * function returns %NULL. - * - * Return value: the user data previously attached or %NULL. - * - * Since: 1.4 - **/ -void * -cairo_get_user_data (cairo_t *cr, - const cairo_user_data_key_t *key) -{ - return _cairo_user_data_array_get_data (&cr->user_data, key); -} - -/** - * cairo_set_user_data: - * @cr: a #cairo_t - * @key: the address of a #cairo_user_data_key_t to attach the user data to - * @user_data: the user data to attach to the #cairo_t - * @destroy: a #cairo_destroy_func_t which will be called when the - * #cairo_t is destroyed or when new user data is attached using the - * same key. - * - * Attach user data to @cr. To remove user data from a surface, - * call this function with the key that was used to set it and %NULL - * for @data. - * - * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a - * slot could not be allocated for the user data. - * - * Since: 1.4 - **/ -cairo_status_t -cairo_set_user_data (cairo_t *cr, - const cairo_user_data_key_t *key, - void *user_data, - cairo_destroy_func_t destroy) -{ - if (CAIRO_REFERENCE_COUNT_IS_INVALID (&cr->ref_count)) - return cr->status; - - return _cairo_user_data_array_set_data (&cr->user_data, - key, user_data, destroy); -} - -/** - * cairo_get_reference_count: - * @cr: a #cairo_t - * - * Returns the current reference count of @cr. - * - * Return value: the current reference count of @cr. If the - * object is a nil object, 0 will be returned. - * - * Since: 1.4 - **/ -unsigned int -cairo_get_reference_count (cairo_t *cr) -{ - if (cr == NULL || CAIRO_REFERENCE_COUNT_IS_INVALID (&cr->ref_count)) - return 0; - - return CAIRO_REFERENCE_COUNT_GET_VALUE (&cr->ref_count); -} - -/** - * cairo_save: - * @cr: a #cairo_t - * - * Makes a copy of the current state of @cr and saves it - * on an internal stack of saved states for @cr. When - * cairo_restore() is called, @cr will be restored to - * the saved state. Multiple calls to cairo_save() and - * cairo_restore() can be nested; each call to cairo_restore() - * restores the state from the matching paired cairo_save(). - * - * It isn't necessary to clear all saved states before - * a #cairo_t is freed. If the reference count of a #cairo_t - * drops to zero in response to a call to cairo_destroy(), - * any saved states will be freed along with the #cairo_t. - * - * Since: 1.0 - **/ -void -cairo_save (cairo_t *cr) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->save (cr); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def(cairo_save); - -/** - * cairo_restore: - * @cr: a #cairo_t - * - * Restores @cr to the state saved by a preceding call to - * cairo_save() and removes that state from the stack of - * saved states. - * - * Since: 1.0 - **/ -void -cairo_restore (cairo_t *cr) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->restore (cr); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def(cairo_restore); - -/** - * cairo_push_group: - * @cr: a cairo context - * - * Temporarily redirects drawing to an intermediate surface known as a - * group. The redirection lasts until the group is completed by a call - * to cairo_pop_group() or cairo_pop_group_to_source(). These calls - * provide the result of any drawing to the group as a pattern, - * (either as an explicit object, or set as the source pattern). - * - * This group functionality can be convenient for performing - * intermediate compositing. One common use of a group is to render - * objects as opaque within the group, (so that they occlude each - * other), and then blend the result with translucence onto the - * destination. - * - * Groups can be nested arbitrarily deep by making balanced calls to - * cairo_push_group()/cairo_pop_group(). Each call pushes/pops the new - * target group onto/from a stack. - * - * The cairo_push_group() function calls cairo_save() so that any - * changes to the graphics state will not be visible outside the - * group, (the pop_group functions call cairo_restore()). - * - * By default the intermediate group will have a content type of - * %CAIRO_CONTENT_COLOR_ALPHA. Other content types can be chosen for - * the group by using cairo_push_group_with_content() instead. - * - * As an example, here is how one might fill and stroke a path with - * translucence, but without any portion of the fill being visible - * under the stroke: - * - * <informalexample><programlisting> - * cairo_push_group (cr); - * cairo_set_source (cr, fill_pattern); - * cairo_fill_preserve (cr); - * cairo_set_source (cr, stroke_pattern); - * cairo_stroke (cr); - * cairo_pop_group_to_source (cr); - * cairo_paint_with_alpha (cr, alpha); - * </programlisting></informalexample> - * - * Since: 1.2 - **/ -void -cairo_push_group (cairo_t *cr) -{ - cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR_ALPHA); -} - -/** - * cairo_push_group_with_content: - * @cr: a cairo context - * @content: a #cairo_content_t indicating the type of group that - * will be created - * - * Temporarily redirects drawing to an intermediate surface known as a - * group. The redirection lasts until the group is completed by a call - * to cairo_pop_group() or cairo_pop_group_to_source(). These calls - * provide the result of any drawing to the group as a pattern, - * (either as an explicit object, or set as the source pattern). - * - * The group will have a content type of @content. The ability to - * control this content type is the only distinction between this - * function and cairo_push_group() which you should see for a more - * detailed description of group rendering. - * - * Since: 1.2 - **/ -void -cairo_push_group_with_content (cairo_t *cr, cairo_content_t content) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->push_group (cr, content); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def(cairo_push_group_with_content); - -/** - * cairo_pop_group: - * @cr: a cairo context - * - * Terminates the redirection begun by a call to cairo_push_group() or - * cairo_push_group_with_content() and returns a new pattern - * containing the results of all drawing operations performed to the - * group. - * - * The cairo_pop_group() function calls cairo_restore(), (balancing a - * call to cairo_save() by the push_group function), so that any - * changes to the graphics state will not be visible outside the - * group. - * - * Return value: a newly created (surface) pattern containing the - * results of all drawing operations performed to the group. The - * caller owns the returned object and should call - * cairo_pattern_destroy() when finished with it. - * - * Since: 1.2 - **/ -cairo_pattern_t * -cairo_pop_group (cairo_t *cr) -{ - cairo_pattern_t *group_pattern; - - if (unlikely (cr->status)) - return _cairo_pattern_create_in_error (cr->status); - - group_pattern = cr->backend->pop_group (cr); - if (unlikely (group_pattern->status)) - _cairo_set_error (cr, group_pattern->status); - - return group_pattern; -} -slim_hidden_def(cairo_pop_group); - -/** - * cairo_pop_group_to_source: - * @cr: a cairo context - * - * Terminates the redirection begun by a call to cairo_push_group() or - * cairo_push_group_with_content() and installs the resulting pattern - * as the source pattern in the given cairo context. - * - * The behavior of this function is equivalent to the sequence of - * operations: - * - * <informalexample><programlisting> - * cairo_pattern_t *group = cairo_pop_group (cr); - * cairo_set_source (cr, group); - * cairo_pattern_destroy (group); - * </programlisting></informalexample> - * - * but is more convenient as their is no need for a variable to store - * the short-lived pointer to the pattern. - * - * The cairo_pop_group() function calls cairo_restore(), (balancing a - * call to cairo_save() by the push_group function), so that any - * changes to the graphics state will not be visible outside the - * group. - * - * Since: 1.2 - **/ -void -cairo_pop_group_to_source (cairo_t *cr) -{ - cairo_pattern_t *group_pattern; - - group_pattern = cairo_pop_group (cr); - cairo_set_source (cr, group_pattern); - cairo_pattern_destroy (group_pattern); -} - -/** - * cairo_set_operator: - * @cr: a #cairo_t - * @op: a compositing operator, specified as a #cairo_operator_t - * - * Sets the compositing operator to be used for all drawing - * operations. See #cairo_operator_t for details on the semantics of - * each available compositing operator. - * - * The default operator is %CAIRO_OPERATOR_OVER. - * - * Since: 1.0 - **/ -void -cairo_set_operator (cairo_t *cr, cairo_operator_t op) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->set_operator (cr, op); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def (cairo_set_operator); - - -#if 0 -/** - * cairo_set_opacity: - * @cr: a #cairo_t - * @opacity: the level of opacity to use when compositing - * - * Sets the compositing opacity to be used for all drawing - * operations. The effect is to fade out the operations - * using the alpha value. - * - * The default opacity is 1. - * - * Since: TBD - **/ -void -cairo_set_opacity (cairo_t *cr, double opacity) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->set_opacity (cr, opacity); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -#endif - -/** - * cairo_set_source_rgb: - * @cr: a cairo context - * @red: red component of color - * @green: green component of color - * @blue: blue component of color - * - * Sets the source pattern within @cr to an opaque color. This opaque - * color will then be used for any subsequent drawing operation until - * a new source pattern is set. - * - * The color components are floating point numbers in the range 0 to - * 1. If the values passed in are outside that range, they will be - * clamped. - * - * The default source pattern is opaque black, (that is, it is - * equivalent to cairo_set_source_rgb(cr, 0.0, 0.0, 0.0)). - * - * Since: 1.0 - **/ -void -cairo_set_source_rgb (cairo_t *cr, double red, double green, double blue) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->set_source_rgba (cr, red, green, blue, 1.); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def (cairo_set_source_rgb); - -/** - * cairo_set_source_rgba: - * @cr: a cairo context - * @red: red component of color - * @green: green component of color - * @blue: blue component of color - * @alpha: alpha component of color - * - * Sets the source pattern within @cr to a translucent color. This - * color will then be used for any subsequent drawing operation until - * a new source pattern is set. - * - * The color and alpha components are floating point numbers in the - * range 0 to 1. If the values passed in are outside that range, they - * will be clamped. - * - * The default source pattern is opaque black, (that is, it is - * equivalent to cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 1.0)). - * - * Since: 1.0 - **/ -void -cairo_set_source_rgba (cairo_t *cr, - double red, double green, double blue, - double alpha) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->set_source_rgba (cr, red, green, blue, alpha); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_set_source_surface: - * @cr: a cairo context - * @surface: a surface to be used to set the source pattern - * @x: User-space X coordinate for surface origin - * @y: User-space Y coordinate for surface origin - * - * This is a convenience function for creating a pattern from @surface - * and setting it as the source in @cr with cairo_set_source(). - * - * The @x and @y parameters give the user-space coordinate at which - * the surface origin should appear. (The surface origin is its - * upper-left corner before any transformation has been applied.) The - * @x and @y parameters are negated and then set as translation values - * in the pattern matrix. - * - * Other than the initial translation pattern matrix, as described - * above, all other pattern attributes, (such as its extend mode), are - * set to the default values as in cairo_pattern_create_for_surface(). - * The resulting pattern can be queried with cairo_get_source() so - * that these attributes can be modified if desired, (eg. to create a - * repeating pattern with cairo_pattern_set_extend()). - * - * Since: 1.0 - **/ -void -cairo_set_source_surface (cairo_t *cr, - cairo_surface_t *surface, - double x, - double y) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - if (unlikely (surface == NULL)) { - _cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER); - return; - } - - status = cr->backend->set_source_surface (cr, surface, x, y); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def (cairo_set_source_surface); - -/** - * cairo_set_source: - * @cr: a cairo context - * @source: a #cairo_pattern_t to be used as the source for - * subsequent drawing operations. - * - * Sets the source pattern within @cr to @source. This pattern - * will then be used for any subsequent drawing operation until a new - * source pattern is set. - * - * Note: The pattern's transformation matrix will be locked to the - * user space in effect at the time of cairo_set_source(). This means - * that further modifications of the current transformation matrix - * will not affect the source pattern. See cairo_pattern_set_matrix(). - * - * The default source pattern is a solid pattern that is opaque black, - * (that is, it is equivalent to cairo_set_source_rgb(cr, 0.0, 0.0, - * 0.0)). - * - * Since: 1.0 - **/ -void -cairo_set_source (cairo_t *cr, cairo_pattern_t *source) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - if (unlikely (source == NULL)) { - _cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER); - return; - } - - if (unlikely (source->status)) { - _cairo_set_error (cr, source->status); - return; - } - - status = cr->backend->set_source (cr, source); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def (cairo_set_source); - -/** - * cairo_get_source: - * @cr: a cairo context - * - * Gets the current source pattern for @cr. - * - * Return value: the current source pattern. This object is owned by - * cairo. To keep a reference to it, you must call - * cairo_pattern_reference(). - * - * Since: 1.0 - **/ -cairo_pattern_t * -cairo_get_source (cairo_t *cr) -{ - if (unlikely (cr->status)) - return _cairo_pattern_create_in_error (cr->status); - - return cr->backend->get_source (cr); -} - -/** - * cairo_set_tolerance: - * @cr: a #cairo_t - * @tolerance: the tolerance, in device units (typically pixels) - * - * Sets the tolerance used when converting paths into trapezoids. - * Curved segments of the path will be subdivided until the maximum - * deviation between the original path and the polygonal approximation - * is less than @tolerance. The default value is 0.1. A larger - * value will give better performance, a smaller value, better - * appearance. (Reducing the value from the default value of 0.1 - * is unlikely to improve appearance significantly.) The accuracy of paths - * within Cairo is limited by the precision of its internal arithmetic, and - * the prescribed @tolerance is restricted to the smallest - * representable internal value. - * - * Since: 1.0 - **/ -void -cairo_set_tolerance (cairo_t *cr, double tolerance) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->set_tolerance (cr, tolerance); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def (cairo_set_tolerance); - -/** - * cairo_set_antialias: - * @cr: a #cairo_t - * @antialias: the new antialiasing mode - * - * Set the antialiasing mode of the rasterizer used for drawing shapes. - * This value is a hint, and a particular backend may or may not support - * a particular value. At the current time, no backend supports - * %CAIRO_ANTIALIAS_SUBPIXEL when drawing shapes. - * - * Note that this option does not affect text rendering, instead see - * cairo_font_options_set_antialias(). - * - * Since: 1.0 - **/ -void -cairo_set_antialias (cairo_t *cr, cairo_antialias_t antialias) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->set_antialias (cr, antialias); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_set_fill_rule: - * @cr: a #cairo_t - * @fill_rule: a fill rule, specified as a #cairo_fill_rule_t - * - * Set the current fill rule within the cairo context. The fill rule - * is used to determine which regions are inside or outside a complex - * (potentially self-intersecting) path. The current fill rule affects - * both cairo_fill() and cairo_clip(). See #cairo_fill_rule_t for details - * on the semantics of each available fill rule. - * - * The default fill rule is %CAIRO_FILL_RULE_WINDING. - * - * Since: 1.0 - **/ -void -cairo_set_fill_rule (cairo_t *cr, cairo_fill_rule_t fill_rule) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->set_fill_rule (cr, fill_rule); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_set_line_width: - * @cr: a #cairo_t - * @width: a line width - * - * Sets the current line width within the cairo context. The line - * width value specifies the diameter of a pen that is circular in - * user space, (though device-space pen may be an ellipse in general - * due to scaling/shear/rotation of the CTM). - * - * Note: When the description above refers to user space and CTM it - * refers to the user space and CTM in effect at the time of the - * stroking operation, not the user space and CTM in effect at the - * time of the call to cairo_set_line_width(). The simplest usage - * makes both of these spaces identical. That is, if there is no - * change to the CTM between a call to cairo_set_line_width() and the - * stroking operation, then one can just pass user-space values to - * cairo_set_line_width() and ignore this note. - * - * As with the other stroke parameters, the current line width is - * examined by cairo_stroke(), cairo_stroke_extents(), and - * cairo_stroke_to_path(), but does not have any effect during path - * construction. - * - * The default line width value is 2.0. - * - * Since: 1.0 - **/ -void -cairo_set_line_width (cairo_t *cr, double width) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - if (width < 0.) - width = 0.; - - status = cr->backend->set_line_width (cr, width); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def (cairo_set_line_width); - -/** - * cairo_set_line_cap: - * @cr: a cairo context - * @line_cap: a line cap style - * - * Sets the current line cap style within the cairo context. See - * #cairo_line_cap_t for details about how the available line cap - * styles are drawn. - * - * As with the other stroke parameters, the current line cap style is - * examined by cairo_stroke(), cairo_stroke_extents(), and - * cairo_stroke_to_path(), but does not have any effect during path - * construction. - * - * The default line cap style is %CAIRO_LINE_CAP_BUTT. - * - * Since: 1.0 - **/ -void -cairo_set_line_cap (cairo_t *cr, cairo_line_cap_t line_cap) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->set_line_cap (cr, line_cap); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def (cairo_set_line_cap); - -/** - * cairo_set_line_join: - * @cr: a cairo context - * @line_join: a line join style - * - * Sets the current line join style within the cairo context. See - * #cairo_line_join_t for details about how the available line join - * styles are drawn. - * - * As with the other stroke parameters, the current line join style is - * examined by cairo_stroke(), cairo_stroke_extents(), and - * cairo_stroke_to_path(), but does not have any effect during path - * construction. - * - * The default line join style is %CAIRO_LINE_JOIN_MITER. - * - * Since: 1.0 - **/ -void -cairo_set_line_join (cairo_t *cr, cairo_line_join_t line_join) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->set_line_join (cr, line_join); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def (cairo_set_line_join); - -/** - * cairo_set_dash: - * @cr: a cairo context - * @dashes: an array specifying alternate lengths of on and off stroke portions - * @num_dashes: the length of the dashes array - * @offset: an offset into the dash pattern at which the stroke should start - * - * Sets the dash pattern to be used by cairo_stroke(). A dash pattern - * is specified by @dashes, an array of positive values. Each value - * provides the length of alternate "on" and "off" portions of the - * stroke. The @offset specifies an offset into the pattern at which - * the stroke begins. - * - * Each "on" segment will have caps applied as if the segment were a - * separate sub-path. In particular, it is valid to use an "on" length - * of 0.0 with %CAIRO_LINE_CAP_ROUND or %CAIRO_LINE_CAP_SQUARE in order - * to distributed dots or squares along a path. - * - * Note: The length values are in user-space units as evaluated at the - * time of stroking. This is not necessarily the same as the user - * space at the time of cairo_set_dash(). - * - * If @num_dashes is 0 dashing is disabled. - * - * If @num_dashes is 1 a symmetric pattern is assumed with alternating - * on and off portions of the size specified by the single value in - * @dashes. - * - * If any value in @dashes is negative, or if all values are 0, then - * @cr will be put into an error state with a status of - * %CAIRO_STATUS_INVALID_DASH. - * - * Since: 1.0 - **/ -void -cairo_set_dash (cairo_t *cr, - const double *dashes, - int num_dashes, - double offset) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->set_dash (cr, dashes, num_dashes, offset); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_get_dash_count: - * @cr: a #cairo_t - * - * This function returns the length of the dash array in @cr (0 if dashing - * is not currently in effect). - * - * See also cairo_set_dash() and cairo_get_dash(). - * - * Return value: the length of the dash array, or 0 if no dash array set. - * - * Since: 1.4 - **/ -int -cairo_get_dash_count (cairo_t *cr) -{ - int num_dashes; - - if (unlikely (cr->status)) - return 0; - - cr->backend->get_dash (cr, NULL, &num_dashes, NULL); - - return num_dashes; -} - -/** - * cairo_get_dash: - * @cr: a #cairo_t - * @dashes: return value for the dash array, or %NULL - * @offset: return value for the current dash offset, or %NULL - * - * Gets the current dash array. If not %NULL, @dashes should be big - * enough to hold at least the number of values returned by - * cairo_get_dash_count(). - * - * Since: 1.4 - **/ -void -cairo_get_dash (cairo_t *cr, - double *dashes, - double *offset) -{ - if (unlikely (cr->status)) - return; - - cr->backend->get_dash (cr, dashes, NULL, offset); -} - -/** - * cairo_set_miter_limit: - * @cr: a cairo context - * @limit: miter limit to set - * - * Sets the current miter limit within the cairo context. - * - * If the current line join style is set to %CAIRO_LINE_JOIN_MITER - * (see cairo_set_line_join()), the miter limit is used to determine - * whether the lines should be joined with a bevel instead of a miter. - * Cairo divides the length of the miter by the line width. - * If the result is greater than the miter limit, the style is - * converted to a bevel. - * - * As with the other stroke parameters, the current line miter limit is - * examined by cairo_stroke(), cairo_stroke_extents(), and - * cairo_stroke_to_path(), but does not have any effect during path - * construction. - * - * The default miter limit value is 10.0, which will convert joins - * with interior angles less than 11 degrees to bevels instead of - * miters. For reference, a miter limit of 2.0 makes the miter cutoff - * at 60 degrees, and a miter limit of 1.414 makes the cutoff at 90 - * degrees. - * - * A miter limit for a desired angle can be computed as: miter limit = - * 1/sin(angle/2) - * - * Since: 1.0 - **/ -void -cairo_set_miter_limit (cairo_t *cr, double limit) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->set_miter_limit (cr, limit); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_translate: - * @cr: a cairo context - * @tx: amount to translate in the X direction - * @ty: amount to translate in the Y direction - * - * Modifies the current transformation matrix (CTM) by translating the - * user-space origin by (@tx, @ty). This offset is interpreted as a - * user-space coordinate according to the CTM in place before the new - * call to cairo_translate(). In other words, the translation of the - * user-space origin takes place after any existing transformation. - * - * Since: 1.0 - **/ -void -cairo_translate (cairo_t *cr, double tx, double ty) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->translate (cr, tx, ty); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def (cairo_translate); - -/** - * cairo_scale: - * @cr: a cairo context - * @sx: scale factor for the X dimension - * @sy: scale factor for the Y dimension - * - * Modifies the current transformation matrix (CTM) by scaling the X - * and Y user-space axes by @sx and @sy respectively. The scaling of - * the axes takes place after any existing transformation of user - * space. - * - * Since: 1.0 - **/ -void -cairo_scale (cairo_t *cr, double sx, double sy) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->scale (cr, sx, sy); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def (cairo_scale); - -/** - * cairo_rotate: - * @cr: a cairo context - * @angle: angle (in radians) by which the user-space axes will be - * rotated - * - * Modifies the current transformation matrix (CTM) by rotating the - * user-space axes by @angle radians. The rotation of the axes takes - * places after any existing transformation of user space. The - * rotation direction for positive angles is from the positive X axis - * toward the positive Y axis. - * - * Since: 1.0 - **/ -void -cairo_rotate (cairo_t *cr, double angle) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->rotate (cr, angle); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_transform: - * @cr: a cairo context - * @matrix: a transformation to be applied to the user-space axes - * - * Modifies the current transformation matrix (CTM) by applying - * @matrix as an additional transformation. The new transformation of - * user space takes place after any existing transformation. - * - * Since: 1.0 - **/ -void -cairo_transform (cairo_t *cr, - const cairo_matrix_t *matrix) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->transform (cr, matrix); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def (cairo_transform); - -/** - * cairo_set_matrix: - * @cr: a cairo context - * @matrix: a transformation matrix from user space to device space - * - * Modifies the current transformation matrix (CTM) by setting it - * equal to @matrix. - * - * Since: 1.0 - **/ -void -cairo_set_matrix (cairo_t *cr, - const cairo_matrix_t *matrix) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->set_matrix (cr, matrix); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def (cairo_set_matrix); - -/** - * cairo_identity_matrix: - * @cr: a cairo context - * - * Resets the current transformation matrix (CTM) by setting it equal - * to the identity matrix. That is, the user-space and device-space - * axes will be aligned and one user-space unit will transform to one - * device-space unit. - * - * Since: 1.0 - **/ -void -cairo_identity_matrix (cairo_t *cr) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->set_identity_matrix (cr); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_user_to_device: - * @cr: a cairo context - * @x: X value of coordinate (in/out parameter) - * @y: Y value of coordinate (in/out parameter) - * - * Transform a coordinate from user space to device space by - * multiplying the given point by the current transformation matrix - * (CTM). - * - * Since: 1.0 - **/ -void -cairo_user_to_device (cairo_t *cr, double *x, double *y) -{ - if (unlikely (cr->status)) - return; - - cr->backend->user_to_device (cr, x, y); -} -slim_hidden_def (cairo_user_to_device); - -/** - * cairo_user_to_device_distance: - * @cr: a cairo context - * @dx: X component of a distance vector (in/out parameter) - * @dy: Y component of a distance vector (in/out parameter) - * - * Transform a distance vector from user space to device space. This - * function is similar to cairo_user_to_device() except that the - * translation components of the CTM will be ignored when transforming - * (@dx,@dy). - * - * Since: 1.0 - **/ -void -cairo_user_to_device_distance (cairo_t *cr, double *dx, double *dy) -{ - if (unlikely (cr->status)) - return; - - cr->backend->user_to_device_distance (cr, dx, dy); -} -slim_hidden_def (cairo_user_to_device_distance); - -/** - * cairo_device_to_user: - * @cr: a cairo - * @x: X value of coordinate (in/out parameter) - * @y: Y value of coordinate (in/out parameter) - * - * Transform a coordinate from device space to user space by - * multiplying the given point by the inverse of the current - * transformation matrix (CTM). - * - * Since: 1.0 - **/ -void -cairo_device_to_user (cairo_t *cr, double *x, double *y) -{ - if (unlikely (cr->status)) - return; - - cr->backend->device_to_user (cr, x, y); -} -slim_hidden_def (cairo_device_to_user); - -/** - * cairo_device_to_user_distance: - * @cr: a cairo context - * @dx: X component of a distance vector (in/out parameter) - * @dy: Y component of a distance vector (in/out parameter) - * - * Transform a distance vector from device space to user space. This - * function is similar to cairo_device_to_user() except that the - * translation components of the inverse CTM will be ignored when - * transforming (@dx,@dy). - * - * Since: 1.0 - **/ -void -cairo_device_to_user_distance (cairo_t *cr, double *dx, double *dy) -{ - if (unlikely (cr->status)) - return; - - cr->backend->device_to_user_distance (cr, dx, dy); -} - -/** - * cairo_new_path: - * @cr: a cairo context - * - * Clears the current path. After this call there will be no path and - * no current point. - * - * Since: 1.0 - **/ -void -cairo_new_path (cairo_t *cr) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->new_path (cr); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def(cairo_new_path); - -/** - * cairo_new_sub_path: - * @cr: a cairo context - * - * Begin a new sub-path. Note that the existing path is not - * affected. After this call there will be no current point. - * - * In many cases, this call is not needed since new sub-paths are - * frequently started with cairo_move_to(). - * - * A call to cairo_new_sub_path() is particularly useful when - * beginning a new sub-path with one of the cairo_arc() calls. This - * makes things easier as it is no longer necessary to manually - * compute the arc's initial coordinates for a call to - * cairo_move_to(). - * - * Since: 1.2 - **/ -void -cairo_new_sub_path (cairo_t *cr) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->new_sub_path (cr); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_move_to: - * @cr: a cairo context - * @x: the X coordinate of the new position - * @y: the Y coordinate of the new position - * - * Begin a new sub-path. After this call the current point will be (@x, - * @y). - * - * Since: 1.0 - **/ -void -cairo_move_to (cairo_t *cr, double x, double y) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->move_to (cr, x, y); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def(cairo_move_to); - - -/** - * cairo_line_to: - * @cr: a cairo context - * @x: the X coordinate of the end of the new line - * @y: the Y coordinate of the end of the new line - * - * Adds a line to the path from the current point to position (@x, @y) - * in user-space coordinates. After this call the current point - * will be (@x, @y). - * - * If there is no current point before the call to cairo_line_to() - * this function will behave as cairo_move_to(@cr, @x, @y). - * - * Since: 1.0 - **/ -void -cairo_line_to (cairo_t *cr, double x, double y) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->line_to (cr, x, y); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def (cairo_line_to); - -/** - * cairo_curve_to: - * @cr: a cairo context - * @x1: the X coordinate of the first control point - * @y1: the Y coordinate of the first control point - * @x2: the X coordinate of the second control point - * @y2: the Y coordinate of the second control point - * @x3: the X coordinate of the end of the curve - * @y3: the Y coordinate of the end of the curve - * - * Adds a cubic Bézier spline to the path from the current point to - * position (@x3, @y3) in user-space coordinates, using (@x1, @y1) and - * (@x2, @y2) as the control points. After this call the current point - * will be (@x3, @y3). - * - * If there is no current point before the call to cairo_curve_to() - * this function will behave as if preceded by a call to - * cairo_move_to(@cr, @x1, @y1). - * - * Since: 1.0 - **/ -void -cairo_curve_to (cairo_t *cr, - double x1, double y1, - double x2, double y2, - double x3, double y3) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->curve_to (cr, - x1, y1, - x2, y2, - x3, y3); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def (cairo_curve_to); - -/** - * cairo_arc: - * @cr: a cairo context - * @xc: X position of the center of the arc - * @yc: Y position of the center of the arc - * @radius: the radius of the arc - * @angle1: the start angle, in radians - * @angle2: the end angle, in radians - * - * Adds a circular arc of the given @radius to the current path. The - * arc is centered at (@xc, @yc), begins at @angle1 and proceeds in - * the direction of increasing angles to end at @angle2. If @angle2 is - * less than @angle1 it will be progressively increased by - * <literal>2*M_PI</literal> until it is greater than @angle1. - * - * If there is a current point, an initial line segment will be added - * to the path to connect the current point to the beginning of the - * arc. If this initial line is undesired, it can be avoided by - * calling cairo_new_sub_path() before calling cairo_arc(). - * - * Angles are measured in radians. An angle of 0.0 is in the direction - * of the positive X axis (in user space). An angle of - * <literal>M_PI/2.0</literal> radians (90 degrees) is in the - * direction of the positive Y axis (in user space). Angles increase - * in the direction from the positive X axis toward the positive Y - * axis. So with the default transformation matrix, angles increase in - * a clockwise direction. - * - * (To convert from degrees to radians, use <literal>degrees * (M_PI / - * 180.)</literal>.) - * - * This function gives the arc in the direction of increasing angles; - * see cairo_arc_negative() to get the arc in the direction of - * decreasing angles. - * - * The arc is circular in user space. To achieve an elliptical arc, - * you can scale the current transformation matrix by different - * amounts in the X and Y directions. For example, to draw an ellipse - * in the box given by @x, @y, @width, @height: - * - * <informalexample><programlisting> - * cairo_save (cr); - * cairo_translate (cr, x + width / 2., y + height / 2.); - * cairo_scale (cr, width / 2., height / 2.); - * cairo_arc (cr, 0., 0., 1., 0., 2 * M_PI); - * cairo_restore (cr); - * </programlisting></informalexample> - * - * Since: 1.0 - **/ -void -cairo_arc (cairo_t *cr, - double xc, double yc, - double radius, - double angle1, double angle2) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - if (angle2 < angle1) { - /* increase angle2 by multiples of full circle until it - * satisfies angle2 >= angle1 */ - angle2 = fmod (angle2 - angle1, 2 * M_PI); - if (angle2 < 0) - angle2 += 2 * M_PI; - angle2 += angle1; - } - - status = cr->backend->arc (cr, xc, yc, radius, angle1, angle2, TRUE); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_arc_negative: - * @cr: a cairo context - * @xc: X position of the center of the arc - * @yc: Y position of the center of the arc - * @radius: the radius of the arc - * @angle1: the start angle, in radians - * @angle2: the end angle, in radians - * - * Adds a circular arc of the given @radius to the current path. The - * arc is centered at (@xc, @yc), begins at @angle1 and proceeds in - * the direction of decreasing angles to end at @angle2. If @angle2 is - * greater than @angle1 it will be progressively decreased by - * <literal>2*M_PI</literal> until it is less than @angle1. - * - * See cairo_arc() for more details. This function differs only in the - * direction of the arc between the two angles. - * - * Since: 1.0 - **/ -void -cairo_arc_negative (cairo_t *cr, - double xc, double yc, - double radius, - double angle1, double angle2) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - if (angle2 > angle1) { - /* decrease angle2 by multiples of full circle until it - * satisfies angle2 <= angle1 */ - angle2 = fmod (angle2 - angle1, 2 * M_PI); - if (angle2 > 0) - angle2 -= 2 * M_PI; - angle2 += angle1; - } - - status = cr->backend->arc (cr, xc, yc, radius, angle1, angle2, FALSE); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/* XXX: NYI -void -cairo_arc_to (cairo_t *cr, - double x1, double y1, - double x2, double y2, - double radius) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->arc_to (cr, x1, y1, x2, y2, radius); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -void -cairo_rel_arc_to (cairo_t *cr, - double dx1, double dy1, - double dx2, double dy2, - double radius) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->rel_arc_to (cr, dx1, dy1, dx2, dy2, radius); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -*/ - -/** - * cairo_rel_move_to: - * @cr: a cairo context - * @dx: the X offset - * @dy: the Y offset - * - * Begin a new sub-path. After this call the current point will offset - * by (@x, @y). - * - * Given a current point of (x, y), cairo_rel_move_to(@cr, @dx, @dy) - * is logically equivalent to cairo_move_to(@cr, x + @dx, y + @dy). - * - * It is an error to call this function with no current point. Doing - * so will cause @cr to shutdown with a status of - * %CAIRO_STATUS_NO_CURRENT_POINT. - * - * Since: 1.0 - **/ -void -cairo_rel_move_to (cairo_t *cr, double dx, double dy) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->rel_move_to (cr, dx, dy); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_rel_line_to: - * @cr: a cairo context - * @dx: the X offset to the end of the new line - * @dy: the Y offset to the end of the new line - * - * Relative-coordinate version of cairo_line_to(). Adds a line to the - * path from the current point to a point that is offset from the - * current point by (@dx, @dy) in user space. After this call the - * current point will be offset by (@dx, @dy). - * - * Given a current point of (x, y), cairo_rel_line_to(@cr, @dx, @dy) - * is logically equivalent to cairo_line_to(@cr, x + @dx, y + @dy). - * - * It is an error to call this function with no current point. Doing - * so will cause @cr to shutdown with a status of - * %CAIRO_STATUS_NO_CURRENT_POINT. - * - * Since: 1.0 - **/ -void -cairo_rel_line_to (cairo_t *cr, double dx, double dy) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->rel_line_to (cr, dx, dy); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def(cairo_rel_line_to); - -/** - * cairo_rel_curve_to: - * @cr: a cairo context - * @dx1: the X offset to the first control point - * @dy1: the Y offset to the first control point - * @dx2: the X offset to the second control point - * @dy2: the Y offset to the second control point - * @dx3: the X offset to the end of the curve - * @dy3: the Y offset to the end of the curve - * - * Relative-coordinate version of cairo_curve_to(). All offsets are - * relative to the current point. Adds a cubic Bézier spline to the - * path from the current point to a point offset from the current - * point by (@dx3, @dy3), using points offset by (@dx1, @dy1) and - * (@dx2, @dy2) as the control points. After this call the current - * point will be offset by (@dx3, @dy3). - * - * Given a current point of (x, y), cairo_rel_curve_to(@cr, @dx1, - * @dy1, @dx2, @dy2, @dx3, @dy3) is logically equivalent to - * cairo_curve_to(@cr, x+@dx1, y+@dy1, x+@dx2, y+@dy2, x+@dx3, y+@dy3). - * - * It is an error to call this function with no current point. Doing - * so will cause @cr to shutdown with a status of - * %CAIRO_STATUS_NO_CURRENT_POINT. - * - * Since: 1.0 - **/ -void -cairo_rel_curve_to (cairo_t *cr, - double dx1, double dy1, - double dx2, double dy2, - double dx3, double dy3) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->rel_curve_to (cr, - dx1, dy1, - dx2, dy2, - dx3, dy3); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_rectangle: - * @cr: a cairo context - * @x: the X coordinate of the top left corner of the rectangle - * @y: the Y coordinate to the top left corner of the rectangle - * @width: the width of the rectangle - * @height: the height of the rectangle - * - * Adds a closed sub-path rectangle of the given size to the current - * path at position (@x, @y) in user-space coordinates. - * - * This function is logically equivalent to: - * <informalexample><programlisting> - * cairo_move_to (cr, x, y); - * cairo_rel_line_to (cr, width, 0); - * cairo_rel_line_to (cr, 0, height); - * cairo_rel_line_to (cr, -width, 0); - * cairo_close_path (cr); - * </programlisting></informalexample> - * - * Since: 1.0 - **/ -void -cairo_rectangle (cairo_t *cr, - double x, double y, - double width, double height) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->rectangle (cr, x, y, width, height); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -#if 0 -/* XXX: NYI */ -void -cairo_stroke_to_path (cairo_t *cr) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - /* The code in _cairo_recording_surface_get_path has a poorman's stroke_to_path */ - - status = _cairo_gstate_stroke_path (cr->gstate); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -#endif - -/** - * cairo_close_path: - * @cr: a cairo context - * - * Adds a line segment to the path from the current point to the - * beginning of the current sub-path, (the most recent point passed to - * cairo_move_to()), and closes this sub-path. After this call the - * current point will be at the joined endpoint of the sub-path. - * - * The behavior of cairo_close_path() is distinct from simply calling - * cairo_line_to() with the equivalent coordinate in the case of - * stroking. When a closed sub-path is stroked, there are no caps on - * the ends of the sub-path. Instead, there is a line join connecting - * the final and initial segments of the sub-path. - * - * If there is no current point before the call to cairo_close_path(), - * this function will have no effect. - * - * Note: As of cairo version 1.2.4 any call to cairo_close_path() will - * place an explicit MOVE_TO element into the path immediately after - * the CLOSE_PATH element, (which can be seen in cairo_copy_path() for - * example). This can simplify path processing in some cases as it may - * not be necessary to save the "last move_to point" during processing - * as the MOVE_TO immediately after the CLOSE_PATH will provide that - * point. - * - * Since: 1.0 - **/ -void -cairo_close_path (cairo_t *cr) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->close_path (cr); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def(cairo_close_path); - -/** - * cairo_path_extents: - * @cr: a cairo context - * @x1: left of the resulting extents - * @y1: top of the resulting extents - * @x2: right of the resulting extents - * @y2: bottom of the resulting extents - * - * Computes a bounding box in user-space coordinates covering the - * points on the current path. If the current path is empty, returns - * an empty rectangle ((0,0), (0,0)). Stroke parameters, fill rule, - * surface dimensions and clipping are not taken into account. - * - * Contrast with cairo_fill_extents() and cairo_stroke_extents() which - * return the extents of only the area that would be "inked" by - * the corresponding drawing operations. - * - * The result of cairo_path_extents() is defined as equivalent to the - * limit of cairo_stroke_extents() with %CAIRO_LINE_CAP_ROUND as the - * line width approaches 0.0, (but never reaching the empty-rectangle - * returned by cairo_stroke_extents() for a line width of 0.0). - * - * Specifically, this means that zero-area sub-paths such as - * cairo_move_to();cairo_line_to() segments, (even degenerate cases - * where the coordinates to both calls are identical), will be - * considered as contributing to the extents. However, a lone - * cairo_move_to() will not contribute to the results of - * cairo_path_extents(). - * - * Since: 1.6 - **/ -void -cairo_path_extents (cairo_t *cr, - double *x1, double *y1, double *x2, double *y2) -{ - if (unlikely (cr->status)) { - if (x1) - *x1 = 0.0; - if (y1) - *y1 = 0.0; - if (x2) - *x2 = 0.0; - if (y2) - *y2 = 0.0; - - return; - } - - cr->backend->path_extents (cr, x1, y1, x2, y2); -} - -/** - * cairo_paint: - * @cr: a cairo context - * - * A drawing operator that paints the current source everywhere within - * the current clip region. - * - * Since: 1.0 - **/ -void -cairo_paint (cairo_t *cr) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->paint (cr); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def (cairo_paint); - -/** - * cairo_paint_with_alpha: - * @cr: a cairo context - * @alpha: alpha value, between 0 (transparent) and 1 (opaque) - * - * A drawing operator that paints the current source everywhere within - * the current clip region using a mask of constant alpha value - * @alpha. The effect is similar to cairo_paint(), but the drawing - * is faded out using the alpha value. - * - * Since: 1.0 - **/ -void -cairo_paint_with_alpha (cairo_t *cr, - double alpha) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->paint_with_alpha (cr, alpha); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_mask: - * @cr: a cairo context - * @pattern: a #cairo_pattern_t - * - * A drawing operator that paints the current source - * using the alpha channel of @pattern as a mask. (Opaque - * areas of @pattern are painted with the source, transparent - * areas are not painted.) - * - * Since: 1.0 - **/ -void -cairo_mask (cairo_t *cr, - cairo_pattern_t *pattern) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - if (unlikely (pattern == NULL)) { - _cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER); - return; - } - - if (unlikely (pattern->status)) { - _cairo_set_error (cr, pattern->status); - return; - } - - status = cr->backend->mask (cr, pattern); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def (cairo_mask); - -/** - * cairo_mask_surface: - * @cr: a cairo context - * @surface: a #cairo_surface_t - * @surface_x: X coordinate at which to place the origin of @surface - * @surface_y: Y coordinate at which to place the origin of @surface - * - * A drawing operator that paints the current source - * using the alpha channel of @surface as a mask. (Opaque - * areas of @surface are painted with the source, transparent - * areas are not painted.) - * - * Since: 1.0 - **/ -void -cairo_mask_surface (cairo_t *cr, - cairo_surface_t *surface, - double surface_x, - double surface_y) -{ - cairo_pattern_t *pattern; - cairo_matrix_t matrix; - - if (unlikely (cr->status)) - return; - - pattern = cairo_pattern_create_for_surface (surface); - - cairo_matrix_init_translate (&matrix, - surface_x, - surface_y); - cairo_pattern_set_matrix (pattern, &matrix); - - cairo_mask (cr, pattern); - - cairo_pattern_destroy (pattern); -} - -/** - * cairo_stroke: - * @cr: a cairo context - * - * A drawing operator that strokes the current path according to the - * current line width, line join, line cap, and dash settings. After - * cairo_stroke(), the current path will be cleared from the cairo - * context. See cairo_set_line_width(), cairo_set_line_join(), - * cairo_set_line_cap(), cairo_set_dash(), and - * cairo_stroke_preserve(). - * - * Note: Degenerate segments and sub-paths are treated specially and - * provide a useful result. These can result in two different - * situations: - * - * 1. Zero-length "on" segments set in cairo_set_dash(). If the cap - * style is %CAIRO_LINE_CAP_ROUND or %CAIRO_LINE_CAP_SQUARE then these - * segments will be drawn as circular dots or squares respectively. In - * the case of %CAIRO_LINE_CAP_SQUARE, the orientation of the squares - * is determined by the direction of the underlying path. - * - * 2. A sub-path created by cairo_move_to() followed by either a - * cairo_close_path() or one or more calls to cairo_line_to() to the - * same coordinate as the cairo_move_to(). If the cap style is - * %CAIRO_LINE_CAP_ROUND then these sub-paths will be drawn as circular - * dots. Note that in the case of %CAIRO_LINE_CAP_SQUARE a degenerate - * sub-path will not be drawn at all, (since the correct orientation - * is indeterminate). - * - * In no case will a cap style of %CAIRO_LINE_CAP_BUTT cause anything - * to be drawn in the case of either degenerate segments or sub-paths. - * - * Since: 1.0 - **/ -void -cairo_stroke (cairo_t *cr) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->stroke (cr); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def(cairo_stroke); - -/** - * cairo_stroke_preserve: - * @cr: a cairo context - * - * A drawing operator that strokes the current path according to the - * current line width, line join, line cap, and dash settings. Unlike - * cairo_stroke(), cairo_stroke_preserve() preserves the path within the - * cairo context. - * - * See cairo_set_line_width(), cairo_set_line_join(), - * cairo_set_line_cap(), cairo_set_dash(), and - * cairo_stroke_preserve(). - * - * Since: 1.0 - **/ -void -cairo_stroke_preserve (cairo_t *cr) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->stroke_preserve (cr); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def(cairo_stroke_preserve); - -/** - * cairo_fill: - * @cr: a cairo context - * - * A drawing operator that fills the current path according to the - * current fill rule, (each sub-path is implicitly closed before being - * filled). After cairo_fill(), the current path will be cleared from - * the cairo context. See cairo_set_fill_rule() and - * cairo_fill_preserve(). - * - * Since: 1.0 - **/ -void -cairo_fill (cairo_t *cr) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->fill (cr); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_fill_preserve: - * @cr: a cairo context - * - * A drawing operator that fills the current path according to the - * current fill rule, (each sub-path is implicitly closed before being - * filled). Unlike cairo_fill(), cairo_fill_preserve() preserves the - * path within the cairo context. - * - * See cairo_set_fill_rule() and cairo_fill(). - * - * Since: 1.0 - **/ -void -cairo_fill_preserve (cairo_t *cr) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->fill_preserve (cr); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def(cairo_fill_preserve); - -/** - * cairo_copy_page: - * @cr: a cairo context - * - * Emits the current page for backends that support multiple pages, but - * doesn't clear it, so, the contents of the current page will be retained - * for the next page too. Use cairo_show_page() if you want to get an - * empty page after the emission. - * - * This is a convenience function that simply calls - * cairo_surface_copy_page() on @cr's target. - * - * Since: 1.0 - **/ -void -cairo_copy_page (cairo_t *cr) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->copy_page (cr); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_show_page: - * @cr: a cairo context - * - * Emits and clears the current page for backends that support multiple - * pages. Use cairo_copy_page() if you don't want to clear the page. - * - * This is a convenience function that simply calls - * cairo_surface_show_page() on @cr's target. - * - * Since: 1.0 - **/ -void -cairo_show_page (cairo_t *cr) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->show_page (cr); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_in_stroke: - * @cr: a cairo context - * @x: X coordinate of the point to test - * @y: Y coordinate of the point to test - * - * Tests whether the given point is inside the area that would be - * affected by a cairo_stroke() operation given the current path and - * stroking parameters. Surface dimensions and clipping are not taken - * into account. - * - * See cairo_stroke(), cairo_set_line_width(), cairo_set_line_join(), - * cairo_set_line_cap(), cairo_set_dash(), and - * cairo_stroke_preserve(). - * - * Return value: A non-zero value if the point is inside, or zero if - * outside. - * - * Since: 1.0 - **/ -cairo_bool_t -cairo_in_stroke (cairo_t *cr, double x, double y) -{ - cairo_status_t status; - cairo_bool_t inside = FALSE; - - if (unlikely (cr->status)) - return FALSE; - - status = cr->backend->in_stroke (cr, x, y, &inside); - if (unlikely (status)) - _cairo_set_error (cr, status); - - return inside; -} - -/** - * cairo_in_fill: - * @cr: a cairo context - * @x: X coordinate of the point to test - * @y: Y coordinate of the point to test - * - * Tests whether the given point is inside the area that would be - * affected by a cairo_fill() operation given the current path and - * filling parameters. Surface dimensions and clipping are not taken - * into account. - * - * See cairo_fill(), cairo_set_fill_rule() and cairo_fill_preserve(). - * - * Return value: A non-zero value if the point is inside, or zero if - * outside. - * - * Since: 1.0 - **/ -cairo_bool_t -cairo_in_fill (cairo_t *cr, double x, double y) -{ - cairo_status_t status; - cairo_bool_t inside = FALSE; - - if (unlikely (cr->status)) - return FALSE; - - status = cr->backend->in_fill (cr, x, y, &inside); - if (unlikely (status)) - _cairo_set_error (cr, status); - - return inside; -} - -/** - * cairo_stroke_extents: - * @cr: a cairo context - * @x1: left of the resulting extents - * @y1: top of the resulting extents - * @x2: right of the resulting extents - * @y2: bottom of the resulting extents - * - * Computes a bounding box in user coordinates covering the area that - * would be affected, (the "inked" area), by a cairo_stroke() - * operation given the current path and stroke parameters. - * If the current path is empty, returns an empty rectangle ((0,0), (0,0)). - * Surface dimensions and clipping are not taken into account. - * - * Note that if the line width is set to exactly zero, then - * cairo_stroke_extents() will return an empty rectangle. Contrast with - * cairo_path_extents() which can be used to compute the non-empty - * bounds as the line width approaches zero. - * - * Note that cairo_stroke_extents() must necessarily do more work to - * compute the precise inked areas in light of the stroke parameters, - * so cairo_path_extents() may be more desirable for sake of - * performance if non-inked path extents are desired. - * - * See cairo_stroke(), cairo_set_line_width(), cairo_set_line_join(), - * cairo_set_line_cap(), cairo_set_dash(), and - * cairo_stroke_preserve(). - * - * Since: 1.0 - **/ -void -cairo_stroke_extents (cairo_t *cr, - double *x1, double *y1, double *x2, double *y2) -{ - cairo_status_t status; - - if (unlikely (cr->status)) { - if (x1) - *x1 = 0.0; - if (y1) - *y1 = 0.0; - if (x2) - *x2 = 0.0; - if (y2) - *y2 = 0.0; - - return; - } - - status = cr->backend->stroke_extents (cr, x1, y1, x2, y2); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_fill_extents: - * @cr: a cairo context - * @x1: left of the resulting extents - * @y1: top of the resulting extents - * @x2: right of the resulting extents - * @y2: bottom of the resulting extents - * - * Computes a bounding box in user coordinates covering the area that - * would be affected, (the "inked" area), by a cairo_fill() operation - * given the current path and fill parameters. If the current path is - * empty, returns an empty rectangle ((0,0), (0,0)). Surface - * dimensions and clipping are not taken into account. - * - * Contrast with cairo_path_extents(), which is similar, but returns - * non-zero extents for some paths with no inked area, (such as a - * simple line segment). - * - * Note that cairo_fill_extents() must necessarily do more work to - * compute the precise inked areas in light of the fill rule, so - * cairo_path_extents() may be more desirable for sake of performance - * if the non-inked path extents are desired. - * - * See cairo_fill(), cairo_set_fill_rule() and cairo_fill_preserve(). - * - * Since: 1.0 - **/ -void -cairo_fill_extents (cairo_t *cr, - double *x1, double *y1, double *x2, double *y2) -{ - cairo_status_t status; - - if (unlikely (cr->status)) { - if (x1) - *x1 = 0.0; - if (y1) - *y1 = 0.0; - if (x2) - *x2 = 0.0; - if (y2) - *y2 = 0.0; - - return; - } - - status = cr->backend->fill_extents (cr, x1, y1, x2, y2); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_clip: - * @cr: a cairo context - * - * Establishes a new clip region by intersecting the current clip - * region with the current path as it would be filled by cairo_fill() - * and according to the current fill rule (see cairo_set_fill_rule()). - * - * After cairo_clip(), the current path will be cleared from the cairo - * context. - * - * The current clip region affects all drawing operations by - * effectively masking out any changes to the surface that are outside - * the current clip region. - * - * Calling cairo_clip() can only make the clip region smaller, never - * larger. But the current clip is part of the graphics state, so a - * temporary restriction of the clip region can be achieved by - * calling cairo_clip() within a cairo_save()/cairo_restore() - * pair. The only other means of increasing the size of the clip - * region is cairo_reset_clip(). - * - * Since: 1.0 - **/ -void -cairo_clip (cairo_t *cr) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->clip (cr); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_clip_preserve: - * @cr: a cairo context - * - * Establishes a new clip region by intersecting the current clip - * region with the current path as it would be filled by cairo_fill() - * and according to the current fill rule (see cairo_set_fill_rule()). - * - * Unlike cairo_clip(), cairo_clip_preserve() preserves the path within - * the cairo context. - * - * The current clip region affects all drawing operations by - * effectively masking out any changes to the surface that are outside - * the current clip region. - * - * Calling cairo_clip_preserve() can only make the clip region smaller, never - * larger. But the current clip is part of the graphics state, so a - * temporary restriction of the clip region can be achieved by - * calling cairo_clip_preserve() within a cairo_save()/cairo_restore() - * pair. The only other means of increasing the size of the clip - * region is cairo_reset_clip(). - * - * Since: 1.0 - **/ -void -cairo_clip_preserve (cairo_t *cr) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->clip_preserve (cr); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def(cairo_clip_preserve); - -/** - * cairo_reset_clip: - * @cr: a cairo context - * - * Reset the current clip region to its original, unrestricted - * state. That is, set the clip region to an infinitely large shape - * containing the target surface. Equivalently, if infinity is too - * hard to grasp, one can imagine the clip region being reset to the - * exact bounds of the target surface. - * - * Note that code meant to be reusable should not call - * cairo_reset_clip() as it will cause results unexpected by - * higher-level code which calls cairo_clip(). Consider using - * cairo_save() and cairo_restore() around cairo_clip() as a more - * robust means of temporarily restricting the clip region. - * - * Since: 1.0 - **/ -void -cairo_reset_clip (cairo_t *cr) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->reset_clip (cr); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_clip_extents: - * @cr: a cairo context - * @x1: left of the resulting extents - * @y1: top of the resulting extents - * @x2: right of the resulting extents - * @y2: bottom of the resulting extents - * - * Computes a bounding box in user coordinates covering the area inside the - * current clip. - * - * Since: 1.4 - **/ -void -cairo_clip_extents (cairo_t *cr, - double *x1, double *y1, - double *x2, double *y2) -{ - cairo_status_t status; - - if (x1) - *x1 = 0.0; - if (y1) - *y1 = 0.0; - if (x2) - *x2 = 0.0; - if (y2) - *y2 = 0.0; - - if (unlikely (cr->status)) - return; - - status = cr->backend->clip_extents (cr, x1, y1, x2, y2); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_in_clip: - * @cr: a cairo context - * @x: X coordinate of the point to test - * @y: Y coordinate of the point to test - * - * Tests whether the given point is inside the area that would be - * visible through the current clip, i.e. the area that would be filled by - * a cairo_paint() operation. - * - * See cairo_clip(), and cairo_clip_preserve(). - * - * Return value: A non-zero value if the point is inside, or zero if - * outside. - * - * Since: 1.10 - **/ -cairo_bool_t -cairo_in_clip (cairo_t *cr, double x, double y) -{ - cairo_status_t status; - cairo_bool_t inside = FALSE; - - if (unlikely (cr->status)) - return FALSE; - - status = cr->backend->in_clip (cr, x, y, &inside); - if (unlikely (status)) - _cairo_set_error (cr, status); - - return inside; -} - -/** - * cairo_copy_clip_rectangle_list: - * @cr: a cairo context - * - * Gets the current clip region as a list of rectangles in user coordinates. - * Never returns %NULL. - * - * The status in the list may be %CAIRO_STATUS_CLIP_NOT_REPRESENTABLE to - * indicate that the clip region cannot be represented as a list of - * user-space rectangles. The status may have other values to indicate - * other errors. - * - * Returns: the current clip region as a list of rectangles in user coordinates, - * which should be destroyed using cairo_rectangle_list_destroy(). - * - * Since: 1.4 - **/ -cairo_rectangle_list_t * -cairo_copy_clip_rectangle_list (cairo_t *cr) -{ - if (unlikely (cr->status)) - return _cairo_rectangle_list_create_in_error (cr->status); - - return cr->backend->clip_copy_rectangle_list (cr); -} - -/** - * cairo_select_font_face: - * @cr: a #cairo_t - * @family: a font family name, encoded in UTF-8 - * @slant: the slant for the font - * @weight: the weight for the font - * - * Note: The cairo_select_font_face() function call is part of what - * the cairo designers call the "toy" text API. It is convenient for - * short demos and simple programs, but it is not expected to be - * adequate for serious text-using applications. - * - * Selects a family and style of font from a simplified description as - * a family name, slant and weight. Cairo provides no operation to - * list available family names on the system (this is a "toy", - * remember), but the standard CSS2 generic family names, ("serif", - * "sans-serif", "cursive", "fantasy", "monospace"), are likely to - * work as expected. - * - * If @family starts with the string "@cairo:", or if no native font - * backends are compiled in, cairo will use an internal font family. - * The internal font family recognizes many modifiers in the @family - * string, most notably, it recognizes the string "monospace". That is, - * the family name "@cairo:monospace" will use the monospace version of - * the internal font family. - * - * For "real" font selection, see the font-backend-specific - * font_face_create functions for the font backend you are using. (For - * example, if you are using the freetype-based cairo-ft font backend, - * see cairo_ft_font_face_create_for_ft_face() or - * cairo_ft_font_face_create_for_pattern().) The resulting font face - * could then be used with cairo_scaled_font_create() and - * cairo_set_scaled_font(). - * - * Similarly, when using the "real" font support, you can call - * directly into the underlying font system, (such as fontconfig or - * freetype), for operations such as listing available fonts, etc. - * - * It is expected that most applications will need to use a more - * comprehensive font handling and text layout library, (for example, - * pango), in conjunction with cairo. - * - * If text is drawn without a call to cairo_select_font_face(), (nor - * cairo_set_font_face() nor cairo_set_scaled_font()), the default - * family is platform-specific, but is essentially "sans-serif". - * Default slant is %CAIRO_FONT_SLANT_NORMAL, and default weight is - * %CAIRO_FONT_WEIGHT_NORMAL. - * - * This function is equivalent to a call to cairo_toy_font_face_create() - * followed by cairo_set_font_face(). - * - * Since: 1.0 - **/ -void -cairo_select_font_face (cairo_t *cr, - const char *family, - cairo_font_slant_t slant, - cairo_font_weight_t weight) -{ - cairo_font_face_t *font_face; - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - font_face = cairo_toy_font_face_create (family, slant, weight); - if (unlikely (font_face->status)) { - _cairo_set_error (cr, font_face->status); - return; - } - - status = cr->backend->set_font_face (cr, font_face); - cairo_font_face_destroy (font_face); - - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_font_extents: - * @cr: a #cairo_t - * @extents: a #cairo_font_extents_t object into which the results - * will be stored. - * - * Gets the font extents for the currently selected font. - * - * Since: 1.0 - **/ -void -cairo_font_extents (cairo_t *cr, - cairo_font_extents_t *extents) -{ - cairo_status_t status; - - extents->ascent = 0.0; - extents->descent = 0.0; - extents->height = 0.0; - extents->max_x_advance = 0.0; - extents->max_y_advance = 0.0; - - if (unlikely (cr->status)) - return; - - status = cr->backend->font_extents (cr, extents); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_set_font_face: - * @cr: a #cairo_t - * @font_face: a #cairo_font_face_t, or %NULL to restore to the default font - * - * Replaces the current #cairo_font_face_t object in the #cairo_t with - * @font_face. The replaced font face in the #cairo_t will be - * destroyed if there are no other references to it. - * - * Since: 1.0 - **/ -void -cairo_set_font_face (cairo_t *cr, - cairo_font_face_t *font_face) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->set_font_face (cr, font_face); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_get_font_face: - * @cr: a #cairo_t - * - * Gets the current font face for a #cairo_t. - * - * Return value: the current font face. This object is owned by - * cairo. To keep a reference to it, you must call - * cairo_font_face_reference(). - * - * This function never returns %NULL. If memory cannot be allocated, a - * special "nil" #cairo_font_face_t object will be returned on which - * cairo_font_face_status() returns %CAIRO_STATUS_NO_MEMORY. Using - * this nil object will cause its error state to propagate to other - * objects it is passed to, (for example, calling - * cairo_set_font_face() with a nil font will trigger an error that - * will shutdown the #cairo_t object). - * - * Since: 1.0 - **/ -cairo_font_face_t * -cairo_get_font_face (cairo_t *cr) -{ - if (unlikely (cr->status)) - return (cairo_font_face_t*) &_cairo_font_face_nil; - - return cr->backend->get_font_face (cr); -} - -/** - * cairo_set_font_size: - * @cr: a #cairo_t - * @size: the new font size, in user space units - * - * Sets the current font matrix to a scale by a factor of @size, replacing - * any font matrix previously set with cairo_set_font_size() or - * cairo_set_font_matrix(). This results in a font size of @size user space - * units. (More precisely, this matrix will result in the font's - * em-square being a @size by @size square in user space.) - * - * If text is drawn without a call to cairo_set_font_size(), (nor - * cairo_set_font_matrix() nor cairo_set_scaled_font()), the default - * font size is 10.0. - * - * Since: 1.0 - **/ -void -cairo_set_font_size (cairo_t *cr, double size) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->set_font_size (cr, size); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def (cairo_set_font_size); - -/** - * cairo_set_font_matrix: - * @cr: a #cairo_t - * @matrix: a #cairo_matrix_t describing a transform to be applied to - * the current font. - * - * Sets the current font matrix to @matrix. The font matrix gives a - * transformation from the design space of the font (in this space, - * the em-square is 1 unit by 1 unit) to user space. Normally, a - * simple scale is used (see cairo_set_font_size()), but a more - * complex font matrix can be used to shear the font - * or stretch it unequally along the two axes - * - * Since: 1.0 - **/ -void -cairo_set_font_matrix (cairo_t *cr, - const cairo_matrix_t *matrix) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cr->backend->set_font_matrix (cr, matrix); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def (cairo_set_font_matrix); - -/** - * cairo_get_font_matrix: - * @cr: a #cairo_t - * @matrix: return value for the matrix - * - * Stores the current font matrix into @matrix. See - * cairo_set_font_matrix(). - * - * Since: 1.0 - **/ -void -cairo_get_font_matrix (cairo_t *cr, cairo_matrix_t *matrix) -{ - if (unlikely (cr->status)) { - cairo_matrix_init_identity (matrix); - return; - } - - cr->backend->get_font_matrix (cr, matrix); -} - -/** - * cairo_set_font_options: - * @cr: a #cairo_t - * @options: font options to use - * - * Sets a set of custom font rendering options for the #cairo_t. - * Rendering options are derived by merging these options with the - * options derived from underlying surface; if the value in @options - * has a default value (like %CAIRO_ANTIALIAS_DEFAULT), then the value - * from the surface is used. - * - * Since: 1.0 - **/ -void -cairo_set_font_options (cairo_t *cr, - const cairo_font_options_t *options) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - status = cairo_font_options_status ((cairo_font_options_t *) options); - if (unlikely (status)) { - _cairo_set_error (cr, status); - return; - } - - status = cr->backend->set_font_options (cr, options); - if (unlikely (status)) - _cairo_set_error (cr, status); -} -slim_hidden_def (cairo_set_font_options); - -/** - * cairo_get_font_options: - * @cr: a #cairo_t - * @options: a #cairo_font_options_t object into which to store - * the retrieved options. All existing values are overwritten - * - * Retrieves font rendering options set via #cairo_set_font_options. - * Note that the returned options do not include any options derived - * from the underlying surface; they are literally the options - * passed to cairo_set_font_options(). - * - * Since: 1.0 - **/ -void -cairo_get_font_options (cairo_t *cr, - cairo_font_options_t *options) -{ - /* check that we aren't trying to overwrite the nil object */ - if (cairo_font_options_status (options)) - return; - - if (unlikely (cr->status)) { - _cairo_font_options_init_default (options); - return; - } - - cr->backend->get_font_options (cr, options); -} - -/** - * cairo_set_scaled_font: - * @cr: a #cairo_t - * @scaled_font: a #cairo_scaled_font_t - * - * Replaces the current font face, font matrix, and font options in - * the #cairo_t with those of the #cairo_scaled_font_t. Except for - * some translation, the current CTM of the #cairo_t should be the - * same as that of the #cairo_scaled_font_t, which can be accessed - * using cairo_scaled_font_get_ctm(). - * - * Since: 1.2 - **/ -void -cairo_set_scaled_font (cairo_t *cr, - const cairo_scaled_font_t *scaled_font) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - if ((scaled_font == NULL)) { - _cairo_set_error (cr, _cairo_error (CAIRO_STATUS_NULL_POINTER)); - return; - } - - status = scaled_font->status; - if (unlikely (status)) { - _cairo_set_error (cr, status); - return; - } - - status = cr->backend->set_scaled_font (cr, (cairo_scaled_font_t *) scaled_font); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_get_scaled_font: - * @cr: a #cairo_t - * - * Gets the current scaled font for a #cairo_t. - * - * Return value: the current scaled font. This object is owned by - * cairo. To keep a reference to it, you must call - * cairo_scaled_font_reference(). - * - * This function never returns %NULL. If memory cannot be allocated, a - * special "nil" #cairo_scaled_font_t object will be returned on which - * cairo_scaled_font_status() returns %CAIRO_STATUS_NO_MEMORY. Using - * this nil object will cause its error state to propagate to other - * objects it is passed to, (for example, calling - * cairo_set_scaled_font() with a nil font will trigger an error that - * will shutdown the #cairo_t object). - * - * Since: 1.4 - **/ -cairo_scaled_font_t * -cairo_get_scaled_font (cairo_t *cr) -{ - if (unlikely (cr->status)) - return _cairo_scaled_font_create_in_error (cr->status); - - return cr->backend->get_scaled_font (cr); -} -slim_hidden_def (cairo_get_scaled_font); - -/** - * cairo_text_extents: - * @cr: a #cairo_t - * @utf8: a NUL-terminated string of text encoded in UTF-8, or %NULL - * @extents: a #cairo_text_extents_t object into which the results - * will be stored - * - * Gets the extents for a string of text. The extents describe a - * user-space rectangle that encloses the "inked" portion of the text, - * (as it would be drawn by cairo_show_text()). Additionally, the - * x_advance and y_advance values indicate the amount by which the - * current point would be advanced by cairo_show_text(). - * - * Note that whitespace characters do not directly contribute to the - * size of the rectangle (extents.width and extents.height). They do - * contribute indirectly by changing the position of non-whitespace - * characters. In particular, trailing whitespace characters are - * likely to not affect the size of the rectangle, though they will - * affect the x_advance and y_advance values. - * - * Since: 1.0 - **/ -void -cairo_text_extents (cairo_t *cr, - const char *utf8, - cairo_text_extents_t *extents) -{ - cairo_status_t status; - cairo_scaled_font_t *scaled_font; - cairo_glyph_t *glyphs = NULL; - int num_glyphs = 0; - double x, y; - - extents->x_bearing = 0.0; - extents->y_bearing = 0.0; - extents->width = 0.0; - extents->height = 0.0; - extents->x_advance = 0.0; - extents->y_advance = 0.0; - - if (unlikely (cr->status)) - return; - - if (utf8 == NULL) - return; - - scaled_font = cairo_get_scaled_font (cr); - if (unlikely (scaled_font->status)) { - _cairo_set_error (cr, scaled_font->status); - return; - } - - cairo_get_current_point (cr, &x, &y); - status = cairo_scaled_font_text_to_glyphs (scaled_font, - x, y, - utf8, -1, - &glyphs, &num_glyphs, - NULL, NULL, NULL); - - if (likely (status == CAIRO_STATUS_SUCCESS)) { - status = cr->backend->glyph_extents (cr, - glyphs, num_glyphs, - extents); - } - cairo_glyph_free (glyphs); - - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_glyph_extents: - * @cr: a #cairo_t - * @glyphs: an array of #cairo_glyph_t objects - * @num_glyphs: the number of elements in @glyphs - * @extents: a #cairo_text_extents_t object into which the results - * will be stored - * - * Gets the extents for an array of glyphs. The extents describe a - * user-space rectangle that encloses the "inked" portion of the - * glyphs, (as they would be drawn by cairo_show_glyphs()). - * Additionally, the x_advance and y_advance values indicate the - * amount by which the current point would be advanced by - * cairo_show_glyphs(). - * - * Note that whitespace glyphs do not contribute to the size of the - * rectangle (extents.width and extents.height). - * - * Since: 1.0 - **/ -void -cairo_glyph_extents (cairo_t *cr, - const cairo_glyph_t *glyphs, - int num_glyphs, - cairo_text_extents_t *extents) -{ - cairo_status_t status; - - extents->x_bearing = 0.0; - extents->y_bearing = 0.0; - extents->width = 0.0; - extents->height = 0.0; - extents->x_advance = 0.0; - extents->y_advance = 0.0; - - if (unlikely (cr->status)) - return; - - if (num_glyphs == 0) - return; - - if (unlikely (num_glyphs < 0)) { - _cairo_set_error (cr, CAIRO_STATUS_NEGATIVE_COUNT); - return; - } - - if (unlikely (glyphs == NULL)) { - _cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER); - return; - } - - status = cr->backend->glyph_extents (cr, glyphs, num_glyphs, extents); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_show_text: - * @cr: a cairo context - * @utf8: a NUL-terminated string of text encoded in UTF-8, or %NULL - * - * A drawing operator that generates the shape from a string of UTF-8 - * characters, rendered according to the current font_face, font_size - * (font_matrix), and font_options. - * - * This function first computes a set of glyphs for the string of - * text. The first glyph is placed so that its origin is at the - * current point. The origin of each subsequent glyph is offset from - * that of the previous glyph by the advance values of the previous - * glyph. - * - * After this call the current point is moved to the origin of where - * the next glyph would be placed in this same progression. That is, - * the current point will be at the origin of the final glyph offset - * by its advance values. This allows for easy display of a single - * logical string with multiple calls to cairo_show_text(). - * - * Note: The cairo_show_text() function call is part of what the cairo - * designers call the "toy" text API. It is convenient for short demos - * and simple programs, but it is not expected to be adequate for - * serious text-using applications. See cairo_show_glyphs() for the - * "real" text display API in cairo. - * - * Since: 1.0 - **/ -void -cairo_show_text (cairo_t *cr, const char *utf8) -{ - cairo_text_extents_t extents; - cairo_status_t status; - cairo_glyph_t *glyphs, *last_glyph; - cairo_text_cluster_t *clusters; - int utf8_len, num_glyphs, num_clusters; - cairo_text_cluster_flags_t cluster_flags; - double x, y; - cairo_bool_t has_show_text_glyphs; - cairo_glyph_t stack_glyphs[CAIRO_STACK_ARRAY_LENGTH (cairo_glyph_t)]; - cairo_text_cluster_t stack_clusters[CAIRO_STACK_ARRAY_LENGTH (cairo_text_cluster_t)]; - cairo_scaled_font_t *scaled_font; - cairo_glyph_text_info_t info, *i; - - if (unlikely (cr->status)) - return; - - if (utf8 == NULL) - return; - - scaled_font = cairo_get_scaled_font (cr); - if (unlikely (scaled_font->status)) { - _cairo_set_error (cr, scaled_font->status); - return; - } - - utf8_len = strlen (utf8); - - has_show_text_glyphs = - cairo_surface_has_show_text_glyphs (cairo_get_target (cr)); - - glyphs = stack_glyphs; - num_glyphs = ARRAY_LENGTH (stack_glyphs); - - if (has_show_text_glyphs) { - clusters = stack_clusters; - num_clusters = ARRAY_LENGTH (stack_clusters); - } else { - clusters = NULL; - num_clusters = 0; - } - - cairo_get_current_point (cr, &x, &y); - status = cairo_scaled_font_text_to_glyphs (scaled_font, - x, y, - utf8, utf8_len, - &glyphs, &num_glyphs, - has_show_text_glyphs ? &clusters : NULL, &num_clusters, - &cluster_flags); - if (unlikely (status)) - goto BAIL; - - if (num_glyphs == 0) - return; - - i = NULL; - if (has_show_text_glyphs) { - info.utf8 = utf8; - info.utf8_len = utf8_len; - info.clusters = clusters; - info.num_clusters = num_clusters; - info.cluster_flags = cluster_flags; - i = &info; - } - - status = cr->backend->glyphs (cr, glyphs, num_glyphs, i); - if (unlikely (status)) - goto BAIL; - - last_glyph = &glyphs[num_glyphs - 1]; - status = cr->backend->glyph_extents (cr, last_glyph, 1, &extents); - if (unlikely (status)) - goto BAIL; - - x = last_glyph->x + extents.x_advance; - y = last_glyph->y + extents.y_advance; - cr->backend->move_to (cr, x, y); - - BAIL: - if (glyphs != stack_glyphs) - cairo_glyph_free (glyphs); - if (clusters != stack_clusters) - cairo_text_cluster_free (clusters); - - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_show_glyphs: - * @cr: a cairo context - * @glyphs: array of glyphs to show - * @num_glyphs: number of glyphs to show - * - * A drawing operator that generates the shape from an array of glyphs, - * rendered according to the current font face, font size - * (font matrix), and font options. - * - * Since: 1.0 - **/ -void -cairo_show_glyphs (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - if (num_glyphs == 0) - return; - - if (num_glyphs < 0) { - _cairo_set_error (cr, CAIRO_STATUS_NEGATIVE_COUNT); - return; - } - - if (glyphs == NULL) { - _cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER); - return; - } - - status = cr->backend->glyphs (cr, glyphs, num_glyphs, NULL); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_show_text_glyphs: - * @cr: a cairo context - * @utf8: a string of text encoded in UTF-8 - * @utf8_len: length of @utf8 in bytes, or -1 if it is NUL-terminated - * @glyphs: array of glyphs to show - * @num_glyphs: number of glyphs to show - * @clusters: array of cluster mapping information - * @num_clusters: number of clusters in the mapping - * @cluster_flags: cluster mapping flags - * - * This operation has rendering effects similar to cairo_show_glyphs() - * but, if the target surface supports it, uses the provided text and - * cluster mapping to embed the text for the glyphs shown in the output. - * If the target does not support the extended attributes, this function - * acts like the basic cairo_show_glyphs() as if it had been passed - * @glyphs and @num_glyphs. - * - * The mapping between @utf8 and @glyphs is provided by an array of - * <firstterm>clusters</firstterm>. Each cluster covers a number of - * text bytes and glyphs, and neighboring clusters cover neighboring - * areas of @utf8 and @glyphs. The clusters should collectively cover @utf8 - * and @glyphs in entirety. - * - * The first cluster always covers bytes from the beginning of @utf8. - * If @cluster_flags do not have the %CAIRO_TEXT_CLUSTER_FLAG_BACKWARD - * set, the first cluster also covers the beginning - * of @glyphs, otherwise it covers the end of the @glyphs array and - * following clusters move backward. - * - * See #cairo_text_cluster_t for constraints on valid clusters. - * - * Since: 1.8 - **/ -void -cairo_show_text_glyphs (cairo_t *cr, - const char *utf8, - int utf8_len, - const cairo_glyph_t *glyphs, - int num_glyphs, - const cairo_text_cluster_t *clusters, - int num_clusters, - cairo_text_cluster_flags_t cluster_flags) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - /* A slew of sanity checks */ - - /* Special case for NULL and -1 */ - if (utf8 == NULL && utf8_len == -1) - utf8_len = 0; - - /* No NULLs for non-zeros */ - if ((num_glyphs && glyphs == NULL) || - (utf8_len && utf8 == NULL) || - (num_clusters && clusters == NULL)) { - _cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER); - return; - } - - /* A -1 for utf8_len means NUL-terminated */ - if (utf8_len == -1) - utf8_len = strlen (utf8); - - /* Apart from that, no negatives */ - if (num_glyphs < 0 || utf8_len < 0 || num_clusters < 0) { - _cairo_set_error (cr, CAIRO_STATUS_NEGATIVE_COUNT); - return; - } - - if (num_glyphs == 0 && utf8_len == 0) - return; - - if (utf8) { - /* Make sure clusters cover the entire glyphs and utf8 arrays, - * and that cluster boundaries are UTF-8 boundaries. */ - status = _cairo_validate_text_clusters (utf8, utf8_len, - glyphs, num_glyphs, - clusters, num_clusters, cluster_flags); - if (status == CAIRO_STATUS_INVALID_CLUSTERS) { - /* Either got invalid UTF-8 text, or cluster mapping is bad. - * Differentiate those. */ - - cairo_status_t status2; - - status2 = _cairo_utf8_to_ucs4 (utf8, utf8_len, NULL, NULL); - if (status2) - status = status2; - } else { - cairo_glyph_text_info_t info; - - info.utf8 = utf8; - info.utf8_len = utf8_len; - info.clusters = clusters; - info.num_clusters = num_clusters; - info.cluster_flags = cluster_flags; - - status = cr->backend->glyphs (cr, glyphs, num_glyphs, &info); - } - } else { - status = cr->backend->glyphs (cr, glyphs, num_glyphs, NULL); - } - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_text_path: - * @cr: a cairo context - * @utf8: a NUL-terminated string of text encoded in UTF-8, or %NULL - * - * Adds closed paths for text to the current path. The generated - * path if filled, achieves an effect similar to that of - * cairo_show_text(). - * - * Text conversion and positioning is done similar to cairo_show_text(). - * - * Like cairo_show_text(), After this call the current point is - * moved to the origin of where the next glyph would be placed in - * this same progression. That is, the current point will be at - * the origin of the final glyph offset by its advance values. - * This allows for chaining multiple calls to to cairo_text_path() - * without having to set current point in between. - * - * Note: The cairo_text_path() function call is part of what the cairo - * designers call the "toy" text API. It is convenient for short demos - * and simple programs, but it is not expected to be adequate for - * serious text-using applications. See cairo_glyph_path() for the - * "real" text path API in cairo. - * - * Since: 1.0 - **/ -void -cairo_text_path (cairo_t *cr, const char *utf8) -{ - cairo_status_t status; - cairo_text_extents_t extents; - cairo_glyph_t stack_glyphs[CAIRO_STACK_ARRAY_LENGTH (cairo_glyph_t)]; - cairo_glyph_t *glyphs, *last_glyph; - cairo_scaled_font_t *scaled_font; - int num_glyphs; - double x, y; - - if (unlikely (cr->status)) - return; - - if (utf8 == NULL) - return; - - - glyphs = stack_glyphs; - num_glyphs = ARRAY_LENGTH (stack_glyphs); - - scaled_font = cairo_get_scaled_font (cr); - if (unlikely (scaled_font->status)) { - _cairo_set_error (cr, scaled_font->status); - return; - } - - cairo_get_current_point (cr, &x, &y); - status = cairo_scaled_font_text_to_glyphs (scaled_font, - x, y, - utf8, -1, - &glyphs, &num_glyphs, - NULL, NULL, NULL); - - if (num_glyphs == 0) - return; - - status = cr->backend->glyph_path (cr, glyphs, num_glyphs); - - if (unlikely (status)) - goto BAIL; - - last_glyph = &glyphs[num_glyphs - 1]; - status = cr->backend->glyph_extents (cr, last_glyph, 1, &extents); - - if (unlikely (status)) - goto BAIL; - - x = last_glyph->x + extents.x_advance; - y = last_glyph->y + extents.y_advance; - cr->backend->move_to (cr, x, y); - - BAIL: - if (glyphs != stack_glyphs) - cairo_glyph_free (glyphs); - - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_glyph_path: - * @cr: a cairo context - * @glyphs: array of glyphs to show - * @num_glyphs: number of glyphs to show - * - * Adds closed paths for the glyphs to the current path. The generated - * path if filled, achieves an effect similar to that of - * cairo_show_glyphs(). - * - * Since: 1.0 - **/ -void -cairo_glyph_path (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - if (num_glyphs == 0) - return; - - if (unlikely (num_glyphs < 0)) { - _cairo_set_error (cr, CAIRO_STATUS_NEGATIVE_COUNT); - return; - } - - if (unlikely (glyphs == NULL)) { - _cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER); - return; - } - - status = cr->backend->glyph_path (cr, glyphs, num_glyphs); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_get_operator: - * @cr: a cairo context - * - * Gets the current compositing operator for a cairo context. - * - * Return value: the current compositing operator. - * - * Since: 1.0 - **/ -cairo_operator_t -cairo_get_operator (cairo_t *cr) -{ - if (unlikely (cr->status)) - return CAIRO_GSTATE_OPERATOR_DEFAULT; - - return cr->backend->get_operator (cr); -} - -#if 0 -/** - * cairo_get_opacity: - * @cr: a cairo context - * - * Gets the current compositing opacity for a cairo context. - * - * Return value: the current compositing opacity. - * - * Since: TBD - **/ -double -cairo_get_opacity (cairo_t *cr) -{ - if (unlikely (cr->status)) - return 1.; - - return cr->backend->get_opacity (cr); -} -#endif - -/** - * cairo_get_tolerance: - * @cr: a cairo context - * - * Gets the current tolerance value, as set by cairo_set_tolerance(). - * - * Return value: the current tolerance value. - * - * Since: 1.0 - **/ -double -cairo_get_tolerance (cairo_t *cr) -{ - if (unlikely (cr->status)) - return CAIRO_GSTATE_TOLERANCE_DEFAULT; - - return cr->backend->get_tolerance (cr); -} -slim_hidden_def (cairo_get_tolerance); - -/** - * cairo_get_antialias: - * @cr: a cairo context - * - * Gets the current shape antialiasing mode, as set by - * cairo_set_antialias(). - * - * Return value: the current shape antialiasing mode. - * - * Since: 1.0 - **/ -cairo_antialias_t -cairo_get_antialias (cairo_t *cr) -{ - if (unlikely (cr->status)) - return CAIRO_ANTIALIAS_DEFAULT; - - return cr->backend->get_antialias (cr); -} - -/** - * cairo_has_current_point: - * @cr: a cairo context - * - * Returns whether a current point is defined on the current path. - * See cairo_get_current_point() for details on the current point. - * - * Return value: whether a current point is defined. - * - * Since: 1.6 - **/ -cairo_bool_t -cairo_has_current_point (cairo_t *cr) -{ - if (unlikely (cr->status)) - return FALSE; - - return cr->backend->has_current_point (cr); -} - -/** - * cairo_get_current_point: - * @cr: a cairo context - * @x: return value for X coordinate of the current point - * @y: return value for Y coordinate of the current point - * - * Gets the current point of the current path, which is - * conceptually the final point reached by the path so far. - * - * The current point is returned in the user-space coordinate - * system. If there is no defined current point or if @cr is in an - * error status, @x and @y will both be set to 0.0. It is possible to - * check this in advance with cairo_has_current_point(). - * - * Most path construction functions alter the current point. See the - * following for details on how they affect the current point: - * cairo_new_path(), cairo_new_sub_path(), - * cairo_append_path(), cairo_close_path(), - * cairo_move_to(), cairo_line_to(), cairo_curve_to(), - * cairo_rel_move_to(), cairo_rel_line_to(), cairo_rel_curve_to(), - * cairo_arc(), cairo_arc_negative(), cairo_rectangle(), - * cairo_text_path(), cairo_glyph_path(), cairo_stroke_to_path(). - * - * Some functions use and alter the current point but do not - * otherwise change current path: - * cairo_show_text(). - * - * Some functions unset the current path and as a result, current point: - * cairo_fill(), cairo_stroke(). - * - * Since: 1.0 - **/ -void -cairo_get_current_point (cairo_t *cr, double *x_ret, double *y_ret) -{ - double x, y; - - x = y = 0; - if (cr->status == CAIRO_STATUS_SUCCESS && - cr->backend->has_current_point (cr)) - { - cr->backend->get_current_point (cr, &x, &y); - } - - if (x_ret) - *x_ret = x; - if (y_ret) - *y_ret = y; -} -slim_hidden_def(cairo_get_current_point); - -/** - * cairo_get_fill_rule: - * @cr: a cairo context - * - * Gets the current fill rule, as set by cairo_set_fill_rule(). - * - * Return value: the current fill rule. - * - * Since: 1.0 - **/ -cairo_fill_rule_t -cairo_get_fill_rule (cairo_t *cr) -{ - if (unlikely (cr->status)) - return CAIRO_GSTATE_FILL_RULE_DEFAULT; - - return cr->backend->get_fill_rule (cr); -} - -/** - * cairo_get_line_width: - * @cr: a cairo context - * - * This function returns the current line width value exactly as set by - * cairo_set_line_width(). Note that the value is unchanged even if - * the CTM has changed between the calls to cairo_set_line_width() and - * cairo_get_line_width(). - * - * Return value: the current line width. - * - * Since: 1.0 - **/ -double -cairo_get_line_width (cairo_t *cr) -{ - if (unlikely (cr->status)) - return CAIRO_GSTATE_LINE_WIDTH_DEFAULT; - - return cr->backend->get_line_width (cr); -} -slim_hidden_def (cairo_get_line_width); - -/** - * cairo_get_line_cap: - * @cr: a cairo context - * - * Gets the current line cap style, as set by cairo_set_line_cap(). - * - * Return value: the current line cap style. - * - * Since: 1.0 - **/ -cairo_line_cap_t -cairo_get_line_cap (cairo_t *cr) -{ - if (unlikely (cr->status)) - return CAIRO_GSTATE_LINE_CAP_DEFAULT; - - return cr->backend->get_line_cap (cr); -} - -/** - * cairo_get_line_join: - * @cr: a cairo context - * - * Gets the current line join style, as set by cairo_set_line_join(). - * - * Return value: the current line join style. - * - * Since: 1.0 - **/ -cairo_line_join_t -cairo_get_line_join (cairo_t *cr) -{ - if (unlikely (cr->status)) - return CAIRO_GSTATE_LINE_JOIN_DEFAULT; - - return cr->backend->get_line_join (cr); -} - -/** - * cairo_get_miter_limit: - * @cr: a cairo context - * - * Gets the current miter limit, as set by cairo_set_miter_limit(). - * - * Return value: the current miter limit. - * - * Since: 1.0 - **/ -double -cairo_get_miter_limit (cairo_t *cr) -{ - if (unlikely (cr->status)) - return CAIRO_GSTATE_MITER_LIMIT_DEFAULT; - - return cr->backend->get_miter_limit (cr); -} - -/** - * cairo_get_matrix: - * @cr: a cairo context - * @matrix: return value for the matrix - * - * Stores the current transformation matrix (CTM) into @matrix. - * - * Since: 1.0 - **/ -void -cairo_get_matrix (cairo_t *cr, cairo_matrix_t *matrix) -{ - if (unlikely (cr->status)) { - cairo_matrix_init_identity (matrix); - return; - } - - cr->backend->get_matrix (cr, matrix); -} -slim_hidden_def (cairo_get_matrix); - -/** - * cairo_get_target: - * @cr: a cairo context - * - * Gets the target surface for the cairo context as passed to - * cairo_create(). - * - * This function will always return a valid pointer, but the result - * can be a "nil" surface if @cr is already in an error state, - * (ie. cairo_status() <literal>!=</literal> %CAIRO_STATUS_SUCCESS). - * A nil surface is indicated by cairo_surface_status() - * <literal>!=</literal> %CAIRO_STATUS_SUCCESS. - * - * Return value: the target surface. This object is owned by cairo. To - * keep a reference to it, you must call cairo_surface_reference(). - * - * Since: 1.0 - **/ -cairo_surface_t * -cairo_get_target (cairo_t *cr) -{ - if (unlikely (cr->status)) - return _cairo_surface_create_in_error (cr->status); - - return cr->backend->get_original_target (cr); -} -slim_hidden_def (cairo_get_target); - -/** - * cairo_get_group_target: - * @cr: a cairo context - * - * Gets the current destination surface for the context. This is either - * the original target surface as passed to cairo_create() or the target - * surface for the current group as started by the most recent call to - * cairo_push_group() or cairo_push_group_with_content(). - * - * This function will always return a valid pointer, but the result - * can be a "nil" surface if @cr is already in an error state, - * (ie. cairo_status() <literal>!=</literal> %CAIRO_STATUS_SUCCESS). - * A nil surface is indicated by cairo_surface_status() - * <literal>!=</literal> %CAIRO_STATUS_SUCCESS. - * - * Return value: the target surface. This object is owned by cairo. To - * keep a reference to it, you must call cairo_surface_reference(). - * - * Since: 1.2 - **/ -cairo_surface_t * -cairo_get_group_target (cairo_t *cr) -{ - if (unlikely (cr->status)) - return _cairo_surface_create_in_error (cr->status); - - return cr->backend->get_current_target (cr); -} - -/** - * cairo_copy_path: - * @cr: a cairo context - * - * Creates a copy of the current path and returns it to the user as a - * #cairo_path_t. See #cairo_path_data_t for hints on how to iterate - * over the returned data structure. - * - * This function will always return a valid pointer, but the result - * will have no data (<literal>data==%NULL</literal> and - * <literal>num_data==0</literal>), if either of the following - * conditions hold: - * - * <orderedlist> - * <listitem>If there is insufficient memory to copy the path. In this - * case <literal>path->status</literal> will be set to - * %CAIRO_STATUS_NO_MEMORY.</listitem> - * <listitem>If @cr is already in an error state. In this case - * <literal>path->status</literal> will contain the same status that - * would be returned by cairo_status().</listitem> - * </orderedlist> - * - * Return value: the copy of the current path. The caller owns the - * returned object and should call cairo_path_destroy() when finished - * with it. - * - * Since: 1.0 - **/ -cairo_path_t * -cairo_copy_path (cairo_t *cr) -{ - if (unlikely (cr->status)) - return _cairo_path_create_in_error (cr->status); - - return cr->backend->copy_path (cr); -} - -/** - * cairo_copy_path_flat: - * @cr: a cairo context - * - * Gets a flattened copy of the current path and returns it to the - * user as a #cairo_path_t. See #cairo_path_data_t for hints on - * how to iterate over the returned data structure. - * - * This function is like cairo_copy_path() except that any curves - * in the path will be approximated with piecewise-linear - * approximations, (accurate to within the current tolerance - * value). That is, the result is guaranteed to not have any elements - * of type %CAIRO_PATH_CURVE_TO which will instead be replaced by a - * series of %CAIRO_PATH_LINE_TO elements. - * - * This function will always return a valid pointer, but the result - * will have no data (<literal>data==%NULL</literal> and - * <literal>num_data==0</literal>), if either of the following - * conditions hold: - * - * <orderedlist> - * <listitem>If there is insufficient memory to copy the path. In this - * case <literal>path->status</literal> will be set to - * %CAIRO_STATUS_NO_MEMORY.</listitem> - * <listitem>If @cr is already in an error state. In this case - * <literal>path->status</literal> will contain the same status that - * would be returned by cairo_status().</listitem> - * </orderedlist> - * - * Return value: the copy of the current path. The caller owns the - * returned object and should call cairo_path_destroy() when finished - * with it. - * - * Since: 1.0 - **/ -cairo_path_t * -cairo_copy_path_flat (cairo_t *cr) -{ - if (unlikely (cr->status)) - return _cairo_path_create_in_error (cr->status); - - return cr->backend->copy_path_flat (cr); -} - -/** - * cairo_append_path: - * @cr: a cairo context - * @path: path to be appended - * - * Append the @path onto the current path. The @path may be either the - * return value from one of cairo_copy_path() or - * cairo_copy_path_flat() or it may be constructed manually. See - * #cairo_path_t for details on how the path data structure should be - * initialized, and note that <literal>path->status</literal> must be - * initialized to %CAIRO_STATUS_SUCCESS. - * - * Since: 1.0 - **/ -void -cairo_append_path (cairo_t *cr, - const cairo_path_t *path) -{ - cairo_status_t status; - - if (unlikely (cr->status)) - return; - - if (unlikely (path == NULL)) { - _cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER); - return; - } - - if (unlikely (path->status)) { - if (path->status > CAIRO_STATUS_SUCCESS && - path->status <= CAIRO_STATUS_LAST_STATUS) - _cairo_set_error (cr, path->status); - else - _cairo_set_error (cr, CAIRO_STATUS_INVALID_STATUS); - return; - } - - if (path->num_data == 0) - return; - - if (unlikely (path->data == NULL)) { - _cairo_set_error (cr, CAIRO_STATUS_NULL_POINTER); - return; - } - - status = cr->backend->append_path (cr, path); - if (unlikely (status)) - _cairo_set_error (cr, status); -} - -/** - * cairo_status: - * @cr: a cairo context - * - * Checks whether an error has previously occurred for this context. - * - * Returns: the current status of this context, see #cairo_status_t - * - * Since: 1.0 - **/ -cairo_status_t -cairo_status (cairo_t *cr) -{ - return cr->status; -} -slim_hidden_def (cairo_status); diff --git a/source/libs/cairo/cairo-src/src/cairo.h b/source/libs/cairo/cairo-src/src/cairo.h deleted file mode 100644 index 3104d47e4c4ab1804dcafd1408b590b8a0ae8a1d..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo.h +++ /dev/null @@ -1,3153 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is University of Southern - * California. - * - * Contributor(s): - * Carl D. Worth <cworth@cworth.org> - */ - -#ifndef CAIRO_H -#define CAIRO_H - -#include "cairo-version.h" -#include "cairo-features.h" -#include "cairo-deprecated.h" - -#ifdef __cplusplus -# define CAIRO_BEGIN_DECLS extern "C" { -# define CAIRO_END_DECLS } -#else -# define CAIRO_BEGIN_DECLS -# define CAIRO_END_DECLS -#endif - -#ifndef cairo_public -# if defined (_MSC_VER) && ! defined (CAIRO_WIN32_STATIC_BUILD) -# define cairo_public __declspec(dllimport) -# else -# define cairo_public -# endif -#endif - -CAIRO_BEGIN_DECLS - -#define CAIRO_VERSION_ENCODE(major, minor, micro) ( \ - ((major) * 10000) \ - + ((minor) * 100) \ - + ((micro) * 1)) - -#define CAIRO_VERSION CAIRO_VERSION_ENCODE( \ - CAIRO_VERSION_MAJOR, \ - CAIRO_VERSION_MINOR, \ - CAIRO_VERSION_MICRO) - - -#define CAIRO_VERSION_STRINGIZE_(major, minor, micro) \ - #major"."#minor"."#micro -#define CAIRO_VERSION_STRINGIZE(major, minor, micro) \ - CAIRO_VERSION_STRINGIZE_(major, minor, micro) - -#define CAIRO_VERSION_STRING CAIRO_VERSION_STRINGIZE( \ - CAIRO_VERSION_MAJOR, \ - CAIRO_VERSION_MINOR, \ - CAIRO_VERSION_MICRO) - - -cairo_public int -cairo_version (void); - -cairo_public const char* -cairo_version_string (void); - -/** - * cairo_bool_t: - * - * #cairo_bool_t is used for boolean values. Returns of type - * #cairo_bool_t will always be either 0 or 1, but testing against - * these values explicitly is not encouraged; just use the - * value as a boolean condition. - * - * <informalexample><programlisting> - * if (cairo_in_stroke (cr, x, y)) { - * /<!-- -->* do something *<!-- -->/ - * } - * </programlisting></informalexample> - * - * Since: 1.0 - **/ -typedef int cairo_bool_t; - -/** - * cairo_t: - * - * A #cairo_t contains the current state of the rendering device, - * including coordinates of yet to be drawn shapes. - * - * Cairo contexts, as #cairo_t objects are named, are central to - * cairo and all drawing with cairo is always done to a #cairo_t - * object. - * - * Memory management of #cairo_t is done with - * cairo_reference() and cairo_destroy(). - * - * Since: 1.0 - **/ -typedef struct _cairo cairo_t; - -/** - * cairo_surface_t: - * - * A #cairo_surface_t represents an image, either as the destination - * of a drawing operation or as source when drawing onto another - * surface. To draw to a #cairo_surface_t, create a cairo context - * with the surface as the target, using cairo_create(). - * - * There are different subtypes of #cairo_surface_t for - * different drawing backends; for example, cairo_image_surface_create() - * creates a bitmap image in memory. - * The type of a surface can be queried with cairo_surface_get_type(). - * - * The initial contents of a surface after creation depend upon the manner - * of its creation. If cairo creates the surface and backing storage for - * the user, it will be initially cleared; for example, - * cairo_image_surface_create() and cairo_surface_create_similar(). - * Alternatively, if the user passes in a reference to some backing storage - * and asks cairo to wrap that in a #cairo_surface_t, then the contents are - * not modified; for example, cairo_image_surface_create_for_data() and - * cairo_xlib_surface_create(). - * - * Memory management of #cairo_surface_t is done with - * cairo_surface_reference() and cairo_surface_destroy(). - * - * Since: 1.0 - **/ -typedef struct _cairo_surface cairo_surface_t; - -/** - * cairo_device_t: - * - * A #cairo_device_t represents the driver interface for drawing - * operations to a #cairo_surface_t. There are different subtypes of - * #cairo_device_t for different drawing backends; for example, - * cairo_egl_device_create() creates a device that wraps an EGL display and - * context. - * - * The type of a device can be queried with cairo_device_get_type(). - * - * Memory management of #cairo_device_t is done with - * cairo_device_reference() and cairo_device_destroy(). - * - * Since: 1.10 - **/ -typedef struct _cairo_device cairo_device_t; - -/** - * cairo_matrix_t: - * @xx: xx component of the affine transformation - * @yx: yx component of the affine transformation - * @xy: xy component of the affine transformation - * @yy: yy component of the affine transformation - * @x0: X translation component of the affine transformation - * @y0: Y translation component of the affine transformation - * - * A #cairo_matrix_t holds an affine transformation, such as a scale, - * rotation, shear, or a combination of those. The transformation of - * a point (x, y) is given by: - * <programlisting> - * x_new = xx * x + xy * y + x0; - * y_new = yx * x + yy * y + y0; - * </programlisting> - * - * Since: 1.0 - **/ -typedef struct _cairo_matrix { - double xx; double yx; - double xy; double yy; - double x0; double y0; -} cairo_matrix_t; - -/** - * cairo_pattern_t: - * - * A #cairo_pattern_t represents a source when drawing onto a - * surface. There are different subtypes of #cairo_pattern_t, - * for different types of sources; for example, - * cairo_pattern_create_rgb() creates a pattern for a solid - * opaque color. - * - * Other than various - * <function>cairo_pattern_create_<emphasis>type</emphasis>()</function> - * functions, some of the pattern types can be implicitly created using various - * <function>cairo_set_source_<emphasis>type</emphasis>()</function> functions; - * for example cairo_set_source_rgb(). - * - * The type of a pattern can be queried with cairo_pattern_get_type(). - * - * Memory management of #cairo_pattern_t is done with - * cairo_pattern_reference() and cairo_pattern_destroy(). - * - * Since: 1.0 - **/ -typedef struct _cairo_pattern cairo_pattern_t; - -/** - * cairo_destroy_func_t: - * @data: The data element being destroyed. - * - * #cairo_destroy_func_t the type of function which is called when a - * data element is destroyed. It is passed the pointer to the data - * element and should free any memory and resources allocated for it. - * - * Since: 1.0 - **/ -typedef void (*cairo_destroy_func_t) (void *data); - -/** - * cairo_user_data_key_t: - * @unused: not used; ignore. - * - * #cairo_user_data_key_t is used for attaching user data to cairo - * data structures. The actual contents of the struct is never used, - * and there is no need to initialize the object; only the unique - * address of a #cairo_data_key_t object is used. Typically, you - * would just use the address of a static #cairo_data_key_t object. - * - * Since: 1.0 - **/ -typedef struct _cairo_user_data_key { - int unused; -} cairo_user_data_key_t; - -/** - * cairo_status_t: - * @CAIRO_STATUS_SUCCESS: no error has occurred (Since 1.0) - * @CAIRO_STATUS_NO_MEMORY: out of memory (Since 1.0) - * @CAIRO_STATUS_INVALID_RESTORE: cairo_restore() called without matching cairo_save() (Since 1.0) - * @CAIRO_STATUS_INVALID_POP_GROUP: no saved group to pop, i.e. cairo_pop_group() without matching cairo_push_group() (Since 1.0) - * @CAIRO_STATUS_NO_CURRENT_POINT: no current point defined (Since 1.0) - * @CAIRO_STATUS_INVALID_MATRIX: invalid matrix (not invertible) (Since 1.0) - * @CAIRO_STATUS_INVALID_STATUS: invalid value for an input #cairo_status_t (Since 1.0) - * @CAIRO_STATUS_NULL_POINTER: %NULL pointer (Since 1.0) - * @CAIRO_STATUS_INVALID_STRING: input string not valid UTF-8 (Since 1.0) - * @CAIRO_STATUS_INVALID_PATH_DATA: input path data not valid (Since 1.0) - * @CAIRO_STATUS_READ_ERROR: error while reading from input stream (Since 1.0) - * @CAIRO_STATUS_WRITE_ERROR: error while writing to output stream (Since 1.0) - * @CAIRO_STATUS_SURFACE_FINISHED: target surface has been finished (Since 1.0) - * @CAIRO_STATUS_SURFACE_TYPE_MISMATCH: the surface type is not appropriate for the operation (Since 1.0) - * @CAIRO_STATUS_PATTERN_TYPE_MISMATCH: the pattern type is not appropriate for the operation (Since 1.0) - * @CAIRO_STATUS_INVALID_CONTENT: invalid value for an input #cairo_content_t (Since 1.0) - * @CAIRO_STATUS_INVALID_FORMAT: invalid value for an input #cairo_format_t (Since 1.0) - * @CAIRO_STATUS_INVALID_VISUAL: invalid value for an input Visual* (Since 1.0) - * @CAIRO_STATUS_FILE_NOT_FOUND: file not found (Since 1.0) - * @CAIRO_STATUS_INVALID_DASH: invalid value for a dash setting (Since 1.0) - * @CAIRO_STATUS_INVALID_DSC_COMMENT: invalid value for a DSC comment (Since 1.2) - * @CAIRO_STATUS_INVALID_INDEX: invalid index passed to getter (Since 1.4) - * @CAIRO_STATUS_CLIP_NOT_REPRESENTABLE: clip region not representable in desired format (Since 1.4) - * @CAIRO_STATUS_TEMP_FILE_ERROR: error creating or writing to a temporary file (Since 1.6) - * @CAIRO_STATUS_INVALID_STRIDE: invalid value for stride (Since 1.6) - * @CAIRO_STATUS_FONT_TYPE_MISMATCH: the font type is not appropriate for the operation (Since 1.8) - * @CAIRO_STATUS_USER_FONT_IMMUTABLE: the user-font is immutable (Since 1.8) - * @CAIRO_STATUS_USER_FONT_ERROR: error occurred in a user-font callback function (Since 1.8) - * @CAIRO_STATUS_NEGATIVE_COUNT: negative number used where it is not allowed (Since 1.8) - * @CAIRO_STATUS_INVALID_CLUSTERS: input clusters do not represent the accompanying text and glyph array (Since 1.8) - * @CAIRO_STATUS_INVALID_SLANT: invalid value for an input #cairo_font_slant_t (Since 1.8) - * @CAIRO_STATUS_INVALID_WEIGHT: invalid value for an input #cairo_font_weight_t (Since 1.8) - * @CAIRO_STATUS_INVALID_SIZE: invalid value (typically too big) for the size of the input (surface, pattern, etc.) (Since 1.10) - * @CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: user-font method not implemented (Since 1.10) - * @CAIRO_STATUS_DEVICE_TYPE_MISMATCH: the device type is not appropriate for the operation (Since 1.10) - * @CAIRO_STATUS_DEVICE_ERROR: an operation to the device caused an unspecified error (Since 1.10) - * @CAIRO_STATUS_INVALID_MESH_CONSTRUCTION: a mesh pattern - * construction operation was used outside of a - * cairo_mesh_pattern_begin_patch()/cairo_mesh_pattern_end_patch() - * pair (Since 1.12) - * @CAIRO_STATUS_DEVICE_FINISHED: target device has been finished (Since 1.12) - * @CAIRO_STATUS_JBIG2_GLOBAL_MISSING: %CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID has been used on at least one image - * but no image provided %CAIRO_MIME_TYPE_JBIG2_GLOBAL (Since 1.14) - * @CAIRO_STATUS_LAST_STATUS: this is a special value indicating the number of - * status values defined in this enumeration. When using this value, note - * that the version of cairo at run-time may have additional status values - * defined than the value of this symbol at compile-time. (Since 1.10) - * - * #cairo_status_t is used to indicate errors that can occur when - * using Cairo. In some cases it is returned directly by functions. - * but when using #cairo_t, the last error, if any, is stored in - * the context and can be retrieved with cairo_status(). - * - * New entries may be added in future versions. Use cairo_status_to_string() - * to get a human-readable representation of an error message. - * - * Since: 1.0 - **/ -typedef enum _cairo_status { - CAIRO_STATUS_SUCCESS = 0, - - CAIRO_STATUS_NO_MEMORY, - CAIRO_STATUS_INVALID_RESTORE, - CAIRO_STATUS_INVALID_POP_GROUP, - CAIRO_STATUS_NO_CURRENT_POINT, - CAIRO_STATUS_INVALID_MATRIX, - CAIRO_STATUS_INVALID_STATUS, - CAIRO_STATUS_NULL_POINTER, - CAIRO_STATUS_INVALID_STRING, - CAIRO_STATUS_INVALID_PATH_DATA, - CAIRO_STATUS_READ_ERROR, - CAIRO_STATUS_WRITE_ERROR, - CAIRO_STATUS_SURFACE_FINISHED, - CAIRO_STATUS_SURFACE_TYPE_MISMATCH, - CAIRO_STATUS_PATTERN_TYPE_MISMATCH, - CAIRO_STATUS_INVALID_CONTENT, - CAIRO_STATUS_INVALID_FORMAT, - CAIRO_STATUS_INVALID_VISUAL, - CAIRO_STATUS_FILE_NOT_FOUND, - CAIRO_STATUS_INVALID_DASH, - CAIRO_STATUS_INVALID_DSC_COMMENT, - CAIRO_STATUS_INVALID_INDEX, - CAIRO_STATUS_CLIP_NOT_REPRESENTABLE, - CAIRO_STATUS_TEMP_FILE_ERROR, - CAIRO_STATUS_INVALID_STRIDE, - CAIRO_STATUS_FONT_TYPE_MISMATCH, - CAIRO_STATUS_USER_FONT_IMMUTABLE, - CAIRO_STATUS_USER_FONT_ERROR, - CAIRO_STATUS_NEGATIVE_COUNT, - CAIRO_STATUS_INVALID_CLUSTERS, - CAIRO_STATUS_INVALID_SLANT, - CAIRO_STATUS_INVALID_WEIGHT, - CAIRO_STATUS_INVALID_SIZE, - CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED, - CAIRO_STATUS_DEVICE_TYPE_MISMATCH, - CAIRO_STATUS_DEVICE_ERROR, - CAIRO_STATUS_INVALID_MESH_CONSTRUCTION, - CAIRO_STATUS_DEVICE_FINISHED, - CAIRO_STATUS_JBIG2_GLOBAL_MISSING, - - CAIRO_STATUS_LAST_STATUS -} cairo_status_t; - -/** - * cairo_content_t: - * @CAIRO_CONTENT_COLOR: The surface will hold color content only. (Since 1.0) - * @CAIRO_CONTENT_ALPHA: The surface will hold alpha content only. (Since 1.0) - * @CAIRO_CONTENT_COLOR_ALPHA: The surface will hold color and alpha content. (Since 1.0) - * - * #cairo_content_t is used to describe the content that a surface will - * contain, whether color information, alpha information (translucence - * vs. opacity), or both. - * - * Note: The large values here are designed to keep #cairo_content_t - * values distinct from #cairo_format_t values so that the - * implementation can detect the error if users confuse the two types. - * - * Since: 1.0 - **/ -typedef enum _cairo_content { - CAIRO_CONTENT_COLOR = 0x1000, - CAIRO_CONTENT_ALPHA = 0x2000, - CAIRO_CONTENT_COLOR_ALPHA = 0x3000 -} cairo_content_t; - -/** - * cairo_format_t: - * @CAIRO_FORMAT_INVALID: no such format exists or is supported. - * @CAIRO_FORMAT_ARGB32: each pixel is a 32-bit quantity, with - * alpha in the upper 8 bits, then red, then green, then blue. - * The 32-bit quantities are stored native-endian. Pre-multiplied - * alpha is used. (That is, 50% transparent red is 0x80800000, - * not 0x80ff0000.) (Since 1.0) - * @CAIRO_FORMAT_RGB24: each pixel is a 32-bit quantity, with - * the upper 8 bits unused. Red, Green, and Blue are stored - * in the remaining 24 bits in that order. (Since 1.0) - * @CAIRO_FORMAT_A8: each pixel is a 8-bit quantity holding - * an alpha value. (Since 1.0) - * @CAIRO_FORMAT_A1: each pixel is a 1-bit quantity holding - * an alpha value. Pixels are packed together into 32-bit - * quantities. The ordering of the bits matches the - * endianess of the platform. On a big-endian machine, the - * first pixel is in the uppermost bit, on a little-endian - * machine the first pixel is in the least-significant bit. (Since 1.0) - * @CAIRO_FORMAT_RGB16_565: each pixel is a 16-bit quantity - * with red in the upper 5 bits, then green in the middle - * 6 bits, and blue in the lower 5 bits. (Since 1.2) - * @CAIRO_FORMAT_RGB30: like RGB24 but with 10bpc. (Since 1.12) - * - * #cairo_format_t is used to identify the memory format of - * image data. - * - * New entries may be added in future versions. - * - * Since: 1.0 - **/ -typedef enum _cairo_format { - CAIRO_FORMAT_INVALID = -1, - CAIRO_FORMAT_ARGB32 = 0, - CAIRO_FORMAT_RGB24 = 1, - CAIRO_FORMAT_A8 = 2, - CAIRO_FORMAT_A1 = 3, - CAIRO_FORMAT_RGB16_565 = 4, - CAIRO_FORMAT_RGB30 = 5 -} cairo_format_t; - - -/** - * cairo_write_func_t: - * @closure: the output closure - * @data: the buffer containing the data to write - * @length: the amount of data to write - * - * #cairo_write_func_t is the type of function which is called when a - * backend needs to write data to an output stream. It is passed the - * closure which was specified by the user at the time the write - * function was registered, the data to write and the length of the - * data in bytes. The write function should return - * %CAIRO_STATUS_SUCCESS if all the data was successfully written, - * %CAIRO_STATUS_WRITE_ERROR otherwise. - * - * Returns: the status code of the write operation - * - * Since: 1.0 - **/ -typedef cairo_status_t (*cairo_write_func_t) (void *closure, - const unsigned char *data, - unsigned int length); - -/** - * cairo_read_func_t: - * @closure: the input closure - * @data: the buffer into which to read the data - * @length: the amount of data to read - * - * #cairo_read_func_t is the type of function which is called when a - * backend needs to read data from an input stream. It is passed the - * closure which was specified by the user at the time the read - * function was registered, the buffer to read the data into and the - * length of the data in bytes. The read function should return - * %CAIRO_STATUS_SUCCESS if all the data was successfully read, - * %CAIRO_STATUS_READ_ERROR otherwise. - * - * Returns: the status code of the read operation - * - * Since: 1.0 - **/ -typedef cairo_status_t (*cairo_read_func_t) (void *closure, - unsigned char *data, - unsigned int length); - -/** - * cairo_rectangle_int_t: - * @x: X coordinate of the left side of the rectangle - * @y: Y coordinate of the the top side of the rectangle - * @width: width of the rectangle - * @height: height of the rectangle - * - * A data structure for holding a rectangle with integer coordinates. - * - * Since: 1.10 - **/ - -typedef struct _cairo_rectangle_int { - int x, y; - int width, height; -} cairo_rectangle_int_t; - - -/* Functions for manipulating state objects */ -cairo_public cairo_t * -cairo_create (cairo_surface_t *target); - -cairo_public cairo_t * -cairo_reference (cairo_t *cr); - -cairo_public void -cairo_destroy (cairo_t *cr); - -cairo_public unsigned int -cairo_get_reference_count (cairo_t *cr); - -cairo_public void * -cairo_get_user_data (cairo_t *cr, - const cairo_user_data_key_t *key); - -cairo_public cairo_status_t -cairo_set_user_data (cairo_t *cr, - const cairo_user_data_key_t *key, - void *user_data, - cairo_destroy_func_t destroy); - -cairo_public void -cairo_save (cairo_t *cr); - -cairo_public void -cairo_restore (cairo_t *cr); - -cairo_public void -cairo_push_group (cairo_t *cr); - -cairo_public void -cairo_push_group_with_content (cairo_t *cr, cairo_content_t content); - -cairo_public cairo_pattern_t * -cairo_pop_group (cairo_t *cr); - -cairo_public void -cairo_pop_group_to_source (cairo_t *cr); - -/* Modify state */ - -/** - * cairo_operator_t: - * @CAIRO_OPERATOR_CLEAR: clear destination layer (bounded) (Since 1.0) - * @CAIRO_OPERATOR_SOURCE: replace destination layer (bounded) (Since 1.0) - * @CAIRO_OPERATOR_OVER: draw source layer on top of destination layer - * (bounded) (Since 1.0) - * @CAIRO_OPERATOR_IN: draw source where there was destination content - * (unbounded) (Since 1.0) - * @CAIRO_OPERATOR_OUT: draw source where there was no destination - * content (unbounded) (Since 1.0) - * @CAIRO_OPERATOR_ATOP: draw source on top of destination content and - * only there (Since 1.0) - * @CAIRO_OPERATOR_DEST: ignore the source (Since 1.0) - * @CAIRO_OPERATOR_DEST_OVER: draw destination on top of source (Since 1.0) - * @CAIRO_OPERATOR_DEST_IN: leave destination only where there was - * source content (unbounded) (Since 1.0) - * @CAIRO_OPERATOR_DEST_OUT: leave destination only where there was no - * source content (Since 1.0) - * @CAIRO_OPERATOR_DEST_ATOP: leave destination on top of source content - * and only there (unbounded) (Since 1.0) - * @CAIRO_OPERATOR_XOR: source and destination are shown where there is only - * one of them (Since 1.0) - * @CAIRO_OPERATOR_ADD: source and destination layers are accumulated (Since 1.0) - * @CAIRO_OPERATOR_SATURATE: like over, but assuming source and dest are - * disjoint geometries (Since 1.0) - * @CAIRO_OPERATOR_MULTIPLY: source and destination layers are multiplied. - * This causes the result to be at least as dark as the darker inputs. (Since 1.10) - * @CAIRO_OPERATOR_SCREEN: source and destination are complemented and - * multiplied. This causes the result to be at least as light as the lighter - * inputs. (Since 1.10) - * @CAIRO_OPERATOR_OVERLAY: multiplies or screens, depending on the - * lightness of the destination color. (Since 1.10) - * @CAIRO_OPERATOR_DARKEN: replaces the destination with the source if it - * is darker, otherwise keeps the source. (Since 1.10) - * @CAIRO_OPERATOR_LIGHTEN: replaces the destination with the source if it - * is lighter, otherwise keeps the source. (Since 1.10) - * @CAIRO_OPERATOR_COLOR_DODGE: brightens the destination color to reflect - * the source color. (Since 1.10) - * @CAIRO_OPERATOR_COLOR_BURN: darkens the destination color to reflect - * the source color. (Since 1.10) - * @CAIRO_OPERATOR_HARD_LIGHT: Multiplies or screens, dependent on source - * color. (Since 1.10) - * @CAIRO_OPERATOR_SOFT_LIGHT: Darkens or lightens, dependent on source - * color. (Since 1.10) - * @CAIRO_OPERATOR_DIFFERENCE: Takes the difference of the source and - * destination color. (Since 1.10) - * @CAIRO_OPERATOR_EXCLUSION: Produces an effect similar to difference, but - * with lower contrast. (Since 1.10) - * @CAIRO_OPERATOR_HSL_HUE: Creates a color with the hue of the source - * and the saturation and luminosity of the target. (Since 1.10) - * @CAIRO_OPERATOR_HSL_SATURATION: Creates a color with the saturation - * of the source and the hue and luminosity of the target. Painting with - * this mode onto a gray area produces no change. (Since 1.10) - * @CAIRO_OPERATOR_HSL_COLOR: Creates a color with the hue and saturation - * of the source and the luminosity of the target. This preserves the gray - * levels of the target and is useful for coloring monochrome images or - * tinting color images. (Since 1.10) - * @CAIRO_OPERATOR_HSL_LUMINOSITY: Creates a color with the luminosity of - * the source and the hue and saturation of the target. This produces an - * inverse effect to @CAIRO_OPERATOR_HSL_COLOR. (Since 1.10) - * - * #cairo_operator_t is used to set the compositing operator for all cairo - * drawing operations. - * - * The default operator is %CAIRO_OPERATOR_OVER. - * - * The operators marked as <firstterm>unbounded</firstterm> modify their - * destination even outside of the mask layer (that is, their effect is not - * bound by the mask layer). However, their effect can still be limited by - * way of clipping. - * - * To keep things simple, the operator descriptions here - * document the behavior for when both source and destination are either fully - * transparent or fully opaque. The actual implementation works for - * translucent layers too. - * For a more detailed explanation of the effects of each operator, including - * the mathematical definitions, see - * <ulink url="http://cairographics.org/operators/">http://cairographics.org/operators/</ulink>. - * - * Since: 1.0 - **/ -typedef enum _cairo_operator { - CAIRO_OPERATOR_CLEAR, - - CAIRO_OPERATOR_SOURCE, - CAIRO_OPERATOR_OVER, - CAIRO_OPERATOR_IN, - CAIRO_OPERATOR_OUT, - CAIRO_OPERATOR_ATOP, - - CAIRO_OPERATOR_DEST, - CAIRO_OPERATOR_DEST_OVER, - CAIRO_OPERATOR_DEST_IN, - CAIRO_OPERATOR_DEST_OUT, - CAIRO_OPERATOR_DEST_ATOP, - - CAIRO_OPERATOR_XOR, - CAIRO_OPERATOR_ADD, - CAIRO_OPERATOR_SATURATE, - - CAIRO_OPERATOR_MULTIPLY, - CAIRO_OPERATOR_SCREEN, - CAIRO_OPERATOR_OVERLAY, - CAIRO_OPERATOR_DARKEN, - CAIRO_OPERATOR_LIGHTEN, - CAIRO_OPERATOR_COLOR_DODGE, - CAIRO_OPERATOR_COLOR_BURN, - CAIRO_OPERATOR_HARD_LIGHT, - CAIRO_OPERATOR_SOFT_LIGHT, - CAIRO_OPERATOR_DIFFERENCE, - CAIRO_OPERATOR_EXCLUSION, - CAIRO_OPERATOR_HSL_HUE, - CAIRO_OPERATOR_HSL_SATURATION, - CAIRO_OPERATOR_HSL_COLOR, - CAIRO_OPERATOR_HSL_LUMINOSITY -} cairo_operator_t; - -cairo_public void -cairo_set_operator (cairo_t *cr, cairo_operator_t op); - -cairo_public void -cairo_set_source (cairo_t *cr, cairo_pattern_t *source); - -cairo_public void -cairo_set_source_rgb (cairo_t *cr, double red, double green, double blue); - -cairo_public void -cairo_set_source_rgba (cairo_t *cr, - double red, double green, double blue, - double alpha); - -cairo_public void -cairo_set_source_surface (cairo_t *cr, - cairo_surface_t *surface, - double x, - double y); - -cairo_public void -cairo_set_tolerance (cairo_t *cr, double tolerance); - -/** - * cairo_antialias_t: - * @CAIRO_ANTIALIAS_DEFAULT: Use the default antialiasing for - * the subsystem and target device, since 1.0 - * @CAIRO_ANTIALIAS_NONE: Use a bilevel alpha mask, since 1.0 - * @CAIRO_ANTIALIAS_GRAY: Perform single-color antialiasing (using - * shades of gray for black text on a white background, for example), since 1.0 - * @CAIRO_ANTIALIAS_SUBPIXEL: Perform antialiasing by taking - * advantage of the order of subpixel elements on devices - * such as LCD panels, since 1.0 - * @CAIRO_ANTIALIAS_FAST: Hint that the backend should perform some - * antialiasing but prefer speed over quality, since 1.12 - * @CAIRO_ANTIALIAS_GOOD: The backend should balance quality against - * performance, since 1.12 - * @CAIRO_ANTIALIAS_BEST: Hint that the backend should render at the highest - * quality, sacrificing speed if necessary, since 1.12 - * - * Specifies the type of antialiasing to do when rendering text or shapes. - * - * As it is not necessarily clear from the above what advantages a particular - * antialias method provides, since 1.12, there is also a set of hints: - * @CAIRO_ANTIALIAS_FAST: Allow the backend to degrade raster quality for speed - * @CAIRO_ANTIALIAS_GOOD: A balance between speed and quality - * @CAIRO_ANTIALIAS_BEST: A high-fidelity, but potentially slow, raster mode - * - * These make no guarantee on how the backend will perform its rasterisation - * (if it even rasterises!), nor that they have any differing effect other - * than to enable some form of antialiasing. In the case of glyph rendering, - * @CAIRO_ANTIALIAS_FAST and @CAIRO_ANTIALIAS_GOOD will be mapped to - * @CAIRO_ANTIALIAS_GRAY, with @CAIRO_ANTALIAS_BEST being equivalent to - * @CAIRO_ANTIALIAS_SUBPIXEL. - * - * The interpretation of @CAIRO_ANTIALIAS_DEFAULT is left entirely up to - * the backend, typically this will be similar to @CAIRO_ANTIALIAS_GOOD. - * - * Since: 1.0 - **/ -typedef enum _cairo_antialias { - CAIRO_ANTIALIAS_DEFAULT, - - /* method */ - CAIRO_ANTIALIAS_NONE, - CAIRO_ANTIALIAS_GRAY, - CAIRO_ANTIALIAS_SUBPIXEL, - - /* hints */ - CAIRO_ANTIALIAS_FAST, - CAIRO_ANTIALIAS_GOOD, - CAIRO_ANTIALIAS_BEST -} cairo_antialias_t; - -cairo_public void -cairo_set_antialias (cairo_t *cr, cairo_antialias_t antialias); - -/** - * cairo_fill_rule_t: - * @CAIRO_FILL_RULE_WINDING: If the path crosses the ray from - * left-to-right, counts +1. If the path crosses the ray - * from right to left, counts -1. (Left and right are determined - * from the perspective of looking along the ray from the starting - * point.) If the total count is non-zero, the point will be filled. (Since 1.0) - * @CAIRO_FILL_RULE_EVEN_ODD: Counts the total number of - * intersections, without regard to the orientation of the contour. If - * the total number of intersections is odd, the point will be - * filled. (Since 1.0) - * - * #cairo_fill_rule_t is used to select how paths are filled. For both - * fill rules, whether or not a point is included in the fill is - * determined by taking a ray from that point to infinity and looking - * at intersections with the path. The ray can be in any direction, - * as long as it doesn't pass through the end point of a segment - * or have a tricky intersection such as intersecting tangent to the path. - * (Note that filling is not actually implemented in this way. This - * is just a description of the rule that is applied.) - * - * The default fill rule is %CAIRO_FILL_RULE_WINDING. - * - * New entries may be added in future versions. - * - * Since: 1.0 - **/ -typedef enum _cairo_fill_rule { - CAIRO_FILL_RULE_WINDING, - CAIRO_FILL_RULE_EVEN_ODD -} cairo_fill_rule_t; - -cairo_public void -cairo_set_fill_rule (cairo_t *cr, cairo_fill_rule_t fill_rule); - -cairo_public void -cairo_set_line_width (cairo_t *cr, double width); - -/** - * cairo_line_cap_t: - * @CAIRO_LINE_CAP_BUTT: start(stop) the line exactly at the start(end) point (Since 1.0) - * @CAIRO_LINE_CAP_ROUND: use a round ending, the center of the circle is the end point (Since 1.0) - * @CAIRO_LINE_CAP_SQUARE: use squared ending, the center of the square is the end point (Since 1.0) - * - * Specifies how to render the endpoints of the path when stroking. - * - * The default line cap style is %CAIRO_LINE_CAP_BUTT. - * - * Since: 1.0 - **/ -typedef enum _cairo_line_cap { - CAIRO_LINE_CAP_BUTT, - CAIRO_LINE_CAP_ROUND, - CAIRO_LINE_CAP_SQUARE -} cairo_line_cap_t; - -cairo_public void -cairo_set_line_cap (cairo_t *cr, cairo_line_cap_t line_cap); - -/** - * cairo_line_join_t: - * @CAIRO_LINE_JOIN_MITER: use a sharp (angled) corner, see - * cairo_set_miter_limit() (Since 1.0) - * @CAIRO_LINE_JOIN_ROUND: use a rounded join, the center of the circle is the - * joint point (Since 1.0) - * @CAIRO_LINE_JOIN_BEVEL: use a cut-off join, the join is cut off at half - * the line width from the joint point (Since 1.0) - * - * Specifies how to render the junction of two lines when stroking. - * - * The default line join style is %CAIRO_LINE_JOIN_MITER. - * - * Since: 1.0 - **/ -typedef enum _cairo_line_join { - CAIRO_LINE_JOIN_MITER, - CAIRO_LINE_JOIN_ROUND, - CAIRO_LINE_JOIN_BEVEL -} cairo_line_join_t; - -cairo_public void -cairo_set_line_join (cairo_t *cr, cairo_line_join_t line_join); - -cairo_public void -cairo_set_dash (cairo_t *cr, - const double *dashes, - int num_dashes, - double offset); - -cairo_public void -cairo_set_miter_limit (cairo_t *cr, double limit); - -cairo_public void -cairo_translate (cairo_t *cr, double tx, double ty); - -cairo_public void -cairo_scale (cairo_t *cr, double sx, double sy); - -cairo_public void -cairo_rotate (cairo_t *cr, double angle); - -cairo_public void -cairo_transform (cairo_t *cr, - const cairo_matrix_t *matrix); - -cairo_public void -cairo_set_matrix (cairo_t *cr, - const cairo_matrix_t *matrix); - -cairo_public void -cairo_identity_matrix (cairo_t *cr); - -cairo_public void -cairo_user_to_device (cairo_t *cr, double *x, double *y); - -cairo_public void -cairo_user_to_device_distance (cairo_t *cr, double *dx, double *dy); - -cairo_public void -cairo_device_to_user (cairo_t *cr, double *x, double *y); - -cairo_public void -cairo_device_to_user_distance (cairo_t *cr, double *dx, double *dy); - -/* Path creation functions */ -cairo_public void -cairo_new_path (cairo_t *cr); - -cairo_public void -cairo_move_to (cairo_t *cr, double x, double y); - -cairo_public void -cairo_new_sub_path (cairo_t *cr); - -cairo_public void -cairo_line_to (cairo_t *cr, double x, double y); - -cairo_public void -cairo_curve_to (cairo_t *cr, - double x1, double y1, - double x2, double y2, - double x3, double y3); - -cairo_public void -cairo_arc (cairo_t *cr, - double xc, double yc, - double radius, - double angle1, double angle2); - -cairo_public void -cairo_arc_negative (cairo_t *cr, - double xc, double yc, - double radius, - double angle1, double angle2); - -/* XXX: NYI -cairo_public void -cairo_arc_to (cairo_t *cr, - double x1, double y1, - double x2, double y2, - double radius); -*/ - -cairo_public void -cairo_rel_move_to (cairo_t *cr, double dx, double dy); - -cairo_public void -cairo_rel_line_to (cairo_t *cr, double dx, double dy); - -cairo_public void -cairo_rel_curve_to (cairo_t *cr, - double dx1, double dy1, - double dx2, double dy2, - double dx3, double dy3); - -cairo_public void -cairo_rectangle (cairo_t *cr, - double x, double y, - double width, double height); - -/* XXX: NYI -cairo_public void -cairo_stroke_to_path (cairo_t *cr); -*/ - -cairo_public void -cairo_close_path (cairo_t *cr); - -cairo_public void -cairo_path_extents (cairo_t *cr, - double *x1, double *y1, - double *x2, double *y2); - -/* Painting functions */ -cairo_public void -cairo_paint (cairo_t *cr); - -cairo_public void -cairo_paint_with_alpha (cairo_t *cr, - double alpha); - -cairo_public void -cairo_mask (cairo_t *cr, - cairo_pattern_t *pattern); - -cairo_public void -cairo_mask_surface (cairo_t *cr, - cairo_surface_t *surface, - double surface_x, - double surface_y); - -cairo_public void -cairo_stroke (cairo_t *cr); - -cairo_public void -cairo_stroke_preserve (cairo_t *cr); - -cairo_public void -cairo_fill (cairo_t *cr); - -cairo_public void -cairo_fill_preserve (cairo_t *cr); - -cairo_public void -cairo_copy_page (cairo_t *cr); - -cairo_public void -cairo_show_page (cairo_t *cr); - -/* Insideness testing */ -cairo_public cairo_bool_t -cairo_in_stroke (cairo_t *cr, double x, double y); - -cairo_public cairo_bool_t -cairo_in_fill (cairo_t *cr, double x, double y); - -cairo_public cairo_bool_t -cairo_in_clip (cairo_t *cr, double x, double y); - -/* Rectangular extents */ -cairo_public void -cairo_stroke_extents (cairo_t *cr, - double *x1, double *y1, - double *x2, double *y2); - -cairo_public void -cairo_fill_extents (cairo_t *cr, - double *x1, double *y1, - double *x2, double *y2); - -/* Clipping */ -cairo_public void -cairo_reset_clip (cairo_t *cr); - -cairo_public void -cairo_clip (cairo_t *cr); - -cairo_public void -cairo_clip_preserve (cairo_t *cr); - -cairo_public void -cairo_clip_extents (cairo_t *cr, - double *x1, double *y1, - double *x2, double *y2); - -/** - * cairo_rectangle_t: - * @x: X coordinate of the left side of the rectangle - * @y: Y coordinate of the the top side of the rectangle - * @width: width of the rectangle - * @height: height of the rectangle - * - * A data structure for holding a rectangle. - * - * Since: 1.4 - **/ -typedef struct _cairo_rectangle { - double x, y, width, height; -} cairo_rectangle_t; - -/** - * cairo_rectangle_list_t: - * @status: Error status of the rectangle list - * @rectangles: Array containing the rectangles - * @num_rectangles: Number of rectangles in this list - * - * A data structure for holding a dynamically allocated - * array of rectangles. - * - * Since: 1.4 - **/ -typedef struct _cairo_rectangle_list { - cairo_status_t status; - cairo_rectangle_t *rectangles; - int num_rectangles; -} cairo_rectangle_list_t; - -cairo_public cairo_rectangle_list_t * -cairo_copy_clip_rectangle_list (cairo_t *cr); - -cairo_public void -cairo_rectangle_list_destroy (cairo_rectangle_list_t *rectangle_list); - -/* Font/Text functions */ - -/** - * cairo_scaled_font_t: - * - * A #cairo_scaled_font_t is a font scaled to a particular size and device - * resolution. A #cairo_scaled_font_t is most useful for low-level font - * usage where a library or application wants to cache a reference - * to a scaled font to speed up the computation of metrics. - * - * There are various types of scaled fonts, depending on the - * <firstterm>font backend</firstterm> they use. The type of a - * scaled font can be queried using cairo_scaled_font_get_type(). - * - * Memory management of #cairo_scaled_font_t is done with - * cairo_scaled_font_reference() and cairo_scaled_font_destroy(). - * - * Since: 1.0 - **/ -typedef struct _cairo_scaled_font cairo_scaled_font_t; - -/** - * cairo_font_face_t: - * - * A #cairo_font_face_t specifies all aspects of a font other - * than the size or font matrix (a font matrix is used to distort - * a font by sheering it or scaling it unequally in the two - * directions) . A font face can be set on a #cairo_t by using - * cairo_set_font_face(); the size and font matrix are set with - * cairo_set_font_size() and cairo_set_font_matrix(). - * - * There are various types of font faces, depending on the - * <firstterm>font backend</firstterm> they use. The type of a - * font face can be queried using cairo_font_face_get_type(). - * - * Memory management of #cairo_font_face_t is done with - * cairo_font_face_reference() and cairo_font_face_destroy(). - * - * Since: 1.0 - **/ -typedef struct _cairo_font_face cairo_font_face_t; - -/** - * cairo_glyph_t: - * @index: glyph index in the font. The exact interpretation of the - * glyph index depends on the font technology being used. - * @x: the offset in the X direction between the origin used for - * drawing or measuring the string and the origin of this glyph. - * @y: the offset in the Y direction between the origin used for - * drawing or measuring the string and the origin of this glyph. - * - * The #cairo_glyph_t structure holds information about a single glyph - * when drawing or measuring text. A font is (in simple terms) a - * collection of shapes used to draw text. A glyph is one of these - * shapes. There can be multiple glyphs for a single character - * (alternates to be used in different contexts, for example), or a - * glyph can be a <firstterm>ligature</firstterm> of multiple - * characters. Cairo doesn't expose any way of converting input text - * into glyphs, so in order to use the Cairo interfaces that take - * arrays of glyphs, you must directly access the appropriate - * underlying font system. - * - * Note that the offsets given by @x and @y are not cumulative. When - * drawing or measuring text, each glyph is individually positioned - * with respect to the overall origin - * - * Since: 1.0 - **/ -typedef struct { - unsigned long index; - double x; - double y; -} cairo_glyph_t; - -cairo_public cairo_glyph_t * -cairo_glyph_allocate (int num_glyphs); - -cairo_public void -cairo_glyph_free (cairo_glyph_t *glyphs); - -/** - * cairo_text_cluster_t: - * @num_bytes: the number of bytes of UTF-8 text covered by cluster - * @num_glyphs: the number of glyphs covered by cluster - * - * The #cairo_text_cluster_t structure holds information about a single - * <firstterm>text cluster</firstterm>. A text cluster is a minimal - * mapping of some glyphs corresponding to some UTF-8 text. - * - * For a cluster to be valid, both @num_bytes and @num_glyphs should - * be non-negative, and at least one should be non-zero. - * Note that clusters with zero glyphs are not as well supported as - * normal clusters. For example, PDF rendering applications typically - * ignore those clusters when PDF text is being selected. - * - * See cairo_show_text_glyphs() for how clusters are used in advanced - * text operations. - * - * Since: 1.8 - **/ -typedef struct { - int num_bytes; - int num_glyphs; -} cairo_text_cluster_t; - -cairo_public cairo_text_cluster_t * -cairo_text_cluster_allocate (int num_clusters); - -cairo_public void -cairo_text_cluster_free (cairo_text_cluster_t *clusters); - -/** - * cairo_text_cluster_flags_t: - * @CAIRO_TEXT_CLUSTER_FLAG_BACKWARD: The clusters in the cluster array - * map to glyphs in the glyph array from end to start. (Since 1.8) - * - * Specifies properties of a text cluster mapping. - * - * Since: 1.8 - **/ -typedef enum _cairo_text_cluster_flags { - CAIRO_TEXT_CLUSTER_FLAG_BACKWARD = 0x00000001 -} cairo_text_cluster_flags_t; - -/** - * cairo_text_extents_t: - * @x_bearing: the horizontal distance from the origin to the - * leftmost part of the glyphs as drawn. Positive if the - * glyphs lie entirely to the right of the origin. - * @y_bearing: the vertical distance from the origin to the - * topmost part of the glyphs as drawn. Positive only if the - * glyphs lie completely below the origin; will usually be - * negative. - * @width: width of the glyphs as drawn - * @height: height of the glyphs as drawn - * @x_advance:distance to advance in the X direction - * after drawing these glyphs - * @y_advance: distance to advance in the Y direction - * after drawing these glyphs. Will typically be zero except - * for vertical text layout as found in East-Asian languages. - * - * The #cairo_text_extents_t structure stores the extents of a single - * glyph or a string of glyphs in user-space coordinates. Because text - * extents are in user-space coordinates, they are mostly, but not - * entirely, independent of the current transformation matrix. If you call - * <literal>cairo_scale(cr, 2.0, 2.0)</literal>, text will - * be drawn twice as big, but the reported text extents will not be - * doubled. They will change slightly due to hinting (so you can't - * assume that metrics are independent of the transformation matrix), - * but otherwise will remain unchanged. - * - * Since: 1.0 - **/ -typedef struct { - double x_bearing; - double y_bearing; - double width; - double height; - double x_advance; - double y_advance; -} cairo_text_extents_t; - -/** - * cairo_font_extents_t: - * @ascent: the distance that the font extends above the baseline. - * Note that this is not always exactly equal to the maximum - * of the extents of all the glyphs in the font, but rather - * is picked to express the font designer's intent as to - * how the font should align with elements above it. - * @descent: the distance that the font extends below the baseline. - * This value is positive for typical fonts that include - * portions below the baseline. Note that this is not always - * exactly equal to the maximum of the extents of all the - * glyphs in the font, but rather is picked to express the - * font designer's intent as to how the font should - * align with elements below it. - * @height: the recommended vertical distance between baselines when - * setting consecutive lines of text with the font. This - * is greater than @ascent+@descent by a - * quantity known as the <firstterm>line spacing</firstterm> - * or <firstterm>external leading</firstterm>. When space - * is at a premium, most fonts can be set with only - * a distance of @ascent+@descent between lines. - * @max_x_advance: the maximum distance in the X direction that - * the origin is advanced for any glyph in the font. - * @max_y_advance: the maximum distance in the Y direction that - * the origin is advanced for any glyph in the font. - * This will be zero for normal fonts used for horizontal - * writing. (The scripts of East Asia are sometimes written - * vertically.) - * - * The #cairo_font_extents_t structure stores metric information for - * a font. Values are given in the current user-space coordinate - * system. - * - * Because font metrics are in user-space coordinates, they are - * mostly, but not entirely, independent of the current transformation - * matrix. If you call <literal>cairo_scale(cr, 2.0, 2.0)</literal>, - * text will be drawn twice as big, but the reported text extents will - * not be doubled. They will change slightly due to hinting (so you - * can't assume that metrics are independent of the transformation - * matrix), but otherwise will remain unchanged. - * - * Since: 1.0 - **/ -typedef struct { - double ascent; - double descent; - double height; - double max_x_advance; - double max_y_advance; -} cairo_font_extents_t; - -/** - * cairo_font_slant_t: - * @CAIRO_FONT_SLANT_NORMAL: Upright font style, since 1.0 - * @CAIRO_FONT_SLANT_ITALIC: Italic font style, since 1.0 - * @CAIRO_FONT_SLANT_OBLIQUE: Oblique font style, since 1.0 - * - * Specifies variants of a font face based on their slant. - * - * Since: 1.0 - **/ -typedef enum _cairo_font_slant { - CAIRO_FONT_SLANT_NORMAL, - CAIRO_FONT_SLANT_ITALIC, - CAIRO_FONT_SLANT_OBLIQUE -} cairo_font_slant_t; - -/** - * cairo_font_weight_t: - * @CAIRO_FONT_WEIGHT_NORMAL: Normal font weight, since 1.0 - * @CAIRO_FONT_WEIGHT_BOLD: Bold font weight, since 1.0 - * - * Specifies variants of a font face based on their weight. - * - * Since: 1.0 - **/ -typedef enum _cairo_font_weight { - CAIRO_FONT_WEIGHT_NORMAL, - CAIRO_FONT_WEIGHT_BOLD -} cairo_font_weight_t; - -/** - * cairo_subpixel_order_t: - * @CAIRO_SUBPIXEL_ORDER_DEFAULT: Use the default subpixel order for - * for the target device, since 1.0 - * @CAIRO_SUBPIXEL_ORDER_RGB: Subpixel elements are arranged horizontally - * with red at the left, since 1.0 - * @CAIRO_SUBPIXEL_ORDER_BGR: Subpixel elements are arranged horizontally - * with blue at the left, since 1.0 - * @CAIRO_SUBPIXEL_ORDER_VRGB: Subpixel elements are arranged vertically - * with red at the top, since 1.0 - * @CAIRO_SUBPIXEL_ORDER_VBGR: Subpixel elements are arranged vertically - * with blue at the top, since 1.0 - * - * The subpixel order specifies the order of color elements within - * each pixel on the display device when rendering with an - * antialiasing mode of %CAIRO_ANTIALIAS_SUBPIXEL. - * - * Since: 1.0 - **/ -typedef enum _cairo_subpixel_order { - CAIRO_SUBPIXEL_ORDER_DEFAULT, - CAIRO_SUBPIXEL_ORDER_RGB, - CAIRO_SUBPIXEL_ORDER_BGR, - CAIRO_SUBPIXEL_ORDER_VRGB, - CAIRO_SUBPIXEL_ORDER_VBGR -} cairo_subpixel_order_t; - -/** - * cairo_hint_style_t: - * @CAIRO_HINT_STYLE_DEFAULT: Use the default hint style for - * font backend and target device, since 1.0 - * @CAIRO_HINT_STYLE_NONE: Do not hint outlines, since 1.0 - * @CAIRO_HINT_STYLE_SLIGHT: Hint outlines slightly to improve - * contrast while retaining good fidelity to the original - * shapes, since 1.0 - * @CAIRO_HINT_STYLE_MEDIUM: Hint outlines with medium strength - * giving a compromise between fidelity to the original shapes - * and contrast, since 1.0 - * @CAIRO_HINT_STYLE_FULL: Hint outlines to maximize contrast, since 1.0 - * - * Specifies the type of hinting to do on font outlines. Hinting - * is the process of fitting outlines to the pixel grid in order - * to improve the appearance of the result. Since hinting outlines - * involves distorting them, it also reduces the faithfulness - * to the original outline shapes. Not all of the outline hinting - * styles are supported by all font backends. - * - * New entries may be added in future versions. - * - * Since: 1.0 - **/ -typedef enum _cairo_hint_style { - CAIRO_HINT_STYLE_DEFAULT, - CAIRO_HINT_STYLE_NONE, - CAIRO_HINT_STYLE_SLIGHT, - CAIRO_HINT_STYLE_MEDIUM, - CAIRO_HINT_STYLE_FULL -} cairo_hint_style_t; - -/** - * cairo_hint_metrics_t: - * @CAIRO_HINT_METRICS_DEFAULT: Hint metrics in the default - * manner for the font backend and target device, since 1.0 - * @CAIRO_HINT_METRICS_OFF: Do not hint font metrics, since 1.0 - * @CAIRO_HINT_METRICS_ON: Hint font metrics, since 1.0 - * - * Specifies whether to hint font metrics; hinting font metrics - * means quantizing them so that they are integer values in - * device space. Doing this improves the consistency of - * letter and line spacing, however it also means that text - * will be laid out differently at different zoom factors. - * - * Since: 1.0 - **/ -typedef enum _cairo_hint_metrics { - CAIRO_HINT_METRICS_DEFAULT, - CAIRO_HINT_METRICS_OFF, - CAIRO_HINT_METRICS_ON -} cairo_hint_metrics_t; - -/** - * cairo_font_options_t: - * - * An opaque structure holding all options that are used when - * rendering fonts. - * - * Individual features of a #cairo_font_options_t can be set or - * accessed using functions named - * <function>cairo_font_options_set_<emphasis>feature_name</emphasis>()</function> and - * <function>cairo_font_options_get_<emphasis>feature_name</emphasis>()</function>, like - * cairo_font_options_set_antialias() and - * cairo_font_options_get_antialias(). - * - * New features may be added to a #cairo_font_options_t in the - * future. For this reason, cairo_font_options_copy(), - * cairo_font_options_equal(), cairo_font_options_merge(), and - * cairo_font_options_hash() should be used to copy, check - * for equality, merge, or compute a hash value of - * #cairo_font_options_t objects. - * - * Since: 1.0 - **/ -typedef struct _cairo_font_options cairo_font_options_t; - -cairo_public cairo_font_options_t * -cairo_font_options_create (void); - -cairo_public cairo_font_options_t * -cairo_font_options_copy (const cairo_font_options_t *original); - -cairo_public void -cairo_font_options_destroy (cairo_font_options_t *options); - -cairo_public cairo_status_t -cairo_font_options_status (cairo_font_options_t *options); - -cairo_public void -cairo_font_options_merge (cairo_font_options_t *options, - const cairo_font_options_t *other); -cairo_public cairo_bool_t -cairo_font_options_equal (const cairo_font_options_t *options, - const cairo_font_options_t *other); - -cairo_public unsigned long -cairo_font_options_hash (const cairo_font_options_t *options); - -cairo_public void -cairo_font_options_set_antialias (cairo_font_options_t *options, - cairo_antialias_t antialias); -cairo_public cairo_antialias_t -cairo_font_options_get_antialias (const cairo_font_options_t *options); - -cairo_public void -cairo_font_options_set_subpixel_order (cairo_font_options_t *options, - cairo_subpixel_order_t subpixel_order); -cairo_public cairo_subpixel_order_t -cairo_font_options_get_subpixel_order (const cairo_font_options_t *options); - -cairo_public void -cairo_font_options_set_hint_style (cairo_font_options_t *options, - cairo_hint_style_t hint_style); -cairo_public cairo_hint_style_t -cairo_font_options_get_hint_style (const cairo_font_options_t *options); - -cairo_public void -cairo_font_options_set_hint_metrics (cairo_font_options_t *options, - cairo_hint_metrics_t hint_metrics); -cairo_public cairo_hint_metrics_t -cairo_font_options_get_hint_metrics (const cairo_font_options_t *options); - -/* This interface is for dealing with text as text, not caring about the - font object inside the the cairo_t. */ - -cairo_public void -cairo_select_font_face (cairo_t *cr, - const char *family, - cairo_font_slant_t slant, - cairo_font_weight_t weight); - -cairo_public void -cairo_set_font_size (cairo_t *cr, double size); - -cairo_public void -cairo_set_font_matrix (cairo_t *cr, - const cairo_matrix_t *matrix); - -cairo_public void -cairo_get_font_matrix (cairo_t *cr, - cairo_matrix_t *matrix); - -cairo_public void -cairo_set_font_options (cairo_t *cr, - const cairo_font_options_t *options); - -cairo_public void -cairo_get_font_options (cairo_t *cr, - cairo_font_options_t *options); - -cairo_public void -cairo_set_font_face (cairo_t *cr, cairo_font_face_t *font_face); - -cairo_public cairo_font_face_t * -cairo_get_font_face (cairo_t *cr); - -cairo_public void -cairo_set_scaled_font (cairo_t *cr, - const cairo_scaled_font_t *scaled_font); - -cairo_public cairo_scaled_font_t * -cairo_get_scaled_font (cairo_t *cr); - -cairo_public void -cairo_show_text (cairo_t *cr, const char *utf8); - -cairo_public void -cairo_show_glyphs (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs); - -cairo_public void -cairo_show_text_glyphs (cairo_t *cr, - const char *utf8, - int utf8_len, - const cairo_glyph_t *glyphs, - int num_glyphs, - const cairo_text_cluster_t *clusters, - int num_clusters, - cairo_text_cluster_flags_t cluster_flags); - -cairo_public void -cairo_text_path (cairo_t *cr, const char *utf8); - -cairo_public void -cairo_glyph_path (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs); - -cairo_public void -cairo_text_extents (cairo_t *cr, - const char *utf8, - cairo_text_extents_t *extents); - -cairo_public void -cairo_glyph_extents (cairo_t *cr, - const cairo_glyph_t *glyphs, - int num_glyphs, - cairo_text_extents_t *extents); - -cairo_public void -cairo_font_extents (cairo_t *cr, - cairo_font_extents_t *extents); - -/* Generic identifier for a font style */ - -cairo_public cairo_font_face_t * -cairo_font_face_reference (cairo_font_face_t *font_face); - -cairo_public void -cairo_font_face_destroy (cairo_font_face_t *font_face); - -cairo_public unsigned int -cairo_font_face_get_reference_count (cairo_font_face_t *font_face); - -cairo_public cairo_status_t -cairo_font_face_status (cairo_font_face_t *font_face); - - -/** - * cairo_font_type_t: - * @CAIRO_FONT_TYPE_TOY: The font was created using cairo's toy font api (Since: 1.2) - * @CAIRO_FONT_TYPE_FT: The font is of type FreeType (Since: 1.2) - * @CAIRO_FONT_TYPE_WIN32: The font is of type Win32 (Since: 1.2) - * @CAIRO_FONT_TYPE_QUARTZ: The font is of type Quartz (Since: 1.6, in 1.2 and - * 1.4 it was named CAIRO_FONT_TYPE_ATSUI) - * @CAIRO_FONT_TYPE_USER: The font was create using cairo's user font api (Since: 1.8) - * - * #cairo_font_type_t is used to describe the type of a given font - * face or scaled font. The font types are also known as "font - * backends" within cairo. - * - * The type of a font face is determined by the function used to - * create it, which will generally be of the form - * <function>cairo_<emphasis>type</emphasis>_font_face_create(<!-- -->)</function>. - * The font face type can be queried with cairo_font_face_get_type() - * - * The various #cairo_font_face_t functions can be used with a font face - * of any type. - * - * The type of a scaled font is determined by the type of the font - * face passed to cairo_scaled_font_create(). The scaled font type can - * be queried with cairo_scaled_font_get_type() - * - * The various #cairo_scaled_font_t functions can be used with scaled - * fonts of any type, but some font backends also provide - * type-specific functions that must only be called with a scaled font - * of the appropriate type. These functions have names that begin with - * <function>cairo_<emphasis>type</emphasis>_scaled_font(<!-- -->)</function> - * such as cairo_ft_scaled_font_lock_face(). - * - * The behavior of calling a type-specific function with a scaled font - * of the wrong type is undefined. - * - * New entries may be added in future versions. - * - * Since: 1.2 - **/ -typedef enum _cairo_font_type { - CAIRO_FONT_TYPE_TOY, - CAIRO_FONT_TYPE_FT, - CAIRO_FONT_TYPE_WIN32, - CAIRO_FONT_TYPE_QUARTZ, - CAIRO_FONT_TYPE_USER -} cairo_font_type_t; - -cairo_public cairo_font_type_t -cairo_font_face_get_type (cairo_font_face_t *font_face); - -cairo_public void * -cairo_font_face_get_user_data (cairo_font_face_t *font_face, - const cairo_user_data_key_t *key); - -cairo_public cairo_status_t -cairo_font_face_set_user_data (cairo_font_face_t *font_face, - const cairo_user_data_key_t *key, - void *user_data, - cairo_destroy_func_t destroy); - -/* Portable interface to general font features. */ - -cairo_public cairo_scaled_font_t * -cairo_scaled_font_create (cairo_font_face_t *font_face, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options); - -cairo_public cairo_scaled_font_t * -cairo_scaled_font_reference (cairo_scaled_font_t *scaled_font); - -cairo_public void -cairo_scaled_font_destroy (cairo_scaled_font_t *scaled_font); - -cairo_public unsigned int -cairo_scaled_font_get_reference_count (cairo_scaled_font_t *scaled_font); - -cairo_public cairo_status_t -cairo_scaled_font_status (cairo_scaled_font_t *scaled_font); - -cairo_public cairo_font_type_t -cairo_scaled_font_get_type (cairo_scaled_font_t *scaled_font); - -cairo_public void * -cairo_scaled_font_get_user_data (cairo_scaled_font_t *scaled_font, - const cairo_user_data_key_t *key); - -cairo_public cairo_status_t -cairo_scaled_font_set_user_data (cairo_scaled_font_t *scaled_font, - const cairo_user_data_key_t *key, - void *user_data, - cairo_destroy_func_t destroy); - -cairo_public void -cairo_scaled_font_extents (cairo_scaled_font_t *scaled_font, - cairo_font_extents_t *extents); - -cairo_public void -cairo_scaled_font_text_extents (cairo_scaled_font_t *scaled_font, - const char *utf8, - cairo_text_extents_t *extents); - -cairo_public void -cairo_scaled_font_glyph_extents (cairo_scaled_font_t *scaled_font, - const cairo_glyph_t *glyphs, - int num_glyphs, - cairo_text_extents_t *extents); - -cairo_public cairo_status_t -cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font, - double x, - double y, - const char *utf8, - int utf8_len, - cairo_glyph_t **glyphs, - int *num_glyphs, - cairo_text_cluster_t **clusters, - int *num_clusters, - cairo_text_cluster_flags_t *cluster_flags); - -cairo_public cairo_font_face_t * -cairo_scaled_font_get_font_face (cairo_scaled_font_t *scaled_font); - -cairo_public void -cairo_scaled_font_get_font_matrix (cairo_scaled_font_t *scaled_font, - cairo_matrix_t *font_matrix); - -cairo_public void -cairo_scaled_font_get_ctm (cairo_scaled_font_t *scaled_font, - cairo_matrix_t *ctm); - -cairo_public void -cairo_scaled_font_get_scale_matrix (cairo_scaled_font_t *scaled_font, - cairo_matrix_t *scale_matrix); - -cairo_public void -cairo_scaled_font_get_font_options (cairo_scaled_font_t *scaled_font, - cairo_font_options_t *options); - - -/* Toy fonts */ - -cairo_public cairo_font_face_t * -cairo_toy_font_face_create (const char *family, - cairo_font_slant_t slant, - cairo_font_weight_t weight); - -cairo_public const char * -cairo_toy_font_face_get_family (cairo_font_face_t *font_face); - -cairo_public cairo_font_slant_t -cairo_toy_font_face_get_slant (cairo_font_face_t *font_face); - -cairo_public cairo_font_weight_t -cairo_toy_font_face_get_weight (cairo_font_face_t *font_face); - - -/* User fonts */ - -cairo_public cairo_font_face_t * -cairo_user_font_face_create (void); - -/* User-font method signatures */ - -/** - * cairo_user_scaled_font_init_func_t: - * @scaled_font: the scaled-font being created - * @cr: a cairo context, in font space - * @extents: font extents to fill in, in font space - * - * #cairo_user_scaled_font_init_func_t is the type of function which is - * called when a scaled-font needs to be created for a user font-face. - * - * The cairo context @cr is not used by the caller, but is prepared in font - * space, similar to what the cairo contexts passed to the render_glyph - * method will look like. The callback can use this context for extents - * computation for example. After the callback is called, @cr is checked - * for any error status. - * - * The @extents argument is where the user font sets the font extents for - * @scaled_font. It is in font space, which means that for most cases its - * ascent and descent members should add to 1.0. @extents is preset to - * hold a value of 1.0 for ascent, height, and max_x_advance, and 0.0 for - * descent and max_y_advance members. - * - * The callback is optional. If not set, default font extents as described - * in the previous paragraph will be used. - * - * Note that @scaled_font is not fully initialized at this - * point and trying to use it for text operations in the callback will result - * in deadlock. - * - * Returns: %CAIRO_STATUS_SUCCESS upon success, or an error status on error. - * - * Since: 1.8 - **/ -typedef cairo_status_t (*cairo_user_scaled_font_init_func_t) (cairo_scaled_font_t *scaled_font, - cairo_t *cr, - cairo_font_extents_t *extents); - -/** - * cairo_user_scaled_font_render_glyph_func_t: - * @scaled_font: user scaled-font - * @glyph: glyph code to render - * @cr: cairo context to draw to, in font space - * @extents: glyph extents to fill in, in font space - * - * #cairo_user_scaled_font_render_glyph_func_t is the type of function which - * is called when a user scaled-font needs to render a glyph. - * - * The callback is mandatory, and expected to draw the glyph with code @glyph to - * the cairo context @cr. @cr is prepared such that the glyph drawing is done in - * font space. That is, the matrix set on @cr is the scale matrix of @scaled_font, - * The @extents argument is where the user font sets the font extents for - * @scaled_font. However, if user prefers to draw in user space, they can - * achieve that by changing the matrix on @cr. All cairo rendering operations - * to @cr are permitted, however, the result is undefined if any source other - * than the default source on @cr is used. That means, glyph bitmaps should - * be rendered using cairo_mask() instead of cairo_paint(). - * - * Other non-default settings on @cr include a font size of 1.0 (given that - * it is set up to be in font space), and font options corresponding to - * @scaled_font. - * - * The @extents argument is preset to have <literal>x_bearing</literal>, - * <literal>width</literal>, and <literal>y_advance</literal> of zero, - * <literal>y_bearing</literal> set to <literal>-font_extents.ascent</literal>, - * <literal>height</literal> to <literal>font_extents.ascent+font_extents.descent</literal>, - * and <literal>x_advance</literal> to <literal>font_extents.max_x_advance</literal>. - * The only field user needs to set in majority of cases is - * <literal>x_advance</literal>. - * If the <literal>width</literal> field is zero upon the callback returning - * (which is its preset value), the glyph extents are automatically computed - * based on the drawings done to @cr. This is in most cases exactly what the - * desired behavior is. However, if for any reason the callback sets the - * extents, it must be ink extents, and include the extents of all drawing - * done to @cr in the callback. - * - * Returns: %CAIRO_STATUS_SUCCESS upon success, or - * %CAIRO_STATUS_USER_FONT_ERROR or any other error status on error. - * - * Since: 1.8 - **/ -typedef cairo_status_t (*cairo_user_scaled_font_render_glyph_func_t) (cairo_scaled_font_t *scaled_font, - unsigned long glyph, - cairo_t *cr, - cairo_text_extents_t *extents); - -/** - * cairo_user_scaled_font_text_to_glyphs_func_t: - * @scaled_font: the scaled-font being created - * @utf8: a string of text encoded in UTF-8 - * @utf8_len: length of @utf8 in bytes - * @glyphs: pointer to array of glyphs to fill, in font space - * @num_glyphs: pointer to number of glyphs - * @clusters: pointer to array of cluster mapping information to fill, or %NULL - * @num_clusters: pointer to number of clusters - * @cluster_flags: pointer to location to store cluster flags corresponding to the - * output @clusters - * - * #cairo_user_scaled_font_text_to_glyphs_func_t is the type of function which - * is called to convert input text to an array of glyphs. This is used by the - * cairo_show_text() operation. - * - * Using this callback the user-font has full control on glyphs and their - * positions. That means, it allows for features like ligatures and kerning, - * as well as complex <firstterm>shaping</firstterm> required for scripts like - * Arabic and Indic. - * - * The @num_glyphs argument is preset to the number of glyph entries available - * in the @glyphs buffer. If the @glyphs buffer is %NULL, the value of - * @num_glyphs will be zero. If the provided glyph array is too short for - * the conversion (or for convenience), a new glyph array may be allocated - * using cairo_glyph_allocate() and placed in @glyphs. Upon return, - * @num_glyphs should contain the number of generated glyphs. If the value - * @glyphs points at has changed after the call, the caller will free the - * allocated glyph array using cairo_glyph_free(). The caller will also free - * the original value of @glyphs, so the callback shouldn't do so. - * The callback should populate the glyph indices and positions (in font space) - * assuming that the text is to be shown at the origin. - * - * If @clusters is not %NULL, @num_clusters and @cluster_flags are also - * non-%NULL, and cluster mapping should be computed. The semantics of how - * cluster array allocation works is similar to the glyph array. That is, - * if @clusters initially points to a non-%NULL value, that array may be used - * as a cluster buffer, and @num_clusters points to the number of cluster - * entries available there. If the provided cluster array is too short for - * the conversion (or for convenience), a new cluster array may be allocated - * using cairo_text_cluster_allocate() and placed in @clusters. In this case, - * the original value of @clusters will still be freed by the caller. Upon - * return, @num_clusters should contain the number of generated clusters. - * If the value @clusters points at has changed after the call, the caller - * will free the allocated cluster array using cairo_text_cluster_free(). - * - * The callback is optional. If @num_glyphs is negative upon - * the callback returning or if the return value - * is %CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED, the unicode_to_glyph callback - * is tried. See #cairo_user_scaled_font_unicode_to_glyph_func_t. - * - * Note: While cairo does not impose any limitation on glyph indices, - * some applications may assume that a glyph index fits in a 16-bit - * unsigned integer. As such, it is advised that user-fonts keep their - * glyphs in the 0 to 65535 range. Furthermore, some applications may - * assume that glyph 0 is a special glyph-not-found glyph. User-fonts - * are advised to use glyph 0 for such purposes and do not use that - * glyph value for other purposes. - * - * Returns: %CAIRO_STATUS_SUCCESS upon success, - * %CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED if fallback options should be tried, - * or %CAIRO_STATUS_USER_FONT_ERROR or any other error status on error. - * - * Since: 1.8 - **/ -typedef cairo_status_t (*cairo_user_scaled_font_text_to_glyphs_func_t) (cairo_scaled_font_t *scaled_font, - const char *utf8, - int utf8_len, - cairo_glyph_t **glyphs, - int *num_glyphs, - cairo_text_cluster_t **clusters, - int *num_clusters, - cairo_text_cluster_flags_t *cluster_flags); - -/** - * cairo_user_scaled_font_unicode_to_glyph_func_t: - * @scaled_font: the scaled-font being created - * @unicode: input unicode character code-point - * @glyph_index: output glyph index - * - * #cairo_user_scaled_font_unicode_to_glyph_func_t is the type of function which - * is called to convert an input Unicode character to a single glyph. - * This is used by the cairo_show_text() operation. - * - * This callback is used to provide the same functionality as the - * text_to_glyphs callback does (see #cairo_user_scaled_font_text_to_glyphs_func_t) - * but has much less control on the output, - * in exchange for increased ease of use. The inherent assumption to using - * this callback is that each character maps to one glyph, and that the - * mapping is context independent. It also assumes that glyphs are positioned - * according to their advance width. These mean no ligatures, kerning, or - * complex scripts can be implemented using this callback. - * - * The callback is optional, and only used if text_to_glyphs callback is not - * set or fails to return glyphs. If this callback is not set or if it returns - * %CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED, an identity mapping from Unicode - * code-points to glyph indices is assumed. - * - * Note: While cairo does not impose any limitation on glyph indices, - * some applications may assume that a glyph index fits in a 16-bit - * unsigned integer. As such, it is advised that user-fonts keep their - * glyphs in the 0 to 65535 range. Furthermore, some applications may - * assume that glyph 0 is a special glyph-not-found glyph. User-fonts - * are advised to use glyph 0 for such purposes and do not use that - * glyph value for other purposes. - * - * Returns: %CAIRO_STATUS_SUCCESS upon success, - * %CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED if fallback options should be tried, - * or %CAIRO_STATUS_USER_FONT_ERROR or any other error status on error. - * - * Since: 1.8 - **/ -typedef cairo_status_t (*cairo_user_scaled_font_unicode_to_glyph_func_t) (cairo_scaled_font_t *scaled_font, - unsigned long unicode, - unsigned long *glyph_index); - -/* User-font method setters */ - -cairo_public void -cairo_user_font_face_set_init_func (cairo_font_face_t *font_face, - cairo_user_scaled_font_init_func_t init_func); - -cairo_public void -cairo_user_font_face_set_render_glyph_func (cairo_font_face_t *font_face, - cairo_user_scaled_font_render_glyph_func_t render_glyph_func); - -cairo_public void -cairo_user_font_face_set_text_to_glyphs_func (cairo_font_face_t *font_face, - cairo_user_scaled_font_text_to_glyphs_func_t text_to_glyphs_func); - -cairo_public void -cairo_user_font_face_set_unicode_to_glyph_func (cairo_font_face_t *font_face, - cairo_user_scaled_font_unicode_to_glyph_func_t unicode_to_glyph_func); - -/* User-font method getters */ - -cairo_public cairo_user_scaled_font_init_func_t -cairo_user_font_face_get_init_func (cairo_font_face_t *font_face); - -cairo_public cairo_user_scaled_font_render_glyph_func_t -cairo_user_font_face_get_render_glyph_func (cairo_font_face_t *font_face); - -cairo_public cairo_user_scaled_font_text_to_glyphs_func_t -cairo_user_font_face_get_text_to_glyphs_func (cairo_font_face_t *font_face); - -cairo_public cairo_user_scaled_font_unicode_to_glyph_func_t -cairo_user_font_face_get_unicode_to_glyph_func (cairo_font_face_t *font_face); - - -/* Query functions */ - -cairo_public cairo_operator_t -cairo_get_operator (cairo_t *cr); - -cairo_public cairo_pattern_t * -cairo_get_source (cairo_t *cr); - -cairo_public double -cairo_get_tolerance (cairo_t *cr); - -cairo_public cairo_antialias_t -cairo_get_antialias (cairo_t *cr); - -cairo_public cairo_bool_t -cairo_has_current_point (cairo_t *cr); - -cairo_public void -cairo_get_current_point (cairo_t *cr, double *x, double *y); - -cairo_public cairo_fill_rule_t -cairo_get_fill_rule (cairo_t *cr); - -cairo_public double -cairo_get_line_width (cairo_t *cr); - -cairo_public cairo_line_cap_t -cairo_get_line_cap (cairo_t *cr); - -cairo_public cairo_line_join_t -cairo_get_line_join (cairo_t *cr); - -cairo_public double -cairo_get_miter_limit (cairo_t *cr); - -cairo_public int -cairo_get_dash_count (cairo_t *cr); - -cairo_public void -cairo_get_dash (cairo_t *cr, double *dashes, double *offset); - -cairo_public void -cairo_get_matrix (cairo_t *cr, cairo_matrix_t *matrix); - -cairo_public cairo_surface_t * -cairo_get_target (cairo_t *cr); - -cairo_public cairo_surface_t * -cairo_get_group_target (cairo_t *cr); - -/** - * cairo_path_data_type_t: - * @CAIRO_PATH_MOVE_TO: A move-to operation, since 1.0 - * @CAIRO_PATH_LINE_TO: A line-to operation, since 1.0 - * @CAIRO_PATH_CURVE_TO: A curve-to operation, since 1.0 - * @CAIRO_PATH_CLOSE_PATH: A close-path operation, since 1.0 - * - * #cairo_path_data_t is used to describe the type of one portion - * of a path when represented as a #cairo_path_t. - * See #cairo_path_data_t for details. - * - * Since: 1.0 - **/ -typedef enum _cairo_path_data_type { - CAIRO_PATH_MOVE_TO, - CAIRO_PATH_LINE_TO, - CAIRO_PATH_CURVE_TO, - CAIRO_PATH_CLOSE_PATH -} cairo_path_data_type_t; - -/** - * cairo_path_data_t: - * - * #cairo_path_data_t is used to represent the path data inside a - * #cairo_path_t. - * - * The data structure is designed to try to balance the demands of - * efficiency and ease-of-use. A path is represented as an array of - * #cairo_path_data_t, which is a union of headers and points. - * - * Each portion of the path is represented by one or more elements in - * the array, (one header followed by 0 or more points). The length - * value of the header is the number of array elements for the current - * portion including the header, (ie. length == 1 + # of points), and - * where the number of points for each element type is as follows: - * - * <programlisting> - * %CAIRO_PATH_MOVE_TO: 1 point - * %CAIRO_PATH_LINE_TO: 1 point - * %CAIRO_PATH_CURVE_TO: 3 points - * %CAIRO_PATH_CLOSE_PATH: 0 points - * </programlisting> - * - * The semantics and ordering of the coordinate values are consistent - * with cairo_move_to(), cairo_line_to(), cairo_curve_to(), and - * cairo_close_path(). - * - * Here is sample code for iterating through a #cairo_path_t: - * - * <informalexample><programlisting> - * int i; - * cairo_path_t *path; - * cairo_path_data_t *data; - * - * path = cairo_copy_path (cr); - * - * for (i=0; i < path->num_data; i += path->data[i].header.length) { - * data = &path->data[i]; - * switch (data->header.type) { - * case CAIRO_PATH_MOVE_TO: - * do_move_to_things (data[1].point.x, data[1].point.y); - * break; - * case CAIRO_PATH_LINE_TO: - * do_line_to_things (data[1].point.x, data[1].point.y); - * break; - * case CAIRO_PATH_CURVE_TO: - * do_curve_to_things (data[1].point.x, data[1].point.y, - * data[2].point.x, data[2].point.y, - * data[3].point.x, data[3].point.y); - * break; - * case CAIRO_PATH_CLOSE_PATH: - * do_close_path_things (); - * break; - * } - * } - * cairo_path_destroy (path); - * </programlisting></informalexample> - * - * As of cairo 1.4, cairo does not mind if there are more elements in - * a portion of the path than needed. Such elements can be used by - * users of the cairo API to hold extra values in the path data - * structure. For this reason, it is recommended that applications - * always use <literal>data->header.length</literal> to - * iterate over the path data, instead of hardcoding the number of - * elements for each element type. - * - * Since: 1.0 - **/ -typedef union _cairo_path_data_t cairo_path_data_t; -union _cairo_path_data_t { - struct { - cairo_path_data_type_t type; - int length; - } header; - struct { - double x, y; - } point; -}; - -/** - * cairo_path_t: - * @status: the current error status - * @data: the elements in the path - * @num_data: the number of elements in the data array - * - * A data structure for holding a path. This data structure serves as - * the return value for cairo_copy_path() and - * cairo_copy_path_flat() as well the input value for - * cairo_append_path(). - * - * See #cairo_path_data_t for hints on how to iterate over the - * actual data within the path. - * - * The num_data member gives the number of elements in the data - * array. This number is larger than the number of independent path - * portions (defined in #cairo_path_data_type_t), since the data - * includes both headers and coordinates for each portion. - * - * Since: 1.0 - **/ -typedef struct cairo_path { - cairo_status_t status; - cairo_path_data_t *data; - int num_data; -} cairo_path_t; - -cairo_public cairo_path_t * -cairo_copy_path (cairo_t *cr); - -cairo_public cairo_path_t * -cairo_copy_path_flat (cairo_t *cr); - -cairo_public void -cairo_append_path (cairo_t *cr, - const cairo_path_t *path); - -cairo_public void -cairo_path_destroy (cairo_path_t *path); - -/* Error status queries */ - -cairo_public cairo_status_t -cairo_status (cairo_t *cr); - -cairo_public const char * -cairo_status_to_string (cairo_status_t status); - -/* Backend device manipulation */ - -cairo_public cairo_device_t * -cairo_device_reference (cairo_device_t *device); - -/** - * cairo_device_type_t: - * @CAIRO_DEVICE_TYPE_DRM: The device is of type Direct Render Manager, since 1.10 - * @CAIRO_DEVICE_TYPE_GL: The device is of type OpenGL, since 1.10 - * @CAIRO_DEVICE_TYPE_SCRIPT: The device is of type script, since 1.10 - * @CAIRO_DEVICE_TYPE_XCB: The device is of type xcb, since 1.10 - * @CAIRO_DEVICE_TYPE_XLIB: The device is of type xlib, since 1.10 - * @CAIRO_DEVICE_TYPE_XML: The device is of type XML, since 1.10 - * @CAIRO_DEVICE_TYPE_COGL: The device is of type cogl, since 1.12 - * @CAIRO_DEVICE_TYPE_WIN32: The device is of type win32, since 1.12 - * @CAIRO_DEVICE_TYPE_INVALID: The device is invalid, since 1.10 - * - * #cairo_device_type_t is used to describe the type of a given - * device. The devices types are also known as "backends" within cairo. - * - * The device type can be queried with cairo_device_get_type() - * - * The various #cairo_device_t functions can be used with devices of - * any type, but some backends also provide type-specific functions - * that must only be called with a device of the appropriate - * type. These functions have names that begin with - * <literal>cairo_<emphasis>type</emphasis>_device</literal> such as - * cairo_xcb_device_debug_cap_xrender_version(). - * - * The behavior of calling a type-specific function with a device of - * the wrong type is undefined. - * - * New entries may be added in future versions. - * - * Since: 1.10 - **/ -typedef enum _cairo_device_type { - CAIRO_DEVICE_TYPE_DRM, - CAIRO_DEVICE_TYPE_GL, - CAIRO_DEVICE_TYPE_SCRIPT, - CAIRO_DEVICE_TYPE_XCB, - CAIRO_DEVICE_TYPE_XLIB, - CAIRO_DEVICE_TYPE_XML, - CAIRO_DEVICE_TYPE_COGL, - CAIRO_DEVICE_TYPE_WIN32, - - CAIRO_DEVICE_TYPE_INVALID = -1 -} cairo_device_type_t; - -cairo_public cairo_device_type_t -cairo_device_get_type (cairo_device_t *device); - -cairo_public cairo_status_t -cairo_device_status (cairo_device_t *device); - -cairo_public cairo_status_t -cairo_device_acquire (cairo_device_t *device); - -cairo_public void -cairo_device_release (cairo_device_t *device); - -cairo_public void -cairo_device_flush (cairo_device_t *device); - -cairo_public void -cairo_device_finish (cairo_device_t *device); - -cairo_public void -cairo_device_destroy (cairo_device_t *device); - -cairo_public unsigned int -cairo_device_get_reference_count (cairo_device_t *device); - -cairo_public void * -cairo_device_get_user_data (cairo_device_t *device, - const cairo_user_data_key_t *key); - -cairo_public cairo_status_t -cairo_device_set_user_data (cairo_device_t *device, - const cairo_user_data_key_t *key, - void *user_data, - cairo_destroy_func_t destroy); - - -/* Surface manipulation */ - -cairo_public cairo_surface_t * -cairo_surface_create_similar (cairo_surface_t *other, - cairo_content_t content, - int width, - int height); - -cairo_public cairo_surface_t * -cairo_surface_create_similar_image (cairo_surface_t *other, - cairo_format_t format, - int width, - int height); - -cairo_public cairo_surface_t * -cairo_surface_map_to_image (cairo_surface_t *surface, - const cairo_rectangle_int_t *extents); - -cairo_public void -cairo_surface_unmap_image (cairo_surface_t *surface, - cairo_surface_t *image); - -cairo_public cairo_surface_t * -cairo_surface_create_for_rectangle (cairo_surface_t *target, - double x, - double y, - double width, - double height); - -/** - * cairo_surface_observer_mode_t: - * @CAIRO_SURFACE_OBSERVER_NORMAL: no recording is done - * @CAIRO_SURFACE_OBSERVER_RECORD_OPERATIONS: operations are recorded - * - * Whether operations should be recorded. - * - * Since: 1.12 - **/ -typedef enum { - CAIRO_SURFACE_OBSERVER_NORMAL = 0, - CAIRO_SURFACE_OBSERVER_RECORD_OPERATIONS = 0x1 -} cairo_surface_observer_mode_t; - -cairo_public cairo_surface_t * -cairo_surface_create_observer (cairo_surface_t *target, - cairo_surface_observer_mode_t mode); - -typedef void (*cairo_surface_observer_callback_t) (cairo_surface_t *observer, - cairo_surface_t *target, - void *data); - -cairo_public cairo_status_t -cairo_surface_observer_add_paint_callback (cairo_surface_t *abstract_surface, - cairo_surface_observer_callback_t func, - void *data); - -cairo_public cairo_status_t -cairo_surface_observer_add_mask_callback (cairo_surface_t *abstract_surface, - cairo_surface_observer_callback_t func, - void *data); - -cairo_public cairo_status_t -cairo_surface_observer_add_fill_callback (cairo_surface_t *abstract_surface, - cairo_surface_observer_callback_t func, - void *data); - -cairo_public cairo_status_t -cairo_surface_observer_add_stroke_callback (cairo_surface_t *abstract_surface, - cairo_surface_observer_callback_t func, - void *data); - -cairo_public cairo_status_t -cairo_surface_observer_add_glyphs_callback (cairo_surface_t *abstract_surface, - cairo_surface_observer_callback_t func, - void *data); - -cairo_public cairo_status_t -cairo_surface_observer_add_flush_callback (cairo_surface_t *abstract_surface, - cairo_surface_observer_callback_t func, - void *data); - -cairo_public cairo_status_t -cairo_surface_observer_add_finish_callback (cairo_surface_t *abstract_surface, - cairo_surface_observer_callback_t func, - void *data); - -cairo_public cairo_status_t -cairo_surface_observer_print (cairo_surface_t *surface, - cairo_write_func_t write_func, - void *closure); -cairo_public double -cairo_surface_observer_elapsed (cairo_surface_t *surface); - -cairo_public cairo_status_t -cairo_device_observer_print (cairo_device_t *device, - cairo_write_func_t write_func, - void *closure); - -cairo_public double -cairo_device_observer_elapsed (cairo_device_t *device); - -cairo_public double -cairo_device_observer_paint_elapsed (cairo_device_t *device); - -cairo_public double -cairo_device_observer_mask_elapsed (cairo_device_t *device); - -cairo_public double -cairo_device_observer_fill_elapsed (cairo_device_t *device); - -cairo_public double -cairo_device_observer_stroke_elapsed (cairo_device_t *device); - -cairo_public double -cairo_device_observer_glyphs_elapsed (cairo_device_t *device); - -cairo_public cairo_surface_t * -cairo_surface_reference (cairo_surface_t *surface); - -cairo_public void -cairo_surface_finish (cairo_surface_t *surface); - -cairo_public void -cairo_surface_destroy (cairo_surface_t *surface); - -cairo_public cairo_device_t * -cairo_surface_get_device (cairo_surface_t *surface); - -cairo_public unsigned int -cairo_surface_get_reference_count (cairo_surface_t *surface); - -cairo_public cairo_status_t -cairo_surface_status (cairo_surface_t *surface); - -/** - * cairo_surface_type_t: - * @CAIRO_SURFACE_TYPE_IMAGE: The surface is of type image, since 1.2 - * @CAIRO_SURFACE_TYPE_PDF: The surface is of type pdf, since 1.2 - * @CAIRO_SURFACE_TYPE_PS: The surface is of type ps, since 1.2 - * @CAIRO_SURFACE_TYPE_XLIB: The surface is of type xlib, since 1.2 - * @CAIRO_SURFACE_TYPE_XCB: The surface is of type xcb, since 1.2 - * @CAIRO_SURFACE_TYPE_GLITZ: The surface is of type glitz, since 1.2 - * @CAIRO_SURFACE_TYPE_QUARTZ: The surface is of type quartz, since 1.2 - * @CAIRO_SURFACE_TYPE_WIN32: The surface is of type win32, since 1.2 - * @CAIRO_SURFACE_TYPE_BEOS: The surface is of type beos, since 1.2 - * @CAIRO_SURFACE_TYPE_DIRECTFB: The surface is of type directfb, since 1.2 - * @CAIRO_SURFACE_TYPE_SVG: The surface is of type svg, since 1.2 - * @CAIRO_SURFACE_TYPE_OS2: The surface is of type os2, since 1.4 - * @CAIRO_SURFACE_TYPE_WIN32_PRINTING: The surface is a win32 printing surface, since 1.6 - * @CAIRO_SURFACE_TYPE_QUARTZ_IMAGE: The surface is of type quartz_image, since 1.6 - * @CAIRO_SURFACE_TYPE_SCRIPT: The surface is of type script, since 1.10 - * @CAIRO_SURFACE_TYPE_QT: The surface is of type Qt, since 1.10 - * @CAIRO_SURFACE_TYPE_RECORDING: The surface is of type recording, since 1.10 - * @CAIRO_SURFACE_TYPE_VG: The surface is a OpenVG surface, since 1.10 - * @CAIRO_SURFACE_TYPE_GL: The surface is of type OpenGL, since 1.10 - * @CAIRO_SURFACE_TYPE_DRM: The surface is of type Direct Render Manager, since 1.10 - * @CAIRO_SURFACE_TYPE_TEE: The surface is of type 'tee' (a multiplexing surface), since 1.10 - * @CAIRO_SURFACE_TYPE_XML: The surface is of type XML (for debugging), since 1.10 - * @CAIRO_SURFACE_TYPE_SKIA: The surface is of type Skia, since 1.10 - * @CAIRO_SURFACE_TYPE_SUBSURFACE: The surface is a subsurface created with - * cairo_surface_create_for_rectangle(), since 1.10 - * @CAIRO_SURFACE_TYPE_COGL: This surface is of type Cogl, since 1.12 - * - * #cairo_surface_type_t is used to describe the type of a given - * surface. The surface types are also known as "backends" or "surface - * backends" within cairo. - * - * The type of a surface is determined by the function used to create - * it, which will generally be of the form - * <function>cairo_<emphasis>type</emphasis>_surface_create(<!-- -->)</function>, - * (though see cairo_surface_create_similar() as well). - * - * The surface type can be queried with cairo_surface_get_type() - * - * The various #cairo_surface_t functions can be used with surfaces of - * any type, but some backends also provide type-specific functions - * that must only be called with a surface of the appropriate - * type. These functions have names that begin with - * <literal>cairo_<emphasis>type</emphasis>_surface</literal> such as cairo_image_surface_get_width(). - * - * The behavior of calling a type-specific function with a surface of - * the wrong type is undefined. - * - * New entries may be added in future versions. - * - * Since: 1.2 - **/ -typedef enum _cairo_surface_type { - CAIRO_SURFACE_TYPE_IMAGE, - CAIRO_SURFACE_TYPE_PDF, - CAIRO_SURFACE_TYPE_PS, - CAIRO_SURFACE_TYPE_XLIB, - CAIRO_SURFACE_TYPE_XCB, - CAIRO_SURFACE_TYPE_GLITZ, - CAIRO_SURFACE_TYPE_QUARTZ, - CAIRO_SURFACE_TYPE_WIN32, - CAIRO_SURFACE_TYPE_BEOS, - CAIRO_SURFACE_TYPE_DIRECTFB, - CAIRO_SURFACE_TYPE_SVG, - CAIRO_SURFACE_TYPE_OS2, - CAIRO_SURFACE_TYPE_WIN32_PRINTING, - CAIRO_SURFACE_TYPE_QUARTZ_IMAGE, - CAIRO_SURFACE_TYPE_SCRIPT, - CAIRO_SURFACE_TYPE_QT, - CAIRO_SURFACE_TYPE_RECORDING, - CAIRO_SURFACE_TYPE_VG, - CAIRO_SURFACE_TYPE_GL, - CAIRO_SURFACE_TYPE_DRM, - CAIRO_SURFACE_TYPE_TEE, - CAIRO_SURFACE_TYPE_XML, - CAIRO_SURFACE_TYPE_SKIA, - CAIRO_SURFACE_TYPE_SUBSURFACE, - CAIRO_SURFACE_TYPE_COGL -} cairo_surface_type_t; - -cairo_public cairo_surface_type_t -cairo_surface_get_type (cairo_surface_t *surface); - -cairo_public cairo_content_t -cairo_surface_get_content (cairo_surface_t *surface); - -#if CAIRO_HAS_PNG_FUNCTIONS - -cairo_public cairo_status_t -cairo_surface_write_to_png (cairo_surface_t *surface, - const char *filename); - -cairo_public cairo_status_t -cairo_surface_write_to_png_stream (cairo_surface_t *surface, - cairo_write_func_t write_func, - void *closure); - -#endif - -cairo_public void * -cairo_surface_get_user_data (cairo_surface_t *surface, - const cairo_user_data_key_t *key); - -cairo_public cairo_status_t -cairo_surface_set_user_data (cairo_surface_t *surface, - const cairo_user_data_key_t *key, - void *user_data, - cairo_destroy_func_t destroy); - -#define CAIRO_MIME_TYPE_JPEG "image/jpeg" -#define CAIRO_MIME_TYPE_PNG "image/png" -#define CAIRO_MIME_TYPE_JP2 "image/jp2" -#define CAIRO_MIME_TYPE_URI "text/x-uri" -#define CAIRO_MIME_TYPE_UNIQUE_ID "application/x-cairo.uuid" -#define CAIRO_MIME_TYPE_JBIG2 "application/x-cairo.jbig2" -#define CAIRO_MIME_TYPE_JBIG2_GLOBAL "application/x-cairo.jbig2-global" -#define CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID "application/x-cairo.jbig2-global-id" - -cairo_public void -cairo_surface_get_mime_data (cairo_surface_t *surface, - const char *mime_type, - const unsigned char **data, - unsigned long *length); - -cairo_public cairo_status_t -cairo_surface_set_mime_data (cairo_surface_t *surface, - const char *mime_type, - const unsigned char *data, - unsigned long length, - cairo_destroy_func_t destroy, - void *closure); - -cairo_public cairo_bool_t -cairo_surface_supports_mime_type (cairo_surface_t *surface, - const char *mime_type); - -cairo_public void -cairo_surface_get_font_options (cairo_surface_t *surface, - cairo_font_options_t *options); - -cairo_public void -cairo_surface_flush (cairo_surface_t *surface); - -cairo_public void -cairo_surface_mark_dirty (cairo_surface_t *surface); - -cairo_public void -cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface, - int x, - int y, - int width, - int height); - -cairo_public void -cairo_surface_set_device_scale (cairo_surface_t *surface, - double x_scale, - double y_scale); - -cairo_public void -cairo_surface_get_device_scale (cairo_surface_t *surface, - double *x_scale, - double *y_scale); - -cairo_public void -cairo_surface_set_device_offset (cairo_surface_t *surface, - double x_offset, - double y_offset); - -cairo_public void -cairo_surface_get_device_offset (cairo_surface_t *surface, - double *x_offset, - double *y_offset); - -cairo_public void -cairo_surface_set_fallback_resolution (cairo_surface_t *surface, - double x_pixels_per_inch, - double y_pixels_per_inch); - -cairo_public void -cairo_surface_get_fallback_resolution (cairo_surface_t *surface, - double *x_pixels_per_inch, - double *y_pixels_per_inch); - -cairo_public void -cairo_surface_copy_page (cairo_surface_t *surface); - -cairo_public void -cairo_surface_show_page (cairo_surface_t *surface); - -cairo_public cairo_bool_t -cairo_surface_has_show_text_glyphs (cairo_surface_t *surface); - -/* Image-surface functions */ - -cairo_public cairo_surface_t * -cairo_image_surface_create (cairo_format_t format, - int width, - int height); - -cairo_public int -cairo_format_stride_for_width (cairo_format_t format, - int width); - -cairo_public cairo_surface_t * -cairo_image_surface_create_for_data (unsigned char *data, - cairo_format_t format, - int width, - int height, - int stride); - -cairo_public unsigned char * -cairo_image_surface_get_data (cairo_surface_t *surface); - -cairo_public cairo_format_t -cairo_image_surface_get_format (cairo_surface_t *surface); - -cairo_public int -cairo_image_surface_get_width (cairo_surface_t *surface); - -cairo_public int -cairo_image_surface_get_height (cairo_surface_t *surface); - -cairo_public int -cairo_image_surface_get_stride (cairo_surface_t *surface); - -#if CAIRO_HAS_PNG_FUNCTIONS - -cairo_public cairo_surface_t * -cairo_image_surface_create_from_png (const char *filename); - -cairo_public cairo_surface_t * -cairo_image_surface_create_from_png_stream (cairo_read_func_t read_func, - void *closure); - -#endif - -/* Recording-surface functions */ - -cairo_public cairo_surface_t * -cairo_recording_surface_create (cairo_content_t content, - const cairo_rectangle_t *extents); - -cairo_public void -cairo_recording_surface_ink_extents (cairo_surface_t *surface, - double *x0, - double *y0, - double *width, - double *height); - -cairo_public cairo_bool_t -cairo_recording_surface_get_extents (cairo_surface_t *surface, - cairo_rectangle_t *extents); - -/* raster-source pattern (callback) functions */ - -/** - * cairo_raster_source_acquire_func_t: - * @pattern: the pattern being rendered from - * @callback_data: the user data supplied during creation - * @target: the rendering target surface - * @extents: rectangular region of interest in pixels in sample space - * - * #cairo_raster_source_acquire_func_t is the type of function which is - * called when a pattern is being rendered from. It should create a surface - * that provides the pixel data for the region of interest as defined by - * extents, though the surface itself does not have to be limited to that - * area. For convenience the surface should probably be of image type, - * created with cairo_surface_create_similar_image() for the target (which - * enables the number of copies to be reduced during transfer to the - * device). Another option, might be to return a similar surface to the - * target for explicit handling by the application of a set of cached sources - * on the device. The region of sample data provided should be defined using - * cairo_surface_set_device_offset() to specify the top-left corner of the - * sample data (along with width and height of the surface). - * - * Returns: a #cairo_surface_t - * - * Since: 1.12 - **/ -typedef cairo_surface_t * -(*cairo_raster_source_acquire_func_t) (cairo_pattern_t *pattern, - void *callback_data, - cairo_surface_t *target, - const cairo_rectangle_int_t *extents); - -/** - * cairo_raster_source_release_func_t: - * @pattern: the pattern being rendered from - * @callback_data: the user data supplied during creation - * @surface: the surface created during acquire - * - * #cairo_raster_source_release_func_t is the type of function which is - * called when the pixel data is no longer being access by the pattern - * for the rendering operation. Typically this function will simply - * destroy the surface created during acquire. - * - * Since: 1.12 - **/ -typedef void -(*cairo_raster_source_release_func_t) (cairo_pattern_t *pattern, - void *callback_data, - cairo_surface_t *surface); - -/** - * cairo_raster_source_snapshot_func_t: - * @pattern: the pattern being rendered from - * @callback_data: the user data supplied during creation - * - * #cairo_raster_source_snapshot_func_t is the type of function which is - * called when the pixel data needs to be preserved for later use - * during printing. This pattern will be accessed again later, and it - * is expected to provide the pixel data that was current at the time - * of snapshotting. - * - * Return value: CAIRO_STATUS_SUCCESS on success, or one of the - * #cairo_status_t error codes for failure. - * - * Since: 1.12 - **/ -typedef cairo_status_t -(*cairo_raster_source_snapshot_func_t) (cairo_pattern_t *pattern, - void *callback_data); - -/** - * cairo_raster_source_copy_func_t: - * @pattern: the #cairo_pattern_t that was copied to - * @callback_data: the user data supplied during creation - * @other: the #cairo_pattern_t being used as the source for the copy - * - * #cairo_raster_source_copy_func_t is the type of function which is - * called when the pattern gets copied as a normal part of rendering. - * - * Return value: CAIRO_STATUS_SUCCESS on success, or one of the - * #cairo_status_t error codes for failure. - * - * Since: 1.12 - **/ -typedef cairo_status_t -(*cairo_raster_source_copy_func_t) (cairo_pattern_t *pattern, - void *callback_data, - const cairo_pattern_t *other); - -/** - * cairo_raster_source_finish_func_t: - * @pattern: the pattern being rendered from - * @callback_data: the user data supplied during creation - * - * #cairo_raster_source_finish_func_t is the type of function which is - * called when the pattern (or a copy thereof) is no longer required. - * - * Since: 1.12 - **/ -typedef void -(*cairo_raster_source_finish_func_t) (cairo_pattern_t *pattern, - void *callback_data); - -cairo_public cairo_pattern_t * -cairo_pattern_create_raster_source (void *user_data, - cairo_content_t content, - int width, int height); - -cairo_public void -cairo_raster_source_pattern_set_callback_data (cairo_pattern_t *pattern, - void *data); - -cairo_public void * -cairo_raster_source_pattern_get_callback_data (cairo_pattern_t *pattern); - -cairo_public void -cairo_raster_source_pattern_set_acquire (cairo_pattern_t *pattern, - cairo_raster_source_acquire_func_t acquire, - cairo_raster_source_release_func_t release); - -cairo_public void -cairo_raster_source_pattern_get_acquire (cairo_pattern_t *pattern, - cairo_raster_source_acquire_func_t *acquire, - cairo_raster_source_release_func_t *release); -cairo_public void -cairo_raster_source_pattern_set_snapshot (cairo_pattern_t *pattern, - cairo_raster_source_snapshot_func_t snapshot); - -cairo_public cairo_raster_source_snapshot_func_t -cairo_raster_source_pattern_get_snapshot (cairo_pattern_t *pattern); - -cairo_public void -cairo_raster_source_pattern_set_copy (cairo_pattern_t *pattern, - cairo_raster_source_copy_func_t copy); - -cairo_public cairo_raster_source_copy_func_t -cairo_raster_source_pattern_get_copy (cairo_pattern_t *pattern); - -cairo_public void -cairo_raster_source_pattern_set_finish (cairo_pattern_t *pattern, - cairo_raster_source_finish_func_t finish); - -cairo_public cairo_raster_source_finish_func_t -cairo_raster_source_pattern_get_finish (cairo_pattern_t *pattern); - -/* Pattern creation functions */ - -cairo_public cairo_pattern_t * -cairo_pattern_create_rgb (double red, double green, double blue); - -cairo_public cairo_pattern_t * -cairo_pattern_create_rgba (double red, double green, double blue, - double alpha); - -cairo_public cairo_pattern_t * -cairo_pattern_create_for_surface (cairo_surface_t *surface); - -cairo_public cairo_pattern_t * -cairo_pattern_create_linear (double x0, double y0, - double x1, double y1); - -cairo_public cairo_pattern_t * -cairo_pattern_create_radial (double cx0, double cy0, double radius0, - double cx1, double cy1, double radius1); - -cairo_public cairo_pattern_t * -cairo_pattern_create_mesh (void); - -cairo_public cairo_pattern_t * -cairo_pattern_reference (cairo_pattern_t *pattern); - -cairo_public void -cairo_pattern_destroy (cairo_pattern_t *pattern); - -cairo_public unsigned int -cairo_pattern_get_reference_count (cairo_pattern_t *pattern); - -cairo_public cairo_status_t -cairo_pattern_status (cairo_pattern_t *pattern); - -cairo_public void * -cairo_pattern_get_user_data (cairo_pattern_t *pattern, - const cairo_user_data_key_t *key); - -cairo_public cairo_status_t -cairo_pattern_set_user_data (cairo_pattern_t *pattern, - const cairo_user_data_key_t *key, - void *user_data, - cairo_destroy_func_t destroy); - -/** - * cairo_pattern_type_t: - * @CAIRO_PATTERN_TYPE_SOLID: The pattern is a solid (uniform) - * color. It may be opaque or translucent, since 1.2. - * @CAIRO_PATTERN_TYPE_SURFACE: The pattern is a based on a surface (an image), since 1.2. - * @CAIRO_PATTERN_TYPE_LINEAR: The pattern is a linear gradient, since 1.2. - * @CAIRO_PATTERN_TYPE_RADIAL: The pattern is a radial gradient, since 1.2. - * @CAIRO_PATTERN_TYPE_MESH: The pattern is a mesh, since 1.12. - * @CAIRO_PATTERN_TYPE_RASTER_SOURCE: The pattern is a user pattern providing raster data, since 1.12. - * - * #cairo_pattern_type_t is used to describe the type of a given pattern. - * - * The type of a pattern is determined by the function used to create - * it. The cairo_pattern_create_rgb() and cairo_pattern_create_rgba() - * functions create SOLID patterns. The remaining - * cairo_pattern_create<!-- --> functions map to pattern types in obvious - * ways. - * - * The pattern type can be queried with cairo_pattern_get_type() - * - * Most #cairo_pattern_t functions can be called with a pattern of any - * type, (though trying to change the extend or filter for a solid - * pattern will have no effect). A notable exception is - * cairo_pattern_add_color_stop_rgb() and - * cairo_pattern_add_color_stop_rgba() which must only be called with - * gradient patterns (either LINEAR or RADIAL). Otherwise the pattern - * will be shutdown and put into an error state. - * - * New entries may be added in future versions. - * - * Since: 1.2 - **/ -typedef enum _cairo_pattern_type { - CAIRO_PATTERN_TYPE_SOLID, - CAIRO_PATTERN_TYPE_SURFACE, - CAIRO_PATTERN_TYPE_LINEAR, - CAIRO_PATTERN_TYPE_RADIAL, - CAIRO_PATTERN_TYPE_MESH, - CAIRO_PATTERN_TYPE_RASTER_SOURCE -} cairo_pattern_type_t; - -cairo_public cairo_pattern_type_t -cairo_pattern_get_type (cairo_pattern_t *pattern); - -cairo_public void -cairo_pattern_add_color_stop_rgb (cairo_pattern_t *pattern, - double offset, - double red, double green, double blue); - -cairo_public void -cairo_pattern_add_color_stop_rgba (cairo_pattern_t *pattern, - double offset, - double red, double green, double blue, - double alpha); - -cairo_public void -cairo_mesh_pattern_begin_patch (cairo_pattern_t *pattern); - -cairo_public void -cairo_mesh_pattern_end_patch (cairo_pattern_t *pattern); - -cairo_public void -cairo_mesh_pattern_curve_to (cairo_pattern_t *pattern, - double x1, double y1, - double x2, double y2, - double x3, double y3); - -cairo_public void -cairo_mesh_pattern_line_to (cairo_pattern_t *pattern, - double x, double y); - -cairo_public void -cairo_mesh_pattern_move_to (cairo_pattern_t *pattern, - double x, double y); - -cairo_public void -cairo_mesh_pattern_set_control_point (cairo_pattern_t *pattern, - unsigned int point_num, - double x, double y); - -cairo_public void -cairo_mesh_pattern_set_corner_color_rgb (cairo_pattern_t *pattern, - unsigned int corner_num, - double red, double green, double blue); - -cairo_public void -cairo_mesh_pattern_set_corner_color_rgba (cairo_pattern_t *pattern, - unsigned int corner_num, - double red, double green, double blue, - double alpha); - -cairo_public void -cairo_pattern_set_matrix (cairo_pattern_t *pattern, - const cairo_matrix_t *matrix); - -cairo_public void -cairo_pattern_get_matrix (cairo_pattern_t *pattern, - cairo_matrix_t *matrix); - -/** - * cairo_extend_t: - * @CAIRO_EXTEND_NONE: pixels outside of the source pattern - * are fully transparent (Since 1.0) - * @CAIRO_EXTEND_REPEAT: the pattern is tiled by repeating (Since 1.0) - * @CAIRO_EXTEND_REFLECT: the pattern is tiled by reflecting - * at the edges (Since 1.0; but only implemented for surface patterns since 1.6) - * @CAIRO_EXTEND_PAD: pixels outside of the pattern copy - * the closest pixel from the source (Since 1.2; but only - * implemented for surface patterns since 1.6) - * - * #cairo_extend_t is used to describe how pattern color/alpha will be - * determined for areas "outside" the pattern's natural area, (for - * example, outside the surface bounds or outside the gradient - * geometry). - * - * Mesh patterns are not affected by the extend mode. - * - * The default extend mode is %CAIRO_EXTEND_NONE for surface patterns - * and %CAIRO_EXTEND_PAD for gradient patterns. - * - * New entries may be added in future versions. - * - * Since: 1.0 - **/ -typedef enum _cairo_extend { - CAIRO_EXTEND_NONE, - CAIRO_EXTEND_REPEAT, - CAIRO_EXTEND_REFLECT, - CAIRO_EXTEND_PAD -} cairo_extend_t; - -cairo_public void -cairo_pattern_set_extend (cairo_pattern_t *pattern, cairo_extend_t extend); - -cairo_public cairo_extend_t -cairo_pattern_get_extend (cairo_pattern_t *pattern); - -/** - * cairo_filter_t: - * @CAIRO_FILTER_FAST: A high-performance filter, with quality similar - * to %CAIRO_FILTER_NEAREST (Since 1.0) - * @CAIRO_FILTER_GOOD: A reasonable-performance filter, with quality - * similar to %CAIRO_FILTER_BILINEAR (Since 1.0) - * @CAIRO_FILTER_BEST: The highest-quality available, performance may - * not be suitable for interactive use. (Since 1.0) - * @CAIRO_FILTER_NEAREST: Nearest-neighbor filtering (Since 1.0) - * @CAIRO_FILTER_BILINEAR: Linear interpolation in two dimensions (Since 1.0) - * @CAIRO_FILTER_GAUSSIAN: This filter value is currently - * unimplemented, and should not be used in current code. (Since 1.0) - * - * #cairo_filter_t is used to indicate what filtering should be - * applied when reading pixel values from patterns. See - * cairo_pattern_set_filter() for indicating the desired filter to be - * used with a particular pattern. - * - * Since: 1.0 - **/ -typedef enum _cairo_filter { - CAIRO_FILTER_FAST, - CAIRO_FILTER_GOOD, - CAIRO_FILTER_BEST, - CAIRO_FILTER_NEAREST, - CAIRO_FILTER_BILINEAR, - CAIRO_FILTER_GAUSSIAN -} cairo_filter_t; - -cairo_public void -cairo_pattern_set_filter (cairo_pattern_t *pattern, cairo_filter_t filter); - -cairo_public cairo_filter_t -cairo_pattern_get_filter (cairo_pattern_t *pattern); - -cairo_public cairo_status_t -cairo_pattern_get_rgba (cairo_pattern_t *pattern, - double *red, double *green, - double *blue, double *alpha); - -cairo_public cairo_status_t -cairo_pattern_get_surface (cairo_pattern_t *pattern, - cairo_surface_t **surface); - - -cairo_public cairo_status_t -cairo_pattern_get_color_stop_rgba (cairo_pattern_t *pattern, - int index, double *offset, - double *red, double *green, - double *blue, double *alpha); - -cairo_public cairo_status_t -cairo_pattern_get_color_stop_count (cairo_pattern_t *pattern, - int *count); - -cairo_public cairo_status_t -cairo_pattern_get_linear_points (cairo_pattern_t *pattern, - double *x0, double *y0, - double *x1, double *y1); - -cairo_public cairo_status_t -cairo_pattern_get_radial_circles (cairo_pattern_t *pattern, - double *x0, double *y0, double *r0, - double *x1, double *y1, double *r1); - -cairo_public cairo_status_t -cairo_mesh_pattern_get_patch_count (cairo_pattern_t *pattern, - unsigned int *count); - -cairo_public cairo_path_t * -cairo_mesh_pattern_get_path (cairo_pattern_t *pattern, - unsigned int patch_num); - -cairo_public cairo_status_t -cairo_mesh_pattern_get_corner_color_rgba (cairo_pattern_t *pattern, - unsigned int patch_num, - unsigned int corner_num, - double *red, double *green, - double *blue, double *alpha); - -cairo_public cairo_status_t -cairo_mesh_pattern_get_control_point (cairo_pattern_t *pattern, - unsigned int patch_num, - unsigned int point_num, - double *x, double *y); - -/* Matrix functions */ - -cairo_public void -cairo_matrix_init (cairo_matrix_t *matrix, - double xx, double yx, - double xy, double yy, - double x0, double y0); - -cairo_public void -cairo_matrix_init_identity (cairo_matrix_t *matrix); - -cairo_public void -cairo_matrix_init_translate (cairo_matrix_t *matrix, - double tx, double ty); - -cairo_public void -cairo_matrix_init_scale (cairo_matrix_t *matrix, - double sx, double sy); - -cairo_public void -cairo_matrix_init_rotate (cairo_matrix_t *matrix, - double radians); - -cairo_public void -cairo_matrix_translate (cairo_matrix_t *matrix, double tx, double ty); - -cairo_public void -cairo_matrix_scale (cairo_matrix_t *matrix, double sx, double sy); - -cairo_public void -cairo_matrix_rotate (cairo_matrix_t *matrix, double radians); - -cairo_public cairo_status_t -cairo_matrix_invert (cairo_matrix_t *matrix); - -cairo_public void -cairo_matrix_multiply (cairo_matrix_t *result, - const cairo_matrix_t *a, - const cairo_matrix_t *b); - -cairo_public void -cairo_matrix_transform_distance (const cairo_matrix_t *matrix, - double *dx, double *dy); - -cairo_public void -cairo_matrix_transform_point (const cairo_matrix_t *matrix, - double *x, double *y); - -/* Region functions */ - -/** - * cairo_region_t: - * - * A #cairo_region_t represents a set of integer-aligned rectangles. - * - * It allows set-theoretical operations like cairo_region_union() and - * cairo_region_intersect() to be performed on them. - * - * Memory management of #cairo_region_t is done with - * cairo_region_reference() and cairo_region_destroy(). - * - * Since: 1.10 - **/ -typedef struct _cairo_region cairo_region_t; - -/** - * cairo_region_overlap_t: - * @CAIRO_REGION_OVERLAP_IN: The contents are entirely inside the region. (Since 1.10) - * @CAIRO_REGION_OVERLAP_OUT: The contents are entirely outside the region. (Since 1.10) - * @CAIRO_REGION_OVERLAP_PART: The contents are partially inside and - * partially outside the region. (Since 1.10) - * - * Used as the return value for cairo_region_contains_rectangle(). - * - * Since: 1.10 - **/ -typedef enum _cairo_region_overlap { - CAIRO_REGION_OVERLAP_IN, /* completely inside region */ - CAIRO_REGION_OVERLAP_OUT, /* completely outside region */ - CAIRO_REGION_OVERLAP_PART /* partly inside region */ -} cairo_region_overlap_t; - -cairo_public cairo_region_t * -cairo_region_create (void); - -cairo_public cairo_region_t * -cairo_region_create_rectangle (const cairo_rectangle_int_t *rectangle); - -cairo_public cairo_region_t * -cairo_region_create_rectangles (const cairo_rectangle_int_t *rects, - int count); - -cairo_public cairo_region_t * -cairo_region_copy (const cairo_region_t *original); - -cairo_public cairo_region_t * -cairo_region_reference (cairo_region_t *region); - -cairo_public void -cairo_region_destroy (cairo_region_t *region); - -cairo_public cairo_bool_t -cairo_region_equal (const cairo_region_t *a, const cairo_region_t *b); - -cairo_public cairo_status_t -cairo_region_status (const cairo_region_t *region); - -cairo_public void -cairo_region_get_extents (const cairo_region_t *region, - cairo_rectangle_int_t *extents); - -cairo_public int -cairo_region_num_rectangles (const cairo_region_t *region); - -cairo_public void -cairo_region_get_rectangle (const cairo_region_t *region, - int nth, - cairo_rectangle_int_t *rectangle); - -cairo_public cairo_bool_t -cairo_region_is_empty (const cairo_region_t *region); - -cairo_public cairo_region_overlap_t -cairo_region_contains_rectangle (const cairo_region_t *region, - const cairo_rectangle_int_t *rectangle); - -cairo_public cairo_bool_t -cairo_region_contains_point (const cairo_region_t *region, int x, int y); - -cairo_public void -cairo_region_translate (cairo_region_t *region, int dx, int dy); - -cairo_public cairo_status_t -cairo_region_subtract (cairo_region_t *dst, const cairo_region_t *other); - -cairo_public cairo_status_t -cairo_region_subtract_rectangle (cairo_region_t *dst, - const cairo_rectangle_int_t *rectangle); - -cairo_public cairo_status_t -cairo_region_intersect (cairo_region_t *dst, const cairo_region_t *other); - -cairo_public cairo_status_t -cairo_region_intersect_rectangle (cairo_region_t *dst, - const cairo_rectangle_int_t *rectangle); - -cairo_public cairo_status_t -cairo_region_union (cairo_region_t *dst, const cairo_region_t *other); - -cairo_public cairo_status_t -cairo_region_union_rectangle (cairo_region_t *dst, - const cairo_rectangle_int_t *rectangle); - -cairo_public cairo_status_t -cairo_region_xor (cairo_region_t *dst, const cairo_region_t *other); - -cairo_public cairo_status_t -cairo_region_xor_rectangle (cairo_region_t *dst, - const cairo_rectangle_int_t *rectangle); - -/* Functions to be used while debugging (not intended for use in production code) */ -cairo_public void -cairo_debug_reset_static_data (void); - - -CAIRO_END_DECLS - -#endif /* CAIRO_H */ diff --git a/source/libs/cairo/cairo-src/src/cairo.pc.in b/source/libs/cairo/cairo-src/src/cairo.pc.in deleted file mode 100644 index b361edf18fb177871b98441c9526e5bd34bc0990..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairo.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: cairo -Description: Multi-platform 2D graphics library -Version: @VERSION@ - -@PKGCONFIG_REQUIRES@: @CAIRO_REQUIRES@ -Libs: -L${libdir} -lcairo -Libs.private: @CAIRO_NONPKGCONFIG_LIBS@ -Cflags: -I${includedir}/cairo diff --git a/source/libs/cairo/cairo-src/src/cairoint.h b/source/libs/cairo/cairo-src/src/cairoint.h deleted file mode 100644 index 555aa8990301cedf7c4e620a1f277019ba8ce4b9..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/cairoint.h +++ /dev/null @@ -1,2082 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - */ - -/* - * These definitions are solely for use by the implementation of cairo - * and constitute no kind of standard. If you need any of these - * functions, please drop me a note. Either the library needs new - * functionality, or there's a way to do what you need using the - * existing published interfaces. cworth@cworth.org - */ - -#ifndef _CAIROINT_H_ -#define _CAIROINT_H_ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef _MSC_VER -#define cairo_public __declspec(dllexport) -#endif - -#include <assert.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <stddef.h> - -#ifdef _MSC_VER -#define _USE_MATH_DEFINES -#endif -#include <math.h> -#include <limits.h> -#include <stdio.h> - -#include "cairo.h" -#include <pixman.h> - -#include "cairo-compiler-private.h" -#include "cairo-error-private.h" - -#if CAIRO_HAS_PDF_SURFACE || \ - CAIRO_HAS_PS_SURFACE || \ - CAIRO_HAS_SCRIPT_SURFACE || \ - CAIRO_HAS_XML_SURFACE -#define CAIRO_HAS_DEFLATE_STREAM 1 -#endif - -#if CAIRO_HAS_PS_SURFACE || \ - CAIRO_HAS_PDF_SURFACE || \ - CAIRO_HAS_SVG_SURFACE || \ - CAIRO_HAS_WIN32_SURFACE -#define CAIRO_HAS_FONT_SUBSET 1 -#endif - -#if CAIRO_HAS_PS_SURFACE || \ - CAIRO_HAS_PDF_SURFACE || \ - CAIRO_HAS_FONT_SUBSET -#define CAIRO_HAS_PDF_OPERATORS 1 -#endif - -CAIRO_BEGIN_DECLS - -#if _WIN32 && !_WIN32_WCE /* Permissions on WinCE? No worries! */ -cairo_private FILE * -_cairo_win32_tmpfile (void); -#define tmpfile() _cairo_win32_tmpfile() -#endif - -#undef MIN -#define MIN(a, b) ((a) < (b) ? (a) : (b)) - -#undef MAX -#define MAX(a, b) ((a) > (b) ? (a) : (b)) - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -#ifndef M_SQRT2 -#define M_SQRT2 1.41421356237309504880 -#endif - -#ifndef M_SQRT1_2 -#define M_SQRT1_2 0.707106781186547524400844362104849039 -#endif - -#undef ARRAY_LENGTH -#define ARRAY_LENGTH(__array) ((int) (sizeof (__array) / sizeof (__array[0]))) - -#undef STRINGIFY -#undef STRINGIFY_ARG -#define STRINGIFY(macro_or_string) STRINGIFY_ARG (macro_or_string) -#define STRINGIFY_ARG(contents) #contents - -#if defined (__GNUC__) -#define cairo_container_of(ptr, type, member) ({ \ - const __typeof__ (((type *) 0)->member) *mptr__ = (ptr); \ - (type *) ((char *) mptr__ - offsetof (type, member)); \ -}) -#else -#define cairo_container_of(ptr, type, member) \ - ((type *)((char *) (ptr) - (char *) &((type *)0)->member)) -#endif - - -#define ASSERT_NOT_REACHED \ -do { \ - assert (!"reached"); \ -} while (0) -#define COMPILE_TIME_ASSERT1(condition, line) \ - typedef int compile_time_assertion_at_line_##line##_failed [(condition)?1:-1] -#define COMPILE_TIME_ASSERT0(condition, line) COMPILE_TIME_ASSERT1(condition, line) -#define COMPILE_TIME_ASSERT(condition) COMPILE_TIME_ASSERT0(condition, __LINE__) - -#define CAIRO_ALPHA_IS_CLEAR(alpha) ((alpha) <= ((double)0x00ff / (double)0xffff)) -#define CAIRO_ALPHA_SHORT_IS_CLEAR(alpha) ((alpha) <= 0x00ff) - -#define CAIRO_ALPHA_IS_OPAQUE(alpha) ((alpha) >= ((double)0xff00 / (double)0xffff)) -#define CAIRO_ALPHA_SHORT_IS_OPAQUE(alpha) ((alpha) >= 0xff00) -#define CAIRO_ALPHA_IS_ZERO(alpha) ((alpha) <= 0.0) - -#define CAIRO_COLOR_IS_CLEAR(color) CAIRO_ALPHA_SHORT_IS_CLEAR ((color)->alpha_short) -#define CAIRO_COLOR_IS_OPAQUE(color) CAIRO_ALPHA_SHORT_IS_OPAQUE ((color)->alpha_short) - -/* Reverse the bits in a byte with 7 operations (no 64-bit): - * Devised by Sean Anderson, July 13, 2001. - * Source: http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith32Bits - */ -#define CAIRO_BITSWAP8(c) ((((c) * 0x0802LU & 0x22110LU) | ((c) * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16) - -/* Return the number of 1 bits in mask. - * - * GCC 3.4 supports a "population count" builtin, which on many targets is - * implemented with a single instruction. There is a fallback definition - * in libgcc in case a target does not have one, which should be just as - * good as the open-coded solution below, (which is "HACKMEM 169"). - */ -static inline int cairo_const -_cairo_popcount (uint32_t mask) -{ -#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) - return __builtin_popcount (mask); -#else - register int y; - - y = (mask >> 1) &033333333333; - y = mask - y - ((y >>1) & 033333333333); - return (((y + (y >> 3)) & 030707070707) % 077); -#endif -} - -static cairo_always_inline cairo_bool_t -_cairo_is_little_endian (void) -{ - static const int i = 1; - return *((char *) &i) == 0x01; -} - -#ifdef WORDS_BIGENDIAN -#define CAIRO_BITSWAP8_IF_LITTLE_ENDIAN(c) (c) -#else -#define CAIRO_BITSWAP8_IF_LITTLE_ENDIAN(c) CAIRO_BITSWAP8(c) -#endif - -#ifdef WORDS_BIGENDIAN - -#define cpu_to_be16(v) (v) -#define be16_to_cpu(v) (v) -#define cpu_to_be32(v) (v) -#define be32_to_cpu(v) (v) - -#else - -static inline uint16_t cairo_const -cpu_to_be16(uint16_t v) -{ - return (v << 8) | (v >> 8); -} - -static inline uint16_t cairo_const -be16_to_cpu(uint16_t v) -{ - return cpu_to_be16 (v); -} - -static inline uint32_t cairo_const -cpu_to_be32(uint32_t v) -{ - return (v >> 24) | ((v >> 8) & 0xff00) | ((v << 8) & 0xff0000) | (v << 24); -} - -static inline uint32_t cairo_const -be32_to_cpu(uint32_t v) -{ - return cpu_to_be32 (v); -} - -#endif - -/* Unaligned big endian access - */ - -static inline uint16_t get_unaligned_be16 (const unsigned char *p) -{ - return p[0] << 8 | p[1]; -} - -static inline uint32_t get_unaligned_be32 (const unsigned char *p) -{ - return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; -} - -static inline void put_unaligned_be16 (uint16_t v, unsigned char *p) -{ - p[0] = (v >> 8) & 0xff; - p[1] = v & 0xff; -} - -static inline void put_unaligned_be32 (uint32_t v, unsigned char *p) -{ - p[0] = (v >> 24) & 0xff; - p[1] = (v >> 16) & 0xff; - p[2] = (v >> 8) & 0xff; - p[3] = v & 0xff; -} - -/* The glibc versions of ispace() and isdigit() are slow in UTF-8 locales. - */ - -static inline int cairo_const -_cairo_isspace (int c) -{ - return (c == 0x20 || (c >= 0x09 && c <= 0x0d)); -} - -static inline int cairo_const -_cairo_isdigit (int c) -{ - return (c >= '0' && c <= '9'); -} - -#include "cairo-types-private.h" -#include "cairo-cache-private.h" -#include "cairo-reference-count-private.h" -#include "cairo-spans-private.h" -#include "cairo-surface-private.h" - -cairo_private void -_cairo_box_from_doubles (cairo_box_t *box, - double *x1, double *y1, - double *x2, double *y2); - -cairo_private void -_cairo_box_to_doubles (const cairo_box_t *box, - double *x1, double *y1, - double *x2, double *y2); - -cairo_private void -_cairo_box_from_rectangle (cairo_box_t *box, - const cairo_rectangle_int_t *rectangle); - -cairo_private void -_cairo_box_round_to_rectangle (const cairo_box_t *box, - cairo_rectangle_int_t *rectangle); - -cairo_private void -_cairo_box_add_curve_to (cairo_box_t *extents, - const cairo_point_t *a, - const cairo_point_t *b, - const cairo_point_t *c, - const cairo_point_t *d); - -cairo_private void -_cairo_boxes_get_extents (const cairo_box_t *boxes, - int num_boxes, - cairo_box_t *extents); - -cairo_private extern const cairo_rectangle_int_t _cairo_empty_rectangle; -cairo_private extern const cairo_rectangle_int_t _cairo_unbounded_rectangle; - -static inline void -_cairo_unbounded_rectangle_init (cairo_rectangle_int_t *rect) -{ - *rect = _cairo_unbounded_rectangle; -} - -cairo_private_no_warn cairo_bool_t -_cairo_rectangle_intersect (cairo_rectangle_int_t *dst, - const cairo_rectangle_int_t *src); - -static inline cairo_bool_t -_cairo_rectangle_intersects (const cairo_rectangle_int_t *dst, - const cairo_rectangle_int_t *src) -{ - return !(src->x >= dst->x + (int) dst->width || - src->x + (int) src->width <= dst->x || - src->y >= dst->y + (int) dst->height || - src->y + (int) src->height <= dst->y); -} - -static inline cairo_bool_t -_cairo_rectangle_contains_rectangle (const cairo_rectangle_int_t *a, - const cairo_rectangle_int_t *b) -{ - return (a->x <= b->x && - a->x + (int) a->width >= b->x + (int) b->width && - a->y <= b->y && - a->y + (int) a->height >= b->y + (int) b->height); -} - -cairo_private void -_cairo_rectangle_int_from_double (cairo_rectangle_int_t *recti, - const cairo_rectangle_t *rectf); - -/* Extends the dst rectangle to also contain src. - * If one of the rectangles is empty, the result is undefined - */ -cairo_private void -_cairo_rectangle_union (cairo_rectangle_int_t *dst, - const cairo_rectangle_int_t *src); - -cairo_private cairo_bool_t -_cairo_box_intersects_line_segment (const cairo_box_t *box, - cairo_line_t *line) cairo_pure; - -cairo_private cairo_bool_t -_cairo_spline_intersects (const cairo_point_t *a, - const cairo_point_t *b, - const cairo_point_t *c, - const cairo_point_t *d, - const cairo_box_t *box) cairo_pure; - -typedef struct { - const cairo_user_data_key_t *key; - void *user_data; - cairo_destroy_func_t destroy; -} cairo_user_data_slot_t; - -cairo_private void -_cairo_user_data_array_init (cairo_user_data_array_t *array); - -cairo_private void -_cairo_user_data_array_fini (cairo_user_data_array_t *array); - -cairo_private void * -_cairo_user_data_array_get_data (cairo_user_data_array_t *array, - const cairo_user_data_key_t *key); - -cairo_private cairo_status_t -_cairo_user_data_array_set_data (cairo_user_data_array_t *array, - const cairo_user_data_key_t *key, - void *user_data, - cairo_destroy_func_t destroy); - -cairo_private cairo_status_t -_cairo_user_data_array_copy (cairo_user_data_array_t *dst, - const cairo_user_data_array_t *src); - -cairo_private void -_cairo_user_data_array_foreach (cairo_user_data_array_t *array, - void (*func) (const void *key, - void *elt, - void *closure), - void *closure); - -#define _CAIRO_HASH_INIT_VALUE 5381 - -cairo_private unsigned long -_cairo_hash_string (const char *c); - -cairo_private unsigned long -_cairo_hash_bytes (unsigned long hash, - const void *bytes, - unsigned int length); - -#define _cairo_scaled_glyph_index(g) ((g)->hash_entry.hash) -#define _cairo_scaled_glyph_set_index(g, i) ((g)->hash_entry.hash = (i)) - -#include "cairo-scaled-font-private.h" - -struct _cairo_font_face { - /* hash_entry must be first */ - cairo_hash_entry_t hash_entry; - cairo_status_t status; - cairo_reference_count_t ref_count; - cairo_user_data_array_t user_data; - const cairo_font_face_backend_t *backend; -}; - -cairo_private void -_cairo_default_context_reset_static_data (void); - -cairo_private void -_cairo_toy_font_face_reset_static_data (void); - -cairo_private void -_cairo_ft_font_reset_static_data (void); - -cairo_private void -_cairo_win32_font_reset_static_data (void); - -#if CAIRO_HAS_COGL_SURFACE -void -_cairo_cogl_context_reset_static_data (void); -#endif - -/* the font backend interface */ - -struct _cairo_unscaled_font_backend { - cairo_bool_t (*destroy) (void *unscaled_font); -}; - -/* #cairo_toy_font_face_t - simple family/slant/weight font faces used for - * the built-in font API - */ - -typedef struct _cairo_toy_font_face { - cairo_font_face_t base; - const char *family; - cairo_bool_t owns_family; - cairo_font_slant_t slant; - cairo_font_weight_t weight; - - cairo_font_face_t *impl_face; /* The non-toy font face this actually uses */ -} cairo_toy_font_face_t; - -typedef enum _cairo_scaled_glyph_info { - CAIRO_SCALED_GLYPH_INFO_METRICS = (1 << 0), - CAIRO_SCALED_GLYPH_INFO_SURFACE = (1 << 1), - CAIRO_SCALED_GLYPH_INFO_PATH = (1 << 2), - CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE = (1 << 3) -} cairo_scaled_glyph_info_t; - -typedef struct _cairo_scaled_font_subset { - cairo_scaled_font_t *scaled_font; - unsigned int font_id; - unsigned int subset_id; - - /* Index of glyphs array is subset_glyph_index. - * Value of glyphs array is scaled_font_glyph_index. - */ - unsigned long *glyphs; - char **utf8; - char **glyph_names; - int *to_latin_char; - unsigned long *latin_to_subset_glyph_index; - unsigned int num_glyphs; - cairo_bool_t is_composite; - cairo_bool_t is_scaled; - cairo_bool_t is_latin; -} cairo_scaled_font_subset_t; - -struct _cairo_scaled_font_backend { - cairo_font_type_t type; - - void - (*fini) (void *scaled_font); - - cairo_warn cairo_int_status_t - (*scaled_glyph_init) (void *scaled_font, - cairo_scaled_glyph_t *scaled_glyph, - cairo_scaled_glyph_info_t info); - - /* A backend only needs to implement this or ucs4_to_index(), not - * both. This allows the backend to do something more sophisticated - * then just converting characters one by one. - */ - cairo_warn cairo_int_status_t - (*text_to_glyphs) (void *scaled_font, - double x, - double y, - const char *utf8, - int utf8_len, - cairo_glyph_t **glyphs, - int *num_glyphs, - cairo_text_cluster_t **clusters, - int *num_clusters, - cairo_text_cluster_flags_t *cluster_flags); - - unsigned long - (*ucs4_to_index) (void *scaled_font, - uint32_t ucs4); - - /* Read data from a sfnt font table. - * @scaled_font: font - * @tag: 4 byte table name specifying the table to read. - * @offset: offset into the table - * @buffer: buffer to write data into. Caller must ensure there is sufficient space. - * If NULL, return the size of the table in @length. - * @length: If @buffer is NULL, the size of the table will be returned in @length. - * If @buffer is not null, @length specifies the number of bytes to read. - * - * If less than @length bytes are available to read this function - * returns CAIRO_INT_STATUS_UNSUPPORTED. Note that requesting more - * bytes than are available in the table may continue reading data - * from the following table and return success. If this is - * undesirable the caller should first query the table size. If an - * error occurs the output value of @length is undefined. - * - * Returns CAIRO_INT_STATUS_UNSUPPORTED if not a sfnt style font or table not found. - */ - cairo_warn cairo_int_status_t - (*load_truetype_table)(void *scaled_font, - unsigned long tag, - long offset, - unsigned char *buffer, - unsigned long *length); - - /* ucs4 is set to -1 if the unicode character could not be found - * for the glyph */ - cairo_warn cairo_int_status_t - (*index_to_ucs4)(void *scaled_font, - unsigned long index, - uint32_t *ucs4); - - cairo_warn cairo_bool_t - (*is_synthetic)(void *scaled_font); - - /* For type 1 fonts, return the glyph name for a given glyph index. - * A glyph index and list of glyph names in the Type 1 fonts is provided. - * The function returns the index of the glyph in the list of glyph names. - * @scaled_font: font - * @glyph_names: the names of each glyph in the Type 1 font in the - * order they appear in the CharStrings array - * @num_glyph_names: the number of names in the glyph_names array - * @glyph_index: the given glyph index - * @glyph_array_index: (index into glyph_names) the glyph name corresponding - * to the glyph_index - */ - - cairo_warn cairo_int_status_t - (*index_to_glyph_name)(void *scaled_font, - char **glyph_names, - int num_glyph_names, - unsigned long glyph_index, - unsigned long *glyph_array_index); - - /* Read data from a PostScript font. - * @scaled_font: font - * @offset: offset into the table - * @buffer: buffer to write data into. Caller must ensure there is sufficient space. - * If NULL, return the size of the table in @length. - * @length: If @buffer is NULL, the size of the table will be returned in @length. - * If @buffer is not null, @length specifies the number of bytes to read. - * - * If less than @length bytes are available to read this function - * returns CAIRO_INT_STATUS_UNSUPPORTED. If an error occurs the - * output value of @length is undefined. - * - * Returns CAIRO_INT_STATUS_UNSUPPORTED if not a Type 1 font. - */ - cairo_warn cairo_int_status_t - (*load_type1_data) (void *scaled_font, - long offset, - unsigned char *buffer, - unsigned long *length); -}; - -struct _cairo_font_face_backend { - cairo_font_type_t type; - - cairo_warn cairo_status_t - (*create_for_toy) (cairo_toy_font_face_t *toy_face, - cairo_font_face_t **font_face); - - /* The destroy() function is allowed to resurrect the font face - * by re-referencing. This is needed for the FreeType backend. - */ - cairo_bool_t - (*destroy) (void *font_face); - - cairo_warn cairo_status_t - (*scaled_font_create) (void *font_face, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options, - cairo_scaled_font_t **scaled_font); - - cairo_font_face_t * - (*get_implementation) (void *font_face, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options); -}; - -extern const cairo_private struct _cairo_font_face_backend _cairo_user_font_face_backend; - -/* concrete font backends */ -#if CAIRO_HAS_FT_FONT - -extern const cairo_private struct _cairo_font_face_backend _cairo_ft_font_face_backend; - -#endif - -#if CAIRO_HAS_WIN32_FONT - -extern const cairo_private struct _cairo_font_face_backend _cairo_win32_font_face_backend; - -#endif - -#if CAIRO_HAS_QUARTZ_FONT - -extern const cairo_private struct _cairo_font_face_backend _cairo_quartz_font_face_backend; - -#endif - -#define CAIRO_EXTEND_SURFACE_DEFAULT CAIRO_EXTEND_NONE -#define CAIRO_EXTEND_GRADIENT_DEFAULT CAIRO_EXTEND_PAD -#define CAIRO_FILTER_DEFAULT CAIRO_FILTER_GOOD - -extern const cairo_private cairo_solid_pattern_t _cairo_pattern_clear; -extern const cairo_private cairo_solid_pattern_t _cairo_pattern_black; -extern const cairo_private cairo_solid_pattern_t _cairo_pattern_white; - -struct _cairo_surface_attributes { - cairo_matrix_t matrix; - cairo_extend_t extend; - cairo_filter_t filter; - cairo_bool_t has_component_alpha; - int x_offset; - int y_offset; - void *extra; -}; - -#define CAIRO_FONT_SLANT_DEFAULT CAIRO_FONT_SLANT_NORMAL -#define CAIRO_FONT_WEIGHT_DEFAULT CAIRO_FONT_WEIGHT_NORMAL - -#define CAIRO_WIN32_FONT_FAMILY_DEFAULT "Arial" -#define CAIRO_QUARTZ_FONT_FAMILY_DEFAULT "Helvetica" -#define CAIRO_FT_FONT_FAMILY_DEFAULT "" -#define CAIRO_USER_FONT_FAMILY_DEFAULT "@cairo:" - -#if CAIRO_HAS_WIN32_FONT - -#define CAIRO_FONT_FAMILY_DEFAULT CAIRO_WIN32_FONT_FAMILY_DEFAULT -#define CAIRO_FONT_FACE_BACKEND_DEFAULT &_cairo_win32_font_face_backend - -#elif CAIRO_HAS_QUARTZ_FONT - -#define CAIRO_FONT_FAMILY_DEFAULT CAIRO_QUARTZ_FONT_FAMILY_DEFAULT -#define CAIRO_FONT_FACE_BACKEND_DEFAULT &_cairo_quartz_font_face_backend - -#elif CAIRO_HAS_FT_FONT - -#define CAIRO_FONT_FAMILY_DEFAULT CAIRO_FT_FONT_FAMILY_DEFAULT -#define CAIRO_FONT_FACE_BACKEND_DEFAULT &_cairo_ft_font_face_backend - -#else - -#define CAIRO_FONT_FAMILY_DEFAULT CAIRO_FT_FONT_FAMILY_DEFAULT -#define CAIRO_FONT_FACE_BACKEND_DEFAULT &_cairo_user_font_face_backend - -#endif - -#define CAIRO_GSTATE_OPERATOR_DEFAULT CAIRO_OPERATOR_OVER -#define CAIRO_GSTATE_TOLERANCE_DEFAULT 0.1 -#define CAIRO_GSTATE_FILL_RULE_DEFAULT CAIRO_FILL_RULE_WINDING -#define CAIRO_GSTATE_LINE_WIDTH_DEFAULT 2.0 -#define CAIRO_GSTATE_LINE_CAP_DEFAULT CAIRO_LINE_CAP_BUTT -#define CAIRO_GSTATE_LINE_JOIN_DEFAULT CAIRO_LINE_JOIN_MITER -#define CAIRO_GSTATE_MITER_LIMIT_DEFAULT 10.0 -#define CAIRO_GSTATE_DEFAULT_FONT_SIZE 10.0 - -#define CAIRO_SURFACE_RESOLUTION_DEFAULT 72.0 -#define CAIRO_SURFACE_FALLBACK_RESOLUTION_DEFAULT 300.0 - -typedef struct _cairo_stroke_face { - cairo_point_t ccw; - cairo_point_t point; - cairo_point_t cw; - cairo_slope_t dev_vector; - cairo_point_double_t dev_slope; - cairo_point_double_t usr_vector; - double length; -} cairo_stroke_face_t; - -/* cairo.c */ - -static inline double cairo_const -_cairo_restrict_value (double value, double min, double max) -{ - if (value < min) - return min; - else if (value > max) - return max; - else - return value; -} - -/* C99 round() rounds to the nearest integral value with halfway cases rounded - * away from 0. _cairo_round rounds halfway cases toward positive infinity. - * This matches the rounding behaviour of _cairo_lround. */ -static inline double cairo_const -_cairo_round (double r) -{ - return floor (r + .5); -} - -#if DISABLE_SOME_FLOATING_POINT -cairo_private int -_cairo_lround (double d) cairo_const; -#else -static inline int cairo_const -_cairo_lround (double r) -{ - return _cairo_round (r); -} -#endif - -cairo_private uint16_t -_cairo_half_from_float (float f) cairo_const; - -cairo_private cairo_bool_t -_cairo_operator_bounded_by_mask (cairo_operator_t op) cairo_const; - -cairo_private cairo_bool_t -_cairo_operator_bounded_by_source (cairo_operator_t op) cairo_const; - -enum { - CAIRO_OPERATOR_BOUND_BY_MASK = 1 << 1, - CAIRO_OPERATOR_BOUND_BY_SOURCE = 1 << 2, -}; - -cairo_private uint32_t -_cairo_operator_bounded_by_either (cairo_operator_t op) cairo_const; -/* cairo-color.c */ -cairo_private const cairo_color_t * -_cairo_stock_color (cairo_stock_t stock) cairo_pure; - -#define CAIRO_COLOR_WHITE _cairo_stock_color (CAIRO_STOCK_WHITE) -#define CAIRO_COLOR_BLACK _cairo_stock_color (CAIRO_STOCK_BLACK) -#define CAIRO_COLOR_TRANSPARENT _cairo_stock_color (CAIRO_STOCK_TRANSPARENT) - -cairo_private uint16_t -_cairo_color_double_to_short (double d) cairo_const; - -cairo_private void -_cairo_color_init_rgba (cairo_color_t *color, - double red, double green, double blue, - double alpha); - -cairo_private void -_cairo_color_multiply_alpha (cairo_color_t *color, - double alpha); - -cairo_private void -_cairo_color_get_rgba (cairo_color_t *color, - double *red, - double *green, - double *blue, - double *alpha); - -cairo_private void -_cairo_color_get_rgba_premultiplied (cairo_color_t *color, - double *red, - double *green, - double *blue, - double *alpha); - -cairo_private cairo_bool_t -_cairo_color_equal (const cairo_color_t *color_a, - const cairo_color_t *color_b) cairo_pure; - -cairo_private cairo_bool_t -_cairo_color_stop_equal (const cairo_color_stop_t *color_a, - const cairo_color_stop_t *color_b) cairo_pure; - -cairo_private cairo_content_t -_cairo_color_get_content (const cairo_color_t *color) cairo_pure; - -/* cairo-font-face.c */ - -extern const cairo_private cairo_font_face_t _cairo_font_face_nil; -extern const cairo_private cairo_font_face_t _cairo_font_face_nil_file_not_found; - -cairo_private void -_cairo_font_face_init (cairo_font_face_t *font_face, - const cairo_font_face_backend_t *backend); - -cairo_private cairo_bool_t -_cairo_font_face_destroy (void *abstract_face); - -cairo_private cairo_status_t -_cairo_font_face_set_error (cairo_font_face_t *font_face, - cairo_status_t status); - -cairo_private void -_cairo_unscaled_font_init (cairo_unscaled_font_t *font, - const cairo_unscaled_font_backend_t *backend); - -cairo_private_no_warn cairo_unscaled_font_t * -_cairo_unscaled_font_reference (cairo_unscaled_font_t *font); - -cairo_private void -_cairo_unscaled_font_destroy (cairo_unscaled_font_t *font); - -/* cairo-font-face-twin.c */ - -cairo_private cairo_font_face_t * -_cairo_font_face_twin_create_fallback (void); - -cairo_private cairo_status_t -_cairo_font_face_twin_create_for_toy (cairo_toy_font_face_t *toy_face, - cairo_font_face_t **font_face); - -/* cairo-font-face-twin-data.c */ - -extern const cairo_private int8_t _cairo_twin_outlines[]; -extern const cairo_private uint16_t _cairo_twin_charmap[128]; - -/* cairo-font-options.c */ - -cairo_private void -_cairo_font_options_init_default (cairo_font_options_t *options); - -cairo_private void -_cairo_font_options_init_copy (cairo_font_options_t *options, - const cairo_font_options_t *other); - -cairo_private void -_cairo_font_options_set_lcd_filter (cairo_font_options_t *options, - cairo_lcd_filter_t lcd_filter); - -cairo_private cairo_lcd_filter_t -_cairo_font_options_get_lcd_filter (const cairo_font_options_t *options); - -cairo_private void -_cairo_font_options_set_round_glyph_positions (cairo_font_options_t *options, - cairo_round_glyph_positions_t round); - -cairo_private cairo_round_glyph_positions_t -_cairo_font_options_get_round_glyph_positions (const cairo_font_options_t *options); - -/* cairo-hull.c */ -cairo_private cairo_status_t -_cairo_hull_compute (cairo_pen_vertex_t *vertices, int *num_vertices); - -/* cairo-lzw.c */ -cairo_private unsigned char * -_cairo_lzw_compress (unsigned char *data, unsigned long *size_in_out); - -/* cairo-misc.c */ -cairo_private cairo_status_t -_cairo_validate_text_clusters (const char *utf8, - int utf8_len, - const cairo_glyph_t *glyphs, - int num_glyphs, - const cairo_text_cluster_t *clusters, - int num_clusters, - cairo_text_cluster_flags_t cluster_flags); - -cairo_private cairo_status_t -_cairo_intern_string (const char **str_inout, int len); - -cairo_private void -_cairo_intern_string_reset_static_data (void); - -cairo_private const char * -cairo_get_locale_decimal_point (void); - -/* cairo-path-fixed.c */ -cairo_private cairo_path_fixed_t * -_cairo_path_fixed_create (void); - -cairo_private void -_cairo_path_fixed_init (cairo_path_fixed_t *path); - -cairo_private cairo_status_t -_cairo_path_fixed_init_copy (cairo_path_fixed_t *path, - const cairo_path_fixed_t *other); - -cairo_private void -_cairo_path_fixed_fini (cairo_path_fixed_t *path); - -cairo_private void -_cairo_path_fixed_destroy (cairo_path_fixed_t *path); - -cairo_private cairo_status_t -_cairo_path_fixed_move_to (cairo_path_fixed_t *path, - cairo_fixed_t x, - cairo_fixed_t y); - -cairo_private void -_cairo_path_fixed_new_sub_path (cairo_path_fixed_t *path); - -cairo_private cairo_status_t -_cairo_path_fixed_rel_move_to (cairo_path_fixed_t *path, - cairo_fixed_t dx, - cairo_fixed_t dy); - -cairo_private cairo_status_t -_cairo_path_fixed_line_to (cairo_path_fixed_t *path, - cairo_fixed_t x, - cairo_fixed_t y); - -cairo_private cairo_status_t -_cairo_path_fixed_rel_line_to (cairo_path_fixed_t *path, - cairo_fixed_t dx, - cairo_fixed_t dy); - -cairo_private cairo_status_t -_cairo_path_fixed_curve_to (cairo_path_fixed_t *path, - cairo_fixed_t x0, cairo_fixed_t y0, - cairo_fixed_t x1, cairo_fixed_t y1, - cairo_fixed_t x2, cairo_fixed_t y2); - -cairo_private cairo_status_t -_cairo_path_fixed_rel_curve_to (cairo_path_fixed_t *path, - cairo_fixed_t dx0, cairo_fixed_t dy0, - cairo_fixed_t dx1, cairo_fixed_t dy1, - cairo_fixed_t dx2, cairo_fixed_t dy2); - -cairo_private cairo_status_t -_cairo_path_fixed_close_path (cairo_path_fixed_t *path); - -cairo_private cairo_bool_t -_cairo_path_fixed_get_current_point (cairo_path_fixed_t *path, - cairo_fixed_t *x, - cairo_fixed_t *y); - -typedef cairo_status_t -(cairo_path_fixed_move_to_func_t) (void *closure, - const cairo_point_t *point); - -typedef cairo_status_t -(cairo_path_fixed_line_to_func_t) (void *closure, - const cairo_point_t *point); - -typedef cairo_status_t -(cairo_path_fixed_curve_to_func_t) (void *closure, - const cairo_point_t *p0, - const cairo_point_t *p1, - const cairo_point_t *p2); - -typedef cairo_status_t -(cairo_path_fixed_close_path_func_t) (void *closure); - -cairo_private cairo_status_t -_cairo_path_fixed_interpret (const cairo_path_fixed_t *path, - cairo_path_fixed_move_to_func_t *move_to, - cairo_path_fixed_line_to_func_t *line_to, - cairo_path_fixed_curve_to_func_t *curve_to, - cairo_path_fixed_close_path_func_t *close_path, - void *closure); - -cairo_private cairo_status_t -_cairo_path_fixed_interpret_flat (const cairo_path_fixed_t *path, - cairo_path_fixed_move_to_func_t *move_to, - cairo_path_fixed_line_to_func_t *line_to, - cairo_path_fixed_close_path_func_t *close_path, - void *closure, - double tolerance); - - -cairo_private cairo_bool_t -_cairo_path_bounder_extents (const cairo_path_fixed_t *path, - cairo_box_t *box); - -cairo_private cairo_bool_t -_cairo_path_fixed_extents (const cairo_path_fixed_t *path, - cairo_box_t *box); - -cairo_private void -_cairo_path_fixed_approximate_clip_extents (const cairo_path_fixed_t *path, - cairo_rectangle_int_t *extents); - -cairo_private void -_cairo_path_fixed_approximate_fill_extents (const cairo_path_fixed_t *path, - cairo_rectangle_int_t *extents); - -cairo_private void -_cairo_path_fixed_fill_extents (const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_rectangle_int_t *extents); - -cairo_private void -_cairo_path_fixed_approximate_stroke_extents (const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - cairo_rectangle_int_t *extents); - -cairo_private cairo_status_t -_cairo_path_fixed_stroke_extents (const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_rectangle_int_t *extents); - -cairo_private void -_cairo_path_fixed_transform (cairo_path_fixed_t *path, - const cairo_matrix_t *matrix); - -cairo_private cairo_bool_t -_cairo_path_fixed_is_box (const cairo_path_fixed_t *path, - cairo_box_t *box); - -cairo_private cairo_bool_t -_cairo_path_fixed_is_rectangle (const cairo_path_fixed_t *path, - cairo_box_t *box); - -/* cairo-path-in-fill.c */ -cairo_private cairo_bool_t -_cairo_path_fixed_in_fill (const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - double x, - double y); - -/* cairo-path-fill.c */ -cairo_private cairo_status_t -_cairo_path_fixed_fill_to_polygon (const cairo_path_fixed_t *path, - double tolerance, - cairo_polygon_t *polygon); - -cairo_private cairo_status_t -_cairo_path_fixed_fill_rectilinear_to_polygon (const cairo_path_fixed_t *path, - cairo_antialias_t antialias, - cairo_polygon_t *polygon); - -cairo_private cairo_status_t -_cairo_path_fixed_fill_rectilinear_to_boxes (const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - cairo_antialias_t antialias, - cairo_boxes_t *boxes); - -cairo_private cairo_region_t * -_cairo_path_fixed_fill_rectilinear_to_region (const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - const cairo_rectangle_int_t *extents); - -cairo_private cairo_status_t -_cairo_path_fixed_fill_to_traps (const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_traps_t *traps); - -/* cairo-path-stroke.c */ -cairo_private cairo_status_t -_cairo_path_fixed_stroke_to_polygon (const cairo_path_fixed_t *path, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_polygon_t *polygon); - -cairo_private cairo_int_status_t -_cairo_path_fixed_stroke_to_tristrip (const cairo_path_fixed_t *path, - const cairo_stroke_style_t*style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_tristrip_t *strip); - -cairo_private cairo_status_t -_cairo_path_fixed_stroke_dashed_to_polygon (const cairo_path_fixed_t *path, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_polygon_t *polygon); - -cairo_private cairo_int_status_t -_cairo_path_fixed_stroke_rectilinear_to_boxes (const cairo_path_fixed_t *path, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *ctm, - cairo_antialias_t antialias, - cairo_boxes_t *boxes); - -cairo_private cairo_int_status_t -_cairo_path_fixed_stroke_to_traps (const cairo_path_fixed_t *path, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_traps_t *traps); - -cairo_private cairo_int_status_t -_cairo_path_fixed_stroke_polygon_to_traps (const cairo_path_fixed_t *path, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_traps_t *traps); - -cairo_private cairo_status_t -_cairo_path_fixed_stroke_to_shaper (cairo_path_fixed_t *path, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_status_t (*add_triangle) (void *closure, - const cairo_point_t triangle[3]), - cairo_status_t (*add_triangle_fan) (void *closure, - const cairo_point_t *midpt, - const cairo_point_t *points, - int npoints), - cairo_status_t (*add_quad) (void *closure, - const cairo_point_t quad[4]), - void *closure); - -/* cairo-scaled-font.c */ - -cairo_private void -_cairo_scaled_font_freeze_cache (cairo_scaled_font_t *scaled_font); - -cairo_private void -_cairo_scaled_font_thaw_cache (cairo_scaled_font_t *scaled_font); - -cairo_private void -_cairo_scaled_font_reset_cache (cairo_scaled_font_t *scaled_font); - -cairo_private cairo_status_t -_cairo_scaled_font_set_error (cairo_scaled_font_t *scaled_font, - cairo_status_t status); - -cairo_private cairo_scaled_font_t * -_cairo_scaled_font_create_in_error (cairo_status_t status); - -cairo_private void -_cairo_scaled_font_reset_static_data (void); - -cairo_private cairo_status_t -_cairo_scaled_font_register_placeholder_and_unlock_font_map (cairo_scaled_font_t *scaled_font); - -cairo_private void -_cairo_scaled_font_unregister_placeholder_and_lock_font_map (cairo_scaled_font_t *scaled_font); - -cairo_private cairo_status_t -_cairo_scaled_font_init (cairo_scaled_font_t *scaled_font, - cairo_font_face_t *font_face, - const cairo_matrix_t *font_matrix, - const cairo_matrix_t *ctm, - const cairo_font_options_t *options, - const cairo_scaled_font_backend_t *backend); - -cairo_private cairo_status_t -_cairo_scaled_font_set_metrics (cairo_scaled_font_t *scaled_font, - cairo_font_extents_t *fs_metrics); - -/* This should only be called on an error path by a scaled_font constructor */ -cairo_private void -_cairo_scaled_font_fini (cairo_scaled_font_t *scaled_font); - -cairo_private cairo_status_t -_cairo_scaled_font_font_extents (cairo_scaled_font_t *scaled_font, - cairo_font_extents_t *extents); - -cairo_private cairo_status_t -_cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font, - const cairo_glyph_t *glyphs, - int num_glyphs, - cairo_rectangle_int_t *extents, - cairo_bool_t *overlap); - -cairo_private cairo_bool_t -_cairo_scaled_font_glyph_approximate_extents (cairo_scaled_font_t *scaled_font, - const cairo_glyph_t *glyphs, - int num_glyphs, - cairo_rectangle_int_t *extents); - -cairo_private cairo_status_t -_cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_surface_t *surface, - int source_x, - int source_y, - int dest_x, - int dest_y, - unsigned int width, - unsigned int height, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_region_t *clip_region); - -cairo_private cairo_status_t -_cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font, - const cairo_glyph_t *glyphs, - int num_glyphs, - cairo_path_fixed_t *path); - -cairo_private void -_cairo_scaled_glyph_set_metrics (cairo_scaled_glyph_t *scaled_glyph, - cairo_scaled_font_t *scaled_font, - cairo_text_extents_t *fs_metrics); - -cairo_private void -_cairo_scaled_glyph_set_surface (cairo_scaled_glyph_t *scaled_glyph, - cairo_scaled_font_t *scaled_font, - cairo_image_surface_t *surface); - -cairo_private void -_cairo_scaled_glyph_set_path (cairo_scaled_glyph_t *scaled_glyph, - cairo_scaled_font_t *scaled_font, - cairo_path_fixed_t *path); - -cairo_private void -_cairo_scaled_glyph_set_recording_surface (cairo_scaled_glyph_t *scaled_glyph, - cairo_scaled_font_t *scaled_font, - cairo_surface_t *recording_surface); - -cairo_private cairo_int_status_t -_cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font, - unsigned long index, - cairo_scaled_glyph_info_t info, - cairo_scaled_glyph_t **scaled_glyph_ret); - -cairo_private double -_cairo_scaled_font_get_max_scale (cairo_scaled_font_t *scaled_font); - -cairo_private void -_cairo_scaled_font_map_destroy (void); - -/* cairo-stroke-style.c */ - -cairo_private void -_cairo_stroke_style_init (cairo_stroke_style_t *style); - -cairo_private cairo_status_t -_cairo_stroke_style_init_copy (cairo_stroke_style_t *style, - const cairo_stroke_style_t *other); - -cairo_private void -_cairo_stroke_style_fini (cairo_stroke_style_t *style); - -cairo_private void -_cairo_stroke_style_max_distance_from_path (const cairo_stroke_style_t *style, - const cairo_path_fixed_t *path, - const cairo_matrix_t *ctm, - double *dx, double *dy); -cairo_private void -_cairo_stroke_style_max_line_distance_from_path (const cairo_stroke_style_t *style, - const cairo_path_fixed_t *path, - const cairo_matrix_t *ctm, - double *dx, double *dy); - -cairo_private void -_cairo_stroke_style_max_join_distance_from_path (const cairo_stroke_style_t *style, - const cairo_path_fixed_t *path, - const cairo_matrix_t *ctm, - double *dx, double *dy); - -cairo_private double -_cairo_stroke_style_dash_period (const cairo_stroke_style_t *style); - -cairo_private double -_cairo_stroke_style_dash_stroked (const cairo_stroke_style_t *style); - -cairo_private cairo_bool_t -_cairo_stroke_style_dash_can_approximate (const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - double tolerance); - -cairo_private void -_cairo_stroke_style_dash_approximate (const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - double tolerance, - double *dash_offset, - double *dashes, - unsigned int *num_dashes); - - -/* cairo-surface.c */ - -cairo_private cairo_status_t -_cairo_surface_copy_mime_data (cairo_surface_t *dst, - cairo_surface_t *src); - -cairo_private_no_warn cairo_int_status_t -_cairo_surface_set_error (cairo_surface_t *surface, - cairo_int_status_t status); - -cairo_private void -_cairo_surface_set_resolution (cairo_surface_t *surface, - double x_res, - double y_res); - -cairo_private cairo_surface_t * -_cairo_surface_create_for_rectangle_int (cairo_surface_t *target, - const cairo_rectangle_int_t *extents); - -cairo_private cairo_surface_t * -_cairo_surface_create_scratch (cairo_surface_t *other, - cairo_content_t content, - int width, - int height, - const cairo_color_t *color); - -cairo_private void -_cairo_surface_init (cairo_surface_t *surface, - const cairo_surface_backend_t *backend, - cairo_device_t *device, - cairo_content_t content); - -cairo_private void -_cairo_surface_set_font_options (cairo_surface_t *surface, - cairo_font_options_t *options); - -cairo_private cairo_status_t -_cairo_surface_paint (cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip); - -cairo_private cairo_image_surface_t * -_cairo_surface_map_to_image (cairo_surface_t *surface, - const cairo_rectangle_int_t *extents); - -cairo_private_no_warn cairo_int_status_t -_cairo_surface_unmap_image (cairo_surface_t *surface, - cairo_image_surface_t *image); - -cairo_private cairo_status_t -_cairo_surface_mask (cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip); - -cairo_private cairo_status_t -_cairo_surface_fill_stroke (cairo_surface_t *surface, - cairo_operator_t fill_op, - const cairo_pattern_t *fill_source, - cairo_fill_rule_t fill_rule, - double fill_tolerance, - cairo_antialias_t fill_antialias, - cairo_path_fixed_t *path, - cairo_operator_t stroke_op, - const cairo_pattern_t *stroke_source, - const cairo_stroke_style_t *stroke_style, - const cairo_matrix_t *stroke_ctm, - const cairo_matrix_t *stroke_ctm_inverse, - double stroke_tolerance, - cairo_antialias_t stroke_antialias, - const cairo_clip_t *clip); - -cairo_private cairo_status_t -_cairo_surface_stroke (cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip); - -cairo_private cairo_status_t -_cairo_surface_fill (cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip); - -cairo_private cairo_status_t -_cairo_surface_show_text_glyphs (cairo_surface_t *surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const char *utf8, - int utf8_len, - cairo_glyph_t *glyphs, - int num_glyphs, - const cairo_text_cluster_t *clusters, - int num_clusters, - cairo_text_cluster_flags_t cluster_flags, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip); - -cairo_private cairo_status_t -_cairo_surface_acquire_source_image (cairo_surface_t *surface, - cairo_image_surface_t **image_out, - void **image_extra); - -cairo_private void -_cairo_surface_release_source_image (cairo_surface_t *surface, - cairo_image_surface_t *image, - void *image_extra); - -cairo_private cairo_surface_t * -_cairo_surface_snapshot (cairo_surface_t *surface); - -cairo_private void -_cairo_surface_attach_snapshot (cairo_surface_t *surface, - cairo_surface_t *snapshot, - cairo_surface_func_t detach_func); - -cairo_private cairo_surface_t * -_cairo_surface_has_snapshot (cairo_surface_t *surface, - const cairo_surface_backend_t *backend); - -cairo_private void -_cairo_surface_detach_snapshot (cairo_surface_t *snapshot); - -cairo_private cairo_status_t -_cairo_surface_begin_modification (cairo_surface_t *surface); - -cairo_private_no_warn cairo_bool_t -_cairo_surface_get_extents (cairo_surface_t *surface, - cairo_rectangle_int_t *extents); - -cairo_private cairo_bool_t -_cairo_surface_has_device_transform (cairo_surface_t *surface) cairo_pure; - -cairo_private void -_cairo_surface_release_device_reference (cairo_surface_t *surface); - -/* cairo-image-surface.c */ - -/* XXX: In cairo 1.2.0 we added a new %CAIRO_FORMAT_RGB16_565 but - * neglected to adjust this macro. The net effect is that it's - * impossible to externally create an image surface with this - * format. This is perhaps a good thing since we also neglected to fix - * up things like cairo_surface_write_to_png() for the new format - * (-Wswitch-enum will tell you where). Is it obvious that format was - * added in haste? - * - * The reason for the new format was to allow the xlib backend to be - * used on X servers with a 565 visual. So the new format did its job - * for that, even without being considered "valid" for the sake of - * things like cairo_image_surface_create(). - * - * Since 1.2.0 we ran into the same situtation with X servers with BGR - * visuals. This time we invented #cairo_internal_format_t instead, - * (see it for more discussion). - * - * The punchline is that %CAIRO_FORMAT_VALID must not conside any - * internal format to be valid. Also we need to decide if the - * RGB16_565 should be moved to instead be an internal format. If so, - * this macro need not change for it. (We probably will need to leave - * an RGB16_565 value in the header files for the sake of code that - * might have that value in it.) - * - * If we do decide to start fully supporting RGB16_565 as an external - * format, then %CAIRO_FORMAT_VALID needs to be adjusted to include - * it. But that should not happen before all necessary code is fixed - * to support it (at least cairo_surface_write_to_png() and a few spots - * in cairo-xlib-surface.c--again see -Wswitch-enum). - */ -#define CAIRO_FORMAT_VALID(format) ((format) >= CAIRO_FORMAT_ARGB32 && \ - (format) <= CAIRO_FORMAT_RGB30) - -/* pixman-required stride alignment in bytes. */ -#define CAIRO_STRIDE_ALIGNMENT (sizeof (uint32_t)) -#define CAIRO_STRIDE_FOR_WIDTH_BPP(w,bpp) \ - ((((bpp)*(w)+7)/8 + CAIRO_STRIDE_ALIGNMENT-1) & -CAIRO_STRIDE_ALIGNMENT) - -#define CAIRO_CONTENT_VALID(content) ((content) && \ - (((content) & ~(CAIRO_CONTENT_COLOR | \ - CAIRO_CONTENT_ALPHA | \ - CAIRO_CONTENT_COLOR_ALPHA))\ - == 0)) - -cairo_private int -_cairo_format_bits_per_pixel (cairo_format_t format) cairo_const; - -cairo_private cairo_format_t -_cairo_format_from_content (cairo_content_t content) cairo_const; - -cairo_private cairo_format_t -_cairo_format_from_pixman_format (pixman_format_code_t pixman_format); - -cairo_private cairo_content_t -_cairo_content_from_format (cairo_format_t format) cairo_const; - -cairo_private cairo_content_t -_cairo_content_from_pixman_format (pixman_format_code_t pixman_format); - -cairo_private cairo_surface_t * -_cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image, - pixman_format_code_t pixman_format); - -cairo_private pixman_format_code_t -_cairo_format_to_pixman_format_code (cairo_format_t format); - -cairo_private cairo_bool_t -_pixman_format_from_masks (cairo_format_masks_t *masks, - pixman_format_code_t *format_ret); - -cairo_private cairo_bool_t -_pixman_format_to_masks (pixman_format_code_t pixman_format, - cairo_format_masks_t *masks); - -cairo_private void -_cairo_image_scaled_glyph_fini (cairo_scaled_font_t *scaled_font, - cairo_scaled_glyph_t *scaled_glyph); - -cairo_private void -_cairo_image_reset_static_data (void); - -cairo_private cairo_surface_t * -_cairo_image_surface_create_with_pixman_format (unsigned char *data, - pixman_format_code_t pixman_format, - int width, - int height, - int stride); - -cairo_private cairo_surface_t * -_cairo_image_surface_create_with_content (cairo_content_t content, - int width, - int height); - -cairo_private void -_cairo_image_surface_assume_ownership_of_data (cairo_image_surface_t *surface); - -cairo_private cairo_image_surface_t * -_cairo_image_surface_coerce (cairo_image_surface_t *surface); - -cairo_private cairo_image_surface_t * -_cairo_image_surface_coerce_to_format (cairo_image_surface_t *surface, - cairo_format_t format); - -cairo_private cairo_image_transparency_t -_cairo_image_analyze_transparency (cairo_image_surface_t *image); - -cairo_private cairo_image_color_t -_cairo_image_analyze_color (cairo_image_surface_t *image); - -/* cairo-pen.c */ -cairo_private int -_cairo_pen_vertices_needed (double tolerance, - double radius, - const cairo_matrix_t *matrix); - -cairo_private cairo_status_t -_cairo_pen_init (cairo_pen_t *pen, - double radius, - double tolerance, - const cairo_matrix_t *ctm); - -cairo_private void -_cairo_pen_init_empty (cairo_pen_t *pen); - -cairo_private cairo_status_t -_cairo_pen_init_copy (cairo_pen_t *pen, const cairo_pen_t *other); - -cairo_private void -_cairo_pen_fini (cairo_pen_t *pen); - -cairo_private cairo_status_t -_cairo_pen_add_points (cairo_pen_t *pen, cairo_point_t *point, int num_points); - -cairo_private int -_cairo_pen_find_active_cw_vertex_index (const cairo_pen_t *pen, - const cairo_slope_t *slope); - -cairo_private int -_cairo_pen_find_active_ccw_vertex_index (const cairo_pen_t *pen, - const cairo_slope_t *slope); - -cairo_private void -_cairo_pen_find_active_cw_vertices (const cairo_pen_t *pen, - const cairo_slope_t *in, - const cairo_slope_t *out, - int *start, int *stop); - -cairo_private void -_cairo_pen_find_active_ccw_vertices (const cairo_pen_t *pen, - const cairo_slope_t *in, - const cairo_slope_t *out, - int *start, int *stop); - -/* cairo-polygon.c */ -cairo_private void -_cairo_polygon_init (cairo_polygon_t *polygon, - const cairo_box_t *boxes, - int num_boxes); - -cairo_private void -_cairo_polygon_init_with_clip (cairo_polygon_t *polygon, - const cairo_clip_t *clip); - -cairo_private cairo_status_t -_cairo_polygon_init_boxes (cairo_polygon_t *polygon, - const cairo_boxes_t *boxes); - -cairo_private cairo_status_t -_cairo_polygon_init_box_array (cairo_polygon_t *polygon, - cairo_box_t *boxes, - int num_boxes); - -cairo_private void -_cairo_polygon_limit (cairo_polygon_t *polygon, - const cairo_box_t *limits, - int num_limits); - -cairo_private void -_cairo_polygon_limit_to_clip (cairo_polygon_t *polygon, - const cairo_clip_t *clip); - -cairo_private void -_cairo_polygon_fini (cairo_polygon_t *polygon); - -cairo_private_no_warn cairo_status_t -_cairo_polygon_add_line (cairo_polygon_t *polygon, - const cairo_line_t *line, - int top, int bottom, - int dir); - -cairo_private_no_warn cairo_status_t -_cairo_polygon_add_external_edge (void *polygon, - const cairo_point_t *p1, - const cairo_point_t *p2); - -cairo_private_no_warn cairo_status_t -_cairo_polygon_add_contour (cairo_polygon_t *polygon, - const cairo_contour_t *contour); - -cairo_private void -_cairo_polygon_translate (cairo_polygon_t *polygon, int dx, int dy); - -cairo_private cairo_status_t -_cairo_polygon_reduce (cairo_polygon_t *polygon, - cairo_fill_rule_t fill_rule); - -cairo_private cairo_status_t -_cairo_polygon_intersect (cairo_polygon_t *a, int winding_a, - cairo_polygon_t *b, int winding_b); - -cairo_private cairo_status_t -_cairo_polygon_intersect_with_boxes (cairo_polygon_t *polygon, - cairo_fill_rule_t *winding, - cairo_box_t *boxes, - int num_boxes); - -static inline cairo_bool_t -_cairo_polygon_is_empty (const cairo_polygon_t *polygon) -{ - return - polygon->num_edges == 0 || - polygon->extents.p2.x <= polygon->extents.p1.x; -} - -#define _cairo_polygon_status(P) ((cairo_polygon_t *) (P))->status - -/* cairo-spline.c */ -cairo_private cairo_bool_t -_cairo_spline_init (cairo_spline_t *spline, - cairo_spline_add_point_func_t add_point_func, - void *closure, - const cairo_point_t *a, const cairo_point_t *b, - const cairo_point_t *c, const cairo_point_t *d); - -cairo_private cairo_status_t -_cairo_spline_decompose (cairo_spline_t *spline, double tolerance); - -cairo_private cairo_status_t -_cairo_spline_bound (cairo_spline_add_point_func_t add_point_func, - void *closure, - const cairo_point_t *p0, const cairo_point_t *p1, - const cairo_point_t *p2, const cairo_point_t *p3); - -/* cairo-matrix.c */ -cairo_private void -_cairo_matrix_get_affine (const cairo_matrix_t *matrix, - double *xx, double *yx, - double *xy, double *yy, - double *x0, double *y0); - -cairo_private void -_cairo_matrix_transform_bounding_box (const cairo_matrix_t *matrix, - double *x1, double *y1, - double *x2, double *y2, - cairo_bool_t *is_tight); - -cairo_private void -_cairo_matrix_transform_bounding_box_fixed (const cairo_matrix_t *matrix, - cairo_box_t *bbox, - cairo_bool_t *is_tight); - -cairo_private cairo_bool_t -_cairo_matrix_is_invertible (const cairo_matrix_t *matrix) cairo_pure; - -cairo_private cairo_bool_t -_cairo_matrix_is_scale_0 (const cairo_matrix_t *matrix) cairo_pure; - -cairo_private double -_cairo_matrix_compute_determinant (const cairo_matrix_t *matrix) cairo_pure; - -cairo_private cairo_status_t -_cairo_matrix_compute_basis_scale_factors (const cairo_matrix_t *matrix, - double *sx, double *sy, int x_major); - -static inline cairo_bool_t -_cairo_matrix_is_identity (const cairo_matrix_t *matrix) -{ - return (matrix->xx == 1.0 && matrix->yx == 0.0 && - matrix->xy == 0.0 && matrix->yy == 1.0 && - matrix->x0 == 0.0 && matrix->y0 == 0.0); -} - -static inline cairo_bool_t -_cairo_matrix_is_translation (const cairo_matrix_t *matrix) -{ - return (matrix->xx == 1.0 && matrix->yx == 0.0 && - matrix->xy == 0.0 && matrix->yy == 1.0); -} - -static inline cairo_bool_t -_cairo_matrix_is_scale (const cairo_matrix_t *matrix) -{ - return matrix->yx == 0.0 && matrix->xy == 0.0; -} - -cairo_private cairo_bool_t -_cairo_matrix_is_integer_translation(const cairo_matrix_t *matrix, - int *itx, int *ity); - -cairo_private cairo_bool_t -_cairo_matrix_has_unity_scale (const cairo_matrix_t *matrix); - -cairo_private cairo_bool_t -_cairo_matrix_is_pixel_exact (const cairo_matrix_t *matrix) cairo_pure; - -cairo_private double -_cairo_matrix_transformed_circle_major_axis (const cairo_matrix_t *matrix, - double radius) cairo_pure; - -cairo_private cairo_bool_t -_cairo_matrix_is_pixman_translation (const cairo_matrix_t *matrix, - cairo_filter_t filter, - int *out_x_offset, - int *out_y_offset); - -cairo_private cairo_status_t -_cairo_matrix_to_pixman_matrix_offset (const cairo_matrix_t *matrix, - cairo_filter_t filter, - double xc, - double yc, - pixman_transform_t *out_transform, - int *out_x_offset, - int *out_y_offset); - -cairo_private cairo_status_t -_cairo_bentley_ottmann_tessellate_rectilinear_polygon (cairo_traps_t *traps, - const cairo_polygon_t *polygon, - cairo_fill_rule_t fill_rule); - -cairo_private cairo_status_t -_cairo_bentley_ottmann_tessellate_polygon (cairo_traps_t *traps, - const cairo_polygon_t *polygon, - cairo_fill_rule_t fill_rule); - -cairo_private cairo_status_t -_cairo_bentley_ottmann_tessellate_traps (cairo_traps_t *traps, - cairo_fill_rule_t fill_rule); - -cairo_private cairo_status_t -_cairo_bentley_ottmann_tessellate_rectangular_traps (cairo_traps_t *traps, - cairo_fill_rule_t fill_rule); - -cairo_private cairo_status_t -_cairo_bentley_ottmann_tessellate_boxes (const cairo_boxes_t *in, - cairo_fill_rule_t fill_rule, - cairo_boxes_t *out); - -cairo_private cairo_status_t -_cairo_bentley_ottmann_tessellate_rectilinear_traps (cairo_traps_t *traps, - cairo_fill_rule_t fill_rule); - -cairo_private cairo_status_t -_cairo_bentley_ottmann_tessellate_rectilinear_polygon_to_boxes (const cairo_polygon_t *polygon, - cairo_fill_rule_t fill_rule, - cairo_boxes_t *boxes); - -cairo_private void -_cairo_trapezoid_array_translate_and_scale (cairo_trapezoid_t *offset_traps, - cairo_trapezoid_t *src_traps, - int num_traps, - double tx, double ty, - double sx, double sy); - -#if CAIRO_HAS_DRM_SURFACE - -cairo_private void -_cairo_drm_device_reset_static_data (void); - -#endif - -cairo_private void -_cairo_clip_reset_static_data (void); - -cairo_private void -_cairo_pattern_reset_static_data (void); - -/* cairo-unicode.c */ - -cairo_private int -_cairo_utf8_get_char_validated (const char *p, - uint32_t *unicode); - -cairo_private cairo_status_t -_cairo_utf8_to_ucs4 (const char *str, - int len, - uint32_t **result, - int *items_written); - -cairo_private int -_cairo_ucs4_to_utf8 (uint32_t unicode, - char *utf8); - -#if CAIRO_HAS_WIN32_FONT || CAIRO_HAS_QUARTZ_FONT || CAIRO_HAS_PDF_OPERATORS -# define CAIRO_HAS_UTF8_TO_UTF16 1 -#endif -#if CAIRO_HAS_UTF8_TO_UTF16 -cairo_private cairo_status_t -_cairo_utf8_to_utf16 (const char *str, - int len, - uint16_t **result, - int *items_written); -#endif - -cairo_private void -_cairo_matrix_multiply (cairo_matrix_t *r, - const cairo_matrix_t *a, - const cairo_matrix_t *b); - -/* cairo-observer.c */ - -cairo_private void -_cairo_observers_notify (cairo_list_t *observers, void *arg); - -/* Avoid unnecessary PLT entries. */ -slim_hidden_proto (cairo_clip_preserve); -slim_hidden_proto (cairo_close_path); -slim_hidden_proto (cairo_create); -slim_hidden_proto (cairo_curve_to); -slim_hidden_proto (cairo_destroy); -slim_hidden_proto (cairo_fill_preserve); -slim_hidden_proto (cairo_font_face_destroy); -slim_hidden_proto (cairo_font_face_get_user_data); -slim_hidden_proto_no_warn (cairo_font_face_reference); -slim_hidden_proto (cairo_font_face_set_user_data); -slim_hidden_proto (cairo_font_options_equal); -slim_hidden_proto (cairo_font_options_hash); -slim_hidden_proto (cairo_font_options_merge); -slim_hidden_proto (cairo_font_options_set_antialias); -slim_hidden_proto (cairo_font_options_set_hint_metrics); -slim_hidden_proto (cairo_font_options_set_hint_style); -slim_hidden_proto (cairo_font_options_set_subpixel_order); -slim_hidden_proto (cairo_font_options_status); -slim_hidden_proto (cairo_format_stride_for_width); -slim_hidden_proto (cairo_get_current_point); -slim_hidden_proto (cairo_get_line_width); -slim_hidden_proto (cairo_get_matrix); -slim_hidden_proto (cairo_get_scaled_font); -slim_hidden_proto (cairo_get_target); -slim_hidden_proto (cairo_get_tolerance); -slim_hidden_proto (cairo_glyph_allocate); -slim_hidden_proto (cairo_glyph_free); -slim_hidden_proto (cairo_image_surface_create); -slim_hidden_proto (cairo_image_surface_create_for_data); -slim_hidden_proto (cairo_image_surface_get_data); -slim_hidden_proto (cairo_image_surface_get_format); -slim_hidden_proto (cairo_image_surface_get_height); -slim_hidden_proto (cairo_image_surface_get_stride); -slim_hidden_proto (cairo_image_surface_get_width); -slim_hidden_proto (cairo_line_to); -slim_hidden_proto (cairo_mask); -slim_hidden_proto (cairo_matrix_init); -slim_hidden_proto (cairo_matrix_init_identity); -slim_hidden_proto (cairo_matrix_init_rotate); -slim_hidden_proto (cairo_matrix_init_scale); -slim_hidden_proto (cairo_matrix_init_translate); -slim_hidden_proto (cairo_matrix_invert); -slim_hidden_proto (cairo_matrix_multiply); -slim_hidden_proto (cairo_matrix_scale); -slim_hidden_proto (cairo_matrix_transform_distance); -slim_hidden_proto (cairo_matrix_transform_point); -slim_hidden_proto (cairo_matrix_translate); -slim_hidden_proto (cairo_move_to); -slim_hidden_proto (cairo_new_path); -slim_hidden_proto (cairo_paint); -slim_hidden_proto (cairo_pattern_add_color_stop_rgba); -slim_hidden_proto (cairo_pattern_create_for_surface); -slim_hidden_proto (cairo_pattern_create_rgb); -slim_hidden_proto (cairo_pattern_create_rgba); -slim_hidden_proto (cairo_pattern_destroy); -slim_hidden_proto (cairo_pattern_get_extend); -slim_hidden_proto (cairo_mesh_pattern_curve_to); -slim_hidden_proto (cairo_mesh_pattern_get_control_point); -slim_hidden_proto (cairo_mesh_pattern_get_corner_color_rgba); -slim_hidden_proto (cairo_mesh_pattern_get_patch_count); -slim_hidden_proto (cairo_mesh_pattern_get_path); -slim_hidden_proto (cairo_mesh_pattern_line_to); -slim_hidden_proto (cairo_mesh_pattern_move_to); -slim_hidden_proto (cairo_mesh_pattern_set_corner_color_rgba); -slim_hidden_proto_no_warn (cairo_pattern_reference); -slim_hidden_proto (cairo_pattern_set_matrix); -slim_hidden_proto (cairo_pop_group); -slim_hidden_proto (cairo_push_group_with_content); -slim_hidden_proto_no_warn (cairo_path_destroy); -slim_hidden_proto (cairo_recording_surface_create); -slim_hidden_proto (cairo_rel_line_to); -slim_hidden_proto (cairo_restore); -slim_hidden_proto (cairo_save); -slim_hidden_proto (cairo_scale); -slim_hidden_proto (cairo_scaled_font_create); -slim_hidden_proto (cairo_scaled_font_destroy); -slim_hidden_proto (cairo_scaled_font_extents); -slim_hidden_proto (cairo_scaled_font_get_ctm); -slim_hidden_proto (cairo_scaled_font_get_font_face); -slim_hidden_proto (cairo_scaled_font_get_font_matrix); -slim_hidden_proto (cairo_scaled_font_get_font_options); -slim_hidden_proto (cairo_scaled_font_glyph_extents); -slim_hidden_proto_no_warn (cairo_scaled_font_reference); -slim_hidden_proto (cairo_scaled_font_status); -slim_hidden_proto (cairo_scaled_font_get_user_data); -slim_hidden_proto (cairo_scaled_font_set_user_data); -slim_hidden_proto (cairo_scaled_font_text_to_glyphs); -slim_hidden_proto (cairo_set_font_matrix); -slim_hidden_proto (cairo_set_font_options); -slim_hidden_proto (cairo_set_font_size); -slim_hidden_proto (cairo_set_line_cap); -slim_hidden_proto (cairo_set_line_join); -slim_hidden_proto (cairo_set_line_width); -slim_hidden_proto (cairo_set_matrix); -slim_hidden_proto (cairo_set_operator); -slim_hidden_proto (cairo_set_source); -slim_hidden_proto (cairo_set_source_rgb); -slim_hidden_proto (cairo_set_source_surface); -slim_hidden_proto (cairo_set_tolerance); -slim_hidden_proto (cairo_status); -slim_hidden_proto (cairo_stroke); -slim_hidden_proto (cairo_stroke_preserve); -slim_hidden_proto (cairo_surface_copy_page); -slim_hidden_proto (cairo_surface_create_similar_image); -slim_hidden_proto (cairo_surface_destroy); -slim_hidden_proto (cairo_surface_finish); -slim_hidden_proto (cairo_surface_flush); -slim_hidden_proto (cairo_surface_get_device_offset); -slim_hidden_proto (cairo_surface_get_device_scale); -slim_hidden_proto (cairo_surface_get_font_options); -slim_hidden_proto (cairo_surface_get_mime_data); -slim_hidden_proto (cairo_surface_has_show_text_glyphs); -slim_hidden_proto (cairo_surface_mark_dirty); -slim_hidden_proto (cairo_surface_mark_dirty_rectangle); -slim_hidden_proto_no_warn (cairo_surface_reference); -slim_hidden_proto (cairo_surface_set_device_offset); -slim_hidden_proto (cairo_surface_set_device_scale); -slim_hidden_proto (cairo_surface_set_fallback_resolution); -slim_hidden_proto (cairo_surface_set_mime_data); -slim_hidden_proto (cairo_surface_show_page); -slim_hidden_proto (cairo_surface_status); -slim_hidden_proto (cairo_surface_supports_mime_type); -slim_hidden_proto (cairo_text_cluster_allocate); -slim_hidden_proto (cairo_text_cluster_free); -slim_hidden_proto (cairo_toy_font_face_create); -slim_hidden_proto (cairo_toy_font_face_get_slant); -slim_hidden_proto (cairo_toy_font_face_get_weight); -slim_hidden_proto (cairo_translate); -slim_hidden_proto (cairo_transform); -slim_hidden_proto (cairo_user_font_face_create); -slim_hidden_proto (cairo_user_font_face_set_init_func); -slim_hidden_proto (cairo_user_font_face_set_render_glyph_func); -slim_hidden_proto (cairo_user_font_face_set_unicode_to_glyph_func); -slim_hidden_proto (cairo_device_to_user); -slim_hidden_proto (cairo_user_to_device); -slim_hidden_proto (cairo_user_to_device_distance); -slim_hidden_proto (cairo_version_string); -slim_hidden_proto (cairo_region_create); -slim_hidden_proto (cairo_region_create_rectangle); -slim_hidden_proto (cairo_region_create_rectangles); -slim_hidden_proto (cairo_region_copy); -slim_hidden_proto (cairo_region_reference); -slim_hidden_proto (cairo_region_destroy); -slim_hidden_proto (cairo_region_equal); -slim_hidden_proto (cairo_region_status); -slim_hidden_proto (cairo_region_get_extents); -slim_hidden_proto (cairo_region_num_rectangles); -slim_hidden_proto (cairo_region_get_rectangle); -slim_hidden_proto (cairo_region_is_empty); -slim_hidden_proto (cairo_region_contains_rectangle); -slim_hidden_proto (cairo_region_contains_point); -slim_hidden_proto (cairo_region_translate); -slim_hidden_proto (cairo_region_subtract); -slim_hidden_proto (cairo_region_subtract_rectangle); -slim_hidden_proto (cairo_region_intersect); -slim_hidden_proto (cairo_region_intersect_rectangle); -slim_hidden_proto (cairo_region_union); -slim_hidden_proto (cairo_region_union_rectangle); -slim_hidden_proto (cairo_region_xor); -slim_hidden_proto (cairo_region_xor_rectangle); - -#if CAIRO_HAS_PNG_FUNCTIONS - -slim_hidden_proto (cairo_surface_write_to_png_stream); - -#endif - -CAIRO_END_DECLS - -#include "cairo-mutex-private.h" -#include "cairo-fixed-private.h" -#include "cairo-wideint-private.h" -#include "cairo-malloc-private.h" -#include "cairo-hash-private.h" - -#if HAVE_VALGRIND -#include <memcheck.h> - -#define VG(x) x - -cairo_private void -_cairo_debug_check_image_surface_is_defined (const cairo_surface_t *surface); - -#else - -#define VG(x) -#define _cairo_debug_check_image_surface_is_defined(X) - -#endif - -cairo_private void -_cairo_debug_print_path (FILE *stream, cairo_path_fixed_t *path); - -cairo_private void -_cairo_debug_print_polygon (FILE *stream, cairo_polygon_t *polygon); - -cairo_private void -_cairo_debug_print_traps (FILE *file, const cairo_traps_t *traps); - -cairo_private void -_cairo_debug_print_clip (FILE *stream, const cairo_clip_t *clip); - -#if 0 -#define TRACE(x) fprintf (stderr, "%s: ", __FILE__), fprintf x -#define TRACE_(x) x -#else -#define TRACE(x) -#define TRACE_(x) -#endif - -#endif diff --git a/source/libs/cairo/cairo-src/src/check-def.sh b/source/libs/cairo/cairo-src/src/check-def.sh deleted file mode 100755 index beefb46a3336d62006856bbe59119b606f0a72fc..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/check-def.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/sh - -LC_ALL=C -export LC_ALL - -if which nm 2>/dev/null >/dev/null; then - : -else - echo "'nm' not found; skipping test" - exit 0 -fi - -test -z "$srcdir" && srcdir=. -test -z "$MAKE" && MAKE=make -stat=0 - -$MAKE check-has-hidden-symbols.i > /dev/null || exit 1 -if tail -1 check-has-hidden-symbols.i | grep CAIRO_HAS_HIDDEN_SYMBOLS >/dev/null; then - echo "Compiler doesn't support symbol visibility; skipping test" - exit 0 -fi - -if [ "`uname -s`" = "Linux" ]; then - get_cairo_syms='( objdump -t "$so" | grep "^[^ ]* [^l.*]*[.]"; objdump -t "$so" | grep "[.]hidden.*\\<cairo"; ) | sed "s/.* //"' -else - get_cairo_syms='nm "$so" | grep " [BCDGINRSTVW] " | cut -d" " -f3' -fi - -defs="cairo.def" -$MAKE $defs > /dev/null -for def in $defs; do - lib=`echo "$def" | sed 's/[.]def$//'` - lib=`echo "$lib" | sed 's@.*/@@'` - so=.libs/lib${lib}.so - - test -f "$so" || continue - - echo Checking that $so has the same symbol list as $def - - { - echo EXPORTS - eval $get_cairo_syms | c++filt --no-params | grep -v '^_cairo_test_\|^_fini\|^_init\|^_save[fg]pr\|^_rest[fg]pr\|^_Z\|^__gnu\|^__bss\|^_edata\|^_end' | sort -u - # cheat: copy the last line from the def file! - tail -n1 "$def" - } | diff "$def" - >&2 || stat=1 -done - -exit $stat diff --git a/source/libs/cairo/cairo-src/src/check-doc-syntax.awk b/source/libs/cairo/cairo-src/src/check-doc-syntax.awk deleted file mode 100644 index 1fa8b8d223240ba95158c696d2668a6fb8a6ba95..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/check-doc-syntax.awk +++ /dev/null @@ -1,106 +0,0 @@ -BEGIN { - name_found = 1 - SECTION_DOC = 0 - PUBLIC_DOC = 1 - PRIVATE_DOC = 2 -} - -function log_msg(severity, msg) -{ - printf "%s (%d): %s: %s %s\n", FILENAME, FNR, severity, doc_name, msg -} - -function log_error(msg) -{ - log_msg("ERROR", msg) -} - -function log_warning(msg) -{ - log_msg("WARNING", msg) -} - -/^\/\*\*$/ { - in_doc = 1 - doc_line = 0 -} - -/^(\/\*\*$| \*[ \t]| \*$| \*\*\/$)/ { - valid_doc = 1 -} - -in_doc { - if (!valid_doc) - log_error("bad line: '" $0 "'") - valid_doc = 0 - - doc_line++ - if (doc_line == 2) { - # new doc name. Did we find the previous one? - # (macros are not expected to be found in the same place as - # their documentation) - if (!name_found && doc_name !~ /CAIRO_/) - log_warning("not found") - doc_name = $2 - if (doc_name ~ /^SECTION:.*$/) { - doc_type = SECTION_DOC - name_found = 1 - } else if (tolower(doc_name) ~ /^cairo_[a-z0-9_]*:$/) { - doc_type = PUBLIC_DOC - name_found = 0 - real_name = substr(doc_name, 1, length(doc_name) - 1) - } else if (tolower(doc_name) ~ /^_[a-z0-9_]*:$/) { - doc_type = PRIVATE_DOC - name_found = 0 - real_name = substr(doc_name, 1, length(doc_name) - 1) - } else { - log_error("invalid doc id (should be 'cairo_...:')") - name_found = 1 - } - } -} - -!in_doc { - regex = "(^|[ \\t\\*])" real_name "([ ;()]|$)" - if ($0 ~ regex) - name_found = 1 -} - -/^ \* Since: ([0-9]*.[0-9]*|TBD)$/ { - if (doc_has_since != 0) { - log_error("Duplicate 'Since' field") - } - doc_has_since = doc_line -} - -/^ \*\*\// { - if (doc_type == PUBLIC_DOC) { - if (!doc_has_since) { - # private types can start with cairo_ - if (doc_name ~ /^cairo_.*_t:$/) - log_warning("missing 'Since' field (is it a private type?)") - else - log_error("missing 'Since' field") - } else if (doc_has_since != doc_line - 1) - log_warning("misplaced 'Since' field (should be right before the end of the comment)") - } else { - if (doc_has_since) - log_warning("'Since' field in non-public element") - } - - in_doc = 0 - doc_has_since = 0 - doc_type = 0 -} - -/\*\// { - if (in_doc) { - in_doc = 0 - log_error("documentation comment not closed with **/") - } -} - -END { - if (!name_found) - log_warning("not found") -} diff --git a/source/libs/cairo/cairo-src/src/check-doc-syntax.sh b/source/libs/cairo/cairo-src/src/check-doc-syntax.sh deleted file mode 100755 index 762a48429b0202c6c387e86bbf32090b8a2488e1..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/check-doc-syntax.sh +++ /dev/null @@ -1,82 +0,0 @@ -#!/bin/sh - -LC_ALL=C -export LC_ALL - -if grep --version 2>/dev/null | grep GNU >/dev/null; then - : -else - echo "GNU grep not found; skipping test" - exit 0 -fi - -test -z "$srcdir" && srcdir=. -stat=0 - -echo Checking documentation for incorrect syntax - -cd "$srcdir" - -if test "x$SGML_DOCS" = x; then - FILES=$all_cairo_files - if test "x$FILES" = x; then - FILES=`find . -name 'cairo*.h' -or -name 'cairo*.c' -or -name 'cairo*.cpp'` - fi -fi - -enum_regexp="\([^%@']\|^\)\<\(FALSE\|TRUE\|NULL\|CAIRO_[0-9A-Z_]*\)\($\|[^(A-Za-z0-9_]\)" -if test "x$SGML_DOCS" = x; then - enum_regexp='^[^:]*:[/ ][*]\(\|[ \t].*\)'$enum_regexp\($\|[^:]\) -fi -if echo $FILES | xargs grep . /dev/null | sed -e '/<programlisting>/,/<\/programlisting>/d' | grep "$enum_regexp" | grep -v '#####'; then - stat=1 - echo Error: some macros in the docs are not prefixed by percent sign. - echo Fix this by searching for the following regexp in the above files: - echo " '$enum_regexp'" -fi >&2 - -type_regexp="\( .*[^#']\| \|^\)\<cairo[0-9a-z_]*_t\>\($\|[^:]$\|[^:].\)" -if test "x$SGML_DOCS" = x; then - type_regexp='^[^:]*:[/ ][*]'$type_regexp -else - type_regexp='\(.'$type_regexp'\)\|\('$type_regexp'.\)' -fi - -if echo $FILES | xargs grep . /dev/null | sed -e '/<programlisting>/,/<\/programlisting>/d' | grep -v "@Title" | grep "$type_regexp" | grep -v '#####'; then - stat=1 - echo Error: some type names in the docs are not prefixed by hash sign, - echo neither are the only token in the doc line followed by colon. - echo Fix this by searching for the following regexp in the above files: - echo " '$type_regexp'" -fi >&2 - -func_regexp="\([^#']\|^\)\<\(cairo_[][<>/0-9a-z_]*\>[^][<>(]\)" -if test "x$SGML_DOCS" = x; then - func_regexp='^[^:]*:[/ ][*]\(\|[ \t].*\)'$func_regexp -fi - -# We need to filter out gtk-doc markup errors for program listings. -if echo $FILES | xargs grep . /dev/null | sed -e '/<programlisting>/,/<\/programlisting>/d' | grep "$func_regexp" | grep -v '^[^:]*: [*] [a-z_0-9]*:$' | grep -v '#####'; then - stat=1 - echo Error: some function names in the docs are not followed by parentheses. - echo Fix this by searching for the following regexp in the above files: - echo " '$func_regexp'" -fi >&2 - -note_regexp='\<NOTE\>' -if echo $FILES | xargs grep "$note_regexp" /dev/null; then - stat=1 - echo Error: some source files contain the string 'NOTE'. - echo Be civil and replace it by 'Note' please. -fi >&2 - -# Only run the syntax checker on the source files (not doc/) -if test -e ./check-doc-syntax.awk; then - if echo $FILES | xargs awk -f ./check-doc-syntax.awk ; then - : - else - stat=1 - fi >&2 -fi - -exit $stat diff --git a/source/libs/cairo/cairo-src/src/check-has-hidden-symbols.c b/source/libs/cairo/cairo-src/src/check-has-hidden-symbols.c deleted file mode 100644 index 12041277692aba7342326a15206e9a8e87c3d3d3..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/check-has-hidden-symbols.c +++ /dev/null @@ -1,3 +0,0 @@ -#include "cairoint.h" - -CAIRO_HAS_HIDDEN_SYMBOLS diff --git a/source/libs/cairo/cairo-src/src/check-headers.sh b/source/libs/cairo/cairo-src/src/check-headers.sh deleted file mode 100755 index 61232954baecf989d23737eed4838f042a0ebac9..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/check-headers.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh - -LC_ALL=C -export LC_ALL - -test -z "$srcdir" && srcdir=. -stat=0 - -echo Checking public headers for missing cairo_public decorators - -cd "$srcdir" -FILES=$all_cairo_headers -if test "x$FILES" = x; then - FILES=`find . -name 'cairo*.h' ! -name '*-private.h' ! -name 'cairoint.h'` -fi - -grep -B 1 '^cairo_.*[ ]\+(' /dev/null $FILES | -awk ' -/^--$/ { context=""; public=0; next; } -/:cairo_.*[ ]+\(/ { if (!public) {print context; print; print "--";} next; } -/-cairo_public.*[ ]/ {public=1;} -{ context=$0; } -' | -sed 's/[.]h-/.h:/' | -grep . >&2 && stat=1 - -exit $stat diff --git a/source/libs/cairo/cairo-src/src/check-link.c b/source/libs/cairo/cairo-src/src/check-link.c deleted file mode 100644 index 66ca1b2413ca619511b6075b73234ef44fd42e3b..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/check-link.c +++ /dev/null @@ -1,24 +0,0 @@ -#define CAIRO_VERSION_H 1 - -#include <cairo.h> - -/* get the "real" version info instead of dummy cairo-version.h */ -#undef CAIRO_VERSION_H -#include "../cairo-version.h" - -#include <stdio.h> - -int -main (void) -{ - printf ("Check linking to the just built cairo library\n"); - if (cairo_version () == CAIRO_VERSION) { - return 0; - } else { - fprintf (stderr, - "Error: linked to cairo version %s instead of %s\n", - cairo_version_string (), - CAIRO_VERSION_STRING); - return 1; - } -} diff --git a/source/libs/cairo/cairo-src/src/check-plt.sh b/source/libs/cairo/cairo-src/src/check-plt.sh deleted file mode 100755 index 5a9dae1269dafd7489a6507a9048e3f200edfc20..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/check-plt.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh - -LC_ALL=C -export LC_ALL - -if which readelf 2>/dev/null >/dev/null; then - : -else - echo "'readelf' not found; skipping test" - exit 0 -fi - -test -z "$srcdir" && srcdir=. -test -z "$MAKE" && MAKE=make -stat=0 - -$MAKE check-has-hidden-symbols.i > /dev/null || exit 1 -if tail -1 check-has-hidden-symbols.i | grep CAIRO_HAS_HIDDEN_SYMBOLS >/dev/null; then - echo "Compiler doesn't support symbol visibility; skipping test" - exit 0 -fi - -for so in .libs/lib*.so; do - echo Checking "$so" for local PLT entries - readelf -W -r "$so" | grep 'JU\?MP_SLO' | grep 'cairo' >&2 && stat=1 -done - -exit $stat diff --git a/source/libs/cairo/cairo-src/src/check-preprocessor-syntax.sh b/source/libs/cairo/cairo-src/src/check-preprocessor-syntax.sh deleted file mode 100755 index b718f604ee72ad608e8ac4117016abacaeb2dcbb..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/check-preprocessor-syntax.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/sh - -LC_ALL=C -export LC_ALL - -test -z "$srcdir" && srcdir=. -cd "$srcdir" -stat=0 - - -HEADERS=$all_cairo_headers -test "x$HEADERS" = x && HEADERS=`find . -name 'cairo*.h' ! -name 'cairo*-private.h' ! -name 'cairo*-inline.h' ! -name 'cairoint.h'` - -PRIVATE=$all_cairo_private -test "x$PRIVATE" = x && PRIVATE=`find . -name 'cairo*-private.h' -or -name 'cairo*-inline.h' -or -name 'cairoint.h'` - -SOURCES=$all_cairo_sources -test "x$SOURCES" = x && SOURCES=`find . -name 'cairo*.c' -or -name 'cairo*.cpp'` - -ALL="/dev/null $HEADERS $PRIVATE $SOURCES" - -echo 'Checking that public header files #include "cairo.h" first (or none)' - -for x in $HEADERS; do - grep '#.*\<include\>' "$x" /dev/null | head -n 1 -done | -grep -v '"cairo[.]h"' | -grep -v 'cairo[.]h:' | -grep . >&2 && stat=1 - - -echo 'Checking that private header files #include "some cairo header" first (or none)' - -for x in $PRIVATE; do - grep '#.*\<include\>' "$x" /dev/null | head -n 1 -done | -grep -v '"cairo.*[.]h"' | -grep -v 'cairoint[.]h:' | -grep . >&2 && stat=1 - - -echo 'Checking that source files #include "cairoint.h" first (or none)' - -for x in $SOURCES; do - grep '#.*\<include\>' "$x" /dev/null | head -n 1 -done | -grep -v '"cairoint[.]h"' | -grep . >&2 && stat=1 - - -echo 'Checking that there is no #include <cairo.*.h>' -grep '#.*\<include\>.*<.*cairo' $ALL >&2 && stat=1 - - -echo 'Checking that feature conditionals are used with #if only (not #ifdef)' -grep '#ifdef CAIRO_HAS_' $ALL && stat=1 -grep '#if.*defined[ ]*(CAIRO_HAS_' $ALL && stat=1 - -exit $stat diff --git a/source/libs/cairo/cairo-src/src/test-base-compositor-surface.c b/source/libs/cairo/cairo-src/src/test-base-compositor-surface.c deleted file mode 100644 index ff84b10aff71e00c49ae6743b463a30874ed05ef..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/test-base-compositor-surface.c +++ /dev/null @@ -1,824 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2002 University of Southern California - * Copyright © 2005 Red Hat, Inc. - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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> - * Joonas Pihlaja <jpihlaja@cc.helsinki.fi> - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "test-compositor-surface-private.h" - -#include "cairo-clip-private.h" -#include "cairo-composite-rectangles-private.h" -#include "cairo-compositor-private.h" -#include "cairo-error-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-region-private.h" -#include "cairo-traps-private.h" - -/* The intention is that this is a surface that just works, and most - * important of all does not try to be clever! - */ - -typedef cairo_int_status_t -(*draw_func_t) (cairo_image_surface_t *dst, - void *closure, - cairo_operator_t op, - const cairo_pattern_t *pattern, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents); - -static pixman_op_t -_pixman_operator (cairo_operator_t op) -{ - switch ((int) op) { - case CAIRO_OPERATOR_CLEAR: - return PIXMAN_OP_CLEAR; - - case CAIRO_OPERATOR_SOURCE: - return PIXMAN_OP_SRC; - case CAIRO_OPERATOR_OVER: - return PIXMAN_OP_OVER; - case CAIRO_OPERATOR_IN: - return PIXMAN_OP_IN; - case CAIRO_OPERATOR_OUT: - return PIXMAN_OP_OUT; - case CAIRO_OPERATOR_ATOP: - return PIXMAN_OP_ATOP; - - case CAIRO_OPERATOR_DEST: - return PIXMAN_OP_DST; - case CAIRO_OPERATOR_DEST_OVER: - return PIXMAN_OP_OVER_REVERSE; - case CAIRO_OPERATOR_DEST_IN: - return PIXMAN_OP_IN_REVERSE; - case CAIRO_OPERATOR_DEST_OUT: - return PIXMAN_OP_OUT_REVERSE; - case CAIRO_OPERATOR_DEST_ATOP: - return PIXMAN_OP_ATOP_REVERSE; - - case CAIRO_OPERATOR_XOR: - return PIXMAN_OP_XOR; - case CAIRO_OPERATOR_ADD: - return PIXMAN_OP_ADD; - case CAIRO_OPERATOR_SATURATE: - return PIXMAN_OP_SATURATE; - - case CAIRO_OPERATOR_MULTIPLY: - return PIXMAN_OP_MULTIPLY; - case CAIRO_OPERATOR_SCREEN: - return PIXMAN_OP_SCREEN; - case CAIRO_OPERATOR_OVERLAY: - return PIXMAN_OP_OVERLAY; - case CAIRO_OPERATOR_DARKEN: - return PIXMAN_OP_DARKEN; - case CAIRO_OPERATOR_LIGHTEN: - return PIXMAN_OP_LIGHTEN; - case CAIRO_OPERATOR_COLOR_DODGE: - return PIXMAN_OP_COLOR_DODGE; - case CAIRO_OPERATOR_COLOR_BURN: - return PIXMAN_OP_COLOR_BURN; - case CAIRO_OPERATOR_HARD_LIGHT: - return PIXMAN_OP_HARD_LIGHT; - case CAIRO_OPERATOR_SOFT_LIGHT: - return PIXMAN_OP_SOFT_LIGHT; - case CAIRO_OPERATOR_DIFFERENCE: - return PIXMAN_OP_DIFFERENCE; - case CAIRO_OPERATOR_EXCLUSION: - return PIXMAN_OP_EXCLUSION; - case CAIRO_OPERATOR_HSL_HUE: - return PIXMAN_OP_HSL_HUE; - case CAIRO_OPERATOR_HSL_SATURATION: - return PIXMAN_OP_HSL_SATURATION; - case CAIRO_OPERATOR_HSL_COLOR: - return PIXMAN_OP_HSL_COLOR; - case CAIRO_OPERATOR_HSL_LUMINOSITY: - return PIXMAN_OP_HSL_LUMINOSITY; - - default: - ASSERT_NOT_REACHED; - return PIXMAN_OP_OVER; - } -} - -static cairo_image_surface_t * -create_composite_mask (cairo_image_surface_t *dst, - void *draw_closure, - draw_func_t draw_func, - const cairo_composite_rectangles_t *extents) -{ - cairo_image_surface_t *surface; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - surface = (cairo_image_surface_t *) - _cairo_image_surface_create_with_pixman_format (NULL, PIXMAN_a8, - extents->bounded.width, - extents->bounded.height, - 0); - if (unlikely (surface->base.status)) - return surface; - - status = draw_func (surface, draw_closure, - CAIRO_OPERATOR_ADD, &_cairo_pattern_white.base, - extents->bounded.x, extents->bounded.y, - &extents->bounded); - if (unlikely (status)) - goto error; - - status = _cairo_clip_combine_with_surface (extents->clip, - &surface->base, - extents->bounded.x, - extents->bounded.y); - if (unlikely (status)) - goto error; - - return surface; - -error: - cairo_surface_destroy (&surface->base); - return (cairo_image_surface_t *)_cairo_surface_create_in_error (status); -} - -/* Handles compositing with a clip surface when the operator allows - * us to combine the clip with the mask - */ -static cairo_status_t -clip_and_composite_with_mask (const cairo_composite_rectangles_t*extents, - draw_func_t draw_func, - void *draw_closure) -{ - cairo_image_surface_t *dst = (cairo_image_surface_t *)extents->surface; - cairo_image_surface_t *mask; - pixman_image_t *src; - cairo_status_t status = CAIRO_STATUS_SUCCESS; - int src_x, src_y; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - mask = create_composite_mask (dst, draw_closure, draw_func, extents); - if (unlikely (mask->base.status)) - return mask->base.status; - - src = _pixman_image_for_pattern (dst, - &extents->source_pattern.base, FALSE, - &extents->bounded, - &extents->source_sample_area, - &src_x, &src_y); - if (unlikely (src == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto error; - } - - pixman_image_composite32 (_pixman_operator (extents->op), - src, mask->pixman_image, dst->pixman_image, - extents->bounded.x + src_x, - extents->bounded.y + src_y, - 0, 0, - extents->bounded.x, extents->bounded.y, - extents->bounded.width, extents->bounded.height); - - pixman_image_unref (src); -error: - cairo_surface_destroy (&mask->base); - return status; -} - -/* Handles compositing with a clip surface when we have to do the operation - * in two pieces and combine them together. - */ -static cairo_status_t -clip_and_composite_combine (const cairo_composite_rectangles_t*extents, - draw_func_t draw_func, - void *draw_closure) -{ - cairo_image_surface_t *dst = (cairo_image_surface_t *)extents->surface; - cairo_image_surface_t *tmp, *clip; - int clip_x, clip_y; - cairo_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - tmp = (cairo_image_surface_t *) - _cairo_image_surface_create_with_pixman_format (NULL, - dst->pixman_format, - extents->bounded.width, - extents->bounded.height, - 0); - if (unlikely (tmp->base.status)) - return tmp->base.status; - - pixman_image_composite32 (PIXMAN_OP_SRC, - dst->pixman_image, NULL, tmp->pixman_image, - extents->bounded.x, extents->bounded.y, - 0, 0, - 0, 0, - extents->bounded.width, extents->bounded.height); - - status = draw_func (tmp, draw_closure, - extents->op, &extents->source_pattern.base, - extents->bounded.x, extents->bounded.y, - &extents->bounded); - if (unlikely (status)) - goto error; - - clip = (cairo_image_surface_t *) - _cairo_clip_get_surface (extents->clip, &dst->base, &clip_x, &clip_y); - if (unlikely (clip->base.status)) - goto error; - - pixman_image_composite32 (PIXMAN_OP_OUT_REVERSE, - clip->pixman_image, NULL, dst->pixman_image, - extents->bounded.x - clip_x, extents->bounded.y - clip_y, - 0, 0, - extents->bounded.x, extents->bounded.y, - extents->bounded.width, extents->bounded.height); - pixman_image_composite32 (PIXMAN_OP_ADD, - tmp->pixman_image, clip->pixman_image, dst->pixman_image, - 0, 0, - extents->bounded.x - clip_x, extents->bounded.y - clip_y, - extents->bounded.x, extents->bounded.y, - extents->bounded.width, extents->bounded.height); - - cairo_surface_destroy (&clip->base); - - error: - cairo_surface_destroy (&tmp->base); - - return status; -} - -/* Handles compositing for %CAIRO_OPERATOR_SOURCE, which is special; it's - * defined as (src IN mask IN clip) ADD (dst OUT (mask IN clip)) - */ -static cairo_status_t -clip_and_composite_source (const cairo_composite_rectangles_t *extents, - draw_func_t draw_func, - void *draw_closure) -{ - cairo_image_surface_t *dst = (cairo_image_surface_t *)extents->surface; - cairo_image_surface_t *mask; - pixman_image_t *src; - int src_x, src_y; - cairo_status_t status = CAIRO_STATUS_SUCCESS; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - mask = create_composite_mask (dst, draw_closure, draw_func, extents); - if (unlikely (mask->base.status)) - return mask->base.status; - - pixman_image_composite32 (PIXMAN_OP_OUT_REVERSE, - mask->pixman_image, NULL, dst->pixman_image, - 0, 0, - 0, 0, - extents->bounded.x, extents->bounded.y, - extents->bounded.width, extents->bounded.height); - - src = _pixman_image_for_pattern (dst, - &extents->source_pattern.base, FALSE, - &extents->bounded, - &extents->source_sample_area, - &src_x, &src_y); - if (unlikely (src == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto error; - } - - pixman_image_composite32 (PIXMAN_OP_ADD, - src, mask->pixman_image, dst->pixman_image, - extents->bounded.x + src_x, extents->bounded.y + src_y, - 0, 0, - extents->bounded.x, extents->bounded.y, - extents->bounded.width, extents->bounded.height); - - pixman_image_unref (src); - -error: - cairo_surface_destroy (&mask->base); - return status; -} - -static cairo_status_t -fixup_unbounded (const cairo_composite_rectangles_t *extents) -{ - cairo_image_surface_t *dst = (cairo_image_surface_t *)extents->surface; - pixman_image_t *mask; - int mask_x, mask_y; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - if (! _cairo_clip_is_region (extents->clip)) { - cairo_image_surface_t *clip; - - clip = (cairo_image_surface_t *) - _cairo_clip_get_surface (extents->clip, &dst->base, - &mask_x, &mask_y); - if (unlikely (clip->base.status)) - return clip->base.status; - - mask = pixman_image_ref (clip->pixman_image); - cairo_surface_destroy (&clip->base); - } else { - mask_x = mask_y = 0; - mask = _pixman_image_for_color (CAIRO_COLOR_WHITE); - if (unlikely (mask == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - /* top */ - if (extents->bounded.y != extents->unbounded.y) { - int x = extents->unbounded.x; - int y = extents->unbounded.y; - int width = extents->unbounded.width; - int height = extents->bounded.y - y; - - pixman_image_composite32 (PIXMAN_OP_OUT_REVERSE, - mask, NULL, dst->pixman_image, - x - mask_x, y - mask_y, - 0, 0, - x, y, - width, height); - } - - /* left */ - if (extents->bounded.x != extents->unbounded.x) { - int x = extents->unbounded.x; - int y = extents->bounded.y; - int width = extents->bounded.x - x; - int height = extents->bounded.height; - - pixman_image_composite32 (PIXMAN_OP_OUT_REVERSE, - mask, NULL, dst->pixman_image, - x - mask_x, y - mask_y, - 0, 0, - x, y, - width, height); - } - - /* right */ - if (extents->bounded.x + extents->bounded.width != extents->unbounded.x + extents->unbounded.width) { - int x = extents->bounded.x + extents->bounded.width; - int y = extents->bounded.y; - int width = extents->unbounded.x + extents->unbounded.width - x; - int height = extents->bounded.height; - - pixman_image_composite32 (PIXMAN_OP_OUT_REVERSE, - mask, NULL, dst->pixman_image, - x - mask_x, y - mask_y, - 0, 0, - x, y, - width, height); - } - - /* bottom */ - if (extents->bounded.y + extents->bounded.height != extents->unbounded.y + extents->unbounded.height) { - int x = extents->unbounded.x; - int y = extents->bounded.y + extents->bounded.height; - int width = extents->unbounded.width; - int height = extents->unbounded.y + extents->unbounded.height - y; - - pixman_image_composite32 (PIXMAN_OP_OUT_REVERSE, - mask, NULL, dst->pixman_image, - x - mask_x, y - mask_y, - 0, 0, - x, y, - width, height); - } - - pixman_image_unref (mask); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -set_clip_region (cairo_composite_rectangles_t *extents) -{ - cairo_image_surface_t *dst = (cairo_image_surface_t *) extents->surface; - cairo_region_t *region = _cairo_clip_get_region (extents->clip); - pixman_region32_t *rgn = region ? ®ion->rgn : NULL; - if (! pixman_image_set_clip_region32 (dst->pixman_image, rgn)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -clip_and_composite (cairo_composite_rectangles_t *extents, - draw_func_t draw_func, - void *draw_closure) -{ - cairo_status_t status; - - status = set_clip_region (extents); - if (unlikely (status)) - return status; - - if (extents->op == CAIRO_OPERATOR_SOURCE) { - status = clip_and_composite_source (extents, draw_func, draw_closure); - } else { - if (extents->op == CAIRO_OPERATOR_CLEAR) { - extents->source_pattern.solid = _cairo_pattern_white; - extents->op = CAIRO_OPERATOR_DEST_OUT; - } - if (! _cairo_clip_is_region (extents->clip)) { - if (extents->is_bounded) - status = clip_and_composite_with_mask (extents, draw_func, draw_closure); - else - status = clip_and_composite_combine (extents, draw_func, draw_closure); - } else { - status = draw_func ((cairo_image_surface_t *) extents->surface, - draw_closure, - extents->op, - &extents->source_pattern.base, - 0, 0, - &extents->bounded); - } - } - - if (status == CAIRO_STATUS_SUCCESS && ! extents->is_bounded) - status = fixup_unbounded (extents); - - return status; -} - -/* high-level compositor interface */ - -static cairo_int_status_t -composite_paint (cairo_image_surface_t *dst, - void *closure, - cairo_operator_t op, - const cairo_pattern_t *pattern, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents) -{ - cairo_rectangle_int_t sample; - pixman_image_t *src; - int src_x, src_y; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - _cairo_pattern_sampled_area (pattern, extents, &sample); - src = _pixman_image_for_pattern (dst, - pattern, FALSE, - extents, &sample, - &src_x, &src_y); - if (unlikely (src == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - TRACE ((stderr, "%s: src=(%d, %d), dst=(%d, %d) size=%dx%d\n", __FUNCTION__, - extents->x + src_x, extents->y + src_y, - extents->x - dst_x, extents->y - dst_y, - extents->width, extents->height)); - - pixman_image_composite32 (_pixman_operator (op), - src, NULL, dst->pixman_image, - extents->x + src_x, extents->y + src_y, - 0, 0, - extents->x - dst_x, extents->y - dst_y, - extents->width, extents->height); - - pixman_image_unref (src); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -base_compositor_paint (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents) -{ - TRACE ((stderr, "%s\n", __FUNCTION__)); - return clip_and_composite (extents, composite_paint, NULL); -} - -static cairo_int_status_t -composite_mask (cairo_image_surface_t *dst, - void *closure, - cairo_operator_t op, - const cairo_pattern_t *pattern, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents) -{ - cairo_rectangle_int_t sample; - pixman_image_t *src, *mask; - int src_x, src_y; - int mask_x, mask_y; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - _cairo_pattern_sampled_area (pattern, extents, &sample); - src = _pixman_image_for_pattern (dst, pattern, FALSE, - extents, &sample, - &src_x, &src_y); - if (unlikely (src == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - _cairo_pattern_sampled_area (closure, extents, &sample); - mask = _pixman_image_for_pattern (dst, closure, TRUE, - extents, &sample, - &mask_x, &mask_y); - if (unlikely (mask == NULL)) { - pixman_image_unref (src); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - pixman_image_composite32 (_pixman_operator (op), - src, mask, dst->pixman_image, - extents->x + src_x, extents->y + src_y, - extents->x + mask_x, extents->y + mask_y, - extents->x - dst_x, extents->y - dst_y, - extents->width, extents->height); - - pixman_image_unref (mask); - pixman_image_unref (src); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -base_compositor_mask (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents) -{ - TRACE ((stderr, "%s\n", __FUNCTION__)); - return clip_and_composite (extents, composite_mask, &extents->mask_pattern.base); -} - -typedef struct { - cairo_traps_t traps; - cairo_antialias_t antialias; -} composite_traps_info_t; - -static cairo_int_status_t -composite_traps (cairo_image_surface_t *dst, - void *closure, - cairo_operator_t op, - const cairo_pattern_t *pattern, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents) -{ - composite_traps_info_t *info = closure; - cairo_rectangle_int_t sample; - pixman_image_t *src, *mask; - int src_x, src_y; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - _cairo_pattern_sampled_area (pattern, extents, &sample); - src = _pixman_image_for_pattern (dst, pattern, FALSE, - extents, &sample, - &src_x, &src_y); - if (unlikely (src == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - mask = pixman_image_create_bits (info->antialias == CAIRO_ANTIALIAS_NONE ? PIXMAN_a1 : PIXMAN_a8, - extents->width, extents->height, - NULL, 0); - if (unlikely (mask == NULL)) { - pixman_image_unref (src); - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - _pixman_image_add_traps (mask, extents->x, extents->y, &info->traps); - pixman_image_composite32 (_pixman_operator (op), - src, mask, dst->pixman_image, - extents->x + src_x - dst_x, extents->y + src_y - dst_y, - 0, 0, - extents->x - dst_x, extents->y - dst_y, - extents->width, extents->height); - - pixman_image_unref (mask); - pixman_image_unref (src); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -trim_extents_to_traps (cairo_composite_rectangles_t *extents, - cairo_traps_t *traps) -{ - cairo_box_t box; - - /* X trims the affected area to the extents of the trapezoids, so - * we need to compensate when fixing up the unbounded area. - */ - _cairo_traps_extents (traps, &box); - return _cairo_composite_rectangles_intersect_mask_extents (extents, &box); -} - -static cairo_int_status_t -base_compositor_stroke (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias) -{ - composite_traps_info_t info; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - info.antialias = antialias; - _cairo_traps_init_with_clip (&info.traps, extents->clip); - status = _cairo_path_fixed_stroke_polygon_to_traps (path, style, - ctm, ctm_inverse, - tolerance, - &info.traps); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) - status = trim_extents_to_traps (extents, &info.traps); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) - status = clip_and_composite (extents, composite_traps, &info); - _cairo_traps_fini (&info.traps); - - return status; -} - -static cairo_int_status_t -base_compositor_fill (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias) -{ - composite_traps_info_t info; - cairo_int_status_t status; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - info.antialias = antialias; - _cairo_traps_init_with_clip (&info.traps, extents->clip); - status = _cairo_path_fixed_fill_to_traps (path, - fill_rule, tolerance, - &info.traps); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) - status = trim_extents_to_traps (extents, &info.traps); - if (likely (status == CAIRO_INT_STATUS_SUCCESS)) - status = clip_and_composite (extents, composite_traps, &info); - _cairo_traps_fini (&info.traps); - - return status; -} - -static cairo_int_status_t -composite_glyphs (cairo_image_surface_t *dst, - void *closure, - cairo_operator_t op, - const cairo_pattern_t *pattern, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents) -{ - cairo_composite_glyphs_info_t *info = closure; - pixman_image_t *mask; - cairo_status_t status; - int i; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - - mask = pixman_image_create_bits (PIXMAN_a8, - extents->width, extents->height, - NULL, 0); - if (unlikely (mask == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - status = CAIRO_STATUS_SUCCESS; - _cairo_scaled_font_freeze_cache (info->font); - for (i = 0; i < info->num_glyphs; i++) { - cairo_image_surface_t *glyph_surface; - cairo_scaled_glyph_t *scaled_glyph; - unsigned long glyph_index = info->glyphs[i].index; - int x, y; - - status = _cairo_scaled_glyph_lookup (info->font, glyph_index, - CAIRO_SCALED_GLYPH_INFO_SURFACE, - &scaled_glyph); - - if (unlikely (status)) - break; - - glyph_surface = scaled_glyph->surface; - if (glyph_surface->width && glyph_surface->height) { - /* round glyph locations to the nearest pixel */ - /* XXX: FRAGILE: We're ignoring device_transform scaling here. A bug? */ - x = _cairo_lround (info->glyphs[i].x - - glyph_surface->base.device_transform.x0); - y = _cairo_lround (info->glyphs[i].y - - glyph_surface->base.device_transform.y0); - - pixman_image_composite32 (PIXMAN_OP_ADD, - glyph_surface->pixman_image, NULL, mask, - 0, 0, - 0, 0, - x - extents->x, y - extents->y, - glyph_surface->width, - glyph_surface->height); - } - } - _cairo_scaled_font_thaw_cache (info->font); - - if (status == CAIRO_STATUS_SUCCESS) { - cairo_rectangle_int_t sample; - pixman_image_t *src; - int src_x, src_y; - - _cairo_pattern_sampled_area (pattern, extents, &sample); - src = _pixman_image_for_pattern (dst, pattern, FALSE, - extents, &sample, - &src_x, &src_y); - if (src != NULL) { - dst_x = extents->x - dst_x; - dst_y = extents->y - dst_y; - pixman_image_composite32 (_pixman_operator (op), - src, mask, dst->pixman_image, - src_x + dst_x, src_y + dst_y, - 0, 0, - dst_x, dst_y, - extents->width, extents->height); - pixman_image_unref (src); - } else - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - pixman_image_unref (mask); - - return status; -} - -static cairo_int_status_t -base_compositor_glyphs (const cairo_compositor_t *_compositor, - cairo_composite_rectangles_t *extents, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_bool_t overlap) -{ - cairo_composite_glyphs_info_t info; - - info.font = scaled_font; - info.glyphs = glyphs; - info.num_glyphs = num_glyphs; - - TRACE ((stderr, "%s\n", __FUNCTION__)); - return clip_and_composite (extents, composite_glyphs, &info); -} - -static const cairo_compositor_t base_compositor = { - &__cairo_no_compositor, - - base_compositor_paint, - base_compositor_mask, - base_compositor_stroke, - base_compositor_fill, - base_compositor_glyphs, -}; - -cairo_surface_t * -_cairo_test_base_compositor_surface_create (cairo_content_t content, - int width, - int height) -{ - return test_compositor_surface_create (&base_compositor, - content, width, height); -} diff --git a/source/libs/cairo/cairo-src/src/test-compositor-surface-private.h b/source/libs/cairo/cairo-src/src/test-compositor-surface-private.h deleted file mode 100644 index 491f241bacc3be0a64f4711bc855f218058dfa56..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/test-compositor-surface-private.h +++ /dev/null @@ -1,56 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Intel Corporation - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef TEST_COMPOSITOR_SURFACE_PRIVATE_H -#define TEST_COMPOSITOR_SURFACE_PRIVATE_H - -#include "cairo.h" - -#include "test-compositor-surface.h" - -#include "cairo-compiler-private.h" -#include "cairo-compositor-private.h" - -CAIRO_BEGIN_DECLS - -cairo_private cairo_surface_t * -test_compositor_surface_create (const cairo_compositor_t *compositor, - cairo_content_t content, - int width, - int height); - -CAIRO_END_DECLS - -#endif /* TEST_COMPOSITOR_SURFACE_PRIVATE H */ diff --git a/source/libs/cairo/cairo-src/src/test-compositor-surface.c b/source/libs/cairo/cairo-src/src/test-compositor-surface.c deleted file mode 100644 index 1cc5f69212037720b3bcb48b09a80c6fea4c49f7..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/test-compositor-surface.c +++ /dev/null @@ -1,264 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Intel Corporation - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#include "cairoint.h" - -#include "test-compositor-surface-private.h" - -#include "cairo-compositor-private.h" -#include "cairo-default-context-private.h" -#include "cairo-error-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-surface-backend-private.h" - -typedef struct _test_compositor_surface { - cairo_image_surface_t base; -} test_compositor_surface_t; - -static const cairo_surface_backend_t test_compositor_surface_backend; - -cairo_surface_t * -test_compositor_surface_create (const cairo_compositor_t *compositor, - cairo_content_t content, - int width, - int height) -{ - test_compositor_surface_t *surface; - pixman_image_t *pixman_image; - pixman_format_code_t pixman_format; - - switch (content) { - case CAIRO_CONTENT_ALPHA: - pixman_format = PIXMAN_a8; - break; - case CAIRO_CONTENT_COLOR: - pixman_format = PIXMAN_x8r8g8b8; - break; - case CAIRO_CONTENT_COLOR_ALPHA: - pixman_format = PIXMAN_a8r8g8b8; - break; - default: - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT)); - } - - pixman_image = pixman_image_create_bits (pixman_format, width, height, - NULL, 0); - if (unlikely (pixman_image == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - surface = malloc (sizeof (test_compositor_surface_t)); - if (unlikely (surface == NULL)) { - pixman_image_unref (pixman_image); - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - _cairo_surface_init (&surface->base.base, - &test_compositor_surface_backend, - NULL, /* device */ - content); - _cairo_image_surface_init (&surface->base, pixman_image, pixman_format); - - surface->base.compositor = compositor; - - return &surface->base.base; -} - -static cairo_surface_t * -test_compositor_surface_create_similar (void *abstract_surface, - cairo_content_t content, - int width, - int height) -{ - test_compositor_surface_t *surface = abstract_surface; - - return test_compositor_surface_create (surface->base.compositor, - content, width, height); -} - -static cairo_int_status_t -test_compositor_surface_paint (void *_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - test_compositor_surface_t *surface = _surface; - return _cairo_compositor_paint (surface->base.compositor, - _surface, op, source, - clip); -} - -static cairo_int_status_t -test_compositor_surface_mask (void *_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - test_compositor_surface_t *surface = _surface; - return _cairo_compositor_mask (surface->base.compositor, - _surface, op, source, mask, - clip); -} - -static cairo_int_status_t -test_compositor_surface_stroke (void *_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - test_compositor_surface_t *surface = _surface; - if (antialias == CAIRO_ANTIALIAS_DEFAULT) - antialias = CAIRO_ANTIALIAS_BEST; - return _cairo_compositor_stroke (surface->base.compositor, - _surface, op, source, - path, style, ctm, ctm_inverse, - tolerance, antialias, - clip); -} - -static cairo_int_status_t -test_compositor_surface_fill (void *_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - test_compositor_surface_t *surface = _surface; - if (antialias == CAIRO_ANTIALIAS_DEFAULT) - antialias = CAIRO_ANTIALIAS_BEST; - return _cairo_compositor_fill (surface->base.compositor, - _surface, op, source, - path, fill_rule, tolerance, antialias, - clip); -} - -static cairo_int_status_t -test_compositor_surface_glyphs (void *_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - test_compositor_surface_t *surface = _surface; - return _cairo_compositor_glyphs (surface->base.compositor, - _surface, op, source, - glyphs, num_glyphs, scaled_font, - clip); -} - -static const cairo_surface_backend_t test_compositor_surface_backend = { - CAIRO_SURFACE_TYPE_IMAGE, - _cairo_image_surface_finish, - _cairo_default_context_create, - - test_compositor_surface_create_similar, - NULL, /* create similar image */ - _cairo_image_surface_map_to_image, - _cairo_image_surface_unmap_image, - - _cairo_image_surface_source, - _cairo_image_surface_acquire_source_image, - _cairo_image_surface_release_source_image, - _cairo_image_surface_snapshot, - - NULL, /* copy_page */ - NULL, /* show_page */ - - _cairo_image_surface_get_extents, - _cairo_image_surface_get_font_options, - - NULL, /* flush */ - NULL, /* mark_dirty_rectangle */ - - test_compositor_surface_paint, - test_compositor_surface_mask, - test_compositor_surface_stroke, - test_compositor_surface_fill, - NULL, /* fill/stroke */ - test_compositor_surface_glyphs, -}; - -static const cairo_compositor_t * -get_fallback_compositor (void) -{ - return &_cairo_fallback_compositor; -} - -cairo_surface_t * -_cairo_test_fallback_compositor_surface_create (cairo_content_t content, - int width, - int height) -{ - return test_compositor_surface_create (get_fallback_compositor(), - content, width, height); -} - -cairo_surface_t * -_cairo_test_mask_compositor_surface_create (cairo_content_t content, - int width, - int height) -{ - return test_compositor_surface_create (_cairo_image_mask_compositor_get(), - content, width, height); -} - -cairo_surface_t * -_cairo_test_traps_compositor_surface_create (cairo_content_t content, - int width, - int height) -{ - return test_compositor_surface_create (_cairo_image_traps_compositor_get(), - content, width, height); -} - -cairo_surface_t * -_cairo_test_spans_compositor_surface_create (cairo_content_t content, - int width, - int height) -{ - return test_compositor_surface_create (_cairo_image_spans_compositor_get(), - content, width, height); -} diff --git a/source/libs/cairo/cairo-src/src/test-compositor-surface.h b/source/libs/cairo/cairo-src/src/test-compositor-surface.h deleted file mode 100644 index 8d8af2d5409b7cda1b9ec452c203114862977905..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/test-compositor-surface.h +++ /dev/null @@ -1,71 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Intel Corporation - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef TEST_COMPOSITOR_SURFACE_H -#define TEST_COMPOSITOR_SURFACE_H - -#include "cairo.h" - -CAIRO_BEGIN_DECLS - -cairo_surface_t * -_cairo_test_fallback_compositor_surface_create (cairo_content_t content, - int width, - int height); - - -cairo_surface_t * -_cairo_test_mask_compositor_surface_create (cairo_content_t content, - int width, - int height); - -cairo_surface_t * -_cairo_test_traps_compositor_surface_create (cairo_content_t content, - int width, - int height); - -cairo_surface_t * -_cairo_test_spans_compositor_surface_create (cairo_content_t content, - int width, - int height); - -cairo_surface_t * -_cairo_test_base_compositor_surface_create (cairo_content_t content, - int width, - int height); - -CAIRO_END_DECLS - -#endif /* TEST_COMPOSITOR_SURFACE_H */ diff --git a/source/libs/cairo/cairo-src/src/test-null-compositor-surface.c b/source/libs/cairo/cairo-src/src/test-null-compositor-surface.c deleted file mode 100644 index 2301055e30a6f57d303d34d233d19229dbffe61a..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/test-null-compositor-surface.c +++ /dev/null @@ -1,480 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Intel Corporation - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - - -#include "cairoint.h" - -#include "test-null-compositor-surface.h" - -#include "cairo-compositor-private.h" -#include "cairo-default-context-private.h" -#include "cairo-error-private.h" -#include "cairo-image-surface-private.h" -#include "cairo-surface-backend-private.h" -#include "cairo-spans-compositor-private.h" -#include "cairo-spans-private.h" - -typedef struct _test_compositor_surface { - cairo_image_surface_t base; -} test_compositor_surface_t; - -static const cairo_surface_backend_t test_compositor_surface_backend; - -static cairo_surface_t * -test_compositor_surface_create (const cairo_compositor_t *compositor, - cairo_content_t content, - int width, - int height) -{ - test_compositor_surface_t *surface; - pixman_image_t *pixman_image; - pixman_format_code_t pixman_format; - - switch (content) { - case CAIRO_CONTENT_ALPHA: - pixman_format = PIXMAN_a8; - break; - case CAIRO_CONTENT_COLOR: - pixman_format = PIXMAN_x8r8g8b8; - break; - case CAIRO_CONTENT_COLOR_ALPHA: - pixman_format = PIXMAN_a8r8g8b8; - break; - default: - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT)); - } - - pixman_image = pixman_image_create_bits (pixman_format, width, height, - NULL, 0); - if (unlikely (pixman_image == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - surface = malloc (sizeof (test_compositor_surface_t)); - if (unlikely (surface == NULL)) { - pixman_image_unref (pixman_image); - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - - _cairo_surface_init (&surface->base.base, - &test_compositor_surface_backend, - NULL, /* device */ - content); - _cairo_image_surface_init (&surface->base, pixman_image, pixman_format); - - surface->base.compositor = compositor; - - return &surface->base.base; -} - -static cairo_surface_t * -test_compositor_surface_create_similar (void *abstract_surface, - cairo_content_t content, - int width, - int height) -{ - test_compositor_surface_t *surface = abstract_surface; - - return test_compositor_surface_create (surface->base.compositor, - content, width, height); -} - -static cairo_int_status_t -test_compositor_surface_paint (void *_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - test_compositor_surface_t *surface = _surface; - return _cairo_compositor_paint (surface->base.compositor, - _surface, op, source, - clip); -} - -static cairo_int_status_t -test_compositor_surface_mask (void *_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - test_compositor_surface_t *surface = _surface; - return _cairo_compositor_mask (surface->base.compositor, - _surface, op, source, mask, - clip); -} - -static cairo_int_status_t -test_compositor_surface_stroke (void *_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - test_compositor_surface_t *surface = _surface; - return _cairo_compositor_stroke (surface->base.compositor, - _surface, op, source, - path, style, ctm, ctm_inverse, - tolerance, antialias, - clip); -} - -static cairo_int_status_t -test_compositor_surface_fill (void *_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - test_compositor_surface_t *surface = _surface; - return _cairo_compositor_fill (surface->base.compositor, - _surface, op, source, - path, fill_rule, tolerance, antialias, - clip); -} - -static cairo_int_status_t -test_compositor_surface_glyphs (void *_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - cairo_glyph_t *glyphs, - int num_glyphs, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - test_compositor_surface_t *surface = _surface; - return _cairo_compositor_glyphs (surface->base.compositor, - _surface, op, source, - glyphs, num_glyphs, scaled_font, - clip); -} - -static const cairo_surface_backend_t test_compositor_surface_backend = { - CAIRO_SURFACE_TYPE_IMAGE, - _cairo_image_surface_finish, - _cairo_default_context_create, - - test_compositor_surface_create_similar, - NULL, /* create similar image */ - _cairo_image_surface_map_to_image, - _cairo_image_surface_unmap_image, - - _cairo_image_surface_source, - _cairo_image_surface_acquire_source_image, - _cairo_image_surface_release_source_image, - NULL, /* snapshot */ - - NULL, /* copy_page */ - NULL, /* show_page */ - - _cairo_image_surface_get_extents, - _cairo_image_surface_get_font_options, - - NULL, /* flush */ - NULL, /* mark_dirty_rectangle */ - - test_compositor_surface_paint, - test_compositor_surface_mask, - test_compositor_surface_stroke, - test_compositor_surface_fill, - NULL, /* fill/stroke */ - test_compositor_surface_glyphs, -}; - -static cairo_int_status_t -acquire (void *abstract_dst) -{ - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -release (void *abstract_dst) -{ - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -set_clip_region (void *_surface, - cairo_region_t *region) -{ - return CAIRO_STATUS_SUCCESS; -} - -static cairo_surface_t * -pattern_to_surface (cairo_surface_t *dst, - const cairo_pattern_t *pattern, - cairo_bool_t is_mask, - const cairo_rectangle_int_t *extents, - const cairo_rectangle_int_t *sample, - int *src_x, int *src_y) -{ - return cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0); -} - -static cairo_int_status_t -fill_boxes (void *_dst, - cairo_operator_t op, - const cairo_color_t *color, - cairo_boxes_t *boxes) -{ - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -draw_image_boxes (void *_dst, - cairo_image_surface_t *image, - cairo_boxes_t *boxes, - int dx, int dy) -{ - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -composite (void *_dst, - cairo_operator_t op, - cairo_surface_t *abstract_src, - cairo_surface_t *abstract_mask, - int src_x, - int src_y, - int mask_x, - int mask_y, - int dst_x, - int dst_y, - unsigned int width, - unsigned int height) -{ - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -lerp (void *_dst, - cairo_surface_t *abstract_src, - cairo_surface_t *abstract_mask, - int src_x, - int src_y, - int mask_x, - int mask_y, - int dst_x, - int dst_y, - unsigned int width, - unsigned int height) -{ - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -composite_boxes (void *_dst, - cairo_operator_t op, - cairo_surface_t *abstract_src, - cairo_surface_t *abstract_mask, - int src_x, - int src_y, - int mask_x, - int mask_y, - int dst_x, - int dst_y, - cairo_boxes_t *boxes, - const cairo_rectangle_int_t *extents) -{ - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -composite_traps (void *_dst, - cairo_operator_t op, - cairo_surface_t *abstract_src, - int src_x, - int src_y, - int dst_x, - int dst_y, - const cairo_rectangle_int_t *extents, - cairo_antialias_t antialias, - cairo_traps_t *traps) -{ - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -check_composite_glyphs (const cairo_composite_rectangles_t *extents, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int *num_glyphs) -{ - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -composite_glyphs (void *_dst, - cairo_operator_t op, - cairo_surface_t *_src, - int src_x, - int src_y, - int dst_x, - int dst_y, - cairo_composite_glyphs_info_t *info) -{ - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -spans (void *abstract_renderer, - int y, int height, - const cairo_half_open_span_t *spans, - unsigned num_spans) -{ - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -finish_spans (void *abstract_renderer) -{ - return CAIRO_STATUS_SUCCESS; -} - -static cairo_int_status_t -span_renderer_init (cairo_abstract_span_renderer_t *_r, - const cairo_composite_rectangles_t *composite, - cairo_antialias_t antialias, - cairo_bool_t needs_clip) -{ - cairo_span_renderer_t *r = (cairo_span_renderer_t *)_r; - r->render_rows = spans; - r->finish = finish_spans; - return CAIRO_STATUS_SUCCESS; -} - -static void -span_renderer_fini (cairo_abstract_span_renderer_t *_r, - cairo_int_status_t status) -{ -} - -static const cairo_compositor_t * -no_fallback_compositor_get (void) -{ - return &__cairo_no_compositor; -} - -static cairo_int_status_t -check_composite (const cairo_composite_rectangles_t *extents) -{ - return CAIRO_STATUS_SUCCESS; -} - -static const cairo_compositor_t * -no_traps_compositor_get (void) -{ - static cairo_traps_compositor_t compositor; - - if (compositor.base.delegate == NULL) { - _cairo_traps_compositor_init (&compositor, - no_fallback_compositor_get ()); - - compositor.acquire = acquire; - compositor.release = release; - compositor.set_clip_region = set_clip_region; - compositor.pattern_to_surface = pattern_to_surface; - compositor.draw_image_boxes = draw_image_boxes; - //compositor.copy_boxes = copy_boxes; - compositor.fill_boxes = fill_boxes; - compositor.check_composite = check_composite; - compositor.composite = composite; - compositor.lerp = lerp; - //compositor.check_composite_boxes = check_composite_boxes; - compositor.composite_boxes = composite_boxes; - //compositor.check_composite_traps = check_composite_traps; - compositor.composite_traps = composite_traps; - compositor.check_composite_glyphs = check_composite_glyphs; - compositor.composite_glyphs = composite_glyphs; - } - - return &compositor.base; -} - -static const cairo_compositor_t * -no_spans_compositor_get (void) -{ - static cairo_spans_compositor_t compositor; - - if (compositor.base.delegate == NULL) { - _cairo_spans_compositor_init (&compositor, - no_traps_compositor_get()); - - //compositor.acquire = acquire; - //compositor.release = release; - compositor.fill_boxes = fill_boxes; - //compositor.check_composite_boxes = check_composite_boxes; - compositor.composite_boxes = composite_boxes; - //compositor.check_span_renderer = check_span_renderer; - compositor.renderer_init = span_renderer_init; - compositor.renderer_fini = span_renderer_fini; - } - - return &compositor.base; -} - -cairo_surface_t * -_cairo_test_no_fallback_compositor_surface_create (cairo_content_t content, - int width, - int height) -{ - return test_compositor_surface_create (no_fallback_compositor_get(), - content, width, height); -} - -cairo_surface_t * -_cairo_test_no_traps_compositor_surface_create (cairo_content_t content, - int width, - int height) -{ - return test_compositor_surface_create (no_traps_compositor_get(), - content, width, height); -} - -cairo_surface_t * -_cairo_test_no_spans_compositor_surface_create (cairo_content_t content, - int width, - int height) -{ - return test_compositor_surface_create (no_spans_compositor_get(), - content, width, height); -} diff --git a/source/libs/cairo/cairo-src/src/test-null-compositor-surface.h b/source/libs/cairo/cairo-src/src/test-null-compositor-surface.h deleted file mode 100644 index 52d864b28df82f017eeef18d78b971ef74a3d228..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/test-null-compositor-surface.h +++ /dev/null @@ -1,60 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * Copyright © 2011 Intel Corporation - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, 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 Intel Corporation - * - * Contributor(s): - * Chris Wilson <chris@chris-wilson.co.uk> - */ - -#ifndef TEST_NULL_COMPOSITOR_SURFACE_H -#define TEST_NULL_COMPOSITOR_SURFACE_H - -#include "cairo.h" - -CAIRO_BEGIN_DECLS - -cairo_surface_t * -_cairo_test_no_fallback_compositor_surface_create (cairo_content_t content, - int width, - int height); - -cairo_surface_t * -_cairo_test_no_traps_compositor_surface_create (cairo_content_t content, - int width, - int height); - -cairo_surface_t * -_cairo_test_no_spans_compositor_surface_create (cairo_content_t content, - int width, - int height); - -CAIRO_END_DECLS - -#endif /* TEST_NULL_COMPOSITOR_SURFACE_H */ diff --git a/source/libs/cairo/cairo-src/src/test-paginated-surface.c b/source/libs/cairo/cairo-src/src/test-paginated-surface.c deleted file mode 100644 index 0a7c79b37bf73e1dcf07e7447368ffb25d529979..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/test-paginated-surface.c +++ /dev/null @@ -1,286 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Carl Worth <cworth@cworth.org> - */ - -/* This isn't a "real" surface, but just something to be used by the - * test suite to help exercise the paginated-surface paths in cairo. - * - * The defining feature of this backend is that it uses a paginated - * surface to record all operations, and then replays everything to an - * image surface. - * - * It's possible that this code might serve as a good starting point - * for someone working on bringing up a new paginated-surface-based - * backend. - */ - -#include "cairoint.h" - -#include "test-paginated-surface.h" - -#include "cairo-default-context-private.h" -#include "cairo-error-private.h" -#include "cairo-paginated-private.h" -#include "cairo-surface-backend-private.h" - -typedef struct _test_paginated_surface { - cairo_surface_t base; - cairo_surface_t *target; - cairo_paginated_mode_t paginated_mode; -} test_paginated_surface_t; - -static const cairo_surface_backend_t test_paginated_surface_backend; -static const cairo_paginated_surface_backend_t test_paginated_surface_paginated_backend; - -cairo_surface_t * -_cairo_test_paginated_surface_create (cairo_surface_t *target) -{ - cairo_status_t status; - cairo_surface_t *paginated; - test_paginated_surface_t *surface; - - status = cairo_surface_status (target); - if (unlikely (status)) - return _cairo_surface_create_in_error (status); - - surface = malloc (sizeof (test_paginated_surface_t)); - if (unlikely (surface == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - _cairo_surface_init (&surface->base, - &test_paginated_surface_backend, - NULL, /* device */ - target->content); - - surface->target = cairo_surface_reference (target); - - paginated = _cairo_paginated_surface_create (&surface->base, - target->content, - &test_paginated_surface_paginated_backend); - status = paginated->status; - if (status == CAIRO_STATUS_SUCCESS) { - /* paginated keeps the only reference to surface now, drop ours */ - cairo_surface_destroy (&surface->base); - return paginated; - } - - cairo_surface_destroy (target); - free (surface); - return _cairo_surface_create_in_error (status); -} - -static cairo_status_t -_test_paginated_surface_finish (void *abstract_surface) -{ - test_paginated_surface_t *surface = abstract_surface; - - cairo_surface_destroy (surface->target); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_bool_t -_test_paginated_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *rectangle) -{ - test_paginated_surface_t *surface = abstract_surface; - - return _cairo_surface_get_extents (surface->target, rectangle); -} - -static cairo_int_status_t -_test_paginated_surface_paint (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_clip_t *clip) -{ - test_paginated_surface_t *surface = abstract_surface; - - if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) - return CAIRO_STATUS_SUCCESS; - - return _cairo_surface_paint (surface->target, op, source, clip); -} - -static cairo_int_status_t -_test_paginated_surface_mask (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_pattern_t *mask, - const cairo_clip_t *clip) -{ - test_paginated_surface_t *surface = abstract_surface; - - if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) - return CAIRO_STATUS_SUCCESS; - - return _cairo_surface_mask (surface->target, - op, source, mask, clip); -} - -static cairo_int_status_t -_test_paginated_surface_stroke (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - const cairo_stroke_style_t *style, - const cairo_matrix_t *ctm, - const cairo_matrix_t *ctm_inverse, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - test_paginated_surface_t *surface = abstract_surface; - - if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) - return CAIRO_STATUS_SUCCESS; - - return _cairo_surface_stroke (surface->target, op, source, - path, style, - ctm, ctm_inverse, - tolerance, antialias, - clip); -} - -static cairo_int_status_t -_test_paginated_surface_fill (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const cairo_path_fixed_t *path, - cairo_fill_rule_t fill_rule, - double tolerance, - cairo_antialias_t antialias, - const cairo_clip_t *clip) -{ - test_paginated_surface_t *surface = abstract_surface; - - if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) - return CAIRO_STATUS_SUCCESS; - - return _cairo_surface_fill (surface->target, op, source, - path, fill_rule, - tolerance, antialias, - clip); -} - -static cairo_bool_t -_test_paginated_surface_has_show_text_glyphs (void *abstract_surface) -{ - test_paginated_surface_t *surface = abstract_surface; - - return cairo_surface_has_show_text_glyphs (surface->target); -} - -static cairo_int_status_t -_test_paginated_surface_show_text_glyphs (void *abstract_surface, - cairo_operator_t op, - const cairo_pattern_t *source, - const char *utf8, - int utf8_len, - cairo_glyph_t *glyphs, - int num_glyphs, - const cairo_text_cluster_t *clusters, - int num_clusters, - cairo_text_cluster_flags_t cluster_flags, - cairo_scaled_font_t *scaled_font, - const cairo_clip_t *clip) -{ - test_paginated_surface_t *surface = abstract_surface; - - if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) - return CAIRO_STATUS_SUCCESS; - - return _cairo_surface_show_text_glyphs (surface->target, op, source, - utf8, utf8_len, - glyphs, num_glyphs, - clusters, num_clusters, - cluster_flags, - scaled_font, - clip); -} - - -static void -_test_paginated_surface_set_paginated_mode (void *abstract_surface, - cairo_paginated_mode_t mode) -{ - test_paginated_surface_t *surface = abstract_surface; - - surface->paginated_mode = mode; -} - -static const cairo_surface_backend_t test_paginated_surface_backend = { - CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED, - _test_paginated_surface_finish, - _cairo_default_context_create, - - /* Since we are a paginated user, we get to regard most of the - * surface backend interface as historical cruft and ignore it. */ - - NULL, /* create_similar */ - NULL, /* create similar image */ - NULL, /* map to image */ - NULL, /* unmap image */ - - _cairo_surface_default_source, - NULL, /* acquire_source_image */ - NULL, /* release_source_image */ - NULL, /* snapshot */ - - NULL, /* copy_page */ - NULL, /* show_page */ - - _test_paginated_surface_get_extents, - NULL, /* get_font_options */ - - NULL, /* flush */ - NULL, /* mark_dirty_rectangle */ - - /* Here is the more "modern" section of the surface backend - * interface which is mostly just drawing functions */ - - _test_paginated_surface_paint, - _test_paginated_surface_mask, - _test_paginated_surface_stroke, - _test_paginated_surface_fill, - NULL, /* fill-stroke */ - NULL, /* replaced by show_text_glyphs */ - _test_paginated_surface_has_show_text_glyphs, - _test_paginated_surface_show_text_glyphs -}; - -static const cairo_paginated_surface_backend_t test_paginated_surface_paginated_backend = { - NULL, /* start_page */ - _test_paginated_surface_set_paginated_mode -}; diff --git a/source/libs/cairo/cairo-src/src/test-paginated-surface.h b/source/libs/cairo/cairo-src/src/test-paginated-surface.h deleted file mode 100644 index 2bd98aa5eeee74f60051b4197f6a94c0f794129a..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo-src/src/test-paginated-surface.h +++ /dev/null @@ -1,48 +0,0 @@ -/* cairo - a vector graphics library with display and print output - * - * 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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Red Hat, Inc. - * - * Contributor(s): - * Carl Worth <cworth@cworth.org> - */ - -#ifndef TEST_PAGINATED_SURFACE_H -#define TEST_PAGINATED_SURFACE_H - -#include "cairo.h" - -CAIRO_BEGIN_DECLS - -cairo_surface_t * -_cairo_test_paginated_surface_create (cairo_surface_t *target); - -CAIRO_END_DECLS - -#endif /* TEST_PAGINATED_SURFACE_H */ diff --git a/source/libs/cairo/cairo.test b/source/libs/cairo/cairo.test deleted file mode 100644 index e1e446e81e8e6e66e28063230865c0139e92e791..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo.test +++ /dev/null @@ -1,7 +0,0 @@ -#! /bin/sh - -# Copyright (C) 2013 Peter Breitenlohner <tex-live@tug.org> -# You may freely use, modify and/or distribute this file. - -./cairotst || exit 1 - diff --git a/source/libs/cairo/cairo/Makefile.am b/source/libs/cairo/cairo/Makefile.am deleted file mode 100644 index 1f15b12c11cdde797c74c6b950f28b7baa862d54..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo/Makefile.am +++ /dev/null @@ -1,51 +0,0 @@ -## Proxy Makefile.am to install cairo headers for TeX Live. -## -## Copyright (C) 2013 Peter Breitenlohner <tex-live@tug.org> -## -## This file is free software; the copyright holder -## gives unlimited permission to copy and/or distribute it, -## with or without modifications, as long as this notice is preserved. -## -CAIRO_SRC = $(top_srcdir)/$(CAIRO_TREE) -CAIRO_BLD = $(top_builddir) - -hdr_links = \ - $(CAIRO_SRC)/src/cairo.h \ - $(CAIRO_SRC)/src/cairo-deprecated.h \ - $(CAIRO_BLD)/cairo-features.h \ - $(CAIRO_SRC)/cairo-version.h - -if CAIRO_HAS_XLIB_SURFACE -hdr_links += $(CAIRO_SRC)/src/cairo-xlib.h -endif CAIRO_HAS_XLIB_SURFACE - -if CAIRO_HAS_XLIB_XRENDER_SURFACE -hdr_links += $(CAIRO_SRC)/src/cairo-xlib-xrender.h -endif CAIRO_HAS_XLIB_XRENDER_SURFACE - -if CAIRO_HAS_XCB_SURFACE -hdr_links += $(CAIRO_SRC)/src/cairo-xcb.h -endif CAIRO_HAS_XCB_SURFACE - -if CAIRO_HAS_QUARTZ_SURFACE -hdr_links += $(CAIRO_SRC)/src/cairo-quartz.h -endif CAIRO_HAS_QUARTZ_SURFACE - -if CAIRO_HAS_QUARTZ_IMAGE_SURFACE -hdr_links += $(CAIRO_SRC)/src/cairo-quartz-image.h -endif CAIRO_HAS_QUARTZ_IMAGE_SURFACE - -if CAIRO_HAS_OS2_SURFACE -hdr_links += $(CAIRO_SRC)/src/cairo-os2.h -endif CAIRO_HAS_OS2_SURFACE - -if CAIRO_HAS_GL_SURFACE -hdr_links += $(CAIRO_SRC)/src/cairo-gl.h -endif CAIRO_HAS_GL_SURFACE - -if CAIRO_HAS_SVG_SURFACE -hdr_links += $(CAIRO_SRC)/src/cairo-svg.h -endif CAIRO_HAS_SVG_SURFACE - -include $(top_srcdir)/../../am/hdr_links.am - diff --git a/source/libs/cairo/cairo/Makefile.in b/source/libs/cairo/cairo/Makefile.in deleted file mode 100644 index 40d5fc14a563c323992a729b8b8757b1dba82844..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairo/Makefile.in +++ /dev/null @@ -1,454 +0,0 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2014 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -@CAIRO_HAS_XLIB_SURFACE_TRUE@am__append_1 = $(CAIRO_SRC)/src/cairo-xlib.h -@CAIRO_HAS_XLIB_XRENDER_SURFACE_TRUE@am__append_2 = $(CAIRO_SRC)/src/cairo-xlib-xrender.h -@CAIRO_HAS_XCB_SURFACE_TRUE@am__append_3 = $(CAIRO_SRC)/src/cairo-xcb.h -@CAIRO_HAS_QUARTZ_SURFACE_TRUE@am__append_4 = $(CAIRO_SRC)/src/cairo-quartz.h -@CAIRO_HAS_QUARTZ_IMAGE_SURFACE_TRUE@am__append_5 = $(CAIRO_SRC)/src/cairo-quartz-image.h -@CAIRO_HAS_OS2_SURFACE_TRUE@am__append_6 = $(CAIRO_SRC)/src/cairo-os2.h -@CAIRO_HAS_GL_SURFACE_TRUE@am__append_7 = $(CAIRO_SRC)/src/cairo-gl.h -@CAIRO_HAS_SVG_SURFACE_TRUE@am__append_8 = $(CAIRO_SRC)/src/cairo-svg.h -subdir = cairo -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/cairo-bigendian.m4 \ - $(top_srcdir)/m4/cairo-features.m4 $(top_srcdir)/m4/float.m4 \ - $(top_srcdir)/../../m4/kpse-common.m4 \ - $(top_srcdir)/../../m4/kpse-pixman-flags.m4 \ - $(top_srcdir)/../../m4/kpse-visibility.m4 \ - $(top_srcdir)/../../m4/kpse-warnings.m4 \ - $(top_srcdir)/version.ac $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h \ - $(top_builddir)/cairo-features.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -SOURCES = -DIST_SOURCES = -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -am__DIST_COMMON = $(srcdir)/Makefile.in \ - $(top_srcdir)/../../am/hdr_links.am -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CAIRO_ATTRIBUTE_FLAG = @CAIRO_ATTRIBUTE_FLAG@ -CAIRO_TREE = @CAIRO_TREE@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PIXMAN_DEPEND = @PIXMAN_DEPEND@ -PIXMAN_INCLUDES = @PIXMAN_INCLUDES@ -PIXMAN_LIBS = @PIXMAN_LIBS@ -PKG_CONFIG = @PKG_CONFIG@ -RANLIB = @RANLIB@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -VISIBILITY_CFLAGS = @VISIBILITY_CFLAGS@ -WARNING_CFLAGS = @WARNING_CFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -CAIRO_SRC = $(top_srcdir)/$(CAIRO_TREE) -CAIRO_BLD = $(top_builddir) -hdr_links = $(CAIRO_SRC)/src/cairo.h \ - $(CAIRO_SRC)/src/cairo-deprecated.h \ - $(CAIRO_BLD)/cairo-features.h $(CAIRO_SRC)/cairo-version.h \ - $(am__append_1) $(am__append_2) $(am__append_3) \ - $(am__append_4) $(am__append_5) $(am__append_6) \ - $(am__append_7) $(am__append_8) -all: all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/../../am/hdr_links.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign cairo/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign cairo/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; -$(top_srcdir)/../../am/hdr_links.am $(am__empty): - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): -tags TAGS: - -ctags CTAGS: - -cscope cscopelist: - - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile all-local -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic distclean-local - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: all all-am all-local check check-am clean clean-generic \ - cscopelist-am ctags-am distclean distclean-generic \ - distclean-local distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic pdf pdf-am ps ps-am tags-am uninstall \ - uninstall-am - -.PRECIOUS: Makefile - -all-local: - @for file in $(hdr_links); do \ - test -f $$file || continue; \ - inst=`echo $$file | sed -e 's/^.*\///'`; \ - test -f $$inst || { \ - rm -f $$inst; \ - if $(AM_V_P); then echo "$(LN_S) $$file $$inst"; \ - else echo " INST $$inst"; fi; \ - $(LN_S) $$file $$inst; } || exit 1; \ - done - -distclean-local: - rm -f *.h - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/source/libs/cairo/cairotst.c b/source/libs/cairo/cairotst.c deleted file mode 100644 index e36a72cf6f3df5c8d0300b4271ec689f508cd30b..0000000000000000000000000000000000000000 --- a/source/libs/cairo/cairotst.c +++ /dev/null @@ -1,18 +0,0 @@ -/* cairotst.c: Basic test for libcairo - * - * Copyright (C) 2013 Peter Breitenlohner <tex-live@tug.org> - * You may freely use, modify and/or distribute this file. - */ - -#include <stdio.h> -#include <pixman.h> -#include <cairo.h> - -int main (int argc, char **argv) -{ - printf ("%s: Compiled with cairo version %s; using %s\n", - argv[0], CAIRO_VERSION_STRING, cairo_version_string ()); - printf ("%s: Compiled with pixman version %s; using %s\n", - argv[0], PIXMAN_VERSION_STRING, pixman_version_string ()); - return 0; -} diff --git a/source/libs/cairo/config.h.in b/source/libs/cairo/config.h.in deleted file mode 100644 index d8eee3eb193646d3ae23f704b9047a6dc832ca9a..0000000000000000000000000000000000000000 --- a/source/libs/cairo/config.h.in +++ /dev/null @@ -1,221 +0,0 @@ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define if building universal (internal helper macro) */ -#undef AC_APPLE_UNIVERSAL_BUILD - -/* Define to 1 if egl functions enabled. */ -#undef CAIRO_HAS_EGL_FUNCTIONS - -/* Define to 1 if fc font enabled. */ -#undef CAIRO_HAS_FC_FONT - -/* Define to 1 if ft font enabled. */ -#undef CAIRO_HAS_FT_FONT - -/* Define to 1 if glx functions enabled. */ -#undef CAIRO_HAS_GLX_FUNCTIONS - -/* Define to 1 if gobject functions enabled. */ -#undef CAIRO_HAS_GOBJECT_FUNCTIONS - -/* Define to 1 if image surface enabled. */ -#undef CAIRO_HAS_IMAGE_SURFACE - -/* Define to 1 if mime surface enabled. */ -#undef CAIRO_HAS_MIME_SURFACE - -/* Define to 1 if observer surface enabled. */ -#undef CAIRO_HAS_OBSERVER_SURFACE - -/* Define to 1 if pdf surface enabled. */ -#undef CAIRO_HAS_PDF_SURFACE - -/* Define to 1 if png functions enabled. */ -#undef CAIRO_HAS_PNG_FUNCTIONS - -/* Define to 1 if ps surface enabled. */ -#undef CAIRO_HAS_PS_SURFACE - -/* Define to 1 if quartz font enabled. */ -#undef CAIRO_HAS_QUARTZ_FONT - -/* Define to 1 if quartz surface enabled. */ -#undef CAIRO_HAS_QUARTZ_SURFACE - -/* Define to 1 if recording surface enabled. */ -#undef CAIRO_HAS_RECORDING_SURFACE - -/* Define to 1 if script surface enabled. */ -#undef CAIRO_HAS_SCRIPT_SURFACE - -/* Define to 1 if svg surface enabled. */ -#undef CAIRO_HAS_SVG_SURFACE - -/* Define to 1 if user font enabled. */ -#undef CAIRO_HAS_USER_FONT - -/* Define to 1 if wgl functions enabled. */ -#undef CAIRO_HAS_WGL_FUNCTIONS - -/* Define to 1 if win32 font enabled. */ -#undef CAIRO_HAS_WIN32_FONT - -/* Define to 1 if win32 functions enabled. */ -#undef CAIRO_HAS_WIN32_FUNCTIONS - -/* Define to 1 if win32 surface enabled. */ -#undef CAIRO_HAS_WIN32_SURFACE - -/* Define to 1 if xcb shm functions enabled. */ -#undef CAIRO_HAS_XCB_SHM_FUNCTIONS - -/* Define to 1 if xcb surface enabled. */ -#undef CAIRO_HAS_XCB_SURFACE - -/* Define to 1 if xlib surface enabled. */ -#undef CAIRO_HAS_XLIB_SURFACE - -/* Define to 1 if xlib xrender surface enabled. */ -#undef CAIRO_HAS_XLIB_XRENDER_SURFACE - -/* Define to 1 if your system stores words within floats with the most - significant word first */ -#undef FLOAT_WORDS_BIGENDIAN - -/* Define to 1 if you have the <inttypes.h> header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if you have the <memory.h> header file. */ -#undef HAVE_MEMORY_H - -/* Define to 1 if you have the <stdint.h> header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the <stdlib.h> header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the <strings.h> header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the <string.h> header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the <sys/int_types.h> header file. */ -#undef HAVE_SYS_INT_TYPES_H - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the <sys/types.h> header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if the system has the type `uint128_t'. */ -#undef HAVE_UINT128_T - -/* Define to 1 if the system has the type `uint64_t'. */ -#undef HAVE_UINT64_T - -/* Define to 1 if you have the <unistd.h> header file. */ -#undef HAVE_UNISTD_H - -/* Define to 1 if the system has the type `__uint128_t'. */ -#undef HAVE___UINT128_T - -/* Name of package */ -#undef PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the home page for this package. */ -#undef PACKAGE_URL - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* The size of `int', as computed by sizeof. */ -#undef SIZEOF_INT - -/* The size of `long', as computed by sizeof. */ -#undef SIZEOF_LONG - -/* The size of `long long', as computed by sizeof. */ -#undef SIZEOF_LONG_LONG - -/* The size of `size_t', as computed by sizeof. */ -#undef SIZEOF_SIZE_T - -/* The size of `void *', as computed by sizeof. */ -#undef SIZEOF_VOID_P - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* Enable extensions on AIX 3, Interix. */ -#ifndef _ALL_SOURCE -# undef _ALL_SOURCE -#endif -/* Enable GNU extensions on systems that have them. */ -#ifndef _GNU_SOURCE -# undef _GNU_SOURCE -#endif -/* Enable threading extensions on Solaris. */ -#ifndef _POSIX_PTHREAD_SEMANTICS -# undef _POSIX_PTHREAD_SEMANTICS -#endif -/* Enable extensions on HP NonStop. */ -#ifndef _TANDEM_SOURCE -# undef _TANDEM_SOURCE -#endif -/* Enable general extensions on Solaris. */ -#ifndef __EXTENSIONS__ -# undef __EXTENSIONS__ -#endif - - -/* Version number of package */ -#undef VERSION - -/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most - significant byte first (like Motorola and SPARC, unlike Intel). */ -#if defined AC_APPLE_UNIVERSAL_BUILD -# if defined __BIG_ENDIAN__ -# define WORDS_BIGENDIAN 1 -# endif -#else -# ifndef WORDS_BIGENDIAN -# undef WORDS_BIGENDIAN -# endif -#endif - - -/* Deal with multiple architecture compiles on Mac OS X */ -#ifdef __APPLE_CC__ -#ifdef __BIG_ENDIAN__ -#define WORDS_BIGENDIAN 1 -#define FLOAT_WORDS_BIGENDIAN 1 -#else -#undef WORDS_BIGENDIAN -#undef FLOAT_WORDS_BIGENDIAN -#endif -#endif - - -/* Define to 1 if on MINIX. */ -#undef _MINIX - -/* Define to 2 if the system does not provide POSIX.1 features except with - this defined. */ -#undef _POSIX_1_SOURCE - -/* Define to 1 if you need to in order for `stat' and other things to work. */ -#undef _POSIX_SOURCE diff --git a/source/libs/cairo/configure b/source/libs/cairo/configure deleted file mode 100755 index 1257a39e154ec6d76d0531d1b886fc5f99439846..0000000000000000000000000000000000000000 --- a/source/libs/cairo/configure +++ /dev/null @@ -1,8201 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for cairo (TeX Live) 1.14.8. -# -# Report bugs to <tex-k@tug.org>. -# -# -# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. -# -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -# Use a proper internal environment variable to ensure we don't fall - # into an infinite loop, continuously re-executing ourselves. - if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then - _as_can_reexec=no; export _as_can_reexec; - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -as_fn_exit 255 - fi - # We don't want this to propagate to other subprocesses. - { _as_can_reexec=; unset _as_can_reexec;} -if test "x$CONFIG_SHELL" = x; then - as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi -" - as_required="as_fn_return () { (exit \$1); } -as_fn_success () { as_fn_return 0; } -as_fn_failure () { as_fn_return 1; } -as_fn_ret_success () { return 0; } -as_fn_ret_failure () { return 1; } - -exitcode=0 -as_fn_success || { exitcode=1; echo as_fn_success failed.; } -as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } -as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } -as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } -if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : - -else - exitcode=1; echo positional parameters were not saved. -fi -test x\$exitcode = x0 || exit 1 -test -x / || exit 1" - as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO - as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO - eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && - test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 -test \$(( 1 + 1 )) = 2 || exit 1" - if (eval "$as_required") 2>/dev/null; then : - as_have_required=yes -else - as_have_required=no -fi - if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : - -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_found=false -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - as_found=: - case $as_dir in #( - /*) - for as_base in sh bash ksh sh5; do - # Try only shells that exist, to save several forks. - as_shell=$as_dir/$as_base - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : - CONFIG_SHELL=$as_shell as_have_required=yes - if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : - break 2 -fi -fi - done;; - esac - as_found=false -done -$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : - CONFIG_SHELL=$SHELL as_have_required=yes -fi; } -IFS=$as_save_IFS - - - if test "x$CONFIG_SHELL" != x; then : - export CONFIG_SHELL - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -exit 255 -fi - - if test x$as_have_required = xno; then : - $as_echo "$0: This script requires a shell more modern than all" - $as_echo "$0: the shells that I found on your system." - if test x${ZSH_VERSION+set} = xset ; then - $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" - $as_echo "$0: be upgraded to zsh 4.3.4 or later." - else - $as_echo "$0: Please tell bug-autoconf@gnu.org and tex-k@tug.org -$0: about your system, including any error possibly output -$0: before this message. Then install a modern shell, or -$0: manually run the script under such a shell if you do -$0: have one." - fi - exit 1 -fi -fi -fi -SHELL=${CONFIG_SHELL-/bin/sh} -export SHELL -# Unset more variables known to interfere with behavior of common tools. -CLICOLOR_FORCE= GREP_OPTIONS= -unset CLICOLOR_FORCE GREP_OPTIONS - -## --------------------- ## -## M4sh Shell Functions. ## -## --------------------- ## -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # If we had to re-execute with $CONFIG_SHELL, we're ensured to have - # already done that, so ensure we don't try to do so again and fall - # in an infinite loop. This has already happened in practice. - _as_can_reexec=no; export _as_can_reexec - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -test -n "$DJDIR" || exec 7<&0 </dev/null -exec 6>&1 - -# Name of the host. -# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_clean_files= -ac_config_libobj_dir=. -LIBOBJS= -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= - -# Identity of this package. -PACKAGE_NAME='cairo (TeX Live)' -PACKAGE_TARNAME='cairo--tex-live-' -PACKAGE_VERSION='1.14.8' -PACKAGE_STRING='cairo (TeX Live) 1.14.8' -PACKAGE_BUGREPORT='tex-k@tug.org' -PACKAGE_URL='' - -ac_unique_file="cairo-src/src/cairo.h" -# Factoring default headers for most tests. -ac_includes_default="\ -#include <stdio.h> -#ifdef HAVE_SYS_TYPES_H -# include <sys/types.h> -#endif -#ifdef HAVE_SYS_STAT_H -# include <sys/stat.h> -#endif -#ifdef STDC_HEADERS -# include <stdlib.h> -# include <stddef.h> -#else -# ifdef HAVE_STDLIB_H -# include <stdlib.h> -# endif -#endif -#ifdef HAVE_STRING_H -# if !defined STDC_HEADERS && defined HAVE_MEMORY_H -# include <memory.h> -# endif -# include <string.h> -#endif -#ifdef HAVE_STRINGS_H -# include <strings.h> -#endif -#ifdef HAVE_INTTYPES_H -# include <inttypes.h> -#endif -#ifdef HAVE_STDINT_H -# include <stdint.h> -#endif -#ifdef HAVE_UNISTD_H -# include <unistd.h> -#endif" - -ac_subst_vars='am__EXEEXT_FALSE -am__EXEEXT_TRUE -LTLIBOBJS -LIBOBJS -CAIRO_TREE -PIXMAN_RULE -PIXMAN_DEPEND -PIXMAN_LIBS -PIXMAN_INCLUDES -PKG_CONFIG -host_os -host_vendor -host_cpu -host -build_os -build_vendor -build_cpu -build -CAIRO_HAS_GL_SURFACE_FALSE -CAIRO_HAS_GL_SURFACE_TRUE -CAIRO_HAS_OS2_SURFACE_FALSE -CAIRO_HAS_OS2_SURFACE_TRUE -CAIRO_HAS_QUARTZ_IMAGE_SURFACE_FALSE -CAIRO_HAS_QUARTZ_IMAGE_SURFACE_TRUE -CAIRO_HAS_XLIB_XRENDER_SURFACE_FALSE -CAIRO_HAS_XLIB_XRENDER_SURFACE_TRUE -CAIRO_HAS_XLIB_SURFACE_FALSE -CAIRO_HAS_XLIB_SURFACE_TRUE -CAIRO_HAS_XCB_SURFACE_FALSE -CAIRO_HAS_XCB_SURFACE_TRUE -CAIRO_HAS_WIN32_SURFACE_FALSE -CAIRO_HAS_WIN32_SURFACE_TRUE -CAIRO_HAS_SVG_SURFACE_FALSE -CAIRO_HAS_SVG_SURFACE_TRUE -CAIRO_HAS_SCRIPT_SURFACE_FALSE -CAIRO_HAS_SCRIPT_SURFACE_TRUE -CAIRO_HAS_QUARTZ_SURFACE_FALSE -CAIRO_HAS_QUARTZ_SURFACE_TRUE -CAIRO_HAS_PS_SURFACE_FALSE -CAIRO_HAS_PS_SURFACE_TRUE -CAIRO_HAS_PDF_SURFACE_FALSE -CAIRO_HAS_PDF_SURFACE_TRUE -CAIRO_HAS_RECORDING_SURFACE_FALSE -CAIRO_HAS_RECORDING_SURFACE_TRUE -CAIRO_HAS_OBSERVER_SURFACE_FALSE -CAIRO_HAS_OBSERVER_SURFACE_TRUE -CAIRO_HAS_MIME_SURFACE_FALSE -CAIRO_HAS_MIME_SURFACE_TRUE -CAIRO_HAS_IMAGE_SURFACE_FALSE -CAIRO_HAS_IMAGE_SURFACE_TRUE -CAIRO_HAS_XCB_SHM_FUNCTIONS_FALSE -CAIRO_HAS_XCB_SHM_FUNCTIONS_TRUE -CAIRO_HAS_WIN32_FUNCTIONS_FALSE -CAIRO_HAS_WIN32_FUNCTIONS_TRUE -CAIRO_HAS_WGL_FUNCTIONS_FALSE -CAIRO_HAS_WGL_FUNCTIONS_TRUE -CAIRO_HAS_PNG_FUNCTIONS_FALSE -CAIRO_HAS_PNG_FUNCTIONS_TRUE -CAIRO_HAS_GOBJECT_FUNCTIONS_FALSE -CAIRO_HAS_GOBJECT_FUNCTIONS_TRUE -CAIRO_HAS_GLX_FUNCTIONS_FALSE -CAIRO_HAS_GLX_FUNCTIONS_TRUE -CAIRO_HAS_EGL_FUNCTIONS_FALSE -CAIRO_HAS_EGL_FUNCTIONS_TRUE -CAIRO_HAS_WIN32_FONT_FALSE -CAIRO_HAS_WIN32_FONT_TRUE -CAIRO_HAS_USER_FONT_FALSE -CAIRO_HAS_USER_FONT_TRUE -CAIRO_HAS_QUARTZ_FONT_FALSE -CAIRO_HAS_QUARTZ_FONT_TRUE -CAIRO_HAS_FT_FONT_FALSE -CAIRO_HAS_FT_FONT_TRUE -CAIRO_HAS_FC_FONT_FALSE -CAIRO_HAS_FC_FONT_TRUE -build_FALSE -build_TRUE -CAIRO_ATTRIBUTE_FLAG -VISIBILITY_CFLAGS -LN_S -RANLIB -WARNING_CFLAGS -MAINT -MAINTAINER_MODE_FALSE -MAINTAINER_MODE_TRUE -AM_BACKSLASH -AM_DEFAULT_VERBOSITY -AM_DEFAULT_V -AM_V -am__fastdepCC_FALSE -am__fastdepCC_TRUE -CCDEPMODE -am__nodep -AMDEPBACKSLASH -AMDEP_FALSE -AMDEP_TRUE -am__quote -am__include -DEPDIR -am__untar -am__tar -AMTAR -am__leading_dot -SET_MAKE -AWK -mkdir_p -MKDIR_P -INSTALL_STRIP_PROGRAM -STRIP -install_sh -MAKEINFO -AUTOHEADER -AUTOMAKE -AUTOCONF -ACLOCAL -VERSION -PACKAGE -CYGPATH_W -am__isrc -INSTALL_DATA -INSTALL_SCRIPT -INSTALL_PROGRAM -EGREP -GREP -CPP -OBJEXT -EXEEXT -ac_ct_CC -CPPFLAGS -LDFLAGS -CFLAGS -CC -target_alias -host_alias -build_alias -LIBS -ECHO_T -ECHO_N -ECHO_C -DEFS -mandir -localedir -libdir -psdir -pdfdir -dvidir -htmldir -infodir -docdir -oldincludedir -includedir -localstatedir -sharedstatedir -sysconfdir -datadir -datarootdir -libexecdir -sbindir -bindir -program_transform_name -prefix -exec_prefix -PACKAGE_URL -PACKAGE_BUGREPORT -PACKAGE_STRING -PACKAGE_VERSION -PACKAGE_TARNAME -PACKAGE_NAME -PATH_SEPARATOR -SHELL' -ac_subst_files='' -ac_user_opts=' -enable_option_checking -enable_dependency_tracking -enable_silent_rules -enable_maintainer_mode -enable_compiler_warnings -with_system_pixman -' - ac_precious_vars='build_alias -host_alias -target_alias -CC -CFLAGS -LDFLAGS -LIBS -CPPFLAGS -CPP' - - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -ac_unrecognized_opts= -ac_unrecognized_sep= -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -# (The list follows the same order as the GNU Coding Standards.) -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datarootdir='${prefix}/share' -datadir='${datarootdir}' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -includedir='${prefix}/include' -oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' -infodir='${datarootdir}/info' -htmldir='${docdir}' -dvidir='${docdir}' -pdfdir='${docdir}' -psdir='${docdir}' -libdir='${exec_prefix}/lib' -localedir='${datarootdir}/locale' -mandir='${datarootdir}/man' - -ac_prev= -ac_dashdash= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval $ac_prev=\$ac_option - ac_prev= - continue - fi - - case $ac_option in - *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *=) ac_optarg= ;; - *) ac_optarg=yes ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_dashdash$ac_option in - --) - ac_dashdash=yes ;; - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=*) - datadir=$ac_optarg ;; - - -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ - | --dataroo | --dataro | --datar) - ac_prev=datarootdir ;; - -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ - | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) - datarootdir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=no ;; - - -docdir | --docdir | --docdi | --doc | --do) - ac_prev=docdir ;; - -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) - docdir=$ac_optarg ;; - - -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) - ac_prev=dvidir ;; - -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) - dvidir=$ac_optarg ;; - - -enable-* | --enable-*) - ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=\$ac_optarg ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) - ac_prev=htmldir ;; - -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ - | --ht=*) - htmldir=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localedir | --localedir | --localedi | --localed | --locale) - ac_prev=localedir ;; - -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) - localedir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst | --locals) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) - ac_prev=pdfdir ;; - -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) - pdfdir=$ac_optarg ;; - - -psdir | --psdir | --psdi | --psd | --ps) - ac_prev=psdir ;; - -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) - psdir=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=\$ac_optarg ;; - - -without-* | --without-*) - ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=no ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) as_fn_error $? "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information" - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - case $ac_envvar in #( - '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; - esac - eval $ac_envvar=\$ac_optarg - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error $? "missing argument to $ac_option" -fi - -if test -n "$ac_unrecognized_opts"; then - case $enable_option_checking in - no) ;; - fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; - esac -fi - -# Check all directory arguments for consistency. -for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir -do - eval ac_val=\$$ac_var - # Remove trailing slashes. - case $ac_val in - */ ) - ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` - eval $ac_var=\$ac_val;; - esac - # Be sure to have absolute directory names. - case $ac_val in - [\\/$]* | ?:[\\/]* ) continue;; - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; - esac - as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -ac_pwd=`pwd` && test -n "$ac_pwd" && -ac_ls_di=`ls -di .` && -ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - as_fn_error $? "working directory cannot be determined" -test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - as_fn_error $? "pwd does not report name of working directory" - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then the parent directory. - ac_confdir=`$as_dirname -- "$as_myself" || -$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_myself" : 'X\(//\)[^/]' \| \ - X"$as_myself" : 'X\(//\)$' \| \ - X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_myself" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r "$srcdir/$ac_unique_file"; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r "$srcdir/$ac_unique_file"; then - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" -fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" -ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" - pwd)` -# When building in place, set srcdir=. -if test "$ac_abs_confdir" = "$ac_pwd"; then - srcdir=. -fi -# Remove unnecessary trailing slashes from srcdir. -# Double slashes in file names in object file debugging info -# mess up M-x gdb in Emacs. -case $srcdir in -*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; -esac -for ac_var in $ac_precious_vars; do - eval ac_env_${ac_var}_set=\${${ac_var}+set} - eval ac_env_${ac_var}_value=\$${ac_var} - eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} - eval ac_cv_env_${ac_var}_value=\$${ac_var} -done - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures cairo (TeX Live) 1.14.8 to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking ...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root - [DATAROOTDIR/doc/cairo--tex-live-] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] -_ACEOF - - cat <<\_ACEOF - -Program names: - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM run sed PROGRAM on installed program names - -System types: - --build=BUILD configure for building on BUILD [guessed] - --host=HOST cross-compile to build programs to run on HOST [BUILD] -_ACEOF -fi - -if test -n "$ac_init_help"; then - case $ac_init_help in - short | recursive ) echo "Configuration of cairo (TeX Live) 1.14.8:";; - esac - cat <<\_ACEOF - -Optional Features: - --disable-option-checking ignore unrecognized --enable/--with options - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-dependency-tracking - do not reject slow dependency extractors - --disable-dependency-tracking - speeds up one-time build - --enable-silent-rules less verbose build output (undo: "make V=1") - --disable-silent-rules verbose build output (undo: "make V=0") - --enable-maintainer-mode - enable make rules and dependencies not useful (and - sometimes confusing) to the casual installer - --enable-compiler-warnings=[no|min|yes|max|all] - Turn on compiler warnings [default: yes if - maintainer-mode, min otherwise] - -Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-system-pixman use installed pixman headers and library (requires - pkg-config) - -Some influential environment variables: - CC C compiler command - CFLAGS C compiler flags - LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a - nonstandard directory <lib dir> - LIBS libraries to pass to the linker, e.g. -l<library> - CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if - you have headers in a nonstandard directory <include dir> - CPP C preprocessor - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -Report bugs to <tex-k@tug.org>. -_ACEOF -ac_status=$? -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d "$ac_dir" || - { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || - continue - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. - if test -f "$ac_srcdir/configure.gnu"; then - echo && - $SHELL "$ac_srcdir/configure.gnu" --help=recursive - elif test -f "$ac_srcdir/configure"; then - echo && - $SHELL "$ac_srcdir/configure" --help=recursive - else - $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi || ac_status=$? - cd "$ac_pwd" || { ac_status=$?; break; } - done -fi - -test -n "$ac_init_help" && exit $ac_status -if $ac_init_version; then - cat <<\_ACEOF -cairo (TeX Live) configure 1.14.8 -generated by GNU Autoconf 2.69 - -Copyright (C) 2012 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit -fi - -## ------------------------ ## -## Autoconf initialization. ## -## ------------------------ ## - -# ac_fn_c_try_compile LINENO -# -------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_compile - -# ac_fn_c_try_cpp LINENO -# ---------------------- -# Try to preprocess conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_cpp () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } > conftest.i && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_cpp - -# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists, giving a warning if it cannot be compiled using -# the include files in INCLUDES and setting the cache variable VAR -# accordingly. -ac_fn_c_check_header_mongrel () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval \${$3+:} false; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -else - # Is the header compilable? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 -$as_echo_n "checking $2 usability... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_header_compiler=yes -else - ac_header_compiler=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 -$as_echo "$ac_header_compiler" >&6; } - -# Is the header present? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 -$as_echo_n "checking $2 presence... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <$2> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - ac_header_preproc=yes -else - ac_header_preproc=no -fi -rm -f conftest.err conftest.i conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 -$as_echo "$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( - yes:no: ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 -$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; - no:yes:* ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 -$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 -$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 -$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 -$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} -( $as_echo "## ---------------------------- ## -## Report this to tex-k@tug.org ## -## ---------------------------- ##" - ) | sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=\$ac_header_compiler" -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_mongrel - -# ac_fn_c_try_run LINENO -# ---------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes -# that executables *can* be run. -ac_fn_c_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then : - ac_retval=0 -else - $as_echo "$as_me: program exited with status $ac_status" >&5 - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status -fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_run - -# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists and can be compiled using the include files in -# INCLUDES, setting the cache variable VAR accordingly. -ac_fn_c_check_header_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_compile - -# ac_fn_c_try_link LINENO -# ----------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_link () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - test -x conftest$ac_exeext - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information - # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would - # interfere with the next link command; also delete a directory that is - # left behind by Apple's compiler. We do this before executing the actions. - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_link - -# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES -# -------------------------------------------- -# Tries to find the compile-time value of EXPR in a program that includes -# INCLUDES, setting VAR accordingly. Returns whether the value could be -# computed -ac_fn_c_compute_int () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) >= 0)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_lo=0 ac_mid=0 - while :; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) <= $ac_mid)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_hi=$ac_mid; break -else - as_fn_arith $ac_mid + 1 && ac_lo=$as_val - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) < 0)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_hi=-1 ac_mid=-1 - while :; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) >= $ac_mid)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_lo=$ac_mid; break -else - as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - ac_lo= ac_hi= -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) <= $ac_mid)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_hi=$ac_mid -else - as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in #(( -?*) eval "$3=\$ac_lo"; ac_retval=0 ;; -'') ac_retval=1 ;; -esac - else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -static long int longval () { return $2; } -static unsigned long int ulongval () { return $2; } -#include <stdio.h> -#include <stdlib.h> -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - return 1; - if (($2) < 0) - { - long int i = longval (); - if (i != ($2)) - return 1; - fprintf (f, "%ld", i); - } - else - { - unsigned long int i = ulongval (); - if (i != ($2)) - return 1; - fprintf (f, "%lu", i); - } - /* Do not output a trailing newline, as this causes \r\n confusion - on some platforms. */ - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - echo >>conftest.val; read $3 <conftest.val; ac_retval=0 -else - ac_retval=1 -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -rm -f conftest.val - - fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_compute_int - -# ac_fn_c_check_type LINENO TYPE VAR INCLUDES -# ------------------------------------------- -# Tests whether TYPE exists after having included INCLUDES, setting cache -# variable VAR accordingly. -ac_fn_c_check_type () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=no" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof ($2)) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof (($2))) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - eval "$3=yes" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_type - -# ac_fn_c_check_func LINENO FUNC VAR -# ---------------------------------- -# Tests whether FUNC exists, setting the cache variable VAR accordingly -ac_fn_c_check_func () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -/* Define $2 to an innocuous variant, in case <limits.h> declares $2. - For example, HP-UX 11i <limits.h> declares gettimeofday. */ -#define $2 innocuous_$2 - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $2 (); below. - Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - <limits.h> exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - -#undef $2 - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $2 (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$2 || defined __stub___$2 -choke me -#endif - -int -main () -{ -return $2 (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_func -cat >config.log <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by cairo (TeX Live) $as_me 1.14.8, which was -generated by GNU Autoconf 2.69. Invocation command line was - - $ $0 $@ - -_ACEOF -exec 5>>config.log -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - $as_echo "PATH: $as_dir" - done -IFS=$as_save_IFS - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *\'*) - ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; - 2) - as_fn_append ac_configure_args1 " '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - as_fn_append ac_configure_args " '$ac_arg'" - ;; - esac - done -done -{ ac_configure_args0=; unset ac_configure_args0;} -{ ac_configure_args1=; unset ac_configure_args1;} - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Use '\'' to represent an apostrophe within the trap. -# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - $as_echo "## ---------------- ## -## Cache variables. ## -## ---------------- ##" - echo - # The following way of writing the cache mishandles newlines in values, -( - for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - (set) 2>&1 | - case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - sed -n \ - "s/'\''/'\''\\\\'\'''\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" - ;; #( - *) - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) - echo - - $as_echo "## ----------------- ## -## Output variables. ## -## ----------------- ##" - echo - for ac_var in $ac_subst_vars - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - - if test -n "$ac_subst_files"; then - $as_echo "## ------------------- ## -## File substitutions. ## -## ------------------- ##" - echo - for ac_var in $ac_subst_files - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - fi - - if test -s confdefs.h; then - $as_echo "## ----------- ## -## confdefs.h. ## -## ----------- ##" - echo - cat confdefs.h - echo - fi - test "$ac_signal" != 0 && - $as_echo "$as_me: caught signal $ac_signal" - $as_echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core core.conftest.* && - rm -f -r conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status -' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -f -r conftest* confdefs.h - -$as_echo "/* confdefs.h */" > confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_URL "$PACKAGE_URL" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer an explicitly selected file to automatically selected ones. -ac_site_file1=NONE -ac_site_file2=NONE -if test -n "$CONFIG_SITE"; then - # We do not want a PATH search for config.site. - case $CONFIG_SITE in #(( - -*) ac_site_file1=./$CONFIG_SITE;; - */*) ac_site_file1=$CONFIG_SITE;; - *) ac_site_file1=./$CONFIG_SITE;; - esac -elif test "x$prefix" != xNONE; then - ac_site_file1=$prefix/share/config.site - ac_site_file2=$prefix/etc/config.site -else - ac_site_file1=$ac_default_prefix/share/config.site - ac_site_file2=$ac_default_prefix/etc/config.site -fi -for ac_site_file in "$ac_site_file1" "$ac_site_file2" -do - test "x$ac_site_file" = xNONE && continue - if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 -$as_echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" \ - || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5; } - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special files - # actually), so we avoid doing that. DJGPP emulates it as a regular file. - if test /dev/null != "$cache_file" && test -f "$cache_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 -$as_echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . "$cache_file";; - *) . "./$cache_file";; - esac - fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 -$as_echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in $ac_precious_vars; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val=\$ac_cv_env_${ac_var}_value - eval ac_new_val=\$ac_env_${ac_var}_value - case $ac_old_set,$ac_new_set in - set,) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - # differences in whitespace do not lead to failure. - ac_old_val_w=`echo x $ac_old_val` - ac_new_val_w=`echo x $ac_new_val` - if test "$ac_old_val_w" != "$ac_new_val_w"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 -$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - ac_cache_corrupted=: - else - { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} - eval $ac_var=\$ac_old_val - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 -$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 -$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) as_fn_append ac_configure_args " '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 -$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 -fi -## -------------------- ## -## Main body of script. ## -## -------------------- ## - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - - -ac_aux_dir= -for ac_dir in ../../build-aux "$srcdir"/../../build-aux; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in ../../build-aux \"$srcdir\"/../../build-aux" "$LINENO" 5 -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - - - - -# Expand $ac_aux_dir to an absolute path. -am_aux_dir=`cd "$ac_aux_dir" && pwd` - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } - -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 -$as_echo_n "checking whether the C compiler works... " >&6; } -ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` - -# The possible output files: -ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" - -ac_rmfiles= -for ac_file in $ac_files -do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - * ) ac_rmfiles="$ac_rmfiles $ac_file";; - esac -done -rm -f $ac_rmfiles - -if { { ac_try="$ac_link_default" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link_default") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' -# in a Makefile. We should not override ac_cv_exeext if it was cached, -# so that the user can short-circuit this test for compilers unknown to -# Autoconf. -for ac_file in $ac_files '' -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; - then :; else - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - fi - # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' - # argument, so we may need to know it at that point already. - # Even if this section looks crufty: it has the advantage of - # actually working. - break;; - * ) - break;; - esac -done -test "$ac_cv_exeext" = no && ac_cv_exeext= - -else - ac_file='' -fi -if test -z "$ac_file"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -$as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 -$as_echo_n "checking for C compiler default output file name... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 -$as_echo "$ac_file" >&6; } -ac_exeext=$ac_cv_exeext - -rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 -$as_echo_n "checking for suffix of executables... " >&6; } -if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - break;; - * ) break;; - esac -done -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest conftest$ac_cv_exeext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 -$as_echo "$ac_cv_exeext" >&6; } - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdio.h> -int -main () -{ -FILE *f = fopen ("conftest.out", "w"); - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -ac_clean_files="$ac_clean_files conftest.out" -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 -$as_echo_n "checking whether we are cross compiling... " >&6; } -if test "$cross_compiling" != yes; then - { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if { ac_try='./conftest$ac_cv_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5; } - fi - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 -$as_echo "$cross_compiling" >&6; } - -rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 -$as_echo_n "checking for suffix of object files... " >&6; } -if ${ac_cv_objext+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - for ac_file in conftest.o conftest.obj conftest.*; do - test -f "$ac_file" || continue; - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 -$as_echo "$ac_cv_objext" >&6; } -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GCC=yes -else - GCC= -fi -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -else - CFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdarg.h> -#include <stdio.h> -struct stat; -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_c89=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : - -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 -$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } -if ${am_cv_prog_cc_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF - # Make sure it works both with $CC and with simple cc. - # Following AC_PROG_CC_C_O, we do the test twice because some - # compilers refuse to overwrite an existing .o file with -o, - # though they will create one. - am_cv_prog_cc_c_o=yes - for am_i in 1 2; do - if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 - ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } \ - && test -f conftest2.$ac_objext; then - : OK - else - am_cv_prog_cc_c_o=no - break - fi - done - rm -f core conftest* - unset am_i -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 -$as_echo "$am_cv_prog_cc_c_o" >&6; } -if test "$am_cv_prog_cc_c_o" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 -$as_echo_n "checking how to run the C preprocessor... " >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if ${ac_cv_prog_CPP+:} false; then : - $as_echo_n "(cached) " >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - # <limits.h> exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <ac_nonexistent.h> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 -$as_echo "$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - # <limits.h> exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <ac_nonexistent.h> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 -$as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if ${ac_cv_path_GREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$GREP"; then - ac_path_GREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_GREP" || continue -# Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_GREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_GREP"; then - as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_GREP=$GREP -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 -$as_echo "$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 -$as_echo_n "checking for egrep... " >&6; } -if ${ac_cv_path_EGREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - if test -z "$EGREP"; then - ac_path_EGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_EGREP" || continue -# Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_EGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_EGREP"; then - as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_EGREP=$EGREP -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 -$as_echo "$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <float.h> - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stdc=yes -else - ac_cv_header_stdc=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <string.h> - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdlib.h> - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : - : -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <ctype.h> -#include <stdlib.h> -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - -else - ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -$as_echo "#define STDC_HEADERS 1" >>confdefs.h - -fi - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default -" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - - - ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" -if test "x$ac_cv_header_minix_config_h" = xyes; then : - MINIX=yes -else - MINIX= -fi - - - if test "$MINIX" = yes; then - -$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h - - -$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h - - -$as_echo "#define _MINIX 1" >>confdefs.h - - fi - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 -$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } -if ${ac_cv_safe_to_define___extensions__+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -# define __EXTENSIONS__ 1 - $ac_includes_default -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_safe_to_define___extensions__=yes -else - ac_cv_safe_to_define___extensions__=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 -$as_echo "$ac_cv_safe_to_define___extensions__" >&6; } - test $ac_cv_safe_to_define___extensions__ = yes && - $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h - - $as_echo "#define _ALL_SOURCE 1" >>confdefs.h - - $as_echo "#define _GNU_SOURCE 1" >>confdefs.h - - $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h - - $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h - - - -am__api_version='1.15' - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -$as_echo_n "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if ${ac_cv_path_install+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in #(( - ./ | .// | /[cC]/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done - ;; -esac - - done -IFS=$as_save_IFS - -rm -rf conftest.one conftest.two conftest.dir - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -$as_echo "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 -$as_echo_n "checking whether build environment is sane... " >&6; } -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[\\\"\#\$\&\'\`$am_lf]*) - as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; -esac -case $srcdir in - *[\\\"\#\$\&\'\`$am_lf\ \ ]*) - as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; -esac - -# Do 'set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - as_fn_error $? "ls -t appears to fail. Make sure there is not a broken - alias in your environment" "$LINENO" 5 - fi - if test "$2" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$2" = conftest.file - ) -then - # Ok. - : -else - as_fn_error $? "newly created file is older than distributed files! -Check your system clock" "$LINENO" 5 -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & - am_sleep_pid=$! -fi - -rm -f conftest.file - -test "$program_prefix" != NONE && - program_transform_name="s&^&$program_prefix&;$program_transform_name" -# Use a double $ so make ignores it. -test "$program_suffix" != NONE && - program_transform_name="s&\$&$program_suffix&;$program_transform_name" -# Double any \ or $. -# By default was `s,x,x', remove it if useless. -ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' -program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` - -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac -fi -# Use eval to expand $SHELL -if eval "$MISSING --is-lightweight"; then - am_missing_run="$MISSING " -else - am_missing_run= - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 -$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} -fi - -if test x"${install_sh+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi - -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. -if test "$cross_compiling" != no; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -$as_echo "$STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_STRIP="strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -$as_echo "$ac_ct_STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 -$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } -if test -z "$MKDIR_P"; then - if ${ac_cv_path_mkdir+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in mkdir gmkdir; do - for ac_exec_ext in '' $ac_executable_extensions; do - as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue - case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( - 'mkdir (GNU coreutils) '* | \ - 'mkdir (coreutils) '* | \ - 'mkdir (fileutils) '4.1*) - ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext - break 3;; - esac - done - done - done -IFS=$as_save_IFS - -fi - - test -d ./--version && rmdir ./--version - if test "${ac_cv_path_mkdir+set}" = set; then - MKDIR_P="$ac_cv_path_mkdir -p" - else - # As a last resort, use the slow shell script. Don't cache a - # value for MKDIR_P within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - MKDIR_P="$ac_install_sh -d" - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 -$as_echo "$MKDIR_P" >&6; } - -for ac_prog in gawk mawk nawk awk -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AWK+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AWK"; then - ac_cv_prog_AWK="$AWK" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AWK="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AWK=$ac_cv_prog_AWK -if test -n "$AWK"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 -$as_echo "$AWK" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AWK" && break -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } -set x ${MAKE-make} -ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat >conftest.make <<\_ACEOF -SHELL = /bin/sh -all: - @echo '@@@%%%=$(MAKE)=@@@%%%' -_ACEOF -# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. -case `${MAKE-make} -f conftest.make 2>/dev/null` in - *@@@%%%=?*=@@@%%%*) - eval ac_cv_prog_make_${ac_make}_set=yes;; - *) - eval ac_cv_prog_make_${ac_make}_set=no;; -esac -rm -f conftest.make -fi -if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - SET_MAKE= -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - SET_MAKE="MAKE=${MAKE-make}" -fi - -rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null - -DEPDIR="${am__leading_dot}deps" - -ac_config_commands="$ac_config_commands depfiles" - - -am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo this is the am__doit target -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 -$as_echo_n "checking for style of include used by $am_make... " >&6; } -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 -$as_echo "$_am_result" >&6; } -rm -f confinc confmf - -# Check whether --enable-dependency-tracking was given. -if test "${enable_dependency_tracking+set}" = set; then : - enableval=$enable_dependency_tracking; -fi - -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' - am__nodep='_no' -fi - if test "x$enable_dependency_tracking" != xno; then - AMDEP_TRUE= - AMDEP_FALSE='#' -else - AMDEP_TRUE='#' - AMDEP_FALSE= -fi - - -# Check whether --enable-silent-rules was given. -if test "${enable_silent_rules+set}" = set; then : - enableval=$enable_silent_rules; -fi - -case $enable_silent_rules in # ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=1;; -esac -am_make=${MAKE-make} -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 -$as_echo_n "checking whether $am_make supports nested variables... " >&6; } -if ${am_cv_make_support_nested_variables+:} false; then : - $as_echo_n "(cached) " >&6 -else - if $as_echo 'TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 -$as_echo "$am_cv_make_support_nested_variables" >&6; } -if test $am_cv_make_support_nested_variables = yes; then - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AM_BACKSLASH='\' - -# Check whether --enable-compiler-warnings was given. -if test "${enable_compiler_warnings+set}" = set; then : - enableval=$enable_compiler_warnings; -fi -case $enable_compiler_warnings in #( - no | min | yes | max | all) : - ;; #( - *) : - if test "x$enable_maintainer_mode" = xyes; then : - enable_compiler_warnings=yes -else - enable_compiler_warnings=min -fi ;; -esac - - -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - am__isrc=' -I$(srcdir)' - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi - - -# Define the identity of the package. - PACKAGE='cairo--tex-live-' - VERSION='1.14.8' - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE "$PACKAGE" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define VERSION "$VERSION" -_ACEOF - -# Some tools Automake needs. - -ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} - - -AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} - - -AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} - - -AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} - - -MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} - -# For better backward compatibility. To be removed once Automake 1.9.x -# dies out for good. For more background, see: -# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> -# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> -mkdir_p='$(MKDIR_P)' - -# We need awk for the "check" target (and possibly the TAP driver). The -# system "awk" is bad on some platforms. -# Always define AMTAR for backward compatibility. Yes, it's still used -# in the wild :-( We should find a proper way to deprecate it ... -AMTAR='$${TAR-tar}' - - -# We'll loop over all known methods to create a tar archive until one works. -_am_tools='gnutar pax cpio none' - -am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' - - - - - -depcc="$CC" am_compiler_list= - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if ${am_cv_CC_dependencies_compiler_type+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named 'D' -- because '-MD' means "put the output - # in D". - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CC_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - am__universal=false - case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with - # Solaris 10 /bin/sh. - echo '/* dummy */' > sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with '-c' and '-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle '-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs. - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # After this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested. - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok '-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CC_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CC_dependencies_compiler_type=none -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 -$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } -CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type - - if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then - am__fastdepCC_TRUE= - am__fastdepCC_FALSE='#' -else - am__fastdepCC_TRUE='#' - am__fastdepCC_FALSE= -fi - - - -# POSIX will say in a future version that running "rm -f" with no argument -# is OK; and we want to be able to make that assumption in our Makefile -# recipes. So use an aggressive probe to check that the usage we want is -# actually supported "in the wild" to an acceptable degree. -# See automake bug#10828. -# To make any issue more visible, cause the running configure to be aborted -# by default if the 'rm' program in use doesn't match our expectations; the -# user can still override this though. -if rm -f && rm -fr && rm -rf; then : OK; else - cat >&2 <<'END' -Oops! - -Your 'rm' program seems unable to run without file operands specified -on the command line, even when the '-f' option is present. This is contrary -to the behaviour of most rm programs out there, and not conforming with -the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> - -Please tell bug-automake@gnu.org about your system, including the value -of your $PATH and any error possibly output before this message. This -can help us improve future automake versions. - -END - if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then - echo 'Configuration will proceed anyway, since you have set the' >&2 - echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 - echo >&2 - else - cat >&2 <<'END' -Aborting the configuration process, to ensure you take notice of the issue. - -You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: <http://www.gnu.org/software/coreutils/>. - -If you want to complete the configuration process using your problematic -'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM -to "yes", and re-run configure. - -END - as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 - fi -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 -$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } - # Check whether --enable-maintainer-mode was given. -if test "${enable_maintainer_mode+set}" = set; then : - enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval -else - USE_MAINTAINER_MODE=no -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 -$as_echo "$USE_MAINTAINER_MODE" >&6; } - if test $USE_MAINTAINER_MODE = yes; then - MAINTAINER_MODE_TRUE= - MAINTAINER_MODE_FALSE='#' -else - MAINTAINER_MODE_TRUE='#' - MAINTAINER_MODE_FALSE= -fi - - MAINT=$MAINTAINER_MODE_TRUE - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler accepts prototypes" >&5 -$as_echo_n "checking whether the compiler accepts prototypes... " >&6; } -if ${kb_cv_c_prototypes+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdarg.h> -int -main () -{ -extern void foo(int i,...); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - kb_cv_c_prototypes=yes -else - kb_cv_c_prototypes=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kb_cv_c_prototypes" >&5 -$as_echo "$kb_cv_c_prototypes" >&6; } -if test "x$kb_cv_c_prototypes" = xno; then - as_fn_error $? "Sorry, your compiler does not understand prototypes." "$LINENO" 5 -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking what warning flags to pass to the C compiler" >&5 -$as_echo_n "checking what warning flags to pass to the C compiler... " >&6; } -if ${kpse_cv_warning_cflags+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "x$GCC" = xyes; then - kpse_cv_warning_cflags= -if test "x$enable_compiler_warnings" != xno; then - kpse_cv_warning_cflags="-Wimplicit -Wreturn-type" - case `$CC -dumpversion` in #( - 3.4.* | 4.* | 5.*) : - kpse_cv_warning_cflags="$kpse_cv_warning_cflags -Wdeclaration-after-statement" ;; #( - *) : - ;; -esac - case `$CC -dumpversion` in #( - 3.[234].* | 4.* | 5.*) : - kpse_cv_warning_cflags="$kpse_cv_warning_cflags -Wno-unknown-pragmas" ;; #( - *) : - ;; -esac - if test "x$enable_compiler_warnings" != xmin; then - kpse_cv_warning_cflags="-Wall -Wunused $kpse_cv_warning_cflags" - kpse_cv_warning_cflags="$kpse_cv_warning_cflags -Wmissing-prototypes -Wmissing-declarations" - if test "x$enable_compiler_warnings" != xyes; then - kpse_cv_warning_cflags="$kpse_cv_warning_cflags -Wparentheses -Wswitch -Wtrigraphs -Wpointer-arith" - kpse_cv_warning_cflags="$kpse_cv_warning_cflags -Wcast-qual -Wcast-align -Wwrite-strings" - case `$CC -dumpversion` in #( - 3.4.* | 4.* | 5.*) : - kpse_cv_warning_cflags="$kpse_cv_warning_cflags -Wold-style-definition" ;; #( - *) : - ;; -esac - if test "x$enable_compiler_warnings" != xmax; then - kpse_cv_warning_cflags="$kpse_cv_warning_cflags -Wshadow" - fi - fi - fi -fi -elif test "x$enable_compiler_warnings" = xno; then - kpse_cv_warning_cflags= -else - kpse_cv_warning_cflags= # FIXME: warning flags for non-GNU C compilers -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kpse_cv_warning_cflags" >&5 -$as_echo "$kpse_cv_warning_cflags" >&6; } -WARNING_CFLAGS=$kpse_cv_warning_cflags - - - - - - - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } - -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GCC=yes -else - GCC= -fi -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -else - CFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdarg.h> -#include <stdio.h> -struct stat; -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_c89=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : - -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 -$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } -if ${am_cv_prog_cc_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF - # Make sure it works both with $CC and with simple cc. - # Following AC_PROG_CC_C_O, we do the test twice because some - # compilers refuse to overwrite an existing .o file with -o, - # though they will create one. - am_cv_prog_cc_c_o=yes - for am_i in 1 2; do - if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 - ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } \ - && test -f conftest2.$ac_objext; then - : OK - else - am_cv_prog_cc_c_o=no - break - fi - done - rm -f core conftest* - unset am_i -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 -$as_echo "$am_cv_prog_cc_c_o" >&6; } -if test "$am_cv_prog_cc_c_o" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 -$as_echo "$RANLIB" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 -$as_echo "$ac_ct_RANLIB" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_RANLIB" = x; then - RANLIB=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - RANLIB=$ac_ct_RANLIB - fi -else - RANLIB="$ac_cv_prog_RANLIB" -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 -$as_echo_n "checking whether ln -s works... " >&6; } -LN_S=$as_ln_s -if test "$LN_S" = "ln -s"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 -$as_echo "no, using $LN_S" >&6; } -fi - - case $host_os in - darwin*) - - ;; - *) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 -$as_echo_n "checking whether byte ordering is bigendian... " >&6; } -if ${ac_cv_c_bigendian+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_c_bigendian=unknown - # See if we're dealing with a universal compiler. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifndef __APPLE_CC__ - not a universal capable compiler - #endif - typedef int dummy; - -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - # Check for potential -arch flags. It is not universal unless - # there are at least two -arch flags with different values. - ac_arch= - ac_prev= - for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do - if test -n "$ac_prev"; then - case $ac_word in - i?86 | x86_64 | ppc | ppc64) - if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then - ac_arch=$ac_word - else - ac_cv_c_bigendian=universal - break - fi - ;; - esac - ac_prev= - elif test "x$ac_word" = "x-arch"; then - ac_prev=arch - fi - done -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - if test $ac_cv_c_bigendian = unknown; then - # See if sys/param.h defines the BYTE_ORDER macro. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <sys/types.h> - #include <sys/param.h> - -int -main () -{ -#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ - && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ - && LITTLE_ENDIAN) - bogus endian macros - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - # It does; now see whether it defined to BIG_ENDIAN or not. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <sys/types.h> - #include <sys/param.h> - -int -main () -{ -#if BYTE_ORDER != BIG_ENDIAN - not big endian - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_bigendian=yes -else - ac_cv_c_bigendian=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test $ac_cv_c_bigendian = unknown; then - # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <limits.h> - -int -main () -{ -#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) - bogus endian macros - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - # It does; now see whether it defined to _BIG_ENDIAN or not. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <limits.h> - -int -main () -{ -#ifndef _BIG_ENDIAN - not big endian - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_bigendian=yes -else - ac_cv_c_bigendian=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test $ac_cv_c_bigendian = unknown; then - # Compile a test program. - if test "$cross_compiling" = yes; then : - # Try to guess by grepping values from an object file. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -short int ascii_mm[] = - { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; - short int ascii_ii[] = - { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; - int use_ascii (int i) { - return ascii_mm[i] + ascii_ii[i]; - } - short int ebcdic_ii[] = - { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; - short int ebcdic_mm[] = - { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; - int use_ebcdic (int i) { - return ebcdic_mm[i] + ebcdic_ii[i]; - } - extern int foo; - -int -main () -{ -return use_ascii (foo) == use_ebcdic (foo); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then - ac_cv_c_bigendian=yes - fi - if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then - if test "$ac_cv_c_bigendian" = unknown; then - ac_cv_c_bigendian=no - else - # finding both strings is unlikely to happen, but who knows? - ac_cv_c_bigendian=unknown - fi - fi -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ - - /* Are we little or big endian? From Harbison&Steele. */ - union - { - long int l; - char c[sizeof (long int)]; - } u; - u.l = 1; - return u.c[sizeof (long int) - 1] == 1; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_c_bigendian=no -else - ac_cv_c_bigendian=yes -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 -$as_echo "$ac_cv_c_bigendian" >&6; } - case $ac_cv_c_bigendian in #( - yes) - $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h -;; #( - no) - ;; #( - universal) - -$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h - - ;; #( - *) - as_fn_error $? "unknown endianness - presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; - esac - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether float word ordering is bigendian" >&5 -$as_echo_n "checking whether float word ordering is bigendian... " >&6; } -if ${ax_cv_c_float_words_bigendian+:} false; then : - $as_echo_n "(cached) " >&6 -else - - -# The endianess is detected by first compiling C code that contains a special -# double float value, then grepping the resulting object file for certain -# strings of ascii values. The double is specially crafted to have a -# binary representation that corresponds with a simple string. In this -# implementation, the string "noonsees" was selected because the individual -# word values ("noon" and "sees") are palindromes, thus making this test -# byte-order agnostic. If grep finds the string "noonsees" in the object -# file, the target platform stores float words in big-endian order. If grep -# finds "seesnoon", float words are in little-endian order. If neither value -# is found, the user is instructed to specify the ordering. - -ax_cv_c_float_words_bigendian=unknown -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -double d = 90904234967036810337470478905505011476211692735615632014797120844053488865816695273723469097858056257517020191247487429516932130503560650002327564517570778480236724525140520121371739201496540132640109977779420565776568942592.0; - - -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - -if strings - conftest.$ac_objext | grep noonsees >/dev/null ; then - ax_cv_c_float_words_bigendian=yes -fi -if strings - conftest.$ac_objext | grep seesnoon >/dev/null ; then - if test "$ax_cv_c_float_words_bigendian" = unknown; then - ax_cv_c_float_words_bigendian=no - else - ax_cv_c_float_words_bigendian=unknown - fi -fi - - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_c_float_words_bigendian" >&5 -$as_echo "$ax_cv_c_float_words_bigendian" >&6; } - -case $ax_cv_c_float_words_bigendian in - yes) - -$as_echo "#define FLOAT_WORDS_BIGENDIAN 1" >>confdefs.h - ;; - no) - ;; - *) - as_fn_error $? " - -Unknown float word ordering. You need to manually preset -ax_cv_c_float_words_bigendian=no (or yes) according to your system. - - " "$LINENO" 5 ;; -esac - - - ;; - esac - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking CFLAGS for C to hide external symbols" >&5 -$as_echo_n "checking CFLAGS for C to hide external symbols... " >&6; } -if ${kpse_cv_visibility_cflags+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -kpse_cv_visibility_cflags=unknown -kpse_save_flags=$CFLAGS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdio.h> - extern void foo(void); - void foo(void){printf("foo\n");} -_ACEOF -# FIXME: Add tests for non-GNU compilers -for kpse_flag in '-fvisibility=hidden -fvisibility-inlines-hidden' '-fvisibility=hidden'; do - CFLAGS="$kpse_save_flags -Werror $kpse_flag" - if ac_fn_c_try_compile "$LINENO"; then : - kpse_cv_visibility_cflags=$kpse_flag; break -fi -rm -f core conftest.err conftest.$ac_objext -done -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kpse_cv_visibility_cflags" >&5 -$as_echo "$kpse_cv_visibility_cflags" >&6; } -CFLAGS=$kpse_save_flags -case $kpse_cv_visibility_cflags in #( - unknown) : - ;; #( - *) : - VISIBILITY_CFLAGS=$kpse_cv_visibility_cflags - ;; -esac - - - - - -cairo_attribute_flag= -if test "x$GCC" = xyes; then - case `$CC -dumpversion` in #( - 4.[01].* ) : - ;; #( - 4.* | 5.*) : - cairo_attribute_flag=-Wno-attributes ;; #( - *) : - ;; -esac -fi -CAIRO_ATTRIBUTE_FLAG=$cairo_attribute_flag - - -# The cast to long int works around a bug in the HP C Compiler -# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -# This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5 -$as_echo_n "checking size of void *... " >&6; } -if ${ac_cv_sizeof_void_p+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default"; then : - -else - if test "$ac_cv_type_void_p" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (void *) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_void_p=0 - fi -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5 -$as_echo "$ac_cv_sizeof_void_p" >&6; } - - - -cat >>confdefs.h <<_ACEOF -#define SIZEOF_VOID_P $ac_cv_sizeof_void_p -_ACEOF - - -# The cast to long int works around a bug in the HP C Compiler -# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -# This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 -$as_echo_n "checking size of int... " >&6; } -if ${ac_cv_sizeof_int+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then : - -else - if test "$ac_cv_type_int" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (int) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_int=0 - fi -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 -$as_echo "$ac_cv_sizeof_int" >&6; } - - - -cat >>confdefs.h <<_ACEOF -#define SIZEOF_INT $ac_cv_sizeof_int -_ACEOF - - -# The cast to long int works around a bug in the HP C Compiler -# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -# This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 -$as_echo_n "checking size of long... " >&6; } -if ${ac_cv_sizeof_long+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then : - -else - if test "$ac_cv_type_long" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (long) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_long=0 - fi -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 -$as_echo "$ac_cv_sizeof_long" >&6; } - - - -cat >>confdefs.h <<_ACEOF -#define SIZEOF_LONG $ac_cv_sizeof_long -_ACEOF - - -# The cast to long int works around a bug in the HP C Compiler -# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -# This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5 -$as_echo_n "checking size of long long... " >&6; } -if ${ac_cv_sizeof_long_long+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long" "$ac_includes_default"; then : - -else - if test "$ac_cv_type_long_long" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (long long) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_long_long=0 - fi -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5 -$as_echo "$ac_cv_sizeof_long_long" >&6; } - - - -cat >>confdefs.h <<_ACEOF -#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long -_ACEOF - - -# The cast to long int works around a bug in the HP C Compiler -# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -# This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of size_t" >&5 -$as_echo_n "checking size of size_t... " >&6; } -if ${ac_cv_sizeof_size_t+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (size_t))" "ac_cv_sizeof_size_t" "$ac_includes_default"; then : - -else - if test "$ac_cv_type_size_t" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (size_t) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_size_t=0 - fi -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_size_t" >&5 -$as_echo "$ac_cv_sizeof_size_t" >&6; } - - - -cat >>confdefs.h <<_ACEOF -#define SIZEOF_SIZE_T $ac_cv_sizeof_size_t -_ACEOF - - - -for ac_header in sys/int_types.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "sys/int_types.h" "ac_cv_header_sys_int_types_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_int_types_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_SYS_INT_TYPES_H 1 -_ACEOF - -fi - -done - -ac_fn_c_check_type "$LINENO" "uint64_t" "ac_cv_type_uint64_t" "$ac_includes_default" -if test "x$ac_cv_type_uint64_t" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_UINT64_T 1 -_ACEOF - - -fi -ac_fn_c_check_type "$LINENO" "uint128_t" "ac_cv_type_uint128_t" "$ac_includes_default" -if test "x$ac_cv_type_uint128_t" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_UINT128_T 1 -_ACEOF - - -fi -ac_fn_c_check_type "$LINENO" "__uint128_t" "ac_cv_type___uint128_t" "$ac_includes_default" -if test "x$ac_cv_type___uint128_t" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE___UINT128_T 1 -_ACEOF - - -fi - - -ac_config_headers="$ac_config_headers config.h cairo-features.h" - - - if test "x$enable_build" != xno; then - build_TRUE= - build_FALSE='#' -else - build_TRUE='#' - build_FALSE= -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing sqrt" >&5 -$as_echo_n "checking for library containing sqrt... " >&6; } -if ${ac_cv_search_sqrt+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char sqrt (); -int -main () -{ -return sqrt (); - ; - return 0; -} -_ACEOF -for ac_lib in '' m; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_sqrt=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_sqrt+:} false; then : - break -fi -done -if ${ac_cv_search_sqrt+:} false; then : - -else - ac_cv_search_sqrt=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_sqrt" >&5 -$as_echo "$ac_cv_search_sqrt" >&6; } -ac_res=$ac_cv_search_sqrt -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - - -if test "x0" = x1; then - -$as_echo "#define CAIRO_HAS_FC_FONT 1" >>confdefs.h - -fi - if test "x0" = x1; then - CAIRO_HAS_FC_FONT_TRUE= - CAIRO_HAS_FC_FONT_FALSE='#' -else - CAIRO_HAS_FC_FONT_TRUE='#' - CAIRO_HAS_FC_FONT_FALSE= -fi - -if test "x0" = x1; then - -$as_echo "#define CAIRO_HAS_FT_FONT 1" >>confdefs.h - -fi - if test "x0" = x1; then - CAIRO_HAS_FT_FONT_TRUE= - CAIRO_HAS_FT_FONT_FALSE='#' -else - CAIRO_HAS_FT_FONT_TRUE='#' - CAIRO_HAS_FT_FONT_FALSE= -fi - -if test "x0" = x1; then - -$as_echo "#define CAIRO_HAS_QUARTZ_FONT 1" >>confdefs.h - -fi - if test "x0" = x1; then - CAIRO_HAS_QUARTZ_FONT_TRUE= - CAIRO_HAS_QUARTZ_FONT_FALSE='#' -else - CAIRO_HAS_QUARTZ_FONT_TRUE='#' - CAIRO_HAS_QUARTZ_FONT_FALSE= -fi - -if test "x1" = x1; then - -$as_echo "#define CAIRO_HAS_USER_FONT 1" >>confdefs.h - -fi - if test "x1" = x1; then - CAIRO_HAS_USER_FONT_TRUE= - CAIRO_HAS_USER_FONT_FALSE='#' -else - CAIRO_HAS_USER_FONT_TRUE='#' - CAIRO_HAS_USER_FONT_FALSE= -fi - -if test "x0" = x1; then - -$as_echo "#define CAIRO_HAS_WIN32_FONT 1" >>confdefs.h - -fi - if test "x0" = x1; then - CAIRO_HAS_WIN32_FONT_TRUE= - CAIRO_HAS_WIN32_FONT_FALSE='#' -else - CAIRO_HAS_WIN32_FONT_TRUE='#' - CAIRO_HAS_WIN32_FONT_FALSE= -fi - -if test "x0" = x1; then - -$as_echo "#define CAIRO_HAS_EGL_FUNCTIONS 1" >>confdefs.h - -fi - if test "x0" = x1; then - CAIRO_HAS_EGL_FUNCTIONS_TRUE= - CAIRO_HAS_EGL_FUNCTIONS_FALSE='#' -else - CAIRO_HAS_EGL_FUNCTIONS_TRUE='#' - CAIRO_HAS_EGL_FUNCTIONS_FALSE= -fi - -if test "x0" = x1; then - -$as_echo "#define CAIRO_HAS_GLX_FUNCTIONS 1" >>confdefs.h - -fi - if test "x0" = x1; then - CAIRO_HAS_GLX_FUNCTIONS_TRUE= - CAIRO_HAS_GLX_FUNCTIONS_FALSE='#' -else - CAIRO_HAS_GLX_FUNCTIONS_TRUE='#' - CAIRO_HAS_GLX_FUNCTIONS_FALSE= -fi - -if test "x0" = x1; then - -$as_echo "#define CAIRO_HAS_GOBJECT_FUNCTIONS 1" >>confdefs.h - -fi - if test "x0" = x1; then - CAIRO_HAS_GOBJECT_FUNCTIONS_TRUE= - CAIRO_HAS_GOBJECT_FUNCTIONS_FALSE='#' -else - CAIRO_HAS_GOBJECT_FUNCTIONS_TRUE='#' - CAIRO_HAS_GOBJECT_FUNCTIONS_FALSE= -fi - -if test "x0" = x1; then - -$as_echo "#define CAIRO_HAS_PNG_FUNCTIONS 1" >>confdefs.h - -fi - if test "x0" = x1; then - CAIRO_HAS_PNG_FUNCTIONS_TRUE= - CAIRO_HAS_PNG_FUNCTIONS_FALSE='#' -else - CAIRO_HAS_PNG_FUNCTIONS_TRUE='#' - CAIRO_HAS_PNG_FUNCTIONS_FALSE= -fi - -if test "x0" = x1; then - -$as_echo "#define CAIRO_HAS_WGL_FUNCTIONS 1" >>confdefs.h - -fi - if test "x0" = x1; then - CAIRO_HAS_WGL_FUNCTIONS_TRUE= - CAIRO_HAS_WGL_FUNCTIONS_FALSE='#' -else - CAIRO_HAS_WGL_FUNCTIONS_TRUE='#' - CAIRO_HAS_WGL_FUNCTIONS_FALSE= -fi - -if test "x0" = x1; then - -$as_echo "#define CAIRO_HAS_WIN32_FUNCTIONS 1" >>confdefs.h - -fi - if test "x0" = x1; then - CAIRO_HAS_WIN32_FUNCTIONS_TRUE= - CAIRO_HAS_WIN32_FUNCTIONS_FALSE='#' -else - CAIRO_HAS_WIN32_FUNCTIONS_TRUE='#' - CAIRO_HAS_WIN32_FUNCTIONS_FALSE= -fi - -if test "x0" = x1; then - -$as_echo "#define CAIRO_HAS_XCB_SHM_FUNCTIONS 1" >>confdefs.h - -fi - if test "x0" = x1; then - CAIRO_HAS_XCB_SHM_FUNCTIONS_TRUE= - CAIRO_HAS_XCB_SHM_FUNCTIONS_FALSE='#' -else - CAIRO_HAS_XCB_SHM_FUNCTIONS_TRUE='#' - CAIRO_HAS_XCB_SHM_FUNCTIONS_FALSE= -fi - -if test "x1" = x1; then - -$as_echo "#define CAIRO_HAS_IMAGE_SURFACE 1" >>confdefs.h - -fi - if test "x1" = x1; then - CAIRO_HAS_IMAGE_SURFACE_TRUE= - CAIRO_HAS_IMAGE_SURFACE_FALSE='#' -else - CAIRO_HAS_IMAGE_SURFACE_TRUE='#' - CAIRO_HAS_IMAGE_SURFACE_FALSE= -fi - -if test "x1" = x1; then - -$as_echo "#define CAIRO_HAS_MIME_SURFACE 1" >>confdefs.h - -fi - if test "x1" = x1; then - CAIRO_HAS_MIME_SURFACE_TRUE= - CAIRO_HAS_MIME_SURFACE_FALSE='#' -else - CAIRO_HAS_MIME_SURFACE_TRUE='#' - CAIRO_HAS_MIME_SURFACE_FALSE= -fi - -if test "x1" = x1; then - -$as_echo "#define CAIRO_HAS_OBSERVER_SURFACE 1" >>confdefs.h - -fi - if test "x1" = x1; then - CAIRO_HAS_OBSERVER_SURFACE_TRUE= - CAIRO_HAS_OBSERVER_SURFACE_FALSE='#' -else - CAIRO_HAS_OBSERVER_SURFACE_TRUE='#' - CAIRO_HAS_OBSERVER_SURFACE_FALSE= -fi - -if test "x1" = x1; then - -$as_echo "#define CAIRO_HAS_RECORDING_SURFACE 1" >>confdefs.h - -fi - if test "x1" = x1; then - CAIRO_HAS_RECORDING_SURFACE_TRUE= - CAIRO_HAS_RECORDING_SURFACE_FALSE='#' -else - CAIRO_HAS_RECORDING_SURFACE_TRUE='#' - CAIRO_HAS_RECORDING_SURFACE_FALSE= -fi - -if test "x0" = x1; then - -$as_echo "#define CAIRO_HAS_PDF_SURFACE 1" >>confdefs.h - -fi - if test "x0" = x1; then - CAIRO_HAS_PDF_SURFACE_TRUE= - CAIRO_HAS_PDF_SURFACE_FALSE='#' -else - CAIRO_HAS_PDF_SURFACE_TRUE='#' - CAIRO_HAS_PDF_SURFACE_FALSE= -fi - -if test "x0" = x1; then - -$as_echo "#define CAIRO_HAS_PS_SURFACE 1" >>confdefs.h - -fi - if test "x0" = x1; then - CAIRO_HAS_PS_SURFACE_TRUE= - CAIRO_HAS_PS_SURFACE_FALSE='#' -else - CAIRO_HAS_PS_SURFACE_TRUE='#' - CAIRO_HAS_PS_SURFACE_FALSE= -fi - -if test "x0" = x1; then - -$as_echo "#define CAIRO_HAS_QUARTZ_SURFACE 1" >>confdefs.h - -fi - if test "x0" = x1; then - CAIRO_HAS_QUARTZ_SURFACE_TRUE= - CAIRO_HAS_QUARTZ_SURFACE_FALSE='#' -else - CAIRO_HAS_QUARTZ_SURFACE_TRUE='#' - CAIRO_HAS_QUARTZ_SURFACE_FALSE= -fi - -if test "x0" = x1; then - -$as_echo "#define CAIRO_HAS_SCRIPT_SURFACE 1" >>confdefs.h - -fi - if test "x0" = x1; then - CAIRO_HAS_SCRIPT_SURFACE_TRUE= - CAIRO_HAS_SCRIPT_SURFACE_FALSE='#' -else - CAIRO_HAS_SCRIPT_SURFACE_TRUE='#' - CAIRO_HAS_SCRIPT_SURFACE_FALSE= -fi - -if test "x0" = x1; then - -$as_echo "#define CAIRO_HAS_SVG_SURFACE 1" >>confdefs.h - -fi - if test "x0" = x1; then - CAIRO_HAS_SVG_SURFACE_TRUE= - CAIRO_HAS_SVG_SURFACE_FALSE='#' -else - CAIRO_HAS_SVG_SURFACE_TRUE='#' - CAIRO_HAS_SVG_SURFACE_FALSE= -fi - -if test "x0" = x1; then - -$as_echo "#define CAIRO_HAS_WIN32_SURFACE 1" >>confdefs.h - -fi - if test "x0" = x1; then - CAIRO_HAS_WIN32_SURFACE_TRUE= - CAIRO_HAS_WIN32_SURFACE_FALSE='#' -else - CAIRO_HAS_WIN32_SURFACE_TRUE='#' - CAIRO_HAS_WIN32_SURFACE_FALSE= -fi - -if test "x0" = x1; then - -$as_echo "#define CAIRO_HAS_XCB_SURFACE 1" >>confdefs.h - -fi - if test "x0" = x1; then - CAIRO_HAS_XCB_SURFACE_TRUE= - CAIRO_HAS_XCB_SURFACE_FALSE='#' -else - CAIRO_HAS_XCB_SURFACE_TRUE='#' - CAIRO_HAS_XCB_SURFACE_FALSE= -fi - -if test "x0" = x1; then - -$as_echo "#define CAIRO_HAS_XLIB_SURFACE 1" >>confdefs.h - -fi - if test "x0" = x1; then - CAIRO_HAS_XLIB_SURFACE_TRUE= - CAIRO_HAS_XLIB_SURFACE_FALSE='#' -else - CAIRO_HAS_XLIB_SURFACE_TRUE='#' - CAIRO_HAS_XLIB_SURFACE_FALSE= -fi - -if test "x0" = x1; then - -$as_echo "#define CAIRO_HAS_XLIB_XRENDER_SURFACE 1" >>confdefs.h - -fi - if test "x0" = x1; then - CAIRO_HAS_XLIB_XRENDER_SURFACE_TRUE= - CAIRO_HAS_XLIB_XRENDER_SURFACE_FALSE='#' -else - CAIRO_HAS_XLIB_XRENDER_SURFACE_TRUE='#' - CAIRO_HAS_XLIB_XRENDER_SURFACE_FALSE= -fi - - - - if false; then - CAIRO_HAS_QUARTZ_IMAGE_SURFACE_TRUE= - CAIRO_HAS_QUARTZ_IMAGE_SURFACE_FALSE='#' -else - CAIRO_HAS_QUARTZ_IMAGE_SURFACE_TRUE='#' - CAIRO_HAS_QUARTZ_IMAGE_SURFACE_FALSE= -fi - - if false; then - CAIRO_HAS_OS2_SURFACE_TRUE= - CAIRO_HAS_OS2_SURFACE_FALSE='#' -else - CAIRO_HAS_OS2_SURFACE_TRUE='#' - CAIRO_HAS_OS2_SURFACE_FALSE= -fi - - if false; then - CAIRO_HAS_GL_SURFACE_TRUE= - CAIRO_HAS_GL_SURFACE_FALSE='#' -else - CAIRO_HAS_GL_SURFACE_TRUE='#' - CAIRO_HAS_GL_SURFACE_FALSE= -fi - - -## _KPSE_INIT: Initialize TL infrastructure -kpse_BLD=`(cd "./../../." && pwd)` -kpse_SRC=`(cd "$srcdir/../../." && pwd)` - -# Make sure we can run config.sub. -$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || - as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 -$as_echo_n "checking build system type... " >&6; } -if ${ac_cv_build+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_build_alias=$build_alias -test "x$ac_build_alias" = x && - ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` -test "x$ac_build_alias" = x && - as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 -ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 -$as_echo "$ac_cv_build" >&6; } -case $ac_cv_build in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; -esac -build=$ac_cv_build -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_build -shift -build_cpu=$1 -build_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -build_os=$* -IFS=$ac_save_IFS -case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 -$as_echo_n "checking host system type... " >&6; } -if ${ac_cv_host+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "x$host_alias" = x; then - ac_cv_host=$ac_cv_build -else - ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 -$as_echo "$ac_cv_host" >&6; } -case $ac_cv_host in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; -esac -host=$ac_cv_host -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_host -shift -host_cpu=$1 -host_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -host_os=$* -IFS=$ac_save_IFS -case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. -set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_PKG_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$PKG_CONFIG"; then - ac_cv_prog_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_PKG_CONFIG="${ac_tool_prefix}pkg-config" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -PKG_CONFIG=$ac_cv_prog_PKG_CONFIG -if test -n "$PKG_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 -$as_echo "$PKG_CONFIG" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_PKG_CONFIG"; then - ac_ct_PKG_CONFIG=$PKG_CONFIG - # Extract the first word of "pkg-config", so it can be a program name with args. -set dummy pkg-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_PKG_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_PKG_CONFIG"; then - ac_cv_prog_ac_ct_PKG_CONFIG="$ac_ct_PKG_CONFIG" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_PKG_CONFIG="pkg-config" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_PKG_CONFIG=$ac_cv_prog_ac_ct_PKG_CONFIG -if test -n "$ac_ct_PKG_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_PKG_CONFIG" >&5 -$as_echo "$ac_ct_PKG_CONFIG" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_PKG_CONFIG" = x; then - PKG_CONFIG="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - PKG_CONFIG=$ac_ct_PKG_CONFIG - fi -else - PKG_CONFIG="$ac_cv_prog_PKG_CONFIG" -fi - -## _KPSE_LIB_FLAGS: Setup pixman (-lpixman) flags - -# Check whether --with-system-pixman was given. -if test "${with_system_pixman+set}" = set; then : - withval=$with_system_pixman; -fi -if test "x$with_system_pixman" = xyes; then - if $PKG_CONFIG pixman-1 --atleast-version=0.18; then - PIXMAN_INCLUDES=`$PKG_CONFIG pixman-1 --cflags` - PIXMAN_LIBS=`$PKG_CONFIG pixman-1 --libs` -elif test "x$need_pixman:$with_system_pixman" = xyes:yes; then - as_fn_error $? "did not find pixman-1 0.18 or better" "$LINENO" 5 -fi -else - PIXMAN_INCLUDES="-I$kpse_BLD/libs/pixman/include" - PIXMAN_LIBS="$kpse_BLD/libs/pixman/libpixman.a" - PIXMAN_DEPEND='${top_builddir}/../../libs/pixman/libpixman.a' - PIXMAN_RULE='# Rebuild libpixman -$(PIXMAN_DEPEND): ${top_builddir}/../../libs/pixman/include/pixman.h - cd ${top_builddir}/../../libs/pixman && $(MAKE) $(AM_MAKEFLAGS) rebuild -${top_builddir}/../../libs/pixman/include/pixman.h: - cd ${top_builddir}/../../libs/pixman && $(MAKE) $(AM_MAKEFLAGS) rebuild' -fi - - -if test "x$enable_build" != xno || test -f config.force; then - -kpse_save_CPPFLAGS=$CPPFLAGS -kpse_save_LIBS=$LIBS - -eval CPPFLAGS=\"$PIXMAN_INCLUDES \$CPPFLAGS\" -eval LIBS=\"$PIXMAN_LIBS \$LIBS\" - -ac_fn_c_check_func "$LINENO" "pixman_version_string" "ac_cv_func_pixman_version_string" -if test "x$ac_cv_func_pixman_version_string" = xyes; then : - -else - as_fn_error $? "pixman not found" "$LINENO" 5 -fi - -CPPFLAGS=$kpse_save_CPPFLAGS -LIBS=$kpse_save_LIBS - - -echo timestamp >config.force -fi - -CAIRO_TREE=cairo-src - - -ac_config_files="$ac_config_files Makefile cairo/Makefile" - - -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes: double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \. - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - if test "x$cache_file" != "x/dev/null"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} - if test ! -f "$cache_file" || test -h "$cache_file"; then - cat confcache >"$cache_file" - else - case $cache_file in #( - */* | ?:*) - mv -f confcache "$cache_file"$$ && - mv -f "$cache_file"$$ "$cache_file" ;; #( - *) - mv -f confcache "$cache_file" ;; - esac - fi - fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -DEFS=-DHAVE_CONFIG_H - -ac_libobjs= -ac_ltlibobjs= -U= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`$as_echo "$ac_i" | sed "$ac_script"` - # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR - # will be set to the directory where LIBOBJS objects are built. - as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" - as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 -$as_echo_n "checking that generated files are newer than configure... " >&6; } - if test -n "$am_sleep_pid"; then - # Hide warnings about reused PIDs. - wait $am_sleep_pid 2>/dev/null - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 -$as_echo "done" >&6; } -if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then - as_fn_error $? "conditional \"AMDEP\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepCC\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi - if test -n "$EXEEXT"; then - am__EXEEXT_TRUE= - am__EXEEXT_FALSE='#' -else - am__EXEEXT_TRUE='#' - am__EXEEXT_FALSE= -fi - -if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then - as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi - -if test -z "${build_TRUE}" && test -z "${build_FALSE}"; then - as_fn_error $? "conditional \"build\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_FC_FONT_TRUE}" && test -z "${CAIRO_HAS_FC_FONT_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_FC_FONT\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_FT_FONT_TRUE}" && test -z "${CAIRO_HAS_FT_FONT_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_FT_FONT\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_QUARTZ_FONT_TRUE}" && test -z "${CAIRO_HAS_QUARTZ_FONT_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_QUARTZ_FONT\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_USER_FONT_TRUE}" && test -z "${CAIRO_HAS_USER_FONT_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_USER_FONT\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_WIN32_FONT_TRUE}" && test -z "${CAIRO_HAS_WIN32_FONT_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_WIN32_FONT\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_EGL_FUNCTIONS_TRUE}" && test -z "${CAIRO_HAS_EGL_FUNCTIONS_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_EGL_FUNCTIONS\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_GLX_FUNCTIONS_TRUE}" && test -z "${CAIRO_HAS_GLX_FUNCTIONS_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_GLX_FUNCTIONS\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_GOBJECT_FUNCTIONS_TRUE}" && test -z "${CAIRO_HAS_GOBJECT_FUNCTIONS_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_GOBJECT_FUNCTIONS\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_PNG_FUNCTIONS_TRUE}" && test -z "${CAIRO_HAS_PNG_FUNCTIONS_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_PNG_FUNCTIONS\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_WGL_FUNCTIONS_TRUE}" && test -z "${CAIRO_HAS_WGL_FUNCTIONS_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_WGL_FUNCTIONS\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_WIN32_FUNCTIONS_TRUE}" && test -z "${CAIRO_HAS_WIN32_FUNCTIONS_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_WIN32_FUNCTIONS\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_XCB_SHM_FUNCTIONS_TRUE}" && test -z "${CAIRO_HAS_XCB_SHM_FUNCTIONS_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_XCB_SHM_FUNCTIONS\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_IMAGE_SURFACE_TRUE}" && test -z "${CAIRO_HAS_IMAGE_SURFACE_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_IMAGE_SURFACE\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_MIME_SURFACE_TRUE}" && test -z "${CAIRO_HAS_MIME_SURFACE_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_MIME_SURFACE\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_OBSERVER_SURFACE_TRUE}" && test -z "${CAIRO_HAS_OBSERVER_SURFACE_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_OBSERVER_SURFACE\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_RECORDING_SURFACE_TRUE}" && test -z "${CAIRO_HAS_RECORDING_SURFACE_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_RECORDING_SURFACE\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_PDF_SURFACE_TRUE}" && test -z "${CAIRO_HAS_PDF_SURFACE_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_PDF_SURFACE\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_PS_SURFACE_TRUE}" && test -z "${CAIRO_HAS_PS_SURFACE_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_PS_SURFACE\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_QUARTZ_SURFACE_TRUE}" && test -z "${CAIRO_HAS_QUARTZ_SURFACE_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_QUARTZ_SURFACE\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_SCRIPT_SURFACE_TRUE}" && test -z "${CAIRO_HAS_SCRIPT_SURFACE_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_SCRIPT_SURFACE\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_SVG_SURFACE_TRUE}" && test -z "${CAIRO_HAS_SVG_SURFACE_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_SVG_SURFACE\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_WIN32_SURFACE_TRUE}" && test -z "${CAIRO_HAS_WIN32_SURFACE_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_WIN32_SURFACE\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_XCB_SURFACE_TRUE}" && test -z "${CAIRO_HAS_XCB_SURFACE_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_XCB_SURFACE\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_XLIB_SURFACE_TRUE}" && test -z "${CAIRO_HAS_XLIB_SURFACE_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_XLIB_SURFACE\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_XLIB_XRENDER_SURFACE_TRUE}" && test -z "${CAIRO_HAS_XLIB_XRENDER_SURFACE_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_XLIB_XRENDER_SURFACE\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_QUARTZ_IMAGE_SURFACE_TRUE}" && test -z "${CAIRO_HAS_QUARTZ_IMAGE_SURFACE_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_QUARTZ_IMAGE_SURFACE\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_OS2_SURFACE_TRUE}" && test -z "${CAIRO_HAS_OS2_SURFACE_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_OS2_SURFACE\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${CAIRO_HAS_GL_SURFACE_TRUE}" && test -z "${CAIRO_HAS_GL_SURFACE_FALSE}"; then - as_fn_error $? "conditional \"CAIRO_HAS_GL_SURFACE\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi - -: "${CONFIG_STATUS=./config.status}" -ac_write_fail=0 -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} -as_write_fail=0 -cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false - -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 -## ----------------------------------- ## -## Main body of $CONFIG_STATUS script. ## -## ----------------------------------- ## -_ASEOF -test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# Save the log message, to keep $0 and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by cairo (TeX Live) $as_me 1.14.8, which was -generated by GNU Autoconf 2.69. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -_ACEOF - -case $ac_config_files in *" -"*) set x $ac_config_files; shift; ac_config_files=$*;; -esac - -case $ac_config_headers in *" -"*) set x $ac_config_headers; shift; ac_config_headers=$*;; -esac - - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# Files that config.status was made for. -config_files="$ac_config_files" -config_headers="$ac_config_headers" -config_commands="$ac_config_commands" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -ac_cs_usage="\ -\`$as_me' instantiates files and other configuration actions -from templates according to the current configuration. Unless the files -and actions are specified as TAGs, all are instantiated by default. - -Usage: $0 [OPTION]... [TAG]... - - -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit - --config print configuration, then exit - -q, --quiet, --silent - do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE - -Configuration files: -$config_files - -Configuration headers: -$config_headers - -Configuration commands: -$config_commands - -Report bugs to <tex-k@tug.org>." - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" -ac_cs_version="\\ -cairo (TeX Live) config.status 1.14.8 -configured by $0, generated by GNU Autoconf 2.69, - with options \\"\$ac_cs_config\\" - -Copyright (C) 2012 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='$ac_pwd' -srcdir='$srcdir' -INSTALL='$INSTALL' -MKDIR_P='$MKDIR_P' -AWK='$AWK' -test -n "\$AWK" || AWK=awk -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# The default lists apply if the user does not specify any file. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=?*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - --*=) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg= - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - $as_echo "$ac_cs_version"; exit ;; - --config | --confi | --conf | --con | --co | --c ) - $as_echo "$ac_cs_config"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - '') as_fn_error $? "missing file argument" ;; - esac - as_fn_append CONFIG_FILES " '$ac_optarg'" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - as_fn_append CONFIG_HEADERS " '$ac_optarg'" - ac_need_defaults=false;; - --he | --h) - # Conflict between --help and --header - as_fn_error $? "ambiguous option: \`$1' -Try \`$0 --help' for more information.";; - --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) as_fn_error $? "unrecognized option: \`$1' -Try \`$0 --help' for more information." ;; - - *) as_fn_append ac_config_targets " $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -if \$ac_cs_recheck; then - set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion - shift - \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 - CONFIG_SHELL='$SHELL' - export CONFIG_SHELL - exec "\$@" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - $as_echo "$ac_log" -} >&5 - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# -# INIT-COMMANDS -# -AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; - "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; - "cairo-features.h") CONFIG_HEADERS="$CONFIG_HEADERS cairo-features.h" ;; - "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "cairo/Makefile") CONFIG_FILES="$CONFIG_FILES cairo/Makefile" ;; - - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers - test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= ac_tmp= - trap 'exit_status=$? - : "${ac_tmp:=$tmp}" - { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status -' 0 - trap 'as_fn_exit 1' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 -ac_tmp=$tmp - -# Set up the scripts for CONFIG_FILES section. -# No need to generate them if there are no CONFIG_FILES. -# This happens for instance with `./config.status config.h'. -if test -n "$CONFIG_FILES"; then - - -ac_cr=`echo X | tr X '\015'` -# On cygwin, bash can eat \r inside `` if the user requested igncr. -# But we know of no other shell where ac_cr would be empty at this -# point, so we can use a bashism as a fallback. -if test "x$ac_cr" = x; then - eval ac_cr=\$\'\\r\' -fi -ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` -if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\\r' -else - ac_cs_awk_cr=$ac_cr -fi - -echo 'BEGIN {' >"$ac_tmp/subs1.awk" && -_ACEOF - - -{ - echo "cat >conf$$subs.awk <<_ACEOF" && - echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && - echo "_ACEOF" -} >conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - . ./conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - - ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` - if test $ac_delim_n = $ac_delim_num; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done -rm -f conf$$subs.sh - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && -_ACEOF -sed -n ' -h -s/^/S["/; s/!.*/"]=/ -p -g -s/^[^!]*!// -:repl -t repl -s/'"$ac_delim"'$// -t delim -:nl -h -s/\(.\{148\}\)..*/\1/ -t more1 -s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ -p -n -b repl -:more1 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t nl -:delim -h -s/\(.\{148\}\)..*/\1/ -t more2 -s/["\\]/\\&/g; s/^/"/; s/$/"/ -p -b -:more2 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t delim -' <conf$$subs.awk | sed ' -/^[^""]/{ - N - s/\n// -} -' >>$CONFIG_STATUS || ac_write_fail=1 -rm -f conf$$subs.awk -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACAWK -cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && - for (key in S) S_is_set[key] = 1 - FS = "" - -} -{ - line = $ 0 - nfields = split(line, field, "@") - substed = 0 - len = length(field[1]) - for (i = 2; i < nfields; i++) { - key = field[i] - keylen = length(key) - if (S_is_set[key]) { - value = S[key] - line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) - len += length(value) + length(field[++i]) - substed = 1 - } else - len += 1 + keylen - } - - print line -} - -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then - sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" -else - cat -fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ - || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 -_ACEOF - -# VPATH may cause trouble with some makes, so we remove sole $(srcdir), -# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ -h -s/// -s/^/:/ -s/[ ]*$/:/ -s/:\$(srcdir):/:/g -s/:\${srcdir}:/:/g -s/:@srcdir@:/:/g -s/^:*// -s/:*$// -x -s/\(=[ ]*\).*/\1/ -G -s/\n// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -fi # test -n "$CONFIG_FILES" - -# Set up the scripts for CONFIG_HEADERS section. -# No need to generate them if there are no CONFIG_HEADERS. -# This happens for instance with `./config.status Makefile'. -if test -n "$CONFIG_HEADERS"; then -cat >"$ac_tmp/defines.awk" <<\_ACAWK || -BEGIN { -_ACEOF - -# Transform confdefs.h into an awk script `defines.awk', embedded as -# here-document in config.status, that substitutes the proper values into -# config.h.in to produce config.h. - -# Create a delimiter string that does not exist in confdefs.h, to ease -# handling of long lines. -ac_delim='%!_!# ' -for ac_last_try in false false :; do - ac_tt=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_tt"; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done - -# For the awk script, D is an array of macro values keyed by name, -# likewise P contains macro parameters if any. Preserve backslash -# newline sequences. - -ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* -sed -n ' -s/.\{148\}/&'"$ac_delim"'/g -t rset -:rset -s/^[ ]*#[ ]*define[ ][ ]*/ / -t def -d -:def -s/\\$// -t bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3"/p -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p -d -:bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3\\\\\\n"\\/p -t cont -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p -t cont -d -:cont -n -s/.\{148\}/&'"$ac_delim"'/g -t clear -:clear -s/\\$// -t bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/"/p -d -:bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p -b cont -' <confdefs.h | sed ' -s/'"$ac_delim"'/"\\\ -"/g' >>$CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - for (key in D) D_is_set[key] = 1 - FS = "" -} -/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { - line = \$ 0 - split(line, arg, " ") - if (arg[1] == "#") { - defundef = arg[2] - mac1 = arg[3] - } else { - defundef = substr(arg[1], 2) - mac1 = arg[2] - } - split(mac1, mac2, "(") #) - macro = mac2[1] - prefix = substr(line, 1, index(line, defundef) - 1) - if (D_is_set[macro]) { - # Preserve the white space surrounding the "#". - print prefix "define", macro P[macro] D[macro] - next - } else { - # Replace #undef with comments. This is necessary, for example, - # in the case of _POSIX_SOURCE, which is predefined and required - # on some systems where configure will not decide to define it. - if (defundef == "undef") { - print "/*", prefix defundef, macro, "*/" - next - } - } -} -{ print } -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 -fi # test -n "$CONFIG_HEADERS" - - -eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" -shift -for ac_tag -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$ac_tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; - esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac - as_fn_append ac_file_inputs " '$ac_f'" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input='Generated from '` - $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' - `' by configure.' - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 -$as_echo "$as_me: creating $ac_file" >&6;} - fi - # Neutralize special characters interpreted by sed in replacement strings. - case $configure_input in #( - *\&* | *\|* | *\\* ) - ac_sed_conf_input=`$as_echo "$configure_input" | - sed 's/[\\\\&|]/\\\\&/g'`;; #( - *) ac_sed_conf_input=$configure_input;; - esac - - case $ac_tag in - *:-:* | *:-) cat >"$ac_tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir="$ac_dir"; as_fn_mkdir_p - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac - ac_MKDIR_P=$MKDIR_P - case $MKDIR_P in - [\\/$]* | ?:[\\/]* ) ;; - */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; - esac -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= -ac_sed_dataroot=' -/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p' -case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; -esac -_ACEOF - -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_sed_extra="$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s|@configure_input@|$ac_sed_conf_input|;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@top_build_prefix@&$ac_top_build_prefix&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t -s&@MKDIR_P@&$ac_MKDIR_P&;t t -$ac_datarootdir_hack -" -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ - >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ - "$ac_tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&2;} - - rm -f "$ac_tmp/stdin" - case $ac_file in - -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; - *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; - esac \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - ;; - :H) - # - # CONFIG_HEADER - # - if test x"$ac_file" != x-; then - { - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" - } >"$ac_tmp/config.h" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 -$as_echo "$as_me: $ac_file is unchanged" >&6;} - else - rm -f "$ac_file" - mv "$ac_tmp/config.h" "$ac_file" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - fi - else - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ - || as_fn_error $? "could not create -" "$LINENO" 5 - fi -# Compute "$ac_file"'s index in $config_headers. -_am_arg="$ac_file" -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $_am_arg | $_am_arg:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || -$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$_am_arg" : 'X\(//\)[^/]' \| \ - X"$_am_arg" : 'X\(//\)$' \| \ - X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$_am_arg" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'`/stamp-h$_am_stamp_count - ;; - - :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 -$as_echo "$as_me: executing $ac_file commands" >&6;} - ;; - esac - - - case $ac_file$ac_mode in - "depfiles":C) test x"$AMDEP_TRUE" != x"" || { - # Older Autoconf quotes --file arguments for eval, but not when files - # are listed without --file. Let's play safe and only enable the eval - # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac - shift - for mf - do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`$as_dirname -- "$mf" || -$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$mf" : 'X\(//\)[^/]' \| \ - X"$mf" : 'X\(//\)$' \| \ - X"$mf" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$mf" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`$as_dirname -- "$file" || -$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$file" : 'X\(//\)[^/]' \| \ - X"$file" : 'X\(//\)$' \| \ - X"$file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir=$dirpart/$fdir; as_fn_mkdir_p - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done - done -} - ;; - - esac -done # for ac_tag - - -as_fn_exit 0 -_ACEOF -ac_clean_files=$ac_clean_files_save - -test $ac_write_fail = 0 || - as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || as_fn_exit 1 -fi -if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} -fi - diff --git a/source/libs/cairo/configure.ac b/source/libs/cairo/configure.ac deleted file mode 100644 index 147aa8c8ea68cf910fbf84f91b2128b645dbb410..0000000000000000000000000000000000000000 --- a/source/libs/cairo/configure.ac +++ /dev/null @@ -1,99 +0,0 @@ -dnl Process this file with autoconf to produce a configure script. -dnl -dnl Copyright (C) 2012-2014 Peter Breitenlohner <tex-live@tug.org> -dnl -dnl This file is free software; the copyright holder -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. -dnl -m4_include([version.ac])[] dnl define cairo_version -AC_INIT([cairo (TeX Live)], cairo_version, [tex-k@tug.org]) -AC_PREREQ([2.65]) -AC_CONFIG_SRCDIR([cairo-src/src/cairo.h]) -AC_CONFIG_AUX_DIR([../../build-aux]) -AC_CONFIG_MACRO_DIRS([../../m4 m4]) - -AC_USE_SYSTEM_EXTENSIONS - -KPSE_BASIC([cairo]) - -AC_PROG_CC -AC_PROG_RANLIB -AC_PROG_LN_S -CAIRO_BIGENDIAN - -KPSE_COMPILER_VISIBILITY - -cairo_attribute_flag= -if test "x$GCC" = xyes; then - AS_CASE([`$CC -dumpversion`], - [4.[[01]].* ], [], - [4.* | 5.*], [cairo_attribute_flag=-Wno-attributes]) -fi -AC_SUBST([CAIRO_ATTRIBUTE_FLAG], [$cairo_attribute_flag]) - -AC_CHECK_SIZEOF([void *]) -AC_CHECK_SIZEOF([int]) -AC_CHECK_SIZEOF([long]) -AC_CHECK_SIZEOF([long long]) -AC_CHECK_SIZEOF([size_t]) - -dnl Checks for precise integer types -AC_CHECK_HEADERS([sys/int_types.h]) -AC_CHECK_TYPES([uint64_t, uint128_t, __uint128_t]) - -AC_CONFIG_HEADERS([config.h cairo-features.h]) - -AM_CONDITIONAL([build], [test "x$enable_build" != xno]) -AC_SEARCH_LIBS([sqrt], [m]) - -CAIRO_FEATURES([dnl -[0, [fc font]], -[0, [ft font]], -[0, [quartz font]], -[1, [user font]], -[0, [win32 font]], -dnl -[0, [egl functions]], -[0, [glx functions]], -[0, [gobject functions]], -[0, [png functions]], -[0, [wgl functions]], -[0, [win32 functions]], -[0, [xcb shm functions]], -dnl -[1, [image surface]], -[1, [mime surface]], -[1, [observer surface]], -[1, [recording surface]], -[0, [pdf surface]], -[0, [ps surface]], -[0, [quartz surface]], -[0, [script surface]], -[0, [svg surface]], -[0, [win32 surface]], -[0, [xcb surface]], -[0, [xlib surface]], -[0, [xlib xrender surface]], -]) - -AM_CONDITIONAL([CAIRO_HAS_QUARTZ_IMAGE_SURFACE], [false]) -AM_CONDITIONAL([CAIRO_HAS_OS2_SURFACE], [false]) -AM_CONDITIONAL([CAIRO_HAS_GL_SURFACE], [false]) - -KPSE_PIXMAN_FLAGS - -if test "x$enable_build" != xno || test -f config.force; then - -KPSE_ADD_FLAGS([pixman]) -AC_CHECK_FUNC([pixman_version_string], , [AC_ERROR([pixman not found])]) -KPSE_RESTORE_FLAGS - -echo timestamp >config.force -fi - -AC_SUBST([CAIRO_TREE], [cairo-src]) - -AC_CONFIG_FILES([Makefile cairo/Makefile]) - -AC_OUTPUT diff --git a/source/libs/cairo/m4/cairo-bigendian.m4 b/source/libs/cairo/m4/cairo-bigendian.m4 deleted file mode 100644 index f7499f6888fbc35660c15eb92e21e6802e265e6f..0000000000000000000000000000000000000000 --- a/source/libs/cairo/m4/cairo-bigendian.m4 +++ /dev/null @@ -1,35 +0,0 @@ -dnl ========================================================================== -dnl -dnl Cairo-specific macros -dnl - -dnl ========================================================================== - -dnl Usage: -dnl CAIRO_BIGENDIAN -dnl -AC_DEFUN([CAIRO_BIGENDIAN], -[dnl - case $host_os in - darwin*) - AH_VERBATIM([X_BYTE_ORDER], -[ -/* Deal with multiple architecture compiles on Mac OS X */ -#ifdef __APPLE_CC__ -#ifdef __BIG_ENDIAN__ -#define WORDS_BIGENDIAN 1 -#define FLOAT_WORDS_BIGENDIAN 1 -#else -#undef WORDS_BIGENDIAN -#undef FLOAT_WORDS_BIGENDIAN -#endif -#endif -]) - ;; - *) - AC_C_BIGENDIAN - AX_C_FLOAT_WORDS_BIGENDIAN - ;; - esac -]) - diff --git a/source/libs/cairo/m4/cairo-features.m4 b/source/libs/cairo/m4/cairo-features.m4 deleted file mode 100644 index f7a58c9e17c866408e62b1e93e555463cd9c013f..0000000000000000000000000000000000000000 --- a/source/libs/cairo/m4/cairo-features.m4 +++ /dev/null @@ -1,27 +0,0 @@ -# Public macros for the TeX Live (TL) tree. -# Copyright (C) 2013 Peter Breitenlohner <tex-live@tug.org> -# -# This file is free software; the copyright holder -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# CAIRO_FEATURES(FEATURE1, FEATURE2, ...) -# --------------------------------------- -# Where each feature has the form '[1-or-o], [text]'. -dnl -AC_DEFUN([CAIRO_FEATURES], [dnl -m4_foreach([Cairo_Feature], [$1], - [m4_ifset([Cairo_Feature], - [_CAIRO_FEATURE(Cairo_Feature)])])[]dnl -]) # CAIRO_FEATURES - -# _CAIRO_FEATURE(COND, TEXT) -# -------------------------- -m4_define([_CAIRO_FEATURE], [dnl -if test "x$1" = x1; then - AC_DEFINE([CAIRO_HAS_]AS_TR_CPP($2), [1], - [Define to 1 if $2 enabled.]) -fi -AM_CONDITIONAL([CAIRO_HAS_]AS_TR_CPP($2), [test "x$1" = x1]) -]) # _CAIRO_FEATURE - diff --git a/source/libs/cairo/m4/float.m4 b/source/libs/cairo/m4/float.m4 deleted file mode 100644 index 18ec3161840b57c71280ded8bc189875047568ee..0000000000000000000000000000000000000000 --- a/source/libs/cairo/m4/float.m4 +++ /dev/null @@ -1,64 +0,0 @@ -# AX_C_FLOAT_WORDS_BIGENDIAN ([ACTION-IF-TRUE], [ACTION-IF-FALSE], -# [ACTION-IF-UNKNOWN]) -# -# Checks the ordering of words within a multi-word float. This check -# is necessary because on some systems (e.g. certain ARM systems), the -# float word ordering can be different from the byte ordering. In a -# multi-word float context, "big-endian" implies that the word containing -# the sign bit is found in the memory location with the lowest address. -# This implemenation was inspired by the AC_C_BIGENDIAN macro in autoconf. -# ------------------------------------------------------------------------- -AC_DEFUN([AX_C_FLOAT_WORDS_BIGENDIAN], - [AC_CACHE_CHECK(whether float word ordering is bigendian, - ax_cv_c_float_words_bigendian, [ - -# The endianess is detected by first compiling C code that contains a special -# double float value, then grepping the resulting object file for certain -# strings of ascii values. The double is specially crafted to have a -# binary representation that corresponds with a simple string. In this -# implementation, the string "noonsees" was selected because the individual -# word values ("noon" and "sees") are palindromes, thus making this test -# byte-order agnostic. If grep finds the string "noonsees" in the object -# file, the target platform stores float words in big-endian order. If grep -# finds "seesnoon", float words are in little-endian order. If neither value -# is found, the user is instructed to specify the ordering. - -ax_cv_c_float_words_bigendian=unknown -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ - -double d = 90904234967036810337470478905505011476211692735615632014797120844053488865816695273723469097858056257517020191247487429516932130503560650002327564517570778480236724525140520121371739201496540132640109977779420565776568942592.0; - -]])], [ - -if strings - conftest.$ac_objext | grep noonsees >/dev/null ; then - ax_cv_c_float_words_bigendian=yes -fi -if strings - conftest.$ac_objext | grep seesnoon >/dev/null ; then - if test "$ax_cv_c_float_words_bigendian" = unknown; then - ax_cv_c_float_words_bigendian=no - else - ax_cv_c_float_words_bigendian=unknown - fi -fi - -])]) - -case $ax_cv_c_float_words_bigendian in - yes) - m4_default([$1], - [AC_DEFINE([FLOAT_WORDS_BIGENDIAN], 1, - [Define to 1 if your system stores words within floats - with the most significant word first])]) ;; - no) - $2 ;; - *) - m4_default([$3], - [AC_MSG_ERROR([ - -Unknown float word ordering. You need to manually preset -ax_cv_c_float_words_bigendian=no (or yes) according to your system. - - ])]) ;; -esac - -])# AX_C_FLOAT_WORDS_BIGENDIAN diff --git a/source/libs/cairo/version.ac b/source/libs/cairo/version.ac deleted file mode 100644 index 4dfbd0bc9bb1d919e03aad4122c758d12d8eeb44..0000000000000000000000000000000000000000 --- a/source/libs/cairo/version.ac +++ /dev/null @@ -1,11 +0,0 @@ -dnl -dnl Copyright (C) 2012-2015 Peter Breitenlohner <tex-live@tug.org> -dnl -dnl This file is free software; the copyright holder -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. -dnl -dnl -------------------------------------------------------- -dnl -dnl m4-include this file to define the current cairo version -m4_define([cairo_version], [1.14.8]) diff --git a/source/libs/configure b/source/libs/configure index 72719d2686bb23c2cc07263faaf3a46c7b730047..42b580587c98ddae1c02f48290e6ec5f970975fd 100755 --- a/source/libs/configure +++ b/source/libs/configure @@ -585,14 +585,12 @@ PACKAGE_BUGREPORT='tex-k@tug.org' PACKAGE_URL='' ac_unique_file="../build-aux/missing" -enable_option_checking=no ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS -CONF_SUBDIRS MAKE_SUBDIRS -subdirs +CONF_SUBDIRS WARNING_CFLAGS MAINT MAINTAINER_MODE_FALSE @@ -751,8 +749,6 @@ with_mpfr_libdir with_system_gmp with_gmp_includes with_gmp_libdir -with_system_cairo -with_system_pixman with_system_libpng with_system_zlib with_zlib_includes @@ -778,16 +774,7 @@ CFLAGS LDFLAGS LIBS CPPFLAGS' -ac_subdirs_all='zziplib -poppler -mpfr -gmp -cairo -pixman -libpng -luajit -lua52 -zlib' + # Initialize some variables set by options. ac_init_help= @@ -1499,10 +1486,6 @@ Optional Packages: --with-system-gmp use installed gmp headers and library --with-gmp-includes=DIR gmp headers installed in DIR --with-gmp-libdir=DIR gmp library installed in DIR - --with-system-cairo use installed cairo headers and library (requires - pkg-config) - --with-system-pixman use installed pixman headers and library (requires - pkg-config) --with-system-libpng use installed libpng headers and library (requires pkg-config) --with-system-zlib use installed zlib headers and library @@ -3392,7 +3375,6 @@ esac test "x$enable_web2c:$enable_luatex" = xyes:yes && { need_poppler=yes need_mpfr=yes - need_cairo=yes need_libpng=yes need_zziplib=yes need_lua52=yes @@ -3411,7 +3393,6 @@ esac test "x$enable_web2c:$enable_luajittex" = xyes:yes && { need_poppler=yes need_mpfr=yes - need_cairo=yes need_libpng=yes need_zziplib=yes need_luajit=yes @@ -3778,60 +3759,6 @@ $as_echo "$as_me: Assuming installed \`gmp' headers and library" >&6;} ac_configure_args="$ac_configure_args '--with-system-gmp=$with_system_gmp'" fi -## libs/cairo/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/cairo/ -## configure options and TL libraries required for cairo - -# Check whether --with-system-cairo was given. -if test "${with_system_cairo+set}" = set; then : - withval=$with_system_cairo; -fi -if test "x$with_system_cairo" = x; then - if test -f $srcdir/../libs/cairo/configure; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Assuming \`cairo' headers and library from TL tree" >&5 -$as_echo "$as_me: Assuming \`cairo' headers and library from TL tree" >&6;} - with_system_cairo=no - else - { $as_echo "$as_me:${as_lineno-$LINENO}: Assuming installed \`cairo' headers and library" >&5 -$as_echo "$as_me: Assuming installed \`cairo' headers and library" >&6;} - with_system_cairo=yes - fi - ac_configure_args="$ac_configure_args '--with-system-cairo=$with_system_cairo'" -fi -if test "x$with_system_cairo" = xyes; then - if test "x$with_system_pixman" = x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: -> installed \`pixman' headers and library" >&5 -$as_echo "$as_me: -> installed \`pixman' headers and library" >&6;} - with_system_pixman=yes - ac_configure_args="$ac_configure_args '--with-system-pixman'" - elif test "x$with_system_pixman" != xyes; then - as_fn_error $? "Sorry, \`--with-system-cairo' requires \`--with-system-pixman'" "$LINENO" 5 - fi -fi - -test "x$need_cairo" = xyes && { - need_pixman=yes -} - -## libs/pixman/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/pixman/ -## configure options and TL libraries required for pixman - -# Check whether --with-system-pixman was given. -if test "${with_system_pixman+set}" = set; then : - withval=$with_system_pixman; -fi -if test "x$with_system_pixman" = x; then - if test -f $srcdir/../libs/pixman/configure; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Assuming \`pixman' headers and library from TL tree" >&5 -$as_echo "$as_me: Assuming \`pixman' headers and library from TL tree" >&6;} - with_system_pixman=no - else - { $as_echo "$as_me:${as_lineno-$LINENO}: Assuming installed \`pixman' headers and library" >&5 -$as_echo "$as_me: Assuming installed \`pixman' headers and library" >&6;} - with_system_pixman=yes - fi - ac_configure_args="$ac_configure_args '--with-system-pixman=$with_system_pixman'" -fi - ## libs/libpng/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/libpng/ ## configure options and TL libraries required for libpng @@ -4851,91 +4778,41 @@ WARNING_CFLAGS=$kpse_cv_warning_cflags - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for generic libraries to build" >&5 $as_echo_n "checking for generic libraries to build... " >&6; } -MAKE_SUBDIRS= CONF_SUBDIRS= -if test -x $srcdir/zziplib/configure; then - test "x$with_system_zziplib" != xyes && test "x$need_zziplib" = xyes && MAKE_SUBDIRS="zziplib $MAKE_SUBDIRS" +MAKE_SUBDIRS= +if test -x $srcdir/zziplib/configure && test "x$with_system_zziplib" != xyes && test "x$need_zziplib" = xyes; then CONF_SUBDIRS="zziplib $CONF_SUBDIRS" - if false; then - subdirs="$subdirs zziplib" - - fi + MAKE_SUBDIRS="zziplib $MAKE_SUBDIRS" fi -if test -x $srcdir/poppler/configure; then - test "x$with_system_poppler" != xyes && test "x$need_poppler" = xyes && MAKE_SUBDIRS="poppler $MAKE_SUBDIRS" +if test -x $srcdir/poppler/configure && test "x$with_system_poppler" != xyes && test "x$need_poppler" = xyes; then CONF_SUBDIRS="poppler $CONF_SUBDIRS" - if false; then - subdirs="$subdirs poppler" - - fi + MAKE_SUBDIRS="poppler $MAKE_SUBDIRS" fi -if test -x $srcdir/mpfr/configure; then - test "x$with_system_mpfr" != xyes && test "x$need_mpfr" = xyes && MAKE_SUBDIRS="mpfr $MAKE_SUBDIRS" +if test -x $srcdir/mpfr/configure && test "x$with_system_mpfr" != xyes && test "x$need_mpfr" = xyes; then CONF_SUBDIRS="mpfr $CONF_SUBDIRS" - if false; then - subdirs="$subdirs mpfr" - - fi + MAKE_SUBDIRS="mpfr $MAKE_SUBDIRS" fi -if test -x $srcdir/gmp/configure; then - test "x$with_system_gmp" != xyes && test "x$need_gmp" = xyes && MAKE_SUBDIRS="gmp $MAKE_SUBDIRS" +if test -x $srcdir/gmp/configure && test "x$with_system_gmp" != xyes && test "x$need_gmp" = xyes; then CONF_SUBDIRS="gmp $CONF_SUBDIRS" - if false; then - subdirs="$subdirs gmp" - - fi -fi -if test -x $srcdir/cairo/configure; then - test "x$with_system_cairo" != xyes && test "x$need_cairo" = xyes && MAKE_SUBDIRS="cairo $MAKE_SUBDIRS" - CONF_SUBDIRS="cairo $CONF_SUBDIRS" - if false; then - subdirs="$subdirs cairo" - - fi + MAKE_SUBDIRS="gmp $MAKE_SUBDIRS" fi -if test -x $srcdir/pixman/configure; then - test "x$with_system_pixman" != xyes && test "x$need_pixman" = xyes && MAKE_SUBDIRS="pixman $MAKE_SUBDIRS" - CONF_SUBDIRS="pixman $CONF_SUBDIRS" - if false; then - subdirs="$subdirs pixman" - - fi -fi -if test -x $srcdir/libpng/configure; then - test "x$with_system_libpng" != xyes && test "x$need_libpng" = xyes && MAKE_SUBDIRS="libpng $MAKE_SUBDIRS" +if test -x $srcdir/libpng/configure && test "x$with_system_libpng" != xyes && test "x$need_libpng" = xyes; then CONF_SUBDIRS="libpng $CONF_SUBDIRS" - if false; then - subdirs="$subdirs libpng" - - fi + MAKE_SUBDIRS="libpng $MAKE_SUBDIRS" fi -if test -x $srcdir/luajit/configure; then - test "x$with_system_luajit" != xyes && test "x$need_luajit" = xyes && MAKE_SUBDIRS="luajit $MAKE_SUBDIRS" +if test -x $srcdir/luajit/configure && test "x$with_system_luajit" != xyes && test "x$need_luajit" = xyes; then CONF_SUBDIRS="luajit $CONF_SUBDIRS" - if false; then - subdirs="$subdirs luajit" - - fi + MAKE_SUBDIRS="luajit $MAKE_SUBDIRS" fi -if test -x $srcdir/lua52/configure; then - test "x$with_system_lua52" != xyes && test "x$need_lua52" = xyes && MAKE_SUBDIRS="lua52 $MAKE_SUBDIRS" +if test -x $srcdir/lua52/configure && test "x$with_system_lua52" != xyes && test "x$need_lua52" = xyes; then CONF_SUBDIRS="lua52 $CONF_SUBDIRS" - if false; then - subdirs="$subdirs lua52" - - fi + MAKE_SUBDIRS="lua52 $MAKE_SUBDIRS" fi -if test -x $srcdir/zlib/configure; then - test "x$with_system_zlib" != xyes && test "x$need_zlib" = xyes && MAKE_SUBDIRS="zlib $MAKE_SUBDIRS" +if test -x $srcdir/zlib/configure && test "x$with_system_zlib" != xyes && test "x$need_zlib" = xyes; then CONF_SUBDIRS="zlib $CONF_SUBDIRS" - if false; then - subdirs="$subdirs zlib" - - fi + MAKE_SUBDIRS="zlib $MAKE_SUBDIRS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAKE_SUBDIRS" >&5 @@ -6246,151 +6123,6 @@ if test "$no_create" != yes; then # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi - -# -# CONFIG_SUBDIRS section. -# -if test "$no_recursion" != yes; then - - # Remove --cache-file, --srcdir, and --disable-option-checking arguments - # so they do not pile up. - ac_sub_configure_args= - ac_prev= - eval "set x $ac_configure_args" - shift - for ac_arg - do - if test -n "$ac_prev"; then - ac_prev= - continue - fi - case $ac_arg in - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \ - | --c=*) - ;; - --config-cache | -C) - ;; - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - ;; - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - ;; - --disable-option-checking) - ;; - *) - case $ac_arg in - *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - as_fn_append ac_sub_configure_args " '$ac_arg'" ;; - esac - done - - # Always prepend --prefix to ensure using the same prefix - # in subdir configurations. - ac_arg="--prefix=$prefix" - case $ac_arg in - *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - ac_sub_configure_args="'$ac_arg' $ac_sub_configure_args" - - # Pass --silent - if test "$silent" = yes; then - ac_sub_configure_args="--silent $ac_sub_configure_args" - fi - - # Always prepend --disable-option-checking to silence warnings, since - # different subdirs can have different --enable and --with options. - ac_sub_configure_args="--disable-option-checking $ac_sub_configure_args" - - ac_popdir=`pwd` - for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue - - # Do not complain, so a configure script can configure whichever - # parts of a large source tree are present. - test -d "$srcdir/$ac_dir" || continue - - ac_msg="=== configuring in $ac_dir (`pwd`/$ac_dir)" - $as_echo "$as_me:${as_lineno-$LINENO}: $ac_msg" >&5 - $as_echo "$ac_msg" >&6 - as_dir="$ac_dir"; as_fn_mkdir_p - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - cd "$ac_dir" - - # Check for guested configure; otherwise get Cygnus style configure. - if test -f "$ac_srcdir/configure.gnu"; then - ac_sub_configure=$ac_srcdir/configure.gnu - elif test -f "$ac_srcdir/configure"; then - ac_sub_configure=$ac_srcdir/configure - elif test -f "$ac_srcdir/configure.in"; then - # This should be Cygnus configure. - ac_sub_configure=$ac_aux_dir/configure - else - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: no configuration information is in $ac_dir" >&5 -$as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;} - ac_sub_configure= - fi - - # The recursion is here. - if test -n "$ac_sub_configure"; then - # Make the cache file name correct relative to the subdirectory. - case $cache_file in - [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;; - *) # Relative name. - ac_sub_cache_file=$ac_top_build_prefix$cache_file ;; - esac - - { $as_echo "$as_me:${as_lineno-$LINENO}: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5 -$as_echo "$as_me: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;} - # The eval makes quoting arguments work. - eval "\$SHELL \"\$ac_sub_configure\" $ac_sub_configure_args \ - --cache-file=\"\$ac_sub_cache_file\" --srcdir=\"\$ac_srcdir\"" || - as_fn_error $? "$ac_sub_configure failed for $ac_dir" "$LINENO" 5 - fi - - cd "$ac_popdir" - done -fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} diff --git a/source/libs/gmp/Makefile.in b/source/libs/gmp/Makefile.in index 91dcf704bbdf507464c501a2269ef58ddd5c2dd0..76e7a8041b9ef5db45bbd3a8d21d5bcd72fade3b 100644 --- a/source/libs/gmp/Makefile.in +++ b/source/libs/gmp/Makefile.in @@ -565,12 +565,12 @@ am__DIST_COMMON = $(srcdir)/../../am/dist_hook.am \ $(top_srcdir)/../../build-aux/install-sh \ $(top_srcdir)/../../build-aux/missing \ $(top_srcdir)/../../build-aux/test-driver \ - $(top_srcdir)/gmp-src/gmp-h.in ../../build-aux/compile \ - ../../build-aux/config.guess ../../build-aux/config.sub \ - ../../build-aux/depcomp ../../build-aux/install-sh \ - ../../build-aux/ltmain.sh ../../build-aux/missing \ - ../../build-aux/texinfo.tex ../../build-aux/ylwrap ChangeLog \ - README + $(top_srcdir)/gmp-src/gmp-h.in ../../build-aux/ar-lib \ + ../../build-aux/compile ../../build-aux/config.guess \ + ../../build-aux/config.sub ../../build-aux/depcomp \ + ../../build-aux/install-sh ../../build-aux/ltmain.sh \ + ../../build-aux/missing ../../build-aux/texinfo.tex \ + ../../build-aux/ylwrap ChangeLog README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) diff --git a/source/libs/gmp/native/Makefile.in b/source/libs/gmp/native/Makefile.in index 5c8069211a2847ffda44826e7d25d5a509af3918..f4cc08ad904b2a03a4c52be34528ae2cc75829e8 100644 --- a/source/libs/gmp/native/Makefile.in +++ b/source/libs/gmp/native/Makefile.in @@ -187,11 +187,11 @@ am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(top_srcdir)/../../../build-aux/depcomp \ $(top_srcdir)/../../../build-aux/install-sh \ $(top_srcdir)/../../../build-aux/missing \ - ../../../build-aux/compile ../../../build-aux/config.guess \ - ../../../build-aux/config.sub ../../../build-aux/depcomp \ - ../../../build-aux/install-sh ../../../build-aux/ltmain.sh \ - ../../../build-aux/missing ../../../build-aux/texinfo.tex \ - ../../../build-aux/ylwrap + ../../../build-aux/ar-lib ../../../build-aux/compile \ + ../../../build-aux/config.guess ../../../build-aux/config.sub \ + ../../../build-aux/depcomp ../../../build-aux/install-sh \ + ../../../build-aux/ltmain.sh ../../../build-aux/missing \ + ../../../build-aux/texinfo.tex ../../../build-aux/ylwrap DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) diff --git a/source/libs/libpng/Makefile.in b/source/libs/libpng/Makefile.in index e38bbc217502278ccfd639f18205ca5cfae912b4..1f79aab879902a23cd0d549ee9f7590700d472bb 100644 --- a/source/libs/libpng/Makefile.in +++ b/source/libs/libpng/Makefile.in @@ -416,11 +416,12 @@ am__DIST_COMMON = $(srcdir)/../../am/dist_hook.am \ $(top_srcdir)/../../build-aux/install-sh \ $(top_srcdir)/../../build-aux/missing \ $(top_srcdir)/../../build-aux/test-driver \ - ../../build-aux/compile ../../build-aux/config.guess \ - ../../build-aux/config.sub ../../build-aux/depcomp \ - ../../build-aux/install-sh ../../build-aux/ltmain.sh \ - ../../build-aux/missing ../../build-aux/texinfo.tex \ - ../../build-aux/ylwrap ChangeLog README + ../../build-aux/ar-lib ../../build-aux/compile \ + ../../build-aux/config.guess ../../build-aux/config.sub \ + ../../build-aux/depcomp ../../build-aux/install-sh \ + ../../build-aux/ltmain.sh ../../build-aux/missing \ + ../../build-aux/texinfo.tex ../../build-aux/ylwrap ChangeLog \ + README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) diff --git a/source/libs/lua52/Makefile.in b/source/libs/lua52/Makefile.in index 9e1764b3bdaf3c90446aec63f9b072c6ce4d7b8c..1ae560fd4f56551a0586df2053f65dd94e710a16 100644 --- a/source/libs/lua52/Makefile.in +++ b/source/libs/lua52/Makefile.in @@ -451,11 +451,11 @@ am__DIST_COMMON = $(srcdir)/../../am/dist_hook.am \ $(top_srcdir)/../../build-aux/ltmain.sh \ $(top_srcdir)/../../build-aux/missing \ $(top_srcdir)/../../build-aux/test-driver \ - ../../build-aux/compile ../../build-aux/config.guess \ - ../../build-aux/config.sub ../../build-aux/depcomp \ - ../../build-aux/install-sh ../../build-aux/ltmain.sh \ - ../../build-aux/missing ../../build-aux/texinfo.tex \ - ../../build-aux/ylwrap ChangeLog + ../../build-aux/ar-lib ../../build-aux/compile \ + ../../build-aux/config.guess ../../build-aux/config.sub \ + ../../build-aux/depcomp ../../build-aux/install-sh \ + ../../build-aux/ltmain.sh ../../build-aux/missing \ + ../../build-aux/texinfo.tex ../../build-aux/ylwrap ChangeLog DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) diff --git a/source/libs/luajit/Makefile.in b/source/libs/luajit/Makefile.in index 539537bad69b78da501421db81985b986310af63..ad0fca5c91b8a026332aa24f50cbae588ae3fea9 100644 --- a/source/libs/luajit/Makefile.in +++ b/source/libs/luajit/Makefile.in @@ -490,11 +490,11 @@ am__DIST_COMMON = $(srcdir)/../../am/dist_hook.am \ $(top_srcdir)/../../build-aux/ltmain.sh \ $(top_srcdir)/../../build-aux/missing \ $(top_srcdir)/../../build-aux/test-driver \ - ../../build-aux/compile ../../build-aux/config.guess \ - ../../build-aux/config.sub ../../build-aux/depcomp \ - ../../build-aux/install-sh ../../build-aux/ltmain.sh \ - ../../build-aux/missing ../../build-aux/texinfo.tex \ - ../../build-aux/ylwrap ChangeLog + ../../build-aux/ar-lib ../../build-aux/compile \ + ../../build-aux/config.guess ../../build-aux/config.sub \ + ../../build-aux/depcomp ../../build-aux/install-sh \ + ../../build-aux/ltmain.sh ../../build-aux/missing \ + ../../build-aux/texinfo.tex ../../build-aux/ylwrap ChangeLog DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) diff --git a/source/libs/luajit/native/Makefile.in b/source/libs/luajit/native/Makefile.in index bfb677c2e08407f4631ac557c3dbe93483435ed4..a25a68a7e59f1640742cf68b6935e2a1417ccf50 100644 --- a/source/libs/luajit/native/Makefile.in +++ b/source/libs/luajit/native/Makefile.in @@ -186,11 +186,11 @@ am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(top_srcdir)/../../../build-aux/depcomp \ $(top_srcdir)/../../../build-aux/install-sh \ $(top_srcdir)/../../../build-aux/missing \ - ../../../build-aux/compile ../../../build-aux/config.guess \ - ../../../build-aux/config.sub ../../../build-aux/depcomp \ - ../../../build-aux/install-sh ../../../build-aux/ltmain.sh \ - ../../../build-aux/missing ../../../build-aux/texinfo.tex \ - ../../../build-aux/ylwrap + ../../../build-aux/ar-lib ../../../build-aux/compile \ + ../../../build-aux/config.guess ../../../build-aux/config.sub \ + ../../../build-aux/depcomp ../../../build-aux/install-sh \ + ../../../build-aux/ltmain.sh ../../../build-aux/missing \ + ../../../build-aux/texinfo.tex ../../../build-aux/ylwrap DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) diff --git a/source/libs/mpfr/Makefile.in b/source/libs/mpfr/Makefile.in index e6fc045b9aa2b9f818d52ae0dbfd52634c7a2b99..478b14c1c1b08dd846646efe98facccc1e2901ea 100644 --- a/source/libs/mpfr/Makefile.in +++ b/source/libs/mpfr/Makefile.in @@ -499,12 +499,12 @@ am__DIST_COMMON = $(srcdir)/../../am/dist_hook.am \ $(top_srcdir)/../../build-aux/install-sh \ $(top_srcdir)/../../build-aux/missing \ $(top_srcdir)/../../build-aux/test-driver \ - $(top_srcdir)/mpfr-src/src/mparam_h.in ../../build-aux/compile \ - ../../build-aux/config.guess ../../build-aux/config.sub \ - ../../build-aux/depcomp ../../build-aux/install-sh \ - ../../build-aux/ltmain.sh ../../build-aux/missing \ - ../../build-aux/texinfo.tex ../../build-aux/ylwrap ChangeLog \ - README + $(top_srcdir)/mpfr-src/src/mparam_h.in ../../build-aux/ar-lib \ + ../../build-aux/compile ../../build-aux/config.guess \ + ../../build-aux/config.sub ../../build-aux/depcomp \ + ../../build-aux/install-sh ../../build-aux/ltmain.sh \ + ../../build-aux/missing ../../build-aux/texinfo.tex \ + ../../build-aux/ylwrap ChangeLog README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) diff --git a/source/libs/pixman/ChangeLog b/source/libs/pixman/ChangeLog deleted file mode 100644 index d29f7df8eb99a4db3f3e43a91ecb54d454524a4a..0000000000000000000000000000000000000000 --- a/source/libs/pixman/ChangeLog +++ /dev/null @@ -1,112 +0,0 @@ -2016-02-15 Karl Berry <karl@tug.org> - - * pixman-PATCHES: rename from pixman-src-PATCHES. - * Makefile.am (EXTRA_DIST): likewise. - -2016-02-04 Akira Kakuto <kakuto@fuk.kindai.ac.jp> - - Import pixman-0.34.0. - * version.ac: Adapted. - * configure.ac: New source tree convension. - -2015-09-26 Peter Breitenlohner <peb@mppmu.mpg.de> - - Import pixman-0.32.8. - * version.ac: Adapted. - -2015-07-06 Peter Breitenlohner <peb@mppmu.mpg.de> - - * Makefile.am: Better dependencies for 'make check'. - -2015-02-16 Peter Breitenlohner <peb@mppmu.mpg.de> - - * Makefile.am: Use the fragment ../../am/dist_hook.am. - -2014-12-03 Peter Breitenlohner <peb@mppmu.mpg.de> - - * configure.ac: Added KPSE_COMPILER_VISIBILITY. - * Makefile.am [AM_CFLAGS]: Added $(VISIBILITY_CFLAGS). - -2014-07-07 Peter Breitenlohner <peb@mppmu.mpg.de> - - Import pixman-0.32.6. - * version.ac: Adapted. - -2014-06-16 Peter Breitenlohner <peb@mppmu.mpg.de> - - * Makefile.am: Drop the obsolete ACLOCAL_AMFLAGS. - -2013-11-18 Peter Breitenlohner <peb@mppmu.mpg.de> - - Import pixman-0.32.4. - * version.ac: Adapted. - -2013-11-12 Peter Breitenlohner <peb@mppmu.mpg.de> - - Import pixman-0.32.2. - * version.ac: Adapted. - -2013-11-11 Peter Breitenlohner <peb@mppmu.mpg.de> - - Import pixman-0.32.0. - * configure.ac, version.ac: Adapted. - -2013-10-29 Peter Breitenlohner <peb@mppmu.mpg.de> - - * pixtest.c: Print more info. - -2013-08-23 Peter Breitenlohner <peb@mppmu.mpg.de> - - * configure.ac: Recover test for sqrtf(). - -2013-08-08 Peter Breitenlohner <peb@mppmu.mpg.de> - - Import pixman-0.30.2. - * version.ac: Adapted. - -2013-07-06 Peter Breitenlohner <peb@mppmu.mpg.de> - - * Makefile.am: Use ../../am/rebuild.am. - -2013-07-05 Peter Breitenlohner <peb@mppmu.mpg.de> - - * include/Makefile.am: Moved Makefile fragments to ../../am/. - -2013-06-26 Peter Breitenlohner <peb@mppmu.mpg.de> - - * Makefile.am (SUBDIRS): Build the library first. - -2013-05-30 Peter Breitenlohner <peb@mppmu.mpg.de> - - Import pixman-0.30.0. - * sources.am, version.ac: Adapted. - -2013-04-15 Peter Breitenlohner <peb@mppmu.mpg.de> - - * Makefile.am, configure.ac: Build non-libtool library. - * pixman.test (new): Shell script for a basic test. - * pixtest.c (new): Source code for test program. - -2013-04-08 Mojca Miklavec <mojca.miklavec.lists@gmail.com> - - * configure.ac: Better handling of sqrtf(). - -2013-04-07 Peter Breitenlohner <peb@mppmu.mpg.de> - - * configure.ac: Define sqrtf as sqrt on systems without sqrtf(). - -2013-03-21 Peter Breitenlohner <peb@mppmu.mpg.de> - - * configure.ac: Define SIZE_MAX if necessary (for Solaris 9). - -2013-01-29 Peter Breitenlohner <peb@mppmu.mpg.de> - - * Makefile.am, sources.am: Allow subdir-objects. - -2012-12-15 Peter Breitenlohner <peb@mppmu.mpg.de> - - * configure.ac: Use KPSE_BASIC to enable silent rules. - -2012-11-10 Taco Hoekwater <taco@metatex.org> - - Import pixman-0.28.0. diff --git a/source/libs/pixman/Makefile.am b/source/libs/pixman/Makefile.am deleted file mode 100644 index 0a0bc589ae3a75bba6365a577bff5d53c7406f6f..0000000000000000000000000000000000000000 --- a/source/libs/pixman/Makefile.am +++ /dev/null @@ -1,55 +0,0 @@ -## Proxy Makefile.am to build pixman for TeX Live. -## -## Copyright (C) 2016 Karl Berry <tex-live@tug.org> -## Copyright (C) 2012-2015 Peter Breitenlohner <tex-live@tug.org> -## Copyright (C) 2012 Taco Hoekwater <taco@metatex.org> -## -## This file is free software; the copyright holder -## gives unlimited permission to copy and/or distribute it, -## with or without modifications, as long as this notice is preserved. -## -## We want to re-distribute the whole pixman source tree. -## -EXTRA_DIST = $(PIXMAN_TREE) - -## Changes applied to the original source tree -## -EXTRA_DIST += pixman-PATCHES - -PIXMAN_SRC = $(PIXMAN_TREE)/pixman - -# Files not to be distributed -include $(srcdir)/../../am/dist_hook.am -NEVER_NAMES += $(NEVER_NAMES_SUB) - -SUBDIRS = . include - -AM_CPPFLAGS = -I$(top_srcdir)/$(PIXMAN_SRC) -AM_CFLAGS = $(VISIBILITY_CFLAGS) # $(WARNING_CFLAGS) - -noinst_LIBRARIES = libpixman.a - -include $(srcdir)/sources.am - -libpixman_a_SOURCES = $(libpixman_sources) $(libpixman_headers) - -if build -check_PROGRAMS = pixtest -dist_check_SCRIPTS = pixman.test -TESTS = pixman.test -endif build -pixman.log: pixtest$(EXEEXT) - -pixtest_SOURCES = pixtest.c - -pixtest_CPPFLAGS = -Iinclude - -LDADD = libpixman.a - -# Rebuild -rebuild_prereq = -rebuild_target = all -CLEANFILES = - -include $(srcdir)/../../am/rebuild.am - diff --git a/source/libs/pixman/Makefile.in b/source/libs/pixman/Makefile.in deleted file mode 100644 index beaf9b8ce76daaa2edd6dcd295f9140349f73f22..0000000000000000000000000000000000000000 --- a/source/libs/pixman/Makefile.in +++ /dev/null @@ -1,1507 +0,0 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2014 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -@build_TRUE@check_PROGRAMS = pixtest$(EXEEXT) -subdir = . -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/../../m4/kpse-common.m4 \ - $(top_srcdir)/../../m4/kpse-lib-version.m4 \ - $(top_srcdir)/../../m4/kpse-size-max.m4 \ - $(top_srcdir)/../../m4/kpse-visibility.m4 \ - $(top_srcdir)/../../m4/kpse-warnings.m4 \ - $(top_srcdir)/version.ac $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ - $(am__configure_deps) $(am__dist_check_SCRIPTS_DIST) \ - $(am__DIST_COMMON) -am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ - configure.lineno config.status.lineno -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = config.h -CONFIG_CLEAN_FILES = pixman-version.h -CONFIG_CLEAN_VPATH_FILES = -LIBRARIES = $(noinst_LIBRARIES) -AR = ar -ARFLAGS = cru -AM_V_AR = $(am__v_AR_@AM_V@) -am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) -am__v_AR_0 = @echo " AR " $@; -am__v_AR_1 = -libpixman_a_AR = $(AR) $(ARFLAGS) -libpixman_a_LIBADD = -am__dirstamp = $(am__leading_dot)dirstamp -am__objects_1 = @PIXMAN_TREE@/pixman/pixman.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-access.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-access-accessors.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-bits-image.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-combine32.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-combine-float.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-conical-gradient.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-x86.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-mips.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-arm.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-ppc.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-edge.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-edge-accessors.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-fast-path.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-filter.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-glyph.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-general.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-gradient-walker.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-image.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-implementation.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-linear-gradient.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-matrix.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-noop.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-radial-gradient.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-region16.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-region32.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-solid-fill.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-timer.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-trap.$(OBJEXT) \ - @PIXMAN_TREE@/pixman/pixman-utils.$(OBJEXT) -am__objects_2 = -am_libpixman_a_OBJECTS = $(am__objects_1) $(am__objects_2) -libpixman_a_OBJECTS = $(am_libpixman_a_OBJECTS) -am_pixtest_OBJECTS = pixtest-pixtest.$(OBJEXT) -pixtest_OBJECTS = $(am_pixtest_OBJECTS) -pixtest_LDADD = $(LDADD) -pixtest_DEPENDENCIES = libpixman.a -am__dist_check_SCRIPTS_DIST = pixman.test -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -depcomp = $(SHELL) $(top_srcdir)/../../build-aux/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(libpixman_a_SOURCES) $(pixtest_SOURCES) -DIST_SOURCES = $(libpixman_a_SOURCES) $(pixtest_SOURCES) -RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ - ctags-recursive dvi-recursive html-recursive info-recursive \ - install-data-recursive install-dvi-recursive \ - install-exec-recursive install-html-recursive \ - install-info-recursive install-pdf-recursive \ - install-ps-recursive install-recursive installcheck-recursive \ - installdirs-recursive pdf-recursive ps-recursive \ - tags-recursive uninstall-recursive -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ - distclean-recursive maintainer-clean-recursive -am__recursive_targets = \ - $(RECURSIVE_TARGETS) \ - $(RECURSIVE_CLEAN_TARGETS) \ - $(am__extra_recursive_targets) -AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ - cscope check recheck distdir dist dist-all distcheck -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ - $(LISP)config.h.in -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -CSCOPE = cscope -am__tty_colors_dummy = \ - mgn= red= grn= lgn= blu= brg= std=; \ - am__color_tests=no -am__tty_colors = { \ - $(am__tty_colors_dummy); \ - if test "X$(AM_COLOR_TESTS)" = Xno; then \ - am__color_tests=no; \ - elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ - am__color_tests=yes; \ - elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ - am__color_tests=yes; \ - fi; \ - if test $$am__color_tests = yes; then \ - red='[0;31m'; \ - grn='[0;32m'; \ - lgn='[1;32m'; \ - blu='[1;34m'; \ - mgn='[0;35m'; \ - brg='[1m'; \ - std='[m'; \ - fi; \ -} -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__recheck_rx = ^[ ]*:recheck:[ ]* -am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* -am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* -# A command that, given a newline-separated list of test names on the -# standard input, print the name of the tests that are to be re-run -# upon "make recheck". -am__list_recheck_tests = $(AWK) '{ \ - recheck = 1; \ - while ((rc = (getline line < ($$0 ".trs"))) != 0) \ - { \ - if (rc < 0) \ - { \ - if ((getline line2 < ($$0 ".log")) < 0) \ - recheck = 0; \ - break; \ - } \ - else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ - { \ - recheck = 0; \ - break; \ - } \ - else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ - { \ - break; \ - } \ - }; \ - if (recheck) \ - print $$0; \ - close ($$0 ".trs"); \ - close ($$0 ".log"); \ -}' -# A command that, given a newline-separated list of test names on the -# standard input, create the global log from their .trs and .log files. -am__create_global_log = $(AWK) ' \ -function fatal(msg) \ -{ \ - print "fatal: making $@: " msg | "cat >&2"; \ - exit 1; \ -} \ -function rst_section(header) \ -{ \ - print header; \ - len = length(header); \ - for (i = 1; i <= len; i = i + 1) \ - printf "="; \ - printf "\n\n"; \ -} \ -{ \ - copy_in_global_log = 1; \ - global_test_result = "RUN"; \ - while ((rc = (getline line < ($$0 ".trs"))) != 0) \ - { \ - if (rc < 0) \ - fatal("failed to read from " $$0 ".trs"); \ - if (line ~ /$(am__global_test_result_rx)/) \ - { \ - sub("$(am__global_test_result_rx)", "", line); \ - sub("[ ]*$$", "", line); \ - global_test_result = line; \ - } \ - else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ - copy_in_global_log = 0; \ - }; \ - if (copy_in_global_log) \ - { \ - rst_section(global_test_result ": " $$0); \ - while ((rc = (getline line < ($$0 ".log"))) != 0) \ - { \ - if (rc < 0) \ - fatal("failed to read from " $$0 ".log"); \ - print line; \ - }; \ - printf "\n"; \ - }; \ - close ($$0 ".trs"); \ - close ($$0 ".log"); \ -}' -# Restructured Text title. -am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } -# Solaris 10 'make', and several other traditional 'make' implementations, -# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it -# by disabling -e (using the XSI extension "set +e") if it's set. -am__sh_e_setup = case $$- in *e*) set +e;; esac -# Default flags passed to test drivers. -am__common_driver_flags = \ - --color-tests "$$am__color_tests" \ - --enable-hard-errors "$$am__enable_hard_errors" \ - --expect-failure "$$am__expect_failure" -# To be inserted before the command running the test. Creates the -# directory for the log if needed. Stores in $dir the directory -# containing $f, in $tst the test, in $log the log. Executes the -# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and -# passes TESTS_ENVIRONMENT. Set up options for the wrapper that -# will run the test scripts (or their associated LOG_COMPILER, if -# thy have one). -am__check_pre = \ -$(am__sh_e_setup); \ -$(am__vpath_adj_setup) $(am__vpath_adj) \ -$(am__tty_colors); \ -srcdir=$(srcdir); export srcdir; \ -case "$@" in \ - */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ - *) am__odir=.;; \ -esac; \ -test "x$$am__odir" = x"." || test -d "$$am__odir" \ - || $(MKDIR_P) "$$am__odir" || exit $$?; \ -if test -f "./$$f"; then dir=./; \ -elif test -f "$$f"; then dir=; \ -else dir="$(srcdir)/"; fi; \ -tst=$$dir$$f; log='$@'; \ -if test -n '$(DISABLE_HARD_ERRORS)'; then \ - am__enable_hard_errors=no; \ -else \ - am__enable_hard_errors=yes; \ -fi; \ -case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ - am__expect_failure=yes;; \ - *) \ - am__expect_failure=no;; \ -esac; \ -$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) -# A shell command to get the names of the tests scripts with any registered -# extension removed (i.e., equivalently, the names of the test logs, with -# the '.log' extension removed). The result is saved in the shell variable -# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, -# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", -# since that might cause problem with VPATH rewrites for suffix-less tests. -# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. -am__set_TESTS_bases = \ - bases='$(TEST_LOGS)'; \ - bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ - bases=`echo $$bases` -RECHECK_LOGS = $(TEST_LOGS) -TEST_SUITE_LOG = test-suite.log -TEST_EXTENSIONS = @EXEEXT@ .test -am__test_logs1 = $(TESTS:=.log) -am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) -TEST_LOGS = $(am__test_logs2:.test.log=.log) -TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/../../build-aux/test-driver -TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ - $(TEST_LOG_FLAGS) -am__set_b = \ - case '$@' in \ - */*) \ - case '$*' in \ - */*) b='$*';; \ - *) b=`echo '$@' | sed 's/\.log$$//'`; \ - esac;; \ - *) \ - b='$*';; \ - esac -DIST_SUBDIRS = $(SUBDIRS) -am__DIST_COMMON = $(srcdir)/../../am/dist_hook.am \ - $(srcdir)/../../am/rebuild.am $(srcdir)/Makefile.in \ - $(srcdir)/config.h.in $(srcdir)/sources.am \ - $(top_srcdir)/../../build-aux/compile \ - $(top_srcdir)/../../build-aux/depcomp \ - $(top_srcdir)/../../build-aux/install-sh \ - $(top_srcdir)/../../build-aux/missing \ - $(top_srcdir)/../../build-aux/test-driver \ - $(top_srcdir)/pixman-src/pixman/pixman-version.h.in \ - ../../build-aux/compile ../../build-aux/config.guess \ - ../../build-aux/config.sub ../../build-aux/depcomp \ - ../../build-aux/install-sh ../../build-aux/ltmain.sh \ - ../../build-aux/missing ../../build-aux/texinfo.tex \ - ../../build-aux/ylwrap ChangeLog README -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -distdir = $(PACKAGE)-$(VERSION) -top_distdir = $(distdir) -am__remove_distdir = \ - if test -d "$(distdir)"; then \ - find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ - && rm -rf "$(distdir)" \ - || { sleep 5 && rm -rf "$(distdir)"; }; \ - else :; fi -am__post_remove_distdir = $(am__remove_distdir) -am__relativize = \ - dir0=`pwd`; \ - sed_first='s,^\([^/]*\)/.*$$,\1,'; \ - sed_rest='s,^[^/]*/*,,'; \ - sed_last='s,^.*/\([^/]*\)$$,\1,'; \ - sed_butlast='s,/*[^/]*$$,,'; \ - while test -n "$$dir1"; do \ - first=`echo "$$dir1" | sed -e "$$sed_first"`; \ - if test "$$first" != "."; then \ - if test "$$first" = ".."; then \ - dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ - dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ - else \ - first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ - if test "$$first2" = "$$first"; then \ - dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ - else \ - dir2="../$$dir2"; \ - fi; \ - dir0="$$dir0"/"$$first"; \ - fi; \ - fi; \ - dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ - done; \ - reldir="$$dir2" -DIST_ARCHIVES = $(distdir).tar.gz -GZIP_ENV = --best -DIST_TARGETS = dist-gzip -distuninstallcheck_listfiles = find . -type f -print -am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ - | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' -distcleancheck_listfiles = find . -type f -print -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PIXMAN_TREE = @PIXMAN_TREE@ -PIXMAN_VERSION_MAJOR = @PIXMAN_VERSION_MAJOR@ -PIXMAN_VERSION_MICRO = @PIXMAN_VERSION_MICRO@ -PIXMAN_VERSION_MINOR = @PIXMAN_VERSION_MINOR@ -RANLIB = @RANLIB@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -VISIBILITY_CFLAGS = @VISIBILITY_CFLAGS@ -WARNING_CFLAGS = @WARNING_CFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build_alias = @build_alias@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host_alias = @host_alias@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -EXTRA_DIST = $(PIXMAN_TREE) pixman-PATCHES -PIXMAN_SRC = $(PIXMAN_TREE)/pixman -NEVER_DIST = `find . $(NEVER_NAMES)` - -# Files not to be distributed -NEVER_NAMES = -name .svn $(NEVER_NAMES_SUB) -NEVER_NAMES_SUB = -o -name .deps -o -name .dirstamp -o -name '*.$(OBJEXT)' -NEVER_NAMES_LT = -o -name .libs -o -name '*.lo' -SUBDIRS = . include -AM_CPPFLAGS = -I$(top_srcdir)/$(PIXMAN_SRC) -AM_CFLAGS = $(VISIBILITY_CFLAGS) # $(WARNING_CFLAGS) -noinst_LIBRARIES = libpixman.a -libpixman_sources = \ - @PIXMAN_TREE@/pixman/pixman.c \ - @PIXMAN_TREE@/pixman/pixman-access.c \ - @PIXMAN_TREE@/pixman/pixman-access-accessors.c \ - @PIXMAN_TREE@/pixman/pixman-bits-image.c \ - @PIXMAN_TREE@/pixman/pixman-combine32.c \ - @PIXMAN_TREE@/pixman/pixman-combine-float.c \ - @PIXMAN_TREE@/pixman/pixman-conical-gradient.c \ - @PIXMAN_TREE@/pixman/pixman-x86.c \ - @PIXMAN_TREE@/pixman/pixman-mips.c \ - @PIXMAN_TREE@/pixman/pixman-arm.c \ - @PIXMAN_TREE@/pixman/pixman-ppc.c \ - @PIXMAN_TREE@/pixman/pixman-edge.c \ - @PIXMAN_TREE@/pixman/pixman-edge-accessors.c \ - @PIXMAN_TREE@/pixman/pixman-fast-path.c \ - @PIXMAN_TREE@/pixman/pixman-filter.c \ - @PIXMAN_TREE@/pixman/pixman-glyph.c \ - @PIXMAN_TREE@/pixman/pixman-general.c \ - @PIXMAN_TREE@/pixman/pixman-gradient-walker.c \ - @PIXMAN_TREE@/pixman/pixman-image.c \ - @PIXMAN_TREE@/pixman/pixman-implementation.c \ - @PIXMAN_TREE@/pixman/pixman-linear-gradient.c \ - @PIXMAN_TREE@/pixman/pixman-matrix.c \ - @PIXMAN_TREE@/pixman/pixman-noop.c \ - @PIXMAN_TREE@/pixman/pixman-radial-gradient.c \ - @PIXMAN_TREE@/pixman/pixman-region16.c \ - @PIXMAN_TREE@/pixman/pixman-region32.c \ - @PIXMAN_TREE@/pixman/pixman-solid-fill.c \ - @PIXMAN_TREE@/pixman/pixman-timer.c \ - @PIXMAN_TREE@/pixman/pixman-trap.c \ - @PIXMAN_TREE@/pixman/pixman-utils.c - -libpixman_headers = \ - @PIXMAN_TREE@/pixman/pixman.h \ - @PIXMAN_TREE@/pixman/pixman-accessor.h \ - @PIXMAN_TREE@/pixman/pixman-combine32.h \ - @PIXMAN_TREE@/pixman/pixman-compiler.h \ - @PIXMAN_TREE@/pixman/pixman-edge-imp.h \ - @PIXMAN_TREE@/pixman/pixman-inlines.h \ - @PIXMAN_TREE@/pixman/pixman-private.h - -libpixman_a_SOURCES = $(libpixman_sources) $(libpixman_headers) -@build_TRUE@dist_check_SCRIPTS = pixman.test -@build_TRUE@TESTS = pixman.test -pixtest_SOURCES = pixtest.c -pixtest_CPPFLAGS = -Iinclude -LDADD = libpixman.a - -# Rebuild -rebuild_prereq = -rebuild_target = all -CLEANFILES = rebuild.stamp -all: config.h - $(MAKE) $(AM_MAKEFLAGS) all-recursive - -.SUFFIXES: -.SUFFIXES: .c .log .o .obj .test .test$(EXEEXT) .trs -am--refresh: Makefile - @: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/../../am/dist_hook.am $(srcdir)/sources.am $(srcdir)/../../am/rebuild.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ - $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ - && exit 0; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - echo ' $(SHELL) ./config.status'; \ - $(SHELL) ./config.status;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ - esac; -$(srcdir)/../../am/dist_hook.am $(srcdir)/sources.am $(srcdir)/../../am/rebuild.am $(am__empty): - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - $(SHELL) ./config.status --recheck - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - $(am__cd) $(srcdir) && $(AUTOCONF) -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) -$(am__aclocal_m4_deps): - -config.h: stamp-h1 - @test -f $@ || rm -f stamp-h1 - @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 - -stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status - @rm -f stamp-h1 - cd $(top_builddir) && $(SHELL) ./config.status config.h -$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) - rm -f stamp-h1 - touch $@ - -distclean-hdr: - -rm -f config.h stamp-h1 -pixman-version.h: $(top_builddir)/config.status $(top_srcdir)/pixman-src/pixman/pixman-version.h.in - cd $(top_builddir) && $(SHELL) ./config.status $@ - -clean-noinstLIBRARIES: - -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) -@PIXMAN_TREE@/pixman/$(am__dirstamp): - @$(MKDIR_P) @PIXMAN_TREE@/pixman - @: > @PIXMAN_TREE@/pixman/$(am__dirstamp) -@PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) @PIXMAN_TREE@/pixman/$(DEPDIR) - @: > @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-access.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-access-accessors.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-bits-image.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-combine32.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-combine-float.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-conical-gradient.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-x86.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-mips.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-arm.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-ppc.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-edge.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-edge-accessors.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-fast-path.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-filter.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-glyph.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-general.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-gradient-walker.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-image.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-implementation.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-linear-gradient.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-matrix.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-noop.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-radial-gradient.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-region16.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-region32.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-solid-fill.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-timer.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-trap.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) -@PIXMAN_TREE@/pixman/pixman-utils.$(OBJEXT): \ - @PIXMAN_TREE@/pixman/$(am__dirstamp) \ - @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) - -libpixman.a: $(libpixman_a_OBJECTS) $(libpixman_a_DEPENDENCIES) $(EXTRA_libpixman_a_DEPENDENCIES) - $(AM_V_at)-rm -f libpixman.a - $(AM_V_AR)$(libpixman_a_AR) libpixman.a $(libpixman_a_OBJECTS) $(libpixman_a_LIBADD) - $(AM_V_at)$(RANLIB) libpixman.a - -clean-checkPROGRAMS: - -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS) - -pixtest$(EXEEXT): $(pixtest_OBJECTS) $(pixtest_DEPENDENCIES) $(EXTRA_pixtest_DEPENDENCIES) - @rm -f pixtest$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(pixtest_OBJECTS) $(pixtest_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -rm -f @PIXMAN_TREE@/pixman/*.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pixtest-pixtest.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-access-accessors.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-access.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-arm.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-bits-image.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-combine-float.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-combine32.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-conical-gradient.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-edge-accessors.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-edge.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-fast-path.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-filter.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-general.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-glyph.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-gradient-walker.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-image.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-implementation.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-linear-gradient.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-matrix.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-mips.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-noop.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-ppc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-radial-gradient.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-region16.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-region32.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-solid-fill.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-timer.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-trap.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-utils.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman-x86.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@@PIXMAN_TREE@/pixman/$(DEPDIR)/pixman.Po@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -pixtest-pixtest.o: pixtest.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pixtest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pixtest-pixtest.o -MD -MP -MF $(DEPDIR)/pixtest-pixtest.Tpo -c -o pixtest-pixtest.o `test -f 'pixtest.c' || echo '$(srcdir)/'`pixtest.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pixtest-pixtest.Tpo $(DEPDIR)/pixtest-pixtest.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pixtest.c' object='pixtest-pixtest.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pixtest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pixtest-pixtest.o `test -f 'pixtest.c' || echo '$(srcdir)/'`pixtest.c - -pixtest-pixtest.obj: pixtest.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pixtest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pixtest-pixtest.obj -MD -MP -MF $(DEPDIR)/pixtest-pixtest.Tpo -c -o pixtest-pixtest.obj `if test -f 'pixtest.c'; then $(CYGPATH_W) 'pixtest.c'; else $(CYGPATH_W) '$(srcdir)/pixtest.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pixtest-pixtest.Tpo $(DEPDIR)/pixtest-pixtest.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pixtest.c' object='pixtest-pixtest.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pixtest_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pixtest-pixtest.obj `if test -f 'pixtest.c'; then $(CYGPATH_W) 'pixtest.c'; else $(CYGPATH_W) '$(srcdir)/pixtest.c'; fi` - -# This directory's subdirectories are mostly independent; you can cd -# into them and run 'make' without going through this Makefile. -# To change the values of 'make' variables: instead of editing Makefiles, -# (1) if the variable is set in 'config.status', edit 'config.status' -# (which will cause the Makefiles to be regenerated when you run 'make'); -# (2) otherwise, pass the desired values on the 'make' command line. -$(am__recursive_targets): - @fail=; \ - if $(am__make_keepgoing); then \ - failcom='fail=yes'; \ - else \ - failcom='exit 1'; \ - fi; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - case "$@" in \ - distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ - *) list='$(SUBDIRS)' ;; \ - esac; \ - for subdir in $$list; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || eval $$failcom; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ - fi; test -z "$$fail" - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-recursive -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ - include_option=--etags-include; \ - empty_fix=.; \ - else \ - include_option=--include; \ - empty_fix=; \ - fi; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test ! -f $$subdir/TAGS || \ - set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ - fi; \ - done; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-recursive - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscope: cscope.files - test ! -s cscope.files \ - || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) -clean-cscope: - -rm -f cscope.files -cscope.files: clean-cscope cscopelist -cscopelist: cscopelist-recursive - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -rm -f cscope.out cscope.in.out cscope.po.out cscope.files - -# Recover from deleted '.trs' file; this should ensure that -# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create -# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells -# to avoid problems with "make -n". -.log.trs: - rm -f $< $@ - $(MAKE) $(AM_MAKEFLAGS) $< - -# Leading 'am--fnord' is there to ensure the list of targets does not -# expand to empty, as could happen e.g. with make check TESTS=''. -am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) -am--force-recheck: - @: - -$(TEST_SUITE_LOG): $(TEST_LOGS) - @$(am__set_TESTS_bases); \ - am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ - redo_bases=`for i in $$bases; do \ - am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ - done`; \ - if test -n "$$redo_bases"; then \ - redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ - redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ - if $(am__make_dryrun); then :; else \ - rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ - fi; \ - fi; \ - if test -n "$$am__remaking_logs"; then \ - echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ - "recursion detected" >&2; \ - elif test -n "$$redo_logs"; then \ - am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ - fi; \ - if $(am__make_dryrun); then :; else \ - st=0; \ - errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ - for i in $$redo_bases; do \ - test -f $$i.trs && test -r $$i.trs \ - || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ - test -f $$i.log && test -r $$i.log \ - || { echo "$$errmsg $$i.log" >&2; st=1; }; \ - done; \ - test $$st -eq 0 || exit 1; \ - fi - @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ - ws='[ ]'; \ - results=`for b in $$bases; do echo $$b.trs; done`; \ - test -n "$$results" || results=/dev/null; \ - all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ - pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ - fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ - skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ - xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ - xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ - error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ - if test `expr $$fail + $$xpass + $$error` -eq 0; then \ - success=true; \ - else \ - success=false; \ - fi; \ - br='==================='; br=$$br$$br$$br$$br; \ - result_count () \ - { \ - if test x"$$1" = x"--maybe-color"; then \ - maybe_colorize=yes; \ - elif test x"$$1" = x"--no-color"; then \ - maybe_colorize=no; \ - else \ - echo "$@: invalid 'result_count' usage" >&2; exit 4; \ - fi; \ - shift; \ - desc=$$1 count=$$2; \ - if test $$maybe_colorize = yes && test $$count -gt 0; then \ - color_start=$$3 color_end=$$std; \ - else \ - color_start= color_end=; \ - fi; \ - echo "$${color_start}# $$desc $$count$${color_end}"; \ - }; \ - create_testsuite_report () \ - { \ - result_count $$1 "TOTAL:" $$all "$$brg"; \ - result_count $$1 "PASS: " $$pass "$$grn"; \ - result_count $$1 "SKIP: " $$skip "$$blu"; \ - result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ - result_count $$1 "FAIL: " $$fail "$$red"; \ - result_count $$1 "XPASS:" $$xpass "$$red"; \ - result_count $$1 "ERROR:" $$error "$$mgn"; \ - }; \ - { \ - echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ - $(am__rst_title); \ - create_testsuite_report --no-color; \ - echo; \ - echo ".. contents:: :depth: 2"; \ - echo; \ - for b in $$bases; do echo $$b; done \ - | $(am__create_global_log); \ - } >$(TEST_SUITE_LOG).tmp || exit 1; \ - mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ - if $$success; then \ - col="$$grn"; \ - else \ - col="$$red"; \ - test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ - fi; \ - echo "$${col}$$br$${std}"; \ - echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ - echo "$${col}$$br$${std}"; \ - create_testsuite_report --maybe-color; \ - echo "$$col$$br$$std"; \ - if $$success; then :; else \ - echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ - if test -n "$(PACKAGE_BUGREPORT)"; then \ - echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ - fi; \ - echo "$$col$$br$$std"; \ - fi; \ - $$success || exit 1 - -check-TESTS: - @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list - @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list - @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - @set +e; $(am__set_TESTS_bases); \ - log_list=`for i in $$bases; do echo $$i.log; done`; \ - trs_list=`for i in $$bases; do echo $$i.trs; done`; \ - log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ - $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ - exit $$?; -recheck: all $(check_PROGRAMS) $(dist_check_SCRIPTS) - @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - @set +e; $(am__set_TESTS_bases); \ - bases=`for i in $$bases; do echo $$i; done \ - | $(am__list_recheck_tests)` || exit 1; \ - log_list=`for i in $$bases; do echo $$i.log; done`; \ - log_list=`echo $$log_list`; \ - $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ - am__force_recheck=am--force-recheck \ - TEST_LOGS="$$log_list"; \ - exit $$? -.test.log: - @p='$<'; \ - $(am__set_b); \ - $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ - --log-file $$b.log --trs-file $$b.trs \ - $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ - "$$tst" $(AM_TESTS_FD_REDIRECT) -@am__EXEEXT_TRUE@.test$(EXEEXT).log: -@am__EXEEXT_TRUE@ @p='$<'; \ -@am__EXEEXT_TRUE@ $(am__set_b); \ -@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ -@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ -@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ -@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) - -distdir: $(DISTFILES) - $(am__remove_distdir) - test -d "$(distdir)" || mkdir "$(distdir)" - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done - @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - $(am__make_dryrun) \ - || test -d "$(distdir)/$$subdir" \ - || $(MKDIR_P) "$(distdir)/$$subdir" \ - || exit 1; \ - dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ - $(am__relativize); \ - new_distdir=$$reldir; \ - dir1=$$subdir; dir2="$(top_distdir)"; \ - $(am__relativize); \ - new_top_distdir=$$reldir; \ - echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ - echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ - ($(am__cd) $$subdir && \ - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$$new_top_distdir" \ - distdir="$$new_distdir" \ - am__remove_distdir=: \ - am__skip_length_check=: \ - am__skip_mode_fix=: \ - distdir) \ - || exit 1; \ - fi; \ - done - $(MAKE) $(AM_MAKEFLAGS) \ - top_distdir="$(top_distdir)" distdir="$(distdir)" \ - dist-hook - -test -n "$(am__skip_mode_fix)" \ - || find "$(distdir)" -type d ! -perm -755 \ - -exec chmod u+rwx,go+rx {} \; -o \ - ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ - ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ - || chmod -R a+r "$(distdir)" -dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz - $(am__post_remove_distdir) - -dist-bzip2: distdir - tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 - $(am__post_remove_distdir) - -dist-lzip: distdir - tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz - $(am__post_remove_distdir) - -dist-xz: distdir - tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz - $(am__post_remove_distdir) - -dist-tarZ: distdir - @echo WARNING: "Support for distribution archives compressed with" \ - "legacy program 'compress' is deprecated." >&2 - @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z - $(am__post_remove_distdir) - -dist-shar: distdir - @echo WARNING: "Support for shar distribution archives is" \ - "deprecated." >&2 - @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz - $(am__post_remove_distdir) - -dist-zip: distdir - -rm -f $(distdir).zip - zip -rq $(distdir).zip $(distdir) - $(am__post_remove_distdir) - -dist dist-all: - $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' - $(am__post_remove_distdir) - -# This target untars the dist file and tries a VPATH configuration. Then -# it guarantees that the distribution is self-contained by making another -# tarfile. -distcheck: dist - case '$(DIST_ARCHIVES)' in \ - *.tar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ - *.tar.bz2*) \ - bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ - *.tar.lz*) \ - lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ - *.tar.xz*) \ - xz -dc $(distdir).tar.xz | $(am__untar) ;;\ - *.tar.Z*) \ - uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ - *.shar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ - *.zip*) \ - unzip $(distdir).zip ;;\ - esac - chmod -R a-w $(distdir) - chmod u+w $(distdir) - mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst - chmod a-w $(distdir) - test -d $(distdir)/_build || exit 0; \ - dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ - && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ - && am__cwd=`pwd` \ - && $(am__cd) $(distdir)/_build/sub \ - && ../../configure \ - $(AM_DISTCHECK_CONFIGURE_FLAGS) \ - $(DISTCHECK_CONFIGURE_FLAGS) \ - --srcdir=../.. --prefix="$$dc_install_base" \ - && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) dvi \ - && $(MAKE) $(AM_MAKEFLAGS) check \ - && $(MAKE) $(AM_MAKEFLAGS) install \ - && $(MAKE) $(AM_MAKEFLAGS) installcheck \ - && $(MAKE) $(AM_MAKEFLAGS) uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ - distuninstallcheck \ - && chmod -R a-w "$$dc_install_base" \ - && ({ \ - (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ - && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ - distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ - } || { rm -rf "$$dc_destdir"; exit 1; }) \ - && rm -rf "$$dc_destdir" \ - && $(MAKE) $(AM_MAKEFLAGS) dist \ - && rm -rf $(DIST_ARCHIVES) \ - && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ - && cd "$$am__cwd" \ - || exit 1 - $(am__post_remove_distdir) - @(echo "$(distdir) archives ready for distribution: "; \ - list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ - sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' -distuninstallcheck: - @test -n '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: trying to run $@ with an empty' \ - '$$(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - $(am__cd) '$(distuninstallcheck_dir)' || { \ - echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ - exit 1; \ - }; \ - test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left after uninstall:" ; \ - if test -n "$(DESTDIR)"; then \ - echo " (check DESTDIR support)"; \ - fi ; \ - $(distuninstallcheck_listfiles) ; \ - exit 1; } >&2 -distcleancheck: distclean - @if test '$(srcdir)' = . ; then \ - echo "ERROR: distcleancheck can only run from a VPATH build" ; \ - exit 1 ; \ - fi - @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ - || { echo "ERROR: files left in build directory after distclean:" ; \ - $(distcleancheck_listfiles) ; \ - exit 1; } >&2 -check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) \ - $(dist_check_SCRIPTS) - $(MAKE) $(AM_MAKEFLAGS) check-TESTS -check: check-recursive -all-am: Makefile $(LIBRARIES) config.h -installdirs: installdirs-recursive -installdirs-am: -install: install-recursive -install-exec: install-exec-recursive -install-data: install-data-recursive -uninstall: uninstall-recursive - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-recursive -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) - -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) - -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - -clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f @PIXMAN_TREE@/pixman/$(DEPDIR)/$(am__dirstamp) - -rm -f @PIXMAN_TREE@/pixman/$(am__dirstamp) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-recursive - -clean-am: clean-checkPROGRAMS clean-generic clean-noinstLIBRARIES \ - mostlyclean-am - -distclean: distclean-recursive - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf ./$(DEPDIR) @PIXMAN_TREE@/pixman/$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-hdr distclean-tags - -dvi: dvi-recursive - -dvi-am: - -html: html-recursive - -html-am: - -info: info-recursive - -info-am: - -install-data-am: - -install-dvi: install-dvi-recursive - -install-dvi-am: - -install-exec-am: - -install-html: install-html-recursive - -install-html-am: - -install-info: install-info-recursive - -install-info-am: - -install-man: - -install-pdf: install-pdf-recursive - -install-pdf-am: - -install-ps: install-ps-recursive - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-recursive - -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf $(top_srcdir)/autom4te.cache - -rm -rf ./$(DEPDIR) @PIXMAN_TREE@/pixman/$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-recursive - -mostlyclean-am: mostlyclean-compile mostlyclean-generic - -pdf: pdf-recursive - -pdf-am: - -ps: ps-recursive - -ps-am: - -uninstall-am: - -.MAKE: $(am__recursive_targets) all check-am install-am install-strip - -.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ - am--refresh check check-TESTS check-am clean \ - clean-checkPROGRAMS clean-cscope clean-generic \ - clean-noinstLIBRARIES cscope cscopelist-am ctags ctags-am dist \ - dist-all dist-bzip2 dist-gzip dist-hook dist-lzip dist-shar \ - dist-tarZ dist-xz dist-zip distcheck distclean \ - distclean-compile distclean-generic distclean-hdr \ - distclean-tags distcleancheck distdir distuninstallcheck dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs installdirs-am \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ - recheck tags tags-am uninstall uninstall-am - -.PRECIOUS: Makefile - -dist-hook: - cd "$(distdir)" && rm -rf $(NEVER_DIST) -pixman.log: pixtest$(EXEEXT) -rebuild.stamp: $(rebuild_target) - echo timestamp >$@ - -.PHONY: rebuild -rebuild: $(rebuild_prereq) - @dry=; for f in x $$MAKEFLAGS; do \ - case $$f in \ - *=*|--*);; \ - *n*) dry=:;; \ - esac; \ - done; \ - if test -f rebuild.stamp; then :; else \ - $$dry trap 'rm -rf rebuild.lock' 1 2 13 15; \ - if $$dry mkdir rebuild.lock 2>/dev/null; then \ - $(MAKE) $(AM_MAKEFLAGS) rebuild.stamp; \ - $$dry rmdir rebuild.lock; \ - else \ - while test -d rebuild.lock && test -z "$$dry"; do sleep 1; done; \ - fi; \ - $$dry test -f rebuild.stamp; exit $$?; \ - fi - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/source/libs/pixman/README b/source/libs/pixman/README deleted file mode 100644 index 7fb53afe2116f5732c37a45f844d0c3fe67d258e..0000000000000000000000000000000000000000 --- a/source/libs/pixman/README +++ /dev/null @@ -1,15 +0,0 @@ - Building pixman-0.34.0 as part of the TL tree - ============================================= - -This directory libs/pixman/ uses a proxy Makefile.am to build the pixman -library 'libpixman' from the unmodified source tree in -libs/pixman/pixman-src/, bypassing the original build system. - -As far as applicable, the tests in libs/pixman/pixman-src/configure have -been translated into equivalent test in libs/pixman/configure.ac. - -============================= - -2012-11-10 Taco Hoekwater <taco@metatex.org> -2012-11-15 Peter Breitenlohner <peb@mppmu.mpg.de> -2016-02-04 Akira Kakuto <kakuto@fuk.kindai.ac.jp> diff --git a/source/libs/pixman/TLpatches/ChangeLog b/source/libs/pixman/TLpatches/ChangeLog deleted file mode 100644 index 39dcd76ca07e967fa98ace227a487e698db648cf..0000000000000000000000000000000000000000 --- a/source/libs/pixman/TLpatches/ChangeLog +++ /dev/null @@ -1,41 +0,0 @@ -2016-02-04 Akira Kakuto <kakuto@fuk.kindai.ac.jp> - - Import pixman-0.34.0. - * patch-01-hide-symbols: Adapted. - -2015-09-26 Peter Breitenlohner <peb@mppmu.mpg.de> - - Import pixman-0.32.8. - * patch-01-hide-symbols: Adapted. - -2014-12-04 Peter Breitenlohner <peb@mppmu.mpg.de> - - * patch-01-hide-symbols (new): Allow to hide all symbols. - -2014-07-07 Peter Breitenlohner <peb@mppmu.mpg.de> - - Import pixman-0.32.6. - -2013-11-18 Peter Breitenlohner <peb@mppmu.mpg.de> - - Import pixman-0.32.4. - -2013-11-12 Peter Breitenlohner <peb@mppmu.mpg.de> - - Import pixman-0.32.2. - -2013-11-11 Peter Breitenlohner <peb@mppmu.mpg.de> - - Import pixman-0.32.0. - -2013-08-08 Peter Breitenlohner <peb@mppmu.mpg.de> - - Import pixman-0.30.2. - -2013-05-30 Peter Breitenlohner <peb@mppmu.mpg.de> - - Import pixman-0.30.0. - -2012-11-10 Taco Hoekwater <taco@metatex.org> - - Import pixman-0.28.0. diff --git a/source/libs/pixman/TLpatches/TL-Changes b/source/libs/pixman/TLpatches/TL-Changes deleted file mode 100644 index 7df6c0ac66a777d46da9082cc0ff7a6e93e8baa9..0000000000000000000000000000000000000000 --- a/source/libs/pixman/TLpatches/TL-Changes +++ /dev/null @@ -1,22 +0,0 @@ -Changes applied to the pixman-0.34.0/ tree as obtained from: - http://cairographics.org/releases/ - -Removed: - Makefile.in - aclocal.m4 - config.guess - config.sub - configure - compile - depcomp - install-sh - ltmain.sh - missing - pixman/Makefile.in - pixman/pixman-version.h - test-driver - -Removed unused dirs: - demos - test - diff --git a/source/libs/pixman/TLpatches/patch-01-hide-symbols b/source/libs/pixman/TLpatches/patch-01-hide-symbols deleted file mode 100644 index 62cc5f039f789a9009afa30b3afb596aff5b8c51..0000000000000000000000000000000000000000 --- a/source/libs/pixman/TLpatches/patch-01-hide-symbols +++ /dev/null @@ -1,12 +0,0 @@ -diff -ur pixman-0.34.0.orig/pixman/pixman-compiler.h pixman-0.34.0/pixman/pixman-compiler.h ---- pixman-0.34.0.orig/pixman/pixman-compiler.h Tue Jun 30 18:48:31 2015 -+++ pixman-0.34.0/pixman/pixman-compiler.h Thu Feb 04 16:56:27 2016 -@@ -91,7 +91,7 @@ - - /* GCC visibility */ - #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(_WIN32) --# define PIXMAN_EXPORT __attribute__ ((visibility("default"))) -+# define PIXMAN_EXPORT - /* Sun Studio 8 visibility */ - #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) - # define PIXMAN_EXPORT __global diff --git a/source/libs/pixman/ac/pixman.ac b/source/libs/pixman/ac/pixman.ac deleted file mode 100644 index f5475081c4df0ecce0594d95699ab3effbbd3c61..0000000000000000000000000000000000000000 --- a/source/libs/pixman/ac/pixman.ac +++ /dev/null @@ -1,9 +0,0 @@ -## libs/pixman/ac/pixman.ac: configure.ac fragment for the TeX Live subdirectory libs/pixman/ -dnl -dnl Copyright (C) 2012 Peter Breitenlohner <tex-live@tug.org> -dnl You may freely use, modify and/or distribute this file. -dnl -## basic check of system pixman -KPSE_TRY_LIB([pixman], - [#include <pixman.h>], - [const char *s = pixman_version_string();]) diff --git a/source/libs/pixman/ac/withenable.ac b/source/libs/pixman/ac/withenable.ac deleted file mode 100644 index 53268928965e8b12bca71fde5bffd0017ef6dde2..0000000000000000000000000000000000000000 --- a/source/libs/pixman/ac/withenable.ac +++ /dev/null @@ -1,7 +0,0 @@ -## libs/pixman/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/pixman/ -dnl -dnl Copyright (C) 2012 Peter Breitenlohner <tex-live@tug.org> -dnl You may freely use, modify and/or distribute this file. -dnl -## configure options and TL libraries required for pixman -KPSE_WITH_LIB([pixman]) diff --git a/source/libs/pixman/aclocal.m4 b/source/libs/pixman/aclocal.m4 deleted file mode 100644 index 62ce5bd33f0be446f4e2c60a471c64fa02b751c4..0000000000000000000000000000000000000000 --- a/source/libs/pixman/aclocal.m4 +++ /dev/null @@ -1,1193 +0,0 @@ -# generated automatically by aclocal 1.15 -*- Autoconf -*- - -# Copyright (C) 1996-2014 Free Software Foundation, Inc. - -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) -m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, -[m4_warning([this file was generated for autoconf 2.69. -You have another version of autoconf. It may work, but is not guaranteed to. -If you have problems, you may need to regenerate the build system entirely. -To do so, use the procedure documented by the package, typically 'autoreconf'.])]) - -# Copyright (C) 2002-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_AUTOMAKE_VERSION(VERSION) -# ---------------------------- -# Automake X.Y traces this macro to ensure aclocal.m4 has been -# generated from the m4 files accompanying Automake X.Y. -# (This private macro should not be called outside this file.) -AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.15' -dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to -dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.15], [], - [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl -]) - -# _AM_AUTOCONF_VERSION(VERSION) -# ----------------------------- -# aclocal traces this macro to find the Autoconf version. -# This is a private macro too. Using m4_define simplifies -# the logic in aclocal, which can simply ignore this definition. -m4_define([_AM_AUTOCONF_VERSION], []) - -# AM_SET_CURRENT_AUTOMAKE_VERSION -# ------------------------------- -# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. -# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. -AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.15])dnl -m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) - -# AM_AUX_DIR_EXPAND -*- Autoconf -*- - -# Copyright (C) 2001-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets -# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to -# '$srcdir', '$srcdir/..', or '$srcdir/../..'. -# -# Of course, Automake must honor this variable whenever it calls a -# tool from the auxiliary directory. The problem is that $srcdir (and -# therefore $ac_aux_dir as well) can be either absolute or relative, -# depending on how configure is run. This is pretty annoying, since -# it makes $ac_aux_dir quite unusable in subdirectories: in the top -# source directory, any form will work fine, but in subdirectories a -# relative path needs to be adjusted first. -# -# $ac_aux_dir/missing -# fails when called from a subdirectory if $ac_aux_dir is relative -# $top_srcdir/$ac_aux_dir/missing -# fails if $ac_aux_dir is absolute, -# fails when called from a subdirectory in a VPATH build with -# a relative $ac_aux_dir -# -# The reason of the latter failure is that $top_srcdir and $ac_aux_dir -# are both prefixed by $srcdir. In an in-source build this is usually -# harmless because $srcdir is '.', but things will broke when you -# start a VPATH build or use an absolute $srcdir. -# -# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, -# iff we strip the leading $srcdir from $ac_aux_dir. That would be: -# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` -# and then we would define $MISSING as -# MISSING="\${SHELL} $am_aux_dir/missing" -# This will work as long as MISSING is not called from configure, because -# unfortunately $(top_srcdir) has no meaning in configure. -# However there are other variables, like CC, which are often used in -# configure, and could therefore not use this "fixed" $ac_aux_dir. -# -# Another solution, used here, is to always expand $ac_aux_dir to an -# absolute PATH. The drawback is that using absolute paths prevent a -# configured tree to be moved without reconfiguration. - -AC_DEFUN([AM_AUX_DIR_EXPAND], -[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl -# Expand $ac_aux_dir to an absolute path. -am_aux_dir=`cd "$ac_aux_dir" && pwd` -]) - -# AM_CONDITIONAL -*- Autoconf -*- - -# Copyright (C) 1997-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_CONDITIONAL(NAME, SHELL-CONDITION) -# ------------------------------------- -# Define a conditional. -AC_DEFUN([AM_CONDITIONAL], -[AC_PREREQ([2.52])dnl - m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], - [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl -AC_SUBST([$1_TRUE])dnl -AC_SUBST([$1_FALSE])dnl -_AM_SUBST_NOTMAKE([$1_TRUE])dnl -_AM_SUBST_NOTMAKE([$1_FALSE])dnl -m4_define([_AM_COND_VALUE_$1], [$2])dnl -if $2; then - $1_TRUE= - $1_FALSE='#' -else - $1_TRUE='#' - $1_FALSE= -fi -AC_CONFIG_COMMANDS_PRE( -[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then - AC_MSG_ERROR([[conditional "$1" was never defined. -Usually this means the macro was only invoked conditionally.]]) -fi])]) - -# Copyright (C) 1999-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - - -# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be -# written in clear, in which case automake, when reading aclocal.m4, -# will think it sees a *use*, and therefore will trigger all it's -# C support machinery. Also note that it means that autoscan, seeing -# CC etc. in the Makefile, will ask for an AC_PROG_CC use... - - -# _AM_DEPENDENCIES(NAME) -# ---------------------- -# See how the compiler implements dependency checking. -# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". -# We try a few techniques and use that to set a single cache variable. -# -# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was -# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular -# dependency, and given that the user is not expected to run this macro, -# just rely on AC_PROG_CC. -AC_DEFUN([_AM_DEPENDENCIES], -[AC_REQUIRE([AM_SET_DEPDIR])dnl -AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl -AC_REQUIRE([AM_MAKE_INCLUDE])dnl -AC_REQUIRE([AM_DEP_TRACK])dnl - -m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], - [$1], [CXX], [depcc="$CXX" am_compiler_list=], - [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], - [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], - [$1], [UPC], [depcc="$UPC" am_compiler_list=], - [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], - [depcc="$$1" am_compiler_list=]) - -AC_CACHE_CHECK([dependency style of $depcc], - [am_cv_$1_dependencies_compiler_type], -[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named 'D' -- because '-MD' means "put the output - # in D". - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_$1_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` - fi - am__universal=false - m4_case([$1], [CC], - [case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac], - [CXX], - [case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac]) - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with - # Solaris 10 /bin/sh. - echo '/* dummy */' > sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with '-c' and '-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle '-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs. - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # After this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested. - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok '-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_$1_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_$1_dependencies_compiler_type=none -fi -]) -AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) -AM_CONDITIONAL([am__fastdep$1], [ - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) -]) - - -# AM_SET_DEPDIR -# ------------- -# Choose a directory name for dependency files. -# This macro is AC_REQUIREd in _AM_DEPENDENCIES. -AC_DEFUN([AM_SET_DEPDIR], -[AC_REQUIRE([AM_SET_LEADING_DOT])dnl -AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl -]) - - -# AM_DEP_TRACK -# ------------ -AC_DEFUN([AM_DEP_TRACK], -[AC_ARG_ENABLE([dependency-tracking], [dnl -AS_HELP_STRING( - [--enable-dependency-tracking], - [do not reject slow dependency extractors]) -AS_HELP_STRING( - [--disable-dependency-tracking], - [speeds up one-time build])]) -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' - am__nodep='_no' -fi -AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) -AC_SUBST([AMDEPBACKSLASH])dnl -_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl -AC_SUBST([am__nodep])dnl -_AM_SUBST_NOTMAKE([am__nodep])dnl -]) - -# Generate code to set up dependency tracking. -*- Autoconf -*- - -# Copyright (C) 1999-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - - -# _AM_OUTPUT_DEPENDENCY_COMMANDS -# ------------------------------ -AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], -[{ - # Older Autoconf quotes --file arguments for eval, but not when files - # are listed without --file. Let's play safe and only enable the eval - # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac - shift - for mf - do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`AS_DIRNAME("$mf")` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`AS_DIRNAME(["$file"])` - AS_MKDIR_P([$dirpart/$fdir]) - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done - done -} -])# _AM_OUTPUT_DEPENDENCY_COMMANDS - - -# AM_OUTPUT_DEPENDENCY_COMMANDS -# ----------------------------- -# This macro should only be invoked once -- use via AC_REQUIRE. -# -# This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each '.P' file that we will -# need in order to bootstrap the dependency handling code. -AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], -[AC_CONFIG_COMMANDS([depfiles], - [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], - [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) -]) - -# Do all the work for Automake. -*- Autoconf -*- - -# Copyright (C) 1996-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This macro actually does too much. Some checks are only needed if -# your package does certain things. But this isn't really a big deal. - -dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. -m4_define([AC_PROG_CC], -m4_defn([AC_PROG_CC]) -[_AM_PROG_CC_C_O -]) - -# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) -# AM_INIT_AUTOMAKE([OPTIONS]) -# ----------------------------------------------- -# The call with PACKAGE and VERSION arguments is the old style -# call (pre autoconf-2.50), which is being phased out. PACKAGE -# and VERSION should now be passed to AC_INIT and removed from -# the call to AM_INIT_AUTOMAKE. -# We support both call styles for the transition. After -# the next Automake release, Autoconf can make the AC_INIT -# arguments mandatory, and then we can depend on a new Autoconf -# release and drop the old call support. -AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_PREREQ([2.65])dnl -dnl Autoconf wants to disallow AM_ names. We explicitly allow -dnl the ones we care about. -m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl -AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl -AC_REQUIRE([AC_PROG_INSTALL])dnl -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi -AC_SUBST([CYGPATH_W]) - -# Define the identity of the package. -dnl Distinguish between old-style and new-style calls. -m4_ifval([$2], -[AC_DIAGNOSE([obsolete], - [$0: two- and three-arguments forms are deprecated.]) -m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl - AC_SUBST([PACKAGE], [$1])dnl - AC_SUBST([VERSION], [$2])], -[_AM_SET_OPTIONS([$1])dnl -dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. -m4_if( - m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), - [ok:ok],, - [m4_fatal([AC_INIT should be called with package and version arguments])])dnl - AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl - AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl - -_AM_IF_OPTION([no-define],, -[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) - AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl - -# Some tools Automake needs. -AC_REQUIRE([AM_SANITY_CHECK])dnl -AC_REQUIRE([AC_ARG_PROGRAM])dnl -AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) -AM_MISSING_PROG([AUTOCONF], [autoconf]) -AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) -AM_MISSING_PROG([AUTOHEADER], [autoheader]) -AM_MISSING_PROG([MAKEINFO], [makeinfo]) -AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl -AC_REQUIRE([AC_PROG_MKDIR_P])dnl -# For better backward compatibility. To be removed once Automake 1.9.x -# dies out for good. For more background, see: -# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> -# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> -AC_SUBST([mkdir_p], ['$(MKDIR_P)']) -# We need awk for the "check" target (and possibly the TAP driver). The -# system "awk" is bad on some platforms. -AC_REQUIRE([AC_PROG_AWK])dnl -AC_REQUIRE([AC_PROG_MAKE_SET])dnl -AC_REQUIRE([AM_SET_LEADING_DOT])dnl -_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], - [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], - [_AM_PROG_TAR([v7])])]) -_AM_IF_OPTION([no-dependencies],, -[AC_PROVIDE_IFELSE([AC_PROG_CC], - [_AM_DEPENDENCIES([CC])], - [m4_define([AC_PROG_CC], - m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_CXX], - [_AM_DEPENDENCIES([CXX])], - [m4_define([AC_PROG_CXX], - m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_OBJC], - [_AM_DEPENDENCIES([OBJC])], - [m4_define([AC_PROG_OBJC], - m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl -AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], - [_AM_DEPENDENCIES([OBJCXX])], - [m4_define([AC_PROG_OBJCXX], - m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl -]) -AC_REQUIRE([AM_SILENT_RULES])dnl -dnl The testsuite driver may need to know about EXEEXT, so add the -dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This -dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. -AC_CONFIG_COMMANDS_PRE(dnl -[m4_provide_if([_AM_COMPILER_EXEEXT], - [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl - -# POSIX will say in a future version that running "rm -f" with no argument -# is OK; and we want to be able to make that assumption in our Makefile -# recipes. So use an aggressive probe to check that the usage we want is -# actually supported "in the wild" to an acceptable degree. -# See automake bug#10828. -# To make any issue more visible, cause the running configure to be aborted -# by default if the 'rm' program in use doesn't match our expectations; the -# user can still override this though. -if rm -f && rm -fr && rm -rf; then : OK; else - cat >&2 <<'END' -Oops! - -Your 'rm' program seems unable to run without file operands specified -on the command line, even when the '-f' option is present. This is contrary -to the behaviour of most rm programs out there, and not conforming with -the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> - -Please tell bug-automake@gnu.org about your system, including the value -of your $PATH and any error possibly output before this message. This -can help us improve future automake versions. - -END - if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then - echo 'Configuration will proceed anyway, since you have set the' >&2 - echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 - echo >&2 - else - cat >&2 <<'END' -Aborting the configuration process, to ensure you take notice of the issue. - -You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: <http://www.gnu.org/software/coreutils/>. - -If you want to complete the configuration process using your problematic -'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM -to "yes", and re-run configure. - -END - AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) - fi -fi -dnl The trailing newline in this macro's definition is deliberate, for -dnl backward compatibility and to allow trailing 'dnl'-style comments -dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. -]) - -dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not -dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further -dnl mangled by Autoconf and run in a shell conditional statement. -m4_define([_AC_COMPILER_EXEEXT], -m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) - -# When config.status generates a header, we must update the stamp-h file. -# This file resides in the same directory as the config header -# that is generated. The stamp files are numbered to have different names. - -# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the -# loop where config.status creates the headers, so we can generate -# our stamp files there. -AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], -[# Compute $1's index in $config_headers. -_am_arg=$1 -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $_am_arg | $_am_arg:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) - -# Copyright (C) 2001-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_INSTALL_SH -# ------------------ -# Define $install_sh. -AC_DEFUN([AM_PROG_INSTALL_SH], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -if test x"${install_sh+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi -AC_SUBST([install_sh])]) - -# Copyright (C) 2003-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# Check whether the underlying file-system supports filenames -# with a leading dot. For instance MS-DOS doesn't. -AC_DEFUN([AM_SET_LEADING_DOT], -[rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null -AC_SUBST([am__leading_dot])]) - -# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- -# From Jim Meyering - -# Copyright (C) 1996-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_MAINTAINER_MODE([DEFAULT-MODE]) -# ---------------------------------- -# Control maintainer-specific portions of Makefiles. -# Default is to disable them, unless 'enable' is passed literally. -# For symmetry, 'disable' may be passed as well. Anyway, the user -# can override the default with the --enable/--disable switch. -AC_DEFUN([AM_MAINTAINER_MODE], -[m4_case(m4_default([$1], [disable]), - [enable], [m4_define([am_maintainer_other], [disable])], - [disable], [m4_define([am_maintainer_other], [enable])], - [m4_define([am_maintainer_other], [enable]) - m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) -AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) - dnl maintainer-mode's default is 'disable' unless 'enable' is passed - AC_ARG_ENABLE([maintainer-mode], - [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], - am_maintainer_other[ make rules and dependencies not useful - (and sometimes confusing) to the casual installer])], - [USE_MAINTAINER_MODE=$enableval], - [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) - AC_MSG_RESULT([$USE_MAINTAINER_MODE]) - AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) - MAINT=$MAINTAINER_MODE_TRUE - AC_SUBST([MAINT])dnl -] -) - -# Check to see how 'make' treats includes. -*- Autoconf -*- - -# Copyright (C) 2001-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_MAKE_INCLUDE() -# ----------------- -# Check to see how make treats includes. -AC_DEFUN([AM_MAKE_INCLUDE], -[am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo this is the am__doit target -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -AC_MSG_CHECKING([for style of include used by $am_make]) -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi -AC_SUBST([am__include]) -AC_SUBST([am__quote]) -AC_MSG_RESULT([$_am_result]) -rm -f confinc confmf -]) - -# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- - -# Copyright (C) 1997-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_MISSING_PROG(NAME, PROGRAM) -# ------------------------------ -AC_DEFUN([AM_MISSING_PROG], -[AC_REQUIRE([AM_MISSING_HAS_RUN]) -$1=${$1-"${am_missing_run}$2"} -AC_SUBST($1)]) - -# AM_MISSING_HAS_RUN -# ------------------ -# Define MISSING if not defined so far and test if it is modern enough. -# If it is, set am_missing_run to use it, otherwise, to nothing. -AC_DEFUN([AM_MISSING_HAS_RUN], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([missing])dnl -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac -fi -# Use eval to expand $SHELL -if eval "$MISSING --is-lightweight"; then - am_missing_run="$MISSING " -else - am_missing_run= - AC_MSG_WARN(['missing' script is too old or missing]) -fi -]) - -# Helper functions for option handling. -*- Autoconf -*- - -# Copyright (C) 2001-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_MANGLE_OPTION(NAME) -# ----------------------- -AC_DEFUN([_AM_MANGLE_OPTION], -[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) - -# _AM_SET_OPTION(NAME) -# -------------------- -# Set option NAME. Presently that only means defining a flag for this option. -AC_DEFUN([_AM_SET_OPTION], -[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) - -# _AM_SET_OPTIONS(OPTIONS) -# ------------------------ -# OPTIONS is a space-separated list of Automake options. -AC_DEFUN([_AM_SET_OPTIONS], -[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) - -# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) -# ------------------------------------------- -# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. -AC_DEFUN([_AM_IF_OPTION], -[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) - -# Copyright (C) 1999-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_PROG_CC_C_O -# --------------- -# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC -# to automatically call this. -AC_DEFUN([_AM_PROG_CC_C_O], -[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl -AC_REQUIRE_AUX_FILE([compile])dnl -AC_LANG_PUSH([C])dnl -AC_CACHE_CHECK( - [whether $CC understands -c and -o together], - [am_cv_prog_cc_c_o], - [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) - # Make sure it works both with $CC and with simple cc. - # Following AC_PROG_CC_C_O, we do the test twice because some - # compilers refuse to overwrite an existing .o file with -o, - # though they will create one. - am_cv_prog_cc_c_o=yes - for am_i in 1 2; do - if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ - && test -f conftest2.$ac_objext; then - : OK - else - am_cv_prog_cc_c_o=no - break - fi - done - rm -f core conftest* - unset am_i]) -if test "$am_cv_prog_cc_c_o" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi -AC_LANG_POP([C])]) - -# For backward compatibility. -AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) - -# Copyright (C) 2001-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_RUN_LOG(COMMAND) -# ------------------- -# Run COMMAND, save the exit status in ac_status, and log it. -# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) -AC_DEFUN([AM_RUN_LOG], -[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD - ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD - (exit $ac_status); }]) - -# Check to make sure that the build environment is sane. -*- Autoconf -*- - -# Copyright (C) 1996-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_SANITY_CHECK -# --------------- -AC_DEFUN([AM_SANITY_CHECK], -[AC_MSG_CHECKING([whether build environment is sane]) -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[[\\\"\#\$\&\'\`$am_lf]]*) - AC_MSG_ERROR([unsafe absolute working directory name]);; -esac -case $srcdir in - *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) - AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; -esac - -# Do 'set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken - alias in your environment]) - fi - if test "$[2]" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$[2]" = conftest.file - ) -then - # Ok. - : -else - AC_MSG_ERROR([newly created file is older than distributed files! -Check your system clock]) -fi -AC_MSG_RESULT([yes]) -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & - am_sleep_pid=$! -fi -AC_CONFIG_COMMANDS_PRE( - [AC_MSG_CHECKING([that generated files are newer than configure]) - if test -n "$am_sleep_pid"; then - # Hide warnings about reused PIDs. - wait $am_sleep_pid 2>/dev/null - fi - AC_MSG_RESULT([done])]) -rm -f conftest.file -]) - -# Copyright (C) 2009-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_SILENT_RULES([DEFAULT]) -# -------------------------- -# Enable less verbose build rules; with the default set to DEFAULT -# ("yes" being less verbose, "no" or empty being verbose). -AC_DEFUN([AM_SILENT_RULES], -[AC_ARG_ENABLE([silent-rules], [dnl -AS_HELP_STRING( - [--enable-silent-rules], - [less verbose build output (undo: "make V=1")]) -AS_HELP_STRING( - [--disable-silent-rules], - [verbose build output (undo: "make V=0")])dnl -]) -case $enable_silent_rules in @%:@ ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; -esac -dnl -dnl A few 'make' implementations (e.g., NonStop OS and NextStep) -dnl do not support nested variable expansions. -dnl See automake bug#9928 and bug#10237. -am_make=${MAKE-make} -AC_CACHE_CHECK([whether $am_make supports nested variables], - [am_cv_make_support_nested_variables], - [if AS_ECHO([['TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi]) -if test $am_cv_make_support_nested_variables = yes; then - dnl Using '$V' instead of '$(V)' breaks IRIX make. - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AC_SUBST([AM_V])dnl -AM_SUBST_NOTMAKE([AM_V])dnl -AC_SUBST([AM_DEFAULT_V])dnl -AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl -AC_SUBST([AM_DEFAULT_VERBOSITY])dnl -AM_BACKSLASH='\' -AC_SUBST([AM_BACKSLASH])dnl -_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl -]) - -# Copyright (C) 2001-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# AM_PROG_INSTALL_STRIP -# --------------------- -# One issue with vendor 'install' (even GNU) is that you can't -# specify the program used to strip binaries. This is especially -# annoying in cross-compiling environments, where the build's strip -# is unlikely to handle the host's binaries. -# Fortunately install-sh will honor a STRIPPROG variable, so we -# always use install-sh in "make install-strip", and initialize -# STRIPPROG with the value of the STRIP variable (set by the user). -AC_DEFUN([AM_PROG_INSTALL_STRIP], -[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. -dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. -if test "$cross_compiling" != no; then - AC_CHECK_TOOL([STRIP], [strip], :) -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" -AC_SUBST([INSTALL_STRIP_PROGRAM])]) - -# Copyright (C) 2006-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_SUBST_NOTMAKE(VARIABLE) -# --------------------------- -# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. -# This macro is traced by Automake. -AC_DEFUN([_AM_SUBST_NOTMAKE]) - -# AM_SUBST_NOTMAKE(VARIABLE) -# -------------------------- -# Public sister of _AM_SUBST_NOTMAKE. -AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) - -# Check how to create a tarball. -*- Autoconf -*- - -# Copyright (C) 2004-2014 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_PROG_TAR(FORMAT) -# -------------------- -# Check how to create a tarball in format FORMAT. -# FORMAT should be one of 'v7', 'ustar', or 'pax'. -# -# Substitute a variable $(am__tar) that is a command -# writing to stdout a FORMAT-tarball containing the directory -# $tardir. -# tardir=directory && $(am__tar) > result.tar -# -# Substitute a variable $(am__untar) that extract such -# a tarball read from stdin. -# $(am__untar) < result.tar -# -AC_DEFUN([_AM_PROG_TAR], -[# Always define AMTAR for backward compatibility. Yes, it's still used -# in the wild :-( We should find a proper way to deprecate it ... -AC_SUBST([AMTAR], ['$${TAR-tar}']) - -# We'll loop over all known methods to create a tar archive until one works. -_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' - -m4_if([$1], [v7], - [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], - - [m4_case([$1], - [ustar], - [# The POSIX 1988 'ustar' format is defined with fixed-size fields. - # There is notably a 21 bits limit for the UID and the GID. In fact, - # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 - # and bug#13588). - am_max_uid=2097151 # 2^21 - 1 - am_max_gid=$am_max_uid - # The $UID and $GID variables are not portable, so we need to resort - # to the POSIX-mandated id(1) utility. Errors in the 'id' calls - # below are definitely unexpected, so allow the users to see them - # (that is, avoid stderr redirection). - am_uid=`id -u || echo unknown` - am_gid=`id -g || echo unknown` - AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) - if test $am_uid -le $am_max_uid; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - _am_tools=none - fi - AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) - if test $am_gid -le $am_max_gid; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - _am_tools=none - fi], - - [pax], - [], - - [m4_fatal([Unknown tar format])]) - - AC_MSG_CHECKING([how to create a $1 tar archive]) - - # Go ahead even if we have the value already cached. We do so because we - # need to set the values for the 'am__tar' and 'am__untar' variables. - _am_tools=${am_cv_prog_tar_$1-$_am_tools} - - for _am_tool in $_am_tools; do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break - - # tar/untar a dummy directory, and stop if the command works. - rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) - rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar <conftest.tar]) - AM_RUN_LOG([cat conftest.dir/file]) - grep GrepMe conftest.dir/file >/dev/null 2>&1 && break - fi - done - rm -rf conftest.dir - - AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) - AC_MSG_RESULT([$am_cv_prog_tar_$1])]) - -AC_SUBST([am__tar]) -AC_SUBST([am__untar]) -]) # _AM_PROG_TAR - -m4_include([../../m4/kpse-common.m4]) -m4_include([../../m4/kpse-lib-version.m4]) -m4_include([../../m4/kpse-size-max.m4]) -m4_include([../../m4/kpse-visibility.m4]) -m4_include([../../m4/kpse-warnings.m4]) diff --git a/source/libs/pixman/config.h.in b/source/libs/pixman/config.h.in deleted file mode 100644 index 7e718e7f18a459f889179a06191ce76fcf2a8dc5..0000000000000000000000000000000000000000 --- a/source/libs/pixman/config.h.in +++ /dev/null @@ -1,133 +0,0 @@ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define if building universal (internal helper macro) */ -#undef AC_APPLE_UNIVERSAL_BUILD - -/* Whether the compiler supports __builtin_clz */ -#undef HAVE_BUILTIN_CLZ - -/* Whether the tool chain supports __float128 */ -#undef HAVE_FLOAT128 - -/* Define to 1 if you have the `getisax' function. */ -#undef HAVE_GETISAX - -/* Define to 1 if you have the <inttypes.h> header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if you have the <memory.h> header file. */ -#undef HAVE_MEMORY_H - -/* Define to 1 if you have the <stdint.h> header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the <stdlib.h> header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the <strings.h> header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the <string.h> header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the <sys/types.h> header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the <unistd.h> header file. */ -#undef HAVE_UNISTD_H - -/* Name of package */ -#undef PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the home page for this package. */ -#undef PACKAGE_URL - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* We do not want threading */ -#undef PIXMAN_NO_TLS - -/* enable TIMER_BEGIN/TIMER_END macros */ -#undef PIXMAN_TIMERS - -/* The size of `long', as computed by sizeof. */ -#undef SIZEOF_LONG - -/* Define to `((size_t)-1)' if <stdint.h> does not define it. */ -#undef SIZE_MAX - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* Whether the tool chain supports __attribute__((constructor)) */ -#undef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR - -/* use ARM IWMMXT compiler intrinsics */ -#undef USE_ARM_IWMMXT - -/* use ARM NEON assembly optimizations */ -#undef USE_ARM_NEON - -/* use ARM SIMD assembly optimizations */ -#undef USE_ARM_SIMD - -/* use GNU-style inline assembler */ -#undef USE_GCC_INLINE_ASM - -/* use Loongson Multimedia Instructions */ -#undef USE_LOONGSON_MMI - -/* use MIPS DSPr2 assembly optimizations */ -#undef USE_MIPS_DSPR2 - -/* use SSE2 compiler intrinsics */ -#undef USE_SSE2 - -/* use SSSE3 compiler intrinsics */ -#undef USE_SSSE3 - -/* use VMX compiler intrinsics */ -#undef USE_VMX - -/* use x86 MMX compiler intrinsics */ -#undef USE_X86_MMX - -/* Version number of package */ -#undef VERSION - -/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most - significant byte first (like Motorola and SPARC, unlike Intel). */ -#if defined AC_APPLE_UNIVERSAL_BUILD -# if defined __BIG_ENDIAN__ -# define WORDS_BIGENDIAN 1 -# endif -#else -# ifndef WORDS_BIGENDIAN -# undef WORDS_BIGENDIAN -# endif -#endif - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -#undef inline -#endif - -/* Define to sqrt if you do not have the `sqrtf' function. */ -#undef sqrtf diff --git a/source/libs/pixman/configure b/source/libs/pixman/configure deleted file mode 100755 index 92f9ad086238385f14fb8fbaacb9c5f8e58c0c7c..0000000000000000000000000000000000000000 --- a/source/libs/pixman/configure +++ /dev/null @@ -1,7513 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for pixman (TeX Live) 0.34.0. -# -# Report bugs to <tex-k@tug.org>. -# -# -# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. -# -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -# Use a proper internal environment variable to ensure we don't fall - # into an infinite loop, continuously re-executing ourselves. - if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then - _as_can_reexec=no; export _as_can_reexec; - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -as_fn_exit 255 - fi - # We don't want this to propagate to other subprocesses. - { _as_can_reexec=; unset _as_can_reexec;} -if test "x$CONFIG_SHELL" = x; then - as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi -" - as_required="as_fn_return () { (exit \$1); } -as_fn_success () { as_fn_return 0; } -as_fn_failure () { as_fn_return 1; } -as_fn_ret_success () { return 0; } -as_fn_ret_failure () { return 1; } - -exitcode=0 -as_fn_success || { exitcode=1; echo as_fn_success failed.; } -as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } -as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } -as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } -if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : - -else - exitcode=1; echo positional parameters were not saved. -fi -test x\$exitcode = x0 || exit 1 -test -x / || exit 1" - as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO - as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO - eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && - test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 -test \$(( 1 + 1 )) = 2 || exit 1" - if (eval "$as_required") 2>/dev/null; then : - as_have_required=yes -else - as_have_required=no -fi - if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : - -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_found=false -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - as_found=: - case $as_dir in #( - /*) - for as_base in sh bash ksh sh5; do - # Try only shells that exist, to save several forks. - as_shell=$as_dir/$as_base - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : - CONFIG_SHELL=$as_shell as_have_required=yes - if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : - break 2 -fi -fi - done;; - esac - as_found=false -done -$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : - CONFIG_SHELL=$SHELL as_have_required=yes -fi; } -IFS=$as_save_IFS - - - if test "x$CONFIG_SHELL" != x; then : - export CONFIG_SHELL - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -exit 255 -fi - - if test x$as_have_required = xno; then : - $as_echo "$0: This script requires a shell more modern than all" - $as_echo "$0: the shells that I found on your system." - if test x${ZSH_VERSION+set} = xset ; then - $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" - $as_echo "$0: be upgraded to zsh 4.3.4 or later." - else - $as_echo "$0: Please tell bug-autoconf@gnu.org and tex-k@tug.org -$0: about your system, including any error possibly output -$0: before this message. Then install a modern shell, or -$0: manually run the script under such a shell if you do -$0: have one." - fi - exit 1 -fi -fi -fi -SHELL=${CONFIG_SHELL-/bin/sh} -export SHELL -# Unset more variables known to interfere with behavior of common tools. -CLICOLOR_FORCE= GREP_OPTIONS= -unset CLICOLOR_FORCE GREP_OPTIONS - -## --------------------- ## -## M4sh Shell Functions. ## -## --------------------- ## -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # If we had to re-execute with $CONFIG_SHELL, we're ensured to have - # already done that, so ensure we don't try to do so again and fall - # in an infinite loop. This has already happened in practice. - _as_can_reexec=no; export _as_can_reexec - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -test -n "$DJDIR" || exec 7<&0 </dev/null -exec 6>&1 - -# Name of the host. -# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_clean_files= -ac_config_libobj_dir=. -LIBOBJS= -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= - -# Identity of this package. -PACKAGE_NAME='pixman (TeX Live)' -PACKAGE_TARNAME='pixman--tex-live-' -PACKAGE_VERSION='0.34.0' -PACKAGE_STRING='pixman (TeX Live) 0.34.0' -PACKAGE_BUGREPORT='tex-k@tug.org' -PACKAGE_URL='' - -ac_unique_file="pixman-src/pixman/pixman.h" -# Factoring default headers for most tests. -ac_includes_default="\ -#include <stdio.h> -#ifdef HAVE_SYS_TYPES_H -# include <sys/types.h> -#endif -#ifdef HAVE_SYS_STAT_H -# include <sys/stat.h> -#endif -#ifdef STDC_HEADERS -# include <stdlib.h> -# include <stddef.h> -#else -# ifdef HAVE_STDLIB_H -# include <stdlib.h> -# endif -#endif -#ifdef HAVE_STRING_H -# if !defined STDC_HEADERS && defined HAVE_MEMORY_H -# include <memory.h> -# endif -# include <string.h> -#endif -#ifdef HAVE_STRINGS_H -# include <strings.h> -#endif -#ifdef HAVE_INTTYPES_H -# include <inttypes.h> -#endif -#ifdef HAVE_STDINT_H -# include <stdint.h> -#endif -#ifdef HAVE_UNISTD_H -# include <unistd.h> -#endif" - -ac_subst_vars='am__EXEEXT_FALSE -am__EXEEXT_TRUE -LTLIBOBJS -LIBOBJS -PIXMAN_TREE -build_FALSE -build_TRUE -VISIBILITY_CFLAGS -EGREP -GREP -CPP -LN_S -RANLIB -PIXMAN_VERSION_MICRO -PIXMAN_VERSION_MINOR -PIXMAN_VERSION_MAJOR -WARNING_CFLAGS -am__fastdepCC_FALSE -am__fastdepCC_TRUE -CCDEPMODE -am__nodep -AMDEPBACKSLASH -AMDEP_FALSE -AMDEP_TRUE -am__quote -am__include -DEPDIR -OBJEXT -EXEEXT -ac_ct_CC -CPPFLAGS -LDFLAGS -CFLAGS -CC -MAINT -MAINTAINER_MODE_FALSE -MAINTAINER_MODE_TRUE -AM_BACKSLASH -AM_DEFAULT_VERBOSITY -AM_DEFAULT_V -AM_V -am__untar -am__tar -AMTAR -am__leading_dot -SET_MAKE -AWK -mkdir_p -MKDIR_P -INSTALL_STRIP_PROGRAM -STRIP -install_sh -MAKEINFO -AUTOHEADER -AUTOMAKE -AUTOCONF -ACLOCAL -VERSION -PACKAGE -CYGPATH_W -am__isrc -INSTALL_DATA -INSTALL_SCRIPT -INSTALL_PROGRAM -target_alias -host_alias -build_alias -LIBS -ECHO_T -ECHO_N -ECHO_C -DEFS -mandir -localedir -libdir -psdir -pdfdir -dvidir -htmldir -infodir -docdir -oldincludedir -includedir -localstatedir -sharedstatedir -sysconfdir -datadir -datarootdir -libexecdir -sbindir -bindir -program_transform_name -prefix -exec_prefix -PACKAGE_URL -PACKAGE_BUGREPORT -PACKAGE_STRING -PACKAGE_VERSION -PACKAGE_TARNAME -PACKAGE_NAME -PATH_SEPARATOR -SHELL' -ac_subst_files='' -ac_user_opts=' -enable_option_checking -enable_silent_rules -enable_maintainer_mode -enable_dependency_tracking -enable_compiler_warnings -' - ac_precious_vars='build_alias -host_alias -target_alias -CC -CFLAGS -LDFLAGS -LIBS -CPPFLAGS -CPP' - - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -ac_unrecognized_opts= -ac_unrecognized_sep= -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -# (The list follows the same order as the GNU Coding Standards.) -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datarootdir='${prefix}/share' -datadir='${datarootdir}' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -includedir='${prefix}/include' -oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' -infodir='${datarootdir}/info' -htmldir='${docdir}' -dvidir='${docdir}' -pdfdir='${docdir}' -psdir='${docdir}' -libdir='${exec_prefix}/lib' -localedir='${datarootdir}/locale' -mandir='${datarootdir}/man' - -ac_prev= -ac_dashdash= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval $ac_prev=\$ac_option - ac_prev= - continue - fi - - case $ac_option in - *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *=) ac_optarg= ;; - *) ac_optarg=yes ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_dashdash$ac_option in - --) - ac_dashdash=yes ;; - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=*) - datadir=$ac_optarg ;; - - -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ - | --dataroo | --dataro | --datar) - ac_prev=datarootdir ;; - -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ - | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) - datarootdir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=no ;; - - -docdir | --docdir | --docdi | --doc | --do) - ac_prev=docdir ;; - -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) - docdir=$ac_optarg ;; - - -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) - ac_prev=dvidir ;; - -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) - dvidir=$ac_optarg ;; - - -enable-* | --enable-*) - ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=\$ac_optarg ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) - ac_prev=htmldir ;; - -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ - | --ht=*) - htmldir=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localedir | --localedir | --localedi | --localed | --locale) - ac_prev=localedir ;; - -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) - localedir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst | --locals) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) - ac_prev=pdfdir ;; - -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) - pdfdir=$ac_optarg ;; - - -psdir | --psdir | --psdi | --psd | --ps) - ac_prev=psdir ;; - -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) - psdir=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=\$ac_optarg ;; - - -without-* | --without-*) - ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=no ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) as_fn_error $? "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information" - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - case $ac_envvar in #( - '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; - esac - eval $ac_envvar=\$ac_optarg - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error $? "missing argument to $ac_option" -fi - -if test -n "$ac_unrecognized_opts"; then - case $enable_option_checking in - no) ;; - fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; - esac -fi - -# Check all directory arguments for consistency. -for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir -do - eval ac_val=\$$ac_var - # Remove trailing slashes. - case $ac_val in - */ ) - ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` - eval $ac_var=\$ac_val;; - esac - # Be sure to have absolute directory names. - case $ac_val in - [\\/$]* | ?:[\\/]* ) continue;; - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; - esac - as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -ac_pwd=`pwd` && test -n "$ac_pwd" && -ac_ls_di=`ls -di .` && -ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - as_fn_error $? "working directory cannot be determined" -test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - as_fn_error $? "pwd does not report name of working directory" - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then the parent directory. - ac_confdir=`$as_dirname -- "$as_myself" || -$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_myself" : 'X\(//\)[^/]' \| \ - X"$as_myself" : 'X\(//\)$' \| \ - X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_myself" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r "$srcdir/$ac_unique_file"; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r "$srcdir/$ac_unique_file"; then - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" -fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" -ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" - pwd)` -# When building in place, set srcdir=. -if test "$ac_abs_confdir" = "$ac_pwd"; then - srcdir=. -fi -# Remove unnecessary trailing slashes from srcdir. -# Double slashes in file names in object file debugging info -# mess up M-x gdb in Emacs. -case $srcdir in -*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; -esac -for ac_var in $ac_precious_vars; do - eval ac_env_${ac_var}_set=\${${ac_var}+set} - eval ac_env_${ac_var}_value=\$${ac_var} - eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} - eval ac_cv_env_${ac_var}_value=\$${ac_var} -done - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures pixman (TeX Live) 0.34.0 to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking ...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root - [DATAROOTDIR/doc/pixman--tex-live-] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] -_ACEOF - - cat <<\_ACEOF - -Program names: - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM run sed PROGRAM on installed program names -_ACEOF -fi - -if test -n "$ac_init_help"; then - case $ac_init_help in - short | recursive ) echo "Configuration of pixman (TeX Live) 0.34.0:";; - esac - cat <<\_ACEOF - -Optional Features: - --disable-option-checking ignore unrecognized --enable/--with options - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-silent-rules less verbose build output (undo: "make V=1") - --disable-silent-rules verbose build output (undo: "make V=0") - --enable-maintainer-mode - enable make rules and dependencies not useful (and - sometimes confusing) to the casual installer - --enable-dependency-tracking - do not reject slow dependency extractors - --disable-dependency-tracking - speeds up one-time build - --enable-compiler-warnings=[no|min|yes|max|all] - Turn on compiler warnings [default: yes if - maintainer-mode, min otherwise] - -Some influential environment variables: - CC C compiler command - CFLAGS C compiler flags - LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a - nonstandard directory <lib dir> - LIBS libraries to pass to the linker, e.g. -l<library> - CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if - you have headers in a nonstandard directory <include dir> - CPP C preprocessor - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -Report bugs to <tex-k@tug.org>. -_ACEOF -ac_status=$? -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d "$ac_dir" || - { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || - continue - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. - if test -f "$ac_srcdir/configure.gnu"; then - echo && - $SHELL "$ac_srcdir/configure.gnu" --help=recursive - elif test -f "$ac_srcdir/configure"; then - echo && - $SHELL "$ac_srcdir/configure" --help=recursive - else - $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi || ac_status=$? - cd "$ac_pwd" || { ac_status=$?; break; } - done -fi - -test -n "$ac_init_help" && exit $ac_status -if $ac_init_version; then - cat <<\_ACEOF -pixman (TeX Live) configure 0.34.0 -generated by GNU Autoconf 2.69 - -Copyright (C) 2012 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit -fi - -## ------------------------ ## -## Autoconf initialization. ## -## ------------------------ ## - -# ac_fn_c_try_compile LINENO -# -------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_compile - -# ac_fn_c_try_link LINENO -# ----------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_link () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - test -x conftest$ac_exeext - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information - # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would - # interfere with the next link command; also delete a directory that is - # left behind by Apple's compiler. We do this before executing the actions. - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_link - -# ac_fn_c_check_func LINENO FUNC VAR -# ---------------------------------- -# Tests whether FUNC exists, setting the cache variable VAR accordingly -ac_fn_c_check_func () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -/* Define $2 to an innocuous variant, in case <limits.h> declares $2. - For example, HP-UX 11i <limits.h> declares gettimeofday. */ -#define $2 innocuous_$2 - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $2 (); below. - Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - <limits.h> exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - -#undef $2 - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $2 (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$2 || defined __stub___$2 -choke me -#endif - -int -main () -{ -return $2 (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_func - -# ac_fn_c_try_run LINENO -# ---------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes -# that executables *can* be run. -ac_fn_c_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then : - ac_retval=0 -else - $as_echo "$as_me: program exited with status $ac_status" >&5 - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status -fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_run - -# ac_fn_c_try_cpp LINENO -# ---------------------- -# Try to preprocess conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_cpp () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } > conftest.i && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_cpp - -# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists and can be compiled using the include files in -# INCLUDES, setting the cache variable VAR accordingly. -ac_fn_c_check_header_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_compile - -# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES -# --------------------------------------------- -# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR -# accordingly. -ac_fn_c_check_decl () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - as_decl_name=`echo $2|sed 's/ *(.*//'` - as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 -$as_echo_n "checking whether $as_decl_name is declared... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -#ifndef $as_decl_name -#ifdef __cplusplus - (void) $as_decl_use; -#else - (void) $as_decl_name; -#endif -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_decl - -# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES -# -------------------------------------------- -# Tries to find the compile-time value of EXPR in a program that includes -# INCLUDES, setting VAR accordingly. Returns whether the value could be -# computed -ac_fn_c_compute_int () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) >= 0)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_lo=0 ac_mid=0 - while :; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) <= $ac_mid)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_hi=$ac_mid; break -else - as_fn_arith $ac_mid + 1 && ac_lo=$as_val - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) < 0)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_hi=-1 ac_mid=-1 - while :; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) >= $ac_mid)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_lo=$ac_mid; break -else - as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - done -else - ac_lo= ac_hi= -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -static int test_array [1 - 2 * !(($2) <= $ac_mid)]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_hi=$ac_mid -else - as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in #(( -?*) eval "$3=\$ac_lo"; ac_retval=0 ;; -'') ac_retval=1 ;; -esac - else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -static long int longval () { return $2; } -static unsigned long int ulongval () { return $2; } -#include <stdio.h> -#include <stdlib.h> -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - return 1; - if (($2) < 0) - { - long int i = longval (); - if (i != ($2)) - return 1; - fprintf (f, "%ld", i); - } - else - { - unsigned long int i = ulongval (); - if (i != ($2)) - return 1; - fprintf (f, "%lu", i); - } - /* Do not output a trailing newline, as this causes \r\n confusion - on some platforms. */ - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - echo >>conftest.val; read $3 <conftest.val; ac_retval=0 -else - ac_retval=1 -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -rm -f conftest.val - - fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_compute_int -cat >config.log <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by pixman (TeX Live) $as_me 0.34.0, which was -generated by GNU Autoconf 2.69. Invocation command line was - - $ $0 $@ - -_ACEOF -exec 5>>config.log -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - $as_echo "PATH: $as_dir" - done -IFS=$as_save_IFS - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *\'*) - ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; - 2) - as_fn_append ac_configure_args1 " '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - as_fn_append ac_configure_args " '$ac_arg'" - ;; - esac - done -done -{ ac_configure_args0=; unset ac_configure_args0;} -{ ac_configure_args1=; unset ac_configure_args1;} - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Use '\'' to represent an apostrophe within the trap. -# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - $as_echo "## ---------------- ## -## Cache variables. ## -## ---------------- ##" - echo - # The following way of writing the cache mishandles newlines in values, -( - for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - (set) 2>&1 | - case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - sed -n \ - "s/'\''/'\''\\\\'\'''\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" - ;; #( - *) - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) - echo - - $as_echo "## ----------------- ## -## Output variables. ## -## ----------------- ##" - echo - for ac_var in $ac_subst_vars - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - - if test -n "$ac_subst_files"; then - $as_echo "## ------------------- ## -## File substitutions. ## -## ------------------- ##" - echo - for ac_var in $ac_subst_files - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - fi - - if test -s confdefs.h; then - $as_echo "## ----------- ## -## confdefs.h. ## -## ----------- ##" - echo - cat confdefs.h - echo - fi - test "$ac_signal" != 0 && - $as_echo "$as_me: caught signal $ac_signal" - $as_echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core core.conftest.* && - rm -f -r conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status -' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -f -r conftest* confdefs.h - -$as_echo "/* confdefs.h */" > confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_URL "$PACKAGE_URL" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer an explicitly selected file to automatically selected ones. -ac_site_file1=NONE -ac_site_file2=NONE -if test -n "$CONFIG_SITE"; then - # We do not want a PATH search for config.site. - case $CONFIG_SITE in #(( - -*) ac_site_file1=./$CONFIG_SITE;; - */*) ac_site_file1=$CONFIG_SITE;; - *) ac_site_file1=./$CONFIG_SITE;; - esac -elif test "x$prefix" != xNONE; then - ac_site_file1=$prefix/share/config.site - ac_site_file2=$prefix/etc/config.site -else - ac_site_file1=$ac_default_prefix/share/config.site - ac_site_file2=$ac_default_prefix/etc/config.site -fi -for ac_site_file in "$ac_site_file1" "$ac_site_file2" -do - test "x$ac_site_file" = xNONE && continue - if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 -$as_echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" \ - || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5; } - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special files - # actually), so we avoid doing that. DJGPP emulates it as a regular file. - if test /dev/null != "$cache_file" && test -f "$cache_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 -$as_echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . "$cache_file";; - *) . "./$cache_file";; - esac - fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 -$as_echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in $ac_precious_vars; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val=\$ac_cv_env_${ac_var}_value - eval ac_new_val=\$ac_env_${ac_var}_value - case $ac_old_set,$ac_new_set in - set,) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - # differences in whitespace do not lead to failure. - ac_old_val_w=`echo x $ac_old_val` - ac_new_val_w=`echo x $ac_new_val` - if test "$ac_old_val_w" != "$ac_new_val_w"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 -$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - ac_cache_corrupted=: - else - { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} - eval $ac_var=\$ac_old_val - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 -$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 -$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) as_fn_append ac_configure_args " '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 -$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 -fi -## -------------------- ## -## Main body of script. ## -## -------------------- ## - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - - -ac_aux_dir= -for ac_dir in ../../build-aux "$srcdir"/../../build-aux; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in ../../build-aux \"$srcdir\"/../../build-aux" "$LINENO" 5 -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - - - - -am__api_version='1.15' - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -$as_echo_n "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if ${ac_cv_path_install+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in #(( - ./ | .// | /[cC]/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done - ;; -esac - - done -IFS=$as_save_IFS - -rm -rf conftest.one conftest.two conftest.dir - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -$as_echo "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 -$as_echo_n "checking whether build environment is sane... " >&6; } -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[\\\"\#\$\&\'\`$am_lf]*) - as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; -esac -case $srcdir in - *[\\\"\#\$\&\'\`$am_lf\ \ ]*) - as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; -esac - -# Do 'set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - as_fn_error $? "ls -t appears to fail. Make sure there is not a broken - alias in your environment" "$LINENO" 5 - fi - if test "$2" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$2" = conftest.file - ) -then - # Ok. - : -else - as_fn_error $? "newly created file is older than distributed files! -Check your system clock" "$LINENO" 5 -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & - am_sleep_pid=$! -fi - -rm -f conftest.file - -test "$program_prefix" != NONE && - program_transform_name="s&^&$program_prefix&;$program_transform_name" -# Use a double $ so make ignores it. -test "$program_suffix" != NONE && - program_transform_name="s&\$&$program_suffix&;$program_transform_name" -# Double any \ or $. -# By default was `s,x,x', remove it if useless. -ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' -program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` - -# Expand $ac_aux_dir to an absolute path. -am_aux_dir=`cd "$ac_aux_dir" && pwd` - -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac -fi -# Use eval to expand $SHELL -if eval "$MISSING --is-lightweight"; then - am_missing_run="$MISSING " -else - am_missing_run= - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 -$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} -fi - -if test x"${install_sh+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi - -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. -if test "$cross_compiling" != no; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -$as_echo "$STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_STRIP="strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -$as_echo "$ac_ct_STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 -$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } -if test -z "$MKDIR_P"; then - if ${ac_cv_path_mkdir+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in mkdir gmkdir; do - for ac_exec_ext in '' $ac_executable_extensions; do - as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue - case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( - 'mkdir (GNU coreutils) '* | \ - 'mkdir (coreutils) '* | \ - 'mkdir (fileutils) '4.1*) - ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext - break 3;; - esac - done - done - done -IFS=$as_save_IFS - -fi - - test -d ./--version && rmdir ./--version - if test "${ac_cv_path_mkdir+set}" = set; then - MKDIR_P="$ac_cv_path_mkdir -p" - else - # As a last resort, use the slow shell script. Don't cache a - # value for MKDIR_P within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - MKDIR_P="$ac_install_sh -d" - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 -$as_echo "$MKDIR_P" >&6; } - -for ac_prog in gawk mawk nawk awk -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AWK+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AWK"; then - ac_cv_prog_AWK="$AWK" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AWK="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AWK=$ac_cv_prog_AWK -if test -n "$AWK"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 -$as_echo "$AWK" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AWK" && break -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } -set x ${MAKE-make} -ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat >conftest.make <<\_ACEOF -SHELL = /bin/sh -all: - @echo '@@@%%%=$(MAKE)=@@@%%%' -_ACEOF -# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. -case `${MAKE-make} -f conftest.make 2>/dev/null` in - *@@@%%%=?*=@@@%%%*) - eval ac_cv_prog_make_${ac_make}_set=yes;; - *) - eval ac_cv_prog_make_${ac_make}_set=no;; -esac -rm -f conftest.make -fi -if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - SET_MAKE= -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - SET_MAKE="MAKE=${MAKE-make}" -fi - -rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null - -# Check whether --enable-silent-rules was given. -if test "${enable_silent_rules+set}" = set; then : - enableval=$enable_silent_rules; -fi - -case $enable_silent_rules in # ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=1;; -esac -am_make=${MAKE-make} -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 -$as_echo_n "checking whether $am_make supports nested variables... " >&6; } -if ${am_cv_make_support_nested_variables+:} false; then : - $as_echo_n "(cached) " >&6 -else - if $as_echo 'TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 -$as_echo "$am_cv_make_support_nested_variables" >&6; } -if test $am_cv_make_support_nested_variables = yes; then - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AM_BACKSLASH='\' - -DEPDIR="${am__leading_dot}deps" - -ac_config_commands="$ac_config_commands depfiles" - - -am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo this is the am__doit target -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 -$as_echo_n "checking for style of include used by $am_make... " >&6; } -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 -$as_echo "$_am_result" >&6; } -rm -f confinc confmf - -# Check whether --enable-dependency-tracking was given. -if test "${enable_dependency_tracking+set}" = set; then : - enableval=$enable_dependency_tracking; -fi - -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' - am__nodep='_no' -fi - if test "x$enable_dependency_tracking" != xno; then - AMDEP_TRUE= - AMDEP_FALSE='#' -else - AMDEP_TRUE='#' - AMDEP_FALSE= -fi - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } - -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 -$as_echo_n "checking whether the C compiler works... " >&6; } -ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` - -# The possible output files: -ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" - -ac_rmfiles= -for ac_file in $ac_files -do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - * ) ac_rmfiles="$ac_rmfiles $ac_file";; - esac -done -rm -f $ac_rmfiles - -if { { ac_try="$ac_link_default" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link_default") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' -# in a Makefile. We should not override ac_cv_exeext if it was cached, -# so that the user can short-circuit this test for compilers unknown to -# Autoconf. -for ac_file in $ac_files '' -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; - then :; else - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - fi - # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' - # argument, so we may need to know it at that point already. - # Even if this section looks crufty: it has the advantage of - # actually working. - break;; - * ) - break;; - esac -done -test "$ac_cv_exeext" = no && ac_cv_exeext= - -else - ac_file='' -fi -if test -z "$ac_file"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -$as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 -$as_echo_n "checking for C compiler default output file name... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 -$as_echo "$ac_file" >&6; } -ac_exeext=$ac_cv_exeext - -rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 -$as_echo_n "checking for suffix of executables... " >&6; } -if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - break;; - * ) break;; - esac -done -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest conftest$ac_cv_exeext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 -$as_echo "$ac_cv_exeext" >&6; } - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdio.h> -int -main () -{ -FILE *f = fopen ("conftest.out", "w"); - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -ac_clean_files="$ac_clean_files conftest.out" -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 -$as_echo_n "checking whether we are cross compiling... " >&6; } -if test "$cross_compiling" != yes; then - { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if { ac_try='./conftest$ac_cv_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5; } - fi - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 -$as_echo "$cross_compiling" >&6; } - -rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 -$as_echo_n "checking for suffix of object files... " >&6; } -if ${ac_cv_objext+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - for ac_file in conftest.o conftest.obj conftest.*; do - test -f "$ac_file" || continue; - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 -$as_echo "$ac_cv_objext" >&6; } -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GCC=yes -else - GCC= -fi -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -else - CFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdarg.h> -#include <stdio.h> -struct stat; -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_c89=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : - -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 -$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } -if ${am_cv_prog_cc_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF - # Make sure it works both with $CC and with simple cc. - # Following AC_PROG_CC_C_O, we do the test twice because some - # compilers refuse to overwrite an existing .o file with -o, - # though they will create one. - am_cv_prog_cc_c_o=yes - for am_i in 1 2; do - if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 - ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } \ - && test -f conftest2.$ac_objext; then - : OK - else - am_cv_prog_cc_c_o=no - break - fi - done - rm -f core conftest* - unset am_i -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 -$as_echo "$am_cv_prog_cc_c_o" >&6; } -if test "$am_cv_prog_cc_c_o" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -depcc="$CC" am_compiler_list= - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if ${am_cv_CC_dependencies_compiler_type+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named 'D' -- because '-MD' means "put the output - # in D". - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CC_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - am__universal=false - case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with - # Solaris 10 /bin/sh. - echo '/* dummy */' > sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with '-c' and '-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle '-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs. - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # After this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested. - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok '-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CC_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CC_dependencies_compiler_type=none -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 -$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } -CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type - - if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then - am__fastdepCC_TRUE= - am__fastdepCC_FALSE='#' -else - am__fastdepCC_TRUE='#' - am__fastdepCC_FALSE= -fi - - - -# Check whether --enable-compiler-warnings was given. -if test "${enable_compiler_warnings+set}" = set; then : - enableval=$enable_compiler_warnings; -fi -case $enable_compiler_warnings in #( - no | min | yes | max | all) : - ;; #( - *) : - if test "x$enable_maintainer_mode" = xyes; then : - enable_compiler_warnings=yes -else - enable_compiler_warnings=min -fi ;; -esac - - -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - am__isrc=' -I$(srcdir)' - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi - - -# Define the identity of the package. - PACKAGE='pixman--tex-live-' - VERSION='0.34.0' - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE "$PACKAGE" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define VERSION "$VERSION" -_ACEOF - -# Some tools Automake needs. - -ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} - - -AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} - - -AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} - - -AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} - - -MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} - -# For better backward compatibility. To be removed once Automake 1.9.x -# dies out for good. For more background, see: -# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> -# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> -mkdir_p='$(MKDIR_P)' - -# We need awk for the "check" target (and possibly the TAP driver). The -# system "awk" is bad on some platforms. -# Always define AMTAR for backward compatibility. Yes, it's still used -# in the wild :-( We should find a proper way to deprecate it ... -AMTAR='$${TAR-tar}' - - -# We'll loop over all known methods to create a tar archive until one works. -_am_tools='gnutar pax cpio none' - -am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' - - - - - - -# POSIX will say in a future version that running "rm -f" with no argument -# is OK; and we want to be able to make that assumption in our Makefile -# recipes. So use an aggressive probe to check that the usage we want is -# actually supported "in the wild" to an acceptable degree. -# See automake bug#10828. -# To make any issue more visible, cause the running configure to be aborted -# by default if the 'rm' program in use doesn't match our expectations; the -# user can still override this though. -if rm -f && rm -fr && rm -rf; then : OK; else - cat >&2 <<'END' -Oops! - -Your 'rm' program seems unable to run without file operands specified -on the command line, even when the '-f' option is present. This is contrary -to the behaviour of most rm programs out there, and not conforming with -the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> - -Please tell bug-automake@gnu.org about your system, including the value -of your $PATH and any error possibly output before this message. This -can help us improve future automake versions. - -END - if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then - echo 'Configuration will proceed anyway, since you have set the' >&2 - echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 - echo >&2 - else - cat >&2 <<'END' -Aborting the configuration process, to ensure you take notice of the issue. - -You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: <http://www.gnu.org/software/coreutils/>. - -If you want to complete the configuration process using your problematic -'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM -to "yes", and re-run configure. - -END - as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 - fi -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 -$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } - # Check whether --enable-maintainer-mode was given. -if test "${enable_maintainer_mode+set}" = set; then : - enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval -else - USE_MAINTAINER_MODE=no -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 -$as_echo "$USE_MAINTAINER_MODE" >&6; } - if test $USE_MAINTAINER_MODE = yes; then - MAINTAINER_MODE_TRUE= - MAINTAINER_MODE_FALSE='#' -else - MAINTAINER_MODE_TRUE='#' - MAINTAINER_MODE_FALSE= -fi - - MAINT=$MAINTAINER_MODE_TRUE - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler accepts prototypes" >&5 -$as_echo_n "checking whether the compiler accepts prototypes... " >&6; } -if ${kb_cv_c_prototypes+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdarg.h> -int -main () -{ -extern void foo(int i,...); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - kb_cv_c_prototypes=yes -else - kb_cv_c_prototypes=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kb_cv_c_prototypes" >&5 -$as_echo "$kb_cv_c_prototypes" >&6; } -if test "x$kb_cv_c_prototypes" = xno; then - as_fn_error $? "Sorry, your compiler does not understand prototypes." "$LINENO" 5 -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking what warning flags to pass to the C compiler" >&5 -$as_echo_n "checking what warning flags to pass to the C compiler... " >&6; } -if ${kpse_cv_warning_cflags+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "x$GCC" = xyes; then - kpse_cv_warning_cflags= -if test "x$enable_compiler_warnings" != xno; then - kpse_cv_warning_cflags="-Wimplicit -Wreturn-type" - case `$CC -dumpversion` in #( - 3.4.* | 4.* | 5.*) : - kpse_cv_warning_cflags="$kpse_cv_warning_cflags -Wdeclaration-after-statement" ;; #( - *) : - ;; -esac - case `$CC -dumpversion` in #( - 3.[234].* | 4.* | 5.*) : - kpse_cv_warning_cflags="$kpse_cv_warning_cflags -Wno-unknown-pragmas" ;; #( - *) : - ;; -esac - if test "x$enable_compiler_warnings" != xmin; then - kpse_cv_warning_cflags="-Wall -Wunused $kpse_cv_warning_cflags" - kpse_cv_warning_cflags="$kpse_cv_warning_cflags -Wmissing-prototypes -Wmissing-declarations" - if test "x$enable_compiler_warnings" != xyes; then - kpse_cv_warning_cflags="$kpse_cv_warning_cflags -Wparentheses -Wswitch -Wtrigraphs -Wpointer-arith" - kpse_cv_warning_cflags="$kpse_cv_warning_cflags -Wcast-qual -Wcast-align -Wwrite-strings" - case `$CC -dumpversion` in #( - 3.4.* | 4.* | 5.*) : - kpse_cv_warning_cflags="$kpse_cv_warning_cflags -Wold-style-definition" ;; #( - *) : - ;; -esac - if test "x$enable_compiler_warnings" != xmax; then - kpse_cv_warning_cflags="$kpse_cv_warning_cflags -Wshadow" - fi - fi - fi -fi -elif test "x$enable_compiler_warnings" = xno; then - kpse_cv_warning_cflags= -else - kpse_cv_warning_cflags= # FIXME: warning flags for non-GNU C compilers -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kpse_cv_warning_cflags" >&5 -$as_echo "$kpse_cv_warning_cflags" >&6; } -WARNING_CFLAGS=$kpse_cv_warning_cflags - - - - - - - - -PIXMAN_VERSION_MAJOR=0 -PIXMAN_VERSION_MINOR=34 -PIXMAN_VERSION_MICRO=0 - -test_CFLAGS=${CFLAGS+set} # We may override autoconf default CFLAGS. - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } - -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GCC=yes -else - GCC= -fi -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -else - CFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdarg.h> -#include <stdio.h> -struct stat; -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_c89=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : - -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 -$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } -if ${am_cv_prog_cc_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF - # Make sure it works both with $CC and with simple cc. - # Following AC_PROG_CC_C_O, we do the test twice because some - # compilers refuse to overwrite an existing .o file with -o, - # though they will create one. - am_cv_prog_cc_c_o=yes - for am_i in 1 2; do - if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 - ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } \ - && test -f conftest2.$ac_objext; then - : OK - else - am_cv_prog_cc_c_o=no - break - fi - done - rm -f core conftest* - unset am_i -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 -$as_echo "$am_cv_prog_cc_c_o" >&6; } -if test "$am_cv_prog_cc_c_o" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -depcc="$CC" am_compiler_list= - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if ${am_cv_CC_dependencies_compiler_type+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named 'D' -- because '-MD' means "put the output - # in D". - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CC_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - am__universal=false - case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with - # Solaris 10 /bin/sh. - echo '/* dummy */' > sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with '-c' and '-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle '-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs. - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # After this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested. - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok '-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CC_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CC_dependencies_compiler_type=none -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 -$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } -CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type - - if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then - am__fastdepCC_TRUE= - am__fastdepCC_FALSE='#' -else - am__fastdepCC_TRUE='#' - am__fastdepCC_FALSE= -fi - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 -$as_echo "$RANLIB" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 -$as_echo "$ac_ct_RANLIB" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_RANLIB" = x; then - RANLIB=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - RANLIB=$ac_ct_RANLIB - fi -else - RANLIB="$ac_cv_prog_RANLIB" -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 -$as_echo_n "checking whether ln -s works... " >&6; } -LN_S=$as_ln_s -if test "$LN_S" = "ln -s"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 -$as_echo "no, using $LN_S" >&6; } -fi - -for ac_func in getisax -do : - ac_fn_c_check_func "$LINENO" "getisax" "ac_cv_func_getisax" -if test "x$ac_cv_func_getisax" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_GETISAX 1 -_ACEOF - -fi -done - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 -$as_echo_n "checking how to run the C preprocessor... " >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if ${ac_cv_prog_CPP+:} false; then : - $as_echo_n "(cached) " >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - # <limits.h> exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <ac_nonexistent.h> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 -$as_echo "$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since - # <limits.h> exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include <limits.h> -#else -# include <assert.h> -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <ac_nonexistent.h> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 -$as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if ${ac_cv_path_GREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$GREP"; then - ac_path_GREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_GREP" || continue -# Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_GREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_GREP"; then - as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_GREP=$GREP -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 -$as_echo "$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 -$as_echo_n "checking for egrep... " >&6; } -if ${ac_cv_path_EGREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - if test -z "$EGREP"; then - ac_path_EGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_EGREP" || continue -# Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_EGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_EGREP"; then - as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_EGREP=$EGREP -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 -$as_echo "$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <float.h> - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stdc=yes -else - ac_cv_header_stdc=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <string.h> - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdlib.h> - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : - : -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <ctype.h> -#include <stdlib.h> -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - -else - ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -$as_echo "#define STDC_HEADERS 1" >>confdefs.h - -fi - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default -" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 -$as_echo_n "checking whether byte ordering is bigendian... " >&6; } -if ${ac_cv_c_bigendian+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_c_bigendian=unknown - # See if we're dealing with a universal compiler. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifndef __APPLE_CC__ - not a universal capable compiler - #endif - typedef int dummy; - -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - # Check for potential -arch flags. It is not universal unless - # there are at least two -arch flags with different values. - ac_arch= - ac_prev= - for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do - if test -n "$ac_prev"; then - case $ac_word in - i?86 | x86_64 | ppc | ppc64) - if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then - ac_arch=$ac_word - else - ac_cv_c_bigendian=universal - break - fi - ;; - esac - ac_prev= - elif test "x$ac_word" = "x-arch"; then - ac_prev=arch - fi - done -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - if test $ac_cv_c_bigendian = unknown; then - # See if sys/param.h defines the BYTE_ORDER macro. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <sys/types.h> - #include <sys/param.h> - -int -main () -{ -#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ - && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ - && LITTLE_ENDIAN) - bogus endian macros - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - # It does; now see whether it defined to BIG_ENDIAN or not. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <sys/types.h> - #include <sys/param.h> - -int -main () -{ -#if BYTE_ORDER != BIG_ENDIAN - not big endian - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_bigendian=yes -else - ac_cv_c_bigendian=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test $ac_cv_c_bigendian = unknown; then - # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <limits.h> - -int -main () -{ -#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) - bogus endian macros - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - # It does; now see whether it defined to _BIG_ENDIAN or not. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <limits.h> - -int -main () -{ -#ifndef _BIG_ENDIAN - not big endian - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_bigendian=yes -else - ac_cv_c_bigendian=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test $ac_cv_c_bigendian = unknown; then - # Compile a test program. - if test "$cross_compiling" = yes; then : - # Try to guess by grepping values from an object file. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -short int ascii_mm[] = - { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; - short int ascii_ii[] = - { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; - int use_ascii (int i) { - return ascii_mm[i] + ascii_ii[i]; - } - short int ebcdic_ii[] = - { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; - short int ebcdic_mm[] = - { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; - int use_ebcdic (int i) { - return ebcdic_mm[i] + ebcdic_ii[i]; - } - extern int foo; - -int -main () -{ -return use_ascii (foo) == use_ebcdic (foo); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then - ac_cv_c_bigendian=yes - fi - if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then - if test "$ac_cv_c_bigendian" = unknown; then - ac_cv_c_bigendian=no - else - # finding both strings is unlikely to happen, but who knows? - ac_cv_c_bigendian=unknown - fi - fi -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ - - /* Are we little or big endian? From Harbison&Steele. */ - union - { - long int l; - char c[sizeof (long int)]; - } u; - u.l = 1; - return u.c[sizeof (long int) - 1] == 1; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_c_bigendian=no -else - ac_cv_c_bigendian=yes -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 -$as_echo "$ac_cv_c_bigendian" >&6; } - case $ac_cv_c_bigendian in #( - yes) - $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h -;; #( - no) - ;; #( - universal) - -$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h - - ;; #( - *) - as_fn_error $? "unknown endianness - presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; - esac - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 -$as_echo_n "checking for inline... " >&6; } -if ${ac_cv_c_inline+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_c_inline=no -for ac_kw in inline __inline__ __inline; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifndef __cplusplus -typedef int foo_t; -static $ac_kw foo_t static_foo () {return 0; } -$ac_kw foo_t foo () {return 0; } -#endif - -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_inline=$ac_kw -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - test "$ac_cv_c_inline" != no && break -done - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 -$as_echo "$ac_cv_c_inline" >&6; } - -case $ac_cv_c_inline in - inline | yes) ;; - *) - case $ac_cv_c_inline in - no) ac_val=;; - *) ac_val=$ac_cv_c_inline;; - esac - cat >>confdefs.h <<_ACEOF -#ifndef __cplusplus -#define inline $ac_val -#endif -_ACEOF - ;; -esac - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking CFLAGS for C to hide external symbols" >&5 -$as_echo_n "checking CFLAGS for C to hide external symbols... " >&6; } -if ${kpse_cv_visibility_cflags+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -kpse_cv_visibility_cflags=unknown -kpse_save_flags=$CFLAGS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <stdio.h> - extern void foo(void); - void foo(void){printf("foo\n");} -_ACEOF -# FIXME: Add tests for non-GNU compilers -for kpse_flag in '-fvisibility=hidden -fvisibility-inlines-hidden' '-fvisibility=hidden'; do - CFLAGS="$kpse_save_flags -Werror $kpse_flag" - if ac_fn_c_try_compile "$LINENO"; then : - kpse_cv_visibility_cflags=$kpse_flag; break -fi -rm -f core conftest.err conftest.$ac_objext -done -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $kpse_cv_visibility_cflags" >&5 -$as_echo "$kpse_cv_visibility_cflags" >&6; } -CFLAGS=$kpse_save_flags -case $kpse_cv_visibility_cflags in #( - unknown) : - ;; #( - *) : - VISIBILITY_CFLAGS=$kpse_cv_visibility_cflags - ;; -esac - - - - - -ac_config_headers="$ac_config_headers config.h" - - - if test "x$enable_build" != xno; then - build_TRUE= - build_FALSE='#' -else - build_TRUE='#' - build_FALSE= -fi - - -if :; then - -$as_echo "#define PIXMAN_NO_TLS 1" >>confdefs.h - -else - -$as_echo "#define USE_LOONGSON_MMI 1" >>confdefs.h - - -$as_echo "#define USE_X86_MMX 1" >>confdefs.h - - -$as_echo "#define USE_SSE2 1" >>confdefs.h - - -$as_echo "#define USE_SSSE3 1" >>confdefs.h - - -$as_echo "#define USE_VMX 1" >>confdefs.h - - -$as_echo "#define USE_ARM_SIMD 1" >>confdefs.h - - -$as_echo "#define USE_ARM_NEON 1" >>confdefs.h - - -$as_echo "#define USE_ARM_IWMMXT 1" >>confdefs.h - - -$as_echo "#define USE_MIPS_DSPR2 1" >>confdefs.h - - -$as_echo "#define USE_GCC_INLINE_ASM 1" >>confdefs.h - - -$as_echo "#define PIXMAN_TIMERS 1" >>confdefs.h - - -$as_echo "#define TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR 1" >>confdefs.h - - -$as_echo "#define HAVE_FLOAT128 /**/" >>confdefs.h - - -$as_echo "#define HAVE_BUILTIN_CLZ /**/" >>confdefs.h - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing sqrtf" >&5 -$as_echo_n "checking for library containing sqrtf... " >&6; } -if ${ac_cv_search_sqrtf+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char sqrtf (); -int -main () -{ -return sqrtf (); - ; - return 0; -} -_ACEOF -for ac_lib in '' m; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_sqrtf=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_sqrtf+:} false; then : - break -fi -done -if ${ac_cv_search_sqrtf+:} false; then : - -else - ac_cv_search_sqrtf=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_sqrtf" >&5 -$as_echo "$ac_cv_search_sqrtf" >&6; } -ac_res=$ac_cv_search_sqrtf -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -else - -$as_echo "#define sqrtf sqrt" >>confdefs.h - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing sqrt" >&5 -$as_echo_n "checking for library containing sqrt... " >&6; } -if ${ac_cv_search_sqrt+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char sqrt (); -int -main () -{ -return sqrt (); - ; - return 0; -} -_ACEOF -for ac_lib in '' m; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_sqrt=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_sqrt+:} false; then : - break -fi -done -if ${ac_cv_search_sqrt+:} false; then : - -else - ac_cv_search_sqrt=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_sqrt" >&5 -$as_echo "$ac_cv_search_sqrt" >&6; } -ac_res=$ac_cv_search_sqrt -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -fi - - - - -ac_fn_c_check_decl "$LINENO" "SIZE_MAX" "ac_cv_have_decl_SIZE_MAX" "$ac_includes_default" -if test "x$ac_cv_have_decl_SIZE_MAX" = xyes; then : - -else - -$as_echo "#define SIZE_MAX ((size_t)-1)" >>confdefs.h - -fi - - -WERROR= -for w in -Werror -errwarn; do - if test "z$WERROR" = "z"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports $w" >&5 -$as_echo_n "checking whether the compiler supports $w... " >&6; } - save_CFLAGS="$CFLAGS" - save_LDFLAGS="$LDFLAGS" - save_LIBS="$LIBS" - CFLAGS="" - LDFLAGS="" - LIBS="" - CFLAGS=$w - CFLAGS="$save_CFLAGS $CFLAGS" - LDFLAGS="$save_LDFLAGS $LDFLAGS" - LIBS="$save_LIBS $LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -int main(int c, char **v) { (void)c; (void)v; return 0; } -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - pixman_cc_stderr=`test -f conftest.err && cat conftest.err` - pixman_cc_flag=yes -else - pixman_cc_stderr=`test -f conftest.err && cat conftest.err` - pixman_cc_flag=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - - if test "x$pixman_cc_stderr" != "x"; then - pixman_cc_flag=no - fi - - if test "x$pixman_cc_flag" = "xyes"; then - WERROR=$w; yesno=yes - else - yesno=no - fi - CFLAGS="$save_CFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $yesno" >&5 -$as_echo "$yesno" >&6; } - fi -done - - - -# The cast to long int works around a bug in the HP C Compiler -# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -# This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 -$as_echo_n "checking size of long... " >&6; } -if ${ac_cv_sizeof_long+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then : - -else - if test "$ac_cv_type_long" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (long) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_long=0 - fi -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 -$as_echo "$ac_cv_sizeof_long" >&6; } - - - -cat >>confdefs.h <<_ACEOF -#define SIZEOF_LONG $ac_cv_sizeof_long -_ACEOF - - - -# Checks for Sun Studio compilers -ac_fn_c_check_decl "$LINENO" "__SUNPRO_C" "ac_cv_have_decl___SUNPRO_C" "$ac_includes_default" -if test "x$ac_cv_have_decl___SUNPRO_C" = xyes; then : - SUNCC="yes" -else - SUNCC="no" -fi - -ac_fn_c_check_decl "$LINENO" "__amd64" "ac_cv_have_decl___amd64" "$ac_includes_default" -if test "x$ac_cv_have_decl___amd64" = xyes; then : - AMD64_ABI="yes" -else - AMD64_ABI="no" -fi - - -# Default CFLAGS to -O -g rather than just the -g from AC_PROG_CC -# if we're using Sun Studio and neither the user nor a config.site -# has set CFLAGS. -if test $SUNCC = yes && \ - test "x$test_CFLAGS" = "x" && \ - test "$CFLAGS" = "-g" -then - CFLAGS="-O -g" -fi - -# Check for dependencies - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports -Wall" >&5 -$as_echo_n "checking whether the compiler supports -Wall... " >&6; } - save_CFLAGS="$CFLAGS" - save_LDFLAGS="$LDFLAGS" - save_LIBS="$LIBS" - CFLAGS="" - LDFLAGS="" - LIBS="" - CFLAGS="$WERROR -Wall" - CFLAGS="$save_CFLAGS $CFLAGS" - LDFLAGS="$save_LDFLAGS $LDFLAGS" - LIBS="$save_LIBS $LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - int main(int c, char **v) { (void)c; (void)v; return 0; } - -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - pixman_cc_stderr=`test -f conftest.err && cat conftest.err` - pixman_cc_flag=yes -else - pixman_cc_stderr=`test -f conftest.err && cat conftest.err` - pixman_cc_flag=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - - if test "x$pixman_cc_stderr" != "x"; then - pixman_cc_flag=no - fi - - if test "x$pixman_cc_flag" = "xyes"; then - _yesno=yes - else - _yesno=no - fi - CFLAGS="$save_CFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - - if test "x$_yesno" = xyes; then - CFLAGS="$CFLAGS -Wall" - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_yesno" >&5 -$as_echo "$_yesno" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports -fno-strict-aliasing" >&5 -$as_echo_n "checking whether the compiler supports -fno-strict-aliasing... " >&6; } - save_CFLAGS="$CFLAGS" - save_LDFLAGS="$LDFLAGS" - save_LIBS="$LIBS" - CFLAGS="" - LDFLAGS="" - LIBS="" - CFLAGS="$WERROR -fno-strict-aliasing" - CFLAGS="$save_CFLAGS $CFLAGS" - LDFLAGS="$save_LDFLAGS $LDFLAGS" - LIBS="$save_LIBS $LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - int main(int c, char **v) { (void)c; (void)v; return 0; } - -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - pixman_cc_stderr=`test -f conftest.err && cat conftest.err` - pixman_cc_flag=yes -else - pixman_cc_stderr=`test -f conftest.err && cat conftest.err` - pixman_cc_flag=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - - if test "x$pixman_cc_stderr" != "x"; then - pixman_cc_flag=no - fi - - if test "x$pixman_cc_flag" = "xyes"; then - _yesno=yes - else - _yesno=no - fi - CFLAGS="$save_CFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - - if test "x$_yesno" = xyes; then - CFLAGS="$CFLAGS -fno-strict-aliasing" - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_yesno" >&5 -$as_echo "$_yesno" >&6; } - - -PIXMAN_TREE=pixman-src - - -if test -f $srcdir/$PIXMAN_TREE/pixman/pixman-version.h; then - as_fn_error $? "Sorry, you must remove the file $PIXMAN_TREE/pixman/pixman-version.h" "$LINENO" 5 -fi - -ac_config_files="$ac_config_files Makefile include/Makefile pixman-version.h:pixman-src/pixman/pixman-version.h.in" - - -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes: double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \. - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - if test "x$cache_file" != "x/dev/null"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} - if test ! -f "$cache_file" || test -h "$cache_file"; then - cat confcache >"$cache_file" - else - case $cache_file in #( - */* | ?:*) - mv -f confcache "$cache_file"$$ && - mv -f "$cache_file"$$ "$cache_file" ;; #( - *) - mv -f confcache "$cache_file" ;; - esac - fi - fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -DEFS=-DHAVE_CONFIG_H - -ac_libobjs= -ac_ltlibobjs= -U= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`$as_echo "$ac_i" | sed "$ac_script"` - # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR - # will be set to the directory where LIBOBJS objects are built. - as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" - as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 -$as_echo_n "checking that generated files are newer than configure... " >&6; } - if test -n "$am_sleep_pid"; then - # Hide warnings about reused PIDs. - wait $am_sleep_pid 2>/dev/null - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 -$as_echo "done" >&6; } - if test -n "$EXEEXT"; then - am__EXEEXT_TRUE= - am__EXEEXT_FALSE='#' -else - am__EXEEXT_TRUE='#' - am__EXEEXT_FALSE= -fi - -if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then - as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then - as_fn_error $? "conditional \"AMDEP\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepCC\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepCC\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi - -if test -z "${build_TRUE}" && test -z "${build_FALSE}"; then - as_fn_error $? "conditional \"build\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi - -: "${CONFIG_STATUS=./config.status}" -ac_write_fail=0 -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} -as_write_fail=0 -cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false - -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 -## ----------------------------------- ## -## Main body of $CONFIG_STATUS script. ## -## ----------------------------------- ## -_ASEOF -test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# Save the log message, to keep $0 and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by pixman (TeX Live) $as_me 0.34.0, which was -generated by GNU Autoconf 2.69. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -_ACEOF - -case $ac_config_files in *" -"*) set x $ac_config_files; shift; ac_config_files=$*;; -esac - -case $ac_config_headers in *" -"*) set x $ac_config_headers; shift; ac_config_headers=$*;; -esac - - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# Files that config.status was made for. -config_files="$ac_config_files" -config_headers="$ac_config_headers" -config_commands="$ac_config_commands" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -ac_cs_usage="\ -\`$as_me' instantiates files and other configuration actions -from templates according to the current configuration. Unless the files -and actions are specified as TAGs, all are instantiated by default. - -Usage: $0 [OPTION]... [TAG]... - - -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit - --config print configuration, then exit - -q, --quiet, --silent - do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE - -Configuration files: -$config_files - -Configuration headers: -$config_headers - -Configuration commands: -$config_commands - -Report bugs to <tex-k@tug.org>." - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" -ac_cs_version="\\ -pixman (TeX Live) config.status 0.34.0 -configured by $0, generated by GNU Autoconf 2.69, - with options \\"\$ac_cs_config\\" - -Copyright (C) 2012 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='$ac_pwd' -srcdir='$srcdir' -INSTALL='$INSTALL' -MKDIR_P='$MKDIR_P' -AWK='$AWK' -test -n "\$AWK" || AWK=awk -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# The default lists apply if the user does not specify any file. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=?*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - --*=) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg= - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - $as_echo "$ac_cs_version"; exit ;; - --config | --confi | --conf | --con | --co | --c ) - $as_echo "$ac_cs_config"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - '') as_fn_error $? "missing file argument" ;; - esac - as_fn_append CONFIG_FILES " '$ac_optarg'" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - as_fn_append CONFIG_HEADERS " '$ac_optarg'" - ac_need_defaults=false;; - --he | --h) - # Conflict between --help and --header - as_fn_error $? "ambiguous option: \`$1' -Try \`$0 --help' for more information.";; - --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) as_fn_error $? "unrecognized option: \`$1' -Try \`$0 --help' for more information." ;; - - *) as_fn_append ac_config_targets " $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -if \$ac_cs_recheck; then - set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion - shift - \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 - CONFIG_SHELL='$SHELL' - export CONFIG_SHELL - exec "\$@" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - $as_echo "$ac_log" -} >&5 - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# -# INIT-COMMANDS -# -AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; - "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; - "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;; - "pixman-version.h") CONFIG_FILES="$CONFIG_FILES pixman-version.h:pixman-src/pixman/pixman-version.h.in" ;; - - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers - test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= ac_tmp= - trap 'exit_status=$? - : "${ac_tmp:=$tmp}" - { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status -' 0 - trap 'as_fn_exit 1' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 -ac_tmp=$tmp - -# Set up the scripts for CONFIG_FILES section. -# No need to generate them if there are no CONFIG_FILES. -# This happens for instance with `./config.status config.h'. -if test -n "$CONFIG_FILES"; then - - -ac_cr=`echo X | tr X '\015'` -# On cygwin, bash can eat \r inside `` if the user requested igncr. -# But we know of no other shell where ac_cr would be empty at this -# point, so we can use a bashism as a fallback. -if test "x$ac_cr" = x; then - eval ac_cr=\$\'\\r\' -fi -ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` -if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\\r' -else - ac_cs_awk_cr=$ac_cr -fi - -echo 'BEGIN {' >"$ac_tmp/subs1.awk" && -_ACEOF - - -{ - echo "cat >conf$$subs.awk <<_ACEOF" && - echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && - echo "_ACEOF" -} >conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - . ./conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - - ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` - if test $ac_delim_n = $ac_delim_num; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done -rm -f conf$$subs.sh - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && -_ACEOF -sed -n ' -h -s/^/S["/; s/!.*/"]=/ -p -g -s/^[^!]*!// -:repl -t repl -s/'"$ac_delim"'$// -t delim -:nl -h -s/\(.\{148\}\)..*/\1/ -t more1 -s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ -p -n -b repl -:more1 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t nl -:delim -h -s/\(.\{148\}\)..*/\1/ -t more2 -s/["\\]/\\&/g; s/^/"/; s/$/"/ -p -b -:more2 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t delim -' <conf$$subs.awk | sed ' -/^[^""]/{ - N - s/\n// -} -' >>$CONFIG_STATUS || ac_write_fail=1 -rm -f conf$$subs.awk -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACAWK -cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && - for (key in S) S_is_set[key] = 1 - FS = "" - -} -{ - line = $ 0 - nfields = split(line, field, "@") - substed = 0 - len = length(field[1]) - for (i = 2; i < nfields; i++) { - key = field[i] - keylen = length(key) - if (S_is_set[key]) { - value = S[key] - line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) - len += length(value) + length(field[++i]) - substed = 1 - } else - len += 1 + keylen - } - - print line -} - -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then - sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" -else - cat -fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ - || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 -_ACEOF - -# VPATH may cause trouble with some makes, so we remove sole $(srcdir), -# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ -h -s/// -s/^/:/ -s/[ ]*$/:/ -s/:\$(srcdir):/:/g -s/:\${srcdir}:/:/g -s/:@srcdir@:/:/g -s/^:*// -s/:*$// -x -s/\(=[ ]*\).*/\1/ -G -s/\n// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -fi # test -n "$CONFIG_FILES" - -# Set up the scripts for CONFIG_HEADERS section. -# No need to generate them if there are no CONFIG_HEADERS. -# This happens for instance with `./config.status Makefile'. -if test -n "$CONFIG_HEADERS"; then -cat >"$ac_tmp/defines.awk" <<\_ACAWK || -BEGIN { -_ACEOF - -# Transform confdefs.h into an awk script `defines.awk', embedded as -# here-document in config.status, that substitutes the proper values into -# config.h.in to produce config.h. - -# Create a delimiter string that does not exist in confdefs.h, to ease -# handling of long lines. -ac_delim='%!_!# ' -for ac_last_try in false false :; do - ac_tt=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_tt"; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done - -# For the awk script, D is an array of macro values keyed by name, -# likewise P contains macro parameters if any. Preserve backslash -# newline sequences. - -ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* -sed -n ' -s/.\{148\}/&'"$ac_delim"'/g -t rset -:rset -s/^[ ]*#[ ]*define[ ][ ]*/ / -t def -d -:def -s/\\$// -t bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3"/p -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p -d -:bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3\\\\\\n"\\/p -t cont -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p -t cont -d -:cont -n -s/.\{148\}/&'"$ac_delim"'/g -t clear -:clear -s/\\$// -t bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/"/p -d -:bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p -b cont -' <confdefs.h | sed ' -s/'"$ac_delim"'/"\\\ -"/g' >>$CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - for (key in D) D_is_set[key] = 1 - FS = "" -} -/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { - line = \$ 0 - split(line, arg, " ") - if (arg[1] == "#") { - defundef = arg[2] - mac1 = arg[3] - } else { - defundef = substr(arg[1], 2) - mac1 = arg[2] - } - split(mac1, mac2, "(") #) - macro = mac2[1] - prefix = substr(line, 1, index(line, defundef) - 1) - if (D_is_set[macro]) { - # Preserve the white space surrounding the "#". - print prefix "define", macro P[macro] D[macro] - next - } else { - # Replace #undef with comments. This is necessary, for example, - # in the case of _POSIX_SOURCE, which is predefined and required - # on some systems where configure will not decide to define it. - if (defundef == "undef") { - print "/*", prefix defundef, macro, "*/" - next - } - } -} -{ print } -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 -fi # test -n "$CONFIG_HEADERS" - - -eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" -shift -for ac_tag -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$ac_tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; - esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac - as_fn_append ac_file_inputs " '$ac_f'" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input='Generated from '` - $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' - `' by configure.' - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 -$as_echo "$as_me: creating $ac_file" >&6;} - fi - # Neutralize special characters interpreted by sed in replacement strings. - case $configure_input in #( - *\&* | *\|* | *\\* ) - ac_sed_conf_input=`$as_echo "$configure_input" | - sed 's/[\\\\&|]/\\\\&/g'`;; #( - *) ac_sed_conf_input=$configure_input;; - esac - - case $ac_tag in - *:-:* | *:-) cat >"$ac_tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir="$ac_dir"; as_fn_mkdir_p - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac - ac_MKDIR_P=$MKDIR_P - case $MKDIR_P in - [\\/$]* | ?:[\\/]* ) ;; - */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; - esac -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= -ac_sed_dataroot=' -/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p' -case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; -esac -_ACEOF - -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_sed_extra="$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s|@configure_input@|$ac_sed_conf_input|;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@top_build_prefix@&$ac_top_build_prefix&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t -s&@MKDIR_P@&$ac_MKDIR_P&;t t -$ac_datarootdir_hack -" -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ - >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ - "$ac_tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&2;} - - rm -f "$ac_tmp/stdin" - case $ac_file in - -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; - *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; - esac \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - ;; - :H) - # - # CONFIG_HEADER - # - if test x"$ac_file" != x-; then - { - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" - } >"$ac_tmp/config.h" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 -$as_echo "$as_me: $ac_file is unchanged" >&6;} - else - rm -f "$ac_file" - mv "$ac_tmp/config.h" "$ac_file" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - fi - else - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ - || as_fn_error $? "could not create -" "$LINENO" 5 - fi -# Compute "$ac_file"'s index in $config_headers. -_am_arg="$ac_file" -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $_am_arg | $_am_arg:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || -$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$_am_arg" : 'X\(//\)[^/]' \| \ - X"$_am_arg" : 'X\(//\)$' \| \ - X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$_am_arg" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'`/stamp-h$_am_stamp_count - ;; - - :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 -$as_echo "$as_me: executing $ac_file commands" >&6;} - ;; - esac - - - case $ac_file$ac_mode in - "depfiles":C) test x"$AMDEP_TRUE" != x"" || { - # Older Autoconf quotes --file arguments for eval, but not when files - # are listed without --file. Let's play safe and only enable the eval - # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac - shift - for mf - do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`$as_dirname -- "$mf" || -$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$mf" : 'X\(//\)[^/]' \| \ - X"$mf" : 'X\(//\)$' \| \ - X"$mf" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$mf" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`$as_dirname -- "$file" || -$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$file" : 'X\(//\)[^/]' \| \ - X"$file" : 'X\(//\)$' \| \ - X"$file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir=$dirpart/$fdir; as_fn_mkdir_p - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done - done -} - ;; - - esac -done # for ac_tag - - -as_fn_exit 0 -_ACEOF -ac_clean_files=$ac_clean_files_save - -test $ac_write_fail = 0 || - as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || as_fn_exit 1 -fi -if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} -fi - diff --git a/source/libs/pixman/configure.ac b/source/libs/pixman/configure.ac deleted file mode 100644 index 5100a54a8e4581fe95ff8eaf693666dc819f304e..0000000000000000000000000000000000000000 --- a/source/libs/pixman/configure.ac +++ /dev/null @@ -1,164 +0,0 @@ -dnl Process this file with autoconf to produce a configure script. -dnl -dnl Copyright (C) 2012-2014 Peter Breitenlohner <tex-live@tug.org> -dnl -dnl This file is free software; the copyright holder -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. -dnl -m4_include([version.ac])[] dnl define pixman_version -AC_INIT([pixman (TeX Live)], pixman_version, [tex-k@tug.org]) -AC_PREREQ([2.65]) -AC_CONFIG_SRCDIR([pixman-src/pixman/pixman.h]) -AC_CONFIG_AUX_DIR([../../build-aux]) -AC_CONFIG_MACRO_DIR([../../m4]) - -KPSE_BASIC([pixman]) - -KPSE_LIB_VERSION([pixman])[]dnl -AC_SUBST([PIXMAN_VERSION_MAJOR], [pixman_major])[]dnl -AC_SUBST([PIXMAN_VERSION_MINOR], [pixman_minor])[]dnl -AC_SUBST([PIXMAN_VERSION_MICRO], [pixman_micro])[]dnl - -test_CFLAGS=${CFLAGS+set} # We may override autoconf default CFLAGS. - -AC_PROG_CC -AC_PROG_RANLIB -AC_PROG_LN_S -AC_CHECK_FUNCS([getisax]) -AC_C_BIGENDIAN -AC_C_INLINE - -KPSE_COMPILER_VISIBILITY - -AC_CONFIG_HEADERS([config.h]) - -AM_CONDITIONAL([build], [test "x$enable_build" != xno]) - -if :; then - AC_DEFINE([PIXMAN_NO_TLS], 1, [We do not want threading]) -else -dnl add all these to config.h.in but do not define them in config.h - AC_DEFINE([USE_LOONGSON_MMI], 1, [use Loongson Multimedia Instructions]) - AC_DEFINE([USE_X86_MMX], 1, [use x86 MMX compiler intrinsics]) - AC_DEFINE([USE_SSE2], 1, [use SSE2 compiler intrinsics]) - AC_DEFINE([USE_SSSE3], 1, [use SSSE3 compiler intrinsics]) - AC_DEFINE([USE_VMX], 1, [use VMX compiler intrinsics]) - AC_DEFINE([USE_ARM_SIMD], 1, [use ARM SIMD assembly optimizations]) - AC_DEFINE([USE_ARM_NEON], 1, [use ARM NEON assembly optimizations]) - AC_DEFINE([USE_ARM_IWMMXT], 1, [use ARM IWMMXT compiler intrinsics]) - AC_DEFINE([USE_MIPS_DSPR2], 1, [use MIPS DSPr2 assembly optimizations]) - AC_DEFINE([USE_GCC_INLINE_ASM], 1, [use GNU-style inline assembler]) - AC_DEFINE([PIXMAN_TIMERS], 1, [enable TIMER_BEGIN/TIMER_END macros]) - AC_DEFINE([TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR], 1, - [Whether the tool chain supports __attribute__((constructor))]) - AC_DEFINE([HAVE_FLOAT128], [], [Whether the tool chain supports __float128]) - AC_DEFINE([HAVE_BUILTIN_CLZ], [], [Whether the compiler supports __builtin_clz]) -fi - -dnl Check for missing sqrtf() as, e.g., for Solaris 9 -AC_SEARCH_LIBS([sqrtf], [m], , - [AC_DEFINE([sqrtf], [sqrt], - [Define to sqrt if you do not have the `sqrtf' function.]) - AC_SEARCH_LIBS([sqrt], [m])]) - -dnl PIXMAN_LINK_WITH_ENV(env-setup, program, true-action, false-action) -dnl -dnl Compiles and links the given program in the environment setup by env-setup -dnl and executes true-action on success and false-action on failure. -AC_DEFUN([PIXMAN_LINK_WITH_ENV],[dnl - save_CFLAGS="$CFLAGS" - save_LDFLAGS="$LDFLAGS" - save_LIBS="$LIBS" - CFLAGS="" - LDFLAGS="" - LIBS="" - $1 - CFLAGS="$save_CFLAGS $CFLAGS" - LDFLAGS="$save_LDFLAGS $LDFLAGS" - LIBS="$save_LIBS $LIBS" - AC_LINK_IFELSE( - [AC_LANG_SOURCE([$2])], - [pixman_cc_stderr=`test -f conftest.err && cat conftest.err` - pixman_cc_flag=yes], - [pixman_cc_stderr=`test -f conftest.err && cat conftest.err` - pixman_cc_flag=no]) - - if test "x$pixman_cc_stderr" != "x"; then - pixman_cc_flag=no - fi - - if test "x$pixman_cc_flag" = "xyes"; then - ifelse([$3], , :, [$3]) - else - ifelse([$4], , :, [$4]) - fi - CFLAGS="$save_CFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" -]) - -KPSE_CHECK_SIZE_MAX - -dnl Find a -Werror for catching warnings. -WERROR= -for w in -Werror -errwarn; do - if test "z$WERROR" = "z"; then - AC_MSG_CHECKING([whether the compiler supports $w]) - PIXMAN_LINK_WITH_ENV( - [CFLAGS=$w], - [int main(int c, char **v) { (void)c; (void)v; return 0; }], - [WERROR=$w; yesno=yes], [yesno=no]) - AC_MSG_RESULT($yesno) - fi -done - -dnl PIXMAN_CHECK_CFLAG(flag, [program]) -dnl Adds flag to CFLAGS if the given program links without warnings or errors. -AC_DEFUN([PIXMAN_CHECK_CFLAG], [dnl - AC_MSG_CHECKING([whether the compiler supports $1]) - PIXMAN_LINK_WITH_ENV( - [CFLAGS="$WERROR $1"], - [$2 - int main(int c, char **v) { (void)c; (void)v; return 0; } - ], - [_yesno=yes], - [_yesno=no]) - if test "x$_yesno" = xyes; then - CFLAGS="$CFLAGS $1" - fi - AC_MSG_RESULT($_yesno) -]) - -AC_CHECK_SIZEOF([long]) - -# Checks for Sun Studio compilers -AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"]) -AC_CHECK_DECL([__amd64], [AMD64_ABI="yes"], [AMD64_ABI="no"]) - -# Default CFLAGS to -O -g rather than just the -g from AC_PROG_CC -# if we're using Sun Studio and neither the user nor a config.site -# has set CFLAGS. -if test $SUNCC = yes && \ - test "x$test_CFLAGS" = "x" && \ - test "$CFLAGS" = "-g" -then - CFLAGS="-O -g" -fi - -# Check for dependencies - -PIXMAN_CHECK_CFLAG([-Wall]) -PIXMAN_CHECK_CFLAG([-fno-strict-aliasing]) - -AC_SUBST([PIXMAN_TREE], [pixman-src]) - -if test -f $srcdir/$PIXMAN_TREE/pixman/pixman-version.h; then - AC_MSG_ERROR([Sorry, you must remove the file $PIXMAN_TREE/pixman/pixman-version.h]) -fi - -AC_CONFIG_FILES([Makefile - include/Makefile - pixman-version.h:pixman-src/pixman/pixman-version.h.in]) - -AC_OUTPUT diff --git a/source/libs/pixman/include/Makefile.am b/source/libs/pixman/include/Makefile.am deleted file mode 100644 index 8e64d9f2b75808dc4aa47dcf85fd9e7a3372de57..0000000000000000000000000000000000000000 --- a/source/libs/pixman/include/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ -## Proxy Makefile.am to install pixman headers for TeX Live. -## -## Copyright (C) 2012-2013 Peter Breitenlohner <tex-live@tug.org> -## -## This file is free software; the copyright holder -## gives unlimited permission to copy and/or distribute it, -## with or without modifications, as long as this notice is preserved. -## -PIXMAN_SRC = $(top_srcdir)/$(PIXMAN_TREE)/pixman -PIXMAN_BLD = $(top_builddir) - -hdr_links = \ - $(PIXMAN_SRC)/pixman.h \ - $(PIXMAN_BLD)/pixman-version.h - -include $(top_srcdir)/../../am/hdr_links.am - diff --git a/source/libs/pixman/include/Makefile.in b/source/libs/pixman/include/Makefile.in deleted file mode 100644 index fdff37c51c45d2516e1b19ad679e10a1e4f3eeac..0000000000000000000000000000000000000000 --- a/source/libs/pixman/include/Makefile.in +++ /dev/null @@ -1,430 +0,0 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2014 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -subdir = include -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/../../m4/kpse-common.m4 \ - $(top_srcdir)/../../m4/kpse-lib-version.m4 \ - $(top_srcdir)/../../m4/kpse-size-max.m4 \ - $(top_srcdir)/../../m4/kpse-visibility.m4 \ - $(top_srcdir)/../../m4/kpse-warnings.m4 \ - $(top_srcdir)/version.ac $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -SOURCES = -DIST_SOURCES = -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -am__DIST_COMMON = $(srcdir)/Makefile.in \ - $(top_srcdir)/../../am/hdr_links.am -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PIXMAN_TREE = @PIXMAN_TREE@ -PIXMAN_VERSION_MAJOR = @PIXMAN_VERSION_MAJOR@ -PIXMAN_VERSION_MICRO = @PIXMAN_VERSION_MICRO@ -PIXMAN_VERSION_MINOR = @PIXMAN_VERSION_MINOR@ -RANLIB = @RANLIB@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -VISIBILITY_CFLAGS = @VISIBILITY_CFLAGS@ -WARNING_CFLAGS = @WARNING_CFLAGS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build_alias = @build_alias@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host_alias = @host_alias@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -PIXMAN_SRC = $(top_srcdir)/$(PIXMAN_TREE)/pixman -PIXMAN_BLD = $(top_builddir) -hdr_links = \ - $(PIXMAN_SRC)/pixman.h \ - $(PIXMAN_BLD)/pixman-version.h - -all: all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/../../am/hdr_links.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign include/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; -$(top_srcdir)/../../am/hdr_links.am $(am__empty): - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): -tags TAGS: - -ctags CTAGS: - -cscope cscopelist: - - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile all-local -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic distclean-local - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: all all-am all-local check check-am clean clean-generic \ - cscopelist-am ctags-am distclean distclean-generic \ - distclean-local distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic pdf pdf-am ps ps-am tags-am uninstall \ - uninstall-am - -.PRECIOUS: Makefile - -all-local: - @for file in $(hdr_links); do \ - test -f $$file || continue; \ - inst=`echo $$file | sed -e 's/^.*\///'`; \ - test -f $$inst || { \ - rm -f $$inst; \ - if $(AM_V_P); then echo "$(LN_S) $$file $$inst"; \ - else echo " INST $$inst"; fi; \ - $(LN_S) $$file $$inst; } || exit 1; \ - done - -distclean-local: - rm -f *.h - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/source/libs/pixman/pixman-src/AUTHORS b/source/libs/pixman/pixman-src/AUTHORS deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/source/libs/pixman/pixman-src/COPYING b/source/libs/pixman/pixman-src/COPYING deleted file mode 100644 index 6168dea56f386e79f99313c26fb0ab320e992854..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/COPYING +++ /dev/null @@ -1,42 +0,0 @@ -The following is the MIT license, agreed upon by most contributors. -Copyright holders of new code should use this license statement where -possible. They may also add themselves to the list below. - -/* - * Copyright 1987, 1988, 1989, 1998 The Open Group - * Copyright 1987, 1988, 1989 Digital Equipment Corporation - * Copyright 1999, 2004, 2008 Keith Packard - * Copyright 2000 SuSE, Inc. - * Copyright 2000 Keith Packard, member of The XFree86 Project, Inc. - * Copyright 2004, 2005, 2007, 2008, 2009, 2010 Red Hat, Inc. - * Copyright 2004 Nicholas Miell - * Copyright 2005 Lars Knoll & Zack Rusin, Trolltech - * Copyright 2005 Trolltech AS - * Copyright 2007 Luca Barbato - * Copyright 2008 Aaron Plattner, NVIDIA Corporation - * Copyright 2008 Rodrigo Kumpera - * Copyright 2008 André Tupinambá - * Copyright 2008 Mozilla Corporation - * Copyright 2008 Frederic Plourde - * Copyright 2009, Oracle and/or its affiliates. All rights reserved. - * Copyright 2009, 2010 Nokia Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ diff --git a/source/libs/pixman/pixman-src/ChangeLog b/source/libs/pixman/pixman-src/ChangeLog deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/source/libs/pixman/pixman-src/INSTALL b/source/libs/pixman/pixman-src/INSTALL deleted file mode 100644 index 5458714e1e2cb289572992ad92eceffc848f64d6..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/INSTALL +++ /dev/null @@ -1,234 +0,0 @@ -Installation Instructions -************************* - -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, -2006 Free Software Foundation, Inc. - -This file is free documentation; the Free Software Foundation gives -unlimited permission to copy, distribute and modify it. - -Basic Installation -================== - -Briefly, the shell commands `./configure; make; make install' should -configure, build, and install this package. The following -more-detailed instructions are generic; see the `README' file for -instructions specific to this package. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). - - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. Caching is -disabled by default to prevent problems with accidental use of stale -cache files. - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you -may remove or edit it. - - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You need `configure.ac' if -you want to change it or regenerate `configure' using a newer version -of `autoconf'. - -The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. - - Running `configure' might take a while. While running, it prints - some messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package. - - 4. Type `make install' to install the programs and any data files and - documentation. - - 5. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - -Compilers and Options -===================== - -Some systems require unusual options for compilation or linking that the -`configure' script does not know about. Run `./configure --help' for -details on some of the pertinent environment variables. - - You can give `configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here -is an example: - - ./configure CC=c99 CFLAGS=-g LIBS=-lposix - - *Note Defining Variables::, for more details. - -Compiling For Multiple Architectures -==================================== - -You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you can use GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. - - With a non-GNU `make', it is safer to compile the package for one -architecture at a time in the source code directory. After you have -installed the package for one architecture, use `make distclean' before -reconfiguring for another architecture. - -Installation Names -================== - -By default, `make install' installs the package's commands under -`/usr/local/bin', include files under `/usr/local/include', etc. You -can specify an installation prefix other than `/usr/local' by giving -`configure' the option `--prefix=PREFIX'. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -pass the option `--exec-prefix=PREFIX' to `configure', the package uses -PREFIX as the prefix for installing programs and libraries. -Documentation and other data files still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=DIR' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - -Optional Features -================= - -Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - -Specifying the System Type -========================== - -There may be some features `configure' cannot figure out automatically, -but needs to determine by the type of machine the package will run on. -Usually, assuming the package is built to be run on the _same_ -architectures, `configure' can figure that out, but if it prints a -message saying it cannot guess the machine type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: - - CPU-COMPANY-SYSTEM - -where SYSTEM can have one of these forms: - - OS KERNEL-OS - - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the machine type. - - If you are _building_ compiler tools for cross-compiling, you should -use the option `--target=TYPE' to select the type of system they will -produce code for. - - If you want to _use_ a cross compiler, that generates code for a -platform different from the build platform, you should specify the -"host" platform (i.e., that on which the generated programs will -eventually be run) with `--host=TYPE'. - -Sharing Defaults -================ - -If you want to set default values for `configure' scripts to share, you -can create a site shell script called `config.site' that gives default -values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Defining Variables -================== - -Variables not defined in a site shell script can be set in the -environment passed to `configure'. However, some packages may run -configure again during the build, and the customized values of these -variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: - - ./configure CC=/usr/local2/bin/gcc - -causes the specified `gcc' to be used as the C compiler (unless it is -overridden in the site shell script). - -Unfortunately, this technique does not work for `CONFIG_SHELL' due to -an Autoconf bug. Until the bug is fixed you can use this workaround: - - CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash - -`configure' Invocation -====================== - -`configure' recognizes the following options to control how it operates. - -`--help' -`-h' - Print a summary of the options to `configure', and exit. - -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`--cache-file=FILE' - Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to - disable caching. - -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. - diff --git a/source/libs/pixman/pixman-src/Makefile.am b/source/libs/pixman/pixman-src/Makefile.am deleted file mode 100644 index 5137c9ea306b7f5f9519da485ec4a151a6eaa0b0..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/Makefile.am +++ /dev/null @@ -1,137 +0,0 @@ -SUBDIRS = pixman demos test - -pkgconfigdir=$(libdir)/pkgconfig -pkgconfig_DATA=pixman-1.pc - -$(pkgconfig_DATA): pixman-1.pc.in - -snapshot: - distdir="$(distdir)-`date '+%Y%m%d'`"; \ - test -d "$(srcdir)/.git" && distdir=$$distdir-`cd "$(srcdir)" && git rev-parse HEAD | cut -c 1-6`; \ - $(MAKE) $(AM_MAKEFLAGS) distdir="$$distdir" dist - -GPGKEY=3892336E -USERNAME=$$USER -RELEASE_OR_SNAPSHOT = $$(if test "x$(PIXMAN_VERSION_MINOR)" = "x$$(echo "$(PIXMAN_VERSION_MINOR)/2*2" | bc)" ; then echo release; else echo snapshot; fi) -RELEASE_CAIRO_HOST = $(USERNAME)@cairographics.org -RELEASE_CAIRO_DIR = /srv/cairo.freedesktop.org/www/$(RELEASE_OR_SNAPSHOT)s -RELEASE_CAIRO_URL = http://cairographics.org/$(RELEASE_OR_SNAPSHOT)s -RELEASE_XORG_URL = http://xorg.freedesktop.org/archive/individual/lib -RELEASE_XORG_HOST = $(USERNAME)@xorg.freedesktop.org -RELEASE_XORG_DIR = /srv/xorg.freedesktop.org/archive/individual/lib -RELEASE_ANNOUNCE_LIST = cairo-announce@cairographics.org, xorg-announce@lists.freedesktop.org, pixman@lists.freedesktop.org - -EXTRA_DIST = \ - Makefile.win32 \ - Makefile.win32.common - -tar_gz = $(PACKAGE)-$(VERSION).tar.gz -tar_bz2 = $(PACKAGE)-$(VERSION).tar.bz2 - -sha1_tgz = $(tar_gz).sha1 -md5_tgz = $(tar_gz).md5 - -sha1_tbz2 = $(tar_bz2).sha1 -md5_tbz2 = $(tar_bz2).md5 - -gpg_file = $(sha1_tgz).asc - -$(sha1_tgz): $(tar_gz) - sha1sum $^ > $@ - -$(md5_tgz): $(tar_gz) - md5sum $^ > $@ - -$(sha1_tbz2): $(tar_bz2) - sha1sum $^ > $@ - -$(md5_tbz2): $(tar_bz2) - md5sum $^ > $@ - -$(gpg_file): $(sha1_tgz) - @echo "Please enter your GPG password to sign the checksum." - gpg --armor --sign $^ - -HASHFILES = $(sha1_tgz) $(sha1_tbz2) $(md5_tgz) $(md5_tbz2) - -release-verify-newer: - @echo -n "Checking that no $(VERSION) release already exists at $(RELEASE_XORG_HOST)..." - @ssh $(RELEASE_XORG_HOST) test ! -e $(RELEASE_XORG_DIR)/$(tar_gz) \ - || (echo "Ouch." && echo "Found: $(RELEASE_XORG_HOST):$(RELEASE_XORG_DIR)/$(tar_gz)" \ - && echo "Refusing to try to generate a new release of the same name." \ - && false) - @ssh $(RELEASE_CAIRO_HOST) test ! -e $(RELEASE_CAIRO_DIR)/$(tar_gz) \ - || (echo "Ouch." && echo "Found: $(RELEASE_CAIRO_HOST):$(RELEASE_CAIRO_DIR)/$(tar_gz)" \ - && echo "Refusing to try to generate a new release of the same name." \ - && false) - @echo "Good." - -release-remove-old: - $(RM) $(tar_gz) $(tar_bz2) $(HASHFILES) $(gpg_file) - -ensure-prev: - @if [[ "$(PREV)" == "" ]]; then \ - echo "" && \ - echo "You must set the PREV variable on the make command line to" && \ - echo "the last version." && \ - echo "" && \ - echo "For example:" && \ - echo " make PREV=0.7.3" && \ - echo "" && \ - false; \ - fi - -release-check: ensure-prev release-verify-newer release-remove-old distcheck - -release-tag: - git tag -u $(GPGKEY) -m "$(PACKAGE) $(VERSION) release" $(PACKAGE)-$(VERSION) - -release-upload: release-check $(tar_gz) $(tar_bz2) $(sha1_tgz) $(sha1_tbz2) $(md5_tgz) $(gpg_file) - scp $(tar_gz) $(sha1_tgz) $(gpg_file) $(RELEASE_CAIRO_HOST):$(RELEASE_CAIRO_DIR) - scp $(tar_gz) $(tar_bz2) $(RELEASE_XORG_HOST):$(RELEASE_XORG_DIR) - ssh $(RELEASE_CAIRO_HOST) "rm -f $(RELEASE_CAIRO_DIR)/LATEST-$(PACKAGE)-[0-9]* && ln -s $(tar_gz) $(RELEASE_CAIRO_DIR)/LATEST-$(PACKAGE)-$(VERSION)" - -RELEASE_TYPE = $$(if test "x$(PIXMAN_VERSION_MINOR)" = "x$$(echo "$(PIXMAN_VERSION_MINOR)/2*2" | bc)" ; then echo "stable release in the" ; else echo "development snapshot leading up to a stable"; fi) - -release-publish-message: $(HASHFILES) ensure-prev - @echo "Please follow the instructions in RELEASING to push stuff out and" - @echo "send out the announcement mails. Here is the excerpt you need:" - @echo "" - @echo "Lists: $(RELEASE_ANNOUNCE_LIST)" - @echo "Subject: [ANNOUNCE] $(PACKAGE) release $(VERSION) now available" - @echo "============================== CUT HERE ==============================" - @echo "A new $(PACKAGE) release $(VERSION) is now available. This is a $(RELEASE_TYPE)" - @echo "" - @echo "tar.gz:" - @echo " $(RELEASE_CAIRO_URL)/$(tar_gz)" - @echo " $(RELEASE_XORG_URL)/$(tar_gz)" - @echo "" - @echo "tar.bz2:" - @echo " $(RELEASE_XORG_URL)/$(tar_bz2)" - @echo "" - @echo "Hashes:" - @echo -n " MD5: " - @cat $(md5_tgz) - @echo -n " MD5: " - @cat $(md5_tbz2) - @echo -n " SHA1: " - @cat $(sha1_tgz) - @echo -n " SHA1: " - @cat $(sha1_tbz2) - @echo "" - @echo "GPG signature:" - @echo " $(RELEASE_CAIRO_URL)/$(gpg_file)" - @echo " (signed by`gpg --list-keys $(GPGKEY) | grep uid | cut -b4- | tr -s " "`)" - @echo "" - @echo "Git:" - @echo " git://git.freedesktop.org/git/pixman" - @echo " tag: $(PACKAGE)-$(VERSION)" - @echo "" - @echo "Log:" - @git log --no-merges "$(PACKAGE)-$(PREV)".."$(PACKAGE)-$(VERSION)" | git shortlog | awk '{ printf "\t"; print ; }' | cut -b1-80 - @echo "============================== CUT HERE ==============================" - @echo "" - -release-publish: release-upload release-tag release-publish-message - -.PHONY: release-upload release-publish release-publish-message release-tag diff --git a/source/libs/pixman/pixman-src/Makefile.win32 b/source/libs/pixman/pixman-src/Makefile.win32 deleted file mode 100644 index c3ca3bc59a7fef77fe974c311889e6d76c180b45..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/Makefile.win32 +++ /dev/null @@ -1,25 +0,0 @@ -default: all - -top_srcdir = . -include $(top_srcdir)/Makefile.win32.common - -all: pixman test - -pixman: - @$(MAKE) -C pixman -f Makefile.win32 - -test: - @$(MAKE) -C test -f Makefile.win32 - -clean_r: - @$(MAKE) -C pixman -f Makefile.win32 clean - @$(MAKE) -C test -f Makefile.win32 clean - -check: - @$(MAKE) -C test -f Makefile.win32 check - - -clean: clean_r - - -.PHONY: all pixman test clean check diff --git a/source/libs/pixman/pixman-src/Makefile.win32.common b/source/libs/pixman/pixman-src/Makefile.win32.common deleted file mode 100644 index 777f94ce2c2d2bd1ab189ee81ca06d2af639da19..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/Makefile.win32.common +++ /dev/null @@ -1,56 +0,0 @@ -LIBRARY = pixman-1 - -CC = cl -LD = link -AR = lib -PERL = perl - -ifeq ($(top_builddir),) -top_builddir = $(top_srcdir) -endif - -CFG_VAR = $(CFG) -ifeq ($(CFG_VAR),) -CFG_VAR = release -endif - -ifeq ($(CFG_VAR),debug) -CFG_CFLAGS = -MDd -Od -Zi -CFG_LDFLAGS = -DEBUG -else -CFG_CFLAGS = -MD -O2 -CFG_LDFLAGS = -endif - -# Package definitions, to be used instead of those provided in config.h -PKG_CFLAGS = -DPACKAGE=$(LIBRARY) -DPACKAGE_VERSION="" -DPACKAGE_BUGREPORT="" - -BASE_CFLAGS = -nologo -I. -I$(top_srcdir) -I$(top_srcdir)/pixman - -PIXMAN_CFLAGS = $(BASE_CFLAGS) $(PKG_CFLAGS) $(CFG_CFLAGS) $(CFLAGS) -PIXMAN_LDFLAGS = -nologo $(CFG_LDFLAGS) $(LDFLAGS) -PIXMAN_ARFLAGS = -nologo $(LDFLAGS) - - -inform: -ifneq ($(CFG),release) -ifneq ($(CFG),debug) -ifneq ($(CFG),) - @echo "Invalid specified configuration option: "$(CFG)"." - @echo - @echo "Possible choices for configuration are 'release' and 'debug'" - @exit 1 -endif - @echo "Using default RELEASE configuration... (use CFG=release or CFG=debug)" -endif -endif - - -$(CFG_VAR)/%.obj: %.c $(libpixman_headers) - @mkdir -p $(CFG_VAR) - @$(CC) -c $(PIXMAN_CFLAGS) -Fo"$@" $< - -clean: inform - @$(RM) $(CFG_VAR)/*.{exe,ilk,lib,obj,pdb} $(BUILT_SOURCES) || exit 0 - -.PHONY: inform clean diff --git a/source/libs/pixman/pixman-src/NEWS b/source/libs/pixman/pixman-src/NEWS deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/source/libs/pixman/pixman-src/README b/source/libs/pixman/pixman-src/README deleted file mode 100644 index 6d8cfd8ad5051ad508536ff7cc37a31673ef6e5e..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/README +++ /dev/null @@ -1,116 +0,0 @@ -Pixman is a library that provides low-level pixel manipulation -features such as image compositing and trapezoid rasterization. - -Questions, bug reports and patches should be directed to the pixman -mailing list: - - http://lists.freedesktop.org/mailman/listinfo/pixman - -You can also file bugs at - - https://bugs.freedesktop.org/enter_bug.cgi?product=pixman - -For real time discussions about pixman, feel free to join the IRC -channels #cairo and #xorg-devel on the FreeNode IRC network. - - -Contributing ------------- - -In order to contribute to pixman, you will need a working knowledge of -the git version control system. For a quick getting started guide, -there is the "Everyday Git With 20 Commands Or So guide" - - http://www.kernel.org/pub/software/scm/git/docs/everyday.html - -from the Git homepage. For more in depth git documentation, see the -resources on the Git community documentation page: - - http://git-scm.com/documentation - -Pixman uses the infrastructure from the freedesktop.org umbrella -project. For instructions about how to use the git service on -freedesktop.org, see: - - http://www.freedesktop.org/wiki/Infrastructure/git/Developers - -The Pixman master repository can be found at: - - git://anongit.freedesktop.org/git/pixman - -and browsed on the web here: - - http://cgit.freedesktop.org/pixman/ - - -Sending patches ---------------- - -The general workflow for sending patches is to first make sure that -git can send mail on your system. Then, - - - create a branch off of master in your local git repository - - - make your changes as one or more commits - - - use the - - git send-email - - command to send the patch series to pixman@lists.freedesktop.org. - -In order for your patches to be accepted, please consider the -following guidelines: - - - This link: - - http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#patch-series - - describes how what a good patch series is, and to create one with - git. - - - At each point in the series, pixman should compile and the test - suite should pass. - - The exception here is if you are changing the test suite to - demonstrate a bug. In this case, make one commit that makes the - test suite fail due to the bug, and then another commit that fixes - the bug. - - You can run the test suite with - - make check - - It will take around two minutes to run on a modern PC. - - - Follow the coding style described in the CODING_STYLE file - - - For bug fixes, include an update to the test suite to make sure - the bug doesn't reappear. - - - For new features, add tests of the feature to the test - suite. Also, add a program demonstrating the new feature to the - demos/ directory. - - - Write descriptive commit messages. Useful information to include: - - Benchmark results, before and after - - Description of the bug that was fixed - - Detailed rationale for any new API - - Alternative approaches that were rejected (and why they - don't work) - - If review comments were incorporated, a brief version - history describing what those changes were. - - - For big patch series, send an introductory email with an overall - description of the patch series, including benchmarks and - motivation. Each commit message should still be descriptive and - include enough information to understand why this particular commit - was necessary. - -Pixman has high standards for code quality and so almost everybody -should expect to have the first versions of their patches rejected. - -If you think that the reviewers are wrong about something, or that the -guidelines above are wrong, feel free to discuss the issue on the -list. The purpose of the guidelines and code review is to ensure high -code quality; it is not an exercise in compliance. diff --git a/source/libs/pixman/pixman-src/config.h.in b/source/libs/pixman/pixman-src/config.h.in deleted file mode 100644 index c707dd52c10a48decd56d6d52756c71e2ec2470a..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/config.h.in +++ /dev/null @@ -1,184 +0,0 @@ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define if building universal (internal helper macro) */ -#undef AC_APPLE_UNIVERSAL_BUILD - -/* Whether we have alarm() */ -#undef HAVE_ALARM - -/* Whether the compiler supports __builtin_clz */ -#undef HAVE_BUILTIN_CLZ - -/* Define to 1 if you have the <dlfcn.h> header file. */ -#undef HAVE_DLFCN_H - -/* Whether we have FE_DIVBYZERO */ -#undef HAVE_FEDIVBYZERO - -/* Whether we have feenableexcept() */ -#undef HAVE_FEENABLEEXCEPT - -/* Define to 1 if we have <fenv.h> */ -#undef HAVE_FENV_H - -/* Whether the tool chain supports __float128 */ -#undef HAVE_FLOAT128 - -/* Whether the compiler supports GCC vector extensions */ -#undef HAVE_GCC_VECTOR_EXTENSIONS - -/* Define to 1 if you have the `getisax' function. */ -#undef HAVE_GETISAX - -/* Whether we have getpagesize() */ -#undef HAVE_GETPAGESIZE - -/* Whether we have gettimeofday() */ -#undef HAVE_GETTIMEOFDAY - -/* Define to 1 if you have the <inttypes.h> header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if you have the `pixman-1' library (-lpixman-1). */ -#undef HAVE_LIBPIXMAN_1 - -/* Whether we have libpng */ -#undef HAVE_LIBPNG - -/* Define to 1 if you have the <memory.h> header file. */ -#undef HAVE_MEMORY_H - -/* Whether we have mmap() */ -#undef HAVE_MMAP - -/* Whether we have mprotect() */ -#undef HAVE_MPROTECT - -/* Whether we have posix_memalign() */ -#undef HAVE_POSIX_MEMALIGN - -/* Whether pthreads is supported */ -#undef HAVE_PTHREADS - -/* Whether we have sigaction() */ -#undef HAVE_SIGACTION - -/* Define to 1 if you have the <stdint.h> header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the <stdlib.h> header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the <strings.h> header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the <string.h> header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if we have <sys/mman.h> */ -#undef HAVE_SYS_MMAN_H - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the <sys/types.h> header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the <unistd.h> header file. */ -#undef HAVE_UNISTD_H - -/* Define to the sub-directory where libtool stores uninstalled libraries. */ -#undef LT_OBJDIR - -/* Name of package */ -#undef PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the home page for this package. */ -#undef PACKAGE_URL - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* enable TIMER_BEGIN/TIMER_END macros */ -#undef PIXMAN_TIMERS - -/* The size of `long', as computed by sizeof. */ -#undef SIZEOF_LONG - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* The compiler supported TLS storage class */ -#undef TLS - -/* Whether the tool chain supports __attribute__((constructor)) */ -#undef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR - -/* use ARM IWMMXT compiler intrinsics */ -#undef USE_ARM_IWMMXT - -/* use ARM NEON assembly optimizations */ -#undef USE_ARM_NEON - -/* use ARM SIMD assembly optimizations */ -#undef USE_ARM_SIMD - -/* use GNU-style inline assembler */ -#undef USE_GCC_INLINE_ASM - -/* use Loongson Multimedia Instructions */ -#undef USE_LOONGSON_MMI - -/* use MIPS DSPr2 assembly optimizations */ -#undef USE_MIPS_DSPR2 - -/* use OpenMP in the test suite */ -#undef USE_OPENMP - -/* use SSE2 compiler intrinsics */ -#undef USE_SSE2 - -/* use SSSE3 compiler intrinsics */ -#undef USE_SSSE3 - -/* use VMX compiler intrinsics */ -#undef USE_VMX - -/* use x86 MMX compiler intrinsics */ -#undef USE_X86_MMX - -/* Version number of package */ -#undef VERSION - -/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most - significant byte first (like Motorola and SPARC, unlike Intel). */ -#if defined AC_APPLE_UNIVERSAL_BUILD -# if defined __BIG_ENDIAN__ -# define WORDS_BIGENDIAN 1 -# endif -#else -# ifndef WORDS_BIGENDIAN -# undef WORDS_BIGENDIAN -# endif -#endif - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -#undef inline -#endif - -/* Define to sqrt if you do not have the `sqrtf' function. */ -#undef sqrtf diff --git a/source/libs/pixman/pixman-src/configure.ac b/source/libs/pixman/pixman-src/configure.ac deleted file mode 100644 index 156edfbf3f905a1d303f9b1ca109d0fb5b5386a1..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/configure.ac +++ /dev/null @@ -1,1148 +0,0 @@ -dnl Copyright 2005 Red Hat, Inc. -dnl -dnl Permission to use, copy, modify, distribute, and sell this software and its -dnl documentation for any purpose is hereby granted without fee, provided that -dnl the above copyright notice appear in all copies and that both that -dnl copyright notice and this permission notice appear in supporting -dnl documentation, and that the name of Red Hat not be used in -dnl advertising or publicity pertaining to distribution of the software without -dnl specific, written prior permission. Red Hat makes no -dnl representations about the suitability of this software for any purpose. It -dnl is provided "as is" without express or implied warranty. -dnl -dnl RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -dnl INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO -dnl EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR -dnl CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, -dnl DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -dnl TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -dnl PERFORMANCE OF THIS SOFTWARE. -dnl -dnl Process this file with autoconf to create configure. - -AC_PREREQ([2.57]) - -# Pixman versioning scheme -# -# - The version in git has an odd MICRO version number -# -# - Released versions, both development and stable, have an -# even MICRO version number -# -# - Released development versions have an odd MINOR number -# -# - Released stable versions have an even MINOR number -# -# - Versions that break ABI must have a new MAJOR number -# -# - If you break the ABI, then at least this must be done: -# -# - increment MAJOR -# -# - In the first development release where you break ABI, find -# all instances of "pixman-n" and change them to pixman-(n+1) -# -# This needs to be done at least in -# configure.ac -# all Makefile.am's -# pixman-n.pc.in -# -# This ensures that binary incompatible versions can be installed -# in parallel. See http://www106.pair.com/rhp/parallel.html for -# more information -# - -m4_define([pixman_major], 0) -m4_define([pixman_minor], 34) -m4_define([pixman_micro], 0) - -m4_define([pixman_version],[pixman_major.pixman_minor.pixman_micro]) - -AC_INIT(pixman, pixman_version, [pixman@lists.freedesktop.org], pixman) -AM_INIT_AUTOMAKE([foreign dist-bzip2]) - -# Suppress verbose compile lines -m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) - -AC_CONFIG_HEADERS(config.h) - -AC_CANONICAL_HOST - -test_CFLAGS=${CFLAGS+set} # We may override autoconf default CFLAGS. - -AC_PROG_CC -AM_PROG_AS -AC_PROG_LIBTOOL -AC_CHECK_FUNCS([getisax]) -AC_C_BIGENDIAN -AC_C_INLINE - -dnl PIXMAN_LINK_WITH_ENV(env-setup, program, true-action, false-action) -dnl -dnl Compiles and links the given program in the environment setup by env-setup -dnl and executes true-action on success and false-action on failure. -AC_DEFUN([PIXMAN_LINK_WITH_ENV],[dnl - save_CFLAGS="$CFLAGS" - save_LDFLAGS="$LDFLAGS" - save_LIBS="$LIBS" - CFLAGS="" - LDFLAGS="" - LIBS="" - $1 - CFLAGS="$save_CFLAGS $CFLAGS" - LDFLAGS="$save_LDFLAGS $LDFLAGS" - LIBS="$save_LIBS $LIBS" - AC_LINK_IFELSE( - [AC_LANG_SOURCE([$2])], - [pixman_cc_stderr=`test -f conftest.err && cat conftest.err` - pixman_cc_flag=yes], - [pixman_cc_stderr=`test -f conftest.err && cat conftest.err` - pixman_cc_flag=no]) - - if test "x$pixman_cc_stderr" != "x"; then - pixman_cc_flag=no - fi - - if test "x$pixman_cc_flag" = "xyes"; then - ifelse([$3], , :, [$3]) - else - ifelse([$4], , :, [$4]) - fi - CFLAGS="$save_CFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" -]) - -dnl Find a -Werror for catching warnings. -WERROR= -for w in -Werror -errwarn; do - if test "z$WERROR" = "z"; then - AC_MSG_CHECKING([whether the compiler supports $w]) - PIXMAN_LINK_WITH_ENV( - [CFLAGS=$w], - [int main(int c, char **v) { (void)c; (void)v; return 0; }], - [WERROR=$w; yesno=yes], [yesno=no]) - AC_MSG_RESULT($yesno) - fi -done - -dnl PIXMAN_CHECK_CFLAG(flag, [program]) -dnl Adds flag to CFLAGS if the given program links without warnings or errors. -AC_DEFUN([PIXMAN_CHECK_CFLAG], [dnl - AC_MSG_CHECKING([whether the compiler supports $1]) - PIXMAN_LINK_WITH_ENV( - [CFLAGS="$WERROR $1"], - [$2 - int main(int c, char **v) { (void)c; (void)v; return 0; } - ], - [_yesno=yes], - [_yesno=no]) - if test "x$_yesno" = xyes; then - CFLAGS="$CFLAGS $1" - fi - AC_MSG_RESULT($_yesno) -]) - -AC_CHECK_SIZEOF(long) - -# Checks for Sun Studio compilers -AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"]) -AC_CHECK_DECL([__amd64], [AMD64_ABI="yes"], [AMD64_ABI="no"]) - -# Default CFLAGS to -O -g rather than just the -g from AC_PROG_CC -# if we're using Sun Studio and neither the user nor a config.site -# has set CFLAGS. -if test $SUNCC = yes && \ - test "x$test_CFLAGS" = "x" && \ - test "$CFLAGS" = "-g" -then - CFLAGS="-O -g" -fi - -# -# We ignore pixman_major in the version here because the major version should -# always be encoded in the actual library name. Ie., the soname is: -# -# pixman-$(pixman_major).0.minor.micro -# -m4_define([lt_current], [pixman_minor]) -m4_define([lt_revision], [pixman_micro]) -m4_define([lt_age], [pixman_minor]) - -LT_VERSION_INFO="lt_current:lt_revision:lt_age" - -PIXMAN_VERSION_MAJOR=pixman_major() -AC_SUBST(PIXMAN_VERSION_MAJOR) -PIXMAN_VERSION_MINOR=pixman_minor() -AC_SUBST(PIXMAN_VERSION_MINOR) -PIXMAN_VERSION_MICRO=pixman_micro() -AC_SUBST(PIXMAN_VERSION_MICRO) - -AC_SUBST(LT_VERSION_INFO) - -# Check for dependencies - -PIXMAN_CHECK_CFLAG([-Wall]) -PIXMAN_CHECK_CFLAG([-Wdeclaration-after-statement]) -PIXMAN_CHECK_CFLAG([-Wno-unused-local-typedefs]) -PIXMAN_CHECK_CFLAG([-fno-strict-aliasing]) - -dnl ========================================================================= -dnl OpenMP for the test suite? -dnl - -# Check for OpenMP support only when autoconf support that (require autoconf >=2.62) -OPENMP_CFLAGS= -m4_ifdef([AC_OPENMP], [AC_OPENMP]) - -if test "x$enable_openmp" = "xyes" && test "x$ac_cv_prog_c_openmp" = "xunsupported" ; then - AC_MSG_WARN([OpenMP support requested but found unsupported]) -fi - -dnl May not fail to link without -Wall -Werror added -dnl So try to link only when openmp is supported -dnl ac_cv_prog_c_openmp is not defined when --disable-openmp is used -if test "x$ac_cv_prog_c_openmp" != "xunsupported" && test "x$ac_cv_prog_c_openmp" != "x"; then - m4_define([openmp_test_program],[dnl - #include <stdio.h> - - extern unsigned int lcg_seed; - #pragma omp threadprivate(lcg_seed) - unsigned int lcg_seed; - - unsigned function(unsigned a, unsigned b) - { - lcg_seed ^= b; - return ((a + b) ^ a ) + lcg_seed; - } - - int main(int argc, char **argv) - { - int i; - int n1 = 0, n2 = argc; - unsigned checksum = 0; - int verbose = argv != NULL; - unsigned (*test_function)(unsigned, unsigned); - test_function = function; - #pragma omp parallel for reduction(+:checksum) default(none) \ - shared(n1, n2, test_function, verbose) - for (i = n1; i < n2; i++) - { - unsigned crc = test_function (i, 0); - if (verbose) - printf ("%d: %08X\n", i, crc); - checksum += crc; - } - printf("%u\n", checksum); - return 0; - } - ]) - - PIXMAN_LINK_WITH_ENV( - [CFLAGS="$OPENMP_CFLAGS" LDFLAGS="$OPENMP_CFLAGS"], - [openmp_test_program], - [have_openmp=yes], - [have_openmp=no]) - if test "x$have_openmp" = "xyes" ; then - AC_DEFINE(USE_OPENMP, 1, [use OpenMP in the test suite]) - fi -fi -AC_SUBST(OPENMP_CFLAGS) - -dnl ========================================================================= -dnl -fvisibility stuff - -PIXMAN_CHECK_CFLAG([-fvisibility=hidden], [dnl -#if defined(__GNUC__) && (__GNUC__ >= 4) -#ifdef _WIN32 -#error Have -fvisibility but it is ignored and generates a warning -#endif -#else -#error Need GCC 4.0 for visibility -#endif -]) - -PIXMAN_CHECK_CFLAG([-xldscope=hidden], [dnl -#if defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) -#else -#error Need Sun Studio 8 for visibility -#endif -]) - -dnl =========================================================================== -dnl Check for Loongson Multimedia Instructions - -if test "x$LS_CFLAGS" = "x" ; then - LS_CFLAGS="-march=loongson2f" -fi - -have_loongson_mmi=no -AC_MSG_CHECKING(whether to use Loongson MMI assembler) - -xserver_save_CFLAGS=$CFLAGS -CFLAGS=" $LS_CFLAGS $CFLAGS -I$srcdir" -AC_LINK_IFELSE([AC_LANG_SOURCE([[ -#ifndef __mips_loongson_vector_rev -#error "Loongson Multimedia Instructions are only available on Loongson" -#endif -#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4)) -#error "Need GCC >= 4.4 for Loongson MMI compilation" -#endif -#include "pixman/loongson-mmintrin.h" -int main () { - union { - __m64 v; - char c[8]; - } a = { .c = {1, 2, 3, 4, 5, 6, 7, 8} }; - int b = 4; - __m64 c = _mm_srli_pi16 (a.v, b); - return 0; -}]])], have_loongson_mmi=yes) -CFLAGS=$xserver_save_CFLAGS - -AC_ARG_ENABLE(loongson-mmi, - [AC_HELP_STRING([--disable-loongson-mmi], - [disable Loongson MMI fast paths])], - [enable_loongson_mmi=$enableval], [enable_loongson_mmi=auto]) - -if test $enable_loongson_mmi = no ; then - have_loongson_mmi=disabled -fi - -if test $have_loongson_mmi = yes ; then - AC_DEFINE(USE_LOONGSON_MMI, 1, [use Loongson Multimedia Instructions]) -else - LS_CFLAGS= -fi - -AC_MSG_RESULT($have_loongson_mmi) -if test $enable_loongson_mmi = yes && test $have_loongson_mmi = no ; then - AC_MSG_ERROR([Loongson MMI not detected]) -fi - -AM_CONDITIONAL(USE_LOONGSON_MMI, test $have_loongson_mmi = yes) - -dnl =========================================================================== -dnl Check for MMX - -if test "x$MMX_CFLAGS" = "x" ; then - if test "x$SUNCC" = "xyes"; then - # Sun Studio doesn't have an -xarch=mmx flag, so we have to use sse - # but if we're building 64-bit, mmx & sse support is on by default and - # -xarch=sse throws an error instead - if test "$AMD64_ABI" = "no" ; then - MMX_CFLAGS="-xarch=sse" - fi - else - MMX_CFLAGS="-mmmx -Winline" - fi -fi - -have_mmx_intrinsics=no -AC_MSG_CHECKING(whether to use MMX intrinsics) -xserver_save_CFLAGS=$CFLAGS -CFLAGS="$MMX_CFLAGS $CFLAGS" -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ -#if defined(__GNUC__) && (__GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 4)) -#error "Need GCC >= 3.4 for MMX intrinsics" -#endif -#include <mmintrin.h> -#include <stdint.h> - -/* Check support for block expressions */ -#define _mm_shuffle_pi16(A, N) \ - ({ \ - __m64 ret; \ - \ - /* Some versions of clang will choke on K */ \ - asm ("pshufw %2, %1, %0\n\t" \ - : "=y" (ret) \ - : "y" (A), "K" ((const int8_t)N) \ - ); \ - \ - ret; \ - }) - -int main () { - __m64 v = _mm_cvtsi32_si64 (1); - __m64 w; - - w = _mm_shuffle_pi16(v, 5); - - /* Some versions of clang will choke on this */ - asm ("pmulhuw %1, %0\n\t" - : "+y" (w) - : "y" (v) - ); - - return _mm_cvtsi64_si32 (v); -}]])], have_mmx_intrinsics=yes) -CFLAGS=$xserver_save_CFLAGS - -AC_ARG_ENABLE(mmx, - [AC_HELP_STRING([--disable-mmx], - [disable x86 MMX fast paths])], - [enable_mmx=$enableval], [enable_mmx=auto]) - -if test $enable_mmx = no ; then - have_mmx_intrinsics=disabled -fi - -if test $have_mmx_intrinsics = yes ; then - AC_DEFINE(USE_X86_MMX, 1, [use x86 MMX compiler intrinsics]) -else - MMX_CFLAGS= -fi - -AC_MSG_RESULT($have_mmx_intrinsics) -if test $enable_mmx = yes && test $have_mmx_intrinsics = no ; then - AC_MSG_ERROR([x86 MMX intrinsics not detected]) -fi - -AM_CONDITIONAL(USE_X86_MMX, test $have_mmx_intrinsics = yes) - -dnl =========================================================================== -dnl Check for SSE2 - -if test "x$SSE2_CFLAGS" = "x" ; then - if test "x$SUNCC" = "xyes"; then - # SSE2 is enabled by default in the Sun Studio 64-bit environment - if test "$AMD64_ABI" = "no" ; then - SSE2_CFLAGS="-xarch=sse2" - fi - else - SSE2_CFLAGS="-msse2 -Winline" - fi -fi - -have_sse2_intrinsics=no -AC_MSG_CHECKING(whether to use SSE2 intrinsics) -xserver_save_CFLAGS=$CFLAGS -CFLAGS="$SSE2_CFLAGS $CFLAGS" - -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ -#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2)) -# if !defined(__amd64__) && !defined(__x86_64__) -# error "Need GCC >= 4.2 for SSE2 intrinsics on x86" -# endif -#endif -#include <mmintrin.h> -#include <xmmintrin.h> -#include <emmintrin.h> -int param; -int main () { - __m128i a = _mm_set1_epi32 (param), b = _mm_set1_epi32 (param + 1), c; - c = _mm_xor_si128 (a, b); - return _mm_cvtsi128_si32(c); -}]])], have_sse2_intrinsics=yes) -CFLAGS=$xserver_save_CFLAGS - -AC_ARG_ENABLE(sse2, - [AC_HELP_STRING([--disable-sse2], - [disable SSE2 fast paths])], - [enable_sse2=$enableval], [enable_sse2=auto]) - -if test $enable_sse2 = no ; then - have_sse2_intrinsics=disabled -fi - -if test $have_sse2_intrinsics = yes ; then - AC_DEFINE(USE_SSE2, 1, [use SSE2 compiler intrinsics]) -fi - -AC_MSG_RESULT($have_sse2_intrinsics) -if test $enable_sse2 = yes && test $have_sse2_intrinsics = no ; then - AC_MSG_ERROR([SSE2 intrinsics not detected]) -fi - -AM_CONDITIONAL(USE_SSE2, test $have_sse2_intrinsics = yes) - -dnl =========================================================================== -dnl Check for SSSE3 - -if test "x$SSSE3_CFLAGS" = "x" ; then - SSSE3_CFLAGS="-mssse3 -Winline" -fi - -have_ssse3_intrinsics=no -AC_MSG_CHECKING(whether to use SSSE3 intrinsics) -xserver_save_CFLAGS=$CFLAGS -CFLAGS="$SSSE3_CFLAGS $CFLAGS" - -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ -#include <mmintrin.h> -#include <xmmintrin.h> -#include <emmintrin.h> -#include <tmmintrin.h> -int param; -int main () { - __m128i a = _mm_set1_epi32 (param), b = _mm_set1_epi32 (param + 1), c; - c = _mm_maddubs_epi16 (a, b); - return _mm_cvtsi128_si32(c); -}]])], have_ssse3_intrinsics=yes) -CFLAGS=$xserver_save_CFLAGS - -AC_ARG_ENABLE(ssse3, - [AC_HELP_STRING([--disable-ssse3], - [disable SSSE3 fast paths])], - [enable_ssse3=$enableval], [enable_ssse3=auto]) - -if test $enable_ssse3 = no ; then - have_ssse3_intrinsics=disabled -fi - -if test $have_ssse3_intrinsics = yes ; then - AC_DEFINE(USE_SSSE3, 1, [use SSSE3 compiler intrinsics]) -fi - -AC_MSG_RESULT($have_ssse3_intrinsics) -if test $enable_ssse3 = yes && test $have_ssse3_intrinsics = no ; then - AC_MSG_ERROR([SSSE3 intrinsics not detected]) -fi - -AM_CONDITIONAL(USE_SSSE3, test $have_ssse3_intrinsics = yes) - -dnl =========================================================================== -dnl Other special flags needed when building code using MMX or SSE instructions -case $host_os in - solaris*) - # When building 32-bit binaries, apply a mapfile to ensure that the - # binaries aren't flagged as only able to run on MMX+SSE capable CPUs - # since they check at runtime before using those instructions. - # Not all linkers grok the mapfile format so we check for that first. - if test "$AMD64_ABI" = "no" ; then - use_hwcap_mapfile=no - AC_MSG_CHECKING(whether to use a hardware capability map file) - hwcap_save_LDFLAGS="$LDFLAGS" - HWCAP_LDFLAGS='-Wl,-M,$(srcdir)/solaris-hwcap.mapfile' - LDFLAGS="$LDFLAGS -Wl,-M,pixman/solaris-hwcap.mapfile" - AC_LINK_IFELSE([AC_LANG_SOURCE([[int main() { return 0; }]])], - use_hwcap_mapfile=yes, - HWCAP_LDFLAGS="") - LDFLAGS="$hwcap_save_LDFLAGS" - AC_MSG_RESULT($use_hwcap_mapfile) - fi - if test "x$MMX_LDFLAGS" = "x" ; then - MMX_LDFLAGS="$HWCAP_LDFLAGS" - fi - if test "x$SSE2_LDFLAGS" = "x" ; then - SSE2_LDFLAGS="$HWCAP_LDFLAGS" - fi - ;; -esac - -AC_SUBST(LS_CFLAGS) -AC_SUBST(IWMMXT_CFLAGS) -AC_SUBST(MMX_CFLAGS) -AC_SUBST(MMX_LDFLAGS) -AC_SUBST(SSE2_CFLAGS) -AC_SUBST(SSE2_LDFLAGS) -AC_SUBST(SSSE3_CFLAGS) - -dnl =========================================================================== -dnl Check for VMX/Altivec -if test -n "`$CC -v 2>&1 | grep version | grep Apple`"; then - VMX_CFLAGS="-faltivec" -else - VMX_CFLAGS="-maltivec -mabi=altivec" -fi - -have_vmx_intrinsics=no -AC_MSG_CHECKING(whether to use VMX/Altivec intrinsics) -xserver_save_CFLAGS=$CFLAGS -CFLAGS="$VMX_CFLAGS $CFLAGS" -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ -#if defined(__GNUC__) && (__GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 4)) -#error "Need GCC >= 3.4 for sane altivec support" -#endif -#include <altivec.h> -int main () { - vector unsigned int v = vec_splat_u32 (1); - v = vec_sub (v, v); - return 0; -}]])], have_vmx_intrinsics=yes) -CFLAGS=$xserver_save_CFLAGS - -AC_ARG_ENABLE(vmx, - [AC_HELP_STRING([--disable-vmx], - [disable VMX fast paths])], - [enable_vmx=$enableval], [enable_vmx=auto]) - -if test $enable_vmx = no ; then - have_vmx_intrinsics=disabled -fi - -if test $have_vmx_intrinsics = yes ; then - AC_DEFINE(USE_VMX, 1, [use VMX compiler intrinsics]) -else - VMX_CFLAGS= -fi - -AC_MSG_RESULT($have_vmx_intrinsics) -if test $enable_vmx = yes && test $have_vmx_intrinsics = no ; then - AC_MSG_ERROR([VMX intrinsics not detected]) -fi - -AC_SUBST(VMX_CFLAGS) - -AM_CONDITIONAL(USE_VMX, test $have_vmx_intrinsics = yes) - -dnl ========================================================================== -dnl Check if assembler is gas compatible and supports ARM SIMD instructions -have_arm_simd=no -AC_MSG_CHECKING(whether to use ARM SIMD assembler) -xserver_save_CFLAGS=$CFLAGS -CFLAGS="-x assembler-with-cpp $CFLAGS" -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ -.text -.arch armv6 -.object_arch armv4 -.arm -.altmacro -#ifndef __ARM_EABI__ -#error EABI is required (to be sure that calling conventions are compatible) -#endif -pld [r0] -uqadd8 r0, r0, r0]])], have_arm_simd=yes) -CFLAGS=$xserver_save_CFLAGS - -AC_ARG_ENABLE(arm-simd, - [AC_HELP_STRING([--disable-arm-simd], - [disable ARM SIMD fast paths])], - [enable_arm_simd=$enableval], [enable_arm_simd=auto]) - -if test $enable_arm_simd = no ; then - have_arm_simd=disabled -fi - -if test $have_arm_simd = yes ; then - AC_DEFINE(USE_ARM_SIMD, 1, [use ARM SIMD assembly optimizations]) -fi - -AM_CONDITIONAL(USE_ARM_SIMD, test $have_arm_simd = yes) - -AC_MSG_RESULT($have_arm_simd) -if test $enable_arm_simd = yes && test $have_arm_simd = no ; then - AC_MSG_ERROR([ARM SIMD intrinsics not detected]) -fi - -dnl ========================================================================== -dnl Check if assembler is gas compatible and supports NEON instructions -have_arm_neon=no -AC_MSG_CHECKING(whether to use ARM NEON assembler) -xserver_save_CFLAGS=$CFLAGS -CFLAGS="-x assembler-with-cpp $CFLAGS" -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ -.text -.fpu neon -.arch armv7a -.object_arch armv4 -.eabi_attribute 10, 0 -.arm -.altmacro -#ifndef __ARM_EABI__ -#error EABI is required (to be sure that calling conventions are compatible) -#endif -pld [r0] -vmovn.u16 d0, q0]])], have_arm_neon=yes) -CFLAGS=$xserver_save_CFLAGS - -AC_ARG_ENABLE(arm-neon, - [AC_HELP_STRING([--disable-arm-neon], - [disable ARM NEON fast paths])], - [enable_arm_neon=$enableval], [enable_arm_neon=auto]) - -if test $enable_arm_neon = no ; then - have_arm_neon=disabled -fi - -if test $have_arm_neon = yes ; then - AC_DEFINE(USE_ARM_NEON, 1, [use ARM NEON assembly optimizations]) -fi - -AM_CONDITIONAL(USE_ARM_NEON, test $have_arm_neon = yes) - -AC_MSG_RESULT($have_arm_neon) -if test $enable_arm_neon = yes && test $have_arm_neon = no ; then - AC_MSG_ERROR([ARM NEON intrinsics not detected]) -fi - -dnl =========================================================================== -dnl Check for IWMMXT - -AC_ARG_ENABLE(arm-iwmmxt, - [AC_HELP_STRING([--disable-arm-iwmmxt], - [disable ARM IWMMXT fast paths])], - [enable_iwmmxt=$enableval], [enable_iwmmxt=auto]) - -AC_ARG_ENABLE(arm-iwmmxt2, - [AC_HELP_STRING([--disable-arm-iwmmxt2], - [build ARM IWMMXT fast paths with -march=iwmmxt instead of -march=iwmmxt2])], - [enable_iwmmxt2=$enableval], [enable_iwmmxt2=auto]) - -if test "x$IWMMXT_CFLAGS" = "x" ; then - IWMMXT_CFLAGS="-flax-vector-conversions -Winline -march=iwmmxt" - if test $enable_iwmmxt2 != no ; then - IWMMXT_CFLAGS="${IWMMXT_CFLAGS}2" - fi -fi - -have_iwmmxt_intrinsics=no -AC_MSG_CHECKING(whether to use ARM IWMMXT intrinsics) -xserver_save_CFLAGS=$CFLAGS -CFLAGS="$CFLAGS $IWMMXT_CFLAGS" -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ -#ifndef __arm__ -#error "IWMMXT is only available on ARM" -#endif -#ifndef __IWMMXT__ -#error "IWMMXT not enabled (with -march=iwmmxt)" -#endif -#if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8)) -#error "Need GCC >= 4.8 for IWMMXT intrinsics" -#endif -#include <mmintrin.h> -int main () { - union { - __m64 v; - char c[8]; - } a = { .c = {1, 2, 3, 4, 5, 6, 7, 8} }; - int b = 4; - __m64 c = _mm_srli_si64 (a.v, b); -}]])], have_iwmmxt_intrinsics=yes) -CFLAGS=$xserver_save_CFLAGS - -if test $enable_iwmmxt = no ; then - have_iwmmxt_intrinsics=disabled -fi - -if test $have_iwmmxt_intrinsics = yes ; then - AC_DEFINE(USE_ARM_IWMMXT, 1, [use ARM IWMMXT compiler intrinsics]) -else - IWMMXT_CFLAGS= -fi - -AC_MSG_RESULT($have_iwmmxt_intrinsics) -if test $enable_iwmmxt = yes && test $have_iwmmxt_intrinsics = no ; then - AC_MSG_ERROR([IWMMXT intrinsics not detected]) -fi - -AM_CONDITIONAL(USE_ARM_IWMMXT, test $have_iwmmxt_intrinsics = yes) - -dnl ========================================================================== -dnl Check if assembler is gas compatible and supports MIPS DSPr2 instructions - -have_mips_dspr2=no -AC_MSG_CHECKING(whether to use MIPS DSPr2 assembler) -xserver_save_CFLAGS=$CFLAGS -CFLAGS="-mdspr2 $CFLAGS" - -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ -#if !(defined(__mips__) && __mips_isa_rev >= 2) -#error MIPS DSPr2 is currently only available on MIPS32r2 platforms. -#endif -int -main () -{ - int c = 0, a = 0, b = 0; - __asm__ __volatile__ ( - "precr.qb.ph %[c], %[a], %[b] \n\t" - : [c] "=r" (c) - : [a] "r" (a), [b] "r" (b) - ); - return c; -}]])], have_mips_dspr2=yes) -CFLAGS=$xserver_save_CFLAGS - -AC_ARG_ENABLE(mips-dspr2, - [AC_HELP_STRING([--disable-mips-dspr2], - [disable MIPS DSPr2 fast paths])], - [enable_mips_dspr2=$enableval], [enable_mips_dspr2=auto]) - -if test $enable_mips_dspr2 = no ; then - have_mips_dspr2=disabled -fi - -if test $have_mips_dspr2 = yes ; then - AC_DEFINE(USE_MIPS_DSPR2, 1, [use MIPS DSPr2 assembly optimizations]) -fi - -AM_CONDITIONAL(USE_MIPS_DSPR2, test $have_mips_dspr2 = yes) - -AC_MSG_RESULT($have_mips_dspr2) -if test $enable_mips_dspr2 = yes && test $have_mips_dspr2 = no ; then - AC_MSG_ERROR([MIPS DSPr2 instructions not detected]) -fi - -dnl ========================================================================================= -dnl Check for GNU-style inline assembly support - -have_gcc_inline_asm=no -AC_MSG_CHECKING(whether to use GNU-style inline assembler) -AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ -int main () { - /* Most modern architectures have a NOP instruction, so this is a fairly generic test. */ - asm volatile ( "\tnop\n" : : : "cc", "memory" ); - return 0; -}]])], have_gcc_inline_asm=yes) - -AC_ARG_ENABLE(gcc-inline-asm, - [AC_HELP_STRING([--disable-gcc-inline-asm], - [disable GNU-style inline assembler])], - [enable_gcc_inline_asm=$enableval], [enable_gcc_inline_asm=auto]) - -if test $enable_gcc_inline_asm = no ; then - have_gcc_inline_asm=disabled -fi - -if test $have_gcc_inline_asm = yes ; then - AC_DEFINE(USE_GCC_INLINE_ASM, 1, [use GNU-style inline assembler]) -fi - -AC_MSG_RESULT($have_gcc_inline_asm) -if test $enable_gcc_inline_asm = yes && test $have_gcc_inline_asm = no ; then - AC_MSG_ERROR([GNU-style inline assembler not detected]) -fi - -AM_CONDITIONAL(USE_GCC_INLINE_ASM, test $have_gcc_inline_asm = yes) - -dnl ============================================== -dnl Static test programs - -AC_ARG_ENABLE(static-testprogs, - [AC_HELP_STRING([--enable-static-testprogs], - [build test programs as static binaries [default=no]])], - [enable_static_testprogs=$enableval], [enable_static_testprogs=no]) - -TESTPROGS_EXTRA_LDFLAGS= -if test "x$enable_static_testprogs" = "xyes" ; then - TESTPROGS_EXTRA_LDFLAGS="-all-static" -fi -AC_SUBST(TESTPROGS_EXTRA_LDFLAGS) - -dnl ============================================== -dnl Timers - -AC_ARG_ENABLE(timers, - [AC_HELP_STRING([--enable-timers], - [enable TIMER_BEGIN and TIMER_END macros [default=no]])], - [enable_timers=$enableval], [enable_timers=no]) - -if test $enable_timers = yes ; then - AC_DEFINE(PIXMAN_TIMERS, 1, [enable TIMER_BEGIN/TIMER_END macros]) -fi -AC_SUBST(PIXMAN_TIMERS) - -dnl =================================== -dnl GTK+ - -AC_ARG_ENABLE(gtk, - [AC_HELP_STRING([--enable-gtk], - [enable tests using GTK+ [default=auto]])], - [enable_gtk=$enableval], [enable_gtk=auto]) - -PKG_PROG_PKG_CONFIG - -if test $enable_gtk = yes ; then - AC_CHECK_LIB([pixman-1], [pixman_version_string]) - PKG_CHECK_MODULES(GTK, [gtk+-2.0 >= 2.16 pixman-1]) -fi - -if test $enable_gtk = auto ; then - AC_CHECK_LIB([pixman-1], [pixman_version_string], [enable_gtk=auto], [enable_gtk=no]) -fi - -if test $enable_gtk = auto ; then - PKG_CHECK_MODULES(GTK, [gtk+-2.0 >= 2.16 pixman-1], [enable_gtk=yes], [enable_gtk=no]) -fi - -AM_CONDITIONAL(HAVE_GTK, [test "x$enable_gtk" = xyes]) - -AC_SUBST(GTK_CFLAGS) -AC_SUBST(GTK_LIBS) - -dnl ===================================== -dnl posix_memalign, sigaction, alarm, gettimeofday - -AC_CHECK_FUNC(posix_memalign, have_posix_memalign=yes, have_posix_memalign=no) -if test x$have_posix_memalign = xyes; then - AC_DEFINE(HAVE_POSIX_MEMALIGN, 1, [Whether we have posix_memalign()]) -fi - -AC_CHECK_FUNC(sigaction, have_sigaction=yes, have_sigaction=no) -if test x$have_sigaction = xyes; then - AC_DEFINE(HAVE_SIGACTION, 1, [Whether we have sigaction()]) -fi - -AC_CHECK_FUNC(alarm, have_alarm=yes, have_alarm=no) -if test x$have_alarm = xyes; then - AC_DEFINE(HAVE_ALARM, 1, [Whether we have alarm()]) -fi - -AC_CHECK_HEADER([sys/mman.h], - [AC_DEFINE(HAVE_SYS_MMAN_H, [1], [Define to 1 if we have <sys/mman.h>])]) - -AC_CHECK_FUNC(mmap, have_mmap=yes, have_mmap=no) -if test x$have_mmap = xyes; then - AC_DEFINE(HAVE_MMAP, 1, [Whether we have mmap()]) -fi - -AC_CHECK_FUNC(mprotect, have_mprotect=yes, have_mprotect=no) -if test x$have_mprotect = xyes; then - AC_DEFINE(HAVE_MPROTECT, 1, [Whether we have mprotect()]) -fi - -AC_CHECK_FUNC(getpagesize, have_getpagesize=yes, have_getpagesize=no) -if test x$have_getpagesize = xyes; then - AC_DEFINE(HAVE_GETPAGESIZE, 1, [Whether we have getpagesize()]) -fi - -AC_CHECK_HEADER([fenv.h], - [AC_DEFINE(HAVE_FENV_H, [1], [Define to 1 if we have <fenv.h>])]) - -AC_CHECK_LIB(m, feenableexcept, have_feenableexcept=yes, have_feenableexcept=no) -if test x$have_feenableexcept = xyes; then - AC_DEFINE(HAVE_FEENABLEEXCEPT, 1, [Whether we have feenableexcept()]) -fi - -AC_CHECK_DECL([FE_DIVBYZERO], - [AC_DEFINE(HAVE_FEDIVBYZERO, 1, [Whether we have FE_DIVBYZERO])], - [], - [[#include <fenv.h>]]) - -AC_CHECK_FUNC(gettimeofday, have_gettimeofday=yes, have_gettimeofday=no) -AC_CHECK_HEADER(sys/time.h, have_sys_time_h=yes, have_sys_time_h=no) -if test x$have_gettimeofday = xyes && test x$have_sys_time_h = xyes; then - AC_DEFINE(HAVE_GETTIMEOFDAY, 1, [Whether we have gettimeofday()]) -fi - -dnl ===================================== -dnl Check for missing sqrtf() as, e.g., for Solaris 9 - -AC_SEARCH_LIBS([sqrtf], [m], [], - [AC_DEFINE([sqrtf], [sqrt], - [Define to sqrt if you do not have the `sqrtf' function.])]) - -dnl ===================================== -dnl Thread local storage - -AC_MSG_CHECKING(for thread local storage (TLS) support) -AC_CACHE_VAL(ac_cv_tls, [ - ac_cv_tls=none - keywords="__thread __declspec(thread)" - for kw in $keywords ; do - AC_TRY_COMPILE([ -#if defined(__MINGW32__) && !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) -#error This MinGW version has broken __thread support -#endif -#ifdef __OpenBSD__ -#error OpenBSD has broken __thread support -#endif - -int $kw test;], [], [ac_cv_tls=$kw; break]) - done -]) -AC_MSG_RESULT($ac_cv_tls) - -if test "$ac_cv_tls" != "none"; then - AC_DEFINE_UNQUOTED([TLS], $ac_cv_tls, [The compiler supported TLS storage class]) -fi - -dnl -dnl posix tls -dnl - -m4_define([pthread_test_program],AC_LANG_SOURCE([[dnl -#include <stdlib.h> -#include <pthread.h> - -static pthread_once_t once_control = PTHREAD_ONCE_INIT; -static pthread_key_t key; - -static void -make_key (void) -{ - pthread_key_create (&key, NULL); -} - -int -main () -{ - void *value = NULL; - - if (pthread_once (&once_control, make_key) != 0) - { - value = NULL; - } - else - { - value = pthread_getspecific (key); - if (!value) - { - value = malloc (100); - pthread_setspecific (key, value); - } - } - return 0; -} -]])) - -AC_DEFUN([PIXMAN_CHECK_PTHREAD],[dnl - if test "z$support_for_pthreads" != "zyes"; then - PIXMAN_LINK_WITH_ENV( - [$1], [pthread_test_program], - [PTHREAD_CFLAGS="$CFLAGS" - PTHREAD_LIBS="$LIBS" - PTHREAD_LDFLAGS="$LDFLAGS" - support_for_pthreads=yes]) - fi -]) - -support_for_pthreads=no - -AC_MSG_CHECKING(for pthreads) - -PIXMAN_CHECK_PTHREAD([CFLAGS="-pthread"; LDFLAGS="-pthread"]) -PIXMAN_CHECK_PTHREAD([CFLAGS="-D_REENTRANT"; LIBS="-lpthread"]) -PIXMAN_CHECK_PTHREAD([CFLAGS="-D_REENTRANT"; LDFLAGS="-lroot"]) - -if test $support_for_pthreads = yes; then - AC_DEFINE([HAVE_PTHREADS], [], [Whether pthreads is supported]) - if test $ac_cv_tls = none ; then - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - fi -fi - -AC_MSG_RESULT($support_for_pthreads) - -AC_SUBST(TOOLCHAIN_SUPPORTS__THREAD) -AC_SUBST(HAVE_PTHREADS) -AC_SUBST(PTHREAD_LDFLAGS) -AC_SUBST(PTHREAD_LIBS) -AC_SUBST(PTHREAD_CFLAGS) - -dnl ===================================== -dnl __attribute__((constructor)) - -support_for_attribute_constructor=no - -AC_MSG_CHECKING(for __attribute__((constructor))) -AC_LINK_IFELSE([AC_LANG_SOURCE([[ -#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)) -/* attribute 'constructor' is supported since gcc 2.7, but some compilers - * may only pretend to be gcc, so let's try to actually use it - */ -static int x = 1; -static void __attribute__((constructor)) constructor_function () { x = 0; } -int main (void) { return x; } -#else -#error not gcc or gcc version is older than 2.7 -#endif -]])], support_for_attribute_constructor=yes) - -if test x$support_for_attribute_constructor = xyes; then - AC_DEFINE([TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR], - [],[Whether the tool chain supports __attribute__((constructor))]) -fi - -AC_MSG_RESULT($support_for_attribute_constructor) -AC_SUBST(TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR) - -dnl ===================================== -dnl __float128 - -support_for_float128=no - -AC_MSG_CHECKING(for __float128) -AC_LINK_IFELSE([AC_LANG_SOURCE([[ -__float128 a = 1.0Q, b = 2.0Q; int main (void) { return a + b; } -]])], support_for_float128=yes) - -if test x$support_for_float128 = xyes; then - AC_DEFINE([HAVE_FLOAT128], [], [Whether the tool chain supports __float128]) -fi - -AC_MSG_RESULT($support_for_float128) - -dnl ===================================== -dnl __builtin_clz - -support_for_builtin_clz=no - -AC_MSG_CHECKING(for __builtin_clz) -AC_LINK_IFELSE([AC_LANG_SOURCE([[ -unsigned int x = 11; int main (void) { return __builtin_clz(x); } -]])], support_for_builtin_clz=yes) - -if test x$support_for_builtin_clz = xyes; then - AC_DEFINE([HAVE_BUILTIN_CLZ], [], [Whether the compiler supports __builtin_clz]) -fi - -AC_MSG_RESULT($support_for_builtin_clz) - -dnl ===================================== -dnl GCC vector extensions - -support_for_gcc_vector_extensions=no - -AC_MSG_CHECKING(for GCC vector extensions) -AC_LINK_IFELSE([AC_LANG_SOURCE([[ -unsigned int __attribute__ ((vector_size(16))) e, a, b; -int main (void) { e = a - ((b << 27) + (b >> (32 - 27))) + 1; return e[0]; } -]])], support_for_gcc_vector_extensions=yes) - -if test x$support_for_gcc_vector_extensions = xyes; then - AC_DEFINE([HAVE_GCC_VECTOR_EXTENSIONS], [], - [Whether the compiler supports GCC vector extensions]) -fi - -AC_MSG_RESULT($support_for_gcc_vector_extensions) - -dnl ================== -dnl libpng - -AC_ARG_ENABLE(libpng, AS_HELP_STRING([--enable-libpng], [Build support for libpng (default: auto)]), - [have_libpng=$enableval], [have_libpng=auto]) - -case x$have_libpng in - xyes) PKG_CHECK_MODULES(PNG, [libpng]) ;; - xno) ;; - *) PKG_CHECK_MODULES(PNG, [libpng], have_libpng=yes, have_libpng=no) ;; -esac - -if test x$have_libpng = xyes; then - AC_DEFINE([HAVE_LIBPNG], [1], [Whether we have libpng]) -fi - -AC_SUBST(HAVE_LIBPNG) - -AC_OUTPUT([pixman-1.pc - pixman-1-uninstalled.pc - Makefile - pixman/Makefile - pixman/pixman-version.h - demos/Makefile - test/Makefile]) - -m4_if(m4_eval(pixman_minor % 2), [1], [ - echo - echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" - echo - echo " Thanks for testing this development snapshot of pixman. Please" - echo " report any problems you find, either by sending email to " - echo - echo " pixman@lists.freedesktop.org" - echo - echo " or by filing a bug at " - echo - echo " https://bugs.freedesktop.org/enter_bug.cgi?product=pixman " - echo - echo " If you are looking for a stable release of pixman, please note " - echo " that stable releases have _even_ minor version numbers. Ie., " - echo " pixman-0.]m4_eval(pixman_minor & ~1)[.x are stable releases, whereas pixman-$PIXMAN_VERSION_MAJOR.$PIXMAN_VERSION_MINOR.$PIXMAN_VERSION_MICRO is a " - echo " development snapshot that may contain bugs and experimental " - echo " features. " - echo - echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" - echo -]) diff --git a/source/libs/pixman/pixman-src/pixman-1-uninstalled.pc.in b/source/libs/pixman/pixman-src/pixman-1-uninstalled.pc.in deleted file mode 100644 index e0347d0101cf629d7cb75219d14d7bca1eb7a5f4..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman-1-uninstalled.pc.in +++ /dev/null @@ -1,5 +0,0 @@ -Name: Pixman -Description: The pixman library (version 1) -Version: @PACKAGE_VERSION@ -Cflags: -I${pc_top_builddir}/${pcfiledir}/pixman -Libs: ${pc_top_builddir}/${pcfiledir}/pixman/libpixman-1.la diff --git a/source/libs/pixman/pixman-src/pixman-1.pc.in b/source/libs/pixman/pixman-src/pixman-1.pc.in deleted file mode 100644 index e3b9711aeb9f952326e75b464b4d0d73f03bed83..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman-1.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: Pixman -Description: The pixman library (version 1) -Version: @PACKAGE_VERSION@ -Cflags: -I${includedir}/pixman-1 -Libs: -L${libdir} -lpixman-1 - diff --git a/source/libs/pixman/pixman-src/pixman/Makefile.am b/source/libs/pixman/pixman-src/pixman/Makefile.am deleted file mode 100644 index 581b6f61e2e525530b22e7e16b395303ab7402f0..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/Makefile.am +++ /dev/null @@ -1,141 +0,0 @@ -include $(top_srcdir)/pixman/Makefile.sources - -lib_LTLIBRARIES = libpixman-1.la - -libpixman_1_la_LDFLAGS = -version-info $(LT_VERSION_INFO) -no-undefined @PTHREAD_LDFLAGS@ -libpixman_1_la_LIBADD = @PTHREAD_LIBS@ -lm -libpixman_1_la_SOURCES = $(libpixman_sources) $(libpixman_headers) - -libpixmanincludedir = $(includedir)/pixman-1 -libpixmaninclude_HEADERS = pixman.h pixman-version.h -noinst_LTLIBRARIES = - -EXTRA_DIST = \ - Makefile.win32 \ - pixman-region.c \ - solaris-hwcap.mapfile \ - $(NULL) - -# mmx code -if USE_X86_MMX -noinst_LTLIBRARIES += libpixman-mmx.la -libpixman_mmx_la_SOURCES = \ - pixman-mmx.c -libpixman_mmx_la_CFLAGS = $(MMX_CFLAGS) -libpixman_1_la_LDFLAGS += $(MMX_LDFLAGS) -libpixman_1_la_LIBADD += libpixman-mmx.la - -ASM_CFLAGS_mmx=$(MMX_CFLAGS) -endif - -# vmx code -if USE_VMX -noinst_LTLIBRARIES += libpixman-vmx.la -libpixman_vmx_la_SOURCES = \ - pixman-vmx.c \ - pixman-combine32.h -libpixman_vmx_la_CFLAGS = $(VMX_CFLAGS) -libpixman_1_la_LIBADD += libpixman-vmx.la - -ASM_CFLAGS_vmx=$(VMX_CFLAGS) -endif - -# sse2 code -if USE_SSE2 -noinst_LTLIBRARIES += libpixman-sse2.la -libpixman_sse2_la_SOURCES = \ - pixman-sse2.c -libpixman_sse2_la_CFLAGS = $(SSE2_CFLAGS) -libpixman_1_la_LDFLAGS += $(SSE2_LDFLAGS) -libpixman_1_la_LIBADD += libpixman-sse2.la - -ASM_CFLAGS_sse2=$(SSE2_CFLAGS) -endif - -# ssse3 code -if USE_SSSE3 -noinst_LTLIBRARIES += libpixman-ssse3.la -libpixman_ssse3_la_SOURCES = \ - pixman-ssse3.c -libpixman_ssse3_la_CFLAGS = $(SSSE3_CFLAGS) -libpixman_1_la_LDFLAGS += $(SSSE3_LDFLAGS) -libpixman_1_la_LIBADD += libpixman-ssse3.la - -ASM_CFLAGS_ssse3=$(SSSE3_CFLAGS) -endif - -# arm simd code -if USE_ARM_SIMD -noinst_LTLIBRARIES += libpixman-arm-simd.la -libpixman_arm_simd_la_SOURCES = \ - pixman-arm-simd.c \ - pixman-arm-common.h \ - pixman-arm-simd-asm.S \ - pixman-arm-simd-asm-scaled.S \ - pixman-arm-asm.h \ - pixman-arm-simd-asm.h -libpixman_1_la_LIBADD += libpixman-arm-simd.la - -ASM_CFLAGS_arm_simd= -endif - -# arm neon code -if USE_ARM_NEON -noinst_LTLIBRARIES += libpixman-arm-neon.la -libpixman_arm_neon_la_SOURCES = \ - pixman-arm-neon.c \ - pixman-arm-common.h \ - pixman-arm-neon-asm.S \ - pixman-arm-neon-asm-bilinear.S \ - pixman-arm-asm.h \ - pixman-arm-neon-asm.h -libpixman_1_la_LIBADD += libpixman-arm-neon.la - -ASM_CFLAGS_arm_neon= -endif - -# iwmmxt code -if USE_ARM_IWMMXT -libpixman_iwmmxt_la_SOURCES = pixman-mmx.c -noinst_LTLIBRARIES += libpixman-iwmmxt.la -libpixman_1_la_LIBADD += libpixman-iwmmxt.la - -libpixman_iwmmxt_la-pixman-mmx.lo: pixman-mmx.c - $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(AM_CPPFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) $(CFLAGS) $(IWMMXT_CFLAGS) -MT libpixman_iwmmxt_la-pixman-mmx.lo -MD -MP -MF $(DEPDIR)/libpixman_iwmmxt_la-pixman-mmx.Tpo -c -o libpixman_iwmmxt_la-pixman-mmx.lo `test -f 'pixman-mmx.c' || echo '$(srcdir)/'`pixman-mmx.c - $(AM_V_at)$(am__mv) $(DEPDIR)/libpixman_iwmmxt_la-pixman-mmx.Tpo $(DEPDIR)/libpixman_iwmmxt_la-pixman-mmx.Plo - -libpixman_iwmmxt_la_DEPENDENCIES = $(am__DEPENDENCIES_1) -libpixman_iwmmxt_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(CFLAGS) $(IWMMXT_CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ - -libpixman-iwmmxt.la: libpixman_iwmmxt_la-pixman-mmx.lo $(libpixman_iwmmxt_la_DEPENDENCIES) - $(AM_V_CCLD)$(libpixman_iwmmxt_la_LINK) libpixman_iwmmxt_la-pixman-mmx.lo $(libpixman_iwmmxt_la_LIBADD) $(LIBS) -endif - -# mips dspr2 code -if USE_MIPS_DSPR2 -noinst_LTLIBRARIES += libpixman-mips-dspr2.la -libpixman_mips_dspr2_la_SOURCES = \ - pixman-mips-dspr2.c \ - pixman-mips-dspr2.h \ - pixman-mips-dspr2-asm.S \ - pixman-mips-dspr2-asm.h \ - pixman-mips-memcpy-asm.S -libpixman_1_la_LIBADD += libpixman-mips-dspr2.la - -ASM_CFLAGS_mips_dspr2= -endif - -# loongson code -if USE_LOONGSON_MMI -noinst_LTLIBRARIES += libpixman-loongson-mmi.la -libpixman_loongson_mmi_la_SOURCES = pixman-mmx.c loongson-mmintrin.h -libpixman_loongson_mmi_la_CFLAGS = $(LS_CFLAGS) -libpixman_1_la_LDFLAGS += $(LS_LDFLAGS) -libpixman_1_la_LIBADD += libpixman-loongson-mmi.la -endif - -.c.s : $(libpixmaninclude_HEADERS) - $(CC) $(CFLAGS) $(ASM_CFLAGS_$(@:pixman-%.s=%)) $(ASM_CFLAGS_$(@:pixman-arm-%.s=arm_%)) -DHAVE_CONFIG_H -I$(srcdir) -I$(builddir) -I$(top_builddir) -S -o $@ $< diff --git a/source/libs/pixman/pixman-src/pixman/Makefile.sources b/source/libs/pixman/pixman-src/pixman/Makefile.sources deleted file mode 100644 index c624eb9a82852c4752ce879f4e7d856b209ff295..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/Makefile.sources +++ /dev/null @@ -1,42 +0,0 @@ -libpixman_sources = \ - pixman.c \ - pixman-access.c \ - pixman-access-accessors.c \ - pixman-bits-image.c \ - pixman-combine32.c \ - pixman-combine-float.c \ - pixman-conical-gradient.c \ - pixman-filter.c \ - pixman-x86.c \ - pixman-mips.c \ - pixman-arm.c \ - pixman-ppc.c \ - pixman-edge.c \ - pixman-edge-accessors.c \ - pixman-fast-path.c \ - pixman-glyph.c \ - pixman-general.c \ - pixman-gradient-walker.c \ - pixman-image.c \ - pixman-implementation.c \ - pixman-linear-gradient.c \ - pixman-matrix.c \ - pixman-noop.c \ - pixman-radial-gradient.c \ - pixman-region16.c \ - pixman-region32.c \ - pixman-solid-fill.c \ - pixman-timer.c \ - pixman-trap.c \ - pixman-utils.c \ - $(NULL) - -libpixman_headers = \ - pixman.h \ - pixman-accessor.h \ - pixman-combine32.h \ - pixman-compiler.h \ - pixman-edge-imp.h \ - pixman-inlines.h \ - pixman-private.h \ - $(NULL) diff --git a/source/libs/pixman/pixman-src/pixman/Makefile.win32 b/source/libs/pixman/pixman-src/pixman/Makefile.win32 deleted file mode 100644 index 7b64033bc513e4cf1f1aae64ac55e947daeff2a3..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/Makefile.win32 +++ /dev/null @@ -1,93 +0,0 @@ -default: all - -top_srcdir = .. -include $(top_srcdir)/pixman/Makefile.sources -include $(top_srcdir)/Makefile.win32.common - -MMX_VAR = $(MMX) -ifeq ($(MMX_VAR),) -MMX_VAR=on -endif - -SSE2_VAR = $(SSE2) -ifeq ($(SSE2_VAR),) -SSE2_VAR=on -endif - -SSSE3_VAR = $(SSSE3) -ifeq ($(SSSE3_VAR),) -SSSE3_VAR=on -endif - -MMX_CFLAGS = -DUSE_X86_MMX -w14710 -w14714 -SSE2_CFLAGS = -DUSE_SSE2 -SSSE3_CFLAGS = -DUSE_SSSE3 - -# MMX compilation flags -ifeq ($(MMX_VAR),on) -PIXMAN_CFLAGS += $(MMX_CFLAGS) -libpixman_sources += pixman-mmx.c -endif - -# SSE2 compilation flags -ifeq ($(SSE2_VAR),on) -PIXMAN_CFLAGS += $(SSE2_CFLAGS) -libpixman_sources += pixman-sse2.c -endif - -# SSSE3 compilation flags -ifeq ($(SSSE3_VAR),on) -PIXMAN_CFLAGS += $(SSSE3_CFLAGS) -libpixman_sources += pixman-ssse3.c -endif - -OBJECTS = $(patsubst %.c, $(CFG_VAR)/%.obj, $(libpixman_sources)) - -# targets -all: inform informMMX informSSE2 informSSSE3 $(CFG_VAR)/$(LIBRARY).lib - -informMMX: -ifneq ($(MMX),off) -ifneq ($(MMX),on) -ifneq ($(MMX),) - @echo "Invalid specified MMX option : "$(MMX_VAR)"." - @echo - @echo "Possible choices for MMX are 'on' or 'off'" - @exit 1 -endif - @echo "Setting MMX flag to default value 'on'... (use MMX=on or MMX=off)" -endif -endif - -informSSE2: -ifneq ($(SSE2),off) -ifneq ($(SSE2),on) -ifneq ($(SSE2),) - @echo "Invalid specified SSE option : "$(SSE2)"." - @echo - @echo "Possible choices for SSE2 are 'on' or 'off'" - @exit 1 -endif - @echo "Setting SSE2 flag to default value 'on'... (use SSE2=on or SSE2=off)" -endif -endif - -informSSSE3: -ifneq ($(SSSE3),off) -ifneq ($(SSSE3),on) -ifneq ($(SSSE3),) - @echo "Invalid specified SSE option : "$(SSSE3)"." - @echo - @echo "Possible choices for SSSE3 are 'on' or 'off'" - @exit 1 -endif - @echo "Setting SSSE3 flag to default value 'on'... (use SSSE3=on or SSSE3=off)" -endif -endif - - -# pixman linking -$(CFG_VAR)/$(LIBRARY).lib: $(OBJECTS) - @$(AR) $(PIXMAN_ARFLAGS) -OUT:$@ $^ - -.PHONY: all informMMX informSSE2 informSSSE3 diff --git a/source/libs/pixman/pixman-src/pixman/loongson-mmintrin.h b/source/libs/pixman/pixman-src/pixman/loongson-mmintrin.h deleted file mode 100644 index 086c6e0f1b24567e60ede6bfc4dc0892d0030527..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/loongson-mmintrin.h +++ /dev/null @@ -1,410 +0,0 @@ -/* The gcc-provided loongson intrinsic functions are way too fucking broken - * to be of any use, otherwise I'd use them. - * - * - The hardware instructions are very similar to MMX or iwMMXt. Certainly - * close enough that they could have implemented the _mm_*-style intrinsic - * interface and had a ton of optimized code available to them. Instead they - * implemented something much, much worse. - * - * - pshuf takes a dead first argument, causing extra instructions to be - * generated. - * - * - There are no 64-bit shift or logical intrinsics, which means you have - * to implement them with inline assembly, but this is a nightmare because - * gcc doesn't understand that the integer vector datatypes are actually in - * floating-point registers, so you end up with braindead code like - * - * punpcklwd $f9,$f9,$f5 - * dmtc1 v0,$f8 - * punpcklwd $f19,$f19,$f5 - * dmfc1 t9,$f9 - * dmtc1 v0,$f9 - * dmtc1 t9,$f20 - * dmfc1 s0,$f19 - * punpcklbh $f20,$f20,$f2 - * - * where crap just gets copied back and forth between integer and floating- - * point registers ad nauseum. - * - * Instead of trying to workaround the problems from these crap intrinsics, I - * just implement the _mm_* intrinsics needed for pixman-mmx.c using inline - * assembly. - */ - -#include <stdint.h> - -/* vectors are stored in 64-bit floating-point registers */ -typedef double __m64; -/* having a 32-bit datatype allows us to use 32-bit loads in places like load8888 */ -typedef float __m32; - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_setzero_si64 (void) -{ - return 0.0; -} - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_add_pi16 (__m64 __m1, __m64 __m2) -{ - __m64 ret; - asm("paddh %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m1), "f" (__m2) - ); - return ret; -} - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_add_pi32 (__m64 __m1, __m64 __m2) -{ - __m64 ret; - asm("paddw %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m1), "f" (__m2) - ); - return ret; -} - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_adds_pu16 (__m64 __m1, __m64 __m2) -{ - __m64 ret; - asm("paddush %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m1), "f" (__m2) - ); - return ret; -} - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_adds_pu8 (__m64 __m1, __m64 __m2) -{ - __m64 ret; - asm("paddusb %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m1), "f" (__m2) - ); - return ret; -} - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_and_si64 (__m64 __m1, __m64 __m2) -{ - __m64 ret; - asm("and %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m1), "f" (__m2) - ); - return ret; -} - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_cmpeq_pi32 (__m64 __m1, __m64 __m2) -{ - __m64 ret; - asm("pcmpeqw %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m1), "f" (__m2) - ); - return ret; -} - -extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_empty (void) -{ - -} - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_madd_pi16 (__m64 __m1, __m64 __m2) -{ - __m64 ret; - asm("pmaddhw %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m1), "f" (__m2) - ); - return ret; -} - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mulhi_pu16 (__m64 __m1, __m64 __m2) -{ - __m64 ret; - asm("pmulhuh %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m1), "f" (__m2) - ); - return ret; -} - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mullo_pi16 (__m64 __m1, __m64 __m2) -{ - __m64 ret; - asm("pmullh %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m1), "f" (__m2) - ); - return ret; -} - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_or_si64 (__m64 __m1, __m64 __m2) -{ - __m64 ret; - asm("or %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m1), "f" (__m2) - ); - return ret; -} - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_packs_pu16 (__m64 __m1, __m64 __m2) -{ - __m64 ret; - asm("packushb %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m1), "f" (__m2) - ); - return ret; -} - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_packs_pi32 (__m64 __m1, __m64 __m2) -{ - __m64 ret; - asm("packsswh %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m1), "f" (__m2) - ); - return ret; -} - -#define _MM_SHUFFLE(fp3,fp2,fp1,fp0) \ - (((fp3) << 6) | ((fp2) << 4) | ((fp1) << 2) | (fp0)) -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_set_pi16 (uint16_t __w3, uint16_t __w2, uint16_t __w1, uint16_t __w0) -{ - if (__builtin_constant_p (__w3) && - __builtin_constant_p (__w2) && - __builtin_constant_p (__w1) && - __builtin_constant_p (__w0)) - { - uint64_t val = ((uint64_t)__w3 << 48) - | ((uint64_t)__w2 << 32) - | ((uint64_t)__w1 << 16) - | ((uint64_t)__w0 << 0); - return *(__m64 *)&val; - } - else if (__w3 == __w2 && __w2 == __w1 && __w1 == __w0) - { - /* TODO: handle other cases */ - uint64_t val = __w3; - uint64_t imm = _MM_SHUFFLE (0, 0, 0, 0); - __m64 ret; - asm("pshufh %0, %1, %2\n\t" - : "=f" (ret) - : "f" (*(__m64 *)&val), "f" (*(__m64 *)&imm) - ); - return ret; - } - uint64_t val = ((uint64_t)__w3 << 48) - | ((uint64_t)__w2 << 32) - | ((uint64_t)__w1 << 16) - | ((uint64_t)__w0 << 0); - return *(__m64 *)&val; -} - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_set_pi32 (unsigned __i1, unsigned __i0) -{ - if (__builtin_constant_p (__i1) && - __builtin_constant_p (__i0)) - { - uint64_t val = ((uint64_t)__i1 << 32) - | ((uint64_t)__i0 << 0); - return *(__m64 *)&val; - } - else if (__i1 == __i0) - { - uint64_t imm = _MM_SHUFFLE (1, 0, 1, 0); - __m64 ret; - asm("pshufh %0, %1, %2\n\t" - : "=f" (ret) - : "f" (*(__m32 *)&__i1), "f" (*(__m64 *)&imm) - ); - return ret; - } - uint64_t val = ((uint64_t)__i1 << 32) - | ((uint64_t)__i0 << 0); - return *(__m64 *)&val; -} -#undef _MM_SHUFFLE - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_shuffle_pi16 (__m64 __m, int64_t __n) -{ - __m64 ret; - asm("pshufh %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m), "f" (*(__m64 *)&__n) - ); - return ret; -} - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_slli_pi16 (__m64 __m, int64_t __count) -{ - __m64 ret; - asm("psllh %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m), "f" (*(__m64 *)&__count) - ); - return ret; -} -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_slli_si64 (__m64 __m, int64_t __count) -{ - __m64 ret; - asm("dsll %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m), "f" (*(__m64 *)&__count) - ); - return ret; -} - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_srli_pi16 (__m64 __m, int64_t __count) -{ - __m64 ret; - asm("psrlh %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m), "f" (*(__m64 *)&__count) - ); - return ret; -} - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_srli_pi32 (__m64 __m, int64_t __count) -{ - __m64 ret; - asm("psrlw %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m), "f" (*(__m64 *)&__count) - ); - return ret; -} - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_srli_si64 (__m64 __m, int64_t __count) -{ - __m64 ret; - asm("dsrl %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m), "f" (*(__m64 *)&__count) - ); - return ret; -} - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_sub_pi16 (__m64 __m1, __m64 __m2) -{ - __m64 ret; - asm("psubh %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m1), "f" (__m2) - ); - return ret; -} - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_unpackhi_pi8 (__m64 __m1, __m64 __m2) -{ - __m64 ret; - asm("punpckhbh %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m1), "f" (__m2) - ); - return ret; -} - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_unpackhi_pi16 (__m64 __m1, __m64 __m2) -{ - __m64 ret; - asm("punpckhhw %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m1), "f" (__m2) - ); - return ret; -} - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_unpacklo_pi8 (__m64 __m1, __m64 __m2) -{ - __m64 ret; - asm("punpcklbh %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m1), "f" (__m2) - ); - return ret; -} - -/* Since punpcklbh doesn't care about the high 32-bits, we use the __m32 datatype which - * allows load8888 to use 32-bit loads */ -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_unpacklo_pi8_f (__m32 __m1, __m64 __m2) -{ - __m64 ret; - asm("punpcklbh %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m1), "f" (__m2) - ); - return ret; -} - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_unpacklo_pi16 (__m64 __m1, __m64 __m2) -{ - __m64 ret; - asm("punpcklhw %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m1), "f" (__m2) - ); - return ret; -} - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_xor_si64 (__m64 __m1, __m64 __m2) -{ - __m64 ret; - asm("xor %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m1), "f" (__m2) - ); - return ret; -} - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -loongson_extract_pi16 (__m64 __m, int64_t __pos) -{ - __m64 ret; - asm("pextrh %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m), "f" (*(__m64 *)&__pos) - ); - return ret; -} - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -loongson_insert_pi16 (__m64 __m1, __m64 __m2, int64_t __pos) -{ - __m64 ret; - asm("pinsrh_%3 %0, %1, %2\n\t" - : "=f" (ret) - : "f" (__m1), "f" (__m2), "i" (__pos) - ); - return ret; -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman-access-accessors.c b/source/libs/pixman/pixman-src/pixman/pixman-access-accessors.c deleted file mode 100644 index 3263582f1858f23bc7fdb5d3d1cd962f340be152..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-access-accessors.c +++ /dev/null @@ -1,3 +0,0 @@ -#define PIXMAN_FB_ACCESSORS - -#include "pixman-access.c" diff --git a/source/libs/pixman/pixman-src/pixman/pixman-access.c b/source/libs/pixman/pixman-src/pixman/pixman-access.c deleted file mode 100644 index 4f0642d7778563aef43ded06a0fefe0fc170f576..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-access.c +++ /dev/null @@ -1,1433 +0,0 @@ -/* - * - * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. - * 2005 Lars Knoll & Zack Rusin, Trolltech - * 2008 Aaron Plattner, NVIDIA Corporation - * - * 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 Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <math.h> - -#include "pixman-accessor.h" -#include "pixman-private.h" - -#define CONVERT_RGB24_TO_Y15(s) \ - (((((s) >> 16) & 0xff) * 153 + \ - (((s) >> 8) & 0xff) * 301 + \ - (((s) ) & 0xff) * 58) >> 2) - -#define CONVERT_RGB24_TO_RGB15(s) \ - ((((s) >> 3) & 0x001f) | \ - (((s) >> 6) & 0x03e0) | \ - (((s) >> 9) & 0x7c00)) - -/* Fetch macros */ - -#ifdef WORDS_BIGENDIAN -#define FETCH_1(img,l,o) \ - (((READ ((img), ((uint32_t *)(l)) + ((o) >> 5))) >> (0x1f - ((o) & 0x1f))) & 0x1) -#else -#define FETCH_1(img,l,o) \ - ((((READ ((img), ((uint32_t *)(l)) + ((o) >> 5))) >> ((o) & 0x1f))) & 0x1) -#endif - -#define FETCH_8(img,l,o) (READ (img, (((uint8_t *)(l)) + ((o) >> 3)))) - -#ifdef WORDS_BIGENDIAN -#define FETCH_4(img,l,o) \ - (((4 * (o)) & 4) ? (FETCH_8 (img,l, 4 * (o)) & 0xf) : (FETCH_8 (img,l,(4 * (o))) >> 4)) -#else -#define FETCH_4(img,l,o) \ - (((4 * (o)) & 4) ? (FETCH_8 (img, l, 4 * (o)) >> 4) : (FETCH_8 (img, l, (4 * (o))) & 0xf)) -#endif - -#ifdef WORDS_BIGENDIAN -#define FETCH_24(img,l,o) \ - ((READ (img, (((uint8_t *)(l)) + ((o) * 3) + 0)) << 16) | \ - (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 1)) << 8) | \ - (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 2)) << 0)) -#else -#define FETCH_24(img,l,o) \ - ((READ (img, (((uint8_t *)(l)) + ((o) * 3) + 0)) << 0) | \ - (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 1)) << 8) | \ - (READ (img, (((uint8_t *)(l)) + ((o) * 3) + 2)) << 16)) -#endif - -/* Store macros */ - -#ifdef WORDS_BIGENDIAN -#define STORE_1(img,l,o,v) \ - do \ - { \ - uint32_t *__d = ((uint32_t *)(l)) + ((o) >> 5); \ - uint32_t __m, __v; \ - \ - __m = 1 << (0x1f - ((o) & 0x1f)); \ - __v = (v)? __m : 0; \ - \ - WRITE((img), __d, (READ((img), __d) & ~__m) | __v); \ - } \ - while (0) -#else -#define STORE_1(img,l,o,v) \ - do \ - { \ - uint32_t *__d = ((uint32_t *)(l)) + ((o) >> 5); \ - uint32_t __m, __v; \ - \ - __m = 1 << ((o) & 0x1f); \ - __v = (v)? __m : 0; \ - \ - WRITE((img), __d, (READ((img), __d) & ~__m) | __v); \ - } \ - while (0) -#endif - -#define STORE_8(img,l,o,v) (WRITE (img, (uint8_t *)(l) + ((o) >> 3), (v))) - -#ifdef WORDS_BIGENDIAN -#define STORE_4(img,l,o,v) \ - do \ - { \ - int bo = 4 * (o); \ - int v4 = (v) & 0x0f; \ - \ - STORE_8 (img, l, bo, ( \ - bo & 4 ? \ - (FETCH_8 (img, l, bo) & 0xf0) | (v4) : \ - (FETCH_8 (img, l, bo) & 0x0f) | (v4 << 4))); \ - } while (0) -#else -#define STORE_4(img,l,o,v) \ - do \ - { \ - int bo = 4 * (o); \ - int v4 = (v) & 0x0f; \ - \ - STORE_8 (img, l, bo, ( \ - bo & 4 ? \ - (FETCH_8 (img, l, bo) & 0x0f) | (v4 << 4) : \ - (FETCH_8 (img, l, bo) & 0xf0) | (v4))); \ - } while (0) -#endif - -#ifdef WORDS_BIGENDIAN -#define STORE_24(img,l,o,v) \ - do \ - { \ - uint8_t *__tmp = (l) + 3 * (o); \ - \ - WRITE ((img), __tmp++, ((v) & 0x00ff0000) >> 16); \ - WRITE ((img), __tmp++, ((v) & 0x0000ff00) >> 8); \ - WRITE ((img), __tmp++, ((v) & 0x000000ff) >> 0); \ - } \ - while (0) -#else -#define STORE_24(img,l,o,v) \ - do \ - { \ - uint8_t *__tmp = (l) + 3 * (o); \ - \ - WRITE ((img), __tmp++, ((v) & 0x000000ff) >> 0); \ - WRITE ((img), __tmp++, ((v) & 0x0000ff00) >> 8); \ - WRITE ((img), __tmp++, ((v) & 0x00ff0000) >> 16); \ - } \ - while (0) -#endif - -/* - * YV12 setup and access macros - */ - -#define YV12_SETUP(image) \ - bits_image_t *__bits_image = (bits_image_t *)image; \ - uint32_t *bits = __bits_image->bits; \ - int stride = __bits_image->rowstride; \ - int offset0 = stride < 0 ? \ - ((-stride) >> 1) * ((__bits_image->height - 1) >> 1) - stride : \ - stride * __bits_image->height; \ - int offset1 = stride < 0 ? \ - offset0 + ((-stride) >> 1) * ((__bits_image->height) >> 1) : \ - offset0 + (offset0 >> 2) - -/* Note no trailing semicolon on the above macro; if it's there, then - * the typical usage of YV12_SETUP(image); will have an extra trailing ; - * that some compilers will interpret as a statement -- and then any further - * variable declarations will cause an error. - */ - -#define YV12_Y(line) \ - ((uint8_t *) ((bits) + (stride) * (line))) - -#define YV12_U(line) \ - ((uint8_t *) ((bits) + offset1 + \ - ((stride) >> 1) * ((line) >> 1))) - -#define YV12_V(line) \ - ((uint8_t *) ((bits) + offset0 + \ - ((stride) >> 1) * ((line) >> 1))) - -/* Misc. helpers */ - -static force_inline void -get_shifts (pixman_format_code_t format, - int *a, - int *r, - int *g, - int *b) -{ - switch (PIXMAN_FORMAT_TYPE (format)) - { - case PIXMAN_TYPE_A: - *b = 0; - *g = 0; - *r = 0; - *a = 0; - break; - - case PIXMAN_TYPE_ARGB: - case PIXMAN_TYPE_ARGB_SRGB: - *b = 0; - *g = *b + PIXMAN_FORMAT_B (format); - *r = *g + PIXMAN_FORMAT_G (format); - *a = *r + PIXMAN_FORMAT_R (format); - break; - - case PIXMAN_TYPE_ABGR: - *r = 0; - *g = *r + PIXMAN_FORMAT_R (format); - *b = *g + PIXMAN_FORMAT_G (format); - *a = *b + PIXMAN_FORMAT_B (format); - break; - - case PIXMAN_TYPE_BGRA: - /* With BGRA formats we start counting at the high end of the pixel */ - *b = PIXMAN_FORMAT_BPP (format) - PIXMAN_FORMAT_B (format); - *g = *b - PIXMAN_FORMAT_B (format); - *r = *g - PIXMAN_FORMAT_G (format); - *a = *r - PIXMAN_FORMAT_R (format); - break; - - case PIXMAN_TYPE_RGBA: - /* With BGRA formats we start counting at the high end of the pixel */ - *r = PIXMAN_FORMAT_BPP (format) - PIXMAN_FORMAT_R (format); - *g = *r - PIXMAN_FORMAT_R (format); - *b = *g - PIXMAN_FORMAT_G (format); - *a = *b - PIXMAN_FORMAT_B (format); - break; - - default: - assert (0); - break; - } -} - -static force_inline uint32_t -convert_channel (uint32_t pixel, uint32_t def_value, - int n_from_bits, int from_shift, - int n_to_bits, int to_shift) -{ - uint32_t v; - - if (n_from_bits && n_to_bits) - v = unorm_to_unorm (pixel >> from_shift, n_from_bits, n_to_bits); - else if (n_to_bits) - v = def_value; - else - v = 0; - - return (v & ((1 << n_to_bits) - 1)) << to_shift; -} - -static force_inline uint32_t -convert_pixel (pixman_format_code_t from, pixman_format_code_t to, uint32_t pixel) -{ - int a_from_shift, r_from_shift, g_from_shift, b_from_shift; - int a_to_shift, r_to_shift, g_to_shift, b_to_shift; - uint32_t a, r, g, b; - - get_shifts (from, &a_from_shift, &r_from_shift, &g_from_shift, &b_from_shift); - get_shifts (to, &a_to_shift, &r_to_shift, &g_to_shift, &b_to_shift); - - a = convert_channel (pixel, ~0, - PIXMAN_FORMAT_A (from), a_from_shift, - PIXMAN_FORMAT_A (to), a_to_shift); - - r = convert_channel (pixel, 0, - PIXMAN_FORMAT_R (from), r_from_shift, - PIXMAN_FORMAT_R (to), r_to_shift); - - g = convert_channel (pixel, 0, - PIXMAN_FORMAT_G (from), g_from_shift, - PIXMAN_FORMAT_G (to), g_to_shift); - - b = convert_channel (pixel, 0, - PIXMAN_FORMAT_B (from), b_from_shift, - PIXMAN_FORMAT_B (to), b_to_shift); - - return a | r | g | b; -} - -static force_inline uint32_t -convert_pixel_to_a8r8g8b8 (bits_image_t *image, - pixman_format_code_t format, - uint32_t pixel) -{ - if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY || - PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR) - { - return image->indexed->rgba[pixel]; - } - else - { - return convert_pixel (format, PIXMAN_a8r8g8b8, pixel); - } -} - -static force_inline uint32_t -convert_pixel_from_a8r8g8b8 (pixman_image_t *image, - pixman_format_code_t format, uint32_t pixel) -{ - if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_GRAY) - { - pixel = CONVERT_RGB24_TO_Y15 (pixel); - - return image->bits.indexed->ent[pixel & 0x7fff]; - } - else if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR) - { - pixel = convert_pixel (PIXMAN_a8r8g8b8, PIXMAN_x1r5g5b5, pixel); - - return image->bits.indexed->ent[pixel & 0x7fff]; - } - else - { - return convert_pixel (PIXMAN_a8r8g8b8, format, pixel); - } -} - -static force_inline uint32_t -fetch_and_convert_pixel (bits_image_t * image, - const uint8_t * bits, - int offset, - pixman_format_code_t format) -{ - uint32_t pixel; - - switch (PIXMAN_FORMAT_BPP (format)) - { - case 1: - pixel = FETCH_1 (image, bits, offset); - break; - - case 4: - pixel = FETCH_4 (image, bits, offset); - break; - - case 8: - pixel = READ (image, bits + offset); - break; - - case 16: - pixel = READ (image, ((uint16_t *)bits + offset)); - break; - - case 24: - pixel = FETCH_24 (image, bits, offset); - break; - - case 32: - pixel = READ (image, ((uint32_t *)bits + offset)); - break; - - default: - pixel = 0xffff00ff; /* As ugly as possible to detect the bug */ - break; - } - - return convert_pixel_to_a8r8g8b8 (image, format, pixel); -} - -static force_inline void -convert_and_store_pixel (bits_image_t * image, - uint8_t * dest, - int offset, - pixman_format_code_t format, - uint32_t pixel) -{ - uint32_t converted = convert_pixel_from_a8r8g8b8 ( - (pixman_image_t *)image, format, pixel); - - switch (PIXMAN_FORMAT_BPP (format)) - { - case 1: - STORE_1 (image, dest, offset, converted & 0x01); - break; - - case 4: - STORE_4 (image, dest, offset, converted & 0xf); - break; - - case 8: - WRITE (image, (dest + offset), converted & 0xff); - break; - - case 16: - WRITE (image, ((uint16_t *)dest + offset), converted & 0xffff); - break; - - case 24: - STORE_24 (image, dest, offset, converted); - break; - - case 32: - WRITE (image, ((uint32_t *)dest + offset), converted); - break; - - default: - *dest = 0x0; - break; - } -} - -#define MAKE_ACCESSORS(format) \ - static void \ - fetch_scanline_ ## format (bits_image_t *image, \ - int x, \ - int y, \ - int width, \ - uint32_t * buffer, \ - const uint32_t *mask) \ - { \ - uint8_t *bits = \ - (uint8_t *)(image->bits + y * image->rowstride); \ - int i; \ - \ - for (i = 0; i < width; ++i) \ - { \ - *buffer++ = \ - fetch_and_convert_pixel (image, bits, x + i, PIXMAN_ ## format); \ - } \ - } \ - \ - static void \ - store_scanline_ ## format (bits_image_t * image, \ - int x, \ - int y, \ - int width, \ - const uint32_t *values) \ - { \ - uint8_t *dest = \ - (uint8_t *)(image->bits + y * image->rowstride); \ - int i; \ - \ - for (i = 0; i < width; ++i) \ - { \ - convert_and_store_pixel ( \ - image, dest, i + x, PIXMAN_ ## format, values[i]); \ - } \ - } \ - \ - static uint32_t \ - fetch_pixel_ ## format (bits_image_t *image, \ - int offset, \ - int line) \ - { \ - uint8_t *bits = \ - (uint8_t *)(image->bits + line * image->rowstride); \ - \ - return fetch_and_convert_pixel ( \ - image, bits, offset, PIXMAN_ ## format); \ - } \ - \ - static const void *const __dummy__ ## format - -MAKE_ACCESSORS(a8r8g8b8); -MAKE_ACCESSORS(x8r8g8b8); -MAKE_ACCESSORS(a8b8g8r8); -MAKE_ACCESSORS(x8b8g8r8); -MAKE_ACCESSORS(x14r6g6b6); -MAKE_ACCESSORS(b8g8r8a8); -MAKE_ACCESSORS(b8g8r8x8); -MAKE_ACCESSORS(r8g8b8x8); -MAKE_ACCESSORS(r8g8b8a8); -MAKE_ACCESSORS(r8g8b8); -MAKE_ACCESSORS(b8g8r8); -MAKE_ACCESSORS(r5g6b5); -MAKE_ACCESSORS(b5g6r5); -MAKE_ACCESSORS(a1r5g5b5); -MAKE_ACCESSORS(x1r5g5b5); -MAKE_ACCESSORS(a1b5g5r5); -MAKE_ACCESSORS(x1b5g5r5); -MAKE_ACCESSORS(a4r4g4b4); -MAKE_ACCESSORS(x4r4g4b4); -MAKE_ACCESSORS(a4b4g4r4); -MAKE_ACCESSORS(x4b4g4r4); -MAKE_ACCESSORS(a8); -MAKE_ACCESSORS(c8); -MAKE_ACCESSORS(g8); -MAKE_ACCESSORS(r3g3b2); -MAKE_ACCESSORS(b2g3r3); -MAKE_ACCESSORS(a2r2g2b2); -MAKE_ACCESSORS(a2b2g2r2); -MAKE_ACCESSORS(x4a4); -MAKE_ACCESSORS(a4); -MAKE_ACCESSORS(g4); -MAKE_ACCESSORS(c4); -MAKE_ACCESSORS(r1g2b1); -MAKE_ACCESSORS(b1g2r1); -MAKE_ACCESSORS(a1r1g1b1); -MAKE_ACCESSORS(a1b1g1r1); -MAKE_ACCESSORS(a1); -MAKE_ACCESSORS(g1); - -/********************************** Fetch ************************************/ -/* Table mapping sRGB-encoded 8 bit numbers to linearly encoded - * floating point numbers. We assume that single precision - * floating point follows the IEEE 754 format. - */ -static const uint32_t to_linear_u[256] = -{ - 0x00000000, 0x399f22b4, 0x3a1f22b4, 0x3a6eb40e, 0x3a9f22b4, 0x3ac6eb61, - 0x3aeeb40e, 0x3b0b3e5d, 0x3b1f22b4, 0x3b33070b, 0x3b46eb61, 0x3b5b518a, - 0x3b70f18a, 0x3b83e1c5, 0x3b8fe614, 0x3b9c87fb, 0x3ba9c9b5, 0x3bb7ad6d, - 0x3bc63547, 0x3bd5635f, 0x3be539bd, 0x3bf5ba70, 0x3c0373b5, 0x3c0c6152, - 0x3c15a703, 0x3c1f45bc, 0x3c293e68, 0x3c3391f4, 0x3c3e4149, 0x3c494d43, - 0x3c54b6c7, 0x3c607eb1, 0x3c6ca5df, 0x3c792d22, 0x3c830aa8, 0x3c89af9e, - 0x3c9085db, 0x3c978dc5, 0x3c9ec7c0, 0x3ca63432, 0x3cadd37d, 0x3cb5a601, - 0x3cbdac20, 0x3cc5e639, 0x3cce54ab, 0x3cd6f7d2, 0x3cdfd00e, 0x3ce8ddb9, - 0x3cf2212c, 0x3cfb9ac1, 0x3d02a569, 0x3d0798dc, 0x3d0ca7e4, 0x3d11d2ae, - 0x3d171963, 0x3d1c7c2e, 0x3d21fb3a, 0x3d2796af, 0x3d2d4ebb, 0x3d332380, - 0x3d39152b, 0x3d3f23e3, 0x3d454fd0, 0x3d4b991c, 0x3d51ffeb, 0x3d588466, - 0x3d5f26b7, 0x3d65e6fe, 0x3d6cc564, 0x3d73c210, 0x3d7add25, 0x3d810b65, - 0x3d84b793, 0x3d88732e, 0x3d8c3e48, 0x3d9018f4, 0x3d940343, 0x3d97fd48, - 0x3d9c0714, 0x3da020b9, 0x3da44a48, 0x3da883d6, 0x3daccd70, 0x3db12728, - 0x3db59110, 0x3dba0b38, 0x3dbe95b2, 0x3dc3308f, 0x3dc7dbe0, 0x3dcc97b4, - 0x3dd1641c, 0x3dd6412a, 0x3ddb2eec, 0x3de02d75, 0x3de53cd3, 0x3dea5d16, - 0x3def8e52, 0x3df4d091, 0x3dfa23e5, 0x3dff885e, 0x3e027f06, 0x3e05427f, - 0x3e080ea2, 0x3e0ae376, 0x3e0dc104, 0x3e10a752, 0x3e139669, 0x3e168e50, - 0x3e198f0e, 0x3e1c98ab, 0x3e1fab2e, 0x3e22c6a0, 0x3e25eb08, 0x3e29186a, - 0x3e2c4ed0, 0x3e2f8e42, 0x3e32d6c4, 0x3e362861, 0x3e39831e, 0x3e3ce702, - 0x3e405416, 0x3e43ca5e, 0x3e4749e4, 0x3e4ad2ae, 0x3e4e64c2, 0x3e520027, - 0x3e55a4e6, 0x3e595303, 0x3e5d0a8a, 0x3e60cb7c, 0x3e6495e0, 0x3e6869bf, - 0x3e6c4720, 0x3e702e08, 0x3e741e7f, 0x3e78188c, 0x3e7c1c34, 0x3e8014c0, - 0x3e822039, 0x3e84308b, 0x3e8645b8, 0x3e885fc3, 0x3e8a7eb0, 0x3e8ca281, - 0x3e8ecb3a, 0x3e90f8df, 0x3e932b72, 0x3e9562f6, 0x3e979f6f, 0x3e99e0e0, - 0x3e9c274e, 0x3e9e72b8, 0x3ea0c322, 0x3ea31892, 0x3ea57308, 0x3ea7d28a, - 0x3eaa3718, 0x3eaca0b7, 0x3eaf0f69, 0x3eb18332, 0x3eb3fc16, 0x3eb67a15, - 0x3eb8fd34, 0x3ebb8576, 0x3ebe12de, 0x3ec0a56e, 0x3ec33d2a, 0x3ec5da14, - 0x3ec87c30, 0x3ecb2380, 0x3ecdd008, 0x3ed081ca, 0x3ed338c9, 0x3ed5f508, - 0x3ed8b68a, 0x3edb7d52, 0x3ede4962, 0x3ee11abe, 0x3ee3f168, 0x3ee6cd64, - 0x3ee9aeb6, 0x3eec955d, 0x3eef815d, 0x3ef272ba, 0x3ef56976, 0x3ef86594, - 0x3efb6717, 0x3efe6e02, 0x3f00bd2b, 0x3f02460c, 0x3f03d1a5, 0x3f055ff8, - 0x3f06f105, 0x3f0884ce, 0x3f0a1b54, 0x3f0bb499, 0x3f0d509f, 0x3f0eef65, - 0x3f1090ef, 0x3f12353c, 0x3f13dc50, 0x3f15862a, 0x3f1732cc, 0x3f18e237, - 0x3f1a946d, 0x3f1c4970, 0x3f1e013f, 0x3f1fbbde, 0x3f21794c, 0x3f23398c, - 0x3f24fca0, 0x3f26c286, 0x3f288b42, 0x3f2a56d3, 0x3f2c253d, 0x3f2df680, - 0x3f2fca9d, 0x3f31a195, 0x3f337b6a, 0x3f35581e, 0x3f3737b1, 0x3f391a24, - 0x3f3aff7a, 0x3f3ce7b2, 0x3f3ed2d0, 0x3f40c0d2, 0x3f42b1bc, 0x3f44a58e, - 0x3f469c49, 0x3f4895ee, 0x3f4a9280, 0x3f4c91ff, 0x3f4e946c, 0x3f5099c8, - 0x3f52a216, 0x3f54ad55, 0x3f56bb88, 0x3f58ccae, 0x3f5ae0cb, 0x3f5cf7de, - 0x3f5f11ec, 0x3f612ef0, 0x3f634eef, 0x3f6571ea, 0x3f6797e1, 0x3f69c0d6, - 0x3f6beccb, 0x3f6e1bc0, 0x3f704db6, 0x3f7282af, 0x3f74baac, 0x3f76f5ae, - 0x3f7933b6, 0x3f7b74c6, 0x3f7db8de, 0x3f800000 -}; - -static const float * const to_linear = (const float *)to_linear_u; - -static uint8_t -to_srgb (float f) -{ - uint8_t low = 0; - uint8_t high = 255; - - while (high - low > 1) - { - uint8_t mid = (low + high) / 2; - - if (to_linear[mid] > f) - high = mid; - else - low = mid; - } - - if (to_linear[high] - f < f - to_linear[low]) - return high; - else - return low; -} - -static void -fetch_scanline_a8r8g8b8_sRGB_float (bits_image_t * image, - int x, - int y, - int width, - uint32_t * b, - const uint32_t *mask) -{ - const uint32_t *bits = image->bits + y * image->rowstride; - const uint32_t *pixel = bits + x; - const uint32_t *end = pixel + width; - argb_t *buffer = (argb_t *)b; - - while (pixel < end) - { - uint32_t p = READ (image, pixel++); - argb_t *argb = buffer; - - argb->a = pixman_unorm_to_float ((p >> 24) & 0xff, 8); - - argb->r = to_linear [(p >> 16) & 0xff]; - argb->g = to_linear [(p >> 8) & 0xff]; - argb->b = to_linear [(p >> 0) & 0xff]; - - buffer++; - } -} - -/* Expects a float buffer */ -static void -fetch_scanline_a2r10g10b10_float (bits_image_t * image, - int x, - int y, - int width, - uint32_t * b, - const uint32_t *mask) -{ - const uint32_t *bits = image->bits + y * image->rowstride; - const uint32_t *pixel = bits + x; - const uint32_t *end = pixel + width; - argb_t *buffer = (argb_t *)b; - - while (pixel < end) - { - uint32_t p = READ (image, pixel++); - uint64_t a = p >> 30; - uint64_t r = (p >> 20) & 0x3ff; - uint64_t g = (p >> 10) & 0x3ff; - uint64_t b = p & 0x3ff; - - buffer->a = pixman_unorm_to_float (a, 2); - buffer->r = pixman_unorm_to_float (r, 10); - buffer->g = pixman_unorm_to_float (g, 10); - buffer->b = pixman_unorm_to_float (b, 10); - - buffer++; - } -} - -/* Expects a float buffer */ -static void -fetch_scanline_x2r10g10b10_float (bits_image_t *image, - int x, - int y, - int width, - uint32_t * b, - const uint32_t *mask) -{ - const uint32_t *bits = image->bits + y * image->rowstride; - const uint32_t *pixel = (uint32_t *)bits + x; - const uint32_t *end = pixel + width; - argb_t *buffer = (argb_t *)b; - - while (pixel < end) - { - uint32_t p = READ (image, pixel++); - uint64_t r = (p >> 20) & 0x3ff; - uint64_t g = (p >> 10) & 0x3ff; - uint64_t b = p & 0x3ff; - - buffer->a = 1.0; - buffer->r = pixman_unorm_to_float (r, 10); - buffer->g = pixman_unorm_to_float (g, 10); - buffer->b = pixman_unorm_to_float (b, 10); - - buffer++; - } -} - -/* Expects a float buffer */ -static void -fetch_scanline_a2b10g10r10_float (bits_image_t *image, - int x, - int y, - int width, - uint32_t * b, - const uint32_t *mask) -{ - const uint32_t *bits = image->bits + y * image->rowstride; - const uint32_t *pixel = bits + x; - const uint32_t *end = pixel + width; - argb_t *buffer = (argb_t *)b; - - while (pixel < end) - { - uint32_t p = READ (image, pixel++); - uint64_t a = p >> 30; - uint64_t b = (p >> 20) & 0x3ff; - uint64_t g = (p >> 10) & 0x3ff; - uint64_t r = p & 0x3ff; - - buffer->a = pixman_unorm_to_float (a, 2); - buffer->r = pixman_unorm_to_float (r, 10); - buffer->g = pixman_unorm_to_float (g, 10); - buffer->b = pixman_unorm_to_float (b, 10); - - buffer++; - } -} - -/* Expects a float buffer */ -static void -fetch_scanline_x2b10g10r10_float (bits_image_t *image, - int x, - int y, - int width, - uint32_t * b, - const uint32_t *mask) -{ - const uint32_t *bits = image->bits + y * image->rowstride; - const uint32_t *pixel = (uint32_t *)bits + x; - const uint32_t *end = pixel + width; - argb_t *buffer = (argb_t *)b; - - while (pixel < end) - { - uint32_t p = READ (image, pixel++); - uint64_t b = (p >> 20) & 0x3ff; - uint64_t g = (p >> 10) & 0x3ff; - uint64_t r = p & 0x3ff; - - buffer->a = 1.0; - buffer->r = pixman_unorm_to_float (r, 10); - buffer->g = pixman_unorm_to_float (g, 10); - buffer->b = pixman_unorm_to_float (b, 10); - - buffer++; - } -} - -static void -fetch_scanline_yuy2 (bits_image_t *image, - int x, - int line, - int width, - uint32_t * buffer, - const uint32_t *mask) -{ - const uint32_t *bits = image->bits + image->rowstride * line; - int i; - - for (i = 0; i < width; i++) - { - int16_t y, u, v; - int32_t r, g, b; - - y = ((uint8_t *) bits)[(x + i) << 1] - 16; - u = ((uint8_t *) bits)[(((x + i) << 1) & - 4) + 1] - 128; - v = ((uint8_t *) bits)[(((x + i) << 1) & - 4) + 3] - 128; - - /* R = 1.164(Y - 16) + 1.596(V - 128) */ - r = 0x012b27 * y + 0x019a2e * v; - /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */ - g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u; - /* B = 1.164(Y - 16) + 2.018(U - 128) */ - b = 0x012b27 * y + 0x0206a2 * u; - - *buffer++ = 0xff000000 | - (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) | - (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) | - (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0); - } -} - -static void -fetch_scanline_yv12 (bits_image_t *image, - int x, - int line, - int width, - uint32_t * buffer, - const uint32_t *mask) -{ - YV12_SETUP (image); - uint8_t *y_line = YV12_Y (line); - uint8_t *u_line = YV12_U (line); - uint8_t *v_line = YV12_V (line); - int i; - - for (i = 0; i < width; i++) - { - int16_t y, u, v; - int32_t r, g, b; - - y = y_line[x + i] - 16; - u = u_line[(x + i) >> 1] - 128; - v = v_line[(x + i) >> 1] - 128; - - /* R = 1.164(Y - 16) + 1.596(V - 128) */ - r = 0x012b27 * y + 0x019a2e * v; - /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */ - g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u; - /* B = 1.164(Y - 16) + 2.018(U - 128) */ - b = 0x012b27 * y + 0x0206a2 * u; - - *buffer++ = 0xff000000 | - (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) | - (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) | - (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0); - } -} - -/**************************** Pixel wise fetching *****************************/ - -static argb_t -fetch_pixel_x2r10g10b10_float (bits_image_t *image, - int offset, - int line) -{ - uint32_t *bits = image->bits + line * image->rowstride; - uint32_t p = READ (image, bits + offset); - uint64_t r = (p >> 20) & 0x3ff; - uint64_t g = (p >> 10) & 0x3ff; - uint64_t b = p & 0x3ff; - argb_t argb; - - argb.a = 1.0; - argb.r = pixman_unorm_to_float (r, 10); - argb.g = pixman_unorm_to_float (g, 10); - argb.b = pixman_unorm_to_float (b, 10); - - return argb; -} - -static argb_t -fetch_pixel_a2r10g10b10_float (bits_image_t *image, - int offset, - int line) -{ - uint32_t *bits = image->bits + line * image->rowstride; - uint32_t p = READ (image, bits + offset); - uint64_t a = p >> 30; - uint64_t r = (p >> 20) & 0x3ff; - uint64_t g = (p >> 10) & 0x3ff; - uint64_t b = p & 0x3ff; - argb_t argb; - - argb.a = pixman_unorm_to_float (a, 2); - argb.r = pixman_unorm_to_float (r, 10); - argb.g = pixman_unorm_to_float (g, 10); - argb.b = pixman_unorm_to_float (b, 10); - - return argb; -} - -static argb_t -fetch_pixel_a2b10g10r10_float (bits_image_t *image, - int offset, - int line) -{ - uint32_t *bits = image->bits + line * image->rowstride; - uint32_t p = READ (image, bits + offset); - uint64_t a = p >> 30; - uint64_t b = (p >> 20) & 0x3ff; - uint64_t g = (p >> 10) & 0x3ff; - uint64_t r = p & 0x3ff; - argb_t argb; - - argb.a = pixman_unorm_to_float (a, 2); - argb.r = pixman_unorm_to_float (r, 10); - argb.g = pixman_unorm_to_float (g, 10); - argb.b = pixman_unorm_to_float (b, 10); - - return argb; -} - -static argb_t -fetch_pixel_x2b10g10r10_float (bits_image_t *image, - int offset, - int line) -{ - uint32_t *bits = image->bits + line * image->rowstride; - uint32_t p = READ (image, bits + offset); - uint64_t b = (p >> 20) & 0x3ff; - uint64_t g = (p >> 10) & 0x3ff; - uint64_t r = p & 0x3ff; - argb_t argb; - - argb.a = 1.0; - argb.r = pixman_unorm_to_float (r, 10); - argb.g = pixman_unorm_to_float (g, 10); - argb.b = pixman_unorm_to_float (b, 10); - - return argb; -} - -static argb_t -fetch_pixel_a8r8g8b8_sRGB_float (bits_image_t *image, - int offset, - int line) -{ - uint32_t *bits = image->bits + line * image->rowstride; - uint32_t p = READ (image, bits + offset); - argb_t argb; - - argb.a = pixman_unorm_to_float ((p >> 24) & 0xff, 8); - - argb.r = to_linear [(p >> 16) & 0xff]; - argb.g = to_linear [(p >> 8) & 0xff]; - argb.b = to_linear [(p >> 0) & 0xff]; - - return argb; -} - -static uint32_t -fetch_pixel_yuy2 (bits_image_t *image, - int offset, - int line) -{ - const uint32_t *bits = image->bits + image->rowstride * line; - - int16_t y, u, v; - int32_t r, g, b; - - y = ((uint8_t *) bits)[offset << 1] - 16; - u = ((uint8_t *) bits)[((offset << 1) & - 4) + 1] - 128; - v = ((uint8_t *) bits)[((offset << 1) & - 4) + 3] - 128; - - /* R = 1.164(Y - 16) + 1.596(V - 128) */ - r = 0x012b27 * y + 0x019a2e * v; - - /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */ - g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u; - - /* B = 1.164(Y - 16) + 2.018(U - 128) */ - b = 0x012b27 * y + 0x0206a2 * u; - - return 0xff000000 | - (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) | - (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) | - (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0); -} - -static uint32_t -fetch_pixel_yv12 (bits_image_t *image, - int offset, - int line) -{ - YV12_SETUP (image); - int16_t y = YV12_Y (line)[offset] - 16; - int16_t u = YV12_U (line)[offset >> 1] - 128; - int16_t v = YV12_V (line)[offset >> 1] - 128; - int32_t r, g, b; - - /* R = 1.164(Y - 16) + 1.596(V - 128) */ - r = 0x012b27 * y + 0x019a2e * v; - - /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */ - g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u; - - /* B = 1.164(Y - 16) + 2.018(U - 128) */ - b = 0x012b27 * y + 0x0206a2 * u; - - return 0xff000000 | - (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) | - (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) | - (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0); -} - -/*********************************** Store ************************************/ - -static void -store_scanline_a2r10g10b10_float (bits_image_t * image, - int x, - int y, - int width, - const uint32_t *v) -{ - uint32_t *bits = image->bits + image->rowstride * y; - uint32_t *pixel = bits + x; - argb_t *values = (argb_t *)v; - int i; - - for (i = 0; i < width; ++i) - { - uint16_t a, r, g, b; - - a = pixman_float_to_unorm (values[i].a, 2); - r = pixman_float_to_unorm (values[i].r, 10); - g = pixman_float_to_unorm (values[i].g, 10); - b = pixman_float_to_unorm (values[i].b, 10); - - WRITE (image, pixel++, - (a << 30) | (r << 20) | (g << 10) | b); - } -} - -static void -store_scanline_x2r10g10b10_float (bits_image_t * image, - int x, - int y, - int width, - const uint32_t *v) -{ - uint32_t *bits = image->bits + image->rowstride * y; - uint32_t *pixel = bits + x; - argb_t *values = (argb_t *)v; - int i; - - for (i = 0; i < width; ++i) - { - uint16_t r, g, b; - - r = pixman_float_to_unorm (values[i].r, 10); - g = pixman_float_to_unorm (values[i].g, 10); - b = pixman_float_to_unorm (values[i].b, 10); - - WRITE (image, pixel++, - (r << 20) | (g << 10) | b); - } -} - -static void -store_scanline_a2b10g10r10_float (bits_image_t * image, - int x, - int y, - int width, - const uint32_t *v) -{ - uint32_t *bits = image->bits + image->rowstride * y; - uint32_t *pixel = bits + x; - argb_t *values = (argb_t *)v; - int i; - - for (i = 0; i < width; ++i) - { - uint16_t a, r, g, b; - - a = pixman_float_to_unorm (values[i].a, 2); - r = pixman_float_to_unorm (values[i].r, 10); - g = pixman_float_to_unorm (values[i].g, 10); - b = pixman_float_to_unorm (values[i].b, 10); - - WRITE (image, pixel++, - (a << 30) | (b << 20) | (g << 10) | r); - } -} - -static void -store_scanline_x2b10g10r10_float (bits_image_t * image, - int x, - int y, - int width, - const uint32_t *v) -{ - uint32_t *bits = image->bits + image->rowstride * y; - uint32_t *pixel = bits + x; - argb_t *values = (argb_t *)v; - int i; - - for (i = 0; i < width; ++i) - { - uint16_t r, g, b; - - r = pixman_float_to_unorm (values[i].r, 10); - g = pixman_float_to_unorm (values[i].g, 10); - b = pixman_float_to_unorm (values[i].b, 10); - - WRITE (image, pixel++, - (b << 20) | (g << 10) | r); - } -} - -static void -store_scanline_a8r8g8b8_sRGB_float (bits_image_t * image, - int x, - int y, - int width, - const uint32_t *v) -{ - uint32_t *bits = image->bits + image->rowstride * y; - uint32_t *pixel = bits + x; - argb_t *values = (argb_t *)v; - int i; - - for (i = 0; i < width; ++i) - { - uint8_t a, r, g, b; - - a = pixman_float_to_unorm (values[i].a, 8); - r = to_srgb (values[i].r); - g = to_srgb (values[i].g); - b = to_srgb (values[i].b); - - WRITE (image, pixel++, - (a << 24) | (r << 16) | (g << 8) | b); - } -} - -/* - * Contracts a floating point image to 32bpp and then stores it using a - * regular 32-bit store proc. Despite the type, this function expects an - * argb_t buffer. - */ -static void -store_scanline_generic_float (bits_image_t * image, - int x, - int y, - int width, - const uint32_t *values) -{ - uint32_t *argb8_pixels; - - assert (image->common.type == BITS); - - argb8_pixels = pixman_malloc_ab (width, sizeof(uint32_t)); - if (!argb8_pixels) - return; - - /* Contract the scanline. We could do this in place if values weren't - * const. - */ - pixman_contract_from_float (argb8_pixels, (argb_t *)values, width); - - image->store_scanline_32 (image, x, y, width, argb8_pixels); - - free (argb8_pixels); -} - -static void -fetch_scanline_generic_float (bits_image_t * image, - int x, - int y, - int width, - uint32_t * buffer, - const uint32_t *mask) -{ - image->fetch_scanline_32 (image, x, y, width, buffer, NULL); - - pixman_expand_to_float ((argb_t *)buffer, buffer, image->format, width); -} - -/* The 32_sRGB paths should be deleted after narrow processing - * is no longer invoked for formats that are considered wide. - * (Also see fetch_pixel_generic_lossy_32) */ -static void -fetch_scanline_a8r8g8b8_32_sRGB (bits_image_t *image, - int x, - int y, - int width, - uint32_t *buffer, - const uint32_t *mask) -{ - const uint32_t *bits = image->bits + y * image->rowstride; - const uint32_t *pixel = (uint32_t *)bits + x; - const uint32_t *end = pixel + width; - uint32_t tmp; - - while (pixel < end) - { - uint8_t a, r, g, b; - - tmp = READ (image, pixel++); - - a = (tmp >> 24) & 0xff; - r = (tmp >> 16) & 0xff; - g = (tmp >> 8) & 0xff; - b = (tmp >> 0) & 0xff; - - r = to_linear[r] * 255.0f + 0.5f; - g = to_linear[g] * 255.0f + 0.5f; - b = to_linear[b] * 255.0f + 0.5f; - - *buffer++ = (a << 24) | (r << 16) | (g << 8) | (b << 0); - } -} - -static uint32_t -fetch_pixel_a8r8g8b8_32_sRGB (bits_image_t *image, - int offset, - int line) -{ - uint32_t *bits = image->bits + line * image->rowstride; - uint32_t tmp = READ (image, bits + offset); - uint8_t a, r, g, b; - - a = (tmp >> 24) & 0xff; - r = (tmp >> 16) & 0xff; - g = (tmp >> 8) & 0xff; - b = (tmp >> 0) & 0xff; - - r = to_linear[r] * 255.0f + 0.5f; - g = to_linear[g] * 255.0f + 0.5f; - b = to_linear[b] * 255.0f + 0.5f; - - return (a << 24) | (r << 16) | (g << 8) | (b << 0); -} - -static void -store_scanline_a8r8g8b8_32_sRGB (bits_image_t *image, - int x, - int y, - int width, - const uint32_t *v) -{ - uint32_t *bits = image->bits + image->rowstride * y; - uint64_t *values = (uint64_t *)v; - uint32_t *pixel = bits + x; - uint64_t tmp; - int i; - - for (i = 0; i < width; ++i) - { - uint8_t a, r, g, b; - - tmp = values[i]; - - a = (tmp >> 24) & 0xff; - r = (tmp >> 16) & 0xff; - g = (tmp >> 8) & 0xff; - b = (tmp >> 0) & 0xff; - - r = to_srgb (r * (1/255.0f)); - g = to_srgb (g * (1/255.0f)); - b = to_srgb (b * (1/255.0f)); - - WRITE (image, pixel++, a | (r << 16) | (g << 8) | (b << 0)); - } -} - -static argb_t -fetch_pixel_generic_float (bits_image_t *image, - int offset, - int line) -{ - uint32_t pixel32 = image->fetch_pixel_32 (image, offset, line); - argb_t f; - - pixman_expand_to_float (&f, &pixel32, image->format, 1); - - return f; -} - -/* - * XXX: The transformed fetch path only works at 32-bpp so far. When all - * paths have wide versions, this can be removed. - * - * WARNING: This function loses precision! - */ -static uint32_t -fetch_pixel_generic_lossy_32 (bits_image_t *image, - int offset, - int line) -{ - argb_t pixel64 = image->fetch_pixel_float (image, offset, line); - uint32_t result; - - pixman_contract_from_float (&result, &pixel64, 1); - - return result; -} - -typedef struct -{ - pixman_format_code_t format; - fetch_scanline_t fetch_scanline_32; - fetch_scanline_t fetch_scanline_float; - fetch_pixel_32_t fetch_pixel_32; - fetch_pixel_float_t fetch_pixel_float; - store_scanline_t store_scanline_32; - store_scanline_t store_scanline_float; -} format_info_t; - -#define FORMAT_INFO(format) \ - { \ - PIXMAN_ ## format, \ - fetch_scanline_ ## format, \ - fetch_scanline_generic_float, \ - fetch_pixel_ ## format, \ - fetch_pixel_generic_float, \ - store_scanline_ ## format, \ - store_scanline_generic_float \ - } - -static const format_info_t accessors[] = -{ -/* 32 bpp formats */ - FORMAT_INFO (a8r8g8b8), - FORMAT_INFO (x8r8g8b8), - FORMAT_INFO (a8b8g8r8), - FORMAT_INFO (x8b8g8r8), - FORMAT_INFO (b8g8r8a8), - FORMAT_INFO (b8g8r8x8), - FORMAT_INFO (r8g8b8a8), - FORMAT_INFO (r8g8b8x8), - FORMAT_INFO (x14r6g6b6), - -/* sRGB formats */ - { PIXMAN_a8r8g8b8_sRGB, - fetch_scanline_a8r8g8b8_32_sRGB, fetch_scanline_a8r8g8b8_sRGB_float, - fetch_pixel_a8r8g8b8_32_sRGB, fetch_pixel_a8r8g8b8_sRGB_float, - store_scanline_a8r8g8b8_32_sRGB, store_scanline_a8r8g8b8_sRGB_float, - }, - -/* 24bpp formats */ - FORMAT_INFO (r8g8b8), - FORMAT_INFO (b8g8r8), - -/* 16bpp formats */ - FORMAT_INFO (r5g6b5), - FORMAT_INFO (b5g6r5), - - FORMAT_INFO (a1r5g5b5), - FORMAT_INFO (x1r5g5b5), - FORMAT_INFO (a1b5g5r5), - FORMAT_INFO (x1b5g5r5), - FORMAT_INFO (a4r4g4b4), - FORMAT_INFO (x4r4g4b4), - FORMAT_INFO (a4b4g4r4), - FORMAT_INFO (x4b4g4r4), - -/* 8bpp formats */ - FORMAT_INFO (a8), - FORMAT_INFO (r3g3b2), - FORMAT_INFO (b2g3r3), - FORMAT_INFO (a2r2g2b2), - FORMAT_INFO (a2b2g2r2), - - FORMAT_INFO (c8), - - FORMAT_INFO (g8), - -#define fetch_scanline_x4c4 fetch_scanline_c8 -#define fetch_pixel_x4c4 fetch_pixel_c8 -#define store_scanline_x4c4 store_scanline_c8 - FORMAT_INFO (x4c4), - -#define fetch_scanline_x4g4 fetch_scanline_g8 -#define fetch_pixel_x4g4 fetch_pixel_g8 -#define store_scanline_x4g4 store_scanline_g8 - FORMAT_INFO (x4g4), - - FORMAT_INFO (x4a4), - -/* 4bpp formats */ - FORMAT_INFO (a4), - FORMAT_INFO (r1g2b1), - FORMAT_INFO (b1g2r1), - FORMAT_INFO (a1r1g1b1), - FORMAT_INFO (a1b1g1r1), - - FORMAT_INFO (c4), - - FORMAT_INFO (g4), - -/* 1bpp formats */ - FORMAT_INFO (a1), - FORMAT_INFO (g1), - -/* Wide formats */ - - { PIXMAN_a2r10g10b10, - NULL, fetch_scanline_a2r10g10b10_float, - fetch_pixel_generic_lossy_32, fetch_pixel_a2r10g10b10_float, - NULL, store_scanline_a2r10g10b10_float }, - - { PIXMAN_x2r10g10b10, - NULL, fetch_scanline_x2r10g10b10_float, - fetch_pixel_generic_lossy_32, fetch_pixel_x2r10g10b10_float, - NULL, store_scanline_x2r10g10b10_float }, - - { PIXMAN_a2b10g10r10, - NULL, fetch_scanline_a2b10g10r10_float, - fetch_pixel_generic_lossy_32, fetch_pixel_a2b10g10r10_float, - NULL, store_scanline_a2b10g10r10_float }, - - { PIXMAN_x2b10g10r10, - NULL, fetch_scanline_x2b10g10r10_float, - fetch_pixel_generic_lossy_32, fetch_pixel_x2b10g10r10_float, - NULL, store_scanline_x2b10g10r10_float }, - -/* YUV formats */ - { PIXMAN_yuy2, - fetch_scanline_yuy2, fetch_scanline_generic_float, - fetch_pixel_yuy2, fetch_pixel_generic_float, - NULL, NULL }, - - { PIXMAN_yv12, - fetch_scanline_yv12, fetch_scanline_generic_float, - fetch_pixel_yv12, fetch_pixel_generic_float, - NULL, NULL }, - - { PIXMAN_null }, -}; - -static void -setup_accessors (bits_image_t *image) -{ - const format_info_t *info = accessors; - - while (info->format != PIXMAN_null) - { - if (info->format == image->format) - { - image->fetch_scanline_32 = info->fetch_scanline_32; - image->fetch_scanline_float = info->fetch_scanline_float; - image->fetch_pixel_32 = info->fetch_pixel_32; - image->fetch_pixel_float = info->fetch_pixel_float; - image->store_scanline_32 = info->store_scanline_32; - image->store_scanline_float = info->store_scanline_float; - - return; - } - - info++; - } -} - -#ifndef PIXMAN_FB_ACCESSORS -void -_pixman_bits_image_setup_accessors_accessors (bits_image_t *image); - -void -_pixman_bits_image_setup_accessors (bits_image_t *image) -{ - if (image->read_func || image->write_func) - _pixman_bits_image_setup_accessors_accessors (image); - else - setup_accessors (image); -} - -#else - -void -_pixman_bits_image_setup_accessors_accessors (bits_image_t *image) -{ - setup_accessors (image); -} - -#endif diff --git a/source/libs/pixman/pixman-src/pixman/pixman-accessor.h b/source/libs/pixman/pixman-src/pixman/pixman-accessor.h deleted file mode 100644 index 8e0b03621b2e4d0a4287328b01a5f4a41e2f1f0d..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-accessor.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifdef PIXMAN_FB_ACCESSORS - -#define READ(img, ptr) \ - (((bits_image_t *)(img))->read_func ((ptr), sizeof(*(ptr)))) -#define WRITE(img, ptr,val) \ - (((bits_image_t *)(img))->write_func ((ptr), (val), sizeof (*(ptr)))) - -#define MEMSET_WRAPPED(img, dst, val, size) \ - do { \ - size_t _i; \ - uint8_t *_dst = (uint8_t*)(dst); \ - for(_i = 0; _i < (size_t) size; _i++) { \ - WRITE((img), _dst +_i, (val)); \ - } \ - } while (0) - -#else - -#define READ(img, ptr) (*(ptr)) -#define WRITE(img, ptr, val) (*(ptr) = (val)) -#define MEMSET_WRAPPED(img, dst, val, size) \ - memset(dst, val, size) - -#endif - diff --git a/source/libs/pixman/pixman-src/pixman/pixman-arm-asm.h b/source/libs/pixman/pixman-src/pixman/pixman-arm-asm.h deleted file mode 100644 index ee78541087377907073c02f15ac546e308c39a3f..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-arm-asm.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright © 2008 Mozilla Corporation - * Copyright © 2010 Nokia Corporation - * - * 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 Mozilla Corporation not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Mozilla Corporation makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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: Jeff Muizelaar (jeff@infidigm.net) - * - */ - -/* Supplementary macro for setting function attributes */ -.macro pixman_asm_function fname - .func fname - .global fname -#ifdef __ELF__ - .hidden fname - .type fname, %function -#endif -fname: -.endm diff --git a/source/libs/pixman/pixman-src/pixman/pixman-arm-common.h b/source/libs/pixman/pixman-src/pixman/pixman-arm-common.h deleted file mode 100644 index 9537688306e6ba2521ab19e13663f596f5cefe95..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-arm-common.h +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Copyright © 2010 Nokia Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Siarhei Siamashka (siarhei.siamashka@nokia.com) - */ - -#ifndef PIXMAN_ARM_COMMON_H -#define PIXMAN_ARM_COMMON_H - -#include "pixman-inlines.h" - -/* Define some macros which can expand into proxy functions between - * ARM assembly optimized functions and the rest of pixman fast path API. - * - * All the low level ARM assembly functions have to use ARM EABI - * calling convention and take up to 8 arguments: - * width, height, dst, dst_stride, src, src_stride, mask, mask_stride - * - * The arguments are ordered with the most important coming first (the - * first 4 arguments are passed to function in registers, the rest are - * on stack). The last arguments are optional, for example if the - * function is not using mask, then 'mask' and 'mask_stride' can be - * omitted when doing a function call. - * - * Arguments 'src' and 'mask' contain either a pointer to the top left - * pixel of the composited rectangle or a pixel color value depending - * on the function type. In the case of just a color value (solid source - * or mask), the corresponding stride argument is unused. - */ - -#define SKIP_ZERO_SRC 1 -#define SKIP_ZERO_MASK 2 - -#define PIXMAN_ARM_BIND_FAST_PATH_SRC_DST(cputype, name, \ - src_type, src_cnt, \ - dst_type, dst_cnt) \ -void \ -pixman_composite_##name##_asm_##cputype (int32_t w, \ - int32_t h, \ - dst_type *dst, \ - int32_t dst_stride, \ - src_type *src, \ - int32_t src_stride); \ - \ -static void \ -cputype##_composite_##name (pixman_implementation_t *imp, \ - pixman_composite_info_t *info) \ -{ \ - PIXMAN_COMPOSITE_ARGS (info); \ - dst_type *dst_line; \ - src_type *src_line; \ - int32_t dst_stride, src_stride; \ - \ - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \ - src_stride, src_line, src_cnt); \ - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \ - dst_stride, dst_line, dst_cnt); \ - \ - pixman_composite_##name##_asm_##cputype (width, height, \ - dst_line, dst_stride, \ - src_line, src_stride); \ -} - -#define PIXMAN_ARM_BIND_FAST_PATH_N_DST(flags, cputype, name, \ - dst_type, dst_cnt) \ -void \ -pixman_composite_##name##_asm_##cputype (int32_t w, \ - int32_t h, \ - dst_type *dst, \ - int32_t dst_stride, \ - uint32_t src); \ - \ -static void \ -cputype##_composite_##name (pixman_implementation_t *imp, \ - pixman_composite_info_t *info) \ -{ \ - PIXMAN_COMPOSITE_ARGS (info); \ - dst_type *dst_line; \ - int32_t dst_stride; \ - uint32_t src; \ - \ - src = _pixman_image_get_solid ( \ - imp, src_image, dest_image->bits.format); \ - \ - if ((flags & SKIP_ZERO_SRC) && src == 0) \ - return; \ - \ - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \ - dst_stride, dst_line, dst_cnt); \ - \ - pixman_composite_##name##_asm_##cputype (width, height, \ - dst_line, dst_stride, \ - src); \ -} - -#define PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST(flags, cputype, name, \ - mask_type, mask_cnt, \ - dst_type, dst_cnt) \ -void \ -pixman_composite_##name##_asm_##cputype (int32_t w, \ - int32_t h, \ - dst_type *dst, \ - int32_t dst_stride, \ - uint32_t src, \ - int32_t unused, \ - mask_type *mask, \ - int32_t mask_stride); \ - \ -static void \ -cputype##_composite_##name (pixman_implementation_t *imp, \ - pixman_composite_info_t *info) \ -{ \ - PIXMAN_COMPOSITE_ARGS (info); \ - dst_type *dst_line; \ - mask_type *mask_line; \ - int32_t dst_stride, mask_stride; \ - uint32_t src; \ - \ - src = _pixman_image_get_solid ( \ - imp, src_image, dest_image->bits.format); \ - \ - if ((flags & SKIP_ZERO_SRC) && src == 0) \ - return; \ - \ - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \ - dst_stride, dst_line, dst_cnt); \ - PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type, \ - mask_stride, mask_line, mask_cnt); \ - \ - pixman_composite_##name##_asm_##cputype (width, height, \ - dst_line, dst_stride, \ - src, 0, \ - mask_line, mask_stride); \ -} - -#define PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST(flags, cputype, name, \ - src_type, src_cnt, \ - dst_type, dst_cnt) \ -void \ -pixman_composite_##name##_asm_##cputype (int32_t w, \ - int32_t h, \ - dst_type *dst, \ - int32_t dst_stride, \ - src_type *src, \ - int32_t src_stride, \ - uint32_t mask); \ - \ -static void \ -cputype##_composite_##name (pixman_implementation_t *imp, \ - pixman_composite_info_t *info) \ -{ \ - PIXMAN_COMPOSITE_ARGS (info); \ - dst_type *dst_line; \ - src_type *src_line; \ - int32_t dst_stride, src_stride; \ - uint32_t mask; \ - \ - mask = _pixman_image_get_solid ( \ - imp, mask_image, dest_image->bits.format); \ - \ - if ((flags & SKIP_ZERO_MASK) && mask == 0) \ - return; \ - \ - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \ - dst_stride, dst_line, dst_cnt); \ - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \ - src_stride, src_line, src_cnt); \ - \ - pixman_composite_##name##_asm_##cputype (width, height, \ - dst_line, dst_stride, \ - src_line, src_stride, \ - mask); \ -} - -#define PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST(cputype, name, \ - src_type, src_cnt, \ - mask_type, mask_cnt, \ - dst_type, dst_cnt) \ -void \ -pixman_composite_##name##_asm_##cputype (int32_t w, \ - int32_t h, \ - dst_type *dst, \ - int32_t dst_stride, \ - src_type *src, \ - int32_t src_stride, \ - mask_type *mask, \ - int32_t mask_stride); \ - \ -static void \ -cputype##_composite_##name (pixman_implementation_t *imp, \ - pixman_composite_info_t *info) \ -{ \ - PIXMAN_COMPOSITE_ARGS (info); \ - dst_type *dst_line; \ - src_type *src_line; \ - mask_type *mask_line; \ - int32_t dst_stride, src_stride, mask_stride; \ - \ - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \ - dst_stride, dst_line, dst_cnt); \ - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \ - src_stride, src_line, src_cnt); \ - PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type, \ - mask_stride, mask_line, mask_cnt); \ - \ - pixman_composite_##name##_asm_##cputype (width, height, \ - dst_line, dst_stride, \ - src_line, src_stride, \ - mask_line, mask_stride); \ -} - -#define PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST(cputype, name, op, \ - src_type, dst_type) \ -void \ -pixman_scaled_nearest_scanline_##name##_##op##_asm_##cputype ( \ - int32_t w, \ - dst_type * dst, \ - const src_type * src, \ - pixman_fixed_t vx, \ - pixman_fixed_t unit_x, \ - pixman_fixed_t max_vx); \ - \ -static force_inline void \ -scaled_nearest_scanline_##cputype##_##name##_##op (dst_type * pd, \ - const src_type * ps, \ - int32_t w, \ - pixman_fixed_t vx, \ - pixman_fixed_t unit_x, \ - pixman_fixed_t max_vx, \ - pixman_bool_t zero_src) \ -{ \ - pixman_scaled_nearest_scanline_##name##_##op##_asm_##cputype (w, pd, ps, \ - vx, unit_x, \ - max_vx); \ -} \ - \ -FAST_NEAREST_MAINLOOP (cputype##_##name##_cover_##op, \ - scaled_nearest_scanline_##cputype##_##name##_##op, \ - src_type, dst_type, COVER) \ -FAST_NEAREST_MAINLOOP (cputype##_##name##_none_##op, \ - scaled_nearest_scanline_##cputype##_##name##_##op, \ - src_type, dst_type, NONE) \ -FAST_NEAREST_MAINLOOP (cputype##_##name##_pad_##op, \ - scaled_nearest_scanline_##cputype##_##name##_##op, \ - src_type, dst_type, PAD) \ -FAST_NEAREST_MAINLOOP (cputype##_##name##_normal_##op, \ - scaled_nearest_scanline_##cputype##_##name##_##op, \ - src_type, dst_type, NORMAL) - -#define PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_A8_DST(flags, cputype, name, op, \ - src_type, dst_type) \ -void \ -pixman_scaled_nearest_scanline_##name##_##op##_asm_##cputype ( \ - int32_t w, \ - dst_type * dst, \ - const src_type * src, \ - pixman_fixed_t vx, \ - pixman_fixed_t unit_x, \ - pixman_fixed_t max_vx, \ - const uint8_t * mask); \ - \ -static force_inline void \ -scaled_nearest_scanline_##cputype##_##name##_##op (const uint8_t * mask, \ - dst_type * pd, \ - const src_type * ps, \ - int32_t w, \ - pixman_fixed_t vx, \ - pixman_fixed_t unit_x, \ - pixman_fixed_t max_vx, \ - pixman_bool_t zero_src) \ -{ \ - if ((flags & SKIP_ZERO_SRC) && zero_src) \ - return; \ - pixman_scaled_nearest_scanline_##name##_##op##_asm_##cputype (w, pd, ps, \ - vx, unit_x, \ - max_vx, \ - mask); \ -} \ - \ -FAST_NEAREST_MAINLOOP_COMMON (cputype##_##name##_cover_##op, \ - scaled_nearest_scanline_##cputype##_##name##_##op,\ - src_type, uint8_t, dst_type, COVER, TRUE, FALSE)\ -FAST_NEAREST_MAINLOOP_COMMON (cputype##_##name##_none_##op, \ - scaled_nearest_scanline_##cputype##_##name##_##op,\ - src_type, uint8_t, dst_type, NONE, TRUE, FALSE) \ -FAST_NEAREST_MAINLOOP_COMMON (cputype##_##name##_pad_##op, \ - scaled_nearest_scanline_##cputype##_##name##_##op,\ - src_type, uint8_t, dst_type, PAD, TRUE, FALSE) \ -FAST_NEAREST_MAINLOOP_COMMON (cputype##_##name##_normal_##op, \ - scaled_nearest_scanline_##cputype##_##name##_##op,\ - src_type, uint8_t, dst_type, NORMAL, TRUE, FALSE) - -/* Provide entries for the fast path table */ -#define PIXMAN_ARM_SIMPLE_NEAREST_A8_MASK_FAST_PATH(op,s,d,func) \ - SIMPLE_NEAREST_A8_MASK_FAST_PATH (op,s,d,func), \ - SIMPLE_NEAREST_A8_MASK_FAST_PATH_NORMAL (op,s,d,func) - -/*****************************************************************************/ - -#define PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_DST(flags, cputype, name, op, \ - src_type, dst_type) \ -void \ -pixman_scaled_bilinear_scanline_##name##_##op##_asm_##cputype ( \ - dst_type * dst, \ - const src_type * top, \ - const src_type * bottom, \ - int wt, \ - int wb, \ - pixman_fixed_t x, \ - pixman_fixed_t ux, \ - int width); \ - \ -static force_inline void \ -scaled_bilinear_scanline_##cputype##_##name##_##op ( \ - dst_type * dst, \ - const uint32_t * mask, \ - const src_type * src_top, \ - const src_type * src_bottom, \ - int32_t w, \ - int wt, \ - int wb, \ - pixman_fixed_t vx, \ - pixman_fixed_t unit_x, \ - pixman_fixed_t max_vx, \ - pixman_bool_t zero_src) \ -{ \ - if ((flags & SKIP_ZERO_SRC) && zero_src) \ - return; \ - pixman_scaled_bilinear_scanline_##name##_##op##_asm_##cputype ( \ - dst, src_top, src_bottom, wt, wb, vx, unit_x, w); \ -} \ - \ -FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_cover_##op, \ - scaled_bilinear_scanline_##cputype##_##name##_##op, \ - src_type, uint32_t, dst_type, COVER, FLAG_NONE) \ -FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_none_##op, \ - scaled_bilinear_scanline_##cputype##_##name##_##op, \ - src_type, uint32_t, dst_type, NONE, FLAG_NONE) \ -FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_pad_##op, \ - scaled_bilinear_scanline_##cputype##_##name##_##op, \ - src_type, uint32_t, dst_type, PAD, FLAG_NONE) \ -FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_normal_##op, \ - scaled_bilinear_scanline_##cputype##_##name##_##op, \ - src_type, uint32_t, dst_type, NORMAL, \ - FLAG_NONE) - - -#define PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_A8_DST(flags, cputype, name, op, \ - src_type, dst_type) \ -void \ -pixman_scaled_bilinear_scanline_##name##_##op##_asm_##cputype ( \ - dst_type * dst, \ - const uint8_t * mask, \ - const src_type * top, \ - const src_type * bottom, \ - int wt, \ - int wb, \ - pixman_fixed_t x, \ - pixman_fixed_t ux, \ - int width); \ - \ -static force_inline void \ -scaled_bilinear_scanline_##cputype##_##name##_##op ( \ - dst_type * dst, \ - const uint8_t * mask, \ - const src_type * src_top, \ - const src_type * src_bottom, \ - int32_t w, \ - int wt, \ - int wb, \ - pixman_fixed_t vx, \ - pixman_fixed_t unit_x, \ - pixman_fixed_t max_vx, \ - pixman_bool_t zero_src) \ -{ \ - if ((flags & SKIP_ZERO_SRC) && zero_src) \ - return; \ - pixman_scaled_bilinear_scanline_##name##_##op##_asm_##cputype ( \ - dst, mask, src_top, src_bottom, wt, wb, vx, unit_x, w); \ -} \ - \ -FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_cover_##op, \ - scaled_bilinear_scanline_##cputype##_##name##_##op, \ - src_type, uint8_t, dst_type, COVER, \ - FLAG_HAVE_NON_SOLID_MASK) \ -FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_none_##op, \ - scaled_bilinear_scanline_##cputype##_##name##_##op, \ - src_type, uint8_t, dst_type, NONE, \ - FLAG_HAVE_NON_SOLID_MASK) \ -FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_pad_##op, \ - scaled_bilinear_scanline_##cputype##_##name##_##op, \ - src_type, uint8_t, dst_type, PAD, \ - FLAG_HAVE_NON_SOLID_MASK) \ -FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_normal_##op, \ - scaled_bilinear_scanline_##cputype##_##name##_##op, \ - src_type, uint8_t, dst_type, NORMAL, \ - FLAG_HAVE_NON_SOLID_MASK) - - -#endif diff --git a/source/libs/pixman/pixman-src/pixman/pixman-arm-neon-asm-bilinear.S b/source/libs/pixman/pixman-src/pixman/pixman-arm-neon-asm-bilinear.S deleted file mode 100644 index 0fd92d61c58204048d5753b0566ae5aa1436f08c..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-arm-neon-asm-bilinear.S +++ /dev/null @@ -1,1358 +0,0 @@ -/* - * Copyright © 2011 SCore Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Siarhei Siamashka (siarhei.siamashka@nokia.com) - * Author: Taekyun Kim (tkq.kim@samsung.com) - */ - -/* - * This file contains scaled bilinear scanline functions implemented - * using older siarhei's bilinear macro template. - * - * << General scanline function procedures >> - * 1. bilinear interpolate source pixels - * 2. load mask pixels - * 3. load destination pixels - * 4. duplicate mask to fill whole register - * 5. interleave source & destination pixels - * 6. apply mask to source pixels - * 7. combine source & destination pixels - * 8, Deinterleave final result - * 9. store destination pixels - * - * All registers with single number (i.e. src0, tmp0) are 64-bits registers. - * Registers with double numbers(src01, dst01) are 128-bits registers. - * All temp registers can be used freely outside the code block. - * Assume that symbol(register .req) OUT and MASK are defined at caller of these macro blocks. - * - * Remarks - * There can be lots of pipeline stalls inside code block and between code blocks. - * Further optimizations will be done by new macro templates using head/tail_head/tail scheme. - */ - -/* Prevent the stack from becoming executable for no reason... */ -#if defined(__linux__) && defined (__ELF__) -.section .note.GNU-stack,"",%progbits -#endif - -.text -.fpu neon -.arch armv7a -.object_arch armv4 -.eabi_attribute 10, 0 -.eabi_attribute 12, 0 -.arm -.altmacro -.p2align 2 - -#include "pixman-private.h" -#include "pixman-arm-asm.h" -#include "pixman-arm-neon-asm.h" - -/* - * Bilinear macros from pixman-arm-neon-asm.S - */ - -/* - * Bilinear scaling support code which tries to provide pixel fetching, color - * format conversion, and interpolation as separate macros which can be used - * as the basic building blocks for constructing bilinear scanline functions. - */ - -.macro bilinear_load_8888 reg1, reg2, tmp - mov TMP1, X, asr #16 - add X, X, UX - add TMP1, TOP, TMP1, asl #2 - vld1.32 {reg1}, [TMP1], STRIDE - vld1.32 {reg2}, [TMP1] -.endm - -.macro bilinear_load_0565 reg1, reg2, tmp - mov TMP1, X, asr #16 - add X, X, UX - add TMP1, TOP, TMP1, asl #1 - vld1.32 {reg2[0]}, [TMP1], STRIDE - vld1.32 {reg2[1]}, [TMP1] - convert_four_0565_to_x888_packed reg2, reg1, reg2, tmp -.endm - -.macro bilinear_load_and_vertical_interpolate_two_8888 \ - acc1, acc2, reg1, reg2, reg3, reg4, tmp1, tmp2 - - bilinear_load_8888 reg1, reg2, tmp1 - vmull.u8 acc1, reg1, d28 - vmlal.u8 acc1, reg2, d29 - bilinear_load_8888 reg3, reg4, tmp2 - vmull.u8 acc2, reg3, d28 - vmlal.u8 acc2, reg4, d29 -.endm - -.macro bilinear_load_and_vertical_interpolate_four_8888 \ - xacc1, xacc2, xreg1, xreg2, xreg3, xreg4, xacc2lo, xacc2hi \ - yacc1, yacc2, yreg1, yreg2, yreg3, yreg4, yacc2lo, yacc2hi - - bilinear_load_and_vertical_interpolate_two_8888 \ - xacc1, xacc2, xreg1, xreg2, xreg3, xreg4, xacc2lo, xacc2hi - bilinear_load_and_vertical_interpolate_two_8888 \ - yacc1, yacc2, yreg1, yreg2, yreg3, yreg4, yacc2lo, yacc2hi -.endm - -.macro bilinear_load_and_vertical_interpolate_two_0565 \ - acc1, acc2, reg1, reg2, reg3, reg4, acc2lo, acc2hi - - mov TMP1, X, asr #16 - add X, X, UX - add TMP1, TOP, TMP1, asl #1 - mov TMP2, X, asr #16 - add X, X, UX - add TMP2, TOP, TMP2, asl #1 - vld1.32 {acc2lo[0]}, [TMP1], STRIDE - vld1.32 {acc2hi[0]}, [TMP2], STRIDE - vld1.32 {acc2lo[1]}, [TMP1] - vld1.32 {acc2hi[1]}, [TMP2] - convert_0565_to_x888 acc2, reg3, reg2, reg1 - vzip.u8 reg1, reg3 - vzip.u8 reg2, reg4 - vzip.u8 reg3, reg4 - vzip.u8 reg1, reg2 - vmull.u8 acc1, reg1, d28 - vmlal.u8 acc1, reg2, d29 - vmull.u8 acc2, reg3, d28 - vmlal.u8 acc2, reg4, d29 -.endm - -.macro bilinear_load_and_vertical_interpolate_four_0565 \ - xacc1, xacc2, xreg1, xreg2, xreg3, xreg4, xacc2lo, xacc2hi \ - yacc1, yacc2, yreg1, yreg2, yreg3, yreg4, yacc2lo, yacc2hi - - mov TMP1, X, asr #16 - add X, X, UX - add TMP1, TOP, TMP1, asl #1 - mov TMP2, X, asr #16 - add X, X, UX - add TMP2, TOP, TMP2, asl #1 - vld1.32 {xacc2lo[0]}, [TMP1], STRIDE - vld1.32 {xacc2hi[0]}, [TMP2], STRIDE - vld1.32 {xacc2lo[1]}, [TMP1] - vld1.32 {xacc2hi[1]}, [TMP2] - convert_0565_to_x888 xacc2, xreg3, xreg2, xreg1 - mov TMP1, X, asr #16 - add X, X, UX - add TMP1, TOP, TMP1, asl #1 - mov TMP2, X, asr #16 - add X, X, UX - add TMP2, TOP, TMP2, asl #1 - vld1.32 {yacc2lo[0]}, [TMP1], STRIDE - vzip.u8 xreg1, xreg3 - vld1.32 {yacc2hi[0]}, [TMP2], STRIDE - vzip.u8 xreg2, xreg4 - vld1.32 {yacc2lo[1]}, [TMP1] - vzip.u8 xreg3, xreg4 - vld1.32 {yacc2hi[1]}, [TMP2] - vzip.u8 xreg1, xreg2 - convert_0565_to_x888 yacc2, yreg3, yreg2, yreg1 - vmull.u8 xacc1, xreg1, d28 - vzip.u8 yreg1, yreg3 - vmlal.u8 xacc1, xreg2, d29 - vzip.u8 yreg2, yreg4 - vmull.u8 xacc2, xreg3, d28 - vzip.u8 yreg3, yreg4 - vmlal.u8 xacc2, xreg4, d29 - vzip.u8 yreg1, yreg2 - vmull.u8 yacc1, yreg1, d28 - vmlal.u8 yacc1, yreg2, d29 - vmull.u8 yacc2, yreg3, d28 - vmlal.u8 yacc2, yreg4, d29 -.endm - -.macro bilinear_store_8888 numpix, tmp1, tmp2 -.if numpix == 4 - vst1.32 {d0, d1}, [OUT]! -.elseif numpix == 2 - vst1.32 {d0}, [OUT]! -.elseif numpix == 1 - vst1.32 {d0[0]}, [OUT, :32]! -.else - .error bilinear_store_8888 numpix is unsupported -.endif -.endm - -.macro bilinear_store_0565 numpix, tmp1, tmp2 - vuzp.u8 d0, d1 - vuzp.u8 d2, d3 - vuzp.u8 d1, d3 - vuzp.u8 d0, d2 - convert_8888_to_0565 d2, d1, d0, q1, tmp1, tmp2 -.if numpix == 4 - vst1.16 {d2}, [OUT]! -.elseif numpix == 2 - vst1.32 {d2[0]}, [OUT]! -.elseif numpix == 1 - vst1.16 {d2[0]}, [OUT]! -.else - .error bilinear_store_0565 numpix is unsupported -.endif -.endm - - -/* - * Macros for loading mask pixels into register 'mask'. - * vdup must be done in somewhere else. - */ -.macro bilinear_load_mask_x numpix, mask -.endm - -.macro bilinear_load_mask_8 numpix, mask -.if numpix == 4 - vld1.32 {mask[0]}, [MASK]! -.elseif numpix == 2 - vld1.16 {mask[0]}, [MASK]! -.elseif numpix == 1 - vld1.8 {mask[0]}, [MASK]! -.else - .error bilinear_load_mask_8 numpix is unsupported -.endif - pld [MASK, #prefetch_offset] -.endm - -.macro bilinear_load_mask mask_fmt, numpix, mask - bilinear_load_mask_&mask_fmt numpix, mask -.endm - - -/* - * Macros for loading destination pixels into register 'dst0' and 'dst1'. - * Interleave should be done somewhere else. - */ -.macro bilinear_load_dst_0565_src numpix, dst0, dst1, dst01 -.endm - -.macro bilinear_load_dst_8888_src numpix, dst0, dst1, dst01 -.endm - -.macro bilinear_load_dst_8888 numpix, dst0, dst1, dst01 -.if numpix == 4 - vld1.32 {dst0, dst1}, [OUT] -.elseif numpix == 2 - vld1.32 {dst0}, [OUT] -.elseif numpix == 1 - vld1.32 {dst0[0]}, [OUT] -.else - .error bilinear_load_dst_8888 numpix is unsupported -.endif - pld [OUT, #(prefetch_offset * 4)] -.endm - -.macro bilinear_load_dst_8888_over numpix, dst0, dst1, dst01 - bilinear_load_dst_8888 numpix, dst0, dst1, dst01 -.endm - -.macro bilinear_load_dst_8888_add numpix, dst0, dst1, dst01 - bilinear_load_dst_8888 numpix, dst0, dst1, dst01 -.endm - -.macro bilinear_load_dst dst_fmt, op, numpix, dst0, dst1, dst01 - bilinear_load_dst_&dst_fmt&_&op numpix, dst0, dst1, dst01 -.endm - -/* - * Macros for duplicating partially loaded mask to fill entire register. - * We will apply mask to interleaved source pixels, that is - * (r0, r1, r2, r3, g0, g1, g2, g3) x (m0, m1, m2, m3, m0, m1, m2, m3) - * (b0, b1, b2, b3, a0, a1, a2, a3) x (m0, m1, m2, m3, m0, m1, m2, m3) - * So, we need to duplicate loaded mask into whole register. - * - * For two pixel case - * (r0, r1, x, x, g0, g1, x, x) x (m0, m1, m0, m1, m0, m1, m0, m1) - * (b0, b1, x, x, a0, a1, x, x) x (m0, m1, m0, m1, m0, m1, m0, m1) - * We can do some optimizations for this including last pixel cases. - */ -.macro bilinear_duplicate_mask_x numpix, mask -.endm - -.macro bilinear_duplicate_mask_8 numpix, mask -.if numpix == 4 - vdup.32 mask, mask[0] -.elseif numpix == 2 - vdup.16 mask, mask[0] -.elseif numpix == 1 - vdup.8 mask, mask[0] -.else - .error bilinear_duplicate_mask_8 is unsupported -.endif -.endm - -.macro bilinear_duplicate_mask mask_fmt, numpix, mask - bilinear_duplicate_mask_&mask_fmt numpix, mask -.endm - -/* - * Macros for interleaving src and dst pixels to rrrr gggg bbbb aaaa form. - * Interleave should be done when maks is enabled or operator is 'over'. - */ -.macro bilinear_interleave src0, src1, dst0, dst1 - vuzp.8 src0, src1 - vuzp.8 dst0, dst1 - vuzp.8 src0, src1 - vuzp.8 dst0, dst1 -.endm - -.macro bilinear_interleave_src_dst_x_src \ - numpix, src0, src1, src01, dst0, dst1, dst01 -.endm - -.macro bilinear_interleave_src_dst_x_over \ - numpix, src0, src1, src01, dst0, dst1, dst01 - - bilinear_interleave src0, src1, dst0, dst1 -.endm - -.macro bilinear_interleave_src_dst_x_add \ - numpix, src0, src1, src01, dst0, dst1, dst01 -.endm - -.macro bilinear_interleave_src_dst_8_src \ - numpix, src0, src1, src01, dst0, dst1, dst01 - - bilinear_interleave src0, src1, dst0, dst1 -.endm - -.macro bilinear_interleave_src_dst_8_over \ - numpix, src0, src1, src01, dst0, dst1, dst01 - - bilinear_interleave src0, src1, dst0, dst1 -.endm - -.macro bilinear_interleave_src_dst_8_add \ - numpix, src0, src1, src01, dst0, dst1, dst01 - - bilinear_interleave src0, src1, dst0, dst1 -.endm - -.macro bilinear_interleave_src_dst \ - mask_fmt, op, numpix, src0, src1, src01, dst0, dst1, dst01 - - bilinear_interleave_src_dst_&mask_fmt&_&op \ - numpix, src0, src1, src01, dst0, dst1, dst01 -.endm - - -/* - * Macros for applying masks to src pixels. (see combine_mask_u() function) - * src, dst should be in interleaved form. - * mask register should be in form (m0, m1, m2, m3). - */ -.macro bilinear_apply_mask_to_src_x \ - numpix, src0, src1, src01, mask, \ - tmp01, tmp23, tmp45, tmp67 -.endm - -.macro bilinear_apply_mask_to_src_8 \ - numpix, src0, src1, src01, mask, \ - tmp01, tmp23, tmp45, tmp67 - - vmull.u8 tmp01, src0, mask - vmull.u8 tmp23, src1, mask - /* bubbles */ - vrshr.u16 tmp45, tmp01, #8 - vrshr.u16 tmp67, tmp23, #8 - /* bubbles */ - vraddhn.u16 src0, tmp45, tmp01 - vraddhn.u16 src1, tmp67, tmp23 -.endm - -.macro bilinear_apply_mask_to_src \ - mask_fmt, numpix, src0, src1, src01, mask, \ - tmp01, tmp23, tmp45, tmp67 - - bilinear_apply_mask_to_src_&mask_fmt \ - numpix, src0, src1, src01, mask, \ - tmp01, tmp23, tmp45, tmp67 -.endm - - -/* - * Macros for combining src and destination pixels. - * Interleave or not is depending on operator 'op'. - */ -.macro bilinear_combine_src \ - numpix, src0, src1, src01, dst0, dst1, dst01, \ - tmp01, tmp23, tmp45, tmp67, tmp8 -.endm - -.macro bilinear_combine_over \ - numpix, src0, src1, src01, dst0, dst1, dst01, \ - tmp01, tmp23, tmp45, tmp67, tmp8 - - vdup.32 tmp8, src1[1] - /* bubbles */ - vmvn.8 tmp8, tmp8 - /* bubbles */ - vmull.u8 tmp01, dst0, tmp8 - /* bubbles */ - vmull.u8 tmp23, dst1, tmp8 - /* bubbles */ - vrshr.u16 tmp45, tmp01, #8 - vrshr.u16 tmp67, tmp23, #8 - /* bubbles */ - vraddhn.u16 dst0, tmp45, tmp01 - vraddhn.u16 dst1, tmp67, tmp23 - /* bubbles */ - vqadd.u8 src01, dst01, src01 -.endm - -.macro bilinear_combine_add \ - numpix, src0, src1, src01, dst0, dst1, dst01, \ - tmp01, tmp23, tmp45, tmp67, tmp8 - - vqadd.u8 src01, dst01, src01 -.endm - -.macro bilinear_combine \ - op, numpix, src0, src1, src01, dst0, dst1, dst01, \ - tmp01, tmp23, tmp45, tmp67, tmp8 - - bilinear_combine_&op \ - numpix, src0, src1, src01, dst0, dst1, dst01, \ - tmp01, tmp23, tmp45, tmp67, tmp8 -.endm - -/* - * Macros for final deinterleaving of destination pixels if needed. - */ -.macro bilinear_deinterleave numpix, dst0, dst1, dst01 - vuzp.8 dst0, dst1 - /* bubbles */ - vuzp.8 dst0, dst1 -.endm - -.macro bilinear_deinterleave_dst_x_src numpix, dst0, dst1, dst01 -.endm - -.macro bilinear_deinterleave_dst_x_over numpix, dst0, dst1, dst01 - bilinear_deinterleave numpix, dst0, dst1, dst01 -.endm - -.macro bilinear_deinterleave_dst_x_add numpix, dst0, dst1, dst01 -.endm - -.macro bilinear_deinterleave_dst_8_src numpix, dst0, dst1, dst01 - bilinear_deinterleave numpix, dst0, dst1, dst01 -.endm - -.macro bilinear_deinterleave_dst_8_over numpix, dst0, dst1, dst01 - bilinear_deinterleave numpix, dst0, dst1, dst01 -.endm - -.macro bilinear_deinterleave_dst_8_add numpix, dst0, dst1, dst01 - bilinear_deinterleave numpix, dst0, dst1, dst01 -.endm - -.macro bilinear_deinterleave_dst mask_fmt, op, numpix, dst0, dst1, dst01 - bilinear_deinterleave_dst_&mask_fmt&_&op numpix, dst0, dst1, dst01 -.endm - - -.macro bilinear_interpolate_last_pixel src_fmt, mask_fmt, dst_fmt, op - bilinear_load_&src_fmt d0, d1, d2 - bilinear_load_mask mask_fmt, 1, d4 - bilinear_load_dst dst_fmt, op, 1, d18, d19, q9 - vmull.u8 q1, d0, d28 - vmlal.u8 q1, d1, d29 - /* 5 cycles bubble */ - vshll.u16 q0, d2, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q0, d2, d30 - vmlal.u16 q0, d3, d30 - /* 5 cycles bubble */ - bilinear_duplicate_mask mask_fmt, 1, d4 - vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS) - /* 3 cycles bubble */ - vmovn.u16 d0, q0 - /* 1 cycle bubble */ - bilinear_interleave_src_dst \ - mask_fmt, op, 1, d0, d1, q0, d18, d19, q9 - bilinear_apply_mask_to_src \ - mask_fmt, 1, d0, d1, q0, d4, \ - q3, q8, q10, q11 - bilinear_combine \ - op, 1, d0, d1, q0, d18, d19, q9, \ - q3, q8, q10, q11, d5 - bilinear_deinterleave_dst mask_fmt, op, 1, d0, d1, q0 - bilinear_store_&dst_fmt 1, q2, q3 -.endm - -.macro bilinear_interpolate_two_pixels src_fmt, mask_fmt, dst_fmt, op - bilinear_load_and_vertical_interpolate_two_&src_fmt \ - q1, q11, d0, d1, d20, d21, d22, d23 - bilinear_load_mask mask_fmt, 2, d4 - bilinear_load_dst dst_fmt, op, 2, d18, d19, q9 - vshll.u16 q0, d2, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q0, d2, d30 - vmlal.u16 q0, d3, d30 - vshll.u16 q10, d22, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q10, d22, d31 - vmlal.u16 q10, d23, d31 - vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d1, q10, #(2 * BILINEAR_INTERPOLATION_BITS) - bilinear_duplicate_mask mask_fmt, 2, d4 - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vadd.u16 q12, q12, q13 - vmovn.u16 d0, q0 - bilinear_interleave_src_dst \ - mask_fmt, op, 2, d0, d1, q0, d18, d19, q9 - bilinear_apply_mask_to_src \ - mask_fmt, 2, d0, d1, q0, d4, \ - q3, q8, q10, q11 - bilinear_combine \ - op, 2, d0, d1, q0, d18, d19, q9, \ - q3, q8, q10, q11, d5 - bilinear_deinterleave_dst mask_fmt, op, 2, d0, d1, q0 - bilinear_store_&dst_fmt 2, q2, q3 -.endm - -.macro bilinear_interpolate_four_pixels src_fmt, mask_fmt, dst_fmt, op - bilinear_load_and_vertical_interpolate_four_&src_fmt \ - q1, q11, d0, d1, d20, d21, d22, d23 \ - q3, q9, d4, d5, d16, d17, d18, d19 - pld [TMP1, PF_OFFS] - sub TMP1, TMP1, STRIDE - vshll.u16 q0, d2, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q0, d2, d30 - vmlal.u16 q0, d3, d30 - vshll.u16 q10, d22, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q10, d22, d31 - vmlal.u16 q10, d23, d31 - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vshll.u16 q2, d6, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q2, d6, d30 - vmlal.u16 q2, d7, d30 - vshll.u16 q8, d18, #BILINEAR_INTERPOLATION_BITS - bilinear_load_mask mask_fmt, 4, d22 - bilinear_load_dst dst_fmt, op, 4, d2, d3, q1 - pld [TMP1, PF_OFFS] - vmlsl.u16 q8, d18, d31 - vmlal.u16 q8, d19, d31 - vadd.u16 q12, q12, q13 - vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d1, q10, #(2 * BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d4, q2, #(2 * BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d5, q8, #(2 * BILINEAR_INTERPOLATION_BITS) - bilinear_duplicate_mask mask_fmt, 4, d22 - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vmovn.u16 d0, q0 - vmovn.u16 d1, q2 - vadd.u16 q12, q12, q13 - bilinear_interleave_src_dst \ - mask_fmt, op, 4, d0, d1, q0, d2, d3, q1 - bilinear_apply_mask_to_src \ - mask_fmt, 4, d0, d1, q0, d22, \ - q3, q8, q9, q10 - bilinear_combine \ - op, 4, d0, d1, q0, d2, d3, q1, \ - q3, q8, q9, q10, d23 - bilinear_deinterleave_dst mask_fmt, op, 4, d0, d1, q0 - bilinear_store_&dst_fmt 4, q2, q3 -.endm - -.set BILINEAR_FLAG_USE_MASK, 1 -.set BILINEAR_FLAG_USE_ALL_NEON_REGS, 2 - -/* - * Main template macro for generating NEON optimized bilinear scanline functions. - * - * Bilinear scanline generator macro take folling arguments: - * fname - name of the function to generate - * src_fmt - source color format (8888 or 0565) - * dst_fmt - destination color format (8888 or 0565) - * src/dst_bpp_shift - (1 << bpp_shift) is the size of src/dst pixel in bytes - * process_last_pixel - code block that interpolate one pixel and does not - * update horizontal weight - * process_two_pixels - code block that interpolate two pixels and update - * horizontal weight - * process_four_pixels - code block that interpolate four pixels and update - * horizontal weight - * process_pixblock_head - head part of middle loop - * process_pixblock_tail - tail part of middle loop - * process_pixblock_tail_head - tail_head of middle loop - * pixblock_size - number of pixels processed in a single middle loop - * prefetch_distance - prefetch in the source image by that many pixels ahead - */ - -.macro generate_bilinear_scanline_func \ - fname, \ - src_fmt, dst_fmt, src_bpp_shift, dst_bpp_shift, \ - bilinear_process_last_pixel, \ - bilinear_process_two_pixels, \ - bilinear_process_four_pixels, \ - bilinear_process_pixblock_head, \ - bilinear_process_pixblock_tail, \ - bilinear_process_pixblock_tail_head, \ - pixblock_size, \ - prefetch_distance, \ - flags - -pixman_asm_function fname -.if pixblock_size == 8 -.elseif pixblock_size == 4 -.else - .error unsupported pixblock size -.endif - -.if ((flags) & BILINEAR_FLAG_USE_MASK) == 0 - OUT .req r0 - TOP .req r1 - BOTTOM .req r2 - WT .req r3 - WB .req r4 - X .req r5 - UX .req r6 - WIDTH .req ip - TMP1 .req r3 - TMP2 .req r4 - PF_OFFS .req r7 - TMP3 .req r8 - TMP4 .req r9 - STRIDE .req r2 - - mov ip, sp - push {r4, r5, r6, r7, r8, r9} - mov PF_OFFS, #prefetch_distance - ldmia ip, {WB, X, UX, WIDTH} -.else - OUT .req r0 - MASK .req r1 - TOP .req r2 - BOTTOM .req r3 - WT .req r4 - WB .req r5 - X .req r6 - UX .req r7 - WIDTH .req ip - TMP1 .req r4 - TMP2 .req r5 - PF_OFFS .req r8 - TMP3 .req r9 - TMP4 .req r10 - STRIDE .req r3 - - .set prefetch_offset, prefetch_distance - - mov ip, sp - push {r4, r5, r6, r7, r8, r9, r10, ip} - mov PF_OFFS, #prefetch_distance - ldmia ip, {WT, WB, X, UX, WIDTH} -.endif - - mul PF_OFFS, PF_OFFS, UX - -.if ((flags) & BILINEAR_FLAG_USE_ALL_NEON_REGS) != 0 - vpush {d8-d15} -.endif - - sub STRIDE, BOTTOM, TOP - .unreq BOTTOM - - cmp WIDTH, #0 - ble 3f - - vdup.u16 q12, X - vdup.u16 q13, UX - vdup.u8 d28, WT - vdup.u8 d29, WB - vadd.u16 d25, d25, d26 - - /* ensure good destination alignment */ - cmp WIDTH, #1 - blt 0f - tst OUT, #(1 << dst_bpp_shift) - beq 0f - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vadd.u16 q12, q12, q13 - bilinear_process_last_pixel - sub WIDTH, WIDTH, #1 -0: - vadd.u16 q13, q13, q13 - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vadd.u16 q12, q12, q13 - - cmp WIDTH, #2 - blt 0f - tst OUT, #(1 << (dst_bpp_shift + 1)) - beq 0f - bilinear_process_two_pixels - sub WIDTH, WIDTH, #2 -0: -.if pixblock_size == 8 - cmp WIDTH, #4 - blt 0f - tst OUT, #(1 << (dst_bpp_shift + 2)) - beq 0f - bilinear_process_four_pixels - sub WIDTH, WIDTH, #4 -0: -.endif - subs WIDTH, WIDTH, #pixblock_size - blt 1f - mov PF_OFFS, PF_OFFS, asr #(16 - src_bpp_shift) - bilinear_process_pixblock_head - subs WIDTH, WIDTH, #pixblock_size - blt 5f -0: - bilinear_process_pixblock_tail_head - subs WIDTH, WIDTH, #pixblock_size - bge 0b -5: - bilinear_process_pixblock_tail -1: -.if pixblock_size == 8 - tst WIDTH, #4 - beq 2f - bilinear_process_four_pixels -2: -.endif - /* handle the remaining trailing pixels */ - tst WIDTH, #2 - beq 2f - bilinear_process_two_pixels -2: - tst WIDTH, #1 - beq 3f - bilinear_process_last_pixel -3: -.if ((flags) & BILINEAR_FLAG_USE_ALL_NEON_REGS) != 0 - vpop {d8-d15} -.endif - -.if ((flags) & BILINEAR_FLAG_USE_MASK) == 0 - pop {r4, r5, r6, r7, r8, r9} -.else - pop {r4, r5, r6, r7, r8, r9, r10, ip} -.endif - bx lr - - .unreq OUT - .unreq TOP - .unreq WT - .unreq WB - .unreq X - .unreq UX - .unreq WIDTH - .unreq TMP1 - .unreq TMP2 - .unreq PF_OFFS - .unreq TMP3 - .unreq TMP4 - .unreq STRIDE -.if ((flags) & BILINEAR_FLAG_USE_MASK) != 0 - .unreq MASK -.endif - -.endfunc - -.endm - -/* src_8888_8_8888 */ -.macro bilinear_src_8888_8_8888_process_last_pixel - bilinear_interpolate_last_pixel 8888, 8, 8888, src -.endm - -.macro bilinear_src_8888_8_8888_process_two_pixels - bilinear_interpolate_two_pixels 8888, 8, 8888, src -.endm - -.macro bilinear_src_8888_8_8888_process_four_pixels - bilinear_interpolate_four_pixels 8888, 8, 8888, src -.endm - -.macro bilinear_src_8888_8_8888_process_pixblock_head - bilinear_src_8888_8_8888_process_four_pixels -.endm - -.macro bilinear_src_8888_8_8888_process_pixblock_tail -.endm - -.macro bilinear_src_8888_8_8888_process_pixblock_tail_head - bilinear_src_8888_8_8888_process_pixblock_tail - bilinear_src_8888_8_8888_process_pixblock_head -.endm - -/* src_8888_8_0565 */ -.macro bilinear_src_8888_8_0565_process_last_pixel - bilinear_interpolate_last_pixel 8888, 8, 0565, src -.endm - -.macro bilinear_src_8888_8_0565_process_two_pixels - bilinear_interpolate_two_pixels 8888, 8, 0565, src -.endm - -.macro bilinear_src_8888_8_0565_process_four_pixels - bilinear_interpolate_four_pixels 8888, 8, 0565, src -.endm - -.macro bilinear_src_8888_8_0565_process_pixblock_head - bilinear_src_8888_8_0565_process_four_pixels -.endm - -.macro bilinear_src_8888_8_0565_process_pixblock_tail -.endm - -.macro bilinear_src_8888_8_0565_process_pixblock_tail_head - bilinear_src_8888_8_0565_process_pixblock_tail - bilinear_src_8888_8_0565_process_pixblock_head -.endm - -/* src_0565_8_x888 */ -.macro bilinear_src_0565_8_x888_process_last_pixel - bilinear_interpolate_last_pixel 0565, 8, 8888, src -.endm - -.macro bilinear_src_0565_8_x888_process_two_pixels - bilinear_interpolate_two_pixels 0565, 8, 8888, src -.endm - -.macro bilinear_src_0565_8_x888_process_four_pixels - bilinear_interpolate_four_pixels 0565, 8, 8888, src -.endm - -.macro bilinear_src_0565_8_x888_process_pixblock_head - bilinear_src_0565_8_x888_process_four_pixels -.endm - -.macro bilinear_src_0565_8_x888_process_pixblock_tail -.endm - -.macro bilinear_src_0565_8_x888_process_pixblock_tail_head - bilinear_src_0565_8_x888_process_pixblock_tail - bilinear_src_0565_8_x888_process_pixblock_head -.endm - -/* src_0565_8_0565 */ -.macro bilinear_src_0565_8_0565_process_last_pixel - bilinear_interpolate_last_pixel 0565, 8, 0565, src -.endm - -.macro bilinear_src_0565_8_0565_process_two_pixels - bilinear_interpolate_two_pixels 0565, 8, 0565, src -.endm - -.macro bilinear_src_0565_8_0565_process_four_pixels - bilinear_interpolate_four_pixels 0565, 8, 0565, src -.endm - -.macro bilinear_src_0565_8_0565_process_pixblock_head - bilinear_src_0565_8_0565_process_four_pixels -.endm - -.macro bilinear_src_0565_8_0565_process_pixblock_tail -.endm - -.macro bilinear_src_0565_8_0565_process_pixblock_tail_head - bilinear_src_0565_8_0565_process_pixblock_tail - bilinear_src_0565_8_0565_process_pixblock_head -.endm - -/* over_8888_8888 */ -.macro bilinear_over_8888_8888_process_last_pixel - bilinear_interpolate_last_pixel 8888, x, 8888, over -.endm - -.macro bilinear_over_8888_8888_process_two_pixels - bilinear_interpolate_two_pixels 8888, x, 8888, over -.endm - -.macro bilinear_over_8888_8888_process_four_pixels - bilinear_interpolate_four_pixels 8888, x, 8888, over -.endm - -.macro bilinear_over_8888_8888_process_pixblock_head - mov TMP1, X, asr #16 - add X, X, UX - add TMP1, TOP, TMP1, asl #2 - mov TMP2, X, asr #16 - add X, X, UX - add TMP2, TOP, TMP2, asl #2 - - vld1.32 {d22}, [TMP1], STRIDE - vld1.32 {d23}, [TMP1] - mov TMP3, X, asr #16 - add X, X, UX - add TMP3, TOP, TMP3, asl #2 - vmull.u8 q8, d22, d28 - vmlal.u8 q8, d23, d29 - - vld1.32 {d22}, [TMP2], STRIDE - vld1.32 {d23}, [TMP2] - mov TMP4, X, asr #16 - add X, X, UX - add TMP4, TOP, TMP4, asl #2 - vmull.u8 q9, d22, d28 - vmlal.u8 q9, d23, d29 - - vld1.32 {d22}, [TMP3], STRIDE - vld1.32 {d23}, [TMP3] - vmull.u8 q10, d22, d28 - vmlal.u8 q10, d23, d29 - - vshll.u16 q0, d16, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q0, d16, d30 - vmlal.u16 q0, d17, d30 - - pld [TMP4, PF_OFFS] - vld1.32 {d16}, [TMP4], STRIDE - vld1.32 {d17}, [TMP4] - pld [TMP4, PF_OFFS] - vmull.u8 q11, d16, d28 - vmlal.u8 q11, d17, d29 - - vshll.u16 q1, d18, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q1, d18, d31 - vmlal.u16 q1, d19, d31 - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vadd.u16 q12, q12, q13 -.endm - -.macro bilinear_over_8888_8888_process_pixblock_tail - vshll.u16 q2, d20, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q2, d20, d30 - vmlal.u16 q2, d21, d30 - vshll.u16 q3, d22, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q3, d22, d31 - vmlal.u16 q3, d23, d31 - vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d1, q1, #(2 * BILINEAR_INTERPOLATION_BITS) - vld1.32 {d2, d3}, [OUT, :128] - pld [OUT, #(prefetch_offset * 4)] - vshrn.u32 d4, q2, #(2 * BILINEAR_INTERPOLATION_BITS) - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d5, q3, #(2 * BILINEAR_INTERPOLATION_BITS) - vmovn.u16 d6, q0 - vmovn.u16 d7, q2 - vuzp.8 d6, d7 - vuzp.8 d2, d3 - vuzp.8 d6, d7 - vuzp.8 d2, d3 - vdup.32 d4, d7[1] - vmvn.8 d4, d4 - vmull.u8 q11, d2, d4 - vmull.u8 q2, d3, d4 - vrshr.u16 q1, q11, #8 - vrshr.u16 q10, q2, #8 - vraddhn.u16 d2, q1, q11 - vraddhn.u16 d3, q10, q2 - vqadd.u8 q3, q1, q3 - vuzp.8 d6, d7 - vuzp.8 d6, d7 - vadd.u16 q12, q12, q13 - vst1.32 {d6, d7}, [OUT, :128]! -.endm - -.macro bilinear_over_8888_8888_process_pixblock_tail_head - vshll.u16 q2, d20, #BILINEAR_INTERPOLATION_BITS - mov TMP1, X, asr #16 - add X, X, UX - add TMP1, TOP, TMP1, asl #2 - vmlsl.u16 q2, d20, d30 - mov TMP2, X, asr #16 - add X, X, UX - add TMP2, TOP, TMP2, asl #2 - vmlal.u16 q2, d21, d30 - vshll.u16 q3, d22, #BILINEAR_INTERPOLATION_BITS - vld1.32 {d20}, [TMP1], STRIDE - vmlsl.u16 q3, d22, d31 - vmlal.u16 q3, d23, d31 - vld1.32 {d21}, [TMP1] - vmull.u8 q8, d20, d28 - vmlal.u8 q8, d21, d29 - vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d1, q1, #(2 * BILINEAR_INTERPOLATION_BITS) - vld1.32 {d2, d3}, [OUT, :128] - pld [OUT, PF_OFFS] - vshrn.u32 d4, q2, #(2 * BILINEAR_INTERPOLATION_BITS) - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vld1.32 {d22}, [TMP2], STRIDE - vshrn.u32 d5, q3, #(2 * BILINEAR_INTERPOLATION_BITS) - vmovn.u16 d6, q0 - vld1.32 {d23}, [TMP2] - vmull.u8 q9, d22, d28 - mov TMP3, X, asr #16 - add X, X, UX - add TMP3, TOP, TMP3, asl #2 - mov TMP4, X, asr #16 - add X, X, UX - add TMP4, TOP, TMP4, asl #2 - vmlal.u8 q9, d23, d29 - vmovn.u16 d7, q2 - vld1.32 {d22}, [TMP3], STRIDE - vuzp.8 d6, d7 - vuzp.8 d2, d3 - vuzp.8 d6, d7 - vuzp.8 d2, d3 - vdup.32 d4, d7[1] - vld1.32 {d23}, [TMP3] - vmvn.8 d4, d4 - vmull.u8 q10, d22, d28 - vmlal.u8 q10, d23, d29 - vmull.u8 q11, d2, d4 - vmull.u8 q2, d3, d4 - vshll.u16 q0, d16, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q0, d16, d30 - vrshr.u16 q1, q11, #8 - vmlal.u16 q0, d17, d30 - vrshr.u16 q8, q2, #8 - vraddhn.u16 d2, q1, q11 - vraddhn.u16 d3, q8, q2 - pld [TMP4, PF_OFFS] - vld1.32 {d16}, [TMP4], STRIDE - vqadd.u8 q3, q1, q3 - vld1.32 {d17}, [TMP4] - pld [TMP4, PF_OFFS] - vmull.u8 q11, d16, d28 - vmlal.u8 q11, d17, d29 - vuzp.8 d6, d7 - vshll.u16 q1, d18, #BILINEAR_INTERPOLATION_BITS - vuzp.8 d6, d7 - vmlsl.u16 q1, d18, d31 - vadd.u16 q12, q12, q13 - vmlal.u16 q1, d19, d31 - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vadd.u16 q12, q12, q13 - vst1.32 {d6, d7}, [OUT, :128]! -.endm - -/* over_8888_8_8888 */ -.macro bilinear_over_8888_8_8888_process_last_pixel - bilinear_interpolate_last_pixel 8888, 8, 8888, over -.endm - -.macro bilinear_over_8888_8_8888_process_two_pixels - bilinear_interpolate_two_pixels 8888, 8, 8888, over -.endm - -.macro bilinear_over_8888_8_8888_process_four_pixels - bilinear_interpolate_four_pixels 8888, 8, 8888, over -.endm - -.macro bilinear_over_8888_8_8888_process_pixblock_head - mov TMP1, X, asr #16 - add X, X, UX - add TMP1, TOP, TMP1, asl #2 - vld1.32 {d0}, [TMP1], STRIDE - mov TMP2, X, asr #16 - add X, X, UX - add TMP2, TOP, TMP2, asl #2 - vld1.32 {d1}, [TMP1] - mov TMP3, X, asr #16 - add X, X, UX - add TMP3, TOP, TMP3, asl #2 - vld1.32 {d2}, [TMP2], STRIDE - mov TMP4, X, asr #16 - add X, X, UX - add TMP4, TOP, TMP4, asl #2 - vld1.32 {d3}, [TMP2] - vmull.u8 q2, d0, d28 - vmull.u8 q3, d2, d28 - vmlal.u8 q2, d1, d29 - vmlal.u8 q3, d3, d29 - vshll.u16 q0, d4, #BILINEAR_INTERPOLATION_BITS - vshll.u16 q1, d6, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q0, d4, d30 - vmlsl.u16 q1, d6, d31 - vmlal.u16 q0, d5, d30 - vmlal.u16 q1, d7, d31 - vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d1, q1, #(2 * BILINEAR_INTERPOLATION_BITS) - vld1.32 {d2}, [TMP3], STRIDE - vld1.32 {d3}, [TMP3] - pld [TMP4, PF_OFFS] - vld1.32 {d4}, [TMP4], STRIDE - vld1.32 {d5}, [TMP4] - pld [TMP4, PF_OFFS] - vmull.u8 q3, d2, d28 - vmlal.u8 q3, d3, d29 - vmull.u8 q1, d4, d28 - vmlal.u8 q1, d5, d29 - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vld1.32 {d22[0]}, [MASK]! - pld [MASK, #prefetch_offset] - vadd.u16 q12, q12, q13 - vmovn.u16 d16, q0 -.endm - -.macro bilinear_over_8888_8_8888_process_pixblock_tail - vshll.u16 q9, d6, #BILINEAR_INTERPOLATION_BITS - vshll.u16 q10, d2, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q9, d6, d30 - vmlsl.u16 q10, d2, d31 - vmlal.u16 q9, d7, d30 - vmlal.u16 q10, d3, d31 - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vadd.u16 q12, q12, q13 - vdup.32 d22, d22[0] - vshrn.u32 d18, q9, #(2 * BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d19, q10, #(2 * BILINEAR_INTERPOLATION_BITS) - vmovn.u16 d17, q9 - vld1.32 {d18, d19}, [OUT, :128] - pld [OUT, PF_OFFS] - vuzp.8 d16, d17 - vuzp.8 d18, d19 - vuzp.8 d16, d17 - vuzp.8 d18, d19 - vmull.u8 q10, d16, d22 - vmull.u8 q11, d17, d22 - vrsra.u16 q10, q10, #8 - vrsra.u16 q11, q11, #8 - vrshrn.u16 d16, q10, #8 - vrshrn.u16 d17, q11, #8 - vdup.32 d22, d17[1] - vmvn.8 d22, d22 - vmull.u8 q10, d18, d22 - vmull.u8 q11, d19, d22 - vrshr.u16 q9, q10, #8 - vrshr.u16 q0, q11, #8 - vraddhn.u16 d18, q9, q10 - vraddhn.u16 d19, q0, q11 - vqadd.u8 q9, q8, q9 - vuzp.8 d18, d19 - vuzp.8 d18, d19 - vst1.32 {d18, d19}, [OUT, :128]! -.endm - -.macro bilinear_over_8888_8_8888_process_pixblock_tail_head - vshll.u16 q9, d6, #BILINEAR_INTERPOLATION_BITS - mov TMP1, X, asr #16 - add X, X, UX - add TMP1, TOP, TMP1, asl #2 - vshll.u16 q10, d2, #BILINEAR_INTERPOLATION_BITS - vld1.32 {d0}, [TMP1], STRIDE - mov TMP2, X, asr #16 - add X, X, UX - add TMP2, TOP, TMP2, asl #2 - vmlsl.u16 q9, d6, d30 - vmlsl.u16 q10, d2, d31 - vld1.32 {d1}, [TMP1] - mov TMP3, X, asr #16 - add X, X, UX - add TMP3, TOP, TMP3, asl #2 - vmlal.u16 q9, d7, d30 - vmlal.u16 q10, d3, d31 - vld1.32 {d2}, [TMP2], STRIDE - mov TMP4, X, asr #16 - add X, X, UX - add TMP4, TOP, TMP4, asl #2 - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vadd.u16 q12, q12, q13 - vld1.32 {d3}, [TMP2] - vdup.32 d22, d22[0] - vshrn.u32 d18, q9, #(2 * BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d19, q10, #(2 * BILINEAR_INTERPOLATION_BITS) - vmull.u8 q2, d0, d28 - vmull.u8 q3, d2, d28 - vmovn.u16 d17, q9 - vld1.32 {d18, d19}, [OUT, :128] - pld [OUT, #(prefetch_offset * 4)] - vmlal.u8 q2, d1, d29 - vmlal.u8 q3, d3, d29 - vuzp.8 d16, d17 - vuzp.8 d18, d19 - vshll.u16 q0, d4, #BILINEAR_INTERPOLATION_BITS - vshll.u16 q1, d6, #BILINEAR_INTERPOLATION_BITS - vuzp.8 d16, d17 - vuzp.8 d18, d19 - vmlsl.u16 q0, d4, d30 - vmlsl.u16 q1, d6, d31 - vmull.u8 q10, d16, d22 - vmull.u8 q11, d17, d22 - vmlal.u16 q0, d5, d30 - vmlal.u16 q1, d7, d31 - vrsra.u16 q10, q10, #8 - vrsra.u16 q11, q11, #8 - vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d1, q1, #(2 * BILINEAR_INTERPOLATION_BITS) - vrshrn.u16 d16, q10, #8 - vrshrn.u16 d17, q11, #8 - vld1.32 {d2}, [TMP3], STRIDE - vdup.32 d22, d17[1] - vld1.32 {d3}, [TMP3] - vmvn.8 d22, d22 - pld [TMP4, PF_OFFS] - vld1.32 {d4}, [TMP4], STRIDE - vmull.u8 q10, d18, d22 - vmull.u8 q11, d19, d22 - vld1.32 {d5}, [TMP4] - pld [TMP4, PF_OFFS] - vmull.u8 q3, d2, d28 - vrshr.u16 q9, q10, #8 - vrshr.u16 q15, q11, #8 - vmlal.u8 q3, d3, d29 - vmull.u8 q1, d4, d28 - vraddhn.u16 d18, q9, q10 - vraddhn.u16 d19, q15, q11 - vmlal.u8 q1, d5, d29 - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vqadd.u8 q9, q8, q9 - vld1.32 {d22[0]}, [MASK]! - vuzp.8 d18, d19 - vadd.u16 q12, q12, q13 - vuzp.8 d18, d19 - vmovn.u16 d16, q0 - vst1.32 {d18, d19}, [OUT, :128]! -.endm - -/* add_8888_8888 */ -.macro bilinear_add_8888_8888_process_last_pixel - bilinear_interpolate_last_pixel 8888, x, 8888, add -.endm - -.macro bilinear_add_8888_8888_process_two_pixels - bilinear_interpolate_two_pixels 8888, x, 8888, add -.endm - -.macro bilinear_add_8888_8888_process_four_pixels - bilinear_interpolate_four_pixels 8888, x, 8888, add -.endm - -.macro bilinear_add_8888_8888_process_pixblock_head - bilinear_add_8888_8888_process_four_pixels -.endm - -.macro bilinear_add_8888_8888_process_pixblock_tail -.endm - -.macro bilinear_add_8888_8888_process_pixblock_tail_head - bilinear_add_8888_8888_process_pixblock_tail - bilinear_add_8888_8888_process_pixblock_head -.endm - -/* add_8888_8_8888 */ -.macro bilinear_add_8888_8_8888_process_last_pixel - bilinear_interpolate_last_pixel 8888, 8, 8888, add -.endm - -.macro bilinear_add_8888_8_8888_process_two_pixels - bilinear_interpolate_two_pixels 8888, 8, 8888, add -.endm - -.macro bilinear_add_8888_8_8888_process_four_pixels - bilinear_interpolate_four_pixels 8888, 8, 8888, add -.endm - -.macro bilinear_add_8888_8_8888_process_pixblock_head - bilinear_add_8888_8_8888_process_four_pixels -.endm - -.macro bilinear_add_8888_8_8888_process_pixblock_tail -.endm - -.macro bilinear_add_8888_8_8888_process_pixblock_tail_head - bilinear_add_8888_8_8888_process_pixblock_tail - bilinear_add_8888_8_8888_process_pixblock_head -.endm - - -/* Bilinear scanline functions */ -generate_bilinear_scanline_func \ - pixman_scaled_bilinear_scanline_8888_8_8888_SRC_asm_neon, \ - 8888, 8888, 2, 2, \ - bilinear_src_8888_8_8888_process_last_pixel, \ - bilinear_src_8888_8_8888_process_two_pixels, \ - bilinear_src_8888_8_8888_process_four_pixels, \ - bilinear_src_8888_8_8888_process_pixblock_head, \ - bilinear_src_8888_8_8888_process_pixblock_tail, \ - bilinear_src_8888_8_8888_process_pixblock_tail_head, \ - 4, 28, BILINEAR_FLAG_USE_MASK - -generate_bilinear_scanline_func \ - pixman_scaled_bilinear_scanline_8888_8_0565_SRC_asm_neon, \ - 8888, 0565, 2, 1, \ - bilinear_src_8888_8_0565_process_last_pixel, \ - bilinear_src_8888_8_0565_process_two_pixels, \ - bilinear_src_8888_8_0565_process_four_pixels, \ - bilinear_src_8888_8_0565_process_pixblock_head, \ - bilinear_src_8888_8_0565_process_pixblock_tail, \ - bilinear_src_8888_8_0565_process_pixblock_tail_head, \ - 4, 28, BILINEAR_FLAG_USE_MASK - -generate_bilinear_scanline_func \ - pixman_scaled_bilinear_scanline_0565_8_x888_SRC_asm_neon, \ - 0565, 8888, 1, 2, \ - bilinear_src_0565_8_x888_process_last_pixel, \ - bilinear_src_0565_8_x888_process_two_pixels, \ - bilinear_src_0565_8_x888_process_four_pixels, \ - bilinear_src_0565_8_x888_process_pixblock_head, \ - bilinear_src_0565_8_x888_process_pixblock_tail, \ - bilinear_src_0565_8_x888_process_pixblock_tail_head, \ - 4, 28, BILINEAR_FLAG_USE_MASK - -generate_bilinear_scanline_func \ - pixman_scaled_bilinear_scanline_0565_8_0565_SRC_asm_neon, \ - 0565, 0565, 1, 1, \ - bilinear_src_0565_8_0565_process_last_pixel, \ - bilinear_src_0565_8_0565_process_two_pixels, \ - bilinear_src_0565_8_0565_process_four_pixels, \ - bilinear_src_0565_8_0565_process_pixblock_head, \ - bilinear_src_0565_8_0565_process_pixblock_tail, \ - bilinear_src_0565_8_0565_process_pixblock_tail_head, \ - 4, 28, BILINEAR_FLAG_USE_MASK - -generate_bilinear_scanline_func \ - pixman_scaled_bilinear_scanline_8888_8888_OVER_asm_neon, \ - 8888, 8888, 2, 2, \ - bilinear_over_8888_8888_process_last_pixel, \ - bilinear_over_8888_8888_process_two_pixels, \ - bilinear_over_8888_8888_process_four_pixels, \ - bilinear_over_8888_8888_process_pixblock_head, \ - bilinear_over_8888_8888_process_pixblock_tail, \ - bilinear_over_8888_8888_process_pixblock_tail_head, \ - 4, 28, 0 - -generate_bilinear_scanline_func \ - pixman_scaled_bilinear_scanline_8888_8_8888_OVER_asm_neon, \ - 8888, 8888, 2, 2, \ - bilinear_over_8888_8_8888_process_last_pixel, \ - bilinear_over_8888_8_8888_process_two_pixels, \ - bilinear_over_8888_8_8888_process_four_pixels, \ - bilinear_over_8888_8_8888_process_pixblock_head, \ - bilinear_over_8888_8_8888_process_pixblock_tail, \ - bilinear_over_8888_8_8888_process_pixblock_tail_head, \ - 4, 28, BILINEAR_FLAG_USE_MASK - -generate_bilinear_scanline_func \ - pixman_scaled_bilinear_scanline_8888_8888_ADD_asm_neon, \ - 8888, 8888, 2, 2, \ - bilinear_add_8888_8888_process_last_pixel, \ - bilinear_add_8888_8888_process_two_pixels, \ - bilinear_add_8888_8888_process_four_pixels, \ - bilinear_add_8888_8888_process_pixblock_head, \ - bilinear_add_8888_8888_process_pixblock_tail, \ - bilinear_add_8888_8888_process_pixblock_tail_head, \ - 4, 28, 0 - -generate_bilinear_scanline_func \ - pixman_scaled_bilinear_scanline_8888_8_8888_ADD_asm_neon, \ - 8888, 8888, 2, 2, \ - bilinear_add_8888_8_8888_process_last_pixel, \ - bilinear_add_8888_8_8888_process_two_pixels, \ - bilinear_add_8888_8_8888_process_four_pixels, \ - bilinear_add_8888_8_8888_process_pixblock_head, \ - bilinear_add_8888_8_8888_process_pixblock_tail, \ - bilinear_add_8888_8_8888_process_pixblock_tail_head, \ - 4, 28, BILINEAR_FLAG_USE_MASK diff --git a/source/libs/pixman/pixman-src/pixman/pixman-arm-neon-asm.S b/source/libs/pixman/pixman-src/pixman/pixman-arm-neon-asm.S deleted file mode 100644 index 7e949a38fd748fe7f0d834b89409b7c0d69a2de8..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-arm-neon-asm.S +++ /dev/null @@ -1,3627 +0,0 @@ -/* - * Copyright © 2009 Nokia Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Siarhei Siamashka (siarhei.siamashka@nokia.com) - */ - -/* - * This file contains implementations of NEON optimized pixel processing - * functions. There is no full and detailed tutorial, but some functions - * (those which are exposing some new or interesting features) are - * extensively commented and can be used as examples. - * - * You may want to have a look at the comments for following functions: - * - pixman_composite_over_8888_0565_asm_neon - * - pixman_composite_over_n_8_0565_asm_neon - */ - -/* Prevent the stack from becoming executable for no reason... */ -#if defined(__linux__) && defined(__ELF__) -.section .note.GNU-stack,"",%progbits -#endif - - .text - .fpu neon - .arch armv7a - .object_arch armv4 - .eabi_attribute 10, 0 /* suppress Tag_FP_arch */ - .eabi_attribute 12, 0 /* suppress Tag_Advanced_SIMD_arch */ - .arm - .altmacro - .p2align 2 - -#include "pixman-private.h" -#include "pixman-arm-asm.h" -#include "pixman-arm-neon-asm.h" - -/* Global configuration options and preferences */ - -/* - * The code can optionally make use of unaligned memory accesses to improve - * performance of handling leading/trailing pixels for each scanline. - * Configuration variable RESPECT_STRICT_ALIGNMENT can be set to 0 for - * example in linux if unaligned memory accesses are not configured to - * generate.exceptions. - */ -.set RESPECT_STRICT_ALIGNMENT, 1 - -/* - * Set default prefetch type. There is a choice between the following options: - * - * PREFETCH_TYPE_NONE (may be useful for the ARM cores where PLD is set to work - * as NOP to workaround some HW bugs or for whatever other reason) - * - * PREFETCH_TYPE_SIMPLE (may be useful for simple single-issue ARM cores where - * advanced prefetch intruduces heavy overhead) - * - * PREFETCH_TYPE_ADVANCED (useful for superscalar cores such as ARM Cortex-A8 - * which can run ARM and NEON instructions simultaneously so that extra ARM - * instructions do not add (many) extra cycles, but improve prefetch efficiency) - * - * Note: some types of function can't support advanced prefetch and fallback - * to simple one (those which handle 24bpp pixels) - */ -.set PREFETCH_TYPE_DEFAULT, PREFETCH_TYPE_ADVANCED - -/* Prefetch distance in pixels for simple prefetch */ -.set PREFETCH_DISTANCE_SIMPLE, 64 - -/* - * Implementation of pixman_composite_over_8888_0565_asm_neon - * - * This function takes a8r8g8b8 source buffer, r5g6b5 destination buffer and - * performs OVER compositing operation. Function fast_composite_over_8888_0565 - * from pixman-fast-path.c does the same in C and can be used as a reference. - * - * First we need to have some NEON assembly code which can do the actual - * operation on the pixels and provide it to the template macro. - * - * Template macro quite conveniently takes care of emitting all the necessary - * code for memory reading and writing (including quite tricky cases of - * handling unaligned leading/trailing pixels), so we only need to deal with - * the data in NEON registers. - * - * NEON registers allocation in general is recommented to be the following: - * d0, d1, d2, d3 - contain loaded source pixel data - * d4, d5, d6, d7 - contain loaded destination pixels (if they are needed) - * d24, d25, d26, d27 - contain loading mask pixel data (if mask is used) - * d28, d29, d30, d31 - place for storing the result (destination pixels) - * - * As can be seen above, four 64-bit NEON registers are used for keeping - * intermediate pixel data and up to 8 pixels can be processed in one step - * for 32bpp formats (16 pixels for 16bpp, 32 pixels for 8bpp). - * - * This particular function uses the following registers allocation: - * d0, d1, d2, d3 - contain loaded source pixel data - * d4, d5 - contain loaded destination pixels (they are needed) - * d28, d29 - place for storing the result (destination pixels) - */ - -/* - * Step one. We need to have some code to do some arithmetics on pixel data. - * This is implemented as a pair of macros: '*_head' and '*_tail'. When used - * back-to-back, they take pixel data from {d0, d1, d2, d3} and {d4, d5}, - * perform all the needed calculations and write the result to {d28, d29}. - * The rationale for having two macros and not just one will be explained - * later. In practice, any single monolitic function which does the work can - * be split into two parts in any arbitrary way without affecting correctness. - * - * There is one special trick here too. Common template macro can optionally - * make our life a bit easier by doing R, G, B, A color components - * deinterleaving for 32bpp pixel formats (and this feature is used in - * 'pixman_composite_over_8888_0565_asm_neon' function). So it means that - * instead of having 8 packed pixels in {d0, d1, d2, d3} registers, we - * actually use d0 register for blue channel (a vector of eight 8-bit - * values), d1 register for green, d2 for red and d3 for alpha. This - * simple conversion can be also done with a few NEON instructions: - * - * Packed to planar conversion: - * vuzp.8 d0, d1 - * vuzp.8 d2, d3 - * vuzp.8 d1, d3 - * vuzp.8 d0, d2 - * - * Planar to packed conversion: - * vzip.8 d0, d2 - * vzip.8 d1, d3 - * vzip.8 d2, d3 - * vzip.8 d0, d1 - * - * But pixel can be loaded directly in planar format using VLD4.8 NEON - * instruction. It is 1 cycle slower than VLD1.32, so this is not always - * desirable, that's why deinterleaving is optional. - * - * But anyway, here is the code: - */ -.macro pixman_composite_over_8888_0565_process_pixblock_head - /* convert 8 r5g6b5 pixel data from {d4, d5} to planar 8-bit format - and put data into d6 - red, d7 - green, d30 - blue */ - vshrn.u16 d6, q2, #8 - vshrn.u16 d7, q2, #3 - vsli.u16 q2, q2, #5 - vsri.u8 d6, d6, #5 - vmvn.8 d3, d3 /* invert source alpha */ - vsri.u8 d7, d7, #6 - vshrn.u16 d30, q2, #2 - /* now do alpha blending, storing results in 8-bit planar format - into d16 - red, d19 - green, d18 - blue */ - vmull.u8 q10, d3, d6 - vmull.u8 q11, d3, d7 - vmull.u8 q12, d3, d30 - vrshr.u16 q13, q10, #8 - vrshr.u16 q3, q11, #8 - vrshr.u16 q15, q12, #8 - vraddhn.u16 d20, q10, q13 - vraddhn.u16 d23, q11, q3 - vraddhn.u16 d22, q12, q15 -.endm - -.macro pixman_composite_over_8888_0565_process_pixblock_tail - /* ... continue alpha blending */ - vqadd.u8 d16, d2, d20 - vqadd.u8 q9, q0, q11 - /* convert the result to r5g6b5 and store it into {d28, d29} */ - vshll.u8 q14, d16, #8 - vshll.u8 q8, d19, #8 - vshll.u8 q9, d18, #8 - vsri.u16 q14, q8, #5 - vsri.u16 q14, q9, #11 -.endm - -/* - * OK, now we got almost everything that we need. Using the above two - * macros, the work can be done right. But now we want to optimize - * it a bit. ARM Cortex-A8 is an in-order core, and benefits really - * a lot from good code scheduling and software pipelining. - * - * Let's construct some code, which will run in the core main loop. - * Some pseudo-code of the main loop will look like this: - * head - * while (...) { - * tail - * head - * } - * tail - * - * It may look a bit weird, but this setup allows to hide instruction - * latencies better and also utilize dual-issue capability more - * efficiently (make pairs of load-store and ALU instructions). - * - * So what we need now is a '*_tail_head' macro, which will be used - * in the core main loop. A trivial straightforward implementation - * of this macro would look like this: - * - * pixman_composite_over_8888_0565_process_pixblock_tail - * vst1.16 {d28, d29}, [DST_W, :128]! - * vld1.16 {d4, d5}, [DST_R, :128]! - * vld4.32 {d0, d1, d2, d3}, [SRC]! - * pixman_composite_over_8888_0565_process_pixblock_head - * cache_preload 8, 8 - * - * Now it also got some VLD/VST instructions. We simply can't move from - * processing one block of pixels to the other one with just arithmetics. - * The previously processed data needs to be written to memory and new - * data needs to be fetched. Fortunately, this main loop does not deal - * with partial leading/trailing pixels and can load/store a full block - * of pixels in a bulk. Additionally, destination buffer is already - * 16 bytes aligned here (which is good for performance). - * - * New things here are DST_R, DST_W, SRC and MASK identifiers. These - * are the aliases for ARM registers which are used as pointers for - * accessing data. We maintain separate pointers for reading and writing - * destination buffer (DST_R and DST_W). - * - * Another new thing is 'cache_preload' macro. It is used for prefetching - * data into CPU L2 cache and improve performance when dealing with large - * images which are far larger than cache size. It uses one argument - * (actually two, but they need to be the same here) - number of pixels - * in a block. Looking into 'pixman-arm-neon-asm.h' can provide some - * details about this macro. Moreover, if good performance is needed - * the code from this macro needs to be copied into '*_tail_head' macro - * and mixed with the rest of code for optimal instructions scheduling. - * We are actually doing it below. - * - * Now after all the explanations, here is the optimized code. - * Different instruction streams (originaling from '*_head', '*_tail' - * and 'cache_preload' macro) use different indentation levels for - * better readability. Actually taking the code from one of these - * indentation levels and ignoring a few VLD/VST instructions would - * result in exactly the code from '*_head', '*_tail' or 'cache_preload' - * macro! - */ - -#if 1 - -.macro pixman_composite_over_8888_0565_process_pixblock_tail_head - vqadd.u8 d16, d2, d20 - vld1.16 {d4, d5}, [DST_R, :128]! - vqadd.u8 q9, q0, q11 - vshrn.u16 d6, q2, #8 - fetch_src_pixblock - vshrn.u16 d7, q2, #3 - vsli.u16 q2, q2, #5 - vshll.u8 q14, d16, #8 - PF add PF_X, PF_X, #8 - vshll.u8 q8, d19, #8 - PF tst PF_CTL, #0xF - vsri.u8 d6, d6, #5 - PF addne PF_X, PF_X, #8 - vmvn.8 d3, d3 - PF subne PF_CTL, PF_CTL, #1 - vsri.u8 d7, d7, #6 - vshrn.u16 d30, q2, #2 - vmull.u8 q10, d3, d6 - PF pld, [PF_SRC, PF_X, lsl #src_bpp_shift] - vmull.u8 q11, d3, d7 - vmull.u8 q12, d3, d30 - PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift] - vsri.u16 q14, q8, #5 - PF cmp PF_X, ORIG_W - vshll.u8 q9, d18, #8 - vrshr.u16 q13, q10, #8 - PF subge PF_X, PF_X, ORIG_W - vrshr.u16 q3, q11, #8 - vrshr.u16 q15, q12, #8 - PF subges PF_CTL, PF_CTL, #0x10 - vsri.u16 q14, q9, #11 - PF ldrgeb DUMMY, [PF_SRC, SRC_STRIDE, lsl #src_bpp_shift]! - vraddhn.u16 d20, q10, q13 - vraddhn.u16 d23, q11, q3 - PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]! - vraddhn.u16 d22, q12, q15 - vst1.16 {d28, d29}, [DST_W, :128]! -.endm - -#else - -/* If we did not care much about the performance, we would just use this... */ -.macro pixman_composite_over_8888_0565_process_pixblock_tail_head - pixman_composite_over_8888_0565_process_pixblock_tail - vst1.16 {d28, d29}, [DST_W, :128]! - vld1.16 {d4, d5}, [DST_R, :128]! - fetch_src_pixblock - pixman_composite_over_8888_0565_process_pixblock_head - cache_preload 8, 8 -.endm - -#endif - -/* - * And now the final part. We are using 'generate_composite_function' macro - * to put all the stuff together. We are specifying the name of the function - * which we want to get, number of bits per pixel for the source, mask and - * destination (0 if unused, like mask in this case). Next come some bit - * flags: - * FLAG_DST_READWRITE - tells that the destination buffer is both read - * and written, for write-only buffer we would use - * FLAG_DST_WRITEONLY flag instead - * FLAG_DEINTERLEAVE_32BPP - tells that we prefer to work with planar data - * and separate color channels for 32bpp format. - * The next things are: - * - the number of pixels processed per iteration (8 in this case, because - * that's the maximum what can fit into four 64-bit NEON registers). - * - prefetch distance, measured in pixel blocks. In this case it is 5 times - * by 8 pixels. That would be 40 pixels, or up to 160 bytes. Optimal - * prefetch distance can be selected by running some benchmarks. - * - * After that we specify some macros, these are 'default_init', - * 'default_cleanup' here which are empty (but it is possible to have custom - * init/cleanup macros to be able to save/restore some extra NEON registers - * like d8-d15 or do anything else) followed by - * 'pixman_composite_over_8888_0565_process_pixblock_head', - * 'pixman_composite_over_8888_0565_process_pixblock_tail' and - * 'pixman_composite_over_8888_0565_process_pixblock_tail_head' - * which we got implemented above. - * - * The last part is the NEON registers allocation scheme. - */ -generate_composite_function \ - pixman_composite_over_8888_0565_asm_neon, 32, 0, 16, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - default_init, \ - default_cleanup, \ - pixman_composite_over_8888_0565_process_pixblock_head, \ - pixman_composite_over_8888_0565_process_pixblock_tail, \ - pixman_composite_over_8888_0565_process_pixblock_tail_head, \ - 28, /* dst_w_basereg */ \ - 4, /* dst_r_basereg */ \ - 0, /* src_basereg */ \ - 24 /* mask_basereg */ - -/******************************************************************************/ - -.macro pixman_composite_over_n_0565_process_pixblock_head - /* convert 8 r5g6b5 pixel data from {d4, d5} to planar 8-bit format - and put data into d6 - red, d7 - green, d30 - blue */ - vshrn.u16 d6, q2, #8 - vshrn.u16 d7, q2, #3 - vsli.u16 q2, q2, #5 - vsri.u8 d6, d6, #5 - vsri.u8 d7, d7, #6 - vshrn.u16 d30, q2, #2 - /* now do alpha blending, storing results in 8-bit planar format - into d16 - red, d19 - green, d18 - blue */ - vmull.u8 q10, d3, d6 - vmull.u8 q11, d3, d7 - vmull.u8 q12, d3, d30 - vrshr.u16 q13, q10, #8 - vrshr.u16 q3, q11, #8 - vrshr.u16 q15, q12, #8 - vraddhn.u16 d20, q10, q13 - vraddhn.u16 d23, q11, q3 - vraddhn.u16 d22, q12, q15 -.endm - -.macro pixman_composite_over_n_0565_process_pixblock_tail - /* ... continue alpha blending */ - vqadd.u8 d16, d2, d20 - vqadd.u8 q9, q0, q11 - /* convert the result to r5g6b5 and store it into {d28, d29} */ - vshll.u8 q14, d16, #8 - vshll.u8 q8, d19, #8 - vshll.u8 q9, d18, #8 - vsri.u16 q14, q8, #5 - vsri.u16 q14, q9, #11 -.endm - -/* TODO: expand macros and do better instructions scheduling */ -.macro pixman_composite_over_n_0565_process_pixblock_tail_head - pixman_composite_over_n_0565_process_pixblock_tail - vld1.16 {d4, d5}, [DST_R, :128]! - vst1.16 {d28, d29}, [DST_W, :128]! - pixman_composite_over_n_0565_process_pixblock_head - cache_preload 8, 8 -.endm - -.macro pixman_composite_over_n_0565_init - add DUMMY, sp, #ARGS_STACK_OFFSET - vld1.32 {d3[0]}, [DUMMY] - vdup.8 d0, d3[0] - vdup.8 d1, d3[1] - vdup.8 d2, d3[2] - vdup.8 d3, d3[3] - vmvn.8 d3, d3 /* invert source alpha */ -.endm - -generate_composite_function \ - pixman_composite_over_n_0565_asm_neon, 0, 0, 16, \ - FLAG_DST_READWRITE, \ - 8, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - pixman_composite_over_n_0565_init, \ - default_cleanup, \ - pixman_composite_over_n_0565_process_pixblock_head, \ - pixman_composite_over_n_0565_process_pixblock_tail, \ - pixman_composite_over_n_0565_process_pixblock_tail_head, \ - 28, /* dst_w_basereg */ \ - 4, /* dst_r_basereg */ \ - 0, /* src_basereg */ \ - 24 /* mask_basereg */ - -/******************************************************************************/ - -.macro pixman_composite_src_8888_0565_process_pixblock_head - vshll.u8 q8, d1, #8 - vshll.u8 q14, d2, #8 - vshll.u8 q9, d0, #8 -.endm - -.macro pixman_composite_src_8888_0565_process_pixblock_tail - vsri.u16 q14, q8, #5 - vsri.u16 q14, q9, #11 -.endm - -.macro pixman_composite_src_8888_0565_process_pixblock_tail_head - vsri.u16 q14, q8, #5 - PF add PF_X, PF_X, #8 - PF tst PF_CTL, #0xF - fetch_src_pixblock - PF addne PF_X, PF_X, #8 - PF subne PF_CTL, PF_CTL, #1 - vsri.u16 q14, q9, #11 - PF cmp PF_X, ORIG_W - PF pld, [PF_SRC, PF_X, lsl #src_bpp_shift] - vshll.u8 q8, d1, #8 - vst1.16 {d28, d29}, [DST_W, :128]! - PF subge PF_X, PF_X, ORIG_W - PF subges PF_CTL, PF_CTL, #0x10 - vshll.u8 q14, d2, #8 - PF ldrgeb DUMMY, [PF_SRC, SRC_STRIDE, lsl #src_bpp_shift]! - vshll.u8 q9, d0, #8 -.endm - -generate_composite_function \ - pixman_composite_src_8888_0565_asm_neon, 32, 0, 16, \ - FLAG_DST_WRITEONLY | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - 10, /* prefetch distance */ \ - default_init, \ - default_cleanup, \ - pixman_composite_src_8888_0565_process_pixblock_head, \ - pixman_composite_src_8888_0565_process_pixblock_tail, \ - pixman_composite_src_8888_0565_process_pixblock_tail_head - -/******************************************************************************/ - -.macro pixman_composite_src_0565_8888_process_pixblock_head - vshrn.u16 d30, q0, #8 - vshrn.u16 d29, q0, #3 - vsli.u16 q0, q0, #5 - vmov.u8 d31, #255 - vsri.u8 d30, d30, #5 - vsri.u8 d29, d29, #6 - vshrn.u16 d28, q0, #2 -.endm - -.macro pixman_composite_src_0565_8888_process_pixblock_tail -.endm - -/* TODO: expand macros and do better instructions scheduling */ -.macro pixman_composite_src_0565_8888_process_pixblock_tail_head - pixman_composite_src_0565_8888_process_pixblock_tail - vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! - fetch_src_pixblock - pixman_composite_src_0565_8888_process_pixblock_head - cache_preload 8, 8 -.endm - -generate_composite_function \ - pixman_composite_src_0565_8888_asm_neon, 16, 0, 32, \ - FLAG_DST_WRITEONLY | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - 10, /* prefetch distance */ \ - default_init, \ - default_cleanup, \ - pixman_composite_src_0565_8888_process_pixblock_head, \ - pixman_composite_src_0565_8888_process_pixblock_tail, \ - pixman_composite_src_0565_8888_process_pixblock_tail_head - -/******************************************************************************/ - -.macro pixman_composite_add_8_8_process_pixblock_head - vqadd.u8 q14, q0, q2 - vqadd.u8 q15, q1, q3 -.endm - -.macro pixman_composite_add_8_8_process_pixblock_tail -.endm - -.macro pixman_composite_add_8_8_process_pixblock_tail_head - fetch_src_pixblock - PF add PF_X, PF_X, #32 - PF tst PF_CTL, #0xF - vld1.8 {d4, d5, d6, d7}, [DST_R, :128]! - PF addne PF_X, PF_X, #32 - PF subne PF_CTL, PF_CTL, #1 - vst1.8 {d28, d29, d30, d31}, [DST_W, :128]! - PF cmp PF_X, ORIG_W - PF pld, [PF_SRC, PF_X, lsl #src_bpp_shift] - PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift] - PF subge PF_X, PF_X, ORIG_W - PF subges PF_CTL, PF_CTL, #0x10 - vqadd.u8 q14, q0, q2 - PF ldrgeb DUMMY, [PF_SRC, SRC_STRIDE, lsl #src_bpp_shift]! - PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]! - vqadd.u8 q15, q1, q3 -.endm - -generate_composite_function \ - pixman_composite_add_8_8_asm_neon, 8, 0, 8, \ - FLAG_DST_READWRITE, \ - 32, /* number of pixels, processed in a single block */ \ - 10, /* prefetch distance */ \ - default_init, \ - default_cleanup, \ - pixman_composite_add_8_8_process_pixblock_head, \ - pixman_composite_add_8_8_process_pixblock_tail, \ - pixman_composite_add_8_8_process_pixblock_tail_head - -/******************************************************************************/ - -.macro pixman_composite_add_8888_8888_process_pixblock_tail_head - fetch_src_pixblock - PF add PF_X, PF_X, #8 - PF tst PF_CTL, #0xF - vld1.32 {d4, d5, d6, d7}, [DST_R, :128]! - PF addne PF_X, PF_X, #8 - PF subne PF_CTL, PF_CTL, #1 - vst1.32 {d28, d29, d30, d31}, [DST_W, :128]! - PF cmp PF_X, ORIG_W - PF pld, [PF_SRC, PF_X, lsl #src_bpp_shift] - PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift] - PF subge PF_X, PF_X, ORIG_W - PF subges PF_CTL, PF_CTL, #0x10 - vqadd.u8 q14, q0, q2 - PF ldrgeb DUMMY, [PF_SRC, SRC_STRIDE, lsl #src_bpp_shift]! - PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]! - vqadd.u8 q15, q1, q3 -.endm - -generate_composite_function \ - pixman_composite_add_8888_8888_asm_neon, 32, 0, 32, \ - FLAG_DST_READWRITE, \ - 8, /* number of pixels, processed in a single block */ \ - 10, /* prefetch distance */ \ - default_init, \ - default_cleanup, \ - pixman_composite_add_8_8_process_pixblock_head, \ - pixman_composite_add_8_8_process_pixblock_tail, \ - pixman_composite_add_8888_8888_process_pixblock_tail_head - -generate_composite_function_single_scanline \ - pixman_composite_scanline_add_asm_neon, 32, 0, 32, \ - FLAG_DST_READWRITE, \ - 8, /* number of pixels, processed in a single block */ \ - default_init, \ - default_cleanup, \ - pixman_composite_add_8_8_process_pixblock_head, \ - pixman_composite_add_8_8_process_pixblock_tail, \ - pixman_composite_add_8888_8888_process_pixblock_tail_head - -/******************************************************************************/ - -.macro pixman_composite_out_reverse_8888_8888_process_pixblock_head - vmvn.8 d24, d3 /* get inverted alpha */ - /* do alpha blending */ - vmull.u8 q8, d24, d4 - vmull.u8 q9, d24, d5 - vmull.u8 q10, d24, d6 - vmull.u8 q11, d24, d7 -.endm - -.macro pixman_composite_out_reverse_8888_8888_process_pixblock_tail - vrshr.u16 q14, q8, #8 - vrshr.u16 q15, q9, #8 - vrshr.u16 q12, q10, #8 - vrshr.u16 q13, q11, #8 - vraddhn.u16 d28, q14, q8 - vraddhn.u16 d29, q15, q9 - vraddhn.u16 d30, q12, q10 - vraddhn.u16 d31, q13, q11 -.endm - -.macro pixman_composite_out_reverse_8888_8888_process_pixblock_tail_head - vld4.8 {d4, d5, d6, d7}, [DST_R, :128]! - vrshr.u16 q14, q8, #8 - PF add PF_X, PF_X, #8 - PF tst PF_CTL, #0xF - vrshr.u16 q15, q9, #8 - vrshr.u16 q12, q10, #8 - vrshr.u16 q13, q11, #8 - PF addne PF_X, PF_X, #8 - PF subne PF_CTL, PF_CTL, #1 - vraddhn.u16 d28, q14, q8 - vraddhn.u16 d29, q15, q9 - PF cmp PF_X, ORIG_W - vraddhn.u16 d30, q12, q10 - vraddhn.u16 d31, q13, q11 - fetch_src_pixblock - PF pld, [PF_SRC, PF_X, lsl #src_bpp_shift] - vmvn.8 d22, d3 - PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift] - vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! - PF subge PF_X, PF_X, ORIG_W - vmull.u8 q8, d22, d4 - PF subges PF_CTL, PF_CTL, #0x10 - vmull.u8 q9, d22, d5 - PF ldrgeb DUMMY, [PF_SRC, SRC_STRIDE, lsl #src_bpp_shift]! - vmull.u8 q10, d22, d6 - PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]! - vmull.u8 q11, d22, d7 -.endm - -generate_composite_function_single_scanline \ - pixman_composite_scanline_out_reverse_asm_neon, 32, 0, 32, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - default_init, \ - default_cleanup, \ - pixman_composite_out_reverse_8888_8888_process_pixblock_head, \ - pixman_composite_out_reverse_8888_8888_process_pixblock_tail, \ - pixman_composite_out_reverse_8888_8888_process_pixblock_tail_head - -/******************************************************************************/ - -.macro pixman_composite_over_8888_8888_process_pixblock_head - pixman_composite_out_reverse_8888_8888_process_pixblock_head -.endm - -.macro pixman_composite_over_8888_8888_process_pixblock_tail - pixman_composite_out_reverse_8888_8888_process_pixblock_tail - vqadd.u8 q14, q0, q14 - vqadd.u8 q15, q1, q15 -.endm - -.macro pixman_composite_over_8888_8888_process_pixblock_tail_head - vld4.8 {d4, d5, d6, d7}, [DST_R, :128]! - vrshr.u16 q14, q8, #8 - PF add PF_X, PF_X, #8 - PF tst PF_CTL, #0xF - vrshr.u16 q15, q9, #8 - vrshr.u16 q12, q10, #8 - vrshr.u16 q13, q11, #8 - PF addne PF_X, PF_X, #8 - PF subne PF_CTL, PF_CTL, #1 - vraddhn.u16 d28, q14, q8 - vraddhn.u16 d29, q15, q9 - PF cmp PF_X, ORIG_W - vraddhn.u16 d30, q12, q10 - vraddhn.u16 d31, q13, q11 - vqadd.u8 q14, q0, q14 - vqadd.u8 q15, q1, q15 - fetch_src_pixblock - PF pld, [PF_SRC, PF_X, lsl #src_bpp_shift] - vmvn.8 d22, d3 - PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift] - vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! - PF subge PF_X, PF_X, ORIG_W - vmull.u8 q8, d22, d4 - PF subges PF_CTL, PF_CTL, #0x10 - vmull.u8 q9, d22, d5 - PF ldrgeb DUMMY, [PF_SRC, SRC_STRIDE, lsl #src_bpp_shift]! - vmull.u8 q10, d22, d6 - PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]! - vmull.u8 q11, d22, d7 -.endm - -generate_composite_function \ - pixman_composite_over_8888_8888_asm_neon, 32, 0, 32, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - default_init, \ - default_cleanup, \ - pixman_composite_over_8888_8888_process_pixblock_head, \ - pixman_composite_over_8888_8888_process_pixblock_tail, \ - pixman_composite_over_8888_8888_process_pixblock_tail_head - -generate_composite_function_single_scanline \ - pixman_composite_scanline_over_asm_neon, 32, 0, 32, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - default_init, \ - default_cleanup, \ - pixman_composite_over_8888_8888_process_pixblock_head, \ - pixman_composite_over_8888_8888_process_pixblock_tail, \ - pixman_composite_over_8888_8888_process_pixblock_tail_head - -/******************************************************************************/ - -.macro pixman_composite_over_n_8888_process_pixblock_head - /* deinterleaved source pixels in {d0, d1, d2, d3} */ - /* inverted alpha in {d24} */ - /* destination pixels in {d4, d5, d6, d7} */ - vmull.u8 q8, d24, d4 - vmull.u8 q9, d24, d5 - vmull.u8 q10, d24, d6 - vmull.u8 q11, d24, d7 -.endm - -.macro pixman_composite_over_n_8888_process_pixblock_tail - vrshr.u16 q14, q8, #8 - vrshr.u16 q15, q9, #8 - vrshr.u16 q2, q10, #8 - vrshr.u16 q3, q11, #8 - vraddhn.u16 d28, q14, q8 - vraddhn.u16 d29, q15, q9 - vraddhn.u16 d30, q2, q10 - vraddhn.u16 d31, q3, q11 - vqadd.u8 q14, q0, q14 - vqadd.u8 q15, q1, q15 -.endm - -.macro pixman_composite_over_n_8888_process_pixblock_tail_head - vrshr.u16 q14, q8, #8 - vrshr.u16 q15, q9, #8 - vrshr.u16 q2, q10, #8 - vrshr.u16 q3, q11, #8 - vraddhn.u16 d28, q14, q8 - vraddhn.u16 d29, q15, q9 - vraddhn.u16 d30, q2, q10 - vraddhn.u16 d31, q3, q11 - vld4.8 {d4, d5, d6, d7}, [DST_R, :128]! - vqadd.u8 q14, q0, q14 - PF add PF_X, PF_X, #8 - PF tst PF_CTL, #0x0F - PF addne PF_X, PF_X, #8 - PF subne PF_CTL, PF_CTL, #1 - vqadd.u8 q15, q1, q15 - PF cmp PF_X, ORIG_W - vmull.u8 q8, d24, d4 - PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift] - vmull.u8 q9, d24, d5 - PF subge PF_X, PF_X, ORIG_W - vmull.u8 q10, d24, d6 - PF subges PF_CTL, PF_CTL, #0x10 - vmull.u8 q11, d24, d7 - PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]! - vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! -.endm - -.macro pixman_composite_over_n_8888_init - add DUMMY, sp, #ARGS_STACK_OFFSET - vld1.32 {d3[0]}, [DUMMY] - vdup.8 d0, d3[0] - vdup.8 d1, d3[1] - vdup.8 d2, d3[2] - vdup.8 d3, d3[3] - vmvn.8 d24, d3 /* get inverted alpha */ -.endm - -generate_composite_function \ - pixman_composite_over_n_8888_asm_neon, 0, 0, 32, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - pixman_composite_over_n_8888_init, \ - default_cleanup, \ - pixman_composite_over_8888_8888_process_pixblock_head, \ - pixman_composite_over_8888_8888_process_pixblock_tail, \ - pixman_composite_over_n_8888_process_pixblock_tail_head - -/******************************************************************************/ - -.macro pixman_composite_over_reverse_n_8888_process_pixblock_tail_head - vrshr.u16 q14, q8, #8 - PF add PF_X, PF_X, #8 - PF tst PF_CTL, #0xF - vrshr.u16 q15, q9, #8 - vrshr.u16 q12, q10, #8 - vrshr.u16 q13, q11, #8 - PF addne PF_X, PF_X, #8 - PF subne PF_CTL, PF_CTL, #1 - vraddhn.u16 d28, q14, q8 - vraddhn.u16 d29, q15, q9 - PF cmp PF_X, ORIG_W - vraddhn.u16 d30, q12, q10 - vraddhn.u16 d31, q13, q11 - vqadd.u8 q14, q0, q14 - vqadd.u8 q15, q1, q15 - vld4.8 {d0, d1, d2, d3}, [DST_R, :128]! - vmvn.8 d22, d3 - PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift] - vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! - PF subge PF_X, PF_X, ORIG_W - vmull.u8 q8, d22, d4 - PF subges PF_CTL, PF_CTL, #0x10 - vmull.u8 q9, d22, d5 - vmull.u8 q10, d22, d6 - PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]! - vmull.u8 q11, d22, d7 -.endm - -.macro pixman_composite_over_reverse_n_8888_init - add DUMMY, sp, #ARGS_STACK_OFFSET - vld1.32 {d7[0]}, [DUMMY] - vdup.8 d4, d7[0] - vdup.8 d5, d7[1] - vdup.8 d6, d7[2] - vdup.8 d7, d7[3] -.endm - -generate_composite_function \ - pixman_composite_over_reverse_n_8888_asm_neon, 0, 0, 32, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - pixman_composite_over_reverse_n_8888_init, \ - default_cleanup, \ - pixman_composite_over_8888_8888_process_pixblock_head, \ - pixman_composite_over_8888_8888_process_pixblock_tail, \ - pixman_composite_over_reverse_n_8888_process_pixblock_tail_head, \ - 28, /* dst_w_basereg */ \ - 0, /* dst_r_basereg */ \ - 4, /* src_basereg */ \ - 24 /* mask_basereg */ - -/******************************************************************************/ - -.macro pixman_composite_over_8888_8_0565_process_pixblock_head - vmull.u8 q0, d24, d8 /* IN for SRC pixels (part1) */ - vmull.u8 q1, d24, d9 - vmull.u8 q6, d24, d10 - vmull.u8 q7, d24, d11 - vshrn.u16 d6, q2, #8 /* convert DST_R data to 32-bpp (part1) */ - vshrn.u16 d7, q2, #3 - vsli.u16 q2, q2, #5 - vrshr.u16 q8, q0, #8 /* IN for SRC pixels (part2) */ - vrshr.u16 q9, q1, #8 - vrshr.u16 q10, q6, #8 - vrshr.u16 q11, q7, #8 - vraddhn.u16 d0, q0, q8 - vraddhn.u16 d1, q1, q9 - vraddhn.u16 d2, q6, q10 - vraddhn.u16 d3, q7, q11 - vsri.u8 d6, d6, #5 /* convert DST_R data to 32-bpp (part2) */ - vsri.u8 d7, d7, #6 - vmvn.8 d3, d3 - vshrn.u16 d30, q2, #2 - vmull.u8 q8, d3, d6 /* now do alpha blending */ - vmull.u8 q9, d3, d7 - vmull.u8 q10, d3, d30 -.endm - -.macro pixman_composite_over_8888_8_0565_process_pixblock_tail - /* 3 cycle bubble (after vmull.u8) */ - vrshr.u16 q13, q8, #8 - vrshr.u16 q11, q9, #8 - vrshr.u16 q15, q10, #8 - vraddhn.u16 d16, q8, q13 - vraddhn.u16 d27, q9, q11 - vraddhn.u16 d26, q10, q15 - vqadd.u8 d16, d2, d16 - /* 1 cycle bubble */ - vqadd.u8 q9, q0, q13 - vshll.u8 q14, d16, #8 /* convert to 16bpp */ - vshll.u8 q8, d19, #8 - vshll.u8 q9, d18, #8 - vsri.u16 q14, q8, #5 - /* 1 cycle bubble */ - vsri.u16 q14, q9, #11 -.endm - -.macro pixman_composite_over_8888_8_0565_process_pixblock_tail_head - vld1.16 {d4, d5}, [DST_R, :128]! - vshrn.u16 d6, q2, #8 - fetch_mask_pixblock - vshrn.u16 d7, q2, #3 - fetch_src_pixblock - vmull.u8 q6, d24, d10 - vrshr.u16 q13, q8, #8 - vrshr.u16 q11, q9, #8 - vrshr.u16 q15, q10, #8 - vraddhn.u16 d16, q8, q13 - vraddhn.u16 d27, q9, q11 - vraddhn.u16 d26, q10, q15 - vqadd.u8 d16, d2, d16 - vmull.u8 q1, d24, d9 - vqadd.u8 q9, q0, q13 - vshll.u8 q14, d16, #8 - vmull.u8 q0, d24, d8 - vshll.u8 q8, d19, #8 - vshll.u8 q9, d18, #8 - vsri.u16 q14, q8, #5 - vmull.u8 q7, d24, d11 - vsri.u16 q14, q9, #11 - - cache_preload 8, 8 - - vsli.u16 q2, q2, #5 - vrshr.u16 q8, q0, #8 - vrshr.u16 q9, q1, #8 - vrshr.u16 q10, q6, #8 - vrshr.u16 q11, q7, #8 - vraddhn.u16 d0, q0, q8 - vraddhn.u16 d1, q1, q9 - vraddhn.u16 d2, q6, q10 - vraddhn.u16 d3, q7, q11 - vsri.u8 d6, d6, #5 - vsri.u8 d7, d7, #6 - vmvn.8 d3, d3 - vshrn.u16 d30, q2, #2 - vst1.16 {d28, d29}, [DST_W, :128]! - vmull.u8 q8, d3, d6 - vmull.u8 q9, d3, d7 - vmull.u8 q10, d3, d30 -.endm - -generate_composite_function \ - pixman_composite_over_8888_8_0565_asm_neon, 32, 8, 16, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - default_init_need_all_regs, \ - default_cleanup_need_all_regs, \ - pixman_composite_over_8888_8_0565_process_pixblock_head, \ - pixman_composite_over_8888_8_0565_process_pixblock_tail, \ - pixman_composite_over_8888_8_0565_process_pixblock_tail_head, \ - 28, /* dst_w_basereg */ \ - 4, /* dst_r_basereg */ \ - 8, /* src_basereg */ \ - 24 /* mask_basereg */ - -/******************************************************************************/ - -/* - * This function needs a special initialization of solid mask. - * Solid source pixel data is fetched from stack at ARGS_STACK_OFFSET - * offset, split into color components and replicated in d8-d11 - * registers. Additionally, this function needs all the NEON registers, - * so it has to save d8-d15 registers which are callee saved according - * to ABI. These registers are restored from 'cleanup' macro. All the - * other NEON registers are caller saved, so can be clobbered freely - * without introducing any problems. - */ -.macro pixman_composite_over_n_8_0565_init - add DUMMY, sp, #ARGS_STACK_OFFSET - vpush {d8-d15} - vld1.32 {d11[0]}, [DUMMY] - vdup.8 d8, d11[0] - vdup.8 d9, d11[1] - vdup.8 d10, d11[2] - vdup.8 d11, d11[3] -.endm - -.macro pixman_composite_over_n_8_0565_cleanup - vpop {d8-d15} -.endm - -generate_composite_function \ - pixman_composite_over_n_8_0565_asm_neon, 0, 8, 16, \ - FLAG_DST_READWRITE, \ - 8, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - pixman_composite_over_n_8_0565_init, \ - pixman_composite_over_n_8_0565_cleanup, \ - pixman_composite_over_8888_8_0565_process_pixblock_head, \ - pixman_composite_over_8888_8_0565_process_pixblock_tail, \ - pixman_composite_over_8888_8_0565_process_pixblock_tail_head - -/******************************************************************************/ - -.macro pixman_composite_over_8888_n_0565_init - add DUMMY, sp, #(ARGS_STACK_OFFSET + 8) - vpush {d8-d15} - vld1.32 {d24[0]}, [DUMMY] - vdup.8 d24, d24[3] -.endm - -.macro pixman_composite_over_8888_n_0565_cleanup - vpop {d8-d15} -.endm - -generate_composite_function \ - pixman_composite_over_8888_n_0565_asm_neon, 32, 0, 16, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - pixman_composite_over_8888_n_0565_init, \ - pixman_composite_over_8888_n_0565_cleanup, \ - pixman_composite_over_8888_8_0565_process_pixblock_head, \ - pixman_composite_over_8888_8_0565_process_pixblock_tail, \ - pixman_composite_over_8888_8_0565_process_pixblock_tail_head, \ - 28, /* dst_w_basereg */ \ - 4, /* dst_r_basereg */ \ - 8, /* src_basereg */ \ - 24 /* mask_basereg */ - -/******************************************************************************/ - -.macro pixman_composite_src_0565_0565_process_pixblock_head -.endm - -.macro pixman_composite_src_0565_0565_process_pixblock_tail -.endm - -.macro pixman_composite_src_0565_0565_process_pixblock_tail_head - vst1.16 {d0, d1, d2, d3}, [DST_W, :128]! - fetch_src_pixblock - cache_preload 16, 16 -.endm - -generate_composite_function \ - pixman_composite_src_0565_0565_asm_neon, 16, 0, 16, \ - FLAG_DST_WRITEONLY, \ - 16, /* number of pixels, processed in a single block */ \ - 10, /* prefetch distance */ \ - default_init, \ - default_cleanup, \ - pixman_composite_src_0565_0565_process_pixblock_head, \ - pixman_composite_src_0565_0565_process_pixblock_tail, \ - pixman_composite_src_0565_0565_process_pixblock_tail_head, \ - 0, /* dst_w_basereg */ \ - 0, /* dst_r_basereg */ \ - 0, /* src_basereg */ \ - 0 /* mask_basereg */ - -/******************************************************************************/ - -.macro pixman_composite_src_n_8_process_pixblock_head -.endm - -.macro pixman_composite_src_n_8_process_pixblock_tail -.endm - -.macro pixman_composite_src_n_8_process_pixblock_tail_head - vst1.8 {d0, d1, d2, d3}, [DST_W, :128]! -.endm - -.macro pixman_composite_src_n_8_init - add DUMMY, sp, #ARGS_STACK_OFFSET - vld1.32 {d0[0]}, [DUMMY] - vsli.u64 d0, d0, #8 - vsli.u64 d0, d0, #16 - vsli.u64 d0, d0, #32 - vorr d1, d0, d0 - vorr q1, q0, q0 -.endm - -.macro pixman_composite_src_n_8_cleanup -.endm - -generate_composite_function \ - pixman_composite_src_n_8_asm_neon, 0, 0, 8, \ - FLAG_DST_WRITEONLY, \ - 32, /* number of pixels, processed in a single block */ \ - 0, /* prefetch distance */ \ - pixman_composite_src_n_8_init, \ - pixman_composite_src_n_8_cleanup, \ - pixman_composite_src_n_8_process_pixblock_head, \ - pixman_composite_src_n_8_process_pixblock_tail, \ - pixman_composite_src_n_8_process_pixblock_tail_head, \ - 0, /* dst_w_basereg */ \ - 0, /* dst_r_basereg */ \ - 0, /* src_basereg */ \ - 0 /* mask_basereg */ - -/******************************************************************************/ - -.macro pixman_composite_src_n_0565_process_pixblock_head -.endm - -.macro pixman_composite_src_n_0565_process_pixblock_tail -.endm - -.macro pixman_composite_src_n_0565_process_pixblock_tail_head - vst1.16 {d0, d1, d2, d3}, [DST_W, :128]! -.endm - -.macro pixman_composite_src_n_0565_init - add DUMMY, sp, #ARGS_STACK_OFFSET - vld1.32 {d0[0]}, [DUMMY] - vsli.u64 d0, d0, #16 - vsli.u64 d0, d0, #32 - vorr d1, d0, d0 - vorr q1, q0, q0 -.endm - -.macro pixman_composite_src_n_0565_cleanup -.endm - -generate_composite_function \ - pixman_composite_src_n_0565_asm_neon, 0, 0, 16, \ - FLAG_DST_WRITEONLY, \ - 16, /* number of pixels, processed in a single block */ \ - 0, /* prefetch distance */ \ - pixman_composite_src_n_0565_init, \ - pixman_composite_src_n_0565_cleanup, \ - pixman_composite_src_n_0565_process_pixblock_head, \ - pixman_composite_src_n_0565_process_pixblock_tail, \ - pixman_composite_src_n_0565_process_pixblock_tail_head, \ - 0, /* dst_w_basereg */ \ - 0, /* dst_r_basereg */ \ - 0, /* src_basereg */ \ - 0 /* mask_basereg */ - -/******************************************************************************/ - -.macro pixman_composite_src_n_8888_process_pixblock_head -.endm - -.macro pixman_composite_src_n_8888_process_pixblock_tail -.endm - -.macro pixman_composite_src_n_8888_process_pixblock_tail_head - vst1.32 {d0, d1, d2, d3}, [DST_W, :128]! -.endm - -.macro pixman_composite_src_n_8888_init - add DUMMY, sp, #ARGS_STACK_OFFSET - vld1.32 {d0[0]}, [DUMMY] - vsli.u64 d0, d0, #32 - vorr d1, d0, d0 - vorr q1, q0, q0 -.endm - -.macro pixman_composite_src_n_8888_cleanup -.endm - -generate_composite_function \ - pixman_composite_src_n_8888_asm_neon, 0, 0, 32, \ - FLAG_DST_WRITEONLY, \ - 8, /* number of pixels, processed in a single block */ \ - 0, /* prefetch distance */ \ - pixman_composite_src_n_8888_init, \ - pixman_composite_src_n_8888_cleanup, \ - pixman_composite_src_n_8888_process_pixblock_head, \ - pixman_composite_src_n_8888_process_pixblock_tail, \ - pixman_composite_src_n_8888_process_pixblock_tail_head, \ - 0, /* dst_w_basereg */ \ - 0, /* dst_r_basereg */ \ - 0, /* src_basereg */ \ - 0 /* mask_basereg */ - -/******************************************************************************/ - -.macro pixman_composite_src_8888_8888_process_pixblock_head -.endm - -.macro pixman_composite_src_8888_8888_process_pixblock_tail -.endm - -.macro pixman_composite_src_8888_8888_process_pixblock_tail_head - vst1.32 {d0, d1, d2, d3}, [DST_W, :128]! - fetch_src_pixblock - cache_preload 8, 8 -.endm - -generate_composite_function \ - pixman_composite_src_8888_8888_asm_neon, 32, 0, 32, \ - FLAG_DST_WRITEONLY, \ - 8, /* number of pixels, processed in a single block */ \ - 10, /* prefetch distance */ \ - default_init, \ - default_cleanup, \ - pixman_composite_src_8888_8888_process_pixblock_head, \ - pixman_composite_src_8888_8888_process_pixblock_tail, \ - pixman_composite_src_8888_8888_process_pixblock_tail_head, \ - 0, /* dst_w_basereg */ \ - 0, /* dst_r_basereg */ \ - 0, /* src_basereg */ \ - 0 /* mask_basereg */ - -/******************************************************************************/ - -.macro pixman_composite_src_x888_8888_process_pixblock_head - vorr q0, q0, q2 - vorr q1, q1, q2 -.endm - -.macro pixman_composite_src_x888_8888_process_pixblock_tail -.endm - -.macro pixman_composite_src_x888_8888_process_pixblock_tail_head - vst1.32 {d0, d1, d2, d3}, [DST_W, :128]! - fetch_src_pixblock - vorr q0, q0, q2 - vorr q1, q1, q2 - cache_preload 8, 8 -.endm - -.macro pixman_composite_src_x888_8888_init - vmov.u8 q2, #0xFF - vshl.u32 q2, q2, #24 -.endm - -generate_composite_function \ - pixman_composite_src_x888_8888_asm_neon, 32, 0, 32, \ - FLAG_DST_WRITEONLY, \ - 8, /* number of pixels, processed in a single block */ \ - 10, /* prefetch distance */ \ - pixman_composite_src_x888_8888_init, \ - default_cleanup, \ - pixman_composite_src_x888_8888_process_pixblock_head, \ - pixman_composite_src_x888_8888_process_pixblock_tail, \ - pixman_composite_src_x888_8888_process_pixblock_tail_head, \ - 0, /* dst_w_basereg */ \ - 0, /* dst_r_basereg */ \ - 0, /* src_basereg */ \ - 0 /* mask_basereg */ - -/******************************************************************************/ - -.macro pixman_composite_src_n_8_8888_process_pixblock_head - /* expecting solid source in {d0, d1, d2, d3} */ - /* mask is in d24 (d25, d26, d27 are unused) */ - - /* in */ - vmull.u8 q8, d24, d0 - vmull.u8 q9, d24, d1 - vmull.u8 q10, d24, d2 - vmull.u8 q11, d24, d3 - vrsra.u16 q8, q8, #8 - vrsra.u16 q9, q9, #8 - vrsra.u16 q10, q10, #8 - vrsra.u16 q11, q11, #8 -.endm - -.macro pixman_composite_src_n_8_8888_process_pixblock_tail - vrshrn.u16 d28, q8, #8 - vrshrn.u16 d29, q9, #8 - vrshrn.u16 d30, q10, #8 - vrshrn.u16 d31, q11, #8 -.endm - -.macro pixman_composite_src_n_8_8888_process_pixblock_tail_head - fetch_mask_pixblock - PF add PF_X, PF_X, #8 - vrshrn.u16 d28, q8, #8 - PF tst PF_CTL, #0x0F - vrshrn.u16 d29, q9, #8 - PF addne PF_X, PF_X, #8 - vrshrn.u16 d30, q10, #8 - PF subne PF_CTL, PF_CTL, #1 - vrshrn.u16 d31, q11, #8 - PF cmp PF_X, ORIG_W - vmull.u8 q8, d24, d0 - PF pld, [PF_MASK, PF_X, lsl #mask_bpp_shift] - vmull.u8 q9, d24, d1 - PF subge PF_X, PF_X, ORIG_W - vmull.u8 q10, d24, d2 - PF subges PF_CTL, PF_CTL, #0x10 - vmull.u8 q11, d24, d3 - PF ldrgeb DUMMY, [PF_MASK, MASK_STRIDE, lsl #mask_bpp_shift]! - vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! - vrsra.u16 q8, q8, #8 - vrsra.u16 q9, q9, #8 - vrsra.u16 q10, q10, #8 - vrsra.u16 q11, q11, #8 -.endm - -.macro pixman_composite_src_n_8_8888_init - add DUMMY, sp, #ARGS_STACK_OFFSET - vld1.32 {d3[0]}, [DUMMY] - vdup.8 d0, d3[0] - vdup.8 d1, d3[1] - vdup.8 d2, d3[2] - vdup.8 d3, d3[3] -.endm - -.macro pixman_composite_src_n_8_8888_cleanup -.endm - -generate_composite_function \ - pixman_composite_src_n_8_8888_asm_neon, 0, 8, 32, \ - FLAG_DST_WRITEONLY | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - pixman_composite_src_n_8_8888_init, \ - pixman_composite_src_n_8_8888_cleanup, \ - pixman_composite_src_n_8_8888_process_pixblock_head, \ - pixman_composite_src_n_8_8888_process_pixblock_tail, \ - pixman_composite_src_n_8_8888_process_pixblock_tail_head, \ - -/******************************************************************************/ - -.macro pixman_composite_src_n_8_8_process_pixblock_head - vmull.u8 q0, d24, d16 - vmull.u8 q1, d25, d16 - vmull.u8 q2, d26, d16 - vmull.u8 q3, d27, d16 - vrsra.u16 q0, q0, #8 - vrsra.u16 q1, q1, #8 - vrsra.u16 q2, q2, #8 - vrsra.u16 q3, q3, #8 -.endm - -.macro pixman_composite_src_n_8_8_process_pixblock_tail - vrshrn.u16 d28, q0, #8 - vrshrn.u16 d29, q1, #8 - vrshrn.u16 d30, q2, #8 - vrshrn.u16 d31, q3, #8 -.endm - -.macro pixman_composite_src_n_8_8_process_pixblock_tail_head - fetch_mask_pixblock - PF add PF_X, PF_X, #8 - vrshrn.u16 d28, q0, #8 - PF tst PF_CTL, #0x0F - vrshrn.u16 d29, q1, #8 - PF addne PF_X, PF_X, #8 - vrshrn.u16 d30, q2, #8 - PF subne PF_CTL, PF_CTL, #1 - vrshrn.u16 d31, q3, #8 - PF cmp PF_X, ORIG_W - vmull.u8 q0, d24, d16 - PF pld, [PF_MASK, PF_X, lsl #mask_bpp_shift] - vmull.u8 q1, d25, d16 - PF subge PF_X, PF_X, ORIG_W - vmull.u8 q2, d26, d16 - PF subges PF_CTL, PF_CTL, #0x10 - vmull.u8 q3, d27, d16 - PF ldrgeb DUMMY, [PF_MASK, MASK_STRIDE, lsl #mask_bpp_shift]! - vst1.8 {d28, d29, d30, d31}, [DST_W, :128]! - vrsra.u16 q0, q0, #8 - vrsra.u16 q1, q1, #8 - vrsra.u16 q2, q2, #8 - vrsra.u16 q3, q3, #8 -.endm - -.macro pixman_composite_src_n_8_8_init - add DUMMY, sp, #ARGS_STACK_OFFSET - vld1.32 {d16[0]}, [DUMMY] - vdup.8 d16, d16[3] -.endm - -.macro pixman_composite_src_n_8_8_cleanup -.endm - -generate_composite_function \ - pixman_composite_src_n_8_8_asm_neon, 0, 8, 8, \ - FLAG_DST_WRITEONLY, \ - 32, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - pixman_composite_src_n_8_8_init, \ - pixman_composite_src_n_8_8_cleanup, \ - pixman_composite_src_n_8_8_process_pixblock_head, \ - pixman_composite_src_n_8_8_process_pixblock_tail, \ - pixman_composite_src_n_8_8_process_pixblock_tail_head - -/******************************************************************************/ - -.macro pixman_composite_over_n_8_8888_process_pixblock_head - /* expecting deinterleaved source data in {d8, d9, d10, d11} */ - /* d8 - blue, d9 - green, d10 - red, d11 - alpha */ - /* and destination data in {d4, d5, d6, d7} */ - /* mask is in d24 (d25, d26, d27 are unused) */ - - /* in */ - vmull.u8 q6, d24, d8 - vmull.u8 q7, d24, d9 - vmull.u8 q8, d24, d10 - vmull.u8 q9, d24, d11 - vrshr.u16 q10, q6, #8 - vrshr.u16 q11, q7, #8 - vrshr.u16 q12, q8, #8 - vrshr.u16 q13, q9, #8 - vraddhn.u16 d0, q6, q10 - vraddhn.u16 d1, q7, q11 - vraddhn.u16 d2, q8, q12 - vraddhn.u16 d3, q9, q13 - vmvn.8 d25, d3 /* get inverted alpha */ - /* source: d0 - blue, d1 - green, d2 - red, d3 - alpha */ - /* destination: d4 - blue, d5 - green, d6 - red, d7 - alpha */ - /* now do alpha blending */ - vmull.u8 q8, d25, d4 - vmull.u8 q9, d25, d5 - vmull.u8 q10, d25, d6 - vmull.u8 q11, d25, d7 -.endm - -.macro pixman_composite_over_n_8_8888_process_pixblock_tail - vrshr.u16 q14, q8, #8 - vrshr.u16 q15, q9, #8 - vrshr.u16 q6, q10, #8 - vrshr.u16 q7, q11, #8 - vraddhn.u16 d28, q14, q8 - vraddhn.u16 d29, q15, q9 - vraddhn.u16 d30, q6, q10 - vraddhn.u16 d31, q7, q11 - vqadd.u8 q14, q0, q14 - vqadd.u8 q15, q1, q15 -.endm - -.macro pixman_composite_over_n_8_8888_process_pixblock_tail_head - vrshr.u16 q14, q8, #8 - vld4.8 {d4, d5, d6, d7}, [DST_R, :128]! - vrshr.u16 q15, q9, #8 - fetch_mask_pixblock - vrshr.u16 q6, q10, #8 - PF add PF_X, PF_X, #8 - vrshr.u16 q7, q11, #8 - PF tst PF_CTL, #0x0F - vraddhn.u16 d28, q14, q8 - PF addne PF_X, PF_X, #8 - vraddhn.u16 d29, q15, q9 - PF subne PF_CTL, PF_CTL, #1 - vraddhn.u16 d30, q6, q10 - PF cmp PF_X, ORIG_W - vraddhn.u16 d31, q7, q11 - PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift] - vmull.u8 q6, d24, d8 - PF pld, [PF_MASK, PF_X, lsl #mask_bpp_shift] - vmull.u8 q7, d24, d9 - PF subge PF_X, PF_X, ORIG_W - vmull.u8 q8, d24, d10 - PF subges PF_CTL, PF_CTL, #0x10 - vmull.u8 q9, d24, d11 - PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]! - vqadd.u8 q14, q0, q14 - PF ldrgeb DUMMY, [PF_MASK, MASK_STRIDE, lsl #mask_bpp_shift]! - vqadd.u8 q15, q1, q15 - vrshr.u16 q10, q6, #8 - vrshr.u16 q11, q7, #8 - vrshr.u16 q12, q8, #8 - vrshr.u16 q13, q9, #8 - vraddhn.u16 d0, q6, q10 - vraddhn.u16 d1, q7, q11 - vraddhn.u16 d2, q8, q12 - vraddhn.u16 d3, q9, q13 - vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! - vmvn.8 d25, d3 - vmull.u8 q8, d25, d4 - vmull.u8 q9, d25, d5 - vmull.u8 q10, d25, d6 - vmull.u8 q11, d25, d7 -.endm - -.macro pixman_composite_over_n_8_8888_init - add DUMMY, sp, #ARGS_STACK_OFFSET - vpush {d8-d15} - vld1.32 {d11[0]}, [DUMMY] - vdup.8 d8, d11[0] - vdup.8 d9, d11[1] - vdup.8 d10, d11[2] - vdup.8 d11, d11[3] -.endm - -.macro pixman_composite_over_n_8_8888_cleanup - vpop {d8-d15} -.endm - -generate_composite_function \ - pixman_composite_over_n_8_8888_asm_neon, 0, 8, 32, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - pixman_composite_over_n_8_8888_init, \ - pixman_composite_over_n_8_8888_cleanup, \ - pixman_composite_over_n_8_8888_process_pixblock_head, \ - pixman_composite_over_n_8_8888_process_pixblock_tail, \ - pixman_composite_over_n_8_8888_process_pixblock_tail_head - -/******************************************************************************/ - -.macro pixman_composite_over_n_8_8_process_pixblock_head - vmull.u8 q0, d24, d8 - vmull.u8 q1, d25, d8 - vmull.u8 q6, d26, d8 - vmull.u8 q7, d27, d8 - vrshr.u16 q10, q0, #8 - vrshr.u16 q11, q1, #8 - vrshr.u16 q12, q6, #8 - vrshr.u16 q13, q7, #8 - vraddhn.u16 d0, q0, q10 - vraddhn.u16 d1, q1, q11 - vraddhn.u16 d2, q6, q12 - vraddhn.u16 d3, q7, q13 - vmvn.8 q12, q0 - vmvn.8 q13, q1 - vmull.u8 q8, d24, d4 - vmull.u8 q9, d25, d5 - vmull.u8 q10, d26, d6 - vmull.u8 q11, d27, d7 -.endm - -.macro pixman_composite_over_n_8_8_process_pixblock_tail - vrshr.u16 q14, q8, #8 - vrshr.u16 q15, q9, #8 - vrshr.u16 q12, q10, #8 - vrshr.u16 q13, q11, #8 - vraddhn.u16 d28, q14, q8 - vraddhn.u16 d29, q15, q9 - vraddhn.u16 d30, q12, q10 - vraddhn.u16 d31, q13, q11 - vqadd.u8 q14, q0, q14 - vqadd.u8 q15, q1, q15 -.endm - -/* TODO: expand macros and do better instructions scheduling */ -.macro pixman_composite_over_n_8_8_process_pixblock_tail_head - vld1.8 {d4, d5, d6, d7}, [DST_R, :128]! - pixman_composite_over_n_8_8_process_pixblock_tail - fetch_mask_pixblock - cache_preload 32, 32 - vst1.8 {d28, d29, d30, d31}, [DST_W, :128]! - pixman_composite_over_n_8_8_process_pixblock_head -.endm - -.macro pixman_composite_over_n_8_8_init - add DUMMY, sp, #ARGS_STACK_OFFSET - vpush {d8-d15} - vld1.32 {d8[0]}, [DUMMY] - vdup.8 d8, d8[3] -.endm - -.macro pixman_composite_over_n_8_8_cleanup - vpop {d8-d15} -.endm - -generate_composite_function \ - pixman_composite_over_n_8_8_asm_neon, 0, 8, 8, \ - FLAG_DST_READWRITE, \ - 32, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - pixman_composite_over_n_8_8_init, \ - pixman_composite_over_n_8_8_cleanup, \ - pixman_composite_over_n_8_8_process_pixblock_head, \ - pixman_composite_over_n_8_8_process_pixblock_tail, \ - pixman_composite_over_n_8_8_process_pixblock_tail_head - -/******************************************************************************/ - -.macro pixman_composite_over_n_8888_8888_ca_process_pixblock_head - /* - * 'combine_mask_ca' replacement - * - * input: solid src (n) in {d8, d9, d10, d11} - * dest in {d4, d5, d6, d7 } - * mask in {d24, d25, d26, d27} - * output: updated src in {d0, d1, d2, d3 } - * updated mask in {d24, d25, d26, d3 } - */ - vmull.u8 q0, d24, d8 - vmull.u8 q1, d25, d9 - vmull.u8 q6, d26, d10 - vmull.u8 q7, d27, d11 - vmull.u8 q9, d11, d25 - vmull.u8 q12, d11, d24 - vmull.u8 q13, d11, d26 - vrshr.u16 q8, q0, #8 - vrshr.u16 q10, q1, #8 - vrshr.u16 q11, q6, #8 - vraddhn.u16 d0, q0, q8 - vraddhn.u16 d1, q1, q10 - vraddhn.u16 d2, q6, q11 - vrshr.u16 q11, q12, #8 - vrshr.u16 q8, q9, #8 - vrshr.u16 q6, q13, #8 - vrshr.u16 q10, q7, #8 - vraddhn.u16 d24, q12, q11 - vraddhn.u16 d25, q9, q8 - vraddhn.u16 d26, q13, q6 - vraddhn.u16 d3, q7, q10 - /* - * 'combine_over_ca' replacement - * - * output: updated dest in {d28, d29, d30, d31} - */ - vmvn.8 q12, q12 - vmvn.8 d26, d26 - vmull.u8 q8, d24, d4 - vmull.u8 q9, d25, d5 - vmvn.8 d27, d3 - vmull.u8 q10, d26, d6 - vmull.u8 q11, d27, d7 -.endm - -.macro pixman_composite_over_n_8888_8888_ca_process_pixblock_tail - /* ... continue 'combine_over_ca' replacement */ - vrshr.u16 q14, q8, #8 - vrshr.u16 q15, q9, #8 - vrshr.u16 q6, q10, #8 - vrshr.u16 q7, q11, #8 - vraddhn.u16 d28, q14, q8 - vraddhn.u16 d29, q15, q9 - vraddhn.u16 d30, q6, q10 - vraddhn.u16 d31, q7, q11 - vqadd.u8 q14, q0, q14 - vqadd.u8 q15, q1, q15 -.endm - -.macro pixman_composite_over_n_8888_8888_ca_process_pixblock_tail_head - vrshr.u16 q14, q8, #8 - vrshr.u16 q15, q9, #8 - vld4.8 {d4, d5, d6, d7}, [DST_R, :128]! - vrshr.u16 q6, q10, #8 - vrshr.u16 q7, q11, #8 - vraddhn.u16 d28, q14, q8 - vraddhn.u16 d29, q15, q9 - vraddhn.u16 d30, q6, q10 - vraddhn.u16 d31, q7, q11 - fetch_mask_pixblock - vqadd.u8 q14, q0, q14 - vqadd.u8 q15, q1, q15 - cache_preload 8, 8 - pixman_composite_over_n_8888_8888_ca_process_pixblock_head - vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! -.endm - -.macro pixman_composite_over_n_8888_8888_ca_init - add DUMMY, sp, #ARGS_STACK_OFFSET - vpush {d8-d15} - vld1.32 {d11[0]}, [DUMMY] - vdup.8 d8, d11[0] - vdup.8 d9, d11[1] - vdup.8 d10, d11[2] - vdup.8 d11, d11[3] -.endm - -.macro pixman_composite_over_n_8888_8888_ca_cleanup - vpop {d8-d15} -.endm - -generate_composite_function \ - pixman_composite_over_n_8888_8888_ca_asm_neon, 0, 32, 32, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - pixman_composite_over_n_8888_8888_ca_init, \ - pixman_composite_over_n_8888_8888_ca_cleanup, \ - pixman_composite_over_n_8888_8888_ca_process_pixblock_head, \ - pixman_composite_over_n_8888_8888_ca_process_pixblock_tail, \ - pixman_composite_over_n_8888_8888_ca_process_pixblock_tail_head - -/******************************************************************************/ - -.macro pixman_composite_over_n_8888_0565_ca_process_pixblock_head - /* - * 'combine_mask_ca' replacement - * - * input: solid src (n) in {d8, d9, d10, d11} [B, G, R, A] - * mask in {d24, d25, d26} [B, G, R] - * output: updated src in {d0, d1, d2 } [B, G, R] - * updated mask in {d24, d25, d26} [B, G, R] - */ - vmull.u8 q0, d24, d8 - vmull.u8 q1, d25, d9 - vmull.u8 q6, d26, d10 - vmull.u8 q9, d11, d25 - vmull.u8 q12, d11, d24 - vmull.u8 q13, d11, d26 - vrshr.u16 q8, q0, #8 - vrshr.u16 q10, q1, #8 - vrshr.u16 q11, q6, #8 - vraddhn.u16 d0, q0, q8 - vraddhn.u16 d1, q1, q10 - vraddhn.u16 d2, q6, q11 - vrshr.u16 q11, q12, #8 - vrshr.u16 q8, q9, #8 - vrshr.u16 q6, q13, #8 - vraddhn.u16 d24, q12, q11 - vraddhn.u16 d25, q9, q8 - /* - * convert 8 r5g6b5 pixel data from {d4, d5} to planar 8-bit format - * and put data into d16 - blue, d17 - green, d18 - red - */ - vshrn.u16 d17, q2, #3 - vshrn.u16 d18, q2, #8 - vraddhn.u16 d26, q13, q6 - vsli.u16 q2, q2, #5 - vsri.u8 d18, d18, #5 - vsri.u8 d17, d17, #6 - /* - * 'combine_over_ca' replacement - * - * output: updated dest in d16 - blue, d17 - green, d18 - red - */ - vmvn.8 q12, q12 - vshrn.u16 d16, q2, #2 - vmvn.8 d26, d26 - vmull.u8 q6, d16, d24 - vmull.u8 q7, d17, d25 - vmull.u8 q11, d18, d26 -.endm - -.macro pixman_composite_over_n_8888_0565_ca_process_pixblock_tail - /* ... continue 'combine_over_ca' replacement */ - vrshr.u16 q10, q6, #8 - vrshr.u16 q14, q7, #8 - vrshr.u16 q15, q11, #8 - vraddhn.u16 d16, q10, q6 - vraddhn.u16 d17, q14, q7 - vraddhn.u16 d18, q15, q11 - vqadd.u8 q8, q0, q8 - vqadd.u8 d18, d2, d18 - /* - * convert the results in d16, d17, d18 to r5g6b5 and store - * them into {d28, d29} - */ - vshll.u8 q14, d18, #8 - vshll.u8 q10, d17, #8 - vshll.u8 q15, d16, #8 - vsri.u16 q14, q10, #5 - vsri.u16 q14, q15, #11 -.endm - -.macro pixman_composite_over_n_8888_0565_ca_process_pixblock_tail_head - fetch_mask_pixblock - vrshr.u16 q10, q6, #8 - vrshr.u16 q14, q7, #8 - vld1.16 {d4, d5}, [DST_R, :128]! - vrshr.u16 q15, q11, #8 - vraddhn.u16 d16, q10, q6 - vraddhn.u16 d17, q14, q7 - vraddhn.u16 d22, q15, q11 - /* process_pixblock_head */ - /* - * 'combine_mask_ca' replacement - * - * input: solid src (n) in {d8, d9, d10, d11} [B, G, R, A] - * mask in {d24, d25, d26} [B, G, R] - * output: updated src in {d0, d1, d2 } [B, G, R] - * updated mask in {d24, d25, d26} [B, G, R] - */ - vmull.u8 q6, d26, d10 - vqadd.u8 q8, q0, q8 - vmull.u8 q0, d24, d8 - vqadd.u8 d22, d2, d22 - vmull.u8 q1, d25, d9 - /* - * convert the result in d16, d17, d22 to r5g6b5 and store - * it into {d28, d29} - */ - vshll.u8 q14, d22, #8 - vshll.u8 q10, d17, #8 - vshll.u8 q15, d16, #8 - vmull.u8 q9, d11, d25 - vsri.u16 q14, q10, #5 - vmull.u8 q12, d11, d24 - vmull.u8 q13, d11, d26 - vsri.u16 q14, q15, #11 - cache_preload 8, 8 - vrshr.u16 q8, q0, #8 - vrshr.u16 q10, q1, #8 - vrshr.u16 q11, q6, #8 - vraddhn.u16 d0, q0, q8 - vraddhn.u16 d1, q1, q10 - vraddhn.u16 d2, q6, q11 - vrshr.u16 q11, q12, #8 - vrshr.u16 q8, q9, #8 - vrshr.u16 q6, q13, #8 - vraddhn.u16 d24, q12, q11 - vraddhn.u16 d25, q9, q8 - /* - * convert 8 r5g6b5 pixel data from {d4, d5} to planar - * 8-bit format and put data into d16 - blue, d17 - green, - * d18 - red - */ - vshrn.u16 d17, q2, #3 - vshrn.u16 d18, q2, #8 - vraddhn.u16 d26, q13, q6 - vsli.u16 q2, q2, #5 - vsri.u8 d17, d17, #6 - vsri.u8 d18, d18, #5 - /* - * 'combine_over_ca' replacement - * - * output: updated dest in d16 - blue, d17 - green, d18 - red - */ - vmvn.8 q12, q12 - vshrn.u16 d16, q2, #2 - vmvn.8 d26, d26 - vmull.u8 q7, d17, d25 - vmull.u8 q6, d16, d24 - vmull.u8 q11, d18, d26 - vst1.16 {d28, d29}, [DST_W, :128]! -.endm - -.macro pixman_composite_over_n_8888_0565_ca_init - add DUMMY, sp, #ARGS_STACK_OFFSET - vpush {d8-d15} - vld1.32 {d11[0]}, [DUMMY] - vdup.8 d8, d11[0] - vdup.8 d9, d11[1] - vdup.8 d10, d11[2] - vdup.8 d11, d11[3] -.endm - -.macro pixman_composite_over_n_8888_0565_ca_cleanup - vpop {d8-d15} -.endm - -generate_composite_function \ - pixman_composite_over_n_8888_0565_ca_asm_neon, 0, 32, 16, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - pixman_composite_over_n_8888_0565_ca_init, \ - pixman_composite_over_n_8888_0565_ca_cleanup, \ - pixman_composite_over_n_8888_0565_ca_process_pixblock_head, \ - pixman_composite_over_n_8888_0565_ca_process_pixblock_tail, \ - pixman_composite_over_n_8888_0565_ca_process_pixblock_tail_head - -/******************************************************************************/ - -.macro pixman_composite_in_n_8_process_pixblock_head - /* expecting source data in {d0, d1, d2, d3} */ - /* and destination data in {d4, d5, d6, d7} */ - vmull.u8 q8, d4, d3 - vmull.u8 q9, d5, d3 - vmull.u8 q10, d6, d3 - vmull.u8 q11, d7, d3 -.endm - -.macro pixman_composite_in_n_8_process_pixblock_tail - vrshr.u16 q14, q8, #8 - vrshr.u16 q15, q9, #8 - vrshr.u16 q12, q10, #8 - vrshr.u16 q13, q11, #8 - vraddhn.u16 d28, q8, q14 - vraddhn.u16 d29, q9, q15 - vraddhn.u16 d30, q10, q12 - vraddhn.u16 d31, q11, q13 -.endm - -.macro pixman_composite_in_n_8_process_pixblock_tail_head - pixman_composite_in_n_8_process_pixblock_tail - vld1.8 {d4, d5, d6, d7}, [DST_R, :128]! - cache_preload 32, 32 - pixman_composite_in_n_8_process_pixblock_head - vst1.8 {d28, d29, d30, d31}, [DST_W, :128]! -.endm - -.macro pixman_composite_in_n_8_init - add DUMMY, sp, #ARGS_STACK_OFFSET - vld1.32 {d3[0]}, [DUMMY] - vdup.8 d3, d3[3] -.endm - -.macro pixman_composite_in_n_8_cleanup -.endm - -generate_composite_function \ - pixman_composite_in_n_8_asm_neon, 0, 0, 8, \ - FLAG_DST_READWRITE, \ - 32, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - pixman_composite_in_n_8_init, \ - pixman_composite_in_n_8_cleanup, \ - pixman_composite_in_n_8_process_pixblock_head, \ - pixman_composite_in_n_8_process_pixblock_tail, \ - pixman_composite_in_n_8_process_pixblock_tail_head, \ - 28, /* dst_w_basereg */ \ - 4, /* dst_r_basereg */ \ - 0, /* src_basereg */ \ - 24 /* mask_basereg */ - -.macro pixman_composite_add_n_8_8_process_pixblock_head - /* expecting source data in {d8, d9, d10, d11} */ - /* d8 - blue, d9 - green, d10 - red, d11 - alpha */ - /* and destination data in {d4, d5, d6, d7} */ - /* mask is in d24, d25, d26, d27 */ - vmull.u8 q0, d24, d11 - vmull.u8 q1, d25, d11 - vmull.u8 q6, d26, d11 - vmull.u8 q7, d27, d11 - vrshr.u16 q10, q0, #8 - vrshr.u16 q11, q1, #8 - vrshr.u16 q12, q6, #8 - vrshr.u16 q13, q7, #8 - vraddhn.u16 d0, q0, q10 - vraddhn.u16 d1, q1, q11 - vraddhn.u16 d2, q6, q12 - vraddhn.u16 d3, q7, q13 - vqadd.u8 q14, q0, q2 - vqadd.u8 q15, q1, q3 -.endm - -.macro pixman_composite_add_n_8_8_process_pixblock_tail -.endm - -/* TODO: expand macros and do better instructions scheduling */ -.macro pixman_composite_add_n_8_8_process_pixblock_tail_head - pixman_composite_add_n_8_8_process_pixblock_tail - vst1.8 {d28, d29, d30, d31}, [DST_W, :128]! - vld1.8 {d4, d5, d6, d7}, [DST_R, :128]! - fetch_mask_pixblock - cache_preload 32, 32 - pixman_composite_add_n_8_8_process_pixblock_head -.endm - -.macro pixman_composite_add_n_8_8_init - add DUMMY, sp, #ARGS_STACK_OFFSET - vpush {d8-d15} - vld1.32 {d11[0]}, [DUMMY] - vdup.8 d11, d11[3] -.endm - -.macro pixman_composite_add_n_8_8_cleanup - vpop {d8-d15} -.endm - -generate_composite_function \ - pixman_composite_add_n_8_8_asm_neon, 0, 8, 8, \ - FLAG_DST_READWRITE, \ - 32, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - pixman_composite_add_n_8_8_init, \ - pixman_composite_add_n_8_8_cleanup, \ - pixman_composite_add_n_8_8_process_pixblock_head, \ - pixman_composite_add_n_8_8_process_pixblock_tail, \ - pixman_composite_add_n_8_8_process_pixblock_tail_head - -/******************************************************************************/ - -.macro pixman_composite_add_8_8_8_process_pixblock_head - /* expecting source data in {d0, d1, d2, d3} */ - /* destination data in {d4, d5, d6, d7} */ - /* mask in {d24, d25, d26, d27} */ - vmull.u8 q8, d24, d0 - vmull.u8 q9, d25, d1 - vmull.u8 q10, d26, d2 - vmull.u8 q11, d27, d3 - vrshr.u16 q0, q8, #8 - vrshr.u16 q1, q9, #8 - vrshr.u16 q12, q10, #8 - vrshr.u16 q13, q11, #8 - vraddhn.u16 d0, q0, q8 - vraddhn.u16 d1, q1, q9 - vraddhn.u16 d2, q12, q10 - vraddhn.u16 d3, q13, q11 - vqadd.u8 q14, q0, q2 - vqadd.u8 q15, q1, q3 -.endm - -.macro pixman_composite_add_8_8_8_process_pixblock_tail -.endm - -/* TODO: expand macros and do better instructions scheduling */ -.macro pixman_composite_add_8_8_8_process_pixblock_tail_head - pixman_composite_add_8_8_8_process_pixblock_tail - vst1.8 {d28, d29, d30, d31}, [DST_W, :128]! - vld1.8 {d4, d5, d6, d7}, [DST_R, :128]! - fetch_mask_pixblock - fetch_src_pixblock - cache_preload 32, 32 - pixman_composite_add_8_8_8_process_pixblock_head -.endm - -.macro pixman_composite_add_8_8_8_init -.endm - -.macro pixman_composite_add_8_8_8_cleanup -.endm - -generate_composite_function \ - pixman_composite_add_8_8_8_asm_neon, 8, 8, 8, \ - FLAG_DST_READWRITE, \ - 32, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - pixman_composite_add_8_8_8_init, \ - pixman_composite_add_8_8_8_cleanup, \ - pixman_composite_add_8_8_8_process_pixblock_head, \ - pixman_composite_add_8_8_8_process_pixblock_tail, \ - pixman_composite_add_8_8_8_process_pixblock_tail_head - -/******************************************************************************/ - -.macro pixman_composite_add_8888_8888_8888_process_pixblock_head - /* expecting source data in {d0, d1, d2, d3} */ - /* destination data in {d4, d5, d6, d7} */ - /* mask in {d24, d25, d26, d27} */ - vmull.u8 q8, d27, d0 - vmull.u8 q9, d27, d1 - vmull.u8 q10, d27, d2 - vmull.u8 q11, d27, d3 - /* 1 cycle bubble */ - vrsra.u16 q8, q8, #8 - vrsra.u16 q9, q9, #8 - vrsra.u16 q10, q10, #8 - vrsra.u16 q11, q11, #8 -.endm - -.macro pixman_composite_add_8888_8888_8888_process_pixblock_tail - /* 2 cycle bubble */ - vrshrn.u16 d28, q8, #8 - vrshrn.u16 d29, q9, #8 - vrshrn.u16 d30, q10, #8 - vrshrn.u16 d31, q11, #8 - vqadd.u8 q14, q2, q14 - /* 1 cycle bubble */ - vqadd.u8 q15, q3, q15 -.endm - -.macro pixman_composite_add_8888_8888_8888_process_pixblock_tail_head - fetch_src_pixblock - vrshrn.u16 d28, q8, #8 - fetch_mask_pixblock - vrshrn.u16 d29, q9, #8 - vmull.u8 q8, d27, d0 - vrshrn.u16 d30, q10, #8 - vmull.u8 q9, d27, d1 - vrshrn.u16 d31, q11, #8 - vmull.u8 q10, d27, d2 - vqadd.u8 q14, q2, q14 - vmull.u8 q11, d27, d3 - vqadd.u8 q15, q3, q15 - vrsra.u16 q8, q8, #8 - vld4.8 {d4, d5, d6, d7}, [DST_R, :128]! - vrsra.u16 q9, q9, #8 - vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! - vrsra.u16 q10, q10, #8 - - cache_preload 8, 8 - - vrsra.u16 q11, q11, #8 -.endm - -generate_composite_function \ - pixman_composite_add_8888_8888_8888_asm_neon, 32, 32, 32, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - 10, /* prefetch distance */ \ - default_init, \ - default_cleanup, \ - pixman_composite_add_8888_8888_8888_process_pixblock_head, \ - pixman_composite_add_8888_8888_8888_process_pixblock_tail, \ - pixman_composite_add_8888_8888_8888_process_pixblock_tail_head - -generate_composite_function_single_scanline \ - pixman_composite_scanline_add_mask_asm_neon, 32, 32, 32, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - default_init, \ - default_cleanup, \ - pixman_composite_add_8888_8888_8888_process_pixblock_head, \ - pixman_composite_add_8888_8888_8888_process_pixblock_tail, \ - pixman_composite_add_8888_8888_8888_process_pixblock_tail_head - -/******************************************************************************/ - -generate_composite_function \ - pixman_composite_add_8888_8_8888_asm_neon, 32, 8, 32, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - default_init, \ - default_cleanup, \ - pixman_composite_add_8888_8888_8888_process_pixblock_head, \ - pixman_composite_add_8888_8888_8888_process_pixblock_tail, \ - pixman_composite_add_8888_8888_8888_process_pixblock_tail_head, \ - 28, /* dst_w_basereg */ \ - 4, /* dst_r_basereg */ \ - 0, /* src_basereg */ \ - 27 /* mask_basereg */ - -/******************************************************************************/ - -.macro pixman_composite_add_n_8_8888_init - add DUMMY, sp, #ARGS_STACK_OFFSET - vld1.32 {d3[0]}, [DUMMY] - vdup.8 d0, d3[0] - vdup.8 d1, d3[1] - vdup.8 d2, d3[2] - vdup.8 d3, d3[3] -.endm - -.macro pixman_composite_add_n_8_8888_cleanup -.endm - -generate_composite_function \ - pixman_composite_add_n_8_8888_asm_neon, 0, 8, 32, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - pixman_composite_add_n_8_8888_init, \ - pixman_composite_add_n_8_8888_cleanup, \ - pixman_composite_add_8888_8888_8888_process_pixblock_head, \ - pixman_composite_add_8888_8888_8888_process_pixblock_tail, \ - pixman_composite_add_8888_8888_8888_process_pixblock_tail_head, \ - 28, /* dst_w_basereg */ \ - 4, /* dst_r_basereg */ \ - 0, /* src_basereg */ \ - 27 /* mask_basereg */ - -/******************************************************************************/ - -.macro pixman_composite_add_8888_n_8888_init - add DUMMY, sp, #(ARGS_STACK_OFFSET + 8) - vld1.32 {d27[0]}, [DUMMY] - vdup.8 d27, d27[3] -.endm - -.macro pixman_composite_add_8888_n_8888_cleanup -.endm - -generate_composite_function \ - pixman_composite_add_8888_n_8888_asm_neon, 32, 0, 32, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - pixman_composite_add_8888_n_8888_init, \ - pixman_composite_add_8888_n_8888_cleanup, \ - pixman_composite_add_8888_8888_8888_process_pixblock_head, \ - pixman_composite_add_8888_8888_8888_process_pixblock_tail, \ - pixman_composite_add_8888_8888_8888_process_pixblock_tail_head, \ - 28, /* dst_w_basereg */ \ - 4, /* dst_r_basereg */ \ - 0, /* src_basereg */ \ - 27 /* mask_basereg */ - -/******************************************************************************/ - -.macro pixman_composite_out_reverse_8888_n_8888_process_pixblock_head - /* expecting source data in {d0, d1, d2, d3} */ - /* destination data in {d4, d5, d6, d7} */ - /* solid mask is in d15 */ - - /* 'in' */ - vmull.u8 q8, d15, d3 - vmull.u8 q6, d15, d2 - vmull.u8 q5, d15, d1 - vmull.u8 q4, d15, d0 - vrshr.u16 q13, q8, #8 - vrshr.u16 q12, q6, #8 - vrshr.u16 q11, q5, #8 - vrshr.u16 q10, q4, #8 - vraddhn.u16 d3, q8, q13 - vraddhn.u16 d2, q6, q12 - vraddhn.u16 d1, q5, q11 - vraddhn.u16 d0, q4, q10 - vmvn.8 d24, d3 /* get inverted alpha */ - /* now do alpha blending */ - vmull.u8 q8, d24, d4 - vmull.u8 q9, d24, d5 - vmull.u8 q10, d24, d6 - vmull.u8 q11, d24, d7 -.endm - -.macro pixman_composite_out_reverse_8888_n_8888_process_pixblock_tail - vrshr.u16 q14, q8, #8 - vrshr.u16 q15, q9, #8 - vrshr.u16 q12, q10, #8 - vrshr.u16 q13, q11, #8 - vraddhn.u16 d28, q14, q8 - vraddhn.u16 d29, q15, q9 - vraddhn.u16 d30, q12, q10 - vraddhn.u16 d31, q13, q11 -.endm - -/* TODO: expand macros and do better instructions scheduling */ -.macro pixman_composite_out_reverse_8888_8888_8888_process_pixblock_tail_head - vld4.8 {d4, d5, d6, d7}, [DST_R, :128]! - pixman_composite_out_reverse_8888_n_8888_process_pixblock_tail - fetch_src_pixblock - cache_preload 8, 8 - fetch_mask_pixblock - pixman_composite_out_reverse_8888_n_8888_process_pixblock_head - vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! -.endm - -generate_composite_function_single_scanline \ - pixman_composite_scanline_out_reverse_mask_asm_neon, 32, 32, 32, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - default_init_need_all_regs, \ - default_cleanup_need_all_regs, \ - pixman_composite_out_reverse_8888_n_8888_process_pixblock_head, \ - pixman_composite_out_reverse_8888_n_8888_process_pixblock_tail, \ - pixman_composite_out_reverse_8888_8888_8888_process_pixblock_tail_head \ - 28, /* dst_w_basereg */ \ - 4, /* dst_r_basereg */ \ - 0, /* src_basereg */ \ - 12 /* mask_basereg */ - -/******************************************************************************/ - -.macro pixman_composite_over_8888_n_8888_process_pixblock_head - pixman_composite_out_reverse_8888_n_8888_process_pixblock_head -.endm - -.macro pixman_composite_over_8888_n_8888_process_pixblock_tail - pixman_composite_out_reverse_8888_n_8888_process_pixblock_tail - vqadd.u8 q14, q0, q14 - vqadd.u8 q15, q1, q15 -.endm - -/* TODO: expand macros and do better instructions scheduling */ -.macro pixman_composite_over_8888_n_8888_process_pixblock_tail_head - vld4.8 {d4, d5, d6, d7}, [DST_R, :128]! - pixman_composite_over_8888_n_8888_process_pixblock_tail - fetch_src_pixblock - cache_preload 8, 8 - pixman_composite_over_8888_n_8888_process_pixblock_head - vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! -.endm - -.macro pixman_composite_over_8888_n_8888_init - add DUMMY, sp, #48 - vpush {d8-d15} - vld1.32 {d15[0]}, [DUMMY] - vdup.8 d15, d15[3] -.endm - -.macro pixman_composite_over_8888_n_8888_cleanup - vpop {d8-d15} -.endm - -generate_composite_function \ - pixman_composite_over_8888_n_8888_asm_neon, 32, 0, 32, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - pixman_composite_over_8888_n_8888_init, \ - pixman_composite_over_8888_n_8888_cleanup, \ - pixman_composite_over_8888_n_8888_process_pixblock_head, \ - pixman_composite_over_8888_n_8888_process_pixblock_tail, \ - pixman_composite_over_8888_n_8888_process_pixblock_tail_head - -/******************************************************************************/ - -/* TODO: expand macros and do better instructions scheduling */ -.macro pixman_composite_over_8888_8888_8888_process_pixblock_tail_head - vld4.8 {d4, d5, d6, d7}, [DST_R, :128]! - pixman_composite_over_8888_n_8888_process_pixblock_tail - fetch_src_pixblock - cache_preload 8, 8 - fetch_mask_pixblock - pixman_composite_over_8888_n_8888_process_pixblock_head - vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! -.endm - -generate_composite_function \ - pixman_composite_over_8888_8888_8888_asm_neon, 32, 32, 32, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - default_init_need_all_regs, \ - default_cleanup_need_all_regs, \ - pixman_composite_over_8888_n_8888_process_pixblock_head, \ - pixman_composite_over_8888_n_8888_process_pixblock_tail, \ - pixman_composite_over_8888_8888_8888_process_pixblock_tail_head \ - 28, /* dst_w_basereg */ \ - 4, /* dst_r_basereg */ \ - 0, /* src_basereg */ \ - 12 /* mask_basereg */ - -generate_composite_function_single_scanline \ - pixman_composite_scanline_over_mask_asm_neon, 32, 32, 32, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - default_init_need_all_regs, \ - default_cleanup_need_all_regs, \ - pixman_composite_over_8888_n_8888_process_pixblock_head, \ - pixman_composite_over_8888_n_8888_process_pixblock_tail, \ - pixman_composite_over_8888_8888_8888_process_pixblock_tail_head \ - 28, /* dst_w_basereg */ \ - 4, /* dst_r_basereg */ \ - 0, /* src_basereg */ \ - 12 /* mask_basereg */ - -/******************************************************************************/ - -/* TODO: expand macros and do better instructions scheduling */ -.macro pixman_composite_over_8888_8_8888_process_pixblock_tail_head - vld4.8 {d4, d5, d6, d7}, [DST_R, :128]! - pixman_composite_over_8888_n_8888_process_pixblock_tail - fetch_src_pixblock - cache_preload 8, 8 - fetch_mask_pixblock - pixman_composite_over_8888_n_8888_process_pixblock_head - vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! -.endm - -generate_composite_function \ - pixman_composite_over_8888_8_8888_asm_neon, 32, 8, 32, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - default_init_need_all_regs, \ - default_cleanup_need_all_regs, \ - pixman_composite_over_8888_n_8888_process_pixblock_head, \ - pixman_composite_over_8888_n_8888_process_pixblock_tail, \ - pixman_composite_over_8888_8_8888_process_pixblock_tail_head \ - 28, /* dst_w_basereg */ \ - 4, /* dst_r_basereg */ \ - 0, /* src_basereg */ \ - 15 /* mask_basereg */ - -/******************************************************************************/ - -.macro pixman_composite_src_0888_0888_process_pixblock_head -.endm - -.macro pixman_composite_src_0888_0888_process_pixblock_tail -.endm - -.macro pixman_composite_src_0888_0888_process_pixblock_tail_head - vst3.8 {d0, d1, d2}, [DST_W]! - fetch_src_pixblock - cache_preload 8, 8 -.endm - -generate_composite_function \ - pixman_composite_src_0888_0888_asm_neon, 24, 0, 24, \ - FLAG_DST_WRITEONLY, \ - 8, /* number of pixels, processed in a single block */ \ - 10, /* prefetch distance */ \ - default_init, \ - default_cleanup, \ - pixman_composite_src_0888_0888_process_pixblock_head, \ - pixman_composite_src_0888_0888_process_pixblock_tail, \ - pixman_composite_src_0888_0888_process_pixblock_tail_head, \ - 0, /* dst_w_basereg */ \ - 0, /* dst_r_basereg */ \ - 0, /* src_basereg */ \ - 0 /* mask_basereg */ - -/******************************************************************************/ - -.macro pixman_composite_src_0888_8888_rev_process_pixblock_head - vswp d0, d2 -.endm - -.macro pixman_composite_src_0888_8888_rev_process_pixblock_tail -.endm - -.macro pixman_composite_src_0888_8888_rev_process_pixblock_tail_head - vst4.8 {d0, d1, d2, d3}, [DST_W]! - fetch_src_pixblock - vswp d0, d2 - cache_preload 8, 8 -.endm - -.macro pixman_composite_src_0888_8888_rev_init - veor d3, d3, d3 -.endm - -generate_composite_function \ - pixman_composite_src_0888_8888_rev_asm_neon, 24, 0, 32, \ - FLAG_DST_WRITEONLY | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - 10, /* prefetch distance */ \ - pixman_composite_src_0888_8888_rev_init, \ - default_cleanup, \ - pixman_composite_src_0888_8888_rev_process_pixblock_head, \ - pixman_composite_src_0888_8888_rev_process_pixblock_tail, \ - pixman_composite_src_0888_8888_rev_process_pixblock_tail_head, \ - 0, /* dst_w_basereg */ \ - 0, /* dst_r_basereg */ \ - 0, /* src_basereg */ \ - 0 /* mask_basereg */ - -/******************************************************************************/ - -.macro pixman_composite_src_0888_0565_rev_process_pixblock_head - vshll.u8 q8, d1, #8 - vshll.u8 q9, d2, #8 -.endm - -.macro pixman_composite_src_0888_0565_rev_process_pixblock_tail - vshll.u8 q14, d0, #8 - vsri.u16 q14, q8, #5 - vsri.u16 q14, q9, #11 -.endm - -.macro pixman_composite_src_0888_0565_rev_process_pixblock_tail_head - vshll.u8 q14, d0, #8 - fetch_src_pixblock - vsri.u16 q14, q8, #5 - vsri.u16 q14, q9, #11 - vshll.u8 q8, d1, #8 - vst1.16 {d28, d29}, [DST_W, :128]! - vshll.u8 q9, d2, #8 -.endm - -generate_composite_function \ - pixman_composite_src_0888_0565_rev_asm_neon, 24, 0, 16, \ - FLAG_DST_WRITEONLY, \ - 8, /* number of pixels, processed in a single block */ \ - 10, /* prefetch distance */ \ - default_init, \ - default_cleanup, \ - pixman_composite_src_0888_0565_rev_process_pixblock_head, \ - pixman_composite_src_0888_0565_rev_process_pixblock_tail, \ - pixman_composite_src_0888_0565_rev_process_pixblock_tail_head, \ - 28, /* dst_w_basereg */ \ - 0, /* dst_r_basereg */ \ - 0, /* src_basereg */ \ - 0 /* mask_basereg */ - -/******************************************************************************/ - -.macro pixman_composite_src_pixbuf_8888_process_pixblock_head - vmull.u8 q8, d3, d0 - vmull.u8 q9, d3, d1 - vmull.u8 q10, d3, d2 -.endm - -.macro pixman_composite_src_pixbuf_8888_process_pixblock_tail - vrshr.u16 q11, q8, #8 - vswp d3, d31 - vrshr.u16 q12, q9, #8 - vrshr.u16 q13, q10, #8 - vraddhn.u16 d30, q11, q8 - vraddhn.u16 d29, q12, q9 - vraddhn.u16 d28, q13, q10 -.endm - -.macro pixman_composite_src_pixbuf_8888_process_pixblock_tail_head - vrshr.u16 q11, q8, #8 - vswp d3, d31 - vrshr.u16 q12, q9, #8 - vrshr.u16 q13, q10, #8 - fetch_src_pixblock - vraddhn.u16 d30, q11, q8 - PF add PF_X, PF_X, #8 - PF tst PF_CTL, #0xF - PF addne PF_X, PF_X, #8 - PF subne PF_CTL, PF_CTL, #1 - vraddhn.u16 d29, q12, q9 - vraddhn.u16 d28, q13, q10 - vmull.u8 q8, d3, d0 - vmull.u8 q9, d3, d1 - vmull.u8 q10, d3, d2 - vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! - PF cmp PF_X, ORIG_W - PF pld, [PF_SRC, PF_X, lsl #src_bpp_shift] - PF subge PF_X, PF_X, ORIG_W - PF subges PF_CTL, PF_CTL, #0x10 - PF ldrgeb DUMMY, [PF_SRC, SRC_STRIDE, lsl #src_bpp_shift]! -.endm - -generate_composite_function \ - pixman_composite_src_pixbuf_8888_asm_neon, 32, 0, 32, \ - FLAG_DST_WRITEONLY | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - 10, /* prefetch distance */ \ - default_init, \ - default_cleanup, \ - pixman_composite_src_pixbuf_8888_process_pixblock_head, \ - pixman_composite_src_pixbuf_8888_process_pixblock_tail, \ - pixman_composite_src_pixbuf_8888_process_pixblock_tail_head, \ - 28, /* dst_w_basereg */ \ - 0, /* dst_r_basereg */ \ - 0, /* src_basereg */ \ - 0 /* mask_basereg */ - -/******************************************************************************/ - -.macro pixman_composite_src_rpixbuf_8888_process_pixblock_head - vmull.u8 q8, d3, d0 - vmull.u8 q9, d3, d1 - vmull.u8 q10, d3, d2 -.endm - -.macro pixman_composite_src_rpixbuf_8888_process_pixblock_tail - vrshr.u16 q11, q8, #8 - vswp d3, d31 - vrshr.u16 q12, q9, #8 - vrshr.u16 q13, q10, #8 - vraddhn.u16 d28, q11, q8 - vraddhn.u16 d29, q12, q9 - vraddhn.u16 d30, q13, q10 -.endm - -.macro pixman_composite_src_rpixbuf_8888_process_pixblock_tail_head - vrshr.u16 q11, q8, #8 - vswp d3, d31 - vrshr.u16 q12, q9, #8 - vrshr.u16 q13, q10, #8 - fetch_src_pixblock - vraddhn.u16 d28, q11, q8 - PF add PF_X, PF_X, #8 - PF tst PF_CTL, #0xF - PF addne PF_X, PF_X, #8 - PF subne PF_CTL, PF_CTL, #1 - vraddhn.u16 d29, q12, q9 - vraddhn.u16 d30, q13, q10 - vmull.u8 q8, d3, d0 - vmull.u8 q9, d3, d1 - vmull.u8 q10, d3, d2 - vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! - PF cmp PF_X, ORIG_W - PF pld, [PF_SRC, PF_X, lsl #src_bpp_shift] - PF subge PF_X, PF_X, ORIG_W - PF subges PF_CTL, PF_CTL, #0x10 - PF ldrgeb DUMMY, [PF_SRC, SRC_STRIDE, lsl #src_bpp_shift]! -.endm - -generate_composite_function \ - pixman_composite_src_rpixbuf_8888_asm_neon, 32, 0, 32, \ - FLAG_DST_WRITEONLY | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - 10, /* prefetch distance */ \ - default_init, \ - default_cleanup, \ - pixman_composite_src_rpixbuf_8888_process_pixblock_head, \ - pixman_composite_src_rpixbuf_8888_process_pixblock_tail, \ - pixman_composite_src_rpixbuf_8888_process_pixblock_tail_head, \ - 28, /* dst_w_basereg */ \ - 0, /* dst_r_basereg */ \ - 0, /* src_basereg */ \ - 0 /* mask_basereg */ - -/******************************************************************************/ - -.macro pixman_composite_over_0565_8_0565_process_pixblock_head - /* mask is in d15 */ - convert_0565_to_x888 q4, d2, d1, d0 - convert_0565_to_x888 q5, d6, d5, d4 - /* source pixel data is in {d0, d1, d2, XX} */ - /* destination pixel data is in {d4, d5, d6, XX} */ - vmvn.8 d7, d15 - vmull.u8 q6, d15, d2 - vmull.u8 q5, d15, d1 - vmull.u8 q4, d15, d0 - vmull.u8 q8, d7, d4 - vmull.u8 q9, d7, d5 - vmull.u8 q13, d7, d6 - vrshr.u16 q12, q6, #8 - vrshr.u16 q11, q5, #8 - vrshr.u16 q10, q4, #8 - vraddhn.u16 d2, q6, q12 - vraddhn.u16 d1, q5, q11 - vraddhn.u16 d0, q4, q10 -.endm - -.macro pixman_composite_over_0565_8_0565_process_pixblock_tail - vrshr.u16 q14, q8, #8 - vrshr.u16 q15, q9, #8 - vrshr.u16 q12, q13, #8 - vraddhn.u16 d28, q14, q8 - vraddhn.u16 d29, q15, q9 - vraddhn.u16 d30, q12, q13 - vqadd.u8 q0, q0, q14 - vqadd.u8 q1, q1, q15 - /* 32bpp result is in {d0, d1, d2, XX} */ - convert_8888_to_0565 d2, d1, d0, q14, q15, q3 -.endm - -/* TODO: expand macros and do better instructions scheduling */ -.macro pixman_composite_over_0565_8_0565_process_pixblock_tail_head - fetch_mask_pixblock - pixman_composite_over_0565_8_0565_process_pixblock_tail - fetch_src_pixblock - vld1.16 {d10, d11}, [DST_R, :128]! - cache_preload 8, 8 - pixman_composite_over_0565_8_0565_process_pixblock_head - vst1.16 {d28, d29}, [DST_W, :128]! -.endm - -generate_composite_function \ - pixman_composite_over_0565_8_0565_asm_neon, 16, 8, 16, \ - FLAG_DST_READWRITE, \ - 8, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - default_init_need_all_regs, \ - default_cleanup_need_all_regs, \ - pixman_composite_over_0565_8_0565_process_pixblock_head, \ - pixman_composite_over_0565_8_0565_process_pixblock_tail, \ - pixman_composite_over_0565_8_0565_process_pixblock_tail_head, \ - 28, /* dst_w_basereg */ \ - 10, /* dst_r_basereg */ \ - 8, /* src_basereg */ \ - 15 /* mask_basereg */ - -/******************************************************************************/ - -.macro pixman_composite_over_0565_n_0565_init - add DUMMY, sp, #(ARGS_STACK_OFFSET + 8) - vpush {d8-d15} - vld1.32 {d15[0]}, [DUMMY] - vdup.8 d15, d15[3] -.endm - -.macro pixman_composite_over_0565_n_0565_cleanup - vpop {d8-d15} -.endm - -generate_composite_function \ - pixman_composite_over_0565_n_0565_asm_neon, 16, 0, 16, \ - FLAG_DST_READWRITE, \ - 8, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - pixman_composite_over_0565_n_0565_init, \ - pixman_composite_over_0565_n_0565_cleanup, \ - pixman_composite_over_0565_8_0565_process_pixblock_head, \ - pixman_composite_over_0565_8_0565_process_pixblock_tail, \ - pixman_composite_over_0565_8_0565_process_pixblock_tail_head, \ - 28, /* dst_w_basereg */ \ - 10, /* dst_r_basereg */ \ - 8, /* src_basereg */ \ - 15 /* mask_basereg */ - -/******************************************************************************/ - -.macro pixman_composite_add_0565_8_0565_process_pixblock_head - /* mask is in d15 */ - convert_0565_to_x888 q4, d2, d1, d0 - convert_0565_to_x888 q5, d6, d5, d4 - /* source pixel data is in {d0, d1, d2, XX} */ - /* destination pixel data is in {d4, d5, d6, XX} */ - vmull.u8 q6, d15, d2 - vmull.u8 q5, d15, d1 - vmull.u8 q4, d15, d0 - vrshr.u16 q12, q6, #8 - vrshr.u16 q11, q5, #8 - vrshr.u16 q10, q4, #8 - vraddhn.u16 d2, q6, q12 - vraddhn.u16 d1, q5, q11 - vraddhn.u16 d0, q4, q10 -.endm - -.macro pixman_composite_add_0565_8_0565_process_pixblock_tail - vqadd.u8 q0, q0, q2 - vqadd.u8 q1, q1, q3 - /* 32bpp result is in {d0, d1, d2, XX} */ - convert_8888_to_0565 d2, d1, d0, q14, q15, q3 -.endm - -/* TODO: expand macros and do better instructions scheduling */ -.macro pixman_composite_add_0565_8_0565_process_pixblock_tail_head - fetch_mask_pixblock - pixman_composite_add_0565_8_0565_process_pixblock_tail - fetch_src_pixblock - vld1.16 {d10, d11}, [DST_R, :128]! - cache_preload 8, 8 - pixman_composite_add_0565_8_0565_process_pixblock_head - vst1.16 {d28, d29}, [DST_W, :128]! -.endm - -generate_composite_function \ - pixman_composite_add_0565_8_0565_asm_neon, 16, 8, 16, \ - FLAG_DST_READWRITE, \ - 8, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - default_init_need_all_regs, \ - default_cleanup_need_all_regs, \ - pixman_composite_add_0565_8_0565_process_pixblock_head, \ - pixman_composite_add_0565_8_0565_process_pixblock_tail, \ - pixman_composite_add_0565_8_0565_process_pixblock_tail_head, \ - 28, /* dst_w_basereg */ \ - 10, /* dst_r_basereg */ \ - 8, /* src_basereg */ \ - 15 /* mask_basereg */ - -/******************************************************************************/ - -.macro pixman_composite_out_reverse_8_0565_process_pixblock_head - /* mask is in d15 */ - convert_0565_to_x888 q5, d6, d5, d4 - /* destination pixel data is in {d4, d5, d6, xx} */ - vmvn.8 d24, d15 /* get inverted alpha */ - /* now do alpha blending */ - vmull.u8 q8, d24, d4 - vmull.u8 q9, d24, d5 - vmull.u8 q10, d24, d6 -.endm - -.macro pixman_composite_out_reverse_8_0565_process_pixblock_tail - vrshr.u16 q14, q8, #8 - vrshr.u16 q15, q9, #8 - vrshr.u16 q12, q10, #8 - vraddhn.u16 d0, q14, q8 - vraddhn.u16 d1, q15, q9 - vraddhn.u16 d2, q12, q10 - /* 32bpp result is in {d0, d1, d2, XX} */ - convert_8888_to_0565 d2, d1, d0, q14, q15, q3 -.endm - -/* TODO: expand macros and do better instructions scheduling */ -.macro pixman_composite_out_reverse_8_0565_process_pixblock_tail_head - fetch_src_pixblock - pixman_composite_out_reverse_8_0565_process_pixblock_tail - vld1.16 {d10, d11}, [DST_R, :128]! - cache_preload 8, 8 - pixman_composite_out_reverse_8_0565_process_pixblock_head - vst1.16 {d28, d29}, [DST_W, :128]! -.endm - -generate_composite_function \ - pixman_composite_out_reverse_8_0565_asm_neon, 8, 0, 16, \ - FLAG_DST_READWRITE, \ - 8, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - default_init_need_all_regs, \ - default_cleanup_need_all_regs, \ - pixman_composite_out_reverse_8_0565_process_pixblock_head, \ - pixman_composite_out_reverse_8_0565_process_pixblock_tail, \ - pixman_composite_out_reverse_8_0565_process_pixblock_tail_head, \ - 28, /* dst_w_basereg */ \ - 10, /* dst_r_basereg */ \ - 15, /* src_basereg */ \ - 0 /* mask_basereg */ - -/******************************************************************************/ - -.macro pixman_composite_out_reverse_8_8888_process_pixblock_head - /* src is in d0 */ - /* destination pixel data is in {d4, d5, d6, d7} */ - vmvn.8 d1, d0 /* get inverted alpha */ - /* now do alpha blending */ - vmull.u8 q8, d1, d4 - vmull.u8 q9, d1, d5 - vmull.u8 q10, d1, d6 - vmull.u8 q11, d1, d7 -.endm - -.macro pixman_composite_out_reverse_8_8888_process_pixblock_tail - vrshr.u16 q14, q8, #8 - vrshr.u16 q15, q9, #8 - vrshr.u16 q12, q10, #8 - vrshr.u16 q13, q11, #8 - vraddhn.u16 d28, q14, q8 - vraddhn.u16 d29, q15, q9 - vraddhn.u16 d30, q12, q10 - vraddhn.u16 d31, q13, q11 - /* 32bpp result is in {d28, d29, d30, d31} */ -.endm - -/* TODO: expand macros and do better instructions scheduling */ -.macro pixman_composite_out_reverse_8_8888_process_pixblock_tail_head - fetch_src_pixblock - pixman_composite_out_reverse_8_8888_process_pixblock_tail - vld4.8 {d4, d5, d6, d7}, [DST_R, :128]! - cache_preload 8, 8 - pixman_composite_out_reverse_8_8888_process_pixblock_head - vst4.8 {d28, d29, d30, d31}, [DST_W, :128]! -.endm - -generate_composite_function \ - pixman_composite_out_reverse_8_8888_asm_neon, 8, 0, 32, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - 5, /* prefetch distance */ \ - default_init, \ - default_cleanup, \ - pixman_composite_out_reverse_8_8888_process_pixblock_head, \ - pixman_composite_out_reverse_8_8888_process_pixblock_tail, \ - pixman_composite_out_reverse_8_8888_process_pixblock_tail_head, \ - 28, /* dst_w_basereg */ \ - 4, /* dst_r_basereg */ \ - 0, /* src_basereg */ \ - 0 /* mask_basereg */ - -/******************************************************************************/ - -generate_composite_function_nearest_scanline \ - pixman_scaled_nearest_scanline_8888_8888_OVER_asm_neon, 32, 0, 32, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - default_init, \ - default_cleanup, \ - pixman_composite_over_8888_8888_process_pixblock_head, \ - pixman_composite_over_8888_8888_process_pixblock_tail, \ - pixman_composite_over_8888_8888_process_pixblock_tail_head - -generate_composite_function_nearest_scanline \ - pixman_scaled_nearest_scanline_8888_0565_OVER_asm_neon, 32, 0, 16, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - default_init, \ - default_cleanup, \ - pixman_composite_over_8888_0565_process_pixblock_head, \ - pixman_composite_over_8888_0565_process_pixblock_tail, \ - pixman_composite_over_8888_0565_process_pixblock_tail_head, \ - 28, /* dst_w_basereg */ \ - 4, /* dst_r_basereg */ \ - 0, /* src_basereg */ \ - 24 /* mask_basereg */ - -generate_composite_function_nearest_scanline \ - pixman_scaled_nearest_scanline_8888_0565_SRC_asm_neon, 32, 0, 16, \ - FLAG_DST_WRITEONLY | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - default_init, \ - default_cleanup, \ - pixman_composite_src_8888_0565_process_pixblock_head, \ - pixman_composite_src_8888_0565_process_pixblock_tail, \ - pixman_composite_src_8888_0565_process_pixblock_tail_head - -generate_composite_function_nearest_scanline \ - pixman_scaled_nearest_scanline_0565_8888_SRC_asm_neon, 16, 0, 32, \ - FLAG_DST_WRITEONLY | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - default_init, \ - default_cleanup, \ - pixman_composite_src_0565_8888_process_pixblock_head, \ - pixman_composite_src_0565_8888_process_pixblock_tail, \ - pixman_composite_src_0565_8888_process_pixblock_tail_head - -generate_composite_function_nearest_scanline \ - pixman_scaled_nearest_scanline_8888_8_0565_OVER_asm_neon, 32, 8, 16, \ - FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \ - 8, /* number of pixels, processed in a single block */ \ - default_init_need_all_regs, \ - default_cleanup_need_all_regs, \ - pixman_composite_over_8888_8_0565_process_pixblock_head, \ - pixman_composite_over_8888_8_0565_process_pixblock_tail, \ - pixman_composite_over_8888_8_0565_process_pixblock_tail_head, \ - 28, /* dst_w_basereg */ \ - 4, /* dst_r_basereg */ \ - 8, /* src_basereg */ \ - 24 /* mask_basereg */ - -generate_composite_function_nearest_scanline \ - pixman_scaled_nearest_scanline_0565_8_0565_OVER_asm_neon, 16, 8, 16, \ - FLAG_DST_READWRITE, \ - 8, /* number of pixels, processed in a single block */ \ - default_init_need_all_regs, \ - default_cleanup_need_all_regs, \ - pixman_composite_over_0565_8_0565_process_pixblock_head, \ - pixman_composite_over_0565_8_0565_process_pixblock_tail, \ - pixman_composite_over_0565_8_0565_process_pixblock_tail_head, \ - 28, /* dst_w_basereg */ \ - 10, /* dst_r_basereg */ \ - 8, /* src_basereg */ \ - 15 /* mask_basereg */ - -/******************************************************************************/ - -/* - * Bilinear scaling support code which tries to provide pixel fetching, color - * format conversion, and interpolation as separate macros which can be used - * as the basic building blocks for constructing bilinear scanline functions. - */ - -.macro bilinear_load_8888 reg1, reg2, tmp - mov TMP1, X, asr #16 - add X, X, UX - add TMP1, TOP, TMP1, asl #2 - vld1.32 {reg1}, [TMP1], STRIDE - vld1.32 {reg2}, [TMP1] -.endm - -.macro bilinear_load_0565 reg1, reg2, tmp - mov TMP1, X, asr #16 - add X, X, UX - add TMP1, TOP, TMP1, asl #1 - vld1.32 {reg2[0]}, [TMP1], STRIDE - vld1.32 {reg2[1]}, [TMP1] - convert_four_0565_to_x888_packed reg2, reg1, reg2, tmp -.endm - -.macro bilinear_load_and_vertical_interpolate_two_8888 \ - acc1, acc2, reg1, reg2, reg3, reg4, tmp1, tmp2 - - bilinear_load_8888 reg1, reg2, tmp1 - vmull.u8 acc1, reg1, d28 - vmlal.u8 acc1, reg2, d29 - bilinear_load_8888 reg3, reg4, tmp2 - vmull.u8 acc2, reg3, d28 - vmlal.u8 acc2, reg4, d29 -.endm - -.macro bilinear_load_and_vertical_interpolate_four_8888 \ - xacc1, xacc2, xreg1, xreg2, xreg3, xreg4, xacc2lo, xacc2hi \ - yacc1, yacc2, yreg1, yreg2, yreg3, yreg4, yacc2lo, yacc2hi - - bilinear_load_and_vertical_interpolate_two_8888 \ - xacc1, xacc2, xreg1, xreg2, xreg3, xreg4, xacc2lo, xacc2hi - bilinear_load_and_vertical_interpolate_two_8888 \ - yacc1, yacc2, yreg1, yreg2, yreg3, yreg4, yacc2lo, yacc2hi -.endm - -.macro bilinear_load_and_vertical_interpolate_two_0565 \ - acc1, acc2, reg1, reg2, reg3, reg4, acc2lo, acc2hi - - mov TMP1, X, asr #16 - add X, X, UX - add TMP1, TOP, TMP1, asl #1 - mov TMP2, X, asr #16 - add X, X, UX - add TMP2, TOP, TMP2, asl #1 - vld1.32 {acc2lo[0]}, [TMP1], STRIDE - vld1.32 {acc2hi[0]}, [TMP2], STRIDE - vld1.32 {acc2lo[1]}, [TMP1] - vld1.32 {acc2hi[1]}, [TMP2] - convert_0565_to_x888 acc2, reg3, reg2, reg1 - vzip.u8 reg1, reg3 - vzip.u8 reg2, reg4 - vzip.u8 reg3, reg4 - vzip.u8 reg1, reg2 - vmull.u8 acc1, reg1, d28 - vmlal.u8 acc1, reg2, d29 - vmull.u8 acc2, reg3, d28 - vmlal.u8 acc2, reg4, d29 -.endm - -.macro bilinear_load_and_vertical_interpolate_four_0565 \ - xacc1, xacc2, xreg1, xreg2, xreg3, xreg4, xacc2lo, xacc2hi \ - yacc1, yacc2, yreg1, yreg2, yreg3, yreg4, yacc2lo, yacc2hi - - mov TMP1, X, asr #16 - add X, X, UX - add TMP1, TOP, TMP1, asl #1 - mov TMP2, X, asr #16 - add X, X, UX - add TMP2, TOP, TMP2, asl #1 - vld1.32 {xacc2lo[0]}, [TMP1], STRIDE - vld1.32 {xacc2hi[0]}, [TMP2], STRIDE - vld1.32 {xacc2lo[1]}, [TMP1] - vld1.32 {xacc2hi[1]}, [TMP2] - convert_0565_to_x888 xacc2, xreg3, xreg2, xreg1 - mov TMP1, X, asr #16 - add X, X, UX - add TMP1, TOP, TMP1, asl #1 - mov TMP2, X, asr #16 - add X, X, UX - add TMP2, TOP, TMP2, asl #1 - vld1.32 {yacc2lo[0]}, [TMP1], STRIDE - vzip.u8 xreg1, xreg3 - vld1.32 {yacc2hi[0]}, [TMP2], STRIDE - vzip.u8 xreg2, xreg4 - vld1.32 {yacc2lo[1]}, [TMP1] - vzip.u8 xreg3, xreg4 - vld1.32 {yacc2hi[1]}, [TMP2] - vzip.u8 xreg1, xreg2 - convert_0565_to_x888 yacc2, yreg3, yreg2, yreg1 - vmull.u8 xacc1, xreg1, d28 - vzip.u8 yreg1, yreg3 - vmlal.u8 xacc1, xreg2, d29 - vzip.u8 yreg2, yreg4 - vmull.u8 xacc2, xreg3, d28 - vzip.u8 yreg3, yreg4 - vmlal.u8 xacc2, xreg4, d29 - vzip.u8 yreg1, yreg2 - vmull.u8 yacc1, yreg1, d28 - vmlal.u8 yacc1, yreg2, d29 - vmull.u8 yacc2, yreg3, d28 - vmlal.u8 yacc2, yreg4, d29 -.endm - -.macro bilinear_store_8888 numpix, tmp1, tmp2 -.if numpix == 4 - vst1.32 {d0, d1}, [OUT, :128]! -.elseif numpix == 2 - vst1.32 {d0}, [OUT, :64]! -.elseif numpix == 1 - vst1.32 {d0[0]}, [OUT, :32]! -.else - .error bilinear_store_8888 numpix is unsupported -.endif -.endm - -.macro bilinear_store_0565 numpix, tmp1, tmp2 - vuzp.u8 d0, d1 - vuzp.u8 d2, d3 - vuzp.u8 d1, d3 - vuzp.u8 d0, d2 - convert_8888_to_0565 d2, d1, d0, q1, tmp1, tmp2 -.if numpix == 4 - vst1.16 {d2}, [OUT, :64]! -.elseif numpix == 2 - vst1.32 {d2[0]}, [OUT, :32]! -.elseif numpix == 1 - vst1.16 {d2[0]}, [OUT, :16]! -.else - .error bilinear_store_0565 numpix is unsupported -.endif -.endm - -.macro bilinear_interpolate_last_pixel src_fmt, dst_fmt - bilinear_load_&src_fmt d0, d1, d2 - vmull.u8 q1, d0, d28 - vmlal.u8 q1, d1, d29 - /* 5 cycles bubble */ - vshll.u16 q0, d2, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q0, d2, d30 - vmlal.u16 q0, d3, d30 - /* 5 cycles bubble */ - vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS) - /* 3 cycles bubble */ - vmovn.u16 d0, q0 - /* 1 cycle bubble */ - bilinear_store_&dst_fmt 1, q2, q3 -.endm - -.macro bilinear_interpolate_two_pixels src_fmt, dst_fmt - bilinear_load_and_vertical_interpolate_two_&src_fmt \ - q1, q11, d0, d1, d20, d21, d22, d23 - vshll.u16 q0, d2, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q0, d2, d30 - vmlal.u16 q0, d3, d30 - vshll.u16 q10, d22, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q10, d22, d31 - vmlal.u16 q10, d23, d31 - vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d1, q10, #(2 * BILINEAR_INTERPOLATION_BITS) - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vadd.u16 q12, q12, q13 - vmovn.u16 d0, q0 - bilinear_store_&dst_fmt 2, q2, q3 -.endm - -.macro bilinear_interpolate_four_pixels src_fmt, dst_fmt - bilinear_load_and_vertical_interpolate_four_&src_fmt \ - q1, q11, d0, d1, d20, d21, d22, d23 \ - q3, q9, d4, d5, d16, d17, d18, d19 - pld [TMP1, PF_OFFS] - sub TMP1, TMP1, STRIDE - vshll.u16 q0, d2, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q0, d2, d30 - vmlal.u16 q0, d3, d30 - vshll.u16 q10, d22, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q10, d22, d31 - vmlal.u16 q10, d23, d31 - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vshll.u16 q2, d6, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q2, d6, d30 - vmlal.u16 q2, d7, d30 - vshll.u16 q8, d18, #BILINEAR_INTERPOLATION_BITS - pld [TMP2, PF_OFFS] - vmlsl.u16 q8, d18, d31 - vmlal.u16 q8, d19, d31 - vadd.u16 q12, q12, q13 - vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d1, q10, #(2 * BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d4, q2, #(2 * BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d5, q8, #(2 * BILINEAR_INTERPOLATION_BITS) - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vmovn.u16 d0, q0 - vmovn.u16 d1, q2 - vadd.u16 q12, q12, q13 - bilinear_store_&dst_fmt 4, q2, q3 -.endm - -.macro bilinear_interpolate_four_pixels_head src_fmt, dst_fmt -.ifdef have_bilinear_interpolate_four_pixels_&src_fmt&_&dst_fmt - bilinear_interpolate_four_pixels_&src_fmt&_&dst_fmt&_head -.else - bilinear_interpolate_four_pixels src_fmt, dst_fmt -.endif -.endm - -.macro bilinear_interpolate_four_pixels_tail src_fmt, dst_fmt -.ifdef have_bilinear_interpolate_four_pixels_&src_fmt&_&dst_fmt - bilinear_interpolate_four_pixels_&src_fmt&_&dst_fmt&_tail -.endif -.endm - -.macro bilinear_interpolate_four_pixels_tail_head src_fmt, dst_fmt -.ifdef have_bilinear_interpolate_four_pixels_&src_fmt&_&dst_fmt - bilinear_interpolate_four_pixels_&src_fmt&_&dst_fmt&_tail_head -.else - bilinear_interpolate_four_pixels src_fmt, dst_fmt -.endif -.endm - -.macro bilinear_interpolate_eight_pixels_head src_fmt, dst_fmt -.ifdef have_bilinear_interpolate_eight_pixels_&src_fmt&_&dst_fmt - bilinear_interpolate_eight_pixels_&src_fmt&_&dst_fmt&_head -.else - bilinear_interpolate_four_pixels_head src_fmt, dst_fmt - bilinear_interpolate_four_pixels_tail_head src_fmt, dst_fmt -.endif -.endm - -.macro bilinear_interpolate_eight_pixels_tail src_fmt, dst_fmt -.ifdef have_bilinear_interpolate_eight_pixels_&src_fmt&_&dst_fmt - bilinear_interpolate_eight_pixels_&src_fmt&_&dst_fmt&_tail -.else - bilinear_interpolate_four_pixels_tail src_fmt, dst_fmt -.endif -.endm - -.macro bilinear_interpolate_eight_pixels_tail_head src_fmt, dst_fmt -.ifdef have_bilinear_interpolate_eight_pixels_&src_fmt&_&dst_fmt - bilinear_interpolate_eight_pixels_&src_fmt&_&dst_fmt&_tail_head -.else - bilinear_interpolate_four_pixels_tail_head src_fmt, dst_fmt - bilinear_interpolate_four_pixels_tail_head src_fmt, dst_fmt -.endif -.endm - -.set BILINEAR_FLAG_UNROLL_4, 0 -.set BILINEAR_FLAG_UNROLL_8, 1 -.set BILINEAR_FLAG_USE_ALL_NEON_REGS, 2 - -/* - * Main template macro for generating NEON optimized bilinear scanline - * functions. - * - * Bilinear scanline scaler macro template uses the following arguments: - * fname - name of the function to generate - * src_fmt - source color format (8888 or 0565) - * dst_fmt - destination color format (8888 or 0565) - * bpp_shift - (1 << bpp_shift) is the size of source pixel in bytes - * prefetch_distance - prefetch in the source image by that many - * pixels ahead - */ - -.macro generate_bilinear_scanline_func fname, src_fmt, dst_fmt, \ - src_bpp_shift, dst_bpp_shift, \ - prefetch_distance, flags - -pixman_asm_function fname - OUT .req r0 - TOP .req r1 - BOTTOM .req r2 - WT .req r3 - WB .req r4 - X .req r5 - UX .req r6 - WIDTH .req ip - TMP1 .req r3 - TMP2 .req r4 - PF_OFFS .req r7 - TMP3 .req r8 - TMP4 .req r9 - STRIDE .req r2 - - mov ip, sp - push {r4, r5, r6, r7, r8, r9} - mov PF_OFFS, #prefetch_distance - ldmia ip, {WB, X, UX, WIDTH} - mul PF_OFFS, PF_OFFS, UX - -.if ((flags) & BILINEAR_FLAG_USE_ALL_NEON_REGS) != 0 - vpush {d8-d15} -.endif - - sub STRIDE, BOTTOM, TOP - .unreq BOTTOM - - cmp WIDTH, #0 - ble 3f - - vdup.u16 q12, X - vdup.u16 q13, UX - vdup.u8 d28, WT - vdup.u8 d29, WB - vadd.u16 d25, d25, d26 - - /* ensure good destination alignment */ - cmp WIDTH, #1 - blt 0f - tst OUT, #(1 << dst_bpp_shift) - beq 0f - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vadd.u16 q12, q12, q13 - bilinear_interpolate_last_pixel src_fmt, dst_fmt - sub WIDTH, WIDTH, #1 -0: - vadd.u16 q13, q13, q13 - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vadd.u16 q12, q12, q13 - - cmp WIDTH, #2 - blt 0f - tst OUT, #(1 << (dst_bpp_shift + 1)) - beq 0f - bilinear_interpolate_two_pixels src_fmt, dst_fmt - sub WIDTH, WIDTH, #2 -0: -.if ((flags) & BILINEAR_FLAG_UNROLL_8) != 0 -/*********** 8 pixels per iteration *****************/ - cmp WIDTH, #4 - blt 0f - tst OUT, #(1 << (dst_bpp_shift + 2)) - beq 0f - bilinear_interpolate_four_pixels src_fmt, dst_fmt - sub WIDTH, WIDTH, #4 -0: - subs WIDTH, WIDTH, #8 - blt 1f - mov PF_OFFS, PF_OFFS, asr #(16 - src_bpp_shift) - bilinear_interpolate_eight_pixels_head src_fmt, dst_fmt - subs WIDTH, WIDTH, #8 - blt 5f -0: - bilinear_interpolate_eight_pixels_tail_head src_fmt, dst_fmt - subs WIDTH, WIDTH, #8 - bge 0b -5: - bilinear_interpolate_eight_pixels_tail src_fmt, dst_fmt -1: - tst WIDTH, #4 - beq 2f - bilinear_interpolate_four_pixels src_fmt, dst_fmt -2: -.else -/*********** 4 pixels per iteration *****************/ - subs WIDTH, WIDTH, #4 - blt 1f - mov PF_OFFS, PF_OFFS, asr #(16 - src_bpp_shift) - bilinear_interpolate_four_pixels_head src_fmt, dst_fmt - subs WIDTH, WIDTH, #4 - blt 5f -0: - bilinear_interpolate_four_pixels_tail_head src_fmt, dst_fmt - subs WIDTH, WIDTH, #4 - bge 0b -5: - bilinear_interpolate_four_pixels_tail src_fmt, dst_fmt -1: -/****************************************************/ -.endif - /* handle the remaining trailing pixels */ - tst WIDTH, #2 - beq 2f - bilinear_interpolate_two_pixels src_fmt, dst_fmt -2: - tst WIDTH, #1 - beq 3f - bilinear_interpolate_last_pixel src_fmt, dst_fmt -3: -.if ((flags) & BILINEAR_FLAG_USE_ALL_NEON_REGS) != 0 - vpop {d8-d15} -.endif - pop {r4, r5, r6, r7, r8, r9} - bx lr - - .unreq OUT - .unreq TOP - .unreq WT - .unreq WB - .unreq X - .unreq UX - .unreq WIDTH - .unreq TMP1 - .unreq TMP2 - .unreq PF_OFFS - .unreq TMP3 - .unreq TMP4 - .unreq STRIDE -.endfunc - -.endm - -/*****************************************************************************/ - -.set have_bilinear_interpolate_four_pixels_8888_8888, 1 - -.macro bilinear_interpolate_four_pixels_8888_8888_head - mov TMP1, X, asr #16 - add X, X, UX - add TMP1, TOP, TMP1, asl #2 - mov TMP2, X, asr #16 - add X, X, UX - add TMP2, TOP, TMP2, asl #2 - - vld1.32 {d22}, [TMP1], STRIDE - vld1.32 {d23}, [TMP1] - mov TMP3, X, asr #16 - add X, X, UX - add TMP3, TOP, TMP3, asl #2 - vmull.u8 q8, d22, d28 - vmlal.u8 q8, d23, d29 - - vld1.32 {d22}, [TMP2], STRIDE - vld1.32 {d23}, [TMP2] - mov TMP4, X, asr #16 - add X, X, UX - add TMP4, TOP, TMP4, asl #2 - vmull.u8 q9, d22, d28 - vmlal.u8 q9, d23, d29 - - vld1.32 {d22}, [TMP3], STRIDE - vld1.32 {d23}, [TMP3] - vmull.u8 q10, d22, d28 - vmlal.u8 q10, d23, d29 - - vshll.u16 q0, d16, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q0, d16, d30 - vmlal.u16 q0, d17, d30 - - pld [TMP4, PF_OFFS] - vld1.32 {d16}, [TMP4], STRIDE - vld1.32 {d17}, [TMP4] - pld [TMP4, PF_OFFS] - vmull.u8 q11, d16, d28 - vmlal.u8 q11, d17, d29 - - vshll.u16 q1, d18, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q1, d18, d31 -.endm - -.macro bilinear_interpolate_four_pixels_8888_8888_tail - vmlal.u16 q1, d19, d31 - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vshll.u16 q2, d20, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q2, d20, d30 - vmlal.u16 q2, d21, d30 - vshll.u16 q3, d22, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q3, d22, d31 - vmlal.u16 q3, d23, d31 - vadd.u16 q12, q12, q13 - vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d1, q1, #(2 * BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d4, q2, #(2 * BILINEAR_INTERPOLATION_BITS) - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d5, q3, #(2 * BILINEAR_INTERPOLATION_BITS) - vmovn.u16 d6, q0 - vmovn.u16 d7, q2 - vadd.u16 q12, q12, q13 - vst1.32 {d6, d7}, [OUT, :128]! -.endm - -.macro bilinear_interpolate_four_pixels_8888_8888_tail_head - mov TMP1, X, asr #16 - add X, X, UX - add TMP1, TOP, TMP1, asl #2 - mov TMP2, X, asr #16 - add X, X, UX - add TMP2, TOP, TMP2, asl #2 - vmlal.u16 q1, d19, d31 - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vshll.u16 q2, d20, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q2, d20, d30 - vmlal.u16 q2, d21, d30 - vshll.u16 q3, d22, #BILINEAR_INTERPOLATION_BITS - vld1.32 {d20}, [TMP1], STRIDE - vmlsl.u16 q3, d22, d31 - vmlal.u16 q3, d23, d31 - vld1.32 {d21}, [TMP1] - vmull.u8 q8, d20, d28 - vmlal.u8 q8, d21, d29 - vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d1, q1, #(2 * BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d4, q2, #(2 * BILINEAR_INTERPOLATION_BITS) - vld1.32 {d22}, [TMP2], STRIDE - vshrn.u32 d5, q3, #(2 * BILINEAR_INTERPOLATION_BITS) - vadd.u16 q12, q12, q13 - vld1.32 {d23}, [TMP2] - vmull.u8 q9, d22, d28 - mov TMP3, X, asr #16 - add X, X, UX - add TMP3, TOP, TMP3, asl #2 - mov TMP4, X, asr #16 - add X, X, UX - add TMP4, TOP, TMP4, asl #2 - vmlal.u8 q9, d23, d29 - vld1.32 {d22}, [TMP3], STRIDE - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vld1.32 {d23}, [TMP3] - vmull.u8 q10, d22, d28 - vmlal.u8 q10, d23, d29 - vmovn.u16 d6, q0 - vshll.u16 q0, d16, #BILINEAR_INTERPOLATION_BITS - vmovn.u16 d7, q2 - vmlsl.u16 q0, d16, d30 - vmlal.u16 q0, d17, d30 - pld [TMP4, PF_OFFS] - vld1.32 {d16}, [TMP4], STRIDE - vadd.u16 q12, q12, q13 - vld1.32 {d17}, [TMP4] - pld [TMP4, PF_OFFS] - vmull.u8 q11, d16, d28 - vmlal.u8 q11, d17, d29 - vst1.32 {d6, d7}, [OUT, :128]! - vshll.u16 q1, d18, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q1, d18, d31 -.endm - -/*****************************************************************************/ - -.set have_bilinear_interpolate_eight_pixels_8888_0565, 1 - -.macro bilinear_interpolate_eight_pixels_8888_0565_head - mov TMP1, X, asr #16 - add X, X, UX - add TMP1, TOP, TMP1, asl #2 - mov TMP2, X, asr #16 - add X, X, UX - add TMP2, TOP, TMP2, asl #2 - vld1.32 {d20}, [TMP1], STRIDE - vld1.32 {d21}, [TMP1] - vmull.u8 q8, d20, d28 - vmlal.u8 q8, d21, d29 - vld1.32 {d22}, [TMP2], STRIDE - vld1.32 {d23}, [TMP2] - vmull.u8 q9, d22, d28 - mov TMP3, X, asr #16 - add X, X, UX - add TMP3, TOP, TMP3, asl #2 - mov TMP4, X, asr #16 - add X, X, UX - add TMP4, TOP, TMP4, asl #2 - vmlal.u8 q9, d23, d29 - vld1.32 {d22}, [TMP3], STRIDE - vld1.32 {d23}, [TMP3] - vmull.u8 q10, d22, d28 - vmlal.u8 q10, d23, d29 - vshll.u16 q0, d16, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q0, d16, d30 - vmlal.u16 q0, d17, d30 - pld [TMP4, PF_OFFS] - vld1.32 {d16}, [TMP4], STRIDE - vld1.32 {d17}, [TMP4] - pld [TMP4, PF_OFFS] - vmull.u8 q11, d16, d28 - vmlal.u8 q11, d17, d29 - vshll.u16 q1, d18, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q1, d18, d31 - - mov TMP1, X, asr #16 - add X, X, UX - add TMP1, TOP, TMP1, asl #2 - mov TMP2, X, asr #16 - add X, X, UX - add TMP2, TOP, TMP2, asl #2 - vmlal.u16 q1, d19, d31 - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vshll.u16 q2, d20, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q2, d20, d30 - vmlal.u16 q2, d21, d30 - vshll.u16 q3, d22, #BILINEAR_INTERPOLATION_BITS - vld1.32 {d20}, [TMP1], STRIDE - vmlsl.u16 q3, d22, d31 - vmlal.u16 q3, d23, d31 - vld1.32 {d21}, [TMP1] - vmull.u8 q8, d20, d28 - vmlal.u8 q8, d21, d29 - vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d1, q1, #(2 * BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d4, q2, #(2 * BILINEAR_INTERPOLATION_BITS) - vld1.32 {d22}, [TMP2], STRIDE - vshrn.u32 d5, q3, #(2 * BILINEAR_INTERPOLATION_BITS) - vadd.u16 q12, q12, q13 - vld1.32 {d23}, [TMP2] - vmull.u8 q9, d22, d28 - mov TMP3, X, asr #16 - add X, X, UX - add TMP3, TOP, TMP3, asl #2 - mov TMP4, X, asr #16 - add X, X, UX - add TMP4, TOP, TMP4, asl #2 - vmlal.u8 q9, d23, d29 - vld1.32 {d22}, [TMP3], STRIDE - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vld1.32 {d23}, [TMP3] - vmull.u8 q10, d22, d28 - vmlal.u8 q10, d23, d29 - vmovn.u16 d8, q0 - vshll.u16 q0, d16, #BILINEAR_INTERPOLATION_BITS - vmovn.u16 d9, q2 - vmlsl.u16 q0, d16, d30 - vmlal.u16 q0, d17, d30 - pld [TMP4, PF_OFFS] - vld1.32 {d16}, [TMP4], STRIDE - vadd.u16 q12, q12, q13 - vld1.32 {d17}, [TMP4] - pld [TMP4, PF_OFFS] - vmull.u8 q11, d16, d28 - vmlal.u8 q11, d17, d29 - vshll.u16 q1, d18, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q1, d18, d31 -.endm - -.macro bilinear_interpolate_eight_pixels_8888_0565_tail - vmlal.u16 q1, d19, d31 - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vshll.u16 q2, d20, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q2, d20, d30 - vmlal.u16 q2, d21, d30 - vshll.u16 q3, d22, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q3, d22, d31 - vmlal.u16 q3, d23, d31 - vadd.u16 q12, q12, q13 - vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d1, q1, #(2 * BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d4, q2, #(2 * BILINEAR_INTERPOLATION_BITS) - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d5, q3, #(2 * BILINEAR_INTERPOLATION_BITS) - vmovn.u16 d10, q0 - vmovn.u16 d11, q2 - vadd.u16 q12, q12, q13 - - vuzp.u8 d8, d9 - vuzp.u8 d10, d11 - vuzp.u8 d9, d11 - vuzp.u8 d8, d10 - vshll.u8 q6, d9, #8 - vshll.u8 q5, d10, #8 - vshll.u8 q7, d8, #8 - vsri.u16 q5, q6, #5 - vsri.u16 q5, q7, #11 - vst1.32 {d10, d11}, [OUT, :128]! -.endm - -.macro bilinear_interpolate_eight_pixels_8888_0565_tail_head - mov TMP1, X, asr #16 - add X, X, UX - add TMP1, TOP, TMP1, asl #2 - mov TMP2, X, asr #16 - add X, X, UX - add TMP2, TOP, TMP2, asl #2 - vmlal.u16 q1, d19, d31 - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vuzp.u8 d8, d9 - vshll.u16 q2, d20, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q2, d20, d30 - vmlal.u16 q2, d21, d30 - vshll.u16 q3, d22, #BILINEAR_INTERPOLATION_BITS - vld1.32 {d20}, [TMP1], STRIDE - vmlsl.u16 q3, d22, d31 - vmlal.u16 q3, d23, d31 - vld1.32 {d21}, [TMP1] - vmull.u8 q8, d20, d28 - vmlal.u8 q8, d21, d29 - vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d1, q1, #(2 * BILINEAR_INTERPOLATION_BITS) - vshrn.u32 d4, q2, #(2 * BILINEAR_INTERPOLATION_BITS) - vld1.32 {d22}, [TMP2], STRIDE - vshrn.u32 d5, q3, #(2 * BILINEAR_INTERPOLATION_BITS) - vadd.u16 q12, q12, q13 - vld1.32 {d23}, [TMP2] - vmull.u8 q9, d22, d28 - mov TMP3, X, asr #16 - add X, X, UX - add TMP3, TOP, TMP3, asl #2 - mov TMP4, X, asr #16 - add X, X, UX - add TMP4, TOP, TMP4, asl #2 - vmlal.u8 q9, d23, d29 - vld1.32 {d22}, [TMP3], STRIDE - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vld1.32 {d23}, [TMP3] - vmull.u8 q10, d22, d28 - vmlal.u8 q10, d23, d29 - vmovn.u16 d10, q0 - vshll.u16 q0, d16, #BILINEAR_INTERPOLATION_BITS - vmovn.u16 d11, q2 - vmlsl.u16 q0, d16, d30 - vmlal.u16 q0, d17, d30 - pld [TMP4, PF_OFFS] - vld1.32 {d16}, [TMP4], STRIDE - vadd.u16 q12, q12, q13 - vld1.32 {d17}, [TMP4] - pld [TMP4, PF_OFFS] - vmull.u8 q11, d16, d28 - vmlal.u8 q11, d17, d29 - vuzp.u8 d10, d11 - vshll.u16 q1, d18, #BILINEAR_INTERPOLATION_BITS - vmlsl.u16 q1, d18, d31 - - mov TMP1, X, asr #16 - add X, X, UX - add TMP1, TOP, TMP1, asl #2 - mov TMP2, X, asr #16 - add X, X, UX - add TMP2, TOP, TMP2, asl #2 - vmlal.u16 q1, d19, d31 - vuzp.u8 d9, d11 - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vshll.u16 q2, d20, #BILINEAR_INTERPOLATION_BITS - vuzp.u8 d8, d10 - vmlsl.u16 q2, d20, d30 - vmlal.u16 q2, d21, d30 - vshll.u16 q3, d22, #BILINEAR_INTERPOLATION_BITS - vld1.32 {d20}, [TMP1], STRIDE - vmlsl.u16 q3, d22, d31 - vmlal.u16 q3, d23, d31 - vld1.32 {d21}, [TMP1] - vmull.u8 q8, d20, d28 - vmlal.u8 q8, d21, d29 - vshll.u8 q6, d9, #8 - vshll.u8 q5, d10, #8 - vshll.u8 q7, d8, #8 - vshrn.u32 d0, q0, #(2 * BILINEAR_INTERPOLATION_BITS) - vsri.u16 q5, q6, #5 - vshrn.u32 d1, q1, #(2 * BILINEAR_INTERPOLATION_BITS) - vsri.u16 q5, q7, #11 - vshrn.u32 d4, q2, #(2 * BILINEAR_INTERPOLATION_BITS) - vld1.32 {d22}, [TMP2], STRIDE - vshrn.u32 d5, q3, #(2 * BILINEAR_INTERPOLATION_BITS) - vadd.u16 q12, q12, q13 - vld1.32 {d23}, [TMP2] - vmull.u8 q9, d22, d28 - mov TMP3, X, asr #16 - add X, X, UX - add TMP3, TOP, TMP3, asl #2 - mov TMP4, X, asr #16 - add X, X, UX - add TMP4, TOP, TMP4, asl #2 - vmlal.u8 q9, d23, d29 - vld1.32 {d22}, [TMP3], STRIDE - vshr.u16 q15, q12, #(16 - BILINEAR_INTERPOLATION_BITS) - vld1.32 {d23}, [TMP3] - vmull.u8 q10, d22, d28 - vmlal.u8 q10, d23, d29 - vmovn.u16 d8, q0 - vshll.u16 q0, d16, #BILINEAR_INTERPOLATION_BITS - vmovn.u16 d9, q2 - vmlsl.u16 q0, d16, d30 - vmlal.u16 q0, d17, d30 - pld [TMP4, PF_OFFS] - vld1.32 {d16}, [TMP4], STRIDE - vadd.u16 q12, q12, q13 - vld1.32 {d17}, [TMP4] - pld [TMP4, PF_OFFS] - vmull.u8 q11, d16, d28 - vmlal.u8 q11, d17, d29 - vshll.u16 q1, d18, #BILINEAR_INTERPOLATION_BITS - vst1.32 {d10, d11}, [OUT, :128]! - vmlsl.u16 q1, d18, d31 -.endm -/*****************************************************************************/ - -generate_bilinear_scanline_func \ - pixman_scaled_bilinear_scanline_8888_8888_SRC_asm_neon, 8888, 8888, \ - 2, 2, 28, BILINEAR_FLAG_UNROLL_4 - -generate_bilinear_scanline_func \ - pixman_scaled_bilinear_scanline_8888_0565_SRC_asm_neon, 8888, 0565, \ - 2, 1, 28, BILINEAR_FLAG_UNROLL_8 | BILINEAR_FLAG_USE_ALL_NEON_REGS - -generate_bilinear_scanline_func \ - pixman_scaled_bilinear_scanline_0565_x888_SRC_asm_neon, 0565, 8888, \ - 1, 2, 28, BILINEAR_FLAG_UNROLL_4 - -generate_bilinear_scanline_func \ - pixman_scaled_bilinear_scanline_0565_0565_SRC_asm_neon, 0565, 0565, \ - 1, 1, 28, BILINEAR_FLAG_UNROLL_4 diff --git a/source/libs/pixman/pixman-src/pixman/pixman-arm-neon-asm.h b/source/libs/pixman/pixman-src/pixman/pixman-arm-neon-asm.h deleted file mode 100644 index bdcf6a9d47f30a93d03267dfe9a4b466f98350b1..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-arm-neon-asm.h +++ /dev/null @@ -1,1184 +0,0 @@ -/* - * Copyright © 2009 Nokia Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Siarhei Siamashka (siarhei.siamashka@nokia.com) - */ - -/* - * This file contains a macro ('generate_composite_function') which can - * construct 2D image processing functions, based on a common template. - * Any combinations of source, destination and mask images with 8bpp, - * 16bpp, 24bpp, 32bpp color formats are supported. - * - * This macro takes care of: - * - handling of leading and trailing unaligned pixels - * - doing most of the work related to L2 cache preload - * - encourages the use of software pipelining for better instructions - * scheduling - * - * The user of this macro has to provide some configuration parameters - * (bit depths for the images, prefetch distance, etc.) and a set of - * macros, which should implement basic code chunks responsible for - * pixels processing. See 'pixman-arm-neon-asm.S' file for the usage - * examples. - * - * TODO: - * - try overlapped pixel method (from Ian Rickards) when processing - * exactly two blocks of pixels - * - maybe add an option to do reverse scanline processing - */ - -/* - * Bit flags for 'generate_composite_function' macro which are used - * to tune generated functions behavior. - */ -.set FLAG_DST_WRITEONLY, 0 -.set FLAG_DST_READWRITE, 1 -.set FLAG_DEINTERLEAVE_32BPP, 2 - -/* - * Offset in stack where mask and source pointer/stride can be accessed - * from 'init' macro. This is useful for doing special handling for solid mask. - */ -.set ARGS_STACK_OFFSET, 40 - -/* - * Constants for selecting preferable prefetch type. - */ -.set PREFETCH_TYPE_NONE, 0 /* No prefetch at all */ -.set PREFETCH_TYPE_SIMPLE, 1 /* A simple, fixed-distance-ahead prefetch */ -.set PREFETCH_TYPE_ADVANCED, 2 /* Advanced fine-grained prefetch */ - -/* - * Definitions of supplementary pixld/pixst macros (for partial load/store of - * pixel data). - */ - -.macro pixldst1 op, elem_size, reg1, mem_operand, abits -.if abits > 0 - op&.&elem_size {d®1}, [&mem_operand&, :&abits&]! -.else - op&.&elem_size {d®1}, [&mem_operand&]! -.endif -.endm - -.macro pixldst2 op, elem_size, reg1, reg2, mem_operand, abits -.if abits > 0 - op&.&elem_size {d®1, d®2}, [&mem_operand&, :&abits&]! -.else - op&.&elem_size {d®1, d®2}, [&mem_operand&]! -.endif -.endm - -.macro pixldst4 op, elem_size, reg1, reg2, reg3, reg4, mem_operand, abits -.if abits > 0 - op&.&elem_size {d®1, d®2, d®3, d®4}, [&mem_operand&, :&abits&]! -.else - op&.&elem_size {d®1, d®2, d®3, d®4}, [&mem_operand&]! -.endif -.endm - -.macro pixldst0 op, elem_size, reg1, idx, mem_operand, abits - op&.&elem_size {d®1[idx]}, [&mem_operand&]! -.endm - -.macro pixldst3 op, elem_size, reg1, reg2, reg3, mem_operand - op&.&elem_size {d®1, d®2, d®3}, [&mem_operand&]! -.endm - -.macro pixldst30 op, elem_size, reg1, reg2, reg3, idx, mem_operand - op&.&elem_size {d®1[idx], d®2[idx], d®3[idx]}, [&mem_operand&]! -.endm - -.macro pixldst numbytes, op, elem_size, basereg, mem_operand, abits -.if numbytes == 32 - pixldst4 op, elem_size, %(basereg+4), %(basereg+5), \ - %(basereg+6), %(basereg+7), mem_operand, abits -.elseif numbytes == 16 - pixldst2 op, elem_size, %(basereg+2), %(basereg+3), mem_operand, abits -.elseif numbytes == 8 - pixldst1 op, elem_size, %(basereg+1), mem_operand, abits -.elseif numbytes == 4 - .if !RESPECT_STRICT_ALIGNMENT || (elem_size == 32) - pixldst0 op, 32, %(basereg+0), 1, mem_operand, abits - .elseif elem_size == 16 - pixldst0 op, 16, %(basereg+0), 2, mem_operand, abits - pixldst0 op, 16, %(basereg+0), 3, mem_operand, abits - .else - pixldst0 op, 8, %(basereg+0), 4, mem_operand, abits - pixldst0 op, 8, %(basereg+0), 5, mem_operand, abits - pixldst0 op, 8, %(basereg+0), 6, mem_operand, abits - pixldst0 op, 8, %(basereg+0), 7, mem_operand, abits - .endif -.elseif numbytes == 2 - .if !RESPECT_STRICT_ALIGNMENT || (elem_size == 16) - pixldst0 op, 16, %(basereg+0), 1, mem_operand, abits - .else - pixldst0 op, 8, %(basereg+0), 2, mem_operand, abits - pixldst0 op, 8, %(basereg+0), 3, mem_operand, abits - .endif -.elseif numbytes == 1 - pixldst0 op, 8, %(basereg+0), 1, mem_operand, abits -.else - .error "unsupported size: numbytes" -.endif -.endm - -.macro pixld numpix, bpp, basereg, mem_operand, abits=0 -.if bpp > 0 -.if (bpp == 32) && (numpix == 8) && (DEINTERLEAVE_32BPP_ENABLED != 0) - pixldst4 vld4, 8, %(basereg+4), %(basereg+5), \ - %(basereg+6), %(basereg+7), mem_operand, abits -.elseif (bpp == 24) && (numpix == 8) - pixldst3 vld3, 8, %(basereg+3), %(basereg+4), %(basereg+5), mem_operand -.elseif (bpp == 24) && (numpix == 4) - pixldst30 vld3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 4, mem_operand - pixldst30 vld3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 5, mem_operand - pixldst30 vld3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 6, mem_operand - pixldst30 vld3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 7, mem_operand -.elseif (bpp == 24) && (numpix == 2) - pixldst30 vld3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 2, mem_operand - pixldst30 vld3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 3, mem_operand -.elseif (bpp == 24) && (numpix == 1) - pixldst30 vld3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 1, mem_operand -.else - pixldst %(numpix * bpp / 8), vld1, %(bpp), basereg, mem_operand, abits -.endif -.endif -.endm - -.macro pixst numpix, bpp, basereg, mem_operand, abits=0 -.if bpp > 0 -.if (bpp == 32) && (numpix == 8) && (DEINTERLEAVE_32BPP_ENABLED != 0) - pixldst4 vst4, 8, %(basereg+4), %(basereg+5), \ - %(basereg+6), %(basereg+7), mem_operand, abits -.elseif (bpp == 24) && (numpix == 8) - pixldst3 vst3, 8, %(basereg+3), %(basereg+4), %(basereg+5), mem_operand -.elseif (bpp == 24) && (numpix == 4) - pixldst30 vst3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 4, mem_operand - pixldst30 vst3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 5, mem_operand - pixldst30 vst3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 6, mem_operand - pixldst30 vst3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 7, mem_operand -.elseif (bpp == 24) && (numpix == 2) - pixldst30 vst3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 2, mem_operand - pixldst30 vst3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 3, mem_operand -.elseif (bpp == 24) && (numpix == 1) - pixldst30 vst3, 8, %(basereg+0), %(basereg+1), %(basereg+2), 1, mem_operand -.else - pixldst %(numpix * bpp / 8), vst1, %(bpp), basereg, mem_operand, abits -.endif -.endif -.endm - -.macro pixld_a numpix, bpp, basereg, mem_operand -.if (bpp * numpix) <= 128 - pixld numpix, bpp, basereg, mem_operand, %(bpp * numpix) -.else - pixld numpix, bpp, basereg, mem_operand, 128 -.endif -.endm - -.macro pixst_a numpix, bpp, basereg, mem_operand -.if (bpp * numpix) <= 128 - pixst numpix, bpp, basereg, mem_operand, %(bpp * numpix) -.else - pixst numpix, bpp, basereg, mem_operand, 128 -.endif -.endm - -/* - * Pixel fetcher for nearest scaling (needs TMP1, TMP2, VX, UNIT_X register - * aliases to be defined) - */ -.macro pixld1_s elem_size, reg1, mem_operand -.if elem_size == 16 - mov TMP1, VX, asr #16 - adds VX, VX, UNIT_X -5: subpls VX, VX, SRC_WIDTH_FIXED - bpl 5b - add TMP1, mem_operand, TMP1, asl #1 - mov TMP2, VX, asr #16 - adds VX, VX, UNIT_X -5: subpls VX, VX, SRC_WIDTH_FIXED - bpl 5b - add TMP2, mem_operand, TMP2, asl #1 - vld1.16 {d®1&[0]}, [TMP1, :16] - mov TMP1, VX, asr #16 - adds VX, VX, UNIT_X -5: subpls VX, VX, SRC_WIDTH_FIXED - bpl 5b - add TMP1, mem_operand, TMP1, asl #1 - vld1.16 {d®1&[1]}, [TMP2, :16] - mov TMP2, VX, asr #16 - adds VX, VX, UNIT_X -5: subpls VX, VX, SRC_WIDTH_FIXED - bpl 5b - add TMP2, mem_operand, TMP2, asl #1 - vld1.16 {d®1&[2]}, [TMP1, :16] - vld1.16 {d®1&[3]}, [TMP2, :16] -.elseif elem_size == 32 - mov TMP1, VX, asr #16 - adds VX, VX, UNIT_X -5: subpls VX, VX, SRC_WIDTH_FIXED - bpl 5b - add TMP1, mem_operand, TMP1, asl #2 - mov TMP2, VX, asr #16 - adds VX, VX, UNIT_X -5: subpls VX, VX, SRC_WIDTH_FIXED - bpl 5b - add TMP2, mem_operand, TMP2, asl #2 - vld1.32 {d®1&[0]}, [TMP1, :32] - vld1.32 {d®1&[1]}, [TMP2, :32] -.else - .error "unsupported" -.endif -.endm - -.macro pixld2_s elem_size, reg1, reg2, mem_operand -.if 0 /* elem_size == 32 */ - mov TMP1, VX, asr #16 - add VX, VX, UNIT_X, asl #1 - add TMP1, mem_operand, TMP1, asl #2 - mov TMP2, VX, asr #16 - sub VX, VX, UNIT_X - add TMP2, mem_operand, TMP2, asl #2 - vld1.32 {d®1&[0]}, [TMP1, :32] - mov TMP1, VX, asr #16 - add VX, VX, UNIT_X, asl #1 - add TMP1, mem_operand, TMP1, asl #2 - vld1.32 {d®2&[0]}, [TMP2, :32] - mov TMP2, VX, asr #16 - add VX, VX, UNIT_X - add TMP2, mem_operand, TMP2, asl #2 - vld1.32 {d®1&[1]}, [TMP1, :32] - vld1.32 {d®2&[1]}, [TMP2, :32] -.else - pixld1_s elem_size, reg1, mem_operand - pixld1_s elem_size, reg2, mem_operand -.endif -.endm - -.macro pixld0_s elem_size, reg1, idx, mem_operand -.if elem_size == 16 - mov TMP1, VX, asr #16 - adds VX, VX, UNIT_X -5: subpls VX, VX, SRC_WIDTH_FIXED - bpl 5b - add TMP1, mem_operand, TMP1, asl #1 - vld1.16 {d®1&[idx]}, [TMP1, :16] -.elseif elem_size == 32 - mov TMP1, VX, asr #16 - adds VX, VX, UNIT_X -5: subpls VX, VX, SRC_WIDTH_FIXED - bpl 5b - add TMP1, mem_operand, TMP1, asl #2 - vld1.32 {d®1&[idx]}, [TMP1, :32] -.endif -.endm - -.macro pixld_s_internal numbytes, elem_size, basereg, mem_operand -.if numbytes == 32 - pixld2_s elem_size, %(basereg+4), %(basereg+5), mem_operand - pixld2_s elem_size, %(basereg+6), %(basereg+7), mem_operand - pixdeinterleave elem_size, %(basereg+4) -.elseif numbytes == 16 - pixld2_s elem_size, %(basereg+2), %(basereg+3), mem_operand -.elseif numbytes == 8 - pixld1_s elem_size, %(basereg+1), mem_operand -.elseif numbytes == 4 - .if elem_size == 32 - pixld0_s elem_size, %(basereg+0), 1, mem_operand - .elseif elem_size == 16 - pixld0_s elem_size, %(basereg+0), 2, mem_operand - pixld0_s elem_size, %(basereg+0), 3, mem_operand - .else - pixld0_s elem_size, %(basereg+0), 4, mem_operand - pixld0_s elem_size, %(basereg+0), 5, mem_operand - pixld0_s elem_size, %(basereg+0), 6, mem_operand - pixld0_s elem_size, %(basereg+0), 7, mem_operand - .endif -.elseif numbytes == 2 - .if elem_size == 16 - pixld0_s elem_size, %(basereg+0), 1, mem_operand - .else - pixld0_s elem_size, %(basereg+0), 2, mem_operand - pixld0_s elem_size, %(basereg+0), 3, mem_operand - .endif -.elseif numbytes == 1 - pixld0_s elem_size, %(basereg+0), 1, mem_operand -.else - .error "unsupported size: numbytes" -.endif -.endm - -.macro pixld_s numpix, bpp, basereg, mem_operand -.if bpp > 0 - pixld_s_internal %(numpix * bpp / 8), %(bpp), basereg, mem_operand -.endif -.endm - -.macro vuzp8 reg1, reg2 - vuzp.8 d®1, d®2 -.endm - -.macro vzip8 reg1, reg2 - vzip.8 d®1, d®2 -.endm - -/* deinterleave B, G, R, A channels for eight 32bpp pixels in 4 registers */ -.macro pixdeinterleave bpp, basereg -.if (bpp == 32) && (DEINTERLEAVE_32BPP_ENABLED != 0) - vuzp8 %(basereg+0), %(basereg+1) - vuzp8 %(basereg+2), %(basereg+3) - vuzp8 %(basereg+1), %(basereg+3) - vuzp8 %(basereg+0), %(basereg+2) -.endif -.endm - -/* interleave B, G, R, A channels for eight 32bpp pixels in 4 registers */ -.macro pixinterleave bpp, basereg -.if (bpp == 32) && (DEINTERLEAVE_32BPP_ENABLED != 0) - vzip8 %(basereg+0), %(basereg+2) - vzip8 %(basereg+1), %(basereg+3) - vzip8 %(basereg+2), %(basereg+3) - vzip8 %(basereg+0), %(basereg+1) -.endif -.endm - -/* - * This is a macro for implementing cache preload. The main idea is that - * cache preload logic is mostly independent from the rest of pixels - * processing code. It starts at the top left pixel and moves forward - * across pixels and can jump across scanlines. Prefetch distance is - * handled in an 'incremental' way: it starts from 0 and advances to the - * optimal distance over time. After reaching optimal prefetch distance, - * it is kept constant. There are some checks which prevent prefetching - * unneeded pixel lines below the image (but it still can prefetch a bit - * more data on the right side of the image - not a big issue and may - * be actually helpful when rendering text glyphs). Additional trick is - * the use of LDR instruction for prefetch instead of PLD when moving to - * the next line, the point is that we have a high chance of getting TLB - * miss in this case, and PLD would be useless. - * - * This sounds like it may introduce a noticeable overhead (when working with - * fully cached data). But in reality, due to having a separate pipeline and - * instruction queue for NEON unit in ARM Cortex-A8, normal ARM code can - * execute simultaneously with NEON and be completely shadowed by it. Thus - * we get no performance overhead at all (*). This looks like a very nice - * feature of Cortex-A8, if used wisely. We don't have a hardware prefetcher, - * but still can implement some rather advanced prefetch logic in software - * for almost zero cost! - * - * (*) The overhead of the prefetcher is visible when running some trivial - * pixels processing like simple copy. Anyway, having prefetch is a must - * when working with the graphics data. - */ -.macro PF a, x:vararg -.if (PREFETCH_TYPE_CURRENT == PREFETCH_TYPE_ADVANCED) - a x -.endif -.endm - -.macro cache_preload std_increment, boost_increment -.if (src_bpp_shift >= 0) || (dst_r_bpp != 0) || (mask_bpp_shift >= 0) -.if regs_shortage - PF ldr ORIG_W, [sp] /* If we are short on regs, ORIG_W is kept on stack */ -.endif -.if std_increment != 0 - PF add PF_X, PF_X, #std_increment -.endif - PF tst PF_CTL, #0xF - PF addne PF_X, PF_X, #boost_increment - PF subne PF_CTL, PF_CTL, #1 - PF cmp PF_X, ORIG_W -.if src_bpp_shift >= 0 - PF pld, [PF_SRC, PF_X, lsl #src_bpp_shift] -.endif -.if dst_r_bpp != 0 - PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift] -.endif -.if mask_bpp_shift >= 0 - PF pld, [PF_MASK, PF_X, lsl #mask_bpp_shift] -.endif - PF subge PF_X, PF_X, ORIG_W - PF subges PF_CTL, PF_CTL, #0x10 -.if src_bpp_shift >= 0 - PF ldrgeb DUMMY, [PF_SRC, SRC_STRIDE, lsl #src_bpp_shift]! -.endif -.if dst_r_bpp != 0 - PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]! -.endif -.if mask_bpp_shift >= 0 - PF ldrgeb DUMMY, [PF_MASK, MASK_STRIDE, lsl #mask_bpp_shift]! -.endif -.endif -.endm - -.macro cache_preload_simple -.if (PREFETCH_TYPE_CURRENT == PREFETCH_TYPE_SIMPLE) -.if src_bpp > 0 - pld [SRC, #(PREFETCH_DISTANCE_SIMPLE * src_bpp / 8)] -.endif -.if dst_r_bpp > 0 - pld [DST_R, #(PREFETCH_DISTANCE_SIMPLE * dst_r_bpp / 8)] -.endif -.if mask_bpp > 0 - pld [MASK, #(PREFETCH_DISTANCE_SIMPLE * mask_bpp / 8)] -.endif -.endif -.endm - -.macro fetch_mask_pixblock - pixld pixblock_size, mask_bpp, \ - (mask_basereg - pixblock_size * mask_bpp / 64), MASK -.endm - -/* - * Macro which is used to process leading pixels until destination - * pointer is properly aligned (at 16 bytes boundary). When destination - * buffer uses 16bpp format, this is unnecessary, or even pointless. - */ -.macro ensure_destination_ptr_alignment process_pixblock_head, \ - process_pixblock_tail, \ - process_pixblock_tail_head -.if dst_w_bpp != 24 - tst DST_R, #0xF - beq 2f - -.irp lowbit, 1, 2, 4, 8, 16 -local skip1 -.if (dst_w_bpp <= (lowbit * 8)) && ((lowbit * 8) < (pixblock_size * dst_w_bpp)) -.if lowbit < 16 /* we don't need more than 16-byte alignment */ - tst DST_R, #lowbit - beq 1f -.endif - pixld_src (lowbit * 8 / dst_w_bpp), src_bpp, src_basereg, SRC - pixld (lowbit * 8 / dst_w_bpp), mask_bpp, mask_basereg, MASK -.if dst_r_bpp > 0 - pixld_a (lowbit * 8 / dst_r_bpp), dst_r_bpp, dst_r_basereg, DST_R -.else - add DST_R, DST_R, #lowbit -.endif - PF add PF_X, PF_X, #(lowbit * 8 / dst_w_bpp) - sub W, W, #(lowbit * 8 / dst_w_bpp) -1: -.endif -.endr - pixdeinterleave src_bpp, src_basereg - pixdeinterleave mask_bpp, mask_basereg - pixdeinterleave dst_r_bpp, dst_r_basereg - - process_pixblock_head - cache_preload 0, pixblock_size - cache_preload_simple - process_pixblock_tail - - pixinterleave dst_w_bpp, dst_w_basereg -.irp lowbit, 1, 2, 4, 8, 16 -.if (dst_w_bpp <= (lowbit * 8)) && ((lowbit * 8) < (pixblock_size * dst_w_bpp)) -.if lowbit < 16 /* we don't need more than 16-byte alignment */ - tst DST_W, #lowbit - beq 1f -.endif - pixst_a (lowbit * 8 / dst_w_bpp), dst_w_bpp, dst_w_basereg, DST_W -1: -.endif -.endr -.endif -2: -.endm - -/* - * Special code for processing up to (pixblock_size - 1) remaining - * trailing pixels. As SIMD processing performs operation on - * pixblock_size pixels, anything smaller than this has to be loaded - * and stored in a special way. Loading and storing of pixel data is - * performed in such a way that we fill some 'slots' in the NEON - * registers (some slots naturally are unused), then perform compositing - * operation as usual. In the end, the data is taken from these 'slots' - * and saved to memory. - * - * cache_preload_flag - allows to suppress prefetch if - * set to 0 - * dst_aligned_flag - selects whether destination buffer - * is aligned - */ -.macro process_trailing_pixels cache_preload_flag, \ - dst_aligned_flag, \ - process_pixblock_head, \ - process_pixblock_tail, \ - process_pixblock_tail_head - tst W, #(pixblock_size - 1) - beq 2f -.irp chunk_size, 16, 8, 4, 2, 1 -.if pixblock_size > chunk_size - tst W, #chunk_size - beq 1f - pixld_src chunk_size, src_bpp, src_basereg, SRC - pixld chunk_size, mask_bpp, mask_basereg, MASK -.if dst_aligned_flag != 0 - pixld_a chunk_size, dst_r_bpp, dst_r_basereg, DST_R -.else - pixld chunk_size, dst_r_bpp, dst_r_basereg, DST_R -.endif -.if cache_preload_flag != 0 - PF add PF_X, PF_X, #chunk_size -.endif -1: -.endif -.endr - pixdeinterleave src_bpp, src_basereg - pixdeinterleave mask_bpp, mask_basereg - pixdeinterleave dst_r_bpp, dst_r_basereg - - process_pixblock_head -.if cache_preload_flag != 0 - cache_preload 0, pixblock_size - cache_preload_simple -.endif - process_pixblock_tail - pixinterleave dst_w_bpp, dst_w_basereg -.irp chunk_size, 16, 8, 4, 2, 1 -.if pixblock_size > chunk_size - tst W, #chunk_size - beq 1f -.if dst_aligned_flag != 0 - pixst_a chunk_size, dst_w_bpp, dst_w_basereg, DST_W -.else - pixst chunk_size, dst_w_bpp, dst_w_basereg, DST_W -.endif -1: -.endif -.endr -2: -.endm - -/* - * Macro, which performs all the needed operations to switch to the next - * scanline and start the next loop iteration unless all the scanlines - * are already processed. - */ -.macro advance_to_next_scanline start_of_loop_label -.if regs_shortage - ldrd W, [sp] /* load W and H (width and height) from stack */ -.else - mov W, ORIG_W -.endif - add DST_W, DST_W, DST_STRIDE, lsl #dst_bpp_shift -.if src_bpp != 0 - add SRC, SRC, SRC_STRIDE, lsl #src_bpp_shift -.endif -.if mask_bpp != 0 - add MASK, MASK, MASK_STRIDE, lsl #mask_bpp_shift -.endif -.if (dst_w_bpp != 24) - sub DST_W, DST_W, W, lsl #dst_bpp_shift -.endif -.if (src_bpp != 24) && (src_bpp != 0) - sub SRC, SRC, W, lsl #src_bpp_shift -.endif -.if (mask_bpp != 24) && (mask_bpp != 0) - sub MASK, MASK, W, lsl #mask_bpp_shift -.endif - subs H, H, #1 - mov DST_R, DST_W -.if regs_shortage - str H, [sp, #4] /* save updated height to stack */ -.endif - bge start_of_loop_label -.endm - -/* - * Registers are allocated in the following way by default: - * d0, d1, d2, d3 - reserved for loading source pixel data - * d4, d5, d6, d7 - reserved for loading destination pixel data - * d24, d25, d26, d27 - reserved for loading mask pixel data - * d28, d29, d30, d31 - final destination pixel data for writeback to memory - */ -.macro generate_composite_function fname, \ - src_bpp_, \ - mask_bpp_, \ - dst_w_bpp_, \ - flags, \ - pixblock_size_, \ - prefetch_distance, \ - init, \ - cleanup, \ - process_pixblock_head, \ - process_pixblock_tail, \ - process_pixblock_tail_head, \ - dst_w_basereg_ = 28, \ - dst_r_basereg_ = 4, \ - src_basereg_ = 0, \ - mask_basereg_ = 24 - - pixman_asm_function fname - - push {r4-r12, lr} /* save all registers */ - -/* - * Select prefetch type for this function. If prefetch distance is - * set to 0 or one of the color formats is 24bpp, SIMPLE prefetch - * has to be used instead of ADVANCED. - */ - .set PREFETCH_TYPE_CURRENT, PREFETCH_TYPE_DEFAULT -.if prefetch_distance == 0 - .set PREFETCH_TYPE_CURRENT, PREFETCH_TYPE_NONE -.elseif (PREFETCH_TYPE_CURRENT > PREFETCH_TYPE_SIMPLE) && \ - ((src_bpp_ == 24) || (mask_bpp_ == 24) || (dst_w_bpp_ == 24)) - .set PREFETCH_TYPE_CURRENT, PREFETCH_TYPE_SIMPLE -.endif - -/* - * Make some macro arguments globally visible and accessible - * from other macros - */ - .set src_bpp, src_bpp_ - .set mask_bpp, mask_bpp_ - .set dst_w_bpp, dst_w_bpp_ - .set pixblock_size, pixblock_size_ - .set dst_w_basereg, dst_w_basereg_ - .set dst_r_basereg, dst_r_basereg_ - .set src_basereg, src_basereg_ - .set mask_basereg, mask_basereg_ - - .macro pixld_src x:vararg - pixld x - .endm - .macro fetch_src_pixblock - pixld_src pixblock_size, src_bpp, \ - (src_basereg - pixblock_size * src_bpp / 64), SRC - .endm -/* - * Assign symbolic names to registers - */ - W .req r0 /* width (is updated during processing) */ - H .req r1 /* height (is updated during processing) */ - DST_W .req r2 /* destination buffer pointer for writes */ - DST_STRIDE .req r3 /* destination image stride */ - SRC .req r4 /* source buffer pointer */ - SRC_STRIDE .req r5 /* source image stride */ - DST_R .req r6 /* destination buffer pointer for reads */ - - MASK .req r7 /* mask pointer */ - MASK_STRIDE .req r8 /* mask stride */ - - PF_CTL .req r9 /* combined lines counter and prefetch */ - /* distance increment counter */ - PF_X .req r10 /* pixel index in a scanline for current */ - /* pretetch position */ - PF_SRC .req r11 /* pointer to source scanline start */ - /* for prefetch purposes */ - PF_DST .req r12 /* pointer to destination scanline start */ - /* for prefetch purposes */ - PF_MASK .req r14 /* pointer to mask scanline start */ - /* for prefetch purposes */ -/* - * Check whether we have enough registers for all the local variables. - * If we don't have enough registers, original width and height are - * kept on top of stack (and 'regs_shortage' variable is set to indicate - * this for the rest of code). Even if there are enough registers, the - * allocation scheme may be a bit different depending on whether source - * or mask is not used. - */ -.if (PREFETCH_TYPE_CURRENT < PREFETCH_TYPE_ADVANCED) - ORIG_W .req r10 /* saved original width */ - DUMMY .req r12 /* temporary register */ - .set regs_shortage, 0 -.elseif mask_bpp == 0 - ORIG_W .req r7 /* saved original width */ - DUMMY .req r8 /* temporary register */ - .set regs_shortage, 0 -.elseif src_bpp == 0 - ORIG_W .req r4 /* saved original width */ - DUMMY .req r5 /* temporary register */ - .set regs_shortage, 0 -.else - ORIG_W .req r1 /* saved original width */ - DUMMY .req r1 /* temporary register */ - .set regs_shortage, 1 -.endif - - .set mask_bpp_shift, -1 -.if src_bpp == 32 - .set src_bpp_shift, 2 -.elseif src_bpp == 24 - .set src_bpp_shift, 0 -.elseif src_bpp == 16 - .set src_bpp_shift, 1 -.elseif src_bpp == 8 - .set src_bpp_shift, 0 -.elseif src_bpp == 0 - .set src_bpp_shift, -1 -.else - .error "requested src bpp (src_bpp) is not supported" -.endif -.if mask_bpp == 32 - .set mask_bpp_shift, 2 -.elseif mask_bpp == 24 - .set mask_bpp_shift, 0 -.elseif mask_bpp == 8 - .set mask_bpp_shift, 0 -.elseif mask_bpp == 0 - .set mask_bpp_shift, -1 -.else - .error "requested mask bpp (mask_bpp) is not supported" -.endif -.if dst_w_bpp == 32 - .set dst_bpp_shift, 2 -.elseif dst_w_bpp == 24 - .set dst_bpp_shift, 0 -.elseif dst_w_bpp == 16 - .set dst_bpp_shift, 1 -.elseif dst_w_bpp == 8 - .set dst_bpp_shift, 0 -.else - .error "requested dst bpp (dst_w_bpp) is not supported" -.endif - -.if (((flags) & FLAG_DST_READWRITE) != 0) - .set dst_r_bpp, dst_w_bpp -.else - .set dst_r_bpp, 0 -.endif -.if (((flags) & FLAG_DEINTERLEAVE_32BPP) != 0) - .set DEINTERLEAVE_32BPP_ENABLED, 1 -.else - .set DEINTERLEAVE_32BPP_ENABLED, 0 -.endif - -.if prefetch_distance < 0 || prefetch_distance > 15 - .error "invalid prefetch distance (prefetch_distance)" -.endif - -.if src_bpp > 0 - ldr SRC, [sp, #40] -.endif -.if mask_bpp > 0 - ldr MASK, [sp, #48] -.endif - PF mov PF_X, #0 -.if src_bpp > 0 - ldr SRC_STRIDE, [sp, #44] -.endif -.if mask_bpp > 0 - ldr MASK_STRIDE, [sp, #52] -.endif - mov DST_R, DST_W - -.if src_bpp == 24 - sub SRC_STRIDE, SRC_STRIDE, W - sub SRC_STRIDE, SRC_STRIDE, W, lsl #1 -.endif -.if mask_bpp == 24 - sub MASK_STRIDE, MASK_STRIDE, W - sub MASK_STRIDE, MASK_STRIDE, W, lsl #1 -.endif -.if dst_w_bpp == 24 - sub DST_STRIDE, DST_STRIDE, W - sub DST_STRIDE, DST_STRIDE, W, lsl #1 -.endif - -/* - * Setup advanced prefetcher initial state - */ - PF mov PF_SRC, SRC - PF mov PF_DST, DST_R - PF mov PF_MASK, MASK - /* PF_CTL = prefetch_distance | ((h - 1) << 4) */ - PF mov PF_CTL, H, lsl #4 - PF add PF_CTL, #(prefetch_distance - 0x10) - - init -.if regs_shortage - push {r0, r1} -.endif - subs H, H, #1 -.if regs_shortage - str H, [sp, #4] /* save updated height to stack */ -.else - mov ORIG_W, W -.endif - blt 9f - cmp W, #(pixblock_size * 2) - blt 8f -/* - * This is the start of the pipelined loop, which if optimized for - * long scanlines - */ -0: - ensure_destination_ptr_alignment process_pixblock_head, \ - process_pixblock_tail, \ - process_pixblock_tail_head - - /* Implement "head (tail_head) ... (tail_head) tail" loop pattern */ - pixld_a pixblock_size, dst_r_bpp, \ - (dst_r_basereg - pixblock_size * dst_r_bpp / 64), DST_R - fetch_src_pixblock - pixld pixblock_size, mask_bpp, \ - (mask_basereg - pixblock_size * mask_bpp / 64), MASK - PF add PF_X, PF_X, #pixblock_size - process_pixblock_head - cache_preload 0, pixblock_size - cache_preload_simple - subs W, W, #(pixblock_size * 2) - blt 2f -1: - process_pixblock_tail_head - cache_preload_simple - subs W, W, #pixblock_size - bge 1b -2: - process_pixblock_tail - pixst_a pixblock_size, dst_w_bpp, \ - (dst_w_basereg - pixblock_size * dst_w_bpp / 64), DST_W - - /* Process the remaining trailing pixels in the scanline */ - process_trailing_pixels 1, 1, \ - process_pixblock_head, \ - process_pixblock_tail, \ - process_pixblock_tail_head - advance_to_next_scanline 0b - -.if regs_shortage - pop {r0, r1} -.endif - cleanup - pop {r4-r12, pc} /* exit */ -/* - * This is the start of the loop, designed to process images with small width - * (less than pixblock_size * 2 pixels). In this case neither pipelining - * nor prefetch are used. - */ -8: - /* Process exactly pixblock_size pixels if needed */ - tst W, #pixblock_size - beq 1f - pixld pixblock_size, dst_r_bpp, \ - (dst_r_basereg - pixblock_size * dst_r_bpp / 64), DST_R - fetch_src_pixblock - pixld pixblock_size, mask_bpp, \ - (mask_basereg - pixblock_size * mask_bpp / 64), MASK - process_pixblock_head - process_pixblock_tail - pixst pixblock_size, dst_w_bpp, \ - (dst_w_basereg - pixblock_size * dst_w_bpp / 64), DST_W -1: - /* Process the remaining trailing pixels in the scanline */ - process_trailing_pixels 0, 0, \ - process_pixblock_head, \ - process_pixblock_tail, \ - process_pixblock_tail_head - advance_to_next_scanline 8b -9: -.if regs_shortage - pop {r0, r1} -.endif - cleanup - pop {r4-r12, pc} /* exit */ - - .purgem fetch_src_pixblock - .purgem pixld_src - - .unreq SRC - .unreq MASK - .unreq DST_R - .unreq DST_W - .unreq ORIG_W - .unreq W - .unreq H - .unreq SRC_STRIDE - .unreq DST_STRIDE - .unreq MASK_STRIDE - .unreq PF_CTL - .unreq PF_X - .unreq PF_SRC - .unreq PF_DST - .unreq PF_MASK - .unreq DUMMY - .endfunc -.endm - -/* - * A simplified variant of function generation template for a single - * scanline processing (for implementing pixman combine functions) - */ -.macro generate_composite_function_scanline use_nearest_scaling, \ - fname, \ - src_bpp_, \ - mask_bpp_, \ - dst_w_bpp_, \ - flags, \ - pixblock_size_, \ - init, \ - cleanup, \ - process_pixblock_head, \ - process_pixblock_tail, \ - process_pixblock_tail_head, \ - dst_w_basereg_ = 28, \ - dst_r_basereg_ = 4, \ - src_basereg_ = 0, \ - mask_basereg_ = 24 - - pixman_asm_function fname - - .set PREFETCH_TYPE_CURRENT, PREFETCH_TYPE_NONE -/* - * Make some macro arguments globally visible and accessible - * from other macros - */ - .set src_bpp, src_bpp_ - .set mask_bpp, mask_bpp_ - .set dst_w_bpp, dst_w_bpp_ - .set pixblock_size, pixblock_size_ - .set dst_w_basereg, dst_w_basereg_ - .set dst_r_basereg, dst_r_basereg_ - .set src_basereg, src_basereg_ - .set mask_basereg, mask_basereg_ - -.if use_nearest_scaling != 0 - /* - * Assign symbolic names to registers for nearest scaling - */ - W .req r0 - DST_W .req r1 - SRC .req r2 - VX .req r3 - UNIT_X .req ip - MASK .req lr - TMP1 .req r4 - TMP2 .req r5 - DST_R .req r6 - SRC_WIDTH_FIXED .req r7 - - .macro pixld_src x:vararg - pixld_s x - .endm - - ldr UNIT_X, [sp] - push {r4-r8, lr} - ldr SRC_WIDTH_FIXED, [sp, #(24 + 4)] - .if mask_bpp != 0 - ldr MASK, [sp, #(24 + 8)] - .endif -.else - /* - * Assign symbolic names to registers - */ - W .req r0 /* width (is updated during processing) */ - DST_W .req r1 /* destination buffer pointer for writes */ - SRC .req r2 /* source buffer pointer */ - DST_R .req ip /* destination buffer pointer for reads */ - MASK .req r3 /* mask pointer */ - - .macro pixld_src x:vararg - pixld x - .endm -.endif - -.if (((flags) & FLAG_DST_READWRITE) != 0) - .set dst_r_bpp, dst_w_bpp -.else - .set dst_r_bpp, 0 -.endif -.if (((flags) & FLAG_DEINTERLEAVE_32BPP) != 0) - .set DEINTERLEAVE_32BPP_ENABLED, 1 -.else - .set DEINTERLEAVE_32BPP_ENABLED, 0 -.endif - - .macro fetch_src_pixblock - pixld_src pixblock_size, src_bpp, \ - (src_basereg - pixblock_size * src_bpp / 64), SRC - .endm - - init - mov DST_R, DST_W - - cmp W, #pixblock_size - blt 8f - - ensure_destination_ptr_alignment process_pixblock_head, \ - process_pixblock_tail, \ - process_pixblock_tail_head - - subs W, W, #pixblock_size - blt 7f - - /* Implement "head (tail_head) ... (tail_head) tail" loop pattern */ - pixld_a pixblock_size, dst_r_bpp, \ - (dst_r_basereg - pixblock_size * dst_r_bpp / 64), DST_R - fetch_src_pixblock - pixld pixblock_size, mask_bpp, \ - (mask_basereg - pixblock_size * mask_bpp / 64), MASK - process_pixblock_head - subs W, W, #pixblock_size - blt 2f -1: - process_pixblock_tail_head - subs W, W, #pixblock_size - bge 1b -2: - process_pixblock_tail - pixst_a pixblock_size, dst_w_bpp, \ - (dst_w_basereg - pixblock_size * dst_w_bpp / 64), DST_W -7: - /* Process the remaining trailing pixels in the scanline (dst aligned) */ - process_trailing_pixels 0, 1, \ - process_pixblock_head, \ - process_pixblock_tail, \ - process_pixblock_tail_head - - cleanup -.if use_nearest_scaling != 0 - pop {r4-r8, pc} /* exit */ -.else - bx lr /* exit */ -.endif -8: - /* Process the remaining trailing pixels in the scanline (dst unaligned) */ - process_trailing_pixels 0, 0, \ - process_pixblock_head, \ - process_pixblock_tail, \ - process_pixblock_tail_head - - cleanup - -.if use_nearest_scaling != 0 - pop {r4-r8, pc} /* exit */ - - .unreq DST_R - .unreq SRC - .unreq W - .unreq VX - .unreq UNIT_X - .unreq TMP1 - .unreq TMP2 - .unreq DST_W - .unreq MASK - .unreq SRC_WIDTH_FIXED - -.else - bx lr /* exit */ - - .unreq SRC - .unreq MASK - .unreq DST_R - .unreq DST_W - .unreq W -.endif - - .purgem fetch_src_pixblock - .purgem pixld_src - - .endfunc -.endm - -.macro generate_composite_function_single_scanline x:vararg - generate_composite_function_scanline 0, x -.endm - -.macro generate_composite_function_nearest_scanline x:vararg - generate_composite_function_scanline 1, x -.endm - -/* Default prologue/epilogue, nothing special needs to be done */ - -.macro default_init -.endm - -.macro default_cleanup -.endm - -/* - * Prologue/epilogue variant which additionally saves/restores d8-d15 - * registers (they need to be saved/restored by callee according to ABI). - * This is required if the code needs to use all the NEON registers. - */ - -.macro default_init_need_all_regs - vpush {d8-d15} -.endm - -.macro default_cleanup_need_all_regs - vpop {d8-d15} -.endm - -/******************************************************************************/ - -/* - * Conversion of 8 r5g6b6 pixels packed in 128-bit register (in) - * into a planar a8r8g8b8 format (with a, r, g, b color components - * stored into 64-bit registers out_a, out_r, out_g, out_b respectively). - * - * Warning: the conversion is destructive and the original - * value (in) is lost. - */ -.macro convert_0565_to_8888 in, out_a, out_r, out_g, out_b - vshrn.u16 out_r, in, #8 - vshrn.u16 out_g, in, #3 - vsli.u16 in, in, #5 - vmov.u8 out_a, #255 - vsri.u8 out_r, out_r, #5 - vsri.u8 out_g, out_g, #6 - vshrn.u16 out_b, in, #2 -.endm - -.macro convert_0565_to_x888 in, out_r, out_g, out_b - vshrn.u16 out_r, in, #8 - vshrn.u16 out_g, in, #3 - vsli.u16 in, in, #5 - vsri.u8 out_r, out_r, #5 - vsri.u8 out_g, out_g, #6 - vshrn.u16 out_b, in, #2 -.endm - -/* - * Conversion from planar a8r8g8b8 format (with a, r, g, b color components - * in 64-bit registers in_a, in_r, in_g, in_b respectively) into 8 r5g6b6 - * pixels packed in 128-bit register (out). Requires two temporary 128-bit - * registers (tmp1, tmp2) - */ -.macro convert_8888_to_0565 in_r, in_g, in_b, out, tmp1, tmp2 - vshll.u8 tmp1, in_g, #8 - vshll.u8 out, in_r, #8 - vshll.u8 tmp2, in_b, #8 - vsri.u16 out, tmp1, #5 - vsri.u16 out, tmp2, #11 -.endm - -/* - * Conversion of four r5g6b5 pixels (in) to four x8r8g8b8 pixels - * returned in (out0, out1) registers pair. Requires one temporary - * 64-bit register (tmp). 'out1' and 'in' may overlap, the original - * value from 'in' is lost - */ -.macro convert_four_0565_to_x888_packed in, out0, out1, tmp - vshl.u16 out0, in, #5 /* G top 6 bits */ - vshl.u16 tmp, in, #11 /* B top 5 bits */ - vsri.u16 in, in, #5 /* R is ready in top bits */ - vsri.u16 out0, out0, #6 /* G is ready in top bits */ - vsri.u16 tmp, tmp, #5 /* B is ready in top bits */ - vshr.u16 out1, in, #8 /* R is in place */ - vsri.u16 out0, tmp, #8 /* G & B is in place */ - vzip.u16 out0, out1 /* everything is in place */ -.endm diff --git a/source/libs/pixman/pixman-src/pixman/pixman-arm-neon.c b/source/libs/pixman/pixman-src/pixman/pixman-arm-neon.c deleted file mode 100644 index be761c96529e999a582b6c1c2b8559a0aaeff8a7..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-arm-neon.c +++ /dev/null @@ -1,472 +0,0 @@ -/* - * Copyright © 2009 ARM Ltd, Movial Creative Technologies Oy - * - * 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 ARM Ltd not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. ARM Ltd makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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: Ian Rickards (ian.rickards@arm.com) - * Author: Jonathan Morton (jonathan.morton@movial.com) - * Author: Markku Vire (markku.vire@movial.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include "pixman-private.h" -#include "pixman-arm-common.h" - -PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_8888_8888, - uint32_t, 1, uint32_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_x888_8888, - uint32_t, 1, uint32_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_0565_0565, - uint16_t, 1, uint16_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_0888_0888, - uint8_t, 3, uint8_t, 3) -PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_8888_0565, - uint32_t, 1, uint16_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_0565_8888, - uint16_t, 1, uint32_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_0888_8888_rev, - uint8_t, 3, uint32_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_0888_0565_rev, - uint8_t, 3, uint16_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_pixbuf_8888, - uint32_t, 1, uint32_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, src_rpixbuf_8888, - uint32_t, 1, uint32_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, add_8_8, - uint8_t, 1, uint8_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, add_8888_8888, - uint32_t, 1, uint32_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, over_8888_0565, - uint32_t, 1, uint16_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, over_8888_8888, - uint32_t, 1, uint32_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, out_reverse_8_0565, - uint8_t, 1, uint16_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, out_reverse_8_8888, - uint8_t, 1, uint32_t, 1) - -PIXMAN_ARM_BIND_FAST_PATH_N_DST (SKIP_ZERO_SRC, neon, over_n_0565, - uint16_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_N_DST (SKIP_ZERO_SRC, neon, over_n_8888, - uint32_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_N_DST (SKIP_ZERO_SRC, neon, over_reverse_n_8888, - uint32_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_N_DST (0, neon, in_n_8, - uint8_t, 1) - -PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, neon, over_n_8_0565, - uint8_t, 1, uint16_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, neon, over_n_8_8888, - uint8_t, 1, uint32_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, neon, over_n_8888_8888_ca, - uint32_t, 1, uint32_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, neon, over_n_8888_0565_ca, - uint32_t, 1, uint16_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, neon, over_n_8_8, - uint8_t, 1, uint8_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, neon, add_n_8_8, - uint8_t, 1, uint8_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, neon, add_n_8_8888, - uint8_t, 1, uint32_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (0, neon, src_n_8_8888, - uint8_t, 1, uint32_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (0, neon, src_n_8_8, - uint8_t, 1, uint8_t, 1) - -PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, neon, over_8888_n_8888, - uint32_t, 1, uint32_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, neon, over_8888_n_0565, - uint32_t, 1, uint16_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, neon, over_0565_n_0565, - uint16_t, 1, uint16_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, neon, add_8888_n_8888, - uint32_t, 1, uint32_t, 1) - -PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST (neon, add_8_8_8, - uint8_t, 1, uint8_t, 1, uint8_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST (neon, add_0565_8_0565, - uint16_t, 1, uint8_t, 1, uint16_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST (neon, add_8888_8_8888, - uint32_t, 1, uint8_t, 1, uint32_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST (neon, add_8888_8888_8888, - uint32_t, 1, uint32_t, 1, uint32_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST (neon, over_8888_8_8888, - uint32_t, 1, uint8_t, 1, uint32_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST (neon, over_8888_8888_8888, - uint32_t, 1, uint32_t, 1, uint32_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST (neon, over_8888_8_0565, - uint32_t, 1, uint8_t, 1, uint16_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST (neon, over_0565_8_0565, - uint16_t, 1, uint8_t, 1, uint16_t, 1) - -PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (neon, 8888_8888, OVER, - uint32_t, uint32_t) -PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (neon, 8888_0565, OVER, - uint32_t, uint16_t) -PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (neon, 8888_0565, SRC, - uint32_t, uint16_t) -PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (neon, 0565_8888, SRC, - uint16_t, uint32_t) - -PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_A8_DST (SKIP_ZERO_SRC, neon, 8888_8_0565, - OVER, uint32_t, uint16_t) -PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_A8_DST (SKIP_ZERO_SRC, neon, 0565_8_0565, - OVER, uint16_t, uint16_t) - -PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_DST (0, neon, 8888_8888, SRC, - uint32_t, uint32_t) -PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_DST (0, neon, 8888_0565, SRC, - uint32_t, uint16_t) -PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_DST (0, neon, 0565_x888, SRC, - uint16_t, uint32_t) -PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_DST (0, neon, 0565_0565, SRC, - uint16_t, uint16_t) -PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_DST (SKIP_ZERO_SRC, neon, 8888_8888, OVER, - uint32_t, uint32_t) -PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_DST (SKIP_ZERO_SRC, neon, 8888_8888, ADD, - uint32_t, uint32_t) - -PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_A8_DST (0, neon, 8888_8_8888, SRC, - uint32_t, uint32_t) -PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_A8_DST (0, neon, 8888_8_0565, SRC, - uint32_t, uint16_t) -PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_A8_DST (0, neon, 0565_8_x888, SRC, - uint16_t, uint32_t) -PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_A8_DST (0, neon, 0565_8_0565, SRC, - uint16_t, uint16_t) -PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_A8_DST (SKIP_ZERO_SRC, neon, 8888_8_8888, OVER, - uint32_t, uint32_t) -PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_A8_DST (SKIP_ZERO_SRC, neon, 8888_8_8888, ADD, - uint32_t, uint32_t) - -void -pixman_composite_src_n_8_asm_neon (int32_t w, - int32_t h, - uint8_t *dst, - int32_t dst_stride, - uint8_t src); - -void -pixman_composite_src_n_0565_asm_neon (int32_t w, - int32_t h, - uint16_t *dst, - int32_t dst_stride, - uint16_t src); - -void -pixman_composite_src_n_8888_asm_neon (int32_t w, - int32_t h, - uint32_t *dst, - int32_t dst_stride, - uint32_t src); - -static pixman_bool_t -arm_neon_fill (pixman_implementation_t *imp, - uint32_t * bits, - int stride, - int bpp, - int x, - int y, - int width, - int height, - uint32_t _xor) -{ - /* stride is always multiple of 32bit units in pixman */ - uint32_t byte_stride = stride * sizeof(uint32_t); - - switch (bpp) - { - case 8: - pixman_composite_src_n_8_asm_neon ( - width, - height, - (uint8_t *)(((char *) bits) + y * byte_stride + x), - byte_stride, - _xor & 0xff); - return TRUE; - case 16: - pixman_composite_src_n_0565_asm_neon ( - width, - height, - (uint16_t *)(((char *) bits) + y * byte_stride + x * 2), - byte_stride / 2, - _xor & 0xffff); - return TRUE; - case 32: - pixman_composite_src_n_8888_asm_neon ( - width, - height, - (uint32_t *)(((char *) bits) + y * byte_stride + x * 4), - byte_stride / 4, - _xor); - return TRUE; - default: - return FALSE; - } -} - -static pixman_bool_t -arm_neon_blt (pixman_implementation_t *imp, - uint32_t * src_bits, - uint32_t * dst_bits, - int src_stride, - int dst_stride, - int src_bpp, - int dst_bpp, - int src_x, - int src_y, - int dest_x, - int dest_y, - int width, - int height) -{ - if (src_bpp != dst_bpp) - return FALSE; - - switch (src_bpp) - { - case 16: - pixman_composite_src_0565_0565_asm_neon ( - width, height, - (uint16_t *)(((char *) dst_bits) + - dest_y * dst_stride * 4 + dest_x * 2), dst_stride * 2, - (uint16_t *)(((char *) src_bits) + - src_y * src_stride * 4 + src_x * 2), src_stride * 2); - return TRUE; - case 32: - pixman_composite_src_8888_8888_asm_neon ( - width, height, - (uint32_t *)(((char *) dst_bits) + - dest_y * dst_stride * 4 + dest_x * 4), dst_stride, - (uint32_t *)(((char *) src_bits) + - src_y * src_stride * 4 + src_x * 4), src_stride); - return TRUE; - default: - return FALSE; - } -} - -static const pixman_fast_path_t arm_neon_fast_paths[] = -{ - PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, r5g6b5, neon_composite_src_0565_0565), - PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, b5g6r5, neon_composite_src_0565_0565), - PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, r5g6b5, neon_composite_src_8888_0565), - PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, r5g6b5, neon_composite_src_8888_0565), - PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, b5g6r5, neon_composite_src_8888_0565), - PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, b5g6r5, neon_composite_src_8888_0565), - PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, a8r8g8b8, neon_composite_src_0565_8888), - PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, x8r8g8b8, neon_composite_src_0565_8888), - PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, a8b8g8r8, neon_composite_src_0565_8888), - PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, x8b8g8r8, neon_composite_src_0565_8888), - PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, neon_composite_src_8888_8888), - PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, neon_composite_src_8888_8888), - PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, neon_composite_src_8888_8888), - PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, neon_composite_src_8888_8888), - PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, a8r8g8b8, neon_composite_src_8888_8888), - PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, a8b8g8r8, neon_composite_src_8888_8888), - PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, a8r8g8b8, neon_composite_src_x888_8888), - PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, a8b8g8r8, neon_composite_src_x888_8888), - PIXMAN_STD_FAST_PATH (SRC, r8g8b8, null, r8g8b8, neon_composite_src_0888_0888), - PIXMAN_STD_FAST_PATH (SRC, b8g8r8, null, x8r8g8b8, neon_composite_src_0888_8888_rev), - PIXMAN_STD_FAST_PATH (SRC, b8g8r8, null, r5g6b5, neon_composite_src_0888_0565_rev), - PIXMAN_STD_FAST_PATH (SRC, pixbuf, pixbuf, a8r8g8b8, neon_composite_src_pixbuf_8888), - PIXMAN_STD_FAST_PATH (SRC, pixbuf, pixbuf, a8b8g8r8, neon_composite_src_rpixbuf_8888), - PIXMAN_STD_FAST_PATH (SRC, rpixbuf, rpixbuf, a8r8g8b8, neon_composite_src_rpixbuf_8888), - PIXMAN_STD_FAST_PATH (SRC, rpixbuf, rpixbuf, a8b8g8r8, neon_composite_src_pixbuf_8888), - PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8r8g8b8, neon_composite_src_n_8_8888), - PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8r8g8b8, neon_composite_src_n_8_8888), - PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8b8g8r8, neon_composite_src_n_8_8888), - PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8b8g8r8, neon_composite_src_n_8_8888), - PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8, neon_composite_src_n_8_8), - - PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8, neon_composite_over_n_8_8), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, r5g6b5, neon_composite_over_n_8_0565), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, b5g6r5, neon_composite_over_n_8_0565), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, neon_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, neon_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, neon_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, neon_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, null, r5g6b5, neon_composite_over_n_0565), - PIXMAN_STD_FAST_PATH (OVER, solid, null, a8r8g8b8, neon_composite_over_n_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, null, x8r8g8b8, neon_composite_over_n_8888), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, a8r8g8b8, neon_composite_over_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, neon_composite_over_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, neon_composite_over_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, neon_composite_over_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, r5g6b5, neon_composite_over_n_8888_0565_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, b5g6r5, neon_composite_over_n_8888_0565_ca), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, a8r8g8b8, neon_composite_over_8888_n_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, x8r8g8b8, neon_composite_over_8888_n_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, r5g6b5, neon_composite_over_8888_n_0565), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, b5g6r5, neon_composite_over_8888_n_0565), - PIXMAN_STD_FAST_PATH (OVER, r5g6b5, solid, r5g6b5, neon_composite_over_0565_n_0565), - PIXMAN_STD_FAST_PATH (OVER, b5g6r5, solid, b5g6r5, neon_composite_over_0565_n_0565), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, a8r8g8b8, neon_composite_over_8888_8_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, x8r8g8b8, neon_composite_over_8888_8_8888), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, a8b8g8r8, neon_composite_over_8888_8_8888), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, x8b8g8r8, neon_composite_over_8888_8_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, r5g6b5, neon_composite_over_8888_8_0565), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, b5g6r5, neon_composite_over_8888_8_0565), - PIXMAN_STD_FAST_PATH (OVER, r5g6b5, a8, r5g6b5, neon_composite_over_0565_8_0565), - PIXMAN_STD_FAST_PATH (OVER, b5g6r5, a8, b5g6r5, neon_composite_over_0565_8_0565), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, a8r8g8b8, neon_composite_over_8888_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, r5g6b5, neon_composite_over_8888_0565), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, b5g6r5, neon_composite_over_8888_0565), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, neon_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, neon_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, neon_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, neon_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, null, a8r8g8b8, neon_composite_src_x888_8888), - PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, null, a8b8g8r8, neon_composite_src_x888_8888), - PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8, neon_composite_add_n_8_8), - PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8r8g8b8, neon_composite_add_n_8_8888), - PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8b8g8r8, neon_composite_add_n_8_8888), - PIXMAN_STD_FAST_PATH (ADD, a8, a8, a8, neon_composite_add_8_8_8), - PIXMAN_STD_FAST_PATH (ADD, r5g6b5, a8, r5g6b5, neon_composite_add_0565_8_0565), - PIXMAN_STD_FAST_PATH (ADD, b5g6r5, a8, b5g6r5, neon_composite_add_0565_8_0565), - PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, a8, a8r8g8b8, neon_composite_add_8888_8_8888), - PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, a8, a8b8g8r8, neon_composite_add_8888_8_8888), - PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, a8r8g8b8, a8r8g8b8, neon_composite_add_8888_8888_8888), - PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, solid, a8r8g8b8, neon_composite_add_8888_n_8888), - PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, solid, a8b8g8r8, neon_composite_add_8888_n_8888), - PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, neon_composite_add_8_8), - PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, null, a8r8g8b8, neon_composite_add_8888_8888), - PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, null, a8b8g8r8, neon_composite_add_8888_8888), - PIXMAN_STD_FAST_PATH (IN, solid, null, a8, neon_composite_in_n_8), - PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8r8g8b8, neon_composite_over_reverse_n_8888), - PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8b8g8r8, neon_composite_over_reverse_n_8888), - PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, r5g6b5, neon_composite_out_reverse_8_0565), - PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, b5g6r5, neon_composite_out_reverse_8_0565), - PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, a8r8g8b8, neon_composite_out_reverse_8_8888), - PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, a8b8g8r8, neon_composite_out_reverse_8_8888), - - SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, neon_8888_8888), - SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, neon_8888_8888), - SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, neon_8888_8888), - SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, neon_8888_8888), - - SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, r5g6b5, neon_8888_0565), - SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, b5g6r5, neon_8888_0565), - - SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, r5g6b5, neon_8888_0565), - SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, r5g6b5, neon_8888_0565), - SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, b5g6r5, neon_8888_0565), - SIMPLE_NEAREST_FAST_PATH (SRC, x8b8g8r8, b5g6r5, neon_8888_0565), - - SIMPLE_NEAREST_FAST_PATH (SRC, b5g6r5, x8b8g8r8, neon_0565_8888), - SIMPLE_NEAREST_FAST_PATH (SRC, r5g6b5, x8r8g8b8, neon_0565_8888), - /* Note: NONE repeat is not supported yet */ - SIMPLE_NEAREST_FAST_PATH_COVER (SRC, r5g6b5, a8r8g8b8, neon_0565_8888), - SIMPLE_NEAREST_FAST_PATH_COVER (SRC, b5g6r5, a8b8g8r8, neon_0565_8888), - SIMPLE_NEAREST_FAST_PATH_PAD (SRC, r5g6b5, a8r8g8b8, neon_0565_8888), - SIMPLE_NEAREST_FAST_PATH_PAD (SRC, b5g6r5, a8b8g8r8, neon_0565_8888), - - PIXMAN_ARM_SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, a8r8g8b8, r5g6b5, neon_8888_8_0565), - PIXMAN_ARM_SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, a8b8g8r8, b5g6r5, neon_8888_8_0565), - - PIXMAN_ARM_SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, r5g6b5, r5g6b5, neon_0565_8_0565), - PIXMAN_ARM_SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, b5g6r5, b5g6r5, neon_0565_8_0565), - - SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, neon_8888_8888), - SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, neon_8888_8888), - SIMPLE_BILINEAR_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, neon_8888_8888), - - SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, r5g6b5, neon_8888_0565), - SIMPLE_BILINEAR_FAST_PATH (SRC, x8r8g8b8, r5g6b5, neon_8888_0565), - - SIMPLE_BILINEAR_FAST_PATH (SRC, r5g6b5, x8r8g8b8, neon_0565_x888), - SIMPLE_BILINEAR_FAST_PATH (SRC, r5g6b5, r5g6b5, neon_0565_0565), - - SIMPLE_BILINEAR_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, neon_8888_8888), - SIMPLE_BILINEAR_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, neon_8888_8888), - - SIMPLE_BILINEAR_FAST_PATH (ADD, a8r8g8b8, a8r8g8b8, neon_8888_8888), - SIMPLE_BILINEAR_FAST_PATH (ADD, a8r8g8b8, x8r8g8b8, neon_8888_8888), - - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, neon_8888_8_8888), - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, neon_8888_8_8888), - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, neon_8888_8_8888), - - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, a8r8g8b8, r5g6b5, neon_8888_8_0565), - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, x8r8g8b8, r5g6b5, neon_8888_8_0565), - - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, r5g6b5, x8r8g8b8, neon_0565_8_x888), - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, r5g6b5, r5g6b5, neon_0565_8_0565), - - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, neon_8888_8_8888), - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, neon_8888_8_8888), - - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (ADD, a8r8g8b8, a8r8g8b8, neon_8888_8_8888), - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (ADD, a8r8g8b8, x8r8g8b8, neon_8888_8_8888), - - { PIXMAN_OP_NONE }, -}; - -#define BIND_COMBINE_U(name) \ -void \ -pixman_composite_scanline_##name##_mask_asm_neon (int32_t w, \ - const uint32_t *dst, \ - const uint32_t *src, \ - const uint32_t *mask); \ - \ -void \ -pixman_composite_scanline_##name##_asm_neon (int32_t w, \ - const uint32_t *dst, \ - const uint32_t *src); \ - \ -static void \ -neon_combine_##name##_u (pixman_implementation_t *imp, \ - pixman_op_t op, \ - uint32_t * dest, \ - const uint32_t * src, \ - const uint32_t * mask, \ - int width) \ -{ \ - if (mask) \ - pixman_composite_scanline_##name##_mask_asm_neon (width, dest, \ - src, mask); \ - else \ - pixman_composite_scanline_##name##_asm_neon (width, dest, src); \ -} - -BIND_COMBINE_U (over) -BIND_COMBINE_U (add) -BIND_COMBINE_U (out_reverse) - -pixman_implementation_t * -_pixman_implementation_create_arm_neon (pixman_implementation_t *fallback) -{ - pixman_implementation_t *imp = - _pixman_implementation_create (fallback, arm_neon_fast_paths); - - imp->combine_32[PIXMAN_OP_OVER] = neon_combine_over_u; - imp->combine_32[PIXMAN_OP_ADD] = neon_combine_add_u; - imp->combine_32[PIXMAN_OP_OUT_REVERSE] = neon_combine_out_reverse_u; - - imp->blt = arm_neon_blt; - imp->fill = arm_neon_fill; - - return imp; -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman-arm-simd-asm-scaled.S b/source/libs/pixman/pixman-src/pixman/pixman-arm-simd-asm-scaled.S deleted file mode 100644 index e050292e05e2c459b08fc40fc840a05dfb92aace..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-arm-simd-asm-scaled.S +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright © 2008 Mozilla Corporation - * Copyright © 2010 Nokia Corporation - * - * 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 Mozilla Corporation not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Mozilla Corporation makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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: Jeff Muizelaar (jeff@infidigm.net) - * - */ - -/* Prevent the stack from becoming executable */ -#if defined(__linux__) && defined(__ELF__) -.section .note.GNU-stack,"",%progbits -#endif - - .text - .arch armv6 - .object_arch armv4 - .arm - .altmacro - .p2align 2 - -#include "pixman-arm-asm.h" - -/* - * Note: This code is only using armv5te instructions (not even armv6), - * but is scheduled for ARM Cortex-A8 pipeline. So it might need to - * be split into a few variants, tuned for each microarchitecture. - * - * TODO: In order to get good performance on ARM9/ARM11 cores (which don't - * have efficient write combining), it needs to be changed to use 16-byte - * aligned writes using STM instruction. - * - * Nearest scanline scaler macro template uses the following arguments: - * fname - name of the function to generate - * bpp_shift - (1 << bpp_shift) is the size of pixel in bytes - * t - type suffix for LDR/STR instructions - * prefetch_distance - prefetch in the source image by that many - * pixels ahead - * prefetch_braking_distance - stop prefetching when that many pixels are - * remaining before the end of scanline - */ - -.macro generate_nearest_scanline_func fname, bpp_shift, t, \ - prefetch_distance, \ - prefetch_braking_distance - -pixman_asm_function fname - W .req r0 - DST .req r1 - SRC .req r2 - VX .req r3 - UNIT_X .req ip - TMP1 .req r4 - TMP2 .req r5 - VXMASK .req r6 - PF_OFFS .req r7 - SRC_WIDTH_FIXED .req r8 - - ldr UNIT_X, [sp] - push {r4, r5, r6, r7, r8, r10} - mvn VXMASK, #((1 << bpp_shift) - 1) - ldr SRC_WIDTH_FIXED, [sp, #28] - - /* define helper macro */ - .macro scale_2_pixels - ldr&t TMP1, [SRC, TMP1] - and TMP2, VXMASK, VX, asr #(16 - bpp_shift) - adds VX, VX, UNIT_X - str&t TMP1, [DST], #(1 << bpp_shift) -9: subpls VX, VX, SRC_WIDTH_FIXED - bpl 9b - - ldr&t TMP2, [SRC, TMP2] - and TMP1, VXMASK, VX, asr #(16 - bpp_shift) - adds VX, VX, UNIT_X - str&t TMP2, [DST], #(1 << bpp_shift) -9: subpls VX, VX, SRC_WIDTH_FIXED - bpl 9b - .endm - - /* now do the scaling */ - and TMP1, VXMASK, VX, asr #(16 - bpp_shift) - adds VX, VX, UNIT_X -9: subpls VX, VX, SRC_WIDTH_FIXED - bpl 9b - subs W, W, #(8 + prefetch_braking_distance) - blt 2f - /* calculate prefetch offset */ - mov PF_OFFS, #prefetch_distance - mla PF_OFFS, UNIT_X, PF_OFFS, VX -1: /* main loop, process 8 pixels per iteration with prefetch */ - pld [SRC, PF_OFFS, asr #(16 - bpp_shift)] - add PF_OFFS, UNIT_X, lsl #3 - scale_2_pixels - scale_2_pixels - scale_2_pixels - scale_2_pixels - subs W, W, #8 - bge 1b -2: - subs W, W, #(4 - 8 - prefetch_braking_distance) - blt 2f -1: /* process the remaining pixels */ - scale_2_pixels - scale_2_pixels - subs W, W, #4 - bge 1b -2: - tst W, #2 - beq 2f - scale_2_pixels -2: - tst W, #1 - ldrne&t TMP1, [SRC, TMP1] - strne&t TMP1, [DST] - /* cleanup helper macro */ - .purgem scale_2_pixels - .unreq DST - .unreq SRC - .unreq W - .unreq VX - .unreq UNIT_X - .unreq TMP1 - .unreq TMP2 - .unreq VXMASK - .unreq PF_OFFS - .unreq SRC_WIDTH_FIXED - /* return */ - pop {r4, r5, r6, r7, r8, r10} - bx lr -.endfunc -.endm - -generate_nearest_scanline_func \ - pixman_scaled_nearest_scanline_0565_0565_SRC_asm_armv6, 1, h, 80, 32 - -generate_nearest_scanline_func \ - pixman_scaled_nearest_scanline_8888_8888_SRC_asm_armv6, 2, , 48, 32 diff --git a/source/libs/pixman/pixman-src/pixman/pixman-arm-simd-asm.S b/source/libs/pixman/pixman-src/pixman/pixman-arm-simd-asm.S deleted file mode 100644 index a74a0a8f3460762f15b78f2f8bced177b9d9e395..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-arm-simd-asm.S +++ /dev/null @@ -1,1179 +0,0 @@ -/* - * Copyright © 2012 Raspberry Pi Foundation - * Copyright © 2012 RISC OS Open Ltd - * - * 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 the copyright holders not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. The copyright holders make no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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: Ben Avison (bavison@riscosopen.org) - * - */ - -/* Prevent the stack from becoming executable */ -#if defined(__linux__) && defined(__ELF__) -.section .note.GNU-stack,"",%progbits -#endif - - .text - .arch armv6 - .object_arch armv4 - .arm - .altmacro - .p2align 2 - -#include "pixman-arm-asm.h" -#include "pixman-arm-simd-asm.h" - -/* A head macro should do all processing which results in an output of up to - * 16 bytes, as far as the final load instruction. The corresponding tail macro - * should complete the processing of the up-to-16 bytes. The calling macro will - * sometimes choose to insert a preload or a decrement of X between them. - * cond ARM condition code for code block - * numbytes Number of output bytes that should be generated this time - * firstreg First WK register in which to place output - * unaligned_src Whether to use non-wordaligned loads of source image - * unaligned_mask Whether to use non-wordaligned loads of mask image - * preload If outputting 16 bytes causes 64 bytes to be read, whether an extra preload should be output - */ - -.macro blit_init - line_saved_regs STRIDE_D, STRIDE_S -.endm - -.macro blit_process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, preload - pixld cond, numbytes, firstreg, SRC, unaligned_src -.endm - -.macro blit_inner_loop process_head, process_tail, unaligned_src, unaligned_mask, dst_alignment - WK4 .req STRIDE_D - WK5 .req STRIDE_S - WK6 .req MASK - WK7 .req STRIDE_M -110: pixld , 16, 0, SRC, unaligned_src - pixld , 16, 4, SRC, unaligned_src - pld [SRC, SCRATCH] - pixst , 16, 0, DST - pixst , 16, 4, DST - subs X, X, #32*8/src_bpp - bhs 110b - .unreq WK4 - .unreq WK5 - .unreq WK6 - .unreq WK7 -.endm - -generate_composite_function \ - pixman_composite_src_8888_8888_asm_armv6, 32, 0, 32, \ - FLAG_DST_WRITEONLY | FLAG_COND_EXEC | FLAG_SPILL_LINE_VARS_WIDE | FLAG_PROCESS_PRESERVES_SCRATCH, \ - 4, /* prefetch distance */ \ - blit_init, \ - nop_macro, /* newline */ \ - nop_macro, /* cleanup */ \ - blit_process_head, \ - nop_macro, /* process tail */ \ - blit_inner_loop - -generate_composite_function \ - pixman_composite_src_0565_0565_asm_armv6, 16, 0, 16, \ - FLAG_DST_WRITEONLY | FLAG_COND_EXEC | FLAG_SPILL_LINE_VARS_WIDE | FLAG_PROCESS_PRESERVES_SCRATCH, \ - 4, /* prefetch distance */ \ - blit_init, \ - nop_macro, /* newline */ \ - nop_macro, /* cleanup */ \ - blit_process_head, \ - nop_macro, /* process tail */ \ - blit_inner_loop - -generate_composite_function \ - pixman_composite_src_8_8_asm_armv6, 8, 0, 8, \ - FLAG_DST_WRITEONLY | FLAG_COND_EXEC | FLAG_SPILL_LINE_VARS_WIDE | FLAG_PROCESS_PRESERVES_SCRATCH, \ - 3, /* prefetch distance */ \ - blit_init, \ - nop_macro, /* newline */ \ - nop_macro, /* cleanup */ \ - blit_process_head, \ - nop_macro, /* process tail */ \ - blit_inner_loop - -/******************************************************************************/ - -.macro src_n_8888_init - ldr SRC, [sp, #ARGS_STACK_OFFSET] - mov STRIDE_S, SRC - mov MASK, SRC - mov STRIDE_M, SRC -.endm - -.macro src_n_0565_init - ldrh SRC, [sp, #ARGS_STACK_OFFSET] - orr SRC, SRC, lsl #16 - mov STRIDE_S, SRC - mov MASK, SRC - mov STRIDE_M, SRC -.endm - -.macro src_n_8_init - ldrb SRC, [sp, #ARGS_STACK_OFFSET] - orr SRC, SRC, lsl #8 - orr SRC, SRC, lsl #16 - mov STRIDE_S, SRC - mov MASK, SRC - mov STRIDE_M, SRC -.endm - -.macro fill_process_tail cond, numbytes, firstreg - WK4 .req SRC - WK5 .req STRIDE_S - WK6 .req MASK - WK7 .req STRIDE_M - pixst cond, numbytes, 4, DST - .unreq WK4 - .unreq WK5 - .unreq WK6 - .unreq WK7 -.endm - -generate_composite_function \ - pixman_composite_src_n_8888_asm_armv6, 0, 0, 32, \ - FLAG_DST_WRITEONLY | FLAG_COND_EXEC | FLAG_PROCESS_PRESERVES_PSR | FLAG_PROCESS_DOES_STORE | FLAG_PROCESS_PRESERVES_SCRATCH \ - 0, /* prefetch distance doesn't apply */ \ - src_n_8888_init \ - nop_macro, /* newline */ \ - nop_macro /* cleanup */ \ - nop_macro /* process head */ \ - fill_process_tail - -generate_composite_function \ - pixman_composite_src_n_0565_asm_armv6, 0, 0, 16, \ - FLAG_DST_WRITEONLY | FLAG_COND_EXEC | FLAG_PROCESS_PRESERVES_PSR | FLAG_PROCESS_DOES_STORE | FLAG_PROCESS_PRESERVES_SCRATCH \ - 0, /* prefetch distance doesn't apply */ \ - src_n_0565_init \ - nop_macro, /* newline */ \ - nop_macro /* cleanup */ \ - nop_macro /* process head */ \ - fill_process_tail - -generate_composite_function \ - pixman_composite_src_n_8_asm_armv6, 0, 0, 8, \ - FLAG_DST_WRITEONLY | FLAG_COND_EXEC | FLAG_PROCESS_PRESERVES_PSR | FLAG_PROCESS_DOES_STORE | FLAG_PROCESS_PRESERVES_SCRATCH \ - 0, /* prefetch distance doesn't apply */ \ - src_n_8_init \ - nop_macro, /* newline */ \ - nop_macro /* cleanup */ \ - nop_macro /* process head */ \ - fill_process_tail - -/******************************************************************************/ - -.macro src_x888_8888_pixel, cond, reg - orr&cond WK®, WK®, #0xFF000000 -.endm - -.macro pixman_composite_src_x888_8888_process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, preload - pixld cond, numbytes, firstreg, SRC, unaligned_src -.endm - -.macro pixman_composite_src_x888_8888_process_tail cond, numbytes, firstreg - src_x888_8888_pixel cond, %(firstreg+0) - .if numbytes >= 8 - src_x888_8888_pixel cond, %(firstreg+1) - .if numbytes == 16 - src_x888_8888_pixel cond, %(firstreg+2) - src_x888_8888_pixel cond, %(firstreg+3) - .endif - .endif -.endm - -generate_composite_function \ - pixman_composite_src_x888_8888_asm_armv6, 32, 0, 32, \ - FLAG_DST_WRITEONLY | FLAG_COND_EXEC | FLAG_PROCESS_PRESERVES_SCRATCH, \ - 3, /* prefetch distance */ \ - nop_macro, /* init */ \ - nop_macro, /* newline */ \ - nop_macro, /* cleanup */ \ - pixman_composite_src_x888_8888_process_head, \ - pixman_composite_src_x888_8888_process_tail - -/******************************************************************************/ - -.macro src_0565_8888_init - /* Hold loop invariants in MASK and STRIDE_M */ - ldr MASK, =0x07E007E0 - mov STRIDE_M, #0xFF000000 - /* Set GE[3:0] to 1010 so SEL instructions do what we want */ - ldr SCRATCH, =0x80008000 - uadd8 SCRATCH, SCRATCH, SCRATCH -.endm - -.macro src_0565_8888_2pixels, reg1, reg2 - and SCRATCH, WK®1, MASK @ 00000GGGGGG0000000000gggggg00000 - bic WK®2, WK®1, MASK @ RRRRR000000BBBBBrrrrr000000bbbbb - orr SCRATCH, SCRATCH, SCRATCH, lsr #6 @ 00000GGGGGGGGGGGG0000ggggggggggg - mov WK®1, WK®2, lsl #16 @ rrrrr000000bbbbb0000000000000000 - mov SCRATCH, SCRATCH, ror #19 @ GGGG0000ggggggggggg00000GGGGGGGG - bic WK®2, WK®2, WK®1, lsr #16 @ RRRRR000000BBBBB0000000000000000 - orr WK®1, WK®1, WK®1, lsr #5 @ rrrrrrrrrr0bbbbbbbbbb00000000000 - orr WK®2, WK®2, WK®2, lsr #5 @ RRRRRRRRRR0BBBBBBBBBB00000000000 - pkhtb WK®1, WK®1, WK®1, asr #5 @ rrrrrrrr--------bbbbbbbb-------- - sel WK®1, WK®1, SCRATCH @ rrrrrrrrggggggggbbbbbbbb-------- - mov SCRATCH, SCRATCH, ror #16 @ ggg00000GGGGGGGGGGGG0000gggggggg - pkhtb WK®2, WK®2, WK®2, asr #5 @ RRRRRRRR--------BBBBBBBB-------- - sel WK®2, WK®2, SCRATCH @ RRRRRRRRGGGGGGGGBBBBBBBB-------- - orr WK®1, STRIDE_M, WK®1, lsr #8 @ 11111111rrrrrrrrggggggggbbbbbbbb - orr WK®2, STRIDE_M, WK®2, lsr #8 @ 11111111RRRRRRRRGGGGGGGGBBBBBBBB -.endm - -/* This version doesn't need STRIDE_M, but is one instruction longer. - It would however be preferable for an XRGB target, since we could knock off the last 2 instructions, but is that a common case? - and SCRATCH, WK®1, MASK @ 00000GGGGGG0000000000gggggg00000 - bic WK®1, WK®1, MASK @ RRRRR000000BBBBBrrrrr000000bbbbb - orr SCRATCH, SCRATCH, SCRATCH, lsr #6 @ 00000GGGGGGGGGGGG0000ggggggggggg - mov WK®2, WK®1, lsr #16 @ 0000000000000000RRRRR000000BBBBB - mov SCRATCH, SCRATCH, ror #27 @ GGGGGGGGGGGG0000ggggggggggg00000 - bic WK®1, WK®1, WK®2, lsl #16 @ 0000000000000000rrrrr000000bbbbb - mov WK®2, WK®2, lsl #3 @ 0000000000000RRRRR000000BBBBB000 - mov WK®1, WK®1, lsl #3 @ 0000000000000rrrrr000000bbbbb000 - orr WK®2, WK®2, WK®2, lsr #5 @ 0000000000000RRRRRRRRRR0BBBBBBBB - orr WK®1, WK®1, WK®1, lsr #5 @ 0000000000000rrrrrrrrrr0bbbbbbbb - pkhbt WK®2, WK®2, WK®2, lsl #5 @ --------RRRRRRRR--------BBBBBBBB - pkhbt WK®1, WK®1, WK®1, lsl #5 @ --------rrrrrrrr--------bbbbbbbb - sel WK®2, SCRATCH, WK®2 @ --------RRRRRRRRGGGGGGGGBBBBBBBB - sel WK®1, SCRATCH, WK®1 @ --------rrrrrrrrggggggggbbbbbbbb - orr WK®2, WK®2, #0xFF000000 @ 11111111RRRRRRRRGGGGGGGGBBBBBBBB - orr WK®1, WK®1, #0xFF000000 @ 11111111rrrrrrrrggggggggbbbbbbbb -*/ - -.macro src_0565_8888_1pixel, reg - bic SCRATCH, WK®, MASK @ 0000000000000000rrrrr000000bbbbb - and WK®, WK®, MASK @ 000000000000000000000gggggg00000 - mov SCRATCH, SCRATCH, lsl #3 @ 0000000000000rrrrr000000bbbbb000 - mov WK®, WK®, lsl #5 @ 0000000000000000gggggg0000000000 - orr SCRATCH, SCRATCH, SCRATCH, lsr #5 @ 0000000000000rrrrrrrrrr0bbbbbbbb - orr WK®, WK®, WK®, lsr #6 @ 000000000000000gggggggggggg00000 - pkhbt SCRATCH, SCRATCH, SCRATCH, lsl #5 @ --------rrrrrrrr--------bbbbbbbb - sel WK®, WK®, SCRATCH @ --------rrrrrrrrggggggggbbbbbbbb - orr WK®, WK®, #0xFF000000 @ 11111111rrrrrrrrggggggggbbbbbbbb -.endm - -.macro src_0565_8888_process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, preload - .if numbytes == 16 - pixldst ld,, 8, firstreg, %(firstreg+2),,, SRC, unaligned_src - .elseif numbytes == 8 - pixld , 4, firstreg, SRC, unaligned_src - .elseif numbytes == 4 - pixld , 2, firstreg, SRC, unaligned_src - .endif -.endm - -.macro src_0565_8888_process_tail cond, numbytes, firstreg - .if numbytes == 16 - src_0565_8888_2pixels firstreg, %(firstreg+1) - src_0565_8888_2pixels %(firstreg+2), %(firstreg+3) - .elseif numbytes == 8 - src_0565_8888_2pixels firstreg, %(firstreg+1) - .else - src_0565_8888_1pixel firstreg - .endif -.endm - -generate_composite_function \ - pixman_composite_src_0565_8888_asm_armv6, 16, 0, 32, \ - FLAG_DST_WRITEONLY | FLAG_BRANCH_OVER, \ - 3, /* prefetch distance */ \ - src_0565_8888_init, \ - nop_macro, /* newline */ \ - nop_macro, /* cleanup */ \ - src_0565_8888_process_head, \ - src_0565_8888_process_tail - -/******************************************************************************/ - -.macro src_x888_0565_init - /* Hold loop invariant in MASK */ - ldr MASK, =0x001F001F - line_saved_regs STRIDE_S, ORIG_W -.endm - -.macro src_x888_0565_1pixel s, d - and WK&d, MASK, WK&s, lsr #3 @ 00000000000rrrrr00000000000bbbbb - and STRIDE_S, WK&s, #0xFC00 @ 0000000000000000gggggg0000000000 - orr WK&d, WK&d, WK&d, lsr #5 @ 00000000000-----rrrrr000000bbbbb - orr WK&d, WK&d, STRIDE_S, lsr #5 @ 00000000000-----rrrrrggggggbbbbb - /* Top 16 bits are discarded during the following STRH */ -.endm - -.macro src_x888_0565_2pixels slo, shi, d, tmp - and SCRATCH, WK&shi, #0xFC00 @ 0000000000000000GGGGGG0000000000 - and WK&tmp, MASK, WK&shi, lsr #3 @ 00000000000RRRRR00000000000BBBBB - and WK&shi, MASK, WK&slo, lsr #3 @ 00000000000rrrrr00000000000bbbbb - orr WK&tmp, WK&tmp, WK&tmp, lsr #5 @ 00000000000-----RRRRR000000BBBBB - orr WK&tmp, WK&tmp, SCRATCH, lsr #5 @ 00000000000-----RRRRRGGGGGGBBBBB - and SCRATCH, WK&slo, #0xFC00 @ 0000000000000000gggggg0000000000 - orr WK&shi, WK&shi, WK&shi, lsr #5 @ 00000000000-----rrrrr000000bbbbb - orr WK&shi, WK&shi, SCRATCH, lsr #5 @ 00000000000-----rrrrrggggggbbbbb - pkhbt WK&d, WK&shi, WK&tmp, lsl #16 @ RRRRRGGGGGGBBBBBrrrrrggggggbbbbb -.endm - -.macro src_x888_0565_process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, preload - WK4 .req STRIDE_S - WK5 .req STRIDE_M - WK6 .req WK3 - WK7 .req ORIG_W - .if numbytes == 16 - pixld , 16, 4, SRC, 0 - src_x888_0565_2pixels 4, 5, 0, 0 - pixld , 8, 4, SRC, 0 - src_x888_0565_2pixels 6, 7, 1, 1 - pixld , 8, 6, SRC, 0 - .else - pixld , numbytes*2, 4, SRC, 0 - .endif -.endm - -.macro src_x888_0565_process_tail cond, numbytes, firstreg - .if numbytes == 16 - src_x888_0565_2pixels 4, 5, 2, 2 - src_x888_0565_2pixels 6, 7, 3, 4 - .elseif numbytes == 8 - src_x888_0565_2pixels 4, 5, 1, 1 - src_x888_0565_2pixels 6, 7, 2, 2 - .elseif numbytes == 4 - src_x888_0565_2pixels 4, 5, 1, 1 - .else - src_x888_0565_1pixel 4, 1 - .endif - .if numbytes == 16 - pixst , numbytes, 0, DST - .else - pixst , numbytes, 1, DST - .endif - .unreq WK4 - .unreq WK5 - .unreq WK6 - .unreq WK7 -.endm - -generate_composite_function \ - pixman_composite_src_x888_0565_asm_armv6, 32, 0, 16, \ - FLAG_DST_WRITEONLY | FLAG_BRANCH_OVER | FLAG_PROCESS_DOES_STORE | FLAG_SPILL_LINE_VARS | FLAG_PROCESS_CORRUPTS_SCRATCH, \ - 3, /* prefetch distance */ \ - src_x888_0565_init, \ - nop_macro, /* newline */ \ - nop_macro, /* cleanup */ \ - src_x888_0565_process_head, \ - src_x888_0565_process_tail - -/******************************************************************************/ - -.macro add_8_8_8pixels cond, dst1, dst2 - uqadd8&cond WK&dst1, WK&dst1, MASK - uqadd8&cond WK&dst2, WK&dst2, STRIDE_M -.endm - -.macro add_8_8_4pixels cond, dst - uqadd8&cond WK&dst, WK&dst, MASK -.endm - -.macro add_8_8_process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, preload - WK4 .req MASK - WK5 .req STRIDE_M - .if numbytes == 16 - pixld cond, 8, 4, SRC, unaligned_src - pixld cond, 16, firstreg, DST, 0 - add_8_8_8pixels cond, firstreg, %(firstreg+1) - pixld cond, 8, 4, SRC, unaligned_src - .else - pixld cond, numbytes, 4, SRC, unaligned_src - pixld cond, numbytes, firstreg, DST, 0 - .endif - .unreq WK4 - .unreq WK5 -.endm - -.macro add_8_8_process_tail cond, numbytes, firstreg - .if numbytes == 16 - add_8_8_8pixels cond, %(firstreg+2), %(firstreg+3) - .elseif numbytes == 8 - add_8_8_8pixels cond, firstreg, %(firstreg+1) - .else - add_8_8_4pixels cond, firstreg - .endif -.endm - -generate_composite_function \ - pixman_composite_add_8_8_asm_armv6, 8, 0, 8, \ - FLAG_DST_READWRITE | FLAG_BRANCH_OVER | FLAG_PROCESS_PRESERVES_SCRATCH, \ - 2, /* prefetch distance */ \ - nop_macro, /* init */ \ - nop_macro, /* newline */ \ - nop_macro, /* cleanup */ \ - add_8_8_process_head, \ - add_8_8_process_tail - -/******************************************************************************/ - -.macro over_8888_8888_init - /* Hold loop invariant in MASK */ - ldr MASK, =0x00800080 - /* Set GE[3:0] to 0101 so SEL instructions do what we want */ - uadd8 SCRATCH, MASK, MASK - line_saved_regs STRIDE_D, STRIDE_S, ORIG_W -.endm - -.macro over_8888_8888_process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, preload - WK4 .req STRIDE_D - WK5 .req STRIDE_S - WK6 .req STRIDE_M - WK7 .req ORIG_W - pixld , numbytes, %(4+firstreg), SRC, unaligned_src - pixld , numbytes, firstreg, DST, 0 - .unreq WK4 - .unreq WK5 - .unreq WK6 - .unreq WK7 -.endm - -.macro over_8888_8888_check_transparent numbytes, reg0, reg1, reg2, reg3 - /* Since these colours a premultiplied by alpha, only 0 indicates transparent (any other colour with 0 in the alpha byte is luminous) */ - teq WK®0, #0 - .if numbytes > 4 - teqeq WK®1, #0 - .if numbytes > 8 - teqeq WK®2, #0 - teqeq WK®3, #0 - .endif - .endif -.endm - -.macro over_8888_8888_prepare next - mov WK&next, WK&next, lsr #24 -.endm - -.macro over_8888_8888_1pixel src, dst, offset, next - /* src = destination component multiplier */ - rsb WK&src, WK&src, #255 - /* Split even/odd bytes of dst into SCRATCH/dst */ - uxtb16 SCRATCH, WK&dst - uxtb16 WK&dst, WK&dst, ror #8 - /* Multiply through, adding 0.5 to the upper byte of result for rounding */ - mla SCRATCH, SCRATCH, WK&src, MASK - mla WK&dst, WK&dst, WK&src, MASK - /* Where we would have had a stall between the result of the first MLA and the shifter input, - * reload the complete source pixel */ - ldr WK&src, [SRC, #offset] - /* Multiply by 257/256 to approximate 256/255 */ - uxtab16 SCRATCH, SCRATCH, SCRATCH, ror #8 - /* In this stall, start processing the next pixel */ - .if offset < -4 - mov WK&next, WK&next, lsr #24 - .endif - uxtab16 WK&dst, WK&dst, WK&dst, ror #8 - /* Recombine even/odd bytes of multiplied destination */ - mov SCRATCH, SCRATCH, ror #8 - sel WK&dst, SCRATCH, WK&dst - /* Saturated add of source to multiplied destination */ - uqadd8 WK&dst, WK&dst, WK&src -.endm - -.macro over_8888_8888_process_tail cond, numbytes, firstreg - WK4 .req STRIDE_D - WK5 .req STRIDE_S - WK6 .req STRIDE_M - WK7 .req ORIG_W - over_8888_8888_check_transparent numbytes, %(4+firstreg), %(5+firstreg), %(6+firstreg), %(7+firstreg) - beq 10f - over_8888_8888_prepare %(4+firstreg) - .set PROCESS_REG, firstreg - .set PROCESS_OFF, -numbytes - .rept numbytes / 4 - over_8888_8888_1pixel %(4+PROCESS_REG), %(0+PROCESS_REG), PROCESS_OFF, %(5+PROCESS_REG) - .set PROCESS_REG, PROCESS_REG+1 - .set PROCESS_OFF, PROCESS_OFF+4 - .endr - pixst , numbytes, firstreg, DST -10: - .unreq WK4 - .unreq WK5 - .unreq WK6 - .unreq WK7 -.endm - -generate_composite_function \ - pixman_composite_over_8888_8888_asm_armv6, 32, 0, 32 \ - FLAG_DST_READWRITE | FLAG_BRANCH_OVER | FLAG_PROCESS_CORRUPTS_PSR | FLAG_PROCESS_DOES_STORE | FLAG_SPILL_LINE_VARS \ - 2, /* prefetch distance */ \ - over_8888_8888_init, \ - nop_macro, /* newline */ \ - nop_macro, /* cleanup */ \ - over_8888_8888_process_head, \ - over_8888_8888_process_tail - -/******************************************************************************/ - -/* Multiply each byte of a word by a byte. - * Useful when there aren't any obvious ways to fill the stalls with other instructions. - * word Register containing 4 bytes - * byte Register containing byte multiplier (bits 8-31 must be 0) - * tmp Scratch register - * half Register containing the constant 0x00800080 - * GE[3:0] bits must contain 0101 - */ -.macro mul_8888_8 word, byte, tmp, half - /* Split even/odd bytes of word apart */ - uxtb16 tmp, word - uxtb16 word, word, ror #8 - /* Multiply bytes together with rounding, then by 257/256 */ - mla tmp, tmp, byte, half - mla word, word, byte, half /* 1 stall follows */ - uxtab16 tmp, tmp, tmp, ror #8 /* 1 stall follows */ - uxtab16 word, word, word, ror #8 - /* Recombine bytes */ - mov tmp, tmp, ror #8 - sel word, tmp, word -.endm - -/******************************************************************************/ - -.macro over_8888_n_8888_init - /* Mask is constant */ - ldr MASK, [sp, #ARGS_STACK_OFFSET+8] - /* Hold loop invariant in STRIDE_M */ - ldr STRIDE_M, =0x00800080 - /* We only want the alpha bits of the constant mask */ - mov MASK, MASK, lsr #24 - /* Set GE[3:0] to 0101 so SEL instructions do what we want */ - uadd8 SCRATCH, STRIDE_M, STRIDE_M - line_saved_regs Y, STRIDE_D, STRIDE_S, ORIG_W -.endm - -.macro over_8888_n_8888_process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, preload - WK4 .req Y - WK5 .req STRIDE_D - WK6 .req STRIDE_S - WK7 .req ORIG_W - pixld , numbytes, %(4+(firstreg%2)), SRC, unaligned_src - pixld , numbytes, firstreg, DST, 0 - .unreq WK4 - .unreq WK5 - .unreq WK6 - .unreq WK7 -.endm - -.macro over_8888_n_8888_1pixel src, dst - mul_8888_8 WK&src, MASK, SCRATCH, STRIDE_M - sub WK7, WK6, WK&src, lsr #24 - mul_8888_8 WK&dst, WK7, SCRATCH, STRIDE_M - uqadd8 WK&dst, WK&dst, WK&src -.endm - -.macro over_8888_n_8888_process_tail cond, numbytes, firstreg - WK4 .req Y - WK5 .req STRIDE_D - WK6 .req STRIDE_S - WK7 .req ORIG_W - over_8888_8888_check_transparent numbytes, %(4+(firstreg%2)), %(5+(firstreg%2)), %(6+firstreg), %(7+firstreg) - beq 10f - mov WK6, #255 - .set PROCESS_REG, firstreg - .rept numbytes / 4 - .if numbytes == 16 && PROCESS_REG == 2 - /* We're using WK6 and WK7 as temporaries, so half way through - * 4 pixels, reload the second two source pixels but this time - * into WK4 and WK5 */ - ldmdb SRC, {WK4, WK5} - .endif - over_8888_n_8888_1pixel %(4+(PROCESS_REG%2)), %(PROCESS_REG) - .set PROCESS_REG, PROCESS_REG+1 - .endr - pixst , numbytes, firstreg, DST -10: - .unreq WK4 - .unreq WK5 - .unreq WK6 - .unreq WK7 -.endm - -generate_composite_function \ - pixman_composite_over_8888_n_8888_asm_armv6, 32, 0, 32 \ - FLAG_DST_READWRITE | FLAG_BRANCH_OVER | FLAG_PROCESS_CORRUPTS_PSR | FLAG_PROCESS_DOES_STORE | FLAG_SPILL_LINE_VARS \ - 2, /* prefetch distance */ \ - over_8888_n_8888_init, \ - nop_macro, /* newline */ \ - nop_macro, /* cleanup */ \ - over_8888_n_8888_process_head, \ - over_8888_n_8888_process_tail - -/******************************************************************************/ - -.macro over_n_8_8888_init - /* Source is constant, but splitting it into even/odd bytes is a loop invariant */ - ldr SRC, [sp, #ARGS_STACK_OFFSET] - /* Not enough registers to hold this constant, but we still use it here to set GE[3:0] */ - ldr SCRATCH, =0x00800080 - uxtb16 STRIDE_S, SRC - uxtb16 SRC, SRC, ror #8 - /* Set GE[3:0] to 0101 so SEL instructions do what we want */ - uadd8 SCRATCH, SCRATCH, SCRATCH - line_saved_regs Y, STRIDE_D, STRIDE_M, ORIG_W -.endm - -.macro over_n_8_8888_newline - ldr STRIDE_D, =0x00800080 - b 1f - .ltorg -1: -.endm - -.macro over_n_8_8888_process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, preload - WK4 .req STRIDE_M - pixld , numbytes/4, 4, MASK, unaligned_mask - pixld , numbytes, firstreg, DST, 0 - .unreq WK4 -.endm - -.macro over_n_8_8888_1pixel src, dst - uxtb Y, WK4, ror #src*8 - /* Trailing part of multiplication of source */ - mla SCRATCH, STRIDE_S, Y, STRIDE_D - mla Y, SRC, Y, STRIDE_D - mov ORIG_W, #255 - uxtab16 SCRATCH, SCRATCH, SCRATCH, ror #8 - uxtab16 Y, Y, Y, ror #8 - mov SCRATCH, SCRATCH, ror #8 - sub ORIG_W, ORIG_W, Y, lsr #24 - sel Y, SCRATCH, Y - /* Then multiply the destination */ - mul_8888_8 WK&dst, ORIG_W, SCRATCH, STRIDE_D - uqadd8 WK&dst, WK&dst, Y -.endm - -.macro over_n_8_8888_process_tail cond, numbytes, firstreg - WK4 .req STRIDE_M - teq WK4, #0 - beq 10f - .set PROCESS_REG, firstreg - .rept numbytes / 4 - over_n_8_8888_1pixel %(PROCESS_REG-firstreg), %(PROCESS_REG) - .set PROCESS_REG, PROCESS_REG+1 - .endr - pixst , numbytes, firstreg, DST -10: - .unreq WK4 -.endm - -generate_composite_function \ - pixman_composite_over_n_8_8888_asm_armv6, 0, 8, 32 \ - FLAG_DST_READWRITE | FLAG_BRANCH_OVER | FLAG_PROCESS_CORRUPTS_PSR | FLAG_PROCESS_DOES_STORE | FLAG_SPILL_LINE_VARS \ - 2, /* prefetch distance */ \ - over_n_8_8888_init, \ - over_n_8_8888_newline, \ - nop_macro, /* cleanup */ \ - over_n_8_8888_process_head, \ - over_n_8_8888_process_tail - -/******************************************************************************/ - -.macro over_reverse_n_8888_init - ldr SRC, [sp, #ARGS_STACK_OFFSET] - ldr MASK, =0x00800080 - /* Split source pixel into RB/AG parts */ - uxtb16 STRIDE_S, SRC - uxtb16 STRIDE_M, SRC, ror #8 - /* Set GE[3:0] to 0101 so SEL instructions do what we want */ - uadd8 SCRATCH, MASK, MASK - line_saved_regs STRIDE_D, ORIG_W -.endm - -.macro over_reverse_n_8888_newline - mov STRIDE_D, #0xFF -.endm - -.macro over_reverse_n_8888_process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, preload - pixld , numbytes, firstreg, DST, 0 -.endm - -.macro over_reverse_n_8888_1pixel d, is_only - teq WK&d, #0 - beq 8f /* replace with source */ - bics ORIG_W, STRIDE_D, WK&d, lsr #24 - .if is_only == 1 - beq 49f /* skip store */ - .else - beq 9f /* write same value back */ - .endif - mla SCRATCH, STRIDE_S, ORIG_W, MASK /* red/blue */ - mla ORIG_W, STRIDE_M, ORIG_W, MASK /* alpha/green */ - uxtab16 SCRATCH, SCRATCH, SCRATCH, ror #8 - uxtab16 ORIG_W, ORIG_W, ORIG_W, ror #8 - mov SCRATCH, SCRATCH, ror #8 - sel ORIG_W, SCRATCH, ORIG_W - uqadd8 WK&d, WK&d, ORIG_W - b 9f -8: mov WK&d, SRC -9: -.endm - -.macro over_reverse_n_8888_tail numbytes, reg1, reg2, reg3, reg4 - .if numbytes == 4 - over_reverse_n_8888_1pixel reg1, 1 - .else - and SCRATCH, WK®1, WK®2 - .if numbytes == 16 - and SCRATCH, SCRATCH, WK®3 - and SCRATCH, SCRATCH, WK®4 - .endif - mvns SCRATCH, SCRATCH, asr #24 - beq 49f /* skip store if all opaque */ - over_reverse_n_8888_1pixel reg1, 0 - over_reverse_n_8888_1pixel reg2, 0 - .if numbytes == 16 - over_reverse_n_8888_1pixel reg3, 0 - over_reverse_n_8888_1pixel reg4, 0 - .endif - .endif - pixst , numbytes, reg1, DST -49: -.endm - -.macro over_reverse_n_8888_process_tail cond, numbytes, firstreg - over_reverse_n_8888_tail numbytes, firstreg, %(firstreg+1), %(firstreg+2), %(firstreg+3) -.endm - -generate_composite_function \ - pixman_composite_over_reverse_n_8888_asm_armv6, 0, 0, 32 \ - FLAG_DST_READWRITE | FLAG_BRANCH_OVER | FLAG_PROCESS_CORRUPTS_PSR | FLAG_PROCESS_DOES_STORE | FLAG_SPILL_LINE_VARS | FLAG_PROCESS_CORRUPTS_SCRATCH, \ - 3, /* prefetch distance */ \ - over_reverse_n_8888_init, \ - over_reverse_n_8888_newline, \ - nop_macro, /* cleanup */ \ - over_reverse_n_8888_process_head, \ - over_reverse_n_8888_process_tail - -/******************************************************************************/ - -.macro over_white_8888_8888_ca_init - HALF .req SRC - TMP0 .req STRIDE_D - TMP1 .req STRIDE_S - TMP2 .req STRIDE_M - TMP3 .req ORIG_W - WK4 .req SCRATCH - line_saved_regs STRIDE_D, STRIDE_M, ORIG_W - ldr SCRATCH, =0x800080 - mov HALF, #0x80 - /* Set GE[3:0] to 0101 so SEL instructions do what we want */ - uadd8 SCRATCH, SCRATCH, SCRATCH - .set DST_PRELOAD_BIAS, 8 -.endm - -.macro over_white_8888_8888_ca_cleanup - .set DST_PRELOAD_BIAS, 0 - .unreq HALF - .unreq TMP0 - .unreq TMP1 - .unreq TMP2 - .unreq TMP3 - .unreq WK4 -.endm - -.macro over_white_8888_8888_ca_combine m, d - uxtb16 TMP1, TMP0 /* rb_notmask */ - uxtb16 TMP2, d /* rb_dest; 1 stall follows */ - smlatt TMP3, TMP2, TMP1, HALF /* red */ - smlabb TMP2, TMP2, TMP1, HALF /* blue */ - uxtb16 TMP0, TMP0, ror #8 /* ag_notmask */ - uxtb16 TMP1, d, ror #8 /* ag_dest; 1 stall follows */ - smlatt d, TMP1, TMP0, HALF /* alpha */ - smlabb TMP1, TMP1, TMP0, HALF /* green */ - pkhbt TMP0, TMP2, TMP3, lsl #16 /* rb; 1 stall follows */ - pkhbt TMP1, TMP1, d, lsl #16 /* ag */ - uxtab16 TMP0, TMP0, TMP0, ror #8 - uxtab16 TMP1, TMP1, TMP1, ror #8 - mov TMP0, TMP0, ror #8 - sel d, TMP0, TMP1 - uqadd8 d, d, m /* d is a late result */ -.endm - -.macro over_white_8888_8888_ca_1pixel_head - pixld , 4, 1, MASK, 0 - pixld , 4, 3, DST, 0 -.endm - -.macro over_white_8888_8888_ca_1pixel_tail - mvn TMP0, WK1 - teq WK1, WK1, asr #32 - bne 01f - bcc 03f - mov WK3, WK1 - b 02f -01: over_white_8888_8888_ca_combine WK1, WK3 -02: pixst , 4, 3, DST -03: -.endm - -.macro over_white_8888_8888_ca_2pixels_head - pixld , 8, 1, MASK, 0 -.endm - -.macro over_white_8888_8888_ca_2pixels_tail - pixld , 8, 3, DST - mvn TMP0, WK1 - teq WK1, WK1, asr #32 - bne 01f - movcs WK3, WK1 - bcs 02f - teq WK2, #0 - beq 05f - b 02f -01: over_white_8888_8888_ca_combine WK1, WK3 -02: mvn TMP0, WK2 - teq WK2, WK2, asr #32 - bne 03f - movcs WK4, WK2 - b 04f -03: over_white_8888_8888_ca_combine WK2, WK4 -04: pixst , 8, 3, DST -05: -.endm - -.macro over_white_8888_8888_ca_process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, preload - .if numbytes == 4 - over_white_8888_8888_ca_1pixel_head - .else - .if numbytes == 16 - over_white_8888_8888_ca_2pixels_head - over_white_8888_8888_ca_2pixels_tail - .endif - over_white_8888_8888_ca_2pixels_head - .endif -.endm - -.macro over_white_8888_8888_ca_process_tail cond, numbytes, firstreg - .if numbytes == 4 - over_white_8888_8888_ca_1pixel_tail - .else - over_white_8888_8888_ca_2pixels_tail - .endif -.endm - -generate_composite_function \ - pixman_composite_over_white_8888_8888_ca_asm_armv6, 0, 32, 32 \ - FLAG_DST_READWRITE | FLAG_BRANCH_OVER | FLAG_PROCESS_CORRUPTS_PSR | FLAG_PROCESS_DOES_STORE | FLAG_SPILL_LINE_VARS | FLAG_PROCESS_CORRUPTS_SCRATCH \ - 2, /* prefetch distance */ \ - over_white_8888_8888_ca_init, \ - nop_macro, /* newline */ \ - over_white_8888_8888_ca_cleanup, \ - over_white_8888_8888_ca_process_head, \ - over_white_8888_8888_ca_process_tail - - -.macro over_n_8888_8888_ca_init - /* Set up constants. RB_SRC and AG_SRC are in registers; - * RB_FLDS, A_SRC, and the two HALF values need to go on the - * stack (and the ful SRC value is already there) */ - ldr SCRATCH, [sp, #ARGS_STACK_OFFSET] - mov WK0, #0x00FF0000 - orr WK0, WK0, #0xFF /* RB_FLDS (0x00FF00FF) */ - mov WK1, #0x80 /* HALF default value */ - mov WK2, SCRATCH, lsr #24 /* A_SRC */ - orr WK3, WK1, WK1, lsl #16 /* HALF alternate value (0x00800080) */ - push {WK0-WK3} - .set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET+16 - uxtb16 SRC, SCRATCH - uxtb16 STRIDE_S, SCRATCH, ror #8 - - /* Set GE[3:0] to 0101 so SEL instructions do what we want */ - uadd8 SCRATCH, WK3, WK3 - - .unreq WK0 - .unreq WK1 - .unreq WK2 - .unreq WK3 - WK0 .req Y - WK1 .req STRIDE_D - RB_SRC .req SRC - AG_SRC .req STRIDE_S - WK2 .req STRIDE_M - RB_FLDS .req r8 /* the reloaded constants have to be at consecutive registers starting at an even one */ - A_SRC .req r8 - HALF .req r9 - WK3 .req r10 - WK4 .req r11 - WK5 .req SCRATCH - WK6 .req ORIG_W - - line_saved_regs Y, STRIDE_D, STRIDE_M, ORIG_W -.endm - -.macro over_n_8888_8888_ca_cleanup - add sp, sp, #16 - .set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET-16 - - .unreq WK0 - .unreq WK1 - .unreq RB_SRC - .unreq AG_SRC - .unreq WK2 - .unreq RB_FLDS - .unreq A_SRC - .unreq HALF - .unreq WK3 - .unreq WK4 - .unreq WK5 - .unreq WK6 - WK0 .req r8 - WK1 .req r9 - WK2 .req r10 - WK3 .req r11 -.endm - -.macro over_n_8888_8888_ca_1pixel_head - pixld , 4, 6, MASK, 0 - pixld , 4, 0, DST, 0 -.endm - -.macro over_n_8888_8888_ca_1pixel_tail - ldrd A_SRC, HALF, [sp, #LOCALS_STACK_OFFSET+8] - uxtb16 WK1, WK6 /* rb_mask (first step of hard case placed in what would otherwise be a stall) */ - teq WK6, WK6, asr #32 /* Zc if transparent, ZC if opaque */ - bne 20f - bcc 40f - /* Mask is fully opaque (all channels) */ - ldr WK6, [sp, #ARGS_STACK_OFFSET] /* get SRC back */ - eors A_SRC, A_SRC, #0xFF - bne 10f - /* Source is also opaque - same as src_8888_8888 */ - mov WK0, WK6 - b 30f -10: /* Same as over_8888_8888 */ - mul_8888_8 WK0, A_SRC, WK5, HALF - uqadd8 WK0, WK0, WK6 - b 30f -20: /* No simplifications possible - do it the hard way */ - uxtb16 WK2, WK6, ror #8 /* ag_mask */ - mla WK3, WK1, A_SRC, HALF /* rb_mul; 2 cycles */ - mla WK4, WK2, A_SRC, HALF /* ag_mul; 2 cycles */ - ldrd RB_FLDS, HALF, [sp, #LOCALS_STACK_OFFSET] - uxtb16 WK5, WK0 /* rb_dest */ - uxtab16 WK3, WK3, WK3, ror #8 - uxtb16 WK6, WK0, ror #8 /* ag_dest */ - uxtab16 WK4, WK4, WK4, ror #8 - smlatt WK0, RB_SRC, WK1, HALF /* red1 */ - smlabb WK1, RB_SRC, WK1, HALF /* blue1 */ - bic WK3, RB_FLDS, WK3, lsr #8 - bic WK4, RB_FLDS, WK4, lsr #8 - pkhbt WK1, WK1, WK0, lsl #16 /* rb1 */ - smlatt WK0, WK5, WK3, HALF /* red2 */ - smlabb WK3, WK5, WK3, HALF /* blue2 */ - uxtab16 WK1, WK1, WK1, ror #8 - smlatt WK5, AG_SRC, WK2, HALF /* alpha1 */ - pkhbt WK3, WK3, WK0, lsl #16 /* rb2 */ - smlabb WK0, AG_SRC, WK2, HALF /* green1 */ - smlatt WK2, WK6, WK4, HALF /* alpha2 */ - smlabb WK4, WK6, WK4, HALF /* green2 */ - pkhbt WK0, WK0, WK5, lsl #16 /* ag1 */ - uxtab16 WK3, WK3, WK3, ror #8 - pkhbt WK4, WK4, WK2, lsl #16 /* ag2 */ - uxtab16 WK0, WK0, WK0, ror #8 - uxtab16 WK4, WK4, WK4, ror #8 - mov WK1, WK1, ror #8 - mov WK3, WK3, ror #8 - sel WK2, WK1, WK0 /* recombine source*mask */ - sel WK1, WK3, WK4 /* recombine dest*(1-source_alpha*mask) */ - uqadd8 WK0, WK1, WK2 /* followed by 1 stall */ -30: /* The destination buffer is already in the L1 cache, so - * there's little point in amalgamating writes */ - pixst , 4, 0, DST -40: -.endm - -.macro over_n_8888_8888_ca_process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, preload - .rept (numbytes / 4) - 1 - over_n_8888_8888_ca_1pixel_head - over_n_8888_8888_ca_1pixel_tail - .endr - over_n_8888_8888_ca_1pixel_head -.endm - -.macro over_n_8888_8888_ca_process_tail cond, numbytes, firstreg - over_n_8888_8888_ca_1pixel_tail -.endm - -pixman_asm_function pixman_composite_over_n_8888_8888_ca_asm_armv6 - ldr ip, [sp] - cmp ip, #-1 - beq pixman_composite_over_white_8888_8888_ca_asm_armv6 - /* else drop through... */ - .endfunc -generate_composite_function \ - pixman_composite_over_n_8888_8888_ca_asm_armv6_helper, 0, 32, 32 \ - FLAG_DST_READWRITE | FLAG_BRANCH_OVER | FLAG_PROCESS_CORRUPTS_PSR | FLAG_PROCESS_DOES_STORE | FLAG_SPILL_LINE_VARS | FLAG_PROCESS_CORRUPTS_SCRATCH | FLAG_PROCESS_CORRUPTS_WK0 \ - 2, /* prefetch distance */ \ - over_n_8888_8888_ca_init, \ - nop_macro, /* newline */ \ - over_n_8888_8888_ca_cleanup, \ - over_n_8888_8888_ca_process_head, \ - over_n_8888_8888_ca_process_tail - -/******************************************************************************/ - -.macro in_reverse_8888_8888_init - /* Hold loop invariant in MASK */ - ldr MASK, =0x00800080 - /* Set GE[3:0] to 0101 so SEL instructions do what we want */ - uadd8 SCRATCH, MASK, MASK - /* Offset the source pointer: we only need the alpha bytes */ - add SRC, SRC, #3 - line_saved_regs ORIG_W -.endm - -.macro in_reverse_8888_8888_head numbytes, reg1, reg2, reg3 - ldrb ORIG_W, [SRC], #4 - .if numbytes >= 8 - ldrb WK®1, [SRC], #4 - .if numbytes == 16 - ldrb WK®2, [SRC], #4 - ldrb WK®3, [SRC], #4 - .endif - .endif - add DST, DST, #numbytes -.endm - -.macro in_reverse_8888_8888_process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, preload - in_reverse_8888_8888_head numbytes, firstreg, %(firstreg+1), %(firstreg+2) -.endm - -.macro in_reverse_8888_8888_1pixel s, d, offset, is_only - .if is_only != 1 - movs s, ORIG_W - .if offset != 0 - ldrb ORIG_W, [SRC, #offset] - .endif - beq 01f - teq STRIDE_M, #0xFF - beq 02f - .endif - uxtb16 SCRATCH, d /* rb_dest */ - uxtb16 d, d, ror #8 /* ag_dest */ - mla SCRATCH, SCRATCH, s, MASK - mla d, d, s, MASK - uxtab16 SCRATCH, SCRATCH, SCRATCH, ror #8 - uxtab16 d, d, d, ror #8 - mov SCRATCH, SCRATCH, ror #8 - sel d, SCRATCH, d - b 02f - .if offset == 0 -48: /* Last mov d,#0 of the set - used as part of shortcut for - * source values all 0 */ - .endif -01: mov d, #0 -02: -.endm - -.macro in_reverse_8888_8888_tail numbytes, reg1, reg2, reg3, reg4 - .if numbytes == 4 - teq ORIG_W, ORIG_W, asr #32 - ldrne WK®1, [DST, #-4] - .elseif numbytes == 8 - teq ORIG_W, WK®1 - teqeq ORIG_W, ORIG_W, asr #32 /* all 0 or all -1? */ - ldmnedb DST, {WK®1-WK®2} - .else - teq ORIG_W, WK®1 - teqeq ORIG_W, WK®2 - teqeq ORIG_W, WK®3 - teqeq ORIG_W, ORIG_W, asr #32 /* all 0 or all -1? */ - ldmnedb DST, {WK®1-WK®4} - .endif - cmnne DST, #0 /* clear C if NE */ - bcs 49f /* no writes to dest if source all -1 */ - beq 48f /* set dest to all 0 if source all 0 */ - .if numbytes == 4 - in_reverse_8888_8888_1pixel ORIG_W, WK®1, 0, 1 - str WK®1, [DST, #-4] - .elseif numbytes == 8 - in_reverse_8888_8888_1pixel STRIDE_M, WK®1, -4, 0 - in_reverse_8888_8888_1pixel STRIDE_M, WK®2, 0, 0 - stmdb DST, {WK®1-WK®2} - .else - in_reverse_8888_8888_1pixel STRIDE_M, WK®1, -12, 0 - in_reverse_8888_8888_1pixel STRIDE_M, WK®2, -8, 0 - in_reverse_8888_8888_1pixel STRIDE_M, WK®3, -4, 0 - in_reverse_8888_8888_1pixel STRIDE_M, WK®4, 0, 0 - stmdb DST, {WK®1-WK®4} - .endif -49: -.endm - -.macro in_reverse_8888_8888_process_tail cond, numbytes, firstreg - in_reverse_8888_8888_tail numbytes, firstreg, %(firstreg+1), %(firstreg+2), %(firstreg+3) -.endm - -generate_composite_function \ - pixman_composite_in_reverse_8888_8888_asm_armv6, 32, 0, 32 \ - FLAG_DST_READWRITE | FLAG_BRANCH_OVER | FLAG_PROCESS_CORRUPTS_PSR | FLAG_PROCESS_DOES_STORE | FLAG_SPILL_LINE_VARS | FLAG_PROCESS_CORRUPTS_SCRATCH | FLAG_NO_PRELOAD_DST \ - 2, /* prefetch distance */ \ - in_reverse_8888_8888_init, \ - nop_macro, /* newline */ \ - nop_macro, /* cleanup */ \ - in_reverse_8888_8888_process_head, \ - in_reverse_8888_8888_process_tail - -/******************************************************************************/ - -.macro over_n_8888_init - ldr SRC, [sp, #ARGS_STACK_OFFSET] - /* Hold loop invariant in MASK */ - ldr MASK, =0x00800080 - /* Hold multiplier for destination in STRIDE_M */ - mov STRIDE_M, #255 - sub STRIDE_M, STRIDE_M, SRC, lsr #24 - /* Set GE[3:0] to 0101 so SEL instructions do what we want */ - uadd8 SCRATCH, MASK, MASK -.endm - -.macro over_n_8888_process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, preload - pixld , numbytes, firstreg, DST, 0 -.endm - -.macro over_n_8888_1pixel dst - mul_8888_8 WK&dst, STRIDE_M, SCRATCH, MASK - uqadd8 WK&dst, WK&dst, SRC -.endm - -.macro over_n_8888_process_tail cond, numbytes, firstreg - .set PROCESS_REG, firstreg - .rept numbytes / 4 - over_n_8888_1pixel %(PROCESS_REG) - .set PROCESS_REG, PROCESS_REG+1 - .endr - pixst , numbytes, firstreg, DST -.endm - -generate_composite_function \ - pixman_composite_over_n_8888_asm_armv6, 0, 0, 32 \ - FLAG_DST_READWRITE | FLAG_BRANCH_OVER | FLAG_PROCESS_DOES_STORE \ - 2, /* prefetch distance */ \ - over_n_8888_init, \ - nop_macro, /* newline */ \ - nop_macro, /* cleanup */ \ - over_n_8888_process_head, \ - over_n_8888_process_tail - -/******************************************************************************/ diff --git a/source/libs/pixman/pixman-src/pixman/pixman-arm-simd-asm.h b/source/libs/pixman/pixman-src/pixman/pixman-arm-simd-asm.h deleted file mode 100644 index da153c3f58571d06f787cfa9af70e035f3e9c1d7..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-arm-simd-asm.h +++ /dev/null @@ -1,966 +0,0 @@ -/* - * Copyright © 2012 Raspberry Pi Foundation - * Copyright © 2012 RISC OS Open Ltd - * - * 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 the copyright holders not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. The copyright holders make no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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: Ben Avison (bavison@riscosopen.org) - * - */ - -/* - * Because the alignment of pixel data to cachelines, and even the number of - * cachelines per row can vary from row to row, and because of the need to - * preload each scanline once and only once, this prefetch strategy treats - * each row of pixels independently. When a pixel row is long enough, there - * are three distinct phases of prefetch: - * * an inner loop section, where each time a cacheline of data is - * processed, another cacheline is preloaded (the exact distance ahead is - * determined empirically using profiling results from lowlevel-blt-bench) - * * a leading section, where enough cachelines are preloaded to ensure no - * cachelines escape being preloaded when the inner loop starts - * * a trailing section, where a limited number (0 or more) of cachelines - * are preloaded to deal with data (if any) that hangs off the end of the - * last iteration of the inner loop, plus any trailing bytes that were not - * enough to make up one whole iteration of the inner loop - * - * There are (in general) three distinct code paths, selected between - * depending upon how long the pixel row is. If it is long enough that there - * is at least one iteration of the inner loop (as described above) then - * this is described as the "wide" case. If it is shorter than that, but - * there are still enough bytes output that there is at least one 16-byte- - * long, 16-byte-aligned write to the destination (the optimum type of - * write), then this is the "medium" case. If it is not even this long, then - * this is the "narrow" case, and there is no attempt to align writes to - * 16-byte boundaries. In the "medium" and "narrow" cases, all the - * cachelines containing data from the pixel row are prefetched up-front. - */ - -/* - * Determine whether we put the arguments on the stack for debugging. - */ -#undef DEBUG_PARAMS - -/* - * Bit flags for 'generate_composite_function' macro which are used - * to tune generated functions behavior. - */ -.set FLAG_DST_WRITEONLY, 0 -.set FLAG_DST_READWRITE, 1 -.set FLAG_COND_EXEC, 0 -.set FLAG_BRANCH_OVER, 2 -.set FLAG_PROCESS_PRESERVES_PSR, 0 -.set FLAG_PROCESS_CORRUPTS_PSR, 4 -.set FLAG_PROCESS_DOESNT_STORE, 0 -.set FLAG_PROCESS_DOES_STORE, 8 /* usually because it needs to conditionally skip it */ -.set FLAG_NO_SPILL_LINE_VARS, 0 -.set FLAG_SPILL_LINE_VARS_WIDE, 16 -.set FLAG_SPILL_LINE_VARS_NON_WIDE, 32 -.set FLAG_SPILL_LINE_VARS, 48 -.set FLAG_PROCESS_CORRUPTS_SCRATCH, 0 -.set FLAG_PROCESS_PRESERVES_SCRATCH, 64 -.set FLAG_PROCESS_PRESERVES_WK0, 0 -.set FLAG_PROCESS_CORRUPTS_WK0, 128 /* if possible, use the specified register(s) instead so WK0 can hold number of leading pixels */ -.set FLAG_PRELOAD_DST, 0 -.set FLAG_NO_PRELOAD_DST, 256 - -/* - * Number of bytes by which to adjust preload offset of destination - * buffer (allows preload instruction to be moved before the load(s)) - */ -.set DST_PRELOAD_BIAS, 0 - -/* - * Offset into stack where mask and source pointer/stride can be accessed. - */ -#ifdef DEBUG_PARAMS -.set ARGS_STACK_OFFSET, (9*4+9*4) -#else -.set ARGS_STACK_OFFSET, (9*4) -#endif - -/* - * Offset into stack where space allocated during init macro can be accessed. - */ -.set LOCALS_STACK_OFFSET, 0 - -/* - * Constants for selecting preferable prefetch type. - */ -.set PREFETCH_TYPE_NONE, 0 -.set PREFETCH_TYPE_STANDARD, 1 - -/* - * Definitions of macros for load/store of pixel data. - */ - -.macro pixldst op, cond=al, numbytes, reg0, reg1, reg2, reg3, base, unaligned=0 - .if numbytes == 16 - .if unaligned == 1 - op&r&cond WK®0, [base], #4 - op&r&cond WK®1, [base], #4 - op&r&cond WK®2, [base], #4 - op&r&cond WK®3, [base], #4 - .else - op&m&cond&ia base!, {WK®0,WK®1,WK®2,WK®3} - .endif - .elseif numbytes == 8 - .if unaligned == 1 - op&r&cond WK®0, [base], #4 - op&r&cond WK®1, [base], #4 - .else - op&m&cond&ia base!, {WK®0,WK®1} - .endif - .elseif numbytes == 4 - op&r&cond WK®0, [base], #4 - .elseif numbytes == 2 - op&r&cond&h WK®0, [base], #2 - .elseif numbytes == 1 - op&r&cond&b WK®0, [base], #1 - .else - .error "unsupported size: numbytes" - .endif -.endm - -.macro pixst_baseupdated cond, numbytes, reg0, reg1, reg2, reg3, base - .if numbytes == 16 - stm&cond&db base, {WK®0,WK®1,WK®2,WK®3} - .elseif numbytes == 8 - stm&cond&db base, {WK®0,WK®1} - .elseif numbytes == 4 - str&cond WK®0, [base, #-4] - .elseif numbytes == 2 - str&cond&h WK®0, [base, #-2] - .elseif numbytes == 1 - str&cond&b WK®0, [base, #-1] - .else - .error "unsupported size: numbytes" - .endif -.endm - -.macro pixld cond, numbytes, firstreg, base, unaligned - pixldst ld, cond, numbytes, %(firstreg+0), %(firstreg+1), %(firstreg+2), %(firstreg+3), base, unaligned -.endm - -.macro pixst cond, numbytes, firstreg, base - .if (flags) & FLAG_DST_READWRITE - pixst_baseupdated cond, numbytes, %(firstreg+0), %(firstreg+1), %(firstreg+2), %(firstreg+3), base - .else - pixldst st, cond, numbytes, %(firstreg+0), %(firstreg+1), %(firstreg+2), %(firstreg+3), base - .endif -.endm - -.macro PF a, x:vararg - .if (PREFETCH_TYPE_CURRENT == PREFETCH_TYPE_STANDARD) - a x - .endif -.endm - - -.macro preload_leading_step1 bpp, ptr, base -/* If the destination is already 16-byte aligned, then we need to preload - * between 0 and prefetch_distance (inclusive) cache lines ahead so there - * are no gaps when the inner loop starts. - */ - .if bpp > 0 - PF bic, ptr, base, #31 - .set OFFSET, 0 - .rept prefetch_distance+1 - PF pld, [ptr, #OFFSET] - .set OFFSET, OFFSET+32 - .endr - .endif -.endm - -.macro preload_leading_step2 bpp, bpp_shift, ptr, base -/* However, if the destination is not 16-byte aligned, we may need to - * preload more cache lines than that. The question we need to ask is: - * are the bytes corresponding to the leading pixels more than the amount - * by which the source pointer will be rounded down for preloading, and if - * so, by how many cache lines? Effectively, we want to calculate - * leading_bytes = ((-dst)&15)*src_bpp/dst_bpp - * inner_loop_offset = (src+leading_bytes)&31 - * extra_needed = leading_bytes - inner_loop_offset - * and test if extra_needed is <= 0, <= 32, or > 32 (where > 32 is only - * possible when there are 4 src bytes for every 1 dst byte). - */ - .if bpp > 0 - .ifc base,DST - /* The test can be simplified further when preloading the destination */ - PF tst, base, #16 - PF beq, 61f - .else - .if bpp/dst_w_bpp == 4 - PF add, SCRATCH, base, WK0, lsl #bpp_shift-dst_bpp_shift - PF and, SCRATCH, SCRATCH, #31 - PF rsb, SCRATCH, SCRATCH, WK0, lsl #bpp_shift-dst_bpp_shift - PF sub, SCRATCH, SCRATCH, #1 /* so now ranges are -16..-1 / 0..31 / 32..63 */ - PF movs, SCRATCH, SCRATCH, lsl #32-6 /* so this sets NC / nc / Nc */ - PF bcs, 61f - PF bpl, 60f - PF pld, [ptr, #32*(prefetch_distance+2)] - .else - PF mov, SCRATCH, base, lsl #32-5 - PF add, SCRATCH, SCRATCH, WK0, lsl #32-5+bpp_shift-dst_bpp_shift - PF rsbs, SCRATCH, SCRATCH, WK0, lsl #32-5+bpp_shift-dst_bpp_shift - PF bls, 61f - .endif - .endif -60: PF pld, [ptr, #32*(prefetch_distance+1)] -61: - .endif -.endm - -#define IS_END_OF_GROUP(INDEX,SIZE) ((SIZE) < 2 || ((INDEX) & ~((INDEX)+1)) & ((SIZE)/2)) -.macro preload_middle bpp, base, scratch_holds_offset - .if bpp > 0 - /* prefetch distance = 256/bpp, stm distance = 128/dst_w_bpp */ - .if IS_END_OF_GROUP(SUBBLOCK,256/128*dst_w_bpp/bpp) - .if scratch_holds_offset - PF pld, [base, SCRATCH] - .else - PF bic, SCRATCH, base, #31 - PF pld, [SCRATCH, #32*prefetch_distance] - .endif - .endif - .endif -.endm - -.macro preload_trailing bpp, bpp_shift, base - .if bpp > 0 - .if bpp*pix_per_block > 256 - /* Calculations are more complex if more than one fetch per block */ - PF and, WK1, base, #31 - PF add, WK1, WK1, WK0, lsl #bpp_shift - PF add, WK1, WK1, #32*(bpp*pix_per_block/256-1)*(prefetch_distance+1) - PF bic, SCRATCH, base, #31 -80: PF pld, [SCRATCH, #32*(prefetch_distance+1)] - PF add, SCRATCH, SCRATCH, #32 - PF subs, WK1, WK1, #32 - PF bhi, 80b - .else - /* If exactly one fetch per block, then we need either 0, 1 or 2 extra preloads */ - PF mov, SCRATCH, base, lsl #32-5 - PF adds, SCRATCH, SCRATCH, X, lsl #32-5+bpp_shift - PF adceqs, SCRATCH, SCRATCH, #0 - /* The instruction above has two effects: ensures Z is only - * set if C was clear (so Z indicates that both shifted quantities - * were 0), and clears C if Z was set (so C indicates that the sum - * of the shifted quantities was greater and not equal to 32) */ - PF beq, 82f - PF bic, SCRATCH, base, #31 - PF bcc, 81f - PF pld, [SCRATCH, #32*(prefetch_distance+2)] -81: PF pld, [SCRATCH, #32*(prefetch_distance+1)] -82: - .endif - .endif -.endm - - -.macro preload_line narrow_case, bpp, bpp_shift, base -/* "narrow_case" - just means that the macro was invoked from the "narrow" - * code path rather than the "medium" one - because in the narrow case, - * the row of pixels is known to output no more than 30 bytes, then - * (assuming the source pixels are no wider than the the destination - * pixels) they cannot possibly straddle more than 2 32-byte cachelines, - * meaning there's no need for a loop. - * "bpp" - number of bits per pixel in the channel (source, mask or - * destination) that's being preloaded, or 0 if this channel is not used - * for reading - * "bpp_shift" - log2 of ("bpp"/8) (except if "bpp"=0 of course) - * "base" - base address register of channel to preload (SRC, MASK or DST) - */ - .if bpp > 0 - .if narrow_case && (bpp <= dst_w_bpp) - /* In these cases, each line for each channel is in either 1 or 2 cache lines */ - PF bic, WK0, base, #31 - PF pld, [WK0] - PF add, WK1, base, X, LSL #bpp_shift - PF sub, WK1, WK1, #1 - PF bic, WK1, WK1, #31 - PF cmp, WK1, WK0 - PF beq, 90f - PF pld, [WK1] -90: - .else - PF bic, WK0, base, #31 - PF pld, [WK0] - PF add, WK1, base, X, lsl #bpp_shift - PF sub, WK1, WK1, #1 - PF bic, WK1, WK1, #31 - PF cmp, WK1, WK0 - PF beq, 92f -91: PF add, WK0, WK0, #32 - PF cmp, WK0, WK1 - PF pld, [WK0] - PF bne, 91b -92: - .endif - .endif -.endm - - -.macro conditional_process1_helper cond, process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx - process_head cond, numbytes, firstreg, unaligned_src, unaligned_mask, 0 - .if decrementx - sub&cond X, X, #8*numbytes/dst_w_bpp - .endif - process_tail cond, numbytes, firstreg - .if !((flags) & FLAG_PROCESS_DOES_STORE) - pixst cond, numbytes, firstreg, DST - .endif -.endm - -.macro conditional_process1 cond, process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx - .if (flags) & FLAG_BRANCH_OVER - .ifc cond,mi - bpl 100f - .endif - .ifc cond,cs - bcc 100f - .endif - .ifc cond,ne - beq 100f - .endif - conditional_process1_helper , process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx -100: - .else - conditional_process1_helper cond, process_head, process_tail, numbytes, firstreg, unaligned_src, unaligned_mask, decrementx - .endif -.endm - -.macro conditional_process2 test, cond1, cond2, process_head, process_tail, numbytes1, numbytes2, firstreg1, firstreg2, unaligned_src, unaligned_mask, decrementx - .if (flags) & (FLAG_DST_READWRITE | FLAG_BRANCH_OVER | FLAG_PROCESS_CORRUPTS_PSR | FLAG_PROCESS_DOES_STORE) - /* Can't interleave reads and writes */ - test - conditional_process1 cond1, process_head, process_tail, numbytes1, firstreg1, unaligned_src, unaligned_mask, decrementx - .if (flags) & FLAG_PROCESS_CORRUPTS_PSR - test - .endif - conditional_process1 cond2, process_head, process_tail, numbytes2, firstreg2, unaligned_src, unaligned_mask, decrementx - .else - /* Can interleave reads and writes for better scheduling */ - test - process_head cond1, numbytes1, firstreg1, unaligned_src, unaligned_mask, 0 - process_head cond2, numbytes2, firstreg2, unaligned_src, unaligned_mask, 0 - .if decrementx - sub&cond1 X, X, #8*numbytes1/dst_w_bpp - sub&cond2 X, X, #8*numbytes2/dst_w_bpp - .endif - process_tail cond1, numbytes1, firstreg1 - process_tail cond2, numbytes2, firstreg2 - pixst cond1, numbytes1, firstreg1, DST - pixst cond2, numbytes2, firstreg2, DST - .endif -.endm - - -.macro test_bits_1_0_ptr - .if (flags) & FLAG_PROCESS_CORRUPTS_WK0 - movs SCRATCH, X, lsl #32-1 /* C,N = bits 1,0 of DST */ - .else - movs SCRATCH, WK0, lsl #32-1 /* C,N = bits 1,0 of DST */ - .endif -.endm - -.macro test_bits_3_2_ptr - .if (flags) & FLAG_PROCESS_CORRUPTS_WK0 - movs SCRATCH, X, lsl #32-3 /* C,N = bits 3, 2 of DST */ - .else - movs SCRATCH, WK0, lsl #32-3 /* C,N = bits 3, 2 of DST */ - .endif -.endm - -.macro leading_15bytes process_head, process_tail - /* On entry, WK0 bits 0-3 = number of bytes until destination is 16-byte aligned */ - .set DECREMENT_X, 1 - .if (flags) & FLAG_PROCESS_CORRUPTS_WK0 - .set DECREMENT_X, 0 - sub X, X, WK0, lsr #dst_bpp_shift - str X, [sp, #LINE_SAVED_REG_COUNT*4] - mov X, WK0 - .endif - /* Use unaligned loads in all cases for simplicity */ - .if dst_w_bpp == 8 - conditional_process2 test_bits_1_0_ptr, mi, cs, process_head, process_tail, 1, 2, 1, 2, 1, 1, DECREMENT_X - .elseif dst_w_bpp == 16 - test_bits_1_0_ptr - conditional_process1 cs, process_head, process_tail, 2, 2, 1, 1, DECREMENT_X - .endif - conditional_process2 test_bits_3_2_ptr, mi, cs, process_head, process_tail, 4, 8, 1, 2, 1, 1, DECREMENT_X - .if (flags) & FLAG_PROCESS_CORRUPTS_WK0 - ldr X, [sp, #LINE_SAVED_REG_COUNT*4] - .endif -.endm - -.macro test_bits_3_2_pix - movs SCRATCH, X, lsl #dst_bpp_shift+32-3 -.endm - -.macro test_bits_1_0_pix - .if dst_w_bpp == 8 - movs SCRATCH, X, lsl #dst_bpp_shift+32-1 - .else - movs SCRATCH, X, lsr #1 - .endif -.endm - -.macro trailing_15bytes process_head, process_tail, unaligned_src, unaligned_mask - conditional_process2 test_bits_3_2_pix, cs, mi, process_head, process_tail, 8, 4, 0, 2, unaligned_src, unaligned_mask, 0 - .if dst_w_bpp == 16 - test_bits_1_0_pix - conditional_process1 cs, process_head, process_tail, 2, 0, unaligned_src, unaligned_mask, 0 - .elseif dst_w_bpp == 8 - conditional_process2 test_bits_1_0_pix, cs, mi, process_head, process_tail, 2, 1, 0, 1, unaligned_src, unaligned_mask, 0 - .endif -.endm - - -.macro wide_case_inner_loop process_head, process_tail, unaligned_src, unaligned_mask, dst_alignment -110: - .set SUBBLOCK, 0 /* this is a count of STMs; there can be up to 8 STMs per block */ - .rept pix_per_block*dst_w_bpp/128 - process_head , 16, 0, unaligned_src, unaligned_mask, 1 - .if (src_bpp > 0) && (mask_bpp == 0) && ((flags) & FLAG_PROCESS_PRESERVES_SCRATCH) - preload_middle src_bpp, SRC, 1 - .elseif (src_bpp == 0) && (mask_bpp > 0) && ((flags) & FLAG_PROCESS_PRESERVES_SCRATCH) - preload_middle mask_bpp, MASK, 1 - .else - preload_middle src_bpp, SRC, 0 - preload_middle mask_bpp, MASK, 0 - .endif - .if (dst_r_bpp > 0) && ((SUBBLOCK % 2) == 0) && (((flags) & FLAG_NO_PRELOAD_DST) == 0) - /* Because we know that writes are 16-byte aligned, it's relatively easy to ensure that - * destination prefetches are 32-byte aligned. It's also the easiest channel to offset - * preloads for, to achieve staggered prefetches for multiple channels, because there are - * always two STMs per prefetch, so there is always an opposite STM on which to put the - * preload. Note, no need to BIC the base register here */ - PF pld, [DST, #32*prefetch_distance - dst_alignment] - .endif - process_tail , 16, 0 - .if !((flags) & FLAG_PROCESS_DOES_STORE) - pixst , 16, 0, DST - .endif - .set SUBBLOCK, SUBBLOCK+1 - .endr - subs X, X, #pix_per_block - bhs 110b -.endm - -.macro wide_case_inner_loop_and_trailing_pixels process_head, process_tail, process_inner_loop, exit_label, unaligned_src, unaligned_mask - /* Destination now 16-byte aligned; we have at least one block before we have to stop preloading */ - .if dst_r_bpp > 0 - tst DST, #16 - bne 111f - process_inner_loop process_head, process_tail, unaligned_src, unaligned_mask, 16 + DST_PRELOAD_BIAS - b 112f -111: - .endif - process_inner_loop process_head, process_tail, unaligned_src, unaligned_mask, 0 + DST_PRELOAD_BIAS -112: - /* Just before the final (prefetch_distance+1) 32-byte blocks, deal with final preloads */ - .if (src_bpp*pix_per_block > 256) || (mask_bpp*pix_per_block > 256) || (dst_r_bpp*pix_per_block > 256) - PF and, WK0, X, #pix_per_block-1 - .endif - preload_trailing src_bpp, src_bpp_shift, SRC - preload_trailing mask_bpp, mask_bpp_shift, MASK - .if ((flags) & FLAG_NO_PRELOAD_DST) == 0 - preload_trailing dst_r_bpp, dst_bpp_shift, DST - .endif - add X, X, #(prefetch_distance+2)*pix_per_block - 128/dst_w_bpp - /* The remainder of the line is handled identically to the medium case */ - medium_case_inner_loop_and_trailing_pixels process_head, process_tail,, exit_label, unaligned_src, unaligned_mask -.endm - -.macro medium_case_inner_loop_and_trailing_pixels process_head, process_tail, unused, exit_label, unaligned_src, unaligned_mask -120: - process_head , 16, 0, unaligned_src, unaligned_mask, 0 - process_tail , 16, 0 - .if !((flags) & FLAG_PROCESS_DOES_STORE) - pixst , 16, 0, DST - .endif - subs X, X, #128/dst_w_bpp - bhs 120b - /* Trailing pixels */ - tst X, #128/dst_w_bpp - 1 - beq exit_label - trailing_15bytes process_head, process_tail, unaligned_src, unaligned_mask -.endm - -.macro narrow_case_inner_loop_and_trailing_pixels process_head, process_tail, unused, exit_label, unaligned_src, unaligned_mask - tst X, #16*8/dst_w_bpp - conditional_process1 ne, process_head, process_tail, 16, 0, unaligned_src, unaligned_mask, 0 - /* Trailing pixels */ - /* In narrow case, it's relatively unlikely to be aligned, so let's do without a branch here */ - trailing_15bytes process_head, process_tail, unaligned_src, unaligned_mask -.endm - -.macro switch_on_alignment action, process_head, process_tail, process_inner_loop, exit_label - /* Note that if we're reading the destination, it's already guaranteed to be aligned at this point */ - .if mask_bpp == 8 || mask_bpp == 16 - tst MASK, #3 - bne 141f - .endif - .if src_bpp == 8 || src_bpp == 16 - tst SRC, #3 - bne 140f - .endif - action process_head, process_tail, process_inner_loop, exit_label, 0, 0 - .if src_bpp == 8 || src_bpp == 16 - b exit_label -140: - action process_head, process_tail, process_inner_loop, exit_label, 1, 0 - .endif - .if mask_bpp == 8 || mask_bpp == 16 - b exit_label -141: - .if src_bpp == 8 || src_bpp == 16 - tst SRC, #3 - bne 142f - .endif - action process_head, process_tail, process_inner_loop, exit_label, 0, 1 - .if src_bpp == 8 || src_bpp == 16 - b exit_label -142: - action process_head, process_tail, process_inner_loop, exit_label, 1, 1 - .endif - .endif -.endm - - -.macro end_of_line restore_x, vars_spilled, loop_label, last_one - .if vars_spilled - /* Sadly, GAS doesn't seem have an equivalent of the DCI directive? */ - /* This is ldmia sp,{} */ - .word 0xE89D0000 | LINE_SAVED_REGS - .endif - subs Y, Y, #1 - .if vars_spilled - .if (LINE_SAVED_REGS) & (1<<1) - str Y, [sp] - .endif - .endif - add DST, DST, STRIDE_D - .if src_bpp > 0 - add SRC, SRC, STRIDE_S - .endif - .if mask_bpp > 0 - add MASK, MASK, STRIDE_M - .endif - .if restore_x - mov X, ORIG_W - .endif - bhs loop_label - .ifc "last_one","" - .if vars_spilled - b 197f - .else - b 198f - .endif - .else - .if (!vars_spilled) && ((flags) & FLAG_SPILL_LINE_VARS) - b 198f - .endif - .endif -.endm - - -.macro generate_composite_function fname, \ - src_bpp_, \ - mask_bpp_, \ - dst_w_bpp_, \ - flags_, \ - prefetch_distance_, \ - init, \ - newline, \ - cleanup, \ - process_head, \ - process_tail, \ - process_inner_loop - - pixman_asm_function fname - -/* - * Make some macro arguments globally visible and accessible - * from other macros - */ - .set src_bpp, src_bpp_ - .set mask_bpp, mask_bpp_ - .set dst_w_bpp, dst_w_bpp_ - .set flags, flags_ - .set prefetch_distance, prefetch_distance_ - -/* - * Select prefetch type for this function. - */ - .if prefetch_distance == 0 - .set PREFETCH_TYPE_CURRENT, PREFETCH_TYPE_NONE - .else - .set PREFETCH_TYPE_CURRENT, PREFETCH_TYPE_STANDARD - .endif - - .if src_bpp == 32 - .set src_bpp_shift, 2 - .elseif src_bpp == 24 - .set src_bpp_shift, 0 - .elseif src_bpp == 16 - .set src_bpp_shift, 1 - .elseif src_bpp == 8 - .set src_bpp_shift, 0 - .elseif src_bpp == 0 - .set src_bpp_shift, -1 - .else - .error "requested src bpp (src_bpp) is not supported" - .endif - - .if mask_bpp == 32 - .set mask_bpp_shift, 2 - .elseif mask_bpp == 24 - .set mask_bpp_shift, 0 - .elseif mask_bpp == 8 - .set mask_bpp_shift, 0 - .elseif mask_bpp == 0 - .set mask_bpp_shift, -1 - .else - .error "requested mask bpp (mask_bpp) is not supported" - .endif - - .if dst_w_bpp == 32 - .set dst_bpp_shift, 2 - .elseif dst_w_bpp == 24 - .set dst_bpp_shift, 0 - .elseif dst_w_bpp == 16 - .set dst_bpp_shift, 1 - .elseif dst_w_bpp == 8 - .set dst_bpp_shift, 0 - .else - .error "requested dst bpp (dst_w_bpp) is not supported" - .endif - - .if (((flags) & FLAG_DST_READWRITE) != 0) - .set dst_r_bpp, dst_w_bpp - .else - .set dst_r_bpp, 0 - .endif - - .set pix_per_block, 16*8/dst_w_bpp - .if src_bpp != 0 - .if 32*8/src_bpp > pix_per_block - .set pix_per_block, 32*8/src_bpp - .endif - .endif - .if mask_bpp != 0 - .if 32*8/mask_bpp > pix_per_block - .set pix_per_block, 32*8/mask_bpp - .endif - .endif - .if dst_r_bpp != 0 - .if 32*8/dst_r_bpp > pix_per_block - .set pix_per_block, 32*8/dst_r_bpp - .endif - .endif - -/* The standard entry conditions set up by pixman-arm-common.h are: - * r0 = width (pixels) - * r1 = height (rows) - * r2 = pointer to top-left pixel of destination - * r3 = destination stride (pixels) - * [sp] = source pixel value, or pointer to top-left pixel of source - * [sp,#4] = 0 or source stride (pixels) - * The following arguments are unused for non-mask operations - * [sp,#8] = mask pixel value, or pointer to top-left pixel of mask - * [sp,#12] = 0 or mask stride (pixels) - */ - -/* - * Assign symbolic names to registers - */ - X .req r0 /* pixels to go on this line */ - Y .req r1 /* lines to go */ - DST .req r2 /* destination pixel pointer */ - STRIDE_D .req r3 /* destination stride (bytes, minus width) */ - SRC .req r4 /* source pixel pointer */ - STRIDE_S .req r5 /* source stride (bytes, minus width) */ - MASK .req r6 /* mask pixel pointer (if applicable) */ - STRIDE_M .req r7 /* mask stride (bytes, minus width) */ - WK0 .req r8 /* pixel data registers */ - WK1 .req r9 - WK2 .req r10 - WK3 .req r11 - SCRATCH .req r12 - ORIG_W .req r14 /* width (pixels) */ - - push {r4-r11, lr} /* save all registers */ - - subs Y, Y, #1 - blo 199f - -#ifdef DEBUG_PARAMS - sub sp, sp, #9*4 -#endif - - .if src_bpp > 0 - ldr SRC, [sp, #ARGS_STACK_OFFSET] - ldr STRIDE_S, [sp, #ARGS_STACK_OFFSET+4] - .endif - .if mask_bpp > 0 - ldr MASK, [sp, #ARGS_STACK_OFFSET+8] - ldr STRIDE_M, [sp, #ARGS_STACK_OFFSET+12] - .endif - -#ifdef DEBUG_PARAMS - add Y, Y, #1 - stmia sp, {r0-r7,pc} - sub Y, Y, #1 -#endif - - init - - .if (flags) & FLAG_PROCESS_CORRUPTS_WK0 - /* Reserve a word in which to store X during leading pixels */ - sub sp, sp, #4 - .set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET+4 - .set LOCALS_STACK_OFFSET, LOCALS_STACK_OFFSET+4 - .endif - - lsl STRIDE_D, #dst_bpp_shift /* stride in bytes */ - sub STRIDE_D, STRIDE_D, X, lsl #dst_bpp_shift - .if src_bpp > 0 - lsl STRIDE_S, #src_bpp_shift - sub STRIDE_S, STRIDE_S, X, lsl #src_bpp_shift - .endif - .if mask_bpp > 0 - lsl STRIDE_M, #mask_bpp_shift - sub STRIDE_M, STRIDE_M, X, lsl #mask_bpp_shift - .endif - - /* Are we not even wide enough to have one 16-byte aligned 16-byte block write? */ - cmp X, #2*16*8/dst_w_bpp - 1 - blo 170f - .if src_bpp || mask_bpp || dst_r_bpp /* Wide and medium cases are the same for fill */ - /* To preload ahead on the current line, we need at least (prefetch_distance+2) 32-byte blocks on all prefetch channels */ - cmp X, #(prefetch_distance+3)*pix_per_block - 1 - blo 160f - - /* Wide case */ - /* Adjust X so that the decrement instruction can also test for - * inner loop termination. We want it to stop when there are - * (prefetch_distance+1) complete blocks to go. */ - sub X, X, #(prefetch_distance+2)*pix_per_block - mov ORIG_W, X - .if (flags) & FLAG_SPILL_LINE_VARS_WIDE - /* This is stmdb sp!,{} */ - .word 0xE92D0000 | LINE_SAVED_REGS - .set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET + LINE_SAVED_REG_COUNT*4 - .set LOCALS_STACK_OFFSET, LOCALS_STACK_OFFSET + LINE_SAVED_REG_COUNT*4 - .endif -151: /* New line */ - newline - preload_leading_step1 src_bpp, WK1, SRC - preload_leading_step1 mask_bpp, WK2, MASK - .if ((flags) & FLAG_NO_PRELOAD_DST) == 0 - preload_leading_step1 dst_r_bpp, WK3, DST - .endif - - ands WK0, DST, #15 - beq 154f - rsb WK0, WK0, #16 /* number of leading bytes until destination aligned */ - - preload_leading_step2 src_bpp, src_bpp_shift, WK1, SRC - preload_leading_step2 mask_bpp, mask_bpp_shift, WK2, MASK - .if ((flags) & FLAG_NO_PRELOAD_DST) == 0 - preload_leading_step2 dst_r_bpp, dst_bpp_shift, WK3, DST - .endif - - leading_15bytes process_head, process_tail - -154: /* Destination now 16-byte aligned; we have at least one prefetch on each channel as well as at least one 16-byte output block */ - .if (src_bpp > 0) && (mask_bpp == 0) && ((flags) & FLAG_PROCESS_PRESERVES_SCRATCH) - and SCRATCH, SRC, #31 - rsb SCRATCH, SCRATCH, #32*prefetch_distance - .elseif (src_bpp == 0) && (mask_bpp > 0) && ((flags) & FLAG_PROCESS_PRESERVES_SCRATCH) - and SCRATCH, MASK, #31 - rsb SCRATCH, SCRATCH, #32*prefetch_distance - .endif - .ifc "process_inner_loop","" - switch_on_alignment wide_case_inner_loop_and_trailing_pixels, process_head, process_tail, wide_case_inner_loop, 157f - .else - switch_on_alignment wide_case_inner_loop_and_trailing_pixels, process_head, process_tail, process_inner_loop, 157f - .endif - -157: /* Check for another line */ - end_of_line 1, %((flags) & FLAG_SPILL_LINE_VARS_WIDE), 151b - .if (flags) & FLAG_SPILL_LINE_VARS_WIDE - .set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET - LINE_SAVED_REG_COUNT*4 - .set LOCALS_STACK_OFFSET, LOCALS_STACK_OFFSET - LINE_SAVED_REG_COUNT*4 - .endif - .endif - - .ltorg - -160: /* Medium case */ - mov ORIG_W, X - .if (flags) & FLAG_SPILL_LINE_VARS_NON_WIDE - /* This is stmdb sp!,{} */ - .word 0xE92D0000 | LINE_SAVED_REGS - .set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET + LINE_SAVED_REG_COUNT*4 - .set LOCALS_STACK_OFFSET, LOCALS_STACK_OFFSET + LINE_SAVED_REG_COUNT*4 - .endif -161: /* New line */ - newline - preload_line 0, src_bpp, src_bpp_shift, SRC /* in: X, corrupts: WK0-WK1 */ - preload_line 0, mask_bpp, mask_bpp_shift, MASK - .if ((flags) & FLAG_NO_PRELOAD_DST) == 0 - preload_line 0, dst_r_bpp, dst_bpp_shift, DST - .endif - - sub X, X, #128/dst_w_bpp /* simplifies inner loop termination */ - ands WK0, DST, #15 - beq 164f - rsb WK0, WK0, #16 /* number of leading bytes until destination aligned */ - - leading_15bytes process_head, process_tail - -164: /* Destination now 16-byte aligned; we have at least one 16-byte output block */ - switch_on_alignment medium_case_inner_loop_and_trailing_pixels, process_head, process_tail,, 167f - -167: /* Check for another line */ - end_of_line 1, %((flags) & FLAG_SPILL_LINE_VARS_NON_WIDE), 161b - - .ltorg - -170: /* Narrow case, less than 31 bytes, so no guarantee of at least one 16-byte block */ - .if dst_w_bpp < 32 - mov ORIG_W, X - .endif - .if (flags) & FLAG_SPILL_LINE_VARS_NON_WIDE - /* This is stmdb sp!,{} */ - .word 0xE92D0000 | LINE_SAVED_REGS - .endif -171: /* New line */ - newline - preload_line 1, src_bpp, src_bpp_shift, SRC /* in: X, corrupts: WK0-WK1 */ - preload_line 1, mask_bpp, mask_bpp_shift, MASK - .if ((flags) & FLAG_NO_PRELOAD_DST) == 0 - preload_line 1, dst_r_bpp, dst_bpp_shift, DST - .endif - - .if dst_w_bpp == 8 - tst DST, #3 - beq 174f -172: subs X, X, #1 - blo 177f - process_head , 1, 0, 1, 1, 0 - process_tail , 1, 0 - .if !((flags) & FLAG_PROCESS_DOES_STORE) - pixst , 1, 0, DST - .endif - tst DST, #3 - bne 172b - .elseif dst_w_bpp == 16 - tst DST, #2 - beq 174f - subs X, X, #1 - blo 177f - process_head , 2, 0, 1, 1, 0 - process_tail , 2, 0 - .if !((flags) & FLAG_PROCESS_DOES_STORE) - pixst , 2, 0, DST - .endif - .endif - -174: /* Destination now 4-byte aligned; we have 0 or more output bytes to go */ - switch_on_alignment narrow_case_inner_loop_and_trailing_pixels, process_head, process_tail,, 177f - -177: /* Check for another line */ - end_of_line %(dst_w_bpp < 32), %((flags) & FLAG_SPILL_LINE_VARS_NON_WIDE), 171b, last_one - .if (flags) & FLAG_SPILL_LINE_VARS_NON_WIDE - .set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET - LINE_SAVED_REG_COUNT*4 - .set LOCALS_STACK_OFFSET, LOCALS_STACK_OFFSET - LINE_SAVED_REG_COUNT*4 - .endif - -197: - .if (flags) & FLAG_SPILL_LINE_VARS - add sp, sp, #LINE_SAVED_REG_COUNT*4 - .endif -198: - .if (flags) & FLAG_PROCESS_CORRUPTS_WK0 - .set ARGS_STACK_OFFSET, ARGS_STACK_OFFSET-4 - .set LOCALS_STACK_OFFSET, LOCALS_STACK_OFFSET-4 - add sp, sp, #4 - .endif - - cleanup - -#ifdef DEBUG_PARAMS - add sp, sp, #9*4 /* junk the debug copy of arguments */ -#endif -199: - pop {r4-r11, pc} /* exit */ - - .ltorg - - .unreq X - .unreq Y - .unreq DST - .unreq STRIDE_D - .unreq SRC - .unreq STRIDE_S - .unreq MASK - .unreq STRIDE_M - .unreq WK0 - .unreq WK1 - .unreq WK2 - .unreq WK3 - .unreq SCRATCH - .unreq ORIG_W - .endfunc -.endm - -.macro line_saved_regs x:vararg - .set LINE_SAVED_REGS, 0 - .set LINE_SAVED_REG_COUNT, 0 - .irp SAVED_REG,x - .ifc "SAVED_REG","Y" - .set LINE_SAVED_REGS, LINE_SAVED_REGS | (1<<1) - .set LINE_SAVED_REG_COUNT, LINE_SAVED_REG_COUNT + 1 - .endif - .ifc "SAVED_REG","STRIDE_D" - .set LINE_SAVED_REGS, LINE_SAVED_REGS | (1<<3) - .set LINE_SAVED_REG_COUNT, LINE_SAVED_REG_COUNT + 1 - .endif - .ifc "SAVED_REG","STRIDE_S" - .set LINE_SAVED_REGS, LINE_SAVED_REGS | (1<<5) - .set LINE_SAVED_REG_COUNT, LINE_SAVED_REG_COUNT + 1 - .endif - .ifc "SAVED_REG","STRIDE_M" - .set LINE_SAVED_REGS, LINE_SAVED_REGS | (1<<7) - .set LINE_SAVED_REG_COUNT, LINE_SAVED_REG_COUNT + 1 - .endif - .ifc "SAVED_REG","ORIG_W" - .set LINE_SAVED_REGS, LINE_SAVED_REGS | (1<<14) - .set LINE_SAVED_REG_COUNT, LINE_SAVED_REG_COUNT + 1 - .endif - .endr -.endm - -.macro nop_macro x:vararg -.endm diff --git a/source/libs/pixman/pixman-src/pixman/pixman-arm-simd.c b/source/libs/pixman/pixman-src/pixman/pixman-arm-simd.c deleted file mode 100644 index f0d14540bcf098faa520acf27358709d6c46f7e0..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-arm-simd.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright © 2008 Mozilla Corporation - * - * 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 Mozilla Corporation not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Mozilla Corporation makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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: Jeff Muizelaar (jeff@infidigm.net) - * - */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "pixman-private.h" -#include "pixman-arm-common.h" -#include "pixman-inlines.h" - -PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_8888_8888, - uint32_t, 1, uint32_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_x888_8888, - uint32_t, 1, uint32_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_0565_0565, - uint16_t, 1, uint16_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_8_8, - uint8_t, 1, uint8_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_0565_8888, - uint16_t, 1, uint32_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, src_x888_0565, - uint32_t, 1, uint16_t, 1) - -PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, add_8_8, - uint8_t, 1, uint8_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, over_8888_8888, - uint32_t, 1, uint32_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (armv6, in_reverse_8888_8888, - uint32_t, 1, uint32_t, 1) - -PIXMAN_ARM_BIND_FAST_PATH_N_DST (SKIP_ZERO_SRC, armv6, over_n_8888, - uint32_t, 1) -PIXMAN_ARM_BIND_FAST_PATH_N_DST (0, armv6, over_reverse_n_8888, - uint32_t, 1) - -PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, armv6, over_8888_n_8888, - uint32_t, 1, uint32_t, 1) - -PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, armv6, over_n_8_8888, - uint8_t, 1, uint32_t, 1) - -PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, armv6, over_n_8888_8888_ca, - uint32_t, 1, uint32_t, 1) - -PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (armv6, 0565_0565, SRC, - uint16_t, uint16_t) -PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (armv6, 8888_8888, SRC, - uint32_t, uint32_t) - -void -pixman_composite_src_n_8888_asm_armv6 (int32_t w, - int32_t h, - uint32_t *dst, - int32_t dst_stride, - uint32_t src); - -void -pixman_composite_src_n_0565_asm_armv6 (int32_t w, - int32_t h, - uint16_t *dst, - int32_t dst_stride, - uint16_t src); - -void -pixman_composite_src_n_8_asm_armv6 (int32_t w, - int32_t h, - uint8_t *dst, - int32_t dst_stride, - uint8_t src); - -static pixman_bool_t -arm_simd_fill (pixman_implementation_t *imp, - uint32_t * bits, - int stride, /* in 32-bit words */ - int bpp, - int x, - int y, - int width, - int height, - uint32_t _xor) -{ - /* stride is always multiple of 32bit units in pixman */ - uint32_t byte_stride = stride * sizeof(uint32_t); - - switch (bpp) - { - case 8: - pixman_composite_src_n_8_asm_armv6 ( - width, - height, - (uint8_t *)(((char *) bits) + y * byte_stride + x), - byte_stride, - _xor & 0xff); - return TRUE; - case 16: - pixman_composite_src_n_0565_asm_armv6 ( - width, - height, - (uint16_t *)(((char *) bits) + y * byte_stride + x * 2), - byte_stride / 2, - _xor & 0xffff); - return TRUE; - case 32: - pixman_composite_src_n_8888_asm_armv6 ( - width, - height, - (uint32_t *)(((char *) bits) + y * byte_stride + x * 4), - byte_stride / 4, - _xor); - return TRUE; - default: - return FALSE; - } -} - -static pixman_bool_t -arm_simd_blt (pixman_implementation_t *imp, - uint32_t * src_bits, - uint32_t * dst_bits, - int src_stride, /* in 32-bit words */ - int dst_stride, /* in 32-bit words */ - int src_bpp, - int dst_bpp, - int src_x, - int src_y, - int dest_x, - int dest_y, - int width, - int height) -{ - if (src_bpp != dst_bpp) - return FALSE; - - switch (src_bpp) - { - case 8: - pixman_composite_src_8_8_asm_armv6 ( - width, height, - (uint8_t *)(((char *) dst_bits) + - dest_y * dst_stride * 4 + dest_x * 1), dst_stride * 4, - (uint8_t *)(((char *) src_bits) + - src_y * src_stride * 4 + src_x * 1), src_stride * 4); - return TRUE; - case 16: - pixman_composite_src_0565_0565_asm_armv6 ( - width, height, - (uint16_t *)(((char *) dst_bits) + - dest_y * dst_stride * 4 + dest_x * 2), dst_stride * 2, - (uint16_t *)(((char *) src_bits) + - src_y * src_stride * 4 + src_x * 2), src_stride * 2); - return TRUE; - case 32: - pixman_composite_src_8888_8888_asm_armv6 ( - width, height, - (uint32_t *)(((char *) dst_bits) + - dest_y * dst_stride * 4 + dest_x * 4), dst_stride, - (uint32_t *)(((char *) src_bits) + - src_y * src_stride * 4 + src_x * 4), src_stride); - return TRUE; - default: - return FALSE; - } -} - -static const pixman_fast_path_t arm_simd_fast_paths[] = -{ - PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, a8r8g8b8, armv6_composite_src_8888_8888), - PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, a8b8g8r8, armv6_composite_src_8888_8888), - PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, armv6_composite_src_8888_8888), - PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, armv6_composite_src_8888_8888), - PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, armv6_composite_src_8888_8888), - PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, armv6_composite_src_8888_8888), - - PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, a8b8g8r8, armv6_composite_src_x888_8888), - PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, a8r8g8b8, armv6_composite_src_x888_8888), - - PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, r5g6b5, armv6_composite_src_0565_0565), - PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, b5g6r5, armv6_composite_src_0565_0565), - PIXMAN_STD_FAST_PATH (SRC, a1r5g5b5, null, a1r5g5b5, armv6_composite_src_0565_0565), - PIXMAN_STD_FAST_PATH (SRC, a1b5g5r5, null, a1b5g5r5, armv6_composite_src_0565_0565), - PIXMAN_STD_FAST_PATH (SRC, a1r5g5b5, null, x1r5g5b5, armv6_composite_src_0565_0565), - PIXMAN_STD_FAST_PATH (SRC, a1b5g5r5, null, x1b5g5r5, armv6_composite_src_0565_0565), - PIXMAN_STD_FAST_PATH (SRC, x1r5g5b5, null, x1r5g5b5, armv6_composite_src_0565_0565), - PIXMAN_STD_FAST_PATH (SRC, x1b5g5r5, null, x1b5g5r5, armv6_composite_src_0565_0565), - PIXMAN_STD_FAST_PATH (SRC, a4r4g4b4, null, a4r4g4b4, armv6_composite_src_0565_0565), - PIXMAN_STD_FAST_PATH (SRC, a4b4g4r4, null, a4b4g4r4, armv6_composite_src_0565_0565), - PIXMAN_STD_FAST_PATH (SRC, a4r4g4b4, null, x4r4g4b4, armv6_composite_src_0565_0565), - PIXMAN_STD_FAST_PATH (SRC, a4b4g4r4, null, x4b4g4r4, armv6_composite_src_0565_0565), - PIXMAN_STD_FAST_PATH (SRC, x4r4g4b4, null, x4r4g4b4, armv6_composite_src_0565_0565), - PIXMAN_STD_FAST_PATH (SRC, x4b4g4r4, null, x4b4g4r4, armv6_composite_src_0565_0565), - - PIXMAN_STD_FAST_PATH (SRC, a8, null, a8, armv6_composite_src_8_8), - PIXMAN_STD_FAST_PATH (SRC, r3g3b2, null, r3g3b2, armv6_composite_src_8_8), - PIXMAN_STD_FAST_PATH (SRC, b2g3r3, null, b2g3r3, armv6_composite_src_8_8), - PIXMAN_STD_FAST_PATH (SRC, a2r2g2b2, null, a2r2g2b2, armv6_composite_src_8_8), - PIXMAN_STD_FAST_PATH (SRC, a2b2g2r2, null, a2b2g2r2, armv6_composite_src_8_8), - PIXMAN_STD_FAST_PATH (SRC, c8, null, c8, armv6_composite_src_8_8), - PIXMAN_STD_FAST_PATH (SRC, g8, null, g8, armv6_composite_src_8_8), - PIXMAN_STD_FAST_PATH (SRC, x4a4, null, x4a4, armv6_composite_src_8_8), - PIXMAN_STD_FAST_PATH (SRC, x4c4, null, x4c4, armv6_composite_src_8_8), - PIXMAN_STD_FAST_PATH (SRC, x4g4, null, x4g4, armv6_composite_src_8_8), - - PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, a8r8g8b8, armv6_composite_src_0565_8888), - PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, x8r8g8b8, armv6_composite_src_0565_8888), - PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, a8b8g8r8, armv6_composite_src_0565_8888), - PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, x8b8g8r8, armv6_composite_src_0565_8888), - - PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, r5g6b5, armv6_composite_src_x888_0565), - PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, r5g6b5, armv6_composite_src_x888_0565), - PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, b5g6r5, armv6_composite_src_x888_0565), - PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, b5g6r5, armv6_composite_src_x888_0565), - - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, armv6_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, armv6_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, armv6_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, armv6_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, a8r8g8b8, armv6_composite_over_8888_n_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, x8r8g8b8, armv6_composite_over_8888_n_8888), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, a8b8g8r8, armv6_composite_over_8888_n_8888), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, x8b8g8r8, armv6_composite_over_8888_n_8888), - - PIXMAN_STD_FAST_PATH (OVER, solid, null, a8r8g8b8, armv6_composite_over_n_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, null, x8r8g8b8, armv6_composite_over_n_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, null, a8b8g8r8, armv6_composite_over_n_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, null, x8b8g8r8, armv6_composite_over_n_8888), - PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8r8g8b8, armv6_composite_over_reverse_n_8888), - PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8b8g8r8, armv6_composite_over_reverse_n_8888), - - PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, armv6_composite_add_8_8), - - PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, armv6_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, armv6_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, armv6_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, armv6_composite_over_n_8_8888), - - PIXMAN_STD_FAST_PATH (IN_REVERSE, a8r8g8b8, null, a8r8g8b8, armv6_composite_in_reverse_8888_8888), - PIXMAN_STD_FAST_PATH (IN_REVERSE, a8r8g8b8, null, x8r8g8b8, armv6_composite_in_reverse_8888_8888), - PIXMAN_STD_FAST_PATH (IN_REVERSE, a8b8g8r8, null, a8b8g8r8, armv6_composite_in_reverse_8888_8888), - PIXMAN_STD_FAST_PATH (IN_REVERSE, a8b8g8r8, null, x8b8g8r8, armv6_composite_in_reverse_8888_8888), - - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, a8r8g8b8, armv6_composite_over_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, armv6_composite_over_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, armv6_composite_over_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, armv6_composite_over_n_8888_8888_ca), - - SIMPLE_NEAREST_FAST_PATH (SRC, r5g6b5, r5g6b5, armv6_0565_0565), - SIMPLE_NEAREST_FAST_PATH (SRC, b5g6r5, b5g6r5, armv6_0565_0565), - - SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, armv6_8888_8888), - SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, armv6_8888_8888), - SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, armv6_8888_8888), - SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, a8b8g8r8, armv6_8888_8888), - SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, x8b8g8r8, armv6_8888_8888), - SIMPLE_NEAREST_FAST_PATH (SRC, x8b8g8r8, x8b8g8r8, armv6_8888_8888), - - { PIXMAN_OP_NONE }, -}; - -pixman_implementation_t * -_pixman_implementation_create_arm_simd (pixman_implementation_t *fallback) -{ - pixman_implementation_t *imp = _pixman_implementation_create (fallback, arm_simd_fast_paths); - - imp->blt = arm_simd_blt; - imp->fill = arm_simd_fill; - - return imp; -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman-arm.c b/source/libs/pixman/pixman-src/pixman/pixman-arm.c deleted file mode 100644 index 23374e41cbbb26b9d3d2b4088d10d643b5c83fc2..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-arm.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright © 2000 SuSE, Inc. - * Copyright © 2007 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 SuSE not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. SuSE makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE - * 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. - */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "pixman-private.h" - -typedef enum -{ - ARM_V7 = (1 << 0), - ARM_V6 = (1 << 1), - ARM_VFP = (1 << 2), - ARM_NEON = (1 << 3), - ARM_IWMMXT = (1 << 4) -} arm_cpu_features_t; - -#if defined(USE_ARM_SIMD) || defined(USE_ARM_NEON) || defined(USE_ARM_IWMMXT) - -#if defined(_MSC_VER) - -/* Needed for EXCEPTION_ILLEGAL_INSTRUCTION */ -#include <windows.h> - -extern int pixman_msvc_try_arm_neon_op (); -extern int pixman_msvc_try_arm_simd_op (); - -static arm_cpu_features_t -detect_cpu_features (void) -{ - arm_cpu_features_t features = 0; - - __try - { - pixman_msvc_try_arm_simd_op (); - features |= ARM_V6; - } - __except (GetExceptionCode () == EXCEPTION_ILLEGAL_INSTRUCTION) - { - } - - __try - { - pixman_msvc_try_arm_neon_op (); - features |= ARM_NEON; - } - __except (GetExceptionCode () == EXCEPTION_ILLEGAL_INSTRUCTION) - { - } - - return features; -} - -#elif defined(__APPLE__) && defined(TARGET_OS_IPHONE) /* iOS */ - -#include "TargetConditionals.h" - -static arm_cpu_features_t -detect_cpu_features (void) -{ - arm_cpu_features_t features = 0; - - features |= ARM_V6; - - /* Detection of ARM NEON on iOS is fairly simple because iOS binaries - * contain separate executable images for each processor architecture. - * So all we have to do is detect the armv7 architecture build. The - * operating system automatically runs the armv7 binary for armv7 devices - * and the armv6 binary for armv6 devices. - */ -#if defined(__ARM_NEON__) - features |= ARM_NEON; -#endif - - return features; -} - -#elif defined(__ANDROID__) || defined(ANDROID) /* Android */ - -#include <cpu-features.h> - -static arm_cpu_features_t -detect_cpu_features (void) -{ - arm_cpu_features_t features = 0; - AndroidCpuFamily cpu_family; - uint64_t cpu_features; - - cpu_family = android_getCpuFamily(); - cpu_features = android_getCpuFeatures(); - - if (cpu_family == ANDROID_CPU_FAMILY_ARM) - { - if (cpu_features & ANDROID_CPU_ARM_FEATURE_ARMv7) - features |= ARM_V7; - - if (cpu_features & ANDROID_CPU_ARM_FEATURE_VFPv3) - features |= ARM_VFP; - - if (cpu_features & ANDROID_CPU_ARM_FEATURE_NEON) - features |= ARM_NEON; - } - - return features; -} - -#elif defined (__linux__) /* linux ELF */ - -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/mman.h> -#include <fcntl.h> -#include <string.h> -#include <elf.h> - -static arm_cpu_features_t -detect_cpu_features (void) -{ - arm_cpu_features_t features = 0; - Elf32_auxv_t aux; - int fd; - - fd = open ("/proc/self/auxv", O_RDONLY); - if (fd >= 0) - { - while (read (fd, &aux, sizeof(Elf32_auxv_t)) == sizeof(Elf32_auxv_t)) - { - if (aux.a_type == AT_HWCAP) - { - uint32_t hwcap = aux.a_un.a_val; - - /* hardcode these values to avoid depending on specific - * versions of the hwcap header, e.g. HWCAP_NEON - */ - if ((hwcap & 64) != 0) - features |= ARM_VFP; - if ((hwcap & 512) != 0) - features |= ARM_IWMMXT; - /* this flag is only present on kernel 2.6.29 */ - if ((hwcap & 4096) != 0) - features |= ARM_NEON; - } - else if (aux.a_type == AT_PLATFORM) - { - const char *plat = (const char*) aux.a_un.a_val; - - if (strncmp (plat, "v7l", 3) == 0) - features |= (ARM_V7 | ARM_V6); - else if (strncmp (plat, "v6l", 3) == 0) - features |= ARM_V6; - } - } - close (fd); - } - - return features; -} - -#else /* Unknown */ - -static arm_cpu_features_t -detect_cpu_features (void) -{ - return 0; -} - -#endif /* Linux elf */ - -static pixman_bool_t -have_feature (arm_cpu_features_t feature) -{ - static pixman_bool_t initialized; - static arm_cpu_features_t features; - - if (!initialized) - { - features = detect_cpu_features(); - initialized = TRUE; - } - - return (features & feature) == feature; -} - -#endif /* USE_ARM_SIMD || USE_ARM_NEON || USE_ARM_IWMMXT */ - -pixman_implementation_t * -_pixman_arm_get_implementations (pixman_implementation_t *imp) -{ -#ifdef USE_ARM_SIMD - if (!_pixman_disabled ("arm-simd") && have_feature (ARM_V6)) - imp = _pixman_implementation_create_arm_simd (imp); -#endif - -#ifdef USE_ARM_IWMMXT - if (!_pixman_disabled ("arm-iwmmxt") && have_feature (ARM_IWMMXT)) - imp = _pixman_implementation_create_mmx (imp); -#endif - -#ifdef USE_ARM_NEON - if (!_pixman_disabled ("arm-neon") && have_feature (ARM_NEON)) - imp = _pixman_implementation_create_arm_neon (imp); -#endif - - return imp; -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman-bits-image.c b/source/libs/pixman/pixman-src/pixman/pixman-bits-image.c deleted file mode 100644 index dcdcc69946dede2bb9967bfa81edb481a1e965ad..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-bits-image.c +++ /dev/null @@ -1,1039 +0,0 @@ -/* - * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. - * 2005 Lars Knoll & Zack Rusin, Trolltech - * 2008 Aaron Plattner, NVIDIA Corporation - * Copyright © 2000 SuSE, Inc. - * Copyright © 2007, 2009 Red Hat, Inc. - * Copyright © 2008 André Tupinambá <andrelrt@gmail.com> - * - * 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 Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "pixman-private.h" -#include "pixman-combine32.h" -#include "pixman-inlines.h" - -static uint32_t * -_pixman_image_get_scanline_generic_float (pixman_iter_t * iter, - const uint32_t *mask) -{ - pixman_iter_get_scanline_t fetch_32 = iter->data; - uint32_t *buffer = iter->buffer; - - fetch_32 (iter, NULL); - - pixman_expand_to_float ((argb_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); - - return iter->buffer; -} - -/* Fetch functions */ - -static force_inline uint32_t -fetch_pixel_no_alpha (bits_image_t *image, - int x, int y, pixman_bool_t check_bounds) -{ - if (check_bounds && - (x < 0 || x >= image->width || y < 0 || y >= image->height)) - { - return 0; - } - - return image->fetch_pixel_32 (image, x, y); -} - -typedef uint32_t (* get_pixel_t) (bits_image_t *image, - int x, int y, pixman_bool_t check_bounds); - -static force_inline uint32_t -bits_image_fetch_pixel_nearest (bits_image_t *image, - pixman_fixed_t x, - pixman_fixed_t y, - get_pixel_t get_pixel) -{ - int x0 = pixman_fixed_to_int (x - pixman_fixed_e); - int y0 = pixman_fixed_to_int (y - pixman_fixed_e); - - if (image->common.repeat != PIXMAN_REPEAT_NONE) - { - repeat (image->common.repeat, &x0, image->width); - repeat (image->common.repeat, &y0, image->height); - - return get_pixel (image, x0, y0, FALSE); - } - else - { - return get_pixel (image, x0, y0, TRUE); - } -} - -static force_inline uint32_t -bits_image_fetch_pixel_bilinear (bits_image_t *image, - pixman_fixed_t x, - pixman_fixed_t y, - get_pixel_t get_pixel) -{ - pixman_repeat_t repeat_mode = image->common.repeat; - int width = image->width; - int height = image->height; - int x1, y1, x2, y2; - uint32_t tl, tr, bl, br; - int32_t distx, disty; - - x1 = x - pixman_fixed_1 / 2; - y1 = y - pixman_fixed_1 / 2; - - distx = pixman_fixed_to_bilinear_weight (x1); - disty = pixman_fixed_to_bilinear_weight (y1); - - x1 = pixman_fixed_to_int (x1); - y1 = pixman_fixed_to_int (y1); - x2 = x1 + 1; - y2 = y1 + 1; - - if (repeat_mode != PIXMAN_REPEAT_NONE) - { - repeat (repeat_mode, &x1, width); - repeat (repeat_mode, &y1, height); - repeat (repeat_mode, &x2, width); - repeat (repeat_mode, &y2, height); - - tl = get_pixel (image, x1, y1, FALSE); - bl = get_pixel (image, x1, y2, FALSE); - tr = get_pixel (image, x2, y1, FALSE); - br = get_pixel (image, x2, y2, FALSE); - } - else - { - tl = get_pixel (image, x1, y1, TRUE); - tr = get_pixel (image, x2, y1, TRUE); - bl = get_pixel (image, x1, y2, TRUE); - br = get_pixel (image, x2, y2, TRUE); - } - - return bilinear_interpolation (tl, tr, bl, br, distx, disty); -} - -static force_inline uint32_t -bits_image_fetch_pixel_convolution (bits_image_t *image, - pixman_fixed_t x, - pixman_fixed_t y, - get_pixel_t get_pixel) -{ - pixman_fixed_t *params = image->common.filter_params; - int x_off = (params[0] - pixman_fixed_1) >> 1; - int y_off = (params[1] - pixman_fixed_1) >> 1; - int32_t cwidth = pixman_fixed_to_int (params[0]); - int32_t cheight = pixman_fixed_to_int (params[1]); - int32_t i, j, x1, x2, y1, y2; - pixman_repeat_t repeat_mode = image->common.repeat; - int width = image->width; - int height = image->height; - int srtot, sgtot, sbtot, satot; - - params += 2; - - x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off); - y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off); - x2 = x1 + cwidth; - y2 = y1 + cheight; - - srtot = sgtot = sbtot = satot = 0; - - for (i = y1; i < y2; ++i) - { - for (j = x1; j < x2; ++j) - { - int rx = j; - int ry = i; - - pixman_fixed_t f = *params; - - if (f) - { - uint32_t pixel; - - if (repeat_mode != PIXMAN_REPEAT_NONE) - { - repeat (repeat_mode, &rx, width); - repeat (repeat_mode, &ry, height); - - pixel = get_pixel (image, rx, ry, FALSE); - } - else - { - pixel = get_pixel (image, rx, ry, TRUE); - } - - srtot += (int)RED_8 (pixel) * f; - sgtot += (int)GREEN_8 (pixel) * f; - sbtot += (int)BLUE_8 (pixel) * f; - satot += (int)ALPHA_8 (pixel) * f; - } - - params++; - } - } - - satot = (satot + 0x8000) >> 16; - srtot = (srtot + 0x8000) >> 16; - sgtot = (sgtot + 0x8000) >> 16; - sbtot = (sbtot + 0x8000) >> 16; - - satot = CLIP (satot, 0, 0xff); - srtot = CLIP (srtot, 0, 0xff); - sgtot = CLIP (sgtot, 0, 0xff); - sbtot = CLIP (sbtot, 0, 0xff); - - return ((satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot)); -} - -static uint32_t -bits_image_fetch_pixel_separable_convolution (bits_image_t *image, - pixman_fixed_t x, - pixman_fixed_t y, - get_pixel_t get_pixel) -{ - pixman_fixed_t *params = image->common.filter_params; - pixman_repeat_t repeat_mode = image->common.repeat; - int width = image->width; - int height = image->height; - int cwidth = pixman_fixed_to_int (params[0]); - int cheight = pixman_fixed_to_int (params[1]); - int x_phase_bits = pixman_fixed_to_int (params[2]); - int y_phase_bits = pixman_fixed_to_int (params[3]); - int x_phase_shift = 16 - x_phase_bits; - int y_phase_shift = 16 - y_phase_bits; - int x_off = ((cwidth << 16) - pixman_fixed_1) >> 1; - int y_off = ((cheight << 16) - pixman_fixed_1) >> 1; - pixman_fixed_t *y_params; - int srtot, sgtot, sbtot, satot; - int32_t x1, x2, y1, y2; - int32_t px, py; - int i, j; - - /* Round x and y to the middle of the closest phase before continuing. This - * ensures that the convolution matrix is aligned right, since it was - * positioned relative to a particular phase (and not relative to whatever - * exact fraction we happen to get here). - */ - x = ((x >> x_phase_shift) << x_phase_shift) + ((1 << x_phase_shift) >> 1); - y = ((y >> y_phase_shift) << y_phase_shift) + ((1 << y_phase_shift) >> 1); - - px = (x & 0xffff) >> x_phase_shift; - py = (y & 0xffff) >> y_phase_shift; - - y_params = params + 4 + (1 << x_phase_bits) * cwidth + py * cheight; - - x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off); - y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off); - x2 = x1 + cwidth; - y2 = y1 + cheight; - - srtot = sgtot = sbtot = satot = 0; - - for (i = y1; i < y2; ++i) - { - pixman_fixed_48_16_t fy = *y_params++; - pixman_fixed_t *x_params = params + 4 + px * cwidth; - - if (fy) - { - for (j = x1; j < x2; ++j) - { - pixman_fixed_t fx = *x_params++; - int rx = j; - int ry = i; - - if (fx) - { - pixman_fixed_t f; - uint32_t pixel; - - if (repeat_mode != PIXMAN_REPEAT_NONE) - { - repeat (repeat_mode, &rx, width); - repeat (repeat_mode, &ry, height); - - pixel = get_pixel (image, rx, ry, FALSE); - } - else - { - pixel = get_pixel (image, rx, ry, TRUE); - } - - f = (fy * fx + 0x8000) >> 16; - - srtot += (int)RED_8 (pixel) * f; - sgtot += (int)GREEN_8 (pixel) * f; - sbtot += (int)BLUE_8 (pixel) * f; - satot += (int)ALPHA_8 (pixel) * f; - } - } - } - } - - satot = (satot + 0x8000) >> 16; - srtot = (srtot + 0x8000) >> 16; - sgtot = (sgtot + 0x8000) >> 16; - sbtot = (sbtot + 0x8000) >> 16; - - satot = CLIP (satot, 0, 0xff); - srtot = CLIP (srtot, 0, 0xff); - sgtot = CLIP (sgtot, 0, 0xff); - sbtot = CLIP (sbtot, 0, 0xff); - - return ((satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot)); -} - -static force_inline uint32_t -bits_image_fetch_pixel_filtered (bits_image_t *image, - pixman_fixed_t x, - pixman_fixed_t y, - get_pixel_t get_pixel) -{ - switch (image->common.filter) - { - case PIXMAN_FILTER_NEAREST: - case PIXMAN_FILTER_FAST: - return bits_image_fetch_pixel_nearest (image, x, y, get_pixel); - break; - - case PIXMAN_FILTER_BILINEAR: - case PIXMAN_FILTER_GOOD: - case PIXMAN_FILTER_BEST: - return bits_image_fetch_pixel_bilinear (image, x, y, get_pixel); - break; - - case PIXMAN_FILTER_CONVOLUTION: - return bits_image_fetch_pixel_convolution (image, x, y, get_pixel); - break; - - case PIXMAN_FILTER_SEPARABLE_CONVOLUTION: - return bits_image_fetch_pixel_separable_convolution (image, x, y, get_pixel); - break; - - default: - break; - } - - return 0; -} - -static uint32_t * -bits_image_fetch_affine_no_alpha (pixman_iter_t * iter, - const uint32_t * mask) -{ - pixman_image_t *image = iter->image; - int offset = iter->x; - int line = iter->y++; - int width = iter->width; - uint32_t * buffer = iter->buffer; - - pixman_fixed_t x, y; - pixman_fixed_t ux, uy; - pixman_vector_t v; - int i; - - /* reference point is the center of the pixel */ - v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2; - v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2; - v.vector[2] = pixman_fixed_1; - - if (image->common.transform) - { - if (!pixman_transform_point_3d (image->common.transform, &v)) - return iter->buffer; - - ux = image->common.transform->matrix[0][0]; - uy = image->common.transform->matrix[1][0]; - } - else - { - ux = pixman_fixed_1; - uy = 0; - } - - x = v.vector[0]; - y = v.vector[1]; - - for (i = 0; i < width; ++i) - { - if (!mask || mask[i]) - { - buffer[i] = bits_image_fetch_pixel_filtered ( - &image->bits, x, y, fetch_pixel_no_alpha); - } - - x += ux; - y += uy; - } - - return buffer; -} - -/* General fetcher */ -static force_inline uint32_t -fetch_pixel_general (bits_image_t *image, int x, int y, pixman_bool_t check_bounds) -{ - uint32_t pixel; - - if (check_bounds && - (x < 0 || x >= image->width || y < 0 || y >= image->height)) - { - return 0; - } - - pixel = image->fetch_pixel_32 (image, x, y); - - if (image->common.alpha_map) - { - uint32_t pixel_a; - - x -= image->common.alpha_origin_x; - y -= image->common.alpha_origin_y; - - if (x < 0 || x >= image->common.alpha_map->width || - y < 0 || y >= image->common.alpha_map->height) - { - pixel_a = 0; - } - else - { - pixel_a = image->common.alpha_map->fetch_pixel_32 ( - image->common.alpha_map, x, y); - - pixel_a = ALPHA_8 (pixel_a); - } - - pixel &= 0x00ffffff; - pixel |= (pixel_a << 24); - } - - return pixel; -} - -static uint32_t * -bits_image_fetch_general (pixman_iter_t *iter, - const uint32_t *mask) -{ - pixman_image_t *image = iter->image; - int offset = iter->x; - int line = iter->y++; - int width = iter->width; - uint32_t * buffer = iter->buffer; - - pixman_fixed_t x, y, w; - pixman_fixed_t ux, uy, uw; - pixman_vector_t v; - int i; - - /* reference point is the center of the pixel */ - v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2; - v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2; - v.vector[2] = pixman_fixed_1; - - if (image->common.transform) - { - if (!pixman_transform_point_3d (image->common.transform, &v)) - return buffer; - - ux = image->common.transform->matrix[0][0]; - uy = image->common.transform->matrix[1][0]; - uw = image->common.transform->matrix[2][0]; - } - else - { - ux = pixman_fixed_1; - uy = 0; - uw = 0; - } - - x = v.vector[0]; - y = v.vector[1]; - w = v.vector[2]; - - for (i = 0; i < width; ++i) - { - pixman_fixed_t x0, y0; - - if (!mask || mask[i]) - { - if (w != 0) - { - x0 = ((pixman_fixed_48_16_t)x << 16) / w; - y0 = ((pixman_fixed_48_16_t)y << 16) / w; - } - else - { - x0 = 0; - y0 = 0; - } - - buffer[i] = bits_image_fetch_pixel_filtered ( - &image->bits, x0, y0, fetch_pixel_general); - } - - x += ux; - y += uy; - w += uw; - } - - return buffer; -} - -static void -replicate_pixel_32 (bits_image_t * bits, - int x, - int y, - int width, - uint32_t * buffer) -{ - uint32_t color; - uint32_t *end; - - color = bits->fetch_pixel_32 (bits, x, y); - - end = buffer + width; - while (buffer < end) - *(buffer++) = color; -} - -static void -replicate_pixel_float (bits_image_t * bits, - int x, - int y, - int width, - uint32_t * b) -{ - argb_t color; - argb_t *buffer = (argb_t *)b; - argb_t *end; - - color = bits->fetch_pixel_float (bits, x, y); - - end = buffer + width; - while (buffer < end) - *(buffer++) = color; -} - -static void -bits_image_fetch_untransformed_repeat_none (bits_image_t *image, - pixman_bool_t wide, - int x, - int y, - int width, - uint32_t * buffer) -{ - uint32_t w; - - if (y < 0 || y >= image->height) - { - memset (buffer, 0, width * (wide? sizeof (argb_t) : 4)); - return; - } - - if (x < 0) - { - w = MIN (width, -x); - - memset (buffer, 0, w * (wide ? sizeof (argb_t) : 4)); - - width -= w; - buffer += w * (wide? 4 : 1); - x += w; - } - - if (x < image->width) - { - w = MIN (width, image->width - x); - - if (wide) - image->fetch_scanline_float (image, x, y, w, buffer, NULL); - else - image->fetch_scanline_32 (image, x, y, w, buffer, NULL); - - width -= w; - buffer += w * (wide? 4 : 1); - x += w; - } - - memset (buffer, 0, width * (wide ? sizeof (argb_t) : 4)); -} - -static void -bits_image_fetch_untransformed_repeat_normal (bits_image_t *image, - pixman_bool_t wide, - int x, - int y, - int width, - uint32_t * buffer) -{ - uint32_t w; - - while (y < 0) - y += image->height; - - while (y >= image->height) - y -= image->height; - - if (image->width == 1) - { - if (wide) - replicate_pixel_float (image, 0, y, width, buffer); - else - replicate_pixel_32 (image, 0, y, width, buffer); - - return; - } - - while (width) - { - while (x < 0) - x += image->width; - while (x >= image->width) - x -= image->width; - - w = MIN (width, image->width - x); - - if (wide) - image->fetch_scanline_float (image, x, y, w, buffer, NULL); - else - image->fetch_scanline_32 (image, x, y, w, buffer, NULL); - - buffer += w * (wide? 4 : 1); - x += w; - width -= w; - } -} - -static uint32_t * -bits_image_fetch_untransformed_32 (pixman_iter_t * iter, - const uint32_t *mask) -{ - pixman_image_t *image = iter->image; - int x = iter->x; - int y = iter->y; - int width = iter->width; - uint32_t * buffer = iter->buffer; - - if (image->common.repeat == PIXMAN_REPEAT_NONE) - { - bits_image_fetch_untransformed_repeat_none ( - &image->bits, FALSE, x, y, width, buffer); - } - else - { - bits_image_fetch_untransformed_repeat_normal ( - &image->bits, FALSE, x, y, width, buffer); - } - - iter->y++; - return buffer; -} - -static uint32_t * -bits_image_fetch_untransformed_float (pixman_iter_t * iter, - const uint32_t *mask) -{ - pixman_image_t *image = iter->image; - int x = iter->x; - int y = iter->y; - int width = iter->width; - uint32_t * buffer = iter->buffer; - - if (image->common.repeat == PIXMAN_REPEAT_NONE) - { - bits_image_fetch_untransformed_repeat_none ( - &image->bits, TRUE, x, y, width, buffer); - } - else - { - bits_image_fetch_untransformed_repeat_normal ( - &image->bits, TRUE, x, y, width, buffer); - } - - iter->y++; - return buffer; -} - -typedef struct -{ - pixman_format_code_t format; - uint32_t flags; - pixman_iter_get_scanline_t get_scanline_32; - pixman_iter_get_scanline_t get_scanline_float; -} fetcher_info_t; - -static const fetcher_info_t fetcher_info[] = -{ - { PIXMAN_any, - (FAST_PATH_NO_ALPHA_MAP | - FAST_PATH_ID_TRANSFORM | - FAST_PATH_NO_CONVOLUTION_FILTER | - FAST_PATH_NO_PAD_REPEAT | - FAST_PATH_NO_REFLECT_REPEAT), - bits_image_fetch_untransformed_32, - bits_image_fetch_untransformed_float - }, - - /* Affine, no alpha */ - { PIXMAN_any, - (FAST_PATH_NO_ALPHA_MAP | FAST_PATH_HAS_TRANSFORM | FAST_PATH_AFFINE_TRANSFORM), - bits_image_fetch_affine_no_alpha, - _pixman_image_get_scanline_generic_float - }, - - /* General */ - { PIXMAN_any, - 0, - bits_image_fetch_general, - _pixman_image_get_scanline_generic_float - }, - - { PIXMAN_null }, -}; - -static void -bits_image_property_changed (pixman_image_t *image) -{ - _pixman_bits_image_setup_accessors (&image->bits); -} - -void -_pixman_bits_image_src_iter_init (pixman_image_t *image, pixman_iter_t *iter) -{ - pixman_format_code_t format = image->common.extended_format_code; - uint32_t flags = image->common.flags; - const fetcher_info_t *info; - - for (info = fetcher_info; info->format != PIXMAN_null; ++info) - { - if ((info->format == format || info->format == PIXMAN_any) && - (info->flags & flags) == info->flags) - { - if (iter->iter_flags & ITER_NARROW) - { - iter->get_scanline = info->get_scanline_32; - } - else - { - iter->data = info->get_scanline_32; - iter->get_scanline = info->get_scanline_float; - } - return; - } - } - - /* Just in case we somehow didn't find a scanline function */ - iter->get_scanline = _pixman_iter_get_scanline_noop; -} - -static uint32_t * -dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) -{ - pixman_image_t *image = iter->image; - int x = iter->x; - int y = iter->y; - int width = iter->width; - uint32_t * buffer = iter->buffer; - - image->bits.fetch_scanline_32 (&image->bits, x, y, width, buffer, mask); - if (image->common.alpha_map) - { - uint32_t *alpha; - - if ((alpha = malloc (width * sizeof (uint32_t)))) - { - int i; - - x -= image->common.alpha_origin_x; - y -= image->common.alpha_origin_y; - - image->common.alpha_map->fetch_scanline_32 ( - image->common.alpha_map, x, y, width, alpha, mask); - - for (i = 0; i < width; ++i) - { - buffer[i] &= ~0xff000000; - buffer[i] |= (alpha[i] & 0xff000000); - } - - free (alpha); - } - } - - return iter->buffer; -} - -static uint32_t * -dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) -{ - bits_image_t * image = &iter->image->bits; - int x = iter->x; - int y = iter->y; - int width = iter->width; - argb_t * buffer = (argb_t *)iter->buffer; - - image->fetch_scanline_float ( - image, x, y, width, (uint32_t *)buffer, mask); - if (image->common.alpha_map) - { - argb_t *alpha; - - if ((alpha = malloc (width * sizeof (argb_t)))) - { - int i; - - x -= image->common.alpha_origin_x; - y -= image->common.alpha_origin_y; - - image->common.alpha_map->fetch_scanline_float ( - image->common.alpha_map, x, y, width, (uint32_t *)alpha, mask); - - for (i = 0; i < width; ++i) - buffer[i].a = alpha[i].a; - - free (alpha); - } - } - - return iter->buffer; -} - -static void -dest_write_back_narrow (pixman_iter_t *iter) -{ - bits_image_t * image = &iter->image->bits; - int x = iter->x; - int y = iter->y; - int width = iter->width; - const uint32_t *buffer = iter->buffer; - - image->store_scanline_32 (image, x, y, width, buffer); - - if (image->common.alpha_map) - { - x -= image->common.alpha_origin_x; - y -= image->common.alpha_origin_y; - - image->common.alpha_map->store_scanline_32 ( - image->common.alpha_map, x, y, width, buffer); - } - - iter->y++; -} - -static void -dest_write_back_wide (pixman_iter_t *iter) -{ - bits_image_t * image = &iter->image->bits; - int x = iter->x; - int y = iter->y; - int width = iter->width; - const uint32_t *buffer = iter->buffer; - - image->store_scanline_float (image, x, y, width, buffer); - - if (image->common.alpha_map) - { - x -= image->common.alpha_origin_x; - y -= image->common.alpha_origin_y; - - image->common.alpha_map->store_scanline_float ( - image->common.alpha_map, x, y, width, buffer); - } - - iter->y++; -} - -void -_pixman_bits_image_dest_iter_init (pixman_image_t *image, pixman_iter_t *iter) -{ - if (iter->iter_flags & ITER_NARROW) - { - if ((iter->iter_flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) == - (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) - { - iter->get_scanline = _pixman_iter_get_scanline_noop; - } - else - { - iter->get_scanline = dest_get_scanline_narrow; - } - - iter->write_back = dest_write_back_narrow; - } - else - { - iter->get_scanline = dest_get_scanline_wide; - iter->write_back = dest_write_back_wide; - } -} - -static uint32_t * -create_bits (pixman_format_code_t format, - int width, - int height, - int * rowstride_bytes, - pixman_bool_t clear) -{ - int stride; - size_t buf_size; - int bpp; - - /* what follows is a long-winded way, avoiding any possibility of integer - * overflows, of saying: - * stride = ((width * bpp + 0x1f) >> 5) * sizeof (uint32_t); - */ - - bpp = PIXMAN_FORMAT_BPP (format); - if (_pixman_multiply_overflows_int (width, bpp)) - return NULL; - - stride = width * bpp; - if (_pixman_addition_overflows_int (stride, 0x1f)) - return NULL; - - stride += 0x1f; - stride >>= 5; - - stride *= sizeof (uint32_t); - - if (_pixman_multiply_overflows_size (height, stride)) - return NULL; - - buf_size = (size_t)height * stride; - - if (rowstride_bytes) - *rowstride_bytes = stride; - - if (clear) - return calloc (buf_size, 1); - else - return malloc (buf_size); -} - -pixman_bool_t -_pixman_bits_image_init (pixman_image_t * image, - pixman_format_code_t format, - int width, - int height, - uint32_t * bits, - int rowstride, - pixman_bool_t clear) -{ - uint32_t *free_me = NULL; - - if (!bits && width && height) - { - int rowstride_bytes; - - free_me = bits = create_bits (format, width, height, &rowstride_bytes, clear); - - if (!bits) - return FALSE; - - rowstride = rowstride_bytes / (int) sizeof (uint32_t); - } - - _pixman_image_init (image); - - image->type = BITS; - image->bits.format = format; - image->bits.width = width; - image->bits.height = height; - image->bits.bits = bits; - image->bits.free_me = free_me; - image->bits.read_func = NULL; - image->bits.write_func = NULL; - image->bits.rowstride = rowstride; - image->bits.indexed = NULL; - - image->common.property_changed = bits_image_property_changed; - - _pixman_image_reset_clip_region (image); - - return TRUE; -} - -static pixman_image_t * -create_bits_image_internal (pixman_format_code_t format, - int width, - int height, - uint32_t * bits, - int rowstride_bytes, - pixman_bool_t clear) -{ - pixman_image_t *image; - - /* must be a whole number of uint32_t's - */ - return_val_if_fail ( - bits == NULL || (rowstride_bytes % sizeof (uint32_t)) == 0, NULL); - - return_val_if_fail (PIXMAN_FORMAT_BPP (format) >= PIXMAN_FORMAT_DEPTH (format), NULL); - - image = _pixman_image_allocate (); - - if (!image) - return NULL; - - if (!_pixman_bits_image_init (image, format, width, height, bits, - rowstride_bytes / (int) sizeof (uint32_t), - clear)) - { - free (image); - return NULL; - } - - return image; -} - -/* If bits is NULL, a buffer will be allocated and initialized to 0 */ -PIXMAN_EXPORT pixman_image_t * -pixman_image_create_bits (pixman_format_code_t format, - int width, - int height, - uint32_t * bits, - int rowstride_bytes) -{ - return create_bits_image_internal ( - format, width, height, bits, rowstride_bytes, TRUE); -} - - -/* If bits is NULL, a buffer will be allocated and _not_ initialized */ -PIXMAN_EXPORT pixman_image_t * -pixman_image_create_bits_no_clear (pixman_format_code_t format, - int width, - int height, - uint32_t * bits, - int rowstride_bytes) -{ - return create_bits_image_internal ( - format, width, height, bits, rowstride_bytes, FALSE); -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman-combine-float.c b/source/libs/pixman/pixman-src/pixman/pixman-combine-float.c deleted file mode 100644 index f5145bc9d78383f34ed2e0576b579c9598e196d9..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-combine-float.c +++ /dev/null @@ -1,1158 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */ -/* - * Copyright © 2010, 2012 Soren Sandmann Pedersen - * Copyright © 2010, 2012 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Soren Sandmann Pedersen (sandmann@cs.au.dk) - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <math.h> -#include <string.h> -#include <float.h> - -#include "pixman-private.h" - -/* Workaround for http://gcc.gnu.org/PR54965 */ -/* GCC 4.6 has problems with force_inline, so just use normal inline instead */ -#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 6) -#undef force_inline -#define force_inline __inline__ -#endif - -typedef float (* combine_channel_t) (float sa, float s, float da, float d); - -static force_inline void -combine_inner (pixman_bool_t component, - float *dest, const float *src, const float *mask, int n_pixels, - combine_channel_t combine_a, combine_channel_t combine_c) -{ - int i; - - if (!mask) - { - for (i = 0; i < 4 * n_pixels; i += 4) - { - float sa = src[i + 0]; - float sr = src[i + 1]; - float sg = src[i + 2]; - float sb = src[i + 3]; - - float da = dest[i + 0]; - float dr = dest[i + 1]; - float dg = dest[i + 2]; - float db = dest[i + 3]; - - dest[i + 0] = combine_a (sa, sa, da, da); - dest[i + 1] = combine_c (sa, sr, da, dr); - dest[i + 2] = combine_c (sa, sg, da, dg); - dest[i + 3] = combine_c (sa, sb, da, db); - } - } - else - { - for (i = 0; i < 4 * n_pixels; i += 4) - { - float sa, sr, sg, sb; - float ma, mr, mg, mb; - float da, dr, dg, db; - - sa = src[i + 0]; - sr = src[i + 1]; - sg = src[i + 2]; - sb = src[i + 3]; - - if (component) - { - ma = mask[i + 0]; - mr = mask[i + 1]; - mg = mask[i + 2]; - mb = mask[i + 3]; - - sr *= mr; - sg *= mg; - sb *= mb; - - ma *= sa; - mr *= sa; - mg *= sa; - mb *= sa; - - sa = ma; - } - else - { - ma = mask[i + 0]; - - sa *= ma; - sr *= ma; - sg *= ma; - sb *= ma; - - ma = mr = mg = mb = sa; - } - - da = dest[i + 0]; - dr = dest[i + 1]; - dg = dest[i + 2]; - db = dest[i + 3]; - - dest[i + 0] = combine_a (ma, sa, da, da); - dest[i + 1] = combine_c (mr, sr, da, dr); - dest[i + 2] = combine_c (mg, sg, da, dg); - dest[i + 3] = combine_c (mb, sb, da, db); - } - } -} - -#define MAKE_COMBINER(name, component, combine_a, combine_c) \ - static void \ - combine_ ## name ## _float (pixman_implementation_t *imp, \ - pixman_op_t op, \ - float *dest, \ - const float *src, \ - const float *mask, \ - int n_pixels) \ - { \ - combine_inner (component, dest, src, mask, n_pixels, \ - combine_a, combine_c); \ - } - -#define MAKE_COMBINERS(name, combine_a, combine_c) \ - MAKE_COMBINER(name ## _ca, TRUE, combine_a, combine_c) \ - MAKE_COMBINER(name ## _u, FALSE, combine_a, combine_c) - - -/* - * Porter/Duff operators - */ -typedef enum -{ - ZERO, - ONE, - SRC_ALPHA, - DEST_ALPHA, - INV_SA, - INV_DA, - SA_OVER_DA, - DA_OVER_SA, - INV_SA_OVER_DA, - INV_DA_OVER_SA, - ONE_MINUS_SA_OVER_DA, - ONE_MINUS_DA_OVER_SA, - ONE_MINUS_INV_DA_OVER_SA, - ONE_MINUS_INV_SA_OVER_DA -} combine_factor_t; - -#define CLAMP(f) \ - (((f) < 0)? 0 : (((f) > 1.0) ? 1.0 : (f))) - -static force_inline float -get_factor (combine_factor_t factor, float sa, float da) -{ - float f = -1; - - switch (factor) - { - case ZERO: - f = 0.0f; - break; - - case ONE: - f = 1.0f; - break; - - case SRC_ALPHA: - f = sa; - break; - - case DEST_ALPHA: - f = da; - break; - - case INV_SA: - f = 1 - sa; - break; - - case INV_DA: - f = 1 - da; - break; - - case SA_OVER_DA: - if (FLOAT_IS_ZERO (da)) - f = 1.0f; - else - f = CLAMP (sa / da); - break; - - case DA_OVER_SA: - if (FLOAT_IS_ZERO (sa)) - f = 1.0f; - else - f = CLAMP (da / sa); - break; - - case INV_SA_OVER_DA: - if (FLOAT_IS_ZERO (da)) - f = 1.0f; - else - f = CLAMP ((1.0f - sa) / da); - break; - - case INV_DA_OVER_SA: - if (FLOAT_IS_ZERO (sa)) - f = 1.0f; - else - f = CLAMP ((1.0f - da) / sa); - break; - - case ONE_MINUS_SA_OVER_DA: - if (FLOAT_IS_ZERO (da)) - f = 0.0f; - else - f = CLAMP (1.0f - sa / da); - break; - - case ONE_MINUS_DA_OVER_SA: - if (FLOAT_IS_ZERO (sa)) - f = 0.0f; - else - f = CLAMP (1.0f - da / sa); - break; - - case ONE_MINUS_INV_DA_OVER_SA: - if (FLOAT_IS_ZERO (sa)) - f = 0.0f; - else - f = CLAMP (1.0f - (1.0f - da) / sa); - break; - - case ONE_MINUS_INV_SA_OVER_DA: - if (FLOAT_IS_ZERO (da)) - f = 0.0f; - else - f = CLAMP (1.0f - (1.0f - sa) / da); - break; - } - - return f; -} - -#define MAKE_PD_COMBINERS(name, a, b) \ - static float force_inline \ - pd_combine_ ## name (float sa, float s, float da, float d) \ - { \ - const float fa = get_factor (a, sa, da); \ - const float fb = get_factor (b, sa, da); \ - \ - return MIN (1.0f, s * fa + d * fb); \ - } \ - \ - MAKE_COMBINERS(name, pd_combine_ ## name, pd_combine_ ## name) - -MAKE_PD_COMBINERS (clear, ZERO, ZERO) -MAKE_PD_COMBINERS (src, ONE, ZERO) -MAKE_PD_COMBINERS (dst, ZERO, ONE) -MAKE_PD_COMBINERS (over, ONE, INV_SA) -MAKE_PD_COMBINERS (over_reverse, INV_DA, ONE) -MAKE_PD_COMBINERS (in, DEST_ALPHA, ZERO) -MAKE_PD_COMBINERS (in_reverse, ZERO, SRC_ALPHA) -MAKE_PD_COMBINERS (out, INV_DA, ZERO) -MAKE_PD_COMBINERS (out_reverse, ZERO, INV_SA) -MAKE_PD_COMBINERS (atop, DEST_ALPHA, INV_SA) -MAKE_PD_COMBINERS (atop_reverse, INV_DA, SRC_ALPHA) -MAKE_PD_COMBINERS (xor, INV_DA, INV_SA) -MAKE_PD_COMBINERS (add, ONE, ONE) - -MAKE_PD_COMBINERS (saturate, INV_DA_OVER_SA, ONE) - -MAKE_PD_COMBINERS (disjoint_clear, ZERO, ZERO) -MAKE_PD_COMBINERS (disjoint_src, ONE, ZERO) -MAKE_PD_COMBINERS (disjoint_dst, ZERO, ONE) -MAKE_PD_COMBINERS (disjoint_over, ONE, INV_SA_OVER_DA) -MAKE_PD_COMBINERS (disjoint_over_reverse, INV_DA_OVER_SA, ONE) -MAKE_PD_COMBINERS (disjoint_in, ONE_MINUS_INV_DA_OVER_SA, ZERO) -MAKE_PD_COMBINERS (disjoint_in_reverse, ZERO, ONE_MINUS_INV_SA_OVER_DA) -MAKE_PD_COMBINERS (disjoint_out, INV_DA_OVER_SA, ZERO) -MAKE_PD_COMBINERS (disjoint_out_reverse, ZERO, INV_SA_OVER_DA) -MAKE_PD_COMBINERS (disjoint_atop, ONE_MINUS_INV_DA_OVER_SA, INV_SA_OVER_DA) -MAKE_PD_COMBINERS (disjoint_atop_reverse, INV_DA_OVER_SA, ONE_MINUS_INV_SA_OVER_DA) -MAKE_PD_COMBINERS (disjoint_xor, INV_DA_OVER_SA, INV_SA_OVER_DA) - -MAKE_PD_COMBINERS (conjoint_clear, ZERO, ZERO) -MAKE_PD_COMBINERS (conjoint_src, ONE, ZERO) -MAKE_PD_COMBINERS (conjoint_dst, ZERO, ONE) -MAKE_PD_COMBINERS (conjoint_over, ONE, ONE_MINUS_SA_OVER_DA) -MAKE_PD_COMBINERS (conjoint_over_reverse, ONE_MINUS_DA_OVER_SA, ONE) -MAKE_PD_COMBINERS (conjoint_in, DA_OVER_SA, ZERO) -MAKE_PD_COMBINERS (conjoint_in_reverse, ZERO, SA_OVER_DA) -MAKE_PD_COMBINERS (conjoint_out, ONE_MINUS_DA_OVER_SA, ZERO) -MAKE_PD_COMBINERS (conjoint_out_reverse, ZERO, ONE_MINUS_SA_OVER_DA) -MAKE_PD_COMBINERS (conjoint_atop, DA_OVER_SA, ONE_MINUS_SA_OVER_DA) -MAKE_PD_COMBINERS (conjoint_atop_reverse, ONE_MINUS_DA_OVER_SA, SA_OVER_DA) -MAKE_PD_COMBINERS (conjoint_xor, ONE_MINUS_DA_OVER_SA, ONE_MINUS_SA_OVER_DA) - -/* - * PDF blend modes: - * - * The following blend modes have been taken from the PDF ISO 32000 - * specification, which at this point in time is available from - * - * http://www.adobe.com/devnet/pdf/pdf_reference.html - * - * The specific documents of interest are the PDF spec itself: - * - * http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/PDF32000_2008.pdf - * - * chapters 11.3.5 and 11.3.6 and a later supplement for Adobe Acrobat - * 9.1 and Reader 9.1: - * - * http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/adobe_supplement_iso32000_1.pdf - * - * that clarifies the specifications for blend modes ColorDodge and - * ColorBurn. - * - * The formula for computing the final pixel color given in 11.3.6 is: - * - * αr × Cr = (1 – αs) × αb × Cb + (1 – αb) × αs × Cs + αb × αs × B(Cb, Cs) - * - * with B() is the blend function. When B(Cb, Cs) = Cs, this formula - * reduces to the regular OVER operator. - * - * Cs and Cb are not premultiplied, so in our implementation we instead - * use: - * - * cr = (1 – αs) × cb + (1 – αb) × cs + αb × αs × B (cb/αb, cs/αs) - * - * where cr, cs, and cb are premultiplied colors, and where the - * - * αb × αs × B(cb/αb, cs/αs) - * - * part is first arithmetically simplified under the assumption that αb - * and αs are not 0, and then updated to produce a meaningful result when - * they are. - * - * For all the blend mode operators, the alpha channel is given by - * - * αr = αs + αb + αb × αs - */ - -#define MAKE_SEPARABLE_PDF_COMBINERS(name) \ - static force_inline float \ - combine_ ## name ## _a (float sa, float s, float da, float d) \ - { \ - return da + sa - da * sa; \ - } \ - \ - static force_inline float \ - combine_ ## name ## _c (float sa, float s, float da, float d) \ - { \ - float f = (1 - sa) * d + (1 - da) * s; \ - \ - return f + blend_ ## name (sa, s, da, d); \ - } \ - \ - MAKE_COMBINERS (name, combine_ ## name ## _a, combine_ ## name ## _c) - -/* - * Multiply - * - * ad * as * B(d / ad, s / as) - * = ad * as * d/ad * s/as - * = d * s - * - */ -static force_inline float -blend_multiply (float sa, float s, float da, float d) -{ - return d * s; -} - -/* - * Screen - * - * ad * as * B(d/ad, s/as) - * = ad * as * (d/ad + s/as - s/as * d/ad) - * = ad * s + as * d - s * d - */ -static force_inline float -blend_screen (float sa, float s, float da, float d) -{ - return d * sa + s * da - s * d; -} - -/* - * Overlay - * - * ad * as * B(d/ad, s/as) - * = ad * as * Hardlight (s, d) - * = if (d / ad < 0.5) - * as * ad * Multiply (s/as, 2 * d/ad) - * else - * as * ad * Screen (s/as, 2 * d / ad - 1) - * = if (d < 0.5 * ad) - * as * ad * s/as * 2 * d /ad - * else - * as * ad * (s/as + 2 * d / ad - 1 - s / as * (2 * d / ad - 1)) - * = if (2 * d < ad) - * 2 * s * d - * else - * ad * s + 2 * as * d - as * ad - ad * s * (2 * d / ad - 1) - * = if (2 * d < ad) - * 2 * s * d - * else - * as * ad - 2 * (ad - d) * (as - s) - */ -static force_inline float -blend_overlay (float sa, float s, float da, float d) -{ - if (2 * d < da) - return 2 * s * d; - else - return sa * da - 2 * (da - d) * (sa - s); -} - -/* - * Darken - * - * ad * as * B(d/ad, s/as) - * = ad * as * MIN(d/ad, s/as) - * = MIN (as * d, ad * s) - */ -static force_inline float -blend_darken (float sa, float s, float da, float d) -{ - s = s * da; - d = d * sa; - - if (s > d) - return d; - else - return s; -} - -/* - * Lighten - * - * ad * as * B(d/ad, s/as) - * = ad * as * MAX(d/ad, s/as) - * = MAX (as * d, ad * s) - */ -static force_inline float -blend_lighten (float sa, float s, float da, float d) -{ - s = s * da; - d = d * sa; - - if (s > d) - return s; - else - return d; -} - -/* - * Color dodge - * - * ad * as * B(d/ad, s/as) - * = if d/ad = 0 - * ad * as * 0 - * else if (d/ad >= (1 - s/as) - * ad * as * 1 - * else - * ad * as * ((d/ad) / (1 - s/as)) - * = if d = 0 - * 0 - * elif as * d >= ad * (as - s) - * ad * as - * else - * as * (as * d / (as - s)) - * - */ -static force_inline float -blend_color_dodge (float sa, float s, float da, float d) -{ - if (FLOAT_IS_ZERO (d)) - return 0.0f; - else if (d * sa >= sa * da - s * da) - return sa * da; - else if (FLOAT_IS_ZERO (sa - s)) - return sa * da; - else - return sa * sa * d / (sa - s); -} - -/* - * Color burn - * - * We modify the first clause "if d = 1" to "if d >= 1" since with - * premultiplied colors d > 1 can actually happen. - * - * ad * as * B(d/ad, s/as) - * = if d/ad >= 1 - * ad * as * 1 - * elif (1 - d/ad) >= s/as - * ad * as * 0 - * else - * ad * as * (1 - ((1 - d/ad) / (s/as))) - * = if d >= ad - * ad * as - * elif as * ad - as * d >= ad * s - * 0 - * else - * ad * as - as * as * (ad - d) / s - */ -static force_inline float -blend_color_burn (float sa, float s, float da, float d) -{ - if (d >= da) - return sa * da; - else if (sa * (da - d) >= s * da) - return 0.0f; - else if (FLOAT_IS_ZERO (s)) - return 0.0f; - else - return sa * (da - sa * (da - d) / s); -} - -/* - * Hard light - * - * ad * as * B(d/ad, s/as) - * = if (s/as <= 0.5) - * ad * as * Multiply (d/ad, 2 * s/as) - * else - * ad * as * Screen (d/ad, 2 * s/as - 1) - * = if 2 * s <= as - * ad * as * d/ad * 2 * s / as - * else - * ad * as * (d/ad + (2 * s/as - 1) + d/ad * (2 * s/as - 1)) - * = if 2 * s <= as - * 2 * s * d - * else - * as * ad - 2 * (ad - d) * (as - s) - */ -static force_inline float -blend_hard_light (float sa, float s, float da, float d) -{ - if (2 * s < sa) - return 2 * s * d; - else - return sa * da - 2 * (da - d) * (sa - s); -} - -/* - * Soft light - * - * ad * as * B(d/ad, s/as) - * = if (s/as <= 0.5) - * ad * as * (d/ad - (1 - 2 * s/as) * d/ad * (1 - d/ad)) - * else if (d/ad <= 0.25) - * ad * as * (d/ad + (2 * s/as - 1) * ((((16 * d/ad - 12) * d/ad + 4) * d/ad) - d/ad)) - * else - * ad * as * (d/ad + (2 * s/as - 1) * sqrt (d/ad)) - * = if (2 * s <= as) - * d * as - d * (ad - d) * (as - 2 * s) / ad; - * else if (4 * d <= ad) - * (2 * s - as) * d * ((16 * d / ad - 12) * d / ad + 3); - * else - * d * as + (sqrt (d * ad) - d) * (2 * s - as); - */ -static force_inline float -blend_soft_light (float sa, float s, float da, float d) -{ - if (2 * s <= sa) - { - if (FLOAT_IS_ZERO (da)) - return d * sa; - else - return d * sa - d * (da - d) * (sa - 2 * s) / da; - } - else - { - if (FLOAT_IS_ZERO (da)) - { - return d * sa; - } - else - { - if (4 * d <= da) - return d * sa + (2 * s - sa) * d * ((16 * d / da - 12) * d / da + 3); - else - return d * sa + (sqrtf (d * da) - d) * (2 * s - sa); - } - } -} - -/* - * Difference - * - * ad * as * B(s/as, d/ad) - * = ad * as * abs (s/as - d/ad) - * = if (s/as <= d/ad) - * ad * as * (d/ad - s/as) - * else - * ad * as * (s/as - d/ad) - * = if (ad * s <= as * d) - * as * d - ad * s - * else - * ad * s - as * d - */ -static force_inline float -blend_difference (float sa, float s, float da, float d) -{ - float dsa = d * sa; - float sda = s * da; - - if (sda < dsa) - return dsa - sda; - else - return sda - dsa; -} - -/* - * Exclusion - * - * ad * as * B(s/as, d/ad) - * = ad * as * (d/ad + s/as - 2 * d/ad * s/as) - * = as * d + ad * s - 2 * s * d - */ -static force_inline float -blend_exclusion (float sa, float s, float da, float d) -{ - return s * da + d * sa - 2 * d * s; -} - -MAKE_SEPARABLE_PDF_COMBINERS (multiply) -MAKE_SEPARABLE_PDF_COMBINERS (screen) -MAKE_SEPARABLE_PDF_COMBINERS (overlay) -MAKE_SEPARABLE_PDF_COMBINERS (darken) -MAKE_SEPARABLE_PDF_COMBINERS (lighten) -MAKE_SEPARABLE_PDF_COMBINERS (color_dodge) -MAKE_SEPARABLE_PDF_COMBINERS (color_burn) -MAKE_SEPARABLE_PDF_COMBINERS (hard_light) -MAKE_SEPARABLE_PDF_COMBINERS (soft_light) -MAKE_SEPARABLE_PDF_COMBINERS (difference) -MAKE_SEPARABLE_PDF_COMBINERS (exclusion) - -/* - * PDF nonseperable blend modes are implemented using the following functions - * to operate in Hsl space, with Cmax, Cmid, Cmin referring to the max, mid - * and min value of the red, green and blue components. - * - * LUM (C) = 0.3 × Cred + 0.59 × Cgreen + 0.11 × Cblue - * - * clip_color (C): - * l = LUM (C) - * min = Cmin - * max = Cmax - * if n < 0.0 - * C = l + (((C – l) × l) â„ (l – min)) - * if x > 1.0 - * C = l + (((C – l) × (1 – l) ) â„ (max – l)) - * return C - * - * set_lum (C, l): - * d = l – LUM (C) - * C += d - * return clip_color (C) - * - * SAT (C) = CH_MAX (C) - CH_MIN (C) - * - * set_sat (C, s): - * if Cmax > Cmin - * Cmid = ( ( ( Cmid – Cmin ) × s ) â„ ( Cmax – Cmin ) ) - * Cmax = s - * else - * Cmid = Cmax = 0.0 - * Cmin = 0.0 - * return C - */ - -/* For premultiplied colors, we need to know what happens when C is - * multiplied by a real number. LUM and SAT are linear: - * - * LUM (r × C) = r × LUM (C) SAT (r * C) = r * SAT (C) - * - * If we extend clip_color with an extra argument a and change - * - * if x >= 1.0 - * - * into - * - * if x >= a - * - * then clip_color is also linear: - * - * r * clip_color (C, a) = clip_color (r * C, r * a); - * - * for positive r. - * - * Similarly, we can extend set_lum with an extra argument that is just passed - * on to clip_color: - * - * r * set_lum (C, l, a) - * - * = r × clip_color (C + l - LUM (C), a) - * - * = clip_color (r * C + r × l - r * LUM (C), r * a) - * - * = set_lum (r * C, r * l, r * a) - * - * Finally, set_sat: - * - * r * set_sat (C, s) = set_sat (x * C, r * s) - * - * The above holds for all non-zero x, because the x'es in the fraction for - * C_mid cancel out. Specifically, it holds for x = r: - * - * r * set_sat (C, s) = set_sat (r * C, r * s) - * - */ -typedef struct -{ - float r; - float g; - float b; -} rgb_t; - -static force_inline float -minf (float a, float b) -{ - return a < b? a : b; -} - -static force_inline float -maxf (float a, float b) -{ - return a > b? a : b; -} - -static force_inline float -channel_min (const rgb_t *c) -{ - return minf (minf (c->r, c->g), c->b); -} - -static force_inline float -channel_max (const rgb_t *c) -{ - return maxf (maxf (c->r, c->g), c->b); -} - -static force_inline float -get_lum (const rgb_t *c) -{ - return c->r * 0.3f + c->g * 0.59f + c->b * 0.11f; -} - -static force_inline float -get_sat (const rgb_t *c) -{ - return channel_max (c) - channel_min (c); -} - -static void -clip_color (rgb_t *color, float a) -{ - float l = get_lum (color); - float n = channel_min (color); - float x = channel_max (color); - float t; - - if (n < 0.0f) - { - t = l - n; - if (FLOAT_IS_ZERO (t)) - { - color->r = 0.0f; - color->g = 0.0f; - color->b = 0.0f; - } - else - { - color->r = l + (((color->r - l) * l) / t); - color->g = l + (((color->g - l) * l) / t); - color->b = l + (((color->b - l) * l) / t); - } - } - if (x > a) - { - t = x - l; - if (FLOAT_IS_ZERO (t)) - { - color->r = a; - color->g = a; - color->b = a; - } - else - { - color->r = l + (((color->r - l) * (a - l) / t)); - color->g = l + (((color->g - l) * (a - l) / t)); - color->b = l + (((color->b - l) * (a - l) / t)); - } - } -} - -static void -set_lum (rgb_t *color, float sa, float l) -{ - float d = l - get_lum (color); - - color->r = color->r + d; - color->g = color->g + d; - color->b = color->b + d; - - clip_color (color, sa); -} - -static void -set_sat (rgb_t *src, float sat) -{ - float *max, *mid, *min; - float t; - - if (src->r > src->g) - { - if (src->r > src->b) - { - max = &(src->r); - - if (src->g > src->b) - { - mid = &(src->g); - min = &(src->b); - } - else - { - mid = &(src->b); - min = &(src->g); - } - } - else - { - max = &(src->b); - mid = &(src->r); - min = &(src->g); - } - } - else - { - if (src->r > src->b) - { - max = &(src->g); - mid = &(src->r); - min = &(src->b); - } - else - { - min = &(src->r); - - if (src->g > src->b) - { - max = &(src->g); - mid = &(src->b); - } - else - { - max = &(src->b); - mid = &(src->g); - } - } - } - - t = *max - *min; - - if (FLOAT_IS_ZERO (t)) - { - *mid = *max = 0.0f; - } - else - { - *mid = ((*mid - *min) * sat) / t; - *max = sat; - } - - *min = 0.0f; -} - -/* Hue: - * - * as * ad * B(s/as, d/as) - * = as * ad * set_lum (set_sat (s/as, SAT (d/ad)), LUM (d/ad), 1) - * = set_lum (set_sat (ad * s, as * SAT (d)), as * LUM (d), as * ad) - * - */ -static force_inline void -blend_hsl_hue (rgb_t *res, - const rgb_t *dest, float da, - const rgb_t *src, float sa) -{ - res->r = src->r * da; - res->g = src->g * da; - res->b = src->b * da; - - set_sat (res, get_sat (dest) * sa); - set_lum (res, sa * da, get_lum (dest) * sa); -} - -/* - * Saturation - * - * as * ad * B(s/as, d/ad) - * = as * ad * set_lum (set_sat (d/ad, SAT (s/as)), LUM (d/ad), 1) - * = set_lum (as * ad * set_sat (d/ad, SAT (s/as)), - * as * LUM (d), as * ad) - * = set_lum (set_sat (as * d, ad * SAT (s), as * LUM (d), as * ad)) - */ -static force_inline void -blend_hsl_saturation (rgb_t *res, - const rgb_t *dest, float da, - const rgb_t *src, float sa) -{ - res->r = dest->r * sa; - res->g = dest->g * sa; - res->b = dest->b * sa; - - set_sat (res, get_sat (src) * da); - set_lum (res, sa * da, get_lum (dest) * sa); -} - -/* - * Color - * - * as * ad * B(s/as, d/as) - * = as * ad * set_lum (s/as, LUM (d/ad), 1) - * = set_lum (s * ad, as * LUM (d), as * ad) - */ -static force_inline void -blend_hsl_color (rgb_t *res, - const rgb_t *dest, float da, - const rgb_t *src, float sa) -{ - res->r = src->r * da; - res->g = src->g * da; - res->b = src->b * da; - - set_lum (res, sa * da, get_lum (dest) * sa); -} - -/* - * Luminosity - * - * as * ad * B(s/as, d/ad) - * = as * ad * set_lum (d/ad, LUM (s/as), 1) - * = set_lum (as * d, ad * LUM (s), as * ad) - */ -static force_inline void -blend_hsl_luminosity (rgb_t *res, - const rgb_t *dest, float da, - const rgb_t *src, float sa) -{ - res->r = dest->r * sa; - res->g = dest->g * sa; - res->b = dest->b * sa; - - set_lum (res, sa * da, get_lum (src) * da); -} - -#define MAKE_NON_SEPARABLE_PDF_COMBINERS(name) \ - static void \ - combine_ ## name ## _u_float (pixman_implementation_t *imp, \ - pixman_op_t op, \ - float *dest, \ - const float *src, \ - const float *mask, \ - int n_pixels) \ - { \ - int i; \ - \ - for (i = 0; i < 4 * n_pixels; i += 4) \ - { \ - float sa, da; \ - rgb_t sc, dc, rc; \ - \ - sa = src[i + 0]; \ - sc.r = src[i + 1]; \ - sc.g = src[i + 2]; \ - sc.b = src[i + 3]; \ - \ - da = dest[i + 0]; \ - dc.r = dest[i + 1]; \ - dc.g = dest[i + 2]; \ - dc.b = dest[i + 3]; \ - \ - if (mask) \ - { \ - float ma = mask[i + 0]; \ - \ - /* Component alpha is not supported for HSL modes */ \ - sa *= ma; \ - sc.r *= ma; \ - sc.g *= ma; \ - sc.g *= ma; \ - } \ - \ - blend_ ## name (&rc, &dc, da, &sc, sa); \ - \ - dest[i + 0] = sa + da - sa * da; \ - dest[i + 1] = (1 - sa) * dc.r + (1 - da) * sc.r + rc.r; \ - dest[i + 2] = (1 - sa) * dc.g + (1 - da) * sc.g + rc.g; \ - dest[i + 3] = (1 - sa) * dc.b + (1 - da) * sc.b + rc.b; \ - } \ - } - -MAKE_NON_SEPARABLE_PDF_COMBINERS(hsl_hue) -MAKE_NON_SEPARABLE_PDF_COMBINERS(hsl_saturation) -MAKE_NON_SEPARABLE_PDF_COMBINERS(hsl_color) -MAKE_NON_SEPARABLE_PDF_COMBINERS(hsl_luminosity) - -void -_pixman_setup_combiner_functions_float (pixman_implementation_t *imp) -{ - /* Unified alpha */ - imp->combine_float[PIXMAN_OP_CLEAR] = combine_clear_u_float; - imp->combine_float[PIXMAN_OP_SRC] = combine_src_u_float; - imp->combine_float[PIXMAN_OP_DST] = combine_dst_u_float; - imp->combine_float[PIXMAN_OP_OVER] = combine_over_u_float; - imp->combine_float[PIXMAN_OP_OVER_REVERSE] = combine_over_reverse_u_float; - imp->combine_float[PIXMAN_OP_IN] = combine_in_u_float; - imp->combine_float[PIXMAN_OP_IN_REVERSE] = combine_in_reverse_u_float; - imp->combine_float[PIXMAN_OP_OUT] = combine_out_u_float; - imp->combine_float[PIXMAN_OP_OUT_REVERSE] = combine_out_reverse_u_float; - imp->combine_float[PIXMAN_OP_ATOP] = combine_atop_u_float; - imp->combine_float[PIXMAN_OP_ATOP_REVERSE] = combine_atop_reverse_u_float; - imp->combine_float[PIXMAN_OP_XOR] = combine_xor_u_float; - imp->combine_float[PIXMAN_OP_ADD] = combine_add_u_float; - imp->combine_float[PIXMAN_OP_SATURATE] = combine_saturate_u_float; - - /* Disjoint, unified */ - imp->combine_float[PIXMAN_OP_DISJOINT_CLEAR] = combine_disjoint_clear_u_float; - imp->combine_float[PIXMAN_OP_DISJOINT_SRC] = combine_disjoint_src_u_float; - imp->combine_float[PIXMAN_OP_DISJOINT_DST] = combine_disjoint_dst_u_float; - imp->combine_float[PIXMAN_OP_DISJOINT_OVER] = combine_disjoint_over_u_float; - imp->combine_float[PIXMAN_OP_DISJOINT_OVER_REVERSE] = combine_disjoint_over_reverse_u_float; - imp->combine_float[PIXMAN_OP_DISJOINT_IN] = combine_disjoint_in_u_float; - imp->combine_float[PIXMAN_OP_DISJOINT_IN_REVERSE] = combine_disjoint_in_reverse_u_float; - imp->combine_float[PIXMAN_OP_DISJOINT_OUT] = combine_disjoint_out_u_float; - imp->combine_float[PIXMAN_OP_DISJOINT_OUT_REVERSE] = combine_disjoint_out_reverse_u_float; - imp->combine_float[PIXMAN_OP_DISJOINT_ATOP] = combine_disjoint_atop_u_float; - imp->combine_float[PIXMAN_OP_DISJOINT_ATOP_REVERSE] = combine_disjoint_atop_reverse_u_float; - imp->combine_float[PIXMAN_OP_DISJOINT_XOR] = combine_disjoint_xor_u_float; - - /* Conjoint, unified */ - imp->combine_float[PIXMAN_OP_CONJOINT_CLEAR] = combine_conjoint_clear_u_float; - imp->combine_float[PIXMAN_OP_CONJOINT_SRC] = combine_conjoint_src_u_float; - imp->combine_float[PIXMAN_OP_CONJOINT_DST] = combine_conjoint_dst_u_float; - imp->combine_float[PIXMAN_OP_CONJOINT_OVER] = combine_conjoint_over_u_float; - imp->combine_float[PIXMAN_OP_CONJOINT_OVER_REVERSE] = combine_conjoint_over_reverse_u_float; - imp->combine_float[PIXMAN_OP_CONJOINT_IN] = combine_conjoint_in_u_float; - imp->combine_float[PIXMAN_OP_CONJOINT_IN_REVERSE] = combine_conjoint_in_reverse_u_float; - imp->combine_float[PIXMAN_OP_CONJOINT_OUT] = combine_conjoint_out_u_float; - imp->combine_float[PIXMAN_OP_CONJOINT_OUT_REVERSE] = combine_conjoint_out_reverse_u_float; - imp->combine_float[PIXMAN_OP_CONJOINT_ATOP] = combine_conjoint_atop_u_float; - imp->combine_float[PIXMAN_OP_CONJOINT_ATOP_REVERSE] = combine_conjoint_atop_reverse_u_float; - imp->combine_float[PIXMAN_OP_CONJOINT_XOR] = combine_conjoint_xor_u_float; - - /* PDF operators, unified */ - imp->combine_float[PIXMAN_OP_MULTIPLY] = combine_multiply_u_float; - imp->combine_float[PIXMAN_OP_SCREEN] = combine_screen_u_float; - imp->combine_float[PIXMAN_OP_OVERLAY] = combine_overlay_u_float; - imp->combine_float[PIXMAN_OP_DARKEN] = combine_darken_u_float; - imp->combine_float[PIXMAN_OP_LIGHTEN] = combine_lighten_u_float; - imp->combine_float[PIXMAN_OP_COLOR_DODGE] = combine_color_dodge_u_float; - imp->combine_float[PIXMAN_OP_COLOR_BURN] = combine_color_burn_u_float; - imp->combine_float[PIXMAN_OP_HARD_LIGHT] = combine_hard_light_u_float; - imp->combine_float[PIXMAN_OP_SOFT_LIGHT] = combine_soft_light_u_float; - imp->combine_float[PIXMAN_OP_DIFFERENCE] = combine_difference_u_float; - imp->combine_float[PIXMAN_OP_EXCLUSION] = combine_exclusion_u_float; - - imp->combine_float[PIXMAN_OP_HSL_HUE] = combine_hsl_hue_u_float; - imp->combine_float[PIXMAN_OP_HSL_SATURATION] = combine_hsl_saturation_u_float; - imp->combine_float[PIXMAN_OP_HSL_COLOR] = combine_hsl_color_u_float; - imp->combine_float[PIXMAN_OP_HSL_LUMINOSITY] = combine_hsl_luminosity_u_float; - - /* Component alpha combiners */ - imp->combine_float_ca[PIXMAN_OP_CLEAR] = combine_clear_ca_float; - imp->combine_float_ca[PIXMAN_OP_SRC] = combine_src_ca_float; - imp->combine_float_ca[PIXMAN_OP_DST] = combine_dst_ca_float; - imp->combine_float_ca[PIXMAN_OP_OVER] = combine_over_ca_float; - imp->combine_float_ca[PIXMAN_OP_OVER_REVERSE] = combine_over_reverse_ca_float; - imp->combine_float_ca[PIXMAN_OP_IN] = combine_in_ca_float; - imp->combine_float_ca[PIXMAN_OP_IN_REVERSE] = combine_in_reverse_ca_float; - imp->combine_float_ca[PIXMAN_OP_OUT] = combine_out_ca_float; - imp->combine_float_ca[PIXMAN_OP_OUT_REVERSE] = combine_out_reverse_ca_float; - imp->combine_float_ca[PIXMAN_OP_ATOP] = combine_atop_ca_float; - imp->combine_float_ca[PIXMAN_OP_ATOP_REVERSE] = combine_atop_reverse_ca_float; - imp->combine_float_ca[PIXMAN_OP_XOR] = combine_xor_ca_float; - imp->combine_float_ca[PIXMAN_OP_ADD] = combine_add_ca_float; - imp->combine_float_ca[PIXMAN_OP_SATURATE] = combine_saturate_ca_float; - - /* Disjoint CA */ - imp->combine_float_ca[PIXMAN_OP_DISJOINT_CLEAR] = combine_disjoint_clear_ca_float; - imp->combine_float_ca[PIXMAN_OP_DISJOINT_SRC] = combine_disjoint_src_ca_float; - imp->combine_float_ca[PIXMAN_OP_DISJOINT_DST] = combine_disjoint_dst_ca_float; - imp->combine_float_ca[PIXMAN_OP_DISJOINT_OVER] = combine_disjoint_over_ca_float; - imp->combine_float_ca[PIXMAN_OP_DISJOINT_OVER_REVERSE] = combine_disjoint_over_reverse_ca_float; - imp->combine_float_ca[PIXMAN_OP_DISJOINT_IN] = combine_disjoint_in_ca_float; - imp->combine_float_ca[PIXMAN_OP_DISJOINT_IN_REVERSE] = combine_disjoint_in_reverse_ca_float; - imp->combine_float_ca[PIXMAN_OP_DISJOINT_OUT] = combine_disjoint_out_ca_float; - imp->combine_float_ca[PIXMAN_OP_DISJOINT_OUT_REVERSE] = combine_disjoint_out_reverse_ca_float; - imp->combine_float_ca[PIXMAN_OP_DISJOINT_ATOP] = combine_disjoint_atop_ca_float; - imp->combine_float_ca[PIXMAN_OP_DISJOINT_ATOP_REVERSE] = combine_disjoint_atop_reverse_ca_float; - imp->combine_float_ca[PIXMAN_OP_DISJOINT_XOR] = combine_disjoint_xor_ca_float; - - /* Conjoint CA */ - imp->combine_float_ca[PIXMAN_OP_CONJOINT_CLEAR] = combine_conjoint_clear_ca_float; - imp->combine_float_ca[PIXMAN_OP_CONJOINT_SRC] = combine_conjoint_src_ca_float; - imp->combine_float_ca[PIXMAN_OP_CONJOINT_DST] = combine_conjoint_dst_ca_float; - imp->combine_float_ca[PIXMAN_OP_CONJOINT_OVER] = combine_conjoint_over_ca_float; - imp->combine_float_ca[PIXMAN_OP_CONJOINT_OVER_REVERSE] = combine_conjoint_over_reverse_ca_float; - imp->combine_float_ca[PIXMAN_OP_CONJOINT_IN] = combine_conjoint_in_ca_float; - imp->combine_float_ca[PIXMAN_OP_CONJOINT_IN_REVERSE] = combine_conjoint_in_reverse_ca_float; - imp->combine_float_ca[PIXMAN_OP_CONJOINT_OUT] = combine_conjoint_out_ca_float; - imp->combine_float_ca[PIXMAN_OP_CONJOINT_OUT_REVERSE] = combine_conjoint_out_reverse_ca_float; - imp->combine_float_ca[PIXMAN_OP_CONJOINT_ATOP] = combine_conjoint_atop_ca_float; - imp->combine_float_ca[PIXMAN_OP_CONJOINT_ATOP_REVERSE] = combine_conjoint_atop_reverse_ca_float; - imp->combine_float_ca[PIXMAN_OP_CONJOINT_XOR] = combine_conjoint_xor_ca_float; - - /* PDF operators CA */ - imp->combine_float_ca[PIXMAN_OP_MULTIPLY] = combine_multiply_ca_float; - imp->combine_float_ca[PIXMAN_OP_SCREEN] = combine_screen_ca_float; - imp->combine_float_ca[PIXMAN_OP_OVERLAY] = combine_overlay_ca_float; - imp->combine_float_ca[PIXMAN_OP_DARKEN] = combine_darken_ca_float; - imp->combine_float_ca[PIXMAN_OP_LIGHTEN] = combine_lighten_ca_float; - imp->combine_float_ca[PIXMAN_OP_COLOR_DODGE] = combine_color_dodge_ca_float; - imp->combine_float_ca[PIXMAN_OP_COLOR_BURN] = combine_color_burn_ca_float; - imp->combine_float_ca[PIXMAN_OP_HARD_LIGHT] = combine_hard_light_ca_float; - imp->combine_float_ca[PIXMAN_OP_SOFT_LIGHT] = combine_soft_light_ca_float; - imp->combine_float_ca[PIXMAN_OP_DIFFERENCE] = combine_difference_ca_float; - imp->combine_float_ca[PIXMAN_OP_EXCLUSION] = combine_exclusion_ca_float; - - /* It is not clear that these make sense, so make them noops for now */ - imp->combine_float_ca[PIXMAN_OP_HSL_HUE] = combine_dst_u_float; - imp->combine_float_ca[PIXMAN_OP_HSL_SATURATION] = combine_dst_u_float; - imp->combine_float_ca[PIXMAN_OP_HSL_COLOR] = combine_dst_u_float; - imp->combine_float_ca[PIXMAN_OP_HSL_LUMINOSITY] = combine_dst_u_float; -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman-combine32.c b/source/libs/pixman/pixman-src/pixman/pixman-combine32.c deleted file mode 100644 index 4c484d3e38cc1dedbc62cc10c6ec3389626d14a4..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-combine32.c +++ /dev/null @@ -1,1189 +0,0 @@ -/* - * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. - * 2005 Lars Knoll & Zack Rusin, Trolltech - * - * 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 Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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. - */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <math.h> -#include <string.h> - -#include "pixman-private.h" -#include "pixman-combine32.h" - -/* component alpha helper functions */ - -static void -combine_mask_ca (uint32_t *src, uint32_t *mask) -{ - uint32_t a = *mask; - - uint32_t x; - uint16_t xa; - - if (!a) - { - *(src) = 0; - return; - } - - x = *(src); - if (a == ~0) - { - x = x >> A_SHIFT; - x |= x << G_SHIFT; - x |= x << R_SHIFT; - *(mask) = x; - return; - } - - xa = x >> A_SHIFT; - UN8x4_MUL_UN8x4 (x, a); - *(src) = x; - - UN8x4_MUL_UN8 (a, xa); - *(mask) = a; -} - -static void -combine_mask_value_ca (uint32_t *src, const uint32_t *mask) -{ - uint32_t a = *mask; - uint32_t x; - - if (!a) - { - *(src) = 0; - return; - } - - if (a == ~0) - return; - - x = *(src); - UN8x4_MUL_UN8x4 (x, a); - *(src) = x; -} - -static void -combine_mask_alpha_ca (const uint32_t *src, uint32_t *mask) -{ - uint32_t a = *(mask); - uint32_t x; - - if (!a) - return; - - x = *(src) >> A_SHIFT; - if (x == MASK) - return; - - if (a == ~0) - { - x |= x << G_SHIFT; - x |= x << R_SHIFT; - *(mask) = x; - return; - } - - UN8x4_MUL_UN8 (a, x); - *(mask) = a; -} - -/* - * There are two ways of handling alpha -- either as a single unified value or - * a separate value for each component, hence each macro must have two - * versions. The unified alpha version has a 'u' at the end of the name, - * the component version has a 'ca'. Similarly, functions which deal with - * this difference will have two versions using the same convention. - */ - -static force_inline uint32_t -combine_mask (const uint32_t *src, const uint32_t *mask, int i) -{ - uint32_t s, m; - - if (mask) - { - m = *(mask + i) >> A_SHIFT; - - if (!m) - return 0; - } - - s = *(src + i); - - if (mask) - UN8x4_MUL_UN8 (s, m); - - return s; -} - -static void -combine_clear (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - memset (dest, 0, width * sizeof (uint32_t)); -} - -static void -combine_dst (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - return; -} - -static void -combine_src_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - if (!mask) - { - memcpy (dest, src, width * sizeof (uint32_t)); - } - else - { - for (i = 0; i < width; ++i) - { - uint32_t s = combine_mask (src, mask, i); - - *(dest + i) = s; - } - } -} - -static void -combine_over_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - if (!mask) - { - for (i = 0; i < width; ++i) - { - uint32_t s = *(src + i); - uint32_t a = ALPHA_8 (s); - if (a == 0xFF) - { - *(dest + i) = s; - } - else if (s) - { - uint32_t d = *(dest + i); - uint32_t ia = a ^ 0xFF; - UN8x4_MUL_UN8_ADD_UN8x4 (d, ia, s); - *(dest + i) = d; - } - } - } - else - { - for (i = 0; i < width; ++i) - { - uint32_t m = ALPHA_8 (*(mask + i)); - if (m == 0xFF) - { - uint32_t s = *(src + i); - uint32_t a = ALPHA_8 (s); - if (a == 0xFF) - { - *(dest + i) = s; - } - else if (s) - { - uint32_t d = *(dest + i); - uint32_t ia = a ^ 0xFF; - UN8x4_MUL_UN8_ADD_UN8x4 (d, ia, s); - *(dest + i) = d; - } - } - else if (m) - { - uint32_t s = *(src + i); - if (s) - { - uint32_t d = *(dest + i); - UN8x4_MUL_UN8 (s, m); - UN8x4_MUL_UN8_ADD_UN8x4 (d, ALPHA_8 (~s), s); - *(dest + i) = d; - } - } - } - } -} - -static void -combine_over_reverse_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t s = combine_mask (src, mask, i); - uint32_t d = *(dest + i); - uint32_t ia = ALPHA_8 (~*(dest + i)); - UN8x4_MUL_UN8_ADD_UN8x4 (s, ia, d); - *(dest + i) = s; - } -} - -static void -combine_in_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t s = combine_mask (src, mask, i); - uint32_t a = ALPHA_8 (*(dest + i)); - UN8x4_MUL_UN8 (s, a); - *(dest + i) = s; - } -} - -static void -combine_in_reverse_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t s = combine_mask (src, mask, i); - uint32_t d = *(dest + i); - uint32_t a = ALPHA_8 (s); - UN8x4_MUL_UN8 (d, a); - *(dest + i) = d; - } -} - -static void -combine_out_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t s = combine_mask (src, mask, i); - uint32_t a = ALPHA_8 (~*(dest + i)); - UN8x4_MUL_UN8 (s, a); - *(dest + i) = s; - } -} - -static void -combine_out_reverse_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t s = combine_mask (src, mask, i); - uint32_t d = *(dest + i); - uint32_t a = ALPHA_8 (~s); - UN8x4_MUL_UN8 (d, a); - *(dest + i) = d; - } -} - -static void -combine_atop_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t s = combine_mask (src, mask, i); - uint32_t d = *(dest + i); - uint32_t dest_a = ALPHA_8 (d); - uint32_t src_ia = ALPHA_8 (~s); - - UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_a, d, src_ia); - *(dest + i) = s; - } -} - -static void -combine_atop_reverse_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t s = combine_mask (src, mask, i); - uint32_t d = *(dest + i); - uint32_t src_a = ALPHA_8 (s); - uint32_t dest_ia = ALPHA_8 (~d); - - UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_ia, d, src_a); - *(dest + i) = s; - } -} - -static void -combine_xor_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t s = combine_mask (src, mask, i); - uint32_t d = *(dest + i); - uint32_t src_ia = ALPHA_8 (~s); - uint32_t dest_ia = ALPHA_8 (~d); - - UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_ia, d, src_ia); - *(dest + i) = s; - } -} - -static void -combine_add_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t s = combine_mask (src, mask, i); - uint32_t d = *(dest + i); - UN8x4_ADD_UN8x4 (d, s); - *(dest + i) = d; - } -} - -/* - * PDF blend modes: - * - * The following blend modes have been taken from the PDF ISO 32000 - * specification, which at this point in time is available from - * - * http://www.adobe.com/devnet/pdf/pdf_reference.html - * - * The specific documents of interest are the PDF spec itself: - * - * http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/PDF32000_2008.pdf - * - * chapters 11.3.5 and 11.3.6 and a later supplement for Adobe Acrobat - * 9.1 and Reader 9.1: - * - * http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/adobe_supplement_iso32000_1.pdf - * - * that clarifies the specifications for blend modes ColorDodge and - * ColorBurn. - * - * The formula for computing the final pixel color given in 11.3.6 is: - * - * αr × Cr = (1 – αs) × αb × Cb + (1 – αb) × αs × Cs + αb × αs × B(Cb, Cs) - * - * with B() is the blend function. When B(Cb, Cs) = Cs, this formula - * reduces to the regular OVER operator. - * - * Cs and Cb are not premultiplied, so in our implementation we instead - * use: - * - * cr = (1 – αs) × cb + (1 – αb) × cs + αb × αs × B (cb/αb, cs/αs) - * - * where cr, cs, and cb are premultiplied colors, and where the - * - * αb × αs × B(cb/αb, cs/αs) - * - * part is first arithmetically simplified under the assumption that αb - * and αs are not 0, and then updated to produce a meaningful result when - * they are. - * - * For all the blend mode operators, the alpha channel is given by - * - * αr = αs + αb + αb × αs - */ - -/* - * Multiply - * - * ad * as * B(d / ad, s / as) - * = ad * as * d/ad * s/as - * = d * s - * - */ -static void -combine_multiply_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t s = combine_mask (src, mask, i); - uint32_t d = *(dest + i); - uint32_t ss = s; - uint32_t src_ia = ALPHA_8 (~s); - uint32_t dest_ia = ALPHA_8 (~d); - - UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (ss, dest_ia, d, src_ia); - UN8x4_MUL_UN8x4 (d, s); - UN8x4_ADD_UN8x4 (d, ss); - - *(dest + i) = d; - } -} - -static void -combine_multiply_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t m = *(mask + i); - uint32_t s = *(src + i); - uint32_t d = *(dest + i); - uint32_t r = d; - uint32_t dest_ia = ALPHA_8 (~d); - - combine_mask_ca (&s, &m); - - UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (r, ~m, s, dest_ia); - UN8x4_MUL_UN8x4 (d, s); - UN8x4_ADD_UN8x4 (r, d); - - *(dest + i) = r; - } -} - -#define CLAMP(v, low, high) \ - do \ - { \ - if (v < (low)) \ - v = (low); \ - if (v > (high)) \ - v = (high); \ - } while (0) - -#define PDF_SEPARABLE_BLEND_MODE(name) \ - static void \ - combine_ ## name ## _u (pixman_implementation_t *imp, \ - pixman_op_t op, \ - uint32_t * dest, \ - const uint32_t * src, \ - const uint32_t * mask, \ - int width) \ - { \ - int i; \ - for (i = 0; i < width; ++i) \ - { \ - uint32_t s = combine_mask (src, mask, i); \ - uint32_t d = *(dest + i); \ - uint8_t sa = ALPHA_8 (s); \ - uint8_t isa = ~sa; \ - uint8_t da = ALPHA_8 (d); \ - uint8_t ida = ~da; \ - int32_t ra, rr, rg, rb; \ - \ - ra = da * 0xff + sa * 0xff - sa * da; \ - rr = isa * RED_8 (d) + ida * RED_8 (s); \ - rg = isa * GREEN_8 (d) + ida * GREEN_8 (s); \ - rb = isa * BLUE_8 (d) + ida * BLUE_8 (s); \ - \ - rr += blend_ ## name (RED_8 (d), da, RED_8 (s), sa); \ - rg += blend_ ## name (GREEN_8 (d), da, GREEN_8 (s), sa); \ - rb += blend_ ## name (BLUE_8 (d), da, BLUE_8 (s), sa); \ - \ - CLAMP (ra, 0, 255 * 255); \ - CLAMP (rr, 0, 255 * 255); \ - CLAMP (rg, 0, 255 * 255); \ - CLAMP (rb, 0, 255 * 255); \ - \ - ra = DIV_ONE_UN8 (ra); \ - rr = DIV_ONE_UN8 (rr); \ - rg = DIV_ONE_UN8 (rg); \ - rb = DIV_ONE_UN8 (rb); \ - \ - *(dest + i) = ra << 24 | rr << 16 | rg << 8 | rb; \ - } \ - } \ - \ - static void \ - combine_ ## name ## _ca (pixman_implementation_t *imp, \ - pixman_op_t op, \ - uint32_t * dest, \ - const uint32_t * src, \ - const uint32_t * mask, \ - int width) \ - { \ - int i; \ - for (i = 0; i < width; ++i) \ - { \ - uint32_t m = *(mask + i); \ - uint32_t s = *(src + i); \ - uint32_t d = *(dest + i); \ - uint8_t da = ALPHA_8 (d); \ - uint8_t ida = ~da; \ - int32_t ra, rr, rg, rb; \ - uint8_t ira, iga, iba; \ - \ - combine_mask_ca (&s, &m); \ - \ - ira = ~RED_8 (m); \ - iga = ~GREEN_8 (m); \ - iba = ~BLUE_8 (m); \ - \ - ra = da * 0xff + ALPHA_8 (s) * 0xff - ALPHA_8 (s) * da; \ - rr = ira * RED_8 (d) + ida * RED_8 (s); \ - rg = iga * GREEN_8 (d) + ida * GREEN_8 (s); \ - rb = iba * BLUE_8 (d) + ida * BLUE_8 (s); \ - \ - rr += blend_ ## name (RED_8 (d), da, RED_8 (s), RED_8 (m)); \ - rg += blend_ ## name (GREEN_8 (d), da, GREEN_8 (s), GREEN_8 (m)); \ - rb += blend_ ## name (BLUE_8 (d), da, BLUE_8 (s), BLUE_8 (m)); \ - \ - CLAMP (ra, 0, 255 * 255); \ - CLAMP (rr, 0, 255 * 255); \ - CLAMP (rg, 0, 255 * 255); \ - CLAMP (rb, 0, 255 * 255); \ - \ - ra = DIV_ONE_UN8 (ra); \ - rr = DIV_ONE_UN8 (rr); \ - rg = DIV_ONE_UN8 (rg); \ - rb = DIV_ONE_UN8 (rb); \ - \ - *(dest + i) = ra << 24 | rr << 16 | rg << 8 | rb; \ - } \ - } - -/* - * Screen - * - * ad * as * B(d/ad, s/as) - * = ad * as * (d/ad + s/as - s/as * d/ad) - * = ad * s + as * d - s * d - */ -static inline int32_t -blend_screen (int32_t d, int32_t ad, int32_t s, int32_t as) -{ - return s * ad + d * as - s * d; -} - -PDF_SEPARABLE_BLEND_MODE (screen) - -/* - * Overlay - * - * ad * as * B(d/ad, s/as) - * = ad * as * Hardlight (s, d) - * = if (d / ad < 0.5) - * as * ad * Multiply (s/as, 2 * d/ad) - * else - * as * ad * Screen (s/as, 2 * d / ad - 1) - * = if (d < 0.5 * ad) - * as * ad * s/as * 2 * d /ad - * else - * as * ad * (s/as + 2 * d / ad - 1 - s / as * (2 * d / ad - 1)) - * = if (2 * d < ad) - * 2 * s * d - * else - * ad * s + 2 * as * d - as * ad - ad * s * (2 * d / ad - 1) - * = if (2 * d < ad) - * 2 * s * d - * else - * as * ad - 2 * (ad - d) * (as - s) - */ -static inline int32_t -blend_overlay (int32_t d, int32_t ad, int32_t s, int32_t as) -{ - uint32_t r; - - if (2 * d < ad) - r = 2 * s * d; - else - r = as * ad - 2 * (ad - d) * (as - s); - - return r; -} - -PDF_SEPARABLE_BLEND_MODE (overlay) - -/* - * Darken - * - * ad * as * B(d/ad, s/as) - * = ad * as * MIN(d/ad, s/as) - * = MIN (as * d, ad * s) - */ -static inline int32_t -blend_darken (int32_t d, int32_t ad, int32_t s, int32_t as) -{ - s = ad * s; - d = as * d; - - return s > d ? d : s; -} - -PDF_SEPARABLE_BLEND_MODE (darken) - -/* - * Lighten - * - * ad * as * B(d/ad, s/as) - * = ad * as * MAX(d/ad, s/as) - * = MAX (as * d, ad * s) - */ -static inline int32_t -blend_lighten (int32_t d, int32_t ad, int32_t s, int32_t as) -{ - s = ad * s; - d = as * d; - - return s > d ? s : d; -} - -PDF_SEPARABLE_BLEND_MODE (lighten) - -/* - * Hard light - * - * ad * as * B(d/ad, s/as) - * = if (s/as <= 0.5) - * ad * as * Multiply (d/ad, 2 * s/as) - * else - * ad * as * Screen (d/ad, 2 * s/as - 1) - * = if 2 * s <= as - * ad * as * d/ad * 2 * s / as - * else - * ad * as * (d/ad + (2 * s/as - 1) + d/ad * (2 * s/as - 1)) - * = if 2 * s <= as - * 2 * s * d - * else - * as * ad - 2 * (ad - d) * (as - s) - */ -static inline int32_t -blend_hard_light (int32_t d, int32_t ad, int32_t s, int32_t as) -{ - if (2 * s < as) - return 2 * s * d; - else - return as * ad - 2 * (ad - d) * (as - s); -} - -PDF_SEPARABLE_BLEND_MODE (hard_light) - -/* - * Difference - * - * ad * as * B(s/as, d/ad) - * = ad * as * abs (s/as - d/ad) - * = if (s/as <= d/ad) - * ad * as * (d/ad - s/as) - * else - * ad * as * (s/as - d/ad) - * = if (ad * s <= as * d) - * as * d - ad * s - * else - * ad * s - as * d - */ -static inline int32_t -blend_difference (int32_t d, int32_t ad, int32_t s, int32_t as) -{ - int32_t das = d * as; - int32_t sad = s * ad; - - if (sad < das) - return das - sad; - else - return sad - das; -} - -PDF_SEPARABLE_BLEND_MODE (difference) - -/* - * Exclusion - * - * ad * as * B(s/as, d/ad) - * = ad * as * (d/ad + s/as - 2 * d/ad * s/as) - * = as * d + ad * s - 2 * s * d - */ - -/* This can be made faster by writing it directly and not using - * PDF_SEPARABLE_BLEND_MODE, but that's a performance optimization */ - -static inline int32_t -blend_exclusion (int32_t d, int32_t ad, int32_t s, int32_t as) -{ - return s * ad + d * as - 2 * d * s; -} - -PDF_SEPARABLE_BLEND_MODE (exclusion) - -#undef PDF_SEPARABLE_BLEND_MODE - -/* Component alpha combiners */ - -static void -combine_clear_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - memset (dest, 0, width * sizeof(uint32_t)); -} - -static void -combine_src_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t s = *(src + i); - uint32_t m = *(mask + i); - - combine_mask_value_ca (&s, &m); - - *(dest + i) = s; - } -} - -static void -combine_over_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t s = *(src + i); - uint32_t m = *(mask + i); - uint32_t a; - - combine_mask_ca (&s, &m); - - a = ~m; - if (a) - { - uint32_t d = *(dest + i); - UN8x4_MUL_UN8x4_ADD_UN8x4 (d, a, s); - s = d; - } - - *(dest + i) = s; - } -} - -static void -combine_over_reverse_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t d = *(dest + i); - uint32_t a = ~d >> A_SHIFT; - - if (a) - { - uint32_t s = *(src + i); - uint32_t m = *(mask + i); - - UN8x4_MUL_UN8x4 (s, m); - UN8x4_MUL_UN8_ADD_UN8x4 (s, a, d); - - *(dest + i) = s; - } - } -} - -static void -combine_in_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t d = *(dest + i); - uint16_t a = d >> A_SHIFT; - uint32_t s = 0; - - if (a) - { - uint32_t m = *(mask + i); - - s = *(src + i); - combine_mask_value_ca (&s, &m); - - if (a != MASK) - UN8x4_MUL_UN8 (s, a); - } - - *(dest + i) = s; - } -} - -static void -combine_in_reverse_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t s = *(src + i); - uint32_t m = *(mask + i); - uint32_t a; - - combine_mask_alpha_ca (&s, &m); - - a = m; - if (a != ~0) - { - uint32_t d = 0; - - if (a) - { - d = *(dest + i); - UN8x4_MUL_UN8x4 (d, a); - } - - *(dest + i) = d; - } - } -} - -static void -combine_out_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t d = *(dest + i); - uint16_t a = ~d >> A_SHIFT; - uint32_t s = 0; - - if (a) - { - uint32_t m = *(mask + i); - - s = *(src + i); - combine_mask_value_ca (&s, &m); - - if (a != MASK) - UN8x4_MUL_UN8 (s, a); - } - - *(dest + i) = s; - } -} - -static void -combine_out_reverse_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t s = *(src + i); - uint32_t m = *(mask + i); - uint32_t a; - - combine_mask_alpha_ca (&s, &m); - - a = ~m; - if (a != ~0) - { - uint32_t d = 0; - - if (a) - { - d = *(dest + i); - UN8x4_MUL_UN8x4 (d, a); - } - - *(dest + i) = d; - } - } -} - -static void -combine_atop_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t d = *(dest + i); - uint32_t s = *(src + i); - uint32_t m = *(mask + i); - uint32_t ad; - uint16_t as = d >> A_SHIFT; - - combine_mask_ca (&s, &m); - - ad = ~m; - - UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (d, ad, s, as); - - *(dest + i) = d; - } -} - -static void -combine_atop_reverse_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t d = *(dest + i); - uint32_t s = *(src + i); - uint32_t m = *(mask + i); - uint32_t ad; - uint16_t as = ~d >> A_SHIFT; - - combine_mask_ca (&s, &m); - - ad = m; - - UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (d, ad, s, as); - - *(dest + i) = d; - } -} - -static void -combine_xor_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t d = *(dest + i); - uint32_t s = *(src + i); - uint32_t m = *(mask + i); - uint32_t ad; - uint16_t as = ~d >> A_SHIFT; - - combine_mask_ca (&s, &m); - - ad = ~m; - - UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (d, ad, s, as); - - *(dest + i) = d; - } -} - -static void -combine_add_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint32_t s = *(src + i); - uint32_t m = *(mask + i); - uint32_t d = *(dest + i); - - combine_mask_value_ca (&s, &m); - - UN8x4_ADD_UN8x4 (d, s); - - *(dest + i) = d; - } -} - -void -_pixman_setup_combiner_functions_32 (pixman_implementation_t *imp) -{ - /* Unified alpha */ - imp->combine_32[PIXMAN_OP_CLEAR] = combine_clear; - imp->combine_32[PIXMAN_OP_SRC] = combine_src_u; - imp->combine_32[PIXMAN_OP_DST] = combine_dst; - imp->combine_32[PIXMAN_OP_OVER] = combine_over_u; - imp->combine_32[PIXMAN_OP_OVER_REVERSE] = combine_over_reverse_u; - imp->combine_32[PIXMAN_OP_IN] = combine_in_u; - imp->combine_32[PIXMAN_OP_IN_REVERSE] = combine_in_reverse_u; - imp->combine_32[PIXMAN_OP_OUT] = combine_out_u; - imp->combine_32[PIXMAN_OP_OUT_REVERSE] = combine_out_reverse_u; - imp->combine_32[PIXMAN_OP_ATOP] = combine_atop_u; - imp->combine_32[PIXMAN_OP_ATOP_REVERSE] = combine_atop_reverse_u; - imp->combine_32[PIXMAN_OP_XOR] = combine_xor_u; - imp->combine_32[PIXMAN_OP_ADD] = combine_add_u; - - imp->combine_32[PIXMAN_OP_MULTIPLY] = combine_multiply_u; - imp->combine_32[PIXMAN_OP_SCREEN] = combine_screen_u; - imp->combine_32[PIXMAN_OP_OVERLAY] = combine_overlay_u; - imp->combine_32[PIXMAN_OP_DARKEN] = combine_darken_u; - imp->combine_32[PIXMAN_OP_LIGHTEN] = combine_lighten_u; - imp->combine_32[PIXMAN_OP_HARD_LIGHT] = combine_hard_light_u; - imp->combine_32[PIXMAN_OP_DIFFERENCE] = combine_difference_u; - imp->combine_32[PIXMAN_OP_EXCLUSION] = combine_exclusion_u; - - /* Component alpha combiners */ - imp->combine_32_ca[PIXMAN_OP_CLEAR] = combine_clear_ca; - imp->combine_32_ca[PIXMAN_OP_SRC] = combine_src_ca; - /* dest */ - imp->combine_32_ca[PIXMAN_OP_OVER] = combine_over_ca; - imp->combine_32_ca[PIXMAN_OP_OVER_REVERSE] = combine_over_reverse_ca; - imp->combine_32_ca[PIXMAN_OP_IN] = combine_in_ca; - imp->combine_32_ca[PIXMAN_OP_IN_REVERSE] = combine_in_reverse_ca; - imp->combine_32_ca[PIXMAN_OP_OUT] = combine_out_ca; - imp->combine_32_ca[PIXMAN_OP_OUT_REVERSE] = combine_out_reverse_ca; - imp->combine_32_ca[PIXMAN_OP_ATOP] = combine_atop_ca; - imp->combine_32_ca[PIXMAN_OP_ATOP_REVERSE] = combine_atop_reverse_ca; - imp->combine_32_ca[PIXMAN_OP_XOR] = combine_xor_ca; - imp->combine_32_ca[PIXMAN_OP_ADD] = combine_add_ca; - - imp->combine_32_ca[PIXMAN_OP_MULTIPLY] = combine_multiply_ca; - imp->combine_32_ca[PIXMAN_OP_SCREEN] = combine_screen_ca; - imp->combine_32_ca[PIXMAN_OP_OVERLAY] = combine_overlay_ca; - imp->combine_32_ca[PIXMAN_OP_DARKEN] = combine_darken_ca; - imp->combine_32_ca[PIXMAN_OP_LIGHTEN] = combine_lighten_ca; - imp->combine_32_ca[PIXMAN_OP_HARD_LIGHT] = combine_hard_light_ca; - imp->combine_32_ca[PIXMAN_OP_DIFFERENCE] = combine_difference_ca; - imp->combine_32_ca[PIXMAN_OP_EXCLUSION] = combine_exclusion_ca; -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman-combine32.h b/source/libs/pixman/pixman-src/pixman/pixman-combine32.h deleted file mode 100644 index cdd56a61a1e809058bae22919f7a5da6b1a740ec..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-combine32.h +++ /dev/null @@ -1,272 +0,0 @@ -#define COMPONENT_SIZE 8 -#define MASK 0xff -#define ONE_HALF 0x80 - -#define A_SHIFT 8 * 3 -#define R_SHIFT 8 * 2 -#define G_SHIFT 8 -#define A_MASK 0xff000000 -#define R_MASK 0xff0000 -#define G_MASK 0xff00 - -#define RB_MASK 0xff00ff -#define AG_MASK 0xff00ff00 -#define RB_ONE_HALF 0x800080 -#define RB_MASK_PLUS_ONE 0x10000100 - -#define ALPHA_8(x) ((x) >> A_SHIFT) -#define RED_8(x) (((x) >> R_SHIFT) & MASK) -#define GREEN_8(x) (((x) >> G_SHIFT) & MASK) -#define BLUE_8(x) ((x) & MASK) - -/* - * ARMv6 has UQADD8 instruction, which implements unsigned saturated - * addition for 8-bit values packed in 32-bit registers. It is very useful - * for UN8x4_ADD_UN8x4, UN8_rb_ADD_UN8_rb and ADD_UN8 macros (which would - * otherwise need a lot of arithmetic operations to simulate this operation). - * Since most of the major ARM linux distros are built for ARMv7, we are - * much less dependent on runtime CPU detection and can get practical - * benefits from conditional compilation here for a lot of users. - */ - -#if defined(USE_GCC_INLINE_ASM) && defined(__arm__) && \ - !defined(__aarch64__) && (!defined(__thumb__) || defined(__thumb2__)) -#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \ - defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || \ - defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) || \ - defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_7__) || \ - defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || \ - defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) - -static force_inline uint32_t -un8x4_add_un8x4 (uint32_t x, uint32_t y) -{ - uint32_t t; - asm ("uqadd8 %0, %1, %2" : "=r" (t) : "%r" (x), "r" (y)); - return t; -} - -#define UN8x4_ADD_UN8x4(x, y) \ - ((x) = un8x4_add_un8x4 ((x), (y))) - -#define UN8_rb_ADD_UN8_rb(x, y, t) \ - ((t) = un8x4_add_un8x4 ((x), (y)), (x) = (t)) - -#define ADD_UN8(x, y, t) \ - ((t) = (x), un8x4_add_un8x4 ((t), (y))) - -#endif -#endif - -/*****************************************************************************/ - -/* - * Helper macros. - */ - -#define MUL_UN8(a, b, t) \ - ((t) = (a) * (uint16_t)(b) + ONE_HALF, ((((t) >> G_SHIFT ) + (t) ) >> G_SHIFT )) - -#define DIV_UN8(a, b) \ - (((uint16_t) (a) * MASK + ((b) / 2)) / (b)) - -#ifndef ADD_UN8 -#define ADD_UN8(x, y, t) \ - ((t) = (x) + (y), \ - (uint32_t) (uint8_t) ((t) | (0 - ((t) >> G_SHIFT)))) -#endif - -#define DIV_ONE_UN8(x) \ - (((x) + ONE_HALF + (((x) + ONE_HALF) >> G_SHIFT)) >> G_SHIFT) - -/* - * The methods below use some tricks to be able to do two color - * components at the same time. - */ - -/* - * x_rb = (x_rb * a) / 255 - */ -#define UN8_rb_MUL_UN8(x, a, t) \ - do \ - { \ - t = ((x) & RB_MASK) * (a); \ - t += RB_ONE_HALF; \ - x = (t + ((t >> G_SHIFT) & RB_MASK)) >> G_SHIFT; \ - x &= RB_MASK; \ - } while (0) - -/* - * x_rb = min (x_rb + y_rb, 255) - */ -#ifndef UN8_rb_ADD_UN8_rb -#define UN8_rb_ADD_UN8_rb(x, y, t) \ - do \ - { \ - t = ((x) + (y)); \ - t |= RB_MASK_PLUS_ONE - ((t >> G_SHIFT) & RB_MASK); \ - x = (t & RB_MASK); \ - } while (0) -#endif - -/* - * x_rb = (x_rb * a_rb) / 255 - */ -#define UN8_rb_MUL_UN8_rb(x, a, t) \ - do \ - { \ - t = (x & MASK) * (a & MASK); \ - t |= (x & R_MASK) * ((a >> R_SHIFT) & MASK); \ - t += RB_ONE_HALF; \ - t = (t + ((t >> G_SHIFT) & RB_MASK)) >> G_SHIFT; \ - x = t & RB_MASK; \ - } while (0) - -/* - * x_c = (x_c * a) / 255 - */ -#define UN8x4_MUL_UN8(x, a) \ - do \ - { \ - uint32_t r1__, r2__, t__; \ - \ - r1__ = (x); \ - UN8_rb_MUL_UN8 (r1__, (a), t__); \ - \ - r2__ = (x) >> G_SHIFT; \ - UN8_rb_MUL_UN8 (r2__, (a), t__); \ - \ - (x) = r1__ | (r2__ << G_SHIFT); \ - } while (0) - -/* - * x_c = (x_c * a) / 255 + y_c - */ -#define UN8x4_MUL_UN8_ADD_UN8x4(x, a, y) \ - do \ - { \ - uint32_t r1__, r2__, r3__, t__; \ - \ - r1__ = (x); \ - r2__ = (y) & RB_MASK; \ - UN8_rb_MUL_UN8 (r1__, (a), t__); \ - UN8_rb_ADD_UN8_rb (r1__, r2__, t__); \ - \ - r2__ = (x) >> G_SHIFT; \ - r3__ = ((y) >> G_SHIFT) & RB_MASK; \ - UN8_rb_MUL_UN8 (r2__, (a), t__); \ - UN8_rb_ADD_UN8_rb (r2__, r3__, t__); \ - \ - (x) = r1__ | (r2__ << G_SHIFT); \ - } while (0) - -/* - * x_c = (x_c * a + y_c * b) / 255 - */ -#define UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8(x, a, y, b) \ - do \ - { \ - uint32_t r1__, r2__, r3__, t__; \ - \ - r1__ = (x); \ - r2__ = (y); \ - UN8_rb_MUL_UN8 (r1__, (a), t__); \ - UN8_rb_MUL_UN8 (r2__, (b), t__); \ - UN8_rb_ADD_UN8_rb (r1__, r2__, t__); \ - \ - r2__ = ((x) >> G_SHIFT); \ - r3__ = ((y) >> G_SHIFT); \ - UN8_rb_MUL_UN8 (r2__, (a), t__); \ - UN8_rb_MUL_UN8 (r3__, (b), t__); \ - UN8_rb_ADD_UN8_rb (r2__, r3__, t__); \ - \ - (x) = r1__ | (r2__ << G_SHIFT); \ - } while (0) - -/* - * x_c = (x_c * a_c) / 255 - */ -#define UN8x4_MUL_UN8x4(x, a) \ - do \ - { \ - uint32_t r1__, r2__, r3__, t__; \ - \ - r1__ = (x); \ - r2__ = (a); \ - UN8_rb_MUL_UN8_rb (r1__, r2__, t__); \ - \ - r2__ = (x) >> G_SHIFT; \ - r3__ = (a) >> G_SHIFT; \ - UN8_rb_MUL_UN8_rb (r2__, r3__, t__); \ - \ - (x) = r1__ | (r2__ << G_SHIFT); \ - } while (0) - -/* - * x_c = (x_c * a_c) / 255 + y_c - */ -#define UN8x4_MUL_UN8x4_ADD_UN8x4(x, a, y) \ - do \ - { \ - uint32_t r1__, r2__, r3__, t__; \ - \ - r1__ = (x); \ - r2__ = (a); \ - UN8_rb_MUL_UN8_rb (r1__, r2__, t__); \ - r2__ = (y) & RB_MASK; \ - UN8_rb_ADD_UN8_rb (r1__, r2__, t__); \ - \ - r2__ = ((x) >> G_SHIFT); \ - r3__ = ((a) >> G_SHIFT); \ - UN8_rb_MUL_UN8_rb (r2__, r3__, t__); \ - r3__ = ((y) >> G_SHIFT) & RB_MASK; \ - UN8_rb_ADD_UN8_rb (r2__, r3__, t__); \ - \ - (x) = r1__ | (r2__ << G_SHIFT); \ - } while (0) - -/* - * x_c = (x_c * a_c + y_c * b) / 255 - */ -#define UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8(x, a, y, b) \ - do \ - { \ - uint32_t r1__, r2__, r3__, t__; \ - \ - r1__ = (x); \ - r2__ = (a); \ - UN8_rb_MUL_UN8_rb (r1__, r2__, t__); \ - r2__ = (y); \ - UN8_rb_MUL_UN8 (r2__, (b), t__); \ - UN8_rb_ADD_UN8_rb (r1__, r2__, t__); \ - \ - r2__ = (x) >> G_SHIFT; \ - r3__ = (a) >> G_SHIFT; \ - UN8_rb_MUL_UN8_rb (r2__, r3__, t__); \ - r3__ = (y) >> G_SHIFT; \ - UN8_rb_MUL_UN8 (r3__, (b), t__); \ - UN8_rb_ADD_UN8_rb (r2__, r3__, t__); \ - \ - x = r1__ | (r2__ << G_SHIFT); \ - } while (0) - -/* - x_c = min(x_c + y_c, 255) -*/ -#ifndef UN8x4_ADD_UN8x4 -#define UN8x4_ADD_UN8x4(x, y) \ - do \ - { \ - uint32_t r1__, r2__, r3__, t__; \ - \ - r1__ = (x) & RB_MASK; \ - r2__ = (y) & RB_MASK; \ - UN8_rb_ADD_UN8_rb (r1__, r2__, t__); \ - \ - r2__ = ((x) >> G_SHIFT) & RB_MASK; \ - r3__ = ((y) >> G_SHIFT) & RB_MASK; \ - UN8_rb_ADD_UN8_rb (r2__, r3__, t__); \ - \ - x = r1__ | (r2__ << G_SHIFT); \ - } while (0) -#endif diff --git a/source/libs/pixman/pixman-src/pixman/pixman-compiler.h b/source/libs/pixman/pixman-src/pixman/pixman-compiler.h deleted file mode 100644 index eb97acdbd0c3e2d9b913534ca54015972bce0db6..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-compiler.h +++ /dev/null @@ -1,232 +0,0 @@ -/* Pixman uses some non-standard compiler features. This file ensures - * they exist - * - * The features are: - * - * FUNC must be defined to expand to the current function - * PIXMAN_EXPORT should be defined to whatever is required to - * export functions from a shared library - * limits limits for various types must be defined - * inline must be defined - * force_inline must be defined - */ -#if defined (__GNUC__) -# define FUNC ((const char*) (__PRETTY_FUNCTION__)) -#elif defined (__sun) || (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) -# define FUNC ((const char*) (__func__)) -#else -# define FUNC ((const char*) ("???")) -#endif - -#if defined (__GNUC__) -# define unlikely(expr) __builtin_expect ((expr), 0) -#else -# define unlikely(expr) (expr) -#endif - -#if defined (__GNUC__) -# define MAYBE_UNUSED __attribute__((unused)) -#else -# define MAYBE_UNUSED -#endif - -#ifndef INT16_MIN -# define INT16_MIN (-32767-1) -#endif - -#ifndef INT16_MAX -# define INT16_MAX (32767) -#endif - -#ifndef INT32_MIN -# define INT32_MIN (-2147483647-1) -#endif - -#ifndef INT32_MAX -# define INT32_MAX (2147483647) -#endif - -#ifndef UINT32_MIN -# define UINT32_MIN (0) -#endif - -#ifndef UINT32_MAX -# define UINT32_MAX (4294967295U) -#endif - -#ifndef INT64_MIN -# define INT64_MIN (-9223372036854775807-1) -#endif - -#ifndef INT64_MAX -# define INT64_MAX (9223372036854775807) -#endif - -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t)-1) -#endif - - -#ifndef M_PI -# define M_PI 3.14159265358979323846 -#endif - -#ifdef _MSC_VER -/* 'inline' is available only in C++ in MSVC */ -# define inline __inline -# define force_inline __forceinline -# define noinline __declspec(noinline) -#elif defined __GNUC__ || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) -# define inline __inline__ -# define force_inline __inline__ __attribute__ ((__always_inline__)) -# define noinline __attribute__((noinline)) -#else -# ifndef force_inline -# define force_inline inline -# endif -# ifndef noinline -# define noinline -# endif -#endif - -/* GCC visibility */ -#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(_WIN32) -# define PIXMAN_EXPORT -/* Sun Studio 8 visibility */ -#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) -# define PIXMAN_EXPORT __global -#else -# define PIXMAN_EXPORT -#endif - -/* member offsets */ -#define CONTAINER_OF(type, member, data) \ - ((type *)(((uint8_t *)data) - offsetof (type, member))) - -/* TLS */ -#if defined(PIXMAN_NO_TLS) - -# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ - static type name -# define PIXMAN_GET_THREAD_LOCAL(name) \ - (&name) - -#elif defined(TLS) - -# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ - static TLS type name -# define PIXMAN_GET_THREAD_LOCAL(name) \ - (&name) - -#elif defined(__MINGW32__) - -# define _NO_W32_PSEUDO_MODIFIERS -# include <windows.h> - -# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ - static volatile int tls_ ## name ## _initialized = 0; \ - static void *tls_ ## name ## _mutex = NULL; \ - static unsigned tls_ ## name ## _index; \ - \ - static type * \ - tls_ ## name ## _alloc (void) \ - { \ - type *value = calloc (1, sizeof (type)); \ - if (value) \ - TlsSetValue (tls_ ## name ## _index, value); \ - return value; \ - } \ - \ - static force_inline type * \ - tls_ ## name ## _get (void) \ - { \ - type *value; \ - if (!tls_ ## name ## _initialized) \ - { \ - if (!tls_ ## name ## _mutex) \ - { \ - void *mutex = CreateMutexA (NULL, 0, NULL); \ - if (InterlockedCompareExchangePointer ( \ - &tls_ ## name ## _mutex, mutex, NULL) != NULL) \ - { \ - CloseHandle (mutex); \ - } \ - } \ - WaitForSingleObject (tls_ ## name ## _mutex, 0xFFFFFFFF); \ - if (!tls_ ## name ## _initialized) \ - { \ - tls_ ## name ## _index = TlsAlloc (); \ - tls_ ## name ## _initialized = 1; \ - } \ - ReleaseMutex (tls_ ## name ## _mutex); \ - } \ - if (tls_ ## name ## _index == 0xFFFFFFFF) \ - return NULL; \ - value = TlsGetValue (tls_ ## name ## _index); \ - if (!value) \ - value = tls_ ## name ## _alloc (); \ - return value; \ - } - -# define PIXMAN_GET_THREAD_LOCAL(name) \ - tls_ ## name ## _get () - -#elif defined(_MSC_VER) - -# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ - static __declspec(thread) type name -# define PIXMAN_GET_THREAD_LOCAL(name) \ - (&name) - -#elif defined(HAVE_PTHREADS) - -#include <pthread.h> - -# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ - static pthread_once_t tls_ ## name ## _once_control = PTHREAD_ONCE_INIT; \ - static pthread_key_t tls_ ## name ## _key; \ - \ - static void \ - tls_ ## name ## _destroy_value (void *value) \ - { \ - free (value); \ - } \ - \ - static void \ - tls_ ## name ## _make_key (void) \ - { \ - pthread_key_create (&tls_ ## name ## _key, \ - tls_ ## name ## _destroy_value); \ - } \ - \ - static type * \ - tls_ ## name ## _alloc (void) \ - { \ - type *value = calloc (1, sizeof (type)); \ - if (value) \ - pthread_setspecific (tls_ ## name ## _key, value); \ - return value; \ - } \ - \ - static force_inline type * \ - tls_ ## name ## _get (void) \ - { \ - type *value = NULL; \ - if (pthread_once (&tls_ ## name ## _once_control, \ - tls_ ## name ## _make_key) == 0) \ - { \ - value = pthread_getspecific (tls_ ## name ## _key); \ - if (!value) \ - value = tls_ ## name ## _alloc (); \ - } \ - return value; \ - } - -# define PIXMAN_GET_THREAD_LOCAL(name) \ - tls_ ## name ## _get () - -#else - -# error "Unknown thread local support for this system. Pixman will not work with multiple threads. Define PIXMAN_NO_TLS to acknowledge and accept this limitation and compile pixman without thread-safety support." - -#endif diff --git a/source/libs/pixman/pixman-src/pixman/pixman-conical-gradient.c b/source/libs/pixman/pixman-src/pixman/pixman-conical-gradient.c deleted file mode 100644 index 8bb46aecdcab60d6118a260f602dac996953874b..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-conical-gradient.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright © 2000 SuSE, Inc. - * Copyright © 2007 Red Hat, Inc. - * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. - * 2005 Lars Knoll & Zack Rusin, Trolltech - * - * 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 Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <math.h> -#include "pixman-private.h" - -static force_inline double -coordinates_to_parameter (double x, double y, double angle) -{ - double t; - - t = atan2 (y, x) + angle; - - while (t < 0) - t += 2 * M_PI; - - while (t >= 2 * M_PI) - t -= 2 * M_PI; - - return 1 - t * (1 / (2 * M_PI)); /* Scale t to [0, 1] and - * make rotation CCW - */ -} - -static uint32_t * -conical_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) -{ - pixman_image_t *image = iter->image; - int x = iter->x; - int y = iter->y; - int width = iter->width; - uint32_t *buffer = iter->buffer; - - gradient_t *gradient = (gradient_t *)image; - conical_gradient_t *conical = (conical_gradient_t *)image; - uint32_t *end = buffer + width; - pixman_gradient_walker_t walker; - pixman_bool_t affine = TRUE; - double cx = 1.; - double cy = 0.; - double cz = 0.; - double rx = x + 0.5; - double ry = y + 0.5; - double rz = 1.; - - _pixman_gradient_walker_init (&walker, gradient, image->common.repeat); - - if (image->common.transform) - { - pixman_vector_t v; - - /* reference point is the center of the pixel */ - v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2; - v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2; - v.vector[2] = pixman_fixed_1; - - if (!pixman_transform_point_3d (image->common.transform, &v)) - return iter->buffer; - - cx = image->common.transform->matrix[0][0] / 65536.; - cy = image->common.transform->matrix[1][0] / 65536.; - cz = image->common.transform->matrix[2][0] / 65536.; - - rx = v.vector[0] / 65536.; - ry = v.vector[1] / 65536.; - rz = v.vector[2] / 65536.; - - affine = - image->common.transform->matrix[2][0] == 0 && - v.vector[2] == pixman_fixed_1; - } - - if (affine) - { - rx -= conical->center.x / 65536.; - ry -= conical->center.y / 65536.; - - while (buffer < end) - { - if (!mask || *mask++) - { - double t = coordinates_to_parameter (rx, ry, conical->angle); - - *buffer = _pixman_gradient_walker_pixel ( - &walker, (pixman_fixed_48_16_t)pixman_double_to_fixed (t)); - } - - ++buffer; - - rx += cx; - ry += cy; - } - } - else - { - while (buffer < end) - { - double x, y; - - if (!mask || *mask++) - { - double t; - - if (rz != 0) - { - x = rx / rz; - y = ry / rz; - } - else - { - x = y = 0.; - } - - x -= conical->center.x / 65536.; - y -= conical->center.y / 65536.; - - t = coordinates_to_parameter (x, y, conical->angle); - - *buffer = _pixman_gradient_walker_pixel ( - &walker, (pixman_fixed_48_16_t)pixman_double_to_fixed (t)); - } - - ++buffer; - - rx += cx; - ry += cy; - rz += cz; - } - } - - iter->y++; - return iter->buffer; -} - -static uint32_t * -conical_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) -{ - uint32_t *buffer = conical_get_scanline_narrow (iter, NULL); - - pixman_expand_to_float ( - (argb_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); - - return buffer; -} - -void -_pixman_conical_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter) -{ - if (iter->iter_flags & ITER_NARROW) - iter->get_scanline = conical_get_scanline_narrow; - else - iter->get_scanline = conical_get_scanline_wide; -} - -PIXMAN_EXPORT pixman_image_t * -pixman_image_create_conical_gradient (const pixman_point_fixed_t * center, - pixman_fixed_t angle, - const pixman_gradient_stop_t *stops, - int n_stops) -{ - pixman_image_t *image = _pixman_image_allocate (); - conical_gradient_t *conical; - - if (!image) - return NULL; - - conical = &image->conical; - - if (!_pixman_init_gradient (&conical->common, stops, n_stops)) - { - free (image); - return NULL; - } - - angle = MOD (angle, pixman_int_to_fixed (360)); - - image->type = CONICAL; - - conical->center = *center; - conical->angle = (pixman_fixed_to_double (angle) / 180.0) * M_PI; - - return image; -} - diff --git a/source/libs/pixman/pixman-src/pixman/pixman-edge-accessors.c b/source/libs/pixman/pixman-src/pixman/pixman-edge-accessors.c deleted file mode 100644 index ea3a31e2f528dfbed91eacc04b79094c67dbe7e6..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-edge-accessors.c +++ /dev/null @@ -1,4 +0,0 @@ - -#define PIXMAN_FB_ACCESSORS - -#include "pixman-edge.c" diff --git a/source/libs/pixman/pixman-src/pixman/pixman-edge-imp.h b/source/libs/pixman/pixman-src/pixman/pixman-edge-imp.h deleted file mode 100644 index a4698eddb2819a1e85f5613f5dd99d7fcb633615..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-edge-imp.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright © 2004 Keith Packard - * - * 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 Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD 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. - */ - -#ifndef rasterize_span -#endif - -static void -RASTERIZE_EDGES (pixman_image_t *image, - pixman_edge_t *l, - pixman_edge_t *r, - pixman_fixed_t t, - pixman_fixed_t b) -{ - pixman_fixed_t y = t; - uint32_t *line; - uint32_t *buf = (image)->bits.bits; - int stride = (image)->bits.rowstride; - int width = (image)->bits.width; - - line = buf + pixman_fixed_to_int (y) * stride; - - for (;;) - { - pixman_fixed_t lx; - pixman_fixed_t rx; - int lxi; - int rxi; - - lx = l->x; - rx = r->x; -#if N_BITS == 1 - /* For the non-antialiased case, round the coordinates up, in effect - * sampling just slightly to the left of the pixel. This is so that - * when the sample point lies exactly on the line, we round towards - * north-west. - * - * (The AA case does a similar adjustment in RENDER_SAMPLES_X) - */ - lx += X_FRAC_FIRST(1) - pixman_fixed_e; - rx += X_FRAC_FIRST(1) - pixman_fixed_e; -#endif - /* clip X */ - if (lx < 0) - lx = 0; - if (pixman_fixed_to_int (rx) >= width) -#if N_BITS == 1 - rx = pixman_int_to_fixed (width); -#else - /* Use the last pixel of the scanline, covered 100%. - * We can't use the first pixel following the scanline, - * because accessing it could result in a buffer overrun. - */ - rx = pixman_int_to_fixed (width) - 1; -#endif - - /* Skip empty (or backwards) sections */ - if (rx > lx) - { - - /* Find pixel bounds for span */ - lxi = pixman_fixed_to_int (lx); - rxi = pixman_fixed_to_int (rx); - -#if N_BITS == 1 - { - -#define LEFT_MASK(x) \ - (((x) & 0x1f) ? \ - SCREEN_SHIFT_RIGHT (0xffffffff, (x) & 0x1f) : 0) -#define RIGHT_MASK(x) \ - (((32 - (x)) & 0x1f) ? \ - SCREEN_SHIFT_LEFT (0xffffffff, (32 - (x)) & 0x1f) : 0) - -#define MASK_BITS(x,w,l,n,r) { \ - n = (w); \ - r = RIGHT_MASK ((x) + n); \ - l = LEFT_MASK (x); \ - if (l) { \ - n -= 32 - ((x) & 0x1f); \ - if (n < 0) { \ - n = 0; \ - l &= r; \ - r = 0; \ - } \ - } \ - n >>= 5; \ - } - - uint32_t *a = line; - uint32_t startmask; - uint32_t endmask; - int nmiddle; - int width = rxi - lxi; - int x = lxi; - - a += x >> 5; - x &= 0x1f; - - MASK_BITS (x, width, startmask, nmiddle, endmask); - - if (startmask) { - WRITE(image, a, READ(image, a) | startmask); - a++; - } - while (nmiddle--) - WRITE(image, a++, 0xffffffff); - if (endmask) - WRITE(image, a, READ(image, a) | endmask); - } -#else - { - DEFINE_ALPHA(line,lxi); - int lxs; - int rxs; - - /* Sample coverage for edge pixels */ - lxs = RENDER_SAMPLES_X (lx, N_BITS); - rxs = RENDER_SAMPLES_X (rx, N_BITS); - - /* Add coverage across row */ - if (lxi == rxi) - { - ADD_ALPHA (rxs - lxs); - } - else - { - int xi; - - ADD_ALPHA (N_X_FRAC(N_BITS) - lxs); - STEP_ALPHA; - for (xi = lxi + 1; xi < rxi; xi++) - { - ADD_ALPHA (N_X_FRAC(N_BITS)); - STEP_ALPHA; - } - ADD_ALPHA (rxs); - } - } -#endif - } - - if (y == b) - break; - -#if N_BITS > 1 - if (pixman_fixed_frac (y) != Y_FRAC_LAST(N_BITS)) - { - RENDER_EDGE_STEP_SMALL (l); - RENDER_EDGE_STEP_SMALL (r); - y += STEP_Y_SMALL(N_BITS); - } - else -#endif - { - RENDER_EDGE_STEP_BIG (l); - RENDER_EDGE_STEP_BIG (r); - y += STEP_Y_BIG(N_BITS); - line += stride; - } - } -} - -#undef rasterize_span diff --git a/source/libs/pixman/pixman-src/pixman/pixman-edge.c b/source/libs/pixman/pixman-src/pixman/pixman-edge.c deleted file mode 100644 index ad6dfc4cfaf97db27e69210d77344ec7c984a24c..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-edge.c +++ /dev/null @@ -1,385 +0,0 @@ -/* - * Copyright © 2004 Keith Packard - * - * 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 Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD 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. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include "pixman-private.h" -#include "pixman-accessor.h" - -/* - * Step across a small sample grid gap - */ -#define RENDER_EDGE_STEP_SMALL(edge) \ - { \ - edge->x += edge->stepx_small; \ - edge->e += edge->dx_small; \ - if (edge->e > 0) \ - { \ - edge->e -= edge->dy; \ - edge->x += edge->signdx; \ - } \ - } - -/* - * Step across a large sample grid gap - */ -#define RENDER_EDGE_STEP_BIG(edge) \ - { \ - edge->x += edge->stepx_big; \ - edge->e += edge->dx_big; \ - if (edge->e > 0) \ - { \ - edge->e -= edge->dy; \ - edge->x += edge->signdx; \ - } \ - } - -#ifdef PIXMAN_FB_ACCESSORS -#define PIXMAN_RASTERIZE_EDGES pixman_rasterize_edges_accessors -#else -#define PIXMAN_RASTERIZE_EDGES pixman_rasterize_edges_no_accessors -#endif - -/* - * 4 bit alpha - */ - -#define N_BITS 4 -#define RASTERIZE_EDGES rasterize_edges_4 - -#ifndef WORDS_BIGENDIAN -#define SHIFT_4(o) ((o) << 2) -#else -#define SHIFT_4(o) ((1 - (o)) << 2) -#endif - -#define GET_4(x, o) (((x) >> SHIFT_4 (o)) & 0xf) -#define PUT_4(x, o, v) \ - (((x) & ~(0xf << SHIFT_4 (o))) | (((v) & 0xf) << SHIFT_4 (o))) - -#define DEFINE_ALPHA(line, x) \ - uint8_t *__ap = (uint8_t *) line + ((x) >> 1); \ - int __ao = (x) & 1 - -#define STEP_ALPHA ((__ap += __ao), (__ao ^= 1)) - -#define ADD_ALPHA(a) \ - { \ - uint8_t __o = READ (image, __ap); \ - uint8_t __a = (a) + GET_4 (__o, __ao); \ - WRITE (image, __ap, PUT_4 (__o, __ao, __a | (0 - ((__a) >> 4)))); \ - } - -#include "pixman-edge-imp.h" - -#undef ADD_ALPHA -#undef STEP_ALPHA -#undef DEFINE_ALPHA -#undef RASTERIZE_EDGES -#undef N_BITS - - -/* - * 1 bit alpha - */ - -#define N_BITS 1 -#define RASTERIZE_EDGES rasterize_edges_1 - -#include "pixman-edge-imp.h" - -#undef RASTERIZE_EDGES -#undef N_BITS - -/* - * 8 bit alpha - */ - -static force_inline uint8_t -clip255 (int x) -{ - if (x > 255) - return 255; - - return x; -} - -#define ADD_SATURATE_8(buf, val, length) \ - do \ - { \ - int i__ = (length); \ - uint8_t *buf__ = (buf); \ - int val__ = (val); \ - \ - while (i__--) \ - { \ - WRITE (image, (buf__), clip255 (READ (image, (buf__)) + (val__))); \ - (buf__)++; \ - } \ - } while (0) - -/* - * We want to detect the case where we add the same value to a long - * span of pixels. The triangles on the end are filled in while we - * count how many sub-pixel scanlines contribute to the middle section. - * - * +--------------------------+ - * fill_height =| \ / - * +------------------+ - * |================| - * fill_start fill_end - */ -static void -rasterize_edges_8 (pixman_image_t *image, - pixman_edge_t * l, - pixman_edge_t * r, - pixman_fixed_t t, - pixman_fixed_t b) -{ - pixman_fixed_t y = t; - uint32_t *line; - int fill_start = -1, fill_end = -1; - int fill_size = 0; - uint32_t *buf = (image)->bits.bits; - int stride = (image)->bits.rowstride; - int width = (image)->bits.width; - - line = buf + pixman_fixed_to_int (y) * stride; - - for (;;) - { - uint8_t *ap = (uint8_t *) line; - pixman_fixed_t lx, rx; - int lxi, rxi; - - /* clip X */ - lx = l->x; - if (lx < 0) - lx = 0; - - rx = r->x; - - if (pixman_fixed_to_int (rx) >= width) - { - /* Use the last pixel of the scanline, covered 100%. - * We can't use the first pixel following the scanline, - * because accessing it could result in a buffer overrun. - */ - rx = pixman_int_to_fixed (width) - 1; - } - - /* Skip empty (or backwards) sections */ - if (rx > lx) - { - int lxs, rxs; - - /* Find pixel bounds for span. */ - lxi = pixman_fixed_to_int (lx); - rxi = pixman_fixed_to_int (rx); - - /* Sample coverage for edge pixels */ - lxs = RENDER_SAMPLES_X (lx, 8); - rxs = RENDER_SAMPLES_X (rx, 8); - - /* Add coverage across row */ - if (lxi == rxi) - { - WRITE (image, ap + lxi, - clip255 (READ (image, ap + lxi) + rxs - lxs)); - } - else - { - WRITE (image, ap + lxi, - clip255 (READ (image, ap + lxi) + N_X_FRAC (8) - lxs)); - - /* Move forward so that lxi/rxi is the pixel span */ - lxi++; - - /* Don't bother trying to optimize the fill unless - * the span is longer than 4 pixels. */ - if (rxi - lxi > 4) - { - if (fill_start < 0) - { - fill_start = lxi; - fill_end = rxi; - fill_size++; - } - else - { - if (lxi >= fill_end || rxi < fill_start) - { - /* We're beyond what we saved, just fill it */ - ADD_SATURATE_8 (ap + fill_start, - fill_size * N_X_FRAC (8), - fill_end - fill_start); - fill_start = lxi; - fill_end = rxi; - fill_size = 1; - } - else - { - /* Update fill_start */ - if (lxi > fill_start) - { - ADD_SATURATE_8 (ap + fill_start, - fill_size * N_X_FRAC (8), - lxi - fill_start); - fill_start = lxi; - } - else if (lxi < fill_start) - { - ADD_SATURATE_8 (ap + lxi, N_X_FRAC (8), - fill_start - lxi); - } - - /* Update fill_end */ - if (rxi < fill_end) - { - ADD_SATURATE_8 (ap + rxi, - fill_size * N_X_FRAC (8), - fill_end - rxi); - fill_end = rxi; - } - else if (fill_end < rxi) - { - ADD_SATURATE_8 (ap + fill_end, - N_X_FRAC (8), - rxi - fill_end); - } - fill_size++; - } - } - } - else - { - ADD_SATURATE_8 (ap + lxi, N_X_FRAC (8), rxi - lxi); - } - - WRITE (image, ap + rxi, clip255 (READ (image, ap + rxi) + rxs)); - } - } - - if (y == b) - { - /* We're done, make sure we clean up any remaining fill. */ - if (fill_start != fill_end) - { - if (fill_size == N_Y_FRAC (8)) - { - MEMSET_WRAPPED (image, ap + fill_start, - 0xff, fill_end - fill_start); - } - else - { - ADD_SATURATE_8 (ap + fill_start, fill_size * N_X_FRAC (8), - fill_end - fill_start); - } - } - break; - } - - if (pixman_fixed_frac (y) != Y_FRAC_LAST (8)) - { - RENDER_EDGE_STEP_SMALL (l); - RENDER_EDGE_STEP_SMALL (r); - y += STEP_Y_SMALL (8); - } - else - { - RENDER_EDGE_STEP_BIG (l); - RENDER_EDGE_STEP_BIG (r); - y += STEP_Y_BIG (8); - if (fill_start != fill_end) - { - if (fill_size == N_Y_FRAC (8)) - { - MEMSET_WRAPPED (image, ap + fill_start, - 0xff, fill_end - fill_start); - } - else - { - ADD_SATURATE_8 (ap + fill_start, fill_size * N_X_FRAC (8), - fill_end - fill_start); - } - - fill_start = fill_end = -1; - fill_size = 0; - } - - line += stride; - } - } -} - -#ifndef PIXMAN_FB_ACCESSORS -static -#endif -void -PIXMAN_RASTERIZE_EDGES (pixman_image_t *image, - pixman_edge_t * l, - pixman_edge_t * r, - pixman_fixed_t t, - pixman_fixed_t b) -{ - switch (PIXMAN_FORMAT_BPP (image->bits.format)) - { - case 1: - rasterize_edges_1 (image, l, r, t, b); - break; - - case 4: - rasterize_edges_4 (image, l, r, t, b); - break; - - case 8: - rasterize_edges_8 (image, l, r, t, b); - break; - - default: - break; - } -} - -#ifndef PIXMAN_FB_ACCESSORS - -PIXMAN_EXPORT void -pixman_rasterize_edges (pixman_image_t *image, - pixman_edge_t * l, - pixman_edge_t * r, - pixman_fixed_t t, - pixman_fixed_t b) -{ - return_if_fail (image->type == BITS); - return_if_fail (PIXMAN_FORMAT_TYPE (image->bits.format) == PIXMAN_TYPE_A); - - if (image->bits.read_func || image->bits.write_func) - pixman_rasterize_edges_accessors (image, l, r, t, b); - else - pixman_rasterize_edges_no_accessors (image, l, r, t, b); -} - -#endif diff --git a/source/libs/pixman/pixman-src/pixman/pixman-fast-path.c b/source/libs/pixman/pixman-src/pixman/pixman-fast-path.c deleted file mode 100644 index 53d4a1f9047a2803ce31326a9b8a8e6a30d1e85e..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-fast-path.c +++ /dev/null @@ -1,3294 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */ -/* - * Copyright © 2000 SuSE, Inc. - * Copyright © 2007 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 SuSE not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. SuSE makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE - * 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: Keith Packard, SuSE, Inc. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <string.h> -#include <stdlib.h> -#include "pixman-private.h" -#include "pixman-combine32.h" -#include "pixman-inlines.h" - -static force_inline uint32_t -fetch_24 (uint8_t *a) -{ - if (((uintptr_t)a) & 1) - { -#ifdef WORDS_BIGENDIAN - return (*a << 16) | (*(uint16_t *)(a + 1)); -#else - return *a | (*(uint16_t *)(a + 1) << 8); -#endif - } - else - { -#ifdef WORDS_BIGENDIAN - return (*(uint16_t *)a << 8) | *(a + 2); -#else - return *(uint16_t *)a | (*(a + 2) << 16); -#endif - } -} - -static force_inline void -store_24 (uint8_t *a, - uint32_t v) -{ - if (((uintptr_t)a) & 1) - { -#ifdef WORDS_BIGENDIAN - *a = (uint8_t) (v >> 16); - *(uint16_t *)(a + 1) = (uint16_t) (v); -#else - *a = (uint8_t) (v); - *(uint16_t *)(a + 1) = (uint16_t) (v >> 8); -#endif - } - else - { -#ifdef WORDS_BIGENDIAN - *(uint16_t *)a = (uint16_t)(v >> 8); - *(a + 2) = (uint8_t)v; -#else - *(uint16_t *)a = (uint16_t)v; - *(a + 2) = (uint8_t)(v >> 16); -#endif - } -} - -static force_inline uint32_t -over (uint32_t src, - uint32_t dest) -{ - uint32_t a = ~src >> 24; - - UN8x4_MUL_UN8_ADD_UN8x4 (dest, a, src); - - return dest; -} - -static force_inline uint32_t -in (uint32_t x, - uint8_t y) -{ - uint16_t a = y; - - UN8x4_MUL_UN8 (x, a); - - return x; -} - -/* - * Naming convention: - * - * op_src_mask_dest - */ -static void -fast_composite_over_x888_8_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t *src, *src_line; - uint32_t *dst, *dst_line; - uint8_t *mask, *mask_line; - int src_stride, mask_stride, dst_stride; - uint8_t m; - uint32_t s, d; - int32_t w; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - - while (height--) - { - src = src_line; - src_line += src_stride; - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - - w = width; - while (w--) - { - m = *mask++; - if (m) - { - s = *src | 0xff000000; - - if (m == 0xff) - { - *dst = s; - } - else - { - d = in (s, m); - *dst = over (d, *dst); - } - } - src++; - dst++; - } - } -} - -static void -fast_composite_in_n_8_8 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src, srca; - uint8_t *dst_line, *dst; - uint8_t *mask_line, *mask, m; - int dst_stride, mask_stride; - int32_t w; - uint16_t t; - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - srca = src >> 24; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); - - if (srca == 0xff) - { - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - w = width; - - while (w--) - { - m = *mask++; - - if (m == 0) - *dst = 0; - else if (m != 0xff) - *dst = MUL_UN8 (m, *dst, t); - - dst++; - } - } - } - else - { - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - w = width; - - while (w--) - { - m = *mask++; - m = MUL_UN8 (m, srca, t); - - if (m == 0) - *dst = 0; - else if (m != 0xff) - *dst = MUL_UN8 (m, *dst, t); - - dst++; - } - } - } -} - -static void -fast_composite_in_8_8 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint8_t *dst_line, *dst; - uint8_t *src_line, *src; - int dst_stride, src_stride; - int32_t w; - uint8_t s; - uint16_t t; - - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint8_t, src_stride, src_line, 1); - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - while (w--) - { - s = *src++; - - if (s == 0) - *dst = 0; - else if (s != 0xff) - *dst = MUL_UN8 (s, *dst, t); - - dst++; - } - } -} - -static void -fast_composite_over_n_8_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src, srca; - uint32_t *dst_line, *dst, d; - uint8_t *mask_line, *mask, m; - int dst_stride, mask_stride; - int32_t w; - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - srca = src >> 24; - if (src == 0) - return; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - w = width; - - while (w--) - { - m = *mask++; - if (m == 0xff) - { - if (srca == 0xff) - *dst = src; - else - *dst = over (src, *dst); - } - else if (m) - { - d = in (src, m); - *dst = over (d, *dst); - } - dst++; - } - } -} - -static void -fast_composite_add_n_8888_8888_ca (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src, s; - uint32_t *dst_line, *dst, d; - uint32_t *mask_line, *mask, ma; - int dst_stride, mask_stride; - int32_t w; - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - if (src == 0) - return; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint32_t, mask_stride, mask_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - w = width; - - while (w--) - { - ma = *mask++; - - if (ma) - { - d = *dst; - s = src; - - UN8x4_MUL_UN8x4_ADD_UN8x4 (s, ma, d); - - *dst = s; - } - - dst++; - } - } -} - -static void -fast_composite_over_n_8888_8888_ca (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src, srca, s; - uint32_t *dst_line, *dst, d; - uint32_t *mask_line, *mask, ma; - int dst_stride, mask_stride; - int32_t w; - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - srca = src >> 24; - if (src == 0) - return; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint32_t, mask_stride, mask_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - w = width; - - while (w--) - { - ma = *mask++; - if (ma == 0xffffffff) - { - if (srca == 0xff) - *dst = src; - else - *dst = over (src, *dst); - } - else if (ma) - { - d = *dst; - s = src; - - UN8x4_MUL_UN8x4 (s, ma); - UN8x4_MUL_UN8 (ma, srca); - ma = ~ma; - UN8x4_MUL_UN8x4_ADD_UN8x4 (d, ma, s); - - *dst = d; - } - - dst++; - } - } -} - -static void -fast_composite_over_n_8_0888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src, srca; - uint8_t *dst_line, *dst; - uint32_t d; - uint8_t *mask_line, *mask, m; - int dst_stride, mask_stride; - int32_t w; - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - srca = src >> 24; - if (src == 0) - return; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 3); - PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - w = width; - - while (w--) - { - m = *mask++; - if (m == 0xff) - { - if (srca == 0xff) - { - d = src; - } - else - { - d = fetch_24 (dst); - d = over (src, d); - } - store_24 (dst, d); - } - else if (m) - { - d = over (in (src, m), fetch_24 (dst)); - store_24 (dst, d); - } - dst += 3; - } - } -} - -static void -fast_composite_over_n_8_0565 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src, srca; - uint16_t *dst_line, *dst; - uint32_t d; - uint8_t *mask_line, *mask, m; - int dst_stride, mask_stride; - int32_t w; - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - srca = src >> 24; - if (src == 0) - return; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - w = width; - - while (w--) - { - m = *mask++; - if (m == 0xff) - { - if (srca == 0xff) - { - d = src; - } - else - { - d = *dst; - d = over (src, convert_0565_to_0888 (d)); - } - *dst = convert_8888_to_0565 (d); - } - else if (m) - { - d = *dst; - d = over (in (src, m), convert_0565_to_0888 (d)); - *dst = convert_8888_to_0565 (d); - } - dst++; - } - } -} - -static void -fast_composite_over_n_8888_0565_ca (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src, srca, s; - uint16_t src16; - uint16_t *dst_line, *dst; - uint32_t d; - uint32_t *mask_line, *mask, ma; - int dst_stride, mask_stride; - int32_t w; - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - srca = src >> 24; - if (src == 0) - return; - - src16 = convert_8888_to_0565 (src); - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint32_t, mask_stride, mask_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - w = width; - - while (w--) - { - ma = *mask++; - if (ma == 0xffffffff) - { - if (srca == 0xff) - { - *dst = src16; - } - else - { - d = *dst; - d = over (src, convert_0565_to_0888 (d)); - *dst = convert_8888_to_0565 (d); - } - } - else if (ma) - { - d = *dst; - d = convert_0565_to_0888 (d); - - s = src; - - UN8x4_MUL_UN8x4 (s, ma); - UN8x4_MUL_UN8 (ma, srca); - ma = ~ma; - UN8x4_MUL_UN8x4_ADD_UN8x4 (d, ma, s); - - *dst = convert_8888_to_0565 (d); - } - dst++; - } - } -} - -static void -fast_composite_over_8888_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t *dst_line, *dst; - uint32_t *src_line, *src, s; - int dst_stride, src_stride; - uint8_t a; - int32_t w; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - while (w--) - { - s = *src++; - a = s >> 24; - if (a == 0xff) - *dst = s; - else if (s) - *dst = over (s, *dst); - dst++; - } - } -} - -static void -fast_composite_src_x888_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t *dst_line, *dst; - uint32_t *src_line, *src; - int dst_stride, src_stride; - int32_t w; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - while (w--) - *dst++ = (*src++) | 0xff000000; - } -} - -#if 0 -static void -fast_composite_over_8888_0888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint8_t *dst_line, *dst; - uint32_t d; - uint32_t *src_line, *src, s; - uint8_t a; - int dst_stride, src_stride; - int32_t w; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 3); - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - while (w--) - { - s = *src++; - a = s >> 24; - if (a) - { - if (a == 0xff) - d = s; - else - d = over (s, fetch_24 (dst)); - - store_24 (dst, d); - } - dst += 3; - } - } -} -#endif - -static void -fast_composite_over_8888_0565 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint16_t *dst_line, *dst; - uint32_t d; - uint32_t *src_line, *src, s; - uint8_t a; - int dst_stride, src_stride; - int32_t w; - - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - while (w--) - { - s = *src++; - a = s >> 24; - if (s) - { - if (a == 0xff) - { - d = s; - } - else - { - d = *dst; - d = over (s, convert_0565_to_0888 (d)); - } - *dst = convert_8888_to_0565 (d); - } - dst++; - } - } -} - -static void -fast_composite_add_8_8 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint8_t *dst_line, *dst; - uint8_t *src_line, *src; - int dst_stride, src_stride; - int32_t w; - uint8_t s, d; - uint16_t t; - - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint8_t, src_stride, src_line, 1); - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - while (w--) - { - s = *src++; - if (s) - { - if (s != 0xff) - { - d = *dst; - t = d + s; - s = t | (0 - (t >> 8)); - } - *dst = s; - } - dst++; - } - } -} - -static void -fast_composite_add_0565_0565 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint16_t *dst_line, *dst; - uint32_t d; - uint16_t *src_line, *src; - uint32_t s; - int dst_stride, src_stride; - int32_t w; - - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint16_t, src_stride, src_line, 1); - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - while (w--) - { - s = *src++; - if (s) - { - d = *dst; - s = convert_0565_to_8888 (s); - if (d) - { - d = convert_0565_to_8888 (d); - UN8x4_ADD_UN8x4 (s, d); - } - *dst = convert_8888_to_0565 (s); - } - dst++; - } - } -} - -static void -fast_composite_add_8888_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t *dst_line, *dst; - uint32_t *src_line, *src; - int dst_stride, src_stride; - int32_t w; - uint32_t s, d; - - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - while (w--) - { - s = *src++; - if (s) - { - if (s != 0xffffffff) - { - d = *dst; - if (d) - UN8x4_ADD_UN8x4 (s, d); - } - *dst = s; - } - dst++; - } - } -} - -static void -fast_composite_add_n_8_8 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint8_t *dst_line, *dst; - uint8_t *mask_line, *mask; - int dst_stride, mask_stride; - int32_t w; - uint32_t src; - uint8_t sa; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - sa = (src >> 24); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - w = width; - - while (w--) - { - uint16_t tmp; - uint16_t a; - uint32_t m, d; - uint32_t r; - - a = *mask++; - d = *dst; - - m = MUL_UN8 (sa, a, tmp); - r = ADD_UN8 (m, d, tmp); - - *dst++ = r; - } - } -} - -#ifdef WORDS_BIGENDIAN -#define CREATE_BITMASK(n) (0x80000000 >> (n)) -#define UPDATE_BITMASK(n) ((n) >> 1) -#else -#define CREATE_BITMASK(n) (1 << (n)) -#define UPDATE_BITMASK(n) ((n) << 1) -#endif - -#define TEST_BIT(p, n) \ - (*((p) + ((n) >> 5)) & CREATE_BITMASK ((n) & 31)) -#define SET_BIT(p, n) \ - do { *((p) + ((n) >> 5)) |= CREATE_BITMASK ((n) & 31); } while (0); - -static void -fast_composite_add_1_1 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t *dst_line, *dst; - uint32_t *src_line, *src; - int dst_stride, src_stride; - int32_t w; - - PIXMAN_IMAGE_GET_LINE (src_image, 0, src_y, uint32_t, - src_stride, src_line, 1); - PIXMAN_IMAGE_GET_LINE (dest_image, 0, dest_y, uint32_t, - dst_stride, dst_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - while (w--) - { - /* - * TODO: improve performance by processing uint32_t data instead - * of individual bits - */ - if (TEST_BIT (src, src_x + w)) - SET_BIT (dst, dest_x + w); - } - } -} - -static void -fast_composite_over_n_1_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src, srca; - uint32_t *dst, *dst_line; - uint32_t *mask, *mask_line; - int mask_stride, dst_stride; - uint32_t bitcache, bitmask; - int32_t w; - - if (width <= 0) - return; - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - srca = src >> 24; - if (src == 0) - return; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, - dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (mask_image, 0, mask_y, uint32_t, - mask_stride, mask_line, 1); - mask_line += mask_x >> 5; - - if (srca == 0xff) - { - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - w = width; - - bitcache = *mask++; - bitmask = CREATE_BITMASK (mask_x & 31); - - while (w--) - { - if (bitmask == 0) - { - bitcache = *mask++; - bitmask = CREATE_BITMASK (0); - } - if (bitcache & bitmask) - *dst = src; - bitmask = UPDATE_BITMASK (bitmask); - dst++; - } - } - } - else - { - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - w = width; - - bitcache = *mask++; - bitmask = CREATE_BITMASK (mask_x & 31); - - while (w--) - { - if (bitmask == 0) - { - bitcache = *mask++; - bitmask = CREATE_BITMASK (0); - } - if (bitcache & bitmask) - *dst = over (src, *dst); - bitmask = UPDATE_BITMASK (bitmask); - dst++; - } - } - } -} - -static void -fast_composite_over_n_1_0565 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src, srca; - uint16_t *dst, *dst_line; - uint32_t *mask, *mask_line; - int mask_stride, dst_stride; - uint32_t bitcache, bitmask; - int32_t w; - uint32_t d; - uint16_t src565; - - if (width <= 0) - return; - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - srca = src >> 24; - if (src == 0) - return; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint16_t, - dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (mask_image, 0, mask_y, uint32_t, - mask_stride, mask_line, 1); - mask_line += mask_x >> 5; - - if (srca == 0xff) - { - src565 = convert_8888_to_0565 (src); - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - w = width; - - bitcache = *mask++; - bitmask = CREATE_BITMASK (mask_x & 31); - - while (w--) - { - if (bitmask == 0) - { - bitcache = *mask++; - bitmask = CREATE_BITMASK (0); - } - if (bitcache & bitmask) - *dst = src565; - bitmask = UPDATE_BITMASK (bitmask); - dst++; - } - } - } - else - { - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - w = width; - - bitcache = *mask++; - bitmask = CREATE_BITMASK (mask_x & 31); - - while (w--) - { - if (bitmask == 0) - { - bitcache = *mask++; - bitmask = CREATE_BITMASK (0); - } - if (bitcache & bitmask) - { - d = over (src, convert_0565_to_0888 (*dst)); - *dst = convert_8888_to_0565 (d); - } - bitmask = UPDATE_BITMASK (bitmask); - dst++; - } - } - } -} - -/* - * Simple bitblt - */ - -static void -fast_composite_solid_fill (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src; - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - if (dest_image->bits.format == PIXMAN_a1) - { - src = src >> 31; - } - else if (dest_image->bits.format == PIXMAN_a8) - { - src = src >> 24; - } - else if (dest_image->bits.format == PIXMAN_r5g6b5 || - dest_image->bits.format == PIXMAN_b5g6r5) - { - src = convert_8888_to_0565 (src); - } - - pixman_fill (dest_image->bits.bits, dest_image->bits.rowstride, - PIXMAN_FORMAT_BPP (dest_image->bits.format), - dest_x, dest_y, - width, height, - src); -} - -static void -fast_composite_src_memcpy (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - int bpp = PIXMAN_FORMAT_BPP (dest_image->bits.format) / 8; - uint32_t n_bytes = width * bpp; - int dst_stride, src_stride; - uint8_t *dst; - uint8_t *src; - - src_stride = src_image->bits.rowstride * 4; - dst_stride = dest_image->bits.rowstride * 4; - - src = (uint8_t *)src_image->bits.bits + src_y * src_stride + src_x * bpp; - dst = (uint8_t *)dest_image->bits.bits + dest_y * dst_stride + dest_x * bpp; - - while (height--) - { - memcpy (dst, src, n_bytes); - - dst += dst_stride; - src += src_stride; - } -} - -FAST_NEAREST (8888_8888_cover, 8888, 8888, uint32_t, uint32_t, SRC, COVER) -FAST_NEAREST (8888_8888_none, 8888, 8888, uint32_t, uint32_t, SRC, NONE) -FAST_NEAREST (8888_8888_pad, 8888, 8888, uint32_t, uint32_t, SRC, PAD) -FAST_NEAREST (8888_8888_normal, 8888, 8888, uint32_t, uint32_t, SRC, NORMAL) -FAST_NEAREST (x888_8888_cover, x888, 8888, uint32_t, uint32_t, SRC, COVER) -FAST_NEAREST (x888_8888_pad, x888, 8888, uint32_t, uint32_t, SRC, PAD) -FAST_NEAREST (x888_8888_normal, x888, 8888, uint32_t, uint32_t, SRC, NORMAL) -FAST_NEAREST (8888_8888_cover, 8888, 8888, uint32_t, uint32_t, OVER, COVER) -FAST_NEAREST (8888_8888_none, 8888, 8888, uint32_t, uint32_t, OVER, NONE) -FAST_NEAREST (8888_8888_pad, 8888, 8888, uint32_t, uint32_t, OVER, PAD) -FAST_NEAREST (8888_8888_normal, 8888, 8888, uint32_t, uint32_t, OVER, NORMAL) -FAST_NEAREST (8888_565_cover, 8888, 0565, uint32_t, uint16_t, SRC, COVER) -FAST_NEAREST (8888_565_none, 8888, 0565, uint32_t, uint16_t, SRC, NONE) -FAST_NEAREST (8888_565_pad, 8888, 0565, uint32_t, uint16_t, SRC, PAD) -FAST_NEAREST (8888_565_normal, 8888, 0565, uint32_t, uint16_t, SRC, NORMAL) -FAST_NEAREST (565_565_normal, 0565, 0565, uint16_t, uint16_t, SRC, NORMAL) -FAST_NEAREST (8888_565_cover, 8888, 0565, uint32_t, uint16_t, OVER, COVER) -FAST_NEAREST (8888_565_none, 8888, 0565, uint32_t, uint16_t, OVER, NONE) -FAST_NEAREST (8888_565_pad, 8888, 0565, uint32_t, uint16_t, OVER, PAD) -FAST_NEAREST (8888_565_normal, 8888, 0565, uint32_t, uint16_t, OVER, NORMAL) - -#define REPEAT_MIN_WIDTH 32 - -static void -fast_composite_tiled_repeat (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - pixman_composite_func_t func; - pixman_format_code_t mask_format; - uint32_t src_flags, mask_flags; - int32_t sx, sy; - int32_t width_remain; - int32_t num_pixels; - int32_t src_width; - int32_t i, j; - pixman_image_t extended_src_image; - uint32_t extended_src[REPEAT_MIN_WIDTH * 2]; - pixman_bool_t need_src_extension; - uint32_t *src_line; - int32_t src_stride; - int32_t src_bpp; - pixman_composite_info_t info2 = *info; - - src_flags = (info->src_flags & ~FAST_PATH_NORMAL_REPEAT) | - FAST_PATH_SAMPLES_COVER_CLIP_NEAREST; - - if (mask_image) - { - mask_format = mask_image->common.extended_format_code; - mask_flags = info->mask_flags; - } - else - { - mask_format = PIXMAN_null; - mask_flags = FAST_PATH_IS_OPAQUE; - } - - _pixman_implementation_lookup_composite ( - imp->toplevel, info->op, - src_image->common.extended_format_code, src_flags, - mask_format, mask_flags, - dest_image->common.extended_format_code, info->dest_flags, - &imp, &func); - - src_bpp = PIXMAN_FORMAT_BPP (src_image->bits.format); - - if (src_image->bits.width < REPEAT_MIN_WIDTH && - (src_bpp == 32 || src_bpp == 16 || src_bpp == 8) && - !src_image->bits.indexed) - { - sx = src_x; - sx = MOD (sx, src_image->bits.width); - sx += width; - src_width = 0; - - while (src_width < REPEAT_MIN_WIDTH && src_width <= sx) - src_width += src_image->bits.width; - - src_stride = (src_width * (src_bpp >> 3) + 3) / (int) sizeof (uint32_t); - - /* Initialize/validate stack-allocated temporary image */ - _pixman_bits_image_init (&extended_src_image, src_image->bits.format, - src_width, 1, &extended_src[0], src_stride, - FALSE); - _pixman_image_validate (&extended_src_image); - - info2.src_image = &extended_src_image; - need_src_extension = TRUE; - } - else - { - src_width = src_image->bits.width; - need_src_extension = FALSE; - } - - sx = src_x; - sy = src_y; - - while (--height >= 0) - { - sx = MOD (sx, src_width); - sy = MOD (sy, src_image->bits.height); - - if (need_src_extension) - { - if (src_bpp == 32) - { - PIXMAN_IMAGE_GET_LINE (src_image, 0, sy, uint32_t, src_stride, src_line, 1); - - for (i = 0; i < src_width; ) - { - for (j = 0; j < src_image->bits.width; j++, i++) - extended_src[i] = src_line[j]; - } - } - else if (src_bpp == 16) - { - uint16_t *src_line_16; - - PIXMAN_IMAGE_GET_LINE (src_image, 0, sy, uint16_t, src_stride, - src_line_16, 1); - src_line = (uint32_t*)src_line_16; - - for (i = 0; i < src_width; ) - { - for (j = 0; j < src_image->bits.width; j++, i++) - ((uint16_t*)extended_src)[i] = ((uint16_t*)src_line)[j]; - } - } - else if (src_bpp == 8) - { - uint8_t *src_line_8; - - PIXMAN_IMAGE_GET_LINE (src_image, 0, sy, uint8_t, src_stride, - src_line_8, 1); - src_line = (uint32_t*)src_line_8; - - for (i = 0; i < src_width; ) - { - for (j = 0; j < src_image->bits.width; j++, i++) - ((uint8_t*)extended_src)[i] = ((uint8_t*)src_line)[j]; - } - } - - info2.src_y = 0; - } - else - { - info2.src_y = sy; - } - - width_remain = width; - - while (width_remain > 0) - { - num_pixels = src_width - sx; - - if (num_pixels > width_remain) - num_pixels = width_remain; - - info2.src_x = sx; - info2.width = num_pixels; - info2.height = 1; - - func (imp, &info2); - - width_remain -= num_pixels; - info2.mask_x += num_pixels; - info2.dest_x += num_pixels; - sx = 0; - } - - sx = src_x; - sy++; - info2.mask_x = info->mask_x; - info2.mask_y++; - info2.dest_x = info->dest_x; - info2.dest_y++; - } - - if (need_src_extension) - _pixman_image_fini (&extended_src_image); -} - -/* Use more unrolling for src_0565_0565 because it is typically CPU bound */ -static force_inline void -scaled_nearest_scanline_565_565_SRC (uint16_t * dst, - const uint16_t * src, - int32_t w, - pixman_fixed_t vx, - pixman_fixed_t unit_x, - pixman_fixed_t max_vx, - pixman_bool_t fully_transparent_src) -{ - uint16_t tmp1, tmp2, tmp3, tmp4; - while ((w -= 4) >= 0) - { - tmp1 = *(src + pixman_fixed_to_int (vx)); - vx += unit_x; - tmp2 = *(src + pixman_fixed_to_int (vx)); - vx += unit_x; - tmp3 = *(src + pixman_fixed_to_int (vx)); - vx += unit_x; - tmp4 = *(src + pixman_fixed_to_int (vx)); - vx += unit_x; - *dst++ = tmp1; - *dst++ = tmp2; - *dst++ = tmp3; - *dst++ = tmp4; - } - if (w & 2) - { - tmp1 = *(src + pixman_fixed_to_int (vx)); - vx += unit_x; - tmp2 = *(src + pixman_fixed_to_int (vx)); - vx += unit_x; - *dst++ = tmp1; - *dst++ = tmp2; - } - if (w & 1) - *dst = *(src + pixman_fixed_to_int (vx)); -} - -FAST_NEAREST_MAINLOOP (565_565_cover_SRC, - scaled_nearest_scanline_565_565_SRC, - uint16_t, uint16_t, COVER) -FAST_NEAREST_MAINLOOP (565_565_none_SRC, - scaled_nearest_scanline_565_565_SRC, - uint16_t, uint16_t, NONE) -FAST_NEAREST_MAINLOOP (565_565_pad_SRC, - scaled_nearest_scanline_565_565_SRC, - uint16_t, uint16_t, PAD) - -static force_inline uint32_t -fetch_nearest (pixman_repeat_t src_repeat, - pixman_format_code_t format, - uint32_t *src, int x, int src_width) -{ - if (repeat (src_repeat, &x, src_width)) - { - if (format == PIXMAN_x8r8g8b8 || format == PIXMAN_x8b8g8r8) - return *(src + x) | 0xff000000; - else - return *(src + x); - } - else - { - return 0; - } -} - -static force_inline void -combine_over (uint32_t s, uint32_t *dst) -{ - if (s) - { - uint8_t ia = 0xff - (s >> 24); - - if (ia) - UN8x4_MUL_UN8_ADD_UN8x4 (*dst, ia, s); - else - *dst = s; - } -} - -static force_inline void -combine_src (uint32_t s, uint32_t *dst) -{ - *dst = s; -} - -static void -fast_composite_scaled_nearest (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t *dst_line; - uint32_t *src_line; - int dst_stride, src_stride; - int src_width, src_height; - pixman_repeat_t src_repeat; - pixman_fixed_t unit_x, unit_y; - pixman_format_code_t src_format; - pixman_vector_t v; - pixman_fixed_t vy; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - /* pass in 0 instead of src_x and src_y because src_x and src_y need to be - * transformed from destination space to source space - */ - PIXMAN_IMAGE_GET_LINE (src_image, 0, 0, uint32_t, src_stride, src_line, 1); - - /* reference point is the center of the pixel */ - v.vector[0] = pixman_int_to_fixed (src_x) + pixman_fixed_1 / 2; - v.vector[1] = pixman_int_to_fixed (src_y) + pixman_fixed_1 / 2; - v.vector[2] = pixman_fixed_1; - - if (!pixman_transform_point_3d (src_image->common.transform, &v)) - return; - - unit_x = src_image->common.transform->matrix[0][0]; - unit_y = src_image->common.transform->matrix[1][1]; - - /* Round down to closest integer, ensuring that 0.5 rounds to 0, not 1 */ - v.vector[0] -= pixman_fixed_e; - v.vector[1] -= pixman_fixed_e; - - src_height = src_image->bits.height; - src_width = src_image->bits.width; - src_repeat = src_image->common.repeat; - src_format = src_image->bits.format; - - vy = v.vector[1]; - while (height--) - { - pixman_fixed_t vx = v.vector[0]; - int y = pixman_fixed_to_int (vy); - uint32_t *dst = dst_line; - - dst_line += dst_stride; - - /* adjust the y location by a unit vector in the y direction - * this is equivalent to transforming y+1 of the destination point to source space */ - vy += unit_y; - - if (!repeat (src_repeat, &y, src_height)) - { - if (op == PIXMAN_OP_SRC) - memset (dst, 0, sizeof (*dst) * width); - } - else - { - int w = width; - - uint32_t *src = src_line + y * src_stride; - - while (w >= 2) - { - uint32_t s1, s2; - int x1, x2; - - x1 = pixman_fixed_to_int (vx); - vx += unit_x; - - x2 = pixman_fixed_to_int (vx); - vx += unit_x; - - w -= 2; - - s1 = fetch_nearest (src_repeat, src_format, src, x1, src_width); - s2 = fetch_nearest (src_repeat, src_format, src, x2, src_width); - - if (op == PIXMAN_OP_OVER) - { - combine_over (s1, dst++); - combine_over (s2, dst++); - } - else - { - combine_src (s1, dst++); - combine_src (s2, dst++); - } - } - - while (w--) - { - uint32_t s; - int x; - - x = pixman_fixed_to_int (vx); - vx += unit_x; - - s = fetch_nearest (src_repeat, src_format, src, x, src_width); - - if (op == PIXMAN_OP_OVER) - combine_over (s, dst++); - else - combine_src (s, dst++); - } - } - } -} - -#define CACHE_LINE_SIZE 64 - -#define FAST_SIMPLE_ROTATE(suffix, pix_type) \ - \ -static void \ -blt_rotated_90_trivial_##suffix (pix_type *dst, \ - int dst_stride, \ - const pix_type *src, \ - int src_stride, \ - int w, \ - int h) \ -{ \ - int x, y; \ - for (y = 0; y < h; y++) \ - { \ - const pix_type *s = src + (h - y - 1); \ - pix_type *d = dst + dst_stride * y; \ - for (x = 0; x < w; x++) \ - { \ - *d++ = *s; \ - s += src_stride; \ - } \ - } \ -} \ - \ -static void \ -blt_rotated_270_trivial_##suffix (pix_type *dst, \ - int dst_stride, \ - const pix_type *src, \ - int src_stride, \ - int w, \ - int h) \ -{ \ - int x, y; \ - for (y = 0; y < h; y++) \ - { \ - const pix_type *s = src + src_stride * (w - 1) + y; \ - pix_type *d = dst + dst_stride * y; \ - for (x = 0; x < w; x++) \ - { \ - *d++ = *s; \ - s -= src_stride; \ - } \ - } \ -} \ - \ -static void \ -blt_rotated_90_##suffix (pix_type *dst, \ - int dst_stride, \ - const pix_type *src, \ - int src_stride, \ - int W, \ - int H) \ -{ \ - int x; \ - int leading_pixels = 0, trailing_pixels = 0; \ - const int TILE_SIZE = CACHE_LINE_SIZE / sizeof(pix_type); \ - \ - /* \ - * split processing into handling destination as TILE_SIZExH cache line \ - * aligned vertical stripes (optimistically assuming that destination \ - * stride is a multiple of cache line, if not - it will be just a bit \ - * slower) \ - */ \ - \ - if ((uintptr_t)dst & (CACHE_LINE_SIZE - 1)) \ - { \ - leading_pixels = TILE_SIZE - (((uintptr_t)dst & \ - (CACHE_LINE_SIZE - 1)) / sizeof(pix_type)); \ - if (leading_pixels > W) \ - leading_pixels = W; \ - \ - /* unaligned leading part NxH (where N < TILE_SIZE) */ \ - blt_rotated_90_trivial_##suffix ( \ - dst, \ - dst_stride, \ - src, \ - src_stride, \ - leading_pixels, \ - H); \ - \ - dst += leading_pixels; \ - src += leading_pixels * src_stride; \ - W -= leading_pixels; \ - } \ - \ - if ((uintptr_t)(dst + W) & (CACHE_LINE_SIZE - 1)) \ - { \ - trailing_pixels = (((uintptr_t)(dst + W) & \ - (CACHE_LINE_SIZE - 1)) / sizeof(pix_type)); \ - if (trailing_pixels > W) \ - trailing_pixels = W; \ - W -= trailing_pixels; \ - } \ - \ - for (x = 0; x < W; x += TILE_SIZE) \ - { \ - /* aligned middle part TILE_SIZExH */ \ - blt_rotated_90_trivial_##suffix ( \ - dst + x, \ - dst_stride, \ - src + src_stride * x, \ - src_stride, \ - TILE_SIZE, \ - H); \ - } \ - \ - if (trailing_pixels) \ - { \ - /* unaligned trailing part NxH (where N < TILE_SIZE) */ \ - blt_rotated_90_trivial_##suffix ( \ - dst + W, \ - dst_stride, \ - src + W * src_stride, \ - src_stride, \ - trailing_pixels, \ - H); \ - } \ -} \ - \ -static void \ -blt_rotated_270_##suffix (pix_type *dst, \ - int dst_stride, \ - const pix_type *src, \ - int src_stride, \ - int W, \ - int H) \ -{ \ - int x; \ - int leading_pixels = 0, trailing_pixels = 0; \ - const int TILE_SIZE = CACHE_LINE_SIZE / sizeof(pix_type); \ - \ - /* \ - * split processing into handling destination as TILE_SIZExH cache line \ - * aligned vertical stripes (optimistically assuming that destination \ - * stride is a multiple of cache line, if not - it will be just a bit \ - * slower) \ - */ \ - \ - if ((uintptr_t)dst & (CACHE_LINE_SIZE - 1)) \ - { \ - leading_pixels = TILE_SIZE - (((uintptr_t)dst & \ - (CACHE_LINE_SIZE - 1)) / sizeof(pix_type)); \ - if (leading_pixels > W) \ - leading_pixels = W; \ - \ - /* unaligned leading part NxH (where N < TILE_SIZE) */ \ - blt_rotated_270_trivial_##suffix ( \ - dst, \ - dst_stride, \ - src + src_stride * (W - leading_pixels), \ - src_stride, \ - leading_pixels, \ - H); \ - \ - dst += leading_pixels; \ - W -= leading_pixels; \ - } \ - \ - if ((uintptr_t)(dst + W) & (CACHE_LINE_SIZE - 1)) \ - { \ - trailing_pixels = (((uintptr_t)(dst + W) & \ - (CACHE_LINE_SIZE - 1)) / sizeof(pix_type)); \ - if (trailing_pixels > W) \ - trailing_pixels = W; \ - W -= trailing_pixels; \ - src += trailing_pixels * src_stride; \ - } \ - \ - for (x = 0; x < W; x += TILE_SIZE) \ - { \ - /* aligned middle part TILE_SIZExH */ \ - blt_rotated_270_trivial_##suffix ( \ - dst + x, \ - dst_stride, \ - src + src_stride * (W - x - TILE_SIZE), \ - src_stride, \ - TILE_SIZE, \ - H); \ - } \ - \ - if (trailing_pixels) \ - { \ - /* unaligned trailing part NxH (where N < TILE_SIZE) */ \ - blt_rotated_270_trivial_##suffix ( \ - dst + W, \ - dst_stride, \ - src - trailing_pixels * src_stride, \ - src_stride, \ - trailing_pixels, \ - H); \ - } \ -} \ - \ -static void \ -fast_composite_rotate_90_##suffix (pixman_implementation_t *imp, \ - pixman_composite_info_t *info) \ -{ \ - PIXMAN_COMPOSITE_ARGS (info); \ - pix_type *dst_line; \ - pix_type *src_line; \ - int dst_stride, src_stride; \ - int src_x_t, src_y_t; \ - \ - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, pix_type, \ - dst_stride, dst_line, 1); \ - src_x_t = -src_y + pixman_fixed_to_int ( \ - src_image->common.transform->matrix[0][2] + \ - pixman_fixed_1 / 2 - pixman_fixed_e) - height;\ - src_y_t = src_x + pixman_fixed_to_int ( \ - src_image->common.transform->matrix[1][2] + \ - pixman_fixed_1 / 2 - pixman_fixed_e); \ - PIXMAN_IMAGE_GET_LINE (src_image, src_x_t, src_y_t, pix_type, \ - src_stride, src_line, 1); \ - blt_rotated_90_##suffix (dst_line, dst_stride, src_line, src_stride, \ - width, height); \ -} \ - \ -static void \ -fast_composite_rotate_270_##suffix (pixman_implementation_t *imp, \ - pixman_composite_info_t *info) \ -{ \ - PIXMAN_COMPOSITE_ARGS (info); \ - pix_type *dst_line; \ - pix_type *src_line; \ - int dst_stride, src_stride; \ - int src_x_t, src_y_t; \ - \ - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, pix_type, \ - dst_stride, dst_line, 1); \ - src_x_t = src_y + pixman_fixed_to_int ( \ - src_image->common.transform->matrix[0][2] + \ - pixman_fixed_1 / 2 - pixman_fixed_e); \ - src_y_t = -src_x + pixman_fixed_to_int ( \ - src_image->common.transform->matrix[1][2] + \ - pixman_fixed_1 / 2 - pixman_fixed_e) - width; \ - PIXMAN_IMAGE_GET_LINE (src_image, src_x_t, src_y_t, pix_type, \ - src_stride, src_line, 1); \ - blt_rotated_270_##suffix (dst_line, dst_stride, src_line, src_stride, \ - width, height); \ -} - -FAST_SIMPLE_ROTATE (8, uint8_t) -FAST_SIMPLE_ROTATE (565, uint16_t) -FAST_SIMPLE_ROTATE (8888, uint32_t) - -static const pixman_fast_path_t c_fast_paths[] = -{ - PIXMAN_STD_FAST_PATH (OVER, solid, a8, r5g6b5, fast_composite_over_n_8_0565), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, b5g6r5, fast_composite_over_n_8_0565), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, r8g8b8, fast_composite_over_n_8_0888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, b8g8r8, fast_composite_over_n_8_0888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, fast_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, fast_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, fast_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, fast_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a1, a8r8g8b8, fast_composite_over_n_1_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a1, x8r8g8b8, fast_composite_over_n_1_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a1, a8b8g8r8, fast_composite_over_n_1_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a1, x8b8g8r8, fast_composite_over_n_1_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a1, r5g6b5, fast_composite_over_n_1_0565), - PIXMAN_STD_FAST_PATH (OVER, solid, a1, b5g6r5, fast_composite_over_n_1_0565), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, a8r8g8b8, fast_composite_over_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, fast_composite_over_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, r5g6b5, fast_composite_over_n_8888_0565_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, fast_composite_over_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, fast_composite_over_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, b5g6r5, fast_composite_over_n_8888_0565_ca), - PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, a8, x8r8g8b8, fast_composite_over_x888_8_8888), - PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, a8, a8r8g8b8, fast_composite_over_x888_8_8888), - PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, a8, x8b8g8r8, fast_composite_over_x888_8_8888), - PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, a8, a8b8g8r8, fast_composite_over_x888_8_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, fast_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, fast_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, r5g6b5, fast_composite_over_8888_0565), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, fast_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, fast_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, b5g6r5, fast_composite_over_8888_0565), - PIXMAN_STD_FAST_PATH (ADD, r5g6b5, null, r5g6b5, fast_composite_add_0565_0565), - PIXMAN_STD_FAST_PATH (ADD, b5g6r5, null, b5g6r5, fast_composite_add_0565_0565), - PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, null, a8r8g8b8, fast_composite_add_8888_8888), - PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, null, a8b8g8r8, fast_composite_add_8888_8888), - PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, fast_composite_add_8_8), - PIXMAN_STD_FAST_PATH (ADD, a1, null, a1, fast_composite_add_1_1), - PIXMAN_STD_FAST_PATH_CA (ADD, solid, a8r8g8b8, a8r8g8b8, fast_composite_add_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8, fast_composite_add_n_8_8), - PIXMAN_STD_FAST_PATH (SRC, solid, null, a8r8g8b8, fast_composite_solid_fill), - PIXMAN_STD_FAST_PATH (SRC, solid, null, x8r8g8b8, fast_composite_solid_fill), - PIXMAN_STD_FAST_PATH (SRC, solid, null, a8b8g8r8, fast_composite_solid_fill), - PIXMAN_STD_FAST_PATH (SRC, solid, null, x8b8g8r8, fast_composite_solid_fill), - PIXMAN_STD_FAST_PATH (SRC, solid, null, a1, fast_composite_solid_fill), - PIXMAN_STD_FAST_PATH (SRC, solid, null, a8, fast_composite_solid_fill), - PIXMAN_STD_FAST_PATH (SRC, solid, null, r5g6b5, fast_composite_solid_fill), - PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, a8r8g8b8, fast_composite_src_x888_8888), - PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, a8b8g8r8, fast_composite_src_x888_8888), - PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, fast_composite_src_memcpy), - PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, a8r8g8b8, fast_composite_src_memcpy), - PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, fast_composite_src_memcpy), - PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, fast_composite_src_memcpy), - PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, a8b8g8r8, fast_composite_src_memcpy), - PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, fast_composite_src_memcpy), - PIXMAN_STD_FAST_PATH (SRC, b8g8r8a8, null, b8g8r8x8, fast_composite_src_memcpy), - PIXMAN_STD_FAST_PATH (SRC, b8g8r8a8, null, b8g8r8a8, fast_composite_src_memcpy), - PIXMAN_STD_FAST_PATH (SRC, b8g8r8x8, null, b8g8r8x8, fast_composite_src_memcpy), - PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, r5g6b5, fast_composite_src_memcpy), - PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, b5g6r5, fast_composite_src_memcpy), - PIXMAN_STD_FAST_PATH (SRC, r8g8b8, null, r8g8b8, fast_composite_src_memcpy), - PIXMAN_STD_FAST_PATH (SRC, b8g8r8, null, b8g8r8, fast_composite_src_memcpy), - PIXMAN_STD_FAST_PATH (SRC, x1r5g5b5, null, x1r5g5b5, fast_composite_src_memcpy), - PIXMAN_STD_FAST_PATH (SRC, a1r5g5b5, null, x1r5g5b5, fast_composite_src_memcpy), - PIXMAN_STD_FAST_PATH (SRC, a8, null, a8, fast_composite_src_memcpy), - PIXMAN_STD_FAST_PATH (IN, a8, null, a8, fast_composite_in_8_8), - PIXMAN_STD_FAST_PATH (IN, solid, a8, a8, fast_composite_in_n_8_8), - - SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, 8888_8888), - SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, 8888_8888), - SIMPLE_NEAREST_FAST_PATH (SRC, x8b8g8r8, x8b8g8r8, 8888_8888), - SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, x8b8g8r8, 8888_8888), - - SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, 8888_8888), - SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, a8b8g8r8, 8888_8888), - - SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, r5g6b5, 8888_565), - SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, r5g6b5, 8888_565), - - SIMPLE_NEAREST_FAST_PATH (SRC, r5g6b5, r5g6b5, 565_565), - - SIMPLE_NEAREST_FAST_PATH_COVER (SRC, x8r8g8b8, a8r8g8b8, x888_8888), - SIMPLE_NEAREST_FAST_PATH_COVER (SRC, x8b8g8r8, a8b8g8r8, x888_8888), - SIMPLE_NEAREST_FAST_PATH_PAD (SRC, x8r8g8b8, a8r8g8b8, x888_8888), - SIMPLE_NEAREST_FAST_PATH_PAD (SRC, x8b8g8r8, a8b8g8r8, x888_8888), - SIMPLE_NEAREST_FAST_PATH_NORMAL (SRC, x8r8g8b8, a8r8g8b8, x888_8888), - SIMPLE_NEAREST_FAST_PATH_NORMAL (SRC, x8b8g8r8, a8b8g8r8, x888_8888), - - SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, 8888_8888), - SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, 8888_8888), - SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, 8888_8888), - SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, 8888_8888), - - SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, r5g6b5, 8888_565), - -#define NEAREST_FAST_PATH(op,s,d) \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, SCALED_NEAREST_FLAGS, \ - PIXMAN_null, 0, \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_scaled_nearest, \ - } - - NEAREST_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8), - NEAREST_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8), - NEAREST_FAST_PATH (SRC, x8b8g8r8, x8b8g8r8), - NEAREST_FAST_PATH (SRC, a8b8g8r8, x8b8g8r8), - - NEAREST_FAST_PATH (SRC, x8r8g8b8, a8r8g8b8), - NEAREST_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8), - NEAREST_FAST_PATH (SRC, x8b8g8r8, a8b8g8r8), - NEAREST_FAST_PATH (SRC, a8b8g8r8, a8b8g8r8), - - NEAREST_FAST_PATH (OVER, x8r8g8b8, x8r8g8b8), - NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8), - NEAREST_FAST_PATH (OVER, x8b8g8r8, x8b8g8r8), - NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8), - - NEAREST_FAST_PATH (OVER, x8r8g8b8, a8r8g8b8), - NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8), - NEAREST_FAST_PATH (OVER, x8b8g8r8, a8b8g8r8), - NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8), - -#define SIMPLE_ROTATE_FLAGS(angle) \ - (FAST_PATH_ROTATE_ ## angle ## _TRANSFORM | \ - FAST_PATH_NEAREST_FILTER | \ - FAST_PATH_SAMPLES_COVER_CLIP_NEAREST | \ - FAST_PATH_STANDARD_FLAGS) - -#define SIMPLE_ROTATE_FAST_PATH(op,s,d,suffix) \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, SIMPLE_ROTATE_FLAGS (90), \ - PIXMAN_null, 0, \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_rotate_90_##suffix, \ - }, \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, SIMPLE_ROTATE_FLAGS (270), \ - PIXMAN_null, 0, \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_rotate_270_##suffix, \ - } - - SIMPLE_ROTATE_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, 8888), - SIMPLE_ROTATE_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, 8888), - SIMPLE_ROTATE_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, 8888), - SIMPLE_ROTATE_FAST_PATH (SRC, r5g6b5, r5g6b5, 565), - SIMPLE_ROTATE_FAST_PATH (SRC, a8, a8, 8), - - /* Simple repeat fast path entry. */ - { PIXMAN_OP_any, - PIXMAN_any, - (FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM | FAST_PATH_BITS_IMAGE | - FAST_PATH_NORMAL_REPEAT), - PIXMAN_any, 0, - PIXMAN_any, FAST_PATH_STD_DEST_FLAGS, - fast_composite_tiled_repeat - }, - - { PIXMAN_OP_NONE }, -}; - -#ifdef WORDS_BIGENDIAN -#define A1_FILL_MASK(n, offs) (((1U << (n)) - 1) << (32 - (offs) - (n))) -#else -#define A1_FILL_MASK(n, offs) (((1U << (n)) - 1) << (offs)) -#endif - -static force_inline void -pixman_fill1_line (uint32_t *dst, int offs, int width, int v) -{ - if (offs) - { - int leading_pixels = 32 - offs; - if (leading_pixels >= width) - { - if (v) - *dst |= A1_FILL_MASK (width, offs); - else - *dst &= ~A1_FILL_MASK (width, offs); - return; - } - else - { - if (v) - *dst++ |= A1_FILL_MASK (leading_pixels, offs); - else - *dst++ &= ~A1_FILL_MASK (leading_pixels, offs); - width -= leading_pixels; - } - } - while (width >= 32) - { - if (v) - *dst++ = 0xFFFFFFFF; - else - *dst++ = 0; - width -= 32; - } - if (width > 0) - { - if (v) - *dst |= A1_FILL_MASK (width, 0); - else - *dst &= ~A1_FILL_MASK (width, 0); - } -} - -static void -pixman_fill1 (uint32_t *bits, - int stride, - int x, - int y, - int width, - int height, - uint32_t filler) -{ - uint32_t *dst = bits + y * stride + (x >> 5); - int offs = x & 31; - - if (filler & 1) - { - while (height--) - { - pixman_fill1_line (dst, offs, width, 1); - dst += stride; - } - } - else - { - while (height--) - { - pixman_fill1_line (dst, offs, width, 0); - dst += stride; - } - } -} - -static void -pixman_fill8 (uint32_t *bits, - int stride, - int x, - int y, - int width, - int height, - uint32_t filler) -{ - int byte_stride = stride * (int) sizeof (uint32_t); - uint8_t *dst = (uint8_t *) bits; - uint8_t v = filler & 0xff; - int i; - - dst = dst + y * byte_stride + x; - - while (height--) - { - for (i = 0; i < width; ++i) - dst[i] = v; - - dst += byte_stride; - } -} - -static void -pixman_fill16 (uint32_t *bits, - int stride, - int x, - int y, - int width, - int height, - uint32_t filler) -{ - int short_stride = - (stride * (int)sizeof (uint32_t)) / (int)sizeof (uint16_t); - uint16_t *dst = (uint16_t *)bits; - uint16_t v = filler & 0xffff; - int i; - - dst = dst + y * short_stride + x; - - while (height--) - { - for (i = 0; i < width; ++i) - dst[i] = v; - - dst += short_stride; - } -} - -static void -pixman_fill32 (uint32_t *bits, - int stride, - int x, - int y, - int width, - int height, - uint32_t filler) -{ - int i; - - bits = bits + y * stride + x; - - while (height--) - { - for (i = 0; i < width; ++i) - bits[i] = filler; - - bits += stride; - } -} - -static pixman_bool_t -fast_path_fill (pixman_implementation_t *imp, - uint32_t * bits, - int stride, - int bpp, - int x, - int y, - int width, - int height, - uint32_t filler) -{ - switch (bpp) - { - case 1: - pixman_fill1 (bits, stride, x, y, width, height, filler); - break; - - case 8: - pixman_fill8 (bits, stride, x, y, width, height, filler); - break; - - case 16: - pixman_fill16 (bits, stride, x, y, width, height, filler); - break; - - case 32: - pixman_fill32 (bits, stride, x, y, width, height, filler); - break; - - default: - return FALSE; - } - - return TRUE; -} - -/*****************************************************************************/ - -static uint32_t * -fast_fetch_r5g6b5 (pixman_iter_t *iter, const uint32_t *mask) -{ - int32_t w = iter->width; - uint32_t *dst = iter->buffer; - const uint16_t *src = (const uint16_t *)iter->bits; - - iter->bits += iter->stride; - - /* Align the source buffer at 4 bytes boundary */ - if (w > 0 && ((uintptr_t)src & 3)) - { - *dst++ = convert_0565_to_8888 (*src++); - w--; - } - /* Process two pixels per iteration */ - while ((w -= 2) >= 0) - { - uint32_t sr, sb, sg, t0, t1; - uint32_t s = *(const uint32_t *)src; - src += 2; - sr = (s >> 8) & 0x00F800F8; - sb = (s << 3) & 0x00F800F8; - sg = (s >> 3) & 0x00FC00FC; - sr |= sr >> 5; - sb |= sb >> 5; - sg |= sg >> 6; - t0 = ((sr << 16) & 0x00FF0000) | ((sg << 8) & 0x0000FF00) | - (sb & 0xFF) | 0xFF000000; - t1 = (sr & 0x00FF0000) | ((sg >> 8) & 0x0000FF00) | - (sb >> 16) | 0xFF000000; -#ifdef WORDS_BIGENDIAN - *dst++ = t1; - *dst++ = t0; -#else - *dst++ = t0; - *dst++ = t1; -#endif - } - if (w & 1) - { - *dst = convert_0565_to_8888 (*src); - } - - return iter->buffer; -} - -static uint32_t * -fast_dest_fetch_noop (pixman_iter_t *iter, const uint32_t *mask) -{ - iter->bits += iter->stride; - return iter->buffer; -} - -/* Helper function for a workaround, which tries to ensure that 0x1F001F - * constant is always allocated in a register on RISC architectures. - */ -static force_inline uint32_t -convert_8888_to_0565_workaround (uint32_t s, uint32_t x1F001F) -{ - uint32_t a, b; - a = (s >> 3) & x1F001F; - b = s & 0xFC00; - a |= a >> 5; - a |= b >> 5; - return a; -} - -static void -fast_write_back_r5g6b5 (pixman_iter_t *iter) -{ - int32_t w = iter->width; - uint16_t *dst = (uint16_t *)(iter->bits - iter->stride); - const uint32_t *src = iter->buffer; - /* Workaround to ensure that x1F001F variable is allocated in a register */ - static volatile uint32_t volatile_x1F001F = 0x1F001F; - uint32_t x1F001F = volatile_x1F001F; - - while ((w -= 4) >= 0) - { - uint32_t s1 = *src++; - uint32_t s2 = *src++; - uint32_t s3 = *src++; - uint32_t s4 = *src++; - *dst++ = convert_8888_to_0565_workaround (s1, x1F001F); - *dst++ = convert_8888_to_0565_workaround (s2, x1F001F); - *dst++ = convert_8888_to_0565_workaround (s3, x1F001F); - *dst++ = convert_8888_to_0565_workaround (s4, x1F001F); - } - if (w & 2) - { - *dst++ = convert_8888_to_0565_workaround (*src++, x1F001F); - *dst++ = convert_8888_to_0565_workaround (*src++, x1F001F); - } - if (w & 1) - { - *dst = convert_8888_to_0565_workaround (*src, x1F001F); - } -} - -typedef struct -{ - int y; - uint64_t * buffer; -} line_t; - -typedef struct -{ - line_t lines[2]; - pixman_fixed_t y; - pixman_fixed_t x; - uint64_t data[1]; -} bilinear_info_t; - -static void -fetch_horizontal (bits_image_t *image, line_t *line, - int y, pixman_fixed_t x, pixman_fixed_t ux, int n) -{ - uint32_t *bits = image->bits + y * image->rowstride; - int i; - - for (i = 0; i < n; ++i) - { - int x0 = pixman_fixed_to_int (x); - int x1 = x0 + 1; - int32_t dist_x; - - uint32_t left = *(bits + x0); - uint32_t right = *(bits + x1); - - dist_x = pixman_fixed_to_bilinear_weight (x); - dist_x <<= (8 - BILINEAR_INTERPOLATION_BITS); - -#if SIZEOF_LONG <= 4 - { - uint32_t lag, rag, ag; - uint32_t lrb, rrb, rb; - - lag = (left & 0xff00ff00) >> 8; - rag = (right & 0xff00ff00) >> 8; - ag = (lag << 8) + dist_x * (rag - lag); - - lrb = (left & 0x00ff00ff); - rrb = (right & 0x00ff00ff); - rb = (lrb << 8) + dist_x * (rrb - lrb); - - *((uint32_t *)(line->buffer + i)) = ag; - *((uint32_t *)(line->buffer + i) + 1) = rb; - } -#else - { - uint64_t lagrb, ragrb; - uint32_t lag, rag; - uint32_t lrb, rrb; - - lag = (left & 0xff00ff00); - lrb = (left & 0x00ff00ff); - rag = (right & 0xff00ff00); - rrb = (right & 0x00ff00ff); - lagrb = (((uint64_t)lag) << 24) | lrb; - ragrb = (((uint64_t)rag) << 24) | rrb; - - line->buffer[i] = (lagrb << 8) + dist_x * (ragrb - lagrb); - } -#endif - - x += ux; - } - - line->y = y; -} - -static uint32_t * -fast_fetch_bilinear_cover (pixman_iter_t *iter, const uint32_t *mask) -{ - pixman_fixed_t fx, ux; - bilinear_info_t *info = iter->data; - line_t *line0, *line1; - int y0, y1; - int32_t dist_y; - int i; - - COMPILE_TIME_ASSERT (BILINEAR_INTERPOLATION_BITS < 8); - - fx = info->x; - ux = iter->image->common.transform->matrix[0][0]; - - y0 = pixman_fixed_to_int (info->y); - y1 = y0 + 1; - dist_y = pixman_fixed_to_bilinear_weight (info->y); - dist_y <<= (8 - BILINEAR_INTERPOLATION_BITS); - - line0 = &info->lines[y0 & 0x01]; - line1 = &info->lines[y1 & 0x01]; - - if (line0->y != y0) - { - fetch_horizontal ( - &iter->image->bits, line0, y0, fx, ux, iter->width); - } - - if (line1->y != y1) - { - fetch_horizontal ( - &iter->image->bits, line1, y1, fx, ux, iter->width); - } - - for (i = 0; i < iter->width; ++i) - { -#if SIZEOF_LONG <= 4 - uint32_t ta, tr, tg, tb; - uint32_t ba, br, bg, bb; - uint32_t tag, trb; - uint32_t bag, brb; - uint32_t a, r, g, b; - - tag = *((uint32_t *)(line0->buffer + i)); - trb = *((uint32_t *)(line0->buffer + i) + 1); - bag = *((uint32_t *)(line1->buffer + i)); - brb = *((uint32_t *)(line1->buffer + i) + 1); - - ta = tag >> 16; - ba = bag >> 16; - a = (ta << 8) + dist_y * (ba - ta); - - tr = trb >> 16; - br = brb >> 16; - r = (tr << 8) + dist_y * (br - tr); - - tg = tag & 0xffff; - bg = bag & 0xffff; - g = (tg << 8) + dist_y * (bg - tg); - - tb = trb & 0xffff; - bb = brb & 0xffff; - b = (tb << 8) + dist_y * (bb - tb); - - a = (a << 8) & 0xff000000; - r = (r << 0) & 0x00ff0000; - g = (g >> 8) & 0x0000ff00; - b = (b >> 16) & 0x000000ff; -#else - uint64_t top = line0->buffer[i]; - uint64_t bot = line1->buffer[i]; - uint64_t tar = (top & 0xffff0000ffff0000ULL) >> 16; - uint64_t bar = (bot & 0xffff0000ffff0000ULL) >> 16; - uint64_t tgb = (top & 0x0000ffff0000ffffULL); - uint64_t bgb = (bot & 0x0000ffff0000ffffULL); - uint64_t ar, gb; - uint32_t a, r, g, b; - - ar = (tar << 8) + dist_y * (bar - tar); - gb = (tgb << 8) + dist_y * (bgb - tgb); - - a = ((ar >> 24) & 0xff000000); - r = ((ar >> 0) & 0x00ff0000); - g = ((gb >> 40) & 0x0000ff00); - b = ((gb >> 16) & 0x000000ff); -#endif - - iter->buffer[i] = a | r | g | b; - } - - info->y += iter->image->common.transform->matrix[1][1]; - - return iter->buffer; -} - -static void -bilinear_cover_iter_fini (pixman_iter_t *iter) -{ - free (iter->data); -} - -static void -fast_bilinear_cover_iter_init (pixman_iter_t *iter, const pixman_iter_info_t *iter_info) -{ - int width = iter->width; - bilinear_info_t *info; - pixman_vector_t v; - - /* Reference point is the center of the pixel */ - v.vector[0] = pixman_int_to_fixed (iter->x) + pixman_fixed_1 / 2; - v.vector[1] = pixman_int_to_fixed (iter->y) + pixman_fixed_1 / 2; - v.vector[2] = pixman_fixed_1; - - if (!pixman_transform_point_3d (iter->image->common.transform, &v)) - goto fail; - - info = malloc (sizeof (*info) + (2 * width - 1) * sizeof (uint64_t)); - if (!info) - goto fail; - - info->x = v.vector[0] - pixman_fixed_1 / 2; - info->y = v.vector[1] - pixman_fixed_1 / 2; - - /* It is safe to set the y coordinates to -1 initially - * because COVER_CLIP_BILINEAR ensures that we will only - * be asked to fetch lines in the [0, height) interval - */ - info->lines[0].y = -1; - info->lines[0].buffer = &(info->data[0]); - info->lines[1].y = -1; - info->lines[1].buffer = &(info->data[width]); - - iter->get_scanline = fast_fetch_bilinear_cover; - iter->fini = bilinear_cover_iter_fini; - - iter->data = info; - return; - -fail: - /* Something went wrong, either a bad matrix or OOM; in such cases, - * we don't guarantee any particular rendering. - */ - _pixman_log_error ( - FUNC, "Allocation failure or bad matrix, skipping rendering\n"); - - iter->get_scanline = _pixman_iter_get_scanline_noop; - iter->fini = NULL; -} - -static uint32_t * -bits_image_fetch_bilinear_no_repeat_8888 (pixman_iter_t *iter, - const uint32_t *mask) -{ - - pixman_image_t * ima = iter->image; - int offset = iter->x; - int line = iter->y++; - int width = iter->width; - uint32_t * buffer = iter->buffer; - - bits_image_t *bits = &ima->bits; - pixman_fixed_t x_top, x_bottom, x; - pixman_fixed_t ux_top, ux_bottom, ux; - pixman_vector_t v; - uint32_t top_mask, bottom_mask; - uint32_t *top_row; - uint32_t *bottom_row; - uint32_t *end; - uint32_t zero[2] = { 0, 0 }; - uint32_t one = 1; - int y, y1, y2; - int disty; - int mask_inc; - int w; - - /* reference point is the center of the pixel */ - v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2; - v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2; - v.vector[2] = pixman_fixed_1; - - if (!pixman_transform_point_3d (bits->common.transform, &v)) - return iter->buffer; - - ux = ux_top = ux_bottom = bits->common.transform->matrix[0][0]; - x = x_top = x_bottom = v.vector[0] - pixman_fixed_1/2; - - y = v.vector[1] - pixman_fixed_1/2; - disty = pixman_fixed_to_bilinear_weight (y); - - /* Load the pointers to the first and second lines from the source - * image that bilinear code must read. - * - * The main trick in this code is about the check if any line are - * outside of the image; - * - * When I realize that a line (any one) is outside, I change - * the pointer to a dummy area with zeros. Once I change this, I - * must be sure the pointer will not change, so I set the - * variables to each pointer increments inside the loop. - */ - y1 = pixman_fixed_to_int (y); - y2 = y1 + 1; - - if (y1 < 0 || y1 >= bits->height) - { - top_row = zero; - x_top = 0; - ux_top = 0; - } - else - { - top_row = bits->bits + y1 * bits->rowstride; - x_top = x; - ux_top = ux; - } - - if (y2 < 0 || y2 >= bits->height) - { - bottom_row = zero; - x_bottom = 0; - ux_bottom = 0; - } - else - { - bottom_row = bits->bits + y2 * bits->rowstride; - x_bottom = x; - ux_bottom = ux; - } - - /* Instead of checking whether the operation uses the mast in - * each loop iteration, verify this only once and prepare the - * variables to make the code smaller inside the loop. - */ - if (!mask) - { - mask_inc = 0; - mask = &one; - } - else - { - /* If have a mask, prepare the variables to check it */ - mask_inc = 1; - } - - /* If both are zero, then the whole thing is zero */ - if (top_row == zero && bottom_row == zero) - { - memset (buffer, 0, width * sizeof (uint32_t)); - return iter->buffer; - } - else if (bits->format == PIXMAN_x8r8g8b8) - { - if (top_row == zero) - { - top_mask = 0; - bottom_mask = 0xff000000; - } - else if (bottom_row == zero) - { - top_mask = 0xff000000; - bottom_mask = 0; - } - else - { - top_mask = 0xff000000; - bottom_mask = 0xff000000; - } - } - else - { - top_mask = 0; - bottom_mask = 0; - } - - end = buffer + width; - - /* Zero fill to the left of the image */ - while (buffer < end && x < pixman_fixed_minus_1) - { - *buffer++ = 0; - x += ux; - x_top += ux_top; - x_bottom += ux_bottom; - mask += mask_inc; - } - - /* Left edge - */ - while (buffer < end && x < 0) - { - uint32_t tr, br; - int32_t distx; - - tr = top_row[pixman_fixed_to_int (x_top) + 1] | top_mask; - br = bottom_row[pixman_fixed_to_int (x_bottom) + 1] | bottom_mask; - - distx = pixman_fixed_to_bilinear_weight (x); - - *buffer++ = bilinear_interpolation (0, tr, 0, br, distx, disty); - - x += ux; - x_top += ux_top; - x_bottom += ux_bottom; - mask += mask_inc; - } - - /* Main part */ - w = pixman_int_to_fixed (bits->width - 1); - - while (buffer < end && x < w) - { - if (*mask) - { - uint32_t tl, tr, bl, br; - int32_t distx; - - tl = top_row [pixman_fixed_to_int (x_top)] | top_mask; - tr = top_row [pixman_fixed_to_int (x_top) + 1] | top_mask; - bl = bottom_row [pixman_fixed_to_int (x_bottom)] | bottom_mask; - br = bottom_row [pixman_fixed_to_int (x_bottom) + 1] | bottom_mask; - - distx = pixman_fixed_to_bilinear_weight (x); - - *buffer = bilinear_interpolation (tl, tr, bl, br, distx, disty); - } - - buffer++; - x += ux; - x_top += ux_top; - x_bottom += ux_bottom; - mask += mask_inc; - } - - /* Right Edge */ - w = pixman_int_to_fixed (bits->width); - while (buffer < end && x < w) - { - if (*mask) - { - uint32_t tl, bl; - int32_t distx; - - tl = top_row [pixman_fixed_to_int (x_top)] | top_mask; - bl = bottom_row [pixman_fixed_to_int (x_bottom)] | bottom_mask; - - distx = pixman_fixed_to_bilinear_weight (x); - - *buffer = bilinear_interpolation (tl, 0, bl, 0, distx, disty); - } - - buffer++; - x += ux; - x_top += ux_top; - x_bottom += ux_bottom; - mask += mask_inc; - } - - /* Zero fill to the left of the image */ - while (buffer < end) - *buffer++ = 0; - - return iter->buffer; -} - -typedef uint32_t (* convert_pixel_t) (const uint8_t *row, int x); - -static force_inline void -bits_image_fetch_separable_convolution_affine (pixman_image_t * image, - int offset, - int line, - int width, - uint32_t * buffer, - const uint32_t * mask, - - convert_pixel_t convert_pixel, - pixman_format_code_t format, - pixman_repeat_t repeat_mode) -{ - bits_image_t *bits = &image->bits; - pixman_fixed_t *params = image->common.filter_params; - int cwidth = pixman_fixed_to_int (params[0]); - int cheight = pixman_fixed_to_int (params[1]); - int x_off = ((cwidth << 16) - pixman_fixed_1) >> 1; - int y_off = ((cheight << 16) - pixman_fixed_1) >> 1; - int x_phase_bits = pixman_fixed_to_int (params[2]); - int y_phase_bits = pixman_fixed_to_int (params[3]); - int x_phase_shift = 16 - x_phase_bits; - int y_phase_shift = 16 - y_phase_bits; - pixman_fixed_t vx, vy; - pixman_fixed_t ux, uy; - pixman_vector_t v; - int k; - - /* reference point is the center of the pixel */ - v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2; - v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2; - v.vector[2] = pixman_fixed_1; - - if (!pixman_transform_point_3d (image->common.transform, &v)) - return; - - ux = image->common.transform->matrix[0][0]; - uy = image->common.transform->matrix[1][0]; - - vx = v.vector[0]; - vy = v.vector[1]; - - for (k = 0; k < width; ++k) - { - pixman_fixed_t *y_params; - int satot, srtot, sgtot, sbtot; - pixman_fixed_t x, y; - int32_t x1, x2, y1, y2; - int32_t px, py; - int i, j; - - if (mask && !mask[k]) - goto next; - - /* Round x and y to the middle of the closest phase before continuing. This - * ensures that the convolution matrix is aligned right, since it was - * positioned relative to a particular phase (and not relative to whatever - * exact fraction we happen to get here). - */ - x = ((vx >> x_phase_shift) << x_phase_shift) + ((1 << x_phase_shift) >> 1); - y = ((vy >> y_phase_shift) << y_phase_shift) + ((1 << y_phase_shift) >> 1); - - px = (x & 0xffff) >> x_phase_shift; - py = (y & 0xffff) >> y_phase_shift; - - x1 = pixman_fixed_to_int (x - pixman_fixed_e - x_off); - y1 = pixman_fixed_to_int (y - pixman_fixed_e - y_off); - x2 = x1 + cwidth; - y2 = y1 + cheight; - - satot = srtot = sgtot = sbtot = 0; - - y_params = params + 4 + (1 << x_phase_bits) * cwidth + py * cheight; - - for (i = y1; i < y2; ++i) - { - pixman_fixed_t fy = *y_params++; - - if (fy) - { - pixman_fixed_t *x_params = params + 4 + px * cwidth; - - for (j = x1; j < x2; ++j) - { - pixman_fixed_t fx = *x_params++; - int rx = j; - int ry = i; - - if (fx) - { - pixman_fixed_t f; - uint32_t pixel, mask; - uint8_t *row; - - mask = PIXMAN_FORMAT_A (format)? 0 : 0xff000000; - - if (repeat_mode != PIXMAN_REPEAT_NONE) - { - repeat (repeat_mode, &rx, bits->width); - repeat (repeat_mode, &ry, bits->height); - - row = (uint8_t *)bits->bits + bits->rowstride * 4 * ry; - pixel = convert_pixel (row, rx) | mask; - } - else - { - if (rx < 0 || ry < 0 || rx >= bits->width || ry >= bits->height) - { - pixel = 0; - } - else - { - row = (uint8_t *)bits->bits + bits->rowstride * 4 * ry; - pixel = convert_pixel (row, rx) | mask; - } - } - - f = ((pixman_fixed_32_32_t)fx * fy + 0x8000) >> 16; - srtot += (int)RED_8 (pixel) * f; - sgtot += (int)GREEN_8 (pixel) * f; - sbtot += (int)BLUE_8 (pixel) * f; - satot += (int)ALPHA_8 (pixel) * f; - } - } - } - } - - satot = (satot + 0x8000) >> 16; - srtot = (srtot + 0x8000) >> 16; - sgtot = (sgtot + 0x8000) >> 16; - sbtot = (sbtot + 0x8000) >> 16; - - satot = CLIP (satot, 0, 0xff); - srtot = CLIP (srtot, 0, 0xff); - sgtot = CLIP (sgtot, 0, 0xff); - sbtot = CLIP (sbtot, 0, 0xff); - - buffer[k] = (satot << 24) | (srtot << 16) | (sgtot << 8) | (sbtot << 0); - - next: - vx += ux; - vy += uy; - } -} - -static const uint8_t zero[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - -static force_inline void -bits_image_fetch_bilinear_affine (pixman_image_t * image, - int offset, - int line, - int width, - uint32_t * buffer, - const uint32_t * mask, - - convert_pixel_t convert_pixel, - pixman_format_code_t format, - pixman_repeat_t repeat_mode) -{ - pixman_fixed_t x, y; - pixman_fixed_t ux, uy; - pixman_vector_t v; - bits_image_t *bits = &image->bits; - int i; - - /* reference point is the center of the pixel */ - v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2; - v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2; - v.vector[2] = pixman_fixed_1; - - if (!pixman_transform_point_3d (image->common.transform, &v)) - return; - - ux = image->common.transform->matrix[0][0]; - uy = image->common.transform->matrix[1][0]; - - x = v.vector[0]; - y = v.vector[1]; - - for (i = 0; i < width; ++i) - { - int x1, y1, x2, y2; - uint32_t tl, tr, bl, br; - int32_t distx, disty; - int width = image->bits.width; - int height = image->bits.height; - const uint8_t *row1; - const uint8_t *row2; - - if (mask && !mask[i]) - goto next; - - x1 = x - pixman_fixed_1 / 2; - y1 = y - pixman_fixed_1 / 2; - - distx = pixman_fixed_to_bilinear_weight (x1); - disty = pixman_fixed_to_bilinear_weight (y1); - - y1 = pixman_fixed_to_int (y1); - y2 = y1 + 1; - x1 = pixman_fixed_to_int (x1); - x2 = x1 + 1; - - if (repeat_mode != PIXMAN_REPEAT_NONE) - { - uint32_t mask; - - mask = PIXMAN_FORMAT_A (format)? 0 : 0xff000000; - - repeat (repeat_mode, &x1, width); - repeat (repeat_mode, &y1, height); - repeat (repeat_mode, &x2, width); - repeat (repeat_mode, &y2, height); - - row1 = (uint8_t *)bits->bits + bits->rowstride * 4 * y1; - row2 = (uint8_t *)bits->bits + bits->rowstride * 4 * y2; - - tl = convert_pixel (row1, x1) | mask; - tr = convert_pixel (row1, x2) | mask; - bl = convert_pixel (row2, x1) | mask; - br = convert_pixel (row2, x2) | mask; - } - else - { - uint32_t mask1, mask2; - int bpp; - - /* Note: PIXMAN_FORMAT_BPP() returns an unsigned value, - * which means if you use it in expressions, those - * expressions become unsigned themselves. Since - * the variables below can be negative in some cases, - * that will lead to crashes on 64 bit architectures. - * - * So this line makes sure bpp is signed - */ - bpp = PIXMAN_FORMAT_BPP (format); - - if (x1 >= width || x2 < 0 || y1 >= height || y2 < 0) - { - buffer[i] = 0; - goto next; - } - - if (y2 == 0) - { - row1 = zero; - mask1 = 0; - } - else - { - row1 = (uint8_t *)bits->bits + bits->rowstride * 4 * y1; - row1 += bpp / 8 * x1; - - mask1 = PIXMAN_FORMAT_A (format)? 0 : 0xff000000; - } - - if (y1 == height - 1) - { - row2 = zero; - mask2 = 0; - } - else - { - row2 = (uint8_t *)bits->bits + bits->rowstride * 4 * y2; - row2 += bpp / 8 * x1; - - mask2 = PIXMAN_FORMAT_A (format)? 0 : 0xff000000; - } - - if (x2 == 0) - { - tl = 0; - bl = 0; - } - else - { - tl = convert_pixel (row1, 0) | mask1; - bl = convert_pixel (row2, 0) | mask2; - } - - if (x1 == width - 1) - { - tr = 0; - br = 0; - } - else - { - tr = convert_pixel (row1, 1) | mask1; - br = convert_pixel (row2, 1) | mask2; - } - } - - buffer[i] = bilinear_interpolation ( - tl, tr, bl, br, distx, disty); - - next: - x += ux; - y += uy; - } -} - -static force_inline void -bits_image_fetch_nearest_affine (pixman_image_t * image, - int offset, - int line, - int width, - uint32_t * buffer, - const uint32_t * mask, - - convert_pixel_t convert_pixel, - pixman_format_code_t format, - pixman_repeat_t repeat_mode) -{ - pixman_fixed_t x, y; - pixman_fixed_t ux, uy; - pixman_vector_t v; - bits_image_t *bits = &image->bits; - int i; - - /* reference point is the center of the pixel */ - v.vector[0] = pixman_int_to_fixed (offset) + pixman_fixed_1 / 2; - v.vector[1] = pixman_int_to_fixed (line) + pixman_fixed_1 / 2; - v.vector[2] = pixman_fixed_1; - - if (!pixman_transform_point_3d (image->common.transform, &v)) - return; - - ux = image->common.transform->matrix[0][0]; - uy = image->common.transform->matrix[1][0]; - - x = v.vector[0]; - y = v.vector[1]; - - for (i = 0; i < width; ++i) - { - int width, height, x0, y0; - const uint8_t *row; - - if (mask && !mask[i]) - goto next; - - width = image->bits.width; - height = image->bits.height; - x0 = pixman_fixed_to_int (x - pixman_fixed_e); - y0 = pixman_fixed_to_int (y - pixman_fixed_e); - - if (repeat_mode == PIXMAN_REPEAT_NONE && - (y0 < 0 || y0 >= height || x0 < 0 || x0 >= width)) - { - buffer[i] = 0; - } - else - { - uint32_t mask = PIXMAN_FORMAT_A (format)? 0 : 0xff000000; - - if (repeat_mode != PIXMAN_REPEAT_NONE) - { - repeat (repeat_mode, &x0, width); - repeat (repeat_mode, &y0, height); - } - - row = (uint8_t *)bits->bits + bits->rowstride * 4 * y0; - - buffer[i] = convert_pixel (row, x0) | mask; - } - - next: - x += ux; - y += uy; - } -} - -static force_inline uint32_t -convert_a8r8g8b8 (const uint8_t *row, int x) -{ - return *(((uint32_t *)row) + x); -} - -static force_inline uint32_t -convert_x8r8g8b8 (const uint8_t *row, int x) -{ - return *(((uint32_t *)row) + x); -} - -static force_inline uint32_t -convert_a8 (const uint8_t *row, int x) -{ - return *(row + x) << 24; -} - -static force_inline uint32_t -convert_r5g6b5 (const uint8_t *row, int x) -{ - return convert_0565_to_0888 (*((uint16_t *)row + x)); -} - -#define MAKE_SEPARABLE_CONVOLUTION_FETCHER(name, format, repeat_mode) \ - static uint32_t * \ - bits_image_fetch_separable_convolution_affine_ ## name (pixman_iter_t *iter, \ - const uint32_t * mask) \ - { \ - bits_image_fetch_separable_convolution_affine ( \ - iter->image, \ - iter->x, iter->y++, \ - iter->width, \ - iter->buffer, mask, \ - convert_ ## format, \ - PIXMAN_ ## format, \ - repeat_mode); \ - \ - return iter->buffer; \ - } - -#define MAKE_BILINEAR_FETCHER(name, format, repeat_mode) \ - static uint32_t * \ - bits_image_fetch_bilinear_affine_ ## name (pixman_iter_t *iter, \ - const uint32_t * mask) \ - { \ - bits_image_fetch_bilinear_affine (iter->image, \ - iter->x, iter->y++, \ - iter->width, \ - iter->buffer, mask, \ - convert_ ## format, \ - PIXMAN_ ## format, \ - repeat_mode); \ - return iter->buffer; \ - } - -#define MAKE_NEAREST_FETCHER(name, format, repeat_mode) \ - static uint32_t * \ - bits_image_fetch_nearest_affine_ ## name (pixman_iter_t *iter, \ - const uint32_t * mask) \ - { \ - bits_image_fetch_nearest_affine (iter->image, \ - iter->x, iter->y++, \ - iter->width, \ - iter->buffer, mask, \ - convert_ ## format, \ - PIXMAN_ ## format, \ - repeat_mode); \ - return iter->buffer; \ - } - -#define MAKE_FETCHERS(name, format, repeat_mode) \ - MAKE_NEAREST_FETCHER (name, format, repeat_mode) \ - MAKE_BILINEAR_FETCHER (name, format, repeat_mode) \ - MAKE_SEPARABLE_CONVOLUTION_FETCHER (name, format, repeat_mode) - -MAKE_FETCHERS (pad_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_PAD) -MAKE_FETCHERS (none_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_NONE) -MAKE_FETCHERS (reflect_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_REFLECT) -MAKE_FETCHERS (normal_a8r8g8b8, a8r8g8b8, PIXMAN_REPEAT_NORMAL) -MAKE_FETCHERS (pad_x8r8g8b8, x8r8g8b8, PIXMAN_REPEAT_PAD) -MAKE_FETCHERS (none_x8r8g8b8, x8r8g8b8, PIXMAN_REPEAT_NONE) -MAKE_FETCHERS (reflect_x8r8g8b8, x8r8g8b8, PIXMAN_REPEAT_REFLECT) -MAKE_FETCHERS (normal_x8r8g8b8, x8r8g8b8, PIXMAN_REPEAT_NORMAL) -MAKE_FETCHERS (pad_a8, a8, PIXMAN_REPEAT_PAD) -MAKE_FETCHERS (none_a8, a8, PIXMAN_REPEAT_NONE) -MAKE_FETCHERS (reflect_a8, a8, PIXMAN_REPEAT_REFLECT) -MAKE_FETCHERS (normal_a8, a8, PIXMAN_REPEAT_NORMAL) -MAKE_FETCHERS (pad_r5g6b5, r5g6b5, PIXMAN_REPEAT_PAD) -MAKE_FETCHERS (none_r5g6b5, r5g6b5, PIXMAN_REPEAT_NONE) -MAKE_FETCHERS (reflect_r5g6b5, r5g6b5, PIXMAN_REPEAT_REFLECT) -MAKE_FETCHERS (normal_r5g6b5, r5g6b5, PIXMAN_REPEAT_NORMAL) - -#define IMAGE_FLAGS \ - (FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM | \ - FAST_PATH_BITS_IMAGE | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST) - -static const pixman_iter_info_t fast_iters[] = -{ - { PIXMAN_r5g6b5, IMAGE_FLAGS, ITER_NARROW | ITER_SRC, - _pixman_iter_init_bits_stride, fast_fetch_r5g6b5, NULL }, - - { PIXMAN_r5g6b5, FAST_PATH_STD_DEST_FLAGS, - ITER_NARROW | ITER_DEST, - _pixman_iter_init_bits_stride, - fast_fetch_r5g6b5, fast_write_back_r5g6b5 }, - - { PIXMAN_r5g6b5, FAST_PATH_STD_DEST_FLAGS, - ITER_NARROW | ITER_DEST | ITER_IGNORE_RGB | ITER_IGNORE_ALPHA, - _pixman_iter_init_bits_stride, - fast_dest_fetch_noop, fast_write_back_r5g6b5 }, - - { PIXMAN_a8r8g8b8, - (FAST_PATH_STANDARD_FLAGS | - FAST_PATH_SCALE_TRANSFORM | - FAST_PATH_BILINEAR_FILTER | - FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR), - ITER_NARROW | ITER_SRC, - fast_bilinear_cover_iter_init, - NULL, NULL - }, - -#define FAST_BILINEAR_FLAGS \ - (FAST_PATH_NO_ALPHA_MAP | \ - FAST_PATH_NO_ACCESSORS | \ - FAST_PATH_HAS_TRANSFORM | \ - FAST_PATH_AFFINE_TRANSFORM | \ - FAST_PATH_X_UNIT_POSITIVE | \ - FAST_PATH_Y_UNIT_ZERO | \ - FAST_PATH_NONE_REPEAT | \ - FAST_PATH_BILINEAR_FILTER) - - { PIXMAN_a8r8g8b8, - FAST_BILINEAR_FLAGS, - ITER_NARROW | ITER_SRC, - NULL, bits_image_fetch_bilinear_no_repeat_8888, NULL - }, - - { PIXMAN_x8r8g8b8, - FAST_BILINEAR_FLAGS, - ITER_NARROW | ITER_SRC, - NULL, bits_image_fetch_bilinear_no_repeat_8888, NULL - }, - -#define GENERAL_BILINEAR_FLAGS \ - (FAST_PATH_NO_ALPHA_MAP | \ - FAST_PATH_NO_ACCESSORS | \ - FAST_PATH_HAS_TRANSFORM | \ - FAST_PATH_AFFINE_TRANSFORM | \ - FAST_PATH_BILINEAR_FILTER) - -#define GENERAL_NEAREST_FLAGS \ - (FAST_PATH_NO_ALPHA_MAP | \ - FAST_PATH_NO_ACCESSORS | \ - FAST_PATH_HAS_TRANSFORM | \ - FAST_PATH_AFFINE_TRANSFORM | \ - FAST_PATH_NEAREST_FILTER) - -#define GENERAL_SEPARABLE_CONVOLUTION_FLAGS \ - (FAST_PATH_NO_ALPHA_MAP | \ - FAST_PATH_NO_ACCESSORS | \ - FAST_PATH_HAS_TRANSFORM | \ - FAST_PATH_AFFINE_TRANSFORM | \ - FAST_PATH_SEPARABLE_CONVOLUTION_FILTER) - -#define SEPARABLE_CONVOLUTION_AFFINE_FAST_PATH(name, format, repeat) \ - { PIXMAN_ ## format, \ - GENERAL_SEPARABLE_CONVOLUTION_FLAGS | FAST_PATH_ ## repeat ## _REPEAT, \ - ITER_NARROW | ITER_SRC, \ - NULL, bits_image_fetch_separable_convolution_affine_ ## name, NULL \ - }, - -#define BILINEAR_AFFINE_FAST_PATH(name, format, repeat) \ - { PIXMAN_ ## format, \ - GENERAL_BILINEAR_FLAGS | FAST_PATH_ ## repeat ## _REPEAT, \ - ITER_NARROW | ITER_SRC, \ - NULL, bits_image_fetch_bilinear_affine_ ## name, NULL, \ - }, - -#define NEAREST_AFFINE_FAST_PATH(name, format, repeat) \ - { PIXMAN_ ## format, \ - GENERAL_NEAREST_FLAGS | FAST_PATH_ ## repeat ## _REPEAT, \ - ITER_NARROW | ITER_SRC, \ - NULL, bits_image_fetch_nearest_affine_ ## name, NULL \ - }, - -#define AFFINE_FAST_PATHS(name, format, repeat) \ - SEPARABLE_CONVOLUTION_AFFINE_FAST_PATH(name, format, repeat) \ - BILINEAR_AFFINE_FAST_PATH(name, format, repeat) \ - NEAREST_AFFINE_FAST_PATH(name, format, repeat) - - AFFINE_FAST_PATHS (pad_a8r8g8b8, a8r8g8b8, PAD) - AFFINE_FAST_PATHS (none_a8r8g8b8, a8r8g8b8, NONE) - AFFINE_FAST_PATHS (reflect_a8r8g8b8, a8r8g8b8, REFLECT) - AFFINE_FAST_PATHS (normal_a8r8g8b8, a8r8g8b8, NORMAL) - AFFINE_FAST_PATHS (pad_x8r8g8b8, x8r8g8b8, PAD) - AFFINE_FAST_PATHS (none_x8r8g8b8, x8r8g8b8, NONE) - AFFINE_FAST_PATHS (reflect_x8r8g8b8, x8r8g8b8, REFLECT) - AFFINE_FAST_PATHS (normal_x8r8g8b8, x8r8g8b8, NORMAL) - AFFINE_FAST_PATHS (pad_a8, a8, PAD) - AFFINE_FAST_PATHS (none_a8, a8, NONE) - AFFINE_FAST_PATHS (reflect_a8, a8, REFLECT) - AFFINE_FAST_PATHS (normal_a8, a8, NORMAL) - AFFINE_FAST_PATHS (pad_r5g6b5, r5g6b5, PAD) - AFFINE_FAST_PATHS (none_r5g6b5, r5g6b5, NONE) - AFFINE_FAST_PATHS (reflect_r5g6b5, r5g6b5, REFLECT) - AFFINE_FAST_PATHS (normal_r5g6b5, r5g6b5, NORMAL) - - { PIXMAN_null }, -}; - -pixman_implementation_t * -_pixman_implementation_create_fast_path (pixman_implementation_t *fallback) -{ - pixman_implementation_t *imp = _pixman_implementation_create (fallback, c_fast_paths); - - imp->fill = fast_path_fill; - imp->iter_info = fast_iters; - - return imp; -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman-filter.c b/source/libs/pixman/pixman-src/pixman/pixman-filter.c deleted file mode 100644 index b2bf53fed147b7cffab3c74f8922376ceac14977..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-filter.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Copyright 2012, Red Hat, Inc. - * Copyright 2012, Soren Sandmann - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Soren Sandmann <soren.sandmann@gmail.com> - */ -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -#include <math.h> -#include <assert.h> -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "pixman-private.h" - -typedef double (* kernel_func_t) (double x); - -typedef struct -{ - pixman_kernel_t kernel; - kernel_func_t func; - double width; -} filter_info_t; - -static double -impulse_kernel (double x) -{ - return (x == 0.0)? 1.0 : 0.0; -} - -static double -box_kernel (double x) -{ - return 1; -} - -static double -linear_kernel (double x) -{ - return 1 - fabs (x); -} - -static double -gaussian_kernel (double x) -{ -#define SQRT2 (1.4142135623730950488016887242096980785696718753769480) -#define SIGMA (SQRT2 / 2.0) - - return exp (- x * x / (2 * SIGMA * SIGMA)) / (SIGMA * sqrt (2.0 * M_PI)); -} - -static double -sinc (double x) -{ - if (x == 0.0) - return 1.0; - else - return sin (M_PI * x) / (M_PI * x); -} - -static double -lanczos (double x, int n) -{ - return sinc (x) * sinc (x * (1.0 / n)); -} - -static double -lanczos2_kernel (double x) -{ - return lanczos (x, 2); -} - -static double -lanczos3_kernel (double x) -{ - return lanczos (x, 3); -} - -static double -nice_kernel (double x) -{ - return lanczos3_kernel (x * 0.75); -} - -static double -general_cubic (double x, double B, double C) -{ - double ax = fabs(x); - - if (ax < 1) - { - return ((12 - 9 * B - 6 * C) * ax * ax * ax + - (-18 + 12 * B + 6 * C) * ax * ax + (6 - 2 * B)) / 6; - } - else if (ax >= 1 && ax < 2) - { - return ((-B - 6 * C) * ax * ax * ax + - (6 * B + 30 * C) * ax * ax + (-12 * B - 48 * C) * - ax + (8 * B + 24 * C)) / 6; - } - else - { - return 0; - } -} - -static double -cubic_kernel (double x) -{ - /* This is the Mitchell-Netravali filter. - * - * (0.0, 0.5) would give us the Catmull-Rom spline, - * but that one seems to be indistinguishable from Lanczos2. - */ - return general_cubic (x, 1/3.0, 1/3.0); -} - -static const filter_info_t filters[] = -{ - { PIXMAN_KERNEL_IMPULSE, impulse_kernel, 0.0 }, - { PIXMAN_KERNEL_BOX, box_kernel, 1.0 }, - { PIXMAN_KERNEL_LINEAR, linear_kernel, 2.0 }, - { PIXMAN_KERNEL_CUBIC, cubic_kernel, 4.0 }, - { PIXMAN_KERNEL_GAUSSIAN, gaussian_kernel, 6 * SIGMA }, - { PIXMAN_KERNEL_LANCZOS2, lanczos2_kernel, 4.0 }, - { PIXMAN_KERNEL_LANCZOS3, lanczos3_kernel, 6.0 }, - { PIXMAN_KERNEL_LANCZOS3_STRETCHED, nice_kernel, 8.0 }, -}; - -/* This function scales @kernel2 by @scale, then - * aligns @x1 in @kernel1 with @x2 in @kernel2 and - * and integrates the product of the kernels across @width. - * - * This function assumes that the intervals are within - * the kernels in question. E.g., the caller must not - * try to integrate a linear kernel ouside of [-1:1] - */ -static double -integral (pixman_kernel_t kernel1, double x1, - pixman_kernel_t kernel2, double scale, double x2, - double width) -{ - /* If the integration interval crosses zero, break it into - * two separate integrals. This ensures that filters such - * as LINEAR that are not differentiable at 0 will still - * integrate properly. - */ - if (x1 < 0 && x1 + width > 0) - { - return - integral (kernel1, x1, kernel2, scale, x2, - x1) + - integral (kernel1, 0, kernel2, scale, x2 - x1, width + x1); - } - else if (x2 < 0 && x2 + width > 0) - { - return - integral (kernel1, x1, kernel2, scale, x2, - x2) + - integral (kernel1, x1 - x2, kernel2, scale, 0, width + x2); - } - else if (kernel1 == PIXMAN_KERNEL_IMPULSE) - { - assert (width == 0.0); - return filters[kernel2].func (x2 * scale); - } - else if (kernel2 == PIXMAN_KERNEL_IMPULSE) - { - assert (width == 0.0); - return filters[kernel1].func (x1); - } - else - { - /* Integration via Simpson's rule */ -#define N_SEGMENTS 128 -#define SAMPLE(a1, a2) \ - (filters[kernel1].func ((a1)) * filters[kernel2].func ((a2) * scale)) - - double s = 0.0; - double h = width / (double)N_SEGMENTS; - int i; - - s = SAMPLE (x1, x2); - - for (i = 1; i < N_SEGMENTS; i += 2) - { - double a1 = x1 + h * i; - double a2 = x2 + h * i; - - s += 2 * SAMPLE (a1, a2); - - if (i >= 2 && i < N_SEGMENTS - 1) - s += 4 * SAMPLE (a1, a2); - } - - s += SAMPLE (x1 + width, x2 + width); - - return h * s * (1.0 / 3.0); - } -} - -static pixman_fixed_t * -create_1d_filter (int *width, - pixman_kernel_t reconstruct, - pixman_kernel_t sample, - double scale, - int n_phases) -{ - pixman_fixed_t *params, *p; - double step; - double size; - int i; - - size = scale * filters[sample].width + filters[reconstruct].width; - *width = ceil (size); - - p = params = malloc (*width * n_phases * sizeof (pixman_fixed_t)); - if (!params) - return NULL; - - step = 1.0 / n_phases; - - for (i = 0; i < n_phases; ++i) - { - double frac = step / 2.0 + i * step; - pixman_fixed_t new_total; - int x, x1, x2; - double total; - - /* Sample convolution of reconstruction and sampling - * filter. See rounding.txt regarding the rounding - * and sample positions. - */ - - x1 = ceil (frac - *width / 2.0 - 0.5); - x2 = x1 + *width; - - total = 0; - for (x = x1; x < x2; ++x) - { - double pos = x + 0.5 - frac; - double rlow = - filters[reconstruct].width / 2.0; - double rhigh = rlow + filters[reconstruct].width; - double slow = pos - scale * filters[sample].width / 2.0; - double shigh = slow + scale * filters[sample].width; - double c = 0.0; - double ilow, ihigh; - - if (rhigh >= slow && rlow <= shigh) - { - ilow = MAX (slow, rlow); - ihigh = MIN (shigh, rhigh); - - c = integral (reconstruct, ilow, - sample, 1.0 / scale, ilow - pos, - ihigh - ilow); - } - - total += c; - *p++ = (pixman_fixed_t)(c * 65536.0 + 0.5); - } - - /* Normalize */ - p -= *width; - total = 1 / total; - new_total = 0; - for (x = x1; x < x2; ++x) - { - pixman_fixed_t t = (*p) * total + 0.5; - - new_total += t; - *p++ = t; - } - - if (new_total != pixman_fixed_1) - *(p - *width / 2) += (pixman_fixed_1 - new_total); - } - - return params; -} - -/* Create the parameter list for a SEPARABLE_CONVOLUTION filter - * with the given kernels and scale parameters - */ -PIXMAN_EXPORT pixman_fixed_t * -pixman_filter_create_separable_convolution (int *n_values, - pixman_fixed_t scale_x, - pixman_fixed_t scale_y, - pixman_kernel_t reconstruct_x, - pixman_kernel_t reconstruct_y, - pixman_kernel_t sample_x, - pixman_kernel_t sample_y, - int subsample_bits_x, - int subsample_bits_y) -{ - double sx = fabs (pixman_fixed_to_double (scale_x)); - double sy = fabs (pixman_fixed_to_double (scale_y)); - pixman_fixed_t *horz = NULL, *vert = NULL, *params = NULL; - int subsample_x, subsample_y; - int width, height; - - subsample_x = (1 << subsample_bits_x); - subsample_y = (1 << subsample_bits_y); - - horz = create_1d_filter (&width, reconstruct_x, sample_x, sx, subsample_x); - vert = create_1d_filter (&height, reconstruct_y, sample_y, sy, subsample_y); - - if (!horz || !vert) - goto out; - - *n_values = 4 + width * subsample_x + height * subsample_y; - - params = malloc (*n_values * sizeof (pixman_fixed_t)); - if (!params) - goto out; - - params[0] = pixman_int_to_fixed (width); - params[1] = pixman_int_to_fixed (height); - params[2] = pixman_int_to_fixed (subsample_bits_x); - params[3] = pixman_int_to_fixed (subsample_bits_y); - - memcpy (params + 4, horz, - width * subsample_x * sizeof (pixman_fixed_t)); - memcpy (params + 4 + width * subsample_x, vert, - height * subsample_y * sizeof (pixman_fixed_t)); - -out: - free (horz); - free (vert); - - return params; -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman-general.c b/source/libs/pixman/pixman-src/pixman/pixman-general.c deleted file mode 100644 index 6141cb0a30cdb767d8d2b896b1eaf8626d84bf61..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-general.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * Copyright © 2009 Red Hat, Inc. - * Copyright © 2000 SuSE, Inc. - * Copyright © 2007 Red Hat, Inc. - * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. - * 2005 Lars Knoll & Zack Rusin, Trolltech - * 2008 Aaron Plattner, NVIDIA Corporation - * - * 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 not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. Red Hat makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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. - */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdlib.h> -#include <string.h> -#include <math.h> -#include <limits.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "pixman-private.h" - -static void -general_iter_init (pixman_iter_t *iter, const pixman_iter_info_t *info) -{ - pixman_image_t *image = iter->image; - - switch (image->type) - { - case BITS: - if ((iter->iter_flags & ITER_SRC) == ITER_SRC) - _pixman_bits_image_src_iter_init (image, iter); - else - _pixman_bits_image_dest_iter_init (image, iter); - break; - - case LINEAR: - _pixman_linear_gradient_iter_init (image, iter); - break; - - case RADIAL: - _pixman_radial_gradient_iter_init (image, iter); - break; - - case CONICAL: - _pixman_conical_gradient_iter_init (image, iter); - break; - - case SOLID: - _pixman_log_error (FUNC, "Solid image not handled by noop"); - break; - - default: - _pixman_log_error (FUNC, "Pixman bug: unknown image type\n"); - break; - } -} - -static const pixman_iter_info_t general_iters[] = -{ - { PIXMAN_any, 0, 0, general_iter_init, NULL, NULL }, - { PIXMAN_null }, -}; - -typedef struct op_info_t op_info_t; -struct op_info_t -{ - uint8_t src, dst; -}; - -#define ITER_IGNORE_BOTH \ - (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB | ITER_LOCALIZED_ALPHA) - -static const op_info_t op_flags[PIXMAN_N_OPERATORS] = -{ - /* Src Dst */ - { ITER_IGNORE_BOTH, ITER_IGNORE_BOTH }, /* CLEAR */ - { ITER_LOCALIZED_ALPHA, ITER_IGNORE_BOTH }, /* SRC */ - { ITER_IGNORE_BOTH, ITER_LOCALIZED_ALPHA }, /* DST */ - { 0, ITER_LOCALIZED_ALPHA }, /* OVER */ - { ITER_LOCALIZED_ALPHA, 0 }, /* OVER_REVERSE */ - { ITER_LOCALIZED_ALPHA, ITER_IGNORE_RGB }, /* IN */ - { ITER_IGNORE_RGB, ITER_LOCALIZED_ALPHA }, /* IN_REVERSE */ - { ITER_LOCALIZED_ALPHA, ITER_IGNORE_RGB }, /* OUT */ - { ITER_IGNORE_RGB, ITER_LOCALIZED_ALPHA }, /* OUT_REVERSE */ - { 0, 0 }, /* ATOP */ - { 0, 0 }, /* ATOP_REVERSE */ - { 0, 0 }, /* XOR */ - { ITER_LOCALIZED_ALPHA, ITER_LOCALIZED_ALPHA }, /* ADD */ - { 0, 0 }, /* SATURATE */ -}; - -#define SCANLINE_BUFFER_LENGTH 8192 - -static pixman_bool_t -operator_needs_division (pixman_op_t op) -{ - static const uint8_t needs_division[] = - { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, /* SATURATE */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, /* DISJOINT */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, /* CONJOINT */ - 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, /* blend ops */ - }; - - return needs_division[op]; -} - -static void -general_composite_rect (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint8_t stack_scanline_buffer[3 * SCANLINE_BUFFER_LENGTH]; - uint8_t *scanline_buffer = (uint8_t *) stack_scanline_buffer; - uint8_t *src_buffer, *mask_buffer, *dest_buffer; - pixman_iter_t src_iter, mask_iter, dest_iter; - pixman_combine_32_func_t compose; - pixman_bool_t component_alpha; - iter_flags_t width_flag, src_iter_flags; - int Bpp; - int i; - - if ((src_image->common.flags & FAST_PATH_NARROW_FORMAT) && - (!mask_image || mask_image->common.flags & FAST_PATH_NARROW_FORMAT) && - (dest_image->common.flags & FAST_PATH_NARROW_FORMAT) && - !(operator_needs_division (op))) - { - width_flag = ITER_NARROW; - Bpp = 4; - } - else - { - width_flag = ITER_WIDE; - Bpp = 16; - } - -#define ALIGN(addr) \ - ((uint8_t *)((((uintptr_t)(addr)) + 15) & (~15))) - - if (width <= 0 || _pixman_multiply_overflows_int (width, Bpp * 3)) - return; - - if (width * Bpp * 3 > sizeof (stack_scanline_buffer) - 15 * 3) - { - scanline_buffer = pixman_malloc_ab_plus_c (width, Bpp * 3, 15 * 3); - - if (!scanline_buffer) - return; - } - - src_buffer = ALIGN (scanline_buffer); - mask_buffer = ALIGN (src_buffer + width * Bpp); - dest_buffer = ALIGN (mask_buffer + width * Bpp); - - if (width_flag == ITER_WIDE) - { - /* To make sure there aren't any NANs in the buffers */ - memset (src_buffer, 0, width * Bpp); - memset (mask_buffer, 0, width * Bpp); - memset (dest_buffer, 0, width * Bpp); - } - - /* src iter */ - src_iter_flags = width_flag | op_flags[op].src | ITER_SRC; - - _pixman_implementation_iter_init (imp->toplevel, &src_iter, src_image, - src_x, src_y, width, height, - src_buffer, src_iter_flags, - info->src_flags); - - /* mask iter */ - if ((src_iter_flags & (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) == - (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) - { - /* If it doesn't matter what the source is, then it doesn't matter - * what the mask is - */ - mask_image = NULL; - } - - component_alpha = mask_image && mask_image->common.component_alpha; - - _pixman_implementation_iter_init ( - imp->toplevel, &mask_iter, - mask_image, mask_x, mask_y, width, height, mask_buffer, - ITER_SRC | width_flag | (component_alpha? 0 : ITER_IGNORE_RGB), - info->mask_flags); - - /* dest iter */ - _pixman_implementation_iter_init ( - imp->toplevel, &dest_iter, dest_image, dest_x, dest_y, width, height, - dest_buffer, ITER_DEST | width_flag | op_flags[op].dst, info->dest_flags); - - compose = _pixman_implementation_lookup_combiner ( - imp->toplevel, op, component_alpha, width_flag != ITER_WIDE); - - for (i = 0; i < height; ++i) - { - uint32_t *s, *m, *d; - - m = mask_iter.get_scanline (&mask_iter, NULL); - s = src_iter.get_scanline (&src_iter, m); - d = dest_iter.get_scanline (&dest_iter, NULL); - - compose (imp->toplevel, op, d, s, m, width); - - dest_iter.write_back (&dest_iter); - } - - if (src_iter.fini) - src_iter.fini (&src_iter); - if (mask_iter.fini) - mask_iter.fini (&mask_iter); - if (dest_iter.fini) - dest_iter.fini (&dest_iter); - - if (scanline_buffer != (uint8_t *) stack_scanline_buffer) - free (scanline_buffer); -} - -static const pixman_fast_path_t general_fast_path[] = -{ - { PIXMAN_OP_any, PIXMAN_any, 0, PIXMAN_any, 0, PIXMAN_any, 0, general_composite_rect }, - { PIXMAN_OP_NONE } -}; - -pixman_implementation_t * -_pixman_implementation_create_general (void) -{ - pixman_implementation_t *imp = _pixman_implementation_create (NULL, general_fast_path); - - _pixman_setup_combiner_functions_32 (imp); - _pixman_setup_combiner_functions_float (imp); - - imp->iter_info = general_iters; - - return imp; -} - diff --git a/source/libs/pixman/pixman-src/pixman/pixman-glyph.c b/source/libs/pixman/pixman-src/pixman/pixman-glyph.c deleted file mode 100644 index 96a349ab472720b4eb27299ba143c8fa9162def0..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-glyph.c +++ /dev/null @@ -1,676 +0,0 @@ -/* - * Copyright 2010, 2012, Soren Sandmann <sandmann@cs.au.dk> - * Copyright 2010, 2011, 2012, Red Hat, Inc - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Soren Sandmann <sandmann@cs.au.dk> - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "pixman-private.h" - -#include <stdlib.h> - -typedef struct glyph_metrics_t glyph_metrics_t; -typedef struct glyph_t glyph_t; - -#define TOMBSTONE ((glyph_t *)0x1) - -/* XXX: These numbers are arbitrary---we've never done any measurements. - */ -#define N_GLYPHS_HIGH_WATER (16384) -#define N_GLYPHS_LOW_WATER (8192) -#define HASH_SIZE (2 * N_GLYPHS_HIGH_WATER) -#define HASH_MASK (HASH_SIZE - 1) - -struct glyph_t -{ - void * font_key; - void * glyph_key; - int origin_x; - int origin_y; - pixman_image_t * image; - pixman_link_t mru_link; -}; - -struct pixman_glyph_cache_t -{ - int n_glyphs; - int n_tombstones; - int freeze_count; - pixman_list_t mru; - glyph_t * glyphs[HASH_SIZE]; -}; - -static void -free_glyph (glyph_t *glyph) -{ - pixman_list_unlink (&glyph->mru_link); - pixman_image_unref (glyph->image); - free (glyph); -} - -static unsigned int -hash (const void *font_key, const void *glyph_key) -{ - size_t key = (size_t)font_key + (size_t)glyph_key; - - /* This hash function is based on one found on Thomas Wang's - * web page at - * - * http://www.concentric.net/~Ttwang/tech/inthash.htm - * - */ - key = (key << 15) - key - 1; - key = key ^ (key >> 12); - key = key + (key << 2); - key = key ^ (key >> 4); - key = key + (key << 3) + (key << 11); - key = key ^ (key >> 16); - - return key; -} - -static glyph_t * -lookup_glyph (pixman_glyph_cache_t *cache, - void *font_key, - void *glyph_key) -{ - unsigned idx; - glyph_t *g; - - idx = hash (font_key, glyph_key); - while ((g = cache->glyphs[idx++ & HASH_MASK])) - { - if (g != TOMBSTONE && - g->font_key == font_key && - g->glyph_key == glyph_key) - { - return g; - } - } - - return NULL; -} - -static void -insert_glyph (pixman_glyph_cache_t *cache, - glyph_t *glyph) -{ - unsigned idx; - glyph_t **loc; - - idx = hash (glyph->font_key, glyph->glyph_key); - - /* Note: we assume that there is room in the table. If there isn't, - * this will be an infinite loop. - */ - do - { - loc = &cache->glyphs[idx++ & HASH_MASK]; - } while (*loc && *loc != TOMBSTONE); - - if (*loc == TOMBSTONE) - cache->n_tombstones--; - cache->n_glyphs++; - - *loc = glyph; -} - -static void -remove_glyph (pixman_glyph_cache_t *cache, - glyph_t *glyph) -{ - unsigned idx; - - idx = hash (glyph->font_key, glyph->glyph_key); - while (cache->glyphs[idx & HASH_MASK] != glyph) - idx++; - - cache->glyphs[idx & HASH_MASK] = TOMBSTONE; - cache->n_tombstones++; - cache->n_glyphs--; - - /* Eliminate tombstones if possible */ - if (cache->glyphs[(idx + 1) & HASH_MASK] == NULL) - { - while (cache->glyphs[idx & HASH_MASK] == TOMBSTONE) - { - cache->glyphs[idx & HASH_MASK] = NULL; - cache->n_tombstones--; - idx--; - } - } -} - -static void -clear_table (pixman_glyph_cache_t *cache) -{ - int i; - - for (i = 0; i < HASH_SIZE; ++i) - { - glyph_t *glyph = cache->glyphs[i]; - - if (glyph && glyph != TOMBSTONE) - free_glyph (glyph); - - cache->glyphs[i] = NULL; - } - - cache->n_glyphs = 0; - cache->n_tombstones = 0; -} - -PIXMAN_EXPORT pixman_glyph_cache_t * -pixman_glyph_cache_create (void) -{ - pixman_glyph_cache_t *cache; - - if (!(cache = malloc (sizeof *cache))) - return NULL; - - memset (cache->glyphs, 0, sizeof (cache->glyphs)); - cache->n_glyphs = 0; - cache->n_tombstones = 0; - cache->freeze_count = 0; - - pixman_list_init (&cache->mru); - - return cache; -} - -PIXMAN_EXPORT void -pixman_glyph_cache_destroy (pixman_glyph_cache_t *cache) -{ - return_if_fail (cache->freeze_count == 0); - - clear_table (cache); - - free (cache); -} - -PIXMAN_EXPORT void -pixman_glyph_cache_freeze (pixman_glyph_cache_t *cache) -{ - cache->freeze_count++; -} - -PIXMAN_EXPORT void -pixman_glyph_cache_thaw (pixman_glyph_cache_t *cache) -{ - if (--cache->freeze_count == 0 && - cache->n_glyphs + cache->n_tombstones > N_GLYPHS_HIGH_WATER) - { - if (cache->n_tombstones > N_GLYPHS_HIGH_WATER) - { - /* More than half the entries are - * tombstones. Just dump the whole table. - */ - clear_table (cache); - } - - while (cache->n_glyphs > N_GLYPHS_LOW_WATER) - { - glyph_t *glyph = CONTAINER_OF (glyph_t, mru_link, cache->mru.tail); - - remove_glyph (cache, glyph); - free_glyph (glyph); - } - } -} - -PIXMAN_EXPORT const void * -pixman_glyph_cache_lookup (pixman_glyph_cache_t *cache, - void *font_key, - void *glyph_key) -{ - return lookup_glyph (cache, font_key, glyph_key); -} - -PIXMAN_EXPORT const void * -pixman_glyph_cache_insert (pixman_glyph_cache_t *cache, - void *font_key, - void *glyph_key, - int origin_x, - int origin_y, - pixman_image_t *image) -{ - glyph_t *glyph; - int32_t width, height; - - return_val_if_fail (cache->freeze_count > 0, NULL); - return_val_if_fail (image->type == BITS, NULL); - - width = image->bits.width; - height = image->bits.height; - - if (cache->n_glyphs >= HASH_SIZE) - return NULL; - - if (!(glyph = malloc (sizeof *glyph))) - return NULL; - - glyph->font_key = font_key; - glyph->glyph_key = glyph_key; - glyph->origin_x = origin_x; - glyph->origin_y = origin_y; - - if (!(glyph->image = pixman_image_create_bits ( - image->bits.format, width, height, NULL, -1))) - { - free (glyph); - return NULL; - } - - pixman_image_composite32 (PIXMAN_OP_SRC, - image, NULL, glyph->image, 0, 0, 0, 0, 0, 0, - width, height); - - if (PIXMAN_FORMAT_A (glyph->image->bits.format) != 0 && - PIXMAN_FORMAT_RGB (glyph->image->bits.format) != 0) - { - pixman_image_set_component_alpha (glyph->image, TRUE); - } - - pixman_list_prepend (&cache->mru, &glyph->mru_link); - - _pixman_image_validate (glyph->image); - insert_glyph (cache, glyph); - - return glyph; -} - -PIXMAN_EXPORT void -pixman_glyph_cache_remove (pixman_glyph_cache_t *cache, - void *font_key, - void *glyph_key) -{ - glyph_t *glyph; - - if ((glyph = lookup_glyph (cache, font_key, glyph_key))) - { - remove_glyph (cache, glyph); - - free_glyph (glyph); - } -} - -PIXMAN_EXPORT void -pixman_glyph_get_extents (pixman_glyph_cache_t *cache, - int n_glyphs, - pixman_glyph_t *glyphs, - pixman_box32_t *extents) -{ - int i; - - extents->x1 = extents->y1 = INT32_MAX; - extents->x2 = extents->y2 = INT32_MIN; - - for (i = 0; i < n_glyphs; ++i) - { - glyph_t *glyph = (glyph_t *)glyphs[i].glyph; - int x1, y1, x2, y2; - - x1 = glyphs[i].x - glyph->origin_x; - y1 = glyphs[i].y - glyph->origin_y; - x2 = glyphs[i].x - glyph->origin_x + glyph->image->bits.width; - y2 = glyphs[i].y - glyph->origin_y + glyph->image->bits.height; - - if (x1 < extents->x1) - extents->x1 = x1; - if (y1 < extents->y1) - extents->y1 = y1; - if (x2 > extents->x2) - extents->x2 = x2; - if (y2 > extents->y2) - extents->y2 = y2; - } -} - -/* This function returns a format that is suitable for use as a mask for the - * set of glyphs in question. - */ -PIXMAN_EXPORT pixman_format_code_t -pixman_glyph_get_mask_format (pixman_glyph_cache_t *cache, - int n_glyphs, - const pixman_glyph_t *glyphs) -{ - pixman_format_code_t format = PIXMAN_a1; - int i; - - for (i = 0; i < n_glyphs; ++i) - { - const glyph_t *glyph = glyphs[i].glyph; - pixman_format_code_t glyph_format = glyph->image->bits.format; - - if (PIXMAN_FORMAT_TYPE (glyph_format) == PIXMAN_TYPE_A) - { - if (PIXMAN_FORMAT_A (glyph_format) > PIXMAN_FORMAT_A (format)) - format = glyph_format; - } - else - { - return PIXMAN_a8r8g8b8; - } - } - - return format; -} - -static pixman_bool_t -box32_intersect (pixman_box32_t *dest, - const pixman_box32_t *box1, - const pixman_box32_t *box2) -{ - dest->x1 = MAX (box1->x1, box2->x1); - dest->y1 = MAX (box1->y1, box2->y1); - dest->x2 = MIN (box1->x2, box2->x2); - dest->y2 = MIN (box1->y2, box2->y2); - - return dest->x2 > dest->x1 && dest->y2 > dest->y1; -} - -#if defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__) -__attribute__((__force_align_arg_pointer__)) -#endif -PIXMAN_EXPORT void -pixman_composite_glyphs_no_mask (pixman_op_t op, - pixman_image_t *src, - pixman_image_t *dest, - int32_t src_x, - int32_t src_y, - int32_t dest_x, - int32_t dest_y, - pixman_glyph_cache_t *cache, - int n_glyphs, - const pixman_glyph_t *glyphs) -{ - pixman_region32_t region; - pixman_format_code_t glyph_format = PIXMAN_null; - uint32_t glyph_flags = 0; - pixman_format_code_t dest_format; - uint32_t dest_flags; - pixman_composite_func_t func = NULL; - pixman_implementation_t *implementation = NULL; - pixman_composite_info_t info; - int i; - - _pixman_image_validate (src); - _pixman_image_validate (dest); - - dest_format = dest->common.extended_format_code; - dest_flags = dest->common.flags; - - pixman_region32_init (®ion); - if (!_pixman_compute_composite_region32 ( - ®ion, - src, NULL, dest, - src_x - dest_x, src_y - dest_y, 0, 0, 0, 0, - dest->bits.width, dest->bits.height)) - { - goto out; - } - - info.op = op; - info.src_image = src; - info.dest_image = dest; - info.src_flags = src->common.flags; - info.dest_flags = dest->common.flags; - - for (i = 0; i < n_glyphs; ++i) - { - glyph_t *glyph = (glyph_t *)glyphs[i].glyph; - pixman_image_t *glyph_img = glyph->image; - pixman_box32_t glyph_box; - pixman_box32_t *pbox; - uint32_t extra = FAST_PATH_SAMPLES_COVER_CLIP_NEAREST; - pixman_box32_t composite_box; - int n; - - glyph_box.x1 = dest_x + glyphs[i].x - glyph->origin_x; - glyph_box.y1 = dest_y + glyphs[i].y - glyph->origin_y; - glyph_box.x2 = glyph_box.x1 + glyph->image->bits.width; - glyph_box.y2 = glyph_box.y1 + glyph->image->bits.height; - - pbox = pixman_region32_rectangles (®ion, &n); - - info.mask_image = glyph_img; - - while (n--) - { - if (box32_intersect (&composite_box, pbox, &glyph_box)) - { - if (glyph_img->common.extended_format_code != glyph_format || - glyph_img->common.flags != glyph_flags) - { - glyph_format = glyph_img->common.extended_format_code; - glyph_flags = glyph_img->common.flags; - - _pixman_implementation_lookup_composite ( - get_implementation(), op, - src->common.extended_format_code, src->common.flags, - glyph_format, glyph_flags | extra, - dest_format, dest_flags, - &implementation, &func); - } - - info.src_x = src_x + composite_box.x1 - dest_x; - info.src_y = src_y + composite_box.y1 - dest_y; - info.mask_x = composite_box.x1 - (dest_x + glyphs[i].x - glyph->origin_x); - info.mask_y = composite_box.y1 - (dest_y + glyphs[i].y - glyph->origin_y); - info.dest_x = composite_box.x1; - info.dest_y = composite_box.y1; - info.width = composite_box.x2 - composite_box.x1; - info.height = composite_box.y2 - composite_box.y1; - - info.mask_flags = glyph_flags; - - func (implementation, &info); - } - - pbox++; - } - pixman_list_move_to_front (&cache->mru, &glyph->mru_link); - } - -out: - pixman_region32_fini (®ion); -} - -static void -add_glyphs (pixman_glyph_cache_t *cache, - pixman_image_t *dest, - int off_x, int off_y, - int n_glyphs, const pixman_glyph_t *glyphs) -{ - pixman_format_code_t glyph_format = PIXMAN_null; - uint32_t glyph_flags = 0; - pixman_composite_func_t func = NULL; - pixman_implementation_t *implementation = NULL; - pixman_format_code_t dest_format; - uint32_t dest_flags; - pixman_box32_t dest_box; - pixman_composite_info_t info; - pixman_image_t *white_img = NULL; - pixman_bool_t white_src = FALSE; - int i; - - _pixman_image_validate (dest); - - dest_format = dest->common.extended_format_code; - dest_flags = dest->common.flags; - - info.op = PIXMAN_OP_ADD; - info.dest_image = dest; - info.src_x = 0; - info.src_y = 0; - info.dest_flags = dest_flags; - - dest_box.x1 = 0; - dest_box.y1 = 0; - dest_box.x2 = dest->bits.width; - dest_box.y2 = dest->bits.height; - - for (i = 0; i < n_glyphs; ++i) - { - glyph_t *glyph = (glyph_t *)glyphs[i].glyph; - pixman_image_t *glyph_img = glyph->image; - pixman_box32_t glyph_box; - pixman_box32_t composite_box; - - if (glyph_img->common.extended_format_code != glyph_format || - glyph_img->common.flags != glyph_flags) - { - pixman_format_code_t src_format, mask_format; - - glyph_format = glyph_img->common.extended_format_code; - glyph_flags = glyph_img->common.flags; - - if (glyph_format == dest->bits.format) - { - src_format = glyph_format; - mask_format = PIXMAN_null; - info.src_flags = glyph_flags | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST; - info.mask_flags = FAST_PATH_IS_OPAQUE; - info.mask_image = NULL; - white_src = FALSE; - } - else - { - if (!white_img) - { - static const pixman_color_t white = { 0xffff, 0xffff, 0xffff, 0xffff }; - - if (!(white_img = pixman_image_create_solid_fill (&white))) - goto out; - - _pixman_image_validate (white_img); - } - - src_format = PIXMAN_solid; - mask_format = glyph_format; - info.src_flags = white_img->common.flags; - info.mask_flags = glyph_flags | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST; - info.src_image = white_img; - white_src = TRUE; - } - - _pixman_implementation_lookup_composite ( - get_implementation(), PIXMAN_OP_ADD, - src_format, info.src_flags, - mask_format, info.mask_flags, - dest_format, dest_flags, - &implementation, &func); - } - - glyph_box.x1 = glyphs[i].x - glyph->origin_x + off_x; - glyph_box.y1 = glyphs[i].y - glyph->origin_y + off_y; - glyph_box.x2 = glyph_box.x1 + glyph->image->bits.width; - glyph_box.y2 = glyph_box.y1 + glyph->image->bits.height; - - if (box32_intersect (&composite_box, &glyph_box, &dest_box)) - { - int src_x = composite_box.x1 - glyph_box.x1; - int src_y = composite_box.y1 - glyph_box.y1; - - if (white_src) - info.mask_image = glyph_img; - else - info.src_image = glyph_img; - - info.mask_x = info.src_x = src_x; - info.mask_y = info.src_y = src_y; - info.dest_x = composite_box.x1; - info.dest_y = composite_box.y1; - info.width = composite_box.x2 - composite_box.x1; - info.height = composite_box.y2 - composite_box.y1; - - func (implementation, &info); - - pixman_list_move_to_front (&cache->mru, &glyph->mru_link); - } - } - -out: - if (white_img) - pixman_image_unref (white_img); -} - -/* Conceptually, for each glyph, (white IN glyph) is PIXMAN_OP_ADDed to an - * infinitely big mask image at the position such that the glyph origin point - * is positioned at the (glyphs[i].x, glyphs[i].y) point. - * - * Then (mask_x, mask_y) in the infinite mask and (src_x, src_y) in the source - * image are both aligned with (dest_x, dest_y) in the destination image. Then - * these three images are composited within the - * - * (dest_x, dest_y, dst_x + width, dst_y + height) - * - * rectangle. - * - * TODO: - * - Trim the mask to the destination clip/image? - * - Trim composite region based on sources, when the op ignores 0s. - */ -#if defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__) -__attribute__((__force_align_arg_pointer__)) -#endif -PIXMAN_EXPORT void -pixman_composite_glyphs (pixman_op_t op, - pixman_image_t *src, - pixman_image_t *dest, - pixman_format_code_t mask_format, - int32_t src_x, - int32_t src_y, - int32_t mask_x, - int32_t mask_y, - int32_t dest_x, - int32_t dest_y, - int32_t width, - int32_t height, - pixman_glyph_cache_t *cache, - int n_glyphs, - const pixman_glyph_t *glyphs) -{ - pixman_image_t *mask; - - if (!(mask = pixman_image_create_bits (mask_format, width, height, NULL, -1))) - return; - - if (PIXMAN_FORMAT_A (mask_format) != 0 && - PIXMAN_FORMAT_RGB (mask_format) != 0) - { - pixman_image_set_component_alpha (mask, TRUE); - } - - add_glyphs (cache, mask, - mask_x, - mask_y, n_glyphs, glyphs); - - pixman_image_composite32 (op, src, mask, dest, - src_x, src_y, - 0, 0, - dest_x, dest_y, - width, height); - - pixman_image_unref (mask); -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman-gradient-walker.c b/source/libs/pixman/pixman-src/pixman/pixman-gradient-walker.c deleted file mode 100644 index 822f8e62bae715b2e4f026915429db4bf9409ef3..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-gradient-walker.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * - * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. - * 2005 Lars Knoll & Zack Rusin, Trolltech - * - * 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 Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "pixman-private.h" - -void -_pixman_gradient_walker_init (pixman_gradient_walker_t *walker, - gradient_t * gradient, - pixman_repeat_t repeat) -{ - walker->num_stops = gradient->n_stops; - walker->stops = gradient->stops; - walker->left_x = 0; - walker->right_x = 0x10000; - walker->a_s = 0.0f; - walker->a_b = 0.0f; - walker->r_s = 0.0f; - walker->r_b = 0.0f; - walker->g_s = 0.0f; - walker->g_b = 0.0f; - walker->b_s = 0.0f; - walker->b_b = 0.0f; - walker->repeat = repeat; - - walker->need_reset = TRUE; -} - -static void -gradient_walker_reset (pixman_gradient_walker_t *walker, - pixman_fixed_48_16_t pos) -{ - int64_t x, left_x, right_x; - pixman_color_t *left_c, *right_c; - int n, count = walker->num_stops; - pixman_gradient_stop_t *stops = walker->stops; - float la, lr, lg, lb; - float ra, rr, rg, rb; - float lx, rx; - - if (walker->repeat == PIXMAN_REPEAT_NORMAL) - { - x = (int32_t)pos & 0xffff; - } - else if (walker->repeat == PIXMAN_REPEAT_REFLECT) - { - x = (int32_t)pos & 0xffff; - if ((int32_t)pos & 0x10000) - x = 0x10000 - x; - } - else - { - x = pos; - } - - for (n = 0; n < count; n++) - { - if (x < stops[n].x) - break; - } - - left_x = stops[n - 1].x; - left_c = &stops[n - 1].color; - - right_x = stops[n].x; - right_c = &stops[n].color; - - if (walker->repeat == PIXMAN_REPEAT_NORMAL) - { - left_x += (pos - x); - right_x += (pos - x); - } - else if (walker->repeat == PIXMAN_REPEAT_REFLECT) - { - if ((int32_t)pos & 0x10000) - { - pixman_color_t *tmp_c; - int32_t tmp_x; - - tmp_x = 0x10000 - right_x; - right_x = 0x10000 - left_x; - left_x = tmp_x; - - tmp_c = right_c; - right_c = left_c; - left_c = tmp_c; - - x = 0x10000 - x; - } - left_x += (pos - x); - right_x += (pos - x); - } - else if (walker->repeat == PIXMAN_REPEAT_NONE) - { - if (n == 0) - right_c = left_c; - else if (n == count) - left_c = right_c; - } - - /* The alpha channel is scaled to be in the [0, 255] interval, - * and the red/green/blue channels are scaled to be in [0, 1]. - * This ensures that after premultiplication all channels will - * be in the [0, 255] interval. - */ - la = (left_c->alpha * (1.0f/257.0f)); - lr = (left_c->red * (1.0f/257.0f)); - lg = (left_c->green * (1.0f/257.0f)); - lb = (left_c->blue * (1.0f/257.0f)); - - ra = (right_c->alpha * (1.0f/257.0f)); - rr = (right_c->red * (1.0f/257.0f)); - rg = (right_c->green * (1.0f/257.0f)); - rb = (right_c->blue * (1.0f/257.0f)); - - lx = left_x * (1.0f/65536.0f); - rx = right_x * (1.0f/65536.0f); - - if (FLOAT_IS_ZERO (rx - lx) || left_x == INT32_MIN || right_x == INT32_MAX) - { - walker->a_s = walker->r_s = walker->g_s = walker->b_s = 0.0f; - walker->a_b = (la + ra) / 2.0f; - walker->r_b = (lr + rr) / 510.0f; - walker->g_b = (lg + rg) / 510.0f; - walker->b_b = (lb + rb) / 510.0f; - } - else - { - float w_rec = 1.0f / (rx - lx); - - walker->a_b = (la * rx - ra * lx) * w_rec; - walker->r_b = (lr * rx - rr * lx) * w_rec * (1.0f/255.0f); - walker->g_b = (lg * rx - rg * lx) * w_rec * (1.0f/255.0f); - walker->b_b = (lb * rx - rb * lx) * w_rec * (1.0f/255.0f); - - walker->a_s = (ra - la) * w_rec; - walker->r_s = (rr - lr) * w_rec * (1.0f/255.0f); - walker->g_s = (rg - lg) * w_rec * (1.0f/255.0f); - walker->b_s = (rb - lb) * w_rec * (1.0f/255.0f); - } - - walker->left_x = left_x; - walker->right_x = right_x; - - walker->need_reset = FALSE; -} - -uint32_t -_pixman_gradient_walker_pixel (pixman_gradient_walker_t *walker, - pixman_fixed_48_16_t x) -{ - float a, r, g, b; - uint8_t a8, r8, g8, b8; - uint32_t v; - float y; - - if (walker->need_reset || x < walker->left_x || x >= walker->right_x) - gradient_walker_reset (walker, x); - - y = x * (1.0f / 65536.0f); - - a = walker->a_s * y + walker->a_b; - r = a * (walker->r_s * y + walker->r_b); - g = a * (walker->g_s * y + walker->g_b); - b = a * (walker->b_s * y + walker->b_b); - - a8 = a + 0.5f; - r8 = r + 0.5f; - g8 = g + 0.5f; - b8 = b + 0.5f; - - v = ((a8 << 24) & 0xff000000) | - ((r8 << 16) & 0x00ff0000) | - ((g8 << 8) & 0x0000ff00) | - ((b8 >> 0) & 0x000000ff); - - return v; -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman-image.c b/source/libs/pixman/pixman-src/pixman/pixman-image.c deleted file mode 100644 index 1ff1a49740433d06f60b03ddca23a4cd52464ccf..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-image.c +++ /dev/null @@ -1,945 +0,0 @@ -/* - * Copyright © 2000 SuSE, Inc. - * Copyright © 2007 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 SuSE not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. SuSE makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE - * 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. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <assert.h> - -#include "pixman-private.h" - -static const pixman_color_t transparent_black = { 0, 0, 0, 0 }; - -static void -gradient_property_changed (pixman_image_t *image) -{ - gradient_t *gradient = &image->gradient; - int n = gradient->n_stops; - pixman_gradient_stop_t *stops = gradient->stops; - pixman_gradient_stop_t *begin = &(gradient->stops[-1]); - pixman_gradient_stop_t *end = &(gradient->stops[n]); - - switch (gradient->common.repeat) - { - default: - case PIXMAN_REPEAT_NONE: - begin->x = INT32_MIN; - begin->color = transparent_black; - end->x = INT32_MAX; - end->color = transparent_black; - break; - - case PIXMAN_REPEAT_NORMAL: - begin->x = stops[n - 1].x - pixman_fixed_1; - begin->color = stops[n - 1].color; - end->x = stops[0].x + pixman_fixed_1; - end->color = stops[0].color; - break; - - case PIXMAN_REPEAT_REFLECT: - begin->x = - stops[0].x; - begin->color = stops[0].color; - end->x = pixman_int_to_fixed (2) - stops[n - 1].x; - end->color = stops[n - 1].color; - break; - - case PIXMAN_REPEAT_PAD: - begin->x = INT32_MIN; - begin->color = stops[0].color; - end->x = INT32_MAX; - end->color = stops[n - 1].color; - break; - } -} - -pixman_bool_t -_pixman_init_gradient (gradient_t * gradient, - const pixman_gradient_stop_t *stops, - int n_stops) -{ - return_val_if_fail (n_stops > 0, FALSE); - - /* We allocate two extra stops, one before the beginning of the stop list, - * and one after the end. These stops are initialized to whatever color - * would be used for positions outside the range of the stop list. - * - * This saves a bit of computation in the gradient walker. - * - * The pointer we store in the gradient_t struct still points to the - * first user-supplied struct, so when freeing, we will have to - * subtract one. - */ - gradient->stops = - pixman_malloc_ab (n_stops + 2, sizeof (pixman_gradient_stop_t)); - if (!gradient->stops) - return FALSE; - - gradient->stops += 1; - memcpy (gradient->stops, stops, n_stops * sizeof (pixman_gradient_stop_t)); - gradient->n_stops = n_stops; - - gradient->common.property_changed = gradient_property_changed; - - return TRUE; -} - -void -_pixman_image_init (pixman_image_t *image) -{ - image_common_t *common = &image->common; - - pixman_region32_init (&common->clip_region); - - common->alpha_count = 0; - common->have_clip_region = FALSE; - common->clip_sources = FALSE; - common->transform = NULL; - common->repeat = PIXMAN_REPEAT_NONE; - common->filter = PIXMAN_FILTER_NEAREST; - common->filter_params = NULL; - common->n_filter_params = 0; - common->alpha_map = NULL; - common->component_alpha = FALSE; - common->ref_count = 1; - common->property_changed = NULL; - common->client_clip = FALSE; - common->destroy_func = NULL; - common->destroy_data = NULL; - common->dirty = TRUE; -} - -pixman_bool_t -_pixman_image_fini (pixman_image_t *image) -{ - image_common_t *common = (image_common_t *)image; - - common->ref_count--; - - if (common->ref_count == 0) - { - if (image->common.destroy_func) - image->common.destroy_func (image, image->common.destroy_data); - - pixman_region32_fini (&common->clip_region); - - free (common->transform); - free (common->filter_params); - - if (common->alpha_map) - pixman_image_unref ((pixman_image_t *)common->alpha_map); - - if (image->type == LINEAR || - image->type == RADIAL || - image->type == CONICAL) - { - if (image->gradient.stops) - { - /* See _pixman_init_gradient() for an explanation of the - 1 */ - free (image->gradient.stops - 1); - } - - /* This will trigger if someone adds a property_changed - * method to the linear/radial/conical gradient overwriting - * the general one. - */ - assert ( - image->common.property_changed == gradient_property_changed); - } - - if (image->type == BITS && image->bits.free_me) - free (image->bits.free_me); - - return TRUE; - } - - return FALSE; -} - -pixman_image_t * -_pixman_image_allocate (void) -{ - pixman_image_t *image = malloc (sizeof (pixman_image_t)); - - if (image) - _pixman_image_init (image); - - return image; -} - -static void -image_property_changed (pixman_image_t *image) -{ - image->common.dirty = TRUE; -} - -/* Ref Counting */ -PIXMAN_EXPORT pixman_image_t * -pixman_image_ref (pixman_image_t *image) -{ - image->common.ref_count++; - - return image; -} - -/* returns TRUE when the image is freed */ -PIXMAN_EXPORT pixman_bool_t -pixman_image_unref (pixman_image_t *image) -{ - if (_pixman_image_fini (image)) - { - free (image); - return TRUE; - } - - return FALSE; -} - -PIXMAN_EXPORT void -pixman_image_set_destroy_function (pixman_image_t * image, - pixman_image_destroy_func_t func, - void * data) -{ - image->common.destroy_func = func; - image->common.destroy_data = data; -} - -PIXMAN_EXPORT void * -pixman_image_get_destroy_data (pixman_image_t *image) -{ - return image->common.destroy_data; -} - -void -_pixman_image_reset_clip_region (pixman_image_t *image) -{ - image->common.have_clip_region = FALSE; -} - -/* Executive Summary: This function is a no-op that only exists - * for historical reasons. - * - * There used to be a bug in the X server where it would rely on - * out-of-bounds accesses when it was asked to composite with a - * window as the source. It would create a pixman image pointing - * to some bogus position in memory, but then set a clip region - * to the position where the actual bits were. - * - * Due to a bug in old versions of pixman, where it would not clip - * against the image bounds when a clip region was set, this would - * actually work. So when the pixman bug was fixed, a workaround was - * added to allow certain out-of-bound accesses. This function disabled - * those workarounds. - * - * Since 0.21.2, pixman doesn't do these workarounds anymore, so now - * this function is a no-op. - */ -PIXMAN_EXPORT void -pixman_disable_out_of_bounds_workaround (void) -{ -} - -static void -compute_image_info (pixman_image_t *image) -{ - pixman_format_code_t code; - uint32_t flags = 0; - - /* Transform */ - if (!image->common.transform) - { - flags |= (FAST_PATH_ID_TRANSFORM | - FAST_PATH_X_UNIT_POSITIVE | - FAST_PATH_Y_UNIT_ZERO | - FAST_PATH_AFFINE_TRANSFORM); - } - else - { - flags |= FAST_PATH_HAS_TRANSFORM; - - if (image->common.transform->matrix[2][0] == 0 && - image->common.transform->matrix[2][1] == 0 && - image->common.transform->matrix[2][2] == pixman_fixed_1) - { - flags |= FAST_PATH_AFFINE_TRANSFORM; - - if (image->common.transform->matrix[0][1] == 0 && - image->common.transform->matrix[1][0] == 0) - { - if (image->common.transform->matrix[0][0] == -pixman_fixed_1 && - image->common.transform->matrix[1][1] == -pixman_fixed_1) - { - flags |= FAST_PATH_ROTATE_180_TRANSFORM; - } - flags |= FAST_PATH_SCALE_TRANSFORM; - } - else if (image->common.transform->matrix[0][0] == 0 && - image->common.transform->matrix[1][1] == 0) - { - pixman_fixed_t m01 = image->common.transform->matrix[0][1]; - pixman_fixed_t m10 = image->common.transform->matrix[1][0]; - - if (m01 == -pixman_fixed_1 && m10 == pixman_fixed_1) - flags |= FAST_PATH_ROTATE_90_TRANSFORM; - else if (m01 == pixman_fixed_1 && m10 == -pixman_fixed_1) - flags |= FAST_PATH_ROTATE_270_TRANSFORM; - } - } - - if (image->common.transform->matrix[0][0] > 0) - flags |= FAST_PATH_X_UNIT_POSITIVE; - - if (image->common.transform->matrix[1][0] == 0) - flags |= FAST_PATH_Y_UNIT_ZERO; - } - - /* Filter */ - switch (image->common.filter) - { - case PIXMAN_FILTER_NEAREST: - case PIXMAN_FILTER_FAST: - flags |= (FAST_PATH_NEAREST_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER); - break; - - case PIXMAN_FILTER_BILINEAR: - case PIXMAN_FILTER_GOOD: - case PIXMAN_FILTER_BEST: - flags |= (FAST_PATH_BILINEAR_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER); - - /* Here we have a chance to optimize BILINEAR filter to NEAREST if - * they are equivalent for the currently used transformation matrix. - */ - if (flags & FAST_PATH_ID_TRANSFORM) - { - flags |= FAST_PATH_NEAREST_FILTER; - } - else if ( - /* affine and integer translation components in matrix ... */ - ((flags & FAST_PATH_AFFINE_TRANSFORM) && - !pixman_fixed_frac (image->common.transform->matrix[0][2] | - image->common.transform->matrix[1][2])) && - ( - /* ... combined with a simple rotation */ - (flags & (FAST_PATH_ROTATE_90_TRANSFORM | - FAST_PATH_ROTATE_180_TRANSFORM | - FAST_PATH_ROTATE_270_TRANSFORM)) || - /* ... or combined with a simple non-rotated translation */ - (image->common.transform->matrix[0][0] == pixman_fixed_1 && - image->common.transform->matrix[1][1] == pixman_fixed_1 && - image->common.transform->matrix[0][1] == 0 && - image->common.transform->matrix[1][0] == 0) - ) - ) - { - /* FIXME: there are some affine-test failures, showing that - * handling of BILINEAR and NEAREST filter is not quite - * equivalent when getting close to 32K for the translation - * components of the matrix. That's likely some bug, but for - * now just skip BILINEAR->NEAREST optimization in this case. - */ - pixman_fixed_t magic_limit = pixman_int_to_fixed (30000); - if (image->common.transform->matrix[0][2] <= magic_limit && - image->common.transform->matrix[1][2] <= magic_limit && - image->common.transform->matrix[0][2] >= -magic_limit && - image->common.transform->matrix[1][2] >= -magic_limit) - { - flags |= FAST_PATH_NEAREST_FILTER; - } - } - break; - - case PIXMAN_FILTER_CONVOLUTION: - break; - - case PIXMAN_FILTER_SEPARABLE_CONVOLUTION: - flags |= FAST_PATH_SEPARABLE_CONVOLUTION_FILTER; - break; - - default: - flags |= FAST_PATH_NO_CONVOLUTION_FILTER; - break; - } - - /* Repeat mode */ - switch (image->common.repeat) - { - case PIXMAN_REPEAT_NONE: - flags |= - FAST_PATH_NO_REFLECT_REPEAT | - FAST_PATH_NO_PAD_REPEAT | - FAST_PATH_NO_NORMAL_REPEAT; - break; - - case PIXMAN_REPEAT_REFLECT: - flags |= - FAST_PATH_NO_PAD_REPEAT | - FAST_PATH_NO_NONE_REPEAT | - FAST_PATH_NO_NORMAL_REPEAT; - break; - - case PIXMAN_REPEAT_PAD: - flags |= - FAST_PATH_NO_REFLECT_REPEAT | - FAST_PATH_NO_NONE_REPEAT | - FAST_PATH_NO_NORMAL_REPEAT; - break; - - default: - flags |= - FAST_PATH_NO_REFLECT_REPEAT | - FAST_PATH_NO_PAD_REPEAT | - FAST_PATH_NO_NONE_REPEAT; - break; - } - - /* Component alpha */ - if (image->common.component_alpha) - flags |= FAST_PATH_COMPONENT_ALPHA; - else - flags |= FAST_PATH_UNIFIED_ALPHA; - - flags |= (FAST_PATH_NO_ACCESSORS | FAST_PATH_NARROW_FORMAT); - - /* Type specific checks */ - switch (image->type) - { - case SOLID: - code = PIXMAN_solid; - - if (image->solid.color.alpha == 0xffff) - flags |= FAST_PATH_IS_OPAQUE; - break; - - case BITS: - if (image->bits.width == 1 && - image->bits.height == 1 && - image->common.repeat != PIXMAN_REPEAT_NONE) - { - code = PIXMAN_solid; - } - else - { - code = image->bits.format; - flags |= FAST_PATH_BITS_IMAGE; - } - - if (!PIXMAN_FORMAT_A (image->bits.format) && - PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_GRAY && - PIXMAN_FORMAT_TYPE (image->bits.format) != PIXMAN_TYPE_COLOR) - { - flags |= FAST_PATH_SAMPLES_OPAQUE; - - if (image->common.repeat != PIXMAN_REPEAT_NONE) - flags |= FAST_PATH_IS_OPAQUE; - } - - if (image->bits.read_func || image->bits.write_func) - flags &= ~FAST_PATH_NO_ACCESSORS; - - if (PIXMAN_FORMAT_IS_WIDE (image->bits.format)) - flags &= ~FAST_PATH_NARROW_FORMAT; - break; - - case RADIAL: - code = PIXMAN_unknown; - - /* - * As explained in pixman-radial-gradient.c, every point of - * the plane has a valid associated radius (and thus will be - * colored) if and only if a is negative (i.e. one of the two - * circles contains the other one). - */ - - if (image->radial.a >= 0) - break; - - /* Fall through */ - - case CONICAL: - case LINEAR: - code = PIXMAN_unknown; - - if (image->common.repeat != PIXMAN_REPEAT_NONE) - { - int i; - - flags |= FAST_PATH_IS_OPAQUE; - for (i = 0; i < image->gradient.n_stops; ++i) - { - if (image->gradient.stops[i].color.alpha != 0xffff) - { - flags &= ~FAST_PATH_IS_OPAQUE; - break; - } - } - } - break; - - default: - code = PIXMAN_unknown; - break; - } - - /* Alpha maps are only supported for BITS images, so it's always - * safe to ignore their presense for non-BITS images - */ - if (!image->common.alpha_map || image->type != BITS) - { - flags |= FAST_PATH_NO_ALPHA_MAP; - } - else - { - if (PIXMAN_FORMAT_IS_WIDE (image->common.alpha_map->format)) - flags &= ~FAST_PATH_NARROW_FORMAT; - } - - /* Both alpha maps and convolution filters can introduce - * non-opaqueness in otherwise opaque images. Also - * an image with component alpha turned on is only opaque - * if all channels are opaque, so we simply turn it off - * unconditionally for those images. - */ - if (image->common.alpha_map || - image->common.filter == PIXMAN_FILTER_CONVOLUTION || - image->common.filter == PIXMAN_FILTER_SEPARABLE_CONVOLUTION || - image->common.component_alpha) - { - flags &= ~(FAST_PATH_IS_OPAQUE | FAST_PATH_SAMPLES_OPAQUE); - } - - image->common.flags = flags; - image->common.extended_format_code = code; -} - -void -_pixman_image_validate (pixman_image_t *image) -{ - if (image->common.dirty) - { - compute_image_info (image); - - /* It is important that property_changed is - * called *after* compute_image_info() because - * property_changed() can make use of the flags - * to set up accessors etc. - */ - if (image->common.property_changed) - image->common.property_changed (image); - - image->common.dirty = FALSE; - } - - if (image->common.alpha_map) - _pixman_image_validate ((pixman_image_t *)image->common.alpha_map); -} - -PIXMAN_EXPORT pixman_bool_t -pixman_image_set_clip_region32 (pixman_image_t * image, - pixman_region32_t *region) -{ - image_common_t *common = (image_common_t *)image; - pixman_bool_t result; - - if (region) - { - if ((result = pixman_region32_copy (&common->clip_region, region))) - image->common.have_clip_region = TRUE; - } - else - { - _pixman_image_reset_clip_region (image); - - result = TRUE; - } - - image_property_changed (image); - - return result; -} - -PIXMAN_EXPORT pixman_bool_t -pixman_image_set_clip_region (pixman_image_t * image, - pixman_region16_t *region) -{ - image_common_t *common = (image_common_t *)image; - pixman_bool_t result; - - if (region) - { - if ((result = pixman_region32_copy_from_region16 (&common->clip_region, region))) - image->common.have_clip_region = TRUE; - } - else - { - _pixman_image_reset_clip_region (image); - - result = TRUE; - } - - image_property_changed (image); - - return result; -} - -PIXMAN_EXPORT void -pixman_image_set_has_client_clip (pixman_image_t *image, - pixman_bool_t client_clip) -{ - image->common.client_clip = client_clip; -} - -PIXMAN_EXPORT pixman_bool_t -pixman_image_set_transform (pixman_image_t * image, - const pixman_transform_t *transform) -{ - static const pixman_transform_t id = - { - { { pixman_fixed_1, 0, 0 }, - { 0, pixman_fixed_1, 0 }, - { 0, 0, pixman_fixed_1 } } - }; - - image_common_t *common = (image_common_t *)image; - pixman_bool_t result; - - if (common->transform == transform) - return TRUE; - - if (!transform || memcmp (&id, transform, sizeof (pixman_transform_t)) == 0) - { - free (common->transform); - common->transform = NULL; - result = TRUE; - - goto out; - } - - if (common->transform && - memcmp (common->transform, transform, sizeof (pixman_transform_t)) == 0) - { - return TRUE; - } - - if (common->transform == NULL) - common->transform = malloc (sizeof (pixman_transform_t)); - - if (common->transform == NULL) - { - result = FALSE; - - goto out; - } - - memcpy (common->transform, transform, sizeof(pixman_transform_t)); - - result = TRUE; - -out: - image_property_changed (image); - - return result; -} - -PIXMAN_EXPORT void -pixman_image_set_repeat (pixman_image_t *image, - pixman_repeat_t repeat) -{ - if (image->common.repeat == repeat) - return; - - image->common.repeat = repeat; - - image_property_changed (image); -} - -PIXMAN_EXPORT pixman_bool_t -pixman_image_set_filter (pixman_image_t * image, - pixman_filter_t filter, - const pixman_fixed_t *params, - int n_params) -{ - image_common_t *common = (image_common_t *)image; - pixman_fixed_t *new_params; - - if (params == common->filter_params && filter == common->filter) - return TRUE; - - if (filter == PIXMAN_FILTER_SEPARABLE_CONVOLUTION) - { - int width = pixman_fixed_to_int (params[0]); - int height = pixman_fixed_to_int (params[1]); - int x_phase_bits = pixman_fixed_to_int (params[2]); - int y_phase_bits = pixman_fixed_to_int (params[3]); - int n_x_phases = (1 << x_phase_bits); - int n_y_phases = (1 << y_phase_bits); - - return_val_if_fail ( - n_params == 4 + n_x_phases * width + n_y_phases * height, FALSE); - } - - new_params = NULL; - if (params) - { - new_params = pixman_malloc_ab (n_params, sizeof (pixman_fixed_t)); - if (!new_params) - return FALSE; - - memcpy (new_params, - params, n_params * sizeof (pixman_fixed_t)); - } - - common->filter = filter; - - if (common->filter_params) - free (common->filter_params); - - common->filter_params = new_params; - common->n_filter_params = n_params; - - image_property_changed (image); - return TRUE; -} - -PIXMAN_EXPORT void -pixman_image_set_source_clipping (pixman_image_t *image, - pixman_bool_t clip_sources) -{ - if (image->common.clip_sources == clip_sources) - return; - - image->common.clip_sources = clip_sources; - - image_property_changed (image); -} - -/* Unlike all the other property setters, this function does not - * copy the content of indexed. Doing this copying is simply - * way, way too expensive. - */ -PIXMAN_EXPORT void -pixman_image_set_indexed (pixman_image_t * image, - const pixman_indexed_t *indexed) -{ - bits_image_t *bits = (bits_image_t *)image; - - if (bits->indexed == indexed) - return; - - bits->indexed = indexed; - - image_property_changed (image); -} - -PIXMAN_EXPORT void -pixman_image_set_alpha_map (pixman_image_t *image, - pixman_image_t *alpha_map, - int16_t x, - int16_t y) -{ - image_common_t *common = (image_common_t *)image; - - return_if_fail (!alpha_map || alpha_map->type == BITS); - - if (alpha_map && common->alpha_count > 0) - { - /* If this image is being used as an alpha map itself, - * then you can't give it an alpha map of its own. - */ - return; - } - - if (alpha_map && alpha_map->common.alpha_map) - { - /* If the image has an alpha map of its own, - * then it can't be used as an alpha map itself - */ - return; - } - - if (common->alpha_map != (bits_image_t *)alpha_map) - { - if (common->alpha_map) - { - common->alpha_map->common.alpha_count--; - - pixman_image_unref ((pixman_image_t *)common->alpha_map); - } - - if (alpha_map) - { - common->alpha_map = (bits_image_t *)pixman_image_ref (alpha_map); - - common->alpha_map->common.alpha_count++; - } - else - { - common->alpha_map = NULL; - } - } - - common->alpha_origin_x = x; - common->alpha_origin_y = y; - - image_property_changed (image); -} - -PIXMAN_EXPORT void -pixman_image_set_component_alpha (pixman_image_t *image, - pixman_bool_t component_alpha) -{ - if (image->common.component_alpha == component_alpha) - return; - - image->common.component_alpha = component_alpha; - - image_property_changed (image); -} - -PIXMAN_EXPORT pixman_bool_t -pixman_image_get_component_alpha (pixman_image_t *image) -{ - return image->common.component_alpha; -} - -PIXMAN_EXPORT void -pixman_image_set_accessors (pixman_image_t * image, - pixman_read_memory_func_t read_func, - pixman_write_memory_func_t write_func) -{ - return_if_fail (image != NULL); - - if (image->type == BITS) - { - image->bits.read_func = read_func; - image->bits.write_func = write_func; - - image_property_changed (image); - } -} - -PIXMAN_EXPORT uint32_t * -pixman_image_get_data (pixman_image_t *image) -{ - if (image->type == BITS) - return image->bits.bits; - - return NULL; -} - -PIXMAN_EXPORT int -pixman_image_get_width (pixman_image_t *image) -{ - if (image->type == BITS) - return image->bits.width; - - return 0; -} - -PIXMAN_EXPORT int -pixman_image_get_height (pixman_image_t *image) -{ - if (image->type == BITS) - return image->bits.height; - - return 0; -} - -PIXMAN_EXPORT int -pixman_image_get_stride (pixman_image_t *image) -{ - if (image->type == BITS) - return image->bits.rowstride * (int) sizeof (uint32_t); - - return 0; -} - -PIXMAN_EXPORT int -pixman_image_get_depth (pixman_image_t *image) -{ - if (image->type == BITS) - return PIXMAN_FORMAT_DEPTH (image->bits.format); - - return 0; -} - -PIXMAN_EXPORT pixman_format_code_t -pixman_image_get_format (pixman_image_t *image) -{ - if (image->type == BITS) - return image->bits.format; - - return PIXMAN_null; -} - -uint32_t -_pixman_image_get_solid (pixman_implementation_t *imp, - pixman_image_t * image, - pixman_format_code_t format) -{ - uint32_t result; - - if (image->type == SOLID) - { - result = image->solid.color_32; - } - else if (image->type == BITS) - { - if (image->bits.format == PIXMAN_a8r8g8b8) - result = image->bits.bits[0]; - else if (image->bits.format == PIXMAN_x8r8g8b8) - result = image->bits.bits[0] | 0xff000000; - else if (image->bits.format == PIXMAN_a8) - result = (*(uint8_t *)image->bits.bits) << 24; - else - goto otherwise; - } - else - { - pixman_iter_t iter; - - otherwise: - _pixman_implementation_iter_init ( - imp, &iter, image, 0, 0, 1, 1, - (uint8_t *)&result, - ITER_NARROW | ITER_SRC, image->common.flags); - - result = *iter.get_scanline (&iter, NULL); - - if (iter.fini) - iter.fini (&iter); - } - - /* If necessary, convert RGB <--> BGR. */ - if (PIXMAN_FORMAT_TYPE (format) != PIXMAN_TYPE_ARGB - && PIXMAN_FORMAT_TYPE (format) != PIXMAN_TYPE_ARGB_SRGB) - { - result = (((result & 0xff000000) >> 0) | - ((result & 0x00ff0000) >> 16) | - ((result & 0x0000ff00) >> 0) | - ((result & 0x000000ff) << 16)); - } - - return result; -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman-implementation.c b/source/libs/pixman/pixman-src/pixman/pixman-implementation.c deleted file mode 100644 index 2c7de4c68797c90a872c283cf35b4b70978cdc49..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-implementation.c +++ /dev/null @@ -1,417 +0,0 @@ -/* - * Copyright © 2009 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 not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. Red Hat makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdlib.h> -#include "pixman-private.h" - -pixman_implementation_t * -_pixman_implementation_create (pixman_implementation_t *fallback, - const pixman_fast_path_t *fast_paths) -{ - pixman_implementation_t *imp; - - assert (fast_paths); - - if ((imp = malloc (sizeof (pixman_implementation_t)))) - { - pixman_implementation_t *d; - - memset (imp, 0, sizeof *imp); - - imp->fallback = fallback; - imp->fast_paths = fast_paths; - - /* Make sure the whole fallback chain has the right toplevel */ - for (d = imp; d != NULL; d = d->fallback) - d->toplevel = imp; - } - - return imp; -} - -#define N_CACHED_FAST_PATHS 8 - -typedef struct -{ - struct - { - pixman_implementation_t * imp; - pixman_fast_path_t fast_path; - } cache [N_CACHED_FAST_PATHS]; -} cache_t; - -PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache); - -static void -dummy_composite_rect (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ -} - -void -_pixman_implementation_lookup_composite (pixman_implementation_t *toplevel, - pixman_op_t op, - pixman_format_code_t src_format, - uint32_t src_flags, - pixman_format_code_t mask_format, - uint32_t mask_flags, - pixman_format_code_t dest_format, - uint32_t dest_flags, - pixman_implementation_t **out_imp, - pixman_composite_func_t *out_func) -{ - pixman_implementation_t *imp; - cache_t *cache; - int i; - - /* Check cache for fast paths */ - cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache); - - for (i = 0; i < N_CACHED_FAST_PATHS; ++i) - { - const pixman_fast_path_t *info = &(cache->cache[i].fast_path); - - /* Note that we check for equality here, not whether - * the cached fast path matches. This is to prevent - * us from selecting an overly general fast path - * when a more specific one would work. - */ - if (info->op == op && - info->src_format == src_format && - info->mask_format == mask_format && - info->dest_format == dest_format && - info->src_flags == src_flags && - info->mask_flags == mask_flags && - info->dest_flags == dest_flags && - info->func) - { - *out_imp = cache->cache[i].imp; - *out_func = cache->cache[i].fast_path.func; - - goto update_cache; - } - } - - for (imp = toplevel; imp != NULL; imp = imp->fallback) - { - const pixman_fast_path_t *info = imp->fast_paths; - - while (info->op != PIXMAN_OP_NONE) - { - if ((info->op == op || info->op == PIXMAN_OP_any) && - /* Formats */ - ((info->src_format == src_format) || - (info->src_format == PIXMAN_any)) && - ((info->mask_format == mask_format) || - (info->mask_format == PIXMAN_any)) && - ((info->dest_format == dest_format) || - (info->dest_format == PIXMAN_any)) && - /* Flags */ - (info->src_flags & src_flags) == info->src_flags && - (info->mask_flags & mask_flags) == info->mask_flags && - (info->dest_flags & dest_flags) == info->dest_flags) - { - *out_imp = imp; - *out_func = info->func; - - /* Set i to the last spot in the cache so that the - * move-to-front code below will work - */ - i = N_CACHED_FAST_PATHS - 1; - - goto update_cache; - } - - ++info; - } - } - - /* We should never reach this point */ - _pixman_log_error ( - FUNC, - "No composite function found\n" - "\n" - "The most likely cause of this is that this system has issues with\n" - "thread local storage\n"); - - *out_imp = NULL; - *out_func = dummy_composite_rect; - return; - -update_cache: - if (i) - { - while (i--) - cache->cache[i + 1] = cache->cache[i]; - - cache->cache[0].imp = *out_imp; - cache->cache[0].fast_path.op = op; - cache->cache[0].fast_path.src_format = src_format; - cache->cache[0].fast_path.src_flags = src_flags; - cache->cache[0].fast_path.mask_format = mask_format; - cache->cache[0].fast_path.mask_flags = mask_flags; - cache->cache[0].fast_path.dest_format = dest_format; - cache->cache[0].fast_path.dest_flags = dest_flags; - cache->cache[0].fast_path.func = *out_func; - } -} - -static void -dummy_combine (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * pd, - const uint32_t * ps, - const uint32_t * pm, - int w) -{ -} - -pixman_combine_32_func_t -_pixman_implementation_lookup_combiner (pixman_implementation_t *imp, - pixman_op_t op, - pixman_bool_t component_alpha, - pixman_bool_t narrow) -{ - while (imp) - { - pixman_combine_32_func_t f = NULL; - - switch ((narrow << 1) | component_alpha) - { - case 0: /* not narrow, not component alpha */ - f = (pixman_combine_32_func_t)imp->combine_float[op]; - break; - - case 1: /* not narrow, component_alpha */ - f = (pixman_combine_32_func_t)imp->combine_float_ca[op]; - break; - - case 2: /* narrow, not component alpha */ - f = imp->combine_32[op]; - break; - - case 3: /* narrow, component_alpha */ - f = imp->combine_32_ca[op]; - break; - } - - if (f) - return f; - - imp = imp->fallback; - } - - /* We should never reach this point */ - _pixman_log_error (FUNC, "No known combine function\n"); - return dummy_combine; -} - -pixman_bool_t -_pixman_implementation_blt (pixman_implementation_t * imp, - uint32_t * src_bits, - uint32_t * dst_bits, - int src_stride, - int dst_stride, - int src_bpp, - int dst_bpp, - int src_x, - int src_y, - int dest_x, - int dest_y, - int width, - int height) -{ - while (imp) - { - if (imp->blt && - (*imp->blt) (imp, src_bits, dst_bits, src_stride, dst_stride, - src_bpp, dst_bpp, src_x, src_y, dest_x, dest_y, - width, height)) - { - return TRUE; - } - - imp = imp->fallback; - } - - return FALSE; -} - -pixman_bool_t -_pixman_implementation_fill (pixman_implementation_t *imp, - uint32_t * bits, - int stride, - int bpp, - int x, - int y, - int width, - int height, - uint32_t filler) -{ - while (imp) - { - if (imp->fill && - ((*imp->fill) (imp, bits, stride, bpp, x, y, width, height, filler))) - { - return TRUE; - } - - imp = imp->fallback; - } - - return FALSE; -} - -static uint32_t * -get_scanline_null (pixman_iter_t *iter, const uint32_t *mask) -{ - return NULL; -} - -void -_pixman_implementation_iter_init (pixman_implementation_t *imp, - pixman_iter_t *iter, - pixman_image_t *image, - int x, - int y, - int width, - int height, - uint8_t *buffer, - iter_flags_t iter_flags, - uint32_t image_flags) -{ - pixman_format_code_t format; - - iter->image = image; - iter->buffer = (uint32_t *)buffer; - iter->x = x; - iter->y = y; - iter->width = width; - iter->height = height; - iter->iter_flags = iter_flags; - iter->image_flags = image_flags; - iter->fini = NULL; - - if (!iter->image) - { - iter->get_scanline = get_scanline_null; - return; - } - - format = iter->image->common.extended_format_code; - - while (imp) - { - if (imp->iter_info) - { - const pixman_iter_info_t *info; - - for (info = imp->iter_info; info->format != PIXMAN_null; ++info) - { - if ((info->format == PIXMAN_any || info->format == format) && - (info->image_flags & image_flags) == info->image_flags && - (info->iter_flags & iter_flags) == info->iter_flags) - { - iter->get_scanline = info->get_scanline; - iter->write_back = info->write_back; - - if (info->initializer) - info->initializer (iter, info); - return; - } - } - } - - imp = imp->fallback; - } -} - -pixman_bool_t -_pixman_disabled (const char *name) -{ - const char *env; - - if ((env = getenv ("PIXMAN_DISABLE"))) - { - do - { - const char *end; - int len; - - if ((end = strchr (env, ' '))) - len = end - env; - else - len = strlen (env); - - if (strlen (name) == len && strncmp (name, env, len) == 0) - { - printf ("pixman: Disabled %s implementation\n", name); - return TRUE; - } - - env += len; - } - while (*env++); - } - - return FALSE; -} - -static const pixman_fast_path_t empty_fast_path[] = -{ - { PIXMAN_OP_NONE } -}; - -pixman_implementation_t * -_pixman_choose_implementation (void) -{ - pixman_implementation_t *imp; - - imp = _pixman_implementation_create_general(); - - if (!_pixman_disabled ("fast")) - imp = _pixman_implementation_create_fast_path (imp); - - imp = _pixman_x86_get_implementations (imp); - imp = _pixman_arm_get_implementations (imp); - imp = _pixman_ppc_get_implementations (imp); - imp = _pixman_mips_get_implementations (imp); - - imp = _pixman_implementation_create_noop (imp); - - if (_pixman_disabled ("wholeops")) - { - pixman_implementation_t *cur; - - /* Disable all whole-operation paths except the general one, - * so that optimized iterators are used as much as possible. - */ - for (cur = imp; cur->fallback; cur = cur->fallback) - cur->fast_paths = empty_fast_path; - } - - return imp; -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman-inlines.h b/source/libs/pixman/pixman-src/pixman/pixman-inlines.h deleted file mode 100644 index 1c8441d6dabef89ca42f9e454b3ff92e844ee379..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-inlines.h +++ /dev/null @@ -1,1340 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */ -/* - * Copyright © 2000 SuSE, Inc. - * Copyright © 2007 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 SuSE not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. SuSE makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE - * 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: Keith Packard, SuSE, Inc. - */ - -#ifndef PIXMAN_FAST_PATH_H__ -#define PIXMAN_FAST_PATH_H__ - -#include "pixman-private.h" - -#define PIXMAN_REPEAT_COVER -1 - -/* Flags describing input parameters to fast path macro template. - * Turning on some flag values may indicate that - * "some property X is available so template can use this" or - * "some property X should be handled by template". - * - * FLAG_HAVE_SOLID_MASK - * Input mask is solid so template should handle this. - * - * FLAG_HAVE_NON_SOLID_MASK - * Input mask is bits mask so template should handle this. - * - * FLAG_HAVE_SOLID_MASK and FLAG_HAVE_NON_SOLID_MASK are mutually - * exclusive. (It's not allowed to turn both flags on) - */ -#define FLAG_NONE (0) -#define FLAG_HAVE_SOLID_MASK (1 << 1) -#define FLAG_HAVE_NON_SOLID_MASK (1 << 2) - -/* To avoid too short repeated scanline function calls, extend source - * scanlines having width less than below constant value. - */ -#define REPEAT_NORMAL_MIN_WIDTH 64 - -static force_inline pixman_bool_t -repeat (pixman_repeat_t repeat, int *c, int size) -{ - if (repeat == PIXMAN_REPEAT_NONE) - { - if (*c < 0 || *c >= size) - return FALSE; - } - else if (repeat == PIXMAN_REPEAT_NORMAL) - { - while (*c >= size) - *c -= size; - while (*c < 0) - *c += size; - } - else if (repeat == PIXMAN_REPEAT_PAD) - { - *c = CLIP (*c, 0, size - 1); - } - else /* REFLECT */ - { - *c = MOD (*c, size * 2); - if (*c >= size) - *c = size * 2 - *c - 1; - } - return TRUE; -} - -static force_inline int -pixman_fixed_to_bilinear_weight (pixman_fixed_t x) -{ - return (x >> (16 - BILINEAR_INTERPOLATION_BITS)) & - ((1 << BILINEAR_INTERPOLATION_BITS) - 1); -} - -#if BILINEAR_INTERPOLATION_BITS <= 4 -/* Inspired by Filter_32_opaque from Skia */ -static force_inline uint32_t -bilinear_interpolation (uint32_t tl, uint32_t tr, - uint32_t bl, uint32_t br, - int distx, int disty) -{ - int distxy, distxiy, distixy, distixiy; - uint32_t lo, hi; - - distx <<= (4 - BILINEAR_INTERPOLATION_BITS); - disty <<= (4 - BILINEAR_INTERPOLATION_BITS); - - distxy = distx * disty; - distxiy = (distx << 4) - distxy; /* distx * (16 - disty) */ - distixy = (disty << 4) - distxy; /* disty * (16 - distx) */ - distixiy = - 16 * 16 - (disty << 4) - - (distx << 4) + distxy; /* (16 - distx) * (16 - disty) */ - - lo = (tl & 0xff00ff) * distixiy; - hi = ((tl >> 8) & 0xff00ff) * distixiy; - - lo += (tr & 0xff00ff) * distxiy; - hi += ((tr >> 8) & 0xff00ff) * distxiy; - - lo += (bl & 0xff00ff) * distixy; - hi += ((bl >> 8) & 0xff00ff) * distixy; - - lo += (br & 0xff00ff) * distxy; - hi += ((br >> 8) & 0xff00ff) * distxy; - - return ((lo >> 8) & 0xff00ff) | (hi & ~0xff00ff); -} - -#else -#if SIZEOF_LONG > 4 - -static force_inline uint32_t -bilinear_interpolation (uint32_t tl, uint32_t tr, - uint32_t bl, uint32_t br, - int distx, int disty) -{ - uint64_t distxy, distxiy, distixy, distixiy; - uint64_t tl64, tr64, bl64, br64; - uint64_t f, r; - - distx <<= (8 - BILINEAR_INTERPOLATION_BITS); - disty <<= (8 - BILINEAR_INTERPOLATION_BITS); - - distxy = distx * disty; - distxiy = distx * (256 - disty); - distixy = (256 - distx) * disty; - distixiy = (256 - distx) * (256 - disty); - - /* Alpha and Blue */ - tl64 = tl & 0xff0000ff; - tr64 = tr & 0xff0000ff; - bl64 = bl & 0xff0000ff; - br64 = br & 0xff0000ff; - - f = tl64 * distixiy + tr64 * distxiy + bl64 * distixy + br64 * distxy; - r = f & 0x0000ff0000ff0000ull; - - /* Red and Green */ - tl64 = tl; - tl64 = ((tl64 << 16) & 0x000000ff00000000ull) | (tl64 & 0x0000ff00ull); - - tr64 = tr; - tr64 = ((tr64 << 16) & 0x000000ff00000000ull) | (tr64 & 0x0000ff00ull); - - bl64 = bl; - bl64 = ((bl64 << 16) & 0x000000ff00000000ull) | (bl64 & 0x0000ff00ull); - - br64 = br; - br64 = ((br64 << 16) & 0x000000ff00000000ull) | (br64 & 0x0000ff00ull); - - f = tl64 * distixiy + tr64 * distxiy + bl64 * distixy + br64 * distxy; - r |= ((f >> 16) & 0x000000ff00000000ull) | (f & 0xff000000ull); - - return (uint32_t)(r >> 16); -} - -#else - -static force_inline uint32_t -bilinear_interpolation (uint32_t tl, uint32_t tr, - uint32_t bl, uint32_t br, - int distx, int disty) -{ - int distxy, distxiy, distixy, distixiy; - uint32_t f, r; - - distx <<= (8 - BILINEAR_INTERPOLATION_BITS); - disty <<= (8 - BILINEAR_INTERPOLATION_BITS); - - distxy = distx * disty; - distxiy = (distx << 8) - distxy; /* distx * (256 - disty) */ - distixy = (disty << 8) - distxy; /* disty * (256 - distx) */ - distixiy = - 256 * 256 - (disty << 8) - - (distx << 8) + distxy; /* (256 - distx) * (256 - disty) */ - - /* Blue */ - r = (tl & 0x000000ff) * distixiy + (tr & 0x000000ff) * distxiy - + (bl & 0x000000ff) * distixy + (br & 0x000000ff) * distxy; - - /* Green */ - f = (tl & 0x0000ff00) * distixiy + (tr & 0x0000ff00) * distxiy - + (bl & 0x0000ff00) * distixy + (br & 0x0000ff00) * distxy; - r |= f & 0xff000000; - - tl >>= 16; - tr >>= 16; - bl >>= 16; - br >>= 16; - r >>= 16; - - /* Red */ - f = (tl & 0x000000ff) * distixiy + (tr & 0x000000ff) * distxiy - + (bl & 0x000000ff) * distixy + (br & 0x000000ff) * distxy; - r |= f & 0x00ff0000; - - /* Alpha */ - f = (tl & 0x0000ff00) * distixiy + (tr & 0x0000ff00) * distxiy - + (bl & 0x0000ff00) * distixy + (br & 0x0000ff00) * distxy; - r |= f & 0xff000000; - - return r; -} - -#endif -#endif // BILINEAR_INTERPOLATION_BITS <= 4 - -/* - * For each scanline fetched from source image with PAD repeat: - * - calculate how many pixels need to be padded on the left side - * - calculate how many pixels need to be padded on the right side - * - update width to only count pixels which are fetched from the image - * All this information is returned via 'width', 'left_pad', 'right_pad' - * arguments. The code is assuming that 'unit_x' is positive. - * - * Note: 64-bit math is used in order to avoid potential overflows, which - * is probably excessive in many cases. This particular function - * may need its own correctness test and performance tuning. - */ -static force_inline void -pad_repeat_get_scanline_bounds (int32_t source_image_width, - pixman_fixed_t vx, - pixman_fixed_t unit_x, - int32_t * width, - int32_t * left_pad, - int32_t * right_pad) -{ - int64_t max_vx = (int64_t) source_image_width << 16; - int64_t tmp; - if (vx < 0) - { - tmp = ((int64_t) unit_x - 1 - vx) / unit_x; - if (tmp > *width) - { - *left_pad = *width; - *width = 0; - } - else - { - *left_pad = (int32_t) tmp; - *width -= (int32_t) tmp; - } - } - else - { - *left_pad = 0; - } - tmp = ((int64_t) unit_x - 1 - vx + max_vx) / unit_x - *left_pad; - if (tmp < 0) - { - *right_pad = *width; - *width = 0; - } - else if (tmp >= *width) - { - *right_pad = 0; - } - else - { - *right_pad = *width - (int32_t) tmp; - *width = (int32_t) tmp; - } -} - -/* A macroified version of specialized nearest scalers for some - * common 8888 and 565 formats. It supports SRC and OVER ops. - * - * There are two repeat versions, one that handles repeat normal, - * and one without repeat handling that only works if the src region - * used is completely covered by the pre-repeated source samples. - * - * The loops are unrolled to process two pixels per iteration for better - * performance on most CPU architectures (superscalar processors - * can issue several operations simultaneously, other processors can hide - * instructions latencies by pipelining operations). Unrolling more - * does not make much sense because the compiler will start running out - * of spare registers soon. - */ - -#define GET_8888_ALPHA(s) ((s) >> 24) - /* This is not actually used since we don't have an OVER with - 565 source, but it is needed to build. */ -#define GET_0565_ALPHA(s) 0xff -#define GET_x888_ALPHA(s) 0xff - -#define FAST_NEAREST_SCANLINE(scanline_func_name, SRC_FORMAT, DST_FORMAT, \ - src_type_t, dst_type_t, OP, repeat_mode) \ -static force_inline void \ -scanline_func_name (dst_type_t *dst, \ - const src_type_t *src, \ - int32_t w, \ - pixman_fixed_t vx, \ - pixman_fixed_t unit_x, \ - pixman_fixed_t src_width_fixed, \ - pixman_bool_t fully_transparent_src) \ -{ \ - uint32_t d; \ - src_type_t s1, s2; \ - uint8_t a1, a2; \ - int x1, x2; \ - \ - if (PIXMAN_OP_ ## OP == PIXMAN_OP_OVER && fully_transparent_src) \ - return; \ - \ - if (PIXMAN_OP_ ## OP != PIXMAN_OP_SRC && PIXMAN_OP_ ## OP != PIXMAN_OP_OVER) \ - abort(); \ - \ - while ((w -= 2) >= 0) \ - { \ - x1 = pixman_fixed_to_int (vx); \ - vx += unit_x; \ - if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NORMAL) \ - { \ - /* This works because we know that unit_x is positive */ \ - while (vx >= 0) \ - vx -= src_width_fixed; \ - } \ - s1 = *(src + x1); \ - \ - x2 = pixman_fixed_to_int (vx); \ - vx += unit_x; \ - if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NORMAL) \ - { \ - /* This works because we know that unit_x is positive */ \ - while (vx >= 0) \ - vx -= src_width_fixed; \ - } \ - s2 = *(src + x2); \ - \ - if (PIXMAN_OP_ ## OP == PIXMAN_OP_OVER) \ - { \ - a1 = GET_ ## SRC_FORMAT ## _ALPHA(s1); \ - a2 = GET_ ## SRC_FORMAT ## _ALPHA(s2); \ - \ - if (a1 == 0xff) \ - { \ - *dst = convert_ ## SRC_FORMAT ## _to_ ## DST_FORMAT (s1); \ - } \ - else if (s1) \ - { \ - d = convert_ ## DST_FORMAT ## _to_8888 (*dst); \ - s1 = convert_ ## SRC_FORMAT ## _to_8888 (s1); \ - a1 ^= 0xff; \ - UN8x4_MUL_UN8_ADD_UN8x4 (d, a1, s1); \ - *dst = convert_8888_to_ ## DST_FORMAT (d); \ - } \ - dst++; \ - \ - if (a2 == 0xff) \ - { \ - *dst = convert_ ## SRC_FORMAT ## _to_ ## DST_FORMAT (s2); \ - } \ - else if (s2) \ - { \ - d = convert_## DST_FORMAT ## _to_8888 (*dst); \ - s2 = convert_## SRC_FORMAT ## _to_8888 (s2); \ - a2 ^= 0xff; \ - UN8x4_MUL_UN8_ADD_UN8x4 (d, a2, s2); \ - *dst = convert_8888_to_ ## DST_FORMAT (d); \ - } \ - dst++; \ - } \ - else /* PIXMAN_OP_SRC */ \ - { \ - *dst++ = convert_ ## SRC_FORMAT ## _to_ ## DST_FORMAT (s1); \ - *dst++ = convert_ ## SRC_FORMAT ## _to_ ## DST_FORMAT (s2); \ - } \ - } \ - \ - if (w & 1) \ - { \ - x1 = pixman_fixed_to_int (vx); \ - s1 = *(src + x1); \ - \ - if (PIXMAN_OP_ ## OP == PIXMAN_OP_OVER) \ - { \ - a1 = GET_ ## SRC_FORMAT ## _ALPHA(s1); \ - \ - if (a1 == 0xff) \ - { \ - *dst = convert_ ## SRC_FORMAT ## _to_ ## DST_FORMAT (s1); \ - } \ - else if (s1) \ - { \ - d = convert_## DST_FORMAT ## _to_8888 (*dst); \ - s1 = convert_ ## SRC_FORMAT ## _to_8888 (s1); \ - a1 ^= 0xff; \ - UN8x4_MUL_UN8_ADD_UN8x4 (d, a1, s1); \ - *dst = convert_8888_to_ ## DST_FORMAT (d); \ - } \ - dst++; \ - } \ - else /* PIXMAN_OP_SRC */ \ - { \ - *dst++ = convert_ ## SRC_FORMAT ## _to_ ## DST_FORMAT (s1); \ - } \ - } \ -} - -#define FAST_NEAREST_MAINLOOP_INT(scale_func_name, scanline_func, src_type_t, mask_type_t, \ - dst_type_t, repeat_mode, have_mask, mask_is_solid) \ -static void \ -fast_composite_scaled_nearest ## scale_func_name (pixman_implementation_t *imp, \ - pixman_composite_info_t *info) \ -{ \ - PIXMAN_COMPOSITE_ARGS (info); \ - dst_type_t *dst_line; \ - mask_type_t *mask_line; \ - src_type_t *src_first_line; \ - int y; \ - pixman_fixed_t src_width_fixed = pixman_int_to_fixed (src_image->bits.width); \ - pixman_fixed_t max_vy; \ - pixman_vector_t v; \ - pixman_fixed_t vx, vy; \ - pixman_fixed_t unit_x, unit_y; \ - int32_t left_pad, right_pad; \ - \ - src_type_t *src; \ - dst_type_t *dst; \ - mask_type_t solid_mask; \ - const mask_type_t *mask = &solid_mask; \ - int src_stride, mask_stride, dst_stride; \ - \ - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type_t, dst_stride, dst_line, 1); \ - if (have_mask) \ - { \ - if (mask_is_solid) \ - solid_mask = _pixman_image_get_solid (imp, mask_image, dest_image->bits.format); \ - else \ - PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type_t, \ - mask_stride, mask_line, 1); \ - } \ - /* pass in 0 instead of src_x and src_y because src_x and src_y need to be \ - * transformed from destination space to source space */ \ - PIXMAN_IMAGE_GET_LINE (src_image, 0, 0, src_type_t, src_stride, src_first_line, 1); \ - \ - /* reference point is the center of the pixel */ \ - v.vector[0] = pixman_int_to_fixed (src_x) + pixman_fixed_1 / 2; \ - v.vector[1] = pixman_int_to_fixed (src_y) + pixman_fixed_1 / 2; \ - v.vector[2] = pixman_fixed_1; \ - \ - if (!pixman_transform_point_3d (src_image->common.transform, &v)) \ - return; \ - \ - unit_x = src_image->common.transform->matrix[0][0]; \ - unit_y = src_image->common.transform->matrix[1][1]; \ - \ - /* Round down to closest integer, ensuring that 0.5 rounds to 0, not 1 */ \ - v.vector[0] -= pixman_fixed_e; \ - v.vector[1] -= pixman_fixed_e; \ - \ - vx = v.vector[0]; \ - vy = v.vector[1]; \ - \ - if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NORMAL) \ - { \ - max_vy = pixman_int_to_fixed (src_image->bits.height); \ - \ - /* Clamp repeating positions inside the actual samples */ \ - repeat (PIXMAN_REPEAT_NORMAL, &vx, src_width_fixed); \ - repeat (PIXMAN_REPEAT_NORMAL, &vy, max_vy); \ - } \ - \ - if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_PAD || \ - PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NONE) \ - { \ - pad_repeat_get_scanline_bounds (src_image->bits.width, vx, unit_x, \ - &width, &left_pad, &right_pad); \ - vx += left_pad * unit_x; \ - } \ - \ - while (--height >= 0) \ - { \ - dst = dst_line; \ - dst_line += dst_stride; \ - if (have_mask && !mask_is_solid) \ - { \ - mask = mask_line; \ - mask_line += mask_stride; \ - } \ - \ - y = pixman_fixed_to_int (vy); \ - vy += unit_y; \ - if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NORMAL) \ - repeat (PIXMAN_REPEAT_NORMAL, &vy, max_vy); \ - if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_PAD) \ - { \ - repeat (PIXMAN_REPEAT_PAD, &y, src_image->bits.height); \ - src = src_first_line + src_stride * y; \ - if (left_pad > 0) \ - { \ - scanline_func (mask, dst, \ - src + src_image->bits.width - src_image->bits.width + 1, \ - left_pad, -pixman_fixed_e, 0, src_width_fixed, FALSE); \ - } \ - if (width > 0) \ - { \ - scanline_func (mask + (mask_is_solid ? 0 : left_pad), \ - dst + left_pad, src + src_image->bits.width, width, \ - vx - src_width_fixed, unit_x, src_width_fixed, FALSE); \ - } \ - if (right_pad > 0) \ - { \ - scanline_func (mask + (mask_is_solid ? 0 : left_pad + width), \ - dst + left_pad + width, src + src_image->bits.width, \ - right_pad, -pixman_fixed_e, 0, src_width_fixed, FALSE); \ - } \ - } \ - else if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NONE) \ - { \ - static const src_type_t zero[1] = { 0 }; \ - if (y < 0 || y >= src_image->bits.height) \ - { \ - scanline_func (mask, dst, zero + 1, left_pad + width + right_pad, \ - -pixman_fixed_e, 0, src_width_fixed, TRUE); \ - continue; \ - } \ - src = src_first_line + src_stride * y; \ - if (left_pad > 0) \ - { \ - scanline_func (mask, dst, zero + 1, left_pad, \ - -pixman_fixed_e, 0, src_width_fixed, TRUE); \ - } \ - if (width > 0) \ - { \ - scanline_func (mask + (mask_is_solid ? 0 : left_pad), \ - dst + left_pad, src + src_image->bits.width, width, \ - vx - src_width_fixed, unit_x, src_width_fixed, FALSE); \ - } \ - if (right_pad > 0) \ - { \ - scanline_func (mask + (mask_is_solid ? 0 : left_pad + width), \ - dst + left_pad + width, zero + 1, right_pad, \ - -pixman_fixed_e, 0, src_width_fixed, TRUE); \ - } \ - } \ - else \ - { \ - src = src_first_line + src_stride * y; \ - scanline_func (mask, dst, src + src_image->bits.width, width, vx - src_width_fixed, \ - unit_x, src_width_fixed, FALSE); \ - } \ - } \ -} - -/* A workaround for old sun studio, see: https://bugs.freedesktop.org/show_bug.cgi?id=32764 */ -#define FAST_NEAREST_MAINLOOP_COMMON(scale_func_name, scanline_func, src_type_t, mask_type_t, \ - dst_type_t, repeat_mode, have_mask, mask_is_solid) \ - FAST_NEAREST_MAINLOOP_INT(_ ## scale_func_name, scanline_func, src_type_t, mask_type_t, \ - dst_type_t, repeat_mode, have_mask, mask_is_solid) - -#define FAST_NEAREST_MAINLOOP_NOMASK(scale_func_name, scanline_func, src_type_t, dst_type_t, \ - repeat_mode) \ - static force_inline void \ - scanline_func##scale_func_name##_wrapper ( \ - const uint8_t *mask, \ - dst_type_t *dst, \ - const src_type_t *src, \ - int32_t w, \ - pixman_fixed_t vx, \ - pixman_fixed_t unit_x, \ - pixman_fixed_t max_vx, \ - pixman_bool_t fully_transparent_src) \ - { \ - scanline_func (dst, src, w, vx, unit_x, max_vx, fully_transparent_src); \ - } \ - FAST_NEAREST_MAINLOOP_INT (scale_func_name, scanline_func##scale_func_name##_wrapper, \ - src_type_t, uint8_t, dst_type_t, repeat_mode, FALSE, FALSE) - -#define FAST_NEAREST_MAINLOOP(scale_func_name, scanline_func, src_type_t, dst_type_t, \ - repeat_mode) \ - FAST_NEAREST_MAINLOOP_NOMASK(_ ## scale_func_name, scanline_func, src_type_t, \ - dst_type_t, repeat_mode) - -#define FAST_NEAREST(scale_func_name, SRC_FORMAT, DST_FORMAT, \ - src_type_t, dst_type_t, OP, repeat_mode) \ - FAST_NEAREST_SCANLINE(scaled_nearest_scanline_ ## scale_func_name ## _ ## OP, \ - SRC_FORMAT, DST_FORMAT, src_type_t, dst_type_t, \ - OP, repeat_mode) \ - FAST_NEAREST_MAINLOOP_NOMASK(_ ## scale_func_name ## _ ## OP, \ - scaled_nearest_scanline_ ## scale_func_name ## _ ## OP, \ - src_type_t, dst_type_t, repeat_mode) - - -#define SCALED_NEAREST_FLAGS \ - (FAST_PATH_SCALE_TRANSFORM | \ - FAST_PATH_NO_ALPHA_MAP | \ - FAST_PATH_NEAREST_FILTER | \ - FAST_PATH_NO_ACCESSORS | \ - FAST_PATH_NARROW_FORMAT) - -#define SIMPLE_NEAREST_FAST_PATH_NORMAL(op,s,d,func) \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, \ - (SCALED_NEAREST_FLAGS | \ - FAST_PATH_NORMAL_REPEAT | \ - FAST_PATH_X_UNIT_POSITIVE), \ - PIXMAN_null, 0, \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_scaled_nearest_ ## func ## _normal ## _ ## op, \ - } - -#define SIMPLE_NEAREST_FAST_PATH_PAD(op,s,d,func) \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, \ - (SCALED_NEAREST_FLAGS | \ - FAST_PATH_PAD_REPEAT | \ - FAST_PATH_X_UNIT_POSITIVE), \ - PIXMAN_null, 0, \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_scaled_nearest_ ## func ## _pad ## _ ## op, \ - } - -#define SIMPLE_NEAREST_FAST_PATH_NONE(op,s,d,func) \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, \ - (SCALED_NEAREST_FLAGS | \ - FAST_PATH_NONE_REPEAT | \ - FAST_PATH_X_UNIT_POSITIVE), \ - PIXMAN_null, 0, \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_scaled_nearest_ ## func ## _none ## _ ## op, \ - } - -#define SIMPLE_NEAREST_FAST_PATH_COVER(op,s,d,func) \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, \ - SCALED_NEAREST_FLAGS | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST, \ - PIXMAN_null, 0, \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_scaled_nearest_ ## func ## _cover ## _ ## op, \ - } - -#define SIMPLE_NEAREST_A8_MASK_FAST_PATH_NORMAL(op,s,d,func) \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, \ - (SCALED_NEAREST_FLAGS | \ - FAST_PATH_NORMAL_REPEAT | \ - FAST_PATH_X_UNIT_POSITIVE), \ - PIXMAN_a8, MASK_FLAGS (a8, FAST_PATH_UNIFIED_ALPHA), \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_scaled_nearest_ ## func ## _normal ## _ ## op, \ - } - -#define SIMPLE_NEAREST_A8_MASK_FAST_PATH_PAD(op,s,d,func) \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, \ - (SCALED_NEAREST_FLAGS | \ - FAST_PATH_PAD_REPEAT | \ - FAST_PATH_X_UNIT_POSITIVE), \ - PIXMAN_a8, MASK_FLAGS (a8, FAST_PATH_UNIFIED_ALPHA), \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_scaled_nearest_ ## func ## _pad ## _ ## op, \ - } - -#define SIMPLE_NEAREST_A8_MASK_FAST_PATH_NONE(op,s,d,func) \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, \ - (SCALED_NEAREST_FLAGS | \ - FAST_PATH_NONE_REPEAT | \ - FAST_PATH_X_UNIT_POSITIVE), \ - PIXMAN_a8, MASK_FLAGS (a8, FAST_PATH_UNIFIED_ALPHA), \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_scaled_nearest_ ## func ## _none ## _ ## op, \ - } - -#define SIMPLE_NEAREST_A8_MASK_FAST_PATH_COVER(op,s,d,func) \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, \ - SCALED_NEAREST_FLAGS | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST, \ - PIXMAN_a8, MASK_FLAGS (a8, FAST_PATH_UNIFIED_ALPHA), \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_scaled_nearest_ ## func ## _cover ## _ ## op, \ - } - -#define SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_NORMAL(op,s,d,func) \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, \ - (SCALED_NEAREST_FLAGS | \ - FAST_PATH_NORMAL_REPEAT | \ - FAST_PATH_X_UNIT_POSITIVE), \ - PIXMAN_solid, MASK_FLAGS (solid, FAST_PATH_UNIFIED_ALPHA), \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_scaled_nearest_ ## func ## _normal ## _ ## op, \ - } - -#define SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_PAD(op,s,d,func) \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, \ - (SCALED_NEAREST_FLAGS | \ - FAST_PATH_PAD_REPEAT | \ - FAST_PATH_X_UNIT_POSITIVE), \ - PIXMAN_solid, MASK_FLAGS (solid, FAST_PATH_UNIFIED_ALPHA), \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_scaled_nearest_ ## func ## _pad ## _ ## op, \ - } - -#define SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_NONE(op,s,d,func) \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, \ - (SCALED_NEAREST_FLAGS | \ - FAST_PATH_NONE_REPEAT | \ - FAST_PATH_X_UNIT_POSITIVE), \ - PIXMAN_solid, MASK_FLAGS (solid, FAST_PATH_UNIFIED_ALPHA), \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_scaled_nearest_ ## func ## _none ## _ ## op, \ - } - -#define SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_COVER(op,s,d,func) \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, \ - SCALED_NEAREST_FLAGS | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST, \ - PIXMAN_solid, MASK_FLAGS (solid, FAST_PATH_UNIFIED_ALPHA), \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_scaled_nearest_ ## func ## _cover ## _ ## op, \ - } - -/* Prefer the use of 'cover' variant, because it is faster */ -#define SIMPLE_NEAREST_FAST_PATH(op,s,d,func) \ - SIMPLE_NEAREST_FAST_PATH_COVER (op,s,d,func), \ - SIMPLE_NEAREST_FAST_PATH_NONE (op,s,d,func), \ - SIMPLE_NEAREST_FAST_PATH_PAD (op,s,d,func), \ - SIMPLE_NEAREST_FAST_PATH_NORMAL (op,s,d,func) - -#define SIMPLE_NEAREST_A8_MASK_FAST_PATH(op,s,d,func) \ - SIMPLE_NEAREST_A8_MASK_FAST_PATH_COVER (op,s,d,func), \ - SIMPLE_NEAREST_A8_MASK_FAST_PATH_NONE (op,s,d,func), \ - SIMPLE_NEAREST_A8_MASK_FAST_PATH_PAD (op,s,d,func) - -#define SIMPLE_NEAREST_SOLID_MASK_FAST_PATH(op,s,d,func) \ - SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_COVER (op,s,d,func), \ - SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_NONE (op,s,d,func), \ - SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_PAD (op,s,d,func), \ - SIMPLE_NEAREST_SOLID_MASK_FAST_PATH_NORMAL (op,s,d,func) - -/*****************************************************************************/ - -/* - * Identify 5 zones in each scanline for bilinear scaling. Depending on - * whether 2 pixels to be interpolated are fetched from the image itself, - * from the padding area around it or from both image and padding area. - */ -static force_inline void -bilinear_pad_repeat_get_scanline_bounds (int32_t source_image_width, - pixman_fixed_t vx, - pixman_fixed_t unit_x, - int32_t * left_pad, - int32_t * left_tz, - int32_t * width, - int32_t * right_tz, - int32_t * right_pad) -{ - int width1 = *width, left_pad1, right_pad1; - int width2 = *width, left_pad2, right_pad2; - - pad_repeat_get_scanline_bounds (source_image_width, vx, unit_x, - &width1, &left_pad1, &right_pad1); - pad_repeat_get_scanline_bounds (source_image_width, vx + pixman_fixed_1, - unit_x, &width2, &left_pad2, &right_pad2); - - *left_pad = left_pad2; - *left_tz = left_pad1 - left_pad2; - *right_tz = right_pad2 - right_pad1; - *right_pad = right_pad1; - *width -= *left_pad + *left_tz + *right_tz + *right_pad; -} - -/* - * Main loop template for single pass bilinear scaling. It needs to be - * provided with 'scanline_func' which should do the compositing operation. - * The needed function has the following prototype: - * - * scanline_func (dst_type_t * dst, - * const mask_type_ * mask, - * const src_type_t * src_top, - * const src_type_t * src_bottom, - * int32_t width, - * int weight_top, - * int weight_bottom, - * pixman_fixed_t vx, - * pixman_fixed_t unit_x, - * pixman_fixed_t max_vx, - * pixman_bool_t zero_src) - * - * Where: - * dst - destination scanline buffer for storing results - * mask - mask buffer (or single value for solid mask) - * src_top, src_bottom - two source scanlines - * width - number of pixels to process - * weight_top - weight of the top row for interpolation - * weight_bottom - weight of the bottom row for interpolation - * vx - initial position for fetching the first pair of - * pixels from the source buffer - * unit_x - position increment needed to move to the next pair - * of pixels - * max_vx - image size as a fixed point value, can be used for - * implementing NORMAL repeat (when it is supported) - * zero_src - boolean hint variable, which is set to TRUE when - * all source pixels are fetched from zero padding - * zone for NONE repeat - * - * Note: normally the sum of 'weight_top' and 'weight_bottom' is equal to - * BILINEAR_INTERPOLATION_RANGE, but sometimes it may be less than that - * for NONE repeat when handling fuzzy antialiased top or bottom image - * edges. Also both top and bottom weight variables are guaranteed to - * have value, which is less than BILINEAR_INTERPOLATION_RANGE. - * For example, the weights can fit into unsigned byte or be used - * with 8-bit SIMD multiplication instructions for 8-bit interpolation - * precision. - */ -#define FAST_BILINEAR_MAINLOOP_INT(scale_func_name, scanline_func, src_type_t, mask_type_t, \ - dst_type_t, repeat_mode, flags) \ -static void \ -fast_composite_scaled_bilinear ## scale_func_name (pixman_implementation_t *imp, \ - pixman_composite_info_t *info) \ -{ \ - PIXMAN_COMPOSITE_ARGS (info); \ - dst_type_t *dst_line; \ - mask_type_t *mask_line; \ - src_type_t *src_first_line; \ - int y1, y2; \ - pixman_fixed_t max_vx = INT32_MAX; /* suppress uninitialized variable warning */ \ - pixman_vector_t v; \ - pixman_fixed_t vx, vy; \ - pixman_fixed_t unit_x, unit_y; \ - int32_t left_pad, left_tz, right_tz, right_pad; \ - \ - dst_type_t *dst; \ - mask_type_t solid_mask; \ - const mask_type_t *mask = &solid_mask; \ - int src_stride, mask_stride, dst_stride; \ - \ - int src_width; \ - pixman_fixed_t src_width_fixed; \ - int max_x; \ - pixman_bool_t need_src_extension; \ - \ - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type_t, dst_stride, dst_line, 1); \ - if (flags & FLAG_HAVE_SOLID_MASK) \ - { \ - solid_mask = _pixman_image_get_solid (imp, mask_image, dest_image->bits.format); \ - mask_stride = 0; \ - } \ - else if (flags & FLAG_HAVE_NON_SOLID_MASK) \ - { \ - PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type_t, \ - mask_stride, mask_line, 1); \ - } \ - \ - /* pass in 0 instead of src_x and src_y because src_x and src_y need to be \ - * transformed from destination space to source space */ \ - PIXMAN_IMAGE_GET_LINE (src_image, 0, 0, src_type_t, src_stride, src_first_line, 1); \ - \ - /* reference point is the center of the pixel */ \ - v.vector[0] = pixman_int_to_fixed (src_x) + pixman_fixed_1 / 2; \ - v.vector[1] = pixman_int_to_fixed (src_y) + pixman_fixed_1 / 2; \ - v.vector[2] = pixman_fixed_1; \ - \ - if (!pixman_transform_point_3d (src_image->common.transform, &v)) \ - return; \ - \ - unit_x = src_image->common.transform->matrix[0][0]; \ - unit_y = src_image->common.transform->matrix[1][1]; \ - \ - v.vector[0] -= pixman_fixed_1 / 2; \ - v.vector[1] -= pixman_fixed_1 / 2; \ - \ - vy = v.vector[1]; \ - \ - if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_PAD || \ - PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NONE) \ - { \ - bilinear_pad_repeat_get_scanline_bounds (src_image->bits.width, v.vector[0], unit_x, \ - &left_pad, &left_tz, &width, &right_tz, &right_pad); \ - if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_PAD) \ - { \ - /* PAD repeat does not need special handling for 'transition zones' and */ \ - /* they can be combined with 'padding zones' safely */ \ - left_pad += left_tz; \ - right_pad += right_tz; \ - left_tz = right_tz = 0; \ - } \ - v.vector[0] += left_pad * unit_x; \ - } \ - \ - if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NORMAL) \ - { \ - vx = v.vector[0]; \ - repeat (PIXMAN_REPEAT_NORMAL, &vx, pixman_int_to_fixed(src_image->bits.width)); \ - max_x = pixman_fixed_to_int (vx + (width - 1) * (int64_t)unit_x) + 1; \ - \ - if (src_image->bits.width < REPEAT_NORMAL_MIN_WIDTH) \ - { \ - src_width = 0; \ - \ - while (src_width < REPEAT_NORMAL_MIN_WIDTH && src_width <= max_x) \ - src_width += src_image->bits.width; \ - \ - need_src_extension = TRUE; \ - } \ - else \ - { \ - src_width = src_image->bits.width; \ - need_src_extension = FALSE; \ - } \ - \ - src_width_fixed = pixman_int_to_fixed (src_width); \ - } \ - \ - while (--height >= 0) \ - { \ - int weight1, weight2; \ - dst = dst_line; \ - dst_line += dst_stride; \ - vx = v.vector[0]; \ - if (flags & FLAG_HAVE_NON_SOLID_MASK) \ - { \ - mask = mask_line; \ - mask_line += mask_stride; \ - } \ - \ - y1 = pixman_fixed_to_int (vy); \ - weight2 = pixman_fixed_to_bilinear_weight (vy); \ - if (weight2) \ - { \ - /* both weight1 and weight2 are smaller than BILINEAR_INTERPOLATION_RANGE */ \ - y2 = y1 + 1; \ - weight1 = BILINEAR_INTERPOLATION_RANGE - weight2; \ - } \ - else \ - { \ - /* set both top and bottom row to the same scanline and tweak weights */ \ - y2 = y1; \ - weight1 = weight2 = BILINEAR_INTERPOLATION_RANGE / 2; \ - } \ - vy += unit_y; \ - if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_PAD) \ - { \ - src_type_t *src1, *src2; \ - src_type_t buf1[2]; \ - src_type_t buf2[2]; \ - repeat (PIXMAN_REPEAT_PAD, &y1, src_image->bits.height); \ - repeat (PIXMAN_REPEAT_PAD, &y2, src_image->bits.height); \ - src1 = src_first_line + src_stride * y1; \ - src2 = src_first_line + src_stride * y2; \ - \ - if (left_pad > 0) \ - { \ - buf1[0] = buf1[1] = src1[0]; \ - buf2[0] = buf2[1] = src2[0]; \ - scanline_func (dst, mask, \ - buf1, buf2, left_pad, weight1, weight2, 0, 0, 0, FALSE); \ - dst += left_pad; \ - if (flags & FLAG_HAVE_NON_SOLID_MASK) \ - mask += left_pad; \ - } \ - if (width > 0) \ - { \ - scanline_func (dst, mask, \ - src1, src2, width, weight1, weight2, vx, unit_x, 0, FALSE); \ - dst += width; \ - if (flags & FLAG_HAVE_NON_SOLID_MASK) \ - mask += width; \ - } \ - if (right_pad > 0) \ - { \ - buf1[0] = buf1[1] = src1[src_image->bits.width - 1]; \ - buf2[0] = buf2[1] = src2[src_image->bits.width - 1]; \ - scanline_func (dst, mask, \ - buf1, buf2, right_pad, weight1, weight2, 0, 0, 0, FALSE); \ - } \ - } \ - else if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NONE) \ - { \ - src_type_t *src1, *src2; \ - src_type_t buf1[2]; \ - src_type_t buf2[2]; \ - /* handle top/bottom zero padding by just setting weights to 0 if needed */ \ - if (y1 < 0) \ - { \ - weight1 = 0; \ - y1 = 0; \ - } \ - if (y1 >= src_image->bits.height) \ - { \ - weight1 = 0; \ - y1 = src_image->bits.height - 1; \ - } \ - if (y2 < 0) \ - { \ - weight2 = 0; \ - y2 = 0; \ - } \ - if (y2 >= src_image->bits.height) \ - { \ - weight2 = 0; \ - y2 = src_image->bits.height - 1; \ - } \ - src1 = src_first_line + src_stride * y1; \ - src2 = src_first_line + src_stride * y2; \ - \ - if (left_pad > 0) \ - { \ - buf1[0] = buf1[1] = 0; \ - buf2[0] = buf2[1] = 0; \ - scanline_func (dst, mask, \ - buf1, buf2, left_pad, weight1, weight2, 0, 0, 0, TRUE); \ - dst += left_pad; \ - if (flags & FLAG_HAVE_NON_SOLID_MASK) \ - mask += left_pad; \ - } \ - if (left_tz > 0) \ - { \ - buf1[0] = 0; \ - buf1[1] = src1[0]; \ - buf2[0] = 0; \ - buf2[1] = src2[0]; \ - scanline_func (dst, mask, \ - buf1, buf2, left_tz, weight1, weight2, \ - pixman_fixed_frac (vx), unit_x, 0, FALSE); \ - dst += left_tz; \ - if (flags & FLAG_HAVE_NON_SOLID_MASK) \ - mask += left_tz; \ - vx += left_tz * unit_x; \ - } \ - if (width > 0) \ - { \ - scanline_func (dst, mask, \ - src1, src2, width, weight1, weight2, vx, unit_x, 0, FALSE); \ - dst += width; \ - if (flags & FLAG_HAVE_NON_SOLID_MASK) \ - mask += width; \ - vx += width * unit_x; \ - } \ - if (right_tz > 0) \ - { \ - buf1[0] = src1[src_image->bits.width - 1]; \ - buf1[1] = 0; \ - buf2[0] = src2[src_image->bits.width - 1]; \ - buf2[1] = 0; \ - scanline_func (dst, mask, \ - buf1, buf2, right_tz, weight1, weight2, \ - pixman_fixed_frac (vx), unit_x, 0, FALSE); \ - dst += right_tz; \ - if (flags & FLAG_HAVE_NON_SOLID_MASK) \ - mask += right_tz; \ - } \ - if (right_pad > 0) \ - { \ - buf1[0] = buf1[1] = 0; \ - buf2[0] = buf2[1] = 0; \ - scanline_func (dst, mask, \ - buf1, buf2, right_pad, weight1, weight2, 0, 0, 0, TRUE); \ - } \ - } \ - else if (PIXMAN_REPEAT_ ## repeat_mode == PIXMAN_REPEAT_NORMAL) \ - { \ - int32_t num_pixels; \ - int32_t width_remain; \ - src_type_t * src_line_top; \ - src_type_t * src_line_bottom; \ - src_type_t buf1[2]; \ - src_type_t buf2[2]; \ - src_type_t extended_src_line0[REPEAT_NORMAL_MIN_WIDTH*2]; \ - src_type_t extended_src_line1[REPEAT_NORMAL_MIN_WIDTH*2]; \ - int i, j; \ - \ - repeat (PIXMAN_REPEAT_NORMAL, &y1, src_image->bits.height); \ - repeat (PIXMAN_REPEAT_NORMAL, &y2, src_image->bits.height); \ - src_line_top = src_first_line + src_stride * y1; \ - src_line_bottom = src_first_line + src_stride * y2; \ - \ - if (need_src_extension) \ - { \ - for (i=0; i<src_width;) \ - { \ - for (j=0; j<src_image->bits.width; j++, i++) \ - { \ - extended_src_line0[i] = src_line_top[j]; \ - extended_src_line1[i] = src_line_bottom[j]; \ - } \ - } \ - \ - src_line_top = &extended_src_line0[0]; \ - src_line_bottom = &extended_src_line1[0]; \ - } \ - \ - /* Top & Bottom wrap around buffer */ \ - buf1[0] = src_line_top[src_width - 1]; \ - buf1[1] = src_line_top[0]; \ - buf2[0] = src_line_bottom[src_width - 1]; \ - buf2[1] = src_line_bottom[0]; \ - \ - width_remain = width; \ - \ - while (width_remain > 0) \ - { \ - /* We use src_width_fixed because it can make vx in original source range */ \ - repeat (PIXMAN_REPEAT_NORMAL, &vx, src_width_fixed); \ - \ - /* Wrap around part */ \ - if (pixman_fixed_to_int (vx) == src_width - 1) \ - { \ - /* for positive unit_x \ - * num_pixels = max(n) + 1, where vx + n*unit_x < src_width_fixed \ - * \ - * vx is in range [0, src_width_fixed - pixman_fixed_e] \ - * So we are safe from overflow. \ - */ \ - num_pixels = ((src_width_fixed - vx - pixman_fixed_e) / unit_x) + 1; \ - \ - if (num_pixels > width_remain) \ - num_pixels = width_remain; \ - \ - scanline_func (dst, mask, buf1, buf2, num_pixels, \ - weight1, weight2, pixman_fixed_frac(vx), \ - unit_x, src_width_fixed, FALSE); \ - \ - width_remain -= num_pixels; \ - vx += num_pixels * unit_x; \ - dst += num_pixels; \ - \ - if (flags & FLAG_HAVE_NON_SOLID_MASK) \ - mask += num_pixels; \ - \ - repeat (PIXMAN_REPEAT_NORMAL, &vx, src_width_fixed); \ - } \ - \ - /* Normal scanline composite */ \ - if (pixman_fixed_to_int (vx) != src_width - 1 && width_remain > 0) \ - { \ - /* for positive unit_x \ - * num_pixels = max(n) + 1, where vx + n*unit_x < (src_width_fixed - 1) \ - * \ - * vx is in range [0, src_width_fixed - pixman_fixed_e] \ - * So we are safe from overflow here. \ - */ \ - num_pixels = ((src_width_fixed - pixman_fixed_1 - vx - pixman_fixed_e) \ - / unit_x) + 1; \ - \ - if (num_pixels > width_remain) \ - num_pixels = width_remain; \ - \ - scanline_func (dst, mask, src_line_top, src_line_bottom, num_pixels, \ - weight1, weight2, vx, unit_x, src_width_fixed, FALSE); \ - \ - width_remain -= num_pixels; \ - vx += num_pixels * unit_x; \ - dst += num_pixels; \ - \ - if (flags & FLAG_HAVE_NON_SOLID_MASK) \ - mask += num_pixels; \ - } \ - } \ - } \ - else \ - { \ - scanline_func (dst, mask, src_first_line + src_stride * y1, \ - src_first_line + src_stride * y2, width, \ - weight1, weight2, vx, unit_x, max_vx, FALSE); \ - } \ - } \ -} - -/* A workaround for old sun studio, see: https://bugs.freedesktop.org/show_bug.cgi?id=32764 */ -#define FAST_BILINEAR_MAINLOOP_COMMON(scale_func_name, scanline_func, src_type_t, mask_type_t, \ - dst_type_t, repeat_mode, flags) \ - FAST_BILINEAR_MAINLOOP_INT(_ ## scale_func_name, scanline_func, src_type_t, mask_type_t,\ - dst_type_t, repeat_mode, flags) - -#define SCALED_BILINEAR_FLAGS \ - (FAST_PATH_SCALE_TRANSFORM | \ - FAST_PATH_NO_ALPHA_MAP | \ - FAST_PATH_BILINEAR_FILTER | \ - FAST_PATH_NO_ACCESSORS | \ - FAST_PATH_NARROW_FORMAT) - -#define SIMPLE_BILINEAR_FAST_PATH_PAD(op,s,d,func) \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, \ - (SCALED_BILINEAR_FLAGS | \ - FAST_PATH_PAD_REPEAT | \ - FAST_PATH_X_UNIT_POSITIVE), \ - PIXMAN_null, 0, \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_scaled_bilinear_ ## func ## _pad ## _ ## op, \ - } - -#define SIMPLE_BILINEAR_FAST_PATH_NONE(op,s,d,func) \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, \ - (SCALED_BILINEAR_FLAGS | \ - FAST_PATH_NONE_REPEAT | \ - FAST_PATH_X_UNIT_POSITIVE), \ - PIXMAN_null, 0, \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_scaled_bilinear_ ## func ## _none ## _ ## op, \ - } - -#define SIMPLE_BILINEAR_FAST_PATH_COVER(op,s,d,func) \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, \ - SCALED_BILINEAR_FLAGS | FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR, \ - PIXMAN_null, 0, \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_scaled_bilinear_ ## func ## _cover ## _ ## op, \ - } - -#define SIMPLE_BILINEAR_FAST_PATH_NORMAL(op,s,d,func) \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, \ - (SCALED_BILINEAR_FLAGS | \ - FAST_PATH_NORMAL_REPEAT | \ - FAST_PATH_X_UNIT_POSITIVE), \ - PIXMAN_null, 0, \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_scaled_bilinear_ ## func ## _normal ## _ ## op, \ - } - -#define SIMPLE_BILINEAR_A8_MASK_FAST_PATH_PAD(op,s,d,func) \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, \ - (SCALED_BILINEAR_FLAGS | \ - FAST_PATH_PAD_REPEAT | \ - FAST_PATH_X_UNIT_POSITIVE), \ - PIXMAN_a8, MASK_FLAGS (a8, FAST_PATH_UNIFIED_ALPHA), \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_scaled_bilinear_ ## func ## _pad ## _ ## op, \ - } - -#define SIMPLE_BILINEAR_A8_MASK_FAST_PATH_NONE(op,s,d,func) \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, \ - (SCALED_BILINEAR_FLAGS | \ - FAST_PATH_NONE_REPEAT | \ - FAST_PATH_X_UNIT_POSITIVE), \ - PIXMAN_a8, MASK_FLAGS (a8, FAST_PATH_UNIFIED_ALPHA), \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_scaled_bilinear_ ## func ## _none ## _ ## op, \ - } - -#define SIMPLE_BILINEAR_A8_MASK_FAST_PATH_COVER(op,s,d,func) \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, \ - SCALED_BILINEAR_FLAGS | FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR, \ - PIXMAN_a8, MASK_FLAGS (a8, FAST_PATH_UNIFIED_ALPHA), \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_scaled_bilinear_ ## func ## _cover ## _ ## op, \ - } - -#define SIMPLE_BILINEAR_A8_MASK_FAST_PATH_NORMAL(op,s,d,func) \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, \ - (SCALED_BILINEAR_FLAGS | \ - FAST_PATH_NORMAL_REPEAT | \ - FAST_PATH_X_UNIT_POSITIVE), \ - PIXMAN_a8, MASK_FLAGS (a8, FAST_PATH_UNIFIED_ALPHA), \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_scaled_bilinear_ ## func ## _normal ## _ ## op, \ - } - -#define SIMPLE_BILINEAR_SOLID_MASK_FAST_PATH_PAD(op,s,d,func) \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, \ - (SCALED_BILINEAR_FLAGS | \ - FAST_PATH_PAD_REPEAT | \ - FAST_PATH_X_UNIT_POSITIVE), \ - PIXMAN_solid, MASK_FLAGS (solid, FAST_PATH_UNIFIED_ALPHA), \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_scaled_bilinear_ ## func ## _pad ## _ ## op, \ - } - -#define SIMPLE_BILINEAR_SOLID_MASK_FAST_PATH_NONE(op,s,d,func) \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, \ - (SCALED_BILINEAR_FLAGS | \ - FAST_PATH_NONE_REPEAT | \ - FAST_PATH_X_UNIT_POSITIVE), \ - PIXMAN_solid, MASK_FLAGS (solid, FAST_PATH_UNIFIED_ALPHA), \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_scaled_bilinear_ ## func ## _none ## _ ## op, \ - } - -#define SIMPLE_BILINEAR_SOLID_MASK_FAST_PATH_COVER(op,s,d,func) \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, \ - SCALED_BILINEAR_FLAGS | FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR, \ - PIXMAN_solid, MASK_FLAGS (solid, FAST_PATH_UNIFIED_ALPHA), \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_scaled_bilinear_ ## func ## _cover ## _ ## op, \ - } - -#define SIMPLE_BILINEAR_SOLID_MASK_FAST_PATH_NORMAL(op,s,d,func) \ - { PIXMAN_OP_ ## op, \ - PIXMAN_ ## s, \ - (SCALED_BILINEAR_FLAGS | \ - FAST_PATH_NORMAL_REPEAT | \ - FAST_PATH_X_UNIT_POSITIVE), \ - PIXMAN_solid, MASK_FLAGS (solid, FAST_PATH_UNIFIED_ALPHA), \ - PIXMAN_ ## d, FAST_PATH_STD_DEST_FLAGS, \ - fast_composite_scaled_bilinear_ ## func ## _normal ## _ ## op, \ - } - -/* Prefer the use of 'cover' variant, because it is faster */ -#define SIMPLE_BILINEAR_FAST_PATH(op,s,d,func) \ - SIMPLE_BILINEAR_FAST_PATH_COVER (op,s,d,func), \ - SIMPLE_BILINEAR_FAST_PATH_NONE (op,s,d,func), \ - SIMPLE_BILINEAR_FAST_PATH_PAD (op,s,d,func), \ - SIMPLE_BILINEAR_FAST_PATH_NORMAL (op,s,d,func) - -#define SIMPLE_BILINEAR_A8_MASK_FAST_PATH(op,s,d,func) \ - SIMPLE_BILINEAR_A8_MASK_FAST_PATH_COVER (op,s,d,func), \ - SIMPLE_BILINEAR_A8_MASK_FAST_PATH_NONE (op,s,d,func), \ - SIMPLE_BILINEAR_A8_MASK_FAST_PATH_PAD (op,s,d,func), \ - SIMPLE_BILINEAR_A8_MASK_FAST_PATH_NORMAL (op,s,d,func) - -#define SIMPLE_BILINEAR_SOLID_MASK_FAST_PATH(op,s,d,func) \ - SIMPLE_BILINEAR_SOLID_MASK_FAST_PATH_COVER (op,s,d,func), \ - SIMPLE_BILINEAR_SOLID_MASK_FAST_PATH_NONE (op,s,d,func), \ - SIMPLE_BILINEAR_SOLID_MASK_FAST_PATH_PAD (op,s,d,func), \ - SIMPLE_BILINEAR_SOLID_MASK_FAST_PATH_NORMAL (op,s,d,func) - -#endif diff --git a/source/libs/pixman/pixman-src/pixman/pixman-linear-gradient.c b/source/libs/pixman/pixman-src/pixman/pixman-linear-gradient.c deleted file mode 100644 index 40c8c9f37dbe4c8dd296e6c4348440d119e885ce..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-linear-gradient.c +++ /dev/null @@ -1,287 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */ -/* - * Copyright © 2000 SuSE, Inc. - * Copyright © 2007 Red Hat, Inc. - * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. - * 2005 Lars Knoll & Zack Rusin, Trolltech - * - * 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 Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdlib.h> -#include "pixman-private.h" - -static pixman_bool_t -linear_gradient_is_horizontal (pixman_image_t *image, - int x, - int y, - int width, - int height) -{ - linear_gradient_t *linear = (linear_gradient_t *)image; - pixman_vector_t v; - pixman_fixed_32_32_t l; - pixman_fixed_48_16_t dx, dy; - double inc; - - if (image->common.transform) - { - /* projective transformation */ - if (image->common.transform->matrix[2][0] != 0 || - image->common.transform->matrix[2][1] != 0 || - image->common.transform->matrix[2][2] == 0) - { - return FALSE; - } - - v.vector[0] = image->common.transform->matrix[0][1]; - v.vector[1] = image->common.transform->matrix[1][1]; - v.vector[2] = image->common.transform->matrix[2][2]; - } - else - { - v.vector[0] = 0; - v.vector[1] = pixman_fixed_1; - v.vector[2] = pixman_fixed_1; - } - - dx = linear->p2.x - linear->p1.x; - dy = linear->p2.y - linear->p1.y; - - l = dx * dx + dy * dy; - - if (l == 0) - return FALSE; - - /* - * compute how much the input of the gradient walked changes - * when moving vertically through the whole image - */ - inc = height * (double) pixman_fixed_1 * pixman_fixed_1 * - (dx * v.vector[0] + dy * v.vector[1]) / - (v.vector[2] * (double) l); - - /* check that casting to integer would result in 0 */ - if (-1 < inc && inc < 1) - return TRUE; - - return FALSE; -} - -static uint32_t * -linear_get_scanline_narrow (pixman_iter_t *iter, - const uint32_t *mask) -{ - pixman_image_t *image = iter->image; - int x = iter->x; - int y = iter->y; - int width = iter->width; - uint32_t * buffer = iter->buffer; - - pixman_vector_t v, unit; - pixman_fixed_32_32_t l; - pixman_fixed_48_16_t dx, dy; - gradient_t *gradient = (gradient_t *)image; - linear_gradient_t *linear = (linear_gradient_t *)image; - uint32_t *end = buffer + width; - pixman_gradient_walker_t walker; - - _pixman_gradient_walker_init (&walker, gradient, image->common.repeat); - - /* reference point is the center of the pixel */ - v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2; - v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2; - v.vector[2] = pixman_fixed_1; - - if (image->common.transform) - { - if (!pixman_transform_point_3d (image->common.transform, &v)) - return iter->buffer; - - unit.vector[0] = image->common.transform->matrix[0][0]; - unit.vector[1] = image->common.transform->matrix[1][0]; - unit.vector[2] = image->common.transform->matrix[2][0]; - } - else - { - unit.vector[0] = pixman_fixed_1; - unit.vector[1] = 0; - unit.vector[2] = 0; - } - - dx = linear->p2.x - linear->p1.x; - dy = linear->p2.y - linear->p1.y; - - l = dx * dx + dy * dy; - - if (l == 0 || unit.vector[2] == 0) - { - /* affine transformation only */ - pixman_fixed_32_32_t t, next_inc; - double inc; - - if (l == 0 || v.vector[2] == 0) - { - t = 0; - inc = 0; - } - else - { - double invden, v2; - - invden = pixman_fixed_1 * (double) pixman_fixed_1 / - (l * (double) v.vector[2]); - v2 = v.vector[2] * (1. / pixman_fixed_1); - t = ((dx * v.vector[0] + dy * v.vector[1]) - - (dx * linear->p1.x + dy * linear->p1.y) * v2) * invden; - inc = (dx * unit.vector[0] + dy * unit.vector[1]) * invden; - } - next_inc = 0; - - if (((pixman_fixed_32_32_t )(inc * width)) == 0) - { - register uint32_t color; - - color = _pixman_gradient_walker_pixel (&walker, t); - while (buffer < end) - *buffer++ = color; - } - else - { - int i; - - i = 0; - while (buffer < end) - { - if (!mask || *mask++) - { - *buffer = _pixman_gradient_walker_pixel (&walker, - t + next_inc); - } - i++; - next_inc = inc * i; - buffer++; - } - } - } - else - { - /* projective transformation */ - double t; - - t = 0; - - while (buffer < end) - { - if (!mask || *mask++) - { - if (v.vector[2] != 0) - { - double invden, v2; - - invden = pixman_fixed_1 * (double) pixman_fixed_1 / - (l * (double) v.vector[2]); - v2 = v.vector[2] * (1. / pixman_fixed_1); - t = ((dx * v.vector[0] + dy * v.vector[1]) - - (dx * linear->p1.x + dy * linear->p1.y) * v2) * invden; - } - - *buffer = _pixman_gradient_walker_pixel (&walker, t); - } - - ++buffer; - - v.vector[0] += unit.vector[0]; - v.vector[1] += unit.vector[1]; - v.vector[2] += unit.vector[2]; - } - } - - iter->y++; - - return iter->buffer; -} - -static uint32_t * -linear_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) -{ - uint32_t *buffer = linear_get_scanline_narrow (iter, NULL); - - pixman_expand_to_float ( - (argb_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); - - return buffer; -} - -void -_pixman_linear_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter) -{ - if (linear_gradient_is_horizontal ( - iter->image, iter->x, iter->y, iter->width, iter->height)) - { - if (iter->iter_flags & ITER_NARROW) - linear_get_scanline_narrow (iter, NULL); - else - linear_get_scanline_wide (iter, NULL); - - iter->get_scanline = _pixman_iter_get_scanline_noop; - } - else - { - if (iter->iter_flags & ITER_NARROW) - iter->get_scanline = linear_get_scanline_narrow; - else - iter->get_scanline = linear_get_scanline_wide; - } -} - -PIXMAN_EXPORT pixman_image_t * -pixman_image_create_linear_gradient (const pixman_point_fixed_t * p1, - const pixman_point_fixed_t * p2, - const pixman_gradient_stop_t *stops, - int n_stops) -{ - pixman_image_t *image; - linear_gradient_t *linear; - - image = _pixman_image_allocate (); - - if (!image) - return NULL; - - linear = &image->linear; - - if (!_pixman_init_gradient (&linear->common, stops, n_stops)) - { - free (image); - return NULL; - } - - linear->p1 = *p1; - linear->p2 = *p2; - - image->type = LINEAR; - - return image; -} - diff --git a/source/libs/pixman/pixman-src/pixman/pixman-matrix.c b/source/libs/pixman/pixman-src/pixman/pixman-matrix.c deleted file mode 100644 index 4032c137a2053fae9435309146e553f83909773f..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-matrix.c +++ /dev/null @@ -1,1073 +0,0 @@ -/* - * Copyright © 2008 Keith Packard - * - * 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 the copyright holders not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make no representations - * about the suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE COPYRIGHT HOLDERS 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. - */ - -/* - * Matrix interfaces - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <math.h> -#include <string.h> -#include "pixman-private.h" - -#define F(x) pixman_int_to_fixed (x) - -static force_inline int -count_leading_zeros (uint32_t x) -{ -#ifdef HAVE_BUILTIN_CLZ - return __builtin_clz (x); -#else - int n = 0; - while (x) - { - n++; - x >>= 1; - } - return 32 - n; -#endif -} - -/* - * Large signed/unsigned integer division with rounding for the platforms with - * only 64-bit integer data type supported (no 128-bit data type). - * - * Arguments: - * hi, lo - high and low 64-bit parts of the dividend - * div - 48-bit divisor - * - * Returns: lowest 64 bits of the result as a return value and highest 64 - * bits of the result to "result_hi" pointer - */ - -/* grade-school unsigned division (128-bit by 48-bit) with rounding to nearest */ -static force_inline uint64_t -rounded_udiv_128_by_48 (uint64_t hi, - uint64_t lo, - uint64_t div, - uint64_t *result_hi) -{ - uint64_t tmp, remainder, result_lo; - assert(div < ((uint64_t)1 << 48)); - - remainder = hi % div; - *result_hi = hi / div; - - tmp = (remainder << 16) + (lo >> 48); - result_lo = tmp / div; - remainder = tmp % div; - - tmp = (remainder << 16) + ((lo >> 32) & 0xFFFF); - result_lo = (result_lo << 16) + (tmp / div); - remainder = tmp % div; - - tmp = (remainder << 16) + ((lo >> 16) & 0xFFFF); - result_lo = (result_lo << 16) + (tmp / div); - remainder = tmp % div; - - tmp = (remainder << 16) + (lo & 0xFFFF); - result_lo = (result_lo << 16) + (tmp / div); - remainder = tmp % div; - - /* round to nearest */ - if (remainder * 2 >= div && ++result_lo == 0) - *result_hi += 1; - - return result_lo; -} - -/* signed division (128-bit by 49-bit) with rounding to nearest */ -static inline int64_t -rounded_sdiv_128_by_49 (int64_t hi, - uint64_t lo, - int64_t div, - int64_t *signed_result_hi) -{ - uint64_t result_lo, result_hi; - int sign = 0; - if (div < 0) - { - div = -div; - sign ^= 1; - } - if (hi < 0) - { - if (lo != 0) - hi++; - hi = -hi; - lo = -lo; - sign ^= 1; - } - result_lo = rounded_udiv_128_by_48 (hi, lo, div, &result_hi); - if (sign) - { - if (result_lo != 0) - result_hi++; - result_hi = -result_hi; - result_lo = -result_lo; - } - if (signed_result_hi) - { - *signed_result_hi = result_hi; - } - return result_lo; -} - -/* - * Multiply 64.16 fixed point value by (2^scalebits) and convert - * to 128-bit integer. - */ -static force_inline void -fixed_64_16_to_int128 (int64_t hi, - int64_t lo, - int64_t *rhi, - int64_t *rlo, - int scalebits) -{ - /* separate integer and fractional parts */ - hi += lo >> 16; - lo &= 0xFFFF; - - if (scalebits <= 0) - { - *rlo = hi >> (-scalebits); - *rhi = *rlo >> 63; - } - else - { - *rhi = hi >> (64 - scalebits); - *rlo = (uint64_t)hi << scalebits; - if (scalebits < 16) - *rlo += lo >> (16 - scalebits); - else - *rlo += lo << (scalebits - 16); - } -} - -/* - * Convert 112.16 fixed point value to 48.16 with clamping for the out - * of range values. - */ -static force_inline pixman_fixed_48_16_t -fixed_112_16_to_fixed_48_16 (int64_t hi, int64_t lo, pixman_bool_t *clampflag) -{ - if ((lo >> 63) != hi) - { - *clampflag = TRUE; - return hi >= 0 ? INT64_MAX : INT64_MIN; - } - else - { - return lo; - } -} - -/* - * Transform a point with 31.16 fixed point coordinates from the destination - * space to a point with 48.16 fixed point coordinates in the source space. - * No overflows are possible for affine transformations and the results are - * accurate including the least significant bit. Projective transformations - * may overflow, in this case the results are just clamped to return maximum - * or minimum 48.16 values (so that the caller can at least handle the NONE - * and PAD repeats correctly) and the return value is FALSE to indicate that - * such clamping has happened. - */ -PIXMAN_EXPORT pixman_bool_t -pixman_transform_point_31_16 (const pixman_transform_t *t, - const pixman_vector_48_16_t *v, - pixman_vector_48_16_t *result) -{ - pixman_bool_t clampflag = FALSE; - int i; - int64_t tmp[3][2], divint; - uint16_t divfrac; - - /* input vector values must have no more than 31 bits (including sign) - * in the integer part */ - assert (v->v[0] < ((pixman_fixed_48_16_t)1 << (30 + 16))); - assert (v->v[0] >= -((pixman_fixed_48_16_t)1 << (30 + 16))); - assert (v->v[1] < ((pixman_fixed_48_16_t)1 << (30 + 16))); - assert (v->v[1] >= -((pixman_fixed_48_16_t)1 << (30 + 16))); - assert (v->v[2] < ((pixman_fixed_48_16_t)1 << (30 + 16))); - assert (v->v[2] >= -((pixman_fixed_48_16_t)1 << (30 + 16))); - - for (i = 0; i < 3; i++) - { - tmp[i][0] = (int64_t)t->matrix[i][0] * (v->v[0] >> 16); - tmp[i][1] = (int64_t)t->matrix[i][0] * (v->v[0] & 0xFFFF); - tmp[i][0] += (int64_t)t->matrix[i][1] * (v->v[1] >> 16); - tmp[i][1] += (int64_t)t->matrix[i][1] * (v->v[1] & 0xFFFF); - tmp[i][0] += (int64_t)t->matrix[i][2] * (v->v[2] >> 16); - tmp[i][1] += (int64_t)t->matrix[i][2] * (v->v[2] & 0xFFFF); - } - - /* - * separate 64-bit integer and 16-bit fractional parts for the divisor, - * which is also scaled by 65536 after fixed point multiplication. - */ - divint = tmp[2][0] + (tmp[2][1] >> 16); - divfrac = tmp[2][1] & 0xFFFF; - - if (divint == pixman_fixed_1 && divfrac == 0) - { - /* - * this is a simple affine transformation - */ - result->v[0] = tmp[0][0] + ((tmp[0][1] + 0x8000) >> 16); - result->v[1] = tmp[1][0] + ((tmp[1][1] + 0x8000) >> 16); - result->v[2] = pixman_fixed_1; - } - else if (divint == 0 && divfrac == 0) - { - /* - * handle zero divisor (if the values are non-zero, set the - * results to maximum positive or minimum negative) - */ - clampflag = TRUE; - - result->v[0] = tmp[0][0] + ((tmp[0][1] + 0x8000) >> 16); - result->v[1] = tmp[1][0] + ((tmp[1][1] + 0x8000) >> 16); - - if (result->v[0] > 0) - result->v[0] = INT64_MAX; - else if (result->v[0] < 0) - result->v[0] = INT64_MIN; - - if (result->v[1] > 0) - result->v[1] = INT64_MAX; - else if (result->v[1] < 0) - result->v[1] = INT64_MIN; - } - else - { - /* - * projective transformation, analyze the top 32 bits of the divisor - */ - int32_t hi32divbits = divint >> 32; - if (hi32divbits < 0) - hi32divbits = ~hi32divbits; - - if (hi32divbits == 0) - { - /* the divisor is small, we can actually keep all the bits */ - int64_t hi, rhi, lo, rlo; - int64_t div = (divint << 16) + divfrac; - - fixed_64_16_to_int128 (tmp[0][0], tmp[0][1], &hi, &lo, 32); - rlo = rounded_sdiv_128_by_49 (hi, lo, div, &rhi); - result->v[0] = fixed_112_16_to_fixed_48_16 (rhi, rlo, &clampflag); - - fixed_64_16_to_int128 (tmp[1][0], tmp[1][1], &hi, &lo, 32); - rlo = rounded_sdiv_128_by_49 (hi, lo, div, &rhi); - result->v[1] = fixed_112_16_to_fixed_48_16 (rhi, rlo, &clampflag); - } - else - { - /* the divisor needs to be reduced to 48 bits */ - int64_t hi, rhi, lo, rlo, div; - int shift = 32 - count_leading_zeros (hi32divbits); - fixed_64_16_to_int128 (divint, divfrac, &hi, &div, 16 - shift); - - fixed_64_16_to_int128 (tmp[0][0], tmp[0][1], &hi, &lo, 32 - shift); - rlo = rounded_sdiv_128_by_49 (hi, lo, div, &rhi); - result->v[0] = fixed_112_16_to_fixed_48_16 (rhi, rlo, &clampflag); - - fixed_64_16_to_int128 (tmp[1][0], tmp[1][1], &hi, &lo, 32 - shift); - rlo = rounded_sdiv_128_by_49 (hi, lo, div, &rhi); - result->v[1] = fixed_112_16_to_fixed_48_16 (rhi, rlo, &clampflag); - } - } - result->v[2] = pixman_fixed_1; - return !clampflag; -} - -PIXMAN_EXPORT void -pixman_transform_point_31_16_affine (const pixman_transform_t *t, - const pixman_vector_48_16_t *v, - pixman_vector_48_16_t *result) -{ - int64_t hi0, lo0, hi1, lo1; - - /* input vector values must have no more than 31 bits (including sign) - * in the integer part */ - assert (v->v[0] < ((pixman_fixed_48_16_t)1 << (30 + 16))); - assert (v->v[0] >= -((pixman_fixed_48_16_t)1 << (30 + 16))); - assert (v->v[1] < ((pixman_fixed_48_16_t)1 << (30 + 16))); - assert (v->v[1] >= -((pixman_fixed_48_16_t)1 << (30 + 16))); - - hi0 = (int64_t)t->matrix[0][0] * (v->v[0] >> 16); - lo0 = (int64_t)t->matrix[0][0] * (v->v[0] & 0xFFFF); - hi0 += (int64_t)t->matrix[0][1] * (v->v[1] >> 16); - lo0 += (int64_t)t->matrix[0][1] * (v->v[1] & 0xFFFF); - hi0 += (int64_t)t->matrix[0][2]; - - hi1 = (int64_t)t->matrix[1][0] * (v->v[0] >> 16); - lo1 = (int64_t)t->matrix[1][0] * (v->v[0] & 0xFFFF); - hi1 += (int64_t)t->matrix[1][1] * (v->v[1] >> 16); - lo1 += (int64_t)t->matrix[1][1] * (v->v[1] & 0xFFFF); - hi1 += (int64_t)t->matrix[1][2]; - - result->v[0] = hi0 + ((lo0 + 0x8000) >> 16); - result->v[1] = hi1 + ((lo1 + 0x8000) >> 16); - result->v[2] = pixman_fixed_1; -} - -PIXMAN_EXPORT void -pixman_transform_point_31_16_3d (const pixman_transform_t *t, - const pixman_vector_48_16_t *v, - pixman_vector_48_16_t *result) -{ - int i; - int64_t tmp[3][2]; - - /* input vector values must have no more than 31 bits (including sign) - * in the integer part */ - assert (v->v[0] < ((pixman_fixed_48_16_t)1 << (30 + 16))); - assert (v->v[0] >= -((pixman_fixed_48_16_t)1 << (30 + 16))); - assert (v->v[1] < ((pixman_fixed_48_16_t)1 << (30 + 16))); - assert (v->v[1] >= -((pixman_fixed_48_16_t)1 << (30 + 16))); - assert (v->v[2] < ((pixman_fixed_48_16_t)1 << (30 + 16))); - assert (v->v[2] >= -((pixman_fixed_48_16_t)1 << (30 + 16))); - - for (i = 0; i < 3; i++) - { - tmp[i][0] = (int64_t)t->matrix[i][0] * (v->v[0] >> 16); - tmp[i][1] = (int64_t)t->matrix[i][0] * (v->v[0] & 0xFFFF); - tmp[i][0] += (int64_t)t->matrix[i][1] * (v->v[1] >> 16); - tmp[i][1] += (int64_t)t->matrix[i][1] * (v->v[1] & 0xFFFF); - tmp[i][0] += (int64_t)t->matrix[i][2] * (v->v[2] >> 16); - tmp[i][1] += (int64_t)t->matrix[i][2] * (v->v[2] & 0xFFFF); - } - - result->v[0] = tmp[0][0] + ((tmp[0][1] + 0x8000) >> 16); - result->v[1] = tmp[1][0] + ((tmp[1][1] + 0x8000) >> 16); - result->v[2] = tmp[2][0] + ((tmp[2][1] + 0x8000) >> 16); -} - -PIXMAN_EXPORT void -pixman_transform_init_identity (struct pixman_transform *matrix) -{ - int i; - - memset (matrix, '\0', sizeof (struct pixman_transform)); - for (i = 0; i < 3; i++) - matrix->matrix[i][i] = F (1); -} - -typedef pixman_fixed_32_32_t pixman_fixed_34_30_t; - -PIXMAN_EXPORT pixman_bool_t -pixman_transform_point_3d (const struct pixman_transform *transform, - struct pixman_vector * vector) -{ - pixman_vector_48_16_t tmp; - tmp.v[0] = vector->vector[0]; - tmp.v[1] = vector->vector[1]; - tmp.v[2] = vector->vector[2]; - - pixman_transform_point_31_16_3d (transform, &tmp, &tmp); - - vector->vector[0] = tmp.v[0]; - vector->vector[1] = tmp.v[1]; - vector->vector[2] = tmp.v[2]; - - return vector->vector[0] == tmp.v[0] && - vector->vector[1] == tmp.v[1] && - vector->vector[2] == tmp.v[2]; -} - -PIXMAN_EXPORT pixman_bool_t -pixman_transform_point (const struct pixman_transform *transform, - struct pixman_vector * vector) -{ - pixman_vector_48_16_t tmp; - tmp.v[0] = vector->vector[0]; - tmp.v[1] = vector->vector[1]; - tmp.v[2] = vector->vector[2]; - - if (!pixman_transform_point_31_16 (transform, &tmp, &tmp)) - return FALSE; - - vector->vector[0] = tmp.v[0]; - vector->vector[1] = tmp.v[1]; - vector->vector[2] = tmp.v[2]; - - return vector->vector[0] == tmp.v[0] && - vector->vector[1] == tmp.v[1] && - vector->vector[2] == tmp.v[2]; -} - -PIXMAN_EXPORT pixman_bool_t -pixman_transform_multiply (struct pixman_transform * dst, - const struct pixman_transform *l, - const struct pixman_transform *r) -{ - struct pixman_transform d; - int dx, dy; - int o; - - for (dy = 0; dy < 3; dy++) - { - for (dx = 0; dx < 3; dx++) - { - pixman_fixed_48_16_t v; - pixman_fixed_32_32_t partial; - - v = 0; - for (o = 0; o < 3; o++) - { - partial = - (pixman_fixed_32_32_t) l->matrix[dy][o] * - (pixman_fixed_32_32_t) r->matrix[o][dx]; - - v += (partial + 0x8000) >> 16; - } - - if (v > pixman_max_fixed_48_16 || v < pixman_min_fixed_48_16) - return FALSE; - - d.matrix[dy][dx] = (pixman_fixed_t) v; - } - } - - *dst = d; - return TRUE; -} - -PIXMAN_EXPORT void -pixman_transform_init_scale (struct pixman_transform *t, - pixman_fixed_t sx, - pixman_fixed_t sy) -{ - memset (t, '\0', sizeof (struct pixman_transform)); - - t->matrix[0][0] = sx; - t->matrix[1][1] = sy; - t->matrix[2][2] = F (1); -} - -static pixman_fixed_t -fixed_inverse (pixman_fixed_t x) -{ - return (pixman_fixed_t) ((((pixman_fixed_48_16_t) F (1)) * F (1)) / x); -} - -PIXMAN_EXPORT pixman_bool_t -pixman_transform_scale (struct pixman_transform *forward, - struct pixman_transform *reverse, - pixman_fixed_t sx, - pixman_fixed_t sy) -{ - struct pixman_transform t; - - if (sx == 0 || sy == 0) - return FALSE; - - if (forward) - { - pixman_transform_init_scale (&t, sx, sy); - if (!pixman_transform_multiply (forward, &t, forward)) - return FALSE; - } - - if (reverse) - { - pixman_transform_init_scale (&t, fixed_inverse (sx), - fixed_inverse (sy)); - if (!pixman_transform_multiply (reverse, reverse, &t)) - return FALSE; - } - - return TRUE; -} - -PIXMAN_EXPORT void -pixman_transform_init_rotate (struct pixman_transform *t, - pixman_fixed_t c, - pixman_fixed_t s) -{ - memset (t, '\0', sizeof (struct pixman_transform)); - - t->matrix[0][0] = c; - t->matrix[0][1] = -s; - t->matrix[1][0] = s; - t->matrix[1][1] = c; - t->matrix[2][2] = F (1); -} - -PIXMAN_EXPORT pixman_bool_t -pixman_transform_rotate (struct pixman_transform *forward, - struct pixman_transform *reverse, - pixman_fixed_t c, - pixman_fixed_t s) -{ - struct pixman_transform t; - - if (forward) - { - pixman_transform_init_rotate (&t, c, s); - if (!pixman_transform_multiply (forward, &t, forward)) - return FALSE; - } - - if (reverse) - { - pixman_transform_init_rotate (&t, c, -s); - if (!pixman_transform_multiply (reverse, reverse, &t)) - return FALSE; - } - - return TRUE; -} - -PIXMAN_EXPORT void -pixman_transform_init_translate (struct pixman_transform *t, - pixman_fixed_t tx, - pixman_fixed_t ty) -{ - memset (t, '\0', sizeof (struct pixman_transform)); - - t->matrix[0][0] = F (1); - t->matrix[0][2] = tx; - t->matrix[1][1] = F (1); - t->matrix[1][2] = ty; - t->matrix[2][2] = F (1); -} - -PIXMAN_EXPORT pixman_bool_t -pixman_transform_translate (struct pixman_transform *forward, - struct pixman_transform *reverse, - pixman_fixed_t tx, - pixman_fixed_t ty) -{ - struct pixman_transform t; - - if (forward) - { - pixman_transform_init_translate (&t, tx, ty); - - if (!pixman_transform_multiply (forward, &t, forward)) - return FALSE; - } - - if (reverse) - { - pixman_transform_init_translate (&t, -tx, -ty); - - if (!pixman_transform_multiply (reverse, reverse, &t)) - return FALSE; - } - return TRUE; -} - -PIXMAN_EXPORT pixman_bool_t -pixman_transform_bounds (const struct pixman_transform *matrix, - struct pixman_box16 * b) - -{ - struct pixman_vector v[4]; - int i; - int x1, y1, x2, y2; - - v[0].vector[0] = F (b->x1); - v[0].vector[1] = F (b->y1); - v[0].vector[2] = F (1); - - v[1].vector[0] = F (b->x2); - v[1].vector[1] = F (b->y1); - v[1].vector[2] = F (1); - - v[2].vector[0] = F (b->x2); - v[2].vector[1] = F (b->y2); - v[2].vector[2] = F (1); - - v[3].vector[0] = F (b->x1); - v[3].vector[1] = F (b->y2); - v[3].vector[2] = F (1); - - for (i = 0; i < 4; i++) - { - if (!pixman_transform_point (matrix, &v[i])) - return FALSE; - - x1 = pixman_fixed_to_int (v[i].vector[0]); - y1 = pixman_fixed_to_int (v[i].vector[1]); - x2 = pixman_fixed_to_int (pixman_fixed_ceil (v[i].vector[0])); - y2 = pixman_fixed_to_int (pixman_fixed_ceil (v[i].vector[1])); - - if (i == 0) - { - b->x1 = x1; - b->y1 = y1; - b->x2 = x2; - b->y2 = y2; - } - else - { - if (x1 < b->x1) b->x1 = x1; - if (y1 < b->y1) b->y1 = y1; - if (x2 > b->x2) b->x2 = x2; - if (y2 > b->y2) b->y2 = y2; - } - } - - return TRUE; -} - -PIXMAN_EXPORT pixman_bool_t -pixman_transform_invert (struct pixman_transform * dst, - const struct pixman_transform *src) -{ - struct pixman_f_transform m; - - pixman_f_transform_from_pixman_transform (&m, src); - - if (!pixman_f_transform_invert (&m, &m)) - return FALSE; - - if (!pixman_transform_from_pixman_f_transform (dst, &m)) - return FALSE; - - return TRUE; -} - -static pixman_bool_t -within_epsilon (pixman_fixed_t a, - pixman_fixed_t b, - pixman_fixed_t epsilon) -{ - pixman_fixed_t t = a - b; - - if (t < 0) - t = -t; - - return t <= epsilon; -} - -#define EPSILON (pixman_fixed_t) (2) - -#define IS_SAME(a, b) (within_epsilon (a, b, EPSILON)) -#define IS_ZERO(a) (within_epsilon (a, 0, EPSILON)) -#define IS_ONE(a) (within_epsilon (a, F (1), EPSILON)) -#define IS_UNIT(a) \ - (within_epsilon (a, F (1), EPSILON) || \ - within_epsilon (a, F (-1), EPSILON) || \ - IS_ZERO (a)) -#define IS_INT(a) (IS_ZERO (pixman_fixed_frac (a))) - -PIXMAN_EXPORT pixman_bool_t -pixman_transform_is_identity (const struct pixman_transform *t) -{ - return (IS_SAME (t->matrix[0][0], t->matrix[1][1]) && - IS_SAME (t->matrix[0][0], t->matrix[2][2]) && - !IS_ZERO (t->matrix[0][0]) && - IS_ZERO (t->matrix[0][1]) && - IS_ZERO (t->matrix[0][2]) && - IS_ZERO (t->matrix[1][0]) && - IS_ZERO (t->matrix[1][2]) && - IS_ZERO (t->matrix[2][0]) && - IS_ZERO (t->matrix[2][1])); -} - -PIXMAN_EXPORT pixman_bool_t -pixman_transform_is_scale (const struct pixman_transform *t) -{ - return (!IS_ZERO (t->matrix[0][0]) && - IS_ZERO (t->matrix[0][1]) && - IS_ZERO (t->matrix[0][2]) && - - IS_ZERO (t->matrix[1][0]) && - !IS_ZERO (t->matrix[1][1]) && - IS_ZERO (t->matrix[1][2]) && - - IS_ZERO (t->matrix[2][0]) && - IS_ZERO (t->matrix[2][1]) && - !IS_ZERO (t->matrix[2][2])); -} - -PIXMAN_EXPORT pixman_bool_t -pixman_transform_is_int_translate (const struct pixman_transform *t) -{ - return (IS_ONE (t->matrix[0][0]) && - IS_ZERO (t->matrix[0][1]) && - IS_INT (t->matrix[0][2]) && - - IS_ZERO (t->matrix[1][0]) && - IS_ONE (t->matrix[1][1]) && - IS_INT (t->matrix[1][2]) && - - IS_ZERO (t->matrix[2][0]) && - IS_ZERO (t->matrix[2][1]) && - IS_ONE (t->matrix[2][2])); -} - -PIXMAN_EXPORT pixman_bool_t -pixman_transform_is_inverse (const struct pixman_transform *a, - const struct pixman_transform *b) -{ - struct pixman_transform t; - - if (!pixman_transform_multiply (&t, a, b)) - return FALSE; - - return pixman_transform_is_identity (&t); -} - -PIXMAN_EXPORT void -pixman_f_transform_from_pixman_transform (struct pixman_f_transform * ft, - const struct pixman_transform *t) -{ - int i, j; - - for (j = 0; j < 3; j++) - { - for (i = 0; i < 3; i++) - ft->m[j][i] = pixman_fixed_to_double (t->matrix[j][i]); - } -} - -PIXMAN_EXPORT pixman_bool_t -pixman_transform_from_pixman_f_transform (struct pixman_transform * t, - const struct pixman_f_transform *ft) -{ - int i, j; - - for (j = 0; j < 3; j++) - { - for (i = 0; i < 3; i++) - { - double d = ft->m[j][i]; - if (d < -32767.0 || d > 32767.0) - return FALSE; - d = d * 65536.0 + 0.5; - t->matrix[j][i] = (pixman_fixed_t) floor (d); - } - } - - return TRUE; -} - -PIXMAN_EXPORT pixman_bool_t -pixman_f_transform_invert (struct pixman_f_transform * dst, - const struct pixman_f_transform *src) -{ - static const int a[3] = { 2, 2, 1 }; - static const int b[3] = { 1, 0, 0 }; - pixman_f_transform_t d; - double det; - int i, j; - - det = 0; - for (i = 0; i < 3; i++) - { - double p; - int ai = a[i]; - int bi = b[i]; - p = src->m[i][0] * (src->m[ai][2] * src->m[bi][1] - - src->m[ai][1] * src->m[bi][2]); - if (i == 1) - p = -p; - det += p; - } - - if (det == 0) - return FALSE; - - det = 1 / det; - for (j = 0; j < 3; j++) - { - for (i = 0; i < 3; i++) - { - double p; - int ai = a[i]; - int aj = a[j]; - int bi = b[i]; - int bj = b[j]; - - p = (src->m[ai][aj] * src->m[bi][bj] - - src->m[ai][bj] * src->m[bi][aj]); - - if (((i + j) & 1) != 0) - p = -p; - - d.m[j][i] = det * p; - } - } - - *dst = d; - - return TRUE; -} - -PIXMAN_EXPORT pixman_bool_t -pixman_f_transform_point (const struct pixman_f_transform *t, - struct pixman_f_vector * v) -{ - struct pixman_f_vector result; - int i, j; - double a; - - for (j = 0; j < 3; j++) - { - a = 0; - for (i = 0; i < 3; i++) - a += t->m[j][i] * v->v[i]; - result.v[j] = a; - } - - if (!result.v[2]) - return FALSE; - - for (j = 0; j < 2; j++) - v->v[j] = result.v[j] / result.v[2]; - - v->v[2] = 1; - - return TRUE; -} - -PIXMAN_EXPORT void -pixman_f_transform_point_3d (const struct pixman_f_transform *t, - struct pixman_f_vector * v) -{ - struct pixman_f_vector result; - int i, j; - double a; - - for (j = 0; j < 3; j++) - { - a = 0; - for (i = 0; i < 3; i++) - a += t->m[j][i] * v->v[i]; - result.v[j] = a; - } - - *v = result; -} - -PIXMAN_EXPORT void -pixman_f_transform_multiply (struct pixman_f_transform * dst, - const struct pixman_f_transform *l, - const struct pixman_f_transform *r) -{ - struct pixman_f_transform d; - int dx, dy; - int o; - - for (dy = 0; dy < 3; dy++) - { - for (dx = 0; dx < 3; dx++) - { - double v = 0; - for (o = 0; o < 3; o++) - v += l->m[dy][o] * r->m[o][dx]; - d.m[dy][dx] = v; - } - } - - *dst = d; -} - -PIXMAN_EXPORT void -pixman_f_transform_init_scale (struct pixman_f_transform *t, - double sx, - double sy) -{ - t->m[0][0] = sx; - t->m[0][1] = 0; - t->m[0][2] = 0; - t->m[1][0] = 0; - t->m[1][1] = sy; - t->m[1][2] = 0; - t->m[2][0] = 0; - t->m[2][1] = 0; - t->m[2][2] = 1; -} - -PIXMAN_EXPORT pixman_bool_t -pixman_f_transform_scale (struct pixman_f_transform *forward, - struct pixman_f_transform *reverse, - double sx, - double sy) -{ - struct pixman_f_transform t; - - if (sx == 0 || sy == 0) - return FALSE; - - if (forward) - { - pixman_f_transform_init_scale (&t, sx, sy); - pixman_f_transform_multiply (forward, &t, forward); - } - - if (reverse) - { - pixman_f_transform_init_scale (&t, 1 / sx, 1 / sy); - pixman_f_transform_multiply (reverse, reverse, &t); - } - - return TRUE; -} - -PIXMAN_EXPORT void -pixman_f_transform_init_rotate (struct pixman_f_transform *t, - double c, - double s) -{ - t->m[0][0] = c; - t->m[0][1] = -s; - t->m[0][2] = 0; - t->m[1][0] = s; - t->m[1][1] = c; - t->m[1][2] = 0; - t->m[2][0] = 0; - t->m[2][1] = 0; - t->m[2][2] = 1; -} - -PIXMAN_EXPORT pixman_bool_t -pixman_f_transform_rotate (struct pixman_f_transform *forward, - struct pixman_f_transform *reverse, - double c, - double s) -{ - struct pixman_f_transform t; - - if (forward) - { - pixman_f_transform_init_rotate (&t, c, s); - pixman_f_transform_multiply (forward, &t, forward); - } - - if (reverse) - { - pixman_f_transform_init_rotate (&t, c, -s); - pixman_f_transform_multiply (reverse, reverse, &t); - } - - return TRUE; -} - -PIXMAN_EXPORT void -pixman_f_transform_init_translate (struct pixman_f_transform *t, - double tx, - double ty) -{ - t->m[0][0] = 1; - t->m[0][1] = 0; - t->m[0][2] = tx; - t->m[1][0] = 0; - t->m[1][1] = 1; - t->m[1][2] = ty; - t->m[2][0] = 0; - t->m[2][1] = 0; - t->m[2][2] = 1; -} - -PIXMAN_EXPORT pixman_bool_t -pixman_f_transform_translate (struct pixman_f_transform *forward, - struct pixman_f_transform *reverse, - double tx, - double ty) -{ - struct pixman_f_transform t; - - if (forward) - { - pixman_f_transform_init_translate (&t, tx, ty); - pixman_f_transform_multiply (forward, &t, forward); - } - - if (reverse) - { - pixman_f_transform_init_translate (&t, -tx, -ty); - pixman_f_transform_multiply (reverse, reverse, &t); - } - - return TRUE; -} - -PIXMAN_EXPORT pixman_bool_t -pixman_f_transform_bounds (const struct pixman_f_transform *t, - struct pixman_box16 * b) -{ - struct pixman_f_vector v[4]; - int i; - int x1, y1, x2, y2; - - v[0].v[0] = b->x1; - v[0].v[1] = b->y1; - v[0].v[2] = 1; - v[1].v[0] = b->x2; - v[1].v[1] = b->y1; - v[1].v[2] = 1; - v[2].v[0] = b->x2; - v[2].v[1] = b->y2; - v[2].v[2] = 1; - v[3].v[0] = b->x1; - v[3].v[1] = b->y2; - v[3].v[2] = 1; - - for (i = 0; i < 4; i++) - { - if (!pixman_f_transform_point (t, &v[i])) - return FALSE; - - x1 = floor (v[i].v[0]); - y1 = floor (v[i].v[1]); - x2 = ceil (v[i].v[0]); - y2 = ceil (v[i].v[1]); - - if (i == 0) - { - b->x1 = x1; - b->y1 = y1; - b->x2 = x2; - b->y2 = y2; - } - else - { - if (x1 < b->x1) b->x1 = x1; - if (y1 < b->y1) b->y1 = y1; - if (x2 > b->x2) b->x2 = x2; - if (y2 > b->y2) b->y2 = y2; - } - } - - return TRUE; -} - -PIXMAN_EXPORT void -pixman_f_transform_init_identity (struct pixman_f_transform *t) -{ - int i, j; - - for (j = 0; j < 3; j++) - { - for (i = 0; i < 3; i++) - t->m[j][i] = i == j ? 1 : 0; - } -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman-mips-dspr2-asm.S b/source/libs/pixman/pixman-src/pixman/pixman-mips-dspr2-asm.S deleted file mode 100644 index 9dad163b792e9fc690a385d4650551aff4be9e7c..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-mips-dspr2-asm.S +++ /dev/null @@ -1,4283 +0,0 @@ -/* - * Copyright (c) 2012 - * MIPS Technologies, Inc., California. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Author: Nemanja Lukic (nemanja.lukic@rt-rk.com) - */ - -#include "pixman-private.h" -#include "pixman-mips-dspr2-asm.h" - -LEAF_MIPS_DSPR2(pixman_fill_buff16_mips) -/* - * a0 - *dest - * a1 - count (bytes) - * a2 - value to fill buffer with - */ - - beqz a1, 3f - andi t1, a0, 0x0002 - beqz t1, 0f /* check if address is 4-byte aligned */ - nop - sh a2, 0(a0) - addiu a0, a0, 2 - addiu a1, a1, -2 -0: - srl t1, a1, 5 /* t1 how many multiples of 32 bytes */ - replv.ph a2, a2 /* replicate fill value (16bit) in a2 */ - beqz t1, 2f - nop -1: - addiu t1, t1, -1 - beqz t1, 11f - addiu a1, a1, -32 - pref 30, 32(a0) - sw a2, 0(a0) - sw a2, 4(a0) - sw a2, 8(a0) - sw a2, 12(a0) - sw a2, 16(a0) - sw a2, 20(a0) - sw a2, 24(a0) - sw a2, 28(a0) - b 1b - addiu a0, a0, 32 -11: - sw a2, 0(a0) - sw a2, 4(a0) - sw a2, 8(a0) - sw a2, 12(a0) - sw a2, 16(a0) - sw a2, 20(a0) - sw a2, 24(a0) - sw a2, 28(a0) - addiu a0, a0, 32 -2: - blez a1, 3f - addiu a1, a1, -2 - sh a2, 0(a0) - b 2b - addiu a0, a0, 2 -3: - jr ra - nop - -END(pixman_fill_buff16_mips) - -LEAF_MIPS32R2(pixman_fill_buff32_mips) -/* - * a0 - *dest - * a1 - count (bytes) - * a2 - value to fill buffer with - */ - - beqz a1, 3f - nop - srl t1, a1, 5 /* t1 how many multiples of 32 bytes */ - beqz t1, 2f - nop -1: - addiu t1, t1, -1 - beqz t1, 11f - addiu a1, a1, -32 - pref 30, 32(a0) - sw a2, 0(a0) - sw a2, 4(a0) - sw a2, 8(a0) - sw a2, 12(a0) - sw a2, 16(a0) - sw a2, 20(a0) - sw a2, 24(a0) - sw a2, 28(a0) - b 1b - addiu a0, a0, 32 -11: - sw a2, 0(a0) - sw a2, 4(a0) - sw a2, 8(a0) - sw a2, 12(a0) - sw a2, 16(a0) - sw a2, 20(a0) - sw a2, 24(a0) - sw a2, 28(a0) - addiu a0, a0, 32 -2: - blez a1, 3f - addiu a1, a1, -4 - sw a2, 0(a0) - b 2b - addiu a0, a0, 4 -3: - jr ra - nop - -END(pixman_fill_buff32_mips) - -LEAF_MIPS_DSPR2(pixman_composite_src_8888_0565_asm_mips) -/* - * a0 - dst (r5g6b5) - * a1 - src (a8r8g8b8) - * a2 - w - */ - - beqz a2, 3f - nop - addiu t1, a2, -1 - beqz t1, 2f - nop - li t4, 0xf800f800 - li t5, 0x07e007e0 - li t6, 0x001f001f -1: - lw t0, 0(a1) - lw t1, 4(a1) - addiu a1, a1, 8 - addiu a2, a2, -2 - - CONVERT_2x8888_TO_2x0565 t0, t1, t2, t3, t4, t5, t6, t7, t8 - - sh t2, 0(a0) - sh t3, 2(a0) - - addiu t2, a2, -1 - bgtz t2, 1b - addiu a0, a0, 4 -2: - beqz a2, 3f - nop - lw t0, 0(a1) - - CONVERT_1x8888_TO_1x0565 t0, t1, t2, t3 - - sh t1, 0(a0) -3: - j ra - nop - -END(pixman_composite_src_8888_0565_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_src_0565_8888_asm_mips) -/* - * a0 - dst (a8r8g8b8) - * a1 - src (r5g6b5) - * a2 - w - */ - - beqz a2, 3f - nop - addiu t1, a2, -1 - beqz t1, 2f - nop - li t4, 0x07e007e0 - li t5, 0x001F001F -1: - lhu t0, 0(a1) - lhu t1, 2(a1) - addiu a1, a1, 4 - addiu a2, a2, -2 - - CONVERT_2x0565_TO_2x8888 t0, t1, t2, t3, t4, t5, t6, t7, t8, t9 - - sw t2, 0(a0) - sw t3, 4(a0) - - addiu t2, a2, -1 - bgtz t2, 1b - addiu a0, a0, 8 -2: - beqz a2, 3f - nop - lhu t0, 0(a1) - - CONVERT_1x0565_TO_1x8888 t0, t1, t2, t3 - - sw t1, 0(a0) -3: - j ra - nop - -END(pixman_composite_src_0565_8888_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_src_x888_8888_asm_mips) -/* - * a0 - dst (a8r8g8b8) - * a1 - src (x8r8g8b8) - * a2 - w - */ - - beqz a2, 4f - nop - li t9, 0xff000000 - srl t8, a2, 3 /* t1 = how many multiples of 8 src pixels */ - beqz t8, 3f /* branch if less than 8 src pixels */ - nop -1: - addiu t8, t8, -1 - beqz t8, 2f - addiu a2, a2, -8 - pref 0, 32(a1) - lw t0, 0(a1) - lw t1, 4(a1) - lw t2, 8(a1) - lw t3, 12(a1) - lw t4, 16(a1) - lw t5, 20(a1) - lw t6, 24(a1) - lw t7, 28(a1) - addiu a1, a1, 32 - or t0, t0, t9 - or t1, t1, t9 - or t2, t2, t9 - or t3, t3, t9 - or t4, t4, t9 - or t5, t5, t9 - or t6, t6, t9 - or t7, t7, t9 - pref 30, 32(a0) - sw t0, 0(a0) - sw t1, 4(a0) - sw t2, 8(a0) - sw t3, 12(a0) - sw t4, 16(a0) - sw t5, 20(a0) - sw t6, 24(a0) - sw t7, 28(a0) - b 1b - addiu a0, a0, 32 -2: - lw t0, 0(a1) - lw t1, 4(a1) - lw t2, 8(a1) - lw t3, 12(a1) - lw t4, 16(a1) - lw t5, 20(a1) - lw t6, 24(a1) - lw t7, 28(a1) - addiu a1, a1, 32 - or t0, t0, t9 - or t1, t1, t9 - or t2, t2, t9 - or t3, t3, t9 - or t4, t4, t9 - or t5, t5, t9 - or t6, t6, t9 - or t7, t7, t9 - sw t0, 0(a0) - sw t1, 4(a0) - sw t2, 8(a0) - sw t3, 12(a0) - sw t4, 16(a0) - sw t5, 20(a0) - sw t6, 24(a0) - sw t7, 28(a0) - beqz a2, 4f - addiu a0, a0, 32 -3: - lw t0, 0(a1) - addiu a1, a1, 4 - addiu a2, a2, -1 - or t1, t0, t9 - sw t1, 0(a0) - bnez a2, 3b - addiu a0, a0, 4 -4: - jr ra - nop - -END(pixman_composite_src_x888_8888_asm_mips) - -#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) -LEAF_MIPS_DSPR2(pixman_composite_src_0888_8888_rev_asm_mips) -/* - * a0 - dst (a8r8g8b8) - * a1 - src (b8g8r8) - * a2 - w - */ - - beqz a2, 6f - nop - - lui t8, 0xff00; - srl t9, a2, 2 /* t9 = how many multiples of 4 src pixels */ - beqz t9, 4f /* branch if less than 4 src pixels */ - nop - - li t0, 0x1 - li t1, 0x2 - li t2, 0x3 - andi t3, a1, 0x3 - beq t3, t0, 1f - nop - beq t3, t1, 2f - nop - beq t3, t2, 3f - nop - -0: - beqz t9, 4f - addiu t9, t9, -1 - lw t0, 0(a1) /* t0 = R2 | B1 | G1 | R1 */ - lw t1, 4(a1) /* t1 = G3 | R3 | B2 | G2 */ - lw t2, 8(a1) /* t2 = B4 | G4 | R4 | B3 */ - - addiu a1, a1, 12 - addiu a2, a2, -4 - - wsbh t0, t0 /* t0 = B1 | R2 | R1 | G1 */ - wsbh t1, t1 /* t1 = R3 | G3 | G2 | B2 */ - wsbh t2, t2 /* t2 = G4 | B4 | B3 | R4 */ - - packrl.ph t3, t1, t0 /* t3 = G2 | B2 | B1 | R2 */ - packrl.ph t4, t0, t0 /* t4 = R1 | G1 | B1 | R2 */ - rotr t3, t3, 16 /* t3 = B1 | R2 | G2 | B2 */ - or t3, t3, t8 /* t3 = FF | R2 | G2 | B2 */ - srl t4, t4, 8 /* t4 = 0 | R1 | G1 | B1 */ - or t4, t4, t8 /* t4 = FF | R1 | G1 | B1 */ - packrl.ph t5, t2, t1 /* t5 = B3 | R4 | R3 | G3 */ - rotr t5, t5, 24 /* t5 = R4 | R3 | G3 | B3 */ - or t5, t5, t8 /* t5 = FF | R3 | G3 | B3 */ - rotr t2, t2, 16 /* t2 = B3 | R4 | G4 | B4 */ - or t2, t2, t8 /* t5 = FF | R3 | G3 | B3 */ - - sw t4, 0(a0) - sw t3, 4(a0) - sw t5, 8(a0) - sw t2, 12(a0) - b 0b - addiu a0, a0, 16 - -1: - lbu t6, 0(a1) /* t6 = 0 | 0 | 0 | R1 */ - lhu t7, 1(a1) /* t7 = 0 | 0 | B1 | G1 */ - sll t6, t6, 16 /* t6 = 0 | R1 | 0 | 0 */ - wsbh t7, t7 /* t7 = 0 | 0 | G1 | B1 */ - or t7, t6, t7 /* t7 = 0 | R1 | G1 | B1 */ -11: - beqz t9, 4f - addiu t9, t9, -1 - lw t0, 3(a1) /* t0 = R3 | B2 | G2 | R2 */ - lw t1, 7(a1) /* t1 = G4 | R4 | B3 | G3 */ - lw t2, 11(a1) /* t2 = B5 | G5 | R5 | B4 */ - - addiu a1, a1, 12 - addiu a2, a2, -4 - - wsbh t0, t0 /* t0 = B2 | R3 | R2 | G2 */ - wsbh t1, t1 /* t1 = R4 | G4 | G3 | B3 */ - wsbh t2, t2 /* t2 = G5 | B5 | B4 | R5 */ - - packrl.ph t3, t1, t0 /* t3 = G3 | B3 | B2 | R3 */ - packrl.ph t4, t2, t1 /* t4 = B4 | R5 | R4 | G4 */ - rotr t0, t0, 24 /* t0 = R3 | R2 | G2 | B2 */ - rotr t3, t3, 16 /* t3 = B2 | R3 | G3 | B3 */ - rotr t4, t4, 24 /* t4 = R5 | R4 | G4 | B4 */ - or t7, t7, t8 /* t7 = FF | R1 | G1 | B1 */ - or t0, t0, t8 /* t0 = FF | R2 | G2 | B2 */ - or t3, t3, t8 /* t1 = FF | R3 | G3 | B3 */ - or t4, t4, t8 /* t3 = FF | R4 | G4 | B4 */ - - sw t7, 0(a0) - sw t0, 4(a0) - sw t3, 8(a0) - sw t4, 12(a0) - rotr t7, t2, 16 /* t7 = xx | R5 | G5 | B5 */ - b 11b - addiu a0, a0, 16 - -2: - lhu t7, 0(a1) /* t7 = 0 | 0 | G1 | R1 */ - wsbh t7, t7 /* t7 = 0 | 0 | R1 | G1 */ -21: - beqz t9, 4f - addiu t9, t9, -1 - lw t0, 2(a1) /* t0 = B2 | G2 | R2 | B1 */ - lw t1, 6(a1) /* t1 = R4 | B3 | G3 | R3 */ - lw t2, 10(a1) /* t2 = G5 | R5 | B4 | G4 */ - - addiu a1, a1, 12 - addiu a2, a2, -4 - - wsbh t0, t0 /* t0 = G2 | B2 | B1 | R2 */ - wsbh t1, t1 /* t1 = B3 | R4 | R3 | G3 */ - wsbh t2, t2 /* t2 = R5 | G5 | G4 | B4 */ - - precr_sra.ph.w t7, t0, 0 /* t7 = R1 | G1 | B1 | R2 */ - rotr t0, t0, 16 /* t0 = B1 | R2 | G2 | B2 */ - packrl.ph t3, t2, t1 /* t3 = G4 | B4 | B3 | R4 */ - rotr t1, t1, 24 /* t1 = R4 | R3 | G3 | B3 */ - srl t7, t7, 8 /* t7 = 0 | R1 | G1 | B1 */ - rotr t3, t3, 16 /* t3 = B3 | R4 | G4 | B4 */ - or t7, t7, t8 /* t7 = FF | R1 | G1 | B1 */ - or t0, t0, t8 /* t0 = FF | R2 | G2 | B2 */ - or t1, t1, t8 /* t1 = FF | R3 | G3 | B3 */ - or t3, t3, t8 /* t3 = FF | R4 | G4 | B4 */ - - sw t7, 0(a0) - sw t0, 4(a0) - sw t1, 8(a0) - sw t3, 12(a0) - srl t7, t2, 16 /* t7 = 0 | 0 | R5 | G5 */ - b 21b - addiu a0, a0, 16 - -3: - lbu t7, 0(a1) /* t7 = 0 | 0 | 0 | R1 */ -31: - beqz t9, 4f - addiu t9, t9, -1 - lw t0, 1(a1) /* t0 = G2 | R2 | B1 | G1 */ - lw t1, 5(a1) /* t1 = B3 | G3 | R3 | B2 */ - lw t2, 9(a1) /* t2 = R5 | B4 | G4 | R4 */ - - addiu a1, a1, 12 - addiu a2, a2, -4 - - wsbh t0, t0 /* t0 = R2 | G2 | G1 | B1 */ - wsbh t1, t1 /* t1 = G3 | B3 | B2 | R3 */ - wsbh t2, t2 /* t2 = B4 | R5 | R4 | G4 */ - - precr_sra.ph.w t7, t0, 0 /* t7 = xx | R1 | G1 | B1 */ - packrl.ph t3, t1, t0 /* t3 = B2 | R3 | R2 | G2 */ - rotr t1, t1, 16 /* t1 = B2 | R3 | G3 | B3 */ - rotr t4, t2, 24 /* t4 = R5 | R4 | G4 | B4 */ - rotr t3, t3, 24 /* t3 = R3 | R2 | G2 | B2 */ - or t7, t7, t8 /* t7 = FF | R1 | G1 | B1 */ - or t3, t3, t8 /* t3 = FF | R2 | G2 | B2 */ - or t1, t1, t8 /* t1 = FF | R3 | G3 | B3 */ - or t4, t4, t8 /* t4 = FF | R4 | G4 | B4 */ - - sw t7, 0(a0) - sw t3, 4(a0) - sw t1, 8(a0) - sw t4, 12(a0) - srl t7, t2, 16 /* t7 = 0 | 0 | xx | R5 */ - b 31b - addiu a0, a0, 16 - -4: - beqz a2, 6f - nop -5: - lbu t0, 0(a1) /* t0 = 0 | 0 | 0 | R */ - lbu t1, 1(a1) /* t1 = 0 | 0 | 0 | G */ - lbu t2, 2(a1) /* t2 = 0 | 0 | 0 | B */ - addiu a1, a1, 3 - - sll t0, t0, 16 /* t2 = 0 | R | 0 | 0 */ - sll t1, t1, 8 /* t1 = 0 | 0 | G | 0 */ - - or t2, t2, t1 /* t2 = 0 | 0 | G | B */ - or t2, t2, t0 /* t2 = 0 | R | G | B */ - or t2, t2, t8 /* t2 = FF | R | G | B */ - - sw t2, 0(a0) - addiu a2, a2, -1 - bnez a2, 5b - addiu a0, a0, 4 -6: - j ra - nop - -END(pixman_composite_src_0888_8888_rev_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_src_0888_0565_rev_asm_mips) -/* - * a0 - dst (r5g6b5) - * a1 - src (b8g8r8) - * a2 - w - */ - - SAVE_REGS_ON_STACK 0, v0, v1 - beqz a2, 6f - nop - - li t6, 0xf800f800 - li t7, 0x07e007e0 - li t8, 0x001F001F - srl t9, a2, 2 /* t9 = how many multiples of 4 src pixels */ - beqz t9, 4f /* branch if less than 4 src pixels */ - nop - - li t0, 0x1 - li t1, 0x2 - li t2, 0x3 - andi t3, a1, 0x3 - beq t3, t0, 1f - nop - beq t3, t1, 2f - nop - beq t3, t2, 3f - nop - -0: - beqz t9, 4f - addiu t9, t9, -1 - lw t0, 0(a1) /* t0 = R2 | B1 | G1 | R1 */ - lw t1, 4(a1) /* t1 = G3 | R3 | B2 | G2 */ - lw t2, 8(a1) /* t2 = B4 | G4 | R4 | B3 */ - - addiu a1, a1, 12 - addiu a2, a2, -4 - - wsbh t0, t0 /* t0 = B1 | R2 | R1 | G1 */ - wsbh t1, t1 /* t1 = R3 | G3 | G2 | B2 */ - wsbh t2, t2 /* t2 = G4 | B4 | B3 | R4 */ - - packrl.ph t3, t1, t0 /* t3 = G2 | B2 | B1 | R2 */ - packrl.ph t4, t0, t0 /* t4 = R1 | G1 | B1 | R2 */ - rotr t3, t3, 16 /* t3 = B1 | R2 | G2 | B2 */ - srl t4, t4, 8 /* t4 = 0 | R1 | G1 | B1 */ - packrl.ph t5, t2, t1 /* t5 = B3 | R4 | R3 | G3 */ - rotr t5, t5, 24 /* t5 = R4 | R3 | G3 | B3 */ - rotr t2, t2, 16 /* t2 = B3 | R4 | G4 | B4 */ - - CONVERT_2x8888_TO_2x0565 t4, t3, t4, t3, t6, t7, t8, v0, v1 - CONVERT_2x8888_TO_2x0565 t5, t2, t5, t2, t6, t7, t8, v0, v1 - - sh t4, 0(a0) - sh t3, 2(a0) - sh t5, 4(a0) - sh t2, 6(a0) - b 0b - addiu a0, a0, 8 - -1: - lbu t4, 0(a1) /* t4 = 0 | 0 | 0 | R1 */ - lhu t5, 1(a1) /* t5 = 0 | 0 | B1 | G1 */ - sll t4, t4, 16 /* t4 = 0 | R1 | 0 | 0 */ - wsbh t5, t5 /* t5 = 0 | 0 | G1 | B1 */ - or t5, t4, t5 /* t5 = 0 | R1 | G1 | B1 */ -11: - beqz t9, 4f - addiu t9, t9, -1 - lw t0, 3(a1) /* t0 = R3 | B2 | G2 | R2 */ - lw t1, 7(a1) /* t1 = G4 | R4 | B3 | G3 */ - lw t2, 11(a1) /* t2 = B5 | G5 | R5 | B4 */ - - addiu a1, a1, 12 - addiu a2, a2, -4 - - wsbh t0, t0 /* t0 = B2 | R3 | R2 | G2 */ - wsbh t1, t1 /* t1 = R4 | G4 | G3 | B3 */ - wsbh t2, t2 /* t2 = G5 | B5 | B4 | R5 */ - - packrl.ph t3, t1, t0 /* t3 = G3 | B3 | B2 | R3 */ - packrl.ph t4, t2, t1 /* t4 = B4 | R5 | R4 | G4 */ - rotr t0, t0, 24 /* t0 = R3 | R2 | G2 | B2 */ - rotr t3, t3, 16 /* t3 = B2 | R3 | G3 | B3 */ - rotr t4, t4, 24 /* t4 = R5 | R4 | G4 | B4 */ - - CONVERT_2x8888_TO_2x0565 t5, t0, t5, t0, t6, t7, t8, v0, v1 - CONVERT_2x8888_TO_2x0565 t3, t4, t3, t4, t6, t7, t8, v0, v1 - - sh t5, 0(a0) - sh t0, 2(a0) - sh t3, 4(a0) - sh t4, 6(a0) - rotr t5, t2, 16 /* t5 = xx | R5 | G5 | B5 */ - b 11b - addiu a0, a0, 8 - -2: - lhu t5, 0(a1) /* t5 = 0 | 0 | G1 | R1 */ - wsbh t5, t5 /* t5 = 0 | 0 | R1 | G1 */ -21: - beqz t9, 4f - addiu t9, t9, -1 - lw t0, 2(a1) /* t0 = B2 | G2 | R2 | B1 */ - lw t1, 6(a1) /* t1 = R4 | B3 | G3 | R3 */ - lw t2, 10(a1) /* t2 = G5 | R5 | B4 | G4 */ - - addiu a1, a1, 12 - addiu a2, a2, -4 - - wsbh t0, t0 /* t0 = G2 | B2 | B1 | R2 */ - wsbh t1, t1 /* t1 = B3 | R4 | R3 | G3 */ - wsbh t2, t2 /* t2 = R5 | G5 | G4 | B4 */ - - precr_sra.ph.w t5, t0, 0 /* t5 = R1 | G1 | B1 | R2 */ - rotr t0, t0, 16 /* t0 = B1 | R2 | G2 | B2 */ - packrl.ph t3, t2, t1 /* t3 = G4 | B4 | B3 | R4 */ - rotr t1, t1, 24 /* t1 = R4 | R3 | G3 | B3 */ - srl t5, t5, 8 /* t5 = 0 | R1 | G1 | B1 */ - rotr t3, t3, 16 /* t3 = B3 | R4 | G4 | B4 */ - - CONVERT_2x8888_TO_2x0565 t5, t0, t5, t0, t6, t7, t8, v0, v1 - CONVERT_2x8888_TO_2x0565 t1, t3, t1, t3, t6, t7, t8, v0, v1 - - sh t5, 0(a0) - sh t0, 2(a0) - sh t1, 4(a0) - sh t3, 6(a0) - srl t5, t2, 16 /* t5 = 0 | 0 | R5 | G5 */ - b 21b - addiu a0, a0, 8 - -3: - lbu t5, 0(a1) /* t5 = 0 | 0 | 0 | R1 */ -31: - beqz t9, 4f - addiu t9, t9, -1 - lw t0, 1(a1) /* t0 = G2 | R2 | B1 | G1 */ - lw t1, 5(a1) /* t1 = B3 | G3 | R3 | B2 */ - lw t2, 9(a1) /* t2 = R5 | B4 | G4 | R4 */ - - addiu a1, a1, 12 - addiu a2, a2, -4 - - wsbh t0, t0 /* t0 = R2 | G2 | G1 | B1 */ - wsbh t1, t1 /* t1 = G3 | B3 | B2 | R3 */ - wsbh t2, t2 /* t2 = B4 | R5 | R4 | G4 */ - - precr_sra.ph.w t5, t0, 0 /* t5 = xx | R1 | G1 | B1 */ - packrl.ph t3, t1, t0 /* t3 = B2 | R3 | R2 | G2 */ - rotr t1, t1, 16 /* t1 = B2 | R3 | G3 | B3 */ - rotr t4, t2, 24 /* t4 = R5 | R4 | G4 | B4 */ - rotr t3, t3, 24 /* t3 = R3 | R2 | G2 | B2 */ - - CONVERT_2x8888_TO_2x0565 t5, t3, t5, t3, t6, t7, t8, v0, v1 - CONVERT_2x8888_TO_2x0565 t1, t4, t1, t4, t6, t7, t8, v0, v1 - - sh t5, 0(a0) - sh t3, 2(a0) - sh t1, 4(a0) - sh t4, 6(a0) - srl t5, t2, 16 /* t5 = 0 | 0 | xx | R5 */ - b 31b - addiu a0, a0, 8 - -4: - beqz a2, 6f - nop -5: - lbu t0, 0(a1) /* t0 = 0 | 0 | 0 | R */ - lbu t1, 1(a1) /* t1 = 0 | 0 | 0 | G */ - lbu t2, 2(a1) /* t2 = 0 | 0 | 0 | B */ - addiu a1, a1, 3 - - sll t0, t0, 16 /* t2 = 0 | R | 0 | 0 */ - sll t1, t1, 8 /* t1 = 0 | 0 | G | 0 */ - - or t2, t2, t1 /* t2 = 0 | 0 | G | B */ - or t2, t2, t0 /* t2 = 0 | R | G | B */ - - CONVERT_1x8888_TO_1x0565 t2, t3, t4, t5 - - sh t3, 0(a0) - addiu a2, a2, -1 - bnez a2, 5b - addiu a0, a0, 2 -6: - RESTORE_REGS_FROM_STACK 0, v0, v1 - j ra - nop - -END(pixman_composite_src_0888_0565_rev_asm_mips) -#endif - -LEAF_MIPS_DSPR2(pixman_composite_src_pixbuf_8888_asm_mips) -/* - * a0 - dst (a8b8g8r8) - * a1 - src (a8r8g8b8) - * a2 - w - */ - - SAVE_REGS_ON_STACK 0, v0 - li v0, 0x00ff00ff - - beqz a2, 3f - nop - addiu t1, a2, -1 - beqz t1, 2f - nop -1: - lw t0, 0(a1) - lw t1, 4(a1) - addiu a1, a1, 8 - addiu a2, a2, -2 - srl t2, t0, 24 - srl t3, t1, 24 - - MIPS_2xUN8x4_MUL_2xUN8 t0, t1, t2, t3, t0, t1, v0, t4, t5, t6, t7, t8, t9 - - sll t0, t0, 8 - sll t1, t1, 8 - andi t2, t2, 0xff - andi t3, t3, 0xff - or t0, t0, t2 - or t1, t1, t3 - wsbh t0, t0 - wsbh t1, t1 - rotr t0, t0, 16 - rotr t1, t1, 16 - sw t0, 0(a0) - sw t1, 4(a0) - - addiu t2, a2, -1 - bgtz t2, 1b - addiu a0, a0, 8 -2: - beqz a2, 3f - nop - lw t0, 0(a1) - srl t1, t0, 24 - - MIPS_UN8x4_MUL_UN8 t0, t1, t0, v0, t3, t4, t5 - - sll t0, t0, 8 - andi t1, t1, 0xff - or t0, t0, t1 - wsbh t0, t0 - rotr t0, t0, 16 - sw t0, 0(a0) -3: - RESTORE_REGS_FROM_STACK 0, v0 - j ra - nop - -END(pixman_composite_src_pixbuf_8888_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_src_rpixbuf_8888_asm_mips) -/* - * a0 - dst (a8r8g8b8) - * a1 - src (a8r8g8b8) - * a2 - w - */ - - SAVE_REGS_ON_STACK 0, v0 - li v0, 0x00ff00ff - - beqz a2, 3f - nop - addiu t1, a2, -1 - beqz t1, 2f - nop -1: - lw t0, 0(a1) - lw t1, 4(a1) - addiu a1, a1, 8 - addiu a2, a2, -2 - srl t2, t0, 24 - srl t3, t1, 24 - - MIPS_2xUN8x4_MUL_2xUN8 t0, t1, t2, t3, t0, t1, v0, t4, t5, t6, t7, t8, t9 - - sll t0, t0, 8 - sll t1, t1, 8 - andi t2, t2, 0xff - andi t3, t3, 0xff - or t0, t0, t2 - or t1, t1, t3 - rotr t0, t0, 8 - rotr t1, t1, 8 - sw t0, 0(a0) - sw t1, 4(a0) - - addiu t2, a2, -1 - bgtz t2, 1b - addiu a0, a0, 8 -2: - beqz a2, 3f - nop - lw t0, 0(a1) - srl t1, t0, 24 - - MIPS_UN8x4_MUL_UN8 t0, t1, t0, v0, t3, t4, t5 - - sll t0, t0, 8 - andi t1, t1, 0xff - or t0, t0, t1 - rotr t0, t0, 8 - sw t0, 0(a0) -3: - RESTORE_REGS_FROM_STACK 0, v0 - j ra - nop - -END(pixman_composite_src_rpixbuf_8888_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_src_n_8_8888_asm_mips) -/* - * a0 - dst (a8r8g8b8) - * a1 - src (32bit constant) - * a2 - mask (a8) - * a3 - w - */ - - - SAVE_REGS_ON_STACK 0, v0 - li v0, 0x00ff00ff - - beqz a3, 3f - nop - addiu t1, a3, -1 - beqz t1, 2f - nop - -1: - /* a1 = source (32bit constant) */ - lbu t0, 0(a2) /* t2 = mask (a8) */ - lbu t1, 1(a2) /* t3 = mask (a8) */ - addiu a2, a2, 2 - - MIPS_2xUN8x4_MUL_2xUN8 a1, a1, t0, t1, t2, t3, v0, t4, t5, t6, t7, t8, t9 - - sw t2, 0(a0) - sw t3, 4(a0) - addiu a3, a3, -2 - addiu t2, a3, -1 - bgtz t2, 1b - addiu a0, a0, 8 - - beqz a3, 3f - nop - -2: - lbu t0, 0(a2) - addiu a2, a2, 1 - - MIPS_UN8x4_MUL_UN8 a1, t0, t1, v0, t3, t4, t5 - - sw t1, 0(a0) - addiu a3, a3, -1 - addiu a0, a0, 4 - -3: - RESTORE_REGS_FROM_STACK 0, v0 - j ra - nop - -END(pixman_composite_src_n_8_8888_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_src_n_8_8_asm_mips) -/* - * a0 - dst (a8) - * a1 - src (32bit constant) - * a2 - mask (a8) - * a3 - w - */ - - li t9, 0x00ff00ff - beqz a3, 3f - nop - srl t7, a3, 2 /* t7 = how many multiples of 4 dst pixels */ - beqz t7, 1f /* branch if less than 4 src pixels */ - nop - - srl t8, a1, 24 - replv.ph t8, t8 - -0: - beqz t7, 1f - addiu t7, t7, -1 - lbu t0, 0(a2) - lbu t1, 1(a2) - lbu t2, 2(a2) - lbu t3, 3(a2) - - addiu a2, a2, 4 - - precr_sra.ph.w t1, t0, 0 - precr_sra.ph.w t3, t2, 0 - precr.qb.ph t0, t3, t1 - - muleu_s.ph.qbl t2, t0, t8 - muleu_s.ph.qbr t3, t0, t8 - shra_r.ph t4, t2, 8 - shra_r.ph t5, t3, 8 - and t4, t4, t9 - and t5, t5, t9 - addq.ph t2, t2, t4 - addq.ph t3, t3, t5 - shra_r.ph t2, t2, 8 - shra_r.ph t3, t3, 8 - precr.qb.ph t2, t2, t3 - - sb t2, 0(a0) - srl t2, t2, 8 - sb t2, 1(a0) - srl t2, t2, 8 - sb t2, 2(a0) - srl t2, t2, 8 - sb t2, 3(a0) - addiu a3, a3, -4 - b 0b - addiu a0, a0, 4 - -1: - beqz a3, 3f - nop - srl t8, a1, 24 -2: - lbu t0, 0(a2) - addiu a2, a2, 1 - - mul t2, t0, t8 - shra_r.ph t3, t2, 8 - andi t3, t3, 0x00ff - addq.ph t2, t2, t3 - shra_r.ph t2, t2, 8 - - sb t2, 0(a0) - addiu a3, a3, -1 - bnez a3, 2b - addiu a0, a0, 1 - -3: - j ra - nop - -END(pixman_composite_src_n_8_8_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_over_n_8888_8888_ca_asm_mips) -/* - * a0 - dst (a8r8g8b8) - * a1 - src (32bit constant) - * a2 - mask (a8r8g8b8) - * a3 - w - */ - - beqz a3, 8f - nop - SAVE_REGS_ON_STACK 8, s0, s1, s2, s3, s4, s5 - - li t6, 0xff - addiu t7, zero, -1 /* t7 = 0xffffffff */ - srl t8, a1, 24 /* t8 = srca */ - li t9, 0x00ff00ff - - addiu t1, a3, -1 - beqz t1, 4f /* last pixel */ - nop - -0: - lw t0, 0(a2) /* t0 = mask */ - lw t1, 4(a2) /* t1 = mask */ - addiu a3, a3, -2 /* w = w - 2 */ - or t2, t0, t1 - beqz t2, 3f /* if (t0 == 0) && (t1 == 0) */ - addiu a2, a2, 8 - and t2, t0, t1 - beq t2, t7, 1f /* if (t0 == 0xffffffff) && (t1 == 0xffffffff) */ - nop - -//if(ma) - lw t2, 0(a0) /* t2 = dst */ - lw t3, 4(a0) /* t3 = dst */ - MIPS_2xUN8x4_MUL_2xUN8x4 a1, a1, t0, t1, t4, t5, t9, s0, s1, s2, s3, s4, s5 - MIPS_2xUN8x4_MUL_2xUN8 t0, t1, t8, t8, t0, t1, t9, s0, s1, s2, s3, s4, s5 - not t0, t0 - not t1, t1 - MIPS_2xUN8x4_MUL_2xUN8x4 t2, t3, t0, t1, t2, t3, t9, s0, s1, s2, s3, s4, s5 - addu_s.qb t2, t4, t2 - addu_s.qb t3, t5, t3 - sw t2, 0(a0) - sw t3, 4(a0) - addiu t1, a3, -1 - bgtz t1, 0b - addiu a0, a0, 8 - b 4f - nop -1: -//if (t0 == 0xffffffff) && (t1 == 0xffffffff): - beq t8, t6, 2f /* if (srca == 0xff) */ - nop - lw t2, 0(a0) /* t2 = dst */ - lw t3, 4(a0) /* t3 = dst */ - not t0, a1 - not t1, a1 - srl t0, t0, 24 - srl t1, t1, 24 - MIPS_2xUN8x4_MUL_2xUN8 t2, t3, t0, t1, t2, t3, t9, s0, s1, s2, s3, s4, s5 - addu_s.qb t2, a1, t2 - addu_s.qb t3, a1, t3 - sw t2, 0(a0) - sw t3, 4(a0) - addiu t1, a3, -1 - bgtz t1, 0b - addiu a0, a0, 8 - b 4f - nop -2: - sw a1, 0(a0) - sw a1, 4(a0) -3: - addiu t1, a3, -1 - bgtz t1, 0b - addiu a0, a0, 8 - -4: - beqz a3, 7f - nop - /* a1 = src */ - lw t0, 0(a2) /* t0 = mask */ - beqz t0, 7f /* if (t0 == 0) */ - nop - beq t0, t7, 5f /* if (t0 == 0xffffffff) */ - nop -//if(ma) - lw t1, 0(a0) /* t1 = dst */ - MIPS_UN8x4_MUL_UN8x4 a1, t0, t2, t9, t3, t4, t5, s0 - MIPS_UN8x4_MUL_UN8 t0, t8, t0, t9, t3, t4, t5 - not t0, t0 - MIPS_UN8x4_MUL_UN8x4 t1, t0, t1, t9, t3, t4, t5, s0 - addu_s.qb t1, t2, t1 - sw t1, 0(a0) - RESTORE_REGS_FROM_STACK 8, s0, s1, s2, s3, s4, s5 - j ra - nop -5: -//if (t0 == 0xffffffff) - beq t8, t6, 6f /* if (srca == 0xff) */ - nop - lw t1, 0(a0) /* t1 = dst */ - not t0, a1 - srl t0, t0, 24 - MIPS_UN8x4_MUL_UN8 t1, t0, t1, t9, t2, t3, t4 - addu_s.qb t1, a1, t1 - sw t1, 0(a0) - RESTORE_REGS_FROM_STACK 8, s0, s1, s2, s3, s4, s5 - j ra - nop -6: - sw a1, 0(a0) -7: - RESTORE_REGS_FROM_STACK 8, s0, s1, s2, s3, s4, s5 -8: - j ra - nop - -END(pixman_composite_over_n_8888_8888_ca_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_over_n_8888_0565_ca_asm_mips) -/* - * a0 - dst (r5g6b5) - * a1 - src (32bit constant) - * a2 - mask (a8r8g8b8) - * a3 - w - */ - - beqz a3, 8f - nop - SAVE_REGS_ON_STACK 20, s0, s1, s2, s3, s4, s5, s6, s7, s8 - - li t6, 0xff - addiu t7, zero, -1 /* t7 = 0xffffffff */ - srl t8, a1, 24 /* t8 = srca */ - li t9, 0x00ff00ff - li s6, 0xf800f800 - li s7, 0x07e007e0 - li s8, 0x001F001F - - addiu t1, a3, -1 - beqz t1, 4f /* last pixel */ - nop - -0: - lw t0, 0(a2) /* t0 = mask */ - lw t1, 4(a2) /* t1 = mask */ - addiu a3, a3, -2 /* w = w - 2 */ - or t2, t0, t1 - beqz t2, 3f /* if (t0 == 0) && (t1 == 0) */ - addiu a2, a2, 8 - and t2, t0, t1 - beq t2, t7, 1f /* if (t0 == 0xffffffff) && (t1 == 0xffffffff) */ - nop - -//if(ma) - lhu t2, 0(a0) /* t2 = dst */ - lhu t3, 2(a0) /* t3 = dst */ - MIPS_2xUN8x4_MUL_2xUN8x4 a1, a1, t0, t1, t4, t5, t9, s0, s1, s2, s3, s4, s5 - MIPS_2xUN8x4_MUL_2xUN8 t0, t1, t8, t8, t0, t1, t9, s0, s1, s2, s3, s4, s5 - not t0, t0 - not t1, t1 - CONVERT_2x0565_TO_2x8888 t2, t3, t2, t3, s7, s8, s0, s1, s2, s3 - MIPS_2xUN8x4_MUL_2xUN8x4 t2, t3, t0, t1, t2, t3, t9, s0, s1, s2, s3, s4, s5 - addu_s.qb t2, t4, t2 - addu_s.qb t3, t5, t3 - CONVERT_2x8888_TO_2x0565 t2, t3, t2, t3, s6, s7, s8, s0, s1 - sh t2, 0(a0) - sh t3, 2(a0) - addiu t1, a3, -1 - bgtz t1, 0b - addiu a0, a0, 4 - b 4f - nop -1: -//if (t0 == 0xffffffff) && (t1 == 0xffffffff): - beq t8, t6, 2f /* if (srca == 0xff) */ - nop - lhu t2, 0(a0) /* t2 = dst */ - lhu t3, 2(a0) /* t3 = dst */ - not t0, a1 - not t1, a1 - srl t0, t0, 24 - srl t1, t1, 24 - CONVERT_2x0565_TO_2x8888 t2, t3, t2, t3, s7, s8, s0, s1, s2, s3 - MIPS_2xUN8x4_MUL_2xUN8 t2, t3, t0, t1, t2, t3, t9, s0, s1, s2, s3, s4, s5 - addu_s.qb t2, a1, t2 - addu_s.qb t3, a1, t3 - CONVERT_2x8888_TO_2x0565 t2, t3, t2, t3, s6, s7, s8, s0, s1 - sh t2, 0(a0) - sh t3, 2(a0) - addiu t1, a3, -1 - bgtz t1, 0b - addiu a0, a0, 4 - b 4f - nop -2: - CONVERT_1x8888_TO_1x0565 a1, t2, s0, s1 - sh t2, 0(a0) - sh t2, 2(a0) -3: - addiu t1, a3, -1 - bgtz t1, 0b - addiu a0, a0, 4 - -4: - beqz a3, 7f - nop - /* a1 = src */ - lw t0, 0(a2) /* t0 = mask */ - beqz t0, 7f /* if (t0 == 0) */ - nop - beq t0, t7, 5f /* if (t0 == 0xffffffff) */ - nop -//if(ma) - lhu t1, 0(a0) /* t1 = dst */ - MIPS_UN8x4_MUL_UN8x4 a1, t0, t2, t9, t3, t4, t5, s0 - MIPS_UN8x4_MUL_UN8 t0, t8, t0, t9, t3, t4, t5 - not t0, t0 - CONVERT_1x0565_TO_1x8888 t1, s1, s2, s3 - MIPS_UN8x4_MUL_UN8x4 s1, t0, s1, t9, t3, t4, t5, s0 - addu_s.qb s1, t2, s1 - CONVERT_1x8888_TO_1x0565 s1, t1, s0, s2 - sh t1, 0(a0) - RESTORE_REGS_FROM_STACK 20, s0, s1, s2, s3, s4, s5, s6, s7, s8 - j ra - nop -5: -//if (t0 == 0xffffffff) - beq t8, t6, 6f /* if (srca == 0xff) */ - nop - lhu t1, 0(a0) /* t1 = dst */ - not t0, a1 - srl t0, t0, 24 - CONVERT_1x0565_TO_1x8888 t1, s1, s2, s3 - MIPS_UN8x4_MUL_UN8 s1, t0, s1, t9, t2, t3, t4 - addu_s.qb s1, a1, s1 - CONVERT_1x8888_TO_1x0565 s1, t1, s0, s2 - sh t1, 0(a0) - RESTORE_REGS_FROM_STACK 20, s0, s1, s2, s3, s4, s5, s6, s7, s8 - j ra - nop -6: - CONVERT_1x8888_TO_1x0565 a1, t1, s0, s2 - sh t1, 0(a0) -7: - RESTORE_REGS_FROM_STACK 20, s0, s1, s2, s3, s4, s5, s6, s7, s8 -8: - j ra - nop - -END(pixman_composite_over_n_8888_0565_ca_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_over_n_8_8_asm_mips) -/* - * a0 - dst (a8) - * a1 - src (32bit constant) - * a2 - mask (a8) - * a3 - w - */ - - SAVE_REGS_ON_STACK 0, v0 - li t9, 0x00ff00ff - beqz a3, 3f - nop - srl v0, a3, 2 /* v0 = how many multiples of 4 dst pixels */ - beqz v0, 1f /* branch if less than 4 src pixels */ - nop - - srl t8, a1, 24 - replv.ph t8, t8 - -0: - beqz v0, 1f - addiu v0, v0, -1 - lbu t0, 0(a2) - lbu t1, 1(a2) - lbu t2, 2(a2) - lbu t3, 3(a2) - lbu t4, 0(a0) - lbu t5, 1(a0) - lbu t6, 2(a0) - lbu t7, 3(a0) - - addiu a2, a2, 4 - - precr_sra.ph.w t1, t0, 0 - precr_sra.ph.w t3, t2, 0 - precr_sra.ph.w t5, t4, 0 - precr_sra.ph.w t7, t6, 0 - - precr.qb.ph t0, t3, t1 - precr.qb.ph t1, t7, t5 - - muleu_s.ph.qbl t2, t0, t8 - muleu_s.ph.qbr t3, t0, t8 - shra_r.ph t4, t2, 8 - shra_r.ph t5, t3, 8 - and t4, t4, t9 - and t5, t5, t9 - addq.ph t2, t2, t4 - addq.ph t3, t3, t5 - shra_r.ph t2, t2, 8 - shra_r.ph t3, t3, 8 - precr.qb.ph t0, t2, t3 - not t6, t0 - - preceu.ph.qbl t7, t6 - preceu.ph.qbr t6, t6 - - muleu_s.ph.qbl t2, t1, t7 - muleu_s.ph.qbr t3, t1, t6 - shra_r.ph t4, t2, 8 - shra_r.ph t5, t3, 8 - and t4, t4, t9 - and t5, t5, t9 - addq.ph t2, t2, t4 - addq.ph t3, t3, t5 - shra_r.ph t2, t2, 8 - shra_r.ph t3, t3, 8 - precr.qb.ph t1, t2, t3 - - addu_s.qb t2, t0, t1 - - sb t2, 0(a0) - srl t2, t2, 8 - sb t2, 1(a0) - srl t2, t2, 8 - sb t2, 2(a0) - srl t2, t2, 8 - sb t2, 3(a0) - addiu a3, a3, -4 - b 0b - addiu a0, a0, 4 - -1: - beqz a3, 3f - nop - srl t8, a1, 24 -2: - lbu t0, 0(a2) - lbu t1, 0(a0) - addiu a2, a2, 1 - - mul t2, t0, t8 - shra_r.ph t3, t2, 8 - andi t3, t3, 0x00ff - addq.ph t2, t2, t3 - shra_r.ph t2, t2, 8 - not t3, t2 - andi t3, t3, 0x00ff - - - mul t4, t1, t3 - shra_r.ph t5, t4, 8 - andi t5, t5, 0x00ff - addq.ph t4, t4, t5 - shra_r.ph t4, t4, 8 - andi t4, t4, 0x00ff - - addu_s.qb t2, t2, t4 - sb t2, 0(a0) - addiu a3, a3, -1 - bnez a3, 2b - addiu a0, a0, 1 - -3: - RESTORE_REGS_FROM_STACK 0, v0 - j ra - nop - -END(pixman_composite_over_n_8_8_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_over_n_8_8888_asm_mips) -/* - * a0 - dst (a8r8g8b8) - * a1 - src (32bit constant) - * a2 - mask (a8) - * a3 - w - */ - - SAVE_REGS_ON_STACK 4, s0, s1, s2, s3, s4 - beqz a3, 4f - nop - li t4, 0x00ff00ff - li t5, 0xff - addiu t0, a3, -1 - beqz t0, 3f /* last pixel */ - srl t6, a1, 24 /* t6 = srca */ - not s4, a1 - beq t5, t6, 2f /* if (srca == 0xff) */ - srl s4, s4, 24 -1: - /* a1 = src */ - lbu t0, 0(a2) /* t0 = mask */ - lbu t1, 1(a2) /* t1 = mask */ - or t2, t0, t1 - beqz t2, 111f /* if (t0 == 0) && (t1 == 0) */ - addiu a2, a2, 2 - and t3, t0, t1 - - lw t2, 0(a0) /* t2 = dst */ - beq t3, t5, 11f /* if (t0 == 0xff) && (t1 == 0xff) */ - lw t3, 4(a0) /* t3 = dst */ - - MIPS_2xUN8x4_MUL_2xUN8 a1, a1, t0, t1, s0, s1, t4, t6, t7, t8, t9, s2, s3 - not s2, s0 - not s3, s1 - srl s2, s2, 24 - srl s3, s3, 24 - MIPS_2xUN8x4_MUL_2xUN8 t2, t3, s2, s3, t2, t3, t4, t0, t1, t6, t7, t8, t9 - addu_s.qb s2, t2, s0 - addu_s.qb s3, t3, s1 - sw s2, 0(a0) - b 111f - sw s3, 4(a0) -11: - MIPS_2xUN8x4_MUL_2xUN8 t2, t3, s4, s4, t2, t3, t4, t0, t1, t6, t7, t8, t9 - addu_s.qb s2, t2, a1 - addu_s.qb s3, t3, a1 - sw s2, 0(a0) - sw s3, 4(a0) - -111: - addiu a3, a3, -2 - addiu t0, a3, -1 - bgtz t0, 1b - addiu a0, a0, 8 - b 3f - nop -2: - /* a1 = src */ - lbu t0, 0(a2) /* t0 = mask */ - lbu t1, 1(a2) /* t1 = mask */ - or t2, t0, t1 - beqz t2, 222f /* if (t0 == 0) && (t1 == 0) */ - addiu a2, a2, 2 - and t3, t0, t1 - beq t3, t5, 22f /* if (t0 == 0xff) && (t1 == 0xff) */ - nop - lw t2, 0(a0) /* t2 = dst */ - lw t3, 4(a0) /* t3 = dst */ - - OVER_2x8888_2x8_2x8888 a1, a1, t0, t1, t2, t3, \ - t6, t7, t4, t8, t9, s0, s1, s2, s3 - sw t6, 0(a0) - b 222f - sw t7, 4(a0) -22: - sw a1, 0(a0) - sw a1, 4(a0) -222: - addiu a3, a3, -2 - addiu t0, a3, -1 - bgtz t0, 2b - addiu a0, a0, 8 -3: - blez a3, 4f - nop - /* a1 = src */ - lbu t0, 0(a2) /* t0 = mask */ - beqz t0, 4f /* if (t0 == 0) */ - addiu a2, a2, 1 - move t3, a1 - beq t0, t5, 31f /* if (t0 == 0xff) */ - lw t1, 0(a0) /* t1 = dst */ - - MIPS_UN8x4_MUL_UN8 a1, t0, t3, t4, t6, t7, t8 -31: - not t2, t3 - srl t2, t2, 24 - MIPS_UN8x4_MUL_UN8 t1, t2, t1, t4, t6, t7, t8 - addu_s.qb t2, t1, t3 - sw t2, 0(a0) -4: - RESTORE_REGS_FROM_STACK 4, s0, s1, s2, s3, s4 - j ra - nop - -END(pixman_composite_over_n_8_8888_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_over_n_8_0565_asm_mips) -/* - * a0 - dst (r5g6b5) - * a1 - src (32bit constant) - * a2 - mask (a8) - * a3 - w - */ - SAVE_REGS_ON_STACK 24, v0, s0, s1, s2, s3, s4, s5, s6, s7, s8 - beqz a3, 4f - nop - li t4, 0x00ff00ff - li t5, 0xff - li t6, 0xf800f800 - li t7, 0x07e007e0 - li t8, 0x001F001F - addiu t1, a3, -1 - beqz t1, 3f /* last pixel */ - srl t0, a1, 24 /* t0 = srca */ - not v0, a1 - beq t0, t5, 2f /* if (srca == 0xff) */ - srl v0, v0, 24 -1: - /* a1 = src */ - lbu t0, 0(a2) /* t0 = mask */ - lbu t1, 1(a2) /* t1 = mask */ - or t2, t0, t1 - beqz t2, 111f /* if (t0 == 0) && (t1 == 0) */ - addiu a2, a2, 2 - lhu t2, 0(a0) /* t2 = dst */ - lhu t3, 2(a0) /* t3 = dst */ - CONVERT_2x0565_TO_2x8888 t2, t3, s0, s1, t7, t8, t9, s2, s3, s4 - and t9, t0, t1 - beq t9, t5, 11f /* if (t0 == 0xff) && (t1 == 0xff) */ - nop - - MIPS_2xUN8x4_MUL_2xUN8 a1, a1, t0, t1, s2, s3, t4, t9, s4, s5, s6, s7, s8 - not s4, s2 - not s5, s3 - srl s4, s4, 24 - srl s5, s5, 24 - MIPS_2xUN8x4_MUL_2xUN8 s0, s1, s4, s5, s0, s1, t4, t9, t0, t1, s6, s7, s8 - addu_s.qb s4, s2, s0 - addu_s.qb s5, s3, s1 - CONVERT_2x8888_TO_2x0565 s4, s5, t2, t3, t6, t7, t8, s0, s1 - sh t2, 0(a0) - b 111f - sh t3, 2(a0) -11: - MIPS_2xUN8x4_MUL_2xUN8 s0, s1, v0, v0, s0, s1, t4, t9, t0, t1, s6, s7, s8 - addu_s.qb s4, a1, s0 - addu_s.qb s5, a1, s1 - CONVERT_2x8888_TO_2x0565 s4, s5, t2, t3, t6, t7, t8, s0, s1 - sh t2, 0(a0) - sh t3, 2(a0) -111: - addiu a3, a3, -2 - addiu t0, a3, -1 - bgtz t0, 1b - addiu a0, a0, 4 - b 3f - nop -2: - CONVERT_1x8888_TO_1x0565 a1, s0, s1, s2 -21: - /* a1 = src */ - lbu t0, 0(a2) /* t0 = mask */ - lbu t1, 1(a2) /* t1 = mask */ - or t2, t0, t1 - beqz t2, 222f /* if (t0 == 0) && (t1 == 0) */ - addiu a2, a2, 2 - and t9, t0, t1 - move s2, s0 - beq t9, t5, 22f /* if (t0 == 0xff) && (t2 == 0xff) */ - move s3, s0 - lhu t2, 0(a0) /* t2 = dst */ - lhu t3, 2(a0) /* t3 = dst */ - - CONVERT_2x0565_TO_2x8888 t2, t3, s2, s3, t7, t8, s4, s5, s6, s7 - OVER_2x8888_2x8_2x8888 a1, a1, t0, t1, s2, s3, \ - t2, t3, t4, t9, s4, s5, s6, s7, s8 - CONVERT_2x8888_TO_2x0565 t2, t3, s2, s3, t6, t7, t8, s4, s5 -22: - sh s2, 0(a0) - sh s3, 2(a0) -222: - addiu a3, a3, -2 - addiu t0, a3, -1 - bgtz t0, 21b - addiu a0, a0, 4 -3: - blez a3, 4f - nop - /* a1 = src */ - lbu t0, 0(a2) /* t0 = mask */ - beqz t0, 4f /* if (t0 == 0) */ - nop - lhu t1, 0(a0) /* t1 = dst */ - CONVERT_1x0565_TO_1x8888 t1, t2, t3, t7 - beq t0, t5, 31f /* if (t0 == 0xff) */ - move t3, a1 - - MIPS_UN8x4_MUL_UN8 a1, t0, t3, t4, t7, t8, t9 -31: - not t6, t3 - srl t6, t6, 24 - MIPS_UN8x4_MUL_UN8 t2, t6, t2, t4, t7, t8, t9 - addu_s.qb t1, t2, t3 - CONVERT_1x8888_TO_1x0565 t1, t2, t3, t7 - sh t2, 0(a0) -4: - RESTORE_REGS_FROM_STACK 24, v0, s0, s1, s2, s3, s4, s5, s6, s7, s8 - j ra - nop - -END(pixman_composite_over_n_8_0565_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_over_8888_n_8888_asm_mips) -/* - * a0 - dst (a8r8g8b8) - * a1 - src (a8r8g8b8) - * a2 - mask (32bit constant) - * a3 - w - */ - - SAVE_REGS_ON_STACK 0, s0 - li t4, 0x00ff00ff - beqz a3, 3f - nop - addiu t1, a3, -1 - srl a2, a2, 24 - beqz t1, 2f - nop - -1: - lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ - lw t1, 4(a1) /* t1 = source (a8r8g8b8) */ - /* a2 = mask (32bit constant) */ - lw t2, 0(a0) /* t2 = destination (a8r8g8b8) */ - lw t3, 4(a0) /* t3 = destination (a8r8g8b8) */ - addiu a1, a1, 8 - - OVER_2x8888_2x8_2x8888 t0, t1, a2, a2, t2, t3, \ - t5, t6, t4, t7, t8, t9, t0, t1, s0 - - sw t5, 0(a0) - sw t6, 4(a0) - addiu a3, a3, -2 - addiu t1, a3, -1 - bgtz t1, 1b - addiu a0, a0, 8 -2: - beqz a3, 3f - nop - lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ - /* a2 = mask (32bit constant) */ - lw t1, 0(a0) /* t1 = destination (a8r8g8b8) */ - - OVER_8888_8_8888 t0, a2, t1, t3, t4, t5, t6, t7, t8 - - sw t3, 0(a0) -3: - RESTORE_REGS_FROM_STACK 0, s0 - j ra - nop - -END(pixman_composite_over_8888_n_8888_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_over_8888_n_0565_asm_mips) -/* - * a0 - dst (r5g6b5) - * a1 - src (a8r8g8b8) - * a2 - mask (32bit constant) - * a3 - w - */ - - SAVE_REGS_ON_STACK 0, s0, s1, s2, s3 - li t6, 0x00ff00ff - li t7, 0xf800f800 - li t8, 0x07e007e0 - li t9, 0x001F001F - beqz a3, 3f - nop - srl a2, a2, 24 - addiu t1, a3, -1 - beqz t1, 2f - nop -1: - lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ - lw t1, 4(a1) /* t1 = source (a8r8g8b8) */ - /* a2 = mask (32bit constant) */ - lhu t2, 0(a0) /* t2 = destination (r5g6b5) */ - lhu t3, 2(a0) /* t2 = destination (r5g6b5) */ - addiu a1, a1, 8 - - CONVERT_2x0565_TO_2x8888 t2, t3, t4, t5, t8, t9, s0, s1, t2, t3 - OVER_2x8888_2x8_2x8888 t0, t1, a2, a2, t4, t5, \ - t2, t3, t6, t0, t1, s0, s1, s2, s3 - CONVERT_2x8888_TO_2x0565 t2, t3, t4, t5, t7, t8, t9, s0, s1 - - sh t4, 0(a0) - sh t5, 2(a0) - addiu a3, a3, -2 - addiu t1, a3, -1 - bgtz t1, 1b - addiu a0, a0, 4 -2: - beqz a3, 3f - nop - lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ - /* a2 = mask (32bit constant) */ - lhu t1, 0(a0) /* t1 = destination (r5g6b5) */ - - CONVERT_1x0565_TO_1x8888 t1, t2, t4, t5 - OVER_8888_8_8888 t0, a2, t2, t1, t6, t3, t4, t5, t7 - CONVERT_1x8888_TO_1x0565 t1, t3, t4, t5 - - sh t3, 0(a0) -3: - RESTORE_REGS_FROM_STACK 0, s0, s1, s2, s3 - j ra - nop - -END(pixman_composite_over_8888_n_0565_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_over_0565_n_0565_asm_mips) -/* - * a0 - dst (r5g6b5) - * a1 - src (r5g6b5) - * a2 - mask (32bit constant) - * a3 - w - */ - - SAVE_REGS_ON_STACK 20, s0, s1, s2, s3, s4, s5 - li t6, 0x00ff00ff - li t7, 0xf800f800 - li t8, 0x07e007e0 - li t9, 0x001F001F - beqz a3, 3f - nop - srl a2, a2, 24 - addiu t1, a3, -1 - beqz t1, 2f - nop -1: - lhu t0, 0(a1) /* t0 = source (r5g6b5) */ - lhu t1, 2(a1) /* t1 = source (r5g6b5) */ - /* a2 = mask (32bit constant) */ - lhu t2, 0(a0) /* t2 = destination (r5g6b5) */ - lhu t3, 2(a0) /* t3 = destination (r5g6b5) */ - addiu a1, a1, 4 - - CONVERT_2x0565_TO_2x8888 t0, t1, t4, t5, t8, t9, s0, s1, s2, s3 - CONVERT_2x0565_TO_2x8888 t2, t3, s0, s1, t8, t9, s2, s3, s4, s5 - OVER_2x8888_2x8_2x8888 t4, t5, a2, a2, s0, s1, \ - t0, t1, t6, s2, s3, s4, s5, t4, t5 - CONVERT_2x8888_TO_2x0565 t0, t1, s0, s1, t7, t8, t9, s2, s3 - - sh s0, 0(a0) - sh s1, 2(a0) - addiu a3, a3, -2 - addiu t1, a3, -1 - bgtz t1, 1b - addiu a0, a0, 4 -2: - beqz a3, 3f - nop - lhu t0, 0(a1) /* t0 = source (r5g6b5) */ - /* a2 = mask (32bit constant) */ - lhu t1, 0(a0) /* t1 = destination (r5g6b5) */ - - CONVERT_1x0565_TO_1x8888 t0, t2, t4, t5 - CONVERT_1x0565_TO_1x8888 t1, t3, t4, t5 - OVER_8888_8_8888 t2, a2, t3, t0, t6, t1, t4, t5, t7 - CONVERT_1x8888_TO_1x0565 t0, t3, t4, t5 - - sh t3, 0(a0) -3: - RESTORE_REGS_FROM_STACK 20, s0, s1, s2, s3, s4, s5 - j ra - nop - -END(pixman_composite_over_0565_n_0565_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_over_8888_8_8888_asm_mips) -/* - * a0 - dst (a8r8g8b8) - * a1 - src (a8r8g8b8) - * a2 - mask (a8) - * a3 - w - */ - - SAVE_REGS_ON_STACK 0, s0, s1 - li t4, 0x00ff00ff - beqz a3, 3f - nop - addiu t1, a3, -1 - beqz t1, 2f - nop -1: - lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ - lw t1, 4(a1) /* t1 = source (a8r8g8b8) */ - lbu t2, 0(a2) /* t2 = mask (a8) */ - lbu t3, 1(a2) /* t3 = mask (a8) */ - lw t5, 0(a0) /* t5 = destination (a8r8g8b8) */ - lw t6, 4(a0) /* t6 = destination (a8r8g8b8) */ - addiu a1, a1, 8 - addiu a2, a2, 2 - - OVER_2x8888_2x8_2x8888 t0, t1, t2, t3, t5, t6, \ - t7, t8, t4, t9, s0, s1, t0, t1, t2 - - sw t7, 0(a0) - sw t8, 4(a0) - addiu a3, a3, -2 - addiu t1, a3, -1 - bgtz t1, 1b - addiu a0, a0, 8 -2: - beqz a3, 3f - nop - lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ - lbu t1, 0(a2) /* t1 = mask (a8) */ - lw t2, 0(a0) /* t2 = destination (a8r8g8b8) */ - - OVER_8888_8_8888 t0, t1, t2, t3, t4, t5, t6, t7, t8 - - sw t3, 0(a0) -3: - RESTORE_REGS_FROM_STACK 0, s0, s1 - j ra - nop - -END(pixman_composite_over_8888_8_8888_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_over_8888_8_0565_asm_mips) -/* - * a0 - dst (r5g6b5) - * a1 - src (a8r8g8b8) - * a2 - mask (a8) - * a3 - w - */ - - SAVE_REGS_ON_STACK 20, s0, s1, s2, s3, s4, s5 - li t6, 0x00ff00ff - li t7, 0xf800f800 - li t8, 0x07e007e0 - li t9, 0x001F001F - beqz a3, 3f - nop - addiu t1, a3, -1 - beqz t1, 2f - nop -1: - lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ - lw t1, 4(a1) /* t1 = source (a8r8g8b8) */ - lbu t2, 0(a2) /* t2 = mask (a8) */ - lbu t3, 1(a2) /* t3 = mask (a8) */ - lhu t4, 0(a0) /* t4 = destination (r5g6b5) */ - lhu t5, 2(a0) /* t5 = destination (r5g6b5) */ - addiu a1, a1, 8 - addiu a2, a2, 2 - - CONVERT_2x0565_TO_2x8888 t4, t5, s0, s1, t8, t9, s2, s3, s4, s5 - OVER_2x8888_2x8_2x8888 t0, t1, t2, t3, s0, s1, \ - t4, t5, t6, s2, s3, s4, s5, t0, t1 - CONVERT_2x8888_TO_2x0565 t4, t5, s0, s1, t7, t8, t9, s2, s3 - - sh s0, 0(a0) - sh s1, 2(a0) - addiu a3, a3, -2 - addiu t1, a3, -1 - bgtz t1, 1b - addiu a0, a0, 4 -2: - beqz a3, 3f - nop - lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ - lbu t1, 0(a2) /* t1 = mask (a8) */ - lhu t2, 0(a0) /* t2 = destination (r5g6b5) */ - - CONVERT_1x0565_TO_1x8888 t2, t3, t4, t5 - OVER_8888_8_8888 t0, t1, t3, t2, t6, t4, t5, t7, t8 - CONVERT_1x8888_TO_1x0565 t2, t3, t4, t5 - - sh t3, 0(a0) -3: - RESTORE_REGS_FROM_STACK 20, s0, s1, s2, s3, s4, s5 - j ra - nop - -END(pixman_composite_over_8888_8_0565_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_over_0565_8_0565_asm_mips) -/* - * a0 - dst (r5g6b5) - * a1 - src (r5g6b5) - * a2 - mask (a8) - * a3 - w - */ - - SAVE_REGS_ON_STACK 20, s0, s1, s2, s3, s4, s5 - li t4, 0xf800f800 - li t5, 0x07e007e0 - li t6, 0x001F001F - li t7, 0x00ff00ff - beqz a3, 3f - nop - addiu t1, a3, -1 - beqz t1, 2f - nop -1: - lhu t0, 0(a1) /* t0 = source (r5g6b5) */ - lhu t1, 2(a1) /* t1 = source (r5g6b5) */ - lbu t2, 0(a2) /* t2 = mask (a8) */ - lbu t3, 1(a2) /* t3 = mask (a8) */ - lhu t8, 0(a0) /* t8 = destination (r5g6b5) */ - lhu t9, 2(a0) /* t9 = destination (r5g6b5) */ - addiu a1, a1, 4 - addiu a2, a2, 2 - - CONVERT_2x0565_TO_2x8888 t0, t1, s0, s1, t5, t6, s2, s3, s4, s5 - CONVERT_2x0565_TO_2x8888 t8, t9, s2, s3, t5, t6, s4, s5, t0, t1 - OVER_2x8888_2x8_2x8888 s0, s1, t2, t3, s2, s3, \ - t0, t1, t7, s4, s5, t8, t9, s0, s1 - CONVERT_2x8888_TO_2x0565 t0, t1, s0, s1, t4, t5, t6, s2, s3 - - sh s0, 0(a0) - sh s1, 2(a0) - addiu a3, a3, -2 - addiu t1, a3, -1 - bgtz t1, 1b - addiu a0, a0, 4 -2: - beqz a3, 3f - nop - lhu t0, 0(a1) /* t0 = source (r5g6b5) */ - lbu t1, 0(a2) /* t1 = mask (a8) */ - lhu t2, 0(a0) /* t2 = destination (r5g6b5) */ - - CONVERT_1x0565_TO_1x8888 t0, t3, t4, t5 - CONVERT_1x0565_TO_1x8888 t2, t4, t5, t6 - OVER_8888_8_8888 t3, t1, t4, t0, t7, t2, t5, t6, t8 - CONVERT_1x8888_TO_1x0565 t0, t3, t4, t5 - - sh t3, 0(a0) -3: - RESTORE_REGS_FROM_STACK 20, s0, s1, s2, s3, s4, s5 - j ra - nop - -END(pixman_composite_over_0565_8_0565_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_over_8888_8888_8888_asm_mips) -/* - * a0 - dst (a8r8g8b8) - * a1 - src (a8r8g8b8) - * a2 - mask (a8r8g8b8) - * a3 - w - */ - - SAVE_REGS_ON_STACK 0, s0, s1, s2 - li t4, 0x00ff00ff - beqz a3, 3f - nop - addiu t1, a3, -1 - beqz t1, 2f - nop -1: - lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ - lw t1, 4(a1) /* t1 = source (a8r8g8b8) */ - lw t2, 0(a2) /* t2 = mask (a8r8g8b8) */ - lw t3, 4(a2) /* t3 = mask (a8r8g8b8) */ - lw t5, 0(a0) /* t5 = destination (a8r8g8b8) */ - lw t6, 4(a0) /* t6 = destination (a8r8g8b8) */ - addiu a1, a1, 8 - addiu a2, a2, 8 - srl t2, t2, 24 - srl t3, t3, 24 - - OVER_2x8888_2x8_2x8888 t0, t1, t2, t3, t5, t6, t7, t8, t4, t9, s0, s1, s2, t0, t1 - - sw t7, 0(a0) - sw t8, 4(a0) - addiu a3, a3, -2 - addiu t1, a3, -1 - bgtz t1, 1b - addiu a0, a0, 8 -2: - beqz a3, 3f - nop - lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ - lw t1, 0(a2) /* t1 = mask (a8r8g8b8) */ - lw t2, 0(a0) /* t2 = destination (a8r8g8b8) */ - srl t1, t1, 24 - - OVER_8888_8_8888 t0, t1, t2, t3, t4, t5, t6, t7, t8 - - sw t3, 0(a0) -3: - RESTORE_REGS_FROM_STACK 0, s0, s1, s2 - j ra - nop - -END(pixman_composite_over_8888_8888_8888_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_over_8888_8888_asm_mips) -/* - * a0 - dst (a8r8g8b8) - * a1 - src (a8r8g8b8) - * a2 - w - */ - - SAVE_REGS_ON_STACK 0, s0, s1, s2 - li t4, 0x00ff00ff - beqz a2, 3f - nop - addiu t1, a2, -1 - beqz t1, 2f - nop -1: - lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ - lw t1, 4(a1) /* t1 = source (a8r8g8b8) */ - lw t2, 0(a0) /* t2 = destination (a8r8g8b8) */ - lw t3, 4(a0) /* t3 = destination (a8r8g8b8) */ - addiu a1, a1, 8 - - not t5, t0 - srl t5, t5, 24 - not t6, t1 - srl t6, t6, 24 - - or t7, t5, t6 - beqz t7, 11f - or t8, t0, t1 - beqz t8, 12f - - MIPS_2xUN8x4_MUL_2xUN8 t2, t3, t5, t6, t7, t8, t4, t9, s0, s1, s2, t2, t3 - - addu_s.qb t0, t7, t0 - addu_s.qb t1, t8, t1 -11: - sw t0, 0(a0) - sw t1, 4(a0) -12: - addiu a2, a2, -2 - addiu t1, a2, -1 - bgtz t1, 1b - addiu a0, a0, 8 -2: - beqz a2, 3f - nop - - lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ - lw t1, 0(a0) /* t1 = destination (a8r8g8b8) */ - addiu a1, a1, 4 - - not t2, t0 - srl t2, t2, 24 - - beqz t2, 21f - nop - beqz t0, 3f - - MIPS_UN8x4_MUL_UN8 t1, t2, t3, t4, t5, t6, t7 - - addu_s.qb t0, t3, t0 -21: - sw t0, 0(a0) - -3: - RESTORE_REGS_FROM_STACK 0, s0, s1, s2 - j ra - nop - -END(pixman_composite_over_8888_8888_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_over_8888_0565_asm_mips) -/* - * a0 - dst (r5g6b5) - * a1 - src (a8r8g8b8) - * a2 - w - */ - - SAVE_REGS_ON_STACK 8, s0, s1, s2, s3, s4, s5 - li t4, 0x00ff00ff - li s3, 0xf800f800 - li s4, 0x07e007e0 - li s5, 0x001F001F - beqz a2, 3f - nop - addiu t1, a2, -1 - beqz t1, 2f - nop -1: - lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ - lw t1, 4(a1) /* t1 = source (a8r8g8b8) */ - lhu t2, 0(a0) /* t2 = destination (r5g6b5) */ - lhu t3, 2(a0) /* t3 = destination (r5g6b5) */ - addiu a1, a1, 8 - - not t5, t0 - srl t5, t5, 24 - not t6, t1 - srl t6, t6, 24 - - or t7, t5, t6 - beqz t7, 11f - or t8, t0, t1 - beqz t8, 12f - - CONVERT_2x0565_TO_2x8888 t2, t3, s0, s1, s4, s5, t7, t8, t9, s2 - MIPS_2xUN8x4_MUL_2xUN8 s0, s1, t5, t6, t7, t8, t4, t9, t2, t3, s2, s0, s1 - - addu_s.qb t0, t7, t0 - addu_s.qb t1, t8, t1 -11: - CONVERT_2x8888_TO_2x0565 t0, t1, t7, t8, s3, s4, s5, t2, t3 - sh t7, 0(a0) - sh t8, 2(a0) -12: - addiu a2, a2, -2 - addiu t1, a2, -1 - bgtz t1, 1b - addiu a0, a0, 4 -2: - beqz a2, 3f - nop - - lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ - lhu t1, 0(a0) /* t1 = destination (r5g6b5) */ - addiu a1, a1, 4 - - not t2, t0 - srl t2, t2, 24 - - beqz t2, 21f - nop - beqz t0, 3f - - CONVERT_1x0565_TO_1x8888 t1, s0, t8, t9 - MIPS_UN8x4_MUL_UN8 s0, t2, t3, t4, t5, t6, t7 - - addu_s.qb t0, t3, t0 -21: - CONVERT_1x8888_TO_1x0565 t0, s0, t8, t9 - sh s0, 0(a0) - -3: - RESTORE_REGS_FROM_STACK 8, s0, s1, s2, s3, s4, s5 - j ra - nop - -END(pixman_composite_over_8888_0565_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_over_n_0565_asm_mips) -/* - * a0 - dst (r5g6b5) - * a1 - src (32bit constant) - * a2 - w - */ - - beqz a2, 5f - nop - - not t0, a1 - srl t0, t0, 24 - bgtz t0, 1f - nop - CONVERT_1x8888_TO_1x0565 a1, t1, t2, t3 -0: - sh t1, 0(a0) - addiu a2, a2, -1 - bgtz a2, 0b - addiu a0, a0, 2 - j ra - nop - -1: - SAVE_REGS_ON_STACK 0, s0, s1, s2 - li t4, 0x00ff00ff - li t5, 0xf800f800 - li t6, 0x07e007e0 - li t7, 0x001F001F - addiu t1, a2, -1 - beqz t1, 3f - nop -2: - lhu t1, 0(a0) /* t1 = destination (r5g6b5) */ - lhu t2, 2(a0) /* t2 = destination (r5g6b5) */ - - CONVERT_2x0565_TO_2x8888 t1, t2, t3, t8, t6, t7, t9, s0, s1, s2 - MIPS_2xUN8x4_MUL_2xUN8 t3, t8, t0, t0, t1, t2, t4, t9, s0, s1, s2, t3, t8 - addu_s.qb t1, t1, a1 - addu_s.qb t2, t2, a1 - CONVERT_2x8888_TO_2x0565 t1, t2, t3, t8, t5, t6, t7, s0, s1 - - sh t3, 0(a0) - sh t8, 2(a0) - - addiu a2, a2, -2 - addiu t1, a2, -1 - bgtz t1, 2b - addiu a0, a0, 4 -3: - beqz a2, 4f - nop - - lhu t1, 0(a0) /* t1 = destination (r5g6b5) */ - - CONVERT_1x0565_TO_1x8888 t1, t2, s0, s1 - MIPS_UN8x4_MUL_UN8 t2, t0, t1, t4, s0, s1, s2 - addu_s.qb t1, t1, a1 - CONVERT_1x8888_TO_1x0565 t1, t2, s0, s1 - - sh t2, 0(a0) - -4: - RESTORE_REGS_FROM_STACK 0, s0, s1, s2 -5: - j ra - nop - -END(pixman_composite_over_n_0565_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_over_n_8888_asm_mips) -/* - * a0 - dst (a8r8g8b8) - * a1 - src (32bit constant) - * a2 - w - */ - - beqz a2, 5f - nop - - not t0, a1 - srl t0, t0, 24 - bgtz t0, 1f - nop -0: - sw a1, 0(a0) - addiu a2, a2, -1 - bgtz a2, 0b - addiu a0, a0, 4 - j ra - nop - -1: - SAVE_REGS_ON_STACK 0, s0, s1, s2 - li t4, 0x00ff00ff - addiu t1, a2, -1 - beqz t1, 3f - nop -2: - lw t2, 0(a0) /* t2 = destination (a8r8g8b8) */ - lw t3, 4(a0) /* t3 = destination (a8r8g8b8) */ - - MIPS_2xUN8x4_MUL_2xUN8 t2, t3, t0, t0, t7, t8, t4, t9, s0, s1, s2, t2, t3 - - addu_s.qb t7, t7, a1 - addu_s.qb t8, t8, a1 - - sw t7, 0(a0) - sw t8, 4(a0) - - addiu a2, a2, -2 - addiu t1, a2, -1 - bgtz t1, 2b - addiu a0, a0, 8 -3: - beqz a2, 4f - nop - - lw t1, 0(a0) /* t1 = destination (a8r8g8b8) */ - - MIPS_UN8x4_MUL_UN8 t1, t0, t3, t4, t5, t6, t7 - - addu_s.qb t3, t3, a1 - - sw t3, 0(a0) - -4: - RESTORE_REGS_FROM_STACK 0, s0, s1, s2 -5: - j ra - nop - -END(pixman_composite_over_n_8888_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_add_8_8_8_asm_mips) -/* - * a0 - dst (a8) - * a1 - src (a8) - * a2 - mask (a8) - * a3 - w - */ - - SAVE_REGS_ON_STACK 0, v0, v1 - li t9, 0x00ff00ff - beqz a3, 3f - nop - - srl v0, a3, 2 /* v0 = how many multiples of 4 dst pixels */ - beqz v0, 1f /* branch if less than 4 src pixels */ - nop - -0: - beqz v0, 1f - addiu v0, v0, -1 - lbu t0, 0(a2) - lbu t1, 1(a2) - lbu t2, 2(a2) - lbu t3, 3(a2) - lbu t4, 0(a0) - lbu t5, 1(a0) - lbu t6, 2(a0) - lbu t7, 3(a0) - - addiu a2, a2, 4 - - precr_sra.ph.w t1, t0, 0 - precr_sra.ph.w t3, t2, 0 - precr_sra.ph.w t5, t4, 0 - precr_sra.ph.w t7, t6, 0 - - precr.qb.ph t0, t3, t1 - precr.qb.ph t1, t7, t5 - - lbu t4, 0(a1) - lbu v1, 1(a1) - lbu t7, 2(a1) - lbu t8, 3(a1) - - addiu a1, a1, 4 - - precr_sra.ph.w v1, t4, 0 - precr_sra.ph.w t8, t7, 0 - - muleu_s.ph.qbl t2, t0, t8 - muleu_s.ph.qbr t3, t0, v1 - shra_r.ph t4, t2, 8 - shra_r.ph t5, t3, 8 - and t4, t4, t9 - and t5, t5, t9 - addq.ph t2, t2, t4 - addq.ph t3, t3, t5 - shra_r.ph t2, t2, 8 - shra_r.ph t3, t3, 8 - precr.qb.ph t0, t2, t3 - - addu_s.qb t2, t0, t1 - - sb t2, 0(a0) - srl t2, t2, 8 - sb t2, 1(a0) - srl t2, t2, 8 - sb t2, 2(a0) - srl t2, t2, 8 - sb t2, 3(a0) - addiu a3, a3, -4 - b 0b - addiu a0, a0, 4 - -1: - beqz a3, 3f - nop -2: - lbu t8, 0(a1) - lbu t0, 0(a2) - lbu t1, 0(a0) - addiu a1, a1, 1 - addiu a2, a2, 1 - - mul t2, t0, t8 - shra_r.ph t3, t2, 8 - andi t3, t3, 0xff - addq.ph t2, t2, t3 - shra_r.ph t2, t2, 8 - andi t2, t2, 0xff - - addu_s.qb t2, t2, t1 - sb t2, 0(a0) - addiu a3, a3, -1 - bnez a3, 2b - addiu a0, a0, 1 - -3: - RESTORE_REGS_FROM_STACK 0, v0, v1 - j ra - nop - -END(pixman_composite_add_8_8_8_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_add_n_8_8_asm_mips) -/* - * a0 - dst (a8) - * a1 - src (32bit constant) - * a2 - mask (a8) - * a3 - w - */ - - SAVE_REGS_ON_STACK 0, v0 - li t9, 0x00ff00ff - beqz a3, 3f - nop - - srl v0, a3, 2 /* v0 = how many multiples of 4 dst pixels */ - beqz v0, 1f /* branch if less than 4 src pixels */ - nop - - srl t8, a1, 24 - replv.ph t8, t8 - -0: - beqz v0, 1f - addiu v0, v0, -1 - lbu t0, 0(a2) - lbu t1, 1(a2) - lbu t2, 2(a2) - lbu t3, 3(a2) - lbu t4, 0(a0) - lbu t5, 1(a0) - lbu t6, 2(a0) - lbu t7, 3(a0) - - addiu a2, a2, 4 - - precr_sra.ph.w t1, t0, 0 - precr_sra.ph.w t3, t2, 0 - precr_sra.ph.w t5, t4, 0 - precr_sra.ph.w t7, t6, 0 - - precr.qb.ph t0, t3, t1 - precr.qb.ph t1, t7, t5 - - muleu_s.ph.qbl t2, t0, t8 - muleu_s.ph.qbr t3, t0, t8 - shra_r.ph t4, t2, 8 - shra_r.ph t5, t3, 8 - and t4, t4, t9 - and t5, t5, t9 - addq.ph t2, t2, t4 - addq.ph t3, t3, t5 - shra_r.ph t2, t2, 8 - shra_r.ph t3, t3, 8 - precr.qb.ph t0, t2, t3 - - addu_s.qb t2, t0, t1 - - sb t2, 0(a0) - srl t2, t2, 8 - sb t2, 1(a0) - srl t2, t2, 8 - sb t2, 2(a0) - srl t2, t2, 8 - sb t2, 3(a0) - addiu a3, a3, -4 - b 0b - addiu a0, a0, 4 - -1: - beqz a3, 3f - nop - srl t8, a1, 24 -2: - lbu t0, 0(a2) - lbu t1, 0(a0) - addiu a2, a2, 1 - - mul t2, t0, t8 - shra_r.ph t3, t2, 8 - andi t3, t3, 0xff - addq.ph t2, t2, t3 - shra_r.ph t2, t2, 8 - andi t2, t2, 0xff - - addu_s.qb t2, t2, t1 - sb t2, 0(a0) - addiu a3, a3, -1 - bnez a3, 2b - addiu a0, a0, 1 - -3: - RESTORE_REGS_FROM_STACK 0, v0 - j ra - nop - -END(pixman_composite_add_n_8_8_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_add_n_8_8888_asm_mips) -/* - * a0 - dst (a8r8g8b8) - * a1 - src (32bit constant) - * a2 - mask (a8) - * a3 - w - */ - - SAVE_REGS_ON_STACK 0, s0, s1, s2 - li t4, 0x00ff00ff - beqz a3, 3f - nop - addiu t1, a3, -1 - beqz t1, 2f - nop -1: - /* a1 = source (32bit constant) */ - lbu t0, 0(a2) /* t0 = mask (a8) */ - lbu t1, 1(a2) /* t1 = mask (a8) */ - lw t2, 0(a0) /* t2 = destination (a8r8g8b8) */ - lw t3, 4(a0) /* t3 = destination (a8r8g8b8) */ - addiu a2, a2, 2 - - MIPS_2xUN8x4_MUL_2xUN8_ADD_2xUN8x4 a1, a1, \ - t0, t1, \ - t2, t3, \ - t5, t6, \ - t4, t7, t8, t9, s0, s1, s2 - - sw t5, 0(a0) - sw t6, 4(a0) - addiu a3, a3, -2 - addiu t1, a3, -1 - bgtz t1, 1b - addiu a0, a0, 8 -2: - beqz a3, 3f - nop - /* a1 = source (32bit constant) */ - lbu t0, 0(a2) /* t0 = mask (a8) */ - lw t1, 0(a0) /* t1 = destination (a8r8g8b8) */ - - MIPS_UN8x4_MUL_UN8_ADD_UN8x4 a1, t0, t1, t2, t4, t3, t5, t6 - - sw t2, 0(a0) -3: - RESTORE_REGS_FROM_STACK 0, s0, s1, s2 - j ra - nop - -END(pixman_composite_add_n_8_8888_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_add_0565_8_0565_asm_mips) -/* - * a0 - dst (r5g6b5) - * a1 - src (r5g6b5) - * a2 - mask (a8) - * a3 - w - */ - - SAVE_REGS_ON_STACK 20, s0, s1, s2, s3, s4, s5, s6, s7 - li t4, 0xf800f800 - li t5, 0x07e007e0 - li t6, 0x001F001F - li t7, 0x00ff00ff - beqz a3, 3f - nop - addiu t1, a3, -1 - beqz t1, 2f - nop -1: - lhu t0, 0(a1) /* t0 = source (r5g6b5) */ - lhu t1, 2(a1) /* t1 = source (r5g6b5) */ - lbu t2, 0(a2) /* t2 = mask (a8) */ - lbu t3, 1(a2) /* t3 = mask (a8) */ - lhu t8, 0(a0) /* t8 = destination (r5g6b5) */ - lhu t9, 2(a0) /* t9 = destination (r5g6b5) */ - addiu a1, a1, 4 - addiu a2, a2, 2 - - CONVERT_2x0565_TO_2x8888 t0, t1, s0, s1, t5, t6, s2, s3, s4, s5 - CONVERT_2x0565_TO_2x8888 t8, t9, s2, s3, t5, t6, s4, s5, s6, s7 - MIPS_2xUN8x4_MUL_2xUN8_ADD_2xUN8x4 s0, s1, \ - t2, t3, \ - s2, s3, \ - t0, t1, \ - t7, s4, s5, s6, s7, t8, t9 - CONVERT_2x8888_TO_2x0565 t0, t1, s0, s1, t4, t5, t6, s2, s3 - - sh s0, 0(a0) - sh s1, 2(a0) - addiu a3, a3, -2 - addiu t1, a3, -1 - bgtz t1, 1b - addiu a0, a0, 4 -2: - beqz a3, 3f - nop - lhu t0, 0(a1) /* t0 = source (r5g6b5) */ - lbu t1, 0(a2) /* t1 = mask (a8) */ - lhu t2, 0(a0) /* t2 = destination (r5g6b5) */ - - CONVERT_1x0565_TO_1x8888 t0, t3, t4, t5 - CONVERT_1x0565_TO_1x8888 t2, t4, t5, t6 - MIPS_UN8x4_MUL_UN8_ADD_UN8x4 t3, t1, t4, t0, t7, t2, t5, t6 - CONVERT_1x8888_TO_1x0565 t0, t3, t4, t5 - - sh t3, 0(a0) -3: - RESTORE_REGS_FROM_STACK 20, s0, s1, s2, s3, s4, s5, s6, s7 - j ra - nop - -END(pixman_composite_add_0565_8_0565_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_add_8888_8_8888_asm_mips) -/* - * a0 - dst (a8r8g8b8) - * a1 - src (a8r8g8b8) - * a2 - mask (a8) - * a3 - w - */ - - SAVE_REGS_ON_STACK 0, s0, s1, s2 - li t4, 0x00ff00ff - beqz a3, 3f - nop - addiu t1, a3, -1 - beqz t1, 2f - nop -1: - lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ - lw t1, 4(a1) /* t1 = source (a8r8g8b8) */ - lbu t2, 0(a2) /* t2 = mask (a8) */ - lbu t3, 1(a2) /* t3 = mask (a8) */ - lw t5, 0(a0) /* t5 = destination (a8r8g8b8) */ - lw t6, 4(a0) /* t6 = destination (a8r8g8b8) */ - addiu a1, a1, 8 - addiu a2, a2, 2 - - MIPS_2xUN8x4_MUL_2xUN8_ADD_2xUN8x4 t0, t1, \ - t2, t3, \ - t5, t6, \ - t7, t8, \ - t4, t9, s0, s1, s2, t0, t1 - - sw t7, 0(a0) - sw t8, 4(a0) - addiu a3, a3, -2 - addiu t1, a3, -1 - bgtz t1, 1b - addiu a0, a0, 8 -2: - beqz a3, 3f - nop - lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ - lbu t1, 0(a2) /* t1 = mask (a8) */ - lw t2, 0(a0) /* t2 = destination (a8r8g8b8) */ - - MIPS_UN8x4_MUL_UN8_ADD_UN8x4 t0, t1, t2, t3, t4, t5, t6, t7 - - sw t3, 0(a0) -3: - RESTORE_REGS_FROM_STACK 0, s0, s1, s2 - j ra - nop - -END(pixman_composite_add_8888_8_8888_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_add_8888_n_8888_asm_mips) -/* - * a0 - dst (a8r8g8b8) - * a1 - src (a8r8g8b8) - * a2 - mask (32bit constant) - * a3 - w - */ - - SAVE_REGS_ON_STACK 0, s0, s1, s2 - li t4, 0x00ff00ff - beqz a3, 3f - nop - srl a2, a2, 24 - addiu t1, a3, -1 - beqz t1, 2f - nop -1: - lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ - lw t1, 4(a1) /* t1 = source (a8r8g8b8) */ - /* a2 = mask (32bit constant) */ - lw t2, 0(a0) /* t2 = destination (a8r8g8b8) */ - lw t3, 4(a0) /* t3 = destination (a8r8g8b8) */ - addiu a1, a1, 8 - - MIPS_2xUN8x4_MUL_2xUN8_ADD_2xUN8x4 t0, t1, \ - a2, a2, \ - t2, t3, \ - t5, t6, \ - t4, t7, t8, t9, s0, s1, s2 - - sw t5, 0(a0) - sw t6, 4(a0) - addiu a3, a3, -2 - addiu t1, a3, -1 - bgtz t1, 1b - addiu a0, a0, 8 -2: - beqz a3, 3f - nop - lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ - /* a2 = mask (32bit constant) */ - lw t1, 0(a0) /* t1 = destination (a8r8g8b8) */ - - MIPS_UN8x4_MUL_UN8_ADD_UN8x4 t0, a2, t1, t3, t4, t5, t6, t7 - - sw t3, 0(a0) -3: - RESTORE_REGS_FROM_STACK 0, s0, s1, s2 - j ra - nop - -END(pixman_composite_add_8888_n_8888_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_add_8888_8888_8888_asm_mips) -/* - * a0 - dst (a8r8g8b8) - * a1 - src (a8r8g8b8) - * a2 - mask (a8r8g8b8) - * a3 - w - */ - - SAVE_REGS_ON_STACK 0, s0, s1, s2 - li t4, 0x00ff00ff - beqz a3, 3f - nop - addiu t1, a3, -1 - beqz t1, 2f - nop -1: - lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ - lw t1, 4(a1) /* t1 = source (a8r8g8b8) */ - lw t2, 0(a2) /* t2 = mask (a8r8g8b8) */ - lw t3, 4(a2) /* t3 = mask (a8r8g8b8) */ - lw t5, 0(a0) /* t5 = destination (a8r8g8b8) */ - lw t6, 4(a0) /* t6 = destination (a8r8g8b8) */ - addiu a1, a1, 8 - addiu a2, a2, 8 - srl t2, t2, 24 - srl t3, t3, 24 - - MIPS_2xUN8x4_MUL_2xUN8_ADD_2xUN8x4 t0, t1, \ - t2, t3, \ - t5, t6, \ - t7, t8, \ - t4, t9, s0, s1, s2, t0, t1 - - sw t7, 0(a0) - sw t8, 4(a0) - addiu a3, a3, -2 - addiu t1, a3, -1 - bgtz t1, 1b - addiu a0, a0, 8 -2: - beqz a3, 3f - nop - lw t0, 0(a1) /* t0 = source (a8r8g8b8) */ - lw t1, 0(a2) /* t1 = mask (a8r8g8b8) */ - lw t2, 0(a0) /* t2 = destination (a8r8g8b8) */ - srl t1, t1, 24 - - MIPS_UN8x4_MUL_UN8_ADD_UN8x4 t0, t1, t2, t3, t4, t5, t6, t7 - - sw t3, 0(a0) -3: - RESTORE_REGS_FROM_STACK 0, s0, s1, s2 - j ra - nop - -END(pixman_composite_add_8888_8888_8888_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_add_8_8_asm_mips) -/* - * a0 - dst (a8) - * a1 - src (a8) - * a2 - w - */ - - beqz a2, 3f - nop - srl t9, a2, 2 /* t9 = how many multiples of 4 dst pixels */ - beqz t9, 1f /* branch if less than 4 src pixels */ - nop - -0: - beqz t9, 1f - addiu t9, t9, -1 - lbu t0, 0(a1) - lbu t1, 1(a1) - lbu t2, 2(a1) - lbu t3, 3(a1) - lbu t4, 0(a0) - lbu t5, 1(a0) - lbu t6, 2(a0) - lbu t7, 3(a0) - - addiu a1, a1, 4 - - precr_sra.ph.w t1, t0, 0 - precr_sra.ph.w t3, t2, 0 - precr_sra.ph.w t5, t4, 0 - precr_sra.ph.w t7, t6, 0 - - precr.qb.ph t0, t3, t1 - precr.qb.ph t1, t7, t5 - - addu_s.qb t2, t0, t1 - - sb t2, 0(a0) - srl t2, t2, 8 - sb t2, 1(a0) - srl t2, t2, 8 - sb t2, 2(a0) - srl t2, t2, 8 - sb t2, 3(a0) - addiu a2, a2, -4 - b 0b - addiu a0, a0, 4 - -1: - beqz a2, 3f - nop -2: - lbu t0, 0(a1) - lbu t1, 0(a0) - addiu a1, a1, 1 - - addu_s.qb t2, t0, t1 - sb t2, 0(a0) - addiu a2, a2, -1 - bnez a2, 2b - addiu a0, a0, 1 - -3: - j ra - nop - -END(pixman_composite_add_8_8_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_add_8888_8888_asm_mips) -/* - * a0 - dst (a8r8g8b8) - * a1 - src (a8r8g8b8) - * a2 - w - */ - - beqz a2, 4f - nop - - srl t9, a2, 2 /* t1 = how many multiples of 4 src pixels */ - beqz t9, 3f /* branch if less than 4 src pixels */ - nop -1: - addiu t9, t9, -1 - beqz t9, 2f - addiu a2, a2, -4 - - lw t0, 0(a1) - lw t1, 4(a1) - lw t2, 8(a1) - lw t3, 12(a1) - lw t4, 0(a0) - lw t5, 4(a0) - lw t6, 8(a0) - lw t7, 12(a0) - addiu a1, a1, 16 - - addu_s.qb t4, t4, t0 - addu_s.qb t5, t5, t1 - addu_s.qb t6, t6, t2 - addu_s.qb t7, t7, t3 - - sw t4, 0(a0) - sw t5, 4(a0) - sw t6, 8(a0) - sw t7, 12(a0) - b 1b - addiu a0, a0, 16 -2: - lw t0, 0(a1) - lw t1, 4(a1) - lw t2, 8(a1) - lw t3, 12(a1) - lw t4, 0(a0) - lw t5, 4(a0) - lw t6, 8(a0) - lw t7, 12(a0) - addiu a1, a1, 16 - - addu_s.qb t4, t4, t0 - addu_s.qb t5, t5, t1 - addu_s.qb t6, t6, t2 - addu_s.qb t7, t7, t3 - - sw t4, 0(a0) - sw t5, 4(a0) - sw t6, 8(a0) - sw t7, 12(a0) - - beqz a2, 4f - addiu a0, a0, 16 -3: - lw t0, 0(a1) - lw t1, 0(a0) - addiu a1, a1, 4 - addiu a2, a2, -1 - addu_s.qb t1, t1, t0 - sw t1, 0(a0) - bnez a2, 3b - addiu a0, a0, 4 -4: - jr ra - nop - -END(pixman_composite_add_8888_8888_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_out_reverse_8_0565_asm_mips) -/* - * a0 - dst (r5g6b5) - * a1 - src (a8) - * a2 - w - */ - - beqz a2, 4f - nop - - SAVE_REGS_ON_STACK 0, s0, s1, s2, s3 - li t2, 0xf800f800 - li t3, 0x07e007e0 - li t4, 0x001F001F - li t5, 0x00ff00ff - - addiu t1, a2, -1 - beqz t1, 2f - nop -1: - lbu t0, 0(a1) /* t0 = source (a8) */ - lbu t1, 1(a1) /* t1 = source (a8) */ - lhu t6, 0(a0) /* t6 = destination (r5g6b5) */ - lhu t7, 2(a0) /* t7 = destination (r5g6b5) */ - addiu a1, a1, 2 - - not t0, t0 - not t1, t1 - andi t0, 0xff /* t0 = neg source1 */ - andi t1, 0xff /* t1 = neg source2 */ - CONVERT_2x0565_TO_2x8888 t6, t7, t8, t9, t3, t4, s0, s1, s2, s3 - MIPS_2xUN8x4_MUL_2xUN8 t8, t9, t0, t1, t6, t7, t5, s0, s1, s2, s3, t8, t9 - CONVERT_2x8888_TO_2x0565 t6, t7, t8, t9, t2, t3, t4, s0, s1 - - sh t8, 0(a0) - sh t9, 2(a0) - addiu a2, a2, -2 - addiu t1, a2, -1 - bgtz t1, 1b - addiu a0, a0, 4 -2: - beqz a2, 3f - nop - lbu t0, 0(a1) /* t0 = source (a8) */ - lhu t1, 0(a0) /* t1 = destination (r5g6b5) */ - - not t0, t0 - andi t0, 0xff /* t0 = neg source */ - CONVERT_1x0565_TO_1x8888 t1, t2, t3, t4 - MIPS_UN8x4_MUL_UN8 t2, t0, t1, t5, t3, t4, t6 - CONVERT_1x8888_TO_1x0565 t1, t2, t3, t4 - - sh t2, 0(a0) -3: - RESTORE_REGS_FROM_STACK 0, s0, s1, s2, s3 -4: - j ra - nop - -END(pixman_composite_out_reverse_8_0565_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_out_reverse_8_8888_asm_mips) -/* - * a0 - dst (a8r8g8b8) - * a1 - src (a8) - * a2 - w - */ - - beqz a2, 3f - nop - li t4, 0x00ff00ff - addiu t1, a2, -1 - beqz t1, 2f - nop -1: - lbu t0, 0(a1) /* t0 = source (a8) */ - lbu t1, 1(a1) /* t1 = source (a8) */ - lw t2, 0(a0) /* t2 = destination (a8r8g8b8) */ - lw t3, 4(a0) /* t3 = destination (a8r8g8b8) */ - addiu a1, a1, 2 - not t0, t0 - not t1, t1 - andi t0, 0xff /* t0 = neg source */ - andi t1, 0xff /* t1 = neg source */ - - MIPS_2xUN8x4_MUL_2xUN8 t2, t3, t0, t1, t5, t6, t4, t7, t8, t9, t2, t3, t0 - - sw t5, 0(a0) - sw t6, 4(a0) - addiu a2, a2, -2 - addiu t1, a2, -1 - bgtz t1, 1b - addiu a0, a0, 8 -2: - beqz a2, 3f - nop - lbu t0, 0(a1) /* t0 = source (a8) */ - lw t1, 0(a0) /* t1 = destination (a8r8g8b8) */ - not t0, t0 - andi t0, 0xff /* t0 = neg source */ - - MIPS_UN8x4_MUL_UN8 t1, t0, t2, t4, t3, t5, t6 - - sw t2, 0(a0) -3: - j ra - nop - -END(pixman_composite_out_reverse_8_8888_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_over_reverse_n_8888_asm_mips) -/* - * a0 - dst (a8r8g8b8) - * a1 - src (32bit constant) - * a2 - w - */ - - beqz a2, 5f - nop - - SAVE_REGS_ON_STACK 20, s0, s1, s2, s3, s4, s5, s6, s7 - li t0, 0x00ff00ff - srl t9, a2, 2 /* t9 = how many multiples of 4 src pixels */ - beqz t9, 2f /* branch if less than 4 src pixels */ - nop -1: - beqz t9, 2f - addiu t9, t9, -1 - - lw t1, 0(a0) - lw t2, 4(a0) - lw t3, 8(a0) - lw t4, 12(a0) - - addiu a2, a2, -4 - - not t5, t1 - not t6, t2 - not t7, t3 - not t8, t4 - srl t5, t5, 24 - srl t6, t6, 24 - srl t7, t7, 24 - srl t8, t8, 24 - replv.ph t5, t5 - replv.ph t6, t6 - replv.ph t7, t7 - replv.ph t8, t8 - muleu_s.ph.qbl s0, a1, t5 - muleu_s.ph.qbr s1, a1, t5 - muleu_s.ph.qbl s2, a1, t6 - muleu_s.ph.qbr s3, a1, t6 - muleu_s.ph.qbl s4, a1, t7 - muleu_s.ph.qbr s5, a1, t7 - muleu_s.ph.qbl s6, a1, t8 - muleu_s.ph.qbr s7, a1, t8 - - shra_r.ph t5, s0, 8 - shra_r.ph t6, s1, 8 - shra_r.ph t7, s2, 8 - shra_r.ph t8, s3, 8 - and t5, t5, t0 - and t6, t6, t0 - and t7, t7, t0 - and t8, t8, t0 - addq.ph s0, s0, t5 - addq.ph s1, s1, t6 - addq.ph s2, s2, t7 - addq.ph s3, s3, t8 - shra_r.ph s0, s0, 8 - shra_r.ph s1, s1, 8 - shra_r.ph s2, s2, 8 - shra_r.ph s3, s3, 8 - shra_r.ph t5, s4, 8 - shra_r.ph t6, s5, 8 - shra_r.ph t7, s6, 8 - shra_r.ph t8, s7, 8 - and t5, t5, t0 - and t6, t6, t0 - and t7, t7, t0 - and t8, t8, t0 - addq.ph s4, s4, t5 - addq.ph s5, s5, t6 - addq.ph s6, s6, t7 - addq.ph s7, s7, t8 - shra_r.ph s4, s4, 8 - shra_r.ph s5, s5, 8 - shra_r.ph s6, s6, 8 - shra_r.ph s7, s7, 8 - - precr.qb.ph t5, s0, s1 - precr.qb.ph t6, s2, s3 - precr.qb.ph t7, s4, s5 - precr.qb.ph t8, s6, s7 - addu_s.qb t5, t1, t5 - addu_s.qb t6, t2, t6 - addu_s.qb t7, t3, t7 - addu_s.qb t8, t4, t8 - - sw t5, 0(a0) - sw t6, 4(a0) - sw t7, 8(a0) - sw t8, 12(a0) - b 1b - addiu a0, a0, 16 - -2: - beqz a2, 4f - nop -3: - lw t1, 0(a0) - - not t2, t1 - srl t2, t2, 24 - replv.ph t2, t2 - - muleu_s.ph.qbl t4, a1, t2 - muleu_s.ph.qbr t5, a1, t2 - shra_r.ph t6, t4, 8 - shra_r.ph t7, t5, 8 - - and t6,t6,t0 - and t7,t7,t0 - - addq.ph t8, t4, t6 - addq.ph t9, t5, t7 - - shra_r.ph t8, t8, 8 - shra_r.ph t9, t9, 8 - - precr.qb.ph t9, t8, t9 - - addu_s.qb t9, t1, t9 - sw t9, 0(a0) - - addiu a2, a2, -1 - bnez a2, 3b - addiu a0, a0, 4 -4: - RESTORE_REGS_FROM_STACK 20, s0, s1, s2, s3, s4, s5, s6, s7 -5: - j ra - nop - -END(pixman_composite_over_reverse_n_8888_asm_mips) - -LEAF_MIPS_DSPR2(pixman_composite_in_n_8_asm_mips) -/* - * a0 - dst (a8) - * a1 - src (32bit constant) - * a2 - w - */ - - li t9, 0x00ff00ff - beqz a2, 3f - nop - srl t7, a2, 2 /* t7 = how many multiples of 4 dst pixels */ - beqz t7, 1f /* branch if less than 4 src pixels */ - nop - - srl t8, a1, 24 - replv.ph t8, t8 - -0: - beqz t7, 1f - addiu t7, t7, -1 - lbu t0, 0(a0) - lbu t1, 1(a0) - lbu t2, 2(a0) - lbu t3, 3(a0) - - precr_sra.ph.w t1, t0, 0 - precr_sra.ph.w t3, t2, 0 - precr.qb.ph t0, t3, t1 - - muleu_s.ph.qbl t2, t0, t8 - muleu_s.ph.qbr t3, t0, t8 - shra_r.ph t4, t2, 8 - shra_r.ph t5, t3, 8 - and t4, t4, t9 - and t5, t5, t9 - addq.ph t2, t2, t4 - addq.ph t3, t3, t5 - shra_r.ph t2, t2, 8 - shra_r.ph t3, t3, 8 - precr.qb.ph t2, t2, t3 - - sb t2, 0(a0) - srl t2, t2, 8 - sb t2, 1(a0) - srl t2, t2, 8 - sb t2, 2(a0) - srl t2, t2, 8 - sb t2, 3(a0) - addiu a2, a2, -4 - b 0b - addiu a0, a0, 4 - -1: - beqz a2, 3f - nop - srl t8, a1, 24 -2: - lbu t0, 0(a0) - - mul t2, t0, t8 - shra_r.ph t3, t2, 8 - andi t3, t3, 0x00ff - addq.ph t2, t2, t3 - shra_r.ph t2, t2, 8 - - sb t2, 0(a0) - addiu a2, a2, -1 - bnez a2, 2b - addiu a0, a0, 1 - -3: - j ra - nop - -END(pixman_composite_in_n_8_asm_mips) - -LEAF_MIPS_DSPR2(pixman_scaled_nearest_scanline_8888_8888_OVER_asm_mips) -/* - * a0 - dst (a8r8g8b8) - * a1 - src (a8r8g8b8) - * a2 - w - * a3 - vx - * 16(sp) - unit_x - */ - - SAVE_REGS_ON_STACK 0, s0, s1, s2, s3 - lw t8, 16(sp) /* t8 = unit_x */ - li t6, 0x00ff00ff - beqz a2, 3f - nop - addiu t1, a2, -1 - beqz t1, 2f - nop -1: - sra t0, a3, 16 /* t0 = vx >> 16 */ - sll t0, t0, 2 /* t0 = t0 * 4 (a8r8g8b8) */ - addu t0, a1, t0 - lw t0, 0(t0) /* t0 = source (a8r8g8b8) */ - addu a3, a3, t8 /* a3 = vx + unit_x */ - - sra t1, a3, 16 /* t0 = vx >> 16 */ - sll t1, t1, 2 /* t0 = t0 * 4 (a8r8g8b8) */ - addu t1, a1, t1 - lw t1, 0(t1) /* t1 = source (a8r8g8b8) */ - addu a3, a3, t8 /* a3 = vx + unit_x */ - - lw t2, 0(a0) /* t2 = destination (a8r8g8b8) */ - lw t3, 4(a0) /* t3 = destination (a8r8g8b8) */ - - OVER_2x8888_2x8888 t0, t1, t2, t3, t4, t5, t6, t7, t9, s0, s1, s2, s3 - - sw t4, 0(a0) - sw t5, 4(a0) - addiu a2, a2, -2 - addiu t1, a2, -1 - bgtz t1, 1b - addiu a0, a0, 8 -2: - beqz a2, 3f - nop - sra t0, a3, 16 /* t0 = vx >> 16 */ - sll t0, t0, 2 /* t0 = t0 * 4 (a8r8g8b8) */ - addu t0, a1, t0 - lw t0, 0(t0) /* t0 = source (a8r8g8b8) */ - lw t1, 0(a0) /* t1 = destination (a8r8g8b8) */ - addu a3, a3, t8 /* a3 = vx + unit_x */ - - OVER_8888_8888 t0, t1, t2, t6, t4, t5, t3, t7 - - sw t2, 0(a0) -3: - RESTORE_REGS_FROM_STACK 0, s0, s1, s2, s3 - j ra - nop - -END(pixman_scaled_nearest_scanline_8888_8888_OVER_asm_mips) - -LEAF_MIPS_DSPR2(pixman_scaled_nearest_scanline_8888_0565_OVER_asm_mips) -/* - * a0 - dst (r5g6b5) - * a1 - src (a8r8g8b8) - * a2 - w - * a3 - vx - * 16(sp) - unit_x - */ - - SAVE_REGS_ON_STACK 24, s0, s1, s2, s3, s4, v0, v1 - lw t8, 40(sp) /* t8 = unit_x */ - li t4, 0x00ff00ff - li t5, 0xf800f800 - li t6, 0x07e007e0 - li t7, 0x001F001F - beqz a2, 3f - nop - addiu t1, a2, -1 - beqz t1, 2f - nop -1: - sra t0, a3, 16 /* t0 = vx >> 16 */ - sll t0, t0, 2 /* t0 = t0 * 4 (a8r8g8b8) */ - addu t0, a1, t0 - lw t0, 0(t0) /* t0 = source (a8r8g8b8) */ - addu a3, a3, t8 /* a3 = vx + unit_x */ - sra t1, a3, 16 /* t0 = vx >> 16 */ - sll t1, t1, 2 /* t0 = t0 * 4 (a8r8g8b8) */ - addu t1, a1, t1 - lw t1, 0(t1) /* t1 = source (a8r8g8b8) */ - addu a3, a3, t8 /* a3 = vx + unit_x */ - lhu t2, 0(a0) /* t2 = destination (r5g6b5) */ - lhu t3, 2(a0) /* t3 = destination (r5g6b5) */ - - CONVERT_2x0565_TO_2x8888 t2, t3, v0, v1, t6, t7, s0, s1, s2, s3 - OVER_2x8888_2x8888 t0, t1, v0, v1, t2, t3, t4, t9, s0, s1, s2, s3, s4 - CONVERT_2x8888_TO_2x0565 t2, t3, v0, v1, t5, t6, t7, t9, s2 - - sh v0, 0(a0) - sh v1, 2(a0) - addiu a2, a2, -2 - addiu t1, a2, -1 - bgtz t1, 1b - addiu a0, a0, 4 -2: - beqz a2, 3f - nop - sra t0, a3, 16 /* t0 = vx >> 16 */ - sll t0, t0, 2 /* t0 = t0 * 4 (a8r8g8b8) */ - addu t0, a1, t0 - lw t0, 0(t0) /* t0 = source (a8r8g8b8) */ - lhu t1, 0(a0) /* t1 = destination (r5g6b5) */ - addu a3, a3, t8 /* a3 = vx + unit_x */ - - CONVERT_1x0565_TO_1x8888 t1, t2, t5, t6 - OVER_8888_8888 t0, t2, t1, t4, t3, t5, t6, t7 - CONVERT_1x8888_TO_1x0565 t1, t2, t5, t6 - - sh t2, 0(a0) -3: - RESTORE_REGS_FROM_STACK 24, s0, s1, s2, s3, s4, v0, v1 - j ra - nop - -END(pixman_scaled_nearest_scanline_8888_0565_OVER_asm_mips) - -LEAF_MIPS_DSPR2(pixman_scaled_nearest_scanline_0565_8888_SRC_asm_mips) -/* - * a0 - dst (a8r8g8b8) - * a1 - src (r5g6b5) - * a2 - w - * a3 - vx - * 16(sp) - unit_x - */ - - SAVE_REGS_ON_STACK 0, v0 - beqz a2, 3f - nop - - lw v0, 16(sp) /* v0 = unit_x */ - addiu t1, a2, -1 - beqz t1, 2f - nop - - li t4, 0x07e007e0 - li t5, 0x001F001F -1: - sra t0, a3, 16 /* t0 = vx >> 16 */ - sll t0, t0, 1 /* t0 = t0 * 2 ((r5g6b5)) */ - addu t0, a1, t0 - lhu t0, 0(t0) /* t0 = source ((r5g6b5)) */ - addu a3, a3, v0 /* a3 = vx + unit_x */ - sra t1, a3, 16 /* t1 = vx >> 16 */ - sll t1, t1, 1 /* t1 = t1 * 2 ((r5g6b5)) */ - addu t1, a1, t1 - lhu t1, 0(t1) /* t1 = source ((r5g6b5)) */ - addu a3, a3, v0 /* a3 = vx + unit_x */ - addiu a2, a2, -2 - - CONVERT_2x0565_TO_2x8888 t0, t1, t2, t3, t4, t5, t6, t7, t8, t9 - - sw t2, 0(a0) - sw t3, 4(a0) - - addiu t2, a2, -1 - bgtz t2, 1b - addiu a0, a0, 8 -2: - beqz a2, 3f - nop - sra t0, a3, 16 /* t0 = vx >> 16 */ - sll t0, t0, 1 /* t0 = t0 * 2 ((r5g6b5)) */ - addu t0, a1, t0 - lhu t0, 0(t0) /* t0 = source ((r5g6b5)) */ - - CONVERT_1x0565_TO_1x8888 t0, t1, t2, t3 - - sw t1, 0(a0) -3: - RESTORE_REGS_FROM_STACK 0, v0 - j ra - nop - -END(pixman_scaled_nearest_scanline_0565_8888_SRC_asm_mips) - -LEAF_MIPS_DSPR2(pixman_scaled_nearest_scanline_8888_8_0565_OVER_asm_mips) -/* - * a0 - dst (r5g6b5) - * a1 - src (a8r8g8b8) - * a2 - mask (a8) - * a3 - w - * 16(sp) - vx - * 20(sp) - unit_x - */ - beqz a3, 4f - nop - - SAVE_REGS_ON_STACK 20, v0, v1, s0, s1, s2, s3, s4, s5 - lw v0, 36(sp) /* v0 = vx */ - lw v1, 40(sp) /* v1 = unit_x */ - li t6, 0x00ff00ff - li t7, 0xf800f800 - li t8, 0x07e007e0 - li t9, 0x001F001F - - addiu t1, a3, -1 - beqz t1, 2f - nop -1: - sra t0, v0, 16 /* t0 = vx >> 16 */ - sll t0, t0, 2 /* t0 = t0 * 4 (a8r8g8b8) */ - addu t0, a1, t0 - lw t0, 0(t0) /* t0 = source (a8r8g8b8) */ - addu v0, v0, v1 /* v0 = vx + unit_x */ - sra t1, v0, 16 /* t1 = vx >> 16 */ - sll t1, t1, 2 /* t1 = t1 * 4 (a8r8g8b8) */ - addu t1, a1, t1 - lw t1, 0(t1) /* t1 = source (a8r8g8b8) */ - addu v0, v0, v1 /* v0 = vx + unit_x */ - lbu t2, 0(a2) /* t2 = mask (a8) */ - lbu t3, 1(a2) /* t3 = mask (a8) */ - lhu t4, 0(a0) /* t4 = destination (r5g6b5) */ - lhu t5, 2(a0) /* t5 = destination (r5g6b5) */ - addiu a2, a2, 2 - - CONVERT_2x0565_TO_2x8888 t4, t5, s0, s1, t8, t9, s2, s3, s4, s5 - OVER_2x8888_2x8_2x8888 t0, t1, \ - t2, t3, \ - s0, s1, \ - t4, t5, \ - t6, s2, s3, s4, s5, t2, t3 - CONVERT_2x8888_TO_2x0565 t4, t5, s0, s1, t7, t8, t9, s2, s3 - - sh s0, 0(a0) - sh s1, 2(a0) - addiu a3, a3, -2 - addiu t1, a3, -1 - bgtz t1, 1b - addiu a0, a0, 4 -2: - beqz a3, 3f - nop - sra t0, v0, 16 /* t0 = vx >> 16 */ - sll t0, t0, 2 /* t0 = t0 * 4 (a8r8g8b8) */ - addu t0, a1, t0 - lw t0, 0(t0) /* t0 = source (a8r8g8b8) */ - lbu t1, 0(a2) /* t1 = mask (a8) */ - lhu t2, 0(a0) /* t2 = destination (r5g6b5) */ - - CONVERT_1x0565_TO_1x8888 t2, t3, t4, t5 - OVER_8888_8_8888 t0, t1, t3, t2, t6, t4, t5, t7, t8 - CONVERT_1x8888_TO_1x0565 t2, t3, t4, t5 - - sh t3, 0(a0) -3: - RESTORE_REGS_FROM_STACK 20, v0, v1, s0, s1, s2, s3, s4, s5 -4: - j ra - nop - -END(pixman_scaled_nearest_scanline_8888_8_0565_OVER_asm_mips) - -LEAF_MIPS_DSPR2(pixman_scaled_nearest_scanline_0565_8_0565_OVER_asm_mips) -/* - * a0 - dst (r5g6b5) - * a1 - src (r5g6b5) - * a2 - mask (a8) - * a3 - w - * 16(sp) - vx - * 20(sp) - unit_x - */ - - beqz a3, 4f - nop - SAVE_REGS_ON_STACK 20, v0, v1, s0, s1, s2, s3, s4, s5 - lw v0, 36(sp) /* v0 = vx */ - lw v1, 40(sp) /* v1 = unit_x */ - li t4, 0xf800f800 - li t5, 0x07e007e0 - li t6, 0x001F001F - li t7, 0x00ff00ff - - addiu t1, a3, -1 - beqz t1, 2f - nop -1: - sra t0, v0, 16 /* t0 = vx >> 16 */ - sll t0, t0, 1 /* t0 = t0 * 2 (r5g6b5) */ - addu t0, a1, t0 - lhu t0, 0(t0) /* t0 = source (r5g6b5) */ - addu v0, v0, v1 /* v0 = vx + unit_x */ - sra t1, v0, 16 /* t1 = vx >> 16 */ - sll t1, t1, 1 /* t1 = t1 * 2 (r5g6b5) */ - addu t1, a1, t1 - lhu t1, 0(t1) /* t1 = source (r5g6b5) */ - addu v0, v0, v1 /* v0 = vx + unit_x */ - lbu t2, 0(a2) /* t2 = mask (a8) */ - lbu t3, 1(a2) /* t3 = mask (a8) */ - lhu t8, 0(a0) /* t8 = destination (r5g6b5) */ - lhu t9, 2(a0) /* t9 = destination (r5g6b5) */ - addiu a2, a2, 2 - - CONVERT_2x0565_TO_2x8888 t0, t1, s0, s1, t5, t6, s2, s3, s4, s5 - CONVERT_2x0565_TO_2x8888 t8, t9, s2, s3, t5, t6, s4, s5, t0, t1 - OVER_2x8888_2x8_2x8888 s0, s1, \ - t2, t3, \ - s2, s3, \ - t0, t1, \ - t7, t8, t9, s4, s5, s0, s1 - CONVERT_2x8888_TO_2x0565 t0, t1, s0, s1, t4, t5, t6, s2, s3 - - sh s0, 0(a0) - sh s1, 2(a0) - addiu a3, a3, -2 - addiu t1, a3, -1 - bgtz t1, 1b - addiu a0, a0, 4 -2: - beqz a3, 3f - nop - sra t0, v0, 16 /* t0 = vx >> 16 */ - sll t0, t0, 1 /* t0 = t0 * 2 (r5g6b5) */ - addu t0, a1, t0 - - lhu t0, 0(t0) /* t0 = source (r5g6b5) */ - lbu t1, 0(a2) /* t1 = mask (a8) */ - lhu t2, 0(a0) /* t2 = destination (r5g6b5) */ - - CONVERT_1x0565_TO_1x8888 t0, t3, t4, t5 - CONVERT_1x0565_TO_1x8888 t2, t4, t5, t6 - OVER_8888_8_8888 t3, t1, t4, t0, t7, t2, t5, t6, t8 - CONVERT_1x8888_TO_1x0565 t0, t3, t4, t5 - - sh t3, 0(a0) -3: - RESTORE_REGS_FROM_STACK 20, v0, v1, s0, s1, s2, s3, s4, s5 -4: - j ra - nop - -END(pixman_scaled_nearest_scanline_0565_8_0565_OVER_asm_mips) - -LEAF_MIPS_DSPR2(pixman_scaled_bilinear_scanline_8888_8888_SRC_asm_mips) -/* - * a0 - *dst - * a1 - *src_top - * a2 - *src_bottom - * a3 - w - * 16(sp) - wt - * 20(sp) - wb - * 24(sp) - vx - * 28(sp) - unit_x - */ - - beqz a3, 1f - nop - - SAVE_REGS_ON_STACK 20, v0, s0, s1, s2, s3, s4, s5, s6, s7 - - lw s0, 36(sp) /* s0 = wt */ - lw s1, 40(sp) /* s1 = wb */ - lw s2, 44(sp) /* s2 = vx */ - lw s3, 48(sp) /* s3 = unit_x */ - li v0, BILINEAR_INTERPOLATION_RANGE - - sll s0, s0, (2 * (8 - BILINEAR_INTERPOLATION_BITS)) - sll s1, s1, (2 * (8 - BILINEAR_INTERPOLATION_BITS)) -0: - andi t4, s2, 0xffff /* t4 = (short)vx */ - srl t4, t4, (16 - BILINEAR_INTERPOLATION_BITS) /* t4 = vx >> 8 */ - subu t5, v0, t4 /* t5 = ( 256 - (vx>>8)) */ - - mul s4, s0, t5 /* s4 = wt*(256-(vx>>8)) */ - mul s5, s0, t4 /* s5 = wt*(vx>>8) */ - mul s6, s1, t5 /* s6 = wb*(256-(vx>>8)) */ - mul s7, s1, t4 /* s7 = wb*(vx>>8) */ - - sra t9, s2, 16 - sll t9, t9, 2 - addiu t8, t9, 4 - lwx t0, t9(a1) /* t0 = tl */ - lwx t1, t8(a1) /* t1 = tr */ - addiu a3, a3, -1 - lwx t2, t9(a2) /* t2 = bl */ - lwx t3, t8(a2) /* t3 = br */ - - BILINEAR_INTERPOLATE_SINGLE_PIXEL t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, s4, s5, s6, s7 - - addu s2, s2, s3 /* vx += unit_x; */ - sw t0, 0(a0) - bnez a3, 0b - addiu a0, a0, 4 - - RESTORE_REGS_FROM_STACK 20, v0, s0, s1, s2, s3, s4, s5, s6, s7 -1: - j ra - nop - -END(pixman_scaled_bilinear_scanline_8888_8888_SRC_asm_mips) - -LEAF_MIPS_DSPR2(pixman_scaled_bilinear_scanline_8888_0565_SRC_asm_mips) -/* - * a0 - *dst - * a1 - *src_top - * a2 - *src_bottom - * a3 - w - * 16(sp) - wt - * 20(sp) - wb - * 24(sp) - vx - * 28(sp) - unit_x - */ - - beqz a3, 1f - nop - - SAVE_REGS_ON_STACK 20, v0, s0, s1, s2, s3, s4, s5, s6, s7 - - lw s0, 36(sp) /* s0 = wt */ - lw s1, 40(sp) /* s1 = wb */ - lw s2, 44(sp) /* s2 = vx */ - lw s3, 48(sp) /* s3 = unit_x */ - li v0, BILINEAR_INTERPOLATION_RANGE - - sll s0, s0, (2 * (8 - BILINEAR_INTERPOLATION_BITS)) - sll s1, s1, (2 * (8 - BILINEAR_INTERPOLATION_BITS)) -0: - andi t4, s2, 0xffff /* t4 = (short)vx */ - srl t4, t4, (16 - BILINEAR_INTERPOLATION_BITS) /* t4 = vx >> 8 */ - subu t5, v0, t4 /* t5 = ( 256 - (vx>>8)) */ - - mul s4, s0, t5 /* s4 = wt*(256-(vx>>8)) */ - mul s5, s0, t4 /* s5 = wt*(vx>>8) */ - mul s6, s1, t5 /* s6 = wb*(256-(vx>>8)) */ - mul s7, s1, t4 /* s7 = wb*(vx>>8) */ - - sra t9, s2, 16 - sll t9, t9, 2 - addiu t8, t9, 4 - lwx t0, t9(a1) /* t0 = tl */ - lwx t1, t8(a1) /* t1 = tr */ - addiu a3, a3, -1 - lwx t2, t9(a2) /* t2 = bl */ - lwx t3, t8(a2) /* t3 = br */ - - BILINEAR_INTERPOLATE_SINGLE_PIXEL t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, s4, s5, s6, s7 - CONVERT_1x8888_TO_1x0565 t0, t1, t2, t3 - - addu s2, s2, s3 /* vx += unit_x; */ - sh t1, 0(a0) - bnez a3, 0b - addiu a0, a0, 2 - - RESTORE_REGS_FROM_STACK 20, v0, s0, s1, s2, s3, s4, s5, s6, s7 -1: - j ra - nop - -END(pixman_scaled_bilinear_scanline_8888_0565_SRC_asm_mips) - -LEAF_MIPS_DSPR2(pixman_scaled_bilinear_scanline_0565_8888_SRC_asm_mips) -/* - * a0 - *dst - * a1 - *src_top - * a2 - *src_bottom - * a3 - w - * 16(sp) - wt - * 20(sp) - wb - * 24(sp) - vx - * 28(sp) - unit_x - */ - - beqz a3, 1f - nop - - SAVE_REGS_ON_STACK 28, v0, v1, s0, s1, s2, s3, s4, s5, s6, s7, s8 - - lw s0, 44(sp) /* s0 = wt */ - lw s1, 48(sp) /* s1 = wb */ - lw s2, 52(sp) /* s2 = vx */ - lw s3, 56(sp) /* s3 = unit_x */ - li v0, BILINEAR_INTERPOLATION_RANGE - li v1, 0x07e007e0 - li s8, 0x001f001f - - sll s0, s0, (2 * (8 - BILINEAR_INTERPOLATION_BITS)) - sll s1, s1, (2 * (8 - BILINEAR_INTERPOLATION_BITS)) -0: - andi t4, s2, 0xffff /* t4 = (short)vx */ - srl t4, t4, (16 - BILINEAR_INTERPOLATION_BITS) /* t4 = vx >> 8 */ - subu t5, v0, t4 /* t5 = ( 256 - (vx>>8)) */ - - mul s4, s0, t5 /* s4 = wt*(256-(vx>>8)) */ - mul s5, s0, t4 /* s5 = wt*(vx>>8) */ - mul s6, s1, t5 /* s6 = wb*(256-(vx>>8)) */ - mul s7, s1, t4 /* s7 = wb*(vx>>8) */ - - sra t9, s2, 16 - sll t9, t9, 1 - addiu t8, t9, 2 - lhx t0, t9(a1) /* t0 = tl */ - lhx t1, t8(a1) /* t1 = tr */ - andi t1, t1, 0xffff - addiu a3, a3, -1 - lhx t2, t9(a2) /* t2 = bl */ - lhx t3, t8(a2) /* t3 = br */ - andi t3, t3, 0xffff - - CONVERT_2x0565_TO_2x8888 t0, t1, t0, t1, v1, s8, t4, t5, t6, t7 - CONVERT_2x0565_TO_2x8888 t2, t3, t2, t3, v1, s8, t4, t5, t6, t7 - BILINEAR_INTERPOLATE_SINGLE_PIXEL t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, s4, s5, s6, s7 - - addu s2, s2, s3 /* vx += unit_x; */ - sw t0, 0(a0) - bnez a3, 0b - addiu a0, a0, 4 - - RESTORE_REGS_FROM_STACK 28, v0, v1, s0, s1, s2, s3, s4, s5, s6, s7, s8 -1: - j ra - nop - -END(pixman_scaled_bilinear_scanline_0565_8888_SRC_asm_mips) - -LEAF_MIPS_DSPR2(pixman_scaled_bilinear_scanline_0565_0565_SRC_asm_mips) -/* - * a0 - *dst - * a1 - *src_top - * a2 - *src_bottom - * a3 - w - * 16(sp) - wt - * 20(sp) - wb - * 24(sp) - vx - * 28(sp) - unit_x - */ - - beqz a3, 1f - nop - - SAVE_REGS_ON_STACK 28, v0, v1, s0, s1, s2, s3, s4, s5, s6, s7, s8 - - lw s0, 44(sp) /* s0 = wt */ - lw s1, 48(sp) /* s1 = wb */ - lw s2, 52(sp) /* s2 = vx */ - lw s3, 56(sp) /* s3 = unit_x */ - li v0, BILINEAR_INTERPOLATION_RANGE - li v1, 0x07e007e0 - li s8, 0x001f001f - - sll s0, s0, (2 * (8 - BILINEAR_INTERPOLATION_BITS)) - sll s1, s1, (2 * (8 - BILINEAR_INTERPOLATION_BITS)) -0: - andi t4, s2, 0xffff /* t4 = (short)vx */ - srl t4, t4, (16 - BILINEAR_INTERPOLATION_BITS) /* t4 = vx >> 8 */ - subu t5, v0, t4 /* t5 = ( 256 - (vx>>8)) */ - - mul s4, s0, t5 /* s4 = wt*(256-(vx>>8)) */ - mul s5, s0, t4 /* s5 = wt*(vx>>8) */ - mul s6, s1, t5 /* s6 = wb*(256-(vx>>8)) */ - mul s7, s1, t4 /* s7 = wb*(vx>>8) */ - - sra t9, s2, 16 - sll t9, t9, 1 - addiu t8, t9, 2 - lhx t0, t9(a1) /* t0 = tl */ - lhx t1, t8(a1) /* t1 = tr */ - andi t1, t1, 0xffff - addiu a3, a3, -1 - lhx t2, t9(a2) /* t2 = bl */ - lhx t3, t8(a2) /* t3 = br */ - andi t3, t3, 0xffff - - CONVERT_2x0565_TO_2x8888 t0, t1, t0, t1, v1, s8, t4, t5, t6, t7 - CONVERT_2x0565_TO_2x8888 t2, t3, t2, t3, v1, s8, t4, t5, t6, t7 - BILINEAR_INTERPOLATE_SINGLE_PIXEL t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, s4, s5, s6, s7 - CONVERT_1x8888_TO_1x0565 t0, t1, t2, t3 - - addu s2, s2, s3 /* vx += unit_x; */ - sh t1, 0(a0) - bnez a3, 0b - addiu a0, a0, 2 - - RESTORE_REGS_FROM_STACK 28, v0, v1, s0, s1, s2, s3, s4, s5, s6, s7, s8 -1: - j ra - nop - -END(pixman_scaled_bilinear_scanline_0565_0565_SRC_asm_mips) - -LEAF_MIPS_DSPR2(pixman_scaled_bilinear_scanline_8888_8888_OVER_asm_mips) -/* - * a0 - *dst - * a1 - *src_top - * a2 - *src_bottom - * a3 - w - * 16(sp) - wt - * 20(sp) - wb - * 24(sp) - vx - * 28(sp) - unit_x - */ - - beqz a3, 1f - nop - - SAVE_REGS_ON_STACK 24, v0, s0, s1, s2, s3, s4, s5, s6, s7, s8 - - lw s0, 40(sp) /* s0 = wt */ - lw s1, 44(sp) /* s1 = wb */ - lw s2, 48(sp) /* s2 = vx */ - lw s3, 52(sp) /* s3 = unit_x */ - li v0, BILINEAR_INTERPOLATION_RANGE - li s8, 0x00ff00ff - - sll s0, s0, (2 * (8 - BILINEAR_INTERPOLATION_BITS)) - sll s1, s1, (2 * (8 - BILINEAR_INTERPOLATION_BITS)) -0: - andi t4, s2, 0xffff /* t4 = (short)vx */ - srl t4, t4, (16 - BILINEAR_INTERPOLATION_BITS) /* t4 = vx >> 8 */ - subu t5, v0, t4 /* t5 = ( 256 - (vx>>8)) */ - - mul s4, s0, t5 /* s4 = wt*(256-(vx>>8)) */ - mul s5, s0, t4 /* s5 = wt*(vx>>8) */ - mul s6, s1, t5 /* s6 = wb*(256-(vx>>8)) */ - mul s7, s1, t4 /* s7 = wb*(vx>>8) */ - - sra t9, s2, 16 - sll t9, t9, 2 - addiu t8, t9, 4 - lwx t0, t9(a1) /* t0 = tl */ - lwx t1, t8(a1) /* t1 = tr */ - addiu a3, a3, -1 - lwx t2, t9(a2) /* t2 = bl */ - lwx t3, t8(a2) /* t3 = br */ - - BILINEAR_INTERPOLATE_SINGLE_PIXEL t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, s4, s5, s6, s7 - lw t1, 0(a0) /* t1 = dest */ - OVER_8888_8888 t0, t1, t2, s8, t3, t4, t5, t6 - - addu s2, s2, s3 /* vx += unit_x; */ - sw t2, 0(a0) - bnez a3, 0b - addiu a0, a0, 4 - - RESTORE_REGS_FROM_STACK 24, v0, s0, s1, s2, s3, s4, s5, s6, s7, s8 -1: - j ra - nop - -END(pixman_scaled_bilinear_scanline_8888_8888_OVER_asm_mips) - -LEAF_MIPS_DSPR2(pixman_scaled_bilinear_scanline_8888_8888_ADD_asm_mips) -/* - * a0 - *dst - * a1 - *src_top - * a2 - *src_bottom - * a3 - w - * 16(sp) - wt - * 20(sp) - wb - * 24(sp) - vx - * 28(sp) - unit_x - */ - - beqz a3, 1f - nop - - SAVE_REGS_ON_STACK 20, v0, s0, s1, s2, s3, s4, s5, s6, s7 - - lw s0, 36(sp) /* s0 = wt */ - lw s1, 40(sp) /* s1 = wb */ - lw s2, 44(sp) /* s2 = vx */ - lw s3, 48(sp) /* s3 = unit_x */ - li v0, BILINEAR_INTERPOLATION_RANGE - - sll s0, s0, (2 * (8 - BILINEAR_INTERPOLATION_BITS)) - sll s1, s1, (2 * (8 - BILINEAR_INTERPOLATION_BITS)) -0: - andi t4, s2, 0xffff /* t4 = (short)vx */ - srl t4, t4, (16 - BILINEAR_INTERPOLATION_BITS) /* t4 = vx >> 8 */ - subu t5, v0, t4 /* t5 = ( 256 - (vx>>8)) */ - - mul s4, s0, t5 /* s4 = wt*(256-(vx>>8)) */ - mul s5, s0, t4 /* s5 = wt*(vx>>8) */ - mul s6, s1, t5 /* s6 = wb*(256-(vx>>8)) */ - mul s7, s1, t4 /* s7 = wb*(vx>>8) */ - - sra t9, s2, 16 - sll t9, t9, 2 - addiu t8, t9, 4 - lwx t0, t9(a1) /* t0 = tl */ - lwx t1, t8(a1) /* t1 = tr */ - addiu a3, a3, -1 - lwx t2, t9(a2) /* t2 = bl */ - lwx t3, t8(a2) /* t3 = br */ - - BILINEAR_INTERPOLATE_SINGLE_PIXEL t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, s4, s5, s6, s7 - lw t1, 0(a0) - addu_s.qb t2, t0, t1 - - addu s2, s2, s3 /* vx += unit_x; */ - sw t2, 0(a0) - bnez a3, 0b - addiu a0, a0, 4 - - RESTORE_REGS_FROM_STACK 20, v0, s0, s1, s2, s3, s4, s5, s6, s7 -1: - j ra - nop - -END(pixman_scaled_bilinear_scanline_8888_8888_ADD_asm_mips) - -LEAF_MIPS_DSPR2(pixman_scaled_bilinear_scanline_8888_8_8888_SRC_asm_mips) -/* - * a0 - *dst - * a1 - *mask - * a2 - *src_top - * a3 - *src_bottom - * 16(sp) - wt - * 20(sp) - wb - * 24(sp) - vx - * 28(sp) - unit_x - * 32(sp) - w - */ - - lw v1, 32(sp) - beqz v1, 1f - nop - - SAVE_REGS_ON_STACK 28, v0, v1, s0, s1, s2, s3, s4, s5, s6, s7, s8 - - lw s0, 44(sp) /* s0 = wt */ - lw s1, 48(sp) /* s1 = wb */ - lw s2, 52(sp) /* s2 = vx */ - lw s3, 56(sp) /* s3 = unit_x */ - li v0, BILINEAR_INTERPOLATION_RANGE - li s8, 0x00ff00ff - - sll s0, s0, (2 * (8 - BILINEAR_INTERPOLATION_BITS)) - sll s1, s1, (2 * (8 - BILINEAR_INTERPOLATION_BITS)) -0: - andi t4, s2, 0xffff /* t4 = (short)vx */ - srl t4, t4, (16 - BILINEAR_INTERPOLATION_BITS) /* t4 = vx >> 8 */ - subu t5, v0, t4 /* t5 = ( 256 - (vx>>8)) */ - - mul s4, s0, t5 /* s4 = wt*(256-(vx>>8)) */ - mul s5, s0, t4 /* s5 = wt*(vx>>8) */ - mul s6, s1, t5 /* s6 = wb*(256-(vx>>8)) */ - mul s7, s1, t4 /* s7 = wb*(vx>>8) */ - - sra t9, s2, 16 - sll t9, t9, 2 - addiu t8, t9, 4 - lwx t0, t9(a2) /* t0 = tl */ - lwx t1, t8(a2) /* t1 = tr */ - addiu v1, v1, -1 - lwx t2, t9(a3) /* t2 = bl */ - lwx t3, t8(a3) /* t3 = br */ - - BILINEAR_INTERPOLATE_SINGLE_PIXEL t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, s4, s5, s6, s7 - lbu t1, 0(a1) /* t1 = mask */ - addiu a1, a1, 1 - MIPS_UN8x4_MUL_UN8 t0, t1, t0, s8, t2, t3, t4 - - addu s2, s2, s3 /* vx += unit_x; */ - sw t0, 0(a0) - bnez v1, 0b - addiu a0, a0, 4 - - RESTORE_REGS_FROM_STACK 28, v0, v1, s0, s1, s2, s3, s4, s5, s6, s7, s8 -1: - j ra - nop - -END(pixman_scaled_bilinear_scanline_8888_8_8888_SRC_asm_mips) - -LEAF_MIPS_DSPR2(pixman_scaled_bilinear_scanline_8888_8_0565_SRC_asm_mips) -/* - * a0 - *dst - * a1 - *mask - * a2 - *src_top - * a3 - *src_bottom - * 16(sp) - wt - * 20(sp) - wb - * 24(sp) - vx - * 28(sp) - unit_x - * 32(sp) - w - */ - - lw v1, 32(sp) - beqz v1, 1f - nop - - SAVE_REGS_ON_STACK 28, v0, v1, s0, s1, s2, s3, s4, s5, s6, s7, s8 - - lw s0, 44(sp) /* s0 = wt */ - lw s1, 48(sp) /* s1 = wb */ - lw s2, 52(sp) /* s2 = vx */ - lw s3, 56(sp) /* s3 = unit_x */ - li v0, BILINEAR_INTERPOLATION_RANGE - li s8, 0x00ff00ff - - sll s0, s0, (2 * (8 - BILINEAR_INTERPOLATION_BITS)) - sll s1, s1, (2 * (8 - BILINEAR_INTERPOLATION_BITS)) -0: - andi t4, s2, 0xffff /* t4 = (short)vx */ - srl t4, t4, (16 - BILINEAR_INTERPOLATION_BITS) /* t4 = vx >> 8 */ - subu t5, v0, t4 /* t5 = ( 256 - (vx>>8)) */ - - mul s4, s0, t5 /* s4 = wt*(256-(vx>>8)) */ - mul s5, s0, t4 /* s5 = wt*(vx>>8) */ - mul s6, s1, t5 /* s6 = wb*(256-(vx>>8)) */ - mul s7, s1, t4 /* s7 = wb*(vx>>8) */ - - sra t9, s2, 16 - sll t9, t9, 2 - addiu t8, t9, 4 - lwx t0, t9(a2) /* t0 = tl */ - lwx t1, t8(a2) /* t1 = tr */ - addiu v1, v1, -1 - lwx t2, t9(a3) /* t2 = bl */ - lwx t3, t8(a3) /* t3 = br */ - - BILINEAR_INTERPOLATE_SINGLE_PIXEL t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, s4, s5, s6, s7 - lbu t1, 0(a1) /* t1 = mask */ - addiu a1, a1, 1 - MIPS_UN8x4_MUL_UN8 t0, t1, t0, s8, t2, t3, t4 - CONVERT_1x8888_TO_1x0565 t0, t1, t2, t3 - - addu s2, s2, s3 /* vx += unit_x; */ - sh t1, 0(a0) - bnez v1, 0b - addiu a0, a0, 2 - - RESTORE_REGS_FROM_STACK 28, v0, v1, s0, s1, s2, s3, s4, s5, s6, s7, s8 -1: - j ra - nop - -END(pixman_scaled_bilinear_scanline_8888_8_0565_SRC_asm_mips) - -LEAF_MIPS_DSPR2(pixman_scaled_bilinear_scanline_0565_8_x888_SRC_asm_mips) -/* - * a0 - *dst - * a1 - *mask - * a2 - *src_top - * a3 - *src_bottom - * 16(sp) - wt - * 20(sp) - wb - * 24(sp) - vx - * 28(sp) - unit_x - * 32(sp) - w - */ - - lw t0, 32(sp) - beqz t0, 1f - nop - - SAVE_REGS_ON_STACK 32, v0, v1, s0, s1, s2, s3, s4, s5, s6, s7, s8, ra - - lw s0, 48(sp) /* s0 = wt */ - lw s1, 52(sp) /* s1 = wb */ - lw s2, 56(sp) /* s2 = vx */ - lw s3, 60(sp) /* s3 = unit_x */ - lw ra, 64(sp) /* ra = w */ - li v0, 0x00ff00ff - li v1, 0x07e007e0 - li s8, 0x001f001f - - sll s0, s0, (2 * (8 - BILINEAR_INTERPOLATION_BITS)) - sll s1, s1, (2 * (8 - BILINEAR_INTERPOLATION_BITS)) -0: - andi t4, s2, 0xffff /* t4 = (short)vx */ - srl t4, t4, (16 - BILINEAR_INTERPOLATION_BITS) /* t4 = vx >> 8 */ - li t5, BILINEAR_INTERPOLATION_RANGE - subu t5, t5, t4 /* t5 = ( 256 - (vx>>8)) */ - - mul s4, s0, t5 /* s4 = wt*(256-(vx>>8)) */ - mul s5, s0, t4 /* s5 = wt*(vx>>8) */ - mul s6, s1, t5 /* s6 = wb*(256-(vx>>8)) */ - mul s7, s1, t4 /* s7 = wb*(vx>>8) */ - - sra t9, s2, 16 - sll t9, t9, 1 - addiu t8, t9, 2 - lhx t0, t9(a2) /* t0 = tl */ - lhx t1, t8(a2) /* t1 = tr */ - andi t1, t1, 0xffff - addiu ra, ra, -1 - lhx t2, t9(a3) /* t2 = bl */ - lhx t3, t8(a3) /* t3 = br */ - andi t3, t3, 0xffff - - CONVERT_2x0565_TO_2x8888 t0, t1, t0, t1, v1, s8, t4, t5, t6, t7 - CONVERT_2x0565_TO_2x8888 t2, t3, t2, t3, v1, s8, t4, t5, t6, t7 - BILINEAR_INTERPOLATE_SINGLE_PIXEL t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, s4, s5, s6, s7 - lbu t1, 0(a1) /* t1 = mask */ - addiu a1, a1, 1 - MIPS_UN8x4_MUL_UN8 t0, t1, t0, v0, t2, t3, t4 - - addu s2, s2, s3 /* vx += unit_x; */ - sw t0, 0(a0) - bnez ra, 0b - addiu a0, a0, 4 - - RESTORE_REGS_FROM_STACK 32, v0, v1, s0, s1, s2, s3, s4, s5, s6, s7, s8, ra -1: - j ra - nop - -END(pixman_scaled_bilinear_scanline_0565_8_x888_SRC_asm_mips) - -LEAF_MIPS_DSPR2(pixman_scaled_bilinear_scanline_0565_8_0565_SRC_asm_mips) -/* - * a0 - *dst - * a1 - *mask - * a2 - *src_top - * a3 - *src_bottom - * 16(sp) - wt - * 20(sp) - wb - * 24(sp) - vx - * 28(sp) - unit_x - * 32(sp) - w - */ - - lw t0, 32(sp) - beqz t0, 1f - nop - - SAVE_REGS_ON_STACK 32, v0, v1, s0, s1, s2, s3, s4, s5, s6, s7, s8, ra - - lw s0, 48(sp) /* s0 = wt */ - lw s1, 52(sp) /* s1 = wb */ - lw s2, 56(sp) /* s2 = vx */ - lw s3, 60(sp) /* s3 = unit_x */ - lw ra, 64(sp) /* ra = w */ - li v0, 0x00ff00ff - li v1, 0x07e007e0 - li s8, 0x001f001f - - sll s0, s0, (2 * (8 - BILINEAR_INTERPOLATION_BITS)) - sll s1, s1, (2 * (8 - BILINEAR_INTERPOLATION_BITS)) -0: - andi t4, s2, 0xffff /* t4 = (short)vx */ - srl t4, t4, (16 - BILINEAR_INTERPOLATION_BITS) /* t4 = vx >> 8 */ - li t5, BILINEAR_INTERPOLATION_RANGE - subu t5, t5, t4 /* t5 = ( 256 - (vx>>8)) */ - - mul s4, s0, t5 /* s4 = wt*(256-(vx>>8)) */ - mul s5, s0, t4 /* s5 = wt*(vx>>8) */ - mul s6, s1, t5 /* s6 = wb*(256-(vx>>8)) */ - mul s7, s1, t4 /* s7 = wb*(vx>>8) */ - - sra t9, s2, 16 - sll t9, t9, 1 - addiu t8, t9, 2 - lhx t0, t9(a2) /* t0 = tl */ - lhx t1, t8(a2) /* t1 = tr */ - andi t1, t1, 0xffff - addiu ra, ra, -1 - lhx t2, t9(a3) /* t2 = bl */ - lhx t3, t8(a3) /* t3 = br */ - andi t3, t3, 0xffff - - CONVERT_2x0565_TO_2x8888 t0, t1, t0, t1, v1, s8, t4, t5, t6, t7 - CONVERT_2x0565_TO_2x8888 t2, t3, t2, t3, v1, s8, t4, t5, t6, t7 - BILINEAR_INTERPOLATE_SINGLE_PIXEL t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, s4, s5, s6, s7 - lbu t1, 0(a1) /* t1 = mask */ - addiu a1, a1, 1 - MIPS_UN8x4_MUL_UN8 t0, t1, t0, v0, t2, t3, t4 - CONVERT_1x8888_TO_1x0565 t0, t1, t2, t3 - - addu s2, s2, s3 /* vx += unit_x; */ - sh t1, 0(a0) - bnez ra, 0b - addiu a0, a0, 2 - - RESTORE_REGS_FROM_STACK 32, v0, v1, s0, s1, s2, s3, s4, s5, s6, s7, s8, ra -1: - j ra - nop - -END(pixman_scaled_bilinear_scanline_0565_8_0565_SRC_asm_mips) - -LEAF_MIPS_DSPR2(pixman_scaled_bilinear_scanline_8888_8_8888_OVER_asm_mips) -/* - * a0 - dst (a8r8g8b8) - * a1 - mask (a8) - * a2 - src_top (a8r8g8b8) - * a3 - src_bottom (a8r8g8b8) - * 16(sp) - wt - * 20(sp) - wb - * 24(sp) - vx - * 28(sp) - unit_x - * 32(sp) - w - */ - - SAVE_REGS_ON_STACK 28, v0, v1, s0, s1, s2, s3, s4, s5, s6, s7, s8 - - lw v1, 60(sp) /* v1 = w(sp + 32 + 28 save regs stack offset)*/ - beqz v1, 1f - nop - - lw s0, 44(sp) /* s0 = wt */ - lw s1, 48(sp) /* s1 = wb */ - lw s2, 52(sp) /* s2 = vx */ - lw s3, 56(sp) /* s3 = unit_x */ - li v0, BILINEAR_INTERPOLATION_RANGE - li s8, 0x00ff00ff - - sll s0, s0, (2 * (8 - BILINEAR_INTERPOLATION_BITS)) - sll s1, s1, (2 * (8 - BILINEAR_INTERPOLATION_BITS)) - -0: - andi t4, s2, 0xffff /* t4 = (short)vx */ - srl t4, t4, (16 - BILINEAR_INTERPOLATION_BITS) /* t4 = vx >> 8 */ - subu t5, v0, t4 /* t5 = ( 256 - (vx>>8)) */ - - mul s4, s0, t5 /* s4 = wt*(256-(vx>>8)) */ - mul s5, s0, t4 /* s5 = wt*(vx>>8) */ - mul s6, s1, t5 /* s6 = wb*(256-(vx>>8)) */ - mul s7, s1, t4 /* s7 = wb*(vx>>8) */ - - sra t9, s2, 16 - sll t9, t9, 2 - addiu t8, t9, 4 - lwx t0, t9(a2) /* t0 = tl */ - lwx t1, t8(a2) /* t1 = tr */ - addiu v1, v1, -1 - lwx t2, t9(a3) /* t2 = bl */ - lwx t3, t8(a3) /* t3 = br */ - - BILINEAR_INTERPOLATE_SINGLE_PIXEL t0, t1, t2, t3, \ - t4, t5, t6, t7, t8, t9, s4, s5, s6, s7 - lbu t1, 0(a1) /* t1 = mask */ - lw t2, 0(a0) /* t2 = dst */ - addiu a1, a1, 1 - OVER_8888_8_8888 t0, t1, t2, t0, s8, t3, t4, t5, t6 - - addu s2, s2, s3 /* vx += unit_x; */ - sw t0, 0(a0) - bnez v1, 0b - addiu a0, a0, 4 - -1: - RESTORE_REGS_FROM_STACK 28, v0, v1, s0, s1, s2, s3, s4, s5, s6, s7, s8 - j ra - nop - -END(pixman_scaled_bilinear_scanline_8888_8_8888_OVER_asm_mips) - -LEAF_MIPS_DSPR2(pixman_scaled_bilinear_scanline_8888_8_8888_ADD_asm_mips) -/* - * a0 - *dst - * a1 - *mask - * a2 - *src_top - * a3 - *src_bottom - * 16(sp) - wt - * 20(sp) - wb - * 24(sp) - vx - * 28(sp) - unit_x - * 32(sp) - w - */ - - lw v1, 32(sp) - beqz v1, 1f - nop - - SAVE_REGS_ON_STACK 28, v0, v1, s0, s1, s2, s3, s4, s5, s6, s7, s8 - - lw s0, 44(sp) /* s0 = wt */ - lw s1, 48(sp) /* s1 = wb */ - lw s2, 52(sp) /* s2 = vx */ - lw s3, 56(sp) /* s3 = unit_x */ - li v0, BILINEAR_INTERPOLATION_RANGE - li s8, 0x00ff00ff - - sll s0, s0, (2 * (8 - BILINEAR_INTERPOLATION_BITS)) - sll s1, s1, (2 * (8 - BILINEAR_INTERPOLATION_BITS)) -0: - andi t4, s2, 0xffff /* t4 = (short)vx */ - srl t4, t4, (16 - BILINEAR_INTERPOLATION_BITS) /* t4 = vx >> 8 */ - subu t5, v0, t4 /* t5 = ( 256 - (vx>>8)) */ - - mul s4, s0, t5 /* s4 = wt*(256-(vx>>8)) */ - mul s5, s0, t4 /* s5 = wt*(vx>>8) */ - mul s6, s1, t5 /* s6 = wb*(256-(vx>>8)) */ - mul s7, s1, t4 /* s7 = wb*(vx>>8) */ - - sra t9, s2, 16 - sll t9, t9, 2 - addiu t8, t9, 4 - lwx t0, t9(a2) /* t0 = tl */ - lwx t1, t8(a2) /* t1 = tr */ - addiu v1, v1, -1 - lwx t2, t9(a3) /* t2 = bl */ - lwx t3, t8(a3) /* t3 = br */ - - BILINEAR_INTERPOLATE_SINGLE_PIXEL t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, s4, s5, s6, s7 - lbu t1, 0(a1) /* t1 = mask */ - lw t2, 0(a0) /* t2 = dst */ - addiu a1, a1, 1 - MIPS_UN8x4_MUL_UN8_ADD_UN8x4 t0, t1, t2, t0, s8, t3, t4, t5 - - addu s2, s2, s3 /* vx += unit_x; */ - sw t0, 0(a0) - bnez v1, 0b - addiu a0, a0, 4 - - RESTORE_REGS_FROM_STACK 28, v0, v1, s0, s1, s2, s3, s4, s5, s6, s7, s8 -1: - j ra - nop - -END(pixman_scaled_bilinear_scanline_8888_8_8888_ADD_asm_mips) diff --git a/source/libs/pixman/pixman-src/pixman/pixman-mips-dspr2-asm.h b/source/libs/pixman/pixman-src/pixman/pixman-mips-dspr2-asm.h deleted file mode 100644 index e2385661966b3db402c9243f50d23fe2d09adf33..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-mips-dspr2-asm.h +++ /dev/null @@ -1,711 +0,0 @@ -/* - * Copyright (c) 2012 - * MIPS Technologies, Inc., California. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Author: Nemanja Lukic (nemanja.lukic@rt-rk.com) - */ - -#ifndef PIXMAN_MIPS_DSPR2_ASM_H -#define PIXMAN_MIPS_DSPR2_ASM_H - -#define zero $0 -#define AT $1 -#define v0 $2 -#define v1 $3 -#define a0 $4 -#define a1 $5 -#define a2 $6 -#define a3 $7 -#define t0 $8 -#define t1 $9 -#define t2 $10 -#define t3 $11 -#define t4 $12 -#define t5 $13 -#define t6 $14 -#define t7 $15 -#define s0 $16 -#define s1 $17 -#define s2 $18 -#define s3 $19 -#define s4 $20 -#define s5 $21 -#define s6 $22 -#define s7 $23 -#define t8 $24 -#define t9 $25 -#define k0 $26 -#define k1 $27 -#define gp $28 -#define sp $29 -#define fp $30 -#define s8 $30 -#define ra $31 - -/* - * LEAF_MIPS32R2 - declare leaf routine for MIPS32r2 - */ -#define LEAF_MIPS32R2(symbol) \ - .globl symbol; \ - .align 2; \ - .hidden symbol; \ - .type symbol, @function; \ - .ent symbol, 0; \ -symbol: .frame sp, 0, ra; \ - .set push; \ - .set arch=mips32r2; \ - .set noreorder; \ - .set noat; - -/* - * LEAF_MIPS32R2 - declare leaf routine for MIPS DSPr2 - */ -#define LEAF_MIPS_DSPR2(symbol) \ -LEAF_MIPS32R2(symbol) \ - .set dspr2; - -/* - * END - mark end of function - */ -#define END(function) \ - .set pop; \ - .end function; \ - .size function,.-function - -/* - * Checks if stack offset is big enough for storing/restoring regs_num - * number of register to/from stack. Stack offset must be greater than - * or equal to the number of bytes needed for storing registers (regs_num*4). - * Since MIPS ABI allows usage of first 16 bytes of stack frame (this is - * preserved for input arguments of the functions, already stored in a0-a3), - * stack size can be further optimized by utilizing this space. - */ -.macro CHECK_STACK_OFFSET regs_num, stack_offset -.if \stack_offset < \regs_num * 4 - 16 -.error "Stack offset too small." -.endif -.endm - -/* - * Saves set of registers on stack. Maximum number of registers that - * can be saved on stack is limitted to 14 (a0-a3, v0-v1 and s0-s7). - * Stack offset is number of bytes that are added to stack pointer (sp) - * before registers are pushed in order to provide enough space on stack - * (offset must be multiple of 4, and must be big enough, as described by - * CHECK_STACK_OFFSET macro). This macro is intended to be used in - * combination with RESTORE_REGS_FROM_STACK macro. Example: - * SAVE_REGS_ON_STACK 4, v0, v1, s0, s1 - * RESTORE_REGS_FROM_STACK 4, v0, v1, s0, s1 - */ -.macro SAVE_REGS_ON_STACK stack_offset = 0, r1, \ - r2 = 0, r3 = 0, r4 = 0, \ - r5 = 0, r6 = 0, r7 = 0, \ - r8 = 0, r9 = 0, r10 = 0, \ - r11 = 0, r12 = 0, r13 = 0, \ - r14 = 0 - .if (\stack_offset < 0) || (\stack_offset - (\stack_offset / 4) * 4) - .error "Stack offset must be pozitive and multiple of 4." - .endif - .if \stack_offset != 0 - addiu sp, sp, -\stack_offset - .endif - sw \r1, 0(sp) - .if \r2 != 0 - sw \r2, 4(sp) - .endif - .if \r3 != 0 - sw \r3, 8(sp) - .endif - .if \r4 != 0 - sw \r4, 12(sp) - .endif - .if \r5 != 0 - CHECK_STACK_OFFSET 5, \stack_offset - sw \r5, 16(sp) - .endif - .if \r6 != 0 - CHECK_STACK_OFFSET 6, \stack_offset - sw \r6, 20(sp) - .endif - .if \r7 != 0 - CHECK_STACK_OFFSET 7, \stack_offset - sw \r7, 24(sp) - .endif - .if \r8 != 0 - CHECK_STACK_OFFSET 8, \stack_offset - sw \r8, 28(sp) - .endif - .if \r9 != 0 - CHECK_STACK_OFFSET 9, \stack_offset - sw \r9, 32(sp) - .endif - .if \r10 != 0 - CHECK_STACK_OFFSET 10, \stack_offset - sw \r10, 36(sp) - .endif - .if \r11 != 0 - CHECK_STACK_OFFSET 11, \stack_offset - sw \r11, 40(sp) - .endif - .if \r12 != 0 - CHECK_STACK_OFFSET 12, \stack_offset - sw \r12, 44(sp) - .endif - .if \r13 != 0 - CHECK_STACK_OFFSET 13, \stack_offset - sw \r13, 48(sp) - .endif - .if \r14 != 0 - CHECK_STACK_OFFSET 14, \stack_offset - sw \r14, 52(sp) - .endif -.endm - -/* - * Restores set of registers from stack. Maximum number of registers that - * can be restored from stack is limitted to 14 (a0-a3, v0-v1 and s0-s7). - * Stack offset is number of bytes that are added to stack pointer (sp) - * after registers are restored (offset must be multiple of 4, and must - * be big enough, as described by CHECK_STACK_OFFSET macro). This macro is - * intended to be used in combination with RESTORE_REGS_FROM_STACK macro. - * Example: - * SAVE_REGS_ON_STACK 4, v0, v1, s0, s1 - * RESTORE_REGS_FROM_STACK 4, v0, v1, s0, s1 - */ -.macro RESTORE_REGS_FROM_STACK stack_offset = 0, r1, \ - r2 = 0, r3 = 0, r4 = 0, \ - r5 = 0, r6 = 0, r7 = 0, \ - r8 = 0, r9 = 0, r10 = 0, \ - r11 = 0, r12 = 0, r13 = 0, \ - r14 = 0 - .if (\stack_offset < 0) || (\stack_offset - (\stack_offset/4)*4) - .error "Stack offset must be pozitive and multiple of 4." - .endif - lw \r1, 0(sp) - .if \r2 != 0 - lw \r2, 4(sp) - .endif - .if \r3 != 0 - lw \r3, 8(sp) - .endif - .if \r4 != 0 - lw \r4, 12(sp) - .endif - .if \r5 != 0 - CHECK_STACK_OFFSET 5, \stack_offset - lw \r5, 16(sp) - .endif - .if \r6 != 0 - CHECK_STACK_OFFSET 6, \stack_offset - lw \r6, 20(sp) - .endif - .if \r7 != 0 - CHECK_STACK_OFFSET 7, \stack_offset - lw \r7, 24(sp) - .endif - .if \r8 != 0 - CHECK_STACK_OFFSET 8, \stack_offset - lw \r8, 28(sp) - .endif - .if \r9 != 0 - CHECK_STACK_OFFSET 9, \stack_offset - lw \r9, 32(sp) - .endif - .if \r10 != 0 - CHECK_STACK_OFFSET 10, \stack_offset - lw \r10, 36(sp) - .endif - .if \r11 != 0 - CHECK_STACK_OFFSET 11, \stack_offset - lw \r11, 40(sp) - .endif - .if \r12 != 0 - CHECK_STACK_OFFSET 12, \stack_offset - lw \r12, 44(sp) - .endif - .if \r13 != 0 - CHECK_STACK_OFFSET 13, \stack_offset - lw \r13, 48(sp) - .endif - .if \r14 != 0 - CHECK_STACK_OFFSET 14, \stack_offset - lw \r14, 52(sp) - .endif - .if \stack_offset != 0 - addiu sp, sp, \stack_offset - .endif -.endm - -/* - * Conversion of single r5g6b5 pixel (in_565) to single a8r8g8b8 pixel - * returned in (out_8888) register. Requires two temporary registers - * (scratch1 and scratch2). - */ -.macro CONVERT_1x0565_TO_1x8888 in_565, \ - out_8888, \ - scratch1, scratch2 - lui \out_8888, 0xff00 - sll \scratch1, \in_565, 0x3 - andi \scratch2, \scratch1, 0xff - ext \scratch1, \in_565, 0x2, 0x3 - or \scratch1, \scratch2, \scratch1 - or \out_8888, \out_8888, \scratch1 - - sll \scratch1, \in_565, 0x5 - andi \scratch1, \scratch1, 0xfc00 - srl \scratch2, \in_565, 0x1 - andi \scratch2, \scratch2, 0x300 - or \scratch2, \scratch1, \scratch2 - or \out_8888, \out_8888, \scratch2 - - andi \scratch1, \in_565, 0xf800 - srl \scratch2, \scratch1, 0x5 - andi \scratch2, \scratch2, 0xff00 - or \scratch1, \scratch1, \scratch2 - sll \scratch1, \scratch1, 0x8 - or \out_8888, \out_8888, \scratch1 -.endm - -/* - * Conversion of two r5g6b5 pixels (in1_565 and in2_565) to two a8r8g8b8 pixels - * returned in (out1_8888 and out2_8888) registers. Requires four scratch - * registers (scratch1 ... scratch4). It also requires maskG and maskB for - * color component extractions. These masks must have following values: - * li maskG, 0x07e007e0 - * li maskB, 0x001F001F - */ -.macro CONVERT_2x0565_TO_2x8888 in1_565, in2_565, \ - out1_8888, out2_8888, \ - maskG, maskB, \ - scratch1, scratch2, scratch3, scratch4 - sll \scratch1, \in1_565, 16 - or \scratch1, \scratch1, \in2_565 - lui \out2_8888, 0xff00 - ori \out2_8888, \out2_8888, 0xff00 - shrl.ph \scratch2, \scratch1, 11 - and \scratch3, \scratch1, \maskG - shra.ph \scratch4, \scratch2, 2 - shll.ph \scratch2, \scratch2, 3 - shll.ph \scratch3, \scratch3, 5 - or \scratch2, \scratch2, \scratch4 - shrl.qb \scratch4, \scratch3, 6 - or \out2_8888, \out2_8888, \scratch2 - or \scratch3, \scratch3, \scratch4 - and \scratch1, \scratch1, \maskB - shll.ph \scratch2, \scratch1, 3 - shra.ph \scratch4, \scratch1, 2 - or \scratch2, \scratch2, \scratch4 - or \scratch3, \scratch2, \scratch3 - precrq.ph.w \out1_8888, \out2_8888, \scratch3 - precr_sra.ph.w \out2_8888, \scratch3, 0 -.endm - -/* - * Conversion of single a8r8g8b8 pixel (in_8888) to single r5g6b5 pixel - * returned in (out_565) register. Requires two temporary registers - * (scratch1 and scratch2). - */ -.macro CONVERT_1x8888_TO_1x0565 in_8888, \ - out_565, \ - scratch1, scratch2 - ext \out_565, \in_8888, 0x3, 0x5 - srl \scratch1, \in_8888, 0x5 - andi \scratch1, \scratch1, 0x07e0 - srl \scratch2, \in_8888, 0x8 - andi \scratch2, \scratch2, 0xf800 - or \out_565, \out_565, \scratch1 - or \out_565, \out_565, \scratch2 -.endm - -/* - * Conversion of two a8r8g8b8 pixels (in1_8888 and in2_8888) to two r5g6b5 - * pixels returned in (out1_565 and out2_565) registers. Requires two temporary - * registers (scratch1 and scratch2). It also requires maskR, maskG and maskB - * for color component extractions. These masks must have following values: - * li maskR, 0xf800f800 - * li maskG, 0x07e007e0 - * li maskB, 0x001F001F - * Value of input register in2_8888 is lost. - */ -.macro CONVERT_2x8888_TO_2x0565 in1_8888, in2_8888, \ - out1_565, out2_565, \ - maskR, maskG, maskB, \ - scratch1, scratch2 - precr.qb.ph \scratch1, \in2_8888, \in1_8888 - precrq.qb.ph \in2_8888, \in2_8888, \in1_8888 - and \out1_565, \scratch1, \maskR - shrl.ph \scratch1, \scratch1, 3 - shll.ph \in2_8888, \in2_8888, 3 - and \scratch1, \scratch1, \maskB - or \out1_565, \out1_565, \scratch1 - and \in2_8888, \in2_8888, \maskG - or \out1_565, \out1_565, \in2_8888 - srl \out2_565, \out1_565, 16 -.endm - -/* - * Multiply pixel (a8) with single pixel (a8r8g8b8). It requires maskLSR needed - * for rounding process. maskLSR must have following value: - * li maskLSR, 0x00ff00ff - */ -.macro MIPS_UN8x4_MUL_UN8 s_8888, \ - m_8, \ - d_8888, \ - maskLSR, \ - scratch1, scratch2, scratch3 - replv.ph \m_8, \m_8 /* 0 | M | 0 | M */ - muleu_s.ph.qbl \scratch1, \s_8888, \m_8 /* A*M | R*M */ - muleu_s.ph.qbr \scratch2, \s_8888, \m_8 /* G*M | B*M */ - shra_r.ph \scratch3, \scratch1, 8 - shra_r.ph \d_8888, \scratch2, 8 - and \scratch3, \scratch3, \maskLSR /* 0 |A*M| 0 |R*M */ - and \d_8888, \d_8888, \maskLSR /* 0 |G*M| 0 |B*M */ - addq.ph \scratch1, \scratch1, \scratch3 /* A*M+A*M | R*M+R*M */ - addq.ph \scratch2, \scratch2, \d_8888 /* G*M+G*M | B*M+B*M */ - shra_r.ph \scratch1, \scratch1, 8 - shra_r.ph \scratch2, \scratch2, 8 - precr.qb.ph \d_8888, \scratch1, \scratch2 -.endm - -/* - * Multiply two pixels (a8) with two pixels (a8r8g8b8). It requires maskLSR - * needed for rounding process. maskLSR must have following value: - * li maskLSR, 0x00ff00ff - */ -.macro MIPS_2xUN8x4_MUL_2xUN8 s1_8888, \ - s2_8888, \ - m1_8, \ - m2_8, \ - d1_8888, \ - d2_8888, \ - maskLSR, \ - scratch1, scratch2, scratch3, \ - scratch4, scratch5, scratch6 - replv.ph \m1_8, \m1_8 /* 0 | M1 | 0 | M1 */ - replv.ph \m2_8, \m2_8 /* 0 | M2 | 0 | M2 */ - muleu_s.ph.qbl \scratch1, \s1_8888, \m1_8 /* A1*M1 | R1*M1 */ - muleu_s.ph.qbr \scratch2, \s1_8888, \m1_8 /* G1*M1 | B1*M1 */ - muleu_s.ph.qbl \scratch3, \s2_8888, \m2_8 /* A2*M2 | R2*M2 */ - muleu_s.ph.qbr \scratch4, \s2_8888, \m2_8 /* G2*M2 | B2*M2 */ - shra_r.ph \scratch5, \scratch1, 8 - shra_r.ph \d1_8888, \scratch2, 8 - shra_r.ph \scratch6, \scratch3, 8 - shra_r.ph \d2_8888, \scratch4, 8 - and \scratch5, \scratch5, \maskLSR /* 0 |A1*M1| 0 |R1*M1 */ - and \d1_8888, \d1_8888, \maskLSR /* 0 |G1*M1| 0 |B1*M1 */ - and \scratch6, \scratch6, \maskLSR /* 0 |A2*M2| 0 |R2*M2 */ - and \d2_8888, \d2_8888, \maskLSR /* 0 |G2*M2| 0 |B2*M2 */ - addq.ph \scratch1, \scratch1, \scratch5 - addq.ph \scratch2, \scratch2, \d1_8888 - addq.ph \scratch3, \scratch3, \scratch6 - addq.ph \scratch4, \scratch4, \d2_8888 - shra_r.ph \scratch1, \scratch1, 8 - shra_r.ph \scratch2, \scratch2, 8 - shra_r.ph \scratch3, \scratch3, 8 - shra_r.ph \scratch4, \scratch4, 8 - precr.qb.ph \d1_8888, \scratch1, \scratch2 - precr.qb.ph \d2_8888, \scratch3, \scratch4 -.endm - -/* - * Multiply pixel (a8r8g8b8) with single pixel (a8r8g8b8). It requires maskLSR - * needed for rounding process. maskLSR must have following value: - * li maskLSR, 0x00ff00ff - */ -.macro MIPS_UN8x4_MUL_UN8x4 s_8888, \ - m_8888, \ - d_8888, \ - maskLSR, \ - scratch1, scratch2, scratch3, scratch4 - preceu.ph.qbl \scratch1, \m_8888 /* 0 | A | 0 | R */ - preceu.ph.qbr \scratch2, \m_8888 /* 0 | G | 0 | B */ - muleu_s.ph.qbl \scratch3, \s_8888, \scratch1 /* A*A | R*R */ - muleu_s.ph.qbr \scratch4, \s_8888, \scratch2 /* G*G | B*B */ - shra_r.ph \scratch1, \scratch3, 8 - shra_r.ph \scratch2, \scratch4, 8 - and \scratch1, \scratch1, \maskLSR /* 0 |A*A| 0 |R*R */ - and \scratch2, \scratch2, \maskLSR /* 0 |G*G| 0 |B*B */ - addq.ph \scratch1, \scratch1, \scratch3 - addq.ph \scratch2, \scratch2, \scratch4 - shra_r.ph \scratch1, \scratch1, 8 - shra_r.ph \scratch2, \scratch2, 8 - precr.qb.ph \d_8888, \scratch1, \scratch2 -.endm - -/* - * Multiply two pixels (a8r8g8b8) with two pixels (a8r8g8b8). It requires - * maskLSR needed for rounding process. maskLSR must have following value: - * li maskLSR, 0x00ff00ff - */ - -.macro MIPS_2xUN8x4_MUL_2xUN8x4 s1_8888, \ - s2_8888, \ - m1_8888, \ - m2_8888, \ - d1_8888, \ - d2_8888, \ - maskLSR, \ - scratch1, scratch2, scratch3, \ - scratch4, scratch5, scratch6 - preceu.ph.qbl \scratch1, \m1_8888 /* 0 | A | 0 | R */ - preceu.ph.qbr \scratch2, \m1_8888 /* 0 | G | 0 | B */ - preceu.ph.qbl \scratch3, \m2_8888 /* 0 | A | 0 | R */ - preceu.ph.qbr \scratch4, \m2_8888 /* 0 | G | 0 | B */ - muleu_s.ph.qbl \scratch5, \s1_8888, \scratch1 /* A*A | R*R */ - muleu_s.ph.qbr \scratch6, \s1_8888, \scratch2 /* G*G | B*B */ - muleu_s.ph.qbl \scratch1, \s2_8888, \scratch3 /* A*A | R*R */ - muleu_s.ph.qbr \scratch2, \s2_8888, \scratch4 /* G*G | B*B */ - shra_r.ph \scratch3, \scratch5, 8 - shra_r.ph \scratch4, \scratch6, 8 - shra_r.ph \d1_8888, \scratch1, 8 - shra_r.ph \d2_8888, \scratch2, 8 - and \scratch3, \scratch3, \maskLSR /* 0 |A*A| 0 |R*R */ - and \scratch4, \scratch4, \maskLSR /* 0 |G*G| 0 |B*B */ - and \d1_8888, \d1_8888, \maskLSR /* 0 |A*A| 0 |R*R */ - and \d2_8888, \d2_8888, \maskLSR /* 0 |G*G| 0 |B*B */ - addq.ph \scratch3, \scratch3, \scratch5 - addq.ph \scratch4, \scratch4, \scratch6 - addq.ph \d1_8888, \d1_8888, \scratch1 - addq.ph \d2_8888, \d2_8888, \scratch2 - shra_r.ph \scratch3, \scratch3, 8 - shra_r.ph \scratch4, \scratch4, 8 - shra_r.ph \scratch5, \d1_8888, 8 - shra_r.ph \scratch6, \d2_8888, 8 - precr.qb.ph \d1_8888, \scratch3, \scratch4 - precr.qb.ph \d2_8888, \scratch5, \scratch6 -.endm - -/* - * OVER operation on single a8r8g8b8 source pixel (s_8888) and single a8r8g8b8 - * destination pixel (d_8888) using a8 mask (m_8). It also requires maskLSR - * needed for rounding process. maskLSR must have following value: - * li maskLSR, 0x00ff00ff - */ -.macro OVER_8888_8_8888 s_8888, \ - m_8, \ - d_8888, \ - out_8888, \ - maskLSR, \ - scratch1, scratch2, scratch3, scratch4 - MIPS_UN8x4_MUL_UN8 \s_8888, \m_8, \ - \scratch1, \maskLSR, \ - \scratch2, \scratch3, \scratch4 - - not \scratch2, \scratch1 - srl \scratch2, \scratch2, 24 - - MIPS_UN8x4_MUL_UN8 \d_8888, \scratch2, \ - \d_8888, \maskLSR, \ - \scratch3, \scratch4, \out_8888 - - addu_s.qb \out_8888, \d_8888, \scratch1 -.endm - -/* - * OVER operation on two a8r8g8b8 source pixels (s1_8888 and s2_8888) and two - * a8r8g8b8 destination pixels (d1_8888 and d2_8888) using a8 masks (m1_8 and - * m2_8). It also requires maskLSR needed for rounding process. maskLSR must - * have following value: - * li maskLSR, 0x00ff00ff - */ -.macro OVER_2x8888_2x8_2x8888 s1_8888, \ - s2_8888, \ - m1_8, \ - m2_8, \ - d1_8888, \ - d2_8888, \ - out1_8888, \ - out2_8888, \ - maskLSR, \ - scratch1, scratch2, scratch3, \ - scratch4, scratch5, scratch6 - MIPS_2xUN8x4_MUL_2xUN8 \s1_8888, \s2_8888, \ - \m1_8, \m2_8, \ - \scratch1, \scratch2, \ - \maskLSR, \ - \scratch3, \scratch4, \out1_8888, \ - \out2_8888, \scratch5, \scratch6 - - not \scratch3, \scratch1 - srl \scratch3, \scratch3, 24 - not \scratch4, \scratch2 - srl \scratch4, \scratch4, 24 - - MIPS_2xUN8x4_MUL_2xUN8 \d1_8888, \d2_8888, \ - \scratch3, \scratch4, \ - \d1_8888, \d2_8888, \ - \maskLSR, \ - \scratch5, \scratch6, \out1_8888, \ - \out2_8888, \scratch3, \scratch4 - - addu_s.qb \out1_8888, \d1_8888, \scratch1 - addu_s.qb \out2_8888, \d2_8888, \scratch2 -.endm - -/* - * OVER operation on single a8r8g8b8 source pixel (s_8888) and single a8r8g8b8 - * destination pixel (d_8888). It also requires maskLSR needed for rounding - * process. maskLSR must have following value: - * li maskLSR, 0x00ff00ff - */ -.macro OVER_8888_8888 s_8888, \ - d_8888, \ - out_8888, \ - maskLSR, \ - scratch1, scratch2, scratch3, scratch4 - not \scratch1, \s_8888 - srl \scratch1, \scratch1, 24 - - MIPS_UN8x4_MUL_UN8 \d_8888, \scratch1, \ - \out_8888, \maskLSR, \ - \scratch2, \scratch3, \scratch4 - - addu_s.qb \out_8888, \out_8888, \s_8888 -.endm - -/* - * OVER operation on two a8r8g8b8 source pixels (s1_8888 and s2_8888) and two - * a8r8g8b8 destination pixels (d1_8888 and d2_8888). It also requires maskLSR - * needed for rounding process. maskLSR must have following value: - * li maskLSR, 0x00ff00ff - */ -.macro OVER_2x8888_2x8888 s1_8888, \ - s2_8888, \ - d1_8888, \ - d2_8888, \ - out1_8888, \ - out2_8888, \ - maskLSR, \ - scratch1, scratch2, scratch3, \ - scratch4, scratch5, scratch6 - not \scratch1, \s1_8888 - srl \scratch1, \scratch1, 24 - not \scratch2, \s2_8888 - srl \scratch2, \scratch2, 24 - MIPS_2xUN8x4_MUL_2xUN8 \d1_8888, \d2_8888, \ - \scratch1, \scratch2, \ - \out1_8888, \out2_8888, \ - \maskLSR, \ - \scratch3, \scratch4, \scratch5, \ - \scratch6, \d1_8888, \d2_8888 - - addu_s.qb \out1_8888, \out1_8888, \s1_8888 - addu_s.qb \out2_8888, \out2_8888, \s2_8888 -.endm - -.macro MIPS_UN8x4_MUL_UN8_ADD_UN8x4 s_8888, \ - m_8, \ - d_8888, \ - out_8888, \ - maskLSR, \ - scratch1, scratch2, scratch3 - MIPS_UN8x4_MUL_UN8 \s_8888, \m_8, \ - \out_8888, \maskLSR, \ - \scratch1, \scratch2, \scratch3 - - addu_s.qb \out_8888, \out_8888, \d_8888 -.endm - -.macro MIPS_2xUN8x4_MUL_2xUN8_ADD_2xUN8x4 s1_8888, \ - s2_8888, \ - m1_8, \ - m2_8, \ - d1_8888, \ - d2_8888, \ - out1_8888, \ - out2_8888, \ - maskLSR, \ - scratch1, scratch2, scratch3, \ - scratch4, scratch5, scratch6 - MIPS_2xUN8x4_MUL_2xUN8 \s1_8888, \s2_8888, \ - \m1_8, \m2_8, \ - \out1_8888, \out2_8888, \ - \maskLSR, \ - \scratch1, \scratch2, \scratch3, \ - \scratch4, \scratch5, \scratch6 - - addu_s.qb \out1_8888, \out1_8888, \d1_8888 - addu_s.qb \out2_8888, \out2_8888, \d2_8888 -.endm - -.macro BILINEAR_INTERPOLATE_SINGLE_PIXEL tl, tr, bl, br, \ - scratch1, scratch2, \ - alpha, red, green, blue \ - wt1, wt2, wb1, wb2 - andi \scratch1, \tl, 0xff - andi \scratch2, \tr, 0xff - andi \alpha, \bl, 0xff - andi \red, \br, 0xff - - multu $ac0, \wt1, \scratch1 - maddu $ac0, \wt2, \scratch2 - maddu $ac0, \wb1, \alpha - maddu $ac0, \wb2, \red - - ext \scratch1, \tl, 8, 8 - ext \scratch2, \tr, 8, 8 - ext \alpha, \bl, 8, 8 - ext \red, \br, 8, 8 - - multu $ac1, \wt1, \scratch1 - maddu $ac1, \wt2, \scratch2 - maddu $ac1, \wb1, \alpha - maddu $ac1, \wb2, \red - - ext \scratch1, \tl, 16, 8 - ext \scratch2, \tr, 16, 8 - ext \alpha, \bl, 16, 8 - ext \red, \br, 16, 8 - - mflo \blue, $ac0 - - multu $ac2, \wt1, \scratch1 - maddu $ac2, \wt2, \scratch2 - maddu $ac2, \wb1, \alpha - maddu $ac2, \wb2, \red - - ext \scratch1, \tl, 24, 8 - ext \scratch2, \tr, 24, 8 - ext \alpha, \bl, 24, 8 - ext \red, \br, 24, 8 - - mflo \green, $ac1 - - multu $ac3, \wt1, \scratch1 - maddu $ac3, \wt2, \scratch2 - maddu $ac3, \wb1, \alpha - maddu $ac3, \wb2, \red - - mflo \red, $ac2 - mflo \alpha, $ac3 - - precr.qb.ph \alpha, \alpha, \red - precr.qb.ph \scratch1, \green, \blue - precrq.qb.ph \tl, \alpha, \scratch1 -.endm - -#endif //PIXMAN_MIPS_DSPR2_ASM_H diff --git a/source/libs/pixman/pixman-src/pixman/pixman-mips-dspr2.c b/source/libs/pixman/pixman-src/pixman/pixman-mips-dspr2.c deleted file mode 100644 index 87969ae704fd5b32722d26bcc32fa4bd43e7cea0..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-mips-dspr2.c +++ /dev/null @@ -1,459 +0,0 @@ -/* - * Copyright (c) 2012 - * MIPS Technologies, Inc., California. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Author: Nemanja Lukic (nemanja.lukic@rt-rk.com) - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "pixman-private.h" -#include "pixman-mips-dspr2.h" - -PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, src_x888_8888, - uint32_t, 1, uint32_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, src_8888_0565, - uint32_t, 1, uint16_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, src_0565_8888, - uint16_t, 1, uint32_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (DO_FAST_MEMCPY, src_0565_0565, - uint16_t, 1, uint16_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (DO_FAST_MEMCPY, src_8888_8888, - uint32_t, 1, uint32_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (DO_FAST_MEMCPY, src_0888_0888, - uint8_t, 3, uint8_t, 3) -#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) -PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, src_0888_8888_rev, - uint8_t, 3, uint32_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, src_0888_0565_rev, - uint8_t, 3, uint16_t, 1) -#endif -PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, src_pixbuf_8888, - uint32_t, 1, uint32_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, src_rpixbuf_8888, - uint32_t, 1, uint32_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, over_8888_8888, - uint32_t, 1, uint32_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, over_8888_0565, - uint32_t, 1, uint16_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, add_8_8, - uint8_t, 1, uint8_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, add_8888_8888, - uint32_t, 1, uint32_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, out_reverse_8_0565, - uint8_t, 1, uint16_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST (0, out_reverse_8_8888, - uint8_t, 1, uint32_t, 1) - -PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (0, src_n_8_8888, - uint8_t, 1, uint32_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (0, src_n_8_8, - uint8_t, 1, uint8_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, over_n_8888_8888_ca, - uint32_t, 1, uint32_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, over_n_8888_0565_ca, - uint32_t, 1, uint16_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, over_n_8_8, - uint8_t, 1, uint8_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, over_n_8_8888, - uint8_t, 1, uint32_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, over_n_8_0565, - uint8_t, 1, uint16_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, add_n_8_8, - uint8_t, 1, uint8_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, add_n_8_8888, - uint8_t, 1, uint32_t, 1) - -PIXMAN_MIPS_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, over_8888_n_8888, - uint32_t, 1, uint32_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, over_8888_n_0565, - uint32_t, 1, uint16_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, over_0565_n_0565, - uint16_t, 1, uint16_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, add_8888_n_8888, - uint32_t, 1, uint32_t, 1) - -PIXMAN_MIPS_BIND_FAST_PATH_N_DST (SKIP_ZERO_SRC, over_n_0565, - uint16_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_N_DST (SKIP_ZERO_SRC, over_n_8888, - uint32_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_N_DST (SKIP_ZERO_SRC, over_reverse_n_8888, - uint32_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_N_DST (0, in_n_8, - uint8_t, 1) - -PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (add_8_8_8, uint8_t, 1, - uint8_t, 1, uint8_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (add_8888_8_8888, uint32_t, 1, - uint8_t, 1, uint32_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (add_8888_8888_8888, uint32_t, 1, - uint32_t, 1, uint32_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (add_0565_8_0565, uint16_t, 1, - uint8_t, 1, uint16_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (over_8888_8_8888, uint32_t, 1, - uint8_t, 1, uint32_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (over_8888_8_0565, uint32_t, 1, - uint8_t, 1, uint16_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (over_0565_8_0565, uint16_t, 1, - uint8_t, 1, uint16_t, 1) -PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST (over_8888_8888_8888, uint32_t, 1, - uint32_t, 1, uint32_t, 1) - -PIXMAN_MIPS_BIND_SCALED_NEAREST_SRC_DST (8888_8888, OVER, - uint32_t, uint32_t) -PIXMAN_MIPS_BIND_SCALED_NEAREST_SRC_DST (8888_0565, OVER, - uint32_t, uint16_t) -PIXMAN_MIPS_BIND_SCALED_NEAREST_SRC_DST (0565_8888, SRC, - uint16_t, uint32_t) - -PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_DST (0, 8888_8888, SRC, - uint32_t, uint32_t) -PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_DST (0, 8888_0565, SRC, - uint32_t, uint16_t) -PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_DST (0, 0565_8888, SRC, - uint16_t, uint32_t) -PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_DST (0, 0565_0565, SRC, - uint16_t, uint16_t) -PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_DST (SKIP_ZERO_SRC, 8888_8888, OVER, - uint32_t, uint32_t) -PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_DST (SKIP_ZERO_SRC, 8888_8888, ADD, - uint32_t, uint32_t) - -PIXMAN_MIPS_BIND_SCALED_NEAREST_SRC_A8_DST (SKIP_ZERO_SRC, 8888_8_0565, - OVER, uint32_t, uint16_t) -PIXMAN_MIPS_BIND_SCALED_NEAREST_SRC_A8_DST (SKIP_ZERO_SRC, 0565_8_0565, - OVER, uint16_t, uint16_t) - -PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_A8_DST (0, 8888_8_8888, SRC, - uint32_t, uint32_t) -PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_A8_DST (0, 8888_8_0565, SRC, - uint32_t, uint16_t) -PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_A8_DST (0, 0565_8_x888, SRC, - uint16_t, uint32_t) -PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_A8_DST (0, 0565_8_0565, SRC, - uint16_t, uint16_t) -PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_A8_DST (SKIP_ZERO_SRC, 8888_8_8888, OVER, - uint32_t, uint32_t) -PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_A8_DST (SKIP_ZERO_SRC, 8888_8_8888, ADD, - uint32_t, uint32_t) - -static pixman_bool_t -mips_dspr2_fill (pixman_implementation_t *imp, - uint32_t * bits, - int stride, - int bpp, - int x, - int y, - int width, - int height, - uint32_t _xor) -{ - uint8_t *byte_line; - uint32_t byte_width; - switch (bpp) - { - case 16: - stride = stride * (int) sizeof (uint32_t) / 2; - byte_line = (uint8_t *)(((uint16_t *)bits) + stride * y + x); - byte_width = width * 2; - stride *= 2; - - while (height--) - { - uint8_t *dst = byte_line; - byte_line += stride; - pixman_fill_buff16_mips (dst, byte_width, _xor & 0xffff); - } - return TRUE; - case 32: - stride = stride * (int) sizeof (uint32_t) / 4; - byte_line = (uint8_t *)(((uint32_t *)bits) + stride * y + x); - byte_width = width * 4; - stride *= 4; - - while (height--) - { - uint8_t *dst = byte_line; - byte_line += stride; - pixman_fill_buff32_mips (dst, byte_width, _xor); - } - return TRUE; - default: - return FALSE; - } -} - -static pixman_bool_t -mips_dspr2_blt (pixman_implementation_t *imp, - uint32_t * src_bits, - uint32_t * dst_bits, - int src_stride, - int dst_stride, - int src_bpp, - int dst_bpp, - int src_x, - int src_y, - int dest_x, - int dest_y, - int width, - int height) -{ - if (src_bpp != dst_bpp) - return FALSE; - - uint8_t *src_bytes; - uint8_t *dst_bytes; - uint32_t byte_width; - - switch (src_bpp) - { - case 16: - src_stride = src_stride * (int) sizeof (uint32_t) / 2; - dst_stride = dst_stride * (int) sizeof (uint32_t) / 2; - src_bytes =(uint8_t *)(((uint16_t *)src_bits) - + src_stride * (src_y) + (src_x)); - dst_bytes = (uint8_t *)(((uint16_t *)dst_bits) - + dst_stride * (dest_y) + (dest_x)); - byte_width = width * 2; - src_stride *= 2; - dst_stride *= 2; - - while (height--) - { - uint8_t *src = src_bytes; - uint8_t *dst = dst_bytes; - src_bytes += src_stride; - dst_bytes += dst_stride; - pixman_mips_fast_memcpy (dst, src, byte_width); - } - return TRUE; - case 32: - src_stride = src_stride * (int) sizeof (uint32_t) / 4; - dst_stride = dst_stride * (int) sizeof (uint32_t) / 4; - src_bytes = (uint8_t *)(((uint32_t *)src_bits) - + src_stride * (src_y) + (src_x)); - dst_bytes = (uint8_t *)(((uint32_t *)dst_bits) - + dst_stride * (dest_y) + (dest_x)); - byte_width = width * 4; - src_stride *= 4; - dst_stride *= 4; - - while (height--) - { - uint8_t *src = src_bytes; - uint8_t *dst = dst_bytes; - src_bytes += src_stride; - dst_bytes += dst_stride; - pixman_mips_fast_memcpy (dst, src, byte_width); - } - return TRUE; - default: - return FALSE; - } -} - -static const pixman_fast_path_t mips_dspr2_fast_paths[] = -{ - PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, r5g6b5, mips_composite_src_0565_0565), - PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, b5g6r5, mips_composite_src_0565_0565), - PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, r5g6b5, mips_composite_src_8888_0565), - PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, r5g6b5, mips_composite_src_8888_0565), - PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, b5g6r5, mips_composite_src_8888_0565), - PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, b5g6r5, mips_composite_src_8888_0565), - PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, a8r8g8b8, mips_composite_src_0565_8888), - PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, x8r8g8b8, mips_composite_src_0565_8888), - PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, a8b8g8r8, mips_composite_src_0565_8888), - PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, x8b8g8r8, mips_composite_src_0565_8888), - PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, mips_composite_src_8888_8888), - PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, mips_composite_src_8888_8888), - PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, mips_composite_src_8888_8888), - PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, mips_composite_src_8888_8888), - PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, a8r8g8b8, mips_composite_src_8888_8888), - PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, a8b8g8r8, mips_composite_src_8888_8888), - PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, a8r8g8b8, mips_composite_src_x888_8888), - PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, a8b8g8r8, mips_composite_src_x888_8888), - PIXMAN_STD_FAST_PATH (SRC, r8g8b8, null, r8g8b8, mips_composite_src_0888_0888), -#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - PIXMAN_STD_FAST_PATH (SRC, b8g8r8, null, x8r8g8b8, mips_composite_src_0888_8888_rev), - PIXMAN_STD_FAST_PATH (SRC, b8g8r8, null, r5g6b5, mips_composite_src_0888_0565_rev), -#endif - PIXMAN_STD_FAST_PATH (SRC, pixbuf, pixbuf, a8r8g8b8, mips_composite_src_pixbuf_8888), - PIXMAN_STD_FAST_PATH (SRC, pixbuf, pixbuf, a8b8g8r8, mips_composite_src_rpixbuf_8888), - PIXMAN_STD_FAST_PATH (SRC, rpixbuf, rpixbuf, a8r8g8b8, mips_composite_src_rpixbuf_8888), - PIXMAN_STD_FAST_PATH (SRC, rpixbuf, rpixbuf, a8b8g8r8, mips_composite_src_pixbuf_8888), - PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8r8g8b8, mips_composite_src_n_8_8888), - PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8r8g8b8, mips_composite_src_n_8_8888), - PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8b8g8r8, mips_composite_src_n_8_8888), - PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8b8g8r8, mips_composite_src_n_8_8888), - PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8, mips_composite_src_n_8_8), - - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, a8r8g8b8, mips_composite_over_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, mips_composite_over_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, mips_composite_over_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, mips_composite_over_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, r5g6b5, mips_composite_over_n_8888_0565_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, b5g6r5, mips_composite_over_n_8888_0565_ca), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8, mips_composite_over_n_8_8), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, mips_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, mips_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, mips_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, mips_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, r5g6b5, mips_composite_over_n_8_0565), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, b5g6r5, mips_composite_over_n_8_0565), - PIXMAN_STD_FAST_PATH (OVER, solid, null, r5g6b5, mips_composite_over_n_0565), - PIXMAN_STD_FAST_PATH (OVER, solid, null, a8r8g8b8, mips_composite_over_n_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, null, x8r8g8b8, mips_composite_over_n_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, a8r8g8b8, mips_composite_over_8888_n_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, x8r8g8b8, mips_composite_over_8888_n_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, r5g6b5, mips_composite_over_8888_n_0565), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, b5g6r5, mips_composite_over_8888_n_0565), - PIXMAN_STD_FAST_PATH (OVER, r5g6b5, solid, r5g6b5, mips_composite_over_0565_n_0565), - PIXMAN_STD_FAST_PATH (OVER, b5g6r5, solid, b5g6r5, mips_composite_over_0565_n_0565), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, a8r8g8b8, mips_composite_over_8888_8_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, x8r8g8b8, mips_composite_over_8888_8_8888), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, a8b8g8r8, mips_composite_over_8888_8_8888), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, x8b8g8r8, mips_composite_over_8888_8_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, r5g6b5, mips_composite_over_8888_8_0565), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, b5g6r5, mips_composite_over_8888_8_0565), - PIXMAN_STD_FAST_PATH (OVER, r5g6b5, a8, r5g6b5, mips_composite_over_0565_8_0565), - PIXMAN_STD_FAST_PATH (OVER, b5g6r5, a8, b5g6r5, mips_composite_over_0565_8_0565), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, a8r8g8b8, mips_composite_over_8888_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, mips_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, mips_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, mips_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, mips_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, r5g6b5, mips_composite_over_8888_0565), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, b5g6r5, mips_composite_over_8888_0565), - PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8, mips_composite_add_n_8_8), - PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8r8g8b8, mips_composite_add_n_8_8888), - PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8b8g8r8, mips_composite_add_n_8_8888), - PIXMAN_STD_FAST_PATH (ADD, a8, a8, a8, mips_composite_add_8_8_8), - PIXMAN_STD_FAST_PATH (ADD, r5g6b5, a8, r5g6b5, mips_composite_add_0565_8_0565), - PIXMAN_STD_FAST_PATH (ADD, b5g6r5, a8, b5g6r5, mips_composite_add_0565_8_0565), - PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, a8, a8r8g8b8, mips_composite_add_8888_8_8888), - PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, a8, a8b8g8r8, mips_composite_add_8888_8_8888), - PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, a8r8g8b8, a8r8g8b8, mips_composite_add_8888_8888_8888), - PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, solid, a8r8g8b8, mips_composite_add_8888_n_8888), - PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, solid, a8b8g8r8, mips_composite_add_8888_n_8888), - PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, mips_composite_add_8_8), - PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, null, a8r8g8b8, mips_composite_add_8888_8888), - PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, null, a8b8g8r8, mips_composite_add_8888_8888), - PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, r5g6b5, mips_composite_out_reverse_8_0565), - PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, b5g6r5, mips_composite_out_reverse_8_0565), - PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, a8r8g8b8, mips_composite_out_reverse_8_8888), - PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, a8b8g8r8, mips_composite_out_reverse_8_8888), - PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8r8g8b8, mips_composite_over_reverse_n_8888), - PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8b8g8r8, mips_composite_over_reverse_n_8888), - PIXMAN_STD_FAST_PATH (IN, solid, null, a8, mips_composite_in_n_8), - - PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, mips_8888_8888), - PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, mips_8888_8888), - PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, mips_8888_8888), - PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, mips_8888_8888), - - PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, r5g6b5, mips_8888_0565), - PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, b5g6r5, mips_8888_0565), - - PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH (SRC, b5g6r5, x8b8g8r8, mips_0565_8888), - PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH (SRC, r5g6b5, x8r8g8b8, mips_0565_8888), - /* Note: NONE repeat is not supported yet */ - SIMPLE_NEAREST_FAST_PATH_COVER (SRC, r5g6b5, a8r8g8b8, mips_0565_8888), - SIMPLE_NEAREST_FAST_PATH_COVER (SRC, b5g6r5, a8b8g8r8, mips_0565_8888), - SIMPLE_NEAREST_FAST_PATH_PAD (SRC, r5g6b5, a8r8g8b8, mips_0565_8888), - SIMPLE_NEAREST_FAST_PATH_PAD (SRC, b5g6r5, a8b8g8r8, mips_0565_8888), - - SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, a8r8g8b8, r5g6b5, mips_8888_8_0565), - SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, a8b8g8r8, b5g6r5, mips_8888_8_0565), - - SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, r5g6b5, r5g6b5, mips_0565_8_0565), - SIMPLE_NEAREST_A8_MASK_FAST_PATH (OVER, b5g6r5, b5g6r5, mips_0565_8_0565), - - SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, mips_8888_8888), - SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, mips_8888_8888), - SIMPLE_BILINEAR_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, mips_8888_8888), - - SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, r5g6b5, mips_8888_0565), - SIMPLE_BILINEAR_FAST_PATH (SRC, x8r8g8b8, r5g6b5, mips_8888_0565), - - SIMPLE_BILINEAR_FAST_PATH (SRC, r5g6b5, x8r8g8b8, mips_0565_8888), - SIMPLE_BILINEAR_FAST_PATH (SRC, r5g6b5, r5g6b5, mips_0565_0565), - - SIMPLE_BILINEAR_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, mips_8888_8888), - SIMPLE_BILINEAR_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, mips_8888_8888), - - SIMPLE_BILINEAR_FAST_PATH (ADD, a8r8g8b8, a8r8g8b8, mips_8888_8888), - SIMPLE_BILINEAR_FAST_PATH (ADD, a8r8g8b8, x8r8g8b8, mips_8888_8888), - - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, mips_8888_8_8888), - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, mips_8888_8_8888), - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, mips_8888_8_8888), - - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, a8r8g8b8, r5g6b5, mips_8888_8_0565), - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, x8r8g8b8, r5g6b5, mips_8888_8_0565), - - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, r5g6b5, x8r8g8b8, mips_0565_8_x888), - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (SRC, r5g6b5, r5g6b5, mips_0565_8_0565), - - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, mips_8888_8_8888), - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, mips_8888_8_8888), - - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (ADD, a8r8g8b8, a8r8g8b8, mips_8888_8_8888), - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (ADD, a8r8g8b8, x8r8g8b8, mips_8888_8_8888), - { PIXMAN_OP_NONE }, -}; - -static void -mips_dspr2_combine_over_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - if (mask) - pixman_composite_over_8888_8888_8888_asm_mips ( - dest, (uint32_t *)src, (uint32_t *)mask, width); - else - pixman_composite_over_8888_8888_asm_mips ( - dest, (uint32_t *)src, width); -} - -pixman_implementation_t * -_pixman_implementation_create_mips_dspr2 (pixman_implementation_t *fallback) -{ - pixman_implementation_t *imp = - _pixman_implementation_create (fallback, mips_dspr2_fast_paths); - - imp->combine_32[PIXMAN_OP_OVER] = mips_dspr2_combine_over_u; - - imp->blt = mips_dspr2_blt; - imp->fill = mips_dspr2_fill; - - return imp; -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman-mips-dspr2.h b/source/libs/pixman/pixman-src/pixman/pixman-mips-dspr2.h deleted file mode 100644 index 57b38359e37ed425a5d13cdece0dbbc9d669ded9..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-mips-dspr2.h +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Copyright (c) 2012 - * MIPS Technologies, Inc., California. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Author: Nemanja Lukic (nemanja.lukic@rt-rk.com) - */ - -#ifndef PIXMAN_MIPS_DSPR2_H -#define PIXMAN_MIPS_DSPR2_H - -#include "pixman-private.h" -#include "pixman-inlines.h" - -#define SKIP_ZERO_SRC 1 -#define SKIP_ZERO_MASK 2 -#define DO_FAST_MEMCPY 3 - -void -pixman_mips_fast_memcpy (void *dst, void *src, uint32_t n_bytes); -void -pixman_fill_buff16_mips (void *dst, uint32_t n_bytes, uint16_t value); -void -pixman_fill_buff32_mips (void *dst, uint32_t n_bytes, uint32_t value); - -/****************************************************************/ - -#define PIXMAN_MIPS_BIND_FAST_PATH_SRC_DST(flags, name, \ - src_type, src_cnt, \ - dst_type, dst_cnt) \ -void \ -pixman_composite_##name##_asm_mips (dst_type *dst, \ - src_type *src, \ - int32_t w); \ - \ -static void \ -mips_composite_##name (pixman_implementation_t *imp, \ - pixman_composite_info_t *info) \ -{ \ - PIXMAN_COMPOSITE_ARGS (info); \ - dst_type *dst_line, *dst; \ - src_type *src_line, *src; \ - int32_t dst_stride, src_stride; \ - int bpp = PIXMAN_FORMAT_BPP (dest_image->bits.format) / 8; \ - \ - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \ - src_stride, src_line, src_cnt); \ - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \ - dst_stride, dst_line, dst_cnt); \ - \ - while (height--) \ - { \ - dst = dst_line; \ - dst_line += dst_stride; \ - src = src_line; \ - src_line += src_stride; \ - \ - if (flags == DO_FAST_MEMCPY) \ - pixman_mips_fast_memcpy (dst, src, width * bpp); \ - else \ - pixman_composite_##name##_asm_mips (dst, src, width); \ - } \ -} - -/****************************************************************/ - -#define PIXMAN_MIPS_BIND_FAST_PATH_N_DST(flags, name, \ - dst_type, dst_cnt) \ -void \ -pixman_composite_##name##_asm_mips (dst_type *dst, \ - uint32_t src, \ - int32_t w); \ - \ -static void \ -mips_composite_##name (pixman_implementation_t *imp, \ - pixman_composite_info_t *info) \ -{ \ - PIXMAN_COMPOSITE_ARGS (info); \ - dst_type *dst_line, *dst; \ - int32_t dst_stride; \ - uint32_t src; \ - \ - src = _pixman_image_get_solid ( \ - imp, src_image, dest_image->bits.format); \ - \ - if ((flags & SKIP_ZERO_SRC) && src == 0) \ - return; \ - \ - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \ - dst_stride, dst_line, dst_cnt); \ - \ - while (height--) \ - { \ - dst = dst_line; \ - dst_line += dst_stride; \ - \ - pixman_composite_##name##_asm_mips (dst, src, width); \ - } \ -} - -/*******************************************************************/ - -#define PIXMAN_MIPS_BIND_FAST_PATH_N_MASK_DST(flags, name, \ - mask_type, mask_cnt, \ - dst_type, dst_cnt) \ -void \ -pixman_composite_##name##_asm_mips (dst_type *dst, \ - uint32_t src, \ - mask_type *mask, \ - int32_t w); \ - \ -static void \ -mips_composite_##name (pixman_implementation_t *imp, \ - pixman_composite_info_t *info) \ -{ \ - PIXMAN_COMPOSITE_ARGS (info); \ - dst_type *dst_line, *dst; \ - mask_type *mask_line, *mask; \ - int32_t dst_stride, mask_stride; \ - uint32_t src; \ - \ - src = _pixman_image_get_solid ( \ - imp, src_image, dest_image->bits.format); \ - \ - if ((flags & SKIP_ZERO_SRC) && src == 0) \ - return; \ - \ - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \ - dst_stride, dst_line, dst_cnt); \ - PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type, \ - mask_stride, mask_line, mask_cnt); \ - \ - while (height--) \ - { \ - dst = dst_line; \ - dst_line += dst_stride; \ - mask = mask_line; \ - mask_line += mask_stride; \ - pixman_composite_##name##_asm_mips (dst, src, mask, width); \ - } \ -} - -/*******************************************************************/ - -#define PIXMAN_MIPS_BIND_FAST_PATH_SRC_N_DST(flags, name, \ - src_type, src_cnt, \ - dst_type, dst_cnt) \ -void \ -pixman_composite_##name##_asm_mips (dst_type *dst, \ - src_type *src, \ - uint32_t mask, \ - int32_t w); \ - \ -static void \ -mips_composite_##name (pixman_implementation_t *imp, \ - pixman_composite_info_t *info) \ -{ \ - PIXMAN_COMPOSITE_ARGS (info); \ - dst_type *dst_line, *dst; \ - src_type *src_line, *src; \ - int32_t dst_stride, src_stride; \ - uint32_t mask; \ - \ - mask = _pixman_image_get_solid ( \ - imp, mask_image, dest_image->bits.format); \ - \ - if ((flags & SKIP_ZERO_MASK) && mask == 0) \ - return; \ - \ - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \ - dst_stride, dst_line, dst_cnt); \ - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \ - src_stride, src_line, src_cnt); \ - \ - while (height--) \ - { \ - dst = dst_line; \ - dst_line += dst_stride; \ - src = src_line; \ - src_line += src_stride; \ - \ - pixman_composite_##name##_asm_mips (dst, src, mask, width); \ - } \ -} - -/************************************************************************/ - -#define PIXMAN_MIPS_BIND_FAST_PATH_SRC_MASK_DST(name, src_type, src_cnt, \ - mask_type, mask_cnt, \ - dst_type, dst_cnt) \ -void \ -pixman_composite_##name##_asm_mips (dst_type *dst, \ - src_type *src, \ - mask_type *mask, \ - int32_t w); \ - \ -static void \ -mips_composite_##name (pixman_implementation_t *imp, \ - pixman_composite_info_t *info) \ -{ \ - PIXMAN_COMPOSITE_ARGS (info); \ - dst_type *dst_line, *dst; \ - src_type *src_line, *src; \ - mask_type *mask_line, *mask; \ - int32_t dst_stride, src_stride, mask_stride; \ - \ - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \ - dst_stride, dst_line, dst_cnt); \ - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \ - src_stride, src_line, src_cnt); \ - PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type, \ - mask_stride, mask_line, mask_cnt); \ - \ - while (height--) \ - { \ - dst = dst_line; \ - dst_line += dst_stride; \ - mask = mask_line; \ - mask_line += mask_stride; \ - src = src_line; \ - src_line += src_stride; \ - pixman_composite_##name##_asm_mips (dst, src, mask, width); \ - } \ -} - -/****************************************************************************/ - -#define PIXMAN_MIPS_BIND_SCALED_NEAREST_SRC_DST(name, op, \ - src_type, dst_type) \ -void \ -pixman_scaled_nearest_scanline_##name##_##op##_asm_mips ( \ - dst_type * dst, \ - const src_type * src, \ - int32_t w, \ - pixman_fixed_t vx, \ - pixman_fixed_t unit_x); \ - \ -static force_inline void \ -scaled_nearest_scanline_mips_##name##_##op (dst_type * pd, \ - const src_type * ps, \ - int32_t w, \ - pixman_fixed_t vx, \ - pixman_fixed_t unit_x, \ - pixman_fixed_t max_vx, \ - pixman_bool_t zero_src) \ -{ \ - pixman_scaled_nearest_scanline_##name##_##op##_asm_mips (pd, ps, w, \ - vx, unit_x); \ -} \ - \ -FAST_NEAREST_MAINLOOP (mips_##name##_cover_##op, \ - scaled_nearest_scanline_mips_##name##_##op, \ - src_type, dst_type, COVER) \ -FAST_NEAREST_MAINLOOP (mips_##name##_none_##op, \ - scaled_nearest_scanline_mips_##name##_##op, \ - src_type, dst_type, NONE) \ -FAST_NEAREST_MAINLOOP (mips_##name##_pad_##op, \ - scaled_nearest_scanline_mips_##name##_##op, \ - src_type, dst_type, PAD) - -/* Provide entries for the fast path table */ -#define PIXMAN_MIPS_SIMPLE_NEAREST_FAST_PATH(op,s,d,func) \ - SIMPLE_NEAREST_FAST_PATH_COVER (op,s,d,func), \ - SIMPLE_NEAREST_FAST_PATH_NONE (op,s,d,func), \ - SIMPLE_NEAREST_FAST_PATH_PAD (op,s,d,func) - - -/*****************************************************************************/ - -#define PIXMAN_MIPS_BIND_SCALED_NEAREST_SRC_A8_DST(flags, name, op, \ - src_type, dst_type) \ -void \ -pixman_scaled_nearest_scanline_##name##_##op##_asm_mips ( \ - dst_type * dst, \ - const src_type * src, \ - const uint8_t * mask, \ - int32_t w, \ - pixman_fixed_t vx, \ - pixman_fixed_t unit_x); \ - \ -static force_inline void \ -scaled_nearest_scanline_mips_##name##_##op (const uint8_t * mask, \ - dst_type * pd, \ - const src_type * ps, \ - int32_t w, \ - pixman_fixed_t vx, \ - pixman_fixed_t unit_x, \ - pixman_fixed_t max_vx, \ - pixman_bool_t zero_src) \ -{ \ - if ((flags & SKIP_ZERO_SRC) && zero_src) \ - return; \ - pixman_scaled_nearest_scanline_##name##_##op##_asm_mips (pd, ps, \ - mask, w, \ - vx, unit_x); \ -} \ - \ -FAST_NEAREST_MAINLOOP_COMMON (mips_##name##_cover_##op, \ - scaled_nearest_scanline_mips_##name##_##op, \ - src_type, uint8_t, dst_type, COVER, TRUE, FALSE)\ -FAST_NEAREST_MAINLOOP_COMMON (mips_##name##_none_##op, \ - scaled_nearest_scanline_mips_##name##_##op, \ - src_type, uint8_t, dst_type, NONE, TRUE, FALSE) \ -FAST_NEAREST_MAINLOOP_COMMON (mips_##name##_pad_##op, \ - scaled_nearest_scanline_mips_##name##_##op, \ - src_type, uint8_t, dst_type, PAD, TRUE, FALSE) - -/****************************************************************************/ - -#define PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_DST(flags, name, op, \ - src_type, dst_type) \ -void \ -pixman_scaled_bilinear_scanline_##name##_##op##_asm_mips( \ - dst_type * dst, \ - const src_type * src_top, \ - const src_type * src_bottom, \ - int32_t w, \ - int wt, \ - int wb, \ - pixman_fixed_t vx, \ - pixman_fixed_t unit_x); \ -static force_inline void \ -scaled_bilinear_scanline_mips_##name##_##op (dst_type * dst, \ - const uint32_t * mask, \ - const src_type * src_top, \ - const src_type * src_bottom, \ - int32_t w, \ - int wt, \ - int wb, \ - pixman_fixed_t vx, \ - pixman_fixed_t unit_x, \ - pixman_fixed_t max_vx, \ - pixman_bool_t zero_src) \ -{ \ - if ((flags & SKIP_ZERO_SRC) && zero_src) \ - return; \ - pixman_scaled_bilinear_scanline_##name##_##op##_asm_mips (dst, src_top, \ - src_bottom, w, \ - wt, wb, \ - vx, unit_x); \ -} \ - \ -FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_cover_##op, \ - scaled_bilinear_scanline_mips_##name##_##op, \ - src_type, uint32_t, dst_type, COVER, FLAG_NONE) \ -FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_none_##op, \ - scaled_bilinear_scanline_mips_##name##_##op, \ - src_type, uint32_t, dst_type, NONE, FLAG_NONE) \ -FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_pad_##op, \ - scaled_bilinear_scanline_mips_##name##_##op, \ - src_type, uint32_t, dst_type, PAD, FLAG_NONE) \ -FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_normal_##op, \ - scaled_bilinear_scanline_mips_##name##_##op, \ - src_type, uint32_t, dst_type, NORMAL, \ - FLAG_NONE) - -/*****************************************************************************/ - -#define PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_A8_DST(flags, name, op, \ - src_type, dst_type) \ -void \ -pixman_scaled_bilinear_scanline_##name##_##op##_asm_mips ( \ - dst_type * dst, \ - const uint8_t * mask, \ - const src_type * top, \ - const src_type * bottom, \ - int wt, \ - int wb, \ - pixman_fixed_t x, \ - pixman_fixed_t ux, \ - int width); \ - \ -static force_inline void \ -scaled_bilinear_scanline_mips_##name##_##op (dst_type * dst, \ - const uint8_t * mask, \ - const src_type * src_top, \ - const src_type * src_bottom, \ - int32_t w, \ - int wt, \ - int wb, \ - pixman_fixed_t vx, \ - pixman_fixed_t unit_x, \ - pixman_fixed_t max_vx, \ - pixman_bool_t zero_src) \ -{ \ - if ((flags & SKIP_ZERO_SRC) && zero_src) \ - return; \ - pixman_scaled_bilinear_scanline_##name##_##op##_asm_mips ( \ - dst, mask, src_top, src_bottom, wt, wb, vx, unit_x, w); \ -} \ - \ -FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_cover_##op, \ - scaled_bilinear_scanline_mips_##name##_##op, \ - src_type, uint8_t, dst_type, COVER, \ - FLAG_HAVE_NON_SOLID_MASK) \ -FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_none_##op, \ - scaled_bilinear_scanline_mips_##name##_##op, \ - src_type, uint8_t, dst_type, NONE, \ - FLAG_HAVE_NON_SOLID_MASK) \ -FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_pad_##op, \ - scaled_bilinear_scanline_mips_##name##_##op, \ - src_type, uint8_t, dst_type, PAD, \ - FLAG_HAVE_NON_SOLID_MASK) \ -FAST_BILINEAR_MAINLOOP_COMMON (mips_##name##_normal_##op, \ - scaled_bilinear_scanline_mips_##name##_##op, \ - src_type, uint8_t, dst_type, NORMAL, \ - FLAG_HAVE_NON_SOLID_MASK) - -#endif //PIXMAN_MIPS_DSPR2_H diff --git a/source/libs/pixman/pixman-src/pixman/pixman-mips-memcpy-asm.S b/source/libs/pixman/pixman-src/pixman/pixman-mips-memcpy-asm.S deleted file mode 100644 index 9ad6da5378628ecabdc572fc20f38b7975feb1e1..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-mips-memcpy-asm.S +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Copyright (c) 2012 - * MIPS Technologies, Inc., California. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "pixman-mips-dspr2-asm.h" - -/* - * This routine could be optimized for MIPS64. The current code only - * uses MIPS32 instructions. - */ - -#ifdef EB -# define LWHI lwl /* high part is left in big-endian */ -# define SWHI swl /* high part is left in big-endian */ -# define LWLO lwr /* low part is right in big-endian */ -# define SWLO swr /* low part is right in big-endian */ -#else -# define LWHI lwr /* high part is right in little-endian */ -# define SWHI swr /* high part is right in little-endian */ -# define LWLO lwl /* low part is left in big-endian */ -# define SWLO swl /* low part is left in big-endian */ -#endif - -LEAF_MIPS32R2(pixman_mips_fast_memcpy) - - slti AT, a2, 8 - bne AT, zero, $last8 - move v0, a0 /* memcpy returns the dst pointer */ - -/* Test if the src and dst are word-aligned, or can be made word-aligned */ - xor t8, a1, a0 - andi t8, t8, 0x3 /* t8 is a0/a1 word-displacement */ - - bne t8, zero, $unaligned - negu a3, a0 - - andi a3, a3, 0x3 /* we need to copy a3 bytes to make a0/a1 aligned */ - beq a3, zero, $chk16w /* when a3=0 then the dst (a0) is word-aligned */ - subu a2, a2, a3 /* now a2 is the remining bytes count */ - - LWHI t8, 0(a1) - addu a1, a1, a3 - SWHI t8, 0(a0) - addu a0, a0, a3 - -/* Now the dst/src are mutually word-aligned with word-aligned addresses */ -$chk16w: andi t8, a2, 0x3f /* any whole 64-byte chunks? */ - /* t8 is the byte count after 64-byte chunks */ - - beq a2, t8, $chk8w /* if a2==t8, no 64-byte chunks */ - /* There will be at most 1 32-byte chunk after it */ - subu a3, a2, t8 /* subtract from a2 the reminder */ - /* Here a3 counts bytes in 16w chunks */ - addu a3, a0, a3 /* Now a3 is the final dst after 64-byte chunks */ - - addu t0, a0, a2 /* t0 is the "past the end" address */ - -/* - * When in the loop we exercise "pref 30, x(a0)", the a0+x should not be past - * the "t0-32" address - * This means: for x=128 the last "safe" a0 address is "t0-160" - * Alternatively, for x=64 the last "safe" a0 address is "t0-96" - * In the current version we use "pref 30, 128(a0)", so "t0-160" is the limit - */ - subu t9, t0, 160 /* t9 is the "last safe pref 30, 128(a0)" address */ - - pref 0, 0(a1) /* bring the first line of src, addr 0 */ - pref 0, 32(a1) /* bring the second line of src, addr 32 */ - pref 0, 64(a1) /* bring the third line of src, addr 64 */ - pref 30, 32(a0) /* safe, as we have at least 64 bytes ahead */ -/* In case the a0 > t9 don't use "pref 30" at all */ - sgtu v1, a0, t9 - bgtz v1, $loop16w /* skip "pref 30, 64(a0)" for too short arrays */ - nop -/* otherwise, start with using pref30 */ - pref 30, 64(a0) -$loop16w: - pref 0, 96(a1) - lw t0, 0(a1) - bgtz v1, $skip_pref30_96 /* skip "pref 30, 96(a0)" */ - lw t1, 4(a1) - pref 30, 96(a0) /* continue setting up the dest, addr 96 */ -$skip_pref30_96: - lw t2, 8(a1) - lw t3, 12(a1) - lw t4, 16(a1) - lw t5, 20(a1) - lw t6, 24(a1) - lw t7, 28(a1) - pref 0, 128(a1) /* bring the next lines of src, addr 128 */ - - sw t0, 0(a0) - sw t1, 4(a0) - sw t2, 8(a0) - sw t3, 12(a0) - sw t4, 16(a0) - sw t5, 20(a0) - sw t6, 24(a0) - sw t7, 28(a0) - - lw t0, 32(a1) - bgtz v1, $skip_pref30_128 /* skip "pref 30, 128(a0)" */ - lw t1, 36(a1) - pref 30, 128(a0) /* continue setting up the dest, addr 128 */ -$skip_pref30_128: - lw t2, 40(a1) - lw t3, 44(a1) - lw t4, 48(a1) - lw t5, 52(a1) - lw t6, 56(a1) - lw t7, 60(a1) - pref 0, 160(a1) /* bring the next lines of src, addr 160 */ - - sw t0, 32(a0) - sw t1, 36(a0) - sw t2, 40(a0) - sw t3, 44(a0) - sw t4, 48(a0) - sw t5, 52(a0) - sw t6, 56(a0) - sw t7, 60(a0) - - addiu a0, a0, 64 /* adding 64 to dest */ - sgtu v1, a0, t9 - bne a0, a3, $loop16w - addiu a1, a1, 64 /* adding 64 to src */ - move a2, t8 - -/* Here we have src and dest word-aligned but less than 64-bytes to go */ - -$chk8w: - pref 0, 0x0(a1) - andi t8, a2, 0x1f /* is there a 32-byte chunk? */ - /* the t8 is the reminder count past 32-bytes */ - beq a2, t8, $chk1w /* when a2=t8, no 32-byte chunk */ - nop - - lw t0, 0(a1) - lw t1, 4(a1) - lw t2, 8(a1) - lw t3, 12(a1) - lw t4, 16(a1) - lw t5, 20(a1) - lw t6, 24(a1) - lw t7, 28(a1) - addiu a1, a1, 32 - - sw t0, 0(a0) - sw t1, 4(a0) - sw t2, 8(a0) - sw t3, 12(a0) - sw t4, 16(a0) - sw t5, 20(a0) - sw t6, 24(a0) - sw t7, 28(a0) - addiu a0, a0, 32 - -$chk1w: - andi a2, t8, 0x3 /* now a2 is the reminder past 1w chunks */ - beq a2, t8, $last8 - subu a3, t8, a2 /* a3 is count of bytes in 1w chunks */ - addu a3, a0, a3 /* now a3 is the dst address past the 1w chunks */ - -/* copying in words (4-byte chunks) */ -$wordCopy_loop: - lw t3, 0(a1) /* the first t3 may be equal t0 ... optimize? */ - addiu a1, a1, 4 - addiu a0, a0, 4 - bne a0, a3, $wordCopy_loop - sw t3, -4(a0) - -/* For the last (<8) bytes */ -$last8: - blez a2, leave - addu a3, a0, a2 /* a3 is the last dst address */ -$last8loop: - lb v1, 0(a1) - addiu a1, a1, 1 - addiu a0, a0, 1 - bne a0, a3, $last8loop - sb v1, -1(a0) - -leave: j ra - nop - -/* - * UNALIGNED case - */ - -$unaligned: - /* got here with a3="negu a0" */ - andi a3, a3, 0x3 /* test if the a0 is word aligned */ - beqz a3, $ua_chk16w - subu a2, a2, a3 /* bytes left after initial a3 bytes */ - - LWHI v1, 0(a1) - LWLO v1, 3(a1) - addu a1, a1, a3 /* a3 may be here 1, 2 or 3 */ - SWHI v1, 0(a0) - addu a0, a0, a3 /* below the dst will be word aligned (NOTE1) */ - -$ua_chk16w: andi t8, a2, 0x3f /* any whole 64-byte chunks? */ - /* t8 is the byte count after 64-byte chunks */ - beq a2, t8, $ua_chk8w /* if a2==t8, no 64-byte chunks */ - /* There will be at most 1 32-byte chunk after it */ - subu a3, a2, t8 /* subtract from a2 the reminder */ - /* Here a3 counts bytes in 16w chunks */ - addu a3, a0, a3 /* Now a3 is the final dst after 64-byte chunks */ - - addu t0, a0, a2 /* t0 is the "past the end" address */ - - subu t9, t0, 160 /* t9 is the "last safe pref 30, 128(a0)" address */ - - pref 0, 0(a1) /* bring the first line of src, addr 0 */ - pref 0, 32(a1) /* bring the second line of src, addr 32 */ - pref 0, 64(a1) /* bring the third line of src, addr 64 */ - pref 30, 32(a0) /* safe, as we have at least 64 bytes ahead */ -/* In case the a0 > t9 don't use "pref 30" at all */ - sgtu v1, a0, t9 - bgtz v1, $ua_loop16w /* skip "pref 30, 64(a0)" for too short arrays */ - nop -/* otherwise, start with using pref30 */ - pref 30, 64(a0) -$ua_loop16w: - pref 0, 96(a1) - LWHI t0, 0(a1) - LWLO t0, 3(a1) - LWHI t1, 4(a1) - bgtz v1, $ua_skip_pref30_96 - LWLO t1, 7(a1) - pref 30, 96(a0) /* continue setting up the dest, addr 96 */ -$ua_skip_pref30_96: - LWHI t2, 8(a1) - LWLO t2, 11(a1) - LWHI t3, 12(a1) - LWLO t3, 15(a1) - LWHI t4, 16(a1) - LWLO t4, 19(a1) - LWHI t5, 20(a1) - LWLO t5, 23(a1) - LWHI t6, 24(a1) - LWLO t6, 27(a1) - LWHI t7, 28(a1) - LWLO t7, 31(a1) - pref 0, 128(a1) /* bring the next lines of src, addr 128 */ - - sw t0, 0(a0) - sw t1, 4(a0) - sw t2, 8(a0) - sw t3, 12(a0) - sw t4, 16(a0) - sw t5, 20(a0) - sw t6, 24(a0) - sw t7, 28(a0) - - LWHI t0, 32(a1) - LWLO t0, 35(a1) - LWHI t1, 36(a1) - bgtz v1, $ua_skip_pref30_128 - LWLO t1, 39(a1) - pref 30, 128(a0) /* continue setting up the dest, addr 128 */ -$ua_skip_pref30_128: - LWHI t2, 40(a1) - LWLO t2, 43(a1) - LWHI t3, 44(a1) - LWLO t3, 47(a1) - LWHI t4, 48(a1) - LWLO t4, 51(a1) - LWHI t5, 52(a1) - LWLO t5, 55(a1) - LWHI t6, 56(a1) - LWLO t6, 59(a1) - LWHI t7, 60(a1) - LWLO t7, 63(a1) - pref 0, 160(a1) /* bring the next lines of src, addr 160 */ - - sw t0, 32(a0) - sw t1, 36(a0) - sw t2, 40(a0) - sw t3, 44(a0) - sw t4, 48(a0) - sw t5, 52(a0) - sw t6, 56(a0) - sw t7, 60(a0) - - addiu a0, a0, 64 /* adding 64 to dest */ - sgtu v1, a0, t9 - bne a0, a3, $ua_loop16w - addiu a1, a1, 64 /* adding 64 to src */ - move a2, t8 - -/* Here we have src and dest word-aligned but less than 64-bytes to go */ - -$ua_chk8w: - pref 0, 0x0(a1) - andi t8, a2, 0x1f /* is there a 32-byte chunk? */ - /* the t8 is the reminder count */ - beq a2, t8, $ua_chk1w /* when a2=t8, no 32-byte chunk */ - - LWHI t0, 0(a1) - LWLO t0, 3(a1) - LWHI t1, 4(a1) - LWLO t1, 7(a1) - LWHI t2, 8(a1) - LWLO t2, 11(a1) - LWHI t3, 12(a1) - LWLO t3, 15(a1) - LWHI t4, 16(a1) - LWLO t4, 19(a1) - LWHI t5, 20(a1) - LWLO t5, 23(a1) - LWHI t6, 24(a1) - LWLO t6, 27(a1) - LWHI t7, 28(a1) - LWLO t7, 31(a1) - addiu a1, a1, 32 - - sw t0, 0(a0) - sw t1, 4(a0) - sw t2, 8(a0) - sw t3, 12(a0) - sw t4, 16(a0) - sw t5, 20(a0) - sw t6, 24(a0) - sw t7, 28(a0) - addiu a0, a0, 32 - -$ua_chk1w: - andi a2, t8, 0x3 /* now a2 is the reminder past 1w chunks */ - beq a2, t8, $ua_smallCopy - subu a3, t8, a2 /* a3 is count of bytes in 1w chunks */ - addu a3, a0, a3 /* now a3 is the dst address past the 1w chunks */ - -/* copying in words (4-byte chunks) */ -$ua_wordCopy_loop: - LWHI v1, 0(a1) - LWLO v1, 3(a1) - addiu a1, a1, 4 - addiu a0, a0, 4 /* note: dst=a0 is word aligned here, see NOTE1 */ - bne a0, a3, $ua_wordCopy_loop - sw v1, -4(a0) - -/* Now less than 4 bytes (value in a2) left to copy */ -$ua_smallCopy: - beqz a2, leave - addu a3, a0, a2 /* a3 is the last dst address */ -$ua_smallCopy_loop: - lb v1, 0(a1) - addiu a1, a1, 1 - addiu a0, a0, 1 - bne a0, a3, $ua_smallCopy_loop - sb v1, -1(a0) - - j ra - nop - -END(pixman_mips_fast_memcpy) diff --git a/source/libs/pixman/pixman-src/pixman/pixman-mips.c b/source/libs/pixman/pixman-src/pixman/pixman-mips.c deleted file mode 100644 index 304881383b53292dac306f69012db8d2996cfbb6..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-mips.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright © 2000 SuSE, Inc. - * Copyright © 2007 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 SuSE not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. SuSE makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE - * 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. - */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "pixman-private.h" - -#if defined(USE_MIPS_DSPR2) || defined(USE_LOONGSON_MMI) - -#include <string.h> -#include <stdlib.h> - -static pixman_bool_t -have_feature (const char *search_string) -{ -#if defined (__linux__) /* linux ELF */ - /* Simple detection of MIPS features at runtime for Linux. - * It is based on /proc/cpuinfo, which reveals hardware configuration - * to user-space applications. According to MIPS (early 2010), no similar - * facility is universally available on the MIPS architectures, so it's up - * to individual OSes to provide such. - */ - const char *file_name = "/proc/cpuinfo"; - char cpuinfo_line[256]; - FILE *f = NULL; - - if ((f = fopen (file_name, "r")) == NULL) - return FALSE; - - while (fgets (cpuinfo_line, sizeof (cpuinfo_line), f) != NULL) - { - if (strstr (cpuinfo_line, search_string) != NULL) - { - fclose (f); - return TRUE; - } - } - - fclose (f); -#endif - - /* Did not find string in the proc file, or not Linux ELF. */ - return FALSE; -} - -#endif - -pixman_implementation_t * -_pixman_mips_get_implementations (pixman_implementation_t *imp) -{ -#ifdef USE_LOONGSON_MMI - /* I really don't know if some Loongson CPUs don't have MMI. */ - if (!_pixman_disabled ("loongson-mmi") && have_feature ("Loongson")) - imp = _pixman_implementation_create_mmx (imp); -#endif - -#ifdef USE_MIPS_DSPR2 - if (!_pixman_disabled ("mips-dspr2")) - { - int already_compiling_everything_for_dspr2 = 0; -#if defined(__mips_dsp) && (__mips_dsp_rev >= 2) - already_compiling_everything_for_dspr2 = 1; -#endif - if (already_compiling_everything_for_dspr2 || - /* Only currently available MIPS core that supports DSPr2 is 74K. */ - have_feature ("MIPS 74K")) - { - imp = _pixman_implementation_create_mips_dspr2 (imp); - } - } -#endif - - return imp; -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman-mmx.c b/source/libs/pixman/pixman-src/pixman/pixman-mmx.c deleted file mode 100644 index dec3974324259f2c5d669870d144fda839adf7ec..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-mmx.c +++ /dev/null @@ -1,4149 +0,0 @@ -/* - * Copyright © 2004, 2005 Red Hat, Inc. - * Copyright © 2004 Nicholas Miell - * Copyright © 2005 Trolltech AS - * - * 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 not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. Red Hat makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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: Søren Sandmann (sandmann@redhat.com) - * Minor Improvements: Nicholas Miell (nmiell@gmail.com) - * MMX code paths for fbcompose.c by Lars Knoll (lars@trolltech.com) - * - * Based on work by Owen Taylor - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#if defined USE_X86_MMX || defined USE_ARM_IWMMXT || defined USE_LOONGSON_MMI - -#ifdef USE_LOONGSON_MMI -#include <loongson-mmintrin.h> -#else -#include <mmintrin.h> -#endif -#include "pixman-private.h" -#include "pixman-combine32.h" -#include "pixman-inlines.h" - -#ifdef VERBOSE -#define CHECKPOINT() error_f ("at %s %d\n", __FUNCTION__, __LINE__) -#else -#define CHECKPOINT() -#endif - -#if defined USE_ARM_IWMMXT && __GNUC__ == 4 && __GNUC_MINOR__ < 8 -/* Empty the multimedia state. For some reason, ARM's mmintrin.h doesn't provide this. */ -extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_empty (void) -{ - -} -#endif - -#ifdef USE_X86_MMX -# if (defined(__SUNPRO_C) || defined(_MSC_VER) || defined(_WIN64)) -# include <xmmintrin.h> -# else -/* We have to compile with -msse to use xmmintrin.h, but that causes SSE - * instructions to be generated that we don't want. Just duplicate the - * functions we want to use. */ -extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_movemask_pi8 (__m64 __A) -{ - int ret; - - asm ("pmovmskb %1, %0\n\t" - : "=r" (ret) - : "y" (__A) - ); - - return ret; -} - -extern __inline __m64 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_mulhi_pu16 (__m64 __A, __m64 __B) -{ - asm ("pmulhuw %1, %0\n\t" - : "+y" (__A) - : "y" (__B) - ); - return __A; -} - -# define _mm_shuffle_pi16(A, N) \ - ({ \ - __m64 ret; \ - \ - asm ("pshufw %2, %1, %0\n\t" \ - : "=y" (ret) \ - : "y" (A), "K" ((const int8_t)N) \ - ); \ - \ - ret; \ - }) -# endif -#endif - -#ifndef _MSC_VER -#define _MM_SHUFFLE(fp3,fp2,fp1,fp0) \ - (((fp3) << 6) | ((fp2) << 4) | ((fp1) << 2) | (fp0)) -#endif - -/* Notes about writing mmx code - * - * give memory operands as the second operand. If you give it as the - * first, gcc will first load it into a register, then use that - * register - * - * ie. use - * - * _mm_mullo_pi16 (x, mmx_constant); - * - * not - * - * _mm_mullo_pi16 (mmx_constant, x); - * - * Also try to minimize dependencies. i.e. when you need a value, try - * to calculate it from a value that was calculated as early as - * possible. - */ - -/* --------------- MMX primitives ------------------------------------- */ - -/* If __m64 is defined as a struct or union, then define M64_MEMBER to be - * the name of the member used to access the data. - * If __m64 requires using mm_cvt* intrinsics functions to convert between - * uint64_t and __m64 values, then define USE_CVT_INTRINSICS. - * If __m64 and uint64_t values can just be cast to each other directly, - * then define USE_M64_CASTS. - * If __m64 is a double datatype, then define USE_M64_DOUBLE. - */ -#ifdef _MSC_VER -# define M64_MEMBER m64_u64 -#elif defined(__ICC) -# define USE_CVT_INTRINSICS -#elif defined(USE_LOONGSON_MMI) -# define USE_M64_DOUBLE -#elif defined(__GNUC__) -# define USE_M64_CASTS -#elif defined(__SUNPRO_C) -# if (__SUNPRO_C >= 0x5120) && !defined(__NOVECTORSIZE__) -/* Solaris Studio 12.3 (Sun C 5.12) introduces __attribute__(__vector_size__) - * support, and defaults to using it to define __m64, unless __NOVECTORSIZE__ - * is defined. If it is used, then the mm_cvt* intrinsics must be used. - */ -# define USE_CVT_INTRINSICS -# else -/* For Studio 12.2 or older, or when __attribute__(__vector_size__) is - * disabled, __m64 is defined as a struct containing "unsigned long long l_". - */ -# define M64_MEMBER l_ -# endif -#endif - -#if defined(USE_M64_CASTS) || defined(USE_CVT_INTRINSICS) || defined(USE_M64_DOUBLE) -typedef uint64_t mmxdatafield; -#else -typedef __m64 mmxdatafield; -#endif - -typedef struct -{ - mmxdatafield mmx_4x00ff; - mmxdatafield mmx_4x0080; - mmxdatafield mmx_565_rgb; - mmxdatafield mmx_565_unpack_multiplier; - mmxdatafield mmx_565_pack_multiplier; - mmxdatafield mmx_565_r; - mmxdatafield mmx_565_g; - mmxdatafield mmx_565_b; - mmxdatafield mmx_packed_565_rb; - mmxdatafield mmx_packed_565_g; - mmxdatafield mmx_expand_565_g; - mmxdatafield mmx_expand_565_b; - mmxdatafield mmx_expand_565_r; -#ifndef USE_LOONGSON_MMI - mmxdatafield mmx_mask_0; - mmxdatafield mmx_mask_1; - mmxdatafield mmx_mask_2; - mmxdatafield mmx_mask_3; -#endif - mmxdatafield mmx_full_alpha; - mmxdatafield mmx_4x0101; - mmxdatafield mmx_ff000000; -} mmx_data_t; - -#if defined(_MSC_VER) -# define MMXDATA_INIT(field, val) { val ## UI64 } -#elif defined(M64_MEMBER) /* __m64 is a struct, not an integral type */ -# define MMXDATA_INIT(field, val) field = { val ## ULL } -#else /* mmxdatafield is an integral type */ -# define MMXDATA_INIT(field, val) field = val ## ULL -#endif - -static const mmx_data_t c = -{ - MMXDATA_INIT (.mmx_4x00ff, 0x00ff00ff00ff00ff), - MMXDATA_INIT (.mmx_4x0080, 0x0080008000800080), - MMXDATA_INIT (.mmx_565_rgb, 0x000001f0003f001f), - MMXDATA_INIT (.mmx_565_unpack_multiplier, 0x0000008404100840), - MMXDATA_INIT (.mmx_565_pack_multiplier, 0x2000000420000004), - MMXDATA_INIT (.mmx_565_r, 0x000000f800000000), - MMXDATA_INIT (.mmx_565_g, 0x0000000000fc0000), - MMXDATA_INIT (.mmx_565_b, 0x00000000000000f8), - MMXDATA_INIT (.mmx_packed_565_rb, 0x00f800f800f800f8), - MMXDATA_INIT (.mmx_packed_565_g, 0x0000fc000000fc00), - MMXDATA_INIT (.mmx_expand_565_g, 0x07e007e007e007e0), - MMXDATA_INIT (.mmx_expand_565_b, 0x001f001f001f001f), - MMXDATA_INIT (.mmx_expand_565_r, 0xf800f800f800f800), -#ifndef USE_LOONGSON_MMI - MMXDATA_INIT (.mmx_mask_0, 0xffffffffffff0000), - MMXDATA_INIT (.mmx_mask_1, 0xffffffff0000ffff), - MMXDATA_INIT (.mmx_mask_2, 0xffff0000ffffffff), - MMXDATA_INIT (.mmx_mask_3, 0x0000ffffffffffff), -#endif - MMXDATA_INIT (.mmx_full_alpha, 0x00ff000000000000), - MMXDATA_INIT (.mmx_4x0101, 0x0101010101010101), - MMXDATA_INIT (.mmx_ff000000, 0xff000000ff000000), -}; - -#ifdef USE_CVT_INTRINSICS -# define MC(x) to_m64 (c.mmx_ ## x) -#elif defined(USE_M64_CASTS) -# define MC(x) ((__m64)c.mmx_ ## x) -#elif defined(USE_M64_DOUBLE) -# define MC(x) (*(__m64 *)&c.mmx_ ## x) -#else -# define MC(x) c.mmx_ ## x -#endif - -static force_inline __m64 -to_m64 (uint64_t x) -{ -#ifdef USE_CVT_INTRINSICS - return _mm_cvtsi64_m64 (x); -#elif defined M64_MEMBER /* __m64 is a struct, not an integral type */ - __m64 res; - - res.M64_MEMBER = x; - return res; -#elif defined USE_M64_DOUBLE - return *(__m64 *)&x; -#else /* USE_M64_CASTS */ - return (__m64)x; -#endif -} - -static force_inline uint64_t -to_uint64 (__m64 x) -{ -#ifdef USE_CVT_INTRINSICS - return _mm_cvtm64_si64 (x); -#elif defined M64_MEMBER /* __m64 is a struct, not an integral type */ - uint64_t res = x.M64_MEMBER; - return res; -#elif defined USE_M64_DOUBLE - return *(uint64_t *)&x; -#else /* USE_M64_CASTS */ - return (uint64_t)x; -#endif -} - -static force_inline __m64 -shift (__m64 v, - int s) -{ - if (s > 0) - return _mm_slli_si64 (v, s); - else if (s < 0) - return _mm_srli_si64 (v, -s); - else - return v; -} - -static force_inline __m64 -negate (__m64 mask) -{ - return _mm_xor_si64 (mask, MC (4x00ff)); -} - -/* Computes the product of two unsigned fixed-point 8-bit values from 0 to 1 - * and maps its result to the same range. - * - * Jim Blinn gives multiple ways to compute this in "Jim Blinn's Corner: - * Notation, Notation, Notation", the first of which is - * - * prod(a, b) = (a * b + 128) / 255. - * - * By approximating the division by 255 as 257/65536 it can be replaced by a - * multiply and a right shift. This is the implementation that we use in - * pix_multiply(), but we _mm_mulhi_pu16() by 257 (part of SSE1 or Extended - * 3DNow!, and unavailable at the time of the book's publication) to perform - * the multiplication and right shift in a single operation. - * - * prod(a, b) = ((a * b + 128) * 257) >> 16. - * - * A third way (how pix_multiply() was implemented prior to 14208344) exists - * also that performs the multiplication by 257 with adds and shifts. - * - * Where temp = a * b + 128 - * - * prod(a, b) = (temp + (temp >> 8)) >> 8. - */ -static force_inline __m64 -pix_multiply (__m64 a, __m64 b) -{ - __m64 res; - - res = _mm_mullo_pi16 (a, b); - res = _mm_adds_pu16 (res, MC (4x0080)); - res = _mm_mulhi_pu16 (res, MC (4x0101)); - - return res; -} - -static force_inline __m64 -pix_add (__m64 a, __m64 b) -{ - return _mm_adds_pu8 (a, b); -} - -static force_inline __m64 -expand_alpha (__m64 pixel) -{ - return _mm_shuffle_pi16 (pixel, _MM_SHUFFLE (3, 3, 3, 3)); -} - -static force_inline __m64 -expand_alpha_rev (__m64 pixel) -{ - return _mm_shuffle_pi16 (pixel, _MM_SHUFFLE (0, 0, 0, 0)); -} - -static force_inline __m64 -invert_colors (__m64 pixel) -{ - return _mm_shuffle_pi16 (pixel, _MM_SHUFFLE (3, 0, 1, 2)); -} - -static force_inline __m64 -over (__m64 src, - __m64 srca, - __m64 dest) -{ - return _mm_adds_pu8 (src, pix_multiply (dest, negate (srca))); -} - -static force_inline __m64 -over_rev_non_pre (__m64 src, __m64 dest) -{ - __m64 srca = expand_alpha (src); - __m64 srcfaaa = _mm_or_si64 (srca, MC (full_alpha)); - - return over (pix_multiply (invert_colors (src), srcfaaa), srca, dest); -} - -static force_inline __m64 -in (__m64 src, __m64 mask) -{ - return pix_multiply (src, mask); -} - -#ifndef _MSC_VER -static force_inline __m64 -in_over (__m64 src, __m64 srca, __m64 mask, __m64 dest) -{ - return over (in (src, mask), pix_multiply (srca, mask), dest); -} - -#else - -#define in_over(src, srca, mask, dest) \ - over (in (src, mask), pix_multiply (srca, mask), dest) - -#endif - -/* Elemental unaligned loads */ - -static force_inline __m64 ldq_u(__m64 *p) -{ -#ifdef USE_X86_MMX - /* x86's alignment restrictions are very relaxed. */ - return *(__m64 *)p; -#elif defined USE_ARM_IWMMXT - int align = (uintptr_t)p & 7; - __m64 *aligned_p; - if (align == 0) - return *p; - aligned_p = (__m64 *)((uintptr_t)p & ~7); - return (__m64) _mm_align_si64 (aligned_p[0], aligned_p[1], align); -#else - struct __una_u64 { __m64 x __attribute__((packed)); }; - const struct __una_u64 *ptr = (const struct __una_u64 *) p; - return (__m64) ptr->x; -#endif -} - -static force_inline uint32_t ldl_u(const uint32_t *p) -{ -#ifdef USE_X86_MMX - /* x86's alignment restrictions are very relaxed. */ - return *p; -#else - struct __una_u32 { uint32_t x __attribute__((packed)); }; - const struct __una_u32 *ptr = (const struct __una_u32 *) p; - return ptr->x; -#endif -} - -static force_inline __m64 -load (const uint32_t *v) -{ -#ifdef USE_LOONGSON_MMI - __m64 ret; - asm ("lwc1 %0, %1\n\t" - : "=f" (ret) - : "m" (*v) - ); - return ret; -#else - return _mm_cvtsi32_si64 (*v); -#endif -} - -static force_inline __m64 -load8888 (const uint32_t *v) -{ -#ifdef USE_LOONGSON_MMI - return _mm_unpacklo_pi8_f (*(__m32 *)v, _mm_setzero_si64 ()); -#else - return _mm_unpacklo_pi8 (load (v), _mm_setzero_si64 ()); -#endif -} - -static force_inline __m64 -load8888u (const uint32_t *v) -{ - uint32_t l = ldl_u (v); - return load8888 (&l); -} - -static force_inline __m64 -pack8888 (__m64 lo, __m64 hi) -{ - return _mm_packs_pu16 (lo, hi); -} - -static force_inline void -store (uint32_t *dest, __m64 v) -{ -#ifdef USE_LOONGSON_MMI - asm ("swc1 %1, %0\n\t" - : "=m" (*dest) - : "f" (v) - : "memory" - ); -#else - *dest = _mm_cvtsi64_si32 (v); -#endif -} - -static force_inline void -store8888 (uint32_t *dest, __m64 v) -{ - v = pack8888 (v, _mm_setzero_si64 ()); - store (dest, v); -} - -static force_inline pixman_bool_t -is_equal (__m64 a, __m64 b) -{ -#ifdef USE_LOONGSON_MMI - /* __m64 is double, we can compare directly. */ - return a == b; -#else - return _mm_movemask_pi8 (_mm_cmpeq_pi8 (a, b)) == 0xff; -#endif -} - -static force_inline pixman_bool_t -is_opaque (__m64 v) -{ -#ifdef USE_LOONGSON_MMI - return is_equal (_mm_and_si64 (v, MC (full_alpha)), MC (full_alpha)); -#else - __m64 ffs = _mm_cmpeq_pi8 (v, v); - return (_mm_movemask_pi8 (_mm_cmpeq_pi8 (v, ffs)) & 0x40); -#endif -} - -static force_inline pixman_bool_t -is_zero (__m64 v) -{ - return is_equal (v, _mm_setzero_si64 ()); -} - -/* Expand 16 bits positioned at @pos (0-3) of a mmx register into - * - * 00RR00GG00BB - * - * --- Expanding 565 in the low word --- - * - * m = (m << (32 - 3)) | (m << (16 - 5)) | m; - * m = m & (01f0003f001f); - * m = m * (008404100840); - * m = m >> 8; - * - * Note the trick here - the top word is shifted by another nibble to - * avoid it bumping into the middle word - */ -static force_inline __m64 -expand565 (__m64 pixel, int pos) -{ - __m64 p = pixel; - __m64 t1, t2; - - /* move pixel to low 16 bit and zero the rest */ -#ifdef USE_LOONGSON_MMI - p = loongson_extract_pi16 (p, pos); -#else - p = shift (shift (p, (3 - pos) * 16), -48); -#endif - - t1 = shift (p, 36 - 11); - t2 = shift (p, 16 - 5); - - p = _mm_or_si64 (t1, p); - p = _mm_or_si64 (t2, p); - p = _mm_and_si64 (p, MC (565_rgb)); - - pixel = _mm_mullo_pi16 (p, MC (565_unpack_multiplier)); - return _mm_srli_pi16 (pixel, 8); -} - -/* Expand 4 16 bit pixels in an mmx register into two mmx registers of - * - * AARRGGBBRRGGBB - */ -static force_inline void -expand_4xpacked565 (__m64 vin, __m64 *vout0, __m64 *vout1, int full_alpha) -{ - __m64 t0, t1, alpha = _mm_setzero_si64 (); - __m64 r = _mm_and_si64 (vin, MC (expand_565_r)); - __m64 g = _mm_and_si64 (vin, MC (expand_565_g)); - __m64 b = _mm_and_si64 (vin, MC (expand_565_b)); - if (full_alpha) - alpha = _mm_cmpeq_pi32 (alpha, alpha); - - /* Replicate high bits into empty low bits. */ - r = _mm_or_si64 (_mm_srli_pi16 (r, 8), _mm_srli_pi16 (r, 13)); - g = _mm_or_si64 (_mm_srli_pi16 (g, 3), _mm_srli_pi16 (g, 9)); - b = _mm_or_si64 (_mm_slli_pi16 (b, 3), _mm_srli_pi16 (b, 2)); - - r = _mm_packs_pu16 (r, _mm_setzero_si64 ()); /* 00 00 00 00 R3 R2 R1 R0 */ - g = _mm_packs_pu16 (g, _mm_setzero_si64 ()); /* 00 00 00 00 G3 G2 G1 G0 */ - b = _mm_packs_pu16 (b, _mm_setzero_si64 ()); /* 00 00 00 00 B3 B2 B1 B0 */ - - t1 = _mm_unpacklo_pi8 (r, alpha); /* A3 R3 A2 R2 A1 R1 A0 R0 */ - t0 = _mm_unpacklo_pi8 (b, g); /* G3 B3 G2 B2 G1 B1 G0 B0 */ - - *vout0 = _mm_unpacklo_pi16 (t0, t1); /* A1 R1 G1 B1 A0 R0 G0 B0 */ - *vout1 = _mm_unpackhi_pi16 (t0, t1); /* A3 R3 G3 B3 A2 R2 G2 B2 */ -} - -static force_inline __m64 -expand8888 (__m64 in, int pos) -{ - if (pos == 0) - return _mm_unpacklo_pi8 (in, _mm_setzero_si64 ()); - else - return _mm_unpackhi_pi8 (in, _mm_setzero_si64 ()); -} - -static force_inline __m64 -expandx888 (__m64 in, int pos) -{ - return _mm_or_si64 (expand8888 (in, pos), MC (full_alpha)); -} - -static force_inline void -expand_4x565 (__m64 vin, __m64 *vout0, __m64 *vout1, __m64 *vout2, __m64 *vout3, int full_alpha) -{ - __m64 v0, v1; - expand_4xpacked565 (vin, &v0, &v1, full_alpha); - *vout0 = expand8888 (v0, 0); - *vout1 = expand8888 (v0, 1); - *vout2 = expand8888 (v1, 0); - *vout3 = expand8888 (v1, 1); -} - -static force_inline __m64 -pack_565 (__m64 pixel, __m64 target, int pos) -{ - __m64 p = pixel; - __m64 t = target; - __m64 r, g, b; - - r = _mm_and_si64 (p, MC (565_r)); - g = _mm_and_si64 (p, MC (565_g)); - b = _mm_and_si64 (p, MC (565_b)); - -#ifdef USE_LOONGSON_MMI - r = shift (r, -(32 - 8)); - g = shift (g, -(16 - 3)); - b = shift (b, -(0 + 3)); - - p = _mm_or_si64 (r, g); - p = _mm_or_si64 (p, b); - return loongson_insert_pi16 (t, p, pos); -#else - r = shift (r, -(32 - 8) + pos * 16); - g = shift (g, -(16 - 3) + pos * 16); - b = shift (b, -(0 + 3) + pos * 16); - - if (pos == 0) - t = _mm_and_si64 (t, MC (mask_0)); - else if (pos == 1) - t = _mm_and_si64 (t, MC (mask_1)); - else if (pos == 2) - t = _mm_and_si64 (t, MC (mask_2)); - else if (pos == 3) - t = _mm_and_si64 (t, MC (mask_3)); - - p = _mm_or_si64 (r, t); - p = _mm_or_si64 (g, p); - - return _mm_or_si64 (b, p); -#endif -} - -static force_inline __m64 -pack_4xpacked565 (__m64 a, __m64 b) -{ - __m64 rb0 = _mm_and_si64 (a, MC (packed_565_rb)); - __m64 rb1 = _mm_and_si64 (b, MC (packed_565_rb)); - - __m64 t0 = _mm_madd_pi16 (rb0, MC (565_pack_multiplier)); - __m64 t1 = _mm_madd_pi16 (rb1, MC (565_pack_multiplier)); - - __m64 g0 = _mm_and_si64 (a, MC (packed_565_g)); - __m64 g1 = _mm_and_si64 (b, MC (packed_565_g)); - - t0 = _mm_or_si64 (t0, g0); - t1 = _mm_or_si64 (t1, g1); - - t0 = shift(t0, -5); -#ifdef USE_ARM_IWMMXT - t1 = shift(t1, -5); - return _mm_packs_pu32 (t0, t1); -#else - t1 = shift(t1, -5 + 16); - return _mm_shuffle_pi16 (_mm_or_si64 (t0, t1), _MM_SHUFFLE (3, 1, 2, 0)); -#endif -} - -#ifndef _MSC_VER - -static force_inline __m64 -pack_4x565 (__m64 v0, __m64 v1, __m64 v2, __m64 v3) -{ - return pack_4xpacked565 (pack8888 (v0, v1), pack8888 (v2, v3)); -} - -static force_inline __m64 -pix_add_mul (__m64 x, __m64 a, __m64 y, __m64 b) -{ - x = pix_multiply (x, a); - y = pix_multiply (y, b); - - return pix_add (x, y); -} - -#else - -/* MSVC only handles a "pass by register" of up to three SSE intrinsics */ - -#define pack_4x565(v0, v1, v2, v3) \ - pack_4xpacked565 (pack8888 (v0, v1), pack8888 (v2, v3)) - -#define pix_add_mul(x, a, y, b) \ - ( x = pix_multiply (x, a), \ - y = pix_multiply (y, b), \ - pix_add (x, y) ) - -#endif - -/* --------------- MMX code patch for fbcompose.c --------------------- */ - -static force_inline __m64 -combine (const uint32_t *src, const uint32_t *mask) -{ - __m64 vsrc = load8888 (src); - - if (mask) - { - __m64 m = load8888 (mask); - - m = expand_alpha (m); - vsrc = pix_multiply (vsrc, m); - } - - return vsrc; -} - -static force_inline __m64 -core_combine_over_u_pixel_mmx (__m64 vsrc, __m64 vdst) -{ - vsrc = _mm_unpacklo_pi8 (vsrc, _mm_setzero_si64 ()); - - if (is_opaque (vsrc)) - { - return vsrc; - } - else if (!is_zero (vsrc)) - { - return over (vsrc, expand_alpha (vsrc), - _mm_unpacklo_pi8 (vdst, _mm_setzero_si64 ())); - } - - return _mm_unpacklo_pi8 (vdst, _mm_setzero_si64 ()); -} - -static void -mmx_combine_over_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - const uint32_t *end = dest + width; - - while (dest < end) - { - __m64 vsrc = combine (src, mask); - - if (is_opaque (vsrc)) - { - store8888 (dest, vsrc); - } - else if (!is_zero (vsrc)) - { - __m64 sa = expand_alpha (vsrc); - store8888 (dest, over (vsrc, sa, load8888 (dest))); - } - - ++dest; - ++src; - if (mask) - ++mask; - } - _mm_empty (); -} - -static void -mmx_combine_over_reverse_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - const uint32_t *end = dest + width; - - while (dest < end) - { - __m64 d, da; - __m64 s = combine (src, mask); - - d = load8888 (dest); - da = expand_alpha (d); - store8888 (dest, over (d, da, s)); - - ++dest; - ++src; - if (mask) - mask++; - } - _mm_empty (); -} - -static void -mmx_combine_in_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - const uint32_t *end = dest + width; - - while (dest < end) - { - __m64 a; - __m64 x = combine (src, mask); - - a = load8888 (dest); - a = expand_alpha (a); - x = pix_multiply (x, a); - - store8888 (dest, x); - - ++dest; - ++src; - if (mask) - mask++; - } - _mm_empty (); -} - -static void -mmx_combine_in_reverse_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - const uint32_t *end = dest + width; - - while (dest < end) - { - __m64 a = combine (src, mask); - __m64 x; - - x = load8888 (dest); - a = expand_alpha (a); - x = pix_multiply (x, a); - store8888 (dest, x); - - ++dest; - ++src; - if (mask) - mask++; - } - _mm_empty (); -} - -static void -mmx_combine_out_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - const uint32_t *end = dest + width; - - while (dest < end) - { - __m64 a; - __m64 x = combine (src, mask); - - a = load8888 (dest); - a = expand_alpha (a); - a = negate (a); - x = pix_multiply (x, a); - store8888 (dest, x); - - ++dest; - ++src; - if (mask) - mask++; - } - _mm_empty (); -} - -static void -mmx_combine_out_reverse_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - const uint32_t *end = dest + width; - - while (dest < end) - { - __m64 a = combine (src, mask); - __m64 x; - - x = load8888 (dest); - a = expand_alpha (a); - a = negate (a); - x = pix_multiply (x, a); - - store8888 (dest, x); - - ++dest; - ++src; - if (mask) - mask++; - } - _mm_empty (); -} - -static void -mmx_combine_atop_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - const uint32_t *end = dest + width; - - while (dest < end) - { - __m64 da, d, sia; - __m64 s = combine (src, mask); - - d = load8888 (dest); - sia = expand_alpha (s); - sia = negate (sia); - da = expand_alpha (d); - s = pix_add_mul (s, da, d, sia); - store8888 (dest, s); - - ++dest; - ++src; - if (mask) - mask++; - } - _mm_empty (); -} - -static void -mmx_combine_atop_reverse_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - const uint32_t *end; - - end = dest + width; - - while (dest < end) - { - __m64 dia, d, sa; - __m64 s = combine (src, mask); - - d = load8888 (dest); - sa = expand_alpha (s); - dia = expand_alpha (d); - dia = negate (dia); - s = pix_add_mul (s, dia, d, sa); - store8888 (dest, s); - - ++dest; - ++src; - if (mask) - mask++; - } - _mm_empty (); -} - -static void -mmx_combine_xor_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - const uint32_t *end = dest + width; - - while (dest < end) - { - __m64 dia, d, sia; - __m64 s = combine (src, mask); - - d = load8888 (dest); - sia = expand_alpha (s); - dia = expand_alpha (d); - sia = negate (sia); - dia = negate (dia); - s = pix_add_mul (s, dia, d, sia); - store8888 (dest, s); - - ++dest; - ++src; - if (mask) - mask++; - } - _mm_empty (); -} - -static void -mmx_combine_add_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - const uint32_t *end = dest + width; - - while (dest < end) - { - __m64 d; - __m64 s = combine (src, mask); - - d = load8888 (dest); - s = pix_add (s, d); - store8888 (dest, s); - - ++dest; - ++src; - if (mask) - mask++; - } - _mm_empty (); -} - -static void -mmx_combine_saturate_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - const uint32_t *end = dest + width; - - while (dest < end) - { - uint32_t s, sa, da; - uint32_t d = *dest; - __m64 ms = combine (src, mask); - __m64 md = load8888 (dest); - - store8888(&s, ms); - da = ~d >> 24; - sa = s >> 24; - - if (sa > da) - { - uint32_t quot = DIV_UN8 (da, sa) << 24; - __m64 msa = load8888 ("); - msa = expand_alpha (msa); - ms = pix_multiply (ms, msa); - } - - md = pix_add (md, ms); - store8888 (dest, md); - - ++src; - ++dest; - if (mask) - mask++; - } - _mm_empty (); -} - -static void -mmx_combine_src_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - const uint32_t *end = src + width; - - while (src < end) - { - __m64 a = load8888 (mask); - __m64 s = load8888 (src); - - s = pix_multiply (s, a); - store8888 (dest, s); - - ++src; - ++mask; - ++dest; - } - _mm_empty (); -} - -static void -mmx_combine_over_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - const uint32_t *end = src + width; - - while (src < end) - { - __m64 a = load8888 (mask); - __m64 s = load8888 (src); - __m64 d = load8888 (dest); - __m64 sa = expand_alpha (s); - - store8888 (dest, in_over (s, sa, a, d)); - - ++src; - ++dest; - ++mask; - } - _mm_empty (); -} - -static void -mmx_combine_over_reverse_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - const uint32_t *end = src + width; - - while (src < end) - { - __m64 a = load8888 (mask); - __m64 s = load8888 (src); - __m64 d = load8888 (dest); - __m64 da = expand_alpha (d); - - store8888 (dest, over (d, da, in (s, a))); - - ++src; - ++dest; - ++mask; - } - _mm_empty (); -} - -static void -mmx_combine_in_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - const uint32_t *end = src + width; - - while (src < end) - { - __m64 a = load8888 (mask); - __m64 s = load8888 (src); - __m64 d = load8888 (dest); - __m64 da = expand_alpha (d); - - s = pix_multiply (s, a); - s = pix_multiply (s, da); - store8888 (dest, s); - - ++src; - ++dest; - ++mask; - } - _mm_empty (); -} - -static void -mmx_combine_in_reverse_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - const uint32_t *end = src + width; - - while (src < end) - { - __m64 a = load8888 (mask); - __m64 s = load8888 (src); - __m64 d = load8888 (dest); - __m64 sa = expand_alpha (s); - - a = pix_multiply (a, sa); - d = pix_multiply (d, a); - store8888 (dest, d); - - ++src; - ++dest; - ++mask; - } - _mm_empty (); -} - -static void -mmx_combine_out_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - const uint32_t *end = src + width; - - while (src < end) - { - __m64 a = load8888 (mask); - __m64 s = load8888 (src); - __m64 d = load8888 (dest); - __m64 da = expand_alpha (d); - - da = negate (da); - s = pix_multiply (s, a); - s = pix_multiply (s, da); - store8888 (dest, s); - - ++src; - ++dest; - ++mask; - } - _mm_empty (); -} - -static void -mmx_combine_out_reverse_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - const uint32_t *end = src + width; - - while (src < end) - { - __m64 a = load8888 (mask); - __m64 s = load8888 (src); - __m64 d = load8888 (dest); - __m64 sa = expand_alpha (s); - - a = pix_multiply (a, sa); - a = negate (a); - d = pix_multiply (d, a); - store8888 (dest, d); - - ++src; - ++dest; - ++mask; - } - _mm_empty (); -} - -static void -mmx_combine_atop_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - const uint32_t *end = src + width; - - while (src < end) - { - __m64 a = load8888 (mask); - __m64 s = load8888 (src); - __m64 d = load8888 (dest); - __m64 da = expand_alpha (d); - __m64 sa = expand_alpha (s); - - s = pix_multiply (s, a); - a = pix_multiply (a, sa); - a = negate (a); - d = pix_add_mul (d, a, s, da); - store8888 (dest, d); - - ++src; - ++dest; - ++mask; - } - _mm_empty (); -} - -static void -mmx_combine_atop_reverse_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - const uint32_t *end = src + width; - - while (src < end) - { - __m64 a = load8888 (mask); - __m64 s = load8888 (src); - __m64 d = load8888 (dest); - __m64 da = expand_alpha (d); - __m64 sa = expand_alpha (s); - - s = pix_multiply (s, a); - a = pix_multiply (a, sa); - da = negate (da); - d = pix_add_mul (d, a, s, da); - store8888 (dest, d); - - ++src; - ++dest; - ++mask; - } - _mm_empty (); -} - -static void -mmx_combine_xor_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - const uint32_t *end = src + width; - - while (src < end) - { - __m64 a = load8888 (mask); - __m64 s = load8888 (src); - __m64 d = load8888 (dest); - __m64 da = expand_alpha (d); - __m64 sa = expand_alpha (s); - - s = pix_multiply (s, a); - a = pix_multiply (a, sa); - da = negate (da); - a = negate (a); - d = pix_add_mul (d, a, s, da); - store8888 (dest, d); - - ++src; - ++dest; - ++mask; - } - _mm_empty (); -} - -static void -mmx_combine_add_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - const uint32_t *end = src + width; - - while (src < end) - { - __m64 a = load8888 (mask); - __m64 s = load8888 (src); - __m64 d = load8888 (dest); - - s = pix_multiply (s, a); - d = pix_add (s, d); - store8888 (dest, d); - - ++src; - ++dest; - ++mask; - } - _mm_empty (); -} - -/* ------------- MMX code paths called from fbpict.c -------------------- */ - -static void -mmx_composite_over_n_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src; - uint32_t *dst_line, *dst; - int32_t w; - int dst_stride; - __m64 vsrc, vsrca; - - CHECKPOINT (); - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - if (src == 0) - return; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - - vsrc = load8888 (&src); - vsrca = expand_alpha (vsrc); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - w = width; - - CHECKPOINT (); - - while (w && (uintptr_t)dst & 7) - { - store8888 (dst, over (vsrc, vsrca, load8888 (dst))); - - w--; - dst++; - } - - while (w >= 2) - { - __m64 vdest; - __m64 dest0, dest1; - - vdest = *(__m64 *)dst; - - dest0 = over (vsrc, vsrca, expand8888 (vdest, 0)); - dest1 = over (vsrc, vsrca, expand8888 (vdest, 1)); - - *(__m64 *)dst = pack8888 (dest0, dest1); - - dst += 2; - w -= 2; - } - - CHECKPOINT (); - - if (w) - { - store8888 (dst, over (vsrc, vsrca, load8888 (dst))); - } - } - - _mm_empty (); -} - -static void -mmx_composite_over_n_0565 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src; - uint16_t *dst_line, *dst; - int32_t w; - int dst_stride; - __m64 vsrc, vsrca; - - CHECKPOINT (); - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - if (src == 0) - return; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1); - - vsrc = load8888 (&src); - vsrca = expand_alpha (vsrc); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - w = width; - - CHECKPOINT (); - - while (w && (uintptr_t)dst & 7) - { - uint64_t d = *dst; - __m64 vdest = expand565 (to_m64 (d), 0); - - vdest = pack_565 (over (vsrc, vsrca, vdest), vdest, 0); - *dst = to_uint64 (vdest); - - w--; - dst++; - } - - while (w >= 4) - { - __m64 vdest = *(__m64 *)dst; - __m64 v0, v1, v2, v3; - - expand_4x565 (vdest, &v0, &v1, &v2, &v3, 0); - - v0 = over (vsrc, vsrca, v0); - v1 = over (vsrc, vsrca, v1); - v2 = over (vsrc, vsrca, v2); - v3 = over (vsrc, vsrca, v3); - - *(__m64 *)dst = pack_4x565 (v0, v1, v2, v3); - - dst += 4; - w -= 4; - } - - CHECKPOINT (); - - while (w) - { - uint64_t d = *dst; - __m64 vdest = expand565 (to_m64 (d), 0); - - vdest = pack_565 (over (vsrc, vsrca, vdest), vdest, 0); - *dst = to_uint64 (vdest); - - w--; - dst++; - } - } - - _mm_empty (); -} - -static void -mmx_composite_over_n_8888_8888_ca (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src; - uint32_t *dst_line; - uint32_t *mask_line; - int dst_stride, mask_stride; - __m64 vsrc, vsrca; - - CHECKPOINT (); - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - if (src == 0) - return; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint32_t, mask_stride, mask_line, 1); - - vsrc = load8888 (&src); - vsrca = expand_alpha (vsrc); - - while (height--) - { - int twidth = width; - uint32_t *p = (uint32_t *)mask_line; - uint32_t *q = (uint32_t *)dst_line; - - while (twidth && (uintptr_t)q & 7) - { - uint32_t m = *(uint32_t *)p; - - if (m) - { - __m64 vdest = load8888 (q); - vdest = in_over (vsrc, vsrca, load8888 (&m), vdest); - store8888 (q, vdest); - } - - twidth--; - p++; - q++; - } - - while (twidth >= 2) - { - uint32_t m0, m1; - m0 = *p; - m1 = *(p + 1); - - if (m0 | m1) - { - __m64 dest0, dest1; - __m64 vdest = *(__m64 *)q; - - dest0 = in_over (vsrc, vsrca, load8888 (&m0), - expand8888 (vdest, 0)); - dest1 = in_over (vsrc, vsrca, load8888 (&m1), - expand8888 (vdest, 1)); - - *(__m64 *)q = pack8888 (dest0, dest1); - } - - p += 2; - q += 2; - twidth -= 2; - } - - if (twidth) - { - uint32_t m = *(uint32_t *)p; - - if (m) - { - __m64 vdest = load8888 (q); - vdest = in_over (vsrc, vsrca, load8888 (&m), vdest); - store8888 (q, vdest); - } - - twidth--; - p++; - q++; - } - - dst_line += dst_stride; - mask_line += mask_stride; - } - - _mm_empty (); -} - -static void -mmx_composite_over_8888_n_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t *dst_line, *dst; - uint32_t *src_line, *src; - uint32_t mask; - __m64 vmask; - int dst_stride, src_stride; - int32_t w; - - CHECKPOINT (); - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - - mask = _pixman_image_get_solid (imp, mask_image, dest_image->bits.format); - vmask = expand_alpha (load8888 (&mask)); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - while (w && (uintptr_t)dst & 7) - { - __m64 s = load8888 (src); - __m64 d = load8888 (dst); - - store8888 (dst, in_over (s, expand_alpha (s), vmask, d)); - - w--; - dst++; - src++; - } - - while (w >= 2) - { - __m64 vs = ldq_u ((__m64 *)src); - __m64 vd = *(__m64 *)dst; - __m64 vsrc0 = expand8888 (vs, 0); - __m64 vsrc1 = expand8888 (vs, 1); - - *(__m64 *)dst = pack8888 ( - in_over (vsrc0, expand_alpha (vsrc0), vmask, expand8888 (vd, 0)), - in_over (vsrc1, expand_alpha (vsrc1), vmask, expand8888 (vd, 1))); - - w -= 2; - dst += 2; - src += 2; - } - - if (w) - { - __m64 s = load8888 (src); - __m64 d = load8888 (dst); - - store8888 (dst, in_over (s, expand_alpha (s), vmask, d)); - } - } - - _mm_empty (); -} - -static void -mmx_composite_over_x888_n_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t *dst_line, *dst; - uint32_t *src_line, *src; - uint32_t mask; - __m64 vmask; - int dst_stride, src_stride; - int32_t w; - __m64 srca; - - CHECKPOINT (); - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - mask = _pixman_image_get_solid (imp, mask_image, dest_image->bits.format); - - vmask = expand_alpha (load8888 (&mask)); - srca = MC (4x00ff); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - while (w && (uintptr_t)dst & 7) - { - uint32_t ssrc = *src | 0xff000000; - __m64 s = load8888 (&ssrc); - __m64 d = load8888 (dst); - - store8888 (dst, in_over (s, srca, vmask, d)); - - w--; - dst++; - src++; - } - - while (w >= 16) - { - __m64 vd0 = *(__m64 *)(dst + 0); - __m64 vd1 = *(__m64 *)(dst + 2); - __m64 vd2 = *(__m64 *)(dst + 4); - __m64 vd3 = *(__m64 *)(dst + 6); - __m64 vd4 = *(__m64 *)(dst + 8); - __m64 vd5 = *(__m64 *)(dst + 10); - __m64 vd6 = *(__m64 *)(dst + 12); - __m64 vd7 = *(__m64 *)(dst + 14); - - __m64 vs0 = ldq_u ((__m64 *)(src + 0)); - __m64 vs1 = ldq_u ((__m64 *)(src + 2)); - __m64 vs2 = ldq_u ((__m64 *)(src + 4)); - __m64 vs3 = ldq_u ((__m64 *)(src + 6)); - __m64 vs4 = ldq_u ((__m64 *)(src + 8)); - __m64 vs5 = ldq_u ((__m64 *)(src + 10)); - __m64 vs6 = ldq_u ((__m64 *)(src + 12)); - __m64 vs7 = ldq_u ((__m64 *)(src + 14)); - - vd0 = pack8888 ( - in_over (expandx888 (vs0, 0), srca, vmask, expand8888 (vd0, 0)), - in_over (expandx888 (vs0, 1), srca, vmask, expand8888 (vd0, 1))); - - vd1 = pack8888 ( - in_over (expandx888 (vs1, 0), srca, vmask, expand8888 (vd1, 0)), - in_over (expandx888 (vs1, 1), srca, vmask, expand8888 (vd1, 1))); - - vd2 = pack8888 ( - in_over (expandx888 (vs2, 0), srca, vmask, expand8888 (vd2, 0)), - in_over (expandx888 (vs2, 1), srca, vmask, expand8888 (vd2, 1))); - - vd3 = pack8888 ( - in_over (expandx888 (vs3, 0), srca, vmask, expand8888 (vd3, 0)), - in_over (expandx888 (vs3, 1), srca, vmask, expand8888 (vd3, 1))); - - vd4 = pack8888 ( - in_over (expandx888 (vs4, 0), srca, vmask, expand8888 (vd4, 0)), - in_over (expandx888 (vs4, 1), srca, vmask, expand8888 (vd4, 1))); - - vd5 = pack8888 ( - in_over (expandx888 (vs5, 0), srca, vmask, expand8888 (vd5, 0)), - in_over (expandx888 (vs5, 1), srca, vmask, expand8888 (vd5, 1))); - - vd6 = pack8888 ( - in_over (expandx888 (vs6, 0), srca, vmask, expand8888 (vd6, 0)), - in_over (expandx888 (vs6, 1), srca, vmask, expand8888 (vd6, 1))); - - vd7 = pack8888 ( - in_over (expandx888 (vs7, 0), srca, vmask, expand8888 (vd7, 0)), - in_over (expandx888 (vs7, 1), srca, vmask, expand8888 (vd7, 1))); - - *(__m64 *)(dst + 0) = vd0; - *(__m64 *)(dst + 2) = vd1; - *(__m64 *)(dst + 4) = vd2; - *(__m64 *)(dst + 6) = vd3; - *(__m64 *)(dst + 8) = vd4; - *(__m64 *)(dst + 10) = vd5; - *(__m64 *)(dst + 12) = vd6; - *(__m64 *)(dst + 14) = vd7; - - w -= 16; - dst += 16; - src += 16; - } - - while (w) - { - uint32_t ssrc = *src | 0xff000000; - __m64 s = load8888 (&ssrc); - __m64 d = load8888 (dst); - - store8888 (dst, in_over (s, srca, vmask, d)); - - w--; - dst++; - src++; - } - } - - _mm_empty (); -} - -static void -mmx_composite_over_8888_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t *dst_line, *dst; - uint32_t *src_line, *src; - uint32_t s; - int dst_stride, src_stride; - uint8_t a; - int32_t w; - - CHECKPOINT (); - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - while (w--) - { - s = *src++; - a = s >> 24; - - if (a == 0xff) - { - *dst = s; - } - else if (s) - { - __m64 ms, sa; - ms = load8888 (&s); - sa = expand_alpha (ms); - store8888 (dst, over (ms, sa, load8888 (dst))); - } - - dst++; - } - } - _mm_empty (); -} - -static void -mmx_composite_over_8888_0565 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint16_t *dst_line, *dst; - uint32_t *src_line, *src; - int dst_stride, src_stride; - int32_t w; - - CHECKPOINT (); - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - -#if 0 - /* FIXME */ - assert (src_image->drawable == mask_image->drawable); -#endif - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - CHECKPOINT (); - - while (w && (uintptr_t)dst & 7) - { - __m64 vsrc = load8888 (src); - uint64_t d = *dst; - __m64 vdest = expand565 (to_m64 (d), 0); - - vdest = pack_565 ( - over (vsrc, expand_alpha (vsrc), vdest), vdest, 0); - - *dst = to_uint64 (vdest); - - w--; - dst++; - src++; - } - - CHECKPOINT (); - - while (w >= 4) - { - __m64 vdest = *(__m64 *)dst; - __m64 v0, v1, v2, v3; - __m64 vsrc0, vsrc1, vsrc2, vsrc3; - - expand_4x565 (vdest, &v0, &v1, &v2, &v3, 0); - - vsrc0 = load8888 ((src + 0)); - vsrc1 = load8888 ((src + 1)); - vsrc2 = load8888 ((src + 2)); - vsrc3 = load8888 ((src + 3)); - - v0 = over (vsrc0, expand_alpha (vsrc0), v0); - v1 = over (vsrc1, expand_alpha (vsrc1), v1); - v2 = over (vsrc2, expand_alpha (vsrc2), v2); - v3 = over (vsrc3, expand_alpha (vsrc3), v3); - - *(__m64 *)dst = pack_4x565 (v0, v1, v2, v3); - - w -= 4; - dst += 4; - src += 4; - } - - CHECKPOINT (); - - while (w) - { - __m64 vsrc = load8888 (src); - uint64_t d = *dst; - __m64 vdest = expand565 (to_m64 (d), 0); - - vdest = pack_565 (over (vsrc, expand_alpha (vsrc), vdest), vdest, 0); - - *dst = to_uint64 (vdest); - - w--; - dst++; - src++; - } - } - - _mm_empty (); -} - -static void -mmx_composite_over_n_8_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src, srca; - uint32_t *dst_line, *dst; - uint8_t *mask_line, *mask; - int dst_stride, mask_stride; - int32_t w; - __m64 vsrc, vsrca; - uint64_t srcsrc; - - CHECKPOINT (); - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - srca = src >> 24; - if (src == 0) - return; - - srcsrc = (uint64_t)src << 32 | src; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); - - vsrc = load8888 (&src); - vsrca = expand_alpha (vsrc); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - w = width; - - CHECKPOINT (); - - while (w && (uintptr_t)dst & 7) - { - uint64_t m = *mask; - - if (m) - { - __m64 vdest = in_over (vsrc, vsrca, - expand_alpha_rev (to_m64 (m)), - load8888 (dst)); - - store8888 (dst, vdest); - } - - w--; - mask++; - dst++; - } - - CHECKPOINT (); - - while (w >= 2) - { - uint64_t m0, m1; - - m0 = *mask; - m1 = *(mask + 1); - - if (srca == 0xff && (m0 & m1) == 0xff) - { - *(uint64_t *)dst = srcsrc; - } - else if (m0 | m1) - { - __m64 vdest; - __m64 dest0, dest1; - - vdest = *(__m64 *)dst; - - dest0 = in_over (vsrc, vsrca, expand_alpha_rev (to_m64 (m0)), - expand8888 (vdest, 0)); - dest1 = in_over (vsrc, vsrca, expand_alpha_rev (to_m64 (m1)), - expand8888 (vdest, 1)); - - *(__m64 *)dst = pack8888 (dest0, dest1); - } - - mask += 2; - dst += 2; - w -= 2; - } - - CHECKPOINT (); - - if (w) - { - uint64_t m = *mask; - - if (m) - { - __m64 vdest = load8888 (dst); - - vdest = in_over ( - vsrc, vsrca, expand_alpha_rev (to_m64 (m)), vdest); - store8888 (dst, vdest); - } - } - } - - _mm_empty (); -} - -static pixman_bool_t -mmx_fill (pixman_implementation_t *imp, - uint32_t * bits, - int stride, - int bpp, - int x, - int y, - int width, - int height, - uint32_t filler) -{ - uint64_t fill; - __m64 vfill; - uint32_t byte_width; - uint8_t *byte_line; - -#if defined __GNUC__ && defined USE_X86_MMX - __m64 v1, v2, v3, v4, v5, v6, v7; -#endif - - if (bpp != 16 && bpp != 32 && bpp != 8) - return FALSE; - - if (bpp == 8) - { - stride = stride * (int) sizeof (uint32_t) / 1; - byte_line = (uint8_t *)(((uint8_t *)bits) + stride * y + x); - byte_width = width; - stride *= 1; - filler = (filler & 0xff) * 0x01010101; - } - else if (bpp == 16) - { - stride = stride * (int) sizeof (uint32_t) / 2; - byte_line = (uint8_t *)(((uint16_t *)bits) + stride * y + x); - byte_width = 2 * width; - stride *= 2; - filler = (filler & 0xffff) * 0x00010001; - } - else - { - stride = stride * (int) sizeof (uint32_t) / 4; - byte_line = (uint8_t *)(((uint32_t *)bits) + stride * y + x); - byte_width = 4 * width; - stride *= 4; - } - - fill = ((uint64_t)filler << 32) | filler; - vfill = to_m64 (fill); - -#if defined __GNUC__ && defined USE_X86_MMX - __asm__ ( - "movq %7, %0\n" - "movq %7, %1\n" - "movq %7, %2\n" - "movq %7, %3\n" - "movq %7, %4\n" - "movq %7, %5\n" - "movq %7, %6\n" - : "=&y" (v1), "=&y" (v2), "=&y" (v3), - "=&y" (v4), "=&y" (v5), "=&y" (v6), "=y" (v7) - : "y" (vfill)); -#endif - - while (height--) - { - int w; - uint8_t *d = byte_line; - - byte_line += stride; - w = byte_width; - - if (w >= 1 && ((uintptr_t)d & 1)) - { - *(uint8_t *)d = (filler & 0xff); - w--; - d++; - } - - if (w >= 2 && ((uintptr_t)d & 3)) - { - *(uint16_t *)d = filler; - w -= 2; - d += 2; - } - - while (w >= 4 && ((uintptr_t)d & 7)) - { - *(uint32_t *)d = filler; - - w -= 4; - d += 4; - } - - while (w >= 64) - { -#if defined __GNUC__ && defined USE_X86_MMX - __asm__ ( - "movq %1, (%0)\n" - "movq %2, 8(%0)\n" - "movq %3, 16(%0)\n" - "movq %4, 24(%0)\n" - "movq %5, 32(%0)\n" - "movq %6, 40(%0)\n" - "movq %7, 48(%0)\n" - "movq %8, 56(%0)\n" - : - : "r" (d), - "y" (vfill), "y" (v1), "y" (v2), "y" (v3), - "y" (v4), "y" (v5), "y" (v6), "y" (v7) - : "memory"); -#else - *(__m64*) (d + 0) = vfill; - *(__m64*) (d + 8) = vfill; - *(__m64*) (d + 16) = vfill; - *(__m64*) (d + 24) = vfill; - *(__m64*) (d + 32) = vfill; - *(__m64*) (d + 40) = vfill; - *(__m64*) (d + 48) = vfill; - *(__m64*) (d + 56) = vfill; -#endif - w -= 64; - d += 64; - } - - while (w >= 4) - { - *(uint32_t *)d = filler; - - w -= 4; - d += 4; - } - if (w >= 2) - { - *(uint16_t *)d = filler; - w -= 2; - d += 2; - } - if (w >= 1) - { - *(uint8_t *)d = (filler & 0xff); - w--; - d++; - } - - } - - _mm_empty (); - return TRUE; -} - -static void -mmx_composite_src_x888_0565 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint16_t *dst_line, *dst; - uint32_t *src_line, *src, s; - int dst_stride, src_stride; - int32_t w; - - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - while (w && (uintptr_t)dst & 7) - { - s = *src++; - *dst = convert_8888_to_0565 (s); - dst++; - w--; - } - - while (w >= 4) - { - __m64 vdest; - __m64 vsrc0 = ldq_u ((__m64 *)(src + 0)); - __m64 vsrc1 = ldq_u ((__m64 *)(src + 2)); - - vdest = pack_4xpacked565 (vsrc0, vsrc1); - - *(__m64 *)dst = vdest; - - w -= 4; - src += 4; - dst += 4; - } - - while (w) - { - s = *src++; - *dst = convert_8888_to_0565 (s); - dst++; - w--; - } - } - - _mm_empty (); -} - -static void -mmx_composite_src_n_8_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src, srca; - uint32_t *dst_line, *dst; - uint8_t *mask_line, *mask; - int dst_stride, mask_stride; - int32_t w; - __m64 vsrc; - uint64_t srcsrc; - - CHECKPOINT (); - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - srca = src >> 24; - if (src == 0) - { - mmx_fill (imp, dest_image->bits.bits, dest_image->bits.rowstride, - PIXMAN_FORMAT_BPP (dest_image->bits.format), - dest_x, dest_y, width, height, 0); - return; - } - - srcsrc = (uint64_t)src << 32 | src; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); - - vsrc = load8888 (&src); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - w = width; - - CHECKPOINT (); - - while (w && (uintptr_t)dst & 7) - { - uint64_t m = *mask; - - if (m) - { - __m64 vdest = in (vsrc, expand_alpha_rev (to_m64 (m))); - - store8888 (dst, vdest); - } - else - { - *dst = 0; - } - - w--; - mask++; - dst++; - } - - CHECKPOINT (); - - while (w >= 2) - { - uint64_t m0, m1; - m0 = *mask; - m1 = *(mask + 1); - - if (srca == 0xff && (m0 & m1) == 0xff) - { - *(uint64_t *)dst = srcsrc; - } - else if (m0 | m1) - { - __m64 dest0, dest1; - - dest0 = in (vsrc, expand_alpha_rev (to_m64 (m0))); - dest1 = in (vsrc, expand_alpha_rev (to_m64 (m1))); - - *(__m64 *)dst = pack8888 (dest0, dest1); - } - else - { - *(uint64_t *)dst = 0; - } - - mask += 2; - dst += 2; - w -= 2; - } - - CHECKPOINT (); - - if (w) - { - uint64_t m = *mask; - - if (m) - { - __m64 vdest = load8888 (dst); - - vdest = in (vsrc, expand_alpha_rev (to_m64 (m))); - store8888 (dst, vdest); - } - else - { - *dst = 0; - } - } - } - - _mm_empty (); -} - -static void -mmx_composite_over_n_8_0565 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src, srca; - uint16_t *dst_line, *dst; - uint8_t *mask_line, *mask; - int dst_stride, mask_stride; - int32_t w; - __m64 vsrc, vsrca, tmp; - __m64 srcsrcsrcsrc; - - CHECKPOINT (); - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - srca = src >> 24; - if (src == 0) - return; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); - - vsrc = load8888 (&src); - vsrca = expand_alpha (vsrc); - - tmp = pack_565 (vsrc, _mm_setzero_si64 (), 0); - srcsrcsrcsrc = expand_alpha_rev (tmp); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - w = width; - - CHECKPOINT (); - - while (w && (uintptr_t)dst & 7) - { - uint64_t m = *mask; - - if (m) - { - uint64_t d = *dst; - __m64 vd = to_m64 (d); - __m64 vdest = in_over ( - vsrc, vsrca, expand_alpha_rev (to_m64 (m)), expand565 (vd, 0)); - - vd = pack_565 (vdest, _mm_setzero_si64 (), 0); - *dst = to_uint64 (vd); - } - - w--; - mask++; - dst++; - } - - CHECKPOINT (); - - while (w >= 4) - { - uint64_t m0, m1, m2, m3; - m0 = *mask; - m1 = *(mask + 1); - m2 = *(mask + 2); - m3 = *(mask + 3); - - if (srca == 0xff && (m0 & m1 & m2 & m3) == 0xff) - { - *(__m64 *)dst = srcsrcsrcsrc; - } - else if (m0 | m1 | m2 | m3) - { - __m64 vdest = *(__m64 *)dst; - __m64 v0, v1, v2, v3; - __m64 vm0, vm1, vm2, vm3; - - expand_4x565 (vdest, &v0, &v1, &v2, &v3, 0); - - vm0 = to_m64 (m0); - v0 = in_over (vsrc, vsrca, expand_alpha_rev (vm0), v0); - - vm1 = to_m64 (m1); - v1 = in_over (vsrc, vsrca, expand_alpha_rev (vm1), v1); - - vm2 = to_m64 (m2); - v2 = in_over (vsrc, vsrca, expand_alpha_rev (vm2), v2); - - vm3 = to_m64 (m3); - v3 = in_over (vsrc, vsrca, expand_alpha_rev (vm3), v3); - - *(__m64 *)dst = pack_4x565 (v0, v1, v2, v3);; - } - - w -= 4; - mask += 4; - dst += 4; - } - - CHECKPOINT (); - - while (w) - { - uint64_t m = *mask; - - if (m) - { - uint64_t d = *dst; - __m64 vd = to_m64 (d); - __m64 vdest = in_over (vsrc, vsrca, expand_alpha_rev (to_m64 (m)), - expand565 (vd, 0)); - vd = pack_565 (vdest, _mm_setzero_si64 (), 0); - *dst = to_uint64 (vd); - } - - w--; - mask++; - dst++; - } - } - - _mm_empty (); -} - -static void -mmx_composite_over_pixbuf_0565 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint16_t *dst_line, *dst; - uint32_t *src_line, *src; - int dst_stride, src_stride; - int32_t w; - - CHECKPOINT (); - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - -#if 0 - /* FIXME */ - assert (src_image->drawable == mask_image->drawable); -#endif - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - CHECKPOINT (); - - while (w && (uintptr_t)dst & 7) - { - __m64 vsrc = load8888 (src); - uint64_t d = *dst; - __m64 vdest = expand565 (to_m64 (d), 0); - - vdest = pack_565 (over_rev_non_pre (vsrc, vdest), vdest, 0); - - *dst = to_uint64 (vdest); - - w--; - dst++; - src++; - } - - CHECKPOINT (); - - while (w >= 4) - { - uint32_t s0, s1, s2, s3; - unsigned char a0, a1, a2, a3; - - s0 = *src; - s1 = *(src + 1); - s2 = *(src + 2); - s3 = *(src + 3); - - a0 = (s0 >> 24); - a1 = (s1 >> 24); - a2 = (s2 >> 24); - a3 = (s3 >> 24); - - if ((a0 & a1 & a2 & a3) == 0xFF) - { - __m64 v0 = invert_colors (load8888 (&s0)); - __m64 v1 = invert_colors (load8888 (&s1)); - __m64 v2 = invert_colors (load8888 (&s2)); - __m64 v3 = invert_colors (load8888 (&s3)); - - *(__m64 *)dst = pack_4x565 (v0, v1, v2, v3); - } - else if (s0 | s1 | s2 | s3) - { - __m64 vdest = *(__m64 *)dst; - __m64 v0, v1, v2, v3; - - __m64 vsrc0 = load8888 (&s0); - __m64 vsrc1 = load8888 (&s1); - __m64 vsrc2 = load8888 (&s2); - __m64 vsrc3 = load8888 (&s3); - - expand_4x565 (vdest, &v0, &v1, &v2, &v3, 0); - - v0 = over_rev_non_pre (vsrc0, v0); - v1 = over_rev_non_pre (vsrc1, v1); - v2 = over_rev_non_pre (vsrc2, v2); - v3 = over_rev_non_pre (vsrc3, v3); - - *(__m64 *)dst = pack_4x565 (v0, v1, v2, v3); - } - - w -= 4; - dst += 4; - src += 4; - } - - CHECKPOINT (); - - while (w) - { - __m64 vsrc = load8888 (src); - uint64_t d = *dst; - __m64 vdest = expand565 (to_m64 (d), 0); - - vdest = pack_565 (over_rev_non_pre (vsrc, vdest), vdest, 0); - - *dst = to_uint64 (vdest); - - w--; - dst++; - src++; - } - } - - _mm_empty (); -} - -static void -mmx_composite_over_pixbuf_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t *dst_line, *dst; - uint32_t *src_line, *src; - int dst_stride, src_stride; - int32_t w; - - CHECKPOINT (); - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - -#if 0 - /* FIXME */ - assert (src_image->drawable == mask_image->drawable); -#endif - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - while (w && (uintptr_t)dst & 7) - { - __m64 s = load8888 (src); - __m64 d = load8888 (dst); - - store8888 (dst, over_rev_non_pre (s, d)); - - w--; - dst++; - src++; - } - - while (w >= 2) - { - uint32_t s0, s1; - unsigned char a0, a1; - __m64 d0, d1; - - s0 = *src; - s1 = *(src + 1); - - a0 = (s0 >> 24); - a1 = (s1 >> 24); - - if ((a0 & a1) == 0xFF) - { - d0 = invert_colors (load8888 (&s0)); - d1 = invert_colors (load8888 (&s1)); - - *(__m64 *)dst = pack8888 (d0, d1); - } - else if (s0 | s1) - { - __m64 vdest = *(__m64 *)dst; - - d0 = over_rev_non_pre (load8888 (&s0), expand8888 (vdest, 0)); - d1 = over_rev_non_pre (load8888 (&s1), expand8888 (vdest, 1)); - - *(__m64 *)dst = pack8888 (d0, d1); - } - - w -= 2; - dst += 2; - src += 2; - } - - if (w) - { - __m64 s = load8888 (src); - __m64 d = load8888 (dst); - - store8888 (dst, over_rev_non_pre (s, d)); - } - } - - _mm_empty (); -} - -static void -mmx_composite_over_n_8888_0565_ca (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src; - uint16_t *dst_line; - uint32_t *mask_line; - int dst_stride, mask_stride; - __m64 vsrc, vsrca; - - CHECKPOINT (); - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - if (src == 0) - return; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint32_t, mask_stride, mask_line, 1); - - vsrc = load8888 (&src); - vsrca = expand_alpha (vsrc); - - while (height--) - { - int twidth = width; - uint32_t *p = (uint32_t *)mask_line; - uint16_t *q = (uint16_t *)dst_line; - - while (twidth && ((uintptr_t)q & 7)) - { - uint32_t m = *(uint32_t *)p; - - if (m) - { - uint64_t d = *q; - __m64 vdest = expand565 (to_m64 (d), 0); - vdest = pack_565 (in_over (vsrc, vsrca, load8888 (&m), vdest), vdest, 0); - *q = to_uint64 (vdest); - } - - twidth--; - p++; - q++; - } - - while (twidth >= 4) - { - uint32_t m0, m1, m2, m3; - - m0 = *p; - m1 = *(p + 1); - m2 = *(p + 2); - m3 = *(p + 3); - - if ((m0 | m1 | m2 | m3)) - { - __m64 vdest = *(__m64 *)q; - __m64 v0, v1, v2, v3; - - expand_4x565 (vdest, &v0, &v1, &v2, &v3, 0); - - v0 = in_over (vsrc, vsrca, load8888 (&m0), v0); - v1 = in_over (vsrc, vsrca, load8888 (&m1), v1); - v2 = in_over (vsrc, vsrca, load8888 (&m2), v2); - v3 = in_over (vsrc, vsrca, load8888 (&m3), v3); - - *(__m64 *)q = pack_4x565 (v0, v1, v2, v3); - } - twidth -= 4; - p += 4; - q += 4; - } - - while (twidth) - { - uint32_t m; - - m = *(uint32_t *)p; - if (m) - { - uint64_t d = *q; - __m64 vdest = expand565 (to_m64 (d), 0); - vdest = pack_565 (in_over (vsrc, vsrca, load8888 (&m), vdest), vdest, 0); - *q = to_uint64 (vdest); - } - - twidth--; - p++; - q++; - } - - mask_line += mask_stride; - dst_line += dst_stride; - } - - _mm_empty (); -} - -static void -mmx_composite_in_n_8_8 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint8_t *dst_line, *dst; - uint8_t *mask_line, *mask; - int dst_stride, mask_stride; - int32_t w; - uint32_t src; - uint8_t sa; - __m64 vsrc, vsrca; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - sa = src >> 24; - - vsrc = load8888 (&src); - vsrca = expand_alpha (vsrc); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - w = width; - - while (w && (uintptr_t)dst & 7) - { - uint16_t tmp; - uint8_t a; - uint32_t m, d; - - a = *mask++; - d = *dst; - - m = MUL_UN8 (sa, a, tmp); - d = MUL_UN8 (m, d, tmp); - - *dst++ = d; - w--; - } - - while (w >= 4) - { - __m64 vmask; - __m64 vdest; - - vmask = load8888u ((uint32_t *)mask); - vdest = load8888 ((uint32_t *)dst); - - store8888 ((uint32_t *)dst, in (in (vsrca, vmask), vdest)); - - dst += 4; - mask += 4; - w -= 4; - } - - while (w--) - { - uint16_t tmp; - uint8_t a; - uint32_t m, d; - - a = *mask++; - d = *dst; - - m = MUL_UN8 (sa, a, tmp); - d = MUL_UN8 (m, d, tmp); - - *dst++ = d; - } - } - - _mm_empty (); -} - -static void -mmx_composite_in_8_8 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint8_t *dst_line, *dst; - uint8_t *src_line, *src; - int src_stride, dst_stride; - int32_t w; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint8_t, src_stride, src_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - while (w && (uintptr_t)dst & 3) - { - uint8_t s, d; - uint16_t tmp; - - s = *src; - d = *dst; - - *dst = MUL_UN8 (s, d, tmp); - - src++; - dst++; - w--; - } - - while (w >= 4) - { - uint32_t *s = (uint32_t *)src; - uint32_t *d = (uint32_t *)dst; - - store8888 (d, in (load8888u (s), load8888 (d))); - - w -= 4; - dst += 4; - src += 4; - } - - while (w--) - { - uint8_t s, d; - uint16_t tmp; - - s = *src; - d = *dst; - - *dst = MUL_UN8 (s, d, tmp); - - src++; - dst++; - } - } - - _mm_empty (); -} - -static void -mmx_composite_add_n_8_8 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint8_t *dst_line, *dst; - uint8_t *mask_line, *mask; - int dst_stride, mask_stride; - int32_t w; - uint32_t src; - uint8_t sa; - __m64 vsrc, vsrca; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - sa = src >> 24; - - if (src == 0) - return; - - vsrc = load8888 (&src); - vsrca = expand_alpha (vsrc); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - w = width; - - while (w && (uintptr_t)dst & 3) - { - uint16_t tmp; - uint16_t a; - uint32_t m, d; - uint32_t r; - - a = *mask++; - d = *dst; - - m = MUL_UN8 (sa, a, tmp); - r = ADD_UN8 (m, d, tmp); - - *dst++ = r; - w--; - } - - while (w >= 4) - { - __m64 vmask; - __m64 vdest; - - vmask = load8888u ((uint32_t *)mask); - vdest = load8888 ((uint32_t *)dst); - - store8888 ((uint32_t *)dst, _mm_adds_pu8 (in (vsrca, vmask), vdest)); - - dst += 4; - mask += 4; - w -= 4; - } - - while (w--) - { - uint16_t tmp; - uint16_t a; - uint32_t m, d; - uint32_t r; - - a = *mask++; - d = *dst; - - m = MUL_UN8 (sa, a, tmp); - r = ADD_UN8 (m, d, tmp); - - *dst++ = r; - } - } - - _mm_empty (); -} - -static void -mmx_composite_add_8_8 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint8_t *dst_line, *dst; - uint8_t *src_line, *src; - int dst_stride, src_stride; - int32_t w; - uint8_t s, d; - uint16_t t; - - CHECKPOINT (); - - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint8_t, src_stride, src_line, 1); - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - while (w && (uintptr_t)dst & 7) - { - s = *src; - d = *dst; - t = d + s; - s = t | (0 - (t >> 8)); - *dst = s; - - dst++; - src++; - w--; - } - - while (w >= 8) - { - *(__m64*)dst = _mm_adds_pu8 (ldq_u ((__m64 *)src), *(__m64*)dst); - dst += 8; - src += 8; - w -= 8; - } - - while (w) - { - s = *src; - d = *dst; - t = d + s; - s = t | (0 - (t >> 8)); - *dst = s; - - dst++; - src++; - w--; - } - } - - _mm_empty (); -} - -static void -mmx_composite_add_0565_0565 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint16_t *dst_line, *dst; - uint32_t d; - uint16_t *src_line, *src; - uint32_t s; - int dst_stride, src_stride; - int32_t w; - - CHECKPOINT (); - - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint16_t, src_stride, src_line, 1); - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - while (w && (uintptr_t)dst & 7) - { - s = *src++; - if (s) - { - d = *dst; - s = convert_0565_to_8888 (s); - if (d) - { - d = convert_0565_to_8888 (d); - UN8x4_ADD_UN8x4 (s, d); - } - *dst = convert_8888_to_0565 (s); - } - dst++; - w--; - } - - while (w >= 4) - { - __m64 vdest = *(__m64 *)dst; - __m64 vsrc = ldq_u ((__m64 *)src); - __m64 vd0, vd1; - __m64 vs0, vs1; - - expand_4xpacked565 (vdest, &vd0, &vd1, 0); - expand_4xpacked565 (vsrc, &vs0, &vs1, 0); - - vd0 = _mm_adds_pu8 (vd0, vs0); - vd1 = _mm_adds_pu8 (vd1, vs1); - - *(__m64 *)dst = pack_4xpacked565 (vd0, vd1); - - dst += 4; - src += 4; - w -= 4; - } - - while (w--) - { - s = *src++; - if (s) - { - d = *dst; - s = convert_0565_to_8888 (s); - if (d) - { - d = convert_0565_to_8888 (d); - UN8x4_ADD_UN8x4 (s, d); - } - *dst = convert_8888_to_0565 (s); - } - dst++; - } - } - - _mm_empty (); -} - -static void -mmx_composite_add_8888_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t *dst_line, *dst; - uint32_t *src_line, *src; - int dst_stride, src_stride; - int32_t w; - - CHECKPOINT (); - - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - while (w && (uintptr_t)dst & 7) - { - store (dst, _mm_adds_pu8 (load ((const uint32_t *)src), - load ((const uint32_t *)dst))); - dst++; - src++; - w--; - } - - while (w >= 2) - { - *(__m64 *)dst = _mm_adds_pu8 (ldq_u ((__m64 *)src), *(__m64*)dst); - dst += 2; - src += 2; - w -= 2; - } - - if (w) - { - store (dst, _mm_adds_pu8 (load ((const uint32_t *)src), - load ((const uint32_t *)dst))); - - } - } - - _mm_empty (); -} - -static pixman_bool_t -mmx_blt (pixman_implementation_t *imp, - uint32_t * src_bits, - uint32_t * dst_bits, - int src_stride, - int dst_stride, - int src_bpp, - int dst_bpp, - int src_x, - int src_y, - int dest_x, - int dest_y, - int width, - int height) -{ - uint8_t * src_bytes; - uint8_t * dst_bytes; - int byte_width; - - if (src_bpp != dst_bpp) - return FALSE; - - if (src_bpp == 16) - { - src_stride = src_stride * (int) sizeof (uint32_t) / 2; - dst_stride = dst_stride * (int) sizeof (uint32_t) / 2; - src_bytes = (uint8_t *)(((uint16_t *)src_bits) + src_stride * (src_y) + (src_x)); - dst_bytes = (uint8_t *)(((uint16_t *)dst_bits) + dst_stride * (dest_y) + (dest_x)); - byte_width = 2 * width; - src_stride *= 2; - dst_stride *= 2; - } - else if (src_bpp == 32) - { - src_stride = src_stride * (int) sizeof (uint32_t) / 4; - dst_stride = dst_stride * (int) sizeof (uint32_t) / 4; - src_bytes = (uint8_t *)(((uint32_t *)src_bits) + src_stride * (src_y) + (src_x)); - dst_bytes = (uint8_t *)(((uint32_t *)dst_bits) + dst_stride * (dest_y) + (dest_x)); - byte_width = 4 * width; - src_stride *= 4; - dst_stride *= 4; - } - else - { - return FALSE; - } - - while (height--) - { - int w; - uint8_t *s = src_bytes; - uint8_t *d = dst_bytes; - src_bytes += src_stride; - dst_bytes += dst_stride; - w = byte_width; - - if (w >= 1 && ((uintptr_t)d & 1)) - { - *(uint8_t *)d = *(uint8_t *)s; - w -= 1; - s += 1; - d += 1; - } - - if (w >= 2 && ((uintptr_t)d & 3)) - { - *(uint16_t *)d = *(uint16_t *)s; - w -= 2; - s += 2; - d += 2; - } - - while (w >= 4 && ((uintptr_t)d & 7)) - { - *(uint32_t *)d = ldl_u ((uint32_t *)s); - - w -= 4; - s += 4; - d += 4; - } - - while (w >= 64) - { -#if (defined (__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))) && defined USE_X86_MMX - __asm__ ( - "movq (%1), %%mm0\n" - "movq 8(%1), %%mm1\n" - "movq 16(%1), %%mm2\n" - "movq 24(%1), %%mm3\n" - "movq 32(%1), %%mm4\n" - "movq 40(%1), %%mm5\n" - "movq 48(%1), %%mm6\n" - "movq 56(%1), %%mm7\n" - - "movq %%mm0, (%0)\n" - "movq %%mm1, 8(%0)\n" - "movq %%mm2, 16(%0)\n" - "movq %%mm3, 24(%0)\n" - "movq %%mm4, 32(%0)\n" - "movq %%mm5, 40(%0)\n" - "movq %%mm6, 48(%0)\n" - "movq %%mm7, 56(%0)\n" - : - : "r" (d), "r" (s) - : "memory", - "%mm0", "%mm1", "%mm2", "%mm3", - "%mm4", "%mm5", "%mm6", "%mm7"); -#else - __m64 v0 = ldq_u ((__m64 *)(s + 0)); - __m64 v1 = ldq_u ((__m64 *)(s + 8)); - __m64 v2 = ldq_u ((__m64 *)(s + 16)); - __m64 v3 = ldq_u ((__m64 *)(s + 24)); - __m64 v4 = ldq_u ((__m64 *)(s + 32)); - __m64 v5 = ldq_u ((__m64 *)(s + 40)); - __m64 v6 = ldq_u ((__m64 *)(s + 48)); - __m64 v7 = ldq_u ((__m64 *)(s + 56)); - *(__m64 *)(d + 0) = v0; - *(__m64 *)(d + 8) = v1; - *(__m64 *)(d + 16) = v2; - *(__m64 *)(d + 24) = v3; - *(__m64 *)(d + 32) = v4; - *(__m64 *)(d + 40) = v5; - *(__m64 *)(d + 48) = v6; - *(__m64 *)(d + 56) = v7; -#endif - - w -= 64; - s += 64; - d += 64; - } - while (w >= 4) - { - *(uint32_t *)d = ldl_u ((uint32_t *)s); - - w -= 4; - s += 4; - d += 4; - } - if (w >= 2) - { - *(uint16_t *)d = *(uint16_t *)s; - w -= 2; - s += 2; - d += 2; - } - } - - _mm_empty (); - - return TRUE; -} - -static void -mmx_composite_copy_area (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - - mmx_blt (imp, src_image->bits.bits, - dest_image->bits.bits, - src_image->bits.rowstride, - dest_image->bits.rowstride, - PIXMAN_FORMAT_BPP (src_image->bits.format), - PIXMAN_FORMAT_BPP (dest_image->bits.format), - src_x, src_y, dest_x, dest_y, width, height); -} - -static void -mmx_composite_over_x888_8_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t *src, *src_line; - uint32_t *dst, *dst_line; - uint8_t *mask, *mask_line; - int src_stride, mask_stride, dst_stride; - int32_t w; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - - while (height--) - { - src = src_line; - src_line += src_stride; - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - - w = width; - - while (w--) - { - uint64_t m = *mask; - - if (m) - { - uint32_t ssrc = *src | 0xff000000; - __m64 s = load8888 (&ssrc); - - if (m == 0xff) - { - store8888 (dst, s); - } - else - { - __m64 sa = expand_alpha (s); - __m64 vm = expand_alpha_rev (to_m64 (m)); - __m64 vdest = in_over (s, sa, vm, load8888 (dst)); - - store8888 (dst, vdest); - } - } - - mask++; - dst++; - src++; - } - } - - _mm_empty (); -} - -static void -mmx_composite_over_reverse_n_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src; - uint32_t *dst_line, *dst; - int32_t w; - int dst_stride; - __m64 vsrc; - - CHECKPOINT (); - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - if (src == 0) - return; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - - vsrc = load8888 (&src); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - w = width; - - CHECKPOINT (); - - while (w && (uintptr_t)dst & 7) - { - __m64 vdest = load8888 (dst); - - store8888 (dst, over (vdest, expand_alpha (vdest), vsrc)); - - w--; - dst++; - } - - while (w >= 2) - { - __m64 vdest = *(__m64 *)dst; - __m64 dest0 = expand8888 (vdest, 0); - __m64 dest1 = expand8888 (vdest, 1); - - - dest0 = over (dest0, expand_alpha (dest0), vsrc); - dest1 = over (dest1, expand_alpha (dest1), vsrc); - - *(__m64 *)dst = pack8888 (dest0, dest1); - - dst += 2; - w -= 2; - } - - CHECKPOINT (); - - if (w) - { - __m64 vdest = load8888 (dst); - - store8888 (dst, over (vdest, expand_alpha (vdest), vsrc)); - } - } - - _mm_empty (); -} - -static force_inline void -scaled_nearest_scanline_mmx_8888_8888_OVER (uint32_t* pd, - const uint32_t* ps, - int32_t w, - pixman_fixed_t vx, - pixman_fixed_t unit_x, - pixman_fixed_t src_width_fixed, - pixman_bool_t fully_transparent_src) -{ - if (fully_transparent_src) - return; - - while (w) - { - __m64 d = load (pd); - __m64 s = load (ps + pixman_fixed_to_int (vx)); - vx += unit_x; - while (vx >= 0) - vx -= src_width_fixed; - - store8888 (pd, core_combine_over_u_pixel_mmx (s, d)); - pd++; - - w--; - } - - _mm_empty (); -} - -FAST_NEAREST_MAINLOOP (mmx_8888_8888_cover_OVER, - scaled_nearest_scanline_mmx_8888_8888_OVER, - uint32_t, uint32_t, COVER) -FAST_NEAREST_MAINLOOP (mmx_8888_8888_none_OVER, - scaled_nearest_scanline_mmx_8888_8888_OVER, - uint32_t, uint32_t, NONE) -FAST_NEAREST_MAINLOOP (mmx_8888_8888_pad_OVER, - scaled_nearest_scanline_mmx_8888_8888_OVER, - uint32_t, uint32_t, PAD) -FAST_NEAREST_MAINLOOP (mmx_8888_8888_normal_OVER, - scaled_nearest_scanline_mmx_8888_8888_OVER, - uint32_t, uint32_t, NORMAL) - -static force_inline void -scaled_nearest_scanline_mmx_8888_n_8888_OVER (const uint32_t * mask, - uint32_t * dst, - const uint32_t * src, - int32_t w, - pixman_fixed_t vx, - pixman_fixed_t unit_x, - pixman_fixed_t src_width_fixed, - pixman_bool_t zero_src) -{ - __m64 mm_mask; - - if (zero_src || (*mask >> 24) == 0) - { - /* A workaround for https://gcc.gnu.org/PR47759 */ - _mm_empty (); - return; - } - - mm_mask = expand_alpha (load8888 (mask)); - - while (w) - { - uint32_t s = *(src + pixman_fixed_to_int (vx)); - vx += unit_x; - while (vx >= 0) - vx -= src_width_fixed; - - if (s) - { - __m64 ms = load8888 (&s); - __m64 alpha = expand_alpha (ms); - __m64 dest = load8888 (dst); - - store8888 (dst, (in_over (ms, alpha, mm_mask, dest))); - } - - dst++; - w--; - } - - _mm_empty (); -} - -FAST_NEAREST_MAINLOOP_COMMON (mmx_8888_n_8888_cover_OVER, - scaled_nearest_scanline_mmx_8888_n_8888_OVER, - uint32_t, uint32_t, uint32_t, COVER, TRUE, TRUE) -FAST_NEAREST_MAINLOOP_COMMON (mmx_8888_n_8888_pad_OVER, - scaled_nearest_scanline_mmx_8888_n_8888_OVER, - uint32_t, uint32_t, uint32_t, PAD, TRUE, TRUE) -FAST_NEAREST_MAINLOOP_COMMON (mmx_8888_n_8888_none_OVER, - scaled_nearest_scanline_mmx_8888_n_8888_OVER, - uint32_t, uint32_t, uint32_t, NONE, TRUE, TRUE) -FAST_NEAREST_MAINLOOP_COMMON (mmx_8888_n_8888_normal_OVER, - scaled_nearest_scanline_mmx_8888_n_8888_OVER, - uint32_t, uint32_t, uint32_t, NORMAL, TRUE, TRUE) - -#define BSHIFT ((1 << BILINEAR_INTERPOLATION_BITS)) -#define BMSK (BSHIFT - 1) - -#define BILINEAR_DECLARE_VARIABLES \ - const __m64 mm_wt = _mm_set_pi16 (wt, wt, wt, wt); \ - const __m64 mm_wb = _mm_set_pi16 (wb, wb, wb, wb); \ - const __m64 mm_addc7 = _mm_set_pi16 (0, 1, 0, 1); \ - const __m64 mm_xorc7 = _mm_set_pi16 (0, BMSK, 0, BMSK); \ - const __m64 mm_ux = _mm_set_pi16 (unit_x, unit_x, unit_x, unit_x); \ - const __m64 mm_zero = _mm_setzero_si64 (); \ - __m64 mm_x = _mm_set_pi16 (vx, vx, vx, vx) - -#define BILINEAR_INTERPOLATE_ONE_PIXEL(pix) \ -do { \ - /* fetch 2x2 pixel block into 2 mmx registers */ \ - __m64 t = ldq_u ((__m64 *)&src_top [pixman_fixed_to_int (vx)]); \ - __m64 b = ldq_u ((__m64 *)&src_bottom [pixman_fixed_to_int (vx)]); \ - /* vertical interpolation */ \ - __m64 t_hi = _mm_mullo_pi16 (_mm_unpackhi_pi8 (t, mm_zero), mm_wt); \ - __m64 t_lo = _mm_mullo_pi16 (_mm_unpacklo_pi8 (t, mm_zero), mm_wt); \ - __m64 b_hi = _mm_mullo_pi16 (_mm_unpackhi_pi8 (b, mm_zero), mm_wb); \ - __m64 b_lo = _mm_mullo_pi16 (_mm_unpacklo_pi8 (b, mm_zero), mm_wb); \ - __m64 hi = _mm_add_pi16 (t_hi, b_hi); \ - __m64 lo = _mm_add_pi16 (t_lo, b_lo); \ - /* calculate horizontal weights */ \ - __m64 mm_wh = _mm_add_pi16 (mm_addc7, _mm_xor_si64 (mm_xorc7, \ - _mm_srli_pi16 (mm_x, \ - 16 - BILINEAR_INTERPOLATION_BITS))); \ - /* horizontal interpolation */ \ - __m64 p = _mm_unpacklo_pi16 (lo, hi); \ - __m64 q = _mm_unpackhi_pi16 (lo, hi); \ - vx += unit_x; \ - lo = _mm_madd_pi16 (p, mm_wh); \ - hi = _mm_madd_pi16 (q, mm_wh); \ - mm_x = _mm_add_pi16 (mm_x, mm_ux); \ - /* shift and pack the result */ \ - hi = _mm_srli_pi32 (hi, BILINEAR_INTERPOLATION_BITS * 2); \ - lo = _mm_srli_pi32 (lo, BILINEAR_INTERPOLATION_BITS * 2); \ - lo = _mm_packs_pi32 (lo, hi); \ - lo = _mm_packs_pu16 (lo, lo); \ - pix = lo; \ -} while (0) - -#define BILINEAR_SKIP_ONE_PIXEL() \ -do { \ - vx += unit_x; \ - mm_x = _mm_add_pi16 (mm_x, mm_ux); \ -} while(0) - -static force_inline void -scaled_bilinear_scanline_mmx_8888_8888_SRC (uint32_t * dst, - const uint32_t * mask, - const uint32_t * src_top, - const uint32_t * src_bottom, - int32_t w, - int wt, - int wb, - pixman_fixed_t vx, - pixman_fixed_t unit_x, - pixman_fixed_t max_vx, - pixman_bool_t zero_src) -{ - BILINEAR_DECLARE_VARIABLES; - __m64 pix; - - while (w--) - { - BILINEAR_INTERPOLATE_ONE_PIXEL (pix); - store (dst, pix); - dst++; - } - - _mm_empty (); -} - -FAST_BILINEAR_MAINLOOP_COMMON (mmx_8888_8888_cover_SRC, - scaled_bilinear_scanline_mmx_8888_8888_SRC, - uint32_t, uint32_t, uint32_t, - COVER, FLAG_NONE) -FAST_BILINEAR_MAINLOOP_COMMON (mmx_8888_8888_pad_SRC, - scaled_bilinear_scanline_mmx_8888_8888_SRC, - uint32_t, uint32_t, uint32_t, - PAD, FLAG_NONE) -FAST_BILINEAR_MAINLOOP_COMMON (mmx_8888_8888_none_SRC, - scaled_bilinear_scanline_mmx_8888_8888_SRC, - uint32_t, uint32_t, uint32_t, - NONE, FLAG_NONE) -FAST_BILINEAR_MAINLOOP_COMMON (mmx_8888_8888_normal_SRC, - scaled_bilinear_scanline_mmx_8888_8888_SRC, - uint32_t, uint32_t, uint32_t, - NORMAL, FLAG_NONE) - -static force_inline void -scaled_bilinear_scanline_mmx_8888_8888_OVER (uint32_t * dst, - const uint32_t * mask, - const uint32_t * src_top, - const uint32_t * src_bottom, - int32_t w, - int wt, - int wb, - pixman_fixed_t vx, - pixman_fixed_t unit_x, - pixman_fixed_t max_vx, - pixman_bool_t zero_src) -{ - BILINEAR_DECLARE_VARIABLES; - __m64 pix1, pix2; - - while (w) - { - BILINEAR_INTERPOLATE_ONE_PIXEL (pix1); - - if (!is_zero (pix1)) - { - pix2 = load (dst); - store8888 (dst, core_combine_over_u_pixel_mmx (pix1, pix2)); - } - - w--; - dst++; - } - - _mm_empty (); -} - -FAST_BILINEAR_MAINLOOP_COMMON (mmx_8888_8888_cover_OVER, - scaled_bilinear_scanline_mmx_8888_8888_OVER, - uint32_t, uint32_t, uint32_t, - COVER, FLAG_NONE) -FAST_BILINEAR_MAINLOOP_COMMON (mmx_8888_8888_pad_OVER, - scaled_bilinear_scanline_mmx_8888_8888_OVER, - uint32_t, uint32_t, uint32_t, - PAD, FLAG_NONE) -FAST_BILINEAR_MAINLOOP_COMMON (mmx_8888_8888_none_OVER, - scaled_bilinear_scanline_mmx_8888_8888_OVER, - uint32_t, uint32_t, uint32_t, - NONE, FLAG_NONE) -FAST_BILINEAR_MAINLOOP_COMMON (mmx_8888_8888_normal_OVER, - scaled_bilinear_scanline_mmx_8888_8888_OVER, - uint32_t, uint32_t, uint32_t, - NORMAL, FLAG_NONE) - -static force_inline void -scaled_bilinear_scanline_mmx_8888_8_8888_OVER (uint32_t * dst, - const uint8_t * mask, - const uint32_t * src_top, - const uint32_t * src_bottom, - int32_t w, - int wt, - int wb, - pixman_fixed_t vx, - pixman_fixed_t unit_x, - pixman_fixed_t max_vx, - pixman_bool_t zero_src) -{ - BILINEAR_DECLARE_VARIABLES; - __m64 pix1, pix2; - uint32_t m; - - while (w) - { - m = (uint32_t) *mask++; - - if (m) - { - BILINEAR_INTERPOLATE_ONE_PIXEL (pix1); - - if (m == 0xff && is_opaque (pix1)) - { - store (dst, pix1); - } - else - { - __m64 ms, md, ma, msa; - - pix2 = load (dst); - ma = expand_alpha_rev (to_m64 (m)); - ms = _mm_unpacklo_pi8 (pix1, _mm_setzero_si64 ()); - md = _mm_unpacklo_pi8 (pix2, _mm_setzero_si64 ()); - - msa = expand_alpha (ms); - - store8888 (dst, (in_over (ms, msa, ma, md))); - } - } - else - { - BILINEAR_SKIP_ONE_PIXEL (); - } - - w--; - dst++; - } - - _mm_empty (); -} - -FAST_BILINEAR_MAINLOOP_COMMON (mmx_8888_8_8888_cover_OVER, - scaled_bilinear_scanline_mmx_8888_8_8888_OVER, - uint32_t, uint8_t, uint32_t, - COVER, FLAG_HAVE_NON_SOLID_MASK) -FAST_BILINEAR_MAINLOOP_COMMON (mmx_8888_8_8888_pad_OVER, - scaled_bilinear_scanline_mmx_8888_8_8888_OVER, - uint32_t, uint8_t, uint32_t, - PAD, FLAG_HAVE_NON_SOLID_MASK) -FAST_BILINEAR_MAINLOOP_COMMON (mmx_8888_8_8888_none_OVER, - scaled_bilinear_scanline_mmx_8888_8_8888_OVER, - uint32_t, uint8_t, uint32_t, - NONE, FLAG_HAVE_NON_SOLID_MASK) -FAST_BILINEAR_MAINLOOP_COMMON (mmx_8888_8_8888_normal_OVER, - scaled_bilinear_scanline_mmx_8888_8_8888_OVER, - uint32_t, uint8_t, uint32_t, - NORMAL, FLAG_HAVE_NON_SOLID_MASK) - -static uint32_t * -mmx_fetch_x8r8g8b8 (pixman_iter_t *iter, const uint32_t *mask) -{ - int w = iter->width; - uint32_t *dst = iter->buffer; - uint32_t *src = (uint32_t *)iter->bits; - - iter->bits += iter->stride; - - while (w && ((uintptr_t)dst) & 7) - { - *dst++ = (*src++) | 0xff000000; - w--; - } - - while (w >= 8) - { - __m64 vsrc1 = ldq_u ((__m64 *)(src + 0)); - __m64 vsrc2 = ldq_u ((__m64 *)(src + 2)); - __m64 vsrc3 = ldq_u ((__m64 *)(src + 4)); - __m64 vsrc4 = ldq_u ((__m64 *)(src + 6)); - - *(__m64 *)(dst + 0) = _mm_or_si64 (vsrc1, MC (ff000000)); - *(__m64 *)(dst + 2) = _mm_or_si64 (vsrc2, MC (ff000000)); - *(__m64 *)(dst + 4) = _mm_or_si64 (vsrc3, MC (ff000000)); - *(__m64 *)(dst + 6) = _mm_or_si64 (vsrc4, MC (ff000000)); - - dst += 8; - src += 8; - w -= 8; - } - - while (w) - { - *dst++ = (*src++) | 0xff000000; - w--; - } - - _mm_empty (); - return iter->buffer; -} - -static uint32_t * -mmx_fetch_r5g6b5 (pixman_iter_t *iter, const uint32_t *mask) -{ - int w = iter->width; - uint32_t *dst = iter->buffer; - uint16_t *src = (uint16_t *)iter->bits; - - iter->bits += iter->stride; - - while (w && ((uintptr_t)dst) & 0x0f) - { - uint16_t s = *src++; - - *dst++ = convert_0565_to_8888 (s); - w--; - } - - while (w >= 4) - { - __m64 vsrc = ldq_u ((__m64 *)src); - __m64 mm0, mm1; - - expand_4xpacked565 (vsrc, &mm0, &mm1, 1); - - *(__m64 *)(dst + 0) = mm0; - *(__m64 *)(dst + 2) = mm1; - - dst += 4; - src += 4; - w -= 4; - } - - while (w) - { - uint16_t s = *src++; - - *dst++ = convert_0565_to_8888 (s); - w--; - } - - _mm_empty (); - return iter->buffer; -} - -static uint32_t * -mmx_fetch_a8 (pixman_iter_t *iter, const uint32_t *mask) -{ - int w = iter->width; - uint32_t *dst = iter->buffer; - uint8_t *src = iter->bits; - - iter->bits += iter->stride; - - while (w && (((uintptr_t)dst) & 15)) - { - *dst++ = *(src++) << 24; - w--; - } - - while (w >= 8) - { - __m64 mm0 = ldq_u ((__m64 *)src); - - __m64 mm1 = _mm_unpacklo_pi8 (_mm_setzero_si64(), mm0); - __m64 mm2 = _mm_unpackhi_pi8 (_mm_setzero_si64(), mm0); - __m64 mm3 = _mm_unpacklo_pi16 (_mm_setzero_si64(), mm1); - __m64 mm4 = _mm_unpackhi_pi16 (_mm_setzero_si64(), mm1); - __m64 mm5 = _mm_unpacklo_pi16 (_mm_setzero_si64(), mm2); - __m64 mm6 = _mm_unpackhi_pi16 (_mm_setzero_si64(), mm2); - - *(__m64 *)(dst + 0) = mm3; - *(__m64 *)(dst + 2) = mm4; - *(__m64 *)(dst + 4) = mm5; - *(__m64 *)(dst + 6) = mm6; - - dst += 8; - src += 8; - w -= 8; - } - - while (w) - { - *dst++ = *(src++) << 24; - w--; - } - - _mm_empty (); - return iter->buffer; -} - -#define IMAGE_FLAGS \ - (FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM | \ - FAST_PATH_BITS_IMAGE | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST) - -static const pixman_iter_info_t mmx_iters[] = -{ - { PIXMAN_x8r8g8b8, IMAGE_FLAGS, ITER_NARROW, - _pixman_iter_init_bits_stride, mmx_fetch_x8r8g8b8, NULL - }, - { PIXMAN_r5g6b5, IMAGE_FLAGS, ITER_NARROW, - _pixman_iter_init_bits_stride, mmx_fetch_r5g6b5, NULL - }, - { PIXMAN_a8, IMAGE_FLAGS, ITER_NARROW, - _pixman_iter_init_bits_stride, mmx_fetch_a8, NULL - }, - { PIXMAN_null }, -}; - -static const pixman_fast_path_t mmx_fast_paths[] = -{ - PIXMAN_STD_FAST_PATH (OVER, solid, a8, r5g6b5, mmx_composite_over_n_8_0565 ), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, b5g6r5, mmx_composite_over_n_8_0565 ), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, mmx_composite_over_n_8_8888 ), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, mmx_composite_over_n_8_8888 ), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, mmx_composite_over_n_8_8888 ), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, mmx_composite_over_n_8_8888 ), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, a8r8g8b8, mmx_composite_over_n_8888_8888_ca ), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, mmx_composite_over_n_8888_8888_ca ), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, r5g6b5, mmx_composite_over_n_8888_0565_ca ), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, mmx_composite_over_n_8888_8888_ca ), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, mmx_composite_over_n_8888_8888_ca ), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, b5g6r5, mmx_composite_over_n_8888_0565_ca ), - PIXMAN_STD_FAST_PATH (OVER, pixbuf, pixbuf, a8r8g8b8, mmx_composite_over_pixbuf_8888 ), - PIXMAN_STD_FAST_PATH (OVER, pixbuf, pixbuf, x8r8g8b8, mmx_composite_over_pixbuf_8888 ), - PIXMAN_STD_FAST_PATH (OVER, pixbuf, pixbuf, r5g6b5, mmx_composite_over_pixbuf_0565 ), - PIXMAN_STD_FAST_PATH (OVER, rpixbuf, rpixbuf, a8b8g8r8, mmx_composite_over_pixbuf_8888 ), - PIXMAN_STD_FAST_PATH (OVER, rpixbuf, rpixbuf, x8b8g8r8, mmx_composite_over_pixbuf_8888 ), - PIXMAN_STD_FAST_PATH (OVER, rpixbuf, rpixbuf, b5g6r5, mmx_composite_over_pixbuf_0565 ), - PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, solid, a8r8g8b8, mmx_composite_over_x888_n_8888 ), - PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, solid, x8r8g8b8, mmx_composite_over_x888_n_8888 ), - PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, solid, a8b8g8r8, mmx_composite_over_x888_n_8888 ), - PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, solid, x8b8g8r8, mmx_composite_over_x888_n_8888 ), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, a8r8g8b8, mmx_composite_over_8888_n_8888 ), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, x8r8g8b8, mmx_composite_over_8888_n_8888 ), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, a8b8g8r8, mmx_composite_over_8888_n_8888 ), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, x8b8g8r8, mmx_composite_over_8888_n_8888 ), - PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, a8, x8r8g8b8, mmx_composite_over_x888_8_8888 ), - PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, a8, a8r8g8b8, mmx_composite_over_x888_8_8888 ), - PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, a8, x8b8g8r8, mmx_composite_over_x888_8_8888 ), - PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, a8, a8b8g8r8, mmx_composite_over_x888_8_8888 ), - PIXMAN_STD_FAST_PATH (OVER, solid, null, a8r8g8b8, mmx_composite_over_n_8888 ), - PIXMAN_STD_FAST_PATH (OVER, solid, null, x8r8g8b8, mmx_composite_over_n_8888 ), - PIXMAN_STD_FAST_PATH (OVER, solid, null, r5g6b5, mmx_composite_over_n_0565 ), - PIXMAN_STD_FAST_PATH (OVER, solid, null, b5g6r5, mmx_composite_over_n_0565 ), - PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, null, x8r8g8b8, mmx_composite_copy_area ), - PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, null, x8b8g8r8, mmx_composite_copy_area ), - - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, mmx_composite_over_8888_8888 ), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, mmx_composite_over_8888_8888 ), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, r5g6b5, mmx_composite_over_8888_0565 ), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, mmx_composite_over_8888_8888 ), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, mmx_composite_over_8888_8888 ), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, b5g6r5, mmx_composite_over_8888_0565 ), - - PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8r8g8b8, mmx_composite_over_reverse_n_8888), - PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8b8g8r8, mmx_composite_over_reverse_n_8888), - - PIXMAN_STD_FAST_PATH (ADD, r5g6b5, null, r5g6b5, mmx_composite_add_0565_0565 ), - PIXMAN_STD_FAST_PATH (ADD, b5g6r5, null, b5g6r5, mmx_composite_add_0565_0565 ), - PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, null, a8r8g8b8, mmx_composite_add_8888_8888 ), - PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, null, a8b8g8r8, mmx_composite_add_8888_8888 ), - PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, mmx_composite_add_8_8 ), - PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8, mmx_composite_add_n_8_8 ), - - PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, r5g6b5, mmx_composite_src_x888_0565 ), - PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, b5g6r5, mmx_composite_src_x888_0565 ), - PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, r5g6b5, mmx_composite_src_x888_0565 ), - PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, b5g6r5, mmx_composite_src_x888_0565 ), - PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8r8g8b8, mmx_composite_src_n_8_8888 ), - PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8r8g8b8, mmx_composite_src_n_8_8888 ), - PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8b8g8r8, mmx_composite_src_n_8_8888 ), - PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8b8g8r8, mmx_composite_src_n_8_8888 ), - PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, a8r8g8b8, mmx_composite_copy_area ), - PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, a8b8g8r8, mmx_composite_copy_area ), - PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, mmx_composite_copy_area ), - PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, mmx_composite_copy_area ), - PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, mmx_composite_copy_area ), - PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, mmx_composite_copy_area ), - PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, r5g6b5, mmx_composite_copy_area ), - PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, b5g6r5, mmx_composite_copy_area ), - - PIXMAN_STD_FAST_PATH (IN, a8, null, a8, mmx_composite_in_8_8 ), - PIXMAN_STD_FAST_PATH (IN, solid, a8, a8, mmx_composite_in_n_8_8 ), - - SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, mmx_8888_8888 ), - SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, mmx_8888_8888 ), - SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, mmx_8888_8888 ), - SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, mmx_8888_8888 ), - - SIMPLE_NEAREST_SOLID_MASK_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, mmx_8888_n_8888 ), - SIMPLE_NEAREST_SOLID_MASK_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, mmx_8888_n_8888 ), - SIMPLE_NEAREST_SOLID_MASK_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, mmx_8888_n_8888 ), - SIMPLE_NEAREST_SOLID_MASK_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, mmx_8888_n_8888 ), - - SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, mmx_8888_8888 ), - SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, mmx_8888_8888 ), - SIMPLE_BILINEAR_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, mmx_8888_8888 ), - SIMPLE_BILINEAR_FAST_PATH (SRC, a8b8g8r8, a8b8g8r8, mmx_8888_8888 ), - SIMPLE_BILINEAR_FAST_PATH (SRC, a8b8g8r8, x8b8g8r8, mmx_8888_8888 ), - SIMPLE_BILINEAR_FAST_PATH (SRC, x8b8g8r8, x8b8g8r8, mmx_8888_8888 ), - - SIMPLE_BILINEAR_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, mmx_8888_8888 ), - SIMPLE_BILINEAR_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, mmx_8888_8888 ), - SIMPLE_BILINEAR_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, mmx_8888_8888 ), - SIMPLE_BILINEAR_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, mmx_8888_8888 ), - - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, mmx_8888_8_8888 ), - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, mmx_8888_8_8888 ), - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, mmx_8888_8_8888 ), - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, mmx_8888_8_8888 ), - - { PIXMAN_OP_NONE }, -}; - -pixman_implementation_t * -_pixman_implementation_create_mmx (pixman_implementation_t *fallback) -{ - pixman_implementation_t *imp = _pixman_implementation_create (fallback, mmx_fast_paths); - - imp->combine_32[PIXMAN_OP_OVER] = mmx_combine_over_u; - imp->combine_32[PIXMAN_OP_OVER_REVERSE] = mmx_combine_over_reverse_u; - imp->combine_32[PIXMAN_OP_IN] = mmx_combine_in_u; - imp->combine_32[PIXMAN_OP_IN_REVERSE] = mmx_combine_in_reverse_u; - imp->combine_32[PIXMAN_OP_OUT] = mmx_combine_out_u; - imp->combine_32[PIXMAN_OP_OUT_REVERSE] = mmx_combine_out_reverse_u; - imp->combine_32[PIXMAN_OP_ATOP] = mmx_combine_atop_u; - imp->combine_32[PIXMAN_OP_ATOP_REVERSE] = mmx_combine_atop_reverse_u; - imp->combine_32[PIXMAN_OP_XOR] = mmx_combine_xor_u; - imp->combine_32[PIXMAN_OP_ADD] = mmx_combine_add_u; - imp->combine_32[PIXMAN_OP_SATURATE] = mmx_combine_saturate_u; - - imp->combine_32_ca[PIXMAN_OP_SRC] = mmx_combine_src_ca; - imp->combine_32_ca[PIXMAN_OP_OVER] = mmx_combine_over_ca; - imp->combine_32_ca[PIXMAN_OP_OVER_REVERSE] = mmx_combine_over_reverse_ca; - imp->combine_32_ca[PIXMAN_OP_IN] = mmx_combine_in_ca; - imp->combine_32_ca[PIXMAN_OP_IN_REVERSE] = mmx_combine_in_reverse_ca; - imp->combine_32_ca[PIXMAN_OP_OUT] = mmx_combine_out_ca; - imp->combine_32_ca[PIXMAN_OP_OUT_REVERSE] = mmx_combine_out_reverse_ca; - imp->combine_32_ca[PIXMAN_OP_ATOP] = mmx_combine_atop_ca; - imp->combine_32_ca[PIXMAN_OP_ATOP_REVERSE] = mmx_combine_atop_reverse_ca; - imp->combine_32_ca[PIXMAN_OP_XOR] = mmx_combine_xor_ca; - imp->combine_32_ca[PIXMAN_OP_ADD] = mmx_combine_add_ca; - - imp->blt = mmx_blt; - imp->fill = mmx_fill; - - imp->iter_info = mmx_iters; - - return imp; -} - -#endif /* USE_X86_MMX || USE_ARM_IWMMXT || USE_LOONGSON_MMI */ diff --git a/source/libs/pixman/pixman-src/pixman/pixman-noop.c b/source/libs/pixman/pixman-src/pixman/pixman-noop.c deleted file mode 100644 index e59890492f809936080fcd51db38e855b7d636a3..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-noop.c +++ /dev/null @@ -1,161 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */ -/* - * Copyright © 2011 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <string.h> -#include <stdlib.h> -#include "pixman-private.h" -#include "pixman-combine32.h" -#include "pixman-inlines.h" - -static void -noop_composite (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - return; -} - -static uint32_t * -noop_get_scanline (pixman_iter_t *iter, const uint32_t *mask) -{ - uint32_t *result = iter->buffer; - - iter->buffer += iter->image->bits.rowstride; - - return result; -} - -static void -noop_init_solid_narrow (pixman_iter_t *iter, - const pixman_iter_info_t *info) -{ - pixman_image_t *image = iter->image; - uint32_t *buffer = iter->buffer; - uint32_t *end = buffer + iter->width; - uint32_t color; - - if (iter->image->type == SOLID) - color = image->solid.color_32; - else - color = image->bits.fetch_pixel_32 (&image->bits, 0, 0); - - while (buffer < end) - *(buffer++) = color; -} - -static void -noop_init_solid_wide (pixman_iter_t *iter, - const pixman_iter_info_t *info) -{ - pixman_image_t *image = iter->image; - argb_t *buffer = (argb_t *)iter->buffer; - argb_t *end = buffer + iter->width; - argb_t color; - - if (iter->image->type == SOLID) - color = image->solid.color_float; - else - color = image->bits.fetch_pixel_float (&image->bits, 0, 0); - - while (buffer < end) - *(buffer++) = color; -} - -static void -noop_init_direct_buffer (pixman_iter_t *iter, const pixman_iter_info_t *info) -{ - pixman_image_t *image = iter->image; - - iter->buffer = - image->bits.bits + iter->y * image->bits.rowstride + iter->x; -} - -static void -dest_write_back_direct (pixman_iter_t *iter) -{ - iter->buffer += iter->image->bits.rowstride; -} - -static const pixman_iter_info_t noop_iters[] = -{ - /* Source iters */ - { PIXMAN_any, - 0, ITER_IGNORE_ALPHA | ITER_IGNORE_RGB | ITER_SRC, - NULL, - _pixman_iter_get_scanline_noop, - NULL - }, - { PIXMAN_solid, - FAST_PATH_NO_ALPHA_MAP, ITER_NARROW | ITER_SRC, - noop_init_solid_narrow, - _pixman_iter_get_scanline_noop, - NULL, - }, - { PIXMAN_solid, - FAST_PATH_NO_ALPHA_MAP, ITER_WIDE | ITER_SRC, - noop_init_solid_wide, - _pixman_iter_get_scanline_noop, - NULL - }, - { PIXMAN_a8r8g8b8, - FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM | - FAST_PATH_BITS_IMAGE | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST, - ITER_NARROW | ITER_SRC, - noop_init_direct_buffer, - noop_get_scanline, - NULL - }, - /* Dest iters */ - { PIXMAN_a8r8g8b8, - FAST_PATH_STD_DEST_FLAGS, ITER_NARROW | ITER_DEST, - noop_init_direct_buffer, - _pixman_iter_get_scanline_noop, - dest_write_back_direct - }, - { PIXMAN_x8r8g8b8, - FAST_PATH_STD_DEST_FLAGS, ITER_NARROW | ITER_DEST | ITER_LOCALIZED_ALPHA, - noop_init_direct_buffer, - _pixman_iter_get_scanline_noop, - dest_write_back_direct - }, - { PIXMAN_null }, -}; - -static const pixman_fast_path_t noop_fast_paths[] = -{ - { PIXMAN_OP_DST, PIXMAN_any, 0, PIXMAN_any, 0, PIXMAN_any, 0, noop_composite }, - { PIXMAN_OP_NONE }, -}; - -pixman_implementation_t * -_pixman_implementation_create_noop (pixman_implementation_t *fallback) -{ - pixman_implementation_t *imp = - _pixman_implementation_create (fallback, noop_fast_paths); - - imp->iter_info = noop_iters; - - return imp; -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman-ppc.c b/source/libs/pixman/pixman-src/pixman/pixman-ppc.c deleted file mode 100644 index a6e7bb0cfb3761b6a04b9ddde3322d6acf7a5f5c..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-ppc.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright © 2000 SuSE, Inc. - * Copyright © 2007 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 SuSE not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. SuSE makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE - * 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. - */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "pixman-private.h" - -#ifdef USE_VMX - -/* The CPU detection code needs to be in a file not compiled with - * "-maltivec -mabi=altivec", as gcc would try to save vector register - * across function calls causing SIGILL on cpus without Altivec/vmx. - */ -#ifdef __APPLE__ -#include <sys/sysctl.h> - -static pixman_bool_t -pixman_have_vmx (void) -{ - int error, have_vmx; - size_t length = sizeof(have_vmx); - - error = sysctlbyname ("hw.optional.altivec", &have_vmx, &length, NULL, 0); - - if (error) - return FALSE; - - return have_vmx; -} - -#elif defined (__OpenBSD__) -#include <sys/param.h> -#include <sys/sysctl.h> -#include <machine/cpu.h> - -static pixman_bool_t -pixman_have_vmx (void) -{ - int error, have_vmx; - int mib[2] = { CTL_MACHDEP, CPU_ALTIVEC }; - size_t length = sizeof(have_vmx); - - error = sysctl (mib, 2, &have_vmx, &length, NULL, 0); - - if (error != 0) - return FALSE; - - return have_vmx; -} - -#elif defined (__linux__) - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <stdio.h> -#include <linux/auxvec.h> -#include <asm/cputable.h> - -static pixman_bool_t -pixman_have_vmx (void) -{ - int have_vmx = FALSE; - int fd; - struct - { - unsigned long type; - unsigned long value; - } aux; - - fd = open ("/proc/self/auxv", O_RDONLY); - if (fd >= 0) - { - while (read (fd, &aux, sizeof (aux)) == sizeof (aux)) - { - if (aux.type == AT_HWCAP && (aux.value & PPC_FEATURE_HAS_ALTIVEC)) - { - have_vmx = TRUE; - break; - } - } - - close (fd); - } - - return have_vmx; -} - -#else /* !__APPLE__ && !__OpenBSD__ && !__linux__ */ -#include <signal.h> -#include <setjmp.h> - -static jmp_buf jump_env; - -static void -vmx_test (int sig, - siginfo_t *si, - void * unused) -{ - longjmp (jump_env, 1); -} - -static pixman_bool_t -pixman_have_vmx (void) -{ - struct sigaction sa, osa; - int jmp_result; - - sa.sa_flags = SA_SIGINFO; - sigemptyset (&sa.sa_mask); - sa.sa_sigaction = vmx_test; - sigaction (SIGILL, &sa, &osa); - jmp_result = setjmp (jump_env); - if (jmp_result == 0) - { - asm volatile ( "vor 0, 0, 0" ); - } - sigaction (SIGILL, &osa, NULL); - return (jmp_result == 0); -} - -#endif /* __APPLE__ */ -#endif /* USE_VMX */ - -pixman_implementation_t * -_pixman_ppc_get_implementations (pixman_implementation_t *imp) -{ -#ifdef USE_VMX - if (!_pixman_disabled ("vmx") && pixman_have_vmx ()) - imp = _pixman_implementation_create_vmx (imp); -#endif - - return imp; -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman-private.h b/source/libs/pixman/pixman-src/pixman/pixman-private.h deleted file mode 100644 index 73108a01d32dbbf49021138176e433667e84ae6c..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-private.h +++ /dev/null @@ -1,1153 +0,0 @@ -#include <float.h> - -#ifndef PIXMAN_PRIVATE_H -#define PIXMAN_PRIVATE_H - -/* - * The defines which are shared between C and assembly code - */ - -/* bilinear interpolation precision (must be < 8) */ -#define BILINEAR_INTERPOLATION_BITS 7 -#define BILINEAR_INTERPOLATION_RANGE (1 << BILINEAR_INTERPOLATION_BITS) - -/* - * C specific part - */ - -#ifndef __ASSEMBLER__ - -#ifndef PACKAGE -# error config.h must be included before pixman-private.h -#endif - -#define PIXMAN_DISABLE_DEPRECATED -#define PIXMAN_USE_INTERNAL_API - -#include "pixman.h" -#include <time.h> -#include <assert.h> -#include <stdio.h> -#include <string.h> -#include <stddef.h> - -#include "pixman-compiler.h" - -/* - * Images - */ -typedef struct image_common image_common_t; -typedef struct solid_fill solid_fill_t; -typedef struct gradient gradient_t; -typedef struct linear_gradient linear_gradient_t; -typedef struct horizontal_gradient horizontal_gradient_t; -typedef struct vertical_gradient vertical_gradient_t; -typedef struct conical_gradient conical_gradient_t; -typedef struct radial_gradient radial_gradient_t; -typedef struct bits_image bits_image_t; -typedef struct circle circle_t; - -typedef struct argb_t argb_t; - -struct argb_t -{ - float a; - float r; - float g; - float b; -}; - -typedef void (*fetch_scanline_t) (bits_image_t *image, - int x, - int y, - int width, - uint32_t *buffer, - const uint32_t *mask); - -typedef uint32_t (*fetch_pixel_32_t) (bits_image_t *image, - int x, - int y); - -typedef argb_t (*fetch_pixel_float_t) (bits_image_t *image, - int x, - int y); - -typedef void (*store_scanline_t) (bits_image_t * image, - int x, - int y, - int width, - const uint32_t *values); - -typedef enum -{ - BITS, - LINEAR, - CONICAL, - RADIAL, - SOLID -} image_type_t; - -typedef void (*property_changed_func_t) (pixman_image_t *image); - -struct image_common -{ - image_type_t type; - int32_t ref_count; - pixman_region32_t clip_region; - int32_t alpha_count; /* How many times this image is being used as an alpha map */ - pixman_bool_t have_clip_region; /* FALSE if there is no clip */ - pixman_bool_t client_clip; /* Whether the source clip was - set by a client */ - pixman_bool_t clip_sources; /* Whether the clip applies when - * the image is used as a source - */ - pixman_bool_t dirty; - pixman_transform_t * transform; - pixman_repeat_t repeat; - pixman_filter_t filter; - pixman_fixed_t * filter_params; - int n_filter_params; - bits_image_t * alpha_map; - int alpha_origin_x; - int alpha_origin_y; - pixman_bool_t component_alpha; - property_changed_func_t property_changed; - - pixman_image_destroy_func_t destroy_func; - void * destroy_data; - - uint32_t flags; - pixman_format_code_t extended_format_code; -}; - -struct solid_fill -{ - image_common_t common; - pixman_color_t color; - - uint32_t color_32; - argb_t color_float; -}; - -struct gradient -{ - image_common_t common; - int n_stops; - pixman_gradient_stop_t *stops; -}; - -struct linear_gradient -{ - gradient_t common; - pixman_point_fixed_t p1; - pixman_point_fixed_t p2; -}; - -struct circle -{ - pixman_fixed_t x; - pixman_fixed_t y; - pixman_fixed_t radius; -}; - -struct radial_gradient -{ - gradient_t common; - - circle_t c1; - circle_t c2; - - circle_t delta; - double a; - double inva; - double mindr; -}; - -struct conical_gradient -{ - gradient_t common; - pixman_point_fixed_t center; - double angle; -}; - -struct bits_image -{ - image_common_t common; - pixman_format_code_t format; - const pixman_indexed_t * indexed; - int width; - int height; - uint32_t * bits; - uint32_t * free_me; - int rowstride; /* in number of uint32_t's */ - - fetch_scanline_t fetch_scanline_32; - fetch_pixel_32_t fetch_pixel_32; - store_scanline_t store_scanline_32; - - fetch_scanline_t fetch_scanline_float; - fetch_pixel_float_t fetch_pixel_float; - store_scanline_t store_scanline_float; - - /* Used for indirect access to the bits */ - pixman_read_memory_func_t read_func; - pixman_write_memory_func_t write_func; -}; - -union pixman_image -{ - image_type_t type; - image_common_t common; - bits_image_t bits; - gradient_t gradient; - linear_gradient_t linear; - conical_gradient_t conical; - radial_gradient_t radial; - solid_fill_t solid; -}; - -typedef struct pixman_iter_t pixman_iter_t; -typedef uint32_t *(* pixman_iter_get_scanline_t) (pixman_iter_t *iter, const uint32_t *mask); -typedef void (* pixman_iter_write_back_t) (pixman_iter_t *iter); -typedef void (* pixman_iter_fini_t) (pixman_iter_t *iter); - -typedef enum -{ - ITER_NARROW = (1 << 0), - ITER_WIDE = (1 << 1), - - /* "Localized alpha" is when the alpha channel is used only to compute - * the alpha value of the destination. This means that the computation - * of the RGB values of the result is independent of the alpha value. - * - * For example, the OVER operator has localized alpha for the - * destination, because the RGB values of the result can be computed - * without knowing the destination alpha. Similarly, ADD has localized - * alpha for both source and destination because the RGB values of the - * result can be computed without knowing the alpha value of source or - * destination. - * - * When he destination is xRGB, this is useful knowledge, because then - * we can treat it as if it were ARGB, which means in some cases we can - * avoid copying it to a temporary buffer. - */ - ITER_LOCALIZED_ALPHA = (1 << 2), - ITER_IGNORE_ALPHA = (1 << 3), - ITER_IGNORE_RGB = (1 << 4), - - /* These indicate whether the iterator is for a source - * or a destination image - */ - ITER_SRC = (1 << 5), - ITER_DEST = (1 << 6) -} iter_flags_t; - -struct pixman_iter_t -{ - /* These are initialized by _pixman_implementation_{src,dest}_init */ - pixman_image_t * image; - uint32_t * buffer; - int x, y; - int width; - int height; - iter_flags_t iter_flags; - uint32_t image_flags; - - /* These function pointers are initialized by the implementation */ - pixman_iter_get_scanline_t get_scanline; - pixman_iter_write_back_t write_back; - pixman_iter_fini_t fini; - - /* These fields are scratch data that implementations can use */ - void * data; - uint8_t * bits; - int stride; -}; - -typedef struct pixman_iter_info_t pixman_iter_info_t; -typedef void (* pixman_iter_initializer_t) (pixman_iter_t *iter, - const pixman_iter_info_t *info); -struct pixman_iter_info_t -{ - pixman_format_code_t format; - uint32_t image_flags; - iter_flags_t iter_flags; - pixman_iter_initializer_t initializer; - pixman_iter_get_scanline_t get_scanline; - pixman_iter_write_back_t write_back; -}; - -void -_pixman_bits_image_setup_accessors (bits_image_t *image); - -void -_pixman_bits_image_src_iter_init (pixman_image_t *image, pixman_iter_t *iter); - -void -_pixman_bits_image_dest_iter_init (pixman_image_t *image, pixman_iter_t *iter); - -void -_pixman_linear_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter); - -void -_pixman_radial_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter); - -void -_pixman_conical_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter); - -void -_pixman_image_init (pixman_image_t *image); - -pixman_bool_t -_pixman_bits_image_init (pixman_image_t * image, - pixman_format_code_t format, - int width, - int height, - uint32_t * bits, - int rowstride, - pixman_bool_t clear); -pixman_bool_t -_pixman_image_fini (pixman_image_t *image); - -pixman_image_t * -_pixman_image_allocate (void); - -pixman_bool_t -_pixman_init_gradient (gradient_t * gradient, - const pixman_gradient_stop_t *stops, - int n_stops); -void -_pixman_image_reset_clip_region (pixman_image_t *image); - -void -_pixman_image_validate (pixman_image_t *image); - -#define PIXMAN_IMAGE_GET_LINE(image, x, y, type, out_stride, line, mul) \ - do \ - { \ - uint32_t *__bits__; \ - int __stride__; \ - \ - __bits__ = image->bits.bits; \ - __stride__ = image->bits.rowstride; \ - (out_stride) = \ - __stride__ * (int) sizeof (uint32_t) / (int) sizeof (type); \ - (line) = \ - ((type *) __bits__) + (out_stride) * (y) + (mul) * (x); \ - } while (0) - -/* - * Gradient walker - */ -typedef struct -{ - float a_s, a_b; - float r_s, r_b; - float g_s, g_b; - float b_s, b_b; - pixman_fixed_48_16_t left_x; - pixman_fixed_48_16_t right_x; - - pixman_gradient_stop_t *stops; - int num_stops; - pixman_repeat_t repeat; - - pixman_bool_t need_reset; -} pixman_gradient_walker_t; - -void -_pixman_gradient_walker_init (pixman_gradient_walker_t *walker, - gradient_t * gradient, - pixman_repeat_t repeat); - -void -_pixman_gradient_walker_reset (pixman_gradient_walker_t *walker, - pixman_fixed_48_16_t pos); - -uint32_t -_pixman_gradient_walker_pixel (pixman_gradient_walker_t *walker, - pixman_fixed_48_16_t x); - -/* - * Edges - */ - -#define MAX_ALPHA(n) ((1 << (n)) - 1) -#define N_Y_FRAC(n) ((n) == 1 ? 1 : (1 << ((n) / 2)) - 1) -#define N_X_FRAC(n) ((n) == 1 ? 1 : (1 << ((n) / 2)) + 1) - -#define STEP_Y_SMALL(n) (pixman_fixed_1 / N_Y_FRAC (n)) -#define STEP_Y_BIG(n) (pixman_fixed_1 - (N_Y_FRAC (n) - 1) * STEP_Y_SMALL (n)) - -#define Y_FRAC_FIRST(n) (STEP_Y_BIG (n) / 2) -#define Y_FRAC_LAST(n) (Y_FRAC_FIRST (n) + (N_Y_FRAC (n) - 1) * STEP_Y_SMALL (n)) - -#define STEP_X_SMALL(n) (pixman_fixed_1 / N_X_FRAC (n)) -#define STEP_X_BIG(n) (pixman_fixed_1 - (N_X_FRAC (n) - 1) * STEP_X_SMALL (n)) - -#define X_FRAC_FIRST(n) (STEP_X_BIG (n) / 2) -#define X_FRAC_LAST(n) (X_FRAC_FIRST (n) + (N_X_FRAC (n) - 1) * STEP_X_SMALL (n)) - -#define RENDER_SAMPLES_X(x, n) \ - ((n) == 1? 0 : (pixman_fixed_frac (x) + \ - X_FRAC_FIRST (n)) / STEP_X_SMALL (n)) - -void -pixman_rasterize_edges_accessors (pixman_image_t *image, - pixman_edge_t * l, - pixman_edge_t * r, - pixman_fixed_t t, - pixman_fixed_t b); - -/* - * Implementations - */ -typedef struct pixman_implementation_t pixman_implementation_t; - -typedef struct -{ - pixman_op_t op; - pixman_image_t * src_image; - pixman_image_t * mask_image; - pixman_image_t * dest_image; - int32_t src_x; - int32_t src_y; - int32_t mask_x; - int32_t mask_y; - int32_t dest_x; - int32_t dest_y; - int32_t width; - int32_t height; - - uint32_t src_flags; - uint32_t mask_flags; - uint32_t dest_flags; -} pixman_composite_info_t; - -#define PIXMAN_COMPOSITE_ARGS(info) \ - MAYBE_UNUSED pixman_op_t op = info->op; \ - MAYBE_UNUSED pixman_image_t * src_image = info->src_image; \ - MAYBE_UNUSED pixman_image_t * mask_image = info->mask_image; \ - MAYBE_UNUSED pixman_image_t * dest_image = info->dest_image; \ - MAYBE_UNUSED int32_t src_x = info->src_x; \ - MAYBE_UNUSED int32_t src_y = info->src_y; \ - MAYBE_UNUSED int32_t mask_x = info->mask_x; \ - MAYBE_UNUSED int32_t mask_y = info->mask_y; \ - MAYBE_UNUSED int32_t dest_x = info->dest_x; \ - MAYBE_UNUSED int32_t dest_y = info->dest_y; \ - MAYBE_UNUSED int32_t width = info->width; \ - MAYBE_UNUSED int32_t height = info->height - -typedef void (*pixman_combine_32_func_t) (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width); - -typedef void (*pixman_combine_float_func_t) (pixman_implementation_t *imp, - pixman_op_t op, - float * dest, - const float * src, - const float * mask, - int n_pixels); - -typedef void (*pixman_composite_func_t) (pixman_implementation_t *imp, - pixman_composite_info_t *info); -typedef pixman_bool_t (*pixman_blt_func_t) (pixman_implementation_t *imp, - uint32_t * src_bits, - uint32_t * dst_bits, - int src_stride, - int dst_stride, - int src_bpp, - int dst_bpp, - int src_x, - int src_y, - int dest_x, - int dest_y, - int width, - int height); -typedef pixman_bool_t (*pixman_fill_func_t) (pixman_implementation_t *imp, - uint32_t * bits, - int stride, - int bpp, - int x, - int y, - int width, - int height, - uint32_t filler); - -void _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp); -void _pixman_setup_combiner_functions_float (pixman_implementation_t *imp); - -typedef struct -{ - pixman_op_t op; - pixman_format_code_t src_format; - uint32_t src_flags; - pixman_format_code_t mask_format; - uint32_t mask_flags; - pixman_format_code_t dest_format; - uint32_t dest_flags; - pixman_composite_func_t func; -} pixman_fast_path_t; - -struct pixman_implementation_t -{ - pixman_implementation_t * toplevel; - pixman_implementation_t * fallback; - const pixman_fast_path_t * fast_paths; - const pixman_iter_info_t * iter_info; - - pixman_blt_func_t blt; - pixman_fill_func_t fill; - - pixman_combine_32_func_t combine_32[PIXMAN_N_OPERATORS]; - pixman_combine_32_func_t combine_32_ca[PIXMAN_N_OPERATORS]; - pixman_combine_float_func_t combine_float[PIXMAN_N_OPERATORS]; - pixman_combine_float_func_t combine_float_ca[PIXMAN_N_OPERATORS]; -}; - -uint32_t -_pixman_image_get_solid (pixman_implementation_t *imp, - pixman_image_t * image, - pixman_format_code_t format); - -pixman_implementation_t * -_pixman_implementation_create (pixman_implementation_t *fallback, - const pixman_fast_path_t *fast_paths); - -void -_pixman_implementation_lookup_composite (pixman_implementation_t *toplevel, - pixman_op_t op, - pixman_format_code_t src_format, - uint32_t src_flags, - pixman_format_code_t mask_format, - uint32_t mask_flags, - pixman_format_code_t dest_format, - uint32_t dest_flags, - pixman_implementation_t **out_imp, - pixman_composite_func_t *out_func); - -pixman_combine_32_func_t -_pixman_implementation_lookup_combiner (pixman_implementation_t *imp, - pixman_op_t op, - pixman_bool_t component_alpha, - pixman_bool_t wide); - -pixman_bool_t -_pixman_implementation_blt (pixman_implementation_t *imp, - uint32_t * src_bits, - uint32_t * dst_bits, - int src_stride, - int dst_stride, - int src_bpp, - int dst_bpp, - int src_x, - int src_y, - int dest_x, - int dest_y, - int width, - int height); - -pixman_bool_t -_pixman_implementation_fill (pixman_implementation_t *imp, - uint32_t * bits, - int stride, - int bpp, - int x, - int y, - int width, - int height, - uint32_t filler); - -void -_pixman_implementation_iter_init (pixman_implementation_t *imp, - pixman_iter_t *iter, - pixman_image_t *image, - int x, - int y, - int width, - int height, - uint8_t *buffer, - iter_flags_t flags, - uint32_t image_flags); - -/* Specific implementations */ -pixman_implementation_t * -_pixman_implementation_create_general (void); - -pixman_implementation_t * -_pixman_implementation_create_fast_path (pixman_implementation_t *fallback); - -pixman_implementation_t * -_pixman_implementation_create_noop (pixman_implementation_t *fallback); - -#if defined USE_X86_MMX || defined USE_ARM_IWMMXT || defined USE_LOONGSON_MMI -pixman_implementation_t * -_pixman_implementation_create_mmx (pixman_implementation_t *fallback); -#endif - -#ifdef USE_SSE2 -pixman_implementation_t * -_pixman_implementation_create_sse2 (pixman_implementation_t *fallback); -#endif - -#ifdef USE_SSSE3 -pixman_implementation_t * -_pixman_implementation_create_ssse3 (pixman_implementation_t *fallback); -#endif - -#ifdef USE_ARM_SIMD -pixman_implementation_t * -_pixman_implementation_create_arm_simd (pixman_implementation_t *fallback); -#endif - -#ifdef USE_ARM_NEON -pixman_implementation_t * -_pixman_implementation_create_arm_neon (pixman_implementation_t *fallback); -#endif - -#ifdef USE_MIPS_DSPR2 -pixman_implementation_t * -_pixman_implementation_create_mips_dspr2 (pixman_implementation_t *fallback); -#endif - -#ifdef USE_VMX -pixman_implementation_t * -_pixman_implementation_create_vmx (pixman_implementation_t *fallback); -#endif - -pixman_bool_t -_pixman_implementation_disabled (const char *name); - -pixman_implementation_t * -_pixman_x86_get_implementations (pixman_implementation_t *imp); - -pixman_implementation_t * -_pixman_arm_get_implementations (pixman_implementation_t *imp); - -pixman_implementation_t * -_pixman_ppc_get_implementations (pixman_implementation_t *imp); - -pixman_implementation_t * -_pixman_mips_get_implementations (pixman_implementation_t *imp); - -pixman_implementation_t * -_pixman_choose_implementation (void); - -pixman_bool_t -_pixman_disabled (const char *name); - - -/* - * Utilities - */ -pixman_bool_t -_pixman_compute_composite_region32 (pixman_region32_t * region, - pixman_image_t * src_image, - pixman_image_t * mask_image, - pixman_image_t * dest_image, - int32_t src_x, - int32_t src_y, - int32_t mask_x, - int32_t mask_y, - int32_t dest_x, - int32_t dest_y, - int32_t width, - int32_t height); -uint32_t * -_pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask); - -void -_pixman_iter_init_bits_stride (pixman_iter_t *iter, const pixman_iter_info_t *info); - -/* These "formats" all have depth 0, so they - * will never clash with any real ones - */ -#define PIXMAN_null PIXMAN_FORMAT (0, 0, 0, 0, 0, 0) -#define PIXMAN_solid PIXMAN_FORMAT (0, 1, 0, 0, 0, 0) -#define PIXMAN_pixbuf PIXMAN_FORMAT (0, 2, 0, 0, 0, 0) -#define PIXMAN_rpixbuf PIXMAN_FORMAT (0, 3, 0, 0, 0, 0) -#define PIXMAN_unknown PIXMAN_FORMAT (0, 4, 0, 0, 0, 0) -#define PIXMAN_any PIXMAN_FORMAT (0, 5, 0, 0, 0, 0) - -#define PIXMAN_OP_any (PIXMAN_N_OPERATORS + 1) - -#define FAST_PATH_ID_TRANSFORM (1 << 0) -#define FAST_PATH_NO_ALPHA_MAP (1 << 1) -#define FAST_PATH_NO_CONVOLUTION_FILTER (1 << 2) -#define FAST_PATH_NO_PAD_REPEAT (1 << 3) -#define FAST_PATH_NO_REFLECT_REPEAT (1 << 4) -#define FAST_PATH_NO_ACCESSORS (1 << 5) -#define FAST_PATH_NARROW_FORMAT (1 << 6) -#define FAST_PATH_COMPONENT_ALPHA (1 << 8) -#define FAST_PATH_SAMPLES_OPAQUE (1 << 7) -#define FAST_PATH_UNIFIED_ALPHA (1 << 9) -#define FAST_PATH_SCALE_TRANSFORM (1 << 10) -#define FAST_PATH_NEAREST_FILTER (1 << 11) -#define FAST_PATH_HAS_TRANSFORM (1 << 12) -#define FAST_PATH_IS_OPAQUE (1 << 13) -#define FAST_PATH_NO_NORMAL_REPEAT (1 << 14) -#define FAST_PATH_NO_NONE_REPEAT (1 << 15) -#define FAST_PATH_X_UNIT_POSITIVE (1 << 16) -#define FAST_PATH_AFFINE_TRANSFORM (1 << 17) -#define FAST_PATH_Y_UNIT_ZERO (1 << 18) -#define FAST_PATH_BILINEAR_FILTER (1 << 19) -#define FAST_PATH_ROTATE_90_TRANSFORM (1 << 20) -#define FAST_PATH_ROTATE_180_TRANSFORM (1 << 21) -#define FAST_PATH_ROTATE_270_TRANSFORM (1 << 22) -#define FAST_PATH_SAMPLES_COVER_CLIP_NEAREST (1 << 23) -#define FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR (1 << 24) -#define FAST_PATH_BITS_IMAGE (1 << 25) -#define FAST_PATH_SEPARABLE_CONVOLUTION_FILTER (1 << 26) - -#define FAST_PATH_PAD_REPEAT \ - (FAST_PATH_NO_NONE_REPEAT | \ - FAST_PATH_NO_NORMAL_REPEAT | \ - FAST_PATH_NO_REFLECT_REPEAT) - -#define FAST_PATH_NORMAL_REPEAT \ - (FAST_PATH_NO_NONE_REPEAT | \ - FAST_PATH_NO_PAD_REPEAT | \ - FAST_PATH_NO_REFLECT_REPEAT) - -#define FAST_PATH_NONE_REPEAT \ - (FAST_PATH_NO_NORMAL_REPEAT | \ - FAST_PATH_NO_PAD_REPEAT | \ - FAST_PATH_NO_REFLECT_REPEAT) - -#define FAST_PATH_REFLECT_REPEAT \ - (FAST_PATH_NO_NONE_REPEAT | \ - FAST_PATH_NO_NORMAL_REPEAT | \ - FAST_PATH_NO_PAD_REPEAT) - -#define FAST_PATH_STANDARD_FLAGS \ - (FAST_PATH_NO_CONVOLUTION_FILTER | \ - FAST_PATH_NO_ACCESSORS | \ - FAST_PATH_NO_ALPHA_MAP | \ - FAST_PATH_NARROW_FORMAT) - -#define FAST_PATH_STD_DEST_FLAGS \ - (FAST_PATH_NO_ACCESSORS | \ - FAST_PATH_NO_ALPHA_MAP | \ - FAST_PATH_NARROW_FORMAT) - -#define SOURCE_FLAGS(format) \ - (FAST_PATH_STANDARD_FLAGS | \ - ((PIXMAN_ ## format == PIXMAN_solid) ? \ - 0 : (FAST_PATH_SAMPLES_COVER_CLIP_NEAREST | FAST_PATH_NEAREST_FILTER | FAST_PATH_ID_TRANSFORM))) - -#define MASK_FLAGS(format, extra) \ - ((PIXMAN_ ## format == PIXMAN_null) ? 0 : (SOURCE_FLAGS (format) | extra)) - -#define FAST_PATH(op, src, src_flags, mask, mask_flags, dest, dest_flags, func) \ - PIXMAN_OP_ ## op, \ - PIXMAN_ ## src, \ - src_flags, \ - PIXMAN_ ## mask, \ - mask_flags, \ - PIXMAN_ ## dest, \ - dest_flags, \ - func - -#define PIXMAN_STD_FAST_PATH(op, src, mask, dest, func) \ - { FAST_PATH ( \ - op, \ - src, SOURCE_FLAGS (src), \ - mask, MASK_FLAGS (mask, FAST_PATH_UNIFIED_ALPHA), \ - dest, FAST_PATH_STD_DEST_FLAGS, \ - func) } - -#define PIXMAN_STD_FAST_PATH_CA(op, src, mask, dest, func) \ - { FAST_PATH ( \ - op, \ - src, SOURCE_FLAGS (src), \ - mask, MASK_FLAGS (mask, FAST_PATH_COMPONENT_ALPHA), \ - dest, FAST_PATH_STD_DEST_FLAGS, \ - func) } - -extern pixman_implementation_t *global_implementation; - -static force_inline pixman_implementation_t * -get_implementation (void) -{ -#ifndef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR - if (!global_implementation) - global_implementation = _pixman_choose_implementation (); -#endif - return global_implementation; -} - -/* This function is exported for the sake of the test suite and not part - * of the ABI. - */ -PIXMAN_EXPORT pixman_implementation_t * -_pixman_internal_only_get_implementation (void); - -/* Memory allocation helpers */ -void * -pixman_malloc_ab (unsigned int n, unsigned int b); - -void * -pixman_malloc_abc (unsigned int a, unsigned int b, unsigned int c); - -void * -pixman_malloc_ab_plus_c (unsigned int a, unsigned int b, unsigned int c); - -pixman_bool_t -_pixman_multiply_overflows_size (size_t a, size_t b); - -pixman_bool_t -_pixman_multiply_overflows_int (unsigned int a, unsigned int b); - -pixman_bool_t -_pixman_addition_overflows_int (unsigned int a, unsigned int b); - -/* Compositing utilities */ -void -pixman_expand_to_float (argb_t *dst, - const uint32_t *src, - pixman_format_code_t format, - int width); - -void -pixman_contract_from_float (uint32_t *dst, - const argb_t *src, - int width); - -/* Region Helpers */ -pixman_bool_t -pixman_region32_copy_from_region16 (pixman_region32_t *dst, - pixman_region16_t *src); - -pixman_bool_t -pixman_region16_copy_from_region32 (pixman_region16_t *dst, - pixman_region32_t *src); - -/* Doubly linked lists */ -typedef struct pixman_link_t pixman_link_t; -struct pixman_link_t -{ - pixman_link_t *next; - pixman_link_t *prev; -}; - -typedef struct pixman_list_t pixman_list_t; -struct pixman_list_t -{ - pixman_link_t *head; - pixman_link_t *tail; -}; - -static force_inline void -pixman_list_init (pixman_list_t *list) -{ - list->head = (pixman_link_t *)list; - list->tail = (pixman_link_t *)list; -} - -static force_inline void -pixman_list_prepend (pixman_list_t *list, pixman_link_t *link) -{ - link->next = list->head; - link->prev = (pixman_link_t *)list; - list->head->prev = link; - list->head = link; -} - -static force_inline void -pixman_list_unlink (pixman_link_t *link) -{ - link->prev->next = link->next; - link->next->prev = link->prev; -} - -static force_inline void -pixman_list_move_to_front (pixman_list_t *list, pixman_link_t *link) -{ - pixman_list_unlink (link); - pixman_list_prepend (list, link); -} - -/* Misc macros */ - -#ifndef FALSE -# define FALSE 0 -#endif - -#ifndef TRUE -# define TRUE 1 -#endif - -#ifndef MIN -# define MIN(a, b) ((a < b) ? a : b) -#endif - -#ifndef MAX -# define MAX(a, b) ((a > b) ? a : b) -#endif - -/* Integer division that rounds towards -infinity */ -#define DIV(a, b) \ - ((((a) < 0) == ((b) < 0)) ? (a) / (b) : \ - ((a) - (b) + 1 - (((b) < 0) << 1)) / (b)) - -/* Modulus that produces the remainder wrt. DIV */ -#define MOD(a, b) ((a) < 0 ? ((b) - ((-(a) - 1) % (b))) - 1 : (a) % (b)) - -#define CLIP(v, low, high) ((v) < (low) ? (low) : ((v) > (high) ? (high) : (v))) - -#define FLOAT_IS_ZERO(f) (-FLT_MIN < (f) && (f) < FLT_MIN) - -/* Conversion between 8888 and 0565 */ - -static force_inline uint16_t -convert_8888_to_0565 (uint32_t s) -{ - /* The following code can be compiled into just 4 instructions on ARM */ - uint32_t a, b; - a = (s >> 3) & 0x1F001F; - b = s & 0xFC00; - a |= a >> 5; - a |= b >> 5; - return (uint16_t)a; -} - -static force_inline uint32_t -convert_0565_to_0888 (uint16_t s) -{ - return (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | - ((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | - ((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000))); -} - -static force_inline uint32_t -convert_0565_to_8888 (uint16_t s) -{ - return convert_0565_to_0888 (s) | 0xff000000; -} - -/* Trivial versions that are useful in macros */ - -static force_inline uint32_t -convert_8888_to_8888 (uint32_t s) -{ - return s; -} - -static force_inline uint32_t -convert_x888_to_8888 (uint32_t s) -{ - return s | 0xff000000; -} - -static force_inline uint16_t -convert_0565_to_0565 (uint16_t s) -{ - return s; -} - -#define PIXMAN_FORMAT_IS_WIDE(f) \ - (PIXMAN_FORMAT_A (f) > 8 || \ - PIXMAN_FORMAT_R (f) > 8 || \ - PIXMAN_FORMAT_G (f) > 8 || \ - PIXMAN_FORMAT_B (f) > 8 || \ - PIXMAN_FORMAT_TYPE (f) == PIXMAN_TYPE_ARGB_SRGB) - -#ifdef WORDS_BIGENDIAN -# define SCREEN_SHIFT_LEFT(x,n) ((x) << (n)) -# define SCREEN_SHIFT_RIGHT(x,n) ((x) >> (n)) -#else -# define SCREEN_SHIFT_LEFT(x,n) ((x) >> (n)) -# define SCREEN_SHIFT_RIGHT(x,n) ((x) << (n)) -#endif - -static force_inline uint32_t -unorm_to_unorm (uint32_t val, int from_bits, int to_bits) -{ - uint32_t result; - - if (from_bits == 0) - return 0; - - /* Delete any extra bits */ - val &= ((1 << from_bits) - 1); - - if (from_bits >= to_bits) - return val >> (from_bits - to_bits); - - /* Start out with the high bit of val in the high bit of result. */ - result = val << (to_bits - from_bits); - - /* Copy the bits in result, doubling the number of bits each time, until - * we fill all to_bits. Unrolled manually because from_bits and to_bits - * are usually known statically, so the compiler can turn all of this - * into a few shifts. - */ -#define REPLICATE() \ - do \ - { \ - if (from_bits < to_bits) \ - { \ - result |= result >> from_bits; \ - \ - from_bits *= 2; \ - } \ - } \ - while (0) - - REPLICATE(); - REPLICATE(); - REPLICATE(); - REPLICATE(); - REPLICATE(); - - return result; -} - -uint16_t pixman_float_to_unorm (float f, int n_bits); -float pixman_unorm_to_float (uint16_t u, int n_bits); - -/* - * Various debugging code - */ - -#undef DEBUG - -#define COMPILE_TIME_ASSERT(x) \ - do { typedef int compile_time_assertion [(x)?1:-1]; } while (0) - -/* Turn on debugging depending on what type of release this is - */ -#if (((PIXMAN_VERSION_MICRO % 2) == 0) && ((PIXMAN_VERSION_MINOR % 2) == 1)) - -/* Debugging gets turned on for development releases because these - * are the things that end up in bleeding edge distributions such - * as Rawhide etc. - * - * For performance reasons we don't turn it on for stable releases or - * random git checkouts. (Random git checkouts are often used for - * performance work). - */ - -# define DEBUG - -#endif - -void -_pixman_log_error (const char *function, const char *message); - -#define return_if_fail(expr) \ - do \ - { \ - if (unlikely (!(expr))) \ - { \ - _pixman_log_error (FUNC, "The expression " # expr " was false"); \ - return; \ - } \ - } \ - while (0) - -#define return_val_if_fail(expr, retval) \ - do \ - { \ - if (unlikely (!(expr))) \ - { \ - _pixman_log_error (FUNC, "The expression " # expr " was false"); \ - return (retval); \ - } \ - } \ - while (0) - -#define critical_if_fail(expr) \ - do \ - { \ - if (unlikely (!(expr))) \ - _pixman_log_error (FUNC, "The expression " # expr " was false"); \ - } \ - while (0) - -/* - * Matrix - */ - -typedef struct { pixman_fixed_48_16_t v[3]; } pixman_vector_48_16_t; - -pixman_bool_t -pixman_transform_point_31_16 (const pixman_transform_t *t, - const pixman_vector_48_16_t *v, - pixman_vector_48_16_t *result); - -void -pixman_transform_point_31_16_3d (const pixman_transform_t *t, - const pixman_vector_48_16_t *v, - pixman_vector_48_16_t *result); - -void -pixman_transform_point_31_16_affine (const pixman_transform_t *t, - const pixman_vector_48_16_t *v, - pixman_vector_48_16_t *result); - -/* - * Timers - */ - -#ifdef PIXMAN_TIMERS - -static inline uint64_t -oil_profile_stamp_rdtsc (void) -{ - uint32_t hi, lo; - - __asm__ __volatile__ ("rdtsc\n" : "=a" (lo), "=d" (hi)); - - return lo | (((uint64_t)hi) << 32); -} - -#define OIL_STAMP oil_profile_stamp_rdtsc - -typedef struct pixman_timer_t pixman_timer_t; - -struct pixman_timer_t -{ - int initialized; - const char * name; - uint64_t n_times; - uint64_t total; - pixman_timer_t *next; -}; - -extern int timer_defined; - -void pixman_timer_register (pixman_timer_t *timer); - -#define TIMER_BEGIN(tname) \ - { \ - static pixman_timer_t timer ## tname; \ - uint64_t begin ## tname; \ - \ - if (!timer ## tname.initialized) \ - { \ - timer ## tname.initialized = 1; \ - timer ## tname.name = # tname; \ - pixman_timer_register (&timer ## tname); \ - } \ - \ - timer ## tname.n_times++; \ - begin ## tname = OIL_STAMP (); - -#define TIMER_END(tname) \ - timer ## tname.total += OIL_STAMP () - begin ## tname; \ - } - -#else - -#define TIMER_BEGIN(tname) -#define TIMER_END(tname) - -#endif /* PIXMAN_TIMERS */ - -#endif /* __ASSEMBLER__ */ - -#endif /* PIXMAN_PRIVATE_H */ diff --git a/source/libs/pixman/pixman-src/pixman/pixman-radial-gradient.c b/source/libs/pixman/pixman-src/pixman/pixman-radial-gradient.c deleted file mode 100644 index 6a217963da18b397330fbc8bb0ab7e87ab48363e..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-radial-gradient.c +++ /dev/null @@ -1,471 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */ -/* - * - * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. - * Copyright © 2000 SuSE, Inc. - * 2005 Lars Knoll & Zack Rusin, Trolltech - * Copyright © 2007 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 Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdlib.h> -#include <math.h> -#include "pixman-private.h" - -static inline pixman_fixed_32_32_t -dot (pixman_fixed_48_16_t x1, - pixman_fixed_48_16_t y1, - pixman_fixed_48_16_t z1, - pixman_fixed_48_16_t x2, - pixman_fixed_48_16_t y2, - pixman_fixed_48_16_t z2) -{ - /* - * Exact computation, assuming that the input values can - * be represented as pixman_fixed_16_16_t - */ - return x1 * x2 + y1 * y2 + z1 * z2; -} - -static inline double -fdot (double x1, - double y1, - double z1, - double x2, - double y2, - double z2) -{ - /* - * Error can be unbound in some special cases. - * Using clever dot product algorithms (for example compensated - * dot product) would improve this but make the code much less - * obvious - */ - return x1 * x2 + y1 * y2 + z1 * z2; -} - -static uint32_t -radial_compute_color (double a, - double b, - double c, - double inva, - double dr, - double mindr, - pixman_gradient_walker_t *walker, - pixman_repeat_t repeat) -{ - /* - * In this function error propagation can lead to bad results: - * - discr can have an unbound error (if b*b-a*c is very small), - * potentially making it the opposite sign of what it should have been - * (thus clearing a pixel that would have been colored or vice-versa) - * or propagating the error to sqrtdiscr; - * if discr has the wrong sign or b is very small, this can lead to bad - * results - * - * - the algorithm used to compute the solutions of the quadratic - * equation is not numerically stable (but saves one division compared - * to the numerically stable one); - * this can be a problem if a*c is much smaller than b*b - * - * - the above problems are worse if a is small (as inva becomes bigger) - */ - double discr; - - if (a == 0) - { - double t; - - if (b == 0) - return 0; - - t = pixman_fixed_1 / 2 * c / b; - if (repeat == PIXMAN_REPEAT_NONE) - { - if (0 <= t && t <= pixman_fixed_1) - return _pixman_gradient_walker_pixel (walker, t); - } - else - { - if (t * dr >= mindr) - return _pixman_gradient_walker_pixel (walker, t); - } - - return 0; - } - - discr = fdot (b, a, 0, b, -c, 0); - if (discr >= 0) - { - double sqrtdiscr, t0, t1; - - sqrtdiscr = sqrt (discr); - t0 = (b + sqrtdiscr) * inva; - t1 = (b - sqrtdiscr) * inva; - - /* - * The root that must be used is the biggest one that belongs - * to the valid range ([0,1] for PIXMAN_REPEAT_NONE, any - * solution that results in a positive radius otherwise). - * - * If a > 0, t0 is the biggest solution, so if it is valid, it - * is the correct result. - * - * If a < 0, only one of the solutions can be valid, so the - * order in which they are tested is not important. - */ - if (repeat == PIXMAN_REPEAT_NONE) - { - if (0 <= t0 && t0 <= pixman_fixed_1) - return _pixman_gradient_walker_pixel (walker, t0); - else if (0 <= t1 && t1 <= pixman_fixed_1) - return _pixman_gradient_walker_pixel (walker, t1); - } - else - { - if (t0 * dr >= mindr) - return _pixman_gradient_walker_pixel (walker, t0); - else if (t1 * dr >= mindr) - return _pixman_gradient_walker_pixel (walker, t1); - } - } - - return 0; -} - -static uint32_t * -radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) -{ - /* - * Implementation of radial gradients following the PDF specification. - * See section 8.7.4.5.4 Type 3 (Radial) Shadings of the PDF Reference - * Manual (PDF 32000-1:2008 at the time of this writing). - * - * In the radial gradient problem we are given two circles (câ‚,râ‚) and - * (câ‚‚,râ‚‚) that define the gradient itself. - * - * Mathematically the gradient can be defined as the family of circles - * - * ((1-t)·câ‚ + t·(câ‚‚), (1-t)·râ‚ + t·râ‚‚) - * - * excluding those circles whose radius would be < 0. When a point - * belongs to more than one circle, the one with a bigger t is the only - * one that contributes to its color. When a point does not belong - * to any of the circles, it is transparent black, i.e. RGBA (0, 0, 0, 0). - * Further limitations on the range of values for t are imposed when - * the gradient is not repeated, namely t must belong to [0,1]. - * - * The graphical result is the same as drawing the valid (radius > 0) - * circles with increasing t in [-inf, +inf] (or in [0,1] if the gradient - * is not repeated) using SOURCE operator composition. - * - * It looks like a cone pointing towards the viewer if the ending circle - * is smaller than the starting one, a cone pointing inside the page if - * the starting circle is the smaller one and like a cylinder if they - * have the same radius. - * - * What we actually do is, given the point whose color we are interested - * in, compute the t values for that point, solving for t in: - * - * length((1-t)·câ‚ + t·(câ‚‚) - p) = (1-t)·râ‚ + t·râ‚‚ - * - * Let's rewrite it in a simpler way, by defining some auxiliary - * variables: - * - * cd = câ‚‚ - câ‚ - * pd = p - câ‚ - * dr = râ‚‚ - râ‚ - * length(t·cd - pd) = râ‚ + t·dr - * - * which actually means - * - * hypot(t·cdx - pdx, t·cdy - pdy) = râ‚ + t·dr - * - * or - * - * ⎷((t·cdx - pdx)² + (t·cdy - pdy)²) = râ‚ + t·dr. - * - * If we impose (as stated earlier) that râ‚ + t·dr >= 0, it becomes: - * - * (t·cdx - pdx)² + (t·cdy - pdy)² = (râ‚ + t·dr)² - * - * where we can actually expand the squares and solve for t: - * - * t²cdx² - 2t·cdx·pdx + pdx² + t²cdy² - 2t·cdy·pdy + pdy² = - * = r₲ + 2·râ‚·t·dr + t²·dr² - * - * (cdx² + cdy² - dr²)t² - 2(cdx·pdx + cdy·pdy + râ‚·dr)t + - * (pdx² + pdy² - r₲) = 0 - * - * A = cdx² + cdy² - dr² - * B = pdx·cdx + pdy·cdy + râ‚·dr - * C = pdx² + pdy² - r₲ - * At² - 2Bt + C = 0 - * - * The solutions (unless the equation degenerates because of A = 0) are: - * - * t = (B ± ⎷(B² - A·C)) / A - * - * The solution we are going to prefer is the bigger one, unless the - * radius associated to it is negative (or it falls outside the valid t - * range). - * - * Additional observations (useful for optimizations): - * A does not depend on p - * - * A < 0 <=> one of the two circles completely contains the other one - * <=> for every p, the radiuses associated with the two t solutions - * have opposite sign - */ - pixman_image_t *image = iter->image; - int x = iter->x; - int y = iter->y; - int width = iter->width; - uint32_t *buffer = iter->buffer; - - gradient_t *gradient = (gradient_t *)image; - radial_gradient_t *radial = (radial_gradient_t *)image; - uint32_t *end = buffer + width; - pixman_gradient_walker_t walker; - pixman_vector_t v, unit; - - /* reference point is the center of the pixel */ - v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2; - v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2; - v.vector[2] = pixman_fixed_1; - - _pixman_gradient_walker_init (&walker, gradient, image->common.repeat); - - if (image->common.transform) - { - if (!pixman_transform_point_3d (image->common.transform, &v)) - return iter->buffer; - - unit.vector[0] = image->common.transform->matrix[0][0]; - unit.vector[1] = image->common.transform->matrix[1][0]; - unit.vector[2] = image->common.transform->matrix[2][0]; - } - else - { - unit.vector[0] = pixman_fixed_1; - unit.vector[1] = 0; - unit.vector[2] = 0; - } - - if (unit.vector[2] == 0 && v.vector[2] == pixman_fixed_1) - { - /* - * Given: - * - * t = (B ± ⎷(B² - A·C)) / A - * - * where - * - * A = cdx² + cdy² - dr² - * B = pdx·cdx + pdy·cdy + râ‚·dr - * C = pdx² + pdy² - r₲ - * det = B² - A·C - * - * Since we have an affine transformation, we know that (pdx, pdy) - * increase linearly with each pixel, - * - * pdx = pdxâ‚€ + n·ux, - * pdy = pdyâ‚€ + n·uy, - * - * we can then express B, C and det through multiple differentiation. - */ - pixman_fixed_32_32_t b, db, c, dc, ddc; - - /* warning: this computation may overflow */ - v.vector[0] -= radial->c1.x; - v.vector[1] -= radial->c1.y; - - /* - * B and C are computed and updated exactly. - * If fdot was used instead of dot, in the worst case it would - * lose 11 bits of precision in each of the multiplication and - * summing up would zero out all the bit that were preserved, - * thus making the result 0 instead of the correct one. - * This would mean a worst case of unbound relative error or - * about 2^10 absolute error - */ - b = dot (v.vector[0], v.vector[1], radial->c1.radius, - radial->delta.x, radial->delta.y, radial->delta.radius); - db = dot (unit.vector[0], unit.vector[1], 0, - radial->delta.x, radial->delta.y, 0); - - c = dot (v.vector[0], v.vector[1], - -((pixman_fixed_48_16_t) radial->c1.radius), - v.vector[0], v.vector[1], radial->c1.radius); - dc = dot (2 * (pixman_fixed_48_16_t) v.vector[0] + unit.vector[0], - 2 * (pixman_fixed_48_16_t) v.vector[1] + unit.vector[1], - 0, - unit.vector[0], unit.vector[1], 0); - ddc = 2 * dot (unit.vector[0], unit.vector[1], 0, - unit.vector[0], unit.vector[1], 0); - - while (buffer < end) - { - if (!mask || *mask++) - { - *buffer = radial_compute_color (radial->a, b, c, - radial->inva, - radial->delta.radius, - radial->mindr, - &walker, - image->common.repeat); - } - - b += db; - c += dc; - dc += ddc; - ++buffer; - } - } - else - { - /* projective */ - /* Warning: - * error propagation guarantees are much looser than in the affine case - */ - while (buffer < end) - { - if (!mask || *mask++) - { - if (v.vector[2] != 0) - { - double pdx, pdy, invv2, b, c; - - invv2 = 1. * pixman_fixed_1 / v.vector[2]; - - pdx = v.vector[0] * invv2 - radial->c1.x; - /* / pixman_fixed_1 */ - - pdy = v.vector[1] * invv2 - radial->c1.y; - /* / pixman_fixed_1 */ - - b = fdot (pdx, pdy, radial->c1.radius, - radial->delta.x, radial->delta.y, - radial->delta.radius); - /* / pixman_fixed_1 / pixman_fixed_1 */ - - c = fdot (pdx, pdy, -radial->c1.radius, - pdx, pdy, radial->c1.radius); - /* / pixman_fixed_1 / pixman_fixed_1 */ - - *buffer = radial_compute_color (radial->a, b, c, - radial->inva, - radial->delta.radius, - radial->mindr, - &walker, - image->common.repeat); - } - else - { - *buffer = 0; - } - } - - ++buffer; - - v.vector[0] += unit.vector[0]; - v.vector[1] += unit.vector[1]; - v.vector[2] += unit.vector[2]; - } - } - - iter->y++; - return iter->buffer; -} - -static uint32_t * -radial_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask) -{ - uint32_t *buffer = radial_get_scanline_narrow (iter, NULL); - - pixman_expand_to_float ( - (argb_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width); - - return buffer; -} - -void -_pixman_radial_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter) -{ - if (iter->iter_flags & ITER_NARROW) - iter->get_scanline = radial_get_scanline_narrow; - else - iter->get_scanline = radial_get_scanline_wide; -} - -PIXMAN_EXPORT pixman_image_t * -pixman_image_create_radial_gradient (const pixman_point_fixed_t * inner, - const pixman_point_fixed_t * outer, - pixman_fixed_t inner_radius, - pixman_fixed_t outer_radius, - const pixman_gradient_stop_t *stops, - int n_stops) -{ - pixman_image_t *image; - radial_gradient_t *radial; - - image = _pixman_image_allocate (); - - if (!image) - return NULL; - - radial = &image->radial; - - if (!_pixman_init_gradient (&radial->common, stops, n_stops)) - { - free (image); - return NULL; - } - - image->type = RADIAL; - - radial->c1.x = inner->x; - radial->c1.y = inner->y; - radial->c1.radius = inner_radius; - radial->c2.x = outer->x; - radial->c2.y = outer->y; - radial->c2.radius = outer_radius; - - /* warning: this computations may overflow */ - radial->delta.x = radial->c2.x - radial->c1.x; - radial->delta.y = radial->c2.y - radial->c1.y; - radial->delta.radius = radial->c2.radius - radial->c1.radius; - - /* computed exactly, then cast to double -> every bit of the double - representation is correct (53 bits) */ - radial->a = dot (radial->delta.x, radial->delta.y, -radial->delta.radius, - radial->delta.x, radial->delta.y, radial->delta.radius); - if (radial->a != 0) - radial->inva = 1. * pixman_fixed_1 / radial->a; - - radial->mindr = -1. * pixman_fixed_1 * radial->c1.radius; - - return image; -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman-region.c b/source/libs/pixman/pixman-src/pixman/pixman-region.c deleted file mode 100644 index 59bc9c7971518dfa60d1c23e376e72d0277251c2..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-region.c +++ /dev/null @@ -1,2792 +0,0 @@ -/* - * Copyright 1987, 1988, 1989, 1998 The Open Group - * - * 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. - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name of The Open Group shall not be - * used in advertising or otherwise to promote the sale, use or other dealings - * in this Software without prior written authorization from The Open Group. - * - * Copyright 1987, 1988, 1989 by - * Digital Equipment Corporation, Maynard, Massachusetts. - * - * All Rights Reserved - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * 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 Digital not be - * used in advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. - * - * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING - * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL - * DIGITAL 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. - * - * Copyright © 1998 Keith Packard - * - * 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 Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD 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. - */ - -#include <stdlib.h> -#include <limits.h> -#include <string.h> -#include <stdio.h> -#include "pixman-private.h" - -#define PIXREGION_NIL(reg) ((reg)->data && !(reg)->data->numRects) -/* not a region */ -#define PIXREGION_NAR(reg) ((reg)->data == pixman_broken_data) -#define PIXREGION_NUMRECTS(reg) ((reg)->data ? (reg)->data->numRects : 1) -#define PIXREGION_SIZE(reg) ((reg)->data ? (reg)->data->size : 0) -#define PIXREGION_RECTS(reg) \ - ((reg)->data ? (box_type_t *)((reg)->data + 1) \ - : &(reg)->extents) -#define PIXREGION_BOXPTR(reg) ((box_type_t *)((reg)->data + 1)) -#define PIXREGION_BOX(reg, i) (&PIXREGION_BOXPTR (reg)[i]) -#define PIXREGION_TOP(reg) PIXREGION_BOX (reg, (reg)->data->numRects) -#define PIXREGION_END(reg) PIXREGION_BOX (reg, (reg)->data->numRects - 1) - -#define GOOD_RECT(rect) ((rect)->x1 < (rect)->x2 && (rect)->y1 < (rect)->y2) -#define BAD_RECT(rect) ((rect)->x1 > (rect)->x2 || (rect)->y1 > (rect)->y2) - -#ifdef DEBUG - -#define GOOD(reg) \ - do \ - { \ - if (!PREFIX (_selfcheck (reg))) \ - _pixman_log_error (FUNC, "Malformed region " # reg); \ - } while (0) - -#else - -#define GOOD(reg) - -#endif - -static const box_type_t PREFIX (_empty_box_) = { 0, 0, 0, 0 }; -static const region_data_type_t PREFIX (_empty_data_) = { 0, 0 }; -#if defined (__llvm__) && !defined (__clang__) -static const volatile region_data_type_t PREFIX (_broken_data_) = { 0, 0 }; -#else -static const region_data_type_t PREFIX (_broken_data_) = { 0, 0 }; -#endif - -static box_type_t *pixman_region_empty_box = - (box_type_t *)&PREFIX (_empty_box_); -static region_data_type_t *pixman_region_empty_data = - (region_data_type_t *)&PREFIX (_empty_data_); -static region_data_type_t *pixman_broken_data = - (region_data_type_t *)&PREFIX (_broken_data_); - -static pixman_bool_t -pixman_break (region_type_t *region); - -/* - * The functions in this file implement the Region abstraction used extensively - * throughout the X11 sample server. A Region is simply a set of disjoint - * (non-overlapping) rectangles, plus an "extent" rectangle which is the - * smallest single rectangle that contains all the non-overlapping rectangles. - * - * A Region is implemented as a "y-x-banded" array of rectangles. This array - * imposes two degrees of order. First, all rectangles are sorted by top side - * y coordinate first (y1), and then by left side x coordinate (x1). - * - * Furthermore, the rectangles are grouped into "bands". Each rectangle in a - * band has the same top y coordinate (y1), and each has the same bottom y - * coordinate (y2). Thus all rectangles in a band differ only in their left - * and right side (x1 and x2). Bands are implicit in the array of rectangles: - * there is no separate list of band start pointers. - * - * The y-x band representation does not minimize rectangles. In particular, - * if a rectangle vertically crosses a band (the rectangle has scanlines in - * the y1 to y2 area spanned by the band), then the rectangle may be broken - * down into two or more smaller rectangles stacked one atop the other. - * - * ----------- ----------- - * | | | | band 0 - * | | -------- ----------- -------- - * | | | | in y-x banded | | | | band 1 - * | | | | form is | | | | - * ----------- | | ----------- -------- - * | | | | band 2 - * -------- -------- - * - * An added constraint on the rectangles is that they must cover as much - * horizontal area as possible: no two rectangles within a band are allowed - * to touch. - * - * Whenever possible, bands will be merged together to cover a greater vertical - * distance (and thus reduce the number of rectangles). Two bands can be merged - * only if the bottom of one touches the top of the other and they have - * rectangles in the same places (of the same width, of course). - * - * Adam de Boor wrote most of the original region code. Joel McCormack - * substantially modified or rewrote most of the core arithmetic routines, and - * added pixman_region_validate in order to support several speed improvements - * to pixman_region_validate_tree. Bob Scheifler changed the representation - * to be more compact when empty or a single rectangle, and did a bunch of - * gratuitous reformatting. Carl Worth did further gratuitous reformatting - * while re-merging the server and client region code into libpixregion. - * Soren Sandmann did even more gratuitous reformatting. - */ - -/* true iff two Boxes overlap */ -#define EXTENTCHECK(r1, r2) \ - (!( ((r1)->x2 <= (r2)->x1) || \ - ((r1)->x1 >= (r2)->x2) || \ - ((r1)->y2 <= (r2)->y1) || \ - ((r1)->y1 >= (r2)->y2) ) ) - -/* true iff (x,y) is in Box */ -#define INBOX(r, x, y) \ - ( ((r)->x2 > x) && \ - ((r)->x1 <= x) && \ - ((r)->y2 > y) && \ - ((r)->y1 <= y) ) - -/* true iff Box r1 contains Box r2 */ -#define SUBSUMES(r1, r2) \ - ( ((r1)->x1 <= (r2)->x1) && \ - ((r1)->x2 >= (r2)->x2) && \ - ((r1)->y1 <= (r2)->y1) && \ - ((r1)->y2 >= (r2)->y2) ) - -static size_t -PIXREGION_SZOF (size_t n) -{ - size_t size = n * sizeof(box_type_t); - - if (n > UINT32_MAX / sizeof(box_type_t)) - return 0; - - if (sizeof(region_data_type_t) > UINT32_MAX - size) - return 0; - - return size + sizeof(region_data_type_t); -} - -static region_data_type_t * -alloc_data (size_t n) -{ - size_t sz = PIXREGION_SZOF (n); - - if (!sz) - return NULL; - - return malloc (sz); -} - -#define FREE_DATA(reg) if ((reg)->data && (reg)->data->size) free ((reg)->data) - -#define RECTALLOC_BAIL(region, n, bail) \ - do \ - { \ - if (!(region)->data || \ - (((region)->data->numRects + (n)) > (region)->data->size)) \ - { \ - if (!pixman_rect_alloc (region, n)) \ - goto bail; \ - } \ - } while (0) - -#define RECTALLOC(region, n) \ - do \ - { \ - if (!(region)->data || \ - (((region)->data->numRects + (n)) > (region)->data->size)) \ - { \ - if (!pixman_rect_alloc (region, n)) { \ - return FALSE; \ - } \ - } \ - } while (0) - -#define ADDRECT(next_rect, nx1, ny1, nx2, ny2) \ - do \ - { \ - next_rect->x1 = nx1; \ - next_rect->y1 = ny1; \ - next_rect->x2 = nx2; \ - next_rect->y2 = ny2; \ - next_rect++; \ - } \ - while (0) - -#define NEWRECT(region, next_rect, nx1, ny1, nx2, ny2) \ - do \ - { \ - if (!(region)->data || \ - ((region)->data->numRects == (region)->data->size)) \ - { \ - if (!pixman_rect_alloc (region, 1)) \ - return FALSE; \ - next_rect = PIXREGION_TOP (region); \ - } \ - ADDRECT (next_rect, nx1, ny1, nx2, ny2); \ - region->data->numRects++; \ - critical_if_fail (region->data->numRects <= region->data->size); \ - } while (0) - -#define DOWNSIZE(reg, numRects) \ - do \ - { \ - if (((numRects) < ((reg)->data->size >> 1)) && \ - ((reg)->data->size > 50)) \ - { \ - region_data_type_t * new_data; \ - size_t data_size = PIXREGION_SZOF (numRects); \ - \ - if (!data_size) \ - { \ - new_data = NULL; \ - } \ - else \ - { \ - new_data = (region_data_type_t *) \ - realloc ((reg)->data, data_size); \ - } \ - \ - if (new_data) \ - { \ - new_data->size = (numRects); \ - (reg)->data = new_data; \ - } \ - } \ - } while (0) - -PIXMAN_EXPORT pixman_bool_t -PREFIX (_equal) (region_type_t *reg1, region_type_t *reg2) -{ - int i; - box_type_t *rects1; - box_type_t *rects2; - - if (reg1->extents.x1 != reg2->extents.x1) - return FALSE; - - if (reg1->extents.x2 != reg2->extents.x2) - return FALSE; - - if (reg1->extents.y1 != reg2->extents.y1) - return FALSE; - - if (reg1->extents.y2 != reg2->extents.y2) - return FALSE; - - if (PIXREGION_NUMRECTS (reg1) != PIXREGION_NUMRECTS (reg2)) - return FALSE; - - rects1 = PIXREGION_RECTS (reg1); - rects2 = PIXREGION_RECTS (reg2); - - for (i = 0; i != PIXREGION_NUMRECTS (reg1); i++) - { - if (rects1[i].x1 != rects2[i].x1) - return FALSE; - - if (rects1[i].x2 != rects2[i].x2) - return FALSE; - - if (rects1[i].y1 != rects2[i].y1) - return FALSE; - - if (rects1[i].y2 != rects2[i].y2) - return FALSE; - } - - return TRUE; -} - -int -PREFIX (_print) (region_type_t *rgn) -{ - int num, size; - int i; - box_type_t * rects; - - num = PIXREGION_NUMRECTS (rgn); - size = PIXREGION_SIZE (rgn); - rects = PIXREGION_RECTS (rgn); - - fprintf (stderr, "num: %d size: %d\n", num, size); - fprintf (stderr, "extents: %d %d %d %d\n", - rgn->extents.x1, - rgn->extents.y1, - rgn->extents.x2, - rgn->extents.y2); - - for (i = 0; i < num; i++) - { - fprintf (stderr, "%d %d %d %d \n", - rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2); - } - - fprintf (stderr, "\n"); - - return(num); -} - - -PIXMAN_EXPORT void -PREFIX (_init) (region_type_t *region) -{ - region->extents = *pixman_region_empty_box; - region->data = pixman_region_empty_data; -} - -PIXMAN_EXPORT void -PREFIX (_init_rect) (region_type_t * region, - int x, - int y, - unsigned int width, - unsigned int height) -{ - region->extents.x1 = x; - region->extents.y1 = y; - region->extents.x2 = x + width; - region->extents.y2 = y + height; - - if (!GOOD_RECT (®ion->extents)) - { - if (BAD_RECT (®ion->extents)) - _pixman_log_error (FUNC, "Invalid rectangle passed"); - PREFIX (_init) (region); - return; - } - - region->data = NULL; -} - -PIXMAN_EXPORT void -PREFIX (_init_with_extents) (region_type_t *region, box_type_t *extents) -{ - if (!GOOD_RECT (extents)) - { - if (BAD_RECT (extents)) - _pixman_log_error (FUNC, "Invalid rectangle passed"); - PREFIX (_init) (region); - return; - } - region->extents = *extents; - - region->data = NULL; -} - -PIXMAN_EXPORT void -PREFIX (_fini) (region_type_t *region) -{ - GOOD (region); - FREE_DATA (region); -} - -PIXMAN_EXPORT int -PREFIX (_n_rects) (region_type_t *region) -{ - return PIXREGION_NUMRECTS (region); -} - -PIXMAN_EXPORT box_type_t * -PREFIX (_rectangles) (region_type_t *region, - int *n_rects) -{ - if (n_rects) - *n_rects = PIXREGION_NUMRECTS (region); - - return PIXREGION_RECTS (region); -} - -static pixman_bool_t -pixman_break (region_type_t *region) -{ - FREE_DATA (region); - - region->extents = *pixman_region_empty_box; - region->data = pixman_broken_data; - - return FALSE; -} - -static pixman_bool_t -pixman_rect_alloc (region_type_t * region, - int n) -{ - region_data_type_t *data; - - if (!region->data) - { - n++; - region->data = alloc_data (n); - - if (!region->data) - return pixman_break (region); - - region->data->numRects = 1; - *PIXREGION_BOXPTR (region) = region->extents; - } - else if (!region->data->size) - { - region->data = alloc_data (n); - - if (!region->data) - return pixman_break (region); - - region->data->numRects = 0; - } - else - { - size_t data_size; - - if (n == 1) - { - n = region->data->numRects; - if (n > 500) /* XXX pick numbers out of a hat */ - n = 250; - } - - n += region->data->numRects; - data_size = PIXREGION_SZOF (n); - - if (!data_size) - { - data = NULL; - } - else - { - data = (region_data_type_t *) - realloc (region->data, PIXREGION_SZOF (n)); - } - - if (!data) - return pixman_break (region); - - region->data = data; - } - - region->data->size = n; - - return TRUE; -} - -PIXMAN_EXPORT pixman_bool_t -PREFIX (_copy) (region_type_t *dst, region_type_t *src) -{ - GOOD (dst); - GOOD (src); - - if (dst == src) - return TRUE; - - dst->extents = src->extents; - - if (!src->data || !src->data->size) - { - FREE_DATA (dst); - dst->data = src->data; - return TRUE; - } - - if (!dst->data || (dst->data->size < src->data->numRects)) - { - FREE_DATA (dst); - - dst->data = alloc_data (src->data->numRects); - - if (!dst->data) - return pixman_break (dst); - - dst->data->size = src->data->numRects; - } - - dst->data->numRects = src->data->numRects; - - memmove ((char *)PIXREGION_BOXPTR (dst), (char *)PIXREGION_BOXPTR (src), - dst->data->numRects * sizeof(box_type_t)); - - return TRUE; -} - -/*====================================================================== - * Generic Region Operator - *====================================================================*/ - -/*- - *----------------------------------------------------------------------- - * pixman_coalesce -- - * Attempt to merge the boxes in the current band with those in the - * previous one. We are guaranteed that the current band extends to - * the end of the rects array. Used only by pixman_op. - * - * Results: - * The new index for the previous band. - * - * Side Effects: - * If coalescing takes place: - * - rectangles in the previous band will have their y2 fields - * altered. - * - region->data->numRects will be decreased. - * - *----------------------------------------------------------------------- - */ -static inline int -pixman_coalesce (region_type_t * region, /* Region to coalesce */ - int prev_start, /* Index of start of previous band */ - int cur_start) /* Index of start of current band */ -{ - box_type_t *prev_box; /* Current box in previous band */ - box_type_t *cur_box; /* Current box in current band */ - int numRects; /* Number rectangles in both bands */ - int y2; /* Bottom of current band */ - - /* - * Figure out how many rectangles are in the band. - */ - numRects = cur_start - prev_start; - critical_if_fail (numRects == region->data->numRects - cur_start); - - if (!numRects) return cur_start; - - /* - * The bands may only be coalesced if the bottom of the previous - * matches the top scanline of the current. - */ - prev_box = PIXREGION_BOX (region, prev_start); - cur_box = PIXREGION_BOX (region, cur_start); - if (prev_box->y2 != cur_box->y1) return cur_start; - - /* - * Make sure the bands have boxes in the same places. This - * assumes that boxes have been added in such a way that they - * cover the most area possible. I.e. two boxes in a band must - * have some horizontal space between them. - */ - y2 = cur_box->y2; - - do - { - if ((prev_box->x1 != cur_box->x1) || (prev_box->x2 != cur_box->x2)) - return (cur_start); - - prev_box++; - cur_box++; - numRects--; - } - while (numRects); - - /* - * The bands may be merged, so set the bottom y of each box - * in the previous band to the bottom y of the current band. - */ - numRects = cur_start - prev_start; - region->data->numRects -= numRects; - - do - { - prev_box--; - prev_box->y2 = y2; - numRects--; - } - while (numRects); - - return prev_start; -} - -/* Quicky macro to avoid trivial reject procedure calls to pixman_coalesce */ - -#define COALESCE(new_reg, prev_band, cur_band) \ - do \ - { \ - if (cur_band - prev_band == new_reg->data->numRects - cur_band) \ - prev_band = pixman_coalesce (new_reg, prev_band, cur_band); \ - else \ - prev_band = cur_band; \ - } while (0) - -/*- - *----------------------------------------------------------------------- - * pixman_region_append_non_o -- - * Handle a non-overlapping band for the union and subtract operations. - * Just adds the (top/bottom-clipped) rectangles into the region. - * Doesn't have to check for subsumption or anything. - * - * Results: - * None. - * - * Side Effects: - * region->data->numRects is incremented and the rectangles overwritten - * with the rectangles we're passed. - * - *----------------------------------------------------------------------- - */ -static inline pixman_bool_t -pixman_region_append_non_o (region_type_t * region, - box_type_t * r, - box_type_t * r_end, - int y1, - int y2) -{ - box_type_t *next_rect; - int new_rects; - - new_rects = r_end - r; - - critical_if_fail (y1 < y2); - critical_if_fail (new_rects != 0); - - /* Make sure we have enough space for all rectangles to be added */ - RECTALLOC (region, new_rects); - next_rect = PIXREGION_TOP (region); - region->data->numRects += new_rects; - - do - { - critical_if_fail (r->x1 < r->x2); - ADDRECT (next_rect, r->x1, y1, r->x2, y2); - r++; - } - while (r != r_end); - - return TRUE; -} - -#define FIND_BAND(r, r_band_end, r_end, ry1) \ - do \ - { \ - ry1 = r->y1; \ - r_band_end = r + 1; \ - while ((r_band_end != r_end) && (r_band_end->y1 == ry1)) { \ - r_band_end++; \ - } \ - } while (0) - -#define APPEND_REGIONS(new_reg, r, r_end) \ - do \ - { \ - int new_rects; \ - if ((new_rects = r_end - r)) { \ - RECTALLOC_BAIL (new_reg, new_rects, bail); \ - memmove ((char *)PIXREGION_TOP (new_reg), (char *)r, \ - new_rects * sizeof(box_type_t)); \ - new_reg->data->numRects += new_rects; \ - } \ - } while (0) - -/*- - *----------------------------------------------------------------------- - * pixman_op -- - * Apply an operation to two regions. Called by pixman_region_union, pixman_region_inverse, - * pixman_region_subtract, pixman_region_intersect.... Both regions MUST have at least one - * rectangle, and cannot be the same object. - * - * Results: - * TRUE if successful. - * - * Side Effects: - * The new region is overwritten. - * overlap set to TRUE if overlap_func ever returns TRUE. - * - * Notes: - * The idea behind this function is to view the two regions as sets. - * Together they cover a rectangle of area that this function divides - * into horizontal bands where points are covered only by one region - * or by both. For the first case, the non_overlap_func is called with - * each the band and the band's upper and lower extents. For the - * second, the overlap_func is called to process the entire band. It - * is responsible for clipping the rectangles in the band, though - * this function provides the boundaries. - * At the end of each band, the new region is coalesced, if possible, - * to reduce the number of rectangles in the region. - * - *----------------------------------------------------------------------- - */ - -typedef pixman_bool_t (*overlap_proc_ptr) (region_type_t *region, - box_type_t * r1, - box_type_t * r1_end, - box_type_t * r2, - box_type_t * r2_end, - int y1, - int y2); - -static pixman_bool_t -pixman_op (region_type_t * new_reg, /* Place to store result */ - region_type_t * reg1, /* First region in operation */ - region_type_t * reg2, /* 2d region in operation */ - overlap_proc_ptr overlap_func, /* Function to call for over- - * lapping bands */ - int append_non1, /* Append non-overlapping bands - * in region 1 ? - */ - int append_non2 /* Append non-overlapping bands - * in region 2 ? - */ - ) -{ - box_type_t *r1; /* Pointer into first region */ - box_type_t *r2; /* Pointer into 2d region */ - box_type_t *r1_end; /* End of 1st region */ - box_type_t *r2_end; /* End of 2d region */ - int ybot; /* Bottom of intersection */ - int ytop; /* Top of intersection */ - region_data_type_t *old_data; /* Old data for new_reg */ - int prev_band; /* Index of start of - * previous band in new_reg */ - int cur_band; /* Index of start of current - * band in new_reg */ - box_type_t * r1_band_end; /* End of current band in r1 */ - box_type_t * r2_band_end; /* End of current band in r2 */ - int top; /* Top of non-overlapping band */ - int bot; /* Bottom of non-overlapping band*/ - int r1y1; /* Temps for r1->y1 and r2->y1 */ - int r2y1; - int new_size; - int numRects; - - /* - * Break any region computed from a broken region - */ - if (PIXREGION_NAR (reg1) || PIXREGION_NAR (reg2)) - return pixman_break (new_reg); - - /* - * Initialization: - * set r1, r2, r1_end and r2_end appropriately, save the rectangles - * of the destination region until the end in case it's one of - * the two source regions, then mark the "new" region empty, allocating - * another array of rectangles for it to use. - */ - - r1 = PIXREGION_RECTS (reg1); - new_size = PIXREGION_NUMRECTS (reg1); - r1_end = r1 + new_size; - - numRects = PIXREGION_NUMRECTS (reg2); - r2 = PIXREGION_RECTS (reg2); - r2_end = r2 + numRects; - - critical_if_fail (r1 != r1_end); - critical_if_fail (r2 != r2_end); - - old_data = (region_data_type_t *)NULL; - - if (((new_reg == reg1) && (new_size > 1)) || - ((new_reg == reg2) && (numRects > 1))) - { - old_data = new_reg->data; - new_reg->data = pixman_region_empty_data; - } - - /* guess at new size */ - if (numRects > new_size) - new_size = numRects; - - new_size <<= 1; - - if (!new_reg->data) - new_reg->data = pixman_region_empty_data; - else if (new_reg->data->size) - new_reg->data->numRects = 0; - - if (new_size > new_reg->data->size) - { - if (!pixman_rect_alloc (new_reg, new_size)) - { - free (old_data); - return FALSE; - } - } - - /* - * Initialize ybot. - * In the upcoming loop, ybot and ytop serve different functions depending - * on whether the band being handled is an overlapping or non-overlapping - * band. - * In the case of a non-overlapping band (only one of the regions - * has points in the band), ybot is the bottom of the most recent - * intersection and thus clips the top of the rectangles in that band. - * ytop is the top of the next intersection between the two regions and - * serves to clip the bottom of the rectangles in the current band. - * For an overlapping band (where the two regions intersect), ytop clips - * the top of the rectangles of both regions and ybot clips the bottoms. - */ - - ybot = MIN (r1->y1, r2->y1); - - /* - * prev_band serves to mark the start of the previous band so rectangles - * can be coalesced into larger rectangles. qv. pixman_coalesce, above. - * In the beginning, there is no previous band, so prev_band == cur_band - * (cur_band is set later on, of course, but the first band will always - * start at index 0). prev_band and cur_band must be indices because of - * the possible expansion, and resultant moving, of the new region's - * array of rectangles. - */ - prev_band = 0; - - do - { - /* - * This algorithm proceeds one source-band (as opposed to a - * destination band, which is determined by where the two regions - * intersect) at a time. r1_band_end and r2_band_end serve to mark the - * rectangle after the last one in the current band for their - * respective regions. - */ - critical_if_fail (r1 != r1_end); - critical_if_fail (r2 != r2_end); - - FIND_BAND (r1, r1_band_end, r1_end, r1y1); - FIND_BAND (r2, r2_band_end, r2_end, r2y1); - - /* - * First handle the band that doesn't intersect, if any. - * - * Note that attention is restricted to one band in the - * non-intersecting region at once, so if a region has n - * bands between the current position and the next place it overlaps - * the other, this entire loop will be passed through n times. - */ - if (r1y1 < r2y1) - { - if (append_non1) - { - top = MAX (r1y1, ybot); - bot = MIN (r1->y2, r2y1); - if (top != bot) - { - cur_band = new_reg->data->numRects; - if (!pixman_region_append_non_o (new_reg, r1, r1_band_end, top, bot)) - goto bail; - COALESCE (new_reg, prev_band, cur_band); - } - } - ytop = r2y1; - } - else if (r2y1 < r1y1) - { - if (append_non2) - { - top = MAX (r2y1, ybot); - bot = MIN (r2->y2, r1y1); - - if (top != bot) - { - cur_band = new_reg->data->numRects; - - if (!pixman_region_append_non_o (new_reg, r2, r2_band_end, top, bot)) - goto bail; - - COALESCE (new_reg, prev_band, cur_band); - } - } - ytop = r1y1; - } - else - { - ytop = r1y1; - } - - /* - * Now see if we've hit an intersecting band. The two bands only - * intersect if ybot > ytop - */ - ybot = MIN (r1->y2, r2->y2); - if (ybot > ytop) - { - cur_band = new_reg->data->numRects; - - if (!(*overlap_func)(new_reg, - r1, r1_band_end, - r2, r2_band_end, - ytop, ybot)) - { - goto bail; - } - - COALESCE (new_reg, prev_band, cur_band); - } - - /* - * If we've finished with a band (y2 == ybot) we skip forward - * in the region to the next band. - */ - if (r1->y2 == ybot) - r1 = r1_band_end; - - if (r2->y2 == ybot) - r2 = r2_band_end; - - } - while (r1 != r1_end && r2 != r2_end); - - /* - * Deal with whichever region (if any) still has rectangles left. - * - * We only need to worry about banding and coalescing for the very first - * band left. After that, we can just group all remaining boxes, - * regardless of how many bands, into one final append to the list. - */ - - if ((r1 != r1_end) && append_non1) - { - /* Do first non_overlap1Func call, which may be able to coalesce */ - FIND_BAND (r1, r1_band_end, r1_end, r1y1); - - cur_band = new_reg->data->numRects; - - if (!pixman_region_append_non_o (new_reg, - r1, r1_band_end, - MAX (r1y1, ybot), r1->y2)) - { - goto bail; - } - - COALESCE (new_reg, prev_band, cur_band); - - /* Just append the rest of the boxes */ - APPEND_REGIONS (new_reg, r1_band_end, r1_end); - } - else if ((r2 != r2_end) && append_non2) - { - /* Do first non_overlap2Func call, which may be able to coalesce */ - FIND_BAND (r2, r2_band_end, r2_end, r2y1); - - cur_band = new_reg->data->numRects; - - if (!pixman_region_append_non_o (new_reg, - r2, r2_band_end, - MAX (r2y1, ybot), r2->y2)) - { - goto bail; - } - - COALESCE (new_reg, prev_band, cur_band); - - /* Append rest of boxes */ - APPEND_REGIONS (new_reg, r2_band_end, r2_end); - } - - free (old_data); - - if (!(numRects = new_reg->data->numRects)) - { - FREE_DATA (new_reg); - new_reg->data = pixman_region_empty_data; - } - else if (numRects == 1) - { - new_reg->extents = *PIXREGION_BOXPTR (new_reg); - FREE_DATA (new_reg); - new_reg->data = (region_data_type_t *)NULL; - } - else - { - DOWNSIZE (new_reg, numRects); - } - - return TRUE; - -bail: - free (old_data); - - return pixman_break (new_reg); -} - -/*- - *----------------------------------------------------------------------- - * pixman_set_extents -- - * Reset the extents of a region to what they should be. Called by - * pixman_region_subtract and pixman_region_intersect as they can't - * figure it out along the way or do so easily, as pixman_region_union can. - * - * Results: - * None. - * - * Side Effects: - * The region's 'extents' structure is overwritten. - * - *----------------------------------------------------------------------- - */ -static void -pixman_set_extents (region_type_t *region) -{ - box_type_t *box, *box_end; - - if (!region->data) - return; - - if (!region->data->size) - { - region->extents.x2 = region->extents.x1; - region->extents.y2 = region->extents.y1; - return; - } - - box = PIXREGION_BOXPTR (region); - box_end = PIXREGION_END (region); - - /* - * Since box is the first rectangle in the region, it must have the - * smallest y1 and since box_end is the last rectangle in the region, - * it must have the largest y2, because of banding. Initialize x1 and - * x2 from box and box_end, resp., as good things to initialize them - * to... - */ - region->extents.x1 = box->x1; - region->extents.y1 = box->y1; - region->extents.x2 = box_end->x2; - region->extents.y2 = box_end->y2; - - critical_if_fail (region->extents.y1 < region->extents.y2); - - while (box <= box_end) - { - if (box->x1 < region->extents.x1) - region->extents.x1 = box->x1; - if (box->x2 > region->extents.x2) - region->extents.x2 = box->x2; - box++; - } - - critical_if_fail (region->extents.x1 < region->extents.x2); -} - -/*====================================================================== - * Region Intersection - *====================================================================*/ -/*- - *----------------------------------------------------------------------- - * pixman_region_intersect_o -- - * Handle an overlapping band for pixman_region_intersect. - * - * Results: - * TRUE if successful. - * - * Side Effects: - * Rectangles may be added to the region. - * - *----------------------------------------------------------------------- - */ -/*ARGSUSED*/ -static pixman_bool_t -pixman_region_intersect_o (region_type_t *region, - box_type_t * r1, - box_type_t * r1_end, - box_type_t * r2, - box_type_t * r2_end, - int y1, - int y2) -{ - int x1; - int x2; - box_type_t * next_rect; - - next_rect = PIXREGION_TOP (region); - - critical_if_fail (y1 < y2); - critical_if_fail (r1 != r1_end && r2 != r2_end); - - do - { - x1 = MAX (r1->x1, r2->x1); - x2 = MIN (r1->x2, r2->x2); - - /* - * If there's any overlap between the two rectangles, add that - * overlap to the new region. - */ - if (x1 < x2) - NEWRECT (region, next_rect, x1, y1, x2, y2); - - /* - * Advance the pointer(s) with the leftmost right side, since the next - * rectangle on that list may still overlap the other region's - * current rectangle. - */ - if (r1->x2 == x2) - { - r1++; - } - if (r2->x2 == x2) - { - r2++; - } - } - while ((r1 != r1_end) && (r2 != r2_end)); - - return TRUE; -} - -PIXMAN_EXPORT pixman_bool_t -PREFIX (_intersect) (region_type_t * new_reg, - region_type_t * reg1, - region_type_t * reg2) -{ - GOOD (reg1); - GOOD (reg2); - GOOD (new_reg); - - /* check for trivial reject */ - if (PIXREGION_NIL (reg1) || PIXREGION_NIL (reg2) || - !EXTENTCHECK (®1->extents, ®2->extents)) - { - /* Covers about 20% of all cases */ - FREE_DATA (new_reg); - new_reg->extents.x2 = new_reg->extents.x1; - new_reg->extents.y2 = new_reg->extents.y1; - if (PIXREGION_NAR (reg1) || PIXREGION_NAR (reg2)) - { - new_reg->data = pixman_broken_data; - return FALSE; - } - else - { - new_reg->data = pixman_region_empty_data; - } - } - else if (!reg1->data && !reg2->data) - { - /* Covers about 80% of cases that aren't trivially rejected */ - new_reg->extents.x1 = MAX (reg1->extents.x1, reg2->extents.x1); - new_reg->extents.y1 = MAX (reg1->extents.y1, reg2->extents.y1); - new_reg->extents.x2 = MIN (reg1->extents.x2, reg2->extents.x2); - new_reg->extents.y2 = MIN (reg1->extents.y2, reg2->extents.y2); - - FREE_DATA (new_reg); - - new_reg->data = (region_data_type_t *)NULL; - } - else if (!reg2->data && SUBSUMES (®2->extents, ®1->extents)) - { - return PREFIX (_copy) (new_reg, reg1); - } - else if (!reg1->data && SUBSUMES (®1->extents, ®2->extents)) - { - return PREFIX (_copy) (new_reg, reg2); - } - else if (reg1 == reg2) - { - return PREFIX (_copy) (new_reg, reg1); - } - else - { - /* General purpose intersection */ - - if (!pixman_op (new_reg, reg1, reg2, pixman_region_intersect_o, FALSE, FALSE)) - return FALSE; - - pixman_set_extents (new_reg); - } - - GOOD (new_reg); - return(TRUE); -} - -#define MERGERECT(r) \ - do \ - { \ - if (r->x1 <= x2) \ - { \ - /* Merge with current rectangle */ \ - if (x2 < r->x2) \ - x2 = r->x2; \ - } \ - else \ - { \ - /* Add current rectangle, start new one */ \ - NEWRECT (region, next_rect, x1, y1, x2, y2); \ - x1 = r->x1; \ - x2 = r->x2; \ - } \ - r++; \ - } while (0) - -/*====================================================================== - * Region Union - *====================================================================*/ - -/*- - *----------------------------------------------------------------------- - * pixman_region_union_o -- - * Handle an overlapping band for the union operation. Picks the - * left-most rectangle each time and merges it into the region. - * - * Results: - * TRUE if successful. - * - * Side Effects: - * region is overwritten. - * overlap is set to TRUE if any boxes overlap. - * - *----------------------------------------------------------------------- - */ -static pixman_bool_t -pixman_region_union_o (region_type_t *region, - box_type_t * r1, - box_type_t * r1_end, - box_type_t * r2, - box_type_t * r2_end, - int y1, - int y2) -{ - box_type_t *next_rect; - int x1; /* left and right side of current union */ - int x2; - - critical_if_fail (y1 < y2); - critical_if_fail (r1 != r1_end && r2 != r2_end); - - next_rect = PIXREGION_TOP (region); - - /* Start off current rectangle */ - if (r1->x1 < r2->x1) - { - x1 = r1->x1; - x2 = r1->x2; - r1++; - } - else - { - x1 = r2->x1; - x2 = r2->x2; - r2++; - } - while (r1 != r1_end && r2 != r2_end) - { - if (r1->x1 < r2->x1) - MERGERECT (r1); - else - MERGERECT (r2); - } - - /* Finish off whoever (if any) is left */ - if (r1 != r1_end) - { - do - { - MERGERECT (r1); - } - while (r1 != r1_end); - } - else if (r2 != r2_end) - { - do - { - MERGERECT (r2); - } - while (r2 != r2_end); - } - - /* Add current rectangle */ - NEWRECT (region, next_rect, x1, y1, x2, y2); - - return TRUE; -} - -PIXMAN_EXPORT pixman_bool_t -PREFIX(_intersect_rect) (region_type_t *dest, - region_type_t *source, - int x, int y, - unsigned int width, - unsigned int height) -{ - region_type_t region; - - region.data = NULL; - region.extents.x1 = x; - region.extents.y1 = y; - region.extents.x2 = x + width; - region.extents.y2 = y + height; - - return PREFIX(_intersect) (dest, source, ®ion); -} - -/* Convenience function for performing union of region with a - * single rectangle - */ -PIXMAN_EXPORT pixman_bool_t -PREFIX (_union_rect) (region_type_t *dest, - region_type_t *source, - int x, - int y, - unsigned int width, - unsigned int height) -{ - region_type_t region; - - region.extents.x1 = x; - region.extents.y1 = y; - region.extents.x2 = x + width; - region.extents.y2 = y + height; - - if (!GOOD_RECT (®ion.extents)) - { - if (BAD_RECT (®ion.extents)) - _pixman_log_error (FUNC, "Invalid rectangle passed"); - return PREFIX (_copy) (dest, source); - } - - region.data = NULL; - - return PREFIX (_union) (dest, source, ®ion); -} - -PIXMAN_EXPORT pixman_bool_t -PREFIX (_union) (region_type_t *new_reg, - region_type_t *reg1, - region_type_t *reg2) -{ - /* Return TRUE if some overlap - * between reg1, reg2 - */ - GOOD (reg1); - GOOD (reg2); - GOOD (new_reg); - - /* checks all the simple cases */ - - /* - * Region 1 and 2 are the same - */ - if (reg1 == reg2) - return PREFIX (_copy) (new_reg, reg1); - - /* - * Region 1 is empty - */ - if (PIXREGION_NIL (reg1)) - { - if (PIXREGION_NAR (reg1)) - return pixman_break (new_reg); - - if (new_reg != reg2) - return PREFIX (_copy) (new_reg, reg2); - - return TRUE; - } - - /* - * Region 2 is empty - */ - if (PIXREGION_NIL (reg2)) - { - if (PIXREGION_NAR (reg2)) - return pixman_break (new_reg); - - if (new_reg != reg1) - return PREFIX (_copy) (new_reg, reg1); - - return TRUE; - } - - /* - * Region 1 completely subsumes region 2 - */ - if (!reg1->data && SUBSUMES (®1->extents, ®2->extents)) - { - if (new_reg != reg1) - return PREFIX (_copy) (new_reg, reg1); - - return TRUE; - } - - /* - * Region 2 completely subsumes region 1 - */ - if (!reg2->data && SUBSUMES (®2->extents, ®1->extents)) - { - if (new_reg != reg2) - return PREFIX (_copy) (new_reg, reg2); - - return TRUE; - } - - if (!pixman_op (new_reg, reg1, reg2, pixman_region_union_o, TRUE, TRUE)) - return FALSE; - - new_reg->extents.x1 = MIN (reg1->extents.x1, reg2->extents.x1); - new_reg->extents.y1 = MIN (reg1->extents.y1, reg2->extents.y1); - new_reg->extents.x2 = MAX (reg1->extents.x2, reg2->extents.x2); - new_reg->extents.y2 = MAX (reg1->extents.y2, reg2->extents.y2); - - GOOD (new_reg); - - return TRUE; -} - -/*====================================================================== - * Batch Rectangle Union - *====================================================================*/ - -#define EXCHANGE_RECTS(a, b) \ - { \ - box_type_t t; \ - t = rects[a]; \ - rects[a] = rects[b]; \ - rects[b] = t; \ - } - -static void -quick_sort_rects ( - box_type_t rects[], - int numRects) -{ - int y1; - int x1; - int i, j; - box_type_t *r; - - /* Always called with numRects > 1 */ - - do - { - if (numRects == 2) - { - if (rects[0].y1 > rects[1].y1 || - (rects[0].y1 == rects[1].y1 && rects[0].x1 > rects[1].x1)) - { - EXCHANGE_RECTS (0, 1); - } - - return; - } - - /* Choose partition element, stick in location 0 */ - EXCHANGE_RECTS (0, numRects >> 1); - y1 = rects[0].y1; - x1 = rects[0].x1; - - /* Partition array */ - i = 0; - j = numRects; - - do - { - r = &(rects[i]); - do - { - r++; - i++; - } - while (i != numRects && (r->y1 < y1 || (r->y1 == y1 && r->x1 < x1))); - - r = &(rects[j]); - do - { - r--; - j--; - } - while (y1 < r->y1 || (y1 == r->y1 && x1 < r->x1)); - - if (i < j) - EXCHANGE_RECTS (i, j); - } - while (i < j); - - /* Move partition element back to middle */ - EXCHANGE_RECTS (0, j); - - /* Recurse */ - if (numRects - j - 1 > 1) - quick_sort_rects (&rects[j + 1], numRects - j - 1); - - numRects = j; - } - while (numRects > 1); -} - -/*- - *----------------------------------------------------------------------- - * pixman_region_validate -- - * - * Take a ``region'' which is a non-y-x-banded random collection of - * rectangles, and compute a nice region which is the union of all the - * rectangles. - * - * Results: - * TRUE if successful. - * - * Side Effects: - * The passed-in ``region'' may be modified. - * overlap set to TRUE if any retangles overlapped, - * else FALSE; - * - * Strategy: - * Step 1. Sort the rectangles into ascending order with primary key y1 - * and secondary key x1. - * - * Step 2. Split the rectangles into the minimum number of proper y-x - * banded regions. This may require horizontally merging - * rectangles, and vertically coalescing bands. With any luck, - * this step in an identity transformation (ala the Box widget), - * or a coalescing into 1 box (ala Menus). - * - * Step 3. Merge the separate regions down to a single region by calling - * pixman_region_union. Maximize the work each pixman_region_union call does by using - * a binary merge. - * - *----------------------------------------------------------------------- - */ - -static pixman_bool_t -validate (region_type_t * badreg) -{ - /* Descriptor for regions under construction in Step 2. */ - typedef struct - { - region_type_t reg; - int prev_band; - int cur_band; - } region_info_t; - - region_info_t stack_regions[64]; - - int numRects; /* Original numRects for badreg */ - region_info_t *ri; /* Array of current regions */ - int num_ri; /* Number of entries used in ri */ - int size_ri; /* Number of entries available in ri */ - int i; /* Index into rects */ - int j; /* Index into ri */ - region_info_t *rit; /* &ri[j] */ - region_type_t *reg; /* ri[j].reg */ - box_type_t *box; /* Current box in rects */ - box_type_t *ri_box; /* Last box in ri[j].reg */ - region_type_t *hreg; /* ri[j_half].reg */ - pixman_bool_t ret = TRUE; - - if (!badreg->data) - { - GOOD (badreg); - return TRUE; - } - - numRects = badreg->data->numRects; - if (!numRects) - { - if (PIXREGION_NAR (badreg)) - return FALSE; - GOOD (badreg); - return TRUE; - } - - if (badreg->extents.x1 < badreg->extents.x2) - { - if ((numRects) == 1) - { - FREE_DATA (badreg); - badreg->data = (region_data_type_t *) NULL; - } - else - { - DOWNSIZE (badreg, numRects); - } - - GOOD (badreg); - - return TRUE; - } - - /* Step 1: Sort the rects array into ascending (y1, x1) order */ - quick_sort_rects (PIXREGION_BOXPTR (badreg), numRects); - - /* Step 2: Scatter the sorted array into the minimum number of regions */ - - /* Set up the first region to be the first rectangle in badreg */ - /* Note that step 2 code will never overflow the ri[0].reg rects array */ - ri = stack_regions; - size_ri = sizeof (stack_regions) / sizeof (stack_regions[0]); - num_ri = 1; - ri[0].prev_band = 0; - ri[0].cur_band = 0; - ri[0].reg = *badreg; - box = PIXREGION_BOXPTR (&ri[0].reg); - ri[0].reg.extents = *box; - ri[0].reg.data->numRects = 1; - badreg->extents = *pixman_region_empty_box; - badreg->data = pixman_region_empty_data; - - /* Now scatter rectangles into the minimum set of valid regions. If the - * next rectangle to be added to a region would force an existing rectangle - * in the region to be split up in order to maintain y-x banding, just - * forget it. Try the next region. If it doesn't fit cleanly into any - * region, make a new one. - */ - - for (i = numRects; --i > 0;) - { - box++; - /* Look for a region to append box to */ - for (j = num_ri, rit = ri; --j >= 0; rit++) - { - reg = &rit->reg; - ri_box = PIXREGION_END (reg); - - if (box->y1 == ri_box->y1 && box->y2 == ri_box->y2) - { - /* box is in same band as ri_box. Merge or append it */ - if (box->x1 <= ri_box->x2) - { - /* Merge it with ri_box */ - if (box->x2 > ri_box->x2) - ri_box->x2 = box->x2; - } - else - { - RECTALLOC_BAIL (reg, 1, bail); - *PIXREGION_TOP (reg) = *box; - reg->data->numRects++; - } - - goto next_rect; /* So sue me */ - } - else if (box->y1 >= ri_box->y2) - { - /* Put box into new band */ - if (reg->extents.x2 < ri_box->x2) - reg->extents.x2 = ri_box->x2; - - if (reg->extents.x1 > box->x1) - reg->extents.x1 = box->x1; - - COALESCE (reg, rit->prev_band, rit->cur_band); - rit->cur_band = reg->data->numRects; - RECTALLOC_BAIL (reg, 1, bail); - *PIXREGION_TOP (reg) = *box; - reg->data->numRects++; - - goto next_rect; - } - /* Well, this region was inappropriate. Try the next one. */ - } /* for j */ - - /* Uh-oh. No regions were appropriate. Create a new one. */ - if (size_ri == num_ri) - { - size_t data_size; - - /* Oops, allocate space for new region information */ - size_ri <<= 1; - - data_size = size_ri * sizeof(region_info_t); - if (data_size / size_ri != sizeof(region_info_t)) - goto bail; - - if (ri == stack_regions) - { - rit = malloc (data_size); - if (!rit) - goto bail; - memcpy (rit, ri, num_ri * sizeof (region_info_t)); - } - else - { - rit = (region_info_t *) realloc (ri, data_size); - if (!rit) - goto bail; - } - ri = rit; - rit = &ri[num_ri]; - } - num_ri++; - rit->prev_band = 0; - rit->cur_band = 0; - rit->reg.extents = *box; - rit->reg.data = (region_data_type_t *)NULL; - - /* MUST force allocation */ - if (!pixman_rect_alloc (&rit->reg, (i + num_ri) / num_ri)) - goto bail; - - next_rect: ; - } /* for i */ - - /* Make a final pass over each region in order to COALESCE and set - * extents.x2 and extents.y2 - */ - for (j = num_ri, rit = ri; --j >= 0; rit++) - { - reg = &rit->reg; - ri_box = PIXREGION_END (reg); - reg->extents.y2 = ri_box->y2; - - if (reg->extents.x2 < ri_box->x2) - reg->extents.x2 = ri_box->x2; - - COALESCE (reg, rit->prev_band, rit->cur_band); - - if (reg->data->numRects == 1) /* keep unions happy below */ - { - FREE_DATA (reg); - reg->data = (region_data_type_t *)NULL; - } - } - - /* Step 3: Union all regions into a single region */ - while (num_ri > 1) - { - int half = num_ri / 2; - for (j = num_ri & 1; j < (half + (num_ri & 1)); j++) - { - reg = &ri[j].reg; - hreg = &ri[j + half].reg; - - if (!pixman_op (reg, reg, hreg, pixman_region_union_o, TRUE, TRUE)) - ret = FALSE; - - if (hreg->extents.x1 < reg->extents.x1) - reg->extents.x1 = hreg->extents.x1; - - if (hreg->extents.y1 < reg->extents.y1) - reg->extents.y1 = hreg->extents.y1; - - if (hreg->extents.x2 > reg->extents.x2) - reg->extents.x2 = hreg->extents.x2; - - if (hreg->extents.y2 > reg->extents.y2) - reg->extents.y2 = hreg->extents.y2; - - FREE_DATA (hreg); - } - - num_ri -= half; - - if (!ret) - goto bail; - } - - *badreg = ri[0].reg; - - if (ri != stack_regions) - free (ri); - - GOOD (badreg); - return ret; - -bail: - for (i = 0; i < num_ri; i++) - FREE_DATA (&ri[i].reg); - - if (ri != stack_regions) - free (ri); - - return pixman_break (badreg); -} - -/*====================================================================== - * Region Subtraction - *====================================================================*/ - -/*- - *----------------------------------------------------------------------- - * pixman_region_subtract_o -- - * Overlapping band subtraction. x1 is the left-most point not yet - * checked. - * - * Results: - * TRUE if successful. - * - * Side Effects: - * region may have rectangles added to it. - * - *----------------------------------------------------------------------- - */ -/*ARGSUSED*/ -static pixman_bool_t -pixman_region_subtract_o (region_type_t * region, - box_type_t * r1, - box_type_t * r1_end, - box_type_t * r2, - box_type_t * r2_end, - int y1, - int y2) -{ - box_type_t * next_rect; - int x1; - - x1 = r1->x1; - - critical_if_fail (y1 < y2); - critical_if_fail (r1 != r1_end && r2 != r2_end); - - next_rect = PIXREGION_TOP (region); - - do - { - if (r2->x2 <= x1) - { - /* - * Subtrahend entirely to left of minuend: go to next subtrahend. - */ - r2++; - } - else if (r2->x1 <= x1) - { - /* - * Subtrahend precedes minuend: nuke left edge of minuend. - */ - x1 = r2->x2; - if (x1 >= r1->x2) - { - /* - * Minuend completely covered: advance to next minuend and - * reset left fence to edge of new minuend. - */ - r1++; - if (r1 != r1_end) - x1 = r1->x1; - } - else - { - /* - * Subtrahend now used up since it doesn't extend beyond - * minuend - */ - r2++; - } - } - else if (r2->x1 < r1->x2) - { - /* - * Left part of subtrahend covers part of minuend: add uncovered - * part of minuend to region and skip to next subtrahend. - */ - critical_if_fail (x1 < r2->x1); - NEWRECT (region, next_rect, x1, y1, r2->x1, y2); - - x1 = r2->x2; - if (x1 >= r1->x2) - { - /* - * Minuend used up: advance to new... - */ - r1++; - if (r1 != r1_end) - x1 = r1->x1; - } - else - { - /* - * Subtrahend used up - */ - r2++; - } - } - else - { - /* - * Minuend used up: add any remaining piece before advancing. - */ - if (r1->x2 > x1) - NEWRECT (region, next_rect, x1, y1, r1->x2, y2); - - r1++; - - if (r1 != r1_end) - x1 = r1->x1; - } - } - while ((r1 != r1_end) && (r2 != r2_end)); - - /* - * Add remaining minuend rectangles to region. - */ - while (r1 != r1_end) - { - critical_if_fail (x1 < r1->x2); - - NEWRECT (region, next_rect, x1, y1, r1->x2, y2); - - r1++; - if (r1 != r1_end) - x1 = r1->x1; - } - return TRUE; -} - -/*- - *----------------------------------------------------------------------- - * pixman_region_subtract -- - * Subtract reg_s from reg_m and leave the result in reg_d. - * S stands for subtrahend, M for minuend and D for difference. - * - * Results: - * TRUE if successful. - * - * Side Effects: - * reg_d is overwritten. - * - *----------------------------------------------------------------------- - */ -PIXMAN_EXPORT pixman_bool_t -PREFIX (_subtract) (region_type_t *reg_d, - region_type_t *reg_m, - region_type_t *reg_s) -{ - GOOD (reg_m); - GOOD (reg_s); - GOOD (reg_d); - - /* check for trivial rejects */ - if (PIXREGION_NIL (reg_m) || PIXREGION_NIL (reg_s) || - !EXTENTCHECK (®_m->extents, ®_s->extents)) - { - if (PIXREGION_NAR (reg_s)) - return pixman_break (reg_d); - - return PREFIX (_copy) (reg_d, reg_m); - } - else if (reg_m == reg_s) - { - FREE_DATA (reg_d); - reg_d->extents.x2 = reg_d->extents.x1; - reg_d->extents.y2 = reg_d->extents.y1; - reg_d->data = pixman_region_empty_data; - - return TRUE; - } - - /* Add those rectangles in region 1 that aren't in region 2, - do yucky subtraction for overlaps, and - just throw away rectangles in region 2 that aren't in region 1 */ - if (!pixman_op (reg_d, reg_m, reg_s, pixman_region_subtract_o, TRUE, FALSE)) - return FALSE; - - /* - * Can't alter reg_d's extents before we call pixman_op because - * it might be one of the source regions and pixman_op depends - * on the extents of those regions being unaltered. Besides, this - * way there's no checking against rectangles that will be nuked - * due to coalescing, so we have to examine fewer rectangles. - */ - pixman_set_extents (reg_d); - GOOD (reg_d); - return TRUE; -} - -/*====================================================================== - * Region Inversion - *====================================================================*/ - -/*- - *----------------------------------------------------------------------- - * pixman_region_inverse -- - * Take a region and a box and return a region that is everything - * in the box but not in the region. The careful reader will note - * that this is the same as subtracting the region from the box... - * - * Results: - * TRUE. - * - * Side Effects: - * new_reg is overwritten. - * - *----------------------------------------------------------------------- - */ -PIXMAN_EXPORT pixman_bool_t -PREFIX (_inverse) (region_type_t *new_reg, /* Destination region */ - region_type_t *reg1, /* Region to invert */ - box_type_t * inv_rect) /* Bounding box for inversion */ -{ - region_type_t inv_reg; /* Quick and dirty region made from the - * bounding box */ - GOOD (reg1); - GOOD (new_reg); - - /* check for trivial rejects */ - if (PIXREGION_NIL (reg1) || !EXTENTCHECK (inv_rect, ®1->extents)) - { - if (PIXREGION_NAR (reg1)) - return pixman_break (new_reg); - - new_reg->extents = *inv_rect; - FREE_DATA (new_reg); - new_reg->data = (region_data_type_t *)NULL; - - return TRUE; - } - - /* Add those rectangles in region 1 that aren't in region 2, - * do yucky subtraction for overlaps, and - * just throw away rectangles in region 2 that aren't in region 1 - */ - inv_reg.extents = *inv_rect; - inv_reg.data = (region_data_type_t *)NULL; - if (!pixman_op (new_reg, &inv_reg, reg1, pixman_region_subtract_o, TRUE, FALSE)) - return FALSE; - - /* - * Can't alter new_reg's extents before we call pixman_op because - * it might be one of the source regions and pixman_op depends - * on the extents of those regions being unaltered. Besides, this - * way there's no checking against rectangles that will be nuked - * due to coalescing, so we have to examine fewer rectangles. - */ - pixman_set_extents (new_reg); - GOOD (new_reg); - return TRUE; -} - -/* In time O(log n), locate the first box whose y2 is greater than y. - * Return @end if no such box exists. - */ -static box_type_t * -find_box_for_y (box_type_t *begin, box_type_t *end, int y) -{ - box_type_t *mid; - - if (end == begin) - return end; - - if (end - begin == 1) - { - if (begin->y2 > y) - return begin; - else - return end; - } - - mid = begin + (end - begin) / 2; - if (mid->y2 > y) - { - /* If no box is found in [begin, mid], the function - * will return @mid, which is then known to be the - * correct answer. - */ - return find_box_for_y (begin, mid, y); - } - else - { - return find_box_for_y (mid, end, y); - } -} - -/* - * rect_in(region, rect) - * This routine takes a pointer to a region and a pointer to a box - * and determines if the box is outside/inside/partly inside the region. - * - * The idea is to travel through the list of rectangles trying to cover the - * passed box with them. Anytime a piece of the rectangle isn't covered - * by a band of rectangles, part_out is set TRUE. Any time a rectangle in - * the region covers part of the box, part_in is set TRUE. The process ends - * when either the box has been completely covered (we reached a band that - * doesn't overlap the box, part_in is TRUE and part_out is false), the - * box has been partially covered (part_in == part_out == TRUE -- because of - * the banding, the first time this is true we know the box is only - * partially in the region) or is outside the region (we reached a band - * that doesn't overlap the box at all and part_in is false) - */ -PIXMAN_EXPORT pixman_region_overlap_t -PREFIX (_contains_rectangle) (region_type_t * region, - box_type_t * prect) -{ - box_type_t * pbox; - box_type_t * pbox_end; - int part_in, part_out; - int numRects; - int x, y; - - GOOD (region); - - numRects = PIXREGION_NUMRECTS (region); - - /* useful optimization */ - if (!numRects || !EXTENTCHECK (®ion->extents, prect)) - return(PIXMAN_REGION_OUT); - - if (numRects == 1) - { - /* We know that it must be PIXMAN_REGION_IN or PIXMAN_REGION_PART */ - if (SUBSUMES (®ion->extents, prect)) - return(PIXMAN_REGION_IN); - else - return(PIXMAN_REGION_PART); - } - - part_out = FALSE; - part_in = FALSE; - - /* (x,y) starts at upper left of rect, moving to the right and down */ - x = prect->x1; - y = prect->y1; - - /* can stop when both part_out and part_in are TRUE, or we reach prect->y2 */ - for (pbox = PIXREGION_BOXPTR (region), pbox_end = pbox + numRects; - pbox != pbox_end; - pbox++) - { - /* getting up to speed or skipping remainder of band */ - if (pbox->y2 <= y) - { - if ((pbox = find_box_for_y (pbox, pbox_end, y)) == pbox_end) - break; - } - - if (pbox->y1 > y) - { - part_out = TRUE; /* missed part of rectangle above */ - if (part_in || (pbox->y1 >= prect->y2)) - break; - y = pbox->y1; /* x guaranteed to be == prect->x1 */ - } - - if (pbox->x2 <= x) - continue; /* not far enough over yet */ - - if (pbox->x1 > x) - { - part_out = TRUE; /* missed part of rectangle to left */ - if (part_in) - break; - } - - if (pbox->x1 < prect->x2) - { - part_in = TRUE; /* definitely overlap */ - if (part_out) - break; - } - - if (pbox->x2 >= prect->x2) - { - y = pbox->y2; /* finished with this band */ - if (y >= prect->y2) - break; - x = prect->x1; /* reset x out to left again */ - } - else - { - /* - * Because boxes in a band are maximal width, if the first box - * to overlap the rectangle doesn't completely cover it in that - * band, the rectangle must be partially out, since some of it - * will be uncovered in that band. part_in will have been set true - * by now... - */ - part_out = TRUE; - break; - } - } - - if (part_in) - { - if (y < prect->y2) - return PIXMAN_REGION_PART; - else - return PIXMAN_REGION_IN; - } - else - { - return PIXMAN_REGION_OUT; - } -} - -/* PREFIX(_translate) (region, x, y) - * translates in place - */ - -PIXMAN_EXPORT void -PREFIX (_translate) (region_type_t *region, int x, int y) -{ - overflow_int_t x1, x2, y1, y2; - int nbox; - box_type_t * pbox; - - GOOD (region); - region->extents.x1 = x1 = region->extents.x1 + x; - region->extents.y1 = y1 = region->extents.y1 + y; - region->extents.x2 = x2 = region->extents.x2 + x; - region->extents.y2 = y2 = region->extents.y2 + y; - - if (((x1 - PIXMAN_REGION_MIN) | (y1 - PIXMAN_REGION_MIN) | (PIXMAN_REGION_MAX - x2) | (PIXMAN_REGION_MAX - y2)) >= 0) - { - if (region->data && (nbox = region->data->numRects)) - { - for (pbox = PIXREGION_BOXPTR (region); nbox--; pbox++) - { - pbox->x1 += x; - pbox->y1 += y; - pbox->x2 += x; - pbox->y2 += y; - } - } - return; - } - - if (((x2 - PIXMAN_REGION_MIN) | (y2 - PIXMAN_REGION_MIN) | (PIXMAN_REGION_MAX - x1) | (PIXMAN_REGION_MAX - y1)) <= 0) - { - region->extents.x2 = region->extents.x1; - region->extents.y2 = region->extents.y1; - FREE_DATA (region); - region->data = pixman_region_empty_data; - return; - } - - if (x1 < PIXMAN_REGION_MIN) - region->extents.x1 = PIXMAN_REGION_MIN; - else if (x2 > PIXMAN_REGION_MAX) - region->extents.x2 = PIXMAN_REGION_MAX; - - if (y1 < PIXMAN_REGION_MIN) - region->extents.y1 = PIXMAN_REGION_MIN; - else if (y2 > PIXMAN_REGION_MAX) - region->extents.y2 = PIXMAN_REGION_MAX; - - if (region->data && (nbox = region->data->numRects)) - { - box_type_t * pbox_out; - - for (pbox_out = pbox = PIXREGION_BOXPTR (region); nbox--; pbox++) - { - pbox_out->x1 = x1 = pbox->x1 + x; - pbox_out->y1 = y1 = pbox->y1 + y; - pbox_out->x2 = x2 = pbox->x2 + x; - pbox_out->y2 = y2 = pbox->y2 + y; - - if (((x2 - PIXMAN_REGION_MIN) | (y2 - PIXMAN_REGION_MIN) | - (PIXMAN_REGION_MAX - x1) | (PIXMAN_REGION_MAX - y1)) <= 0) - { - region->data->numRects--; - continue; - } - - if (x1 < PIXMAN_REGION_MIN) - pbox_out->x1 = PIXMAN_REGION_MIN; - else if (x2 > PIXMAN_REGION_MAX) - pbox_out->x2 = PIXMAN_REGION_MAX; - - if (y1 < PIXMAN_REGION_MIN) - pbox_out->y1 = PIXMAN_REGION_MIN; - else if (y2 > PIXMAN_REGION_MAX) - pbox_out->y2 = PIXMAN_REGION_MAX; - - pbox_out++; - } - - if (pbox_out != pbox) - { - if (region->data->numRects == 1) - { - region->extents = *PIXREGION_BOXPTR (region); - FREE_DATA (region); - region->data = (region_data_type_t *)NULL; - } - else - { - pixman_set_extents (region); - } - } - } - - GOOD (region); -} - -PIXMAN_EXPORT void -PREFIX (_reset) (region_type_t *region, box_type_t *box) -{ - GOOD (region); - - critical_if_fail (GOOD_RECT (box)); - - region->extents = *box; - - FREE_DATA (region); - - region->data = NULL; -} - -PIXMAN_EXPORT void -PREFIX (_clear) (region_type_t *region) -{ - GOOD (region); - FREE_DATA (region); - - region->extents = *pixman_region_empty_box; - region->data = pixman_region_empty_data; -} - -/* box is "return" value */ -PIXMAN_EXPORT int -PREFIX (_contains_point) (region_type_t * region, - int x, int y, - box_type_t * box) -{ - box_type_t *pbox, *pbox_end; - int numRects; - - GOOD (region); - numRects = PIXREGION_NUMRECTS (region); - - if (!numRects || !INBOX (®ion->extents, x, y)) - return(FALSE); - - if (numRects == 1) - { - if (box) - *box = region->extents; - - return(TRUE); - } - - pbox = PIXREGION_BOXPTR (region); - pbox_end = pbox + numRects; - - pbox = find_box_for_y (pbox, pbox_end, y); - - for (;pbox != pbox_end; pbox++) - { - if ((y < pbox->y1) || (x < pbox->x1)) - break; /* missed it */ - - if (x >= pbox->x2) - continue; /* not there yet */ - - if (box) - *box = *pbox; - - return(TRUE); - } - - return(FALSE); -} - -PIXMAN_EXPORT int -PREFIX (_not_empty) (region_type_t * region) -{ - GOOD (region); - - return(!PIXREGION_NIL (region)); -} - -PIXMAN_EXPORT box_type_t * -PREFIX (_extents) (region_type_t * region) -{ - GOOD (region); - - return(®ion->extents); -} - -/* - * Clip a list of scanlines to a region. The caller has allocated the - * space. FSorted is non-zero if the scanline origins are in ascending order. - * - * returns the number of new, clipped scanlines. - */ - -PIXMAN_EXPORT pixman_bool_t -PREFIX (_selfcheck) (region_type_t *reg) -{ - int i, numRects; - - if ((reg->extents.x1 > reg->extents.x2) || - (reg->extents.y1 > reg->extents.y2)) - { - return FALSE; - } - - numRects = PIXREGION_NUMRECTS (reg); - if (!numRects) - { - return ((reg->extents.x1 == reg->extents.x2) && - (reg->extents.y1 == reg->extents.y2) && - (reg->data->size || (reg->data == pixman_region_empty_data))); - } - else if (numRects == 1) - { - return (!reg->data); - } - else - { - box_type_t * pbox_p, * pbox_n; - box_type_t box; - - pbox_p = PIXREGION_RECTS (reg); - box = *pbox_p; - box.y2 = pbox_p[numRects - 1].y2; - pbox_n = pbox_p + 1; - - for (i = numRects; --i > 0; pbox_p++, pbox_n++) - { - if ((pbox_n->x1 >= pbox_n->x2) || - (pbox_n->y1 >= pbox_n->y2)) - { - return FALSE; - } - - if (pbox_n->x1 < box.x1) - box.x1 = pbox_n->x1; - - if (pbox_n->x2 > box.x2) - box.x2 = pbox_n->x2; - - if ((pbox_n->y1 < pbox_p->y1) || - ((pbox_n->y1 == pbox_p->y1) && - ((pbox_n->x1 < pbox_p->x2) || (pbox_n->y2 != pbox_p->y2)))) - { - return FALSE; - } - } - - return ((box.x1 == reg->extents.x1) && - (box.x2 == reg->extents.x2) && - (box.y1 == reg->extents.y1) && - (box.y2 == reg->extents.y2)); - } -} - -PIXMAN_EXPORT pixman_bool_t -PREFIX (_init_rects) (region_type_t *region, - const box_type_t *boxes, int count) -{ - box_type_t *rects; - int displacement; - int i; - - /* if it's 1, then we just want to set the extents, so call - * the existing method. */ - if (count == 1) - { - PREFIX (_init_rect) (region, - boxes[0].x1, - boxes[0].y1, - boxes[0].x2 - boxes[0].x1, - boxes[0].y2 - boxes[0].y1); - return TRUE; - } - - PREFIX (_init) (region); - - /* if it's 0, don't call pixman_rect_alloc -- 0 rectangles is - * a special case, and causing pixman_rect_alloc would cause - * us to leak memory (because the 0-rect case should be the - * static pixman_region_empty_data data). - */ - if (count == 0) - return TRUE; - - if (!pixman_rect_alloc (region, count)) - return FALSE; - - rects = PIXREGION_RECTS (region); - - /* Copy in the rects */ - memcpy (rects, boxes, sizeof(box_type_t) * count); - region->data->numRects = count; - - /* Eliminate empty and malformed rectangles */ - displacement = 0; - - for (i = 0; i < count; ++i) - { - box_type_t *box = &rects[i]; - - if (box->x1 >= box->x2 || box->y1 >= box->y2) - displacement++; - else if (displacement) - rects[i - displacement] = rects[i]; - } - - region->data->numRects -= displacement; - - /* If eliminating empty rectangles caused there - * to be only 0 or 1 rectangles, deal with that. - */ - if (region->data->numRects == 0) - { - FREE_DATA (region); - PREFIX (_init) (region); - - return TRUE; - } - - if (region->data->numRects == 1) - { - region->extents = rects[0]; - - FREE_DATA (region); - region->data = NULL; - - GOOD (region); - - return TRUE; - } - - /* Validate */ - region->extents.x1 = region->extents.x2 = 0; - - return validate (region); -} - -#define READ(_ptr) (*(_ptr)) - -static inline box_type_t * -bitmap_addrect (region_type_t *reg, - box_type_t *r, - box_type_t **first_rect, - int rx1, int ry1, - int rx2, int ry2) -{ - if ((rx1 < rx2) && (ry1 < ry2) && - (!(reg->data->numRects && - ((r-1)->y1 == ry1) && ((r-1)->y2 == ry2) && - ((r-1)->x1 <= rx1) && ((r-1)->x2 >= rx2)))) - { - if (reg->data->numRects == reg->data->size) - { - if (!pixman_rect_alloc (reg, 1)) - return NULL; - *first_rect = PIXREGION_BOXPTR(reg); - r = *first_rect + reg->data->numRects; - } - r->x1 = rx1; - r->y1 = ry1; - r->x2 = rx2; - r->y2 = ry2; - reg->data->numRects++; - if (r->x1 < reg->extents.x1) - reg->extents.x1 = r->x1; - if (r->x2 > reg->extents.x2) - reg->extents.x2 = r->x2; - r++; - } - return r; -} - -/* Convert bitmap clip mask into clipping region. - * First, goes through each line and makes boxes by noting the transitions - * from 0 to 1 and 1 to 0. - * Then it coalesces the current line with the previous if they have boxes - * at the same X coordinates. - * Stride is in number of uint32_t per line. - */ -PIXMAN_EXPORT void -PREFIX (_init_from_image) (region_type_t *region, - pixman_image_t *image) -{ - uint32_t mask0 = 0xffffffff & ~SCREEN_SHIFT_RIGHT(0xffffffff, 1); - box_type_t *first_rect, *rects, *prect_line_start; - box_type_t *old_rect, *new_rect; - uint32_t *pw, w, *pw_line, *pw_line_end; - int irect_prev_start, irect_line_start; - int h, base, rx1 = 0, crects; - int ib; - pixman_bool_t in_box, same; - int width, height, stride; - - PREFIX(_init) (region); - - critical_if_fail (region->data); - - return_if_fail (image->type == BITS); - return_if_fail (image->bits.format == PIXMAN_a1); - - pw_line = pixman_image_get_data (image); - width = pixman_image_get_width (image); - height = pixman_image_get_height (image); - stride = pixman_image_get_stride (image) / 4; - - first_rect = PIXREGION_BOXPTR(region); - rects = first_rect; - - region->extents.x1 = width - 1; - region->extents.x2 = 0; - irect_prev_start = -1; - for (h = 0; h < height; h++) - { - pw = pw_line; - pw_line += stride; - irect_line_start = rects - first_rect; - - /* If the Screen left most bit of the word is set, we're starting in - * a box */ - if (READ(pw) & mask0) - { - in_box = TRUE; - rx1 = 0; - } - else - { - in_box = FALSE; - } - - /* Process all words which are fully in the pixmap */ - pw_line_end = pw + (width >> 5); - for (base = 0; pw < pw_line_end; base += 32) - { - w = READ(pw++); - if (in_box) - { - if (!~w) - continue; - } - else - { - if (!w) - continue; - } - for (ib = 0; ib < 32; ib++) - { - /* If the Screen left most bit of the word is set, we're - * starting a box */ - if (w & mask0) - { - if (!in_box) - { - rx1 = base + ib; - /* start new box */ - in_box = TRUE; - } - } - else - { - if (in_box) - { - /* end box */ - rects = bitmap_addrect (region, rects, &first_rect, - rx1, h, base + ib, h + 1); - if (rects == NULL) - goto error; - in_box = FALSE; - } - } - /* Shift the word VISUALLY left one. */ - w = SCREEN_SHIFT_LEFT(w, 1); - } - } - - if (width & 31) - { - /* Process final partial word on line */ - w = READ(pw++); - for (ib = 0; ib < (width & 31); ib++) - { - /* If the Screen left most bit of the word is set, we're - * starting a box */ - if (w & mask0) - { - if (!in_box) - { - rx1 = base + ib; - /* start new box */ - in_box = TRUE; - } - } - else - { - if (in_box) - { - /* end box */ - rects = bitmap_addrect(region, rects, &first_rect, - rx1, h, base + ib, h + 1); - if (rects == NULL) - goto error; - in_box = FALSE; - } - } - /* Shift the word VISUALLY left one. */ - w = SCREEN_SHIFT_LEFT(w, 1); - } - } - /* If scanline ended with last bit set, end the box */ - if (in_box) - { - rects = bitmap_addrect(region, rects, &first_rect, - rx1, h, base + (width & 31), h + 1); - if (rects == NULL) - goto error; - } - /* if all rectangles on this line have the same x-coords as - * those on the previous line, then add 1 to all the previous y2s and - * throw away all the rectangles from this line - */ - same = FALSE; - if (irect_prev_start != -1) - { - crects = irect_line_start - irect_prev_start; - if (crects != 0 && - crects == ((rects - first_rect) - irect_line_start)) - { - old_rect = first_rect + irect_prev_start; - new_rect = prect_line_start = first_rect + irect_line_start; - same = TRUE; - while (old_rect < prect_line_start) - { - if ((old_rect->x1 != new_rect->x1) || - (old_rect->x2 != new_rect->x2)) - { - same = FALSE; - break; - } - old_rect++; - new_rect++; - } - if (same) - { - old_rect = first_rect + irect_prev_start; - while (old_rect < prect_line_start) - { - old_rect->y2 += 1; - old_rect++; - } - rects -= crects; - region->data->numRects -= crects; - } - } - } - if(!same) - irect_prev_start = irect_line_start; - } - if (!region->data->numRects) - { - region->extents.x1 = region->extents.x2 = 0; - } - else - { - region->extents.y1 = PIXREGION_BOXPTR(region)->y1; - region->extents.y2 = PIXREGION_END(region)->y2; - if (region->data->numRects == 1) - { - free (region->data); - region->data = NULL; - } - } - - error: - return; -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman-region16.c b/source/libs/pixman/pixman-src/pixman/pixman-region16.c deleted file mode 100644 index d88d3380f8b9b28f8cef09232682454a8c960fe9..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-region16.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright © 2008 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: Soren Sandmann <sandmann@redhat.com> - */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#undef PIXMAN_DISABLE_DEPRECATED - -#include "pixman-private.h" - -#include <stdlib.h> - -typedef pixman_box16_t box_type_t; -typedef pixman_region16_data_t region_data_type_t; -typedef pixman_region16_t region_type_t; -typedef int32_t overflow_int_t; - -typedef struct { - int x, y; -} point_type_t; - -#define PREFIX(x) pixman_region##x - -#define PIXMAN_REGION_MAX INT16_MAX -#define PIXMAN_REGION_MIN INT16_MIN - -#include "pixman-region.c" - -/* This function exists only to make it possible to preserve the X ABI - - * it should go away at first opportunity. - * - * The problem is that the X ABI exports the three structs and has used - * them through macros. So the X server calls this function with - * the addresses of those structs which makes the existing code continue to - * work. - */ -PIXMAN_EXPORT void -pixman_region_set_static_pointers (pixman_box16_t *empty_box, - pixman_region16_data_t *empty_data, - pixman_region16_data_t *broken_data) -{ - pixman_region_empty_box = empty_box; - pixman_region_empty_data = empty_data; - pixman_broken_data = broken_data; -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman-region32.c b/source/libs/pixman/pixman-src/pixman/pixman-region32.c deleted file mode 100644 index abd6b1a93714ec84666930696e58489e354fc9bf..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-region32.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright © 2008 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: Soren Sandmann <sandmann@redhat.com> - */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "pixman-private.h" - -#include <stdlib.h> - -typedef pixman_box32_t box_type_t; -typedef pixman_region32_data_t region_data_type_t; -typedef pixman_region32_t region_type_t; -typedef int64_t overflow_int_t; - -typedef struct { - int x, y; -} point_type_t; - -#define PREFIX(x) pixman_region32##x - -#define PIXMAN_REGION_MAX INT32_MAX -#define PIXMAN_REGION_MIN INT32_MIN - -#include "pixman-region.c" diff --git a/source/libs/pixman/pixman-src/pixman/pixman-solid-fill.c b/source/libs/pixman/pixman-src/pixman/pixman-solid-fill.c deleted file mode 100644 index 5f9fef630648c4d96fa1f60acd94d0f1dd4cecba..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-solid-fill.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright © 2000 SuSE, Inc. - * Copyright © 2007, 2009 Red Hat, Inc. - * Copyright © 2009 Soren Sandmann - * - * 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 SuSE not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. SuSE makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE - * 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. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "pixman-private.h" - -static uint32_t -color_to_uint32 (const pixman_color_t *color) -{ - return - (color->alpha >> 8 << 24) | - (color->red >> 8 << 16) | - (color->green & 0xff00) | - (color->blue >> 8); -} - -static argb_t -color_to_float (const pixman_color_t *color) -{ - argb_t result; - - result.a = pixman_unorm_to_float (color->alpha, 16); - result.r = pixman_unorm_to_float (color->red, 16); - result.g = pixman_unorm_to_float (color->green, 16); - result.b = pixman_unorm_to_float (color->blue, 16); - - return result; -} - -PIXMAN_EXPORT pixman_image_t * -pixman_image_create_solid_fill (const pixman_color_t *color) -{ - pixman_image_t *img = _pixman_image_allocate (); - - if (!img) - return NULL; - - img->type = SOLID; - img->solid.color = *color; - img->solid.color_32 = color_to_uint32 (color); - img->solid.color_float = color_to_float (color); - - return img; -} - diff --git a/source/libs/pixman/pixman-src/pixman/pixman-sse2.c b/source/libs/pixman/pixman-src/pixman/pixman-sse2.c deleted file mode 100644 index 895510372fd1cc5d6e3b18996fb376668abc8d69..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-sse2.c +++ /dev/null @@ -1,6524 +0,0 @@ -/* - * Copyright © 2008 Rodrigo Kumpera - * Copyright © 2008 André Tupinambá - * - * 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 not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. Red Hat makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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: Rodrigo Kumpera (kumpera@gmail.com) - * André Tupinambá (andrelrt@gmail.com) - * - * Based on work by Owen Taylor and Søren Sandmann - */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -/* PSHUFD is slow on a lot of old processors, and new processors have SSSE3 */ -#define PSHUFD_IS_FAST 0 - -#include <xmmintrin.h> /* for _mm_shuffle_pi16 and _MM_SHUFFLE */ -#include <emmintrin.h> /* for SSE2 intrinsics */ -#include "pixman-private.h" -#include "pixman-combine32.h" -#include "pixman-inlines.h" - -static __m128i mask_0080; -static __m128i mask_00ff; -static __m128i mask_0101; -static __m128i mask_ffff; -static __m128i mask_ff000000; -static __m128i mask_alpha; - -static __m128i mask_565_r; -static __m128i mask_565_g1, mask_565_g2; -static __m128i mask_565_b; -static __m128i mask_red; -static __m128i mask_green; -static __m128i mask_blue; - -static __m128i mask_565_fix_rb; -static __m128i mask_565_fix_g; - -static __m128i mask_565_rb; -static __m128i mask_565_pack_multiplier; - -static force_inline __m128i -unpack_32_1x128 (uint32_t data) -{ - return _mm_unpacklo_epi8 (_mm_cvtsi32_si128 (data), _mm_setzero_si128 ()); -} - -static force_inline void -unpack_128_2x128 (__m128i data, __m128i* data_lo, __m128i* data_hi) -{ - *data_lo = _mm_unpacklo_epi8 (data, _mm_setzero_si128 ()); - *data_hi = _mm_unpackhi_epi8 (data, _mm_setzero_si128 ()); -} - -static force_inline __m128i -unpack_565_to_8888 (__m128i lo) -{ - __m128i r, g, b, rb, t; - - r = _mm_and_si128 (_mm_slli_epi32 (lo, 8), mask_red); - g = _mm_and_si128 (_mm_slli_epi32 (lo, 5), mask_green); - b = _mm_and_si128 (_mm_slli_epi32 (lo, 3), mask_blue); - - rb = _mm_or_si128 (r, b); - t = _mm_and_si128 (rb, mask_565_fix_rb); - t = _mm_srli_epi32 (t, 5); - rb = _mm_or_si128 (rb, t); - - t = _mm_and_si128 (g, mask_565_fix_g); - t = _mm_srli_epi32 (t, 6); - g = _mm_or_si128 (g, t); - - return _mm_or_si128 (rb, g); -} - -static force_inline void -unpack_565_128_4x128 (__m128i data, - __m128i* data0, - __m128i* data1, - __m128i* data2, - __m128i* data3) -{ - __m128i lo, hi; - - lo = _mm_unpacklo_epi16 (data, _mm_setzero_si128 ()); - hi = _mm_unpackhi_epi16 (data, _mm_setzero_si128 ()); - - lo = unpack_565_to_8888 (lo); - hi = unpack_565_to_8888 (hi); - - unpack_128_2x128 (lo, data0, data1); - unpack_128_2x128 (hi, data2, data3); -} - -static force_inline uint16_t -pack_565_32_16 (uint32_t pixel) -{ - return (uint16_t) (((pixel >> 8) & 0xf800) | - ((pixel >> 5) & 0x07e0) | - ((pixel >> 3) & 0x001f)); -} - -static force_inline __m128i -pack_2x128_128 (__m128i lo, __m128i hi) -{ - return _mm_packus_epi16 (lo, hi); -} - -static force_inline __m128i -pack_565_2packedx128_128 (__m128i lo, __m128i hi) -{ - __m128i rb0 = _mm_and_si128 (lo, mask_565_rb); - __m128i rb1 = _mm_and_si128 (hi, mask_565_rb); - - __m128i t0 = _mm_madd_epi16 (rb0, mask_565_pack_multiplier); - __m128i t1 = _mm_madd_epi16 (rb1, mask_565_pack_multiplier); - - __m128i g0 = _mm_and_si128 (lo, mask_green); - __m128i g1 = _mm_and_si128 (hi, mask_green); - - t0 = _mm_or_si128 (t0, g0); - t1 = _mm_or_si128 (t1, g1); - - /* Simulates _mm_packus_epi32 */ - t0 = _mm_slli_epi32 (t0, 16 - 5); - t1 = _mm_slli_epi32 (t1, 16 - 5); - t0 = _mm_srai_epi32 (t0, 16); - t1 = _mm_srai_epi32 (t1, 16); - return _mm_packs_epi32 (t0, t1); -} - -static force_inline __m128i -pack_565_2x128_128 (__m128i lo, __m128i hi) -{ - __m128i data; - __m128i r, g1, g2, b; - - data = pack_2x128_128 (lo, hi); - - r = _mm_and_si128 (data, mask_565_r); - g1 = _mm_and_si128 (_mm_slli_epi32 (data, 3), mask_565_g1); - g2 = _mm_and_si128 (_mm_srli_epi32 (data, 5), mask_565_g2); - b = _mm_and_si128 (_mm_srli_epi32 (data, 3), mask_565_b); - - return _mm_or_si128 (_mm_or_si128 (_mm_or_si128 (r, g1), g2), b); -} - -static force_inline __m128i -pack_565_4x128_128 (__m128i* xmm0, __m128i* xmm1, __m128i* xmm2, __m128i* xmm3) -{ - return _mm_packus_epi16 (pack_565_2x128_128 (*xmm0, *xmm1), - pack_565_2x128_128 (*xmm2, *xmm3)); -} - -static force_inline int -is_opaque (__m128i x) -{ - __m128i ffs = _mm_cmpeq_epi8 (x, x); - - return (_mm_movemask_epi8 (_mm_cmpeq_epi8 (x, ffs)) & 0x8888) == 0x8888; -} - -static force_inline int -is_zero (__m128i x) -{ - return _mm_movemask_epi8 ( - _mm_cmpeq_epi8 (x, _mm_setzero_si128 ())) == 0xffff; -} - -static force_inline int -is_transparent (__m128i x) -{ - return (_mm_movemask_epi8 ( - _mm_cmpeq_epi8 (x, _mm_setzero_si128 ())) & 0x8888) == 0x8888; -} - -static force_inline __m128i -expand_pixel_32_1x128 (uint32_t data) -{ - return _mm_shuffle_epi32 (unpack_32_1x128 (data), _MM_SHUFFLE (1, 0, 1, 0)); -} - -static force_inline __m128i -expand_alpha_1x128 (__m128i data) -{ - return _mm_shufflehi_epi16 (_mm_shufflelo_epi16 (data, - _MM_SHUFFLE (3, 3, 3, 3)), - _MM_SHUFFLE (3, 3, 3, 3)); -} - -static force_inline void -expand_alpha_2x128 (__m128i data_lo, - __m128i data_hi, - __m128i* alpha_lo, - __m128i* alpha_hi) -{ - __m128i lo, hi; - - lo = _mm_shufflelo_epi16 (data_lo, _MM_SHUFFLE (3, 3, 3, 3)); - hi = _mm_shufflelo_epi16 (data_hi, _MM_SHUFFLE (3, 3, 3, 3)); - - *alpha_lo = _mm_shufflehi_epi16 (lo, _MM_SHUFFLE (3, 3, 3, 3)); - *alpha_hi = _mm_shufflehi_epi16 (hi, _MM_SHUFFLE (3, 3, 3, 3)); -} - -static force_inline void -expand_alpha_rev_2x128 (__m128i data_lo, - __m128i data_hi, - __m128i* alpha_lo, - __m128i* alpha_hi) -{ - __m128i lo, hi; - - lo = _mm_shufflelo_epi16 (data_lo, _MM_SHUFFLE (0, 0, 0, 0)); - hi = _mm_shufflelo_epi16 (data_hi, _MM_SHUFFLE (0, 0, 0, 0)); - *alpha_lo = _mm_shufflehi_epi16 (lo, _MM_SHUFFLE (0, 0, 0, 0)); - *alpha_hi = _mm_shufflehi_epi16 (hi, _MM_SHUFFLE (0, 0, 0, 0)); -} - -static force_inline void -pix_multiply_2x128 (__m128i* data_lo, - __m128i* data_hi, - __m128i* alpha_lo, - __m128i* alpha_hi, - __m128i* ret_lo, - __m128i* ret_hi) -{ - __m128i lo, hi; - - lo = _mm_mullo_epi16 (*data_lo, *alpha_lo); - hi = _mm_mullo_epi16 (*data_hi, *alpha_hi); - lo = _mm_adds_epu16 (lo, mask_0080); - hi = _mm_adds_epu16 (hi, mask_0080); - *ret_lo = _mm_mulhi_epu16 (lo, mask_0101); - *ret_hi = _mm_mulhi_epu16 (hi, mask_0101); -} - -static force_inline void -pix_add_multiply_2x128 (__m128i* src_lo, - __m128i* src_hi, - __m128i* alpha_dst_lo, - __m128i* alpha_dst_hi, - __m128i* dst_lo, - __m128i* dst_hi, - __m128i* alpha_src_lo, - __m128i* alpha_src_hi, - __m128i* ret_lo, - __m128i* ret_hi) -{ - __m128i t1_lo, t1_hi; - __m128i t2_lo, t2_hi; - - pix_multiply_2x128 (src_lo, src_hi, alpha_dst_lo, alpha_dst_hi, &t1_lo, &t1_hi); - pix_multiply_2x128 (dst_lo, dst_hi, alpha_src_lo, alpha_src_hi, &t2_lo, &t2_hi); - - *ret_lo = _mm_adds_epu8 (t1_lo, t2_lo); - *ret_hi = _mm_adds_epu8 (t1_hi, t2_hi); -} - -static force_inline void -negate_2x128 (__m128i data_lo, - __m128i data_hi, - __m128i* neg_lo, - __m128i* neg_hi) -{ - *neg_lo = _mm_xor_si128 (data_lo, mask_00ff); - *neg_hi = _mm_xor_si128 (data_hi, mask_00ff); -} - -static force_inline void -invert_colors_2x128 (__m128i data_lo, - __m128i data_hi, - __m128i* inv_lo, - __m128i* inv_hi) -{ - __m128i lo, hi; - - lo = _mm_shufflelo_epi16 (data_lo, _MM_SHUFFLE (3, 0, 1, 2)); - hi = _mm_shufflelo_epi16 (data_hi, _MM_SHUFFLE (3, 0, 1, 2)); - *inv_lo = _mm_shufflehi_epi16 (lo, _MM_SHUFFLE (3, 0, 1, 2)); - *inv_hi = _mm_shufflehi_epi16 (hi, _MM_SHUFFLE (3, 0, 1, 2)); -} - -static force_inline void -over_2x128 (__m128i* src_lo, - __m128i* src_hi, - __m128i* alpha_lo, - __m128i* alpha_hi, - __m128i* dst_lo, - __m128i* dst_hi) -{ - __m128i t1, t2; - - negate_2x128 (*alpha_lo, *alpha_hi, &t1, &t2); - - pix_multiply_2x128 (dst_lo, dst_hi, &t1, &t2, dst_lo, dst_hi); - - *dst_lo = _mm_adds_epu8 (*src_lo, *dst_lo); - *dst_hi = _mm_adds_epu8 (*src_hi, *dst_hi); -} - -static force_inline void -over_rev_non_pre_2x128 (__m128i src_lo, - __m128i src_hi, - __m128i* dst_lo, - __m128i* dst_hi) -{ - __m128i lo, hi; - __m128i alpha_lo, alpha_hi; - - expand_alpha_2x128 (src_lo, src_hi, &alpha_lo, &alpha_hi); - - lo = _mm_or_si128 (alpha_lo, mask_alpha); - hi = _mm_or_si128 (alpha_hi, mask_alpha); - - invert_colors_2x128 (src_lo, src_hi, &src_lo, &src_hi); - - pix_multiply_2x128 (&src_lo, &src_hi, &lo, &hi, &lo, &hi); - - over_2x128 (&lo, &hi, &alpha_lo, &alpha_hi, dst_lo, dst_hi); -} - -static force_inline void -in_over_2x128 (__m128i* src_lo, - __m128i* src_hi, - __m128i* alpha_lo, - __m128i* alpha_hi, - __m128i* mask_lo, - __m128i* mask_hi, - __m128i* dst_lo, - __m128i* dst_hi) -{ - __m128i s_lo, s_hi; - __m128i a_lo, a_hi; - - pix_multiply_2x128 (src_lo, src_hi, mask_lo, mask_hi, &s_lo, &s_hi); - pix_multiply_2x128 (alpha_lo, alpha_hi, mask_lo, mask_hi, &a_lo, &a_hi); - - over_2x128 (&s_lo, &s_hi, &a_lo, &a_hi, dst_lo, dst_hi); -} - -/* load 4 pixels from a 16-byte boundary aligned address */ -static force_inline __m128i -load_128_aligned (__m128i* src) -{ - return _mm_load_si128 (src); -} - -/* load 4 pixels from a unaligned address */ -static force_inline __m128i -load_128_unaligned (const __m128i* src) -{ - return _mm_loadu_si128 (src); -} - -/* save 4 pixels using Write Combining memory on a 16-byte - * boundary aligned address - */ -static force_inline void -save_128_write_combining (__m128i* dst, - __m128i data) -{ - _mm_stream_si128 (dst, data); -} - -/* save 4 pixels on a 16-byte boundary aligned address */ -static force_inline void -save_128_aligned (__m128i* dst, - __m128i data) -{ - _mm_store_si128 (dst, data); -} - -/* save 4 pixels on a unaligned address */ -static force_inline void -save_128_unaligned (__m128i* dst, - __m128i data) -{ - _mm_storeu_si128 (dst, data); -} - -static force_inline __m128i -load_32_1x128 (uint32_t data) -{ - return _mm_cvtsi32_si128 (data); -} - -static force_inline __m128i -expand_alpha_rev_1x128 (__m128i data) -{ - return _mm_shufflelo_epi16 (data, _MM_SHUFFLE (0, 0, 0, 0)); -} - -static force_inline __m128i -expand_pixel_8_1x128 (uint8_t data) -{ - return _mm_shufflelo_epi16 ( - unpack_32_1x128 ((uint32_t)data), _MM_SHUFFLE (0, 0, 0, 0)); -} - -static force_inline __m128i -pix_multiply_1x128 (__m128i data, - __m128i alpha) -{ - return _mm_mulhi_epu16 (_mm_adds_epu16 (_mm_mullo_epi16 (data, alpha), - mask_0080), - mask_0101); -} - -static force_inline __m128i -pix_add_multiply_1x128 (__m128i* src, - __m128i* alpha_dst, - __m128i* dst, - __m128i* alpha_src) -{ - __m128i t1 = pix_multiply_1x128 (*src, *alpha_dst); - __m128i t2 = pix_multiply_1x128 (*dst, *alpha_src); - - return _mm_adds_epu8 (t1, t2); -} - -static force_inline __m128i -negate_1x128 (__m128i data) -{ - return _mm_xor_si128 (data, mask_00ff); -} - -static force_inline __m128i -invert_colors_1x128 (__m128i data) -{ - return _mm_shufflelo_epi16 (data, _MM_SHUFFLE (3, 0, 1, 2)); -} - -static force_inline __m128i -over_1x128 (__m128i src, __m128i alpha, __m128i dst) -{ - return _mm_adds_epu8 (src, pix_multiply_1x128 (dst, negate_1x128 (alpha))); -} - -static force_inline __m128i -in_over_1x128 (__m128i* src, __m128i* alpha, __m128i* mask, __m128i* dst) -{ - return over_1x128 (pix_multiply_1x128 (*src, *mask), - pix_multiply_1x128 (*alpha, *mask), - *dst); -} - -static force_inline __m128i -over_rev_non_pre_1x128 (__m128i src, __m128i dst) -{ - __m128i alpha = expand_alpha_1x128 (src); - - return over_1x128 (pix_multiply_1x128 (invert_colors_1x128 (src), - _mm_or_si128 (alpha, mask_alpha)), - alpha, - dst); -} - -static force_inline uint32_t -pack_1x128_32 (__m128i data) -{ - return _mm_cvtsi128_si32 (_mm_packus_epi16 (data, _mm_setzero_si128 ())); -} - -static force_inline __m128i -expand565_16_1x128 (uint16_t pixel) -{ - __m128i m = _mm_cvtsi32_si128 (pixel); - - m = unpack_565_to_8888 (m); - - return _mm_unpacklo_epi8 (m, _mm_setzero_si128 ()); -} - -static force_inline uint32_t -core_combine_over_u_pixel_sse2 (uint32_t src, uint32_t dst) -{ - uint8_t a; - __m128i xmms; - - a = src >> 24; - - if (a == 0xff) - { - return src; - } - else if (src) - { - xmms = unpack_32_1x128 (src); - return pack_1x128_32 ( - over_1x128 (xmms, expand_alpha_1x128 (xmms), - unpack_32_1x128 (dst))); - } - - return dst; -} - -static force_inline uint32_t -combine1 (const uint32_t *ps, const uint32_t *pm) -{ - uint32_t s = *ps; - - if (pm) - { - __m128i ms, mm; - - mm = unpack_32_1x128 (*pm); - mm = expand_alpha_1x128 (mm); - - ms = unpack_32_1x128 (s); - ms = pix_multiply_1x128 (ms, mm); - - s = pack_1x128_32 (ms); - } - - return s; -} - -static force_inline __m128i -combine4 (const __m128i *ps, const __m128i *pm) -{ - __m128i xmm_src_lo, xmm_src_hi; - __m128i xmm_msk_lo, xmm_msk_hi; - __m128i s; - - if (pm) - { - xmm_msk_lo = load_128_unaligned (pm); - - if (is_transparent (xmm_msk_lo)) - return _mm_setzero_si128 (); - } - - s = load_128_unaligned (ps); - - if (pm) - { - unpack_128_2x128 (s, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_msk_lo, &xmm_msk_lo, &xmm_msk_hi); - - expand_alpha_2x128 (xmm_msk_lo, xmm_msk_hi, &xmm_msk_lo, &xmm_msk_hi); - - pix_multiply_2x128 (&xmm_src_lo, &xmm_src_hi, - &xmm_msk_lo, &xmm_msk_hi, - &xmm_src_lo, &xmm_src_hi); - - s = pack_2x128_128 (xmm_src_lo, xmm_src_hi); - } - - return s; -} - -static force_inline void -core_combine_over_u_sse2_mask (uint32_t * pd, - const uint32_t* ps, - const uint32_t* pm, - int w) -{ - uint32_t s, d; - - /* Align dst on a 16-byte boundary */ - while (w && ((uintptr_t)pd & 15)) - { - d = *pd; - s = combine1 (ps, pm); - - if (s) - *pd = core_combine_over_u_pixel_sse2 (s, d); - pd++; - ps++; - pm++; - w--; - } - - while (w >= 4) - { - __m128i mask = load_128_unaligned ((__m128i *)pm); - - if (!is_zero (mask)) - { - __m128i src; - __m128i src_hi, src_lo; - __m128i mask_hi, mask_lo; - __m128i alpha_hi, alpha_lo; - - src = load_128_unaligned ((__m128i *)ps); - - if (is_opaque (_mm_and_si128 (src, mask))) - { - save_128_aligned ((__m128i *)pd, src); - } - else - { - __m128i dst = load_128_aligned ((__m128i *)pd); - __m128i dst_hi, dst_lo; - - unpack_128_2x128 (mask, &mask_lo, &mask_hi); - unpack_128_2x128 (src, &src_lo, &src_hi); - - expand_alpha_2x128 (mask_lo, mask_hi, &mask_lo, &mask_hi); - pix_multiply_2x128 (&src_lo, &src_hi, - &mask_lo, &mask_hi, - &src_lo, &src_hi); - - unpack_128_2x128 (dst, &dst_lo, &dst_hi); - - expand_alpha_2x128 (src_lo, src_hi, - &alpha_lo, &alpha_hi); - - over_2x128 (&src_lo, &src_hi, &alpha_lo, &alpha_hi, - &dst_lo, &dst_hi); - - save_128_aligned ( - (__m128i *)pd, - pack_2x128_128 (dst_lo, dst_hi)); - } - } - - pm += 4; - ps += 4; - pd += 4; - w -= 4; - } - while (w) - { - d = *pd; - s = combine1 (ps, pm); - - if (s) - *pd = core_combine_over_u_pixel_sse2 (s, d); - pd++; - ps++; - pm++; - - w--; - } -} - -static force_inline void -core_combine_over_u_sse2_no_mask (uint32_t * pd, - const uint32_t* ps, - int w) -{ - uint32_t s, d; - - /* Align dst on a 16-byte boundary */ - while (w && ((uintptr_t)pd & 15)) - { - d = *pd; - s = *ps; - - if (s) - *pd = core_combine_over_u_pixel_sse2 (s, d); - pd++; - ps++; - w--; - } - - while (w >= 4) - { - __m128i src; - __m128i src_hi, src_lo, dst_hi, dst_lo; - __m128i alpha_hi, alpha_lo; - - src = load_128_unaligned ((__m128i *)ps); - - if (!is_zero (src)) - { - if (is_opaque (src)) - { - save_128_aligned ((__m128i *)pd, src); - } - else - { - __m128i dst = load_128_aligned ((__m128i *)pd); - - unpack_128_2x128 (src, &src_lo, &src_hi); - unpack_128_2x128 (dst, &dst_lo, &dst_hi); - - expand_alpha_2x128 (src_lo, src_hi, - &alpha_lo, &alpha_hi); - over_2x128 (&src_lo, &src_hi, &alpha_lo, &alpha_hi, - &dst_lo, &dst_hi); - - save_128_aligned ( - (__m128i *)pd, - pack_2x128_128 (dst_lo, dst_hi)); - } - } - - ps += 4; - pd += 4; - w -= 4; - } - while (w) - { - d = *pd; - s = *ps; - - if (s) - *pd = core_combine_over_u_pixel_sse2 (s, d); - pd++; - ps++; - - w--; - } -} - -static force_inline void -sse2_combine_over_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * pd, - const uint32_t * ps, - const uint32_t * pm, - int w) -{ - if (pm) - core_combine_over_u_sse2_mask (pd, ps, pm, w); - else - core_combine_over_u_sse2_no_mask (pd, ps, w); -} - -static void -sse2_combine_over_reverse_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * pd, - const uint32_t * ps, - const uint32_t * pm, - int w) -{ - uint32_t s, d; - - __m128i xmm_dst_lo, xmm_dst_hi; - __m128i xmm_src_lo, xmm_src_hi; - __m128i xmm_alpha_lo, xmm_alpha_hi; - - /* Align dst on a 16-byte boundary */ - while (w && - ((uintptr_t)pd & 15)) - { - d = *pd; - s = combine1 (ps, pm); - - *pd++ = core_combine_over_u_pixel_sse2 (d, s); - w--; - ps++; - if (pm) - pm++; - } - - while (w >= 4) - { - /* I'm loading unaligned because I'm not sure - * about the address alignment. - */ - xmm_src_hi = combine4 ((__m128i*)ps, (__m128i*)pm); - xmm_dst_hi = load_128_aligned ((__m128i*) pd); - - unpack_128_2x128 (xmm_src_hi, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_dst_hi, &xmm_dst_lo, &xmm_dst_hi); - - expand_alpha_2x128 (xmm_dst_lo, xmm_dst_hi, - &xmm_alpha_lo, &xmm_alpha_hi); - - over_2x128 (&xmm_dst_lo, &xmm_dst_hi, - &xmm_alpha_lo, &xmm_alpha_hi, - &xmm_src_lo, &xmm_src_hi); - - /* rebuid the 4 pixel data and save*/ - save_128_aligned ((__m128i*)pd, - pack_2x128_128 (xmm_src_lo, xmm_src_hi)); - - w -= 4; - ps += 4; - pd += 4; - - if (pm) - pm += 4; - } - - while (w) - { - d = *pd; - s = combine1 (ps, pm); - - *pd++ = core_combine_over_u_pixel_sse2 (d, s); - ps++; - w--; - if (pm) - pm++; - } -} - -static force_inline uint32_t -core_combine_in_u_pixel_sse2 (uint32_t src, uint32_t dst) -{ - uint32_t maska = src >> 24; - - if (maska == 0) - { - return 0; - } - else if (maska != 0xff) - { - return pack_1x128_32 ( - pix_multiply_1x128 (unpack_32_1x128 (dst), - expand_alpha_1x128 (unpack_32_1x128 (src)))); - } - - return dst; -} - -static void -sse2_combine_in_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * pd, - const uint32_t * ps, - const uint32_t * pm, - int w) -{ - uint32_t s, d; - - __m128i xmm_src_lo, xmm_src_hi; - __m128i xmm_dst_lo, xmm_dst_hi; - - while (w && ((uintptr_t)pd & 15)) - { - s = combine1 (ps, pm); - d = *pd; - - *pd++ = core_combine_in_u_pixel_sse2 (d, s); - w--; - ps++; - if (pm) - pm++; - } - - while (w >= 4) - { - xmm_dst_hi = load_128_aligned ((__m128i*) pd); - xmm_src_hi = combine4 ((__m128i*) ps, (__m128i*) pm); - - unpack_128_2x128 (xmm_dst_hi, &xmm_dst_lo, &xmm_dst_hi); - expand_alpha_2x128 (xmm_dst_lo, xmm_dst_hi, &xmm_dst_lo, &xmm_dst_hi); - - unpack_128_2x128 (xmm_src_hi, &xmm_src_lo, &xmm_src_hi); - pix_multiply_2x128 (&xmm_src_lo, &xmm_src_hi, - &xmm_dst_lo, &xmm_dst_hi, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ((__m128i*)pd, - pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - - ps += 4; - pd += 4; - w -= 4; - if (pm) - pm += 4; - } - - while (w) - { - s = combine1 (ps, pm); - d = *pd; - - *pd++ = core_combine_in_u_pixel_sse2 (d, s); - w--; - ps++; - if (pm) - pm++; - } -} - -static void -sse2_combine_in_reverse_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * pd, - const uint32_t * ps, - const uint32_t * pm, - int w) -{ - uint32_t s, d; - - __m128i xmm_src_lo, xmm_src_hi; - __m128i xmm_dst_lo, xmm_dst_hi; - - while (w && ((uintptr_t)pd & 15)) - { - s = combine1 (ps, pm); - d = *pd; - - *pd++ = core_combine_in_u_pixel_sse2 (s, d); - ps++; - w--; - if (pm) - pm++; - } - - while (w >= 4) - { - xmm_dst_hi = load_128_aligned ((__m128i*) pd); - xmm_src_hi = combine4 ((__m128i*) ps, (__m128i*)pm); - - unpack_128_2x128 (xmm_src_hi, &xmm_src_lo, &xmm_src_hi); - expand_alpha_2x128 (xmm_src_lo, xmm_src_hi, &xmm_src_lo, &xmm_src_hi); - - unpack_128_2x128 (xmm_dst_hi, &xmm_dst_lo, &xmm_dst_hi); - pix_multiply_2x128 (&xmm_dst_lo, &xmm_dst_hi, - &xmm_src_lo, &xmm_src_hi, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ( - (__m128i*)pd, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - - ps += 4; - pd += 4; - w -= 4; - if (pm) - pm += 4; - } - - while (w) - { - s = combine1 (ps, pm); - d = *pd; - - *pd++ = core_combine_in_u_pixel_sse2 (s, d); - w--; - ps++; - if (pm) - pm++; - } -} - -static void -sse2_combine_out_reverse_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * pd, - const uint32_t * ps, - const uint32_t * pm, - int w) -{ - while (w && ((uintptr_t)pd & 15)) - { - uint32_t s = combine1 (ps, pm); - uint32_t d = *pd; - - *pd++ = pack_1x128_32 ( - pix_multiply_1x128 ( - unpack_32_1x128 (d), negate_1x128 ( - expand_alpha_1x128 (unpack_32_1x128 (s))))); - - if (pm) - pm++; - ps++; - w--; - } - - while (w >= 4) - { - __m128i xmm_src_lo, xmm_src_hi; - __m128i xmm_dst_lo, xmm_dst_hi; - - xmm_src_hi = combine4 ((__m128i*)ps, (__m128i*)pm); - xmm_dst_hi = load_128_aligned ((__m128i*) pd); - - unpack_128_2x128 (xmm_src_hi, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_dst_hi, &xmm_dst_lo, &xmm_dst_hi); - - expand_alpha_2x128 (xmm_src_lo, xmm_src_hi, &xmm_src_lo, &xmm_src_hi); - negate_2x128 (xmm_src_lo, xmm_src_hi, &xmm_src_lo, &xmm_src_hi); - - pix_multiply_2x128 (&xmm_dst_lo, &xmm_dst_hi, - &xmm_src_lo, &xmm_src_hi, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ( - (__m128i*)pd, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - - ps += 4; - pd += 4; - if (pm) - pm += 4; - - w -= 4; - } - - while (w) - { - uint32_t s = combine1 (ps, pm); - uint32_t d = *pd; - - *pd++ = pack_1x128_32 ( - pix_multiply_1x128 ( - unpack_32_1x128 (d), negate_1x128 ( - expand_alpha_1x128 (unpack_32_1x128 (s))))); - ps++; - if (pm) - pm++; - w--; - } -} - -static void -sse2_combine_out_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * pd, - const uint32_t * ps, - const uint32_t * pm, - int w) -{ - while (w && ((uintptr_t)pd & 15)) - { - uint32_t s = combine1 (ps, pm); - uint32_t d = *pd; - - *pd++ = pack_1x128_32 ( - pix_multiply_1x128 ( - unpack_32_1x128 (s), negate_1x128 ( - expand_alpha_1x128 (unpack_32_1x128 (d))))); - w--; - ps++; - if (pm) - pm++; - } - - while (w >= 4) - { - __m128i xmm_src_lo, xmm_src_hi; - __m128i xmm_dst_lo, xmm_dst_hi; - - xmm_src_hi = combine4 ((__m128i*) ps, (__m128i*)pm); - xmm_dst_hi = load_128_aligned ((__m128i*) pd); - - unpack_128_2x128 (xmm_src_hi, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_dst_hi, &xmm_dst_lo, &xmm_dst_hi); - - expand_alpha_2x128 (xmm_dst_lo, xmm_dst_hi, &xmm_dst_lo, &xmm_dst_hi); - negate_2x128 (xmm_dst_lo, xmm_dst_hi, &xmm_dst_lo, &xmm_dst_hi); - - pix_multiply_2x128 (&xmm_src_lo, &xmm_src_hi, - &xmm_dst_lo, &xmm_dst_hi, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ( - (__m128i*)pd, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - - ps += 4; - pd += 4; - w -= 4; - if (pm) - pm += 4; - } - - while (w) - { - uint32_t s = combine1 (ps, pm); - uint32_t d = *pd; - - *pd++ = pack_1x128_32 ( - pix_multiply_1x128 ( - unpack_32_1x128 (s), negate_1x128 ( - expand_alpha_1x128 (unpack_32_1x128 (d))))); - w--; - ps++; - if (pm) - pm++; - } -} - -static force_inline uint32_t -core_combine_atop_u_pixel_sse2 (uint32_t src, - uint32_t dst) -{ - __m128i s = unpack_32_1x128 (src); - __m128i d = unpack_32_1x128 (dst); - - __m128i sa = negate_1x128 (expand_alpha_1x128 (s)); - __m128i da = expand_alpha_1x128 (d); - - return pack_1x128_32 (pix_add_multiply_1x128 (&s, &da, &d, &sa)); -} - -static void -sse2_combine_atop_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * pd, - const uint32_t * ps, - const uint32_t * pm, - int w) -{ - uint32_t s, d; - - __m128i xmm_src_lo, xmm_src_hi; - __m128i xmm_dst_lo, xmm_dst_hi; - __m128i xmm_alpha_src_lo, xmm_alpha_src_hi; - __m128i xmm_alpha_dst_lo, xmm_alpha_dst_hi; - - while (w && ((uintptr_t)pd & 15)) - { - s = combine1 (ps, pm); - d = *pd; - - *pd++ = core_combine_atop_u_pixel_sse2 (s, d); - w--; - ps++; - if (pm) - pm++; - } - - while (w >= 4) - { - xmm_src_hi = combine4 ((__m128i*)ps, (__m128i*)pm); - xmm_dst_hi = load_128_aligned ((__m128i*) pd); - - unpack_128_2x128 (xmm_src_hi, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_dst_hi, &xmm_dst_lo, &xmm_dst_hi); - - expand_alpha_2x128 (xmm_src_lo, xmm_src_hi, - &xmm_alpha_src_lo, &xmm_alpha_src_hi); - expand_alpha_2x128 (xmm_dst_lo, xmm_dst_hi, - &xmm_alpha_dst_lo, &xmm_alpha_dst_hi); - - negate_2x128 (xmm_alpha_src_lo, xmm_alpha_src_hi, - &xmm_alpha_src_lo, &xmm_alpha_src_hi); - - pix_add_multiply_2x128 ( - &xmm_src_lo, &xmm_src_hi, &xmm_alpha_dst_lo, &xmm_alpha_dst_hi, - &xmm_dst_lo, &xmm_dst_hi, &xmm_alpha_src_lo, &xmm_alpha_src_hi, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ( - (__m128i*)pd, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - - ps += 4; - pd += 4; - w -= 4; - if (pm) - pm += 4; - } - - while (w) - { - s = combine1 (ps, pm); - d = *pd; - - *pd++ = core_combine_atop_u_pixel_sse2 (s, d); - w--; - ps++; - if (pm) - pm++; - } -} - -static force_inline uint32_t -core_combine_reverse_atop_u_pixel_sse2 (uint32_t src, - uint32_t dst) -{ - __m128i s = unpack_32_1x128 (src); - __m128i d = unpack_32_1x128 (dst); - - __m128i sa = expand_alpha_1x128 (s); - __m128i da = negate_1x128 (expand_alpha_1x128 (d)); - - return pack_1x128_32 (pix_add_multiply_1x128 (&s, &da, &d, &sa)); -} - -static void -sse2_combine_atop_reverse_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * pd, - const uint32_t * ps, - const uint32_t * pm, - int w) -{ - uint32_t s, d; - - __m128i xmm_src_lo, xmm_src_hi; - __m128i xmm_dst_lo, xmm_dst_hi; - __m128i xmm_alpha_src_lo, xmm_alpha_src_hi; - __m128i xmm_alpha_dst_lo, xmm_alpha_dst_hi; - - while (w && ((uintptr_t)pd & 15)) - { - s = combine1 (ps, pm); - d = *pd; - - *pd++ = core_combine_reverse_atop_u_pixel_sse2 (s, d); - ps++; - w--; - if (pm) - pm++; - } - - while (w >= 4) - { - xmm_src_hi = combine4 ((__m128i*)ps, (__m128i*)pm); - xmm_dst_hi = load_128_aligned ((__m128i*) pd); - - unpack_128_2x128 (xmm_src_hi, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_dst_hi, &xmm_dst_lo, &xmm_dst_hi); - - expand_alpha_2x128 (xmm_src_lo, xmm_src_hi, - &xmm_alpha_src_lo, &xmm_alpha_src_hi); - expand_alpha_2x128 (xmm_dst_lo, xmm_dst_hi, - &xmm_alpha_dst_lo, &xmm_alpha_dst_hi); - - negate_2x128 (xmm_alpha_dst_lo, xmm_alpha_dst_hi, - &xmm_alpha_dst_lo, &xmm_alpha_dst_hi); - - pix_add_multiply_2x128 ( - &xmm_src_lo, &xmm_src_hi, &xmm_alpha_dst_lo, &xmm_alpha_dst_hi, - &xmm_dst_lo, &xmm_dst_hi, &xmm_alpha_src_lo, &xmm_alpha_src_hi, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ( - (__m128i*)pd, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - - ps += 4; - pd += 4; - w -= 4; - if (pm) - pm += 4; - } - - while (w) - { - s = combine1 (ps, pm); - d = *pd; - - *pd++ = core_combine_reverse_atop_u_pixel_sse2 (s, d); - ps++; - w--; - if (pm) - pm++; - } -} - -static force_inline uint32_t -core_combine_xor_u_pixel_sse2 (uint32_t src, - uint32_t dst) -{ - __m128i s = unpack_32_1x128 (src); - __m128i d = unpack_32_1x128 (dst); - - __m128i neg_d = negate_1x128 (expand_alpha_1x128 (d)); - __m128i neg_s = negate_1x128 (expand_alpha_1x128 (s)); - - return pack_1x128_32 (pix_add_multiply_1x128 (&s, &neg_d, &d, &neg_s)); -} - -static void -sse2_combine_xor_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dst, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int w = width; - uint32_t s, d; - uint32_t* pd = dst; - const uint32_t* ps = src; - const uint32_t* pm = mask; - - __m128i xmm_src, xmm_src_lo, xmm_src_hi; - __m128i xmm_dst, xmm_dst_lo, xmm_dst_hi; - __m128i xmm_alpha_src_lo, xmm_alpha_src_hi; - __m128i xmm_alpha_dst_lo, xmm_alpha_dst_hi; - - while (w && ((uintptr_t)pd & 15)) - { - s = combine1 (ps, pm); - d = *pd; - - *pd++ = core_combine_xor_u_pixel_sse2 (s, d); - w--; - ps++; - if (pm) - pm++; - } - - while (w >= 4) - { - xmm_src = combine4 ((__m128i*) ps, (__m128i*) pm); - xmm_dst = load_128_aligned ((__m128i*) pd); - - unpack_128_2x128 (xmm_src, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_dst, &xmm_dst_lo, &xmm_dst_hi); - - expand_alpha_2x128 (xmm_src_lo, xmm_src_hi, - &xmm_alpha_src_lo, &xmm_alpha_src_hi); - expand_alpha_2x128 (xmm_dst_lo, xmm_dst_hi, - &xmm_alpha_dst_lo, &xmm_alpha_dst_hi); - - negate_2x128 (xmm_alpha_src_lo, xmm_alpha_src_hi, - &xmm_alpha_src_lo, &xmm_alpha_src_hi); - negate_2x128 (xmm_alpha_dst_lo, xmm_alpha_dst_hi, - &xmm_alpha_dst_lo, &xmm_alpha_dst_hi); - - pix_add_multiply_2x128 ( - &xmm_src_lo, &xmm_src_hi, &xmm_alpha_dst_lo, &xmm_alpha_dst_hi, - &xmm_dst_lo, &xmm_dst_hi, &xmm_alpha_src_lo, &xmm_alpha_src_hi, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ( - (__m128i*)pd, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - - ps += 4; - pd += 4; - w -= 4; - if (pm) - pm += 4; - } - - while (w) - { - s = combine1 (ps, pm); - d = *pd; - - *pd++ = core_combine_xor_u_pixel_sse2 (s, d); - w--; - ps++; - if (pm) - pm++; - } -} - -static force_inline void -sse2_combine_add_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dst, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int w = width; - uint32_t s, d; - uint32_t* pd = dst; - const uint32_t* ps = src; - const uint32_t* pm = mask; - - while (w && (uintptr_t)pd & 15) - { - s = combine1 (ps, pm); - d = *pd; - - ps++; - if (pm) - pm++; - *pd++ = _mm_cvtsi128_si32 ( - _mm_adds_epu8 (_mm_cvtsi32_si128 (s), _mm_cvtsi32_si128 (d))); - w--; - } - - while (w >= 4) - { - __m128i s; - - s = combine4 ((__m128i*)ps, (__m128i*)pm); - - save_128_aligned ( - (__m128i*)pd, _mm_adds_epu8 (s, load_128_aligned ((__m128i*)pd))); - - pd += 4; - ps += 4; - if (pm) - pm += 4; - w -= 4; - } - - while (w--) - { - s = combine1 (ps, pm); - d = *pd; - - ps++; - *pd++ = _mm_cvtsi128_si32 ( - _mm_adds_epu8 (_mm_cvtsi32_si128 (s), _mm_cvtsi32_si128 (d))); - if (pm) - pm++; - } -} - -static force_inline uint32_t -core_combine_saturate_u_pixel_sse2 (uint32_t src, - uint32_t dst) -{ - __m128i ms = unpack_32_1x128 (src); - __m128i md = unpack_32_1x128 (dst); - uint32_t sa = src >> 24; - uint32_t da = ~dst >> 24; - - if (sa > da) - { - ms = pix_multiply_1x128 ( - ms, expand_alpha_1x128 (unpack_32_1x128 (DIV_UN8 (da, sa) << 24))); - } - - return pack_1x128_32 (_mm_adds_epu16 (md, ms)); -} - -static void -sse2_combine_saturate_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * pd, - const uint32_t * ps, - const uint32_t * pm, - int w) -{ - uint32_t s, d; - - uint32_t pack_cmp; - __m128i xmm_src, xmm_dst; - - while (w && (uintptr_t)pd & 15) - { - s = combine1 (ps, pm); - d = *pd; - - *pd++ = core_combine_saturate_u_pixel_sse2 (s, d); - w--; - ps++; - if (pm) - pm++; - } - - while (w >= 4) - { - xmm_dst = load_128_aligned ((__m128i*)pd); - xmm_src = combine4 ((__m128i*)ps, (__m128i*)pm); - - pack_cmp = _mm_movemask_epi8 ( - _mm_cmpgt_epi32 ( - _mm_srli_epi32 (xmm_src, 24), - _mm_srli_epi32 (_mm_xor_si128 (xmm_dst, mask_ff000000), 24))); - - /* if some alpha src is grater than respective ~alpha dst */ - if (pack_cmp) - { - s = combine1 (ps++, pm); - d = *pd; - *pd++ = core_combine_saturate_u_pixel_sse2 (s, d); - if (pm) - pm++; - - s = combine1 (ps++, pm); - d = *pd; - *pd++ = core_combine_saturate_u_pixel_sse2 (s, d); - if (pm) - pm++; - - s = combine1 (ps++, pm); - d = *pd; - *pd++ = core_combine_saturate_u_pixel_sse2 (s, d); - if (pm) - pm++; - - s = combine1 (ps++, pm); - d = *pd; - *pd++ = core_combine_saturate_u_pixel_sse2 (s, d); - if (pm) - pm++; - } - else - { - save_128_aligned ((__m128i*)pd, _mm_adds_epu8 (xmm_dst, xmm_src)); - - pd += 4; - ps += 4; - if (pm) - pm += 4; - } - - w -= 4; - } - - while (w--) - { - s = combine1 (ps, pm); - d = *pd; - - *pd++ = core_combine_saturate_u_pixel_sse2 (s, d); - ps++; - if (pm) - pm++; - } -} - -static void -sse2_combine_src_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * pd, - const uint32_t * ps, - const uint32_t * pm, - int w) -{ - uint32_t s, m; - - __m128i xmm_src_lo, xmm_src_hi; - __m128i xmm_mask_lo, xmm_mask_hi; - __m128i xmm_dst_lo, xmm_dst_hi; - - while (w && (uintptr_t)pd & 15) - { - s = *ps++; - m = *pm++; - *pd++ = pack_1x128_32 ( - pix_multiply_1x128 (unpack_32_1x128 (s), unpack_32_1x128 (m))); - w--; - } - - while (w >= 4) - { - xmm_src_hi = load_128_unaligned ((__m128i*)ps); - xmm_mask_hi = load_128_unaligned ((__m128i*)pm); - - unpack_128_2x128 (xmm_src_hi, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_mask_hi, &xmm_mask_lo, &xmm_mask_hi); - - pix_multiply_2x128 (&xmm_src_lo, &xmm_src_hi, - &xmm_mask_lo, &xmm_mask_hi, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ( - (__m128i*)pd, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - - ps += 4; - pd += 4; - pm += 4; - w -= 4; - } - - while (w) - { - s = *ps++; - m = *pm++; - *pd++ = pack_1x128_32 ( - pix_multiply_1x128 (unpack_32_1x128 (s), unpack_32_1x128 (m))); - w--; - } -} - -static force_inline uint32_t -core_combine_over_ca_pixel_sse2 (uint32_t src, - uint32_t mask, - uint32_t dst) -{ - __m128i s = unpack_32_1x128 (src); - __m128i expAlpha = expand_alpha_1x128 (s); - __m128i unpk_mask = unpack_32_1x128 (mask); - __m128i unpk_dst = unpack_32_1x128 (dst); - - return pack_1x128_32 (in_over_1x128 (&s, &expAlpha, &unpk_mask, &unpk_dst)); -} - -static void -sse2_combine_over_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * pd, - const uint32_t * ps, - const uint32_t * pm, - int w) -{ - uint32_t s, m, d; - - __m128i xmm_alpha_lo, xmm_alpha_hi; - __m128i xmm_src_lo, xmm_src_hi; - __m128i xmm_dst_lo, xmm_dst_hi; - __m128i xmm_mask_lo, xmm_mask_hi; - - while (w && (uintptr_t)pd & 15) - { - s = *ps++; - m = *pm++; - d = *pd; - - *pd++ = core_combine_over_ca_pixel_sse2 (s, m, d); - w--; - } - - while (w >= 4) - { - xmm_dst_hi = load_128_aligned ((__m128i*)pd); - xmm_src_hi = load_128_unaligned ((__m128i*)ps); - xmm_mask_hi = load_128_unaligned ((__m128i*)pm); - - unpack_128_2x128 (xmm_dst_hi, &xmm_dst_lo, &xmm_dst_hi); - unpack_128_2x128 (xmm_src_hi, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_mask_hi, &xmm_mask_lo, &xmm_mask_hi); - - expand_alpha_2x128 (xmm_src_lo, xmm_src_hi, - &xmm_alpha_lo, &xmm_alpha_hi); - - in_over_2x128 (&xmm_src_lo, &xmm_src_hi, - &xmm_alpha_lo, &xmm_alpha_hi, - &xmm_mask_lo, &xmm_mask_hi, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ( - (__m128i*)pd, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - - ps += 4; - pd += 4; - pm += 4; - w -= 4; - } - - while (w) - { - s = *ps++; - m = *pm++; - d = *pd; - - *pd++ = core_combine_over_ca_pixel_sse2 (s, m, d); - w--; - } -} - -static force_inline uint32_t -core_combine_over_reverse_ca_pixel_sse2 (uint32_t src, - uint32_t mask, - uint32_t dst) -{ - __m128i d = unpack_32_1x128 (dst); - - return pack_1x128_32 ( - over_1x128 (d, expand_alpha_1x128 (d), - pix_multiply_1x128 (unpack_32_1x128 (src), - unpack_32_1x128 (mask)))); -} - -static void -sse2_combine_over_reverse_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * pd, - const uint32_t * ps, - const uint32_t * pm, - int w) -{ - uint32_t s, m, d; - - __m128i xmm_alpha_lo, xmm_alpha_hi; - __m128i xmm_src_lo, xmm_src_hi; - __m128i xmm_dst_lo, xmm_dst_hi; - __m128i xmm_mask_lo, xmm_mask_hi; - - while (w && (uintptr_t)pd & 15) - { - s = *ps++; - m = *pm++; - d = *pd; - - *pd++ = core_combine_over_reverse_ca_pixel_sse2 (s, m, d); - w--; - } - - while (w >= 4) - { - xmm_dst_hi = load_128_aligned ((__m128i*)pd); - xmm_src_hi = load_128_unaligned ((__m128i*)ps); - xmm_mask_hi = load_128_unaligned ((__m128i*)pm); - - unpack_128_2x128 (xmm_dst_hi, &xmm_dst_lo, &xmm_dst_hi); - unpack_128_2x128 (xmm_src_hi, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_mask_hi, &xmm_mask_lo, &xmm_mask_hi); - - expand_alpha_2x128 (xmm_dst_lo, xmm_dst_hi, - &xmm_alpha_lo, &xmm_alpha_hi); - pix_multiply_2x128 (&xmm_src_lo, &xmm_src_hi, - &xmm_mask_lo, &xmm_mask_hi, - &xmm_mask_lo, &xmm_mask_hi); - - over_2x128 (&xmm_dst_lo, &xmm_dst_hi, - &xmm_alpha_lo, &xmm_alpha_hi, - &xmm_mask_lo, &xmm_mask_hi); - - save_128_aligned ( - (__m128i*)pd, pack_2x128_128 (xmm_mask_lo, xmm_mask_hi)); - - ps += 4; - pd += 4; - pm += 4; - w -= 4; - } - - while (w) - { - s = *ps++; - m = *pm++; - d = *pd; - - *pd++ = core_combine_over_reverse_ca_pixel_sse2 (s, m, d); - w--; - } -} - -static void -sse2_combine_in_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * pd, - const uint32_t * ps, - const uint32_t * pm, - int w) -{ - uint32_t s, m, d; - - __m128i xmm_alpha_lo, xmm_alpha_hi; - __m128i xmm_src_lo, xmm_src_hi; - __m128i xmm_dst_lo, xmm_dst_hi; - __m128i xmm_mask_lo, xmm_mask_hi; - - while (w && (uintptr_t)pd & 15) - { - s = *ps++; - m = *pm++; - d = *pd; - - *pd++ = pack_1x128_32 ( - pix_multiply_1x128 ( - pix_multiply_1x128 (unpack_32_1x128 (s), unpack_32_1x128 (m)), - expand_alpha_1x128 (unpack_32_1x128 (d)))); - - w--; - } - - while (w >= 4) - { - xmm_dst_hi = load_128_aligned ((__m128i*)pd); - xmm_src_hi = load_128_unaligned ((__m128i*)ps); - xmm_mask_hi = load_128_unaligned ((__m128i*)pm); - - unpack_128_2x128 (xmm_dst_hi, &xmm_dst_lo, &xmm_dst_hi); - unpack_128_2x128 (xmm_src_hi, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_mask_hi, &xmm_mask_lo, &xmm_mask_hi); - - expand_alpha_2x128 (xmm_dst_lo, xmm_dst_hi, - &xmm_alpha_lo, &xmm_alpha_hi); - - pix_multiply_2x128 (&xmm_src_lo, &xmm_src_hi, - &xmm_mask_lo, &xmm_mask_hi, - &xmm_dst_lo, &xmm_dst_hi); - - pix_multiply_2x128 (&xmm_dst_lo, &xmm_dst_hi, - &xmm_alpha_lo, &xmm_alpha_hi, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ( - (__m128i*)pd, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - - ps += 4; - pd += 4; - pm += 4; - w -= 4; - } - - while (w) - { - s = *ps++; - m = *pm++; - d = *pd; - - *pd++ = pack_1x128_32 ( - pix_multiply_1x128 ( - pix_multiply_1x128 ( - unpack_32_1x128 (s), unpack_32_1x128 (m)), - expand_alpha_1x128 (unpack_32_1x128 (d)))); - - w--; - } -} - -static void -sse2_combine_in_reverse_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * pd, - const uint32_t * ps, - const uint32_t * pm, - int w) -{ - uint32_t s, m, d; - - __m128i xmm_alpha_lo, xmm_alpha_hi; - __m128i xmm_src_lo, xmm_src_hi; - __m128i xmm_dst_lo, xmm_dst_hi; - __m128i xmm_mask_lo, xmm_mask_hi; - - while (w && (uintptr_t)pd & 15) - { - s = *ps++; - m = *pm++; - d = *pd; - - *pd++ = pack_1x128_32 ( - pix_multiply_1x128 ( - unpack_32_1x128 (d), - pix_multiply_1x128 (unpack_32_1x128 (m), - expand_alpha_1x128 (unpack_32_1x128 (s))))); - w--; - } - - while (w >= 4) - { - xmm_dst_hi = load_128_aligned ((__m128i*)pd); - xmm_src_hi = load_128_unaligned ((__m128i*)ps); - xmm_mask_hi = load_128_unaligned ((__m128i*)pm); - - unpack_128_2x128 (xmm_dst_hi, &xmm_dst_lo, &xmm_dst_hi); - unpack_128_2x128 (xmm_src_hi, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_mask_hi, &xmm_mask_lo, &xmm_mask_hi); - - expand_alpha_2x128 (xmm_src_lo, xmm_src_hi, - &xmm_alpha_lo, &xmm_alpha_hi); - pix_multiply_2x128 (&xmm_mask_lo, &xmm_mask_hi, - &xmm_alpha_lo, &xmm_alpha_hi, - &xmm_alpha_lo, &xmm_alpha_hi); - - pix_multiply_2x128 (&xmm_dst_lo, &xmm_dst_hi, - &xmm_alpha_lo, &xmm_alpha_hi, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ( - (__m128i*)pd, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - - ps += 4; - pd += 4; - pm += 4; - w -= 4; - } - - while (w) - { - s = *ps++; - m = *pm++; - d = *pd; - - *pd++ = pack_1x128_32 ( - pix_multiply_1x128 ( - unpack_32_1x128 (d), - pix_multiply_1x128 (unpack_32_1x128 (m), - expand_alpha_1x128 (unpack_32_1x128 (s))))); - w--; - } -} - -static void -sse2_combine_out_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * pd, - const uint32_t * ps, - const uint32_t * pm, - int w) -{ - uint32_t s, m, d; - - __m128i xmm_alpha_lo, xmm_alpha_hi; - __m128i xmm_src_lo, xmm_src_hi; - __m128i xmm_dst_lo, xmm_dst_hi; - __m128i xmm_mask_lo, xmm_mask_hi; - - while (w && (uintptr_t)pd & 15) - { - s = *ps++; - m = *pm++; - d = *pd; - - *pd++ = pack_1x128_32 ( - pix_multiply_1x128 ( - pix_multiply_1x128 ( - unpack_32_1x128 (s), unpack_32_1x128 (m)), - negate_1x128 (expand_alpha_1x128 (unpack_32_1x128 (d))))); - w--; - } - - while (w >= 4) - { - xmm_dst_hi = load_128_aligned ((__m128i*)pd); - xmm_src_hi = load_128_unaligned ((__m128i*)ps); - xmm_mask_hi = load_128_unaligned ((__m128i*)pm); - - unpack_128_2x128 (xmm_dst_hi, &xmm_dst_lo, &xmm_dst_hi); - unpack_128_2x128 (xmm_src_hi, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_mask_hi, &xmm_mask_lo, &xmm_mask_hi); - - expand_alpha_2x128 (xmm_dst_lo, xmm_dst_hi, - &xmm_alpha_lo, &xmm_alpha_hi); - negate_2x128 (xmm_alpha_lo, xmm_alpha_hi, - &xmm_alpha_lo, &xmm_alpha_hi); - - pix_multiply_2x128 (&xmm_src_lo, &xmm_src_hi, - &xmm_mask_lo, &xmm_mask_hi, - &xmm_dst_lo, &xmm_dst_hi); - pix_multiply_2x128 (&xmm_dst_lo, &xmm_dst_hi, - &xmm_alpha_lo, &xmm_alpha_hi, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ( - (__m128i*)pd, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - - ps += 4; - pd += 4; - pm += 4; - w -= 4; - } - - while (w) - { - s = *ps++; - m = *pm++; - d = *pd; - - *pd++ = pack_1x128_32 ( - pix_multiply_1x128 ( - pix_multiply_1x128 ( - unpack_32_1x128 (s), unpack_32_1x128 (m)), - negate_1x128 (expand_alpha_1x128 (unpack_32_1x128 (d))))); - - w--; - } -} - -static void -sse2_combine_out_reverse_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * pd, - const uint32_t * ps, - const uint32_t * pm, - int w) -{ - uint32_t s, m, d; - - __m128i xmm_alpha_lo, xmm_alpha_hi; - __m128i xmm_src_lo, xmm_src_hi; - __m128i xmm_dst_lo, xmm_dst_hi; - __m128i xmm_mask_lo, xmm_mask_hi; - - while (w && (uintptr_t)pd & 15) - { - s = *ps++; - m = *pm++; - d = *pd; - - *pd++ = pack_1x128_32 ( - pix_multiply_1x128 ( - unpack_32_1x128 (d), - negate_1x128 (pix_multiply_1x128 ( - unpack_32_1x128 (m), - expand_alpha_1x128 (unpack_32_1x128 (s)))))); - w--; - } - - while (w >= 4) - { - xmm_dst_hi = load_128_aligned ((__m128i*)pd); - xmm_src_hi = load_128_unaligned ((__m128i*)ps); - xmm_mask_hi = load_128_unaligned ((__m128i*)pm); - - unpack_128_2x128 (xmm_dst_hi, &xmm_dst_lo, &xmm_dst_hi); - unpack_128_2x128 (xmm_src_hi, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_mask_hi, &xmm_mask_lo, &xmm_mask_hi); - - expand_alpha_2x128 (xmm_src_lo, xmm_src_hi, - &xmm_alpha_lo, &xmm_alpha_hi); - - pix_multiply_2x128 (&xmm_mask_lo, &xmm_mask_hi, - &xmm_alpha_lo, &xmm_alpha_hi, - &xmm_mask_lo, &xmm_mask_hi); - - negate_2x128 (xmm_mask_lo, xmm_mask_hi, - &xmm_mask_lo, &xmm_mask_hi); - - pix_multiply_2x128 (&xmm_dst_lo, &xmm_dst_hi, - &xmm_mask_lo, &xmm_mask_hi, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ( - (__m128i*)pd, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - - ps += 4; - pd += 4; - pm += 4; - w -= 4; - } - - while (w) - { - s = *ps++; - m = *pm++; - d = *pd; - - *pd++ = pack_1x128_32 ( - pix_multiply_1x128 ( - unpack_32_1x128 (d), - negate_1x128 (pix_multiply_1x128 ( - unpack_32_1x128 (m), - expand_alpha_1x128 (unpack_32_1x128 (s)))))); - w--; - } -} - -static force_inline uint32_t -core_combine_atop_ca_pixel_sse2 (uint32_t src, - uint32_t mask, - uint32_t dst) -{ - __m128i m = unpack_32_1x128 (mask); - __m128i s = unpack_32_1x128 (src); - __m128i d = unpack_32_1x128 (dst); - __m128i sa = expand_alpha_1x128 (s); - __m128i da = expand_alpha_1x128 (d); - - s = pix_multiply_1x128 (s, m); - m = negate_1x128 (pix_multiply_1x128 (m, sa)); - - return pack_1x128_32 (pix_add_multiply_1x128 (&d, &m, &s, &da)); -} - -static void -sse2_combine_atop_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * pd, - const uint32_t * ps, - const uint32_t * pm, - int w) -{ - uint32_t s, m, d; - - __m128i xmm_src_lo, xmm_src_hi; - __m128i xmm_dst_lo, xmm_dst_hi; - __m128i xmm_alpha_src_lo, xmm_alpha_src_hi; - __m128i xmm_alpha_dst_lo, xmm_alpha_dst_hi; - __m128i xmm_mask_lo, xmm_mask_hi; - - while (w && (uintptr_t)pd & 15) - { - s = *ps++; - m = *pm++; - d = *pd; - - *pd++ = core_combine_atop_ca_pixel_sse2 (s, m, d); - w--; - } - - while (w >= 4) - { - xmm_dst_hi = load_128_aligned ((__m128i*)pd); - xmm_src_hi = load_128_unaligned ((__m128i*)ps); - xmm_mask_hi = load_128_unaligned ((__m128i*)pm); - - unpack_128_2x128 (xmm_dst_hi, &xmm_dst_lo, &xmm_dst_hi); - unpack_128_2x128 (xmm_src_hi, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_mask_hi, &xmm_mask_lo, &xmm_mask_hi); - - expand_alpha_2x128 (xmm_src_lo, xmm_src_hi, - &xmm_alpha_src_lo, &xmm_alpha_src_hi); - expand_alpha_2x128 (xmm_dst_lo, xmm_dst_hi, - &xmm_alpha_dst_lo, &xmm_alpha_dst_hi); - - pix_multiply_2x128 (&xmm_src_lo, &xmm_src_hi, - &xmm_mask_lo, &xmm_mask_hi, - &xmm_src_lo, &xmm_src_hi); - pix_multiply_2x128 (&xmm_mask_lo, &xmm_mask_hi, - &xmm_alpha_src_lo, &xmm_alpha_src_hi, - &xmm_mask_lo, &xmm_mask_hi); - - negate_2x128 (xmm_mask_lo, xmm_mask_hi, &xmm_mask_lo, &xmm_mask_hi); - - pix_add_multiply_2x128 ( - &xmm_dst_lo, &xmm_dst_hi, &xmm_mask_lo, &xmm_mask_hi, - &xmm_src_lo, &xmm_src_hi, &xmm_alpha_dst_lo, &xmm_alpha_dst_hi, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ( - (__m128i*)pd, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - - ps += 4; - pd += 4; - pm += 4; - w -= 4; - } - - while (w) - { - s = *ps++; - m = *pm++; - d = *pd; - - *pd++ = core_combine_atop_ca_pixel_sse2 (s, m, d); - w--; - } -} - -static force_inline uint32_t -core_combine_reverse_atop_ca_pixel_sse2 (uint32_t src, - uint32_t mask, - uint32_t dst) -{ - __m128i m = unpack_32_1x128 (mask); - __m128i s = unpack_32_1x128 (src); - __m128i d = unpack_32_1x128 (dst); - - __m128i da = negate_1x128 (expand_alpha_1x128 (d)); - __m128i sa = expand_alpha_1x128 (s); - - s = pix_multiply_1x128 (s, m); - m = pix_multiply_1x128 (m, sa); - - return pack_1x128_32 (pix_add_multiply_1x128 (&d, &m, &s, &da)); -} - -static void -sse2_combine_atop_reverse_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * pd, - const uint32_t * ps, - const uint32_t * pm, - int w) -{ - uint32_t s, m, d; - - __m128i xmm_src_lo, xmm_src_hi; - __m128i xmm_dst_lo, xmm_dst_hi; - __m128i xmm_alpha_src_lo, xmm_alpha_src_hi; - __m128i xmm_alpha_dst_lo, xmm_alpha_dst_hi; - __m128i xmm_mask_lo, xmm_mask_hi; - - while (w && (uintptr_t)pd & 15) - { - s = *ps++; - m = *pm++; - d = *pd; - - *pd++ = core_combine_reverse_atop_ca_pixel_sse2 (s, m, d); - w--; - } - - while (w >= 4) - { - xmm_dst_hi = load_128_aligned ((__m128i*)pd); - xmm_src_hi = load_128_unaligned ((__m128i*)ps); - xmm_mask_hi = load_128_unaligned ((__m128i*)pm); - - unpack_128_2x128 (xmm_dst_hi, &xmm_dst_lo, &xmm_dst_hi); - unpack_128_2x128 (xmm_src_hi, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_mask_hi, &xmm_mask_lo, &xmm_mask_hi); - - expand_alpha_2x128 (xmm_src_lo, xmm_src_hi, - &xmm_alpha_src_lo, &xmm_alpha_src_hi); - expand_alpha_2x128 (xmm_dst_lo, xmm_dst_hi, - &xmm_alpha_dst_lo, &xmm_alpha_dst_hi); - - pix_multiply_2x128 (&xmm_src_lo, &xmm_src_hi, - &xmm_mask_lo, &xmm_mask_hi, - &xmm_src_lo, &xmm_src_hi); - pix_multiply_2x128 (&xmm_mask_lo, &xmm_mask_hi, - &xmm_alpha_src_lo, &xmm_alpha_src_hi, - &xmm_mask_lo, &xmm_mask_hi); - - negate_2x128 (xmm_alpha_dst_lo, xmm_alpha_dst_hi, - &xmm_alpha_dst_lo, &xmm_alpha_dst_hi); - - pix_add_multiply_2x128 ( - &xmm_dst_lo, &xmm_dst_hi, &xmm_mask_lo, &xmm_mask_hi, - &xmm_src_lo, &xmm_src_hi, &xmm_alpha_dst_lo, &xmm_alpha_dst_hi, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ( - (__m128i*)pd, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - - ps += 4; - pd += 4; - pm += 4; - w -= 4; - } - - while (w) - { - s = *ps++; - m = *pm++; - d = *pd; - - *pd++ = core_combine_reverse_atop_ca_pixel_sse2 (s, m, d); - w--; - } -} - -static force_inline uint32_t -core_combine_xor_ca_pixel_sse2 (uint32_t src, - uint32_t mask, - uint32_t dst) -{ - __m128i a = unpack_32_1x128 (mask); - __m128i s = unpack_32_1x128 (src); - __m128i d = unpack_32_1x128 (dst); - - __m128i alpha_dst = negate_1x128 (pix_multiply_1x128 ( - a, expand_alpha_1x128 (s))); - __m128i dest = pix_multiply_1x128 (s, a); - __m128i alpha_src = negate_1x128 (expand_alpha_1x128 (d)); - - return pack_1x128_32 (pix_add_multiply_1x128 (&d, - &alpha_dst, - &dest, - &alpha_src)); -} - -static void -sse2_combine_xor_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * pd, - const uint32_t * ps, - const uint32_t * pm, - int w) -{ - uint32_t s, m, d; - - __m128i xmm_src_lo, xmm_src_hi; - __m128i xmm_dst_lo, xmm_dst_hi; - __m128i xmm_alpha_src_lo, xmm_alpha_src_hi; - __m128i xmm_alpha_dst_lo, xmm_alpha_dst_hi; - __m128i xmm_mask_lo, xmm_mask_hi; - - while (w && (uintptr_t)pd & 15) - { - s = *ps++; - m = *pm++; - d = *pd; - - *pd++ = core_combine_xor_ca_pixel_sse2 (s, m, d); - w--; - } - - while (w >= 4) - { - xmm_dst_hi = load_128_aligned ((__m128i*)pd); - xmm_src_hi = load_128_unaligned ((__m128i*)ps); - xmm_mask_hi = load_128_unaligned ((__m128i*)pm); - - unpack_128_2x128 (xmm_dst_hi, &xmm_dst_lo, &xmm_dst_hi); - unpack_128_2x128 (xmm_src_hi, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_mask_hi, &xmm_mask_lo, &xmm_mask_hi); - - expand_alpha_2x128 (xmm_src_lo, xmm_src_hi, - &xmm_alpha_src_lo, &xmm_alpha_src_hi); - expand_alpha_2x128 (xmm_dst_lo, xmm_dst_hi, - &xmm_alpha_dst_lo, &xmm_alpha_dst_hi); - - pix_multiply_2x128 (&xmm_src_lo, &xmm_src_hi, - &xmm_mask_lo, &xmm_mask_hi, - &xmm_src_lo, &xmm_src_hi); - pix_multiply_2x128 (&xmm_mask_lo, &xmm_mask_hi, - &xmm_alpha_src_lo, &xmm_alpha_src_hi, - &xmm_mask_lo, &xmm_mask_hi); - - negate_2x128 (xmm_alpha_dst_lo, xmm_alpha_dst_hi, - &xmm_alpha_dst_lo, &xmm_alpha_dst_hi); - negate_2x128 (xmm_mask_lo, xmm_mask_hi, - &xmm_mask_lo, &xmm_mask_hi); - - pix_add_multiply_2x128 ( - &xmm_dst_lo, &xmm_dst_hi, &xmm_mask_lo, &xmm_mask_hi, - &xmm_src_lo, &xmm_src_hi, &xmm_alpha_dst_lo, &xmm_alpha_dst_hi, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ( - (__m128i*)pd, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - - ps += 4; - pd += 4; - pm += 4; - w -= 4; - } - - while (w) - { - s = *ps++; - m = *pm++; - d = *pd; - - *pd++ = core_combine_xor_ca_pixel_sse2 (s, m, d); - w--; - } -} - -static void -sse2_combine_add_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * pd, - const uint32_t * ps, - const uint32_t * pm, - int w) -{ - uint32_t s, m, d; - - __m128i xmm_src_lo, xmm_src_hi; - __m128i xmm_dst_lo, xmm_dst_hi; - __m128i xmm_mask_lo, xmm_mask_hi; - - while (w && (uintptr_t)pd & 15) - { - s = *ps++; - m = *pm++; - d = *pd; - - *pd++ = pack_1x128_32 ( - _mm_adds_epu8 (pix_multiply_1x128 (unpack_32_1x128 (s), - unpack_32_1x128 (m)), - unpack_32_1x128 (d))); - w--; - } - - while (w >= 4) - { - xmm_src_hi = load_128_unaligned ((__m128i*)ps); - xmm_mask_hi = load_128_unaligned ((__m128i*)pm); - xmm_dst_hi = load_128_aligned ((__m128i*)pd); - - unpack_128_2x128 (xmm_src_hi, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_mask_hi, &xmm_mask_lo, &xmm_mask_hi); - unpack_128_2x128 (xmm_dst_hi, &xmm_dst_lo, &xmm_dst_hi); - - pix_multiply_2x128 (&xmm_src_lo, &xmm_src_hi, - &xmm_mask_lo, &xmm_mask_hi, - &xmm_src_lo, &xmm_src_hi); - - save_128_aligned ( - (__m128i*)pd, pack_2x128_128 ( - _mm_adds_epu8 (xmm_src_lo, xmm_dst_lo), - _mm_adds_epu8 (xmm_src_hi, xmm_dst_hi))); - - ps += 4; - pd += 4; - pm += 4; - w -= 4; - } - - while (w) - { - s = *ps++; - m = *pm++; - d = *pd; - - *pd++ = pack_1x128_32 ( - _mm_adds_epu8 (pix_multiply_1x128 (unpack_32_1x128 (s), - unpack_32_1x128 (m)), - unpack_32_1x128 (d))); - w--; - } -} - -static force_inline __m128i -create_mask_16_128 (uint16_t mask) -{ - return _mm_set1_epi16 (mask); -} - -/* Work around a code generation bug in Sun Studio 12. */ -#if defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590) -# define create_mask_2x32_128(mask0, mask1) \ - (_mm_set_epi32 ((mask0), (mask1), (mask0), (mask1))) -#else -static force_inline __m128i -create_mask_2x32_128 (uint32_t mask0, - uint32_t mask1) -{ - return _mm_set_epi32 (mask0, mask1, mask0, mask1); -} -#endif - -static void -sse2_composite_over_n_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src; - uint32_t *dst_line, *dst, d; - int32_t w; - int dst_stride; - __m128i xmm_src, xmm_alpha; - __m128i xmm_dst, xmm_dst_lo, xmm_dst_hi; - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - if (src == 0) - return; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - - xmm_src = expand_pixel_32_1x128 (src); - xmm_alpha = expand_alpha_1x128 (xmm_src); - - while (height--) - { - dst = dst_line; - - dst_line += dst_stride; - w = width; - - while (w && (uintptr_t)dst & 15) - { - d = *dst; - *dst++ = pack_1x128_32 (over_1x128 (xmm_src, - xmm_alpha, - unpack_32_1x128 (d))); - w--; - } - - while (w >= 4) - { - xmm_dst = load_128_aligned ((__m128i*)dst); - - unpack_128_2x128 (xmm_dst, &xmm_dst_lo, &xmm_dst_hi); - - over_2x128 (&xmm_src, &xmm_src, - &xmm_alpha, &xmm_alpha, - &xmm_dst_lo, &xmm_dst_hi); - - /* rebuid the 4 pixel data and save*/ - save_128_aligned ( - (__m128i*)dst, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - - w -= 4; - dst += 4; - } - - while (w) - { - d = *dst; - *dst++ = pack_1x128_32 (over_1x128 (xmm_src, - xmm_alpha, - unpack_32_1x128 (d))); - w--; - } - - } -} - -static void -sse2_composite_over_n_0565 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src; - uint16_t *dst_line, *dst, d; - int32_t w; - int dst_stride; - __m128i xmm_src, xmm_alpha; - __m128i xmm_dst, xmm_dst0, xmm_dst1, xmm_dst2, xmm_dst3; - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - if (src == 0) - return; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1); - - xmm_src = expand_pixel_32_1x128 (src); - xmm_alpha = expand_alpha_1x128 (xmm_src); - - while (height--) - { - dst = dst_line; - - dst_line += dst_stride; - w = width; - - while (w && (uintptr_t)dst & 15) - { - d = *dst; - - *dst++ = pack_565_32_16 ( - pack_1x128_32 (over_1x128 (xmm_src, - xmm_alpha, - expand565_16_1x128 (d)))); - w--; - } - - while (w >= 8) - { - xmm_dst = load_128_aligned ((__m128i*)dst); - - unpack_565_128_4x128 (xmm_dst, - &xmm_dst0, &xmm_dst1, &xmm_dst2, &xmm_dst3); - - over_2x128 (&xmm_src, &xmm_src, - &xmm_alpha, &xmm_alpha, - &xmm_dst0, &xmm_dst1); - over_2x128 (&xmm_src, &xmm_src, - &xmm_alpha, &xmm_alpha, - &xmm_dst2, &xmm_dst3); - - xmm_dst = pack_565_4x128_128 ( - &xmm_dst0, &xmm_dst1, &xmm_dst2, &xmm_dst3); - - save_128_aligned ((__m128i*)dst, xmm_dst); - - dst += 8; - w -= 8; - } - - while (w--) - { - d = *dst; - *dst++ = pack_565_32_16 ( - pack_1x128_32 (over_1x128 (xmm_src, xmm_alpha, - expand565_16_1x128 (d)))); - } - } - -} - -static void -sse2_composite_add_n_8888_8888_ca (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src; - uint32_t *dst_line, d; - uint32_t *mask_line, m; - uint32_t pack_cmp; - int dst_stride, mask_stride; - - __m128i xmm_src; - __m128i xmm_dst; - __m128i xmm_mask, xmm_mask_lo, xmm_mask_hi; - - __m128i mmx_src, mmx_mask, mmx_dest; - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - if (src == 0) - return; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE ( - mask_image, mask_x, mask_y, uint32_t, mask_stride, mask_line, 1); - - xmm_src = _mm_unpacklo_epi8 ( - create_mask_2x32_128 (src, src), _mm_setzero_si128 ()); - mmx_src = xmm_src; - - while (height--) - { - int w = width; - const uint32_t *pm = (uint32_t *)mask_line; - uint32_t *pd = (uint32_t *)dst_line; - - dst_line += dst_stride; - mask_line += mask_stride; - - while (w && (uintptr_t)pd & 15) - { - m = *pm++; - - if (m) - { - d = *pd; - - mmx_mask = unpack_32_1x128 (m); - mmx_dest = unpack_32_1x128 (d); - - *pd = pack_1x128_32 ( - _mm_adds_epu8 (pix_multiply_1x128 (mmx_mask, mmx_src), - mmx_dest)); - } - - pd++; - w--; - } - - while (w >= 4) - { - xmm_mask = load_128_unaligned ((__m128i*)pm); - - pack_cmp = - _mm_movemask_epi8 ( - _mm_cmpeq_epi32 (xmm_mask, _mm_setzero_si128 ())); - - /* if all bits in mask are zero, pack_cmp are equal to 0xffff */ - if (pack_cmp != 0xffff) - { - xmm_dst = load_128_aligned ((__m128i*)pd); - - unpack_128_2x128 (xmm_mask, &xmm_mask_lo, &xmm_mask_hi); - - pix_multiply_2x128 (&xmm_src, &xmm_src, - &xmm_mask_lo, &xmm_mask_hi, - &xmm_mask_lo, &xmm_mask_hi); - xmm_mask_hi = pack_2x128_128 (xmm_mask_lo, xmm_mask_hi); - - save_128_aligned ( - (__m128i*)pd, _mm_adds_epu8 (xmm_mask_hi, xmm_dst)); - } - - pd += 4; - pm += 4; - w -= 4; - } - - while (w) - { - m = *pm++; - - if (m) - { - d = *pd; - - mmx_mask = unpack_32_1x128 (m); - mmx_dest = unpack_32_1x128 (d); - - *pd = pack_1x128_32 ( - _mm_adds_epu8 (pix_multiply_1x128 (mmx_mask, mmx_src), - mmx_dest)); - } - - pd++; - w--; - } - } - -} - -static void -sse2_composite_over_n_8888_8888_ca (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src; - uint32_t *dst_line, d; - uint32_t *mask_line, m; - uint32_t pack_cmp; - int dst_stride, mask_stride; - - __m128i xmm_src, xmm_alpha; - __m128i xmm_dst, xmm_dst_lo, xmm_dst_hi; - __m128i xmm_mask, xmm_mask_lo, xmm_mask_hi; - - __m128i mmx_src, mmx_alpha, mmx_mask, mmx_dest; - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - if (src == 0) - return; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE ( - mask_image, mask_x, mask_y, uint32_t, mask_stride, mask_line, 1); - - xmm_src = _mm_unpacklo_epi8 ( - create_mask_2x32_128 (src, src), _mm_setzero_si128 ()); - xmm_alpha = expand_alpha_1x128 (xmm_src); - mmx_src = xmm_src; - mmx_alpha = xmm_alpha; - - while (height--) - { - int w = width; - const uint32_t *pm = (uint32_t *)mask_line; - uint32_t *pd = (uint32_t *)dst_line; - - dst_line += dst_stride; - mask_line += mask_stride; - - while (w && (uintptr_t)pd & 15) - { - m = *pm++; - - if (m) - { - d = *pd; - mmx_mask = unpack_32_1x128 (m); - mmx_dest = unpack_32_1x128 (d); - - *pd = pack_1x128_32 (in_over_1x128 (&mmx_src, - &mmx_alpha, - &mmx_mask, - &mmx_dest)); - } - - pd++; - w--; - } - - while (w >= 4) - { - xmm_mask = load_128_unaligned ((__m128i*)pm); - - pack_cmp = - _mm_movemask_epi8 ( - _mm_cmpeq_epi32 (xmm_mask, _mm_setzero_si128 ())); - - /* if all bits in mask are zero, pack_cmp are equal to 0xffff */ - if (pack_cmp != 0xffff) - { - xmm_dst = load_128_aligned ((__m128i*)pd); - - unpack_128_2x128 (xmm_mask, &xmm_mask_lo, &xmm_mask_hi); - unpack_128_2x128 (xmm_dst, &xmm_dst_lo, &xmm_dst_hi); - - in_over_2x128 (&xmm_src, &xmm_src, - &xmm_alpha, &xmm_alpha, - &xmm_mask_lo, &xmm_mask_hi, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ( - (__m128i*)pd, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - } - - pd += 4; - pm += 4; - w -= 4; - } - - while (w) - { - m = *pm++; - - if (m) - { - d = *pd; - mmx_mask = unpack_32_1x128 (m); - mmx_dest = unpack_32_1x128 (d); - - *pd = pack_1x128_32 ( - in_over_1x128 (&mmx_src, &mmx_alpha, &mmx_mask, &mmx_dest)); - } - - pd++; - w--; - } - } - -} - -static void -sse2_composite_over_8888_n_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t *dst_line, *dst; - uint32_t *src_line, *src; - uint32_t mask; - int32_t w; - int dst_stride, src_stride; - - __m128i xmm_mask; - __m128i xmm_src, xmm_src_lo, xmm_src_hi; - __m128i xmm_dst, xmm_dst_lo, xmm_dst_hi; - __m128i xmm_alpha_lo, xmm_alpha_hi; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE ( - src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - - mask = _pixman_image_get_solid (imp, mask_image, PIXMAN_a8r8g8b8); - - xmm_mask = create_mask_16_128 (mask >> 24); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - while (w && (uintptr_t)dst & 15) - { - uint32_t s = *src++; - - if (s) - { - uint32_t d = *dst; - - __m128i ms = unpack_32_1x128 (s); - __m128i alpha = expand_alpha_1x128 (ms); - __m128i dest = xmm_mask; - __m128i alpha_dst = unpack_32_1x128 (d); - - *dst = pack_1x128_32 ( - in_over_1x128 (&ms, &alpha, &dest, &alpha_dst)); - } - dst++; - w--; - } - - while (w >= 4) - { - xmm_src = load_128_unaligned ((__m128i*)src); - - if (!is_zero (xmm_src)) - { - xmm_dst = load_128_aligned ((__m128i*)dst); - - unpack_128_2x128 (xmm_src, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_dst, &xmm_dst_lo, &xmm_dst_hi); - expand_alpha_2x128 (xmm_src_lo, xmm_src_hi, - &xmm_alpha_lo, &xmm_alpha_hi); - - in_over_2x128 (&xmm_src_lo, &xmm_src_hi, - &xmm_alpha_lo, &xmm_alpha_hi, - &xmm_mask, &xmm_mask, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ( - (__m128i*)dst, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - } - - dst += 4; - src += 4; - w -= 4; - } - - while (w) - { - uint32_t s = *src++; - - if (s) - { - uint32_t d = *dst; - - __m128i ms = unpack_32_1x128 (s); - __m128i alpha = expand_alpha_1x128 (ms); - __m128i mask = xmm_mask; - __m128i dest = unpack_32_1x128 (d); - - *dst = pack_1x128_32 ( - in_over_1x128 (&ms, &alpha, &mask, &dest)); - } - - dst++; - w--; - } - } - -} - -static void -sse2_composite_src_x888_0565 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint16_t *dst_line, *dst; - uint32_t *src_line, *src, s; - int dst_stride, src_stride; - int32_t w; - - PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - while (w && (uintptr_t)dst & 15) - { - s = *src++; - *dst = convert_8888_to_0565 (s); - dst++; - w--; - } - - while (w >= 8) - { - __m128i xmm_src0 = load_128_unaligned ((__m128i *)src + 0); - __m128i xmm_src1 = load_128_unaligned ((__m128i *)src + 1); - - save_128_aligned ((__m128i*)dst, pack_565_2packedx128_128 (xmm_src0, xmm_src1)); - - w -= 8; - src += 8; - dst += 8; - } - - while (w) - { - s = *src++; - *dst = convert_8888_to_0565 (s); - dst++; - w--; - } - } -} - -static void -sse2_composite_src_x888_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t *dst_line, *dst; - uint32_t *src_line, *src; - int32_t w; - int dst_stride, src_stride; - - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE ( - src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - while (w && (uintptr_t)dst & 15) - { - *dst++ = *src++ | 0xff000000; - w--; - } - - while (w >= 16) - { - __m128i xmm_src1, xmm_src2, xmm_src3, xmm_src4; - - xmm_src1 = load_128_unaligned ((__m128i*)src + 0); - xmm_src2 = load_128_unaligned ((__m128i*)src + 1); - xmm_src3 = load_128_unaligned ((__m128i*)src + 2); - xmm_src4 = load_128_unaligned ((__m128i*)src + 3); - - save_128_aligned ((__m128i*)dst + 0, _mm_or_si128 (xmm_src1, mask_ff000000)); - save_128_aligned ((__m128i*)dst + 1, _mm_or_si128 (xmm_src2, mask_ff000000)); - save_128_aligned ((__m128i*)dst + 2, _mm_or_si128 (xmm_src3, mask_ff000000)); - save_128_aligned ((__m128i*)dst + 3, _mm_or_si128 (xmm_src4, mask_ff000000)); - - dst += 16; - src += 16; - w -= 16; - } - - while (w) - { - *dst++ = *src++ | 0xff000000; - w--; - } - } - -} - -static void -sse2_composite_over_x888_n_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t *dst_line, *dst; - uint32_t *src_line, *src; - uint32_t mask; - int dst_stride, src_stride; - int32_t w; - - __m128i xmm_mask, xmm_alpha; - __m128i xmm_src, xmm_src_lo, xmm_src_hi; - __m128i xmm_dst, xmm_dst_lo, xmm_dst_hi; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE ( - src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - - mask = _pixman_image_get_solid (imp, mask_image, PIXMAN_a8r8g8b8); - - xmm_mask = create_mask_16_128 (mask >> 24); - xmm_alpha = mask_00ff; - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - while (w && (uintptr_t)dst & 15) - { - uint32_t s = (*src++) | 0xff000000; - uint32_t d = *dst; - - __m128i src = unpack_32_1x128 (s); - __m128i alpha = xmm_alpha; - __m128i mask = xmm_mask; - __m128i dest = unpack_32_1x128 (d); - - *dst++ = pack_1x128_32 ( - in_over_1x128 (&src, &alpha, &mask, &dest)); - - w--; - } - - while (w >= 4) - { - xmm_src = _mm_or_si128 ( - load_128_unaligned ((__m128i*)src), mask_ff000000); - xmm_dst = load_128_aligned ((__m128i*)dst); - - unpack_128_2x128 (xmm_src, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_dst, &xmm_dst_lo, &xmm_dst_hi); - - in_over_2x128 (&xmm_src_lo, &xmm_src_hi, - &xmm_alpha, &xmm_alpha, - &xmm_mask, &xmm_mask, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ( - (__m128i*)dst, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - - dst += 4; - src += 4; - w -= 4; - - } - - while (w) - { - uint32_t s = (*src++) | 0xff000000; - uint32_t d = *dst; - - __m128i src = unpack_32_1x128 (s); - __m128i alpha = xmm_alpha; - __m128i mask = xmm_mask; - __m128i dest = unpack_32_1x128 (d); - - *dst++ = pack_1x128_32 ( - in_over_1x128 (&src, &alpha, &mask, &dest)); - - w--; - } - } - -} - -static void -sse2_composite_over_8888_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - int dst_stride, src_stride; - uint32_t *dst_line, *dst; - uint32_t *src_line, *src; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE ( - src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - - dst = dst_line; - src = src_line; - - while (height--) - { - sse2_combine_over_u (imp, op, dst, src, NULL, width); - - dst += dst_stride; - src += src_stride; - } -} - -static force_inline uint16_t -composite_over_8888_0565pixel (uint32_t src, uint16_t dst) -{ - __m128i ms; - - ms = unpack_32_1x128 (src); - return pack_565_32_16 ( - pack_1x128_32 ( - over_1x128 ( - ms, expand_alpha_1x128 (ms), expand565_16_1x128 (dst)))); -} - -static void -sse2_composite_over_8888_0565 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint16_t *dst_line, *dst, d; - uint32_t *src_line, *src, s; - int dst_stride, src_stride; - int32_t w; - - __m128i xmm_alpha_lo, xmm_alpha_hi; - __m128i xmm_src, xmm_src_lo, xmm_src_hi; - __m128i xmm_dst, xmm_dst0, xmm_dst1, xmm_dst2, xmm_dst3; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE ( - src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - - while (height--) - { - dst = dst_line; - src = src_line; - - dst_line += dst_stride; - src_line += src_stride; - w = width; - - /* Align dst on a 16-byte boundary */ - while (w && - ((uintptr_t)dst & 15)) - { - s = *src++; - d = *dst; - - *dst++ = composite_over_8888_0565pixel (s, d); - w--; - } - - /* It's a 8 pixel loop */ - while (w >= 8) - { - /* I'm loading unaligned because I'm not sure - * about the address alignment. - */ - xmm_src = load_128_unaligned ((__m128i*) src); - xmm_dst = load_128_aligned ((__m128i*) dst); - - /* Unpacking */ - unpack_128_2x128 (xmm_src, &xmm_src_lo, &xmm_src_hi); - unpack_565_128_4x128 (xmm_dst, - &xmm_dst0, &xmm_dst1, &xmm_dst2, &xmm_dst3); - expand_alpha_2x128 (xmm_src_lo, xmm_src_hi, - &xmm_alpha_lo, &xmm_alpha_hi); - - /* I'm loading next 4 pixels from memory - * before to optimze the memory read. - */ - xmm_src = load_128_unaligned ((__m128i*) (src + 4)); - - over_2x128 (&xmm_src_lo, &xmm_src_hi, - &xmm_alpha_lo, &xmm_alpha_hi, - &xmm_dst0, &xmm_dst1); - - /* Unpacking */ - unpack_128_2x128 (xmm_src, &xmm_src_lo, &xmm_src_hi); - expand_alpha_2x128 (xmm_src_lo, xmm_src_hi, - &xmm_alpha_lo, &xmm_alpha_hi); - - over_2x128 (&xmm_src_lo, &xmm_src_hi, - &xmm_alpha_lo, &xmm_alpha_hi, - &xmm_dst2, &xmm_dst3); - - save_128_aligned ( - (__m128i*)dst, pack_565_4x128_128 ( - &xmm_dst0, &xmm_dst1, &xmm_dst2, &xmm_dst3)); - - w -= 8; - dst += 8; - src += 8; - } - - while (w--) - { - s = *src++; - d = *dst; - - *dst++ = composite_over_8888_0565pixel (s, d); - } - } - -} - -static void -sse2_composite_over_n_8_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src, srca; - uint32_t *dst_line, *dst; - uint8_t *mask_line, *mask; - int dst_stride, mask_stride; - int32_t w; - uint32_t m, d; - - __m128i xmm_src, xmm_alpha, xmm_def; - __m128i xmm_dst, xmm_dst_lo, xmm_dst_hi; - __m128i xmm_mask, xmm_mask_lo, xmm_mask_hi; - - __m128i mmx_src, mmx_alpha, mmx_mask, mmx_dest; - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - srca = src >> 24; - if (src == 0) - return; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE ( - mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); - - xmm_def = create_mask_2x32_128 (src, src); - xmm_src = expand_pixel_32_1x128 (src); - xmm_alpha = expand_alpha_1x128 (xmm_src); - mmx_src = xmm_src; - mmx_alpha = xmm_alpha; - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - w = width; - - while (w && (uintptr_t)dst & 15) - { - uint8_t m = *mask++; - - if (m) - { - d = *dst; - mmx_mask = expand_pixel_8_1x128 (m); - mmx_dest = unpack_32_1x128 (d); - - *dst = pack_1x128_32 (in_over_1x128 (&mmx_src, - &mmx_alpha, - &mmx_mask, - &mmx_dest)); - } - - w--; - dst++; - } - - while (w >= 4) - { - m = *((uint32_t*)mask); - - if (srca == 0xff && m == 0xffffffff) - { - save_128_aligned ((__m128i*)dst, xmm_def); - } - else if (m) - { - xmm_dst = load_128_aligned ((__m128i*) dst); - xmm_mask = unpack_32_1x128 (m); - xmm_mask = _mm_unpacklo_epi8 (xmm_mask, _mm_setzero_si128 ()); - - /* Unpacking */ - unpack_128_2x128 (xmm_dst, &xmm_dst_lo, &xmm_dst_hi); - unpack_128_2x128 (xmm_mask, &xmm_mask_lo, &xmm_mask_hi); - - expand_alpha_rev_2x128 (xmm_mask_lo, xmm_mask_hi, - &xmm_mask_lo, &xmm_mask_hi); - - in_over_2x128 (&xmm_src, &xmm_src, - &xmm_alpha, &xmm_alpha, - &xmm_mask_lo, &xmm_mask_hi, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ( - (__m128i*)dst, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - } - - w -= 4; - dst += 4; - mask += 4; - } - - while (w) - { - uint8_t m = *mask++; - - if (m) - { - d = *dst; - mmx_mask = expand_pixel_8_1x128 (m); - mmx_dest = unpack_32_1x128 (d); - - *dst = pack_1x128_32 (in_over_1x128 (&mmx_src, - &mmx_alpha, - &mmx_mask, - &mmx_dest)); - } - - w--; - dst++; - } - } - -} - -#if defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__) -__attribute__((__force_align_arg_pointer__)) -#endif -static pixman_bool_t -sse2_fill (pixman_implementation_t *imp, - uint32_t * bits, - int stride, - int bpp, - int x, - int y, - int width, - int height, - uint32_t filler) -{ - uint32_t byte_width; - uint8_t *byte_line; - - __m128i xmm_def; - - if (bpp == 8) - { - uint8_t b; - uint16_t w; - - stride = stride * (int) sizeof (uint32_t) / 1; - byte_line = (uint8_t *)(((uint8_t *)bits) + stride * y + x); - byte_width = width; - stride *= 1; - - b = filler & 0xff; - w = (b << 8) | b; - filler = (w << 16) | w; - } - else if (bpp == 16) - { - stride = stride * (int) sizeof (uint32_t) / 2; - byte_line = (uint8_t *)(((uint16_t *)bits) + stride * y + x); - byte_width = 2 * width; - stride *= 2; - - filler = (filler & 0xffff) * 0x00010001; - } - else if (bpp == 32) - { - stride = stride * (int) sizeof (uint32_t) / 4; - byte_line = (uint8_t *)(((uint32_t *)bits) + stride * y + x); - byte_width = 4 * width; - stride *= 4; - } - else - { - return FALSE; - } - - xmm_def = create_mask_2x32_128 (filler, filler); - - while (height--) - { - int w; - uint8_t *d = byte_line; - byte_line += stride; - w = byte_width; - - if (w >= 1 && ((uintptr_t)d & 1)) - { - *(uint8_t *)d = filler; - w -= 1; - d += 1; - } - - while (w >= 2 && ((uintptr_t)d & 3)) - { - *(uint16_t *)d = filler; - w -= 2; - d += 2; - } - - while (w >= 4 && ((uintptr_t)d & 15)) - { - *(uint32_t *)d = filler; - - w -= 4; - d += 4; - } - - while (w >= 128) - { - save_128_aligned ((__m128i*)(d), xmm_def); - save_128_aligned ((__m128i*)(d + 16), xmm_def); - save_128_aligned ((__m128i*)(d + 32), xmm_def); - save_128_aligned ((__m128i*)(d + 48), xmm_def); - save_128_aligned ((__m128i*)(d + 64), xmm_def); - save_128_aligned ((__m128i*)(d + 80), xmm_def); - save_128_aligned ((__m128i*)(d + 96), xmm_def); - save_128_aligned ((__m128i*)(d + 112), xmm_def); - - d += 128; - w -= 128; - } - - if (w >= 64) - { - save_128_aligned ((__m128i*)(d), xmm_def); - save_128_aligned ((__m128i*)(d + 16), xmm_def); - save_128_aligned ((__m128i*)(d + 32), xmm_def); - save_128_aligned ((__m128i*)(d + 48), xmm_def); - - d += 64; - w -= 64; - } - - if (w >= 32) - { - save_128_aligned ((__m128i*)(d), xmm_def); - save_128_aligned ((__m128i*)(d + 16), xmm_def); - - d += 32; - w -= 32; - } - - if (w >= 16) - { - save_128_aligned ((__m128i*)(d), xmm_def); - - d += 16; - w -= 16; - } - - while (w >= 4) - { - *(uint32_t *)d = filler; - - w -= 4; - d += 4; - } - - if (w >= 2) - { - *(uint16_t *)d = filler; - w -= 2; - d += 2; - } - - if (w >= 1) - { - *(uint8_t *)d = filler; - w -= 1; - d += 1; - } - } - - return TRUE; -} - -static void -sse2_composite_src_n_8_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src, srca; - uint32_t *dst_line, *dst; - uint8_t *mask_line, *mask; - int dst_stride, mask_stride; - int32_t w; - uint32_t m; - - __m128i xmm_src, xmm_def; - __m128i xmm_mask, xmm_mask_lo, xmm_mask_hi; - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - srca = src >> 24; - if (src == 0) - { - sse2_fill (imp, dest_image->bits.bits, dest_image->bits.rowstride, - PIXMAN_FORMAT_BPP (dest_image->bits.format), - dest_x, dest_y, width, height, 0); - return; - } - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE ( - mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); - - xmm_def = create_mask_2x32_128 (src, src); - xmm_src = expand_pixel_32_1x128 (src); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - w = width; - - while (w && (uintptr_t)dst & 15) - { - uint8_t m = *mask++; - - if (m) - { - *dst = pack_1x128_32 ( - pix_multiply_1x128 (xmm_src, expand_pixel_8_1x128 (m))); - } - else - { - *dst = 0; - } - - w--; - dst++; - } - - while (w >= 4) - { - m = *((uint32_t*)mask); - - if (srca == 0xff && m == 0xffffffff) - { - save_128_aligned ((__m128i*)dst, xmm_def); - } - else if (m) - { - xmm_mask = unpack_32_1x128 (m); - xmm_mask = _mm_unpacklo_epi8 (xmm_mask, _mm_setzero_si128 ()); - - /* Unpacking */ - unpack_128_2x128 (xmm_mask, &xmm_mask_lo, &xmm_mask_hi); - - expand_alpha_rev_2x128 (xmm_mask_lo, xmm_mask_hi, - &xmm_mask_lo, &xmm_mask_hi); - - pix_multiply_2x128 (&xmm_src, &xmm_src, - &xmm_mask_lo, &xmm_mask_hi, - &xmm_mask_lo, &xmm_mask_hi); - - save_128_aligned ( - (__m128i*)dst, pack_2x128_128 (xmm_mask_lo, xmm_mask_hi)); - } - else - { - save_128_aligned ((__m128i*)dst, _mm_setzero_si128 ()); - } - - w -= 4; - dst += 4; - mask += 4; - } - - while (w) - { - uint8_t m = *mask++; - - if (m) - { - *dst = pack_1x128_32 ( - pix_multiply_1x128 ( - xmm_src, expand_pixel_8_1x128 (m))); - } - else - { - *dst = 0; - } - - w--; - dst++; - } - } - -} - -static void -sse2_composite_over_n_8_0565 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src; - uint16_t *dst_line, *dst, d; - uint8_t *mask_line, *mask; - int dst_stride, mask_stride; - int32_t w; - uint32_t m; - __m128i mmx_src, mmx_alpha, mmx_mask, mmx_dest; - - __m128i xmm_src, xmm_alpha; - __m128i xmm_mask, xmm_mask_lo, xmm_mask_hi; - __m128i xmm_dst, xmm_dst0, xmm_dst1, xmm_dst2, xmm_dst3; - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - if (src == 0) - return; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE ( - mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); - - xmm_src = expand_pixel_32_1x128 (src); - xmm_alpha = expand_alpha_1x128 (xmm_src); - mmx_src = xmm_src; - mmx_alpha = xmm_alpha; - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - w = width; - - while (w && (uintptr_t)dst & 15) - { - m = *mask++; - - if (m) - { - d = *dst; - mmx_mask = expand_alpha_rev_1x128 (unpack_32_1x128 (m)); - mmx_dest = expand565_16_1x128 (d); - - *dst = pack_565_32_16 ( - pack_1x128_32 ( - in_over_1x128 ( - &mmx_src, &mmx_alpha, &mmx_mask, &mmx_dest))); - } - - w--; - dst++; - } - - while (w >= 8) - { - xmm_dst = load_128_aligned ((__m128i*) dst); - unpack_565_128_4x128 (xmm_dst, - &xmm_dst0, &xmm_dst1, &xmm_dst2, &xmm_dst3); - - m = *((uint32_t*)mask); - mask += 4; - - if (m) - { - xmm_mask = unpack_32_1x128 (m); - xmm_mask = _mm_unpacklo_epi8 (xmm_mask, _mm_setzero_si128 ()); - - /* Unpacking */ - unpack_128_2x128 (xmm_mask, &xmm_mask_lo, &xmm_mask_hi); - - expand_alpha_rev_2x128 (xmm_mask_lo, xmm_mask_hi, - &xmm_mask_lo, &xmm_mask_hi); - - in_over_2x128 (&xmm_src, &xmm_src, - &xmm_alpha, &xmm_alpha, - &xmm_mask_lo, &xmm_mask_hi, - &xmm_dst0, &xmm_dst1); - } - - m = *((uint32_t*)mask); - mask += 4; - - if (m) - { - xmm_mask = unpack_32_1x128 (m); - xmm_mask = _mm_unpacklo_epi8 (xmm_mask, _mm_setzero_si128 ()); - - /* Unpacking */ - unpack_128_2x128 (xmm_mask, &xmm_mask_lo, &xmm_mask_hi); - - expand_alpha_rev_2x128 (xmm_mask_lo, xmm_mask_hi, - &xmm_mask_lo, &xmm_mask_hi); - in_over_2x128 (&xmm_src, &xmm_src, - &xmm_alpha, &xmm_alpha, - &xmm_mask_lo, &xmm_mask_hi, - &xmm_dst2, &xmm_dst3); - } - - save_128_aligned ( - (__m128i*)dst, pack_565_4x128_128 ( - &xmm_dst0, &xmm_dst1, &xmm_dst2, &xmm_dst3)); - - w -= 8; - dst += 8; - } - - while (w) - { - m = *mask++; - - if (m) - { - d = *dst; - mmx_mask = expand_alpha_rev_1x128 (unpack_32_1x128 (m)); - mmx_dest = expand565_16_1x128 (d); - - *dst = pack_565_32_16 ( - pack_1x128_32 ( - in_over_1x128 ( - &mmx_src, &mmx_alpha, &mmx_mask, &mmx_dest))); - } - - w--; - dst++; - } - } - -} - -static void -sse2_composite_over_pixbuf_0565 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint16_t *dst_line, *dst, d; - uint32_t *src_line, *src, s; - int dst_stride, src_stride; - int32_t w; - uint32_t opaque, zero; - - __m128i ms; - __m128i xmm_src, xmm_src_lo, xmm_src_hi; - __m128i xmm_dst, xmm_dst0, xmm_dst1, xmm_dst2, xmm_dst3; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE ( - src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - while (w && (uintptr_t)dst & 15) - { - s = *src++; - d = *dst; - - ms = unpack_32_1x128 (s); - - *dst++ = pack_565_32_16 ( - pack_1x128_32 ( - over_rev_non_pre_1x128 (ms, expand565_16_1x128 (d)))); - w--; - } - - while (w >= 8) - { - /* First round */ - xmm_src = load_128_unaligned ((__m128i*)src); - xmm_dst = load_128_aligned ((__m128i*)dst); - - opaque = is_opaque (xmm_src); - zero = is_zero (xmm_src); - - unpack_565_128_4x128 (xmm_dst, - &xmm_dst0, &xmm_dst1, &xmm_dst2, &xmm_dst3); - unpack_128_2x128 (xmm_src, &xmm_src_lo, &xmm_src_hi); - - /* preload next round*/ - xmm_src = load_128_unaligned ((__m128i*)(src + 4)); - - if (opaque) - { - invert_colors_2x128 (xmm_src_lo, xmm_src_hi, - &xmm_dst0, &xmm_dst1); - } - else if (!zero) - { - over_rev_non_pre_2x128 (xmm_src_lo, xmm_src_hi, - &xmm_dst0, &xmm_dst1); - } - - /* Second round */ - opaque = is_opaque (xmm_src); - zero = is_zero (xmm_src); - - unpack_128_2x128 (xmm_src, &xmm_src_lo, &xmm_src_hi); - - if (opaque) - { - invert_colors_2x128 (xmm_src_lo, xmm_src_hi, - &xmm_dst2, &xmm_dst3); - } - else if (!zero) - { - over_rev_non_pre_2x128 (xmm_src_lo, xmm_src_hi, - &xmm_dst2, &xmm_dst3); - } - - save_128_aligned ( - (__m128i*)dst, pack_565_4x128_128 ( - &xmm_dst0, &xmm_dst1, &xmm_dst2, &xmm_dst3)); - - w -= 8; - src += 8; - dst += 8; - } - - while (w) - { - s = *src++; - d = *dst; - - ms = unpack_32_1x128 (s); - - *dst++ = pack_565_32_16 ( - pack_1x128_32 ( - over_rev_non_pre_1x128 (ms, expand565_16_1x128 (d)))); - w--; - } - } - -} - -static void -sse2_composite_over_pixbuf_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t *dst_line, *dst, d; - uint32_t *src_line, *src, s; - int dst_stride, src_stride; - int32_t w; - uint32_t opaque, zero; - - __m128i xmm_src_lo, xmm_src_hi; - __m128i xmm_dst_lo, xmm_dst_hi; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE ( - src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - while (w && (uintptr_t)dst & 15) - { - s = *src++; - d = *dst; - - *dst++ = pack_1x128_32 ( - over_rev_non_pre_1x128 ( - unpack_32_1x128 (s), unpack_32_1x128 (d))); - - w--; - } - - while (w >= 4) - { - xmm_src_hi = load_128_unaligned ((__m128i*)src); - - opaque = is_opaque (xmm_src_hi); - zero = is_zero (xmm_src_hi); - - unpack_128_2x128 (xmm_src_hi, &xmm_src_lo, &xmm_src_hi); - - if (opaque) - { - invert_colors_2x128 (xmm_src_lo, xmm_src_hi, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ( - (__m128i*)dst, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - } - else if (!zero) - { - xmm_dst_hi = load_128_aligned ((__m128i*)dst); - - unpack_128_2x128 (xmm_dst_hi, &xmm_dst_lo, &xmm_dst_hi); - - over_rev_non_pre_2x128 (xmm_src_lo, xmm_src_hi, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ( - (__m128i*)dst, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - } - - w -= 4; - dst += 4; - src += 4; - } - - while (w) - { - s = *src++; - d = *dst; - - *dst++ = pack_1x128_32 ( - over_rev_non_pre_1x128 ( - unpack_32_1x128 (s), unpack_32_1x128 (d))); - - w--; - } - } - -} - -static void -sse2_composite_over_n_8888_0565_ca (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src; - uint16_t *dst_line, *dst, d; - uint32_t *mask_line, *mask, m; - int dst_stride, mask_stride; - int w; - uint32_t pack_cmp; - - __m128i xmm_src, xmm_alpha; - __m128i xmm_mask, xmm_mask_lo, xmm_mask_hi; - __m128i xmm_dst, xmm_dst0, xmm_dst1, xmm_dst2, xmm_dst3; - - __m128i mmx_src, mmx_alpha, mmx_mask, mmx_dest; - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - if (src == 0) - return; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint16_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE ( - mask_image, mask_x, mask_y, uint32_t, mask_stride, mask_line, 1); - - xmm_src = expand_pixel_32_1x128 (src); - xmm_alpha = expand_alpha_1x128 (xmm_src); - mmx_src = xmm_src; - mmx_alpha = xmm_alpha; - - while (height--) - { - w = width; - mask = mask_line; - dst = dst_line; - mask_line += mask_stride; - dst_line += dst_stride; - - while (w && ((uintptr_t)dst & 15)) - { - m = *(uint32_t *) mask; - - if (m) - { - d = *dst; - mmx_mask = unpack_32_1x128 (m); - mmx_dest = expand565_16_1x128 (d); - - *dst = pack_565_32_16 ( - pack_1x128_32 ( - in_over_1x128 ( - &mmx_src, &mmx_alpha, &mmx_mask, &mmx_dest))); - } - - w--; - dst++; - mask++; - } - - while (w >= 8) - { - /* First round */ - xmm_mask = load_128_unaligned ((__m128i*)mask); - xmm_dst = load_128_aligned ((__m128i*)dst); - - pack_cmp = _mm_movemask_epi8 ( - _mm_cmpeq_epi32 (xmm_mask, _mm_setzero_si128 ())); - - unpack_565_128_4x128 (xmm_dst, - &xmm_dst0, &xmm_dst1, &xmm_dst2, &xmm_dst3); - unpack_128_2x128 (xmm_mask, &xmm_mask_lo, &xmm_mask_hi); - - /* preload next round */ - xmm_mask = load_128_unaligned ((__m128i*)(mask + 4)); - - /* preload next round */ - if (pack_cmp != 0xffff) - { - in_over_2x128 (&xmm_src, &xmm_src, - &xmm_alpha, &xmm_alpha, - &xmm_mask_lo, &xmm_mask_hi, - &xmm_dst0, &xmm_dst1); - } - - /* Second round */ - pack_cmp = _mm_movemask_epi8 ( - _mm_cmpeq_epi32 (xmm_mask, _mm_setzero_si128 ())); - - unpack_128_2x128 (xmm_mask, &xmm_mask_lo, &xmm_mask_hi); - - if (pack_cmp != 0xffff) - { - in_over_2x128 (&xmm_src, &xmm_src, - &xmm_alpha, &xmm_alpha, - &xmm_mask_lo, &xmm_mask_hi, - &xmm_dst2, &xmm_dst3); - } - - save_128_aligned ( - (__m128i*)dst, pack_565_4x128_128 ( - &xmm_dst0, &xmm_dst1, &xmm_dst2, &xmm_dst3)); - - w -= 8; - dst += 8; - mask += 8; - } - - while (w) - { - m = *(uint32_t *) mask; - - if (m) - { - d = *dst; - mmx_mask = unpack_32_1x128 (m); - mmx_dest = expand565_16_1x128 (d); - - *dst = pack_565_32_16 ( - pack_1x128_32 ( - in_over_1x128 ( - &mmx_src, &mmx_alpha, &mmx_mask, &mmx_dest))); - } - - w--; - dst++; - mask++; - } - } - -} - -static void -sse2_composite_in_n_8_8 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint8_t *dst_line, *dst; - uint8_t *mask_line, *mask; - int dst_stride, mask_stride; - uint32_t d, m; - uint32_t src; - int32_t w; - - __m128i xmm_alpha; - __m128i xmm_mask, xmm_mask_lo, xmm_mask_hi; - __m128i xmm_dst, xmm_dst_lo, xmm_dst_hi; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE ( - mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - xmm_alpha = expand_alpha_1x128 (expand_pixel_32_1x128 (src)); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - w = width; - - while (w && ((uintptr_t)dst & 15)) - { - m = (uint32_t) *mask++; - d = (uint32_t) *dst; - - *dst++ = (uint8_t) pack_1x128_32 ( - pix_multiply_1x128 ( - pix_multiply_1x128 (xmm_alpha, - unpack_32_1x128 (m)), - unpack_32_1x128 (d))); - w--; - } - - while (w >= 16) - { - xmm_mask = load_128_unaligned ((__m128i*)mask); - xmm_dst = load_128_aligned ((__m128i*)dst); - - unpack_128_2x128 (xmm_mask, &xmm_mask_lo, &xmm_mask_hi); - unpack_128_2x128 (xmm_dst, &xmm_dst_lo, &xmm_dst_hi); - - pix_multiply_2x128 (&xmm_alpha, &xmm_alpha, - &xmm_mask_lo, &xmm_mask_hi, - &xmm_mask_lo, &xmm_mask_hi); - - pix_multiply_2x128 (&xmm_mask_lo, &xmm_mask_hi, - &xmm_dst_lo, &xmm_dst_hi, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ( - (__m128i*)dst, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - - mask += 16; - dst += 16; - w -= 16; - } - - while (w) - { - m = (uint32_t) *mask++; - d = (uint32_t) *dst; - - *dst++ = (uint8_t) pack_1x128_32 ( - pix_multiply_1x128 ( - pix_multiply_1x128 ( - xmm_alpha, unpack_32_1x128 (m)), - unpack_32_1x128 (d))); - w--; - } - } - -} - -static void -sse2_composite_in_n_8 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint8_t *dst_line, *dst; - int dst_stride; - uint32_t d; - uint32_t src; - int32_t w; - - __m128i xmm_alpha; - __m128i xmm_dst, xmm_dst_lo, xmm_dst_hi; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1); - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - xmm_alpha = expand_alpha_1x128 (expand_pixel_32_1x128 (src)); - - src = src >> 24; - - if (src == 0xff) - return; - - if (src == 0x00) - { - pixman_fill (dest_image->bits.bits, dest_image->bits.rowstride, - 8, dest_x, dest_y, width, height, src); - - return; - } - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - w = width; - - while (w && ((uintptr_t)dst & 15)) - { - d = (uint32_t) *dst; - - *dst++ = (uint8_t) pack_1x128_32 ( - pix_multiply_1x128 ( - xmm_alpha, - unpack_32_1x128 (d))); - w--; - } - - while (w >= 16) - { - xmm_dst = load_128_aligned ((__m128i*)dst); - - unpack_128_2x128 (xmm_dst, &xmm_dst_lo, &xmm_dst_hi); - - pix_multiply_2x128 (&xmm_alpha, &xmm_alpha, - &xmm_dst_lo, &xmm_dst_hi, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ( - (__m128i*)dst, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - - dst += 16; - w -= 16; - } - - while (w) - { - d = (uint32_t) *dst; - - *dst++ = (uint8_t) pack_1x128_32 ( - pix_multiply_1x128 ( - xmm_alpha, - unpack_32_1x128 (d))); - w--; - } - } - -} - -static void -sse2_composite_in_8_8 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint8_t *dst_line, *dst; - uint8_t *src_line, *src; - int src_stride, dst_stride; - int32_t w; - uint32_t s, d; - - __m128i xmm_src, xmm_src_lo, xmm_src_hi; - __m128i xmm_dst, xmm_dst_lo, xmm_dst_hi; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE ( - src_image, src_x, src_y, uint8_t, src_stride, src_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - while (w && ((uintptr_t)dst & 15)) - { - s = (uint32_t) *src++; - d = (uint32_t) *dst; - - *dst++ = (uint8_t) pack_1x128_32 ( - pix_multiply_1x128 ( - unpack_32_1x128 (s), unpack_32_1x128 (d))); - w--; - } - - while (w >= 16) - { - xmm_src = load_128_unaligned ((__m128i*)src); - xmm_dst = load_128_aligned ((__m128i*)dst); - - unpack_128_2x128 (xmm_src, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_dst, &xmm_dst_lo, &xmm_dst_hi); - - pix_multiply_2x128 (&xmm_src_lo, &xmm_src_hi, - &xmm_dst_lo, &xmm_dst_hi, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ( - (__m128i*)dst, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - - src += 16; - dst += 16; - w -= 16; - } - - while (w) - { - s = (uint32_t) *src++; - d = (uint32_t) *dst; - - *dst++ = (uint8_t) pack_1x128_32 ( - pix_multiply_1x128 (unpack_32_1x128 (s), unpack_32_1x128 (d))); - w--; - } - } - -} - -static void -sse2_composite_add_n_8_8 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint8_t *dst_line, *dst; - uint8_t *mask_line, *mask; - int dst_stride, mask_stride; - int32_t w; - uint32_t src; - uint32_t m, d; - - __m128i xmm_alpha; - __m128i xmm_mask, xmm_mask_lo, xmm_mask_hi; - __m128i xmm_dst, xmm_dst_lo, xmm_dst_hi; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE ( - mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - xmm_alpha = expand_alpha_1x128 (expand_pixel_32_1x128 (src)); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - w = width; - - while (w && ((uintptr_t)dst & 15)) - { - m = (uint32_t) *mask++; - d = (uint32_t) *dst; - - *dst++ = (uint8_t) pack_1x128_32 ( - _mm_adds_epu16 ( - pix_multiply_1x128 ( - xmm_alpha, unpack_32_1x128 (m)), - unpack_32_1x128 (d))); - w--; - } - - while (w >= 16) - { - xmm_mask = load_128_unaligned ((__m128i*)mask); - xmm_dst = load_128_aligned ((__m128i*)dst); - - unpack_128_2x128 (xmm_mask, &xmm_mask_lo, &xmm_mask_hi); - unpack_128_2x128 (xmm_dst, &xmm_dst_lo, &xmm_dst_hi); - - pix_multiply_2x128 (&xmm_alpha, &xmm_alpha, - &xmm_mask_lo, &xmm_mask_hi, - &xmm_mask_lo, &xmm_mask_hi); - - xmm_dst_lo = _mm_adds_epu16 (xmm_mask_lo, xmm_dst_lo); - xmm_dst_hi = _mm_adds_epu16 (xmm_mask_hi, xmm_dst_hi); - - save_128_aligned ( - (__m128i*)dst, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - - mask += 16; - dst += 16; - w -= 16; - } - - while (w) - { - m = (uint32_t) *mask++; - d = (uint32_t) *dst; - - *dst++ = (uint8_t) pack_1x128_32 ( - _mm_adds_epu16 ( - pix_multiply_1x128 ( - xmm_alpha, unpack_32_1x128 (m)), - unpack_32_1x128 (d))); - - w--; - } - } - -} - -static void -sse2_composite_add_n_8 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint8_t *dst_line, *dst; - int dst_stride; - int32_t w; - uint32_t src; - - __m128i xmm_src; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1); - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - src >>= 24; - - if (src == 0x00) - return; - - if (src == 0xff) - { - pixman_fill (dest_image->bits.bits, dest_image->bits.rowstride, - 8, dest_x, dest_y, width, height, 0xff); - - return; - } - - src = (src << 24) | (src << 16) | (src << 8) | src; - xmm_src = _mm_set_epi32 (src, src, src, src); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - w = width; - - while (w && ((uintptr_t)dst & 15)) - { - *dst = (uint8_t)_mm_cvtsi128_si32 ( - _mm_adds_epu8 ( - xmm_src, - _mm_cvtsi32_si128 (*dst))); - - w--; - dst++; - } - - while (w >= 16) - { - save_128_aligned ( - (__m128i*)dst, _mm_adds_epu8 (xmm_src, load_128_aligned ((__m128i*)dst))); - - dst += 16; - w -= 16; - } - - while (w) - { - *dst = (uint8_t)_mm_cvtsi128_si32 ( - _mm_adds_epu8 ( - xmm_src, - _mm_cvtsi32_si128 (*dst))); - - w--; - dst++; - } - } - -} - -static void -sse2_composite_add_8_8 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint8_t *dst_line, *dst; - uint8_t *src_line, *src; - int dst_stride, src_stride; - int32_t w; - uint16_t t; - - PIXMAN_IMAGE_GET_LINE ( - src_image, src_x, src_y, uint8_t, src_stride, src_line, 1); - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1); - - while (height--) - { - dst = dst_line; - src = src_line; - - dst_line += dst_stride; - src_line += src_stride; - w = width; - - /* Small head */ - while (w && (uintptr_t)dst & 3) - { - t = (*dst) + (*src++); - *dst++ = t | (0 - (t >> 8)); - w--; - } - - sse2_combine_add_u (imp, op, - (uint32_t*)dst, (uint32_t*)src, NULL, w >> 2); - - /* Small tail */ - dst += w & 0xfffc; - src += w & 0xfffc; - - w &= 3; - - while (w) - { - t = (*dst) + (*src++); - *dst++ = t | (0 - (t >> 8)); - w--; - } - } - -} - -static void -sse2_composite_add_8888_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t *dst_line, *dst; - uint32_t *src_line, *src; - int dst_stride, src_stride; - - PIXMAN_IMAGE_GET_LINE ( - src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - - sse2_combine_add_u (imp, op, dst, src, NULL, width); - } -} - -static void -sse2_composite_add_n_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t *dst_line, *dst, src; - int dst_stride; - - __m128i xmm_src; - - PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - if (src == 0) - return; - - if (src == ~0) - { - pixman_fill (dest_image->bits.bits, dest_image->bits.rowstride, 32, - dest_x, dest_y, width, height, ~0); - - return; - } - - xmm_src = _mm_set_epi32 (src, src, src, src); - while (height--) - { - int w = width; - uint32_t d; - - dst = dst_line; - dst_line += dst_stride; - - while (w && (uintptr_t)dst & 15) - { - d = *dst; - *dst++ = - _mm_cvtsi128_si32 ( _mm_adds_epu8 (xmm_src, _mm_cvtsi32_si128 (d))); - w--; - } - - while (w >= 4) - { - save_128_aligned - ((__m128i*)dst, - _mm_adds_epu8 (xmm_src, load_128_aligned ((__m128i*)dst))); - - dst += 4; - w -= 4; - } - - while (w--) - { - d = *dst; - *dst++ = - _mm_cvtsi128_si32 (_mm_adds_epu8 (xmm_src, - _mm_cvtsi32_si128 (d))); - } - } -} - -static void -sse2_composite_add_n_8_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t *dst_line, *dst; - uint8_t *mask_line, *mask; - int dst_stride, mask_stride; - int32_t w; - uint32_t src; - - __m128i xmm_src; - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - if (src == 0) - return; - xmm_src = expand_pixel_32_1x128 (src); - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE ( - mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - w = width; - - while (w && ((uintptr_t)dst & 15)) - { - uint8_t m = *mask++; - if (m) - { - *dst = pack_1x128_32 - (_mm_adds_epu16 - (pix_multiply_1x128 (xmm_src, expand_pixel_8_1x128 (m)), - unpack_32_1x128 (*dst))); - } - dst++; - w--; - } - - while (w >= 4) - { - uint32_t m = *(uint32_t*)mask; - if (m) - { - __m128i xmm_mask_lo, xmm_mask_hi; - __m128i xmm_dst_lo, xmm_dst_hi; - - __m128i xmm_dst = load_128_aligned ((__m128i*)dst); - __m128i xmm_mask = - _mm_unpacklo_epi8 (unpack_32_1x128(m), - _mm_setzero_si128 ()); - - unpack_128_2x128 (xmm_mask, &xmm_mask_lo, &xmm_mask_hi); - unpack_128_2x128 (xmm_dst, &xmm_dst_lo, &xmm_dst_hi); - - expand_alpha_rev_2x128 (xmm_mask_lo, xmm_mask_hi, - &xmm_mask_lo, &xmm_mask_hi); - - pix_multiply_2x128 (&xmm_src, &xmm_src, - &xmm_mask_lo, &xmm_mask_hi, - &xmm_mask_lo, &xmm_mask_hi); - - xmm_dst_lo = _mm_adds_epu16 (xmm_mask_lo, xmm_dst_lo); - xmm_dst_hi = _mm_adds_epu16 (xmm_mask_hi, xmm_dst_hi); - - save_128_aligned ( - (__m128i*)dst, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - } - - w -= 4; - dst += 4; - mask += 4; - } - - while (w) - { - uint8_t m = *mask++; - if (m) - { - *dst = pack_1x128_32 - (_mm_adds_epu16 - (pix_multiply_1x128 (xmm_src, expand_pixel_8_1x128 (m)), - unpack_32_1x128 (*dst))); - } - dst++; - w--; - } - } -} - -static pixman_bool_t -sse2_blt (pixman_implementation_t *imp, - uint32_t * src_bits, - uint32_t * dst_bits, - int src_stride, - int dst_stride, - int src_bpp, - int dst_bpp, - int src_x, - int src_y, - int dest_x, - int dest_y, - int width, - int height) -{ - uint8_t * src_bytes; - uint8_t * dst_bytes; - int byte_width; - - if (src_bpp != dst_bpp) - return FALSE; - - if (src_bpp == 16) - { - src_stride = src_stride * (int) sizeof (uint32_t) / 2; - dst_stride = dst_stride * (int) sizeof (uint32_t) / 2; - src_bytes =(uint8_t *)(((uint16_t *)src_bits) + src_stride * (src_y) + (src_x)); - dst_bytes = (uint8_t *)(((uint16_t *)dst_bits) + dst_stride * (dest_y) + (dest_x)); - byte_width = 2 * width; - src_stride *= 2; - dst_stride *= 2; - } - else if (src_bpp == 32) - { - src_stride = src_stride * (int) sizeof (uint32_t) / 4; - dst_stride = dst_stride * (int) sizeof (uint32_t) / 4; - src_bytes = (uint8_t *)(((uint32_t *)src_bits) + src_stride * (src_y) + (src_x)); - dst_bytes = (uint8_t *)(((uint32_t *)dst_bits) + dst_stride * (dest_y) + (dest_x)); - byte_width = 4 * width; - src_stride *= 4; - dst_stride *= 4; - } - else - { - return FALSE; - } - - while (height--) - { - int w; - uint8_t *s = src_bytes; - uint8_t *d = dst_bytes; - src_bytes += src_stride; - dst_bytes += dst_stride; - w = byte_width; - - while (w >= 2 && ((uintptr_t)d & 3)) - { - *(uint16_t *)d = *(uint16_t *)s; - w -= 2; - s += 2; - d += 2; - } - - while (w >= 4 && ((uintptr_t)d & 15)) - { - *(uint32_t *)d = *(uint32_t *)s; - - w -= 4; - s += 4; - d += 4; - } - - while (w >= 64) - { - __m128i xmm0, xmm1, xmm2, xmm3; - - xmm0 = load_128_unaligned ((__m128i*)(s)); - xmm1 = load_128_unaligned ((__m128i*)(s + 16)); - xmm2 = load_128_unaligned ((__m128i*)(s + 32)); - xmm3 = load_128_unaligned ((__m128i*)(s + 48)); - - save_128_aligned ((__m128i*)(d), xmm0); - save_128_aligned ((__m128i*)(d + 16), xmm1); - save_128_aligned ((__m128i*)(d + 32), xmm2); - save_128_aligned ((__m128i*)(d + 48), xmm3); - - s += 64; - d += 64; - w -= 64; - } - - while (w >= 16) - { - save_128_aligned ((__m128i*)d, load_128_unaligned ((__m128i*)s) ); - - w -= 16; - d += 16; - s += 16; - } - - while (w >= 4) - { - *(uint32_t *)d = *(uint32_t *)s; - - w -= 4; - s += 4; - d += 4; - } - - if (w >= 2) - { - *(uint16_t *)d = *(uint16_t *)s; - w -= 2; - s += 2; - d += 2; - } - } - - return TRUE; -} - -static void -sse2_composite_copy_area (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - sse2_blt (imp, src_image->bits.bits, - dest_image->bits.bits, - src_image->bits.rowstride, - dest_image->bits.rowstride, - PIXMAN_FORMAT_BPP (src_image->bits.format), - PIXMAN_FORMAT_BPP (dest_image->bits.format), - src_x, src_y, dest_x, dest_y, width, height); -} - -static void -sse2_composite_over_x888_8_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t *src, *src_line, s; - uint32_t *dst, *dst_line, d; - uint8_t *mask, *mask_line; - uint32_t m; - int src_stride, mask_stride, dst_stride; - int32_t w; - __m128i ms; - - __m128i xmm_src, xmm_src_lo, xmm_src_hi; - __m128i xmm_dst, xmm_dst_lo, xmm_dst_hi; - __m128i xmm_mask, xmm_mask_lo, xmm_mask_hi; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE ( - mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); - PIXMAN_IMAGE_GET_LINE ( - src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - - while (height--) - { - src = src_line; - src_line += src_stride; - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - - w = width; - - while (w && (uintptr_t)dst & 15) - { - s = 0xff000000 | *src++; - m = (uint32_t) *mask++; - d = *dst; - ms = unpack_32_1x128 (s); - - if (m != 0xff) - { - __m128i ma = expand_alpha_rev_1x128 (unpack_32_1x128 (m)); - __m128i md = unpack_32_1x128 (d); - - ms = in_over_1x128 (&ms, &mask_00ff, &ma, &md); - } - - *dst++ = pack_1x128_32 (ms); - w--; - } - - while (w >= 4) - { - m = *(uint32_t*) mask; - xmm_src = _mm_or_si128 ( - load_128_unaligned ((__m128i*)src), mask_ff000000); - - if (m == 0xffffffff) - { - save_128_aligned ((__m128i*)dst, xmm_src); - } - else - { - xmm_dst = load_128_aligned ((__m128i*)dst); - - xmm_mask = _mm_unpacklo_epi16 (unpack_32_1x128 (m), _mm_setzero_si128()); - - unpack_128_2x128 (xmm_src, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_mask, &xmm_mask_lo, &xmm_mask_hi); - unpack_128_2x128 (xmm_dst, &xmm_dst_lo, &xmm_dst_hi); - - expand_alpha_rev_2x128 ( - xmm_mask_lo, xmm_mask_hi, &xmm_mask_lo, &xmm_mask_hi); - - in_over_2x128 (&xmm_src_lo, &xmm_src_hi, - &mask_00ff, &mask_00ff, &xmm_mask_lo, &xmm_mask_hi, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ((__m128i*)dst, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - } - - src += 4; - dst += 4; - mask += 4; - w -= 4; - } - - while (w) - { - m = (uint32_t) *mask++; - - if (m) - { - s = 0xff000000 | *src; - - if (m == 0xff) - { - *dst = s; - } - else - { - __m128i ma, md, ms; - - d = *dst; - - ma = expand_alpha_rev_1x128 (unpack_32_1x128 (m)); - md = unpack_32_1x128 (d); - ms = unpack_32_1x128 (s); - - *dst = pack_1x128_32 (in_over_1x128 (&ms, &mask_00ff, &ma, &md)); - } - - } - - src++; - dst++; - w--; - } - } - -} - -static void -sse2_composite_over_8888_8_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t *src, *src_line, s; - uint32_t *dst, *dst_line, d; - uint8_t *mask, *mask_line; - uint32_t m; - int src_stride, mask_stride, dst_stride; - int32_t w; - - __m128i xmm_src, xmm_src_lo, xmm_src_hi, xmm_srca_lo, xmm_srca_hi; - __m128i xmm_dst, xmm_dst_lo, xmm_dst_hi; - __m128i xmm_mask, xmm_mask_lo, xmm_mask_hi; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE ( - mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); - PIXMAN_IMAGE_GET_LINE ( - src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - - while (height--) - { - src = src_line; - src_line += src_stride; - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - - w = width; - - while (w && (uintptr_t)dst & 15) - { - uint32_t sa; - - s = *src++; - m = (uint32_t) *mask++; - d = *dst; - - sa = s >> 24; - - if (m) - { - if (sa == 0xff && m == 0xff) - { - *dst = s; - } - else - { - __m128i ms, md, ma, msa; - - ma = expand_alpha_rev_1x128 (load_32_1x128 (m)); - ms = unpack_32_1x128 (s); - md = unpack_32_1x128 (d); - - msa = expand_alpha_rev_1x128 (load_32_1x128 (sa)); - - *dst = pack_1x128_32 (in_over_1x128 (&ms, &msa, &ma, &md)); - } - } - - dst++; - w--; - } - - while (w >= 4) - { - m = *(uint32_t *) mask; - - if (m) - { - xmm_src = load_128_unaligned ((__m128i*)src); - - if (m == 0xffffffff && is_opaque (xmm_src)) - { - save_128_aligned ((__m128i *)dst, xmm_src); - } - else - { - xmm_dst = load_128_aligned ((__m128i *)dst); - - xmm_mask = _mm_unpacklo_epi16 (unpack_32_1x128 (m), _mm_setzero_si128()); - - unpack_128_2x128 (xmm_src, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_mask, &xmm_mask_lo, &xmm_mask_hi); - unpack_128_2x128 (xmm_dst, &xmm_dst_lo, &xmm_dst_hi); - - expand_alpha_2x128 (xmm_src_lo, xmm_src_hi, &xmm_srca_lo, &xmm_srca_hi); - expand_alpha_rev_2x128 (xmm_mask_lo, xmm_mask_hi, &xmm_mask_lo, &xmm_mask_hi); - - in_over_2x128 (&xmm_src_lo, &xmm_src_hi, &xmm_srca_lo, &xmm_srca_hi, - &xmm_mask_lo, &xmm_mask_hi, &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ((__m128i*)dst, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - } - } - - src += 4; - dst += 4; - mask += 4; - w -= 4; - } - - while (w) - { - uint32_t sa; - - s = *src++; - m = (uint32_t) *mask++; - d = *dst; - - sa = s >> 24; - - if (m) - { - if (sa == 0xff && m == 0xff) - { - *dst = s; - } - else - { - __m128i ms, md, ma, msa; - - ma = expand_alpha_rev_1x128 (load_32_1x128 (m)); - ms = unpack_32_1x128 (s); - md = unpack_32_1x128 (d); - - msa = expand_alpha_rev_1x128 (load_32_1x128 (sa)); - - *dst = pack_1x128_32 (in_over_1x128 (&ms, &msa, &ma, &md)); - } - } - - dst++; - w--; - } - } - -} - -static void -sse2_composite_over_reverse_n_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src; - uint32_t *dst_line, *dst; - __m128i xmm_src; - __m128i xmm_dst, xmm_dst_lo, xmm_dst_hi; - __m128i xmm_dsta_hi, xmm_dsta_lo; - int dst_stride; - int32_t w; - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - if (src == 0) - return; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - - xmm_src = expand_pixel_32_1x128 (src); - - while (height--) - { - dst = dst_line; - - dst_line += dst_stride; - w = width; - - while (w && (uintptr_t)dst & 15) - { - __m128i vd; - - vd = unpack_32_1x128 (*dst); - - *dst = pack_1x128_32 (over_1x128 (vd, expand_alpha_1x128 (vd), - xmm_src)); - w--; - dst++; - } - - while (w >= 4) - { - __m128i tmp_lo, tmp_hi; - - xmm_dst = load_128_aligned ((__m128i*)dst); - - unpack_128_2x128 (xmm_dst, &xmm_dst_lo, &xmm_dst_hi); - expand_alpha_2x128 (xmm_dst_lo, xmm_dst_hi, &xmm_dsta_lo, &xmm_dsta_hi); - - tmp_lo = xmm_src; - tmp_hi = xmm_src; - - over_2x128 (&xmm_dst_lo, &xmm_dst_hi, - &xmm_dsta_lo, &xmm_dsta_hi, - &tmp_lo, &tmp_hi); - - save_128_aligned ( - (__m128i*)dst, pack_2x128_128 (tmp_lo, tmp_hi)); - - w -= 4; - dst += 4; - } - - while (w) - { - __m128i vd; - - vd = unpack_32_1x128 (*dst); - - *dst = pack_1x128_32 (over_1x128 (vd, expand_alpha_1x128 (vd), - xmm_src)); - w--; - dst++; - } - - } - -} - -static void -sse2_composite_over_8888_8888_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t *src, *src_line, s; - uint32_t *dst, *dst_line, d; - uint32_t *mask, *mask_line; - uint32_t m; - int src_stride, mask_stride, dst_stride; - int32_t w; - - __m128i xmm_src, xmm_src_lo, xmm_src_hi, xmm_srca_lo, xmm_srca_hi; - __m128i xmm_dst, xmm_dst_lo, xmm_dst_hi; - __m128i xmm_mask, xmm_mask_lo, xmm_mask_hi; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE ( - mask_image, mask_x, mask_y, uint32_t, mask_stride, mask_line, 1); - PIXMAN_IMAGE_GET_LINE ( - src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - - while (height--) - { - src = src_line; - src_line += src_stride; - dst = dst_line; - dst_line += dst_stride; - mask = mask_line; - mask_line += mask_stride; - - w = width; - - while (w && (uintptr_t)dst & 15) - { - uint32_t sa; - - s = *src++; - m = (*mask++) >> 24; - d = *dst; - - sa = s >> 24; - - if (m) - { - if (sa == 0xff && m == 0xff) - { - *dst = s; - } - else - { - __m128i ms, md, ma, msa; - - ma = expand_alpha_rev_1x128 (load_32_1x128 (m)); - ms = unpack_32_1x128 (s); - md = unpack_32_1x128 (d); - - msa = expand_alpha_rev_1x128 (load_32_1x128 (sa)); - - *dst = pack_1x128_32 (in_over_1x128 (&ms, &msa, &ma, &md)); - } - } - - dst++; - w--; - } - - while (w >= 4) - { - xmm_mask = load_128_unaligned ((__m128i*)mask); - - if (!is_transparent (xmm_mask)) - { - xmm_src = load_128_unaligned ((__m128i*)src); - - if (is_opaque (xmm_mask) && is_opaque (xmm_src)) - { - save_128_aligned ((__m128i *)dst, xmm_src); - } - else - { - xmm_dst = load_128_aligned ((__m128i *)dst); - - unpack_128_2x128 (xmm_src, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_mask, &xmm_mask_lo, &xmm_mask_hi); - unpack_128_2x128 (xmm_dst, &xmm_dst_lo, &xmm_dst_hi); - - expand_alpha_2x128 (xmm_src_lo, xmm_src_hi, &xmm_srca_lo, &xmm_srca_hi); - expand_alpha_2x128 (xmm_mask_lo, xmm_mask_hi, &xmm_mask_lo, &xmm_mask_hi); - - in_over_2x128 (&xmm_src_lo, &xmm_src_hi, &xmm_srca_lo, &xmm_srca_hi, - &xmm_mask_lo, &xmm_mask_hi, &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ((__m128i*)dst, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - } - } - - src += 4; - dst += 4; - mask += 4; - w -= 4; - } - - while (w) - { - uint32_t sa; - - s = *src++; - m = (*mask++) >> 24; - d = *dst; - - sa = s >> 24; - - if (m) - { - if (sa == 0xff && m == 0xff) - { - *dst = s; - } - else - { - __m128i ms, md, ma, msa; - - ma = expand_alpha_rev_1x128 (load_32_1x128 (m)); - ms = unpack_32_1x128 (s); - md = unpack_32_1x128 (d); - - msa = expand_alpha_rev_1x128 (load_32_1x128 (sa)); - - *dst = pack_1x128_32 (in_over_1x128 (&ms, &msa, &ma, &md)); - } - } - - dst++; - w--; - } - } - -} - -/* A variant of 'sse2_combine_over_u' with minor tweaks */ -static force_inline void -scaled_nearest_scanline_sse2_8888_8888_OVER (uint32_t* pd, - const uint32_t* ps, - int32_t w, - pixman_fixed_t vx, - pixman_fixed_t unit_x, - pixman_fixed_t src_width_fixed, - pixman_bool_t fully_transparent_src) -{ - uint32_t s, d; - const uint32_t* pm = NULL; - - __m128i xmm_dst_lo, xmm_dst_hi; - __m128i xmm_src_lo, xmm_src_hi; - __m128i xmm_alpha_lo, xmm_alpha_hi; - - if (fully_transparent_src) - return; - - /* Align dst on a 16-byte boundary */ - while (w && ((uintptr_t)pd & 15)) - { - d = *pd; - s = combine1 (ps + pixman_fixed_to_int (vx), pm); - vx += unit_x; - while (vx >= 0) - vx -= src_width_fixed; - - *pd++ = core_combine_over_u_pixel_sse2 (s, d); - if (pm) - pm++; - w--; - } - - while (w >= 4) - { - __m128i tmp; - uint32_t tmp1, tmp2, tmp3, tmp4; - - tmp1 = *(ps + pixman_fixed_to_int (vx)); - vx += unit_x; - while (vx >= 0) - vx -= src_width_fixed; - tmp2 = *(ps + pixman_fixed_to_int (vx)); - vx += unit_x; - while (vx >= 0) - vx -= src_width_fixed; - tmp3 = *(ps + pixman_fixed_to_int (vx)); - vx += unit_x; - while (vx >= 0) - vx -= src_width_fixed; - tmp4 = *(ps + pixman_fixed_to_int (vx)); - vx += unit_x; - while (vx >= 0) - vx -= src_width_fixed; - - tmp = _mm_set_epi32 (tmp4, tmp3, tmp2, tmp1); - - xmm_src_hi = combine4 ((__m128i*)&tmp, (__m128i*)pm); - - if (is_opaque (xmm_src_hi)) - { - save_128_aligned ((__m128i*)pd, xmm_src_hi); - } - else if (!is_zero (xmm_src_hi)) - { - xmm_dst_hi = load_128_aligned ((__m128i*) pd); - - unpack_128_2x128 (xmm_src_hi, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_dst_hi, &xmm_dst_lo, &xmm_dst_hi); - - expand_alpha_2x128 ( - xmm_src_lo, xmm_src_hi, &xmm_alpha_lo, &xmm_alpha_hi); - - over_2x128 (&xmm_src_lo, &xmm_src_hi, - &xmm_alpha_lo, &xmm_alpha_hi, - &xmm_dst_lo, &xmm_dst_hi); - - /* rebuid the 4 pixel data and save*/ - save_128_aligned ((__m128i*)pd, - pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - } - - w -= 4; - pd += 4; - if (pm) - pm += 4; - } - - while (w) - { - d = *pd; - s = combine1 (ps + pixman_fixed_to_int (vx), pm); - vx += unit_x; - while (vx >= 0) - vx -= src_width_fixed; - - *pd++ = core_combine_over_u_pixel_sse2 (s, d); - if (pm) - pm++; - - w--; - } -} - -FAST_NEAREST_MAINLOOP (sse2_8888_8888_cover_OVER, - scaled_nearest_scanline_sse2_8888_8888_OVER, - uint32_t, uint32_t, COVER) -FAST_NEAREST_MAINLOOP (sse2_8888_8888_none_OVER, - scaled_nearest_scanline_sse2_8888_8888_OVER, - uint32_t, uint32_t, NONE) -FAST_NEAREST_MAINLOOP (sse2_8888_8888_pad_OVER, - scaled_nearest_scanline_sse2_8888_8888_OVER, - uint32_t, uint32_t, PAD) -FAST_NEAREST_MAINLOOP (sse2_8888_8888_normal_OVER, - scaled_nearest_scanline_sse2_8888_8888_OVER, - uint32_t, uint32_t, NORMAL) - -static force_inline void -scaled_nearest_scanline_sse2_8888_n_8888_OVER (const uint32_t * mask, - uint32_t * dst, - const uint32_t * src, - int32_t w, - pixman_fixed_t vx, - pixman_fixed_t unit_x, - pixman_fixed_t src_width_fixed, - pixman_bool_t zero_src) -{ - __m128i xmm_mask; - __m128i xmm_src, xmm_src_lo, xmm_src_hi; - __m128i xmm_dst, xmm_dst_lo, xmm_dst_hi; - __m128i xmm_alpha_lo, xmm_alpha_hi; - - if (zero_src || (*mask >> 24) == 0) - return; - - xmm_mask = create_mask_16_128 (*mask >> 24); - - while (w && (uintptr_t)dst & 15) - { - uint32_t s = *(src + pixman_fixed_to_int (vx)); - vx += unit_x; - while (vx >= 0) - vx -= src_width_fixed; - - if (s) - { - uint32_t d = *dst; - - __m128i ms = unpack_32_1x128 (s); - __m128i alpha = expand_alpha_1x128 (ms); - __m128i dest = xmm_mask; - __m128i alpha_dst = unpack_32_1x128 (d); - - *dst = pack_1x128_32 ( - in_over_1x128 (&ms, &alpha, &dest, &alpha_dst)); - } - dst++; - w--; - } - - while (w >= 4) - { - uint32_t tmp1, tmp2, tmp3, tmp4; - - tmp1 = *(src + pixman_fixed_to_int (vx)); - vx += unit_x; - while (vx >= 0) - vx -= src_width_fixed; - tmp2 = *(src + pixman_fixed_to_int (vx)); - vx += unit_x; - while (vx >= 0) - vx -= src_width_fixed; - tmp3 = *(src + pixman_fixed_to_int (vx)); - vx += unit_x; - while (vx >= 0) - vx -= src_width_fixed; - tmp4 = *(src + pixman_fixed_to_int (vx)); - vx += unit_x; - while (vx >= 0) - vx -= src_width_fixed; - - xmm_src = _mm_set_epi32 (tmp4, tmp3, tmp2, tmp1); - - if (!is_zero (xmm_src)) - { - xmm_dst = load_128_aligned ((__m128i*)dst); - - unpack_128_2x128 (xmm_src, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_dst, &xmm_dst_lo, &xmm_dst_hi); - expand_alpha_2x128 (xmm_src_lo, xmm_src_hi, - &xmm_alpha_lo, &xmm_alpha_hi); - - in_over_2x128 (&xmm_src_lo, &xmm_src_hi, - &xmm_alpha_lo, &xmm_alpha_hi, - &xmm_mask, &xmm_mask, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ( - (__m128i*)dst, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - } - - dst += 4; - w -= 4; - } - - while (w) - { - uint32_t s = *(src + pixman_fixed_to_int (vx)); - vx += unit_x; - while (vx >= 0) - vx -= src_width_fixed; - - if (s) - { - uint32_t d = *dst; - - __m128i ms = unpack_32_1x128 (s); - __m128i alpha = expand_alpha_1x128 (ms); - __m128i mask = xmm_mask; - __m128i dest = unpack_32_1x128 (d); - - *dst = pack_1x128_32 ( - in_over_1x128 (&ms, &alpha, &mask, &dest)); - } - - dst++; - w--; - } - -} - -FAST_NEAREST_MAINLOOP_COMMON (sse2_8888_n_8888_cover_OVER, - scaled_nearest_scanline_sse2_8888_n_8888_OVER, - uint32_t, uint32_t, uint32_t, COVER, TRUE, TRUE) -FAST_NEAREST_MAINLOOP_COMMON (sse2_8888_n_8888_pad_OVER, - scaled_nearest_scanline_sse2_8888_n_8888_OVER, - uint32_t, uint32_t, uint32_t, PAD, TRUE, TRUE) -FAST_NEAREST_MAINLOOP_COMMON (sse2_8888_n_8888_none_OVER, - scaled_nearest_scanline_sse2_8888_n_8888_OVER, - uint32_t, uint32_t, uint32_t, NONE, TRUE, TRUE) -FAST_NEAREST_MAINLOOP_COMMON (sse2_8888_n_8888_normal_OVER, - scaled_nearest_scanline_sse2_8888_n_8888_OVER, - uint32_t, uint32_t, uint32_t, NORMAL, TRUE, TRUE) - -#if PSHUFD_IS_FAST - -/***********************************************************************************/ - -# define BILINEAR_DECLARE_VARIABLES \ - const __m128i xmm_wt = _mm_set_epi16 (wt, wt, wt, wt, wt, wt, wt, wt); \ - const __m128i xmm_wb = _mm_set_epi16 (wb, wb, wb, wb, wb, wb, wb, wb); \ - const __m128i xmm_addc = _mm_set_epi16 (0, 1, 0, 1, 0, 1, 0, 1); \ - const __m128i xmm_ux1 = _mm_set_epi16 (unit_x, -unit_x, unit_x, -unit_x, \ - unit_x, -unit_x, unit_x, -unit_x); \ - const __m128i xmm_ux4 = _mm_set_epi16 (unit_x * 4, -unit_x * 4, \ - unit_x * 4, -unit_x * 4, \ - unit_x * 4, -unit_x * 4, \ - unit_x * 4, -unit_x * 4); \ - const __m128i xmm_zero = _mm_setzero_si128 (); \ - __m128i xmm_x = _mm_set_epi16 (vx + unit_x * 3, -(vx + 1) - unit_x * 3, \ - vx + unit_x * 2, -(vx + 1) - unit_x * 2, \ - vx + unit_x * 1, -(vx + 1) - unit_x * 1, \ - vx + unit_x * 0, -(vx + 1) - unit_x * 0); \ - __m128i xmm_wh_state; - -#define BILINEAR_INTERPOLATE_ONE_PIXEL_HELPER(pix, phase_) \ -do { \ - int phase = phase_; \ - __m128i xmm_wh, xmm_a, xmm_b; \ - /* fetch 2x2 pixel block into sse2 registers */ \ - __m128i tltr = _mm_loadl_epi64 ((__m128i *)&src_top[vx >> 16]); \ - __m128i blbr = _mm_loadl_epi64 ((__m128i *)&src_bottom[vx >> 16]); \ - vx += unit_x; \ - /* vertical interpolation */ \ - xmm_a = _mm_mullo_epi16 (_mm_unpacklo_epi8 (tltr, xmm_zero), xmm_wt); \ - xmm_b = _mm_mullo_epi16 (_mm_unpacklo_epi8 (blbr, xmm_zero), xmm_wb); \ - xmm_a = _mm_add_epi16 (xmm_a, xmm_b); \ - /* calculate horizontal weights */ \ - if (phase <= 0) \ - { \ - xmm_wh_state = _mm_add_epi16 (xmm_addc, _mm_srli_epi16 (xmm_x, \ - 16 - BILINEAR_INTERPOLATION_BITS)); \ - xmm_x = _mm_add_epi16 (xmm_x, (phase < 0) ? xmm_ux1 : xmm_ux4); \ - phase = 0; \ - } \ - xmm_wh = _mm_shuffle_epi32 (xmm_wh_state, _MM_SHUFFLE (phase, phase, \ - phase, phase)); \ - /* horizontal interpolation */ \ - xmm_a = _mm_madd_epi16 (_mm_unpackhi_epi16 (_mm_shuffle_epi32 ( \ - xmm_a, _MM_SHUFFLE (1, 0, 3, 2)), xmm_a), xmm_wh); \ - /* shift the result */ \ - pix = _mm_srli_epi32 (xmm_a, BILINEAR_INTERPOLATION_BITS * 2); \ -} while (0) - -#else /************************************************************************/ - -# define BILINEAR_DECLARE_VARIABLES \ - const __m128i xmm_wt = _mm_set_epi16 (wt, wt, wt, wt, wt, wt, wt, wt); \ - const __m128i xmm_wb = _mm_set_epi16 (wb, wb, wb, wb, wb, wb, wb, wb); \ - const __m128i xmm_addc = _mm_set_epi16 (0, 1, 0, 1, 0, 1, 0, 1); \ - const __m128i xmm_ux1 = _mm_set_epi16 (unit_x, -unit_x, unit_x, -unit_x, \ - unit_x, -unit_x, unit_x, -unit_x); \ - const __m128i xmm_ux4 = _mm_set_epi16 (unit_x * 4, -unit_x * 4, \ - unit_x * 4, -unit_x * 4, \ - unit_x * 4, -unit_x * 4, \ - unit_x * 4, -unit_x * 4); \ - const __m128i xmm_zero = _mm_setzero_si128 (); \ - __m128i xmm_x = _mm_set_epi16 (vx, -(vx + 1), vx, -(vx + 1), \ - vx, -(vx + 1), vx, -(vx + 1)) - -#define BILINEAR_INTERPOLATE_ONE_PIXEL_HELPER(pix, phase) \ -do { \ - __m128i xmm_wh, xmm_a, xmm_b; \ - /* fetch 2x2 pixel block into sse2 registers */ \ - __m128i tltr = _mm_loadl_epi64 ((__m128i *)&src_top[vx >> 16]); \ - __m128i blbr = _mm_loadl_epi64 ((__m128i *)&src_bottom[vx >> 16]); \ - (void)xmm_ux4; /* suppress warning: unused variable 'xmm_ux4' */ \ - vx += unit_x; \ - /* vertical interpolation */ \ - xmm_a = _mm_mullo_epi16 (_mm_unpacklo_epi8 (tltr, xmm_zero), xmm_wt); \ - xmm_b = _mm_mullo_epi16 (_mm_unpacklo_epi8 (blbr, xmm_zero), xmm_wb); \ - xmm_a = _mm_add_epi16 (xmm_a, xmm_b); \ - /* calculate horizontal weights */ \ - xmm_wh = _mm_add_epi16 (xmm_addc, _mm_srli_epi16 (xmm_x, \ - 16 - BILINEAR_INTERPOLATION_BITS)); \ - xmm_x = _mm_add_epi16 (xmm_x, xmm_ux1); \ - /* horizontal interpolation */ \ - xmm_b = _mm_unpacklo_epi64 (/* any value is fine here */ xmm_b, xmm_a); \ - xmm_a = _mm_madd_epi16 (_mm_unpackhi_epi16 (xmm_b, xmm_a), xmm_wh); \ - /* shift the result */ \ - pix = _mm_srli_epi32 (xmm_a, BILINEAR_INTERPOLATION_BITS * 2); \ -} while (0) - -/***********************************************************************************/ - -#endif - -#define BILINEAR_INTERPOLATE_ONE_PIXEL(pix); \ -do { \ - __m128i xmm_pix; \ - BILINEAR_INTERPOLATE_ONE_PIXEL_HELPER (xmm_pix, -1); \ - xmm_pix = _mm_packs_epi32 (xmm_pix, xmm_pix); \ - xmm_pix = _mm_packus_epi16 (xmm_pix, xmm_pix); \ - pix = _mm_cvtsi128_si32 (xmm_pix); \ -} while(0) - -#define BILINEAR_INTERPOLATE_FOUR_PIXELS(pix); \ -do { \ - __m128i xmm_pix1, xmm_pix2, xmm_pix3, xmm_pix4; \ - BILINEAR_INTERPOLATE_ONE_PIXEL_HELPER (xmm_pix1, 0); \ - BILINEAR_INTERPOLATE_ONE_PIXEL_HELPER (xmm_pix2, 1); \ - BILINEAR_INTERPOLATE_ONE_PIXEL_HELPER (xmm_pix3, 2); \ - BILINEAR_INTERPOLATE_ONE_PIXEL_HELPER (xmm_pix4, 3); \ - xmm_pix1 = _mm_packs_epi32 (xmm_pix1, xmm_pix2); \ - xmm_pix3 = _mm_packs_epi32 (xmm_pix3, xmm_pix4); \ - pix = _mm_packus_epi16 (xmm_pix1, xmm_pix3); \ -} while(0) - -#define BILINEAR_SKIP_ONE_PIXEL() \ -do { \ - vx += unit_x; \ - xmm_x = _mm_add_epi16 (xmm_x, xmm_ux1); \ -} while(0) - -#define BILINEAR_SKIP_FOUR_PIXELS() \ -do { \ - vx += unit_x * 4; \ - xmm_x = _mm_add_epi16 (xmm_x, xmm_ux4); \ -} while(0) - -/***********************************************************************************/ - -static force_inline void -scaled_bilinear_scanline_sse2_8888_8888_SRC (uint32_t * dst, - const uint32_t * mask, - const uint32_t * src_top, - const uint32_t * src_bottom, - int32_t w, - int wt, - int wb, - pixman_fixed_t vx_, - pixman_fixed_t unit_x_, - pixman_fixed_t max_vx, - pixman_bool_t zero_src) -{ - intptr_t vx = vx_; - intptr_t unit_x = unit_x_; - BILINEAR_DECLARE_VARIABLES; - uint32_t pix1, pix2; - - while (w && ((uintptr_t)dst & 15)) - { - BILINEAR_INTERPOLATE_ONE_PIXEL (pix1); - *dst++ = pix1; - w--; - } - - while ((w -= 4) >= 0) { - __m128i xmm_src; - BILINEAR_INTERPOLATE_FOUR_PIXELS (xmm_src); - _mm_store_si128 ((__m128i *)dst, xmm_src); - dst += 4; - } - - if (w & 2) - { - BILINEAR_INTERPOLATE_ONE_PIXEL (pix1); - BILINEAR_INTERPOLATE_ONE_PIXEL (pix2); - *dst++ = pix1; - *dst++ = pix2; - } - - if (w & 1) - { - BILINEAR_INTERPOLATE_ONE_PIXEL (pix1); - *dst = pix1; - } - -} - -FAST_BILINEAR_MAINLOOP_COMMON (sse2_8888_8888_cover_SRC, - scaled_bilinear_scanline_sse2_8888_8888_SRC, - uint32_t, uint32_t, uint32_t, - COVER, FLAG_NONE) -FAST_BILINEAR_MAINLOOP_COMMON (sse2_8888_8888_pad_SRC, - scaled_bilinear_scanline_sse2_8888_8888_SRC, - uint32_t, uint32_t, uint32_t, - PAD, FLAG_NONE) -FAST_BILINEAR_MAINLOOP_COMMON (sse2_8888_8888_none_SRC, - scaled_bilinear_scanline_sse2_8888_8888_SRC, - uint32_t, uint32_t, uint32_t, - NONE, FLAG_NONE) -FAST_BILINEAR_MAINLOOP_COMMON (sse2_8888_8888_normal_SRC, - scaled_bilinear_scanline_sse2_8888_8888_SRC, - uint32_t, uint32_t, uint32_t, - NORMAL, FLAG_NONE) - -static force_inline void -scaled_bilinear_scanline_sse2_x888_8888_SRC (uint32_t * dst, - const uint32_t * mask, - const uint32_t * src_top, - const uint32_t * src_bottom, - int32_t w, - int wt, - int wb, - pixman_fixed_t vx_, - pixman_fixed_t unit_x_, - pixman_fixed_t max_vx, - pixman_bool_t zero_src) -{ - intptr_t vx = vx_; - intptr_t unit_x = unit_x_; - BILINEAR_DECLARE_VARIABLES; - uint32_t pix1, pix2; - - while (w && ((uintptr_t)dst & 15)) - { - BILINEAR_INTERPOLATE_ONE_PIXEL (pix1); - *dst++ = pix1 | 0xFF000000; - w--; - } - - while ((w -= 4) >= 0) { - __m128i xmm_src; - BILINEAR_INTERPOLATE_FOUR_PIXELS (xmm_src); - _mm_store_si128 ((__m128i *)dst, _mm_or_si128 (xmm_src, mask_ff000000)); - dst += 4; - } - - if (w & 2) - { - BILINEAR_INTERPOLATE_ONE_PIXEL (pix1); - BILINEAR_INTERPOLATE_ONE_PIXEL (pix2); - *dst++ = pix1 | 0xFF000000; - *dst++ = pix2 | 0xFF000000; - } - - if (w & 1) - { - BILINEAR_INTERPOLATE_ONE_PIXEL (pix1); - *dst = pix1 | 0xFF000000; - } -} - -FAST_BILINEAR_MAINLOOP_COMMON (sse2_x888_8888_cover_SRC, - scaled_bilinear_scanline_sse2_x888_8888_SRC, - uint32_t, uint32_t, uint32_t, - COVER, FLAG_NONE) -FAST_BILINEAR_MAINLOOP_COMMON (sse2_x888_8888_pad_SRC, - scaled_bilinear_scanline_sse2_x888_8888_SRC, - uint32_t, uint32_t, uint32_t, - PAD, FLAG_NONE) -FAST_BILINEAR_MAINLOOP_COMMON (sse2_x888_8888_normal_SRC, - scaled_bilinear_scanline_sse2_x888_8888_SRC, - uint32_t, uint32_t, uint32_t, - NORMAL, FLAG_NONE) - -static force_inline void -scaled_bilinear_scanline_sse2_8888_8888_OVER (uint32_t * dst, - const uint32_t * mask, - const uint32_t * src_top, - const uint32_t * src_bottom, - int32_t w, - int wt, - int wb, - pixman_fixed_t vx_, - pixman_fixed_t unit_x_, - pixman_fixed_t max_vx, - pixman_bool_t zero_src) -{ - intptr_t vx = vx_; - intptr_t unit_x = unit_x_; - BILINEAR_DECLARE_VARIABLES; - uint32_t pix1, pix2; - - while (w && ((uintptr_t)dst & 15)) - { - BILINEAR_INTERPOLATE_ONE_PIXEL (pix1); - - if (pix1) - { - pix2 = *dst; - *dst = core_combine_over_u_pixel_sse2 (pix1, pix2); - } - - w--; - dst++; - } - - while (w >= 4) - { - __m128i xmm_src; - __m128i xmm_src_hi, xmm_src_lo, xmm_dst_hi, xmm_dst_lo; - __m128i xmm_alpha_hi, xmm_alpha_lo; - - BILINEAR_INTERPOLATE_FOUR_PIXELS (xmm_src); - - if (!is_zero (xmm_src)) - { - if (is_opaque (xmm_src)) - { - save_128_aligned ((__m128i *)dst, xmm_src); - } - else - { - __m128i xmm_dst = load_128_aligned ((__m128i *)dst); - - unpack_128_2x128 (xmm_src, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_dst, &xmm_dst_lo, &xmm_dst_hi); - - expand_alpha_2x128 (xmm_src_lo, xmm_src_hi, &xmm_alpha_lo, &xmm_alpha_hi); - over_2x128 (&xmm_src_lo, &xmm_src_hi, &xmm_alpha_lo, &xmm_alpha_hi, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ((__m128i *)dst, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - } - } - - w -= 4; - dst += 4; - } - - while (w) - { - BILINEAR_INTERPOLATE_ONE_PIXEL (pix1); - - if (pix1) - { - pix2 = *dst; - *dst = core_combine_over_u_pixel_sse2 (pix1, pix2); - } - - w--; - dst++; - } -} - -FAST_BILINEAR_MAINLOOP_COMMON (sse2_8888_8888_cover_OVER, - scaled_bilinear_scanline_sse2_8888_8888_OVER, - uint32_t, uint32_t, uint32_t, - COVER, FLAG_NONE) -FAST_BILINEAR_MAINLOOP_COMMON (sse2_8888_8888_pad_OVER, - scaled_bilinear_scanline_sse2_8888_8888_OVER, - uint32_t, uint32_t, uint32_t, - PAD, FLAG_NONE) -FAST_BILINEAR_MAINLOOP_COMMON (sse2_8888_8888_none_OVER, - scaled_bilinear_scanline_sse2_8888_8888_OVER, - uint32_t, uint32_t, uint32_t, - NONE, FLAG_NONE) -FAST_BILINEAR_MAINLOOP_COMMON (sse2_8888_8888_normal_OVER, - scaled_bilinear_scanline_sse2_8888_8888_OVER, - uint32_t, uint32_t, uint32_t, - NORMAL, FLAG_NONE) - -static force_inline void -scaled_bilinear_scanline_sse2_8888_8_8888_OVER (uint32_t * dst, - const uint8_t * mask, - const uint32_t * src_top, - const uint32_t * src_bottom, - int32_t w, - int wt, - int wb, - pixman_fixed_t vx_, - pixman_fixed_t unit_x_, - pixman_fixed_t max_vx, - pixman_bool_t zero_src) -{ - intptr_t vx = vx_; - intptr_t unit_x = unit_x_; - BILINEAR_DECLARE_VARIABLES; - uint32_t pix1, pix2; - uint32_t m; - - while (w && ((uintptr_t)dst & 15)) - { - uint32_t sa; - - m = (uint32_t) *mask++; - - if (m) - { - BILINEAR_INTERPOLATE_ONE_PIXEL (pix1); - sa = pix1 >> 24; - - if (sa == 0xff && m == 0xff) - { - *dst = pix1; - } - else - { - __m128i ms, md, ma, msa; - - pix2 = *dst; - ma = expand_alpha_rev_1x128 (load_32_1x128 (m)); - ms = unpack_32_1x128 (pix1); - md = unpack_32_1x128 (pix2); - - msa = expand_alpha_rev_1x128 (load_32_1x128 (sa)); - - *dst = pack_1x128_32 (in_over_1x128 (&ms, &msa, &ma, &md)); - } - } - else - { - BILINEAR_SKIP_ONE_PIXEL (); - } - - w--; - dst++; - } - - while (w >= 4) - { - __m128i xmm_src, xmm_src_lo, xmm_src_hi, xmm_srca_lo, xmm_srca_hi; - __m128i xmm_dst, xmm_dst_lo, xmm_dst_hi; - __m128i xmm_mask, xmm_mask_lo, xmm_mask_hi; - - m = *(uint32_t*)mask; - - if (m) - { - BILINEAR_INTERPOLATE_FOUR_PIXELS (xmm_src); - - if (m == 0xffffffff && is_opaque (xmm_src)) - { - save_128_aligned ((__m128i *)dst, xmm_src); - } - else - { - xmm_dst = load_128_aligned ((__m128i *)dst); - - xmm_mask = _mm_unpacklo_epi16 (unpack_32_1x128 (m), _mm_setzero_si128()); - - unpack_128_2x128 (xmm_src, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_mask, &xmm_mask_lo, &xmm_mask_hi); - unpack_128_2x128 (xmm_dst, &xmm_dst_lo, &xmm_dst_hi); - - expand_alpha_2x128 (xmm_src_lo, xmm_src_hi, &xmm_srca_lo, &xmm_srca_hi); - expand_alpha_rev_2x128 (xmm_mask_lo, xmm_mask_hi, &xmm_mask_lo, &xmm_mask_hi); - - in_over_2x128 (&xmm_src_lo, &xmm_src_hi, &xmm_srca_lo, &xmm_srca_hi, - &xmm_mask_lo, &xmm_mask_hi, &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned ((__m128i*)dst, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - } - } - else - { - BILINEAR_SKIP_FOUR_PIXELS (); - } - - w -= 4; - dst += 4; - mask += 4; - } - - while (w) - { - uint32_t sa; - - m = (uint32_t) *mask++; - - if (m) - { - BILINEAR_INTERPOLATE_ONE_PIXEL (pix1); - sa = pix1 >> 24; - - if (sa == 0xff && m == 0xff) - { - *dst = pix1; - } - else - { - __m128i ms, md, ma, msa; - - pix2 = *dst; - ma = expand_alpha_rev_1x128 (load_32_1x128 (m)); - ms = unpack_32_1x128 (pix1); - md = unpack_32_1x128 (pix2); - - msa = expand_alpha_rev_1x128 (load_32_1x128 (sa)); - - *dst = pack_1x128_32 (in_over_1x128 (&ms, &msa, &ma, &md)); - } - } - else - { - BILINEAR_SKIP_ONE_PIXEL (); - } - - w--; - dst++; - } -} - -FAST_BILINEAR_MAINLOOP_COMMON (sse2_8888_8_8888_cover_OVER, - scaled_bilinear_scanline_sse2_8888_8_8888_OVER, - uint32_t, uint8_t, uint32_t, - COVER, FLAG_HAVE_NON_SOLID_MASK) -FAST_BILINEAR_MAINLOOP_COMMON (sse2_8888_8_8888_pad_OVER, - scaled_bilinear_scanline_sse2_8888_8_8888_OVER, - uint32_t, uint8_t, uint32_t, - PAD, FLAG_HAVE_NON_SOLID_MASK) -FAST_BILINEAR_MAINLOOP_COMMON (sse2_8888_8_8888_none_OVER, - scaled_bilinear_scanline_sse2_8888_8_8888_OVER, - uint32_t, uint8_t, uint32_t, - NONE, FLAG_HAVE_NON_SOLID_MASK) -FAST_BILINEAR_MAINLOOP_COMMON (sse2_8888_8_8888_normal_OVER, - scaled_bilinear_scanline_sse2_8888_8_8888_OVER, - uint32_t, uint8_t, uint32_t, - NORMAL, FLAG_HAVE_NON_SOLID_MASK) - -static force_inline void -scaled_bilinear_scanline_sse2_8888_n_8888_OVER (uint32_t * dst, - const uint32_t * mask, - const uint32_t * src_top, - const uint32_t * src_bottom, - int32_t w, - int wt, - int wb, - pixman_fixed_t vx_, - pixman_fixed_t unit_x_, - pixman_fixed_t max_vx, - pixman_bool_t zero_src) -{ - intptr_t vx = vx_; - intptr_t unit_x = unit_x_; - BILINEAR_DECLARE_VARIABLES; - uint32_t pix1; - __m128i xmm_mask; - - if (zero_src || (*mask >> 24) == 0) - return; - - xmm_mask = create_mask_16_128 (*mask >> 24); - - while (w && ((uintptr_t)dst & 15)) - { - BILINEAR_INTERPOLATE_ONE_PIXEL (pix1); - if (pix1) - { - uint32_t d = *dst; - - __m128i ms = unpack_32_1x128 (pix1); - __m128i alpha = expand_alpha_1x128 (ms); - __m128i dest = xmm_mask; - __m128i alpha_dst = unpack_32_1x128 (d); - - *dst = pack_1x128_32 - (in_over_1x128 (&ms, &alpha, &dest, &alpha_dst)); - } - - dst++; - w--; - } - - while (w >= 4) - { - __m128i xmm_src; - BILINEAR_INTERPOLATE_FOUR_PIXELS (xmm_src); - - if (!is_zero (xmm_src)) - { - __m128i xmm_src_lo, xmm_src_hi; - __m128i xmm_dst, xmm_dst_lo, xmm_dst_hi; - __m128i xmm_alpha_lo, xmm_alpha_hi; - - xmm_dst = load_128_aligned ((__m128i*)dst); - - unpack_128_2x128 (xmm_src, &xmm_src_lo, &xmm_src_hi); - unpack_128_2x128 (xmm_dst, &xmm_dst_lo, &xmm_dst_hi); - expand_alpha_2x128 (xmm_src_lo, xmm_src_hi, - &xmm_alpha_lo, &xmm_alpha_hi); - - in_over_2x128 (&xmm_src_lo, &xmm_src_hi, - &xmm_alpha_lo, &xmm_alpha_hi, - &xmm_mask, &xmm_mask, - &xmm_dst_lo, &xmm_dst_hi); - - save_128_aligned - ((__m128i*)dst, pack_2x128_128 (xmm_dst_lo, xmm_dst_hi)); - } - - dst += 4; - w -= 4; - } - - while (w) - { - BILINEAR_INTERPOLATE_ONE_PIXEL (pix1); - if (pix1) - { - uint32_t d = *dst; - - __m128i ms = unpack_32_1x128 (pix1); - __m128i alpha = expand_alpha_1x128 (ms); - __m128i dest = xmm_mask; - __m128i alpha_dst = unpack_32_1x128 (d); - - *dst = pack_1x128_32 - (in_over_1x128 (&ms, &alpha, &dest, &alpha_dst)); - } - - dst++; - w--; - } -} - -FAST_BILINEAR_MAINLOOP_COMMON (sse2_8888_n_8888_cover_OVER, - scaled_bilinear_scanline_sse2_8888_n_8888_OVER, - uint32_t, uint32_t, uint32_t, - COVER, FLAG_HAVE_SOLID_MASK) -FAST_BILINEAR_MAINLOOP_COMMON (sse2_8888_n_8888_pad_OVER, - scaled_bilinear_scanline_sse2_8888_n_8888_OVER, - uint32_t, uint32_t, uint32_t, - PAD, FLAG_HAVE_SOLID_MASK) -FAST_BILINEAR_MAINLOOP_COMMON (sse2_8888_n_8888_none_OVER, - scaled_bilinear_scanline_sse2_8888_n_8888_OVER, - uint32_t, uint32_t, uint32_t, - NONE, FLAG_HAVE_SOLID_MASK) -FAST_BILINEAR_MAINLOOP_COMMON (sse2_8888_n_8888_normal_OVER, - scaled_bilinear_scanline_sse2_8888_n_8888_OVER, - uint32_t, uint32_t, uint32_t, - NORMAL, FLAG_HAVE_SOLID_MASK) - -static const pixman_fast_path_t sse2_fast_paths[] = -{ - /* PIXMAN_OP_OVER */ - PIXMAN_STD_FAST_PATH (OVER, solid, a8, r5g6b5, sse2_composite_over_n_8_0565), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, b5g6r5, sse2_composite_over_n_8_0565), - PIXMAN_STD_FAST_PATH (OVER, solid, null, a8r8g8b8, sse2_composite_over_n_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, null, x8r8g8b8, sse2_composite_over_n_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, null, r5g6b5, sse2_composite_over_n_0565), - PIXMAN_STD_FAST_PATH (OVER, solid, null, b5g6r5, sse2_composite_over_n_0565), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, sse2_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, sse2_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, sse2_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, sse2_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, r5g6b5, sse2_composite_over_8888_0565), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, b5g6r5, sse2_composite_over_8888_0565), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, sse2_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, sse2_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, sse2_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, sse2_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, a8r8g8b8, sse2_composite_over_8888_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, x8r8g8b8, sse2_composite_over_8888_8_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, a8, a8r8g8b8, sse2_composite_over_8888_8_8888), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, x8b8g8r8, sse2_composite_over_8888_8_8888), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, a8, a8b8g8r8, sse2_composite_over_8888_8_8888), - PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, a8, x8r8g8b8, sse2_composite_over_x888_8_8888), - PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, a8, a8r8g8b8, sse2_composite_over_x888_8_8888), - PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, a8, x8b8g8r8, sse2_composite_over_x888_8_8888), - PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, a8, a8b8g8r8, sse2_composite_over_x888_8_8888), - PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, solid, a8r8g8b8, sse2_composite_over_x888_n_8888), - PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, solid, x8r8g8b8, sse2_composite_over_x888_n_8888), - PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, solid, a8b8g8r8, sse2_composite_over_x888_n_8888), - PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, solid, x8b8g8r8, sse2_composite_over_x888_n_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, a8r8g8b8, sse2_composite_over_8888_n_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, solid, x8r8g8b8, sse2_composite_over_8888_n_8888), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, a8b8g8r8, sse2_composite_over_8888_n_8888), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, solid, x8b8g8r8, sse2_composite_over_8888_n_8888), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, a8r8g8b8, sse2_composite_over_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, sse2_composite_over_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, sse2_composite_over_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, sse2_composite_over_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, r5g6b5, sse2_composite_over_n_8888_0565_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, b5g6r5, sse2_composite_over_n_8888_0565_ca), - PIXMAN_STD_FAST_PATH (OVER, pixbuf, pixbuf, a8r8g8b8, sse2_composite_over_pixbuf_8888), - PIXMAN_STD_FAST_PATH (OVER, pixbuf, pixbuf, x8r8g8b8, sse2_composite_over_pixbuf_8888), - PIXMAN_STD_FAST_PATH (OVER, rpixbuf, rpixbuf, a8b8g8r8, sse2_composite_over_pixbuf_8888), - PIXMAN_STD_FAST_PATH (OVER, rpixbuf, rpixbuf, x8b8g8r8, sse2_composite_over_pixbuf_8888), - PIXMAN_STD_FAST_PATH (OVER, pixbuf, pixbuf, r5g6b5, sse2_composite_over_pixbuf_0565), - PIXMAN_STD_FAST_PATH (OVER, rpixbuf, rpixbuf, b5g6r5, sse2_composite_over_pixbuf_0565), - PIXMAN_STD_FAST_PATH (OVER, x8r8g8b8, null, x8r8g8b8, sse2_composite_copy_area), - PIXMAN_STD_FAST_PATH (OVER, x8b8g8r8, null, x8b8g8r8, sse2_composite_copy_area), - - /* PIXMAN_OP_OVER_REVERSE */ - PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8r8g8b8, sse2_composite_over_reverse_n_8888), - PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8b8g8r8, sse2_composite_over_reverse_n_8888), - - /* PIXMAN_OP_ADD */ - PIXMAN_STD_FAST_PATH_CA (ADD, solid, a8r8g8b8, a8r8g8b8, sse2_composite_add_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, sse2_composite_add_8_8), - PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, null, a8r8g8b8, sse2_composite_add_8888_8888), - PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, null, a8b8g8r8, sse2_composite_add_8888_8888), - PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8, sse2_composite_add_n_8_8), - PIXMAN_STD_FAST_PATH (ADD, solid, null, a8, sse2_composite_add_n_8), - PIXMAN_STD_FAST_PATH (ADD, solid, null, x8r8g8b8, sse2_composite_add_n_8888), - PIXMAN_STD_FAST_PATH (ADD, solid, null, a8r8g8b8, sse2_composite_add_n_8888), - PIXMAN_STD_FAST_PATH (ADD, solid, null, x8b8g8r8, sse2_composite_add_n_8888), - PIXMAN_STD_FAST_PATH (ADD, solid, null, a8b8g8r8, sse2_composite_add_n_8888), - PIXMAN_STD_FAST_PATH (ADD, solid, a8, x8r8g8b8, sse2_composite_add_n_8_8888), - PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8r8g8b8, sse2_composite_add_n_8_8888), - PIXMAN_STD_FAST_PATH (ADD, solid, a8, x8b8g8r8, sse2_composite_add_n_8_8888), - PIXMAN_STD_FAST_PATH (ADD, solid, a8, a8b8g8r8, sse2_composite_add_n_8_8888), - - /* PIXMAN_OP_SRC */ - PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8r8g8b8, sse2_composite_src_n_8_8888), - PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8r8g8b8, sse2_composite_src_n_8_8888), - PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8b8g8r8, sse2_composite_src_n_8_8888), - PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8b8g8r8, sse2_composite_src_n_8_8888), - PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, r5g6b5, sse2_composite_src_x888_0565), - PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, b5g6r5, sse2_composite_src_x888_0565), - PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, r5g6b5, sse2_composite_src_x888_0565), - PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, b5g6r5, sse2_composite_src_x888_0565), - PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, a8r8g8b8, sse2_composite_src_x888_8888), - PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, a8b8g8r8, sse2_composite_src_x888_8888), - PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, a8r8g8b8, sse2_composite_copy_area), - PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, a8b8g8r8, sse2_composite_copy_area), - PIXMAN_STD_FAST_PATH (SRC, a8r8g8b8, null, x8r8g8b8, sse2_composite_copy_area), - PIXMAN_STD_FAST_PATH (SRC, a8b8g8r8, null, x8b8g8r8, sse2_composite_copy_area), - PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, x8r8g8b8, sse2_composite_copy_area), - PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, x8b8g8r8, sse2_composite_copy_area), - PIXMAN_STD_FAST_PATH (SRC, r5g6b5, null, r5g6b5, sse2_composite_copy_area), - PIXMAN_STD_FAST_PATH (SRC, b5g6r5, null, b5g6r5, sse2_composite_copy_area), - - /* PIXMAN_OP_IN */ - PIXMAN_STD_FAST_PATH (IN, a8, null, a8, sse2_composite_in_8_8), - PIXMAN_STD_FAST_PATH (IN, solid, a8, a8, sse2_composite_in_n_8_8), - PIXMAN_STD_FAST_PATH (IN, solid, null, a8, sse2_composite_in_n_8), - - SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, sse2_8888_8888), - SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, sse2_8888_8888), - SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, sse2_8888_8888), - SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, sse2_8888_8888), - - SIMPLE_NEAREST_SOLID_MASK_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, sse2_8888_n_8888), - SIMPLE_NEAREST_SOLID_MASK_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, sse2_8888_n_8888), - SIMPLE_NEAREST_SOLID_MASK_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, sse2_8888_n_8888), - SIMPLE_NEAREST_SOLID_MASK_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, sse2_8888_n_8888), - - SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, a8r8g8b8, sse2_8888_8888), - SIMPLE_BILINEAR_FAST_PATH (SRC, a8r8g8b8, x8r8g8b8, sse2_8888_8888), - SIMPLE_BILINEAR_FAST_PATH (SRC, x8r8g8b8, x8r8g8b8, sse2_8888_8888), - SIMPLE_BILINEAR_FAST_PATH (SRC, a8b8g8r8, a8b8g8r8, sse2_8888_8888), - SIMPLE_BILINEAR_FAST_PATH (SRC, a8b8g8r8, x8b8g8r8, sse2_8888_8888), - SIMPLE_BILINEAR_FAST_PATH (SRC, x8b8g8r8, x8b8g8r8, sse2_8888_8888), - - SIMPLE_BILINEAR_FAST_PATH_COVER (SRC, x8r8g8b8, a8r8g8b8, sse2_x888_8888), - SIMPLE_BILINEAR_FAST_PATH_COVER (SRC, x8b8g8r8, a8b8g8r8, sse2_x888_8888), - SIMPLE_BILINEAR_FAST_PATH_PAD (SRC, x8r8g8b8, a8r8g8b8, sse2_x888_8888), - SIMPLE_BILINEAR_FAST_PATH_PAD (SRC, x8b8g8r8, a8b8g8r8, sse2_x888_8888), - SIMPLE_BILINEAR_FAST_PATH_NORMAL (SRC, x8r8g8b8, a8r8g8b8, sse2_x888_8888), - SIMPLE_BILINEAR_FAST_PATH_NORMAL (SRC, x8b8g8r8, a8b8g8r8, sse2_x888_8888), - - SIMPLE_BILINEAR_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, sse2_8888_8888), - SIMPLE_BILINEAR_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, sse2_8888_8888), - SIMPLE_BILINEAR_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, sse2_8888_8888), - SIMPLE_BILINEAR_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, sse2_8888_8888), - - SIMPLE_BILINEAR_SOLID_MASK_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, sse2_8888_n_8888), - SIMPLE_BILINEAR_SOLID_MASK_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, sse2_8888_n_8888), - SIMPLE_BILINEAR_SOLID_MASK_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, sse2_8888_n_8888), - SIMPLE_BILINEAR_SOLID_MASK_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, sse2_8888_n_8888), - - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, sse2_8888_8_8888), - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, sse2_8888_8_8888), - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, sse2_8888_8_8888), - SIMPLE_BILINEAR_A8_MASK_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, sse2_8888_8_8888), - - { PIXMAN_OP_NONE }, -}; - -static uint32_t * -sse2_fetch_x8r8g8b8 (pixman_iter_t *iter, const uint32_t *mask) -{ - int w = iter->width; - __m128i ff000000 = mask_ff000000; - uint32_t *dst = iter->buffer; - uint32_t *src = (uint32_t *)iter->bits; - - iter->bits += iter->stride; - - while (w && ((uintptr_t)dst) & 0x0f) - { - *dst++ = (*src++) | 0xff000000; - w--; - } - - while (w >= 4) - { - save_128_aligned ( - (__m128i *)dst, _mm_or_si128 ( - load_128_unaligned ((__m128i *)src), ff000000)); - - dst += 4; - src += 4; - w -= 4; - } - - while (w) - { - *dst++ = (*src++) | 0xff000000; - w--; - } - - return iter->buffer; -} - -static uint32_t * -sse2_fetch_r5g6b5 (pixman_iter_t *iter, const uint32_t *mask) -{ - int w = iter->width; - uint32_t *dst = iter->buffer; - uint16_t *src = (uint16_t *)iter->bits; - __m128i ff000000 = mask_ff000000; - - iter->bits += iter->stride; - - while (w && ((uintptr_t)dst) & 0x0f) - { - uint16_t s = *src++; - - *dst++ = convert_0565_to_8888 (s); - w--; - } - - while (w >= 8) - { - __m128i lo, hi, s; - - s = _mm_loadu_si128 ((__m128i *)src); - - lo = unpack_565_to_8888 (_mm_unpacklo_epi16 (s, _mm_setzero_si128 ())); - hi = unpack_565_to_8888 (_mm_unpackhi_epi16 (s, _mm_setzero_si128 ())); - - save_128_aligned ((__m128i *)(dst + 0), _mm_or_si128 (lo, ff000000)); - save_128_aligned ((__m128i *)(dst + 4), _mm_or_si128 (hi, ff000000)); - - dst += 8; - src += 8; - w -= 8; - } - - while (w) - { - uint16_t s = *src++; - - *dst++ = convert_0565_to_8888 (s); - w--; - } - - return iter->buffer; -} - -static uint32_t * -sse2_fetch_a8 (pixman_iter_t *iter, const uint32_t *mask) -{ - int w = iter->width; - uint32_t *dst = iter->buffer; - uint8_t *src = iter->bits; - __m128i xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6; - - iter->bits += iter->stride; - - while (w && (((uintptr_t)dst) & 15)) - { - *dst++ = *(src++) << 24; - w--; - } - - while (w >= 16) - { - xmm0 = _mm_loadu_si128((__m128i *)src); - - xmm1 = _mm_unpacklo_epi8 (_mm_setzero_si128(), xmm0); - xmm2 = _mm_unpackhi_epi8 (_mm_setzero_si128(), xmm0); - xmm3 = _mm_unpacklo_epi16 (_mm_setzero_si128(), xmm1); - xmm4 = _mm_unpackhi_epi16 (_mm_setzero_si128(), xmm1); - xmm5 = _mm_unpacklo_epi16 (_mm_setzero_si128(), xmm2); - xmm6 = _mm_unpackhi_epi16 (_mm_setzero_si128(), xmm2); - - _mm_store_si128(((__m128i *)(dst + 0)), xmm3); - _mm_store_si128(((__m128i *)(dst + 4)), xmm4); - _mm_store_si128(((__m128i *)(dst + 8)), xmm5); - _mm_store_si128(((__m128i *)(dst + 12)), xmm6); - - dst += 16; - src += 16; - w -= 16; - } - - while (w) - { - *dst++ = *(src++) << 24; - w--; - } - - return iter->buffer; -} - -#define IMAGE_FLAGS \ - (FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM | \ - FAST_PATH_BITS_IMAGE | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST) - -static const pixman_iter_info_t sse2_iters[] = -{ - { PIXMAN_x8r8g8b8, IMAGE_FLAGS, ITER_NARROW, - _pixman_iter_init_bits_stride, sse2_fetch_x8r8g8b8, NULL - }, - { PIXMAN_r5g6b5, IMAGE_FLAGS, ITER_NARROW, - _pixman_iter_init_bits_stride, sse2_fetch_r5g6b5, NULL - }, - { PIXMAN_a8, IMAGE_FLAGS, ITER_NARROW, - _pixman_iter_init_bits_stride, sse2_fetch_a8, NULL - }, - { PIXMAN_null }, -}; - -#if defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__) -__attribute__((__force_align_arg_pointer__)) -#endif -pixman_implementation_t * -_pixman_implementation_create_sse2 (pixman_implementation_t *fallback) -{ - pixman_implementation_t *imp = _pixman_implementation_create (fallback, sse2_fast_paths); - - /* SSE2 constants */ - mask_565_r = create_mask_2x32_128 (0x00f80000, 0x00f80000); - mask_565_g1 = create_mask_2x32_128 (0x00070000, 0x00070000); - mask_565_g2 = create_mask_2x32_128 (0x000000e0, 0x000000e0); - mask_565_b = create_mask_2x32_128 (0x0000001f, 0x0000001f); - mask_red = create_mask_2x32_128 (0x00f80000, 0x00f80000); - mask_green = create_mask_2x32_128 (0x0000fc00, 0x0000fc00); - mask_blue = create_mask_2x32_128 (0x000000f8, 0x000000f8); - mask_565_fix_rb = create_mask_2x32_128 (0x00e000e0, 0x00e000e0); - mask_565_fix_g = create_mask_2x32_128 (0x0000c000, 0x0000c000); - mask_0080 = create_mask_16_128 (0x0080); - mask_00ff = create_mask_16_128 (0x00ff); - mask_0101 = create_mask_16_128 (0x0101); - mask_ffff = create_mask_16_128 (0xffff); - mask_ff000000 = create_mask_2x32_128 (0xff000000, 0xff000000); - mask_alpha = create_mask_2x32_128 (0x00ff0000, 0x00000000); - mask_565_rb = create_mask_2x32_128 (0x00f800f8, 0x00f800f8); - mask_565_pack_multiplier = create_mask_2x32_128 (0x20000004, 0x20000004); - - /* Set up function pointers */ - imp->combine_32[PIXMAN_OP_OVER] = sse2_combine_over_u; - imp->combine_32[PIXMAN_OP_OVER_REVERSE] = sse2_combine_over_reverse_u; - imp->combine_32[PIXMAN_OP_IN] = sse2_combine_in_u; - imp->combine_32[PIXMAN_OP_IN_REVERSE] = sse2_combine_in_reverse_u; - imp->combine_32[PIXMAN_OP_OUT] = sse2_combine_out_u; - imp->combine_32[PIXMAN_OP_OUT_REVERSE] = sse2_combine_out_reverse_u; - imp->combine_32[PIXMAN_OP_ATOP] = sse2_combine_atop_u; - imp->combine_32[PIXMAN_OP_ATOP_REVERSE] = sse2_combine_atop_reverse_u; - imp->combine_32[PIXMAN_OP_XOR] = sse2_combine_xor_u; - imp->combine_32[PIXMAN_OP_ADD] = sse2_combine_add_u; - - imp->combine_32[PIXMAN_OP_SATURATE] = sse2_combine_saturate_u; - - imp->combine_32_ca[PIXMAN_OP_SRC] = sse2_combine_src_ca; - imp->combine_32_ca[PIXMAN_OP_OVER] = sse2_combine_over_ca; - imp->combine_32_ca[PIXMAN_OP_OVER_REVERSE] = sse2_combine_over_reverse_ca; - imp->combine_32_ca[PIXMAN_OP_IN] = sse2_combine_in_ca; - imp->combine_32_ca[PIXMAN_OP_IN_REVERSE] = sse2_combine_in_reverse_ca; - imp->combine_32_ca[PIXMAN_OP_OUT] = sse2_combine_out_ca; - imp->combine_32_ca[PIXMAN_OP_OUT_REVERSE] = sse2_combine_out_reverse_ca; - imp->combine_32_ca[PIXMAN_OP_ATOP] = sse2_combine_atop_ca; - imp->combine_32_ca[PIXMAN_OP_ATOP_REVERSE] = sse2_combine_atop_reverse_ca; - imp->combine_32_ca[PIXMAN_OP_XOR] = sse2_combine_xor_ca; - imp->combine_32_ca[PIXMAN_OP_ADD] = sse2_combine_add_ca; - - imp->blt = sse2_blt; - imp->fill = sse2_fill; - - imp->iter_info = sse2_iters; - - return imp; -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman-ssse3.c b/source/libs/pixman/pixman-src/pixman/pixman-ssse3.c deleted file mode 100644 index 680d6b95a08574027eb38b926ac465e913457550..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-ssse3.c +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright © 2013 Soren Sandmann Pedersen - * Copyright © 2013 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Author: Soren Sandmann (soren.sandmann@gmail.com) - */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <mmintrin.h> -#include <xmmintrin.h> -#include <emmintrin.h> -#include <tmmintrin.h> -#include "pixman-private.h" -#include "pixman-inlines.h" - -typedef struct -{ - int y; - uint64_t * buffer; -} line_t; - -typedef struct -{ - line_t lines[2]; - pixman_fixed_t y; - pixman_fixed_t x; - uint64_t data[1]; -} bilinear_info_t; - -static void -ssse3_fetch_horizontal (bits_image_t *image, line_t *line, - int y, pixman_fixed_t x, pixman_fixed_t ux, int n) -{ - uint32_t *bits = image->bits + y * image->rowstride; - __m128i vx = _mm_set_epi16 ( - - (x + 1), x, - (x + 1), x, - - (x + ux + 1), x + ux, - (x + ux + 1), x + ux); - __m128i vux = _mm_set_epi16 ( - - 2 * ux, 2 * ux, - 2 * ux, 2 * ux, - - 2 * ux, 2 * ux, - 2 * ux, 2 * ux); - __m128i vaddc = _mm_set_epi16 (1, 0, 1, 0, 1, 0, 1, 0); - __m128i *b = (__m128i *)line->buffer; - __m128i vrl0, vrl1; - - while ((n -= 2) >= 0) - { - __m128i vw, vr, s; - - vrl1 = _mm_loadl_epi64 ( - (__m128i *)(bits + pixman_fixed_to_int (x + ux))); - /* vrl1: R1, L1 */ - - final_pixel: - vrl0 = _mm_loadl_epi64 ( - (__m128i *)(bits + pixman_fixed_to_int (x))); - /* vrl0: R0, L0 */ - - /* The weights are based on vx which is a vector of - * - * - (x + 1), x, - (x + 1), x, - * - (x + ux + 1), x + ux, - (x + ux + 1), x + ux - * - * so the 16 bit weights end up like this: - * - * iw0, w0, iw0, w0, iw1, w1, iw1, w1 - * - * and after shifting and packing, we get these bytes: - * - * iw0, w0, iw0, w0, iw1, w1, iw1, w1, - * iw0, w0, iw0, w0, iw1, w1, iw1, w1, - * - * which means the first and the second input pixel - * have to be interleaved like this: - * - * la0, ra0, lr0, rr0, la1, ra1, lr1, rr1, - * lg0, rg0, lb0, rb0, lg1, rg1, lb1, rb1 - * - * before maddubsw can be used. - */ - - vw = _mm_add_epi16 ( - vaddc, _mm_srli_epi16 (vx, 16 - BILINEAR_INTERPOLATION_BITS)); - /* vw: iw0, w0, iw0, w0, iw1, w1, iw1, w1 - */ - - vw = _mm_packus_epi16 (vw, vw); - /* vw: iw0, w0, iw0, w0, iw1, w1, iw1, w1, - * iw0, w0, iw0, w0, iw1, w1, iw1, w1 - */ - vx = _mm_add_epi16 (vx, vux); - - x += 2 * ux; - - vr = _mm_unpacklo_epi16 (vrl1, vrl0); - /* vr: rar0, rar1, rgb0, rgb1, lar0, lar1, lgb0, lgb1 */ - - s = _mm_shuffle_epi32 (vr, _MM_SHUFFLE (1, 0, 3, 2)); - /* s: lar0, lar1, lgb0, lgb1, rar0, rar1, rgb0, rgb1 */ - - vr = _mm_unpackhi_epi8 (vr, s); - /* vr: la0, ra0, lr0, rr0, la1, ra1, lr1, rr1, - * lg0, rg0, lb0, rb0, lg1, rg1, lb1, rb1 - */ - - vr = _mm_maddubs_epi16 (vr, vw); - - /* When the weight is 0, the inverse weight is - * 128 which can't be represented in a signed byte. - * As a result maddubsw computes the following: - * - * r = l * -128 + r * 0 - * - * rather than the desired - * - * r = l * 128 + r * 0 - * - * We fix this by taking the absolute value of the - * result. - */ - vr = _mm_abs_epi16 (vr); - - /* vr: A0, R0, A1, R1, G0, B0, G1, B1 */ - _mm_store_si128 (b++, vr); - } - - if (n == -1) - { - vrl1 = _mm_setzero_si128(); - goto final_pixel; - } - - line->y = y; -} - -static uint32_t * -ssse3_fetch_bilinear_cover (pixman_iter_t *iter, const uint32_t *mask) -{ - pixman_fixed_t fx, ux; - bilinear_info_t *info = iter->data; - line_t *line0, *line1; - int y0, y1; - int32_t dist_y; - __m128i vw; - int i; - - fx = info->x; - ux = iter->image->common.transform->matrix[0][0]; - - y0 = pixman_fixed_to_int (info->y); - y1 = y0 + 1; - - line0 = &info->lines[y0 & 0x01]; - line1 = &info->lines[y1 & 0x01]; - - if (line0->y != y0) - { - ssse3_fetch_horizontal ( - &iter->image->bits, line0, y0, fx, ux, iter->width); - } - - if (line1->y != y1) - { - ssse3_fetch_horizontal ( - &iter->image->bits, line1, y1, fx, ux, iter->width); - } - - dist_y = pixman_fixed_to_bilinear_weight (info->y); - dist_y <<= (16 - BILINEAR_INTERPOLATION_BITS); - - vw = _mm_set_epi16 ( - dist_y, dist_y, dist_y, dist_y, dist_y, dist_y, dist_y, dist_y); - - for (i = 0; i + 3 < iter->width; i += 4) - { - __m128i top0 = _mm_load_si128 ((__m128i *)(line0->buffer + i)); - __m128i bot0 = _mm_load_si128 ((__m128i *)(line1->buffer + i)); - __m128i top1 = _mm_load_si128 ((__m128i *)(line0->buffer + i + 2)); - __m128i bot1 = _mm_load_si128 ((__m128i *)(line1->buffer + i + 2)); - __m128i r0, r1, tmp, p; - - r0 = _mm_mulhi_epu16 ( - _mm_sub_epi16 (bot0, top0), vw); - tmp = _mm_cmplt_epi16 (bot0, top0); - tmp = _mm_and_si128 (tmp, vw); - r0 = _mm_sub_epi16 (r0, tmp); - r0 = _mm_add_epi16 (r0, top0); - r0 = _mm_srli_epi16 (r0, BILINEAR_INTERPOLATION_BITS); - /* r0: A0 R0 A1 R1 G0 B0 G1 B1 */ - r0 = _mm_shuffle_epi32 (r0, _MM_SHUFFLE (2, 0, 3, 1)); - /* r0: A1 R1 G1 B1 A0 R0 G0 B0 */ - - r1 = _mm_mulhi_epu16 ( - _mm_sub_epi16 (bot1, top1), vw); - tmp = _mm_cmplt_epi16 (bot1, top1); - tmp = _mm_and_si128 (tmp, vw); - r1 = _mm_sub_epi16 (r1, tmp); - r1 = _mm_add_epi16 (r1, top1); - r1 = _mm_srli_epi16 (r1, BILINEAR_INTERPOLATION_BITS); - r1 = _mm_shuffle_epi32 (r1, _MM_SHUFFLE (2, 0, 3, 1)); - /* r1: A3 R3 G3 B3 A2 R2 G2 B2 */ - - p = _mm_packus_epi16 (r0, r1); - - _mm_storeu_si128 ((__m128i *)(iter->buffer + i), p); - } - - while (i < iter->width) - { - __m128i top0 = _mm_load_si128 ((__m128i *)(line0->buffer + i)); - __m128i bot0 = _mm_load_si128 ((__m128i *)(line1->buffer + i)); - __m128i r0, tmp, p; - - r0 = _mm_mulhi_epu16 ( - _mm_sub_epi16 (bot0, top0), vw); - tmp = _mm_cmplt_epi16 (bot0, top0); - tmp = _mm_and_si128 (tmp, vw); - r0 = _mm_sub_epi16 (r0, tmp); - r0 = _mm_add_epi16 (r0, top0); - r0 = _mm_srli_epi16 (r0, BILINEAR_INTERPOLATION_BITS); - /* r0: A0 R0 A1 R1 G0 B0 G1 B1 */ - r0 = _mm_shuffle_epi32 (r0, _MM_SHUFFLE (2, 0, 3, 1)); - /* r0: A1 R1 G1 B1 A0 R0 G0 B0 */ - - p = _mm_packus_epi16 (r0, r0); - - if (iter->width - i == 1) - { - *(uint32_t *)(iter->buffer + i) = _mm_cvtsi128_si32 (p); - i++; - } - else - { - _mm_storel_epi64 ((__m128i *)(iter->buffer + i), p); - i += 2; - } - } - - info->y += iter->image->common.transform->matrix[1][1]; - - return iter->buffer; -} - -static void -ssse3_bilinear_cover_iter_fini (pixman_iter_t *iter) -{ - free (iter->data); -} - -static void -ssse3_bilinear_cover_iter_init (pixman_iter_t *iter, const pixman_iter_info_t *iter_info) -{ - int width = iter->width; - bilinear_info_t *info; - pixman_vector_t v; - - /* Reference point is the center of the pixel */ - v.vector[0] = pixman_int_to_fixed (iter->x) + pixman_fixed_1 / 2; - v.vector[1] = pixman_int_to_fixed (iter->y) + pixman_fixed_1 / 2; - v.vector[2] = pixman_fixed_1; - - if (!pixman_transform_point_3d (iter->image->common.transform, &v)) - goto fail; - - info = malloc (sizeof (*info) + (2 * width - 1) * sizeof (uint64_t) + 64); - if (!info) - goto fail; - - info->x = v.vector[0] - pixman_fixed_1 / 2; - info->y = v.vector[1] - pixman_fixed_1 / 2; - -#define ALIGN(addr) \ - ((void *)((((uintptr_t)(addr)) + 15) & (~15))) - - /* It is safe to set the y coordinates to -1 initially - * because COVER_CLIP_BILINEAR ensures that we will only - * be asked to fetch lines in the [0, height) interval - */ - info->lines[0].y = -1; - info->lines[0].buffer = ALIGN (&(info->data[0])); - info->lines[1].y = -1; - info->lines[1].buffer = ALIGN (info->lines[0].buffer + width); - - iter->get_scanline = ssse3_fetch_bilinear_cover; - iter->fini = ssse3_bilinear_cover_iter_fini; - - iter->data = info; - return; - -fail: - /* Something went wrong, either a bad matrix or OOM; in such cases, - * we don't guarantee any particular rendering. - */ - _pixman_log_error ( - FUNC, "Allocation failure or bad matrix, skipping rendering\n"); - - iter->get_scanline = _pixman_iter_get_scanline_noop; - iter->fini = NULL; -} - -static const pixman_iter_info_t ssse3_iters[] = -{ - { PIXMAN_a8r8g8b8, - (FAST_PATH_STANDARD_FLAGS | - FAST_PATH_SCALE_TRANSFORM | - FAST_PATH_BILINEAR_FILTER | - FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR), - ITER_NARROW | ITER_SRC, - ssse3_bilinear_cover_iter_init, - NULL, NULL - }, - - { PIXMAN_null }, -}; - -static const pixman_fast_path_t ssse3_fast_paths[] = -{ - { PIXMAN_OP_NONE }, -}; - -pixman_implementation_t * -_pixman_implementation_create_ssse3 (pixman_implementation_t *fallback) -{ - pixman_implementation_t *imp = - _pixman_implementation_create (fallback, ssse3_fast_paths); - - imp->iter_info = ssse3_iters; - - return imp; -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman-timer.c b/source/libs/pixman/pixman-src/pixman/pixman-timer.c deleted file mode 100644 index f5ae18e89f9b9f56bb6a51fdfdbf5f4d80e33bff..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-timer.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright © 2007 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 not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. Red Hat makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT - * 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. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <stdio.h> -#include "pixman-private.h" - -#ifdef PIXMAN_TIMERS - -static pixman_timer_t *timers; - -static void -dump_timers (void) -{ - pixman_timer_t *timer; - - for (timer = timers; timer != NULL; timer = timer->next) - { - printf ("%s: total: %llu n: %llu avg: %f\n", - timer->name, - timer->total, - timer->n_times, - timer->total / (double)timer->n_times); - } -} - -void -pixman_timer_register (pixman_timer_t *timer) -{ - static int initialized; - - int atexit (void (*function)(void)); - - if (!initialized) - { - atexit (dump_timers); - initialized = 1; - } - - timer->next = timers; - timers = timer; -} - -#endif diff --git a/source/libs/pixman/pixman-src/pixman/pixman-trap.c b/source/libs/pixman/pixman-src/pixman/pixman-trap.c deleted file mode 100644 index 91766fdbfca02d39d1df910e72e61fe212e87e98..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-trap.c +++ /dev/null @@ -1,711 +0,0 @@ -/* - * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc. - * Copyright © 2004 Keith Packard - * - * 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 Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD 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. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include "pixman-private.h" - -/* - * Compute the smallest value greater than or equal to y which is on a - * grid row. - */ - -PIXMAN_EXPORT pixman_fixed_t -pixman_sample_ceil_y (pixman_fixed_t y, int n) -{ - pixman_fixed_t f = pixman_fixed_frac (y); - pixman_fixed_t i = pixman_fixed_floor (y); - - f = DIV (f - Y_FRAC_FIRST (n) + (STEP_Y_SMALL (n) - pixman_fixed_e), STEP_Y_SMALL (n)) * STEP_Y_SMALL (n) + - Y_FRAC_FIRST (n); - - if (f > Y_FRAC_LAST (n)) - { - if (pixman_fixed_to_int (i) == 0x7fff) - { - f = 0xffff; /* saturate */ - } - else - { - f = Y_FRAC_FIRST (n); - i += pixman_fixed_1; - } - } - return (i | f); -} - -/* - * Compute the largest value strictly less than y which is on a - * grid row. - */ -PIXMAN_EXPORT pixman_fixed_t -pixman_sample_floor_y (pixman_fixed_t y, - int n) -{ - pixman_fixed_t f = pixman_fixed_frac (y); - pixman_fixed_t i = pixman_fixed_floor (y); - - f = DIV (f - pixman_fixed_e - Y_FRAC_FIRST (n), STEP_Y_SMALL (n)) * STEP_Y_SMALL (n) + - Y_FRAC_FIRST (n); - - if (f < Y_FRAC_FIRST (n)) - { - if (pixman_fixed_to_int (i) == 0x8000) - { - f = 0; /* saturate */ - } - else - { - f = Y_FRAC_LAST (n); - i -= pixman_fixed_1; - } - } - return (i | f); -} - -/* - * Step an edge by any amount (including negative values) - */ -PIXMAN_EXPORT void -pixman_edge_step (pixman_edge_t *e, - int n) -{ - pixman_fixed_48_16_t ne; - - e->x += n * e->stepx; - - ne = e->e + n * (pixman_fixed_48_16_t) e->dx; - - if (n >= 0) - { - if (ne > 0) - { - int nx = (ne + e->dy - 1) / e->dy; - e->e = ne - nx * (pixman_fixed_48_16_t) e->dy; - e->x += nx * e->signdx; - } - } - else - { - if (ne <= -e->dy) - { - int nx = (-ne) / e->dy; - e->e = ne + nx * (pixman_fixed_48_16_t) e->dy; - e->x -= nx * e->signdx; - } - } -} - -/* - * A private routine to initialize the multi-step - * elements of an edge structure - */ -static void -_pixman_edge_multi_init (pixman_edge_t * e, - int n, - pixman_fixed_t *stepx_p, - pixman_fixed_t *dx_p) -{ - pixman_fixed_t stepx; - pixman_fixed_48_16_t ne; - - ne = n * (pixman_fixed_48_16_t) e->dx; - stepx = n * e->stepx; - - if (ne > 0) - { - int nx = ne / e->dy; - ne -= nx * (pixman_fixed_48_16_t)e->dy; - stepx += nx * e->signdx; - } - - *dx_p = ne; - *stepx_p = stepx; -} - -/* - * Initialize one edge structure given the line endpoints and a - * starting y value - */ -PIXMAN_EXPORT void -pixman_edge_init (pixman_edge_t *e, - int n, - pixman_fixed_t y_start, - pixman_fixed_t x_top, - pixman_fixed_t y_top, - pixman_fixed_t x_bot, - pixman_fixed_t y_bot) -{ - pixman_fixed_t dx, dy; - - e->x = x_top; - e->e = 0; - dx = x_bot - x_top; - dy = y_bot - y_top; - e->dy = dy; - e->dx = 0; - - if (dy) - { - if (dx >= 0) - { - e->signdx = 1; - e->stepx = dx / dy; - e->dx = dx % dy; - e->e = -dy; - } - else - { - e->signdx = -1; - e->stepx = -(-dx / dy); - e->dx = -dx % dy; - e->e = 0; - } - - _pixman_edge_multi_init (e, STEP_Y_SMALL (n), - &e->stepx_small, &e->dx_small); - - _pixman_edge_multi_init (e, STEP_Y_BIG (n), - &e->stepx_big, &e->dx_big); - } - pixman_edge_step (e, y_start - y_top); -} - -/* - * Initialize one edge structure given a line, starting y value - * and a pixel offset for the line - */ -PIXMAN_EXPORT void -pixman_line_fixed_edge_init (pixman_edge_t * e, - int n, - pixman_fixed_t y, - const pixman_line_fixed_t *line, - int x_off, - int y_off) -{ - pixman_fixed_t x_off_fixed = pixman_int_to_fixed (x_off); - pixman_fixed_t y_off_fixed = pixman_int_to_fixed (y_off); - const pixman_point_fixed_t *top, *bot; - - if (line->p1.y <= line->p2.y) - { - top = &line->p1; - bot = &line->p2; - } - else - { - top = &line->p2; - bot = &line->p1; - } - - pixman_edge_init (e, n, y, - top->x + x_off_fixed, - top->y + y_off_fixed, - bot->x + x_off_fixed, - bot->y + y_off_fixed); -} - -PIXMAN_EXPORT void -pixman_add_traps (pixman_image_t * image, - int16_t x_off, - int16_t y_off, - int ntrap, - const pixman_trap_t *traps) -{ - int bpp; - int height; - - pixman_fixed_t x_off_fixed; - pixman_fixed_t y_off_fixed; - pixman_edge_t l, r; - pixman_fixed_t t, b; - - _pixman_image_validate (image); - - height = image->bits.height; - bpp = PIXMAN_FORMAT_BPP (image->bits.format); - - x_off_fixed = pixman_int_to_fixed (x_off); - y_off_fixed = pixman_int_to_fixed (y_off); - - while (ntrap--) - { - t = traps->top.y + y_off_fixed; - if (t < 0) - t = 0; - t = pixman_sample_ceil_y (t, bpp); - - b = traps->bot.y + y_off_fixed; - if (pixman_fixed_to_int (b) >= height) - b = pixman_int_to_fixed (height) - 1; - b = pixman_sample_floor_y (b, bpp); - - if (b >= t) - { - /* initialize edge walkers */ - pixman_edge_init (&l, bpp, t, - traps->top.l + x_off_fixed, - traps->top.y + y_off_fixed, - traps->bot.l + x_off_fixed, - traps->bot.y + y_off_fixed); - - pixman_edge_init (&r, bpp, t, - traps->top.r + x_off_fixed, - traps->top.y + y_off_fixed, - traps->bot.r + x_off_fixed, - traps->bot.y + y_off_fixed); - - pixman_rasterize_edges (image, &l, &r, t, b); - } - - traps++; - } -} - -#if 0 -static void -dump_image (pixman_image_t *image, - const char * title) -{ - int i, j; - - if (!image->type == BITS) - printf ("%s is not a regular image\n", title); - - if (!image->bits.format == PIXMAN_a8) - printf ("%s is not an alpha mask\n", title); - - printf ("\n\n\n%s: \n", title); - - for (i = 0; i < image->bits.height; ++i) - { - uint8_t *line = - (uint8_t *)&(image->bits.bits[i * image->bits.rowstride]); - - for (j = 0; j < image->bits.width; ++j) - printf ("%c", line[j] ? '#' : ' '); - - printf ("\n"); - } -} -#endif - -PIXMAN_EXPORT void -pixman_add_trapezoids (pixman_image_t * image, - int16_t x_off, - int y_off, - int ntraps, - const pixman_trapezoid_t *traps) -{ - int i; - -#if 0 - dump_image (image, "before"); -#endif - - for (i = 0; i < ntraps; ++i) - { - const pixman_trapezoid_t *trap = &(traps[i]); - - if (!pixman_trapezoid_valid (trap)) - continue; - - pixman_rasterize_trapezoid (image, trap, x_off, y_off); - } - -#if 0 - dump_image (image, "after"); -#endif -} - -PIXMAN_EXPORT void -pixman_rasterize_trapezoid (pixman_image_t * image, - const pixman_trapezoid_t *trap, - int x_off, - int y_off) -{ - int bpp; - int height; - - pixman_fixed_t y_off_fixed; - pixman_edge_t l, r; - pixman_fixed_t t, b; - - return_if_fail (image->type == BITS); - - _pixman_image_validate (image); - - if (!pixman_trapezoid_valid (trap)) - return; - - height = image->bits.height; - bpp = PIXMAN_FORMAT_BPP (image->bits.format); - - y_off_fixed = pixman_int_to_fixed (y_off); - - t = trap->top + y_off_fixed; - if (t < 0) - t = 0; - t = pixman_sample_ceil_y (t, bpp); - - b = trap->bottom + y_off_fixed; - if (pixman_fixed_to_int (b) >= height) - b = pixman_int_to_fixed (height) - 1; - b = pixman_sample_floor_y (b, bpp); - - if (b >= t) - { - /* initialize edge walkers */ - pixman_line_fixed_edge_init (&l, bpp, t, &trap->left, x_off, y_off); - pixman_line_fixed_edge_init (&r, bpp, t, &trap->right, x_off, y_off); - - pixman_rasterize_edges (image, &l, &r, t, b); - } -} - -static const pixman_bool_t zero_src_has_no_effect[PIXMAN_N_OPERATORS] = -{ - FALSE, /* Clear 0 0 */ - FALSE, /* Src 1 0 */ - TRUE, /* Dst 0 1 */ - TRUE, /* Over 1 1-Aa */ - TRUE, /* OverReverse 1-Ab 1 */ - FALSE, /* In Ab 0 */ - FALSE, /* InReverse 0 Aa */ - FALSE, /* Out 1-Ab 0 */ - TRUE, /* OutReverse 0 1-Aa */ - TRUE, /* Atop Ab 1-Aa */ - FALSE, /* AtopReverse 1-Ab Aa */ - TRUE, /* Xor 1-Ab 1-Aa */ - TRUE, /* Add 1 1 */ -}; - -static pixman_bool_t -get_trap_extents (pixman_op_t op, pixman_image_t *dest, - const pixman_trapezoid_t *traps, int n_traps, - pixman_box32_t *box) -{ - int i; - - /* When the operator is such that a zero source has an - * effect on the underlying image, we have to - * composite across the entire destination - */ - if (!zero_src_has_no_effect [op]) - { - box->x1 = 0; - box->y1 = 0; - box->x2 = dest->bits.width; - box->y2 = dest->bits.height; - return TRUE; - } - - box->x1 = INT32_MAX; - box->y1 = INT32_MAX; - box->x2 = INT32_MIN; - box->y2 = INT32_MIN; - - for (i = 0; i < n_traps; ++i) - { - const pixman_trapezoid_t *trap = &(traps[i]); - int y1, y2; - - if (!pixman_trapezoid_valid (trap)) - continue; - - y1 = pixman_fixed_to_int (trap->top); - if (y1 < box->y1) - box->y1 = y1; - - y2 = pixman_fixed_to_int (pixman_fixed_ceil (trap->bottom)); - if (y2 > box->y2) - box->y2 = y2; - -#define EXTEND_MIN(x) \ - if (pixman_fixed_to_int ((x)) < box->x1) \ - box->x1 = pixman_fixed_to_int ((x)); -#define EXTEND_MAX(x) \ - if (pixman_fixed_to_int (pixman_fixed_ceil ((x))) > box->x2) \ - box->x2 = pixman_fixed_to_int (pixman_fixed_ceil ((x))); - -#define EXTEND(x) \ - EXTEND_MIN(x); \ - EXTEND_MAX(x); - - EXTEND(trap->left.p1.x); - EXTEND(trap->left.p2.x); - EXTEND(trap->right.p1.x); - EXTEND(trap->right.p2.x); - } - - if (box->x1 >= box->x2 || box->y1 >= box->y2) - return FALSE; - - return TRUE; -} - -/* - * pixman_composite_trapezoids() - * - * All the trapezoids are conceptually rendered to an infinitely big image. - * The (0, 0) coordinates of this image are then aligned with the (x, y) - * coordinates of the source image, and then both images are aligned with - * the (x, y) coordinates of the destination. Then these three images are - * composited across the entire destination. - */ -PIXMAN_EXPORT void -pixman_composite_trapezoids (pixman_op_t op, - pixman_image_t * src, - pixman_image_t * dst, - pixman_format_code_t mask_format, - int x_src, - int y_src, - int x_dst, - int y_dst, - int n_traps, - const pixman_trapezoid_t * traps) -{ - int i; - - return_if_fail (PIXMAN_FORMAT_TYPE (mask_format) == PIXMAN_TYPE_A); - - if (n_traps <= 0) - return; - - _pixman_image_validate (src); - _pixman_image_validate (dst); - - if (op == PIXMAN_OP_ADD && - (src->common.flags & FAST_PATH_IS_OPAQUE) && - (mask_format == dst->common.extended_format_code) && - !(dst->common.have_clip_region)) - { - for (i = 0; i < n_traps; ++i) - { - const pixman_trapezoid_t *trap = &(traps[i]); - - if (!pixman_trapezoid_valid (trap)) - continue; - - pixman_rasterize_trapezoid (dst, trap, x_dst, y_dst); - } - } - else - { - pixman_image_t *tmp; - pixman_box32_t box; - int i; - - if (!get_trap_extents (op, dst, traps, n_traps, &box)) - return; - - if (!(tmp = pixman_image_create_bits ( - mask_format, box.x2 - box.x1, box.y2 - box.y1, NULL, -1))) - return; - - for (i = 0; i < n_traps; ++i) - { - const pixman_trapezoid_t *trap = &(traps[i]); - - if (!pixman_trapezoid_valid (trap)) - continue; - - pixman_rasterize_trapezoid (tmp, trap, - box.x1, - box.y1); - } - - pixman_image_composite (op, src, tmp, dst, - x_src + box.x1, y_src + box.y1, - 0, 0, - x_dst + box.x1, y_dst + box.y1, - box.x2 - box.x1, box.y2 - box.y1); - - pixman_image_unref (tmp); - } -} - -static int -greater_y (const pixman_point_fixed_t *a, const pixman_point_fixed_t *b) -{ - if (a->y == b->y) - return a->x > b->x; - return a->y > b->y; -} - -/* - * Note that the definition of this function is a bit odd because - * of the X coordinate space (y increasing downwards). - */ -static int -clockwise (const pixman_point_fixed_t *ref, - const pixman_point_fixed_t *a, - const pixman_point_fixed_t *b) -{ - pixman_point_fixed_t ad, bd; - - ad.x = a->x - ref->x; - ad.y = a->y - ref->y; - bd.x = b->x - ref->x; - bd.y = b->y - ref->y; - - return ((pixman_fixed_32_32_t) bd.y * ad.x - - (pixman_fixed_32_32_t) ad.y * bd.x) < 0; -} - -static void -triangle_to_trapezoids (const pixman_triangle_t *tri, pixman_trapezoid_t *traps) -{ - const pixman_point_fixed_t *top, *left, *right, *tmp; - - top = &tri->p1; - left = &tri->p2; - right = &tri->p3; - - if (greater_y (top, left)) - { - tmp = left; - left = top; - top = tmp; - } - - if (greater_y (top, right)) - { - tmp = right; - right = top; - top = tmp; - } - - if (clockwise (top, right, left)) - { - tmp = right; - right = left; - left = tmp; - } - - /* - * Two cases: - * - * + + - * / \ / \ - * / \ / \ - * / + + \ - * / -- -- \ - * / -- -- \ - * / --- --- \ - * +-- --+ - */ - - traps->top = top->y; - traps->left.p1 = *top; - traps->left.p2 = *left; - traps->right.p1 = *top; - traps->right.p2 = *right; - - if (right->y < left->y) - traps->bottom = right->y; - else - traps->bottom = left->y; - - traps++; - - *traps = *(traps - 1); - - if (right->y < left->y) - { - traps->top = right->y; - traps->bottom = left->y; - traps->right.p1 = *right; - traps->right.p2 = *left; - } - else - { - traps->top = left->y; - traps->bottom = right->y; - traps->left.p1 = *left; - traps->left.p2 = *right; - } -} - -static pixman_trapezoid_t * -convert_triangles (int n_tris, const pixman_triangle_t *tris) -{ - pixman_trapezoid_t *traps; - int i; - - if (n_tris <= 0) - return NULL; - - traps = pixman_malloc_ab (n_tris, 2 * sizeof (pixman_trapezoid_t)); - if (!traps) - return NULL; - - for (i = 0; i < n_tris; ++i) - triangle_to_trapezoids (&(tris[i]), traps + 2 * i); - - return traps; -} - -PIXMAN_EXPORT void -pixman_composite_triangles (pixman_op_t op, - pixman_image_t * src, - pixman_image_t * dst, - pixman_format_code_t mask_format, - int x_src, - int y_src, - int x_dst, - int y_dst, - int n_tris, - const pixman_triangle_t * tris) -{ - pixman_trapezoid_t *traps; - - if ((traps = convert_triangles (n_tris, tris))) - { - pixman_composite_trapezoids (op, src, dst, mask_format, - x_src, y_src, x_dst, y_dst, - n_tris * 2, traps); - - free (traps); - } -} - -PIXMAN_EXPORT void -pixman_add_triangles (pixman_image_t *image, - int32_t x_off, - int32_t y_off, - int n_tris, - const pixman_triangle_t *tris) -{ - pixman_trapezoid_t *traps; - - if ((traps = convert_triangles (n_tris, tris))) - { - pixman_add_trapezoids (image, x_off, y_off, - n_tris * 2, traps); - - free (traps); - } -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman-utils.c b/source/libs/pixman/pixman-src/pixman/pixman-utils.c deleted file mode 100644 index 4a3a835c4239ad3166d58dec238b3870698bbd35..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-utils.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright © 2000 SuSE, Inc. - * Copyright © 1999 Keith Packard - * - * 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 SuSE not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. SuSE makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE - * 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: Keith Packard, SuSE, Inc. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include <stdlib.h> - -#include "pixman-private.h" - -pixman_bool_t -_pixman_multiply_overflows_size (size_t a, size_t b) -{ - return a >= SIZE_MAX / b; -} - -pixman_bool_t -_pixman_multiply_overflows_int (unsigned int a, unsigned int b) -{ - return a >= INT32_MAX / b; -} - -pixman_bool_t -_pixman_addition_overflows_int (unsigned int a, unsigned int b) -{ - return a > INT32_MAX - b; -} - -void * -pixman_malloc_ab_plus_c (unsigned int a, unsigned int b, unsigned int c) -{ - if (!b || a >= INT32_MAX / b || (a * b) > INT32_MAX - c) - return NULL; - - return malloc (a * b + c); -} - -void * -pixman_malloc_ab (unsigned int a, - unsigned int b) -{ - if (a >= INT32_MAX / b) - return NULL; - - return malloc (a * b); -} - -void * -pixman_malloc_abc (unsigned int a, - unsigned int b, - unsigned int c) -{ - if (a >= INT32_MAX / b) - return NULL; - else if (a * b >= INT32_MAX / c) - return NULL; - else - return malloc (a * b * c); -} - -static force_inline uint16_t -float_to_unorm (float f, int n_bits) -{ - uint32_t u; - - if (f > 1.0) - f = 1.0; - if (f < 0.0) - f = 0.0; - - u = f * (1 << n_bits); - u -= (u >> n_bits); - - return u; -} - -static force_inline float -unorm_to_float (uint16_t u, int n_bits) -{ - uint32_t m = ((1 << n_bits) - 1); - - return (u & m) * (1.f / (float)m); -} - -/* - * This function expands images from a8r8g8b8 to argb_t. To preserve - * precision, it needs to know from which source format the a8r8g8b8 pixels - * originally came. - * - * For example, if the source was PIXMAN_x1r5g5b5 and the red component - * contained bits 12345, then the 8-bit value is 12345123. To correctly - * expand this to floating point, it should be 12345 / 31.0 and not - * 12345123 / 255.0. - */ -void -pixman_expand_to_float (argb_t *dst, - const uint32_t *src, - pixman_format_code_t format, - int width) -{ - static const float multipliers[16] = { - 0.0f, - 1.0f / ((1 << 1) - 1), - 1.0f / ((1 << 2) - 1), - 1.0f / ((1 << 3) - 1), - 1.0f / ((1 << 4) - 1), - 1.0f / ((1 << 5) - 1), - 1.0f / ((1 << 6) - 1), - 1.0f / ((1 << 7) - 1), - 1.0f / ((1 << 8) - 1), - 1.0f / ((1 << 9) - 1), - 1.0f / ((1 << 10) - 1), - 1.0f / ((1 << 11) - 1), - 1.0f / ((1 << 12) - 1), - 1.0f / ((1 << 13) - 1), - 1.0f / ((1 << 14) - 1), - 1.0f / ((1 << 15) - 1), - }; - int a_size, r_size, g_size, b_size; - int a_shift, r_shift, g_shift, b_shift; - float a_mul, r_mul, g_mul, b_mul; - uint32_t a_mask, r_mask, g_mask, b_mask; - int i; - - if (!PIXMAN_FORMAT_VIS (format)) - format = PIXMAN_a8r8g8b8; - - /* - * Determine the sizes of each component and the masks and shifts - * required to extract them from the source pixel. - */ - a_size = PIXMAN_FORMAT_A (format); - r_size = PIXMAN_FORMAT_R (format); - g_size = PIXMAN_FORMAT_G (format); - b_size = PIXMAN_FORMAT_B (format); - - a_shift = 32 - a_size; - r_shift = 24 - r_size; - g_shift = 16 - g_size; - b_shift = 8 - b_size; - - a_mask = ((1 << a_size) - 1); - r_mask = ((1 << r_size) - 1); - g_mask = ((1 << g_size) - 1); - b_mask = ((1 << b_size) - 1); - - a_mul = multipliers[a_size]; - r_mul = multipliers[r_size]; - g_mul = multipliers[g_size]; - b_mul = multipliers[b_size]; - - /* Start at the end so that we can do the expansion in place - * when src == dst - */ - for (i = width - 1; i >= 0; i--) - { - const uint32_t pixel = src[i]; - - dst[i].a = a_mask? ((pixel >> a_shift) & a_mask) * a_mul : 1.0f; - dst[i].r = ((pixel >> r_shift) & r_mask) * r_mul; - dst[i].g = ((pixel >> g_shift) & g_mask) * g_mul; - dst[i].b = ((pixel >> b_shift) & b_mask) * b_mul; - } -} - -uint16_t -pixman_float_to_unorm (float f, int n_bits) -{ - return float_to_unorm (f, n_bits); -} - -float -pixman_unorm_to_float (uint16_t u, int n_bits) -{ - return unorm_to_float (u, n_bits); -} - -void -pixman_contract_from_float (uint32_t *dst, - const argb_t *src, - int width) -{ - int i; - - for (i = 0; i < width; ++i) - { - uint8_t a, r, g, b; - - a = float_to_unorm (src[i].a, 8); - r = float_to_unorm (src[i].r, 8); - g = float_to_unorm (src[i].g, 8); - b = float_to_unorm (src[i].b, 8); - - dst[i] = (a << 24) | (r << 16) | (g << 8) | (b << 0); - } -} - -uint32_t * -_pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask) -{ - return iter->buffer; -} - -void -_pixman_iter_init_bits_stride (pixman_iter_t *iter, const pixman_iter_info_t *info) -{ - pixman_image_t *image = iter->image; - uint8_t *b = (uint8_t *)image->bits.bits; - int s = image->bits.rowstride * 4; - - iter->bits = b + s * iter->y + iter->x * PIXMAN_FORMAT_BPP (info->format) / 8; - iter->stride = s; -} - -#define N_TMP_BOXES (16) - -pixman_bool_t -pixman_region16_copy_from_region32 (pixman_region16_t *dst, - pixman_region32_t *src) -{ - int n_boxes, i; - pixman_box32_t *boxes32; - pixman_box16_t *boxes16; - pixman_bool_t retval; - - boxes32 = pixman_region32_rectangles (src, &n_boxes); - - boxes16 = pixman_malloc_ab (n_boxes, sizeof (pixman_box16_t)); - - if (!boxes16) - return FALSE; - - for (i = 0; i < n_boxes; ++i) - { - boxes16[i].x1 = boxes32[i].x1; - boxes16[i].y1 = boxes32[i].y1; - boxes16[i].x2 = boxes32[i].x2; - boxes16[i].y2 = boxes32[i].y2; - } - - pixman_region_fini (dst); - retval = pixman_region_init_rects (dst, boxes16, n_boxes); - free (boxes16); - return retval; -} - -pixman_bool_t -pixman_region32_copy_from_region16 (pixman_region32_t *dst, - pixman_region16_t *src) -{ - int n_boxes, i; - pixman_box16_t *boxes16; - pixman_box32_t *boxes32; - pixman_box32_t tmp_boxes[N_TMP_BOXES]; - pixman_bool_t retval; - - boxes16 = pixman_region_rectangles (src, &n_boxes); - - if (n_boxes > N_TMP_BOXES) - boxes32 = pixman_malloc_ab (n_boxes, sizeof (pixman_box32_t)); - else - boxes32 = tmp_boxes; - - if (!boxes32) - return FALSE; - - for (i = 0; i < n_boxes; ++i) - { - boxes32[i].x1 = boxes16[i].x1; - boxes32[i].y1 = boxes16[i].y1; - boxes32[i].x2 = boxes16[i].x2; - boxes32[i].y2 = boxes16[i].y2; - } - - pixman_region32_fini (dst); - retval = pixman_region32_init_rects (dst, boxes32, n_boxes); - - if (boxes32 != tmp_boxes) - free (boxes32); - - return retval; -} - -/* This function is exported for the sake of the test suite and not part - * of the ABI. - */ -PIXMAN_EXPORT pixman_implementation_t * -_pixman_internal_only_get_implementation (void) -{ - return get_implementation (); -} - -void -_pixman_log_error (const char *function, const char *message) -{ - static int n_messages = 0; - - if (n_messages < 10) - { - fprintf (stderr, - "*** BUG ***\n" - "In %s: %s\n" - "Set a breakpoint on '_pixman_log_error' to debug\n\n", - function, message); - - n_messages++; - } -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman-version.h.in b/source/libs/pixman/pixman-src/pixman/pixman-version.h.in deleted file mode 100644 index 256b2e6f1e4a9bda7f13d4424492f0c9836ccbfe..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-version.h.in +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright © 2008 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Author: Carl D. Worth <cworth@cworth.org> - */ - -#ifndef PIXMAN_VERSION_H__ -#define PIXMAN_VERSION_H__ - -#ifndef PIXMAN_H__ -# error pixman-version.h should only be included by pixman.h -#endif - -#define PIXMAN_VERSION_MAJOR @PIXMAN_VERSION_MAJOR@ -#define PIXMAN_VERSION_MINOR @PIXMAN_VERSION_MINOR@ -#define PIXMAN_VERSION_MICRO @PIXMAN_VERSION_MICRO@ - -#define PIXMAN_VERSION_STRING "@PIXMAN_VERSION_MAJOR@.@PIXMAN_VERSION_MINOR@.@PIXMAN_VERSION_MICRO@" - -#define PIXMAN_VERSION_ENCODE(major, minor, micro) ( \ - ((major) * 10000) \ - + ((minor) * 100) \ - + ((micro) * 1)) - -#define PIXMAN_VERSION PIXMAN_VERSION_ENCODE( \ - PIXMAN_VERSION_MAJOR, \ - PIXMAN_VERSION_MINOR, \ - PIXMAN_VERSION_MICRO) - -#endif /* PIXMAN_VERSION_H__ */ diff --git a/source/libs/pixman/pixman-src/pixman/pixman-vmx.c b/source/libs/pixman/pixman-src/pixman/pixman-vmx.c deleted file mode 100644 index 41efdcfa1de49f23738f4e3febcbde298287eb6b..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-vmx.c +++ /dev/null @@ -1,3159 +0,0 @@ -/* - * Copyright © 2007 Luca Barbato - * - * 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 Luca Barbato not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. Luca Barbato makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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: Luca Barbato (lu_zero@gentoo.org) - * - * Based on fbmmx.c by Owen Taylor, Søren Sandmann and Nicholas Miell - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "pixman-private.h" -#include "pixman-combine32.h" -#include "pixman-inlines.h" -#include <altivec.h> - -#define AVV(x...) {x} - -static vector unsigned int mask_ff000000; -static vector unsigned int mask_red; -static vector unsigned int mask_green; -static vector unsigned int mask_blue; -static vector unsigned int mask_565_fix_rb; -static vector unsigned int mask_565_fix_g; - -static force_inline vector unsigned int -splat_alpha (vector unsigned int pix) -{ -#ifdef WORDS_BIGENDIAN - return vec_perm (pix, pix, - (vector unsigned char)AVV ( - 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, - 0x08, 0x08, 0x08, 0x08, 0x0C, 0x0C, 0x0C, 0x0C)); -#else - return vec_perm (pix, pix, - (vector unsigned char)AVV ( - 0x03, 0x03, 0x03, 0x03, 0x07, 0x07, 0x07, 0x07, - 0x0B, 0x0B, 0x0B, 0x0B, 0x0F, 0x0F, 0x0F, 0x0F)); -#endif -} - -static force_inline vector unsigned int -splat_pixel (vector unsigned int pix) -{ - return vec_perm (pix, pix, - (vector unsigned char)AVV ( - 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, - 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03)); -} - -static force_inline vector unsigned int -pix_multiply (vector unsigned int p, vector unsigned int a) -{ - vector unsigned short hi, lo, mod; - - /* unpack to short */ - hi = (vector unsigned short) -#ifdef WORDS_BIGENDIAN - vec_mergeh ((vector unsigned char)AVV (0), - (vector unsigned char)p); -#else - vec_mergeh ((vector unsigned char) p, - (vector unsigned char) AVV (0)); -#endif - - mod = (vector unsigned short) -#ifdef WORDS_BIGENDIAN - vec_mergeh ((vector unsigned char)AVV (0), - (vector unsigned char)a); -#else - vec_mergeh ((vector unsigned char) a, - (vector unsigned char) AVV (0)); -#endif - - hi = vec_mladd (hi, mod, (vector unsigned short) - AVV (0x0080, 0x0080, 0x0080, 0x0080, - 0x0080, 0x0080, 0x0080, 0x0080)); - - hi = vec_adds (hi, vec_sr (hi, vec_splat_u16 (8))); - - hi = vec_sr (hi, vec_splat_u16 (8)); - - /* unpack to short */ - lo = (vector unsigned short) -#ifdef WORDS_BIGENDIAN - vec_mergel ((vector unsigned char)AVV (0), - (vector unsigned char)p); -#else - vec_mergel ((vector unsigned char) p, - (vector unsigned char) AVV (0)); -#endif - - mod = (vector unsigned short) -#ifdef WORDS_BIGENDIAN - vec_mergel ((vector unsigned char)AVV (0), - (vector unsigned char)a); -#else - vec_mergel ((vector unsigned char) a, - (vector unsigned char) AVV (0)); -#endif - - lo = vec_mladd (lo, mod, (vector unsigned short) - AVV (0x0080, 0x0080, 0x0080, 0x0080, - 0x0080, 0x0080, 0x0080, 0x0080)); - - lo = vec_adds (lo, vec_sr (lo, vec_splat_u16 (8))); - - lo = vec_sr (lo, vec_splat_u16 (8)); - - return (vector unsigned int)vec_packsu (hi, lo); -} - -static force_inline vector unsigned int -pix_add (vector unsigned int a, vector unsigned int b) -{ - return (vector unsigned int)vec_adds ((vector unsigned char)a, - (vector unsigned char)b); -} - -static force_inline vector unsigned int -pix_add_mul (vector unsigned int x, - vector unsigned int a, - vector unsigned int y, - vector unsigned int b) -{ - vector unsigned int t1, t2; - - t1 = pix_multiply (x, a); - t2 = pix_multiply (y, b); - - return pix_add (t1, t2); -} - -static force_inline vector unsigned int -negate (vector unsigned int src) -{ - return vec_nor (src, src); -} - -/* dest*~srca + src */ -static force_inline vector unsigned int -over (vector unsigned int src, - vector unsigned int srca, - vector unsigned int dest) -{ - vector unsigned char tmp = (vector unsigned char) - pix_multiply (dest, negate (srca)); - - tmp = vec_adds ((vector unsigned char)src, tmp); - return (vector unsigned int)tmp; -} - -/* in == pix_multiply */ -#define in_over(src, srca, mask, dest) \ - over (pix_multiply (src, mask), \ - pix_multiply (srca, mask), dest) - -#ifdef WORDS_BIGENDIAN - -#define COMPUTE_SHIFT_MASK(source) \ - source ## _mask = vec_lvsl (0, source); - -#define COMPUTE_SHIFT_MASKS(dest, source) \ - source ## _mask = vec_lvsl (0, source); - -#define COMPUTE_SHIFT_MASKC(dest, source, mask) \ - mask ## _mask = vec_lvsl (0, mask); \ - source ## _mask = vec_lvsl (0, source); - -#define LOAD_VECTOR(source) \ -do \ -{ \ - vector unsigned char tmp1, tmp2; \ - tmp1 = (typeof(tmp1))vec_ld (0, source); \ - tmp2 = (typeof(tmp2))vec_ld (15, source); \ - v ## source = (typeof(v ## source)) \ - vec_perm (tmp1, tmp2, source ## _mask); \ -} while (0) - -#define LOAD_VECTORS(dest, source) \ -do \ -{ \ - LOAD_VECTOR(source); \ - v ## dest = (typeof(v ## dest))vec_ld (0, dest); \ -} while (0) - -#define LOAD_VECTORSC(dest, source, mask) \ -do \ -{ \ - LOAD_VECTORS(dest, source); \ - LOAD_VECTOR(mask); \ -} while (0) - -#define DECLARE_SRC_MASK_VAR vector unsigned char src_mask -#define DECLARE_MASK_MASK_VAR vector unsigned char mask_mask - -#else - -/* Now the COMPUTE_SHIFT_{MASK, MASKS, MASKC} below are just no-op. - * They are defined that way because little endian altivec can do unaligned - * reads natively and have no need for constructing the permutation pattern - * variables. - */ -#define COMPUTE_SHIFT_MASK(source) - -#define COMPUTE_SHIFT_MASKS(dest, source) - -#define COMPUTE_SHIFT_MASKC(dest, source, mask) - -# define LOAD_VECTOR(source) \ - v ## source = *((typeof(v ## source)*)source); - -# define LOAD_VECTORS(dest, source) \ - LOAD_VECTOR(source); \ - LOAD_VECTOR(dest); \ - -# define LOAD_VECTORSC(dest, source, mask) \ - LOAD_VECTORS(dest, source); \ - LOAD_VECTOR(mask); \ - -#define DECLARE_SRC_MASK_VAR -#define DECLARE_MASK_MASK_VAR - -#endif /* WORDS_BIGENDIAN */ - -#define LOAD_VECTORSM(dest, source, mask) \ - LOAD_VECTORSC (dest, source, mask); \ - v ## source = pix_multiply (v ## source, \ - splat_alpha (v ## mask)); - -#define STORE_VECTOR(dest) \ - vec_st ((vector unsigned int) v ## dest, 0, dest); - -/* load 4 pixels from a 16-byte boundary aligned address */ -static force_inline vector unsigned int -load_128_aligned (const uint32_t* src) -{ - return *((vector unsigned int *) src); -} - -/* load 4 pixels from a unaligned address */ -static force_inline vector unsigned int -load_128_unaligned (const uint32_t* src) -{ - vector unsigned int vsrc; - DECLARE_SRC_MASK_VAR; - - COMPUTE_SHIFT_MASK (src); - LOAD_VECTOR (src); - - return vsrc; -} - -/* save 4 pixels on a 16-byte boundary aligned address */ -static force_inline void -save_128_aligned (uint32_t* data, - vector unsigned int vdata) -{ - STORE_VECTOR(data) -} - -static force_inline vector unsigned int -create_mask_1x32_128 (const uint32_t *src) -{ - vector unsigned int vsrc; - DECLARE_SRC_MASK_VAR; - - COMPUTE_SHIFT_MASK (src); - LOAD_VECTOR (src); - return vec_splat(vsrc, 0); -} - -static force_inline vector unsigned int -create_mask_32_128 (uint32_t mask) -{ - return create_mask_1x32_128(&mask); -} - -static force_inline vector unsigned int -unpacklo_128_16x8 (vector unsigned int data1, vector unsigned int data2) -{ - vector unsigned char lo; - - /* unpack to short */ - lo = (vector unsigned char) -#ifdef WORDS_BIGENDIAN - vec_mergel ((vector unsigned char) data2, - (vector unsigned char) data1); -#else - vec_mergel ((vector unsigned char) data1, - (vector unsigned char) data2); -#endif - - return (vector unsigned int) lo; -} - -static force_inline vector unsigned int -unpackhi_128_16x8 (vector unsigned int data1, vector unsigned int data2) -{ - vector unsigned char hi; - - /* unpack to short */ - hi = (vector unsigned char) -#ifdef WORDS_BIGENDIAN - vec_mergeh ((vector unsigned char) data2, - (vector unsigned char) data1); -#else - vec_mergeh ((vector unsigned char) data1, - (vector unsigned char) data2); -#endif - - return (vector unsigned int) hi; -} - -static force_inline vector unsigned int -unpacklo_128_8x16 (vector unsigned int data1, vector unsigned int data2) -{ - vector unsigned short lo; - - /* unpack to char */ - lo = (vector unsigned short) -#ifdef WORDS_BIGENDIAN - vec_mergel ((vector unsigned short) data2, - (vector unsigned short) data1); -#else - vec_mergel ((vector unsigned short) data1, - (vector unsigned short) data2); -#endif - - return (vector unsigned int) lo; -} - -static force_inline vector unsigned int -unpackhi_128_8x16 (vector unsigned int data1, vector unsigned int data2) -{ - vector unsigned short hi; - - /* unpack to char */ - hi = (vector unsigned short) -#ifdef WORDS_BIGENDIAN - vec_mergeh ((vector unsigned short) data2, - (vector unsigned short) data1); -#else - vec_mergeh ((vector unsigned short) data1, - (vector unsigned short) data2); -#endif - - return (vector unsigned int) hi; -} - -static force_inline void -unpack_128_2x128 (vector unsigned int data1, vector unsigned int data2, - vector unsigned int* data_lo, vector unsigned int* data_hi) -{ - *data_lo = unpacklo_128_16x8(data1, data2); - *data_hi = unpackhi_128_16x8(data1, data2); -} - -static force_inline void -unpack_128_2x128_16 (vector unsigned int data1, vector unsigned int data2, - vector unsigned int* data_lo, vector unsigned int* data_hi) -{ - *data_lo = unpacklo_128_8x16(data1, data2); - *data_hi = unpackhi_128_8x16(data1, data2); -} - -static force_inline vector unsigned int -unpack_565_to_8888 (vector unsigned int lo) -{ - vector unsigned int r, g, b, rb, t; - - r = vec_and (vec_sl(lo, create_mask_32_128(8)), mask_red); - g = vec_and (vec_sl(lo, create_mask_32_128(5)), mask_green); - b = vec_and (vec_sl(lo, create_mask_32_128(3)), mask_blue); - - rb = vec_or (r, b); - t = vec_and (rb, mask_565_fix_rb); - t = vec_sr (t, create_mask_32_128(5)); - rb = vec_or (rb, t); - - t = vec_and (g, mask_565_fix_g); - t = vec_sr (t, create_mask_32_128(6)); - g = vec_or (g, t); - - return vec_or (rb, g); -} - -static force_inline int -is_opaque (vector unsigned int x) -{ - uint32_t cmp_result; - vector bool int ffs = vec_cmpeq(x, x); - - cmp_result = vec_all_eq(x, ffs); - - return (cmp_result & 0x8888) == 0x8888; -} - -static force_inline int -is_zero (vector unsigned int x) -{ - uint32_t cmp_result; - - cmp_result = vec_all_eq(x, (vector unsigned int) AVV(0)); - - return cmp_result == 0xffff; -} - -static force_inline int -is_transparent (vector unsigned int x) -{ - uint32_t cmp_result; - - cmp_result = vec_all_eq(x, (vector unsigned int) AVV(0)); - return (cmp_result & 0x8888) == 0x8888; -} - -static force_inline uint32_t -core_combine_over_u_pixel_vmx (uint32_t src, uint32_t dst) -{ - uint32_t a; - - a = ALPHA_8(src); - - if (a == 0xff) - { - return src; - } - else if (src) - { - UN8x4_MUL_UN8_ADD_UN8x4(dst, (~a & MASK), src); - } - - return dst; -} - -static force_inline uint32_t -combine1 (const uint32_t *ps, const uint32_t *pm) -{ - uint32_t s = *ps; - - if (pm) - UN8x4_MUL_UN8(s, ALPHA_8(*pm)); - - return s; -} - -static force_inline vector unsigned int -combine4 (const uint32_t* ps, const uint32_t* pm) -{ - vector unsigned int src, msk; - - if (pm) - { - msk = load_128_unaligned(pm); - - if (is_transparent(msk)) - return (vector unsigned int) AVV(0); - } - - src = load_128_unaligned(ps); - - if (pm) - src = pix_multiply(src, msk); - - return src; -} - -static void -vmx_combine_over_u_no_mask (uint32_t * dest, - const uint32_t *src, - int width) -{ - int i; - vector unsigned int vdest, vsrc; - DECLARE_SRC_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t s = *src++; - uint32_t d = *dest; - uint32_t ia = ALPHA_8 (~s); - - UN8x4_MUL_UN8_ADD_UN8x4 (d, ia, s); - - *dest++ = d; - width--; - } - - COMPUTE_SHIFT_MASKS (dest, src); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - - LOAD_VECTORS (dest, src); - - vdest = over (vsrc, splat_alpha (vsrc), vdest); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t s = src[i]; - uint32_t d = dest[i]; - uint32_t ia = ALPHA_8 (~s); - - UN8x4_MUL_UN8_ADD_UN8x4 (d, ia, s); - - dest[i] = d; - } -} - -static void -vmx_combine_over_u_mask (uint32_t * dest, - const uint32_t *src, - const uint32_t *mask, - int width) -{ - int i; - vector unsigned int vdest, vsrc, vmask; - DECLARE_SRC_MASK_VAR; - DECLARE_MASK_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t m = ALPHA_8 (*mask++); - uint32_t s = *src++; - uint32_t d = *dest; - uint32_t ia; - - UN8x4_MUL_UN8 (s, m); - - ia = ALPHA_8 (~s); - - UN8x4_MUL_UN8_ADD_UN8x4 (d, ia, s); - *dest++ = d; - width--; - } - - COMPUTE_SHIFT_MASKC (dest, src, mask); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - LOAD_VECTORSM (dest, src, mask); - - vdest = over (vsrc, splat_alpha (vsrc), vdest); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - mask += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t m = ALPHA_8 (mask[i]); - uint32_t s = src[i]; - uint32_t d = dest[i]; - uint32_t ia; - - UN8x4_MUL_UN8 (s, m); - - ia = ALPHA_8 (~s); - - UN8x4_MUL_UN8_ADD_UN8x4 (d, ia, s); - dest[i] = d; - } -} - -static void -vmx_combine_over_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - if (mask) - vmx_combine_over_u_mask (dest, src, mask, width); - else - vmx_combine_over_u_no_mask (dest, src, width); -} - -static void -vmx_combine_over_reverse_u_no_mask (uint32_t * dest, - const uint32_t *src, - int width) -{ - int i; - vector unsigned int vdest, vsrc; - DECLARE_SRC_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t s = *src++; - uint32_t d = *dest; - uint32_t ia = ALPHA_8 (~d); - - UN8x4_MUL_UN8_ADD_UN8x4 (s, ia, d); - *dest++ = s; - width--; - } - - COMPUTE_SHIFT_MASKS (dest, src); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - - LOAD_VECTORS (dest, src); - - vdest = over (vdest, splat_alpha (vdest), vsrc); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t s = src[i]; - uint32_t d = dest[i]; - uint32_t ia = ALPHA_8 (~dest[i]); - - UN8x4_MUL_UN8_ADD_UN8x4 (s, ia, d); - dest[i] = s; - } -} - -static void -vmx_combine_over_reverse_u_mask (uint32_t * dest, - const uint32_t *src, - const uint32_t *mask, - int width) -{ - int i; - vector unsigned int vdest, vsrc, vmask; - DECLARE_SRC_MASK_VAR; - DECLARE_MASK_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t m = ALPHA_8 (*mask++); - uint32_t s = *src++; - uint32_t d = *dest; - uint32_t ia = ALPHA_8 (~d); - - UN8x4_MUL_UN8 (s, m); - - UN8x4_MUL_UN8_ADD_UN8x4 (s, ia, d); - *dest++ = s; - width--; - } - - COMPUTE_SHIFT_MASKC (dest, src, mask); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - - LOAD_VECTORSM (dest, src, mask); - - vdest = over (vdest, splat_alpha (vdest), vsrc); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - mask += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t m = ALPHA_8 (mask[i]); - uint32_t s = src[i]; - uint32_t d = dest[i]; - uint32_t ia = ALPHA_8 (~dest[i]); - - UN8x4_MUL_UN8 (s, m); - - UN8x4_MUL_UN8_ADD_UN8x4 (s, ia, d); - dest[i] = s; - } -} - -static void -vmx_combine_over_reverse_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - if (mask) - vmx_combine_over_reverse_u_mask (dest, src, mask, width); - else - vmx_combine_over_reverse_u_no_mask (dest, src, width); -} - -static void -vmx_combine_in_u_no_mask (uint32_t * dest, - const uint32_t *src, - int width) -{ - int i; - vector unsigned int vdest, vsrc; - DECLARE_SRC_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t s = *src++; - uint32_t a = ALPHA_8 (*dest); - - UN8x4_MUL_UN8 (s, a); - *dest++ = s; - width--; - } - - COMPUTE_SHIFT_MASKS (dest, src); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - LOAD_VECTORS (dest, src); - - vdest = pix_multiply (vsrc, splat_alpha (vdest)); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t s = src[i]; - uint32_t a = ALPHA_8 (dest[i]); - - UN8x4_MUL_UN8 (s, a); - dest[i] = s; - } -} - -static void -vmx_combine_in_u_mask (uint32_t * dest, - const uint32_t *src, - const uint32_t *mask, - int width) -{ - int i; - vector unsigned int vdest, vsrc, vmask; - DECLARE_SRC_MASK_VAR; - DECLARE_MASK_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t m = ALPHA_8 (*mask++); - uint32_t s = *src++; - uint32_t a = ALPHA_8 (*dest); - - UN8x4_MUL_UN8 (s, m); - UN8x4_MUL_UN8 (s, a); - - *dest++ = s; - width--; - } - - COMPUTE_SHIFT_MASKC (dest, src, mask); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - LOAD_VECTORSM (dest, src, mask); - - vdest = pix_multiply (vsrc, splat_alpha (vdest)); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - mask += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t m = ALPHA_8 (mask[i]); - uint32_t s = src[i]; - uint32_t a = ALPHA_8 (dest[i]); - - UN8x4_MUL_UN8 (s, m); - UN8x4_MUL_UN8 (s, a); - - dest[i] = s; - } -} - -static void -vmx_combine_in_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - if (mask) - vmx_combine_in_u_mask (dest, src, mask, width); - else - vmx_combine_in_u_no_mask (dest, src, width); -} - -static void -vmx_combine_in_reverse_u_no_mask (uint32_t * dest, - const uint32_t *src, - int width) -{ - int i; - vector unsigned int vdest, vsrc; - DECLARE_SRC_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t d = *dest; - uint32_t a = ALPHA_8 (*src++); - - UN8x4_MUL_UN8 (d, a); - - *dest++ = d; - width--; - } - - COMPUTE_SHIFT_MASKS (dest, src); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - LOAD_VECTORS (dest, src); - - vdest = pix_multiply (vdest, splat_alpha (vsrc)); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t d = dest[i]; - uint32_t a = ALPHA_8 (src[i]); - - UN8x4_MUL_UN8 (d, a); - - dest[i] = d; - } -} - -static void -vmx_combine_in_reverse_u_mask (uint32_t * dest, - const uint32_t *src, - const uint32_t *mask, - int width) -{ - int i; - vector unsigned int vdest, vsrc, vmask; - DECLARE_SRC_MASK_VAR; - DECLARE_MASK_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t m = ALPHA_8 (*mask++); - uint32_t d = *dest; - uint32_t a = *src++; - - UN8x4_MUL_UN8 (a, m); - a = ALPHA_8 (a); - UN8x4_MUL_UN8 (d, a); - - *dest++ = d; - width--; - } - - COMPUTE_SHIFT_MASKC (dest, src, mask); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - LOAD_VECTORSM (dest, src, mask); - - vdest = pix_multiply (vdest, splat_alpha (vsrc)); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - mask += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t m = ALPHA_8 (mask[i]); - uint32_t d = dest[i]; - uint32_t a = src[i]; - - UN8x4_MUL_UN8 (a, m); - a = ALPHA_8 (a); - UN8x4_MUL_UN8 (d, a); - - dest[i] = d; - } -} - -static void -vmx_combine_in_reverse_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - if (mask) - vmx_combine_in_reverse_u_mask (dest, src, mask, width); - else - vmx_combine_in_reverse_u_no_mask (dest, src, width); -} - -static void -vmx_combine_out_u_no_mask (uint32_t * dest, - const uint32_t *src, - int width) -{ - int i; - vector unsigned int vdest, vsrc; - DECLARE_SRC_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t s = *src++; - uint32_t a = ALPHA_8 (~(*dest)); - - UN8x4_MUL_UN8 (s, a); - - *dest++ = s; - width--; - } - - COMPUTE_SHIFT_MASKS (dest, src); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - LOAD_VECTORS (dest, src); - - vdest = pix_multiply (vsrc, splat_alpha (negate (vdest))); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t s = src[i]; - uint32_t a = ALPHA_8 (~dest[i]); - - UN8x4_MUL_UN8 (s, a); - - dest[i] = s; - } -} - -static void -vmx_combine_out_u_mask (uint32_t * dest, - const uint32_t *src, - const uint32_t *mask, - int width) -{ - int i; - vector unsigned int vdest, vsrc, vmask; - DECLARE_SRC_MASK_VAR; - DECLARE_MASK_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t m = ALPHA_8 (*mask++); - uint32_t s = *src++; - uint32_t a = ALPHA_8 (~(*dest)); - - UN8x4_MUL_UN8 (s, m); - UN8x4_MUL_UN8 (s, a); - - *dest++ = s; - width--; - } - - COMPUTE_SHIFT_MASKC (dest, src, mask); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - LOAD_VECTORSM (dest, src, mask); - - vdest = pix_multiply (vsrc, splat_alpha (negate (vdest))); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - mask += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t m = ALPHA_8 (mask[i]); - uint32_t s = src[i]; - uint32_t a = ALPHA_8 (~dest[i]); - - UN8x4_MUL_UN8 (s, m); - UN8x4_MUL_UN8 (s, a); - - dest[i] = s; - } -} - -static void -vmx_combine_out_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - if (mask) - vmx_combine_out_u_mask (dest, src, mask, width); - else - vmx_combine_out_u_no_mask (dest, src, width); -} - -static void -vmx_combine_out_reverse_u_no_mask (uint32_t * dest, - const uint32_t *src, - int width) -{ - int i; - vector unsigned int vdest, vsrc; - DECLARE_SRC_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t d = *dest; - uint32_t a = ALPHA_8 (~(*src++)); - - UN8x4_MUL_UN8 (d, a); - - *dest++ = d; - width--; - } - - COMPUTE_SHIFT_MASKS (dest, src); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - - LOAD_VECTORS (dest, src); - - vdest = pix_multiply (vdest, splat_alpha (negate (vsrc))); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t d = dest[i]; - uint32_t a = ALPHA_8 (~src[i]); - - UN8x4_MUL_UN8 (d, a); - - dest[i] = d; - } -} - -static void -vmx_combine_out_reverse_u_mask (uint32_t * dest, - const uint32_t *src, - const uint32_t *mask, - int width) -{ - int i; - vector unsigned int vdest, vsrc, vmask; - DECLARE_SRC_MASK_VAR; - DECLARE_MASK_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t m = ALPHA_8 (*mask++); - uint32_t d = *dest; - uint32_t a = *src++; - - UN8x4_MUL_UN8 (a, m); - a = ALPHA_8 (~a); - UN8x4_MUL_UN8 (d, a); - - *dest++ = d; - width--; - } - - COMPUTE_SHIFT_MASKC (dest, src, mask); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - LOAD_VECTORSM (dest, src, mask); - - vdest = pix_multiply (vdest, splat_alpha (negate (vsrc))); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - mask += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t m = ALPHA_8 (mask[i]); - uint32_t d = dest[i]; - uint32_t a = src[i]; - - UN8x4_MUL_UN8 (a, m); - a = ALPHA_8 (~a); - UN8x4_MUL_UN8 (d, a); - - dest[i] = d; - } -} - -static void -vmx_combine_out_reverse_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - if (mask) - vmx_combine_out_reverse_u_mask (dest, src, mask, width); - else - vmx_combine_out_reverse_u_no_mask (dest, src, width); -} - -static void -vmx_combine_atop_u_no_mask (uint32_t * dest, - const uint32_t *src, - int width) -{ - int i; - vector unsigned int vdest, vsrc; - DECLARE_SRC_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t s = *src++; - uint32_t d = *dest; - uint32_t dest_a = ALPHA_8 (d); - uint32_t src_ia = ALPHA_8 (~s); - - UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_a, d, src_ia); - - *dest++ = s; - width--; - } - - COMPUTE_SHIFT_MASKS (dest, src); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - LOAD_VECTORS (dest, src); - - vdest = pix_add_mul (vsrc, splat_alpha (vdest), - vdest, splat_alpha (negate (vsrc))); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t s = src[i]; - uint32_t d = dest[i]; - uint32_t dest_a = ALPHA_8 (d); - uint32_t src_ia = ALPHA_8 (~s); - - UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_a, d, src_ia); - - dest[i] = s; - } -} - -static void -vmx_combine_atop_u_mask (uint32_t * dest, - const uint32_t *src, - const uint32_t *mask, - int width) -{ - int i; - vector unsigned int vdest, vsrc, vmask; - DECLARE_SRC_MASK_VAR; - DECLARE_MASK_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t m = ALPHA_8 (*mask++); - uint32_t s = *src++; - uint32_t d = *dest; - uint32_t dest_a = ALPHA_8 (d); - uint32_t src_ia; - - UN8x4_MUL_UN8 (s, m); - - src_ia = ALPHA_8 (~s); - - UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_a, d, src_ia); - - *dest++ = s; - width--; - } - - COMPUTE_SHIFT_MASKC (dest, src, mask); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - LOAD_VECTORSM (dest, src, mask); - - vdest = pix_add_mul (vsrc, splat_alpha (vdest), - vdest, splat_alpha (negate (vsrc))); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - mask += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t m = ALPHA_8 (mask[i]); - uint32_t s = src[i]; - uint32_t d = dest[i]; - uint32_t dest_a = ALPHA_8 (d); - uint32_t src_ia; - - UN8x4_MUL_UN8 (s, m); - - src_ia = ALPHA_8 (~s); - - UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_a, d, src_ia); - - dest[i] = s; - } -} - -static void -vmx_combine_atop_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - if (mask) - vmx_combine_atop_u_mask (dest, src, mask, width); - else - vmx_combine_atop_u_no_mask (dest, src, width); -} - -static void -vmx_combine_atop_reverse_u_no_mask (uint32_t * dest, - const uint32_t *src, - int width) -{ - int i; - vector unsigned int vdest, vsrc; - DECLARE_SRC_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t s = *src++; - uint32_t d = *dest; - uint32_t src_a = ALPHA_8 (s); - uint32_t dest_ia = ALPHA_8 (~d); - - UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_ia, d, src_a); - - *dest++ = s; - width--; - } - - COMPUTE_SHIFT_MASKS (dest, src); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - LOAD_VECTORS (dest, src); - - vdest = pix_add_mul (vdest, splat_alpha (vsrc), - vsrc, splat_alpha (negate (vdest))); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t s = src[i]; - uint32_t d = dest[i]; - uint32_t src_a = ALPHA_8 (s); - uint32_t dest_ia = ALPHA_8 (~d); - - UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_ia, d, src_a); - - dest[i] = s; - } -} - -static void -vmx_combine_atop_reverse_u_mask (uint32_t * dest, - const uint32_t *src, - const uint32_t *mask, - int width) -{ - int i; - vector unsigned int vdest, vsrc, vmask; - DECLARE_SRC_MASK_VAR; - DECLARE_MASK_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t m = ALPHA_8 (*mask++); - uint32_t s = *src++; - uint32_t d = *dest; - uint32_t src_a; - uint32_t dest_ia = ALPHA_8 (~d); - - UN8x4_MUL_UN8 (s, m); - - src_a = ALPHA_8 (s); - - UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_ia, d, src_a); - - *dest++ = s; - width--; - } - - COMPUTE_SHIFT_MASKC (dest, src, mask); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - LOAD_VECTORSM (dest, src, mask); - - vdest = pix_add_mul (vdest, splat_alpha (vsrc), - vsrc, splat_alpha (negate (vdest))); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - mask += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t m = ALPHA_8 (mask[i]); - uint32_t s = src[i]; - uint32_t d = dest[i]; - uint32_t src_a; - uint32_t dest_ia = ALPHA_8 (~d); - - UN8x4_MUL_UN8 (s, m); - - src_a = ALPHA_8 (s); - - UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_ia, d, src_a); - - dest[i] = s; - } -} - -static void -vmx_combine_atop_reverse_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - if (mask) - vmx_combine_atop_reverse_u_mask (dest, src, mask, width); - else - vmx_combine_atop_reverse_u_no_mask (dest, src, width); -} - -static void -vmx_combine_xor_u_no_mask (uint32_t * dest, - const uint32_t *src, - int width) -{ - int i; - vector unsigned int vdest, vsrc; - DECLARE_SRC_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t s = *src++; - uint32_t d = *dest; - uint32_t src_ia = ALPHA_8 (~s); - uint32_t dest_ia = ALPHA_8 (~d); - - UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_ia, d, src_ia); - - *dest++ = s; - width--; - } - - COMPUTE_SHIFT_MASKS (dest, src); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - LOAD_VECTORS (dest, src); - - vdest = pix_add_mul (vsrc, splat_alpha (negate (vdest)), - vdest, splat_alpha (negate (vsrc))); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t s = src[i]; - uint32_t d = dest[i]; - uint32_t src_ia = ALPHA_8 (~s); - uint32_t dest_ia = ALPHA_8 (~d); - - UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_ia, d, src_ia); - - dest[i] = s; - } -} - -static void -vmx_combine_xor_u_mask (uint32_t * dest, - const uint32_t *src, - const uint32_t *mask, - int width) -{ - int i; - vector unsigned int vdest, vsrc, vmask; - DECLARE_SRC_MASK_VAR; - DECLARE_MASK_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t m = ALPHA_8 (*mask++); - uint32_t s = *src++; - uint32_t d = *dest; - uint32_t src_ia; - uint32_t dest_ia = ALPHA_8 (~d); - - UN8x4_MUL_UN8 (s, m); - - src_ia = ALPHA_8 (~s); - - UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_ia, d, src_ia); - - *dest++ = s; - width--; - } - - COMPUTE_SHIFT_MASKC (dest, src, mask); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - LOAD_VECTORSM (dest, src, mask); - - vdest = pix_add_mul (vsrc, splat_alpha (negate (vdest)), - vdest, splat_alpha (negate (vsrc))); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - mask += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t m = ALPHA_8 (mask[i]); - uint32_t s = src[i]; - uint32_t d = dest[i]; - uint32_t src_ia; - uint32_t dest_ia = ALPHA_8 (~d); - - UN8x4_MUL_UN8 (s, m); - - src_ia = ALPHA_8 (~s); - - UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_ia, d, src_ia); - - dest[i] = s; - } -} - -static void -vmx_combine_xor_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - if (mask) - vmx_combine_xor_u_mask (dest, src, mask, width); - else - vmx_combine_xor_u_no_mask (dest, src, width); -} - -static void -vmx_combine_add_u_no_mask (uint32_t * dest, - const uint32_t *src, - int width) -{ - int i; - vector unsigned int vdest, vsrc; - DECLARE_SRC_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t s = *src++; - uint32_t d = *dest; - - UN8x4_ADD_UN8x4 (d, s); - - *dest++ = d; - width--; - } - - COMPUTE_SHIFT_MASKS (dest, src); - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - LOAD_VECTORS (dest, src); - - vdest = pix_add (vsrc, vdest); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t s = src[i]; - uint32_t d = dest[i]; - - UN8x4_ADD_UN8x4 (d, s); - - dest[i] = d; - } -} - -static void -vmx_combine_add_u_mask (uint32_t * dest, - const uint32_t *src, - const uint32_t *mask, - int width) -{ - int i; - vector unsigned int vdest, vsrc, vmask; - DECLARE_SRC_MASK_VAR; - DECLARE_MASK_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t m = ALPHA_8 (*mask++); - uint32_t s = *src++; - uint32_t d = *dest; - - UN8x4_MUL_UN8 (s, m); - UN8x4_ADD_UN8x4 (d, s); - - *dest++ = d; - width--; - } - - COMPUTE_SHIFT_MASKC (dest, src, mask); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - LOAD_VECTORSM (dest, src, mask); - - vdest = pix_add (vsrc, vdest); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - mask += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t m = ALPHA_8 (mask[i]); - uint32_t s = src[i]; - uint32_t d = dest[i]; - - UN8x4_MUL_UN8 (s, m); - UN8x4_ADD_UN8x4 (d, s); - - dest[i] = d; - } -} - -static void -vmx_combine_add_u (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - if (mask) - vmx_combine_add_u_mask (dest, src, mask, width); - else - vmx_combine_add_u_no_mask (dest, src, width); -} - -static void -vmx_combine_src_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - vector unsigned int vdest, vsrc, vmask; - DECLARE_SRC_MASK_VAR; - DECLARE_MASK_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t a = *mask++; - uint32_t s = *src++; - - UN8x4_MUL_UN8x4 (s, a); - - *dest++ = s; - width--; - } - - COMPUTE_SHIFT_MASKC (dest, src, mask); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - LOAD_VECTORSC (dest, src, mask); - - vdest = pix_multiply (vsrc, vmask); - - STORE_VECTOR (dest); - - mask += 4; - src += 4; - dest += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t a = mask[i]; - uint32_t s = src[i]; - - UN8x4_MUL_UN8x4 (s, a); - - dest[i] = s; - } -} - -static void -vmx_combine_over_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - vector unsigned int vdest, vsrc, vmask; - DECLARE_SRC_MASK_VAR; - DECLARE_MASK_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t a = *mask++; - uint32_t s = *src++; - uint32_t d = *dest; - uint32_t sa = ALPHA_8 (s); - - UN8x4_MUL_UN8x4 (s, a); - UN8x4_MUL_UN8 (a, sa); - UN8x4_MUL_UN8x4_ADD_UN8x4 (d, ~a, s); - - *dest++ = d; - width--; - } - - COMPUTE_SHIFT_MASKC (dest, src, mask); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - LOAD_VECTORSC (dest, src, mask); - - vdest = in_over (vsrc, splat_alpha (vsrc), vmask, vdest); - - STORE_VECTOR (dest); - - mask += 4; - src += 4; - dest += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t a = mask[i]; - uint32_t s = src[i]; - uint32_t d = dest[i]; - uint32_t sa = ALPHA_8 (s); - - UN8x4_MUL_UN8x4 (s, a); - UN8x4_MUL_UN8 (a, sa); - UN8x4_MUL_UN8x4_ADD_UN8x4 (d, ~a, s); - - dest[i] = d; - } -} - -static void -vmx_combine_over_reverse_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - vector unsigned int vdest, vsrc, vmask; - DECLARE_SRC_MASK_VAR; - DECLARE_MASK_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t a = *mask++; - uint32_t s = *src++; - uint32_t d = *dest; - uint32_t ida = ALPHA_8 (~d); - - UN8x4_MUL_UN8x4 (s, a); - UN8x4_MUL_UN8_ADD_UN8x4 (s, ida, d); - - *dest++ = s; - width--; - } - - COMPUTE_SHIFT_MASKC (dest, src, mask); - - /* printf("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - LOAD_VECTORSC (dest, src, mask); - - vdest = over (vdest, splat_alpha (vdest), pix_multiply (vsrc, vmask)); - - STORE_VECTOR (dest); - - mask += 4; - src += 4; - dest += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t a = mask[i]; - uint32_t s = src[i]; - uint32_t d = dest[i]; - uint32_t ida = ALPHA_8 (~d); - - UN8x4_MUL_UN8x4 (s, a); - UN8x4_MUL_UN8_ADD_UN8x4 (s, ida, d); - - dest[i] = s; - } -} - -static void -vmx_combine_in_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - vector unsigned int vdest, vsrc, vmask; - DECLARE_SRC_MASK_VAR; - DECLARE_MASK_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t a = *mask++; - uint32_t s = *src++; - uint32_t da = ALPHA_8 (*dest); - - UN8x4_MUL_UN8x4 (s, a); - UN8x4_MUL_UN8 (s, da); - - *dest++ = s; - width--; - } - - COMPUTE_SHIFT_MASKC (dest, src, mask); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - LOAD_VECTORSC (dest, src, mask); - - vdest = pix_multiply (pix_multiply (vsrc, vmask), splat_alpha (vdest)); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - mask += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t a = mask[i]; - uint32_t s = src[i]; - uint32_t da = ALPHA_8 (dest[i]); - - UN8x4_MUL_UN8x4 (s, a); - UN8x4_MUL_UN8 (s, da); - - dest[i] = s; - } -} - -static void -vmx_combine_in_reverse_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - vector unsigned int vdest, vsrc, vmask; - DECLARE_SRC_MASK_VAR; - DECLARE_MASK_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t a = *mask++; - uint32_t d = *dest; - uint32_t sa = ALPHA_8 (*src++); - - UN8x4_MUL_UN8 (a, sa); - UN8x4_MUL_UN8x4 (d, a); - - *dest++ = d; - width--; - } - - COMPUTE_SHIFT_MASKC (dest, src, mask); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - - LOAD_VECTORSC (dest, src, mask); - - vdest = pix_multiply (vdest, pix_multiply (vmask, splat_alpha (vsrc))); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - mask += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t a = mask[i]; - uint32_t d = dest[i]; - uint32_t sa = ALPHA_8 (src[i]); - - UN8x4_MUL_UN8 (a, sa); - UN8x4_MUL_UN8x4 (d, a); - - dest[i] = d; - } -} - -static void -vmx_combine_out_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - vector unsigned int vdest, vsrc, vmask; - DECLARE_SRC_MASK_VAR; - DECLARE_MASK_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t a = *mask++; - uint32_t s = *src++; - uint32_t d = *dest; - uint32_t da = ALPHA_8 (~d); - - UN8x4_MUL_UN8x4 (s, a); - UN8x4_MUL_UN8 (s, da); - - *dest++ = s; - width--; - } - - COMPUTE_SHIFT_MASKC (dest, src, mask); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - LOAD_VECTORSC (dest, src, mask); - - vdest = pix_multiply ( - pix_multiply (vsrc, vmask), splat_alpha (negate (vdest))); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - mask += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t a = mask[i]; - uint32_t s = src[i]; - uint32_t d = dest[i]; - uint32_t da = ALPHA_8 (~d); - - UN8x4_MUL_UN8x4 (s, a); - UN8x4_MUL_UN8 (s, da); - - dest[i] = s; - } -} - -static void -vmx_combine_out_reverse_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - vector unsigned int vdest, vsrc, vmask; - DECLARE_SRC_MASK_VAR; - DECLARE_MASK_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t a = *mask++; - uint32_t s = *src++; - uint32_t d = *dest; - uint32_t sa = ALPHA_8 (s); - - UN8x4_MUL_UN8 (a, sa); - UN8x4_MUL_UN8x4 (d, ~a); - - *dest++ = d; - width--; - } - - COMPUTE_SHIFT_MASKC (dest, src, mask); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - LOAD_VECTORSC (dest, src, mask); - - vdest = pix_multiply ( - vdest, negate (pix_multiply (vmask, splat_alpha (vsrc)))); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - mask += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t a = mask[i]; - uint32_t s = src[i]; - uint32_t d = dest[i]; - uint32_t sa = ALPHA_8 (s); - - UN8x4_MUL_UN8 (a, sa); - UN8x4_MUL_UN8x4 (d, ~a); - - dest[i] = d; - } -} - -static void -vmx_combine_atop_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - vector unsigned int vdest, vsrc, vmask, vsrca; - DECLARE_SRC_MASK_VAR; - DECLARE_MASK_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t a = *mask++; - uint32_t s = *src++; - uint32_t d = *dest; - uint32_t sa = ALPHA_8 (s); - uint32_t da = ALPHA_8 (d); - - UN8x4_MUL_UN8x4 (s, a); - UN8x4_MUL_UN8 (a, sa); - UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (d, ~a, s, da); - - *dest++ = d; - width--; - } - - COMPUTE_SHIFT_MASKC (dest, src, mask); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - LOAD_VECTORSC (dest, src, mask); - - vsrca = splat_alpha (vsrc); - - vsrc = pix_multiply (vsrc, vmask); - vmask = pix_multiply (vmask, vsrca); - - vdest = pix_add_mul (vsrc, splat_alpha (vdest), - negate (vmask), vdest); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - mask += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t a = mask[i]; - uint32_t s = src[i]; - uint32_t d = dest[i]; - uint32_t sa = ALPHA_8 (s); - uint32_t da = ALPHA_8 (d); - - UN8x4_MUL_UN8x4 (s, a); - UN8x4_MUL_UN8 (a, sa); - UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (d, ~a, s, da); - - dest[i] = d; - } -} - -static void -vmx_combine_atop_reverse_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - vector unsigned int vdest, vsrc, vmask; - DECLARE_SRC_MASK_VAR; - DECLARE_MASK_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t a = *mask++; - uint32_t s = *src++; - uint32_t d = *dest; - uint32_t sa = ALPHA_8 (s); - uint32_t da = ALPHA_8 (~d); - - UN8x4_MUL_UN8x4 (s, a); - UN8x4_MUL_UN8 (a, sa); - UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (d, a, s, da); - - *dest++ = d; - width--; - } - - COMPUTE_SHIFT_MASKC (dest, src, mask); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - LOAD_VECTORSC (dest, src, mask); - - vdest = pix_add_mul (vdest, - pix_multiply (vmask, splat_alpha (vsrc)), - pix_multiply (vsrc, vmask), - negate (splat_alpha (vdest))); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - mask += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t a = mask[i]; - uint32_t s = src[i]; - uint32_t d = dest[i]; - uint32_t sa = ALPHA_8 (s); - uint32_t da = ALPHA_8 (~d); - - UN8x4_MUL_UN8x4 (s, a); - UN8x4_MUL_UN8 (a, sa); - UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (d, a, s, da); - - dest[i] = d; - } -} - -static void -vmx_combine_xor_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - vector unsigned int vdest, vsrc, vmask; - DECLARE_SRC_MASK_VAR; - DECLARE_MASK_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t a = *mask++; - uint32_t s = *src++; - uint32_t d = *dest; - uint32_t sa = ALPHA_8 (s); - uint32_t da = ALPHA_8 (~d); - - UN8x4_MUL_UN8x4 (s, a); - UN8x4_MUL_UN8 (a, sa); - UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (d, ~a, s, da); - - *dest++ = d; - width--; - } - - COMPUTE_SHIFT_MASKC (dest, src, mask); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - LOAD_VECTORSC (dest, src, mask); - - vdest = pix_add_mul (vdest, - negate (pix_multiply (vmask, splat_alpha (vsrc))), - pix_multiply (vsrc, vmask), - negate (splat_alpha (vdest))); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - mask += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t a = mask[i]; - uint32_t s = src[i]; - uint32_t d = dest[i]; - uint32_t sa = ALPHA_8 (s); - uint32_t da = ALPHA_8 (~d); - - UN8x4_MUL_UN8x4 (s, a); - UN8x4_MUL_UN8 (a, sa); - UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (d, ~a, s, da); - - dest[i] = d; - } -} - -static void -vmx_combine_add_ca (pixman_implementation_t *imp, - pixman_op_t op, - uint32_t * dest, - const uint32_t * src, - const uint32_t * mask, - int width) -{ - int i; - vector unsigned int vdest, vsrc, vmask; - DECLARE_SRC_MASK_VAR; - DECLARE_MASK_MASK_VAR; - - while (width && ((uintptr_t)dest & 15)) - { - uint32_t a = *mask++; - uint32_t s = *src++; - uint32_t d = *dest; - - UN8x4_MUL_UN8x4 (s, a); - UN8x4_ADD_UN8x4 (s, d); - - *dest++ = s; - width--; - } - - COMPUTE_SHIFT_MASKC (dest, src, mask); - - /* printf ("%s\n",__PRETTY_FUNCTION__); */ - for (i = width / 4; i > 0; i--) - { - LOAD_VECTORSC (dest, src, mask); - - vdest = pix_add (pix_multiply (vsrc, vmask), vdest); - - STORE_VECTOR (dest); - - src += 4; - dest += 4; - mask += 4; - } - - for (i = width % 4; --i >= 0;) - { - uint32_t a = mask[i]; - uint32_t s = src[i]; - uint32_t d = dest[i]; - - UN8x4_MUL_UN8x4 (s, a); - UN8x4_ADD_UN8x4 (s, d); - - dest[i] = s; - } -} - -static void -vmx_composite_over_n_8_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src, srca; - uint32_t *dst_line, *dst; - uint8_t *mask_line; - int dst_stride, mask_stride; - int32_t w; - uint32_t m, d, s, ia; - - vector unsigned int vsrc, valpha, vmask, vdst; - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - srca = ALPHA_8(src); - if (src == 0) - return; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE ( - mask_image, mask_x, mask_y, uint8_t, mask_stride, mask_line, 1); - - vsrc = (vector unsigned int) {src, src, src, src}; - valpha = splat_alpha(vsrc); - - while (height--) - { - const uint8_t *pm = mask_line; - dst = dst_line; - dst_line += dst_stride; - mask_line += mask_stride; - w = width; - - while (w && (uintptr_t)dst & 15) - { - s = src; - m = *pm++; - - if (m) - { - d = *dst; - UN8x4_MUL_UN8 (s, m); - ia = ALPHA_8 (~s); - UN8x4_MUL_UN8_ADD_UN8x4 (d, ia, s); - *dst = d; - } - - w--; - dst++; - } - - while (w >= 4) - { - m = *((uint32_t*)pm); - - if (srca == 0xff && m == 0xffffffff) - { - save_128_aligned(dst, vsrc); - } - else if (m) - { - vmask = splat_pixel((vector unsigned int) {m, m, m, m}); - - /* dst is 16-byte aligned */ - vdst = in_over (vsrc, valpha, vmask, load_128_aligned (dst)); - - save_128_aligned(dst, vdst); - } - - w -= 4; - dst += 4; - pm += 4; - } - - while (w) - { - s = src; - m = *pm++; - - if (m) - { - d = *dst; - UN8x4_MUL_UN8 (s, m); - ia = ALPHA_8 (~s); - UN8x4_MUL_UN8_ADD_UN8x4 (d, ia, s); - *dst = d; - } - - w--; - dst++; - } - } - -} - -static pixman_bool_t -vmx_fill (pixman_implementation_t *imp, - uint32_t * bits, - int stride, - int bpp, - int x, - int y, - int width, - int height, - uint32_t filler) -{ - uint32_t byte_width; - uint8_t *byte_line; - - vector unsigned int vfiller; - - if (bpp == 8) - { - uint8_t b; - uint16_t w; - - stride = stride * (int) sizeof (uint32_t) / 1; - byte_line = (uint8_t *)(((uint8_t *)bits) + stride * y + x); - byte_width = width; - stride *= 1; - - b = filler & 0xff; - w = (b << 8) | b; - filler = (w << 16) | w; - } - else if (bpp == 16) - { - stride = stride * (int) sizeof (uint32_t) / 2; - byte_line = (uint8_t *)(((uint16_t *)bits) + stride * y + x); - byte_width = 2 * width; - stride *= 2; - - filler = (filler & 0xffff) * 0x00010001; - } - else if (bpp == 32) - { - stride = stride * (int) sizeof (uint32_t) / 4; - byte_line = (uint8_t *)(((uint32_t *)bits) + stride * y + x); - byte_width = 4 * width; - stride *= 4; - } - else - { - return FALSE; - } - - vfiller = create_mask_1x32_128(&filler); - - while (height--) - { - int w; - uint8_t *d = byte_line; - byte_line += stride; - w = byte_width; - - if (w >= 1 && ((uintptr_t)d & 1)) - { - *(uint8_t *)d = filler; - w -= 1; - d += 1; - } - - while (w >= 2 && ((uintptr_t)d & 3)) - { - *(uint16_t *)d = filler; - w -= 2; - d += 2; - } - - while (w >= 4 && ((uintptr_t)d & 15)) - { - *(uint32_t *)d = filler; - - w -= 4; - d += 4; - } - - while (w >= 128) - { - vec_st(vfiller, 0, (uint32_t *) d); - vec_st(vfiller, 0, (uint32_t *) d + 4); - vec_st(vfiller, 0, (uint32_t *) d + 8); - vec_st(vfiller, 0, (uint32_t *) d + 12); - vec_st(vfiller, 0, (uint32_t *) d + 16); - vec_st(vfiller, 0, (uint32_t *) d + 20); - vec_st(vfiller, 0, (uint32_t *) d + 24); - vec_st(vfiller, 0, (uint32_t *) d + 28); - - d += 128; - w -= 128; - } - - if (w >= 64) - { - vec_st(vfiller, 0, (uint32_t *) d); - vec_st(vfiller, 0, (uint32_t *) d + 4); - vec_st(vfiller, 0, (uint32_t *) d + 8); - vec_st(vfiller, 0, (uint32_t *) d + 12); - - d += 64; - w -= 64; - } - - if (w >= 32) - { - vec_st(vfiller, 0, (uint32_t *) d); - vec_st(vfiller, 0, (uint32_t *) d + 4); - - d += 32; - w -= 32; - } - - if (w >= 16) - { - vec_st(vfiller, 0, (uint32_t *) d); - - d += 16; - w -= 16; - } - - while (w >= 4) - { - *(uint32_t *)d = filler; - - w -= 4; - d += 4; - } - - if (w >= 2) - { - *(uint16_t *)d = filler; - w -= 2; - d += 2; - } - - if (w >= 1) - { - *(uint8_t *)d = filler; - w -= 1; - d += 1; - } - } - - return TRUE; -} - -static void -vmx_composite_src_x888_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t *dst_line, *dst; - uint32_t *src_line, *src; - int32_t w; - int dst_stride, src_stride; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE ( - src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - w = width; - - while (w && (uintptr_t)dst & 15) - { - *dst++ = *src++ | 0xff000000; - w--; - } - - while (w >= 16) - { - vector unsigned int vmx_src1, vmx_src2, vmx_src3, vmx_src4; - - vmx_src1 = load_128_unaligned (src); - vmx_src2 = load_128_unaligned (src + 4); - vmx_src3 = load_128_unaligned (src + 8); - vmx_src4 = load_128_unaligned (src + 12); - - save_128_aligned (dst, vec_or (vmx_src1, mask_ff000000)); - save_128_aligned (dst + 4, vec_or (vmx_src2, mask_ff000000)); - save_128_aligned (dst + 8, vec_or (vmx_src3, mask_ff000000)); - save_128_aligned (dst + 12, vec_or (vmx_src4, mask_ff000000)); - - dst += 16; - src += 16; - w -= 16; - } - - while (w) - { - *dst++ = *src++ | 0xff000000; - w--; - } - } -} - -static void -vmx_composite_over_n_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t *dst_line, *dst; - uint32_t src, ia; - int i, w, dst_stride; - vector unsigned int vdst, vsrc, via; - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - if (src == 0) - return; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - - vsrc = (vector unsigned int){src, src, src, src}; - via = negate (splat_alpha (vsrc)); - ia = ALPHA_8 (~src); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - w = width; - - while (w && ((uintptr_t)dst & 15)) - { - uint32_t d = *dst; - UN8x4_MUL_UN8_ADD_UN8x4 (d, ia, src); - *dst++ = d; - w--; - } - - for (i = w / 4; i > 0; i--) - { - vdst = pix_multiply (load_128_aligned (dst), via); - save_128_aligned (dst, pix_add (vsrc, vdst)); - dst += 4; - } - - for (i = w % 4; --i >= 0;) - { - uint32_t d = dst[i]; - UN8x4_MUL_UN8_ADD_UN8x4 (d, ia, src); - dst[i] = d; - } - } -} - -static void -vmx_composite_over_8888_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - int dst_stride, src_stride; - uint32_t *dst_line, *dst; - uint32_t *src_line, *src; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE ( - src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - - dst = dst_line; - src = src_line; - - while (height--) - { - vmx_combine_over_u (imp, op, dst, src, NULL, width); - - dst += dst_stride; - src += src_stride; - } -} - -static void -vmx_composite_over_n_8888_8888_ca (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t src, ia; - uint32_t *dst_line, d; - uint32_t *mask_line, m; - uint32_t pack_cmp; - int dst_stride, mask_stride; - - vector unsigned int vsrc, valpha, vmask, vdest; - - src = _pixman_image_get_solid (imp, src_image, dest_image->bits.format); - - if (src == 0) - return; - - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - PIXMAN_IMAGE_GET_LINE ( - mask_image, mask_x, mask_y, uint32_t, mask_stride, mask_line, 1); - - vsrc = (vector unsigned int) {src, src, src, src}; - valpha = splat_alpha(vsrc); - ia = ALPHA_8 (src); - - while (height--) - { - int w = width; - const uint32_t *pm = (uint32_t *)mask_line; - uint32_t *pd = (uint32_t *)dst_line; - uint32_t s; - - dst_line += dst_stride; - mask_line += mask_stride; - - while (w && (uintptr_t)pd & 15) - { - s = src; - m = *pm++; - - if (m) - { - d = *pd; - UN8x4_MUL_UN8x4 (s, m); - UN8x4_MUL_UN8 (m, ia); - m = ~m; - UN8x4_MUL_UN8x4_ADD_UN8x4 (d, m, s); - *pd = d; - } - - pd++; - w--; - } - - while (w >= 4) - { - /* pm is NOT necessarily 16-byte aligned */ - vmask = load_128_unaligned (pm); - - pack_cmp = vec_all_eq(vmask, (vector unsigned int) AVV(0)); - - /* if all bits in mask are zero, pack_cmp is not 0 */ - if (pack_cmp == 0) - { - /* pd is 16-byte aligned */ - vdest = in_over (vsrc, valpha, vmask, load_128_aligned (pd)); - - save_128_aligned(pd, vdest); - } - - pd += 4; - pm += 4; - w -= 4; - } - - while (w) - { - s = src; - m = *pm++; - - if (m) - { - d = *pd; - UN8x4_MUL_UN8x4 (s, m); - UN8x4_MUL_UN8 (m, ia); - m = ~m; - UN8x4_MUL_UN8x4_ADD_UN8x4 (d, m, s); - *pd = d; - } - - pd++; - w--; - } - } -} - -static void -vmx_composite_add_8_8 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint8_t *dst_line, *dst; - uint8_t *src_line, *src; - int dst_stride, src_stride; - int32_t w; - uint16_t t; - - PIXMAN_IMAGE_GET_LINE ( - src_image, src_x, src_y, uint8_t, src_stride, src_line, 1); - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint8_t, dst_stride, dst_line, 1); - - while (height--) - { - dst = dst_line; - src = src_line; - - dst_line += dst_stride; - src_line += src_stride; - w = width; - - /* Small head */ - while (w && (uintptr_t)dst & 3) - { - t = (*dst) + (*src++); - *dst++ = t | (0 - (t >> 8)); - w--; - } - - vmx_combine_add_u (imp, op, - (uint32_t*)dst, (uint32_t*)src, NULL, w >> 2); - - /* Small tail */ - dst += w & 0xfffc; - src += w & 0xfffc; - - w &= 3; - - while (w) - { - t = (*dst) + (*src++); - *dst++ = t | (0 - (t >> 8)); - w--; - } - } -} - -static void -vmx_composite_add_8888_8888 (pixman_implementation_t *imp, - pixman_composite_info_t *info) -{ - PIXMAN_COMPOSITE_ARGS (info); - uint32_t *dst_line, *dst; - uint32_t *src_line, *src; - int dst_stride, src_stride; - - PIXMAN_IMAGE_GET_LINE ( - src_image, src_x, src_y, uint32_t, src_stride, src_line, 1); - PIXMAN_IMAGE_GET_LINE ( - dest_image, dest_x, dest_y, uint32_t, dst_stride, dst_line, 1); - - while (height--) - { - dst = dst_line; - dst_line += dst_stride; - src = src_line; - src_line += src_stride; - - vmx_combine_add_u (imp, op, dst, src, NULL, width); - } -} - -static force_inline void -scaled_nearest_scanline_vmx_8888_8888_OVER (uint32_t* pd, - const uint32_t* ps, - int32_t w, - pixman_fixed_t vx, - pixman_fixed_t unit_x, - pixman_fixed_t src_width_fixed, - pixman_bool_t fully_transparent_src) -{ - uint32_t s, d; - const uint32_t* pm = NULL; - - vector unsigned int vsrc, vdst; - - if (fully_transparent_src) - return; - - /* Align dst on a 16-byte boundary */ - while (w && ((uintptr_t)pd & 15)) - { - d = *pd; - s = combine1 (ps + pixman_fixed_to_int (vx), pm); - vx += unit_x; - while (vx >= 0) - vx -= src_width_fixed; - - *pd++ = core_combine_over_u_pixel_vmx (s, d); - if (pm) - pm++; - w--; - } - - while (w >= 4) - { - vector unsigned int tmp; - uint32_t tmp1, tmp2, tmp3, tmp4; - - tmp1 = *(ps + pixman_fixed_to_int (vx)); - vx += unit_x; - while (vx >= 0) - vx -= src_width_fixed; - tmp2 = *(ps + pixman_fixed_to_int (vx)); - vx += unit_x; - while (vx >= 0) - vx -= src_width_fixed; - tmp3 = *(ps + pixman_fixed_to_int (vx)); - vx += unit_x; - while (vx >= 0) - vx -= src_width_fixed; - tmp4 = *(ps + pixman_fixed_to_int (vx)); - vx += unit_x; - while (vx >= 0) - vx -= src_width_fixed; - - tmp[0] = tmp1; - tmp[1] = tmp2; - tmp[2] = tmp3; - tmp[3] = tmp4; - - vsrc = combine4 ((const uint32_t *) &tmp, pm); - - if (is_opaque (vsrc)) - { - save_128_aligned (pd, vsrc); - } - else if (!is_zero (vsrc)) - { - vdst = over(vsrc, splat_alpha(vsrc), load_128_aligned (pd)); - - save_128_aligned (pd, vdst); - } - - w -= 4; - pd += 4; - if (pm) - pm += 4; - } - - while (w) - { - d = *pd; - s = combine1 (ps + pixman_fixed_to_int (vx), pm); - vx += unit_x; - while (vx >= 0) - vx -= src_width_fixed; - - *pd++ = core_combine_over_u_pixel_vmx (s, d); - if (pm) - pm++; - - w--; - } -} - -FAST_NEAREST_MAINLOOP (vmx_8888_8888_cover_OVER, - scaled_nearest_scanline_vmx_8888_8888_OVER, - uint32_t, uint32_t, COVER) -FAST_NEAREST_MAINLOOP (vmx_8888_8888_none_OVER, - scaled_nearest_scanline_vmx_8888_8888_OVER, - uint32_t, uint32_t, NONE) -FAST_NEAREST_MAINLOOP (vmx_8888_8888_pad_OVER, - scaled_nearest_scanline_vmx_8888_8888_OVER, - uint32_t, uint32_t, PAD) -FAST_NEAREST_MAINLOOP (vmx_8888_8888_normal_OVER, - scaled_nearest_scanline_vmx_8888_8888_OVER, - uint32_t, uint32_t, NORMAL) - -static const pixman_fast_path_t vmx_fast_paths[] = -{ - PIXMAN_STD_FAST_PATH (OVER, solid, null, a8r8g8b8, vmx_composite_over_n_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, null, x8r8g8b8, vmx_composite_over_n_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, vmx_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, x8r8g8b8, vmx_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, a8b8g8r8, vmx_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, a8b8g8r8, null, x8b8g8r8, vmx_composite_over_8888_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8r8g8b8, vmx_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8r8g8b8, vmx_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, vmx_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, vmx_composite_over_n_8_8888), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, a8r8g8b8, vmx_composite_over_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8r8g8b8, x8r8g8b8, vmx_composite_over_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, a8b8g8r8, vmx_composite_over_n_8888_8888_ca), - PIXMAN_STD_FAST_PATH_CA (OVER, solid, a8b8g8r8, x8b8g8r8, vmx_composite_over_n_8888_8888_ca), - - /* PIXMAN_OP_ADD */ - PIXMAN_STD_FAST_PATH (ADD, a8, null, a8, vmx_composite_add_8_8), - PIXMAN_STD_FAST_PATH (ADD, a8r8g8b8, null, a8r8g8b8, vmx_composite_add_8888_8888), - PIXMAN_STD_FAST_PATH (ADD, a8b8g8r8, null, a8b8g8r8, vmx_composite_add_8888_8888), - - /* PIXMAN_OP_SRC */ - PIXMAN_STD_FAST_PATH (SRC, x8r8g8b8, null, a8r8g8b8, vmx_composite_src_x888_8888), - PIXMAN_STD_FAST_PATH (SRC, x8b8g8r8, null, a8b8g8r8, vmx_composite_src_x888_8888), - - SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, vmx_8888_8888), - SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, vmx_8888_8888), - SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, vmx_8888_8888), - SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, vmx_8888_8888), - - { PIXMAN_OP_NONE }, -}; - -static uint32_t * -vmx_fetch_x8r8g8b8 (pixman_iter_t *iter, const uint32_t *mask) -{ - int w = iter->width; - vector unsigned int ff000000 = mask_ff000000; - uint32_t *dst = iter->buffer; - uint32_t *src = (uint32_t *)iter->bits; - - iter->bits += iter->stride; - - while (w && ((uintptr_t)dst) & 0x0f) - { - *dst++ = (*src++) | 0xff000000; - w--; - } - - while (w >= 4) - { - save_128_aligned(dst, vec_or(load_128_unaligned(src), ff000000)); - - dst += 4; - src += 4; - w -= 4; - } - - while (w) - { - *dst++ = (*src++) | 0xff000000; - w--; - } - - return iter->buffer; -} - -static uint32_t * -vmx_fetch_a8 (pixman_iter_t *iter, const uint32_t *mask) -{ - int w = iter->width; - uint32_t *dst = iter->buffer; - uint8_t *src = iter->bits; - vector unsigned int vmx0, vmx1, vmx2, vmx3, vmx4, vmx5, vmx6; - - iter->bits += iter->stride; - - while (w && (((uintptr_t)dst) & 15)) - { - *dst++ = *(src++) << 24; - w--; - } - - while (w >= 16) - { - vmx0 = load_128_unaligned((uint32_t *) src); - - unpack_128_2x128((vector unsigned int) AVV(0), vmx0, &vmx1, &vmx2); - unpack_128_2x128_16((vector unsigned int) AVV(0), vmx1, &vmx3, &vmx4); - unpack_128_2x128_16((vector unsigned int) AVV(0), vmx2, &vmx5, &vmx6); - - save_128_aligned(dst, vmx6); - save_128_aligned((dst + 4), vmx5); - save_128_aligned((dst + 8), vmx4); - save_128_aligned((dst + 12), vmx3); - - dst += 16; - src += 16; - w -= 16; - } - - while (w) - { - *dst++ = *(src++) << 24; - w--; - } - - return iter->buffer; -} - -#define IMAGE_FLAGS \ - (FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM | \ - FAST_PATH_BITS_IMAGE | FAST_PATH_SAMPLES_COVER_CLIP_NEAREST) - -static const pixman_iter_info_t vmx_iters[] = -{ - { PIXMAN_x8r8g8b8, IMAGE_FLAGS, ITER_NARROW, - _pixman_iter_init_bits_stride, vmx_fetch_x8r8g8b8, NULL - }, - { PIXMAN_a8, IMAGE_FLAGS, ITER_NARROW, - _pixman_iter_init_bits_stride, vmx_fetch_a8, NULL - }, - { PIXMAN_null }, -}; - -pixman_implementation_t * -_pixman_implementation_create_vmx (pixman_implementation_t *fallback) -{ - pixman_implementation_t *imp = _pixman_implementation_create (fallback, vmx_fast_paths); - - /* VMX constants */ - mask_ff000000 = create_mask_32_128 (0xff000000); - mask_red = create_mask_32_128 (0x00f80000); - mask_green = create_mask_32_128 (0x0000fc00); - mask_blue = create_mask_32_128 (0x000000f8); - mask_565_fix_rb = create_mask_32_128 (0x00e000e0); - mask_565_fix_g = create_mask_32_128 (0x0000c000); - - /* Set up function pointers */ - - imp->combine_32[PIXMAN_OP_OVER] = vmx_combine_over_u; - imp->combine_32[PIXMAN_OP_OVER_REVERSE] = vmx_combine_over_reverse_u; - imp->combine_32[PIXMAN_OP_IN] = vmx_combine_in_u; - imp->combine_32[PIXMAN_OP_IN_REVERSE] = vmx_combine_in_reverse_u; - imp->combine_32[PIXMAN_OP_OUT] = vmx_combine_out_u; - imp->combine_32[PIXMAN_OP_OUT_REVERSE] = vmx_combine_out_reverse_u; - imp->combine_32[PIXMAN_OP_ATOP] = vmx_combine_atop_u; - imp->combine_32[PIXMAN_OP_ATOP_REVERSE] = vmx_combine_atop_reverse_u; - imp->combine_32[PIXMAN_OP_XOR] = vmx_combine_xor_u; - - imp->combine_32[PIXMAN_OP_ADD] = vmx_combine_add_u; - - imp->combine_32_ca[PIXMAN_OP_SRC] = vmx_combine_src_ca; - imp->combine_32_ca[PIXMAN_OP_OVER] = vmx_combine_over_ca; - imp->combine_32_ca[PIXMAN_OP_OVER_REVERSE] = vmx_combine_over_reverse_ca; - imp->combine_32_ca[PIXMAN_OP_IN] = vmx_combine_in_ca; - imp->combine_32_ca[PIXMAN_OP_IN_REVERSE] = vmx_combine_in_reverse_ca; - imp->combine_32_ca[PIXMAN_OP_OUT] = vmx_combine_out_ca; - imp->combine_32_ca[PIXMAN_OP_OUT_REVERSE] = vmx_combine_out_reverse_ca; - imp->combine_32_ca[PIXMAN_OP_ATOP] = vmx_combine_atop_ca; - imp->combine_32_ca[PIXMAN_OP_ATOP_REVERSE] = vmx_combine_atop_reverse_ca; - imp->combine_32_ca[PIXMAN_OP_XOR] = vmx_combine_xor_ca; - imp->combine_32_ca[PIXMAN_OP_ADD] = vmx_combine_add_ca; - - imp->fill = vmx_fill; - - imp->iter_info = vmx_iters; - - return imp; -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman-x86.c b/source/libs/pixman/pixman-src/pixman/pixman-x86.c deleted file mode 100644 index 05297c47603420b88b9707e7df8ded6cad43e54a..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman-x86.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright © 2000 SuSE, Inc. - * Copyright © 2007 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 SuSE not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. SuSE makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE - * 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. - */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "pixman-private.h" - -#if defined(USE_X86_MMX) || defined (USE_SSE2) || defined (USE_SSSE3) - -/* The CPU detection code needs to be in a file not compiled with - * "-mmmx -msse", as gcc would generate CMOV instructions otherwise - * that would lead to SIGILL instructions on old CPUs that don't have - * it. - */ - -typedef enum -{ - X86_MMX = (1 << 0), - X86_MMX_EXTENSIONS = (1 << 1), - X86_SSE = (1 << 2) | X86_MMX_EXTENSIONS, - X86_SSE2 = (1 << 3), - X86_CMOV = (1 << 4), - X86_SSSE3 = (1 << 5) -} cpu_features_t; - -#ifdef HAVE_GETISAX - -#include <sys/auxv.h> - -static cpu_features_t -detect_cpu_features (void) -{ - cpu_features_t features = 0; - unsigned int result = 0; - - if (getisax (&result, 1)) - { - if (result & AV_386_CMOV) - features |= X86_CMOV; - if (result & AV_386_MMX) - features |= X86_MMX; - if (result & AV_386_AMD_MMX) - features |= X86_MMX_EXTENSIONS; - if (result & AV_386_SSE) - features |= X86_SSE; - if (result & AV_386_SSE2) - features |= X86_SSE2; - if (result & AV_386_SSSE3) - features |= X86_SSSE3; - } - - return features; -} - -#else - -#define _PIXMAN_X86_64 \ - (defined(__amd64__) || defined(__x86_64__) || defined(_M_AMD64)) - -static pixman_bool_t -have_cpuid (void) -{ -#if _PIXMAN_X86_64 || defined (_MSC_VER) - - return TRUE; - -#elif defined (__GNUC__) - uint32_t result; - - __asm__ volatile ( - "pushf" "\n\t" - "pop %%eax" "\n\t" - "mov %%eax, %%ecx" "\n\t" - "xor $0x00200000, %%eax" "\n\t" - "push %%eax" "\n\t" - "popf" "\n\t" - "pushf" "\n\t" - "pop %%eax" "\n\t" - "xor %%ecx, %%eax" "\n\t" - "mov %%eax, %0" "\n\t" - : "=r" (result) - : - : "%eax", "%ecx"); - - return !!result; - -#else -#error "Unknown compiler" -#endif -} - -static void -pixman_cpuid (uint32_t feature, - uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d) -{ -#if defined (__GNUC__) - -#if _PIXMAN_X86_64 - __asm__ volatile ( - "cpuid" "\n\t" - : "=a" (*a), "=b" (*b), "=c" (*c), "=d" (*d) - : "a" (feature)); -#else - /* On x86-32 we need to be careful about the handling of %ebx - * and %esp. We can't declare either one as clobbered - * since they are special registers (%ebx is the "PIC - * register" holding an offset to global data, %esp the - * stack pointer), so we need to make sure that %ebx is - * preserved, and that %esp has its original value when - * accessing the output operands. - */ - __asm__ volatile ( - "xchg %%ebx, %1" "\n\t" - "cpuid" "\n\t" - "xchg %%ebx, %1" "\n\t" - : "=a" (*a), "=r" (*b), "=c" (*c), "=d" (*d) - : "a" (feature)); -#endif - -#elif defined (_MSC_VER) - int info[4]; - - __cpuid (info, feature); - - *a = info[0]; - *b = info[1]; - *c = info[2]; - *d = info[3]; -#else -#error Unknown compiler -#endif -} - -static cpu_features_t -detect_cpu_features (void) -{ - uint32_t a, b, c, d; - cpu_features_t features = 0; - - if (!have_cpuid()) - return features; - - /* Get feature bits */ - pixman_cpuid (0x01, &a, &b, &c, &d); - if (d & (1 << 15)) - features |= X86_CMOV; - if (d & (1 << 23)) - features |= X86_MMX; - if (d & (1 << 25)) - features |= X86_SSE; - if (d & (1 << 26)) - features |= X86_SSE2; - if (c & (1 << 9)) - features |= X86_SSSE3; - - /* Check for AMD specific features */ - if ((features & X86_MMX) && !(features & X86_SSE)) - { - char vendor[13]; - - /* Get vendor string */ - memset (vendor, 0, sizeof vendor); - - pixman_cpuid (0x00, &a, &b, &c, &d); - memcpy (vendor + 0, &b, 4); - memcpy (vendor + 4, &d, 4); - memcpy (vendor + 8, &c, 4); - - if (strcmp (vendor, "AuthenticAMD") == 0 || - strcmp (vendor, "Geode by NSC") == 0) - { - pixman_cpuid (0x80000000, &a, &b, &c, &d); - if (a >= 0x80000001) - { - pixman_cpuid (0x80000001, &a, &b, &c, &d); - - if (d & (1 << 22)) - features |= X86_MMX_EXTENSIONS; - } - } - } - - return features; -} - -#endif - -static pixman_bool_t -have_feature (cpu_features_t feature) -{ - static pixman_bool_t initialized; - static cpu_features_t features; - - if (!initialized) - { - features = detect_cpu_features(); - initialized = TRUE; - } - - return (features & feature) == feature; -} - -#endif - -pixman_implementation_t * -_pixman_x86_get_implementations (pixman_implementation_t *imp) -{ -#define MMX_BITS (X86_MMX | X86_MMX_EXTENSIONS) -#define SSE2_BITS (X86_MMX | X86_MMX_EXTENSIONS | X86_SSE | X86_SSE2) -#define SSSE3_BITS (X86_SSE | X86_SSE2 | X86_SSSE3) - -#ifdef USE_X86_MMX - if (!_pixman_disabled ("mmx") && have_feature (MMX_BITS)) - imp = _pixman_implementation_create_mmx (imp); -#endif - -#ifdef USE_SSE2 - if (!_pixman_disabled ("sse2") && have_feature (SSE2_BITS)) - imp = _pixman_implementation_create_sse2 (imp); -#endif - -#ifdef USE_SSSE3 - if (!_pixman_disabled ("ssse3") && have_feature (SSSE3_BITS)) - imp = _pixman_implementation_create_ssse3 (imp); -#endif - - return imp; -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman.c b/source/libs/pixman/pixman-src/pixman/pixman.c deleted file mode 100644 index f932eac3c1b6fbf82033c5aa4a5c8c80484d5837..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman.c +++ /dev/null @@ -1,1128 +0,0 @@ -/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */ -/* - * Copyright © 2000 SuSE, Inc. - * Copyright © 2007 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 SuSE not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. SuSE makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE - * 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: Keith Packard, SuSE, Inc. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "pixman-private.h" - -#include <stdlib.h> - -pixman_implementation_t *global_implementation; - -#ifdef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR -static void __attribute__((constructor)) -pixman_constructor (void) -{ - global_implementation = _pixman_choose_implementation (); -} -#endif - -typedef struct operator_info_t operator_info_t; - -struct operator_info_t -{ - uint8_t opaque_info[4]; -}; - -#define PACK(neither, src, dest, both) \ - {{ (uint8_t)PIXMAN_OP_ ## neither, \ - (uint8_t)PIXMAN_OP_ ## src, \ - (uint8_t)PIXMAN_OP_ ## dest, \ - (uint8_t)PIXMAN_OP_ ## both }} - -static const operator_info_t operator_table[] = -{ - /* Neither Opaque Src Opaque Dst Opaque Both Opaque */ - PACK (CLEAR, CLEAR, CLEAR, CLEAR), - PACK (SRC, SRC, SRC, SRC), - PACK (DST, DST, DST, DST), - PACK (OVER, SRC, OVER, SRC), - PACK (OVER_REVERSE, OVER_REVERSE, DST, DST), - PACK (IN, IN, SRC, SRC), - PACK (IN_REVERSE, DST, IN_REVERSE, DST), - PACK (OUT, OUT, CLEAR, CLEAR), - PACK (OUT_REVERSE, CLEAR, OUT_REVERSE, CLEAR), - PACK (ATOP, IN, OVER, SRC), - PACK (ATOP_REVERSE, OVER_REVERSE, IN_REVERSE, DST), - PACK (XOR, OUT, OUT_REVERSE, CLEAR), - PACK (ADD, ADD, ADD, ADD), - PACK (SATURATE, OVER_REVERSE, DST, DST), - - {{ 0 /* 0x0e */ }}, - {{ 0 /* 0x0f */ }}, - - PACK (CLEAR, CLEAR, CLEAR, CLEAR), - PACK (SRC, SRC, SRC, SRC), - PACK (DST, DST, DST, DST), - PACK (DISJOINT_OVER, DISJOINT_OVER, DISJOINT_OVER, DISJOINT_OVER), - PACK (DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE, DISJOINT_OVER_REVERSE), - PACK (DISJOINT_IN, DISJOINT_IN, DISJOINT_IN, DISJOINT_IN), - PACK (DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE, DISJOINT_IN_REVERSE), - PACK (DISJOINT_OUT, DISJOINT_OUT, DISJOINT_OUT, DISJOINT_OUT), - PACK (DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE, DISJOINT_OUT_REVERSE), - PACK (DISJOINT_ATOP, DISJOINT_ATOP, DISJOINT_ATOP, DISJOINT_ATOP), - PACK (DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE, DISJOINT_ATOP_REVERSE), - PACK (DISJOINT_XOR, DISJOINT_XOR, DISJOINT_XOR, DISJOINT_XOR), - - {{ 0 /* 0x1c */ }}, - {{ 0 /* 0x1d */ }}, - {{ 0 /* 0x1e */ }}, - {{ 0 /* 0x1f */ }}, - - PACK (CLEAR, CLEAR, CLEAR, CLEAR), - PACK (SRC, SRC, SRC, SRC), - PACK (DST, DST, DST, DST), - PACK (CONJOINT_OVER, CONJOINT_OVER, CONJOINT_OVER, CONJOINT_OVER), - PACK (CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE, CONJOINT_OVER_REVERSE), - PACK (CONJOINT_IN, CONJOINT_IN, CONJOINT_IN, CONJOINT_IN), - PACK (CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE, CONJOINT_IN_REVERSE), - PACK (CONJOINT_OUT, CONJOINT_OUT, CONJOINT_OUT, CONJOINT_OUT), - PACK (CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE, CONJOINT_OUT_REVERSE), - PACK (CONJOINT_ATOP, CONJOINT_ATOP, CONJOINT_ATOP, CONJOINT_ATOP), - PACK (CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE, CONJOINT_ATOP_REVERSE), - PACK (CONJOINT_XOR, CONJOINT_XOR, CONJOINT_XOR, CONJOINT_XOR), - - {{ 0 /* 0x2c */ }}, - {{ 0 /* 0x2d */ }}, - {{ 0 /* 0x2e */ }}, - {{ 0 /* 0x2f */ }}, - - PACK (MULTIPLY, MULTIPLY, MULTIPLY, MULTIPLY), - PACK (SCREEN, SCREEN, SCREEN, SCREEN), - PACK (OVERLAY, OVERLAY, OVERLAY, OVERLAY), - PACK (DARKEN, DARKEN, DARKEN, DARKEN), - PACK (LIGHTEN, LIGHTEN, LIGHTEN, LIGHTEN), - PACK (COLOR_DODGE, COLOR_DODGE, COLOR_DODGE, COLOR_DODGE), - PACK (COLOR_BURN, COLOR_BURN, COLOR_BURN, COLOR_BURN), - PACK (HARD_LIGHT, HARD_LIGHT, HARD_LIGHT, HARD_LIGHT), - PACK (SOFT_LIGHT, SOFT_LIGHT, SOFT_LIGHT, SOFT_LIGHT), - PACK (DIFFERENCE, DIFFERENCE, DIFFERENCE, DIFFERENCE), - PACK (EXCLUSION, EXCLUSION, EXCLUSION, EXCLUSION), - PACK (HSL_HUE, HSL_HUE, HSL_HUE, HSL_HUE), - PACK (HSL_SATURATION, HSL_SATURATION, HSL_SATURATION, HSL_SATURATION), - PACK (HSL_COLOR, HSL_COLOR, HSL_COLOR, HSL_COLOR), - PACK (HSL_LUMINOSITY, HSL_LUMINOSITY, HSL_LUMINOSITY, HSL_LUMINOSITY), -}; - -/* - * Optimize the current operator based on opacity of source or destination - * The output operator should be mathematically equivalent to the source. - */ -static pixman_op_t -optimize_operator (pixman_op_t op, - uint32_t src_flags, - uint32_t mask_flags, - uint32_t dst_flags) -{ - pixman_bool_t is_source_opaque, is_dest_opaque; - -#define OPAQUE_SHIFT 13 - - COMPILE_TIME_ASSERT (FAST_PATH_IS_OPAQUE == (1 << OPAQUE_SHIFT)); - - is_dest_opaque = (dst_flags & FAST_PATH_IS_OPAQUE); - is_source_opaque = ((src_flags & mask_flags) & FAST_PATH_IS_OPAQUE); - - is_dest_opaque >>= OPAQUE_SHIFT - 1; - is_source_opaque >>= OPAQUE_SHIFT; - - return operator_table[op].opaque_info[is_dest_opaque | is_source_opaque]; -} - -/* - * Computing composite region - */ -static inline pixman_bool_t -clip_general_image (pixman_region32_t * region, - pixman_region32_t * clip, - int dx, - int dy) -{ - if (pixman_region32_n_rects (region) == 1 && - pixman_region32_n_rects (clip) == 1) - { - pixman_box32_t * rbox = pixman_region32_rectangles (region, NULL); - pixman_box32_t * cbox = pixman_region32_rectangles (clip, NULL); - int v; - - if (rbox->x1 < (v = cbox->x1 + dx)) - rbox->x1 = v; - if (rbox->x2 > (v = cbox->x2 + dx)) - rbox->x2 = v; - if (rbox->y1 < (v = cbox->y1 + dy)) - rbox->y1 = v; - if (rbox->y2 > (v = cbox->y2 + dy)) - rbox->y2 = v; - if (rbox->x1 >= rbox->x2 || rbox->y1 >= rbox->y2) - { - pixman_region32_init (region); - return FALSE; - } - } - else if (!pixman_region32_not_empty (clip)) - { - return FALSE; - } - else - { - if (dx || dy) - pixman_region32_translate (region, -dx, -dy); - - if (!pixman_region32_intersect (region, region, clip)) - return FALSE; - - if (dx || dy) - pixman_region32_translate (region, dx, dy); - } - - return pixman_region32_not_empty (region); -} - -static inline pixman_bool_t -clip_source_image (pixman_region32_t * region, - pixman_image_t * image, - int dx, - int dy) -{ - /* Source clips are ignored, unless they are explicitly turned on - * and the clip in question was set by an X client. (Because if - * the clip was not set by a client, then it is a hierarchy - * clip and those should always be ignored for sources). - */ - if (!image->common.clip_sources || !image->common.client_clip) - return TRUE; - - return clip_general_image (region, - &image->common.clip_region, - dx, dy); -} - -/* - * returns FALSE if the final region is empty. Indistinguishable from - * an allocation failure, but rendering ignores those anyways. - */ -pixman_bool_t -_pixman_compute_composite_region32 (pixman_region32_t * region, - pixman_image_t * src_image, - pixman_image_t * mask_image, - pixman_image_t * dest_image, - int32_t src_x, - int32_t src_y, - int32_t mask_x, - int32_t mask_y, - int32_t dest_x, - int32_t dest_y, - int32_t width, - int32_t height) -{ - region->extents.x1 = dest_x; - region->extents.x2 = dest_x + width; - region->extents.y1 = dest_y; - region->extents.y2 = dest_y + height; - - region->extents.x1 = MAX (region->extents.x1, 0); - region->extents.y1 = MAX (region->extents.y1, 0); - region->extents.x2 = MIN (region->extents.x2, dest_image->bits.width); - region->extents.y2 = MIN (region->extents.y2, dest_image->bits.height); - - region->data = 0; - - /* Check for empty operation */ - if (region->extents.x1 >= region->extents.x2 || - region->extents.y1 >= region->extents.y2) - { - region->extents.x1 = 0; - region->extents.x2 = 0; - region->extents.y1 = 0; - region->extents.y2 = 0; - return FALSE; - } - - if (dest_image->common.have_clip_region) - { - if (!clip_general_image (region, &dest_image->common.clip_region, 0, 0)) - return FALSE; - } - - if (dest_image->common.alpha_map) - { - if (!pixman_region32_intersect_rect (region, region, - dest_image->common.alpha_origin_x, - dest_image->common.alpha_origin_y, - dest_image->common.alpha_map->width, - dest_image->common.alpha_map->height)) - { - return FALSE; - } - if (!pixman_region32_not_empty (region)) - return FALSE; - if (dest_image->common.alpha_map->common.have_clip_region) - { - if (!clip_general_image (region, &dest_image->common.alpha_map->common.clip_region, - -dest_image->common.alpha_origin_x, - -dest_image->common.alpha_origin_y)) - { - return FALSE; - } - } - } - - /* clip against src */ - if (src_image->common.have_clip_region) - { - if (!clip_source_image (region, src_image, dest_x - src_x, dest_y - src_y)) - return FALSE; - } - if (src_image->common.alpha_map && src_image->common.alpha_map->common.have_clip_region) - { - if (!clip_source_image (region, (pixman_image_t *)src_image->common.alpha_map, - dest_x - (src_x - src_image->common.alpha_origin_x), - dest_y - (src_y - src_image->common.alpha_origin_y))) - { - return FALSE; - } - } - /* clip against mask */ - if (mask_image && mask_image->common.have_clip_region) - { - if (!clip_source_image (region, mask_image, dest_x - mask_x, dest_y - mask_y)) - return FALSE; - - if (mask_image->common.alpha_map && mask_image->common.alpha_map->common.have_clip_region) - { - if (!clip_source_image (region, (pixman_image_t *)mask_image->common.alpha_map, - dest_x - (mask_x - mask_image->common.alpha_origin_x), - dest_y - (mask_y - mask_image->common.alpha_origin_y))) - { - return FALSE; - } - } - } - - return TRUE; -} - -typedef struct box_48_16 box_48_16_t; - -struct box_48_16 -{ - pixman_fixed_48_16_t x1; - pixman_fixed_48_16_t y1; - pixman_fixed_48_16_t x2; - pixman_fixed_48_16_t y2; -}; - -static pixman_bool_t -compute_transformed_extents (pixman_transform_t *transform, - const pixman_box32_t *extents, - box_48_16_t *transformed) -{ - pixman_fixed_48_16_t tx1, ty1, tx2, ty2; - pixman_fixed_t x1, y1, x2, y2; - int i; - - x1 = pixman_int_to_fixed (extents->x1) + pixman_fixed_1 / 2; - y1 = pixman_int_to_fixed (extents->y1) + pixman_fixed_1 / 2; - x2 = pixman_int_to_fixed (extents->x2) - pixman_fixed_1 / 2; - y2 = pixman_int_to_fixed (extents->y2) - pixman_fixed_1 / 2; - - if (!transform) - { - transformed->x1 = x1; - transformed->y1 = y1; - transformed->x2 = x2; - transformed->y2 = y2; - - return TRUE; - } - - tx1 = ty1 = INT64_MAX; - tx2 = ty2 = INT64_MIN; - - for (i = 0; i < 4; ++i) - { - pixman_fixed_48_16_t tx, ty; - pixman_vector_t v; - - v.vector[0] = (i & 0x01)? x1 : x2; - v.vector[1] = (i & 0x02)? y1 : y2; - v.vector[2] = pixman_fixed_1; - - if (!pixman_transform_point (transform, &v)) - return FALSE; - - tx = (pixman_fixed_48_16_t)v.vector[0]; - ty = (pixman_fixed_48_16_t)v.vector[1]; - - if (tx < tx1) - tx1 = tx; - if (ty < ty1) - ty1 = ty; - if (tx > tx2) - tx2 = tx; - if (ty > ty2) - ty2 = ty; - } - - transformed->x1 = tx1; - transformed->y1 = ty1; - transformed->x2 = tx2; - transformed->y2 = ty2; - - return TRUE; -} - -#define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX)) -#define ABS(f) (((f) < 0)? (-(f)) : (f)) -#define IS_16_16(f) (((f) >= pixman_min_fixed_48_16 && ((f) <= pixman_max_fixed_48_16))) - -static pixman_bool_t -analyze_extent (pixman_image_t *image, - const pixman_box32_t *extents, - uint32_t *flags) -{ - pixman_transform_t *transform; - pixman_fixed_t x_off, y_off; - pixman_fixed_t width, height; - pixman_fixed_t *params; - box_48_16_t transformed; - pixman_box32_t exp_extents; - - if (!image) - return TRUE; - - /* Some compositing functions walk one step - * outside the destination rectangle, so we - * check here that the expanded-by-one source - * extents in destination space fits in 16 bits - */ - if (!IS_16BIT (extents->x1 - 1) || - !IS_16BIT (extents->y1 - 1) || - !IS_16BIT (extents->x2 + 1) || - !IS_16BIT (extents->y2 + 1)) - { - return FALSE; - } - - transform = image->common.transform; - if (image->common.type == BITS) - { - /* During repeat mode calculations we might convert the - * width/height of an image to fixed 16.16, so we need - * them to be smaller than 16 bits. - */ - if (image->bits.width >= 0x7fff || image->bits.height >= 0x7fff) - return FALSE; - - if ((image->common.flags & FAST_PATH_ID_TRANSFORM) == FAST_PATH_ID_TRANSFORM && - extents->x1 >= 0 && - extents->y1 >= 0 && - extents->x2 <= image->bits.width && - extents->y2 <= image->bits.height) - { - *flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST; - return TRUE; - } - - switch (image->common.filter) - { - case PIXMAN_FILTER_CONVOLUTION: - params = image->common.filter_params; - x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1); - y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1); - width = params[0]; - height = params[1]; - break; - - case PIXMAN_FILTER_SEPARABLE_CONVOLUTION: - params = image->common.filter_params; - x_off = - pixman_fixed_e - ((params[0] - pixman_fixed_1) >> 1); - y_off = - pixman_fixed_e - ((params[1] - pixman_fixed_1) >> 1); - width = params[0]; - height = params[1]; - break; - - case PIXMAN_FILTER_GOOD: - case PIXMAN_FILTER_BEST: - case PIXMAN_FILTER_BILINEAR: - x_off = - pixman_fixed_1 / 2; - y_off = - pixman_fixed_1 / 2; - width = pixman_fixed_1; - height = pixman_fixed_1; - break; - - case PIXMAN_FILTER_FAST: - case PIXMAN_FILTER_NEAREST: - x_off = - pixman_fixed_e; - y_off = - pixman_fixed_e; - width = 0; - height = 0; - break; - - default: - return FALSE; - } - } - else - { - x_off = 0; - y_off = 0; - width = 0; - height = 0; - } - - if (!compute_transformed_extents (transform, extents, &transformed)) - return FALSE; - - if (image->common.type == BITS) - { - if (pixman_fixed_to_int (transformed.x1 - pixman_fixed_e) >= 0 && - pixman_fixed_to_int (transformed.y1 - pixman_fixed_e) >= 0 && - pixman_fixed_to_int (transformed.x2 - pixman_fixed_e) < image->bits.width && - pixman_fixed_to_int (transformed.y2 - pixman_fixed_e) < image->bits.height) - { - *flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST; - } - - if (pixman_fixed_to_int (transformed.x1 - pixman_fixed_1 / 2) >= 0 && - pixman_fixed_to_int (transformed.y1 - pixman_fixed_1 / 2) >= 0 && - pixman_fixed_to_int (transformed.x2 + pixman_fixed_1 / 2) < image->bits.width && - pixman_fixed_to_int (transformed.y2 + pixman_fixed_1 / 2) < image->bits.height) - { - *flags |= FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR; - } - } - - /* Check we don't overflow when the destination extents are expanded by one. - * This ensures that compositing functions can simply walk the source space - * using 16.16 variables without worrying about overflow. - */ - exp_extents = *extents; - exp_extents.x1 -= 1; - exp_extents.y1 -= 1; - exp_extents.x2 += 1; - exp_extents.y2 += 1; - - if (!compute_transformed_extents (transform, &exp_extents, &transformed)) - return FALSE; - - if (!IS_16_16 (transformed.x1 + x_off - 8 * pixman_fixed_e) || - !IS_16_16 (transformed.y1 + y_off - 8 * pixman_fixed_e) || - !IS_16_16 (transformed.x2 + x_off + 8 * pixman_fixed_e + width) || - !IS_16_16 (transformed.y2 + y_off + 8 * pixman_fixed_e + height)) - { - return FALSE; - } - - return TRUE; -} - -/* - * Work around GCC bug causing crashes in Mozilla with SSE2 - * - * When using -msse, gcc generates movdqa instructions assuming that - * the stack is 16 byte aligned. Unfortunately some applications, such - * as Mozilla and Mono, end up aligning the stack to 4 bytes, which - * causes the movdqa instructions to fail. - * - * The __force_align_arg_pointer__ makes gcc generate a prologue that - * realigns the stack pointer to 16 bytes. - * - * On x86-64 this is not necessary because the standard ABI already - * calls for a 16 byte aligned stack. - * - * See https://bugs.freedesktop.org/show_bug.cgi?id=15693 - */ -#if defined (USE_SSE2) && defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__) -__attribute__((__force_align_arg_pointer__)) -#endif -PIXMAN_EXPORT void -pixman_image_composite32 (pixman_op_t op, - pixman_image_t * src, - pixman_image_t * mask, - pixman_image_t * dest, - int32_t src_x, - int32_t src_y, - int32_t mask_x, - int32_t mask_y, - int32_t dest_x, - int32_t dest_y, - int32_t width, - int32_t height) -{ - pixman_format_code_t src_format, mask_format, dest_format; - pixman_region32_t region; - pixman_box32_t extents; - pixman_implementation_t *imp; - pixman_composite_func_t func; - pixman_composite_info_t info; - const pixman_box32_t *pbox; - int n; - - _pixman_image_validate (src); - if (mask) - _pixman_image_validate (mask); - _pixman_image_validate (dest); - - src_format = src->common.extended_format_code; - info.src_flags = src->common.flags; - - if (mask && !(mask->common.flags & FAST_PATH_IS_OPAQUE)) - { - mask_format = mask->common.extended_format_code; - info.mask_flags = mask->common.flags; - } - else - { - mask_format = PIXMAN_null; - info.mask_flags = FAST_PATH_IS_OPAQUE | FAST_PATH_NO_ALPHA_MAP; - } - - dest_format = dest->common.extended_format_code; - info.dest_flags = dest->common.flags; - - /* Check for pixbufs */ - if ((mask_format == PIXMAN_a8r8g8b8 || mask_format == PIXMAN_a8b8g8r8) && - (src->type == BITS && src->bits.bits == mask->bits.bits) && - (src->common.repeat == mask->common.repeat) && - (info.src_flags & info.mask_flags & FAST_PATH_ID_TRANSFORM) && - (src_x == mask_x && src_y == mask_y)) - { - if (src_format == PIXMAN_x8b8g8r8) - src_format = mask_format = PIXMAN_pixbuf; - else if (src_format == PIXMAN_x8r8g8b8) - src_format = mask_format = PIXMAN_rpixbuf; - } - - pixman_region32_init (®ion); - - if (!_pixman_compute_composite_region32 ( - ®ion, src, mask, dest, - src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height)) - { - goto out; - } - - extents = *pixman_region32_extents (®ion); - - extents.x1 -= dest_x - src_x; - extents.y1 -= dest_y - src_y; - extents.x2 -= dest_x - src_x; - extents.y2 -= dest_y - src_y; - - if (!analyze_extent (src, &extents, &info.src_flags)) - goto out; - - extents.x1 -= src_x - mask_x; - extents.y1 -= src_y - mask_y; - extents.x2 -= src_x - mask_x; - extents.y2 -= src_y - mask_y; - - if (!analyze_extent (mask, &extents, &info.mask_flags)) - goto out; - - /* If the clip is within the source samples, and the samples are - * opaque, then the source is effectively opaque. - */ -#define NEAREST_OPAQUE (FAST_PATH_SAMPLES_OPAQUE | \ - FAST_PATH_NEAREST_FILTER | \ - FAST_PATH_SAMPLES_COVER_CLIP_NEAREST) -#define BILINEAR_OPAQUE (FAST_PATH_SAMPLES_OPAQUE | \ - FAST_PATH_BILINEAR_FILTER | \ - FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR) - - if ((info.src_flags & NEAREST_OPAQUE) == NEAREST_OPAQUE || - (info.src_flags & BILINEAR_OPAQUE) == BILINEAR_OPAQUE) - { - info.src_flags |= FAST_PATH_IS_OPAQUE; - } - - if ((info.mask_flags & NEAREST_OPAQUE) == NEAREST_OPAQUE || - (info.mask_flags & BILINEAR_OPAQUE) == BILINEAR_OPAQUE) - { - info.mask_flags |= FAST_PATH_IS_OPAQUE; - } - - /* - * Check if we can replace our operator by a simpler one - * if the src or dest are opaque. The output operator should be - * mathematically equivalent to the source. - */ - info.op = optimize_operator (op, info.src_flags, info.mask_flags, info.dest_flags); - - _pixman_implementation_lookup_composite ( - get_implementation (), info.op, - src_format, info.src_flags, - mask_format, info.mask_flags, - dest_format, info.dest_flags, - &imp, &func); - - info.src_image = src; - info.mask_image = mask; - info.dest_image = dest; - - pbox = pixman_region32_rectangles (®ion, &n); - - while (n--) - { - info.src_x = pbox->x1 + src_x - dest_x; - info.src_y = pbox->y1 + src_y - dest_y; - info.mask_x = pbox->x1 + mask_x - dest_x; - info.mask_y = pbox->y1 + mask_y - dest_y; - info.dest_x = pbox->x1; - info.dest_y = pbox->y1; - info.width = pbox->x2 - pbox->x1; - info.height = pbox->y2 - pbox->y1; - - func (imp, &info); - - pbox++; - } - -out: - pixman_region32_fini (®ion); -} - -PIXMAN_EXPORT void -pixman_image_composite (pixman_op_t op, - pixman_image_t * src, - pixman_image_t * mask, - pixman_image_t * dest, - int16_t src_x, - int16_t src_y, - int16_t mask_x, - int16_t mask_y, - int16_t dest_x, - int16_t dest_y, - uint16_t width, - uint16_t height) -{ - pixman_image_composite32 (op, src, mask, dest, src_x, src_y, - mask_x, mask_y, dest_x, dest_y, width, height); -} - -PIXMAN_EXPORT pixman_bool_t -pixman_blt (uint32_t *src_bits, - uint32_t *dst_bits, - int src_stride, - int dst_stride, - int src_bpp, - int dst_bpp, - int src_x, - int src_y, - int dest_x, - int dest_y, - int width, - int height) -{ - return _pixman_implementation_blt (get_implementation(), - src_bits, dst_bits, src_stride, dst_stride, - src_bpp, dst_bpp, - src_x, src_y, - dest_x, dest_y, - width, height); -} - -PIXMAN_EXPORT pixman_bool_t -pixman_fill (uint32_t *bits, - int stride, - int bpp, - int x, - int y, - int width, - int height, - uint32_t filler) -{ - return _pixman_implementation_fill ( - get_implementation(), bits, stride, bpp, x, y, width, height, filler); -} - -static uint32_t -color_to_uint32 (const pixman_color_t *color) -{ - return - (color->alpha >> 8 << 24) | - (color->red >> 8 << 16) | - (color->green & 0xff00) | - (color->blue >> 8); -} - -static pixman_bool_t -color_to_pixel (const pixman_color_t *color, - uint32_t * pixel, - pixman_format_code_t format) -{ - uint32_t c = color_to_uint32 (color); - - if (!(format == PIXMAN_a8r8g8b8 || - format == PIXMAN_x8r8g8b8 || - format == PIXMAN_a8b8g8r8 || - format == PIXMAN_x8b8g8r8 || - format == PIXMAN_b8g8r8a8 || - format == PIXMAN_b8g8r8x8 || - format == PIXMAN_r8g8b8a8 || - format == PIXMAN_r8g8b8x8 || - format == PIXMAN_r5g6b5 || - format == PIXMAN_b5g6r5 || - format == PIXMAN_a8 || - format == PIXMAN_a1)) - { - return FALSE; - } - - if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR) - { - c = ((c & 0xff000000) >> 0) | - ((c & 0x00ff0000) >> 16) | - ((c & 0x0000ff00) >> 0) | - ((c & 0x000000ff) << 16); - } - if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_BGRA) - { - c = ((c & 0xff000000) >> 24) | - ((c & 0x00ff0000) >> 8) | - ((c & 0x0000ff00) << 8) | - ((c & 0x000000ff) << 24); - } - if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_RGBA) - c = ((c & 0xff000000) >> 24) | (c << 8); - - if (format == PIXMAN_a1) - c = c >> 31; - else if (format == PIXMAN_a8) - c = c >> 24; - else if (format == PIXMAN_r5g6b5 || - format == PIXMAN_b5g6r5) - c = convert_8888_to_0565 (c); - -#if 0 - printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue); - printf ("pixel: %x\n", c); -#endif - - *pixel = c; - return TRUE; -} - -PIXMAN_EXPORT pixman_bool_t -pixman_image_fill_rectangles (pixman_op_t op, - pixman_image_t * dest, - const pixman_color_t * color, - int n_rects, - const pixman_rectangle16_t *rects) -{ - pixman_box32_t stack_boxes[6]; - pixman_box32_t *boxes; - pixman_bool_t result; - int i; - - if (n_rects > 6) - { - boxes = pixman_malloc_ab (sizeof (pixman_box32_t), n_rects); - if (boxes == NULL) - return FALSE; - } - else - { - boxes = stack_boxes; - } - - for (i = 0; i < n_rects; ++i) - { - boxes[i].x1 = rects[i].x; - boxes[i].y1 = rects[i].y; - boxes[i].x2 = boxes[i].x1 + rects[i].width; - boxes[i].y2 = boxes[i].y1 + rects[i].height; - } - - result = pixman_image_fill_boxes (op, dest, color, n_rects, boxes); - - if (boxes != stack_boxes) - free (boxes); - - return result; -} - -PIXMAN_EXPORT pixman_bool_t -pixman_image_fill_boxes (pixman_op_t op, - pixman_image_t * dest, - const pixman_color_t *color, - int n_boxes, - const pixman_box32_t *boxes) -{ - pixman_image_t *solid; - pixman_color_t c; - int i; - - _pixman_image_validate (dest); - - if (color->alpha == 0xffff) - { - if (op == PIXMAN_OP_OVER) - op = PIXMAN_OP_SRC; - } - - if (op == PIXMAN_OP_CLEAR) - { - c.red = 0; - c.green = 0; - c.blue = 0; - c.alpha = 0; - - color = &c; - - op = PIXMAN_OP_SRC; - } - - if (op == PIXMAN_OP_SRC) - { - uint32_t pixel; - - if (color_to_pixel (color, &pixel, dest->bits.format)) - { - pixman_region32_t fill_region; - int n_rects, j; - pixman_box32_t *rects; - - if (!pixman_region32_init_rects (&fill_region, boxes, n_boxes)) - return FALSE; - - if (dest->common.have_clip_region) - { - if (!pixman_region32_intersect (&fill_region, - &fill_region, - &dest->common.clip_region)) - return FALSE; - } - - rects = pixman_region32_rectangles (&fill_region, &n_rects); - for (j = 0; j < n_rects; ++j) - { - const pixman_box32_t *rect = &(rects[j]); - pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format), - rect->x1, rect->y1, rect->x2 - rect->x1, rect->y2 - rect->y1, - pixel); - } - - pixman_region32_fini (&fill_region); - return TRUE; - } - } - - solid = pixman_image_create_solid_fill (color); - if (!solid) - return FALSE; - - for (i = 0; i < n_boxes; ++i) - { - const pixman_box32_t *box = &(boxes[i]); - - pixman_image_composite32 (op, solid, NULL, dest, - 0, 0, 0, 0, - box->x1, box->y1, - box->x2 - box->x1, box->y2 - box->y1); - } - - pixman_image_unref (solid); - - return TRUE; -} - -/** - * pixman_version: - * - * Returns the version of the pixman library encoded in a single - * integer as per %PIXMAN_VERSION_ENCODE. The encoding ensures that - * later versions compare greater than earlier versions. - * - * A run-time comparison to check that pixman's version is greater than - * or equal to version X.Y.Z could be performed as follows: - * - * <informalexample><programlisting> - * if (pixman_version() >= PIXMAN_VERSION_ENCODE(X,Y,Z)) {...} - * </programlisting></informalexample> - * - * See also pixman_version_string() as well as the compile-time - * equivalents %PIXMAN_VERSION and %PIXMAN_VERSION_STRING. - * - * Return value: the encoded version. - **/ -PIXMAN_EXPORT int -pixman_version (void) -{ - return PIXMAN_VERSION; -} - -/** - * pixman_version_string: - * - * Returns the version of the pixman library as a human-readable string - * of the form "X.Y.Z". - * - * See also pixman_version() as well as the compile-time equivalents - * %PIXMAN_VERSION_STRING and %PIXMAN_VERSION. - * - * Return value: a string containing the version. - **/ -PIXMAN_EXPORT const char* -pixman_version_string (void) -{ - return PIXMAN_VERSION_STRING; -} - -/** - * pixman_format_supported_source: - * @format: A pixman_format_code_t format - * - * Return value: whether the provided format code is a supported - * format for a pixman surface used as a source in - * rendering. - * - * Currently, all pixman_format_code_t values are supported. - **/ -PIXMAN_EXPORT pixman_bool_t -pixman_format_supported_source (pixman_format_code_t format) -{ - switch (format) - { - /* 32 bpp formats */ - case PIXMAN_a2b10g10r10: - case PIXMAN_x2b10g10r10: - case PIXMAN_a2r10g10b10: - case PIXMAN_x2r10g10b10: - case PIXMAN_a8r8g8b8: - case PIXMAN_a8r8g8b8_sRGB: - case PIXMAN_x8r8g8b8: - case PIXMAN_a8b8g8r8: - case PIXMAN_x8b8g8r8: - case PIXMAN_b8g8r8a8: - case PIXMAN_b8g8r8x8: - case PIXMAN_r8g8b8a8: - case PIXMAN_r8g8b8x8: - case PIXMAN_r8g8b8: - case PIXMAN_b8g8r8: - case PIXMAN_r5g6b5: - case PIXMAN_b5g6r5: - case PIXMAN_x14r6g6b6: - /* 16 bpp formats */ - case PIXMAN_a1r5g5b5: - case PIXMAN_x1r5g5b5: - case PIXMAN_a1b5g5r5: - case PIXMAN_x1b5g5r5: - case PIXMAN_a4r4g4b4: - case PIXMAN_x4r4g4b4: - case PIXMAN_a4b4g4r4: - case PIXMAN_x4b4g4r4: - /* 8bpp formats */ - case PIXMAN_a8: - case PIXMAN_r3g3b2: - case PIXMAN_b2g3r3: - case PIXMAN_a2r2g2b2: - case PIXMAN_a2b2g2r2: - case PIXMAN_c8: - case PIXMAN_g8: - case PIXMAN_x4a4: - /* Collides with PIXMAN_c8 - case PIXMAN_x4c4: - */ - /* Collides with PIXMAN_g8 - case PIXMAN_x4g4: - */ - /* 4bpp formats */ - case PIXMAN_a4: - case PIXMAN_r1g2b1: - case PIXMAN_b1g2r1: - case PIXMAN_a1r1g1b1: - case PIXMAN_a1b1g1r1: - case PIXMAN_c4: - case PIXMAN_g4: - /* 1bpp formats */ - case PIXMAN_a1: - case PIXMAN_g1: - /* YUV formats */ - case PIXMAN_yuy2: - case PIXMAN_yv12: - return TRUE; - - default: - return FALSE; - } -} - -/** - * pixman_format_supported_destination: - * @format: A pixman_format_code_t format - * - * Return value: whether the provided format code is a supported - * format for a pixman surface used as a destination in - * rendering. - * - * Currently, all pixman_format_code_t values are supported - * except for the YUV formats. - **/ -PIXMAN_EXPORT pixman_bool_t -pixman_format_supported_destination (pixman_format_code_t format) -{ - /* YUV formats cannot be written to at the moment */ - if (format == PIXMAN_yuy2 || format == PIXMAN_yv12) - return FALSE; - - return pixman_format_supported_source (format); -} - -PIXMAN_EXPORT pixman_bool_t -pixman_compute_composite_region (pixman_region16_t * region, - pixman_image_t * src_image, - pixman_image_t * mask_image, - pixman_image_t * dest_image, - int16_t src_x, - int16_t src_y, - int16_t mask_x, - int16_t mask_y, - int16_t dest_x, - int16_t dest_y, - uint16_t width, - uint16_t height) -{ - pixman_region32_t r32; - pixman_bool_t retval; - - pixman_region32_init (&r32); - - retval = _pixman_compute_composite_region32 ( - &r32, src_image, mask_image, dest_image, - src_x, src_y, mask_x, mask_y, dest_x, dest_y, - width, height); - - if (retval) - { - if (!pixman_region16_copy_from_region32 (region, &r32)) - retval = FALSE; - } - - pixman_region32_fini (&r32); - return retval; -} diff --git a/source/libs/pixman/pixman-src/pixman/pixman.h b/source/libs/pixman/pixman-src/pixman/pixman.h deleted file mode 100644 index 509ba5e534a80e285b308dae7cfc8ff3f3d3ce15..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/pixman.h +++ /dev/null @@ -1,1111 +0,0 @@ -/*********************************************************** - -Copyright 1987, 1998 The Open Group - -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. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -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 Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL 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. - -******************************************************************/ -/* - * Copyright © 1998, 2004 Keith Packard - * Copyright 2007 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 Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD 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. - */ - -#ifndef PIXMAN_H__ -#define PIXMAN_H__ - -#include <pixman-version.h> - -#ifdef __cplusplus -#define PIXMAN_BEGIN_DECLS extern "C" { -#define PIXMAN_END_DECLS } -#else -#define PIXMAN_BEGIN_DECLS -#define PIXMAN_END_DECLS -#endif - -PIXMAN_BEGIN_DECLS - -/* - * Standard integers - */ - -#if !defined (PIXMAN_DONT_DEFINE_STDINT) - -#if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || defined (_sgi) || defined (__sun) || defined (sun) || defined (__digital__) || defined (__HP_cc) -# include <inttypes.h> -/* VS 2010 (_MSC_VER 1600) has stdint.h */ -#elif defined (_MSC_VER) && _MSC_VER < 1600 -typedef __int8 int8_t; -typedef unsigned __int8 uint8_t; -typedef __int16 int16_t; -typedef unsigned __int16 uint16_t; -typedef __int32 int32_t; -typedef unsigned __int32 uint32_t; -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; -#elif defined (_AIX) -# include <sys/inttypes.h> -#else -# include <stdint.h> -#endif - -#endif - -/* - * Boolean - */ -typedef int pixman_bool_t; - -/* - * Fixpoint numbers - */ -typedef int64_t pixman_fixed_32_32_t; -typedef pixman_fixed_32_32_t pixman_fixed_48_16_t; -typedef uint32_t pixman_fixed_1_31_t; -typedef uint32_t pixman_fixed_1_16_t; -typedef int32_t pixman_fixed_16_16_t; -typedef pixman_fixed_16_16_t pixman_fixed_t; - -#define pixman_fixed_e ((pixman_fixed_t) 1) -#define pixman_fixed_1 (pixman_int_to_fixed(1)) -#define pixman_fixed_1_minus_e (pixman_fixed_1 - pixman_fixed_e) -#define pixman_fixed_minus_1 (pixman_int_to_fixed(-1)) -#define pixman_fixed_to_int(f) ((int) ((f) >> 16)) -#define pixman_int_to_fixed(i) ((pixman_fixed_t) ((i) << 16)) -#define pixman_fixed_to_double(f) (double) ((f) / (double) pixman_fixed_1) -#define pixman_double_to_fixed(d) ((pixman_fixed_t) ((d) * 65536.0)) -#define pixman_fixed_frac(f) ((f) & pixman_fixed_1_minus_e) -#define pixman_fixed_floor(f) ((f) & ~pixman_fixed_1_minus_e) -#define pixman_fixed_ceil(f) pixman_fixed_floor ((f) + pixman_fixed_1_minus_e) -#define pixman_fixed_fraction(f) ((f) & pixman_fixed_1_minus_e) -#define pixman_fixed_mod_2(f) ((f) & (pixman_fixed1 | pixman_fixed_1_minus_e)) -#define pixman_max_fixed_48_16 ((pixman_fixed_48_16_t) 0x7fffffff) -#define pixman_min_fixed_48_16 (-((pixman_fixed_48_16_t) 1 << 31)) - -/* - * Misc structs - */ -typedef struct pixman_color pixman_color_t; -typedef struct pixman_point_fixed pixman_point_fixed_t; -typedef struct pixman_line_fixed pixman_line_fixed_t; -typedef struct pixman_vector pixman_vector_t; -typedef struct pixman_transform pixman_transform_t; - -struct pixman_color -{ - uint16_t red; - uint16_t green; - uint16_t blue; - uint16_t alpha; -}; - -struct pixman_point_fixed -{ - pixman_fixed_t x; - pixman_fixed_t y; -}; - -struct pixman_line_fixed -{ - pixman_point_fixed_t p1, p2; -}; - -/* - * Fixed point matrices - */ - -struct pixman_vector -{ - pixman_fixed_t vector[3]; -}; - -struct pixman_transform -{ - pixman_fixed_t matrix[3][3]; -}; - -/* forward declaration (sorry) */ -struct pixman_box16; -typedef union pixman_image pixman_image_t; - -void pixman_transform_init_identity (struct pixman_transform *matrix); -pixman_bool_t pixman_transform_point_3d (const struct pixman_transform *transform, - struct pixman_vector *vector); -pixman_bool_t pixman_transform_point (const struct pixman_transform *transform, - struct pixman_vector *vector); -pixman_bool_t pixman_transform_multiply (struct pixman_transform *dst, - const struct pixman_transform *l, - const struct pixman_transform *r); -void pixman_transform_init_scale (struct pixman_transform *t, - pixman_fixed_t sx, - pixman_fixed_t sy); -pixman_bool_t pixman_transform_scale (struct pixman_transform *forward, - struct pixman_transform *reverse, - pixman_fixed_t sx, - pixman_fixed_t sy); -void pixman_transform_init_rotate (struct pixman_transform *t, - pixman_fixed_t cos, - pixman_fixed_t sin); -pixman_bool_t pixman_transform_rotate (struct pixman_transform *forward, - struct pixman_transform *reverse, - pixman_fixed_t c, - pixman_fixed_t s); -void pixman_transform_init_translate (struct pixman_transform *t, - pixman_fixed_t tx, - pixman_fixed_t ty); -pixman_bool_t pixman_transform_translate (struct pixman_transform *forward, - struct pixman_transform *reverse, - pixman_fixed_t tx, - pixman_fixed_t ty); -pixman_bool_t pixman_transform_bounds (const struct pixman_transform *matrix, - struct pixman_box16 *b); -pixman_bool_t pixman_transform_invert (struct pixman_transform *dst, - const struct pixman_transform *src); -pixman_bool_t pixman_transform_is_identity (const struct pixman_transform *t); -pixman_bool_t pixman_transform_is_scale (const struct pixman_transform *t); -pixman_bool_t pixman_transform_is_int_translate (const struct pixman_transform *t); -pixman_bool_t pixman_transform_is_inverse (const struct pixman_transform *a, - const struct pixman_transform *b); - -/* - * Floating point matrices - */ -typedef struct pixman_f_transform pixman_f_transform_t; -typedef struct pixman_f_vector pixman_f_vector_t; - -struct pixman_f_vector -{ - double v[3]; -}; - -struct pixman_f_transform -{ - double m[3][3]; -}; - -pixman_bool_t pixman_transform_from_pixman_f_transform (struct pixman_transform *t, - const struct pixman_f_transform *ft); -void pixman_f_transform_from_pixman_transform (struct pixman_f_transform *ft, - const struct pixman_transform *t); -pixman_bool_t pixman_f_transform_invert (struct pixman_f_transform *dst, - const struct pixman_f_transform *src); -pixman_bool_t pixman_f_transform_point (const struct pixman_f_transform *t, - struct pixman_f_vector *v); -void pixman_f_transform_point_3d (const struct pixman_f_transform *t, - struct pixman_f_vector *v); -void pixman_f_transform_multiply (struct pixman_f_transform *dst, - const struct pixman_f_transform *l, - const struct pixman_f_transform *r); -void pixman_f_transform_init_scale (struct pixman_f_transform *t, - double sx, - double sy); -pixman_bool_t pixman_f_transform_scale (struct pixman_f_transform *forward, - struct pixman_f_transform *reverse, - double sx, - double sy); -void pixman_f_transform_init_rotate (struct pixman_f_transform *t, - double cos, - double sin); -pixman_bool_t pixman_f_transform_rotate (struct pixman_f_transform *forward, - struct pixman_f_transform *reverse, - double c, - double s); -void pixman_f_transform_init_translate (struct pixman_f_transform *t, - double tx, - double ty); -pixman_bool_t pixman_f_transform_translate (struct pixman_f_transform *forward, - struct pixman_f_transform *reverse, - double tx, - double ty); -pixman_bool_t pixman_f_transform_bounds (const struct pixman_f_transform *t, - struct pixman_box16 *b); -void pixman_f_transform_init_identity (struct pixman_f_transform *t); - -typedef enum -{ - PIXMAN_REPEAT_NONE, - PIXMAN_REPEAT_NORMAL, - PIXMAN_REPEAT_PAD, - PIXMAN_REPEAT_REFLECT -} pixman_repeat_t; - -typedef enum -{ - PIXMAN_FILTER_FAST, - PIXMAN_FILTER_GOOD, - PIXMAN_FILTER_BEST, - PIXMAN_FILTER_NEAREST, - PIXMAN_FILTER_BILINEAR, - PIXMAN_FILTER_CONVOLUTION, - - /* The SEPARABLE_CONVOLUTION filter takes the following parameters: - * - * width: integer given as 16.16 fixpoint number - * height: integer given as 16.16 fixpoint number - * x_phase_bits: integer given as 16.16 fixpoint - * y_phase_bits: integer given as 16.16 fixpoint - * xtables: (1 << x_phase_bits) tables of size width - * ytables: (1 << y_phase_bits) tables of size height - * - * When sampling at (x, y), the location is first rounded to one of - * n_x_phases * n_y_phases subpixel positions. These subpixel positions - * determine an xtable and a ytable to use. - * - * Conceptually a width x height matrix is then formed in which each entry - * is the product of the corresponding entries in the x and y tables. - * This matrix is then aligned with the image pixels such that its center - * is as close as possible to the subpixel location chosen earlier. Then - * the image is convolved with the matrix and the resulting pixel returned. - */ - PIXMAN_FILTER_SEPARABLE_CONVOLUTION -} pixman_filter_t; - -typedef enum -{ - PIXMAN_OP_CLEAR = 0x00, - PIXMAN_OP_SRC = 0x01, - PIXMAN_OP_DST = 0x02, - PIXMAN_OP_OVER = 0x03, - PIXMAN_OP_OVER_REVERSE = 0x04, - PIXMAN_OP_IN = 0x05, - PIXMAN_OP_IN_REVERSE = 0x06, - PIXMAN_OP_OUT = 0x07, - PIXMAN_OP_OUT_REVERSE = 0x08, - PIXMAN_OP_ATOP = 0x09, - PIXMAN_OP_ATOP_REVERSE = 0x0a, - PIXMAN_OP_XOR = 0x0b, - PIXMAN_OP_ADD = 0x0c, - PIXMAN_OP_SATURATE = 0x0d, - - PIXMAN_OP_DISJOINT_CLEAR = 0x10, - PIXMAN_OP_DISJOINT_SRC = 0x11, - PIXMAN_OP_DISJOINT_DST = 0x12, - PIXMAN_OP_DISJOINT_OVER = 0x13, - PIXMAN_OP_DISJOINT_OVER_REVERSE = 0x14, - PIXMAN_OP_DISJOINT_IN = 0x15, - PIXMAN_OP_DISJOINT_IN_REVERSE = 0x16, - PIXMAN_OP_DISJOINT_OUT = 0x17, - PIXMAN_OP_DISJOINT_OUT_REVERSE = 0x18, - PIXMAN_OP_DISJOINT_ATOP = 0x19, - PIXMAN_OP_DISJOINT_ATOP_REVERSE = 0x1a, - PIXMAN_OP_DISJOINT_XOR = 0x1b, - - PIXMAN_OP_CONJOINT_CLEAR = 0x20, - PIXMAN_OP_CONJOINT_SRC = 0x21, - PIXMAN_OP_CONJOINT_DST = 0x22, - PIXMAN_OP_CONJOINT_OVER = 0x23, - PIXMAN_OP_CONJOINT_OVER_REVERSE = 0x24, - PIXMAN_OP_CONJOINT_IN = 0x25, - PIXMAN_OP_CONJOINT_IN_REVERSE = 0x26, - PIXMAN_OP_CONJOINT_OUT = 0x27, - PIXMAN_OP_CONJOINT_OUT_REVERSE = 0x28, - PIXMAN_OP_CONJOINT_ATOP = 0x29, - PIXMAN_OP_CONJOINT_ATOP_REVERSE = 0x2a, - PIXMAN_OP_CONJOINT_XOR = 0x2b, - - PIXMAN_OP_MULTIPLY = 0x30, - PIXMAN_OP_SCREEN = 0x31, - PIXMAN_OP_OVERLAY = 0x32, - PIXMAN_OP_DARKEN = 0x33, - PIXMAN_OP_LIGHTEN = 0x34, - PIXMAN_OP_COLOR_DODGE = 0x35, - PIXMAN_OP_COLOR_BURN = 0x36, - PIXMAN_OP_HARD_LIGHT = 0x37, - PIXMAN_OP_SOFT_LIGHT = 0x38, - PIXMAN_OP_DIFFERENCE = 0x39, - PIXMAN_OP_EXCLUSION = 0x3a, - PIXMAN_OP_HSL_HUE = 0x3b, - PIXMAN_OP_HSL_SATURATION = 0x3c, - PIXMAN_OP_HSL_COLOR = 0x3d, - PIXMAN_OP_HSL_LUMINOSITY = 0x3e - -#ifdef PIXMAN_USE_INTERNAL_API - , - PIXMAN_N_OPERATORS, - PIXMAN_OP_NONE = PIXMAN_N_OPERATORS -#endif -} pixman_op_t; - -/* - * Regions - */ -typedef struct pixman_region16_data pixman_region16_data_t; -typedef struct pixman_box16 pixman_box16_t; -typedef struct pixman_rectangle16 pixman_rectangle16_t; -typedef struct pixman_region16 pixman_region16_t; - -struct pixman_region16_data { - long size; - long numRects; -/* pixman_box16_t rects[size]; in memory but not explicitly declared */ -}; - -struct pixman_rectangle16 -{ - int16_t x, y; - uint16_t width, height; -}; - -struct pixman_box16 -{ - int16_t x1, y1, x2, y2; -}; - -struct pixman_region16 -{ - pixman_box16_t extents; - pixman_region16_data_t *data; -}; - -typedef enum -{ - PIXMAN_REGION_OUT, - PIXMAN_REGION_IN, - PIXMAN_REGION_PART -} pixman_region_overlap_t; - -/* This function exists only to make it possible to preserve - * the X ABI - it should go away at first opportunity. - */ -void pixman_region_set_static_pointers (pixman_box16_t *empty_box, - pixman_region16_data_t *empty_data, - pixman_region16_data_t *broken_data); - -/* creation/destruction */ -void pixman_region_init (pixman_region16_t *region); -void pixman_region_init_rect (pixman_region16_t *region, - int x, - int y, - unsigned int width, - unsigned int height); -pixman_bool_t pixman_region_init_rects (pixman_region16_t *region, - const pixman_box16_t *boxes, - int count); -void pixman_region_init_with_extents (pixman_region16_t *region, - pixman_box16_t *extents); -void pixman_region_init_from_image (pixman_region16_t *region, - pixman_image_t *image); -void pixman_region_fini (pixman_region16_t *region); - - -/* manipulation */ -void pixman_region_translate (pixman_region16_t *region, - int x, - int y); -pixman_bool_t pixman_region_copy (pixman_region16_t *dest, - pixman_region16_t *source); -pixman_bool_t pixman_region_intersect (pixman_region16_t *new_reg, - pixman_region16_t *reg1, - pixman_region16_t *reg2); -pixman_bool_t pixman_region_union (pixman_region16_t *new_reg, - pixman_region16_t *reg1, - pixman_region16_t *reg2); -pixman_bool_t pixman_region_union_rect (pixman_region16_t *dest, - pixman_region16_t *source, - int x, - int y, - unsigned int width, - unsigned int height); -pixman_bool_t pixman_region_intersect_rect (pixman_region16_t *dest, - pixman_region16_t *source, - int x, - int y, - unsigned int width, - unsigned int height); -pixman_bool_t pixman_region_subtract (pixman_region16_t *reg_d, - pixman_region16_t *reg_m, - pixman_region16_t *reg_s); -pixman_bool_t pixman_region_inverse (pixman_region16_t *new_reg, - pixman_region16_t *reg1, - pixman_box16_t *inv_rect); -pixman_bool_t pixman_region_contains_point (pixman_region16_t *region, - int x, - int y, - pixman_box16_t *box); -pixman_region_overlap_t pixman_region_contains_rectangle (pixman_region16_t *region, - pixman_box16_t *prect); -pixman_bool_t pixman_region_not_empty (pixman_region16_t *region); -pixman_box16_t * pixman_region_extents (pixman_region16_t *region); -int pixman_region_n_rects (pixman_region16_t *region); -pixman_box16_t * pixman_region_rectangles (pixman_region16_t *region, - int *n_rects); -pixman_bool_t pixman_region_equal (pixman_region16_t *region1, - pixman_region16_t *region2); -pixman_bool_t pixman_region_selfcheck (pixman_region16_t *region); -void pixman_region_reset (pixman_region16_t *region, - pixman_box16_t *box); -void pixman_region_clear (pixman_region16_t *region); -/* - * 32 bit regions - */ -typedef struct pixman_region32_data pixman_region32_data_t; -typedef struct pixman_box32 pixman_box32_t; -typedef struct pixman_rectangle32 pixman_rectangle32_t; -typedef struct pixman_region32 pixman_region32_t; - -struct pixman_region32_data { - long size; - long numRects; -/* pixman_box32_t rects[size]; in memory but not explicitly declared */ -}; - -struct pixman_rectangle32 -{ - int32_t x, y; - uint32_t width, height; -}; - -struct pixman_box32 -{ - int32_t x1, y1, x2, y2; -}; - -struct pixman_region32 -{ - pixman_box32_t extents; - pixman_region32_data_t *data; -}; - -/* creation/destruction */ -void pixman_region32_init (pixman_region32_t *region); -void pixman_region32_init_rect (pixman_region32_t *region, - int x, - int y, - unsigned int width, - unsigned int height); -pixman_bool_t pixman_region32_init_rects (pixman_region32_t *region, - const pixman_box32_t *boxes, - int count); -void pixman_region32_init_with_extents (pixman_region32_t *region, - pixman_box32_t *extents); -void pixman_region32_init_from_image (pixman_region32_t *region, - pixman_image_t *image); -void pixman_region32_fini (pixman_region32_t *region); - - -/* manipulation */ -void pixman_region32_translate (pixman_region32_t *region, - int x, - int y); -pixman_bool_t pixman_region32_copy (pixman_region32_t *dest, - pixman_region32_t *source); -pixman_bool_t pixman_region32_intersect (pixman_region32_t *new_reg, - pixman_region32_t *reg1, - pixman_region32_t *reg2); -pixman_bool_t pixman_region32_union (pixman_region32_t *new_reg, - pixman_region32_t *reg1, - pixman_region32_t *reg2); -pixman_bool_t pixman_region32_intersect_rect (pixman_region32_t *dest, - pixman_region32_t *source, - int x, - int y, - unsigned int width, - unsigned int height); -pixman_bool_t pixman_region32_union_rect (pixman_region32_t *dest, - pixman_region32_t *source, - int x, - int y, - unsigned int width, - unsigned int height); -pixman_bool_t pixman_region32_subtract (pixman_region32_t *reg_d, - pixman_region32_t *reg_m, - pixman_region32_t *reg_s); -pixman_bool_t pixman_region32_inverse (pixman_region32_t *new_reg, - pixman_region32_t *reg1, - pixman_box32_t *inv_rect); -pixman_bool_t pixman_region32_contains_point (pixman_region32_t *region, - int x, - int y, - pixman_box32_t *box); -pixman_region_overlap_t pixman_region32_contains_rectangle (pixman_region32_t *region, - pixman_box32_t *prect); -pixman_bool_t pixman_region32_not_empty (pixman_region32_t *region); -pixman_box32_t * pixman_region32_extents (pixman_region32_t *region); -int pixman_region32_n_rects (pixman_region32_t *region); -pixman_box32_t * pixman_region32_rectangles (pixman_region32_t *region, - int *n_rects); -pixman_bool_t pixman_region32_equal (pixman_region32_t *region1, - pixman_region32_t *region2); -pixman_bool_t pixman_region32_selfcheck (pixman_region32_t *region); -void pixman_region32_reset (pixman_region32_t *region, - pixman_box32_t *box); -void pixman_region32_clear (pixman_region32_t *region); - - -/* Copy / Fill / Misc */ -pixman_bool_t pixman_blt (uint32_t *src_bits, - uint32_t *dst_bits, - int src_stride, - int dst_stride, - int src_bpp, - int dst_bpp, - int src_x, - int src_y, - int dest_x, - int dest_y, - int width, - int height); -pixman_bool_t pixman_fill (uint32_t *bits, - int stride, - int bpp, - int x, - int y, - int width, - int height, - uint32_t _xor); - -int pixman_version (void); -const char* pixman_version_string (void); - -/* - * Images - */ -typedef struct pixman_indexed pixman_indexed_t; -typedef struct pixman_gradient_stop pixman_gradient_stop_t; - -typedef uint32_t (* pixman_read_memory_func_t) (const void *src, int size); -typedef void (* pixman_write_memory_func_t) (void *dst, uint32_t value, int size); - -typedef void (* pixman_image_destroy_func_t) (pixman_image_t *image, void *data); - -struct pixman_gradient_stop { - pixman_fixed_t x; - pixman_color_t color; -}; - -#define PIXMAN_MAX_INDEXED 256 /* XXX depth must be <= 8 */ - -#if PIXMAN_MAX_INDEXED <= 256 -typedef uint8_t pixman_index_type; -#endif - -struct pixman_indexed -{ - pixman_bool_t color; - uint32_t rgba[PIXMAN_MAX_INDEXED]; - pixman_index_type ent[32768]; -}; - -/* - * While the protocol is generous in format support, the - * sample implementation allows only packed RGB and GBR - * representations for data to simplify software rendering, - */ -#define PIXMAN_FORMAT(bpp,type,a,r,g,b) (((bpp) << 24) | \ - ((type) << 16) | \ - ((a) << 12) | \ - ((r) << 8) | \ - ((g) << 4) | \ - ((b))) - -#define PIXMAN_FORMAT_BPP(f) (((f) >> 24) ) -#define PIXMAN_FORMAT_TYPE(f) (((f) >> 16) & 0xff) -#define PIXMAN_FORMAT_A(f) (((f) >> 12) & 0x0f) -#define PIXMAN_FORMAT_R(f) (((f) >> 8) & 0x0f) -#define PIXMAN_FORMAT_G(f) (((f) >> 4) & 0x0f) -#define PIXMAN_FORMAT_B(f) (((f) ) & 0x0f) -#define PIXMAN_FORMAT_RGB(f) (((f) ) & 0xfff) -#define PIXMAN_FORMAT_VIS(f) (((f) ) & 0xffff) -#define PIXMAN_FORMAT_DEPTH(f) (PIXMAN_FORMAT_A(f) + \ - PIXMAN_FORMAT_R(f) + \ - PIXMAN_FORMAT_G(f) + \ - PIXMAN_FORMAT_B(f)) - -#define PIXMAN_TYPE_OTHER 0 -#define PIXMAN_TYPE_A 1 -#define PIXMAN_TYPE_ARGB 2 -#define PIXMAN_TYPE_ABGR 3 -#define PIXMAN_TYPE_COLOR 4 -#define PIXMAN_TYPE_GRAY 5 -#define PIXMAN_TYPE_YUY2 6 -#define PIXMAN_TYPE_YV12 7 -#define PIXMAN_TYPE_BGRA 8 -#define PIXMAN_TYPE_RGBA 9 -#define PIXMAN_TYPE_ARGB_SRGB 10 - -#define PIXMAN_FORMAT_COLOR(f) \ - (PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ARGB || \ - PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ABGR || \ - PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_BGRA || \ - PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_RGBA) - -/* 32bpp formats */ -typedef enum { - PIXMAN_a8r8g8b8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,8,8,8,8), - PIXMAN_x8r8g8b8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,0,8,8,8), - PIXMAN_a8b8g8r8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ABGR,8,8,8,8), - PIXMAN_x8b8g8r8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ABGR,0,8,8,8), - PIXMAN_b8g8r8a8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_BGRA,8,8,8,8), - PIXMAN_b8g8r8x8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_BGRA,0,8,8,8), - PIXMAN_r8g8b8a8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_RGBA,8,8,8,8), - PIXMAN_r8g8b8x8 = PIXMAN_FORMAT(32,PIXMAN_TYPE_RGBA,0,8,8,8), - PIXMAN_x14r6g6b6 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,0,6,6,6), - PIXMAN_x2r10g10b10 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,0,10,10,10), - PIXMAN_a2r10g10b10 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB,2,10,10,10), - PIXMAN_x2b10g10r10 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ABGR,0,10,10,10), - PIXMAN_a2b10g10r10 = PIXMAN_FORMAT(32,PIXMAN_TYPE_ABGR,2,10,10,10), - -/* sRGB formats */ - PIXMAN_a8r8g8b8_sRGB = PIXMAN_FORMAT(32,PIXMAN_TYPE_ARGB_SRGB,8,8,8,8), - -/* 24bpp formats */ - PIXMAN_r8g8b8 = PIXMAN_FORMAT(24,PIXMAN_TYPE_ARGB,0,8,8,8), - PIXMAN_b8g8r8 = PIXMAN_FORMAT(24,PIXMAN_TYPE_ABGR,0,8,8,8), - -/* 16bpp formats */ - PIXMAN_r5g6b5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ARGB,0,5,6,5), - PIXMAN_b5g6r5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ABGR,0,5,6,5), - - PIXMAN_a1r5g5b5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ARGB,1,5,5,5), - PIXMAN_x1r5g5b5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ARGB,0,5,5,5), - PIXMAN_a1b5g5r5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ABGR,1,5,5,5), - PIXMAN_x1b5g5r5 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ABGR,0,5,5,5), - PIXMAN_a4r4g4b4 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ARGB,4,4,4,4), - PIXMAN_x4r4g4b4 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ARGB,0,4,4,4), - PIXMAN_a4b4g4r4 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ABGR,4,4,4,4), - PIXMAN_x4b4g4r4 = PIXMAN_FORMAT(16,PIXMAN_TYPE_ABGR,0,4,4,4), - -/* 8bpp formats */ - PIXMAN_a8 = PIXMAN_FORMAT(8,PIXMAN_TYPE_A,8,0,0,0), - PIXMAN_r3g3b2 = PIXMAN_FORMAT(8,PIXMAN_TYPE_ARGB,0,3,3,2), - PIXMAN_b2g3r3 = PIXMAN_FORMAT(8,PIXMAN_TYPE_ABGR,0,3,3,2), - PIXMAN_a2r2g2b2 = PIXMAN_FORMAT(8,PIXMAN_TYPE_ARGB,2,2,2,2), - PIXMAN_a2b2g2r2 = PIXMAN_FORMAT(8,PIXMAN_TYPE_ABGR,2,2,2,2), - - PIXMAN_c8 = PIXMAN_FORMAT(8,PIXMAN_TYPE_COLOR,0,0,0,0), - PIXMAN_g8 = PIXMAN_FORMAT(8,PIXMAN_TYPE_GRAY,0,0,0,0), - - PIXMAN_x4a4 = PIXMAN_FORMAT(8,PIXMAN_TYPE_A,4,0,0,0), - - PIXMAN_x4c4 = PIXMAN_FORMAT(8,PIXMAN_TYPE_COLOR,0,0,0,0), - PIXMAN_x4g4 = PIXMAN_FORMAT(8,PIXMAN_TYPE_GRAY,0,0,0,0), - -/* 4bpp formats */ - PIXMAN_a4 = PIXMAN_FORMAT(4,PIXMAN_TYPE_A,4,0,0,0), - PIXMAN_r1g2b1 = PIXMAN_FORMAT(4,PIXMAN_TYPE_ARGB,0,1,2,1), - PIXMAN_b1g2r1 = PIXMAN_FORMAT(4,PIXMAN_TYPE_ABGR,0,1,2,1), - PIXMAN_a1r1g1b1 = PIXMAN_FORMAT(4,PIXMAN_TYPE_ARGB,1,1,1,1), - PIXMAN_a1b1g1r1 = PIXMAN_FORMAT(4,PIXMAN_TYPE_ABGR,1,1,1,1), - - PIXMAN_c4 = PIXMAN_FORMAT(4,PIXMAN_TYPE_COLOR,0,0,0,0), - PIXMAN_g4 = PIXMAN_FORMAT(4,PIXMAN_TYPE_GRAY,0,0,0,0), - -/* 1bpp formats */ - PIXMAN_a1 = PIXMAN_FORMAT(1,PIXMAN_TYPE_A,1,0,0,0), - - PIXMAN_g1 = PIXMAN_FORMAT(1,PIXMAN_TYPE_GRAY,0,0,0,0), - -/* YUV formats */ - PIXMAN_yuy2 = PIXMAN_FORMAT(16,PIXMAN_TYPE_YUY2,0,0,0,0), - PIXMAN_yv12 = PIXMAN_FORMAT(12,PIXMAN_TYPE_YV12,0,0,0,0) -} pixman_format_code_t; - -/* Querying supported format values. */ -pixman_bool_t pixman_format_supported_destination (pixman_format_code_t format); -pixman_bool_t pixman_format_supported_source (pixman_format_code_t format); - -/* Constructors */ -pixman_image_t *pixman_image_create_solid_fill (const pixman_color_t *color); -pixman_image_t *pixman_image_create_linear_gradient (const pixman_point_fixed_t *p1, - const pixman_point_fixed_t *p2, - const pixman_gradient_stop_t *stops, - int n_stops); -pixman_image_t *pixman_image_create_radial_gradient (const pixman_point_fixed_t *inner, - const pixman_point_fixed_t *outer, - pixman_fixed_t inner_radius, - pixman_fixed_t outer_radius, - const pixman_gradient_stop_t *stops, - int n_stops); -pixman_image_t *pixman_image_create_conical_gradient (const pixman_point_fixed_t *center, - pixman_fixed_t angle, - const pixman_gradient_stop_t *stops, - int n_stops); -pixman_image_t *pixman_image_create_bits (pixman_format_code_t format, - int width, - int height, - uint32_t *bits, - int rowstride_bytes); -pixman_image_t *pixman_image_create_bits_no_clear (pixman_format_code_t format, - int width, - int height, - uint32_t * bits, - int rowstride_bytes); - -/* Destructor */ -pixman_image_t *pixman_image_ref (pixman_image_t *image); -pixman_bool_t pixman_image_unref (pixman_image_t *image); - -void pixman_image_set_destroy_function (pixman_image_t *image, - pixman_image_destroy_func_t function, - void *data); -void * pixman_image_get_destroy_data (pixman_image_t *image); - -/* Set properties */ -pixman_bool_t pixman_image_set_clip_region (pixman_image_t *image, - pixman_region16_t *region); -pixman_bool_t pixman_image_set_clip_region32 (pixman_image_t *image, - pixman_region32_t *region); -void pixman_image_set_has_client_clip (pixman_image_t *image, - pixman_bool_t clien_clip); -pixman_bool_t pixman_image_set_transform (pixman_image_t *image, - const pixman_transform_t *transform); -void pixman_image_set_repeat (pixman_image_t *image, - pixman_repeat_t repeat); -pixman_bool_t pixman_image_set_filter (pixman_image_t *image, - pixman_filter_t filter, - const pixman_fixed_t *filter_params, - int n_filter_params); -void pixman_image_set_source_clipping (pixman_image_t *image, - pixman_bool_t source_clipping); -void pixman_image_set_alpha_map (pixman_image_t *image, - pixman_image_t *alpha_map, - int16_t x, - int16_t y); -void pixman_image_set_component_alpha (pixman_image_t *image, - pixman_bool_t component_alpha); -pixman_bool_t pixman_image_get_component_alpha (pixman_image_t *image); -void pixman_image_set_accessors (pixman_image_t *image, - pixman_read_memory_func_t read_func, - pixman_write_memory_func_t write_func); -void pixman_image_set_indexed (pixman_image_t *image, - const pixman_indexed_t *indexed); -uint32_t *pixman_image_get_data (pixman_image_t *image); -int pixman_image_get_width (pixman_image_t *image); -int pixman_image_get_height (pixman_image_t *image); -int pixman_image_get_stride (pixman_image_t *image); /* in bytes */ -int pixman_image_get_depth (pixman_image_t *image); -pixman_format_code_t pixman_image_get_format (pixman_image_t *image); - -typedef enum -{ - PIXMAN_KERNEL_IMPULSE, - PIXMAN_KERNEL_BOX, - PIXMAN_KERNEL_LINEAR, - PIXMAN_KERNEL_CUBIC, - PIXMAN_KERNEL_GAUSSIAN, - PIXMAN_KERNEL_LANCZOS2, - PIXMAN_KERNEL_LANCZOS3, - PIXMAN_KERNEL_LANCZOS3_STRETCHED /* Jim Blinn's 'nice' filter */ -} pixman_kernel_t; - -/* Create the parameter list for a SEPARABLE_CONVOLUTION filter - * with the given kernels and scale parameters. - */ -pixman_fixed_t * -pixman_filter_create_separable_convolution (int *n_values, - pixman_fixed_t scale_x, - pixman_fixed_t scale_y, - pixman_kernel_t reconstruct_x, - pixman_kernel_t reconstruct_y, - pixman_kernel_t sample_x, - pixman_kernel_t sample_y, - int subsample_bits_x, - int subsample_bits_y); - -pixman_bool_t pixman_image_fill_rectangles (pixman_op_t op, - pixman_image_t *image, - const pixman_color_t *color, - int n_rects, - const pixman_rectangle16_t *rects); -pixman_bool_t pixman_image_fill_boxes (pixman_op_t op, - pixman_image_t *dest, - const pixman_color_t *color, - int n_boxes, - const pixman_box32_t *boxes); - -/* Composite */ -pixman_bool_t pixman_compute_composite_region (pixman_region16_t *region, - pixman_image_t *src_image, - pixman_image_t *mask_image, - pixman_image_t *dest_image, - int16_t src_x, - int16_t src_y, - int16_t mask_x, - int16_t mask_y, - int16_t dest_x, - int16_t dest_y, - uint16_t width, - uint16_t height); -void pixman_image_composite (pixman_op_t op, - pixman_image_t *src, - pixman_image_t *mask, - pixman_image_t *dest, - int16_t src_x, - int16_t src_y, - int16_t mask_x, - int16_t mask_y, - int16_t dest_x, - int16_t dest_y, - uint16_t width, - uint16_t height); -void pixman_image_composite32 (pixman_op_t op, - pixman_image_t *src, - pixman_image_t *mask, - pixman_image_t *dest, - int32_t src_x, - int32_t src_y, - int32_t mask_x, - int32_t mask_y, - int32_t dest_x, - int32_t dest_y, - int32_t width, - int32_t height); - -/* Executive Summary: This function is a no-op that only exists - * for historical reasons. - * - * There used to be a bug in the X server where it would rely on - * out-of-bounds accesses when it was asked to composite with a - * window as the source. It would create a pixman image pointing - * to some bogus position in memory, but then set a clip region - * to the position where the actual bits were. - * - * Due to a bug in old versions of pixman, where it would not clip - * against the image bounds when a clip region was set, this would - * actually work. So when the pixman bug was fixed, a workaround was - * added to allow certain out-of-bound accesses. This function disabled - * those workarounds. - * - * Since 0.21.2, pixman doesn't do these workarounds anymore, so now this - * function is a no-op. - */ -void pixman_disable_out_of_bounds_workaround (void); - -/* - * Glyphs - */ -typedef struct pixman_glyph_cache_t pixman_glyph_cache_t; -typedef struct -{ - int x, y; - const void *glyph; -} pixman_glyph_t; - -pixman_glyph_cache_t *pixman_glyph_cache_create (void); -void pixman_glyph_cache_destroy (pixman_glyph_cache_t *cache); -void pixman_glyph_cache_freeze (pixman_glyph_cache_t *cache); -void pixman_glyph_cache_thaw (pixman_glyph_cache_t *cache); -const void * pixman_glyph_cache_lookup (pixman_glyph_cache_t *cache, - void *font_key, - void *glyph_key); -const void * pixman_glyph_cache_insert (pixman_glyph_cache_t *cache, - void *font_key, - void *glyph_key, - int origin_x, - int origin_y, - pixman_image_t *glyph_image); -void pixman_glyph_cache_remove (pixman_glyph_cache_t *cache, - void *font_key, - void *glyph_key); -void pixman_glyph_get_extents (pixman_glyph_cache_t *cache, - int n_glyphs, - pixman_glyph_t *glyphs, - pixman_box32_t *extents); -pixman_format_code_t pixman_glyph_get_mask_format (pixman_glyph_cache_t *cache, - int n_glyphs, - const pixman_glyph_t *glyphs); -void pixman_composite_glyphs (pixman_op_t op, - pixman_image_t *src, - pixman_image_t *dest, - pixman_format_code_t mask_format, - int32_t src_x, - int32_t src_y, - int32_t mask_x, - int32_t mask_y, - int32_t dest_x, - int32_t dest_y, - int32_t width, - int32_t height, - pixman_glyph_cache_t *cache, - int n_glyphs, - const pixman_glyph_t *glyphs); -void pixman_composite_glyphs_no_mask (pixman_op_t op, - pixman_image_t *src, - pixman_image_t *dest, - int32_t src_x, - int32_t src_y, - int32_t dest_x, - int32_t dest_y, - pixman_glyph_cache_t *cache, - int n_glyphs, - const pixman_glyph_t *glyphs); - -/* - * Trapezoids - */ -typedef struct pixman_edge pixman_edge_t; -typedef struct pixman_trapezoid pixman_trapezoid_t; -typedef struct pixman_trap pixman_trap_t; -typedef struct pixman_span_fix pixman_span_fix_t; -typedef struct pixman_triangle pixman_triangle_t; - -/* - * An edge structure. This represents a single polygon edge - * and can be quickly stepped across small or large gaps in the - * sample grid - */ -struct pixman_edge -{ - pixman_fixed_t x; - pixman_fixed_t e; - pixman_fixed_t stepx; - pixman_fixed_t signdx; - pixman_fixed_t dy; - pixman_fixed_t dx; - - pixman_fixed_t stepx_small; - pixman_fixed_t stepx_big; - pixman_fixed_t dx_small; - pixman_fixed_t dx_big; -}; - -struct pixman_trapezoid -{ - pixman_fixed_t top, bottom; - pixman_line_fixed_t left, right; -}; - -struct pixman_triangle -{ - pixman_point_fixed_t p1, p2, p3; -}; - -/* whether 't' is a well defined not obviously empty trapezoid */ -#define pixman_trapezoid_valid(t) \ - ((t)->left.p1.y != (t)->left.p2.y && \ - (t)->right.p1.y != (t)->right.p2.y && \ - ((t)->bottom > (t)->top)) - -struct pixman_span_fix -{ - pixman_fixed_t l, r, y; -}; - -struct pixman_trap -{ - pixman_span_fix_t top, bot; -}; - -pixman_fixed_t pixman_sample_ceil_y (pixman_fixed_t y, - int bpp); -pixman_fixed_t pixman_sample_floor_y (pixman_fixed_t y, - int bpp); -void pixman_edge_step (pixman_edge_t *e, - int n); -void pixman_edge_init (pixman_edge_t *e, - int bpp, - pixman_fixed_t y_start, - pixman_fixed_t x_top, - pixman_fixed_t y_top, - pixman_fixed_t x_bot, - pixman_fixed_t y_bot); -void pixman_line_fixed_edge_init (pixman_edge_t *e, - int bpp, - pixman_fixed_t y, - const pixman_line_fixed_t *line, - int x_off, - int y_off); -void pixman_rasterize_edges (pixman_image_t *image, - pixman_edge_t *l, - pixman_edge_t *r, - pixman_fixed_t t, - pixman_fixed_t b); -void pixman_add_traps (pixman_image_t *image, - int16_t x_off, - int16_t y_off, - int ntrap, - const pixman_trap_t *traps); -void pixman_add_trapezoids (pixman_image_t *image, - int16_t x_off, - int y_off, - int ntraps, - const pixman_trapezoid_t *traps); -void pixman_rasterize_trapezoid (pixman_image_t *image, - const pixman_trapezoid_t *trap, - int x_off, - int y_off); -void pixman_composite_trapezoids (pixman_op_t op, - pixman_image_t * src, - pixman_image_t * dst, - pixman_format_code_t mask_format, - int x_src, - int y_src, - int x_dst, - int y_dst, - int n_traps, - const pixman_trapezoid_t * traps); -void pixman_composite_triangles (pixman_op_t op, - pixman_image_t * src, - pixman_image_t * dst, - pixman_format_code_t mask_format, - int x_src, - int y_src, - int x_dst, - int y_dst, - int n_tris, - const pixman_triangle_t * tris); -void pixman_add_triangles (pixman_image_t *image, - int32_t x_off, - int32_t y_off, - int n_tris, - const pixman_triangle_t *tris); - -PIXMAN_END_DECLS - -#endif /* PIXMAN_H__ */ diff --git a/source/libs/pixman/pixman-src/pixman/solaris-hwcap.mapfile b/source/libs/pixman/pixman-src/pixman/solaris-hwcap.mapfile deleted file mode 100644 index 87efce1e34fa18767823dac72e7215c8707f2850..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman-src/pixman/solaris-hwcap.mapfile +++ /dev/null @@ -1,30 +0,0 @@ -############################################################################### -# -# Copyright 2009, Oracle and/or its affiliates. All rights reserved. -# -# Permission is hereby granted, free of charge, to any person obtaining a -# copy of this software and associated documentation files (the "Software"), -# to deal in the Software without restriction, including without limitation -# the rights to use, copy, modify, merge, publish, distribute, sublicense, -# and/or sell copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice (including the next -# paragraph) shall be included in all copies or substantial portions of the -# Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -# DEALINGS IN THE SOFTWARE. -# -############################################################################### -# -# Override the linker's detection of CMOV/MMX/SSE instructions so this -# library isn't flagged as only usable on CPU's with those ISA's, since it -# checks at runtime for availability before calling them - -hwcap_1 = V0x0 FPU OVERRIDE; diff --git a/source/libs/pixman/pixman.test b/source/libs/pixman/pixman.test deleted file mode 100644 index 6b75a1c74f44882c8a2e540b936dcb9c5e21e097..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixman.test +++ /dev/null @@ -1,7 +0,0 @@ -#! /bin/sh - -# Copyright (C) 2013 Peter Breitenlohner <tex-live@tug.org> -# You may freely use, modify and/or distribute this file. - -./pixtest || exit 1 - diff --git a/source/libs/pixman/pixtest.c b/source/libs/pixman/pixtest.c deleted file mode 100644 index 8d501d24c00f87f1585408c24ab56eceeabdb85e..0000000000000000000000000000000000000000 --- a/source/libs/pixman/pixtest.c +++ /dev/null @@ -1,15 +0,0 @@ -/* pixtest.c: Basic test for libpixman - * - * Copyright (C) 2013 Peter Breitenlohner <tex-live@tug.org> - * You may freely use, modify and/or distribute this file. - */ - -#include <stdio.h> -#include <pixman.h> - -int main (int argc, char **argv) -{ - printf ("%s: Compiled with pixman version %s; using %s\n", - argv[0], PIXMAN_VERSION_STRING, pixman_version_string ()); - return 0; -} diff --git a/source/libs/pixman/sources.am b/source/libs/pixman/sources.am deleted file mode 100644 index 49b9505b6fc6481c599a2c23fca18a48af892f69..0000000000000000000000000000000000000000 --- a/source/libs/pixman/sources.am +++ /dev/null @@ -1,40 +0,0 @@ -libpixman_sources = \ - @PIXMAN_TREE@/pixman/pixman.c \ - @PIXMAN_TREE@/pixman/pixman-access.c \ - @PIXMAN_TREE@/pixman/pixman-access-accessors.c \ - @PIXMAN_TREE@/pixman/pixman-bits-image.c \ - @PIXMAN_TREE@/pixman/pixman-combine32.c \ - @PIXMAN_TREE@/pixman/pixman-combine-float.c \ - @PIXMAN_TREE@/pixman/pixman-conical-gradient.c \ - @PIXMAN_TREE@/pixman/pixman-x86.c \ - @PIXMAN_TREE@/pixman/pixman-mips.c \ - @PIXMAN_TREE@/pixman/pixman-arm.c \ - @PIXMAN_TREE@/pixman/pixman-ppc.c \ - @PIXMAN_TREE@/pixman/pixman-edge.c \ - @PIXMAN_TREE@/pixman/pixman-edge-accessors.c \ - @PIXMAN_TREE@/pixman/pixman-fast-path.c \ - @PIXMAN_TREE@/pixman/pixman-filter.c \ - @PIXMAN_TREE@/pixman/pixman-glyph.c \ - @PIXMAN_TREE@/pixman/pixman-general.c \ - @PIXMAN_TREE@/pixman/pixman-gradient-walker.c \ - @PIXMAN_TREE@/pixman/pixman-image.c \ - @PIXMAN_TREE@/pixman/pixman-implementation.c \ - @PIXMAN_TREE@/pixman/pixman-linear-gradient.c \ - @PIXMAN_TREE@/pixman/pixman-matrix.c \ - @PIXMAN_TREE@/pixman/pixman-noop.c \ - @PIXMAN_TREE@/pixman/pixman-radial-gradient.c \ - @PIXMAN_TREE@/pixman/pixman-region16.c \ - @PIXMAN_TREE@/pixman/pixman-region32.c \ - @PIXMAN_TREE@/pixman/pixman-solid-fill.c \ - @PIXMAN_TREE@/pixman/pixman-timer.c \ - @PIXMAN_TREE@/pixman/pixman-trap.c \ - @PIXMAN_TREE@/pixman/pixman-utils.c - -libpixman_headers = \ - @PIXMAN_TREE@/pixman/pixman.h \ - @PIXMAN_TREE@/pixman/pixman-accessor.h \ - @PIXMAN_TREE@/pixman/pixman-combine32.h \ - @PIXMAN_TREE@/pixman/pixman-compiler.h \ - @PIXMAN_TREE@/pixman/pixman-edge-imp.h \ - @PIXMAN_TREE@/pixman/pixman-inlines.h \ - @PIXMAN_TREE@/pixman/pixman-private.h diff --git a/source/libs/pixman/version.ac b/source/libs/pixman/version.ac deleted file mode 100644 index 149bb50d120c3f58ff8c2da62e6f99eada471a6d..0000000000000000000000000000000000000000 --- a/source/libs/pixman/version.ac +++ /dev/null @@ -1,11 +0,0 @@ -dnl -dnl Copyright (C) 2012-2014 Peter Breitenlohner <tex-live@tug.org> -dnl -dnl This file is free software; the copyright holder -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. -dnl -dnl -------------------------------------------------------- -dnl -dnl m4-include this file to define the current pixman version -m4_define([pixman_version], [0.34.0]) diff --git a/source/libs/poppler/Makefile.in b/source/libs/poppler/Makefile.in index bf99ea5f586b27261f62b11f01d808f41cd11aff..9132e2cb493812b11db4fb032775ccfe907f4513 100644 --- a/source/libs/poppler/Makefile.in +++ b/source/libs/poppler/Makefile.in @@ -279,11 +279,11 @@ am__DIST_COMMON = $(srcdir)/../../am/dist_hook.am \ $(top_srcdir)/../../build-aux/install-sh \ $(top_srcdir)/../../build-aux/missing \ $(top_srcdir)/poppler-src/poppler/poppler-config.h.in \ - ../../build-aux/compile ../../build-aux/config.guess \ - ../../build-aux/config.sub ../../build-aux/depcomp \ - ../../build-aux/install-sh ../../build-aux/ltmain.sh \ - ../../build-aux/missing ../../build-aux/texinfo.tex \ - ../../build-aux/ylwrap ChangeLog + ../../build-aux/ar-lib ../../build-aux/compile \ + ../../build-aux/config.guess ../../build-aux/config.sub \ + ../../build-aux/depcomp ../../build-aux/install-sh \ + ../../build-aux/ltmain.sh ../../build-aux/missing \ + ../../build-aux/texinfo.tex ../../build-aux/ylwrap ChangeLog DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) diff --git a/source/libs/zlib/Makefile.in b/source/libs/zlib/Makefile.in index 60c4caec1749ed5d4afb7c26848a8588500a15dc..0e5643efb74af3442a5d096c20ebea64c5db3c04 100644 --- a/source/libs/zlib/Makefile.in +++ b/source/libs/zlib/Makefile.in @@ -416,11 +416,12 @@ am__DIST_COMMON = $(srcdir)/../../am/dist_hook.am \ $(top_srcdir)/../../build-aux/install-sh \ $(top_srcdir)/../../build-aux/missing \ $(top_srcdir)/../../build-aux/test-driver \ - ../../build-aux/compile ../../build-aux/config.guess \ - ../../build-aux/config.sub ../../build-aux/depcomp \ - ../../build-aux/install-sh ../../build-aux/ltmain.sh \ - ../../build-aux/missing ../../build-aux/texinfo.tex \ - ../../build-aux/ylwrap ChangeLog README + ../../build-aux/ar-lib ../../build-aux/compile \ + ../../build-aux/config.guess ../../build-aux/config.sub \ + ../../build-aux/depcomp ../../build-aux/install-sh \ + ../../build-aux/ltmain.sh ../../build-aux/missing \ + ../../build-aux/texinfo.tex ../../build-aux/ylwrap ChangeLog \ + README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) diff --git a/source/libs/zziplib/Makefile.in b/source/libs/zziplib/Makefile.in index cf24c97e0c6fee11ec8e154c12c2f67081fadf60..2c95b9e90c8f7d0d943d5391cba8ea286d29ddbe 100644 --- a/source/libs/zziplib/Makefile.in +++ b/source/libs/zziplib/Makefile.in @@ -419,11 +419,12 @@ am__DIST_COMMON = $(srcdir)/../../am/dist_hook.am \ $(top_srcdir)/../../build-aux/install-sh \ $(top_srcdir)/../../build-aux/missing \ $(top_srcdir)/../../build-aux/test-driver \ - ../../build-aux/compile ../../build-aux/config.guess \ - ../../build-aux/config.sub ../../build-aux/depcomp \ - ../../build-aux/install-sh ../../build-aux/ltmain.sh \ - ../../build-aux/missing ../../build-aux/texinfo.tex \ - ../../build-aux/ylwrap ChangeLog README + ../../build-aux/ar-lib ../../build-aux/compile \ + ../../build-aux/config.guess ../../build-aux/config.sub \ + ../../build-aux/depcomp ../../build-aux/install-sh \ + ../../build-aux/ltmain.sh ../../build-aux/missing \ + ../../build-aux/texinfo.tex ../../build-aux/ylwrap ChangeLog \ + README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) diff --git a/source/m4/ChangeLog b/source/m4/ChangeLog index 2dd0e21e50c0ce36f5b06983accac7cb3b147d1a..d8e2d2d11a844fb67211b91f29623792678f6ea5 100644 --- a/source/m4/ChangeLog +++ b/source/m4/ChangeLog @@ -1,3 +1,12 @@ +2017-02-17 Karl Berry <karl@freefriends.org> + + * kpse-setup.m4 (_KPSE_RECURSE): do not add a package to + CONF_SUBDIRS if --disable-PKG was given. Thus, the directory for a + disabled package will no longer be descended into at all, as if it + were nonexistent. This way, if a package's configure causes + problems on some systems (like dvisvgm v2's new requirement for + C++11), --disable-PKG can be given and work can go on. + 2016-03-07 Karl Berry <karl@tug.org> * kpse-pkgs (KPSE_UTILS_PKGS): add autosp. @@ -440,3 +449,5 @@ 2009-08-17 Peter Breitenlohner <peb@mppmu.mpg.de> * kpse-warnings.m4: Implement Objective C compiler warnings. + +(This file public domain.) diff --git a/source/m4/README b/source/m4/README index 52e429face6572da0606e3ecafb97baf4e7009df..f11f697a2f27b4b269c7e7228b614207113a6dca 100644 --- a/source/m4/README +++ b/source/m4/README @@ -1,8 +1,10 @@ -Copyright (C) 2009-2012 Peter Breitenlohner <tex-live@tug.org> +$Id: README 43261 2017-02-17 22:37:44Z karl $ +Copyright 2009-2017 Karl Berry <tex-live@tug.org> +Copyright 2009-2012 Peter Breitenlohner <tex-live@tug.org> You may freely use, modify and/or distribute this file. This directory is the central repository for Autoconf macros needed to build -the TeX Live (TL) tree. +the TeX Live (TL) tree. They are incorporated into the configure scripts. (1) Public macros such as libtool.m4 used to build the libraries and programs in the TL subdirectories libs/*/, utils/*/, and texk/*/ that are @@ -25,7 +27,9 @@ owned by the TL tree. kpse-pkgs.m4: defines lists of subdirectories libs/Lib/, utils/Util/, and tex/Prog/ with libraries and programs that can be built as part of the TL tree. + kpse-setup.m4: macros that walk through these lists to provide configure options. They depend on configure fragments */*/ac/withenable.ac defining the dependencies between these libraries and programs. +See also the sibling top-level am/ directory. diff --git a/source/m4/kpse-setup.m4 b/source/m4/kpse-setup.m4 index 192a10b598c754165ed2c4d4c540a8b5aa0e0f18..cd47762b05999f2d80311b7b533734de3cdead89 100644 --- a/source/m4/kpse-setup.m4 +++ b/source/m4/kpse-setup.m4 @@ -1,5 +1,7 @@ +# $Id: kpse-setup.m4 43262 2017-02-17 22:40:41Z karl $ (m4/kpse-setup.m4) # Private macros for the TeX Live (TL) tree. -# Copyright (C) 2009-2015 Peter Breitenlohner <tex-live@tug.org> +# Copyright 2017 Karl Berry <tex-live@tug.org> +# Copyright 2009-2015 Peter Breitenlohner <tex-live@tug.org> # # This file is free software; the copyright holder # gives unlimited permission to copy and/or distribute it, @@ -8,12 +10,13 @@ # KPSE_SETUP(TOP-LEVEL) # --------------------- # Initialize path prefix kpse_TL to top-level TeX Live (TL) directory. -# Sinclude all withenable.ac files providing: -# configure options --with-system-LIB, --with-LIB-includes, and --with-LIB-libdir -# for libraries -# configure option --disable-PKG or --enable-PKG for programs -# additional program specific configure options (if any) -# library dependencies for programs and libraries +# Sinclude all pkgdir/ac/withenable.ac files, which are supposed to provide: +# configure options for libraries: +# --with-system-LIB --with-LIB-includes --with-LIB-libdir +# configure options for programs: +# --disable-PROG --enable-PROG +# additional package-specific configure options, if any +# library dependencies for programs and libraries, if any AC_DEFUN([KPSE_SETUP], [dnl AC_REQUIRE([AC_CANONICAL_HOST])[]dnl AC_REQUIRE([_KPSE_MSG_WARN_PREPARE])[]dnl @@ -262,25 +265,24 @@ m4_popdef([Kpse_add])[]dnl # _KPSE_RECURSE(LIST, TEXT, COND, [PREFIX]) # ----------------------------------------- # Internal subroutine. Determine which of the libraries or programs in -# kpse_LIST_pkgs to build, and set output variables MAKE_SUBDIRS and -# CONF_SUBDIRS. Cause 'make dist', 'configure -hr', and 'autoreconf' -# to recurse into all existing ones. +# kpse_LIST_pkgs to build: if a package's source directory contains a +# configure script, and COND is true, then add to the output variables +# MAKE_SUBDIRS and CONF_SUBDIRS. Thus, if a package directory does not +# exist at all, or if the package has been disabled, it will be ignored. +# m4_define([_KPSE_RECURSE], [dnl AC_MSG_CHECKING([for $2 to build]) -MAKE_SUBDIRS= CONF_SUBDIRS= +MAKE_SUBDIRS= KPSE_FOR_PKGS([$1], [dnl m4_ifdef([have_]Kpse_pkg, [dnl -if test -x $srcdir/$4Kpse_Pkg/configure; then - $3 && Kpse_add([MAKE_SUBDIRS]) +if test -x $srcdir/$4Kpse_Pkg/configure && $3; then Kpse_add([CONF_SUBDIRS]) - if false; then - AC_CONFIG_SUBDIRS($4Kpse_Pkg) - fi + Kpse_add([MAKE_SUBDIRS]) fi ])[]dnl m4_ifdef ]) -AC_SUBST([MAKE_SUBDIRS])[]dnl AC_SUBST([CONF_SUBDIRS])[]dnl +AC_SUBST([MAKE_SUBDIRS])[]dnl AC_MSG_RESULT([$MAKE_SUBDIRS])[]dnl ]) # _KPSE_RECURSE diff --git a/source/texk/ChangeLog b/source/texk/ChangeLog index b2ba4a4ed497fb1872346ca21060aecf0ea01cf6..c1a388747d5e3c8a9c5589182f4c4e626f53f629 100644 --- a/source/texk/ChangeLog +++ b/source/texk/ChangeLog @@ -1,3 +1,7 @@ +2017-02-16 Karl Berry <karl@freefriends.org> + + * configure.ac (AC_INIT): tex-live@tug.org instead of peb. + 2016-01-16 Karl Berry <karl@tug.org> (web2c/Makefile): do not try to make the nonexistent subtexk target. @@ -1097,3 +1101,5 @@ Thu Sep 30 14:27:17 1993 Karl Berry (karl@cs.umb.edu) * Makefile.in (*install*): Only do program directories. (most targets): Add `else true' for stupid sh's. * README: Update appropriately. + +(This ChangeLog file public domain.) diff --git a/source/texk/Makefile.in b/source/texk/Makefile.in index 0f3a53cf602b2d5acb0a3bad0d0fb22fba87bba4..f42c6f9d0cad57a9f76a5d7dfb350741ed523c7e 100644 --- a/source/texk/Makefile.in +++ b/source/texk/Makefile.in @@ -89,8 +89,7 @@ build_triplet = @build@ host_triplet = @host@ subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/../m4/kpse-cairo-flags.m4 \ - $(top_srcdir)/../m4/kpse-common.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/../m4/kpse-common.m4 \ $(top_srcdir)/../m4/kpse-cxx-hack.m4 \ $(top_srcdir)/../m4/kpse-gmp-flags.m4 \ $(top_srcdir)/../m4/kpse-kpathsea-flags.m4 \ @@ -99,7 +98,6 @@ am__aclocal_m4_deps = $(top_srcdir)/../m4/kpse-cairo-flags.m4 \ $(top_srcdir)/../m4/kpse-mktex.m4 \ $(top_srcdir)/../m4/kpse-mpfr-flags.m4 \ $(top_srcdir)/../m4/kpse-options.m4 \ - $(top_srcdir)/../m4/kpse-pixman-flags.m4 \ $(top_srcdir)/../m4/kpse-pkgs.m4 \ $(top_srcdir)/../m4/kpse-poppler-flags.m4 \ $(top_srcdir)/../m4/kpse-setup.m4 \ @@ -117,8 +115,6 @@ am__aclocal_m4_deps = $(top_srcdir)/../m4/kpse-cairo-flags.m4 \ $(top_srcdir)/../libs/poppler/ac/withenable.ac \ $(top_srcdir)/../libs/mpfr/ac/withenable.ac \ $(top_srcdir)/../libs/gmp/ac/withenable.ac \ - $(top_srcdir)/../libs/cairo/ac/withenable.ac \ - $(top_srcdir)/../libs/pixman/ac/withenable.ac \ $(top_srcdir)/../libs/libpng/ac/withenable.ac \ $(top_srcdir)/../libs/luajit/ac/withenable.ac \ $(top_srcdir)/../libs/lua52/ac/withenable.ac \ @@ -196,11 +192,12 @@ am__DIST_COMMON = $(srcdir)/../am/dist_hook.am \ $(top_srcdir)/../build-aux/config.guess \ $(top_srcdir)/../build-aux/config.sub \ $(top_srcdir)/../build-aux/install-sh \ - $(top_srcdir)/../build-aux/missing ../build-aux/compile \ - ../build-aux/config.guess ../build-aux/config.sub \ - ../build-aux/depcomp ../build-aux/install-sh \ - ../build-aux/ltmain.sh ../build-aux/missing \ - ../build-aux/texinfo.tex ../build-aux/ylwrap ChangeLog README + $(top_srcdir)/../build-aux/missing ../build-aux/ar-lib \ + ../build-aux/compile ../build-aux/config.guess \ + ../build-aux/config.sub ../build-aux/depcomp \ + ../build-aux/install-sh ../build-aux/ltmain.sh \ + ../build-aux/missing ../build-aux/texinfo.tex \ + ../build-aux/ylwrap ChangeLog README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) @@ -334,7 +331,6 @@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ -subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ @@ -351,11 +347,18 @@ NEVER_NAMES_LT = -o -name .libs -o -name '*.lo' recurse_this = texk/ recurse_top = ../ -# We must configure all subdirs since 'make dist' needs the Makefile. -# For those not required for the current set of configure options +# $Id: recurse.am 43261 2017-02-17 22:37:44Z karl $ +# +# Requires $(recurse_this) and $(recurse_top). +# Uses CONF_SUBDIRS and MAKE_SUBDIRS (set by kpse-setup.m4). +# +# For subdirs not required for the current set of configure options # we append '--disable-build' so they can skip tests that would # fail because, e.g., some required libraries were not built. +# (By manually testing $enable_build in configure, e.g., dvisvgm/configure.) +# # Code inspired by automake's way to handle recursive targets. +# cf_silent = $(cf_silent_@AM_V@) cf_silent_ = $(cf_silent_@AM_DEFAULT_V@) cf_silent_0 = --silent diff --git a/source/texk/README b/source/texk/README index 7c88c8cdb487fb8172b4e5a0af0cec2d3cd23a6c..0b65d0fbe3788e7cc586c17e0afdf01b2ea2f089 100644 --- a/source/texk/README +++ b/source/texk/README @@ -1,4 +1,4 @@ -$Id: README 43102 2017-01-31 18:37:40Z karl $ +$Id: README 43293 2017-02-21 23:54:15Z karl $ Copyright 2006-2017 TeX Users Group. You may freely use, modify and/or distribute this file. @@ -58,7 +58,7 @@ dvipos - ? dvipsk - maintained here, by us -dvisvgm 2.1 - checked 31jan17 +dvisvgm 2.1.3 - checked 21feb17 http://dvisvgm.bplaced.net/Downloads gregorio 4.2.0 - checked 25sep16 diff --git a/source/texk/aclocal.m4 b/source/texk/aclocal.m4 index 4415289d78cc49af68e39e5d25ba3298a5ac6650..aed27c46ff0b2d5593740bbd7e752acaf7529a91 100644 --- a/source/texk/aclocal.m4 +++ b/source/texk/aclocal.m4 @@ -1186,7 +1186,6 @@ AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR -m4_include([../m4/kpse-cairo-flags.m4]) m4_include([../m4/kpse-common.m4]) m4_include([../m4/kpse-cxx-hack.m4]) m4_include([../m4/kpse-gmp-flags.m4]) @@ -1196,7 +1195,6 @@ m4_include([../m4/kpse-lt-hack.m4]) m4_include([../m4/kpse-mktex.m4]) m4_include([../m4/kpse-mpfr-flags.m4]) m4_include([../m4/kpse-options.m4]) -m4_include([../m4/kpse-pixman-flags.m4]) m4_include([../m4/kpse-pkgs.m4]) m4_include([../m4/kpse-poppler-flags.m4]) m4_include([../m4/kpse-setup.m4]) diff --git a/source/texk/configure b/source/texk/configure index 933f547f64b8cf896fab10187b9db5815ad09011..bbbaa92674b445df3ece7f46b10dd22a35e24129 100755 --- a/source/texk/configure +++ b/source/texk/configure @@ -2,7 +2,7 @@ # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for TeX Live texk 2017/dev. # -# Report bugs to <peb@mppmu.mpg.de>. +# Report bugs to <tex-live@tug.org>. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -265,7 +265,7 @@ fi $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else - $as_echo "$0: Please tell bug-autoconf@gnu.org and peb@mppmu.mpg.de + $as_echo "$0: Please tell bug-autoconf@gnu.org and tex-live@tug.org $0: about your system, including any error possibly output $0: before this message. Then install a modern shell, or $0: manually run the script under such a shell if you do @@ -581,18 +581,16 @@ PACKAGE_NAME='TeX Live texk' PACKAGE_TARNAME='tex-live-texk' PACKAGE_VERSION='2017/dev' PACKAGE_STRING='TeX Live texk 2017/dev' -PACKAGE_BUGREPORT='peb@mppmu.mpg.de' +PACKAGE_BUGREPORT='tex-live@tug.org' PACKAGE_URL='' ac_unique_file="../build-aux/missing" -enable_option_checking=no ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS -CONF_SUBDIRS MAKE_SUBDIRS -subdirs +CONF_SUBDIRS WARNING_CFLAGS MAINT MAINTAINER_MODE_FALSE @@ -751,8 +749,6 @@ with_mpfr_libdir with_system_gmp with_gmp_includes with_gmp_libdir -with_system_cairo -with_system_pixman with_system_libpng with_system_zlib with_zlib_includes @@ -778,8 +774,7 @@ CFLAGS LDFLAGS LIBS CPPFLAGS' -ac_subdirs_all='web2c -texlive' + # Initialize some variables set by options. ac_init_help= @@ -1491,10 +1486,6 @@ Optional Packages: --with-system-gmp use installed gmp headers and library --with-gmp-includes=DIR gmp headers installed in DIR --with-gmp-libdir=DIR gmp library installed in DIR - --with-system-cairo use installed cairo headers and library (requires - pkg-config) - --with-system-pixman use installed pixman headers and library (requires - pkg-config) --with-system-libpng use installed libpng headers and library (requires pkg-config) --with-system-zlib use installed zlib headers and library @@ -1516,7 +1507,7 @@ Some influential environment variables: Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. -Report bugs to <peb@mppmu.mpg.de>. +Report bugs to <tex-live@tug.org>. _ACEOF ac_status=$? fi @@ -3384,7 +3375,6 @@ esac test "x$enable_web2c:$enable_luatex" = xyes:yes && { need_poppler=yes need_mpfr=yes - need_cairo=yes need_libpng=yes need_zziplib=yes need_lua52=yes @@ -3403,7 +3393,6 @@ esac test "x$enable_web2c:$enable_luajittex" = xyes:yes && { need_poppler=yes need_mpfr=yes - need_cairo=yes need_libpng=yes need_zziplib=yes need_luajit=yes @@ -3770,60 +3759,6 @@ $as_echo "$as_me: Assuming installed \`gmp' headers and library" >&6;} ac_configure_args="$ac_configure_args '--with-system-gmp=$with_system_gmp'" fi -## libs/cairo/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/cairo/ -## configure options and TL libraries required for cairo - -# Check whether --with-system-cairo was given. -if test "${with_system_cairo+set}" = set; then : - withval=$with_system_cairo; -fi -if test "x$with_system_cairo" = x; then - if test -f $srcdir/../libs/cairo/configure; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Assuming \`cairo' headers and library from TL tree" >&5 -$as_echo "$as_me: Assuming \`cairo' headers and library from TL tree" >&6;} - with_system_cairo=no - else - { $as_echo "$as_me:${as_lineno-$LINENO}: Assuming installed \`cairo' headers and library" >&5 -$as_echo "$as_me: Assuming installed \`cairo' headers and library" >&6;} - with_system_cairo=yes - fi - ac_configure_args="$ac_configure_args '--with-system-cairo=$with_system_cairo'" -fi -if test "x$with_system_cairo" = xyes; then - if test "x$with_system_pixman" = x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: -> installed \`pixman' headers and library" >&5 -$as_echo "$as_me: -> installed \`pixman' headers and library" >&6;} - with_system_pixman=yes - ac_configure_args="$ac_configure_args '--with-system-pixman'" - elif test "x$with_system_pixman" != xyes; then - as_fn_error $? "Sorry, \`--with-system-cairo' requires \`--with-system-pixman'" "$LINENO" 5 - fi -fi - -test "x$need_cairo" = xyes && { - need_pixman=yes -} - -## libs/pixman/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/pixman/ -## configure options and TL libraries required for pixman - -# Check whether --with-system-pixman was given. -if test "${with_system_pixman+set}" = set; then : - withval=$with_system_pixman; -fi -if test "x$with_system_pixman" = x; then - if test -f $srcdir/../libs/pixman/configure; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Assuming \`pixman' headers and library from TL tree" >&5 -$as_echo "$as_me: Assuming \`pixman' headers and library from TL tree" >&6;} - with_system_pixman=no - else - { $as_echo "$as_me:${as_lineno-$LINENO}: Assuming installed \`pixman' headers and library" >&5 -$as_echo "$as_me: Assuming installed \`pixman' headers and library" >&6;} - with_system_pixman=yes - fi - ac_configure_args="$ac_configure_args '--with-system-pixman=$with_system_pixman'" -fi - ## libs/libpng/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/libpng/ ## configure options and TL libraries required for libpng @@ -4843,27 +4778,17 @@ WARNING_CFLAGS=$kpse_cv_warning_cflags - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TeXk programs to build" >&5 $as_echo_n "checking for TeXk programs to build... " >&6; } -MAKE_SUBDIRS= CONF_SUBDIRS= -if test -x $srcdir/web2c/configure; then - test "x$enable_web2c" = xyes && MAKE_SUBDIRS="$MAKE_SUBDIRS web2c" +MAKE_SUBDIRS= +if test -x $srcdir/web2c/configure && test "x$enable_web2c" = xyes; then CONF_SUBDIRS="$CONF_SUBDIRS web2c" - if false; then - subdirs="$subdirs web2c" - - fi + MAKE_SUBDIRS="$MAKE_SUBDIRS web2c" fi -if test -x $srcdir/texlive/configure; then - test "x$enable_texlive" = xyes && MAKE_SUBDIRS="$MAKE_SUBDIRS texlive" +if test -x $srcdir/texlive/configure && test "x$enable_texlive" = xyes; then CONF_SUBDIRS="$CONF_SUBDIRS texlive" - if false; then - subdirs="$subdirs texlive" - - fi + MAKE_SUBDIRS="$MAKE_SUBDIRS texlive" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAKE_SUBDIRS" >&5 @@ -5493,7 +5418,7 @@ $config_files Configuration commands: $config_commands -Report bugs to <peb@mppmu.mpg.de>." +Report bugs to <tex-live@tug.org>." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 @@ -6174,151 +6099,6 @@ if test "$no_create" != yes; then # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi - -# -# CONFIG_SUBDIRS section. -# -if test "$no_recursion" != yes; then - - # Remove --cache-file, --srcdir, and --disable-option-checking arguments - # so they do not pile up. - ac_sub_configure_args= - ac_prev= - eval "set x $ac_configure_args" - shift - for ac_arg - do - if test -n "$ac_prev"; then - ac_prev= - continue - fi - case $ac_arg in - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \ - | --c=*) - ;; - --config-cache | -C) - ;; - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - ;; - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - ;; - --disable-option-checking) - ;; - *) - case $ac_arg in - *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - as_fn_append ac_sub_configure_args " '$ac_arg'" ;; - esac - done - - # Always prepend --prefix to ensure using the same prefix - # in subdir configurations. - ac_arg="--prefix=$prefix" - case $ac_arg in - *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - ac_sub_configure_args="'$ac_arg' $ac_sub_configure_args" - - # Pass --silent - if test "$silent" = yes; then - ac_sub_configure_args="--silent $ac_sub_configure_args" - fi - - # Always prepend --disable-option-checking to silence warnings, since - # different subdirs can have different --enable and --with options. - ac_sub_configure_args="--disable-option-checking $ac_sub_configure_args" - - ac_popdir=`pwd` - for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue - - # Do not complain, so a configure script can configure whichever - # parts of a large source tree are present. - test -d "$srcdir/$ac_dir" || continue - - ac_msg="=== configuring in $ac_dir (`pwd`/$ac_dir)" - $as_echo "$as_me:${as_lineno-$LINENO}: $ac_msg" >&5 - $as_echo "$ac_msg" >&6 - as_dir="$ac_dir"; as_fn_mkdir_p - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - cd "$ac_dir" - - # Check for guested configure; otherwise get Cygnus style configure. - if test -f "$ac_srcdir/configure.gnu"; then - ac_sub_configure=$ac_srcdir/configure.gnu - elif test -f "$ac_srcdir/configure"; then - ac_sub_configure=$ac_srcdir/configure - elif test -f "$ac_srcdir/configure.in"; then - # This should be Cygnus configure. - ac_sub_configure=$ac_aux_dir/configure - else - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: no configuration information is in $ac_dir" >&5 -$as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;} - ac_sub_configure= - fi - - # The recursion is here. - if test -n "$ac_sub_configure"; then - # Make the cache file name correct relative to the subdirectory. - case $cache_file in - [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;; - *) # Relative name. - ac_sub_cache_file=$ac_top_build_prefix$cache_file ;; - esac - - { $as_echo "$as_me:${as_lineno-$LINENO}: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5 -$as_echo "$as_me: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;} - # The eval makes quoting arguments work. - eval "\$SHELL \"\$ac_sub_configure\" $ac_sub_configure_args \ - --cache-file=\"\$ac_sub_cache_file\" --srcdir=\"\$ac_srcdir\"" || - as_fn_error $? "$ac_sub_configure failed for $ac_dir" "$LINENO" 5 - fi - - cd "$ac_popdir" - done -fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} diff --git a/source/texk/configure.ac b/source/texk/configure.ac index d2d02a940c15bbb6e8db374999856ed4cbda0a4c..78146bcd7071407b49c9d52e4c2946fa5243e20d 100644 --- a/source/texk/configure.ac +++ b/source/texk/configure.ac @@ -1,13 +1,15 @@ +# $Id: configure.ac 43246 2017-02-16 18:45:03Z karl $ dnl Process this file with autoconf to produce a configure script. dnl -dnl Copyright (C) 2009-2013 Peter Breitenlohner <tex-live@tug.org> +dnl Copyright 2017 Karl Berry <tex-live@tug.org> +dnl Copyright 2009-2013 Peter Breitenlohner <tex-live@tug.org> dnl dnl This file is free software; the copyright holder dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl m4_include([../version.ac])[] dnl define tex_live_version -AC_INIT([TeX Live texk], tex_live_version(), [peb@mppmu.mpg.de]) +AC_INIT([TeX Live texk], tex_live_version(), [tex-live@tug.org]) AC_PREREQ([2.65]) AC_CONFIG_SRCDIR([../build-aux/missing]) AC_CONFIG_AUX_DIR([../build-aux]) diff --git a/source/texk/kpathsea/ChangeLog b/source/texk/kpathsea/ChangeLog index 26b65c355db777b3b3483927b7b0824716b2e49c..a1647ec24e82ef6d8d2025070dd41f52cfe7ced8 100644 --- a/source/texk/kpathsea/ChangeLog +++ b/source/texk/kpathsea/ChangeLog @@ -1,3 +1,8 @@ +2017-03-02 Karl Berry <karl@tug.org> + + * texmf.cnf (TEXINPUTS.luajitlatex): add, same as lualatex. + Report from Ulrike Fischer, 2 Mar 2017 17:46:50. + 2016-12-28 Akira Kakuto <kakuto@fuk.kindai.ac.jp> * xgetcwd.c: Typo. Thanks Luigi. diff --git a/source/texk/kpathsea/Makefile.in b/source/texk/kpathsea/Makefile.in index b1d2f34ba35df39e94c2fbcbbc3feb661f884693..98bce4c18dfb010b5fdd1df93c9d35fe88104010 100644 --- a/source/texk/kpathsea/Makefile.in +++ b/source/texk/kpathsea/Makefile.in @@ -523,11 +523,12 @@ am__DIST_COMMON = $(srcdir)/../../am/rebuild.am $(srcdir)/Makefile.in \ $(top_srcdir)/../../build-aux/ltmain.sh \ $(top_srcdir)/../../build-aux/missing \ $(top_srcdir)/../../build-aux/test-driver \ - ../../build-aux/compile ../../build-aux/config.guess \ - ../../build-aux/config.sub ../../build-aux/depcomp \ - ../../build-aux/install-sh ../../build-aux/ltmain.sh \ - ../../build-aux/missing ../../build-aux/texinfo.tex \ - ../../build-aux/ylwrap AUTHORS ChangeLog NEWS README putenv.c + ../../build-aux/ar-lib ../../build-aux/compile \ + ../../build-aux/config.guess ../../build-aux/config.sub \ + ../../build-aux/depcomp ../../build-aux/install-sh \ + ../../build-aux/ltmain.sh ../../build-aux/missing \ + ../../build-aux/texinfo.tex ../../build-aux/ylwrap AUTHORS \ + ChangeLog NEWS README putenv.c DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) @@ -2329,9 +2330,13 @@ uninstall-local: rm -f "$(DESTDIR)$(web2cdir)/$$f"; \ else :; fi; \ done + +# $Id: bin_links.am 43248 2017-02-16 21:38:29Z karl $ +# am/bin_links.am: Makefile fragment for bindir links. .PHONY: install-bin-links uninstall-bin-links install-bin-links: +@WIN32_FALSE@ $(MKDIR_P) $(DESTDIR)$(bindir) @WIN32_FALSE@ @cd $(DESTDIR)$(bindir) && \ @WIN32_FALSE@ for s in $(bin_links); do \ @WIN32_FALSE@ link=`echo $$s | sed 's,.*:,,'`; \ diff --git a/source/texk/kpathsea/texmf.cnf b/source/texk/kpathsea/texmf.cnf index a51e41d000ab07eca3a35a563f41d528ceb469d5..aeb10efb88c2e14e91eaf276c76139a3296154f5 100644 --- a/source/texk/kpathsea/texmf.cnf +++ b/source/texk/kpathsea/texmf.cnf @@ -193,11 +193,12 @@ TEXINPUTS.pdfelatex = .;$TEXMF/tex/{latex,generic,}// TEXINPUTS.pdfetex = .;$TEXMF/tex/{plain,generic,}// % LuaTeX. -TEXINPUTS.lualatex = .;$TEXMF/tex/{lualatex,latex,luatex,generic,}// -TEXINPUTS.dvilualatex = .;$TEXMF/tex/{lualatex,latex,luatex,generic,}// TEXINPUTS.luatex = .;$TEXMF/tex/{luatex,plain,generic,}// TEXINPUTS.luajittex = .;$TEXMF/tex/{luatex,plain,generic,}// TEXINPUTS.dviluatex = .;$TEXMF/tex/{luatex,plain,generic,}// +TEXINPUTS.lualatex = .;$TEXMF/tex/{lualatex,latex,luatex,generic,}// +TEXINPUTS.luajitlatex = .;$TEXMF/tex/{lualatex,latex,luatex,generic,}// +TEXINPUTS.dvilualatex = .;$TEXMF/tex/{lualatex,latex,luatex,generic,}// % XeTeX. TEXINPUTS.xelatex = .;$TEXMF/tex/{xelatex,latex,xetex,generic,}// diff --git a/source/texk/texlive/Makefile.in b/source/texk/texlive/Makefile.in index d909c0db804293deabb6e4580b20dcda13b80077..a22bd32858702139816d13d86790bfaaca2a2e61 100644 --- a/source/texk/texlive/Makefile.in +++ b/source/texk/texlive/Makefile.in @@ -360,11 +360,11 @@ am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/../../build-aux/install-sh \ $(top_srcdir)/../../build-aux/missing \ $(top_srcdir)/../../build-aux/test-driver \ - ../../build-aux/compile ../../build-aux/config.guess \ - ../../build-aux/config.sub ../../build-aux/depcomp \ - ../../build-aux/install-sh ../../build-aux/ltmain.sh \ - ../../build-aux/missing ../../build-aux/texinfo.tex \ - ../../build-aux/ylwrap ChangeLog + ../../build-aux/ar-lib ../../build-aux/compile \ + ../../build-aux/config.guess ../../build-aux/config.sub \ + ../../build-aux/depcomp ../../build-aux/install-sh \ + ../../build-aux/ltmain.sh ../../build-aux/missing \ + ../../build-aux/texinfo.tex ../../build-aux/ylwrap ChangeLog DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) diff --git a/source/texk/texlive/linked_scripts/Makefile.am b/source/texk/texlive/linked_scripts/Makefile.am index 08ce6f8688884b05e01768b17d3f8df49b56cdec..1d6db0fa415be22e5892236abdd8b8f1bf618748 100644 --- a/source/texk/texlive/linked_scripts/Makefile.am +++ b/source/texk/texlive/linked_scripts/Makefile.am @@ -136,6 +136,7 @@ texmf_other_scripts = \ lilyglyphs/lily-rebuild-pdfs.py \ ltximg/ltximg.pl \ luaotfload/luaotfload-tool.lua \ + lwarp/lwarpmk.lua \ m-tx/m-tx.lua \ makedtx/makedtx.pl \ make4ht/make4ht \ @@ -162,6 +163,9 @@ texmf_other_scripts = \ pmx/pmx2pdf.lua \ pmxchords/pmxchords.lua \ pst2pdf/pst2pdf.pl \ + ptex-fontmaps/kanji-config-updmap-sys.sh \ + ptex-fontmaps/kanji-config-updmap.pl \ + ptex-fontmaps/kanji-fontmap-creator.pl \ ptex2pdf/ptex2pdf.lua \ purifyeps/purifyeps \ pygmentex/pygmentex.py \ diff --git a/source/texk/texlive/linked_scripts/Makefile.in b/source/texk/texlive/linked_scripts/Makefile.in index cf0464d427b7dc79682026df8c51a4cbc7fac63b..02e82040f0937d0e0d5c1efda09e7552a899b312 100644 --- a/source/texk/texlive/linked_scripts/Makefile.in +++ b/source/texk/texlive/linked_scripts/Makefile.in @@ -351,6 +351,7 @@ texmf_other_scripts = \ lilyglyphs/lily-rebuild-pdfs.py \ ltximg/ltximg.pl \ luaotfload/luaotfload-tool.lua \ + lwarp/lwarpmk.lua \ m-tx/m-tx.lua \ makedtx/makedtx.pl \ make4ht/make4ht \ @@ -377,6 +378,9 @@ texmf_other_scripts = \ pmx/pmx2pdf.lua \ pmxchords/pmxchords.lua \ pst2pdf/pst2pdf.pl \ + ptex-fontmaps/kanji-config-updmap-sys.sh \ + ptex-fontmaps/kanji-config-updmap.pl \ + ptex-fontmaps/kanji-fontmap-creator.pl \ ptex2pdf/ptex2pdf.lua \ purifyeps/purifyeps \ pygmentex/pygmentex.py \ diff --git a/source/texk/texlive/tl_scripts/Makefile.in b/source/texk/texlive/tl_scripts/Makefile.in index d3736463370b3d5b89e4a434077811cff7481065..107e94b63c67f1096e576875d7491e35d02d8b27 100644 --- a/source/texk/texlive/tl_scripts/Makefile.in +++ b/source/texk/texlive/tl_scripts/Makefile.in @@ -825,9 +825,13 @@ uninstall-links: install-data-hook: install-bin-links install-man1-links install-perl-links install-sh-links uninstall-hook: uninstall-bin-links uninstall-man1-links uninstall-links + +# $Id: bin_links.am 43248 2017-02-16 21:38:29Z karl $ +# am/bin_links.am: Makefile fragment for bindir links. .PHONY: install-bin-links uninstall-bin-links install-bin-links: +@WIN32_FALSE@ $(MKDIR_P) $(DESTDIR)$(bindir) @WIN32_FALSE@ @cd $(DESTDIR)$(bindir) && \ @WIN32_FALSE@ for s in $(bin_links); do \ @WIN32_FALSE@ link=`echo $$s | sed 's,.*:,,'`; \ diff --git a/source/texk/web2c/ChangeLog b/source/texk/web2c/ChangeLog index a8c401afe104f9562f005ce9762be6d5dd59a96a..b8c886fca1339532c43adf7d5daba34209bddd36 100644 --- a/source/texk/web2c/ChangeLog +++ b/source/texk/web2c/ChangeLog @@ -1,3 +1,7 @@ +2017-02-09 Akira Kakuto <kakuto@fuk.kindai.ac.jp> + + * Makefile.am: Sync with the LuaTeX upstream. + 2017-01-28 Karl Berry <karl@freefriends.org> * tex.ch (texarray), diff --git a/source/texk/web2c/Makefile.in b/source/texk/web2c/Makefile.in index bc317b2dca5ef12340795ce77346c4d22439229d..d2609d183c75f166914b6b70d099ae352261edd9 100644 --- a/source/texk/web2c/Makefile.in +++ b/source/texk/web2c/Makefile.in @@ -1114,7 +1114,6 @@ am__objects_33 = luatexdir/luajittex-luatex.$(OBJEXT) \ nodist_luajittex_OBJECTS = $(am__objects_33) luajittex_OBJECTS = $(nodist_luajittex_OBJECTS) am__DEPENDENCIES_6 = libmplibcore.a $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) libmputil.a \ @@ -1848,12 +1847,12 @@ am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/../../am/bin_links.am \ $(top_srcdir)/otps/Makefile.in \ $(top_srcdir)/otps/win32/Makefile.in \ $(top_srcdir)/synctexdir/synctex.pc.in \ - $(top_srcdir)/window/Makefile.in ../../build-aux/compile \ - ../../build-aux/config.guess ../../build-aux/config.sub \ - ../../build-aux/depcomp ../../build-aux/install-sh \ - ../../build-aux/ltmain.sh ../../build-aux/missing \ - ../../build-aux/texinfo.tex ../../build-aux/ylwrap AUTHORS \ - ChangeLog NEWS README + $(top_srcdir)/window/Makefile.in ../../build-aux/ar-lib \ + ../../build-aux/compile ../../build-aux/config.guess \ + ../../build-aux/config.sub ../../build-aux/depcomp \ + ../../build-aux/install-sh ../../build-aux/ltmain.sh \ + ../../build-aux/missing ../../build-aux/texinfo.tex \ + ../../build-aux/ylwrap AUTHORS ChangeLog NEWS README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) @@ -2829,11 +2828,10 @@ libmputil_a_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/mplibdir libmputil_a_SOURCES = mplibdir/avl.h mplibdir/avl.c mplibdir/decNumber.c mplibdir/decNumber.h \ mplibdir/decNumberLocal.h mplibdir/decContext.h mplibdir/decContext.c -libmplib_a_CPPFLAGS = $(MPFR_INCLUDES) $(GMP_INCLUDES) $(CAIRO_INCLUDES) $(PIXMAN_INCLUDES) \ +libmplibcore_a_CPPFLAGS = $(MPFR_INCLUDES) $(GMP_INCLUDES) $(LIBPNG_INCLUDES) $(ZLIB_INCLUDES) $(AM_CPPFLAGS) -I$(srcdir)/mplibdir +libmplibbackends_a_CPPFLAGS = $(MPFR_INCLUDES) $(GMP_INCLUDES) $(CAIRO_INCLUDES) $(PIXMAN_INCLUDES) \ $(LIBPNG_INCLUDES) $(ZLIB_INCLUDES) $(AM_CPPFLAGS) -I$(srcdir)/mplibdir -libmplibcore_a_CPPFLAGS = $(libmplib_a_CPPFLAGS) -libmplibbackends_a_CPPFLAGS = $(libmplib_a_CPPFLAGS) nodist_libmplibcore_a_SOURCES = tfmin.c $(mp_c_h) $(mpmath_c_h) $(mpmathbinary_c_h) $(mpmathdecimal_c_h) \ $(mpmathdouble_c_h) $(mpstrings_c_h) $(psout_c_h) @@ -3568,13 +3566,9 @@ luatex_CXXFLAGS = $(WARNING_CXXFLAGS) luajittex_CXXFLAGS = $(WARNING_CXXFLAGS) luatex_LDFLAGS = -export-dynamic luajittex_LDFLAGS = -export-dynamic $(LUAJIT_LDEXTRA) - -#luatex_postldadd = libmplib.a $(MPFR_LIBS) $(GMP_LIBS) $(CAIRO_LIBS) $(PIXMAN_LIBS) -#luatex_postldadd = libmplibcore.a libmplibbackends.a $(MPFR_LIBS) $(GMP_LIBS) $(CAIRO_LIBS) $(PIXMAN_LIBS) luatex_postldadd = libmplibcore.a $(MPFR_LIBS) $(GMP_LIBS) \ - $(CAIRO_LIBS) $(PIXMAN_LIBS) $(ZZIPLIB_LIBS) $(LIBPNG_LIBS) \ - $(ZLIB_LIBS) $(POPPLER_LIBS) $(LDADD) libmputil.a libunilib.a \ - libmd5.a $(lua_socketlibs) + $(ZZIPLIB_LIBS) $(LIBPNG_LIBS) $(ZLIB_LIBS) $(POPPLER_LIBS) \ + $(LDADD) libmputil.a libunilib.a libmd5.a $(lua_socketlibs) luatex_LDADD = libluatex.a libff.a libluamisc.a libluasocket.a libluaffi.a $(LUA_LIBS) $(luatex_postldadd) luajittex_LDADD = libluajittex.a libff.a libluajitmisc.a libluajitsocket.a $(LUAJIT_LIBS) $(luatex_postldadd) luatex_depend = $(proglib) $(KPATHSEA_DEPEND) $(LIBPNG_DEPEND) libmputil.a libmd5.a @@ -14893,7 +14887,7 @@ svgout-tangle: ctangle$(EXEEXT) mplibdir/svgout.w tangle-sh $(nodist_libmplibcore_a_SOURCES): $(svgout_c_h) $(pngout_c_h) -$(libmplibcore_a_OBJECTS): $(nodist_libmplibcore_a_SOURCES) $(KPATHSEA_DEPEND) $(CAIRO_DEPEND) $(MPFR_DEPEND) +$(libmplibcore_a_OBJECTS): $(nodist_libmplibcore_a_SOURCES) $(KPATHSEA_DEPEND) $(MPFR_DEPEND) $(libmplibbackends_a_OBJECTS): $(nodist_libmplibbackends_a_SOURCES) $(KPATHSEA_DEPEND) $(CAIRO_DEPEND) $(MPFR_DEPEND) $(etex_OBJECTS): $(etex_prereq) @@ -15182,16 +15176,6 @@ $(libluamisc_a_OBJECTS): $(libluamisc_a_DEPENDENCIES) $(libluajitmisc_a_OBJECTS): $(libluajitmisc_a_DEPENDENCIES) $(libff_a_OBJECTS): libunilib.a -#nodist_libluajittex_a_SOURCES = \ -# luajitstuff.c texluajitc.c \ -# $(dist_libluatex_sources) \ -# $(nodist_libluatex_sources) - -#$(libluatex_a_OBJECTS): libff.a libmplib.a libluamisc.a $(POPPLER_DEPEND) -#$(libluajittex_a_OBJECTS): libff.a libmplib.a libluajitmisc.a $(POPPLER_DEPEND) - -#$(libluatex_a_OBJECTS): libff.a libmplibcore.a libmplibbackends.a libluamisc.a $(POPPLER_DEPEND) -#$(libluajittex_a_OBJECTS): libff.a libmplibcore.a libmplibbackends.a libluajitmisc.a $(POPPLER_DEPEND) $(libluatex_a_OBJECTS): libff.a libmplibcore.a libluamisc.a $(POPPLER_DEPEND) $(libluajittex_a_OBJECTS): libff.a libmplibcore.a libluajitmisc.a $(POPPLER_DEPEND) @@ -15544,9 +15528,13 @@ $(libsynctex_la_OBJECTS): $(ZLIB_DEPEND) $(libsynctex_a_OBJECTS): $(ZLIB_DEPEND) synctexdir/synctex.log: synctex$(EXEEXT) libmd5/md5.log: md5main$(EXEEXT) + +# $Id: bin_links.am 43248 2017-02-16 21:38:29Z karl $ +# am/bin_links.am: Makefile fragment for bindir links. .PHONY: install-bin-links uninstall-bin-links install-bin-links: +@WIN32_FALSE@ $(MKDIR_P) $(DESTDIR)$(bindir) @WIN32_FALSE@ @cd $(DESTDIR)$(bindir) && \ @WIN32_FALSE@ for s in $(bin_links); do \ @WIN32_FALSE@ link=`echo $$s | sed 's,.*:,,'`; \ diff --git a/source/texk/web2c/ac/web2c.ac b/source/texk/web2c/ac/web2c.ac index bb9d559ed2066943c28eb42fd587c3acf5572991..7acbb825187a9ae315d14e39c9e82cbb2b643540 100644 --- a/source/texk/web2c/ac/web2c.ac +++ b/source/texk/web2c/ac/web2c.ac @@ -35,8 +35,8 @@ m4_define([kpse_tex_progs], [dnl [[euptex], [yes], [yes], [e-upTeX], [ptexenc]], [[aleph], [yes], [], [Aleph], []], [[pdftex], [yes], [yes], [pdfTeX], [xpdf libpng]], -[[luatex], [yes], [], [LuaTeX], [poppler mpfr cairo libpng zziplib lua52]], -[[luajittex], [yes], [], [LuaJITTeX], [poppler mpfr cairo libpng zziplib luajit]], +[[luatex], [yes], [], [LuaTeX], [poppler mpfr libpng zziplib lua52]], +[[luajittex], [yes], [], [LuaJITTeX], [poppler mpfr libpng zziplib luajit]], [[mp], [yes], [], [MetaPost], [mpfr cairo libpng]], [[pmp], [yes], [], [pMetaPost], [mpfr cairo libpng ptexenc]], [[upmp], [yes], [], [upMetaPost], [mpfr cairo libpng ptexenc]], diff --git a/source/texk/web2c/configure b/source/texk/web2c/configure index 7e278b7c096bffd45e789fad599a53e551c30232..959d346378f348afb6aa93f464a28b8b979e7d10 100755 --- a/source/texk/web2c/configure +++ b/source/texk/web2c/configure @@ -18758,7 +18758,6 @@ esac test "x$enable_web2c:$enable_luatex" = xyes:yes && { need_poppler=yes need_mpfr=yes - need_cairo=yes need_libpng=yes need_zziplib=yes need_lua52=yes @@ -18777,7 +18776,6 @@ esac test "x$enable_web2c:$enable_luajittex" = xyes:yes && { need_poppler=yes need_mpfr=yes - need_cairo=yes need_libpng=yes need_zziplib=yes need_luajit=yes diff --git a/source/texk/web2c/ctangleboot.cin b/source/texk/web2c/ctangleboot.cin index 42c4a71018e6bbbe1d5360adaebe36273e5e5bcb..83e0a3a59e3eaec7192bd73213d3bc8f65e01156 100644 --- a/source/texk/web2c/ctangleboot.cin +++ b/source/texk/web2c/ctangleboot.cin @@ -220,13 +220,14 @@ extern char change_file_name[]; extern int line[]; extern int change_line; #line 150 "cwebdir/common.h" +extern change_depth; extern boolean input_has_ended; extern boolean changing; extern boolean web_file_open; -#line 156 "cwebdir/common.h" +#line 157 "cwebdir/common.h" /*:10*//*11:*/ -#line 158 "cwebdir/common.h" +#line 159 "cwebdir/common.h" typedef unsigned short sixteen_bits; extern sixteen_bits section_count; @@ -235,14 +236,14 @@ extern boolean change_pending; extern boolean print_where; /*:11*//*12:*/ -#line 170 "cwebdir/common.h" +#line 171 "cwebdir/common.h" extern int argc; extern char**argv; extern boolean flags[]; /*:12*//*13:*/ -#line 182 "cwebdir/common.h" +#line 183 "cwebdir/common.h" extern FILE*C_file; extern FILE*tex_file; @@ -251,7 +252,7 @@ extern FILE*scn_file; extern FILE*active_file; /*:13*//*14:*/ -#line 191 "cwebdir/common.h" +#line 192 "cwebdir/common.h" #line 128 "cwebdir/ctangle.w" @@ -358,7 +359,7 @@ text_pointer cur_text; eight_bits next_control; /*:74*//*81:*/ -#line 1350 "cwebdir/ctangle.w" +#line 1353 "cwebdir/ctangle.w" extern sixteen_bits section_count; @@ -387,18 +388,18 @@ static void out_char(eight_bits); #line 650 "cwebdir/ctangle.w" /*:47*//*89:*/ -#line 1457 "cwebdir/ctangle.w" +#line 1460 "cwebdir/ctangle.w" #line 440 "cwebdir/ctang-w2c.ch" static void phase_one(void); -#line 1459 "cwebdir/ctangle.w" +#line 1462 "cwebdir/ctangle.w" /*:89*//*91:*/ -#line 1475 "cwebdir/ctangle.w" +#line 1478 "cwebdir/ctangle.w" #line 458 "cwebdir/ctang-w2c.ch" static void skip_limbo(void); -#line 1477 "cwebdir/ctangle.w" +#line 1480 "cwebdir/ctangle.w" /*:91*/ #line 70 "cwebdir/ctangle.w" @@ -919,15 +920,18 @@ print_where= 0; #line 1225 "cwebdir/ctangle.w" store_two_bytes(0150000); -if(changing)id_first= change_file_name; -else id_first= cur_file_name; +if(changing&&include_depth==change_depth){ +id_first= change_file_name; +store_two_bytes((sixteen_bits)change_line); +}else{ +id_first= cur_file_name; +store_two_bytes((sixteen_bits)cur_line); +} id_loc= id_first+strlen(id_first); -if(changing)store_two_bytes((sixteen_bits)change_line); -else store_two_bytes((sixteen_bits)cur_line); #line 408 "cwebdir/ctang-w2c.ch" {int a_l= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a_l/0400)+0200); app_repl(a_l%0400);} -#line 1234 "cwebdir/ctangle.w" +#line 1237 "cwebdir/ctangle.w" /*:76*/ #line 912 "cwebdir/ctangle.w" @@ -1230,22 +1234,25 @@ if(t==section_name){/*76:*/ #line 1225 "cwebdir/ctangle.w" store_two_bytes(0150000); -if(changing)id_first= change_file_name; -else id_first= cur_file_name; +if(changing&&include_depth==change_depth){ +id_first= change_file_name; +store_two_bytes((sixteen_bits)change_line); +}else{ +id_first= cur_file_name; +store_two_bytes((sixteen_bits)cur_line); +} id_loc= id_first+strlen(id_first); -if(changing)store_two_bytes((sixteen_bits)change_line); -else store_two_bytes((sixteen_bits)cur_line); #line 408 "cwebdir/ctang-w2c.ch" {int a_l= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a_l/0400)+0200); app_repl(a_l%0400);} -#line 1234 "cwebdir/ctangle.w" +#line 1237 "cwebdir/ctangle.w" /*:76*/ #line 1205 "cwebdir/ctangle.w" ;} while(1)switch(a= get_next()){ /*77:*/ -#line 1235 "cwebdir/ctangle.w" +#line 1238 "cwebdir/ctangle.w" case identifier:a= id_lookup(id_first,id_loc,0)-name_dir; app_repl((a/0400)+0200); @@ -1253,7 +1260,7 @@ app_repl(a%0400);break; case section_name:if(t!=section_name)goto done; else{ /*78:*/ -#line 1268 "cwebdir/ctangle.w" +#line 1271 "cwebdir/ctangle.w" { char*try_loc= loc; while(*try_loc==' '&&try_loc<limit)try_loc++; @@ -1266,7 +1273,7 @@ if(*try_loc=='=')err_print("! Missing `@ ' before a named section"); } /*:78*/ -#line 1241 "cwebdir/ctangle.w" +#line 1244 "cwebdir/ctangle.w" ; a= cur_section_name-name_dir; app_repl((a/0400)+0250); @@ -1275,18 +1282,21 @@ app_repl(a%0400); #line 1225 "cwebdir/ctangle.w" store_two_bytes(0150000); -if(changing)id_first= change_file_name; -else id_first= cur_file_name; +if(changing&&include_depth==change_depth){ +id_first= change_file_name; +store_two_bytes((sixteen_bits)change_line); +}else{ +id_first= cur_file_name; +store_two_bytes((sixteen_bits)cur_line); +} id_loc= id_first+strlen(id_first); -if(changing)store_two_bytes((sixteen_bits)change_line); -else store_two_bytes((sixteen_bits)cur_line); #line 408 "cwebdir/ctang-w2c.ch" {int a_l= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a_l/0400)+0200); app_repl(a_l%0400);} -#line 1234 "cwebdir/ctangle.w" +#line 1237 "cwebdir/ctangle.w" /*:76*/ -#line 1245 "cwebdir/ctangle.w" +#line 1248 "cwebdir/ctangle.w" ;break; } case output_defs_code:if(t!=section_name)err_print("! Misplaced @h"); @@ -1300,24 +1310,27 @@ app_repl(a%0400); #line 1225 "cwebdir/ctangle.w" store_two_bytes(0150000); -if(changing)id_first= change_file_name; -else id_first= cur_file_name; +if(changing&&include_depth==change_depth){ +id_first= change_file_name; +store_two_bytes((sixteen_bits)change_line); +}else{ +id_first= cur_file_name; +store_two_bytes((sixteen_bits)cur_line); +} id_loc= id_first+strlen(id_first); -if(changing)store_two_bytes((sixteen_bits)change_line); -else store_two_bytes((sixteen_bits)cur_line); #line 408 "cwebdir/ctang-w2c.ch" {int a_l= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a_l/0400)+0200); app_repl(a_l%0400);} -#line 1234 "cwebdir/ctangle.w" +#line 1237 "cwebdir/ctangle.w" /*:76*/ -#line 1254 "cwebdir/ctangle.w" +#line 1257 "cwebdir/ctangle.w" ; } break; case constant:case string: /*79:*/ -#line 1279 "cwebdir/ctangle.w" +#line 1282 "cwebdir/ctangle.w" app_repl(a); while(id_first<id_loc){ @@ -1331,11 +1344,11 @@ app_repl(*id_first++); app_repl(a);break; /*:79*/ -#line 1258 "cwebdir/ctangle.w" +#line 1261 "cwebdir/ctangle.w" ; case ord: /*80:*/ -#line 1295 "cwebdir/ctangle.w" +#line 1298 "cwebdir/ctangle.w" { int c= (eight_bits)*id_first; if(c=='\\'){ @@ -1363,14 +1376,14 @@ else if(xisxdigit(*(id_first+1))){ ++id_first; #line 417 "cwebdir/ctang-w2c.ch" c= toupper((unsigned char)*id_first)-'A'+10; -#line 1321 "cwebdir/ctangle.w" +#line 1324 "cwebdir/ctangle.w" } if(xisdigit(*(id_first+1)))c= 16*c+*(++id_first)-'0'; else if(xisxdigit(*(id_first+1))){ ++id_first; #line 422 "cwebdir/ctang-w2c.ch" c= 16*c+toupper((unsigned char)*id_first)-'A'+10; -#line 1326 "cwebdir/ctangle.w" +#line 1329 "cwebdir/ctangle.w" } break; case'\\':c= '\\';break; @@ -1390,7 +1403,7 @@ app_repl(constant); break; /*:80*/ -#line 1260 "cwebdir/ctangle.w" +#line 1263 "cwebdir/ctangle.w" ; case definition:case format_code:case begin_C:if(t!=section_name)goto done; else{ @@ -1413,12 +1426,12 @@ cur_text= text_ptr;(++text_ptr)->tok_start= tok_ptr; } /*:75*//*82:*/ -#line 1357 "cwebdir/ctangle.w" +#line 1360 "cwebdir/ctangle.w" #line 431 "cwebdir/ctang-w2c.ch" static void scan_section(void) -#line 1360 "cwebdir/ctangle.w" +#line 1363 "cwebdir/ctangle.w" { name_pointer p; text_pointer q; @@ -1430,7 +1443,7 @@ printf("*%d",section_count);update_terminal; next_control= 0; while(1){ /*83:*/ -#line 1396 "cwebdir/ctangle.w" +#line 1399 "cwebdir/ctangle.w" while(next_control<definition) @@ -1439,11 +1452,11 @@ loc-= 2;next_control= get_next(); } /*:83*/ -#line 1371 "cwebdir/ctangle.w" +#line 1374 "cwebdir/ctangle.w" ; if(next_control==definition){ /*84:*/ -#line 1403 "cwebdir/ctangle.w" +#line 1406 "cwebdir/ctangle.w" { while((next_control= get_next())=='\n'); if(next_control!=identifier){ @@ -1462,7 +1475,7 @@ cur_text->text_link= 0; } /*:84*/ -#line 1373 "cwebdir/ctangle.w" +#line 1376 "cwebdir/ctangle.w" continue; } @@ -1472,14 +1485,14 @@ p= name_dir;break; if(next_control==section_name){ p= cur_section_name; /*85:*/ -#line 1428 "cwebdir/ctangle.w" +#line 1431 "cwebdir/ctangle.w" while((next_control= get_next())=='+'); if(next_control!='='&&next_control!=eq_eq) continue; /*:85*/ -#line 1381 "cwebdir/ctangle.w" +#line 1384 "cwebdir/ctangle.w" ; break; } @@ -1487,20 +1500,20 @@ return; } no_where= print_where= 0; /*86:*/ -#line 1433 "cwebdir/ctangle.w" +#line 1436 "cwebdir/ctangle.w" /*87:*/ -#line 1438 "cwebdir/ctangle.w" +#line 1441 "cwebdir/ctangle.w" store_two_bytes((sixteen_bits)(0150000+section_count)); /*:87*/ -#line 1434 "cwebdir/ctangle.w" +#line 1437 "cwebdir/ctangle.w" ; scan_repl(section_name); /*88:*/ -#line 1442 "cwebdir/ctangle.w" +#line 1445 "cwebdir/ctangle.w" if(p==name_dir||p==0){ (last_unnamed)->text_link= cur_text-text_info;last_unnamed= cur_text; @@ -1517,21 +1530,21 @@ cur_text->text_link= section_flag; /*:88*/ -#line 1436 "cwebdir/ctangle.w" +#line 1439 "cwebdir/ctangle.w" ; /*:86*/ -#line 1387 "cwebdir/ctangle.w" +#line 1390 "cwebdir/ctangle.w" ; } /*:82*//*90:*/ -#line 1460 "cwebdir/ctangle.w" +#line 1463 "cwebdir/ctangle.w" #line 449 "cwebdir/ctang-w2c.ch" static void phase_one(void){ -#line 1463 "cwebdir/ctangle.w" +#line 1466 "cwebdir/ctangle.w" phase= 1; section_count= 0; reset_input(); @@ -1542,12 +1555,12 @@ phase= 2; } /*:90*//*92:*/ -#line 1478 "cwebdir/ctangle.w" +#line 1481 "cwebdir/ctangle.w" #line 467 "cwebdir/ctang-w2c.ch" static void skip_limbo(void) -#line 1481 "cwebdir/ctangle.w" +#line 1484 "cwebdir/ctangle.w" { char c; while(1){ @@ -1559,7 +1572,7 @@ c= *loc++; if(ccode[(eight_bits)c]==new_section)break; switch(ccode[(eight_bits)c]){ case translit_code:/*93:*/ -#line 1507 "cwebdir/ctangle.w" +#line 1510 "cwebdir/ctangle.w" while(xisspace(*loc)&&loc<limit)loc++; loc+= 3; @@ -1584,7 +1597,7 @@ translit[i-0200][loc-beg]= '\0'; } /*:93*/ -#line 1491 "cwebdir/ctangle.w" +#line 1494 "cwebdir/ctangle.w" ;break; case format_code:case'@':break; case control_text:if(c=='q'||c=='Q'){ @@ -1602,12 +1615,12 @@ default:err_print("! Double @ should be used in limbo"); } /*:92*//*94:*/ -#line 1533 "cwebdir/ctangle.w" +#line 1536 "cwebdir/ctangle.w" void #line 476 "cwebdir/ctang-w2c.ch" print_stats(void){ -#line 1536 "cwebdir/ctangle.w" +#line 1539 "cwebdir/ctangle.w" printf("\nMemory usage statistics:\n"); printf("%ld names (out of %ld)\n", (long)(name_ptr-name_dir),(long)max_names); diff --git a/source/texk/web2c/cwebdir/common.h b/source/texk/web2c/cwebdir/common.h index b1cd2e15e5332ed8243ed01b4981aa1fad35a27c..d6c0bfb601bfb932bb56d319d49460319a430b02 100644 --- a/source/texk/web2c/cwebdir/common.h +++ b/source/texk/web2c/cwebdir/common.h @@ -2,7 +2,7 @@ % This program by Silvio Levy and Donald E. Knuth % is based on a program by Knuth. % It is distributed WITHOUT ANY WARRANTY, express or implied. -% Version 3.0 --- June 1993 (works also with later versions) +% Version 3.64 --- February 2017 (works also with later versions) % Copyright (C) 1987,1990,1993 Silvio Levy and Donald E. Knuth @@ -147,6 +147,7 @@ extern char file_name[][max_file_name_length]; extern char change_file_name[]; /* name of change file */ extern line[]; /* number of current line in the stacked files */ extern change_line; /* number of current line in change file */ +extern change_depth; /* where \.{@@y} originated during a change */ extern boolean input_has_ended; /* if there is no more input */ extern boolean changing; /* if the current line is from |change_file| */ extern boolean web_file_open; /* if the web file is being read */ diff --git a/source/texk/web2c/cwebdir/ctangle.c b/source/texk/web2c/cwebdir/ctangle.c index 01fa7c407cd6e9b100caa18ff00b52581f2d8986..b7a1b553cee437f000cebbebc17471c2c4bc288a 100644 --- a/source/texk/web2c/cwebdir/ctangle.c +++ b/source/texk/web2c/cwebdir/ctangle.c @@ -215,6 +215,7 @@ extern char file_name[][max_file_name_length]; extern char change_file_name[]; extern line[]; extern change_line; +extern change_depth; extern boolean input_has_ended; extern boolean changing; extern boolean web_file_open; @@ -223,7 +224,7 @@ extern get_line(); extern check_complete(); /*:11*//*12:*/ -#line 158 "common.h" +#line 159 "common.h" typedef unsigned short sixteen_bits; extern sixteen_bits section_count; @@ -232,14 +233,14 @@ extern boolean change_pending; extern boolean print_where; /*:12*//*13:*/ -#line 170 "common.h" +#line 171 "common.h" extern int argc; extern char**argv; extern boolean flags[]; /*:13*//*14:*/ -#line 182 "common.h" +#line 183 "common.h" extern FILE*C_file; extern FILE*tex_file; @@ -248,7 +249,7 @@ extern FILE*scn_file; extern FILE*active_file; /*:14*//*15:*/ -#line 191 "common.h" +#line 192 "common.h" extern void common_init(); #line 128 "ctangle.w" @@ -356,7 +357,7 @@ text_pointer cur_text; eight_bits next_control; /*:75*//*82:*/ -#line 1350 "ctangle.w" +#line 1353 "ctangle.w" extern sixteen_bits section_count; @@ -388,12 +389,12 @@ void output_defs(); static void out_char(); /*:48*//*90:*/ -#line 1457 "ctangle.w" +#line 1460 "ctangle.w" void phase_one(); /*:90*//*92:*/ -#line 1475 "ctangle.w" +#line 1478 "ctangle.w" void skip_limbo(); @@ -888,11 +889,14 @@ print_where= 0; #line 1225 "ctangle.w" store_two_bytes(0150000); -if(changing)id_first= change_file_name; -else id_first= cur_file_name; +if(changing&&include_depth==change_depth){ +id_first= change_file_name; +store_two_bytes((sixteen_bits)change_line); +}else{ +id_first= cur_file_name; +store_two_bytes((sixteen_bits)cur_line); +} id_loc= id_first+strlen(id_first); -if(changing)store_two_bytes((sixteen_bits)change_line); -else store_two_bytes((sixteen_bits)cur_line); {int a= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a/0400)+0200); app_repl(a%0400);} @@ -1192,11 +1196,14 @@ if(t==section_name){/*77:*/ #line 1225 "ctangle.w" store_two_bytes(0150000); -if(changing)id_first= change_file_name; -else id_first= cur_file_name; +if(changing&&include_depth==change_depth){ +id_first= change_file_name; +store_two_bytes((sixteen_bits)change_line); +}else{ +id_first= cur_file_name; +store_two_bytes((sixteen_bits)cur_line); +} id_loc= id_first+strlen(id_first); -if(changing)store_two_bytes((sixteen_bits)change_line); -else store_two_bytes((sixteen_bits)cur_line); {int a= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a/0400)+0200); app_repl(a%0400);} @@ -1205,7 +1212,7 @@ app_repl(a%0400);} ;} while(1)switch(a= get_next()){ /*78:*/ -#line 1235 "ctangle.w" +#line 1238 "ctangle.w" case identifier:a= id_lookup(id_first,id_loc,0)-name_dir; app_repl((a/0400)+0200); @@ -1213,7 +1220,7 @@ app_repl(a%0400);break; case section_name:if(t!=section_name)goto done; else{ /*79:*/ -#line 1268 "ctangle.w" +#line 1271 "ctangle.w" { char*try_loc= loc; while(*try_loc==' '&&try_loc<limit)try_loc++; @@ -1226,7 +1233,7 @@ if(*try_loc=='=')err_print("! Missing `@ ' before a named section"); } /*:79*/ -#line 1241 "ctangle.w" +#line 1244 "ctangle.w" ; a= cur_section_name-name_dir; app_repl((a/0400)+0250); @@ -1235,16 +1242,19 @@ app_repl(a%0400); #line 1225 "ctangle.w" store_two_bytes(0150000); -if(changing)id_first= change_file_name; -else id_first= cur_file_name; +if(changing&&include_depth==change_depth){ +id_first= change_file_name; +store_two_bytes((sixteen_bits)change_line); +}else{ +id_first= cur_file_name; +store_two_bytes((sixteen_bits)cur_line); +} id_loc= id_first+strlen(id_first); -if(changing)store_two_bytes((sixteen_bits)change_line); -else store_two_bytes((sixteen_bits)cur_line); {int a= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a/0400)+0200); app_repl(a%0400);} /*:77*/ -#line 1245 "ctangle.w" +#line 1248 "ctangle.w" ;break; } case output_defs_code:if(t!=section_name)err_print("! Misplaced @h"); @@ -1258,22 +1268,25 @@ app_repl(a%0400); #line 1225 "ctangle.w" store_two_bytes(0150000); -if(changing)id_first= change_file_name; -else id_first= cur_file_name; +if(changing&&include_depth==change_depth){ +id_first= change_file_name; +store_two_bytes((sixteen_bits)change_line); +}else{ +id_first= cur_file_name; +store_two_bytes((sixteen_bits)cur_line); +} id_loc= id_first+strlen(id_first); -if(changing)store_two_bytes((sixteen_bits)change_line); -else store_two_bytes((sixteen_bits)cur_line); {int a= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a/0400)+0200); app_repl(a%0400);} /*:77*/ -#line 1254 "ctangle.w" +#line 1257 "ctangle.w" ; } break; case constant:case string: /*80:*/ -#line 1279 "ctangle.w" +#line 1282 "ctangle.w" app_repl(a); while(id_first<id_loc){ @@ -1287,11 +1300,11 @@ app_repl(*id_first++); app_repl(a);break; /*:80*/ -#line 1258 "ctangle.w" +#line 1261 "ctangle.w" ; case ord: /*81:*/ -#line 1295 "ctangle.w" +#line 1298 "ctangle.w" { int c= (eight_bits)*id_first; if(c=='\\'){ @@ -1342,7 +1355,7 @@ app_repl(constant); break; /*:81*/ -#line 1260 "ctangle.w" +#line 1263 "ctangle.w" ; case definition:case format_code:case begin_C:if(t!=section_name)goto done; else{ @@ -1365,7 +1378,7 @@ cur_text= text_ptr;(++text_ptr)->tok_start= tok_ptr; } /*:76*//*83:*/ -#line 1357 "ctangle.w" +#line 1360 "ctangle.w" void scan_section() @@ -1380,7 +1393,7 @@ printf("*%d",section_count);update_terminal; next_control= 0; while(1){ /*84:*/ -#line 1396 "ctangle.w" +#line 1399 "ctangle.w" while(next_control<definition) @@ -1389,11 +1402,11 @@ loc-= 2;next_control= get_next(); } /*:84*/ -#line 1371 "ctangle.w" +#line 1374 "ctangle.w" ; if(next_control==definition){ /*85:*/ -#line 1403 "ctangle.w" +#line 1406 "ctangle.w" { while((next_control= get_next())=='\n'); if(next_control!=identifier){ @@ -1412,7 +1425,7 @@ cur_text->text_link= 0; } /*:85*/ -#line 1373 "ctangle.w" +#line 1376 "ctangle.w" continue; } @@ -1422,14 +1435,14 @@ p= name_dir;break; if(next_control==section_name){ p= cur_section_name; /*86:*/ -#line 1428 "ctangle.w" +#line 1431 "ctangle.w" while((next_control= get_next())=='+'); if(next_control!='='&&next_control!=eq_eq) continue; /*:86*/ -#line 1381 "ctangle.w" +#line 1384 "ctangle.w" ; break; } @@ -1437,20 +1450,20 @@ return; } no_where= print_where= 0; /*87:*/ -#line 1433 "ctangle.w" +#line 1436 "ctangle.w" /*88:*/ -#line 1438 "ctangle.w" +#line 1441 "ctangle.w" store_two_bytes((sixteen_bits)(0150000+section_count)); /*:88*/ -#line 1434 "ctangle.w" +#line 1437 "ctangle.w" ; scan_repl(section_name); /*89:*/ -#line 1442 "ctangle.w" +#line 1445 "ctangle.w" if(p==name_dir||p==0){ (last_unnamed)->text_link= cur_text-text_info;last_unnamed= cur_text; @@ -1467,16 +1480,16 @@ cur_text->text_link= section_flag; /*:89*/ -#line 1436 "ctangle.w" +#line 1439 "ctangle.w" ; /*:87*/ -#line 1387 "ctangle.w" +#line 1390 "ctangle.w" ; } /*:83*//*91:*/ -#line 1460 "ctangle.w" +#line 1463 "ctangle.w" void phase_one(){ @@ -1490,7 +1503,7 @@ phase= 2; } /*:91*//*93:*/ -#line 1478 "ctangle.w" +#line 1481 "ctangle.w" void skip_limbo() @@ -1505,7 +1518,7 @@ c= *loc++; if(ccode[(eight_bits)c]==new_section)break; switch(ccode[(eight_bits)c]){ case translit_code:/*94:*/ -#line 1507 "ctangle.w" +#line 1510 "ctangle.w" while(xisspace(*loc)&&loc<limit)loc++; loc+= 3; @@ -1530,7 +1543,7 @@ translit[i-0200][loc-beg]= '\0'; } /*:94*/ -#line 1491 "ctangle.w" +#line 1494 "ctangle.w" ;break; case format_code:case'@':break; case control_text:if(c=='q'||c=='Q'){ @@ -1548,7 +1561,7 @@ default:err_print("! Double @ should be used in limbo"); } /*:93*//*95:*/ -#line 1533 "ctangle.w" +#line 1536 "ctangle.w" void print_stats(){ diff --git a/source/texk/web2c/cwebdir/ctangle.w b/source/texk/web2c/cwebdir/ctangle.w index 2b10a243a5bbe83180d1cb46f13813773a27a085..130800210e50b2c8b6fdfa6b982d0dedd30218c5 100644 --- a/source/texk/web2c/cwebdir/ctangle.w +++ b/source/texk/web2c/cwebdir/ctangle.w @@ -1224,11 +1224,14 @@ file name. @<Insert the line...@>= store_two_bytes(0150000); -if (changing) id_first=change_file_name; -else id_first=cur_file_name; +if (changing && include_depth==change_depth) { /* correction made Feb 2017 */ + id_first=change_file_name; + store_two_bytes((sixteen_bits)change_line); +}@+else { + id_first=cur_file_name; + store_two_bytes((sixteen_bits)cur_line); +} id_loc=id_first+strlen(id_first); -if (changing) store_two_bytes((sixteen_bits)change_line); -else store_two_bytes((sixteen_bits)cur_line); {int a=id_lookup(id_first,id_loc,0)-name_dir; app_repl((a / 0400)+0200); app_repl(a % 0400);} diff --git a/source/texk/web2c/lib/ChangeLog b/source/texk/web2c/lib/ChangeLog index 390ae351183f3396a605477c52d7d0d047c1e4f7..53058e6a8c56d54b5627dabac7a512b6b1733a1c 100644 --- a/source/texk/web2c/lib/ChangeLog +++ b/source/texk/web2c/lib/ChangeLog @@ -1,3 +1,7 @@ +2017-02-13 Akira Kakuto <kakuto@fuk.kinidai.ac.jp> + + * texmfmp.c: unsigned long long >= 0. Thanks Luigi. + 2017-02-01 Akira Kakuto <kakuto@fuk.kinidai.ac.jp> * texmfmp.c: Avoid a crash in xelatex for diff --git a/source/texk/web2c/lib/texmfmp.c b/source/texk/web2c/lib/texmfmp.c index 47086d9bc0a53fb6d91ea1ef6d3d9589e73f36a3..152a2312e5a47809b315946e04e635bfdd2b2507 100644 --- a/source/texk/web2c/lib/texmfmp.c +++ b/source/texk/web2c/lib/texmfmp.c @@ -2218,7 +2218,7 @@ void init_start_time() { if (source_date_epoch) { errno = 0; epoch = strtoull(source_date_epoch, &endptr, 10); - if (epoch < 0 || *endptr != '\0' || errno != 0) { + if (*endptr != '\0' || errno != 0) { FATAL1 ("invalid epoch-seconds-timezone value for environment variable $SOURCE_DATE_EPOCH: %s", source_date_epoch); } diff --git a/source/texk/web2c/luatexdir/am/libluatex.am b/source/texk/web2c/luatexdir/am/libluatex.am index 800aa43cb2cba9ddcd95f23552d0a290dc0e0c2b..cabbaa0b5d622202b26c1afec77fd16c98377013 100644 --- a/source/texk/web2c/luatexdir/am/libluatex.am +++ b/source/texk/web2c/luatexdir/am/libluatex.am @@ -44,18 +44,8 @@ nodist_libluajittex_a_SOURCES = \ luastuff.c texluajitc.c \ $(dist_libluatex_sources) \ $(nodist_libluatex_sources) -#nodist_libluajittex_a_SOURCES = \ -# luajitstuff.c texluajitc.c \ -# $(dist_libluatex_sources) \ -# $(nodist_libluatex_sources) -#$(libluatex_a_OBJECTS): libff.a libmplib.a libluamisc.a $(POPPLER_DEPEND) -#$(libluajittex_a_OBJECTS): libff.a libmplib.a libluajitmisc.a $(POPPLER_DEPEND) - -#$(libluatex_a_OBJECTS): libff.a libmplibcore.a libmplibbackends.a libluamisc.a $(POPPLER_DEPEND) -#$(libluajittex_a_OBJECTS): libff.a libmplibcore.a libmplibbackends.a libluajitmisc.a $(POPPLER_DEPEND) - -## mplib stub backends are in mplibstuff.c +## mplib "stub" backends are in mplibstuff.c $(libluatex_a_OBJECTS): libff.a libmplibcore.a libluamisc.a $(POPPLER_DEPEND) $(libluajittex_a_OBJECTS): libff.a libmplibcore.a libluajitmisc.a $(POPPLER_DEPEND) diff --git a/source/texk/web2c/luatexdir/am/luatex.am b/source/texk/web2c/luatexdir/am/luatex.am index 0f8fad573be29007ecaa3ec972eb7c00cd7333a8..2436d8891d40e942aa8ebabb6d1a994ffb7d11ce 100644 --- a/source/texk/web2c/luatexdir/am/luatex.am +++ b/source/texk/web2c/luatexdir/am/luatex.am @@ -48,9 +48,7 @@ luajittex_CXXFLAGS = $(WARNING_CXXFLAGS) luatex_LDFLAGS = -export-dynamic luajittex_LDFLAGS = -export-dynamic $(LUAJIT_LDEXTRA) -#luatex_postldadd = libmplib.a $(MPFR_LIBS) $(GMP_LIBS) $(CAIRO_LIBS) $(PIXMAN_LIBS) -#luatex_postldadd = libmplibcore.a libmplibbackends.a $(MPFR_LIBS) $(GMP_LIBS) $(CAIRO_LIBS) $(PIXMAN_LIBS) -luatex_postldadd = libmplibcore.a $(MPFR_LIBS) $(GMP_LIBS) $(CAIRO_LIBS) $(PIXMAN_LIBS) +luatex_postldadd = libmplibcore.a $(MPFR_LIBS) $(GMP_LIBS) luatex_postldadd += $(ZZIPLIB_LIBS) $(LIBPNG_LIBS) $(ZLIB_LIBS) $(POPPLER_LIBS) luatex_postldadd += $(LDADD) libmputil.a libunilib.a libmd5.a $(lua_socketlibs) diff --git a/source/texk/web2c/luatexdir/font/luafont.w b/source/texk/web2c/luatexdir/font/luafont.w index 9c7354a3f8fbaf26c4a1868b38926a2121114cb7..8013883c454d37aec1164457d15884c5638715af 100644 --- a/source/texk/web2c/luatexdir/font/luafont.w +++ b/source/texk/web2c/luatexdir/font/luafont.w @@ -438,6 +438,7 @@ int font_to_lua(lua_State * L, int f) dump_stringfield(L,writingmode,font_writingmode_strings[font_writingmode(f)]); dump_stringfield(L,identity,font_identity_strings[font_identity(f)]); dump_stringfield(L,embedding,font_embedding_strings[font_embedding(f)]); + dump_intfield(L,streamprovider,font_streamprovider(f)); dump_intfield(L,units_per_em,font_units_per_em(f)); dump_intfield(L,size,font_size(f)); @@ -1383,6 +1384,8 @@ int font_from_lua(lua_State * L, int f) set_font_natural_dir(f, i); i = lua_numeric_field_by_index(L,lua_key_index(encodingbytes), 0); set_font_encodingbytes(f, (char) i); + i = lua_numeric_field_by_index(L,lua_key_index(streamprovider), 0); + set_font_streamprovider(f, (char) i); i = n_boolean_field(L,lua_key_index(oldmath), 0); set_font_oldmath(f, i); i = lua_numeric_field_by_index(L,lua_key_index(tounicode), 0); diff --git a/source/texk/web2c/luatexdir/font/luatexfont.h b/source/texk/web2c/luatexdir/font/luatexfont.h index bd84a61672c2279f30f8589dad59f3efc605d483..9ef5110db24059843e62751456155ea01edd093a 100644 --- a/source/texk/web2c/luatexdir/font/luatexfont.h +++ b/source/texk/web2c/luatexdir/font/luatexfont.h @@ -102,6 +102,7 @@ typedef struct fd_entry_ { fm_entry *fm; /* pointer to font map structure */ struct avl_table *tx_tree; /* tree of non-reencoded TeX characters marked as used */ struct avl_table *gl_tree; /* tree of all marked glyphs */ + internal_font_number tex_font; /* needed for variable */ } fd_entry; typedef struct fo_entry_ { @@ -162,7 +163,7 @@ void writetype0(PDF pdf, fd_entry * fd); /* writefont.c */ void do_pdf_font(PDF, internal_font_number); fd_entry *lookup_fd_entry(char *); -fd_entry *new_fd_entry(void); +fd_entry *new_fd_entry(internal_font_number); void write_fontstuff(PDF); void register_fd_entry(fd_entry * fd); diff --git a/source/texk/web2c/luatexdir/font/texfont.h b/source/texk/web2c/luatexdir/font/texfont.h index ff15cc791b4f1d2d31bd5bf1510495d597a260ef..98557992f9760c70ef4b586627791d7ead6bfe85 100644 --- a/source/texk/web2c/luatexdir/font/texfont.h +++ b/source/texk/web2c/luatexdir/font/texfont.h @@ -153,6 +153,7 @@ typedef struct texfont { int _font_writingmode; int _font_identity; int _font_embedding; + int _font_streamprovider; int _font_bc; int _hyphen_char; int _skew_char; @@ -316,6 +317,10 @@ boolean cmp_font_area(int, str_number); # define font_encodingbytes(a) font_tables[a]->_font_encodingbytes # define set_font_encodingbytes(a,b) font_encodingbytes(a) = b +# define font_streamprovider(a) font_tables[a]->_font_streamprovider +# define set_font_streamprovider(a,b) font_streamprovider(a) = b + + # define font_oldmath(a) font_tables[a]->_font_oldmath # define set_font_oldmath(a,b) font_oldmath(a) = b diff --git a/source/texk/web2c/luatexdir/font/texfont.w b/source/texk/web2c/luatexdir/font/texfont.w index ab72a52f59247b2dc31660b481f85875343ed456..0c64045752e7cb23a367843c55faacf274166549 100644 --- a/source/texk/web2c/luatexdir/font/texfont.w +++ b/source/texk/web2c/luatexdir/font/texfont.w @@ -1542,6 +1542,7 @@ static void dump_font_entry(texfont * f) dump_int(f->_font_writingmode); dump_int(f->_font_identity); dump_int(f->_font_embedding); + dump_int(f->_font_streamprovider); dump_int(f->_font_bc); dump_int(f->_hyphen_char); dump_int(f->_skew_char); @@ -1721,6 +1722,7 @@ static void undump_font_entry(texfont * f) undump_int(x); f->_font_writingmode = x; undump_int(x); f->_font_identity = x; undump_int(x); f->_font_embedding = x; + undump_int(x); f->_font_streamprovider = x; undump_int(x); f->_font_bc = x; undump_int(x); f->_hyphen_char = x; undump_int(x); f->_skew_char = x; diff --git a/source/texk/web2c/luatexdir/font/tt_glyf.h b/source/texk/web2c/luatexdir/font/tt_glyf.h index a16cfbc9f0535d5eede7711c4c71f0a64db79052..780b77793dc0cbbf0c3d68365e87dcc368e57e85 100644 --- a/source/texk/web2c/luatexdir/font/tt_glyf.h +++ b/source/texk/web2c/luatexdir/font/tt_glyf.h @@ -1,5 +1,5 @@ /* tt_glyf.h - + Copyright 2002 by Jin-Hwan Cho and Shunsaku Hirata, the dvipdfmx project team <dvipdfmx@project.ktug.or.kr> Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> @@ -52,7 +52,7 @@ extern USHORT tt_add_glyph(struct tt_glyphs *g, USHORT gid, USHORT new_gid); extern USHORT tt_get_index(struct tt_glyphs *g, USHORT gid); extern USHORT tt_find_glyph(struct tt_glyphs *g, USHORT gid); -extern int tt_build_tables(sfnt * sfont, struct tt_glyphs *g); +extern int tt_build_tables(sfnt * sfont, struct tt_glyphs *g, fd_entry * fd); extern int tt_get_metrics(sfnt * sfont, struct tt_glyphs *g); #endif /* _TT_GLYF_H_ */ diff --git a/source/texk/web2c/luatexdir/font/tt_glyf.w b/source/texk/web2c/luatexdir/font/tt_glyf.w index 167d8df2038ac8bec44dd85e02ed22fb6e30169a..c0f17e5ab592ccf76bfc97eebf4747733d253a23 100644 --- a/source/texk/web2c/luatexdir/font/tt_glyf.w +++ b/source/texk/web2c/luatexdir/font/tt_glyf.w @@ -174,11 +174,11 @@ static int glyf_cmp(const void *v1, const void *v2) } @ @c -int tt_build_tables(sfnt * sfont, struct tt_glyphs *g) +int tt_build_tables(sfnt * sfont, struct tt_glyphs *g, fd_entry * fd) { char *hmtx_table_data = NULL, *loca_table_data = NULL; char *glyf_table_data = NULL; - ULONG hmtx_table_size, loca_table_size, glyf_table_size; + ULONG hmtx_table_size, loca_table_size, glyf_table_size, glyf_table_used; /* some information available from other TrueType table */ struct tt_head_table *head = NULL; struct tt_hhea_table *hhea = NULL; @@ -190,6 +190,14 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g) long i; USHORT *w_stat; /* Estimate most frequently appeared width */ + int tex_font = fd->tex_font; + int streamprovider = 0; + int callback_id = 0 ; + if ((tex_font > 0) && (font_streamprovider(tex_font) == 2)) { + streamprovider = font_streamprovider(tex_font); + callback_id = callback_defined(glyph_stream_provider_callback); + } + ASSERT(g); if (sfont->type != SFNT_TYPE_TRUETYPE && sfont->type != SFNT_TYPE_TTC) @@ -307,6 +315,7 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g) formatted_error("ttf","invalid glyph data (gid %u)", gid); } +/* todo: no need for this */ g->gd[i].data = p = NEW(len, BYTE); endptr = p + len; @@ -432,6 +441,7 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g) hmtx_table_data = p = NEW(hmtx_table_size, char); loca_table_data = q = NEW(loca_table_size, char); glyf_table_data = NEW(glyf_table_size, char); + glyf_table_used = 0; offset = 0UL; prev = 0; @@ -451,8 +461,6 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g) q += sfnt_put_ulong(q, (LONG) offset); } } - padlen = - (int) ((g->gd[i].length % 4) ? (4 - (g->gd[i].length % 4)) : 0); if (g->gd[i].gid < hhea->numberOfHMetrics) { p += sfnt_put_ushort(p, g->gd[i].advw); } @@ -462,13 +470,35 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g) } else { q += sfnt_put_ulong(q, (LONG) offset); } - memset(glyf_table_data + offset, 0, - (size_t) (g->gd[i].length + (ULONG) padlen)); - memcpy(glyf_table_data + offset, g->gd[i].data, g->gd[i].length); - offset += (g->gd[i].length + (ULONG) padlen); + + if (callback_id > 0) { + + lstring * result; + long size = 0; + run_callback(callback_id, "ddd->L", tex_font, g->gd[i].gid, streamprovider, &result); /* this call can be sped up */ + padlen = (int) ((result->l % 4) ? (4 - (result->l % 4)) : 0); + size = (size_t) result->l + (ULONG) padlen; + if (glyf_table_used + size >= glyf_table_size) { + glyf_table_size = glyf_table_size + 20 * size; /* just a guess */ + glyf_table_data = xrealloc(glyf_table_data, (unsigned)((unsigned)glyf_table_size*sizeof(char))); + } + glyf_table_used += size; + memset(glyf_table_data + offset, 0, (size_t) size); + memcpy(glyf_table_data + offset, (const char *) result->s, (size_t) result->l); + offset += size; + xfree(result); + + } else { + + padlen = (int) ((g->gd[i].length % 4) ? (4 - (g->gd[i].length % 4)) : 0); + memset(glyf_table_data + offset, 0, (size_t) (g->gd[i].length + (ULONG) padlen)); + memcpy(glyf_table_data + offset, g->gd[i].data, g->gd[i].length); + offset += (g->gd[i].length + (ULONG) padlen); + + } prev = g->gd[i].gid; - /* free data here since it consume much memory */ RELEASE(g->gd[i].data); + /* free data here since it consume much memory */ g->gd[i].length = 0; g->gd[i].data = NULL; } @@ -478,12 +508,12 @@ int tt_build_tables(sfnt * sfont, struct tt_glyphs *g) q += sfnt_put_ulong(q, (LONG) offset); } - sfnt_set_table(sfont, "hmtx", (char *) hmtx_table_data, - hmtx_table_size); - sfnt_set_table(sfont, "loca", (char *) loca_table_data, - loca_table_size); - sfnt_set_table(sfont, "glyf", (char *) glyf_table_data, - glyf_table_size); + sfnt_set_table(sfont, "hmtx", (char *) hmtx_table_data, hmtx_table_size); + sfnt_set_table(sfont, "loca", (char *) loca_table_data, loca_table_size); + if (callback_id > 0) { + glyf_table_size = glyf_table_used; + } + sfnt_set_table(sfont, "glyf", (char *) glyf_table_data, glyf_table_size); } head->checkSumAdjustment = 0; diff --git a/source/texk/web2c/luatexdir/font/writecff.h b/source/texk/web2c/luatexdir/font/writecff.h index 3063eadb0c5fec1c3ae3fb1a9315480161375c80..1a24df483b41718a3e3525f86845703a5fb7ffae 100644 --- a/source/texk/web2c/luatexdir/font/writecff.h +++ b/source/texk/web2c/luatexdir/font/writecff.h @@ -1,5 +1,5 @@ /* writecff.h - + Copyright 2002 by Jin-Hwan Cho and Shunsaku Hirata, the dvipdfmx project team <dvipdfmx@project.ktug.or.kr> Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> @@ -327,11 +327,6 @@ typedef struct { } seac; /* unused in Type 2 charstring */ } cs_ginfo; -extern long cs_copy_charstring(card8 * dest, long destlen, - card8 * src, long srclen, - cff_index * gsubr, cff_index * subr, - double default_width, double nominal_width, - cs_ginfo * ginfo); #endif /* _CS_TYPE2_H_ */ #define cff_is_cidfont(a) (a->flag & FONTTYPE_CIDFONT) diff --git a/source/texk/web2c/luatexdir/font/writecff.w b/source/texk/web2c/luatexdir/font/writecff.w index 2c95ac88e410b52ff7a821813095eb421bb43fa9..9707c751e25001669a56a8486b9b4085cb3d701f 100644 --- a/source/texk/web2c/luatexdir/font/writecff.w +++ b/source/texk/web2c/luatexdir/font/writecff.w @@ -19,7 +19,6 @@ @ @c - #include "ptexlib.h" #include "lua/luatex-api.h" #include "font/writecff.h" @@ -30,6 +29,7 @@ extern int cidset; #define get_offset(s,n) get_unsigned(s, (n)) #define get_card8(a) (card8)(a->stream[a->offset++]) #define get_card16(a) (card16)(get_unsigned(a,2)) +#define get_card32(a) (get_unsigned(a,4)) #undef b0 #undef b1 @@ -146,75 +146,61 @@ const char *const cff_stdstr[CFF_STDSTR_MAX] = { "Black", "Bold", "Book", "Light", "Medium", "Regular", "Roman", "Semibold" }; - @ Only read header part but not body @c cff_index *cff_get_index_header(cff_font * cff) { cff_index *idx; card16 i, count; - idx = xcalloc(1, sizeof(cff_index)); - - idx->count = count = get_card16(cff); + if (cff->header_major == 2) { + idx->count = count = get_card32(cff); + } else { + idx->count = count = get_card16(cff); + } if (count > 0) { idx->offsize = get_card8(cff); if (idx->offsize < 1 || idx->offsize > 4) - normal_error("cff","invalid offsize data"); - - idx->offset = - xmalloc((unsigned) (((unsigned) count + 1) * sizeof(l_offset))); + normal_error("cff","invalid offsize data (1)"); + idx->offset = xmalloc((unsigned) (((unsigned) count + 1) * sizeof(l_offset))); for (i = 0; i <count + 1 ; i++) { (idx->offset)[i] = get_offset(cff, idx->offsize); if (i == USHRT_MAX) break; } - if (idx->offset[0] != 1) normal_error("cff","invalid index data"); - idx->data = NULL; } else { idx->offsize = 0; idx->offset = NULL; idx->data = NULL; } - return idx; } - - @ @c cff_index *cff_get_index(cff_font * cff) { cff_index *idx; card16 i, count; size_t length; - idx = xcalloc(1, sizeof(cff_index)); - idx->count = count = get_card16(cff); if (count > 0) { idx->offsize = get_card8(cff); if (idx->offsize < 1 || idx->offsize > 4) - normal_error("cff","invalid offsize data"); - - idx->offset = - xmalloc((unsigned) (((unsigned) count + 1) * sizeof(l_offset))); + normal_error("cff","invalid offsize data (2)"); + idx->offset = xmalloc((unsigned) (((unsigned) count + 1) * sizeof(l_offset))); for (i = 0; i < count + 1; i++) { idx->offset[i] = get_offset(cff, idx->offsize); } - if (idx->offset[0] != 1) normal_error("cff","invalid index offset data"); - length = (size_t) (idx->offset[count] - idx->offset[0]); - idx->data = xmalloc((unsigned) length * sizeof(card8)); memcpy(idx->data, &cff->stream[cff->offset], length); cff->offset += length; - } else { idx->offsize = 0; idx->offset = NULL; @@ -223,6 +209,40 @@ cff_index *cff_get_index(cff_font * cff) return idx; } +static cff_index *cff_empty_index(cff_font * cff) +{ + cff_index *idx; + idx = xcalloc(1, sizeof(cff_index)); + idx->count = 0; + idx->offsize = 0; + idx->offset = NULL; + idx->data = NULL; + return idx; +} + +static cff_index *cff_get_index2(cff_font * cff) +{ + /* we fake a dict array */ + + cff_index *idx; + size_t length; + + idx = xcalloc(1, sizeof(cff_index)); + + length = (size_t) cff->header_offsize; + + idx->offsize = 2; + idx->count = 1; + idx->offset = xmalloc((unsigned) (((unsigned) 2) * sizeof(l_offset))); + idx->offset[0] = 1; // get_offset(cff, idx->offsize); + idx->offset[1] = length + 1; // idx->offset[0] + length; + + idx->data = xmalloc((unsigned) length * sizeof(card8)); + memcpy(idx->data, &cff->stream[cff->offset], length ); + cff->offset += length ; + + return idx; +} @ @c long cff_pack_index(cff_index * idx, card8 * dest, long destlen) @@ -230,23 +250,18 @@ long cff_pack_index(cff_index * idx, card8 * dest, long destlen) long len = 0; unsigned long datalen; card16 i; - if (idx->count < 1) { if (destlen < 2) normal_error("cff","not enough space available"); memset(dest, 0, 2); return 2; } - len = cff_index_size(idx); datalen = idx->offset[idx->count] - 1; - if (destlen < len) normal_error("cff","not enough space available"); - *(dest++) = (card8) ((idx->count >> 8) & 0xff); *(dest++) = (card8) (idx->count & 0xff); - if (datalen < 0xffUL) { idx->offsize = 1; *(dest++) = 1; @@ -278,9 +293,7 @@ long cff_pack_index(cff_index * idx, card8 * dest, long destlen) *(dest++) = (card8) (idx->offset[i] & 0xff); } } - memmove(dest, idx->data, idx->offset[idx->count] - 1); - return len; } @@ -289,7 +302,6 @@ long cff_index_size(cff_index * idx) { if (idx->count > 0) { l_offset datalen; - datalen = idx->offset[idx->count] - 1; if (datalen < 0xffUL) { idx->offsize = 1; @@ -310,11 +322,9 @@ long cff_index_size(cff_index * idx) cff_index *cff_new_index(card16 count) { cff_index *idx; - idx = xcalloc(1, sizeof(cff_index)); idx->count = count; idx->offsize = 0; - if (count > 0) { idx->offset = xcalloc((unsigned) (count + 1), sizeof(l_offset)); (idx->offset)[0] = 1; @@ -322,11 +332,9 @@ cff_index *cff_new_index(card16 count) idx->offset = NULL; } idx->data = NULL; - return idx; } - @ @c void cff_release_index(cff_index * idx) { @@ -352,7 +360,6 @@ void cff_release_dict(cff_dict * dict) } } - @ @c void cff_release_encoding(cff_encoding * encoding) { @@ -407,12 +414,10 @@ void cff_release_fdselect(cff_fdselect * fdselect) } } - @ @c void cff_close(cff_font * cff) { card16 i; - if (cff) { xfree(cff->fontname); if (cff->name) @@ -456,7 +461,6 @@ void cff_close(cff_font * cff) cff_release_index(cff->_string); xfree(cff); } - return; } @@ -466,28 +470,22 @@ char *cff_get_name(cff_font * cff) char *fontname; l_offset len; cff_index *idx; - idx = cff->name; len = idx->offset[cff->index + 1] - idx->offset[cff->index]; fontname = xmalloc((unsigned) (len + 1) * sizeof(char)); memcpy(fontname, idx->data + idx->offset[cff->index] - 1, len); fontname[len] = '\0'; - return fontname; } - @ @c long cff_set_name(cff_font * cff, char *name) { cff_index *idx; - if (strlen(name) > 127) normal_error("cff","FontName string length too large"); - if (cff->name) cff_release_index(cff->name); - cff->name = idx = xcalloc(1, sizeof(cff_index)); idx->count = 1; idx->offsize = 1; @@ -495,8 +493,7 @@ long cff_set_name(cff_font * cff, char *name) (idx->offset)[0] = 1; (idx->offset)[1] = strlen(name) + 1; idx->data = xmalloc((unsigned) strlen(name) * sizeof(card8)); - memmove(idx->data, name, strlen(name)); /* no trailing |'\0'| */ - + memmove(idx->data, name, strlen(name)); /* no trailing |'\0'| */ return (long) (5 + strlen(name)); } @@ -505,15 +502,16 @@ long cff_put_header(cff_font * cff, card8 * dest, long destlen) if (destlen < 4) normal_error("cff","not enough space available"); - *(dest++) = cff->header_major; + *(dest++) = 1; /* cff->header_major; */ *(dest++) = cff->header_minor; - *(dest++) = 4; /* Additional data in between header and - * Name INDEX ignored. - */ - /* We will set all offset (0) to four-byte integer. */ *(dest++) = 4; - cff->header_offsize = 4; + /* + Additional data in between header and Name INDEX is ignored. + We will set all offset (0) to a four-byte integer. + */ + *(dest++) = 4; + cff->header_offsize = 4; return 4; } @@ -529,7 +527,6 @@ long cff_put_header(cff_font * cff, card8 * dest, long destlen) cff_dict *cff_new_dict(void) { cff_dict *dict; - dict = xcalloc(1, sizeof(cff_dict)); dict->max = DICT_ENTRY_MAX; dict->count = 0; @@ -537,30 +534,22 @@ cff_dict *cff_new_dict(void) return dict; } -@ - -Operand stack: - only numbers are stored (as double) +@ Operand stack: only numbers are stored (as double). Operand types are: -Operand types: - -number : double (integer or real) -boolean: stored as a number -SID : stored as a number -array : array of numbers -delta : array of numbers +\item number: double (integer or real) +\item boolean: stored as a number +\item SID: stored as a number +\item array: array of numbers +\item delta: array of numbers @c #define CFF_DICT_STACK_LIMIT 64 static int stack_top = 0; static double arg_stack[CFF_DICT_STACK_LIMIT]; -@ -CFF DICT encoding: -TODO: default values - +@ CFF DICT encoding. @c -#define CFF_LAST_DICT_OP1 22 +#define CFF_LAST_DICT_OP1 26 /* 22 */ #define CFF_LAST_DICT_OP2 39 #define CFF_LAST_DICT_OP (CFF_LAST_DICT_OP1 + CFF_LAST_DICT_OP2) @@ -568,78 +557,73 @@ static struct { const char *opname; int argtype; } dict_operator[CFF_LAST_DICT_OP] = { - { - "version", CFF_TYPE_SID}, { - "Notice", CFF_TYPE_SID}, { - "FullName", CFF_TYPE_SID}, { - "FamilyName", CFF_TYPE_SID}, { - "Weight", CFF_TYPE_SID}, { - "FontBBox", CFF_TYPE_ARRAY}, { - "BlueValues", CFF_TYPE_DELTA}, { - "OtherBlues", CFF_TYPE_DELTA}, { - "FamilyBlues", CFF_TYPE_DELTA}, { - "FamilyOtherBlues", CFF_TYPE_DELTA}, { - "StdHW", CFF_TYPE_NUMBER}, { - "StdVW", CFF_TYPE_NUMBER}, { - NULL, -1}, /* first byte of two-byte operator */ - /* Top */ - { - "UniqueID", CFF_TYPE_NUMBER}, { - "XUID", CFF_TYPE_ARRAY}, { - "charset", CFF_TYPE_OFFSET}, { - "Encoding", CFF_TYPE_OFFSET}, { - "CharStrings", CFF_TYPE_OFFSET}, { - "Private", CFF_TYPE_SZOFF}, /* two numbers (size and offset) */ - /* Private */ - { - "Subrs", CFF_TYPE_OFFSET}, { - "defaultWidthX", CFF_TYPE_NUMBER}, { - "nominalWidthX", CFF_TYPE_NUMBER}, - /* Operator 2 */ - { - "Copyright", CFF_TYPE_SID}, { - "IsFixedPitch", CFF_TYPE_BOOLEAN}, { - "ItalicAngle", CFF_TYPE_NUMBER}, { - "UnderlinePosition", CFF_TYPE_NUMBER}, { - "UnderlineThickness", CFF_TYPE_NUMBER}, { - "PaintType", CFF_TYPE_NUMBER}, { - "CharstringType", CFF_TYPE_NUMBER}, { - "FontMatrix", CFF_TYPE_ARRAY}, { - "StrokeWidth", CFF_TYPE_NUMBER}, { - "BlueScale", CFF_TYPE_NUMBER}, { - "BlueShift", CFF_TYPE_NUMBER}, { - "BlueFuzz", CFF_TYPE_NUMBER}, { - "StemSnapH", CFF_TYPE_DELTA}, { - "StemSnapV", CFF_TYPE_DELTA}, { - "ForceBold", CFF_TYPE_BOOLEAN}, { - NULL, -1}, { - NULL, -1}, { - "LanguageGroup", CFF_TYPE_NUMBER}, { - "ExpansionFactor", CFF_TYPE_NUMBER}, { - "InitialRandomSeed", CFF_TYPE_NUMBER}, { - "SyntheticBase", CFF_TYPE_NUMBER}, { - "PostScript", CFF_TYPE_SID}, { - "BaseFontName", CFF_TYPE_SID}, { - "BaseFontBlend", CFF_TYPE_DELTA}, /* MMaster ? */ - { - NULL, -1}, { - NULL, -1}, { - NULL, -1}, { - NULL, -1}, { - NULL, -1}, { - NULL, -1}, - /* CID-Keyed font */ - { - "ROS", CFF_TYPE_ROS}, /* SID SID number */ - { - "CIDFontVersion", CFF_TYPE_NUMBER}, { - "CIDFontRevision", CFF_TYPE_NUMBER}, { - "CIDFontType", CFF_TYPE_NUMBER}, { - "CIDCount", CFF_TYPE_NUMBER}, { - "UIDBase", CFF_TYPE_NUMBER}, { - "FDArray", CFF_TYPE_OFFSET}, { - "FDSelect", CFF_TYPE_OFFSET}, { -"FontName", CFF_TYPE_SID},}; + { "version", CFF_TYPE_SID }, + { "Notice", CFF_TYPE_SID }, + { "FullName", CFF_TYPE_SID }, + { "FamilyName", CFF_TYPE_SID }, + { "Weight", CFF_TYPE_SID }, + { "FontBBox", CFF_TYPE_ARRAY }, + { "BlueValues", CFF_TYPE_DELTA }, + { "OtherBlues", CFF_TYPE_DELTA }, + { "FamilyBlues", CFF_TYPE_DELTA }, + { "FamilyOtherBlues", CFF_TYPE_DELTA }, + { "StdHW", CFF_TYPE_NUMBER }, + { "StdVW", CFF_TYPE_NUMBER }, + { NULL, -1 }, /* first byte of two-byte operator 12 */ + { "UniqueID", CFF_TYPE_NUMBER }, + { "XUID", CFF_TYPE_ARRAY }, + { "charset", CFF_TYPE_OFFSET }, + { "Encoding", CFF_TYPE_OFFSET }, + { "CharStrings", CFF_TYPE_OFFSET }, + { "Private", CFF_TYPE_SZOFF }, /* two numbers (size and offset) */ + { "Subrs", CFF_TYPE_OFFSET }, + { "defaultWidthX", CFF_TYPE_NUMBER }, + { "nominalWidthX", CFF_TYPE_NUMBER }, + { NULL, -1 }, + { NULL, -1 }, + { "vstore", CFF_TYPE_OFFSET }, /* cff2 */ + { "maxstack", CFF_TYPE_NUMBER }, /* cff2 */ + /* Here we start with operator 2 of 12 */ + { "Copyright", CFF_TYPE_SID }, + { "IsFixedPitch", CFF_TYPE_BOOLEAN }, + { "ItalicAngle", CFF_TYPE_NUMBER }, + { "UnderlinePosition", CFF_TYPE_NUMBER }, + { "UnderlineThickness", CFF_TYPE_NUMBER }, + { "PaintType", CFF_TYPE_NUMBER }, + { "CharstringType", CFF_TYPE_NUMBER }, + { "FontMatrix", CFF_TYPE_ARRAY }, + { "StrokeWidth", CFF_TYPE_NUMBER }, + { "BlueScale", CFF_TYPE_NUMBER }, + { "BlueShift", CFF_TYPE_NUMBER }, + { "BlueFuzz", CFF_TYPE_NUMBER }, + { "StemSnapH", CFF_TYPE_DELTA }, + { "StemSnapV", CFF_TYPE_DELTA }, + { "ForceBold", CFF_TYPE_BOOLEAN }, + { NULL, -1 }, + { NULL, -1 }, + { "LanguageGroup", CFF_TYPE_NUMBER }, + { "ExpansionFactor", CFF_TYPE_NUMBER }, + { "InitialRandomSeed", CFF_TYPE_NUMBER }, + { "SyntheticBase", CFF_TYPE_NUMBER }, + { "PostScript", CFF_TYPE_SID }, + { "BaseFontName", CFF_TYPE_SID }, + { "BaseFontBlend", CFF_TYPE_DELTA }, + { NULL, -1 }, + { NULL, -1 }, + { NULL, -1 }, + { NULL, -1 }, + { NULL, -1 }, + { NULL, -1 }, + { "ROS", CFF_TYPE_ROS }, + { "CIDFontVersion", CFF_TYPE_NUMBER }, + { "CIDFontRevision", CFF_TYPE_NUMBER }, + { "CIDFontType", CFF_TYPE_NUMBER }, + { "CIDCount", CFF_TYPE_NUMBER }, + { "UIDBase", CFF_TYPE_NUMBER }, + { "FDArray", CFF_TYPE_OFFSET }, + { "FDSelect", CFF_TYPE_OFFSET }, + { "FontName", CFF_TYPE_SID } +}; @ Parse DICT data @c @@ -833,12 +817,10 @@ cff_dict *cff_dict_unpack(card8 * data, card8 * endptr) { cff_dict *dict; int status = CFF_PARSE_OK; - stack_top = 0; - dict = cff_new_dict(); while (data < endptr && status == CFF_PARSE_OK) { - if (*data < 22) { /* operator */ + if (*data < CFF_LAST_DICT_OP1) { /* operator */ add_dict(dict, &data, endptr, &status); } else if (*data == 30) { /* real - First byte of a sequence (variable) */ if (stack_top < CFF_DICT_STACK_LIMIT) { @@ -847,7 +829,7 @@ cff_dict *cff_dict_unpack(card8 * data, card8 * endptr) } else { status = CFF_CFF_ERROR_STACK_OVERFLOW; } - } else if (*data == 255 || (*data >= 22 && *data <= 27)) { /* reserved */ + } else if (*data == 255 || (*data >= CFF_LAST_DICT_OP1 && *data <= 27)) { /* reserved */ data++; } else { /* everything else are integer */ if (stack_top < CFF_DICT_STACK_LIMIT) { @@ -858,14 +840,12 @@ cff_dict *cff_dict_unpack(card8 * data, card8 * endptr) } } } - if (status != CFF_PARSE_OK) { formatted_error("cff","parsing DICT failed (error=%d)", status); } else if (stack_top != 0) { normal_warning("cff","garbage in DICT data"); stack_top = 0; } - return dict; } @@ -873,13 +853,11 @@ cff_dict *cff_dict_unpack(card8 * data, card8 * endptr) int cff_dict_known(cff_dict * dict, const char *key) { int i; - for (i = 0; i < dict->count; i++) { if (key && strcmp(key, (dict->entries)[i].key) == 0 && (dict->entries)[i].count > 0) return 1; } - return 0; } @@ -888,9 +866,7 @@ double cff_dict_get(cff_dict * dict, const char *key, int idx) { double value = 0.0; int i; - assert(key && dict); - for (i = 0; i < dict->count; i++) { if (strcmp(key, (dict->entries)[i].key) == 0) { if ((dict->entries)[i].count > idx) @@ -900,10 +876,8 @@ double cff_dict_get(cff_dict * dict, const char *key, int idx) break; } } - if (i == dict->count) formatted_error("cff","DICT entry '%s' not found", key); - return value; } @@ -957,7 +931,6 @@ long cff_read_subrs(cff_font * cff) long offset; int i; - if ((cff->flag & FONTTYPE_CIDFONT) && cff->fdselect == NULL) { cff_read_fdselect(cff); } @@ -988,23 +961,19 @@ long cff_read_subrs(cff_font * cff) len += cff_index_size((cff->subrs)[i]); } } + } else if (cff->private[0] == NULL || !cff_dict_known(cff->private[0], "Subrs")) { + (cff->subrs)[0] = NULL; } else { - if (cff->private[0] == NULL || - !cff_dict_known(cff->private[0], "Subrs")) { - (cff->subrs)[0] = NULL; - } else { - offset = (long) cff_dict_get(cff->topdict, "Private", 1); - offset += (long) cff_dict_get(cff->private[0], "Subrs", 0); - cff->offset = (l_offset) offset; - (cff->subrs)[0] = cff_get_index(cff); - len += cff_index_size((cff->subrs)[0]); - } + offset = (long) cff_dict_get(cff->topdict, "Private", 1); + offset += (long) cff_dict_get(cff->private[0], "Subrs", 0); + cff->offset = (l_offset) offset; + (cff->subrs)[0] = cff_get_index(cff); + len += cff_index_size((cff->subrs)[0]); } return len; } - @ @c long cff_read_fdarray(cff_font * cff) { @@ -1057,9 +1026,8 @@ long cff_read_private(cff_font * cff) cff->private = xmalloc((unsigned) (cff->num_fds * sizeof(cff_dict *))); for (i = 0; i < cff->num_fds; i++) { if (cff->fdarray[i] != NULL && - cff_dict_known(cff->fdarray[i], "Private") && - (size = (long) cff_dict_get(cff->fdarray[i], "Private", 0)) - > 0) { + cff_dict_known(cff->fdarray[i], "Private") && + (size = (long) cff_dict_get(cff->fdarray[i], "Private", 0)) > 0) { offset = (long) cff_dict_get(cff->fdarray[i], "Private", 1); cff->offset = (l_offset) offset; data = xmalloc((unsigned) size * sizeof(card8)); @@ -1076,7 +1044,7 @@ long cff_read_private(cff_font * cff) cff->num_fds = 1; cff->private = xmalloc(sizeof(cff_dict *)); if (cff_dict_known(cff->topdict, "Private") && - (size = (long) cff_dict_get(cff->topdict, "Private", 0)) > 0) { + (size = (long) cff_dict_get(cff->topdict, "Private", 0)) > 0) { offset = (long) cff_dict_get(cff->topdict, "Private", 1); cff->offset = (l_offset) offset; data = xmalloc((unsigned) size * sizeof(card8)); @@ -1102,7 +1070,6 @@ cff_font *read_cff(unsigned char *buf, long buflength, int n) cff_index *idx; long offset; - cff = xcalloc(1, sizeof(cff_font)); cff->stream = buf; @@ -1112,13 +1079,18 @@ cff_font *read_cff(unsigned char *buf, long buflength, int n) cff->header_major = get_card8(cff); cff->header_minor = get_card8(cff); cff->header_hdr_size = get_card8(cff); - cff->header_offsize = get_card8(cff); - if (cff->header_offsize < 1 || cff->header_offsize > 4) { - normal_warning("cff","invalid offsize data"); - cff_close(cff); - return NULL; + if (cff->header_major == 2) { + /* we have only one top dictionary */ + cff->header_offsize = get_card16(cff); + } else { + cff->header_offsize = get_card8(cff); + if (cff->header_offsize < 1 || cff->header_offsize > 4) { + normal_warning("cff","invalid offsize data (4)"); + cff_close(cff); + return NULL; + } } - if (cff->header_major > 1) { + if (cff->header_major > 2) { formatted_warning("cff","major version %u not supported", cff->header_major); cff_close(cff); return NULL; @@ -1126,19 +1098,27 @@ cff_font *read_cff(unsigned char *buf, long buflength, int n) cff->offset = cff->header_hdr_size; /* Name INDEX */ - idx = cff_get_index(cff); - if (n > idx->count - 1) { - normal_warning("cff","invalid fontset index number"); - cff_close(cff); - return NULL; + if (cff->header_major == 2) { + cff->name = cff_empty_index(cff); + } else { + idx = cff_get_index(cff); + if (n > idx->count - 1) { + normal_warning("cff","invalid fontset index number"); + cff_close(cff); + return NULL; + } + cff->name = idx; + cff->fontname = cff_get_name(cff); } - cff->name = idx; - - cff->fontname = cff_get_name(cff); - /* Top DICT INDEX */ - idx = cff_get_index(cff); + if (cff->header_major == 2) { + /* we fake an index (just one entry) */ + idx = cff_get_index2(cff); + } else { + idx = cff_get_index(cff); + } + if (n > idx->count - 1) { normal_warning("cff","top DICT not exist"); cff_close(cff); @@ -1167,7 +1147,11 @@ cff_font *read_cff(unsigned char *buf, long buflength, int n) } /* String INDEX */ - cff->string = cff_get_index(cff); + if (cff->header_major == 2) { + // cff->string = cff_empty_index(cff); + } else { + cff->string = cff_get_index(cff); + } /* offset to GSubr */ cff->gsubr_offset = cff->offset; @@ -1211,33 +1195,33 @@ static long pack_integer(card8 * dest, long destlen, long value) if (value >= -107 && value <= 107) { if (destlen < 1) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (1)"); dest[0] = (card8) ((value + 139) & 0xff); len = 1; } else if (value >= 108 && value <= 1131) { if (destlen < 2) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (2)"); value = (long) 0xf700u + value - 108; dest[0] = (card8) ((value >> 8) & 0xff); dest[1] = (card8) (value & 0xff); len = 2; } else if (value >= -1131 && value <= -108) { if (destlen < 2) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (3)"); value = (long) 0xfb00u - value - 108; dest[0] = (card8) ((value >> 8) & 0xff); dest[1] = (card8) (value & 0xff); len = 2; } else if (value >= -32768 && value <= 32767) { /* shortint */ if (destlen < 3) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (4)"); dest[0] = 28; dest[1] = (card8) ((value >> 8) & 0xff); dest[2] = (card8) (value & 0xff); len = 3; } else { /* longint */ if (destlen < 5) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (5)"); dest[0] = 29; dest[1] = (card8) ((value >> 24) & 0xff); dest[2] = (card8) ((value >> 16) & 0xff); @@ -1257,7 +1241,7 @@ static long pack_real(card8 * dest, long destlen, double value) #define CFF_REAL_MAX_LEN 17 if (destlen < 2) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (6)"); dest[0] = 30; @@ -1305,7 +1289,7 @@ static long pack_real(card8 * dest, long destlen, double value) } if (destlen < pos / 2 + 1) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (7)"); if (pos % 2) { dest[pos / 2] = (card8) (dest[pos / 2] + ch); @@ -1320,7 +1304,7 @@ static long pack_real(card8 * dest, long destlen, double value) dest[pos / 2] = (card8) (dest[pos / 2] + 0x0b); } else { if (destlen < pos / 2 + 1) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (8)"); dest[pos / 2] = (card8) (0xb0); } pos++; @@ -1329,7 +1313,7 @@ static long pack_real(card8 * dest, long destlen, double value) dest[pos / 2] = (card8) (dest[pos / 2] + 0x0c); } else { if (destlen < pos / 2 + 1) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (9)"); dest[pos / 2] = (card8) (0xc0); } e *= -1; @@ -1351,7 +1335,7 @@ static long pack_real(card8 * dest, long destlen, double value) } if (destlen < pos / 2 + 1) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (10)"); if (pos % 2) { dest[pos / 2] = (card8) (dest[pos / 2] + ch); @@ -1367,7 +1351,7 @@ static long pack_real(card8 * dest, long destlen, double value) pos++; } else { if (destlen < pos / 2 + 1) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (11)"); dest[pos / 2] = (card8) (0xff); pos += 2; } @@ -1386,10 +1370,9 @@ static long cff_dict_put_number(double value, /* set offset to longint */ if (type == CFF_TYPE_OFFSET) { long lvalue; - lvalue = (long) value; if (destlen < 5) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (12)"); dest[0] = 29; dest[1] = (card8) ((lvalue >> 24) & 0xff); dest[2] = (card8) ((lvalue >> 16) & 0xff); @@ -1420,16 +1403,15 @@ static long put_dict_entry(cff_dict_entry * de, card8 * dest, long destlen) type = CFF_TYPE_NUMBER; } for (i = 0; i < de->count; i++) { - len += cff_dict_put_number(de->values[i], - dest + len, destlen - len, type); + len += cff_dict_put_number(de->values[i], dest + len, destlen - len, type); } if (id >= 0 && id < CFF_LAST_DICT_OP1) { if (len + 1 > destlen) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (13)"); dest[len++] = (card8) id; } else if (id >= 0 && id < CFF_LAST_DICT_OP) { if (len + 2 > destlen) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (14)"); dest[len++] = 12; dest[len++] = (card8) (id - CFF_LAST_DICT_OP1); } else { @@ -1461,7 +1443,6 @@ long cff_dict_pack(cff_dict * dict, card8 * dest, long destlen) return len; } - @ @c void cff_dict_add(cff_dict * dict, const char *key, int count) { @@ -1506,7 +1487,6 @@ void cff_dict_add(cff_dict * dict, const char *key, int count) return; } - @ @c void cff_dict_remove(cff_dict * dict, const char *key) { @@ -1593,90 +1573,81 @@ long cff_get_sid(cff_font * cff, const char *str) return -1; } - @ @c void cff_update_string(cff_font * cff) { if (cff == NULL) normal_error("cff","CFF font not opened"); - if (cff->string) cff_release_index(cff->string); cff->string = cff->_string; cff->_string = NULL; } - @ @c s_SID cff_add_string(cff_font * cff, const char *str) { card16 idx; cff_index *strings; l_offset offset, size; - - if (cff == NULL) + if (cff == NULL) { normal_error("cff","CFF font not opened"); - - if (cff->_string == NULL) + } + if (cff->_string == NULL) { cff->_string = cff_new_index(0); + } strings = cff->_string; - for (idx = 0; idx < strings->count; idx++) { size = strings->offset[idx + 1] - strings->offset[idx]; offset = strings->offset[idx]; - if (size == strlen(str) && - !memcmp(strings->data + offset - 1, str, strlen(str))) + if (size == strlen(str) && !memcmp(strings->data + offset - 1, str, strlen(str))) { return (s_SID) (idx + CFF_STDSTR_MAX); + } } - for (idx = 0; idx < CFF_STDSTR_MAX; idx++) { - if (cff_stdstr[idx] && !strcmp(cff_stdstr[idx], str)) + if (cff_stdstr[idx] && !strcmp(cff_stdstr[idx], str)) { return idx; + } } offset = (strings->count > 0) ? strings->offset[strings->count] : 1; - strings->offset = - xrealloc(strings->offset, - (unsigned) (((unsigned) strings->count + - 2) * sizeof(l_offset))); + strings->offset = xrealloc(strings->offset, (unsigned) (((unsigned) strings->count + 2) * sizeof(l_offset))); if (strings->count == 0) strings->offset[0] = 1; idx = strings->count; strings->count = (card16) (strings->count + 1); strings->offset[strings->count] = offset + strlen(str); - strings->data = - xrealloc(strings->data, - (unsigned) ((offset + strlen(str) - 1) * sizeof(card8))); + strings->data = xrealloc(strings->data, (unsigned) ((offset + strlen(str) - 1) * sizeof(card8))); memcpy(strings->data + offset - 1, str, strlen(str)); - return (s_SID) (idx + CFF_STDSTR_MAX); } - @ @c void cff_dict_update(cff_dict * dict, cff_font * cff) { int i; - for (i = 0; i < dict->count; i++) { if ((dict->entries)[i].count > 0) { char *str; int id; - id = (dict->entries)[i].id; - if (dict_operator[id].argtype == CFF_TYPE_SID) { str = cff_get_string(cff, (s_SID) (dict->entries)[i].values[0]); - (dict->entries)[i].values[0] = cff_add_string(cff, str); - xfree(str); + if (str != NULL) { + (dict->entries)[i].values[0] = cff_add_string(cff, str); + xfree(str); + } } else if (dict_operator[id].argtype == CFF_TYPE_ROS) { str = cff_get_string(cff, (s_SID) (dict->entries)[i].values[0]); - (dict->entries)[i].values[0] = cff_add_string(cff, str); - xfree(str); + if (str != NULL) { + (dict->entries)[i].values[0] = cff_add_string(cff, str); + xfree(str); + } str = cff_get_string(cff, (s_SID) (dict->entries)[i].values[1]); - (dict->entries)[i].values[1] = cff_add_string(cff, str); - xfree(str); + if (str != NULL) { + (dict->entries)[i].values[1] = cff_add_string(cff, str); + xfree(str); + } } - } } } @@ -1775,7 +1746,6 @@ long cff_read_charsets(cff_font * cff) } if (count > 0) { - /* fprintf(stdout, "count=%d\n", count); */ normal_warning("cff","charset data possibly broken (too many glyphs)"); } @@ -1793,7 +1763,7 @@ long cff_pack_charsets(cff_font * cff, card8 * dest, long destlen) return 0; if (destlen < 1) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (15)"); charset = cff->charsets; @@ -1801,7 +1771,7 @@ long cff_pack_charsets(cff_font * cff, card8 * dest, long destlen) switch (charset->format) { case 0: if (destlen < len + (charset->num_entries) * 2) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (16)"); for (i = 0; i < (charset->num_entries); i++) { s_SID sid = (charset->data).glyphs[i]; /* or CID */ dest[len++] = (card8) ((sid >> 8) & 0xff); @@ -1811,10 +1781,9 @@ long cff_pack_charsets(cff_font * cff, card8 * dest, long destlen) case 1: { if (destlen < len + (charset->num_entries) * 3) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (17)"); for (i = 0; i < (charset->num_entries); i++) { - dest[len++] = - (card8) (((charset->data).range1[i].first >> 8) & 0xff); + dest[len++] = (card8) (((charset->data).range1[i].first >> 8) & 0xff); dest[len++] = (card8) ((charset->data).range1[i].first & 0xff); dest[len++] = (card8) ((charset->data).range1[i].n_left); } @@ -1823,13 +1792,11 @@ long cff_pack_charsets(cff_font * cff, card8 * dest, long destlen) case 2: { if (destlen < len + (charset->num_entries) * 4) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (18)"); for (i = 0; i < (charset->num_entries); i++) { - dest[len++] = - (card8) (((charset->data).range2[i].first >> 8) & 0xff); + dest[len++] = (card8) (((charset->data).range2[i].first >> 8) & 0xff); dest[len++] = (card8) ((charset->data).range2[i].first & 0xff); - dest[len++] = - (card8) (((charset->data).range2[i].n_left >> 8) & 0xff); + dest[len++] = (card8) (((charset->data).range2[i].n_left >> 8) & 0xff); dest[len++] = (card8) ((charset->data).range2[i].n_left & 0xff); } } @@ -1869,7 +1836,6 @@ number in the range (0, 1] and push them into argument stack. How pseudo-random sequences are generated is not documented in the Type 2 charstring spec.. - @c #define CS_TYPE2_DEBUG_STR "Type2 Charstring Parser" #define CS_TYPE2_DEBUG 5 @@ -1900,10 +1866,9 @@ static int cs2_nest = 0; static int have_width = 0; static double width = 0.0; -@ - Standard Encoding Accented Characters: - Optional four arguments for endchar. See, CFF spec., p.35. - This is obsolete feature and is no longer supported. +@ Standard Encoding Accented Characters: Optional four arguments for +endchar. See, CFF spec., p.35. This is obsolete feature and is no longer +supported. @c #if 0 /* adx ady bchar achar endchar */ @@ -1920,7 +1885,7 @@ static double trn_array[CS_TRANS_ARRAY_MAX]; @c /* - 1-byte CharString operaotrs: + 1-byte CharString operators: |cs_escape| is first byte of two-byte operator */ @@ -1939,8 +1904,8 @@ static double trn_array[CS_TRANS_ARRAY_MAX]; #define cs_escape 12 /* |cs_hsbw| 13 : TYPE1 */ #define cs_endchar 14 -/* RESERVED 15 */ -/* RESERVED 16 */ +#define cs_setvsindex 15 +#define cs_blend 16 /* RESERVED 17 */ #define cs_hstemhm 18 #define cs_hintmask 19 @@ -2001,8 +1966,7 @@ static double trn_array[CS_TRANS_ARRAY_MAX]; #define cs_hflex1 36 #define cs_flex1 37 -@ -|clear_stack()| put all operands sotred in operand stack to dest. +@ |clear_stack()| put all operands sotred in operand stack to dest. @c static void clear_stack(card8 ** dest, card8 * limit) { @@ -2016,18 +1980,18 @@ static void clear_stack(card8 ** dest, card8 * limit) ivalue = (long) floor(value + 0.5); if (value >= 0x8000L || value <= (-0x8000L - 1)) { /* - This number cannot be represented as a single operand. - We must use `a b mul ...' or `a c div' to represent large values. - */ + This number cannot be represented as a single operand. We must + use `a b mul ...' or `a c div' to represent large values. + */ normal_error("cff","argument value too large (this is bug)"); } else if (fabs(value - (double) ivalue) > 3.0e-5) { /* 16.16-bit signed fixed value */ DST_NEED(limit, *dest + 5); *(*dest)++ = 255; - ivalue = (long) floor(value); /* mantissa */ + ivalue = (long) floor(value); /* mantissa */ *(*dest)++ = (card8) ((ivalue >> 8) & 0xff); *(*dest)++ = (card8) (ivalue & 0xff); - ivalue = (long) ((value - (double) ivalue) * 0x10000l); /* fraction */ + ivalue = (long) ((value - (double) ivalue) * 0x10000l); /* fraction */ *(*dest)++ = (card8) ((ivalue >> 8) & 0xff); *(*dest)++ = (card8) (ivalue & 0xff); /* Everything else are integers. */ @@ -2044,7 +2008,8 @@ static void clear_stack(card8 ** dest, card8 * limit) ivalue = (long) 0xfb00u - ivalue - 108; *(*dest)++ = (card8) ((ivalue >> 8) & 0xff); *(*dest)++ = (card8) (ivalue & 0xff); - } else if (ivalue >= -32768 && ivalue <= 32767) { /* shortint */ + } else if (ivalue >= -32768 && ivalue <= 32767) { + /* shortint */ DST_NEED(limit, *dest + 3); *(*dest)++ = 28; *(*dest)++ = (card8) ((ivalue >> 8) & 0xff); @@ -2053,24 +2018,25 @@ static void clear_stack(card8 ** dest, card8 * limit) normal_error("cff","unexpected error"); } } - - cs2_stack_top = 0; /* clear stack */ - + cs2_stack_top = 0; /* clear stack */ return; } -@ - Single byte operators: - Path construction, Operator for finishing a path, Hint operators. +@ Single byte operators: Path construction, Operator for finishing a +path, Hint operators. Phases: - phase: - \item 0: inital state - \item 1: hint declaration, first stack-clearing operator appeared - \item 2: in path construction +\item 0: inital state +\item 1: hint declaration, first stack-clearing operator appeared +\item 2: in path construction @c -static void -do_operator1(card8 ** dest, card8 * limit, card8 ** data, card8 * endptr) +/* +static int vsindex = 0; +static int blends = 0; +static int regions = 5; +*/ + +static void do_operator1(card8 ** dest, card8 * limit, card8 ** data, card8 * endptr) { card8 op = **data; @@ -2151,7 +2117,24 @@ do_operator1(card8 ** dest, card8 * limit, card8 ** data, card8 * endptr) *(*dest)++ = op; status = CS_CHAR_END; break; - /* above oprators are candidate for first stack-clearing operator */ + /* above operators are candidate for first stack-clearing operator */ + case cs_setvsindex: + /* + vsindex = cs2_arg_stack[cs2_stack_top-1]; + cs2_stack_top -= 1; + */ + normal_warning("cff2","unsupported setvindex operator"); + status = CS_PARSE_CFF_ERROR; + break; + case cs_blend: + /* + blends = cs2_arg_stack[cs2_stack_top-1]; + cs2_stack_top -= 1; + cs2_stack_top -= blends * regions ; + */ + normal_warning("cff2","unsupported blend operator"); + status = CS_PARSE_CFF_ERROR; + break; case cs_rlineto: case cs_hlineto: case cs_vlineto: @@ -2184,20 +2167,14 @@ do_operator1(card8 ** dest, card8 * limit, card8 ** data, card8 * endptr) status = CS_PARSE_CFF_ERROR; break; } - return; } -@ - Double byte operators: - Flex, arithmetic, conditional, and storage operators. - - Following operators are not supported: - random: How random ? +@ Double byte operators: Flex, arithmetic, conditional, and storage operators. +The following operators are not supported: random: How random ? @c -static void -do_operator2(card8 ** dest, card8 * limit, card8 ** data, card8 * endptr) +static void do_operator2(card8 ** dest, card8 * limit, card8 ** data, card8 * endptr) { card8 op; @@ -2398,13 +2375,10 @@ do_operator2(card8 ** dest, card8 * limit, card8 ** data, card8 * endptr) status = CS_PARSE_CFF_ERROR; break; } - return; } -@ - integer: - exactly the same as the DICT encoding (except 29) +@ integer: exactly the same as the DICT encoding (except 29) @c static void cs2_get_integer(card8 ** data, card8 * endptr) { @@ -2437,15 +2411,12 @@ static void cs2_get_integer(card8 ** data, card8 * endptr) status = CS_PARSE_CFF_ERROR; return; } - NEED(CS_ARG_STACK_MAX, cs2_stack_top + 1); cs2_arg_stack[cs2_stack_top++] = (double) result; - return; } -@ -Signed 16.16-bits fixed number for Type 2 charstring encoding +@ Signed 16.16-bits fixed number for Type 2 charstring encoding @c static void get_fixed(card8 ** data, card8 * endptr) { @@ -2468,14 +2439,13 @@ static void get_fixed(card8 ** data, card8 * endptr) return; } -@ - Subroutines: - The bias for subroutine number is introduced in type 2 charstrings. +@ Subroutines: the bias for subroutine number is introduced in type 2 +charstrings. - subr: set to a pointer to the subroutine charstring. - len: set to the length of subroutine charstring. - |subr_idx|: CFF INDEX data that contains subroutines. - id: biased subroutine number. +\item subr: set to a pointer to the subroutine charstring. +\item len: set to the length of subroutine charstring. +\item |subr_idx|: CFF INDEX data that contains subroutines. +\item id: biased subroutine number. @c static void get_subr(card8 ** subr, long *len, cff_index * subr_idx, long id) @@ -2505,17 +2475,14 @@ static void get_subr(card8 ** subr, long *len, cff_index * subr_idx, long id) return; } - -@ NOTE: - The Type 2 interpretation of a number encoded in five-bytes (those with - an initial byte value of 255) differs from how it is interpreted in the - Type 1 format. +@ The Type 2 interpretation of a number encoded in five-bytes (those with +an initial byte value of 255) differs from how it is interpreted in the +Type 1 format. @c -static void -do_charstring(card8 ** dest, card8 * limit, - card8 ** data, card8 * endptr, - cff_index * gsubr_idx, cff_index * subr_idx) +static void do_charstring(card8 ** dest, card8 * limit, + card8 ** data, card8 * endptr, + cff_index * gsubr_idx, cff_index * subr_idx, int cff2) { card8 b0 = 0, *subr; long len; @@ -2539,8 +2506,8 @@ do_charstring(card8 ** dest, card8 * limit, get_subr(&subr, &len, gsubr_idx, (long) cs2_arg_stack[cs2_stack_top]); if (*dest + len > limit) - formatted_error("cff","%s: possible buffer overflow", CS_TYPE2_DEBUG_STR); - do_charstring(dest, limit, &subr, subr + len, gsubr_idx, subr_idx); + formatted_error("cff","%s: possible buffer overflow (1)", CS_TYPE2_DEBUG_STR); + do_charstring(dest, limit, &subr, subr + len, gsubr_idx, subr_idx, cff2); *data += 1; } } else if (b0 == cs_callsubr) { @@ -2551,8 +2518,8 @@ do_charstring(card8 ** dest, card8 * limit, get_subr(&subr, &len, subr_idx, (long) cs2_arg_stack[cs2_stack_top]); if (limit < *dest + len) - formatted_error("cff","%s: possible buffer overflow", CS_TYPE2_DEBUG_STR); - do_charstring(dest, limit, &subr, subr + len, gsubr_idx, subr_idx); + formatted_error("cff","%s: possible buffer overflow (2)", CS_TYPE2_DEBUG_STR); + do_charstring(dest, limit, &subr, subr + len, gsubr_idx, subr_idx, cff2); *data += 1; } } else if (b0 == cs_escape) { @@ -2566,7 +2533,12 @@ do_charstring(card8 ** dest, card8 * limit, } } - if (status == CS_SUBR_RETURN) { + if (cff2) { + DST_NEED(limit, *dest + 1); + ++endptr; + *(*dest)++ = cs_endchar; + /* no return and endchar */ + } else if (status == CS_SUBR_RETURN) { status = CS_PARSE_OK; } else if (status == CS_CHAR_END && *data < endptr) { formatted_warning("cff","%s: garbage after endchar", CS_TYPE2_DEBUG_STR); @@ -2589,14 +2561,11 @@ static void cs_parse_init(void) cs2_stack_top = 0; } - @ Not just copying... @c -long -cs_copy_charstring(card8 * dst, long dstlen, - card8 * src, long srclen, - cff_index * gsubr, cff_index * subr, - double default_width, double nominal_width, cs_ginfo * ginfo) +static long cs_copy_charstring(card8 * dst, long dstlen, card8 * src, long srclen, + cff_index * gsubr, cff_index * subr, double default_width, + double nominal_width, cs_ginfo * ginfo, int cff2) { card8 *save = dst; @@ -2606,7 +2575,7 @@ cs_copy_charstring(card8 * dst, long dstlen, have_width = 0; /* expand call(g)subrs */ - do_charstring(&dst, dst + dstlen, &src, src + srclen, gsubr, subr); + do_charstring(&dst, dst + dstlen, &src, src + srclen, gsubr, subr, cff2); if (ginfo) { ginfo->flags = 0; /* not used */ @@ -2622,9 +2591,7 @@ cs_copy_charstring(card8 * dst, long dstlen, @* encodings. -@ Encoding and Charset - -Encoding and Charset arrays always begin with GID = 1. +@ Encoding and Charset arrays always begin with GID = 1. @c long cff_read_encoding(cff_font * cff) @@ -2686,7 +2653,6 @@ long cff_read_encoding(cff_font * cff) normal_error("cff","unknown encoding format"); break; } - /* Supplementary data */ if ((encoding->format) & 0x80) { cff_map *map; @@ -2716,7 +2682,7 @@ long cff_pack_encoding(cff_font * cff, card8 * dest, long destlen) return 0; if (destlen < 2) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (19)"); encoding = cff->encoding; @@ -2725,7 +2691,7 @@ long cff_pack_encoding(cff_font * cff, card8 * dest, long destlen) switch (encoding->format & (~0x80)) { case 0: if (destlen < len + encoding->num_entries) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (20)"); for (i = 0; i < (encoding->num_entries); i++) { dest[len++] = (encoding->data).codes[i]; } @@ -2733,7 +2699,7 @@ long cff_pack_encoding(cff_font * cff, card8 * dest, long destlen) case 1: { if (destlen < len + (encoding->num_entries) * 2) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (21)"); for (i = 0; i < (encoding->num_entries); i++) { dest[len++] = (card8) ((encoding->data).range1[i].first & 0xff); dest[len++] = (card8) ((encoding->data).range1[i].n_left); @@ -2747,7 +2713,7 @@ long cff_pack_encoding(cff_font * cff, card8 * dest, long destlen) if ((encoding->format) & 0x80) { if (destlen < len + (encoding->num_supps) * 3 + 1) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (22)"); dest[len++] = encoding->num_supps; for (i = 0; i < (encoding->num_supps); i++) { dest[len++] = (card8) ((encoding->supp)[i].code); @@ -2815,7 +2781,6 @@ long cff_read_fdselect(cff_font * cff) return length; } - @ @c long cff_pack_fdselect(cff_font * cff, card8 * dest, long destlen) { @@ -2827,7 +2792,7 @@ long cff_pack_fdselect(cff_font * cff, card8 * dest, long destlen) return 0; if (destlen < 1) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (23)"); fdsel = cff->fdselect; @@ -2837,7 +2802,7 @@ long cff_pack_fdselect(cff_font * cff, card8 * dest, long destlen) if (fdsel->num_entries != cff->num_glyphs) normal_error("cff","invalid data"); if (destlen < len + fdsel->num_entries) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (24)"); for (i = 0; i < fdsel->num_entries; i++) { dest[len++] = (fdsel->data).fds[i]; } @@ -2845,18 +2810,18 @@ long cff_pack_fdselect(cff_font * cff, card8 * dest, long destlen) case 3: { if (destlen < len + 2) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (25)"); len += 2; for (i = 0; i < (fdsel->num_entries); i++) { if (destlen < len + 3) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (26)"); dest[len++] = (card8) (((fdsel->data).ranges[i].first >> 8) & 0xff); dest[len++] = (card8) ((fdsel->data).ranges[i].first & 0xff); dest[len++] = (card8) ((fdsel->data).ranges[i].fd); } if (destlen < len + 2) - normal_error("cff","buffer overflow"); + normal_error("cff","buffer overflow (27)"); dest[len++] = (card8) ((cff->num_glyphs >> 8) & 0xff); dest[len++] = (card8) (cff->num_glyphs & 0xff); dest[1] = (card8) (((len / 3 - 1) >> 8) & 0xff); @@ -2871,8 +2836,6 @@ long cff_pack_fdselect(cff_font * cff, card8 * dest, long destlen) return len; } - - @ Create an instance of embeddable font. @c @@ -2892,26 +2855,23 @@ static void write_fontfile(PDF pdf, cff_font * cffont, char *fullname) cff_dict_remove(cffont->topdict, "XUID"); cff_dict_remove(cffont->topdict, "Private"); /* some bad font may have */ cff_dict_remove(cffont->topdict, "Encoding"); /* some bad font may have */ + cff_dict_remove(cffont->topdict, "vstore"); /* cff2 */ + cff_dict_remove(cffont->topdict, "maxstack"); /* cff2 */ - topdict->offset[1] = (l_offset) cff_dict_pack(cffont->topdict, - (card8 *) work_buffer, - WORK_BUFFER_SIZE) + 1; + topdict->offset[1] = (l_offset) cff_dict_pack(cffont->topdict, (card8 *) work_buffer, WORK_BUFFER_SIZE) + 1; for (i = 0; i < cffont->num_fds; i++) { size = 0; if (cffont->private && cffont->private[i]) { - size = cff_dict_pack(cffont->private[i], - (card8 *) work_buffer, WORK_BUFFER_SIZE); - if (size < 1) { /* Private had contained only Subr */ + size = cff_dict_pack(cffont->private[i], (card8 *) work_buffer, WORK_BUFFER_SIZE); + if (size < 1) { + /* Private had contained only Subr. */ cff_dict_remove(cffont->fdarray[i], "Private"); } } - (private->offset)[i + 1] = - (unsigned long) ((private->offset)[i] + (unsigned) size); - (fdarray->offset)[i + 1] = - (unsigned long) ((fdarray->offset)[i] + (unsigned) - cff_dict_pack(cffont->fdarray[i], - (card8 *) work_buffer, - WORK_BUFFER_SIZE)); + (private->offset)[i + 1] = (unsigned long) ((private->offset)[i] + + (unsigned) size); + (fdarray->offset)[i + 1] = (unsigned long) ((fdarray->offset)[i] + + (unsigned) cff_dict_pack(cffont->fdarray[i], (card8 *) work_buffer, WORK_BUFFER_SIZE)); } destlen = 4; /* header size */ @@ -2924,7 +2884,6 @@ static void write_fontfile(PDF pdf, cff_font * cffont, char *fullname) destlen += cff_index_size(cffont->cstrings); destlen += cff_index_size(fdarray); destlen = (long) (destlen + (long) private->offset[private->count] - 1); /* Private is not INDEX */ - dest = xcalloc((unsigned) destlen, sizeof(card8)); offset = 0; @@ -2939,30 +2898,23 @@ static void write_fontfile(PDF pdf, cff_font * cffont, char *fullname) offset += cff_pack_index(cffont->string, dest + offset, destlen - offset); /* Global Subrs */ offset += cff_pack_index(cffont->gsubr, dest + offset, destlen - offset); - /* charset */ cff_dict_set(cffont->topdict, "charset", 0, (double) offset); offset += cff_pack_charsets(cffont, dest + offset, destlen - offset); - /* FDSelect */ cff_dict_set(cffont->topdict, "FDSelect", 0, (double) offset); offset += cff_pack_fdselect(cffont, dest + offset, destlen - offset); - /* CharStrings */ cff_dict_set(cffont->topdict, "CharStrings", 0, (double) offset); - offset += cff_pack_index(cffont->cstrings, - dest + offset, cff_index_size(cffont->cstrings)); + offset += cff_pack_index(cffont->cstrings, dest + offset, cff_index_size(cffont->cstrings)); cff_release_index(cffont->cstrings); cffont->cstrings = NULL; /* Charstrings cosumes huge memory */ - /* FDArray and Private */ cff_dict_set(cffont->topdict, "FDArray", 0, (double) offset); fdarray_offset = offset; offset += cff_index_size(fdarray); - fdarray->data = - xcalloc((unsigned) (fdarray->offset[fdarray->count] - 1), - sizeof(card8)); + fdarray->data = xcalloc((unsigned) (fdarray->offset[fdarray->count] - 1), sizeof(card8)); for (i = 0; i < cffont->num_fds; i++) { size = (long) (private->offset[i + 1] - private->offset[i]); if (cffont->private[i] && size > 0) { @@ -2970,56 +2922,27 @@ static void write_fontfile(PDF pdf, cff_font * cffont, char *fullname) cff_dict_set(cffont->fdarray[i], "Private", 0, (double) size); cff_dict_set(cffont->fdarray[i], "Private", 1, (double) offset); } - cff_dict_pack(cffont->fdarray[i], - fdarray->data + (fdarray->offset)[i] - 1, - (long) (fdarray->offset[fdarray->count] - 1)); + cff_dict_pack(cffont->fdarray[i], fdarray->data + (fdarray->offset)[i] - 1, (long) (fdarray->offset[fdarray->count] - 1)); offset += size; } - cff_pack_index(fdarray, dest + fdarray_offset, cff_index_size(fdarray)); cff_release_index(fdarray); cff_release_index(private); /* Finally Top DICT */ - topdict->data = - xcalloc((unsigned) (topdict->offset[topdict->count] - 1), - sizeof(card8)); - cff_dict_pack(cffont->topdict, topdict->data, - (long) (topdict->offset[topdict->count] - 1)); + topdict->data = xcalloc((unsigned) (topdict->offset[topdict->count] - 1), sizeof(card8)); + cff_dict_pack(cffont->topdict, topdict->data, (long) (topdict->offset[topdict->count] - 1)); cff_pack_index(topdict, dest + topdict_offset, cff_index_size(topdict)); cff_release_index(topdict); - for (i = 0; i < offset; i++) + for (i = 0; i < offset; i++) { +// printf("%i\n",(unsigned char)dest[i]); strbuf_putchar(pdf->fb, dest[i]); - + } xfree(dest); return; } - -@ this block is used a few times -@c -#define DO_COPY_CHARSTRING() \ - if ((avl_find(fd->gl_tree,glyph) != NULL)) { \ - size = (long)(cs_idx->offset[code+1] - cs_idx->offset[code]); \ - if (size > CS_STR_LEN_MAX) { \ - formatted_error("cff","charstring too long: gid=%u, %ld bytes", code, size); \ - } \ - if (charstring_len + CS_STR_LEN_MAX >= max_len) { \ - max_len = (long)(charstring_len + 2 * CS_STR_LEN_MAX); \ - charstrings->data = xrealloc(charstrings->data, (unsigned)((unsigned)max_len*sizeof(card8))); \ - } \ - (charstrings->offset)[gid] = (unsigned)(charstring_len + 1); \ - cffont->offset= (l_offset)((unsigned)offset + (cs_idx->offset)[code] - 1); \ - memcpy(data,&cffont->stream[cffont->offset],(size_t)size); \ - charstring_len += cs_copy_charstring(charstrings->data + charstring_len, \ - max_len - charstring_len, \ - data, size, \ - cffont->gsubr, (cffont->subrs)[0], \ - default_width, nominal_width, NULL); \ - gid++; \ - } - @ @c void write_cff(PDF pdf, cff_font * cffont, fd_entry * fd) { @@ -3033,11 +2956,17 @@ void write_cff(PDF pdf, cff_font * cffont, fd_entry * fd) double nominal_width, default_width; + char *fontname; char *fullname; glw_entry *glyph, *found; struct avl_traverser t; +cffont->_string = NULL; + + fontname = xcalloc((unsigned) (1 + strlen(fd->fontname)), 1); + sprintf(fontname, "%s", fd->fontname); + fullname = xcalloc((unsigned) (8 + strlen(fd->fontname)), 1); sprintf(fullname, "%s+%s", fd->subset_tag, fd->fontname); @@ -3045,20 +2974,14 @@ void write_cff(PDF pdf, cff_font * cffont, fd_entry * fd) cff_read_private(cffont); cff_read_subrs(cffont); - /* - Widths - */ - if (cffont->private[0] && - cff_dict_known(cffont->private[0], "defaultWidthX")) { - default_width = - (double) cff_dict_get(cffont->private[0], "defaultWidthX", 0); + /* Widths */ + if (cffont->private[0] && cff_dict_known(cffont->private[0], "defaultWidthX")) { + default_width = (double) cff_dict_get(cffont->private[0], "defaultWidthX", 0); } else { default_width = CFF_DEFAULTWIDTHX_DEFAULT; } - if (cffont->private[0] && - cff_dict_known(cffont->private[0], "nominalWidthX")) { - nominal_width = - (double) cff_dict_get(cffont->private[0], "nominalWidthX", 0); + if (cffont->private[0] && cff_dict_known(cffont->private[0], "nominalWidthX")) { + nominal_width = (double) cff_dict_get(cffont->private[0], "nominalWidthX", 0); } else { nominal_width = CFF_NOMINALWIDTHX_DEFAULT; } @@ -3113,15 +3036,31 @@ void write_cff(PDF pdf, cff_font * cffont, fd_entry * fd) } } cffont->charsets = charset; - } + if (cffont->header_major == 2) { + cff_dict_add(cffont->topdict, "charset", 1); + } + } cff_dict_add(cffont->topdict, "CIDCount", 1); cff_dict_set(cffont->topdict, "CIDCount", 0, last_cid + 1); + if (cffont->header_major == 2) { + + cff_dict_add(cffont->topdict, "FullName", 1); + cff_dict_set(cffont->topdict, "FullName", 0, (double) cff_add_string(cffont, fontname)); + + cff_dict_add(cffont->topdict, "FontBBox", 4); + cff_dict_set(cffont->topdict, "FontBBox", 0, fd->font_dim[FONTBBOX1_CODE].val); + cff_dict_set(cffont->topdict, "FontBBox", 1, fd->font_dim[FONTBBOX2_CODE].val); + cff_dict_set(cffont->topdict, "FontBBox", 2, fd->font_dim[FONTBBOX3_CODE].val); + cff_dict_set(cffont->topdict, "FontBBox", 3, fd->font_dim[FONTBBOX4_CODE].val); + } + cffont->fdarray = xcalloc(1, sizeof(cff_dict *)); cffont->fdarray[0] = cff_new_dict(); cff_dict_add(cffont->fdarray[0], "FontName", 1); - cff_dict_set(cffont->fdarray[0], "FontName", 0, (double) cff_add_string(cffont, fullname)); /* FIXME: Skip XXXXXX+ */ + /* FIXME: Skip XXXXXX+ */ + cff_dict_set(cffont->fdarray[0], "FontName", 0, (double) cff_add_string(cffont, fullname)); cff_dict_add(cffont->fdarray[0], "Private", 2); cff_dict_set(cffont->fdarray[0], "Private", 0, 0.0); cff_dict_set(cffont->fdarray[0], "Private", 0, 0.0); @@ -3157,40 +3096,89 @@ void write_cff(PDF pdf, cff_font * cffont, fd_entry * fd) { int i; + int tex_font = fd->tex_font; + int streamprovider = 0; + int callback_id = 0 ; + if ((tex_font > 0) && (font_streamprovider(tex_font) == 1)) { + streamprovider = font_streamprovider(tex_font); + callback_id = callback_defined(glyph_stream_provider_callback); + } for (i = 0; i < cs_count1; i++) { code = (card16) i; glyph->id = code; - DO_COPY_CHARSTRING(); + if ((avl_find(fd->gl_tree,glyph) != NULL)) { + /* this code is the same as below, apart from small details */ + if (callback_id > 0) { + lstring * result; + run_callback(callback_id, "ddd->L", tex_font, i, streamprovider, &result); /* this call can be sped up */ + size = (size_t) result->l ; + if (size > 0) { + if (charstring_len + CS_STR_LEN_MAX >= max_len) { + max_len = (long)(charstring_len + 2 * CS_STR_LEN_MAX); + charstrings->data = xrealloc(charstrings->data, (unsigned)((unsigned)max_len*sizeof(card8))); + } + (charstrings->offset)[gid] = (unsigned)(charstring_len + 1); + cffont->offset = (l_offset)((unsigned)offset + (cs_idx->offset)[code] - 1); + memcpy(charstrings->data+charstring_len,(const char *) result->s,(size_t) size); + charstring_len += size; + xfree(result); + } + } else { + size = (long)(cs_idx->offset[code+1] - cs_idx->offset[code]); + if (size > CS_STR_LEN_MAX) { + formatted_error("cff","charstring too long: gid=%u, %ld bytes", code, size); + } + if (charstring_len + CS_STR_LEN_MAX >= max_len) { + max_len = (long)(charstring_len + 2 * CS_STR_LEN_MAX); + charstrings->data = xrealloc(charstrings->data, (unsigned)((unsigned)max_len*sizeof(card8))); + } + (charstrings->offset)[gid] = (unsigned)(charstring_len + 1); + cffont->offset = (l_offset)((unsigned)offset + (cs_idx->offset)[code] - 1); + memcpy(data,&cffont->stream[cffont->offset],(size_t)size); + charstring_len += cs_copy_charstring( + charstrings->data + charstring_len, + max_len - charstring_len, + data, size, + cffont->gsubr, (cffont->subrs)[0], + default_width, nominal_width, NULL, + cffont->header_major == 2 + ); + } + gid++; + } } } - - /* CIDSet: a table of bits indexed by cid, bytes with high order bit first, - each (set) bit is a (present) CID. */ + /* + CIDSet: a table of bits indexed by cid, bytes with high order bit first, + each (set) bit is a (present) CID. + */ if (1) { - int cid; - cidset = pdf_create_obj(pdf, obj_type_others, 0); - if (cidset != 0) { - size_t l = (last_cid/8)+1; - char *stream = xmalloc(l); - memset(stream, 0, l); - for (cid = 1; cid <= (long) last_cid; cid++) { - glyph->id = cid; - if (avl_find(fd->gl_tree,glyph) != NULL) { - stream[(cid / 8)] |= (1 << (7 - (cid % 8))); - } - } - pdf_begin_obj(pdf, cidset, OBJSTM_NEVER); - pdf_begin_dict(pdf); - pdf_dict_add_streaminfo(pdf); - pdf_end_dict(pdf); - pdf_begin_stream(pdf); - pdf_out_block(pdf, stream, l); - pdf_end_stream(pdf); - pdf_end_obj(pdf); - } - } - - /* this happens if the internal metrics do not agree with the actual disk font */ + int cid; + cidset = pdf_create_obj(pdf, obj_type_others, 0); + if (cidset != 0) { + size_t l = (last_cid/8)+1; + char *stream = xmalloc(l); + memset(stream, 0, l); + for (cid = 1; cid <= (long) last_cid; cid++) { + glyph->id = cid; + if (avl_find(fd->gl_tree,glyph) != NULL) { + stream[(cid / 8)] |= (1 << (7 - (cid % 8))); + } + } + pdf_begin_obj(pdf, cidset, OBJSTM_NEVER); + pdf_begin_dict(pdf); + pdf_dict_add_streaminfo(pdf); + pdf_end_dict(pdf); + pdf_begin_stream(pdf); + pdf_out_block(pdf, stream, l); + pdf_end_stream(pdf); + pdf_end_obj(pdf); + } + } + /* + This happens if the internal metrics do not agree with the actual + disk font. + */ if (gid < num_glyphs) { formatted_warning("cff","embedded subset is smaller than expected: %d instead of %d glyphs", gid, num_glyphs); num_glyphs = gid; @@ -3203,10 +3191,9 @@ void write_cff(PDF pdf, cff_font * cffont, fd_entry * fd) charstrings->count = num_glyphs; cffont->num_glyphs = num_glyphs; cffont->cstrings = charstrings; - /* - We don't use subroutines at all. - */ + We don't use subroutines at all. + */ if (cffont->gsubr) cff_release_index(cffont->gsubr); cffont->gsubr = cff_new_index(0); @@ -3219,33 +3206,34 @@ void write_cff(PDF pdf, cff_font * cffont, fd_entry * fd) cff_dict_remove((cffont->private)[0], "Subrs"); /* no Subrs */ } + cff_dict_update(cffont->topdict, cffont); + cff_add_string(cffont, "Adobe"); cff_add_string(cffont, "Identity"); - - cff_dict_update(cffont->topdict, cffont); - cff_dict_update(cffont->private[0], cffont); + if (cffont->header_major == 2) { + /* crash */ + } else { + cff_dict_update(cffont->private[0], cffont); + } cff_update_string(cffont); - /* CFF code need to be rewrote... */ + /* CFF code need to be rewritten */ cff_dict_add(cffont->topdict, "ROS", 3); - cff_dict_set(cffont->topdict, "ROS", 0, - (double) cff_get_sid(cffont, "Adobe")); - cff_dict_set(cffont->topdict, "ROS", 1, - (double) cff_get_sid(cffont, "Identity")); + cff_dict_set(cffont->topdict, "ROS", 0, (double) cff_get_sid(cffont, "Adobe")); + cff_dict_set(cffont->topdict, "ROS", 1, (double) cff_get_sid(cffont, "Identity")); cff_dict_set(cffont->topdict, "ROS", 2, 0.0); write_fontfile(pdf, cffont, fullname); + xfree(fontname); xfree(fullname); cff_close(cffont); - } @ @c -#undef ERROR /* for mingw */ +#undef ERROR /* for mingw */ #define ERROR(a) { perror(a); return 0; } -@ Input : SID or CID (16-bit unsigned int) - Output: glyph index +@ Input : SID or CID (16-bit unsigned int) Output: glyph index @c card16 cff_charsets_lookup(cff_font * cff, card16 cid) @@ -3279,9 +3267,7 @@ card16 cff_charsets_lookup(cff_font * cff, card16 cid) case 1: for (i = 0; i < charset->num_entries; i++) { if (cid >= charset->data.range1[i].first && - cid <= - charset->data.range1[i].first + - charset->data.range1[i].n_left) { + cid <= charset->data.range1[i].first + charset->data.range1[i].n_left) { gid = (card16) (gid + cid - charset->data.range1[i].first + 1); return gid; } @@ -3291,9 +3277,7 @@ card16 cff_charsets_lookup(cff_font * cff, card16 cid) case 2: for (i = 0; i < charset->num_entries; i++) { if (cid >= charset->data.range2[i].first && - cid <= - charset->data.range2[i].first + - charset->data.range2[i].n_left) { + cid <= charset->data.range2[i].first + charset->data.range2[i].n_left) { gid = (card16) (gid + cid - charset->data.range2[i].first + 1); return gid; } @@ -3307,22 +3291,24 @@ card16 cff_charsets_lookup(cff_font * cff, card16 cid) return 0; /* not found */ } - @ @c #define is_cidfont(a) ((a)->flag & FONTTYPE_CIDFONT) #define CID_MAX 65535 + void write_cid_cff(PDF pdf, cff_font * cffont, fd_entry * fd) { cff_index *charstrings, *cs_idx; long charstring_len, max_len; long size, offset = 0; + int tex_font = fd->tex_font; + int streamprovider = 0; + int callback_id = 0 ; card8 *data; card16 num_glyphs, cs_count1, gid, last_cid; - - int fdsel, prev_fd, cid_count, cid; + int fdsel, prev_fd, cid_count, cid ; char *fullname; glw_entry *glyph; @@ -3332,12 +3318,16 @@ void write_cid_cff(PDF pdf, cff_font * cffont, fd_entry * fd) cff_fdselect *fdselect = NULL; cff_charsets *charset = NULL; - if (!is_cidfont(cffont)) { perror("Not a CIDfont."); return; } + if ((tex_font > 0) && (font_streamprovider(tex_font) == 1)) { + streamprovider = font_streamprovider(tex_font); + callback_id = callback_defined(glyph_stream_provider_callback); + } + fullname = xcalloc((unsigned) (8 + strlen(fd->fontname)), 1); sprintf(fullname, "%s+%s", fd->subset_tag, fd->fontname); @@ -3348,9 +3338,12 @@ void write_cid_cff(PDF pdf, cff_font * cffont, fd_entry * fd) } else { cid_count = CFF_CIDCOUNT_DEFAULT; } - cff_read_charsets(cffont); - CIDToGIDMap = xmalloc((unsigned) - ((2 * (unsigned) cid_count) * sizeof(unsigned char))); + if (cffont->header_major == 2) { + /* hm */ + } else { + cff_read_charsets(cffont); + } + CIDToGIDMap = xmalloc((unsigned) ((2 * (unsigned) cid_count) * sizeof(unsigned char))); memset(CIDToGIDMap, 0, (size_t) (2 * cid_count)); glyph = xtalloc(1, glw_entry); @@ -3376,12 +3369,15 @@ void write_cid_cff(PDF pdf, cff_font * cffont, fd_entry * fd) num_glyphs++; } } - if (last_cid >= cffont->num_glyphs) { + if (cffont->header_major == 2) { + /* hm */ + } else if (last_cid >= cffont->num_glyphs) { formatted_error("cff font","bad glyph index %i",last_cid); } - - /* CIDSet: a table of bits indexed by cid, bytes with high order bit first, - each (set) bit is a (present) CID. */ + /* + CIDSet: a table of bits indexed by cid, bytes with high order bit + first, each (set) bit is a (present) CID. + */ if (1) { cidset = pdf_create_obj(pdf, obj_type_others, 0); if (cidset != 0) { @@ -3397,7 +3393,7 @@ void write_cid_cff(PDF pdf, cff_font * cffont, fd_entry * fd) pdf_begin_dict(pdf); pdf_dict_add_streaminfo(pdf); pdf_end_dict(pdf); - pdf_begin_stream(pdf); + pdf_begin_stream(pdf); pdf_out_block(pdf, stream, l); pdf_end_stream(pdf); pdf_end_obj(pdf); @@ -3405,14 +3401,12 @@ void write_cid_cff(PDF pdf, cff_font * cffont, fd_entry * fd) } } - cff_read_fdselect(cffont); cff_read_fdarray(cffont); cff_read_private(cffont); cff_read_subrs(cffont); - cffont->offset = (l_offset) cff_dict_get(cffont->topdict, "CharStrings", 0); cs_idx = cff_get_index_header(cffont); @@ -3447,31 +3441,46 @@ void write_cid_cff(PDF pdf, cff_font * cffont, fd_entry * fd) if (avl_find(fd->gl_tree, glyph) == NULL) continue; - gid_org = - (short unsigned) ((CIDToGIDMap[2 * cid] << 8) | - (CIDToGIDMap[2 * cid + 1])); - size = (long) (cs_idx->offset[gid_org + 1] - cs_idx->offset[gid_org]); - if (size > CS_STR_LEN_MAX) { - formatted_error("cff","charstring too long: gid=%u, %ld bytes", cid, size); - } - if (charstring_len + CS_STR_LEN_MAX >= max_len) { - max_len = charstring_len + 2 * CS_STR_LEN_MAX; - charstrings->data = - xrealloc(charstrings->data, - (unsigned) ((unsigned) max_len * sizeof(card8))); - } - (charstrings->offset)[gid] = (l_offset) (charstring_len + 1); - cffont->offset = - (l_offset) ((unsigned) offset + (cs_idx->offset)[gid_org] - 1); - memcpy(data, &cffont->stream[cffont->offset], (size_t) size); + gid_org = (short unsigned) ((CIDToGIDMap[2 * cid] << 8) | (CIDToGIDMap[2 * cid + 1])); fdsel = cff_fdselect_lookup(cffont, gid_org); - charstring_len += cs_copy_charstring(charstrings->data + charstring_len, - max_len - charstring_len, - data, size, - cffont->gsubr, - (cffont->subrs)[fdsel], 0, 0, - NULL); + if (callback_id > 0) { + /* the next blob is not yet tested ... i need a font */ + lstring * result; + run_callback(callback_id, "ddd->L", tex_font, gid_org, streamprovider, &result); /* this call can be sped up */ + size = (size_t) result->l ; + if (size > 0) { + if (charstring_len + CS_STR_LEN_MAX >= max_len) { + max_len = (long)(charstring_len + 2 * CS_STR_LEN_MAX); + charstrings->data = xrealloc(charstrings->data, (unsigned)((unsigned)max_len*sizeof(card8))); + } + (charstrings->offset)[gid] = (unsigned)(charstring_len + 1); + cffont->offset = (l_offset)((unsigned)offset + (cs_idx->offset)[gid_org] - 1); + memcpy(charstrings->data+charstring_len,(const char *) result->s,(size_t)size); + charstring_len += size; + xfree(result); + } + } else { + size = (long) (cs_idx->offset[gid_org + 1] - cs_idx->offset[gid_org]); + if (size > CS_STR_LEN_MAX) { + formatted_error("cff","charstring too long: gid=%u, %ld bytes", cid, size); + } + if (charstring_len + CS_STR_LEN_MAX >= max_len) { + max_len = charstring_len + 2 * CS_STR_LEN_MAX; + charstrings->data = xrealloc(charstrings->data, (unsigned) ((unsigned) max_len * sizeof(card8))); + } + (charstrings->offset)[gid] = (l_offset) (charstring_len + 1); + cffont->offset = (l_offset) ((unsigned) offset + (cs_idx->offset)[gid_org] - 1); + memcpy(data, &cffont->stream[cffont->offset], (size_t) size); + charstring_len += cs_copy_charstring( + charstrings->data + charstring_len, + max_len - charstring_len, + data, size, + cffont->gsubr, (cffont->subrs)[fdsel], + 0, 0, NULL, + cffont->header_major == 2 + ); + } if (cid > 0 && gid_org > 0) { charset->data.glyphs[charset->num_entries] = (s_SID) cid; charset->num_entries++; @@ -3496,15 +3505,13 @@ void write_cid_cff(PDF pdf, cff_font * cffont, fd_entry * fd) charstrings->count = num_glyphs; cffont->num_glyphs = num_glyphs; cffont->cstrings = charstrings; - cff_release_charsets(cffont->charsets); cffont->charsets = charset; cff_release_fdselect(cffont->fdselect); cffont->fdselect = fdselect; - /* - * We don't use subroutines at all. - */ + We don't use subroutines at all. + */ if (cffont->gsubr) cff_release_index(cffont->gsubr); cffont->gsubr = cff_new_index(0); @@ -3518,14 +3525,12 @@ void write_cid_cff(PDF pdf, cff_font * cffont, fd_entry * fd) cff_dict_remove((cffont->private)[fdsel], "Subrs"); /* no Subrs */ } } - write_fontfile(pdf, cffont, fullname); xfree(fullname); cff_close(cffont); - } -@ here is a sneaky trick: fontforge knows how to convert Type1 to CFF, so +@ Here is a sneaky trick: fontforge knows how to convert Type1 to CFF, so I have defined a utility function in luafflib.c that does exactly that. If it works out ok, I will clean up this code. diff --git a/source/texk/web2c/luatexdir/font/writefont.w b/source/texk/web2c/luatexdir/font/writefont.w index 66c26fa7c167871efd7b7ee9c4572679975a8b3e..76d88b68bc4e44ec08a4717ce5e650d24375af83 100644 --- a/source/texk/web2c/luatexdir/font/writefont.w +++ b/source/texk/web2c/luatexdir/font/writefont.w @@ -28,23 +28,23 @@ void write_cid_fontdictionary(PDF pdf, fo_entry * fo, internal_font_number f); static void create_cid_fontdictionary(PDF pdf, internal_font_number f); const key_entry font_key[FONT_KEYS_NUM] = { - {"Ascent", "Ascender", 1} - , {"CapHeight", "CapHeight", 1} - , {"Descent", "Descender", 1} - , {"ItalicAngle", "ItalicAngle", 1} - , {"StemV", "StdVW", 1} - , {"XHeight", "XHeight", 1} - , {"FontBBox", "FontBBox", 1} - , {"", "", 0} - , {"", "", 0} - , {"", "", 0} - , {"FontName", "FontName", 1} + { "Ascent", "Ascender", 1 }, + { "CapHeight", "CapHeight", 1 }, + { "Descent", "Descender", 1 }, + { "ItalicAngle", "ItalicAngle", 1 }, + { "StemV", "StdVW", 1 }, + { "XHeight", "XHeight", 1 }, + { "FontBBox", "FontBBox", 1 }, + { "", "", 0 }, + { "", "", 0 }, + { "", "", 0 }, + { "FontName", "FontName", 1 } }; @ @c -struct avl_table *fo_tree = NULL; /* tree of font dictionaries */ -struct avl_table *fd_tree = NULL; /* tree of font descriptor objects */ +struct avl_table *fo_tree = NULL; /* tree of font dictionaries */ +struct avl_table *fd_tree = NULL; /* tree of font descriptor objects */ static int comp_fo_entry(const void *pa, const void *pb, void *p) { @@ -83,7 +83,7 @@ static fo_entry *new_fo_entry(void) @ initialize data structure for /Type /FontDescriptor @c -fd_entry *new_fd_entry(void) +fd_entry *new_fd_entry(internal_font_number f) { fd_entry *fd; int i; @@ -104,6 +104,7 @@ fd_entry *new_fd_entry(void) fd->fm = NULL; fd->tx_tree = NULL; fd->gl_tree = NULL; + fd->tex_font = f; return fd; } @@ -249,7 +250,8 @@ void register_fd_entry(fd_entry * fd) assert(fd_tree != NULL); } assert(fd != NULL && fd->fm != NULL && is_fontfile(fd->fm)); - assert(lookup_fd_entry(fd->fm->ff_name) == NULL); /* font descriptor not yet registered */ + /* font descriptor not yet registered: */ + assert(lookup_fd_entry(fd->fm->ff_name) == NULL); aa = avl_probe(fd_tree, fd); assert(aa != NULL); } @@ -259,11 +261,13 @@ static void create_fontdescriptor(fo_entry * fo, internal_font_number f) assert(fo != NULL); assert(fo->fm != NULL); assert(fo->fd == NULL); - fo->fd = new_fd_entry(); + fo->fd = new_fd_entry(f); preset_fontname(fo, f); preset_fontmetrics(fo->fd, f); - fo->fd->fe = fo->fe; /* encoding needed by TrueType writing */ - fo->fd->fm = fo->fm; /* map entry needed by TrueType writing */ + /* encoding needed by TrueType writing: */ + fo->fd->fe = fo->fe; + /* map entry needed by TrueType writing: */ + fo->fd->fm = fo->fm; fo->fd->gl_tree = avl_create(comp_string_entry, NULL, &avl_xallocator); assert(fo->fd->gl_tree != NULL); } @@ -285,7 +289,8 @@ static void mark_reenc_glyphs(fo_entry * fo, internal_font_number f) /* mark glyphs from TeX (externally reencoded characters) */ g = fo->fe->glyph_names; for (i = fo->first_char; i <= fo->last_char; i++) { - if (pdf_char_marked(f, i) && g[i] != notdef + if (pdf_char_marked(f, i) + && g[i] != notdef && (char *) avl_find(fo->fd->gl_tree, g[i]) == NULL) { aa = avl_probe(fo->fd->gl_tree, xstrdup(g[i])); assert(aa != NULL); @@ -301,7 +306,7 @@ Function |mark_chars| has 2 uses: @c static struct avl_table *mark_chars(fo_entry * fo, struct avl_table *tx_tree, - internal_font_number f) + internal_font_number f) { int i, *j; void **aa; @@ -326,7 +331,8 @@ static void get_char_range(fo_entry * fo, internal_font_number f) { int i; assert(fo != NULL); - for (i = font_bc(f); i <= font_ec(f); i++) /* search for |first_char| and |last_char| */ + /* search for |first_char| and |last_char| */ + for (i = font_bc(f); i <= font_ec(f); i++) if (pdf_char_marked(f, i)) break; fo->first_char = i; @@ -334,8 +340,8 @@ static void get_char_range(fo_entry * fo, internal_font_number f) if (pdf_char_marked(f, i)) break; fo->last_char = i; - if ((fo->first_char > fo->last_char) - || !pdf_char_marked(f, fo->first_char)) { /* no character used from this font */ + if ((fo->first_char > fo->last_char) || !pdf_char_marked(f, fo->first_char)) { + /* no character used from this font */ fo->last_char = 0; fo->first_char = fo->last_char + 1; } @@ -344,7 +350,8 @@ static void get_char_range(fo_entry * fo, internal_font_number f) static int font_has_subset(internal_font_number f) { int i, s; - for (i = font_bc(f); i <= font_ec(f); i++) /* search for |first_char| and |last_char| */ + /* search for |first_char| and |last_char| */ + for (i = font_bc(f); i <= font_ec(f); i++) if (pdf_char_marked(f, i)) break; s = i; @@ -359,8 +366,7 @@ static int font_has_subset(internal_font_number f) @ @c -static void write_charwidth_array(PDF pdf, fo_entry * fo, - internal_font_number f) +static void write_charwidth_array(PDF pdf, fo_entry * fo, internal_font_number f) { int i, j, *ip, *fip; struct avl_traverser t; @@ -420,13 +426,13 @@ static void register_fo_entry(fo_entry * fo) } @ +In principle we could replace the pdftex derived ttf.otf inclusion part +by using the regular code for this and assigning indices and tounicodes +to the character blobs, but for the moment we keep the current approach. @c static void write_fontfile(PDF pdf, fd_entry * fd) { assert(is_included(fd->fm)); - /* In principle we could replace the pdftex derived ttf.otf inclusion part */ - /* by using the regular code for this and assigning indices and tounicodes */ - /* to the character blobs, but for the moment we keep the current approach */ if (is_cidkeyed(fd->fm)) { if (is_opentype(fd->fm)) { writetype0(pdf, fd); @@ -453,7 +459,7 @@ static void write_fontfile(PDF pdf, fd_entry * fd) return; assert(fd->ff_objnum == 0); fd->ff_objnum = pdf_create_obj(pdf, obj_type_others, 0); - pdf_begin_obj(pdf, fd->ff_objnum, OBJSTM_NEVER); /* font file stream */ + pdf_begin_obj(pdf, fd->ff_objnum, OBJSTM_NEVER); /* font file stream */ pdf_begin_dict(pdf); if (is_cidkeyed(fd->fm)) { /* No subtype is used for TrueType-based OpenType fonts */ @@ -463,17 +469,16 @@ static void write_fontfile(PDF pdf, fd_entry * fd) else pdf_dict_add_name(pdf, "Subtype", "OpenType"); #endif + } else if (is_type1(fd->fm)) { + pdf_dict_add_int(pdf, "Length1", (int) t1_length1); + pdf_dict_add_int(pdf, "Length2", (int) t1_length2); + pdf_dict_add_int(pdf, "Length3", (int) t1_length3); + } else if (is_truetype(fd->fm)) { + pdf_dict_add_int(pdf, "Length1", (int) ttf_length); + } else if (is_opentype(fd->fm)) { + pdf_dict_add_name(pdf, "Subtype", "Type1C"); } else { - if (is_type1(fd->fm)) { - pdf_dict_add_int(pdf, "Length1", (int) t1_length1); - pdf_dict_add_int(pdf, "Length2", (int) t1_length2); - pdf_dict_add_int(pdf, "Length3", (int) t1_length3); - } else if (is_truetype(fd->fm)) - pdf_dict_add_int(pdf, "Length1", (int) ttf_length); - else if (is_opentype(fd->fm)) - pdf_dict_add_name(pdf, "Subtype", "Type1C"); - else - assert(0); + assert(0); /* todo: error messages */ } pdf_dict_add_streaminfo(pdf); pdf_end_dict(pdf); @@ -489,32 +494,36 @@ int cidset = 0; static void write_fontdescriptor(PDF pdf, fd_entry * fd) { static const int std_flags[] = { - /* indices for << start with 0, but bits start with 1, so the numbers - * for << are 1 lower than the bits in table 5.20 */ + /* + The indices for << start with 0, but bits start with 1, so the + numbers for << are 1 lower than the bits in table 5.20. + */ /* *INDENT-OFF* */ - 1 + 2 + (1 << 5), /* Courier */ - 1 + 2 + (1 << 5) + (1 << 18),/* Courier-Bold */ - 1 + 2 + (1 << 5) + (1 << 6), /* Courier-Oblique */ - 1 + 2 + (1 << 5) + (1 << 6) + (1 << 18),/* Courier-BoldOblique */ - (1 << 5), /* Helvetica */ - (1 << 5) + (1 << 18),/* Helvetica-Bold */ - (1 << 5) + (1 << 6), /* Helvetica-Oblique */ - (1 << 5) + (1 << 6) + (1 << 18),/* Helvetica-BoldOblique */ - 4, /* Symbol */ - 2 + (1 << 5), /* Times-Roman */ - 2 + (1 << 5) + (1 << 18),/* Times-Bold */ - 2 + (1 << 5) + (1 << 6), /* Times-Italic */ - 2 + (1 << 5) + (1 << 6) + (1 << 18),/* Times-BoldItalic */ - 4 /* ZapfDingbats */ + 1 + 2 + (1 << 5), /* Courier */ + 1 + 2 + (1 << 5) + (1 << 18), /* Courier-Bold */ + 1 + 2 + (1 << 5) + (1 << 6), /* Courier-Oblique */ + 1 + 2 + (1 << 5) + (1 << 6) + (1 << 18), /* Courier-BoldOblique */ + (1 << 5), /* Helvetica */ + (1 << 5) + (1 << 18), /* Helvetica-Bold */ + (1 << 5) + (1 << 6), /* Helvetica-Oblique */ + (1 << 5) + (1 << 6) + (1 << 18), /* Helvetica-BoldOblique */ + 4, /* Symbol */ + 2 + (1 << 5), /* Times-Roman */ + 2 + (1 << 5) + (1 << 18), /* Times-Bold */ + 2 + (1 << 5) + (1 << 6), /* Times-Italic */ + 2 + (1 << 5) + (1 << 6) + (1 << 18), /* Times-BoldItalic */ + 4 /* ZapfDingbats */ /* *INDENT-ON* */ }; char *glyph; struct avl_traverser t; int fd_flags; assert(fd != NULL && fd->fm != NULL); - cidset = 0; /* possibly updated by |write_fontfile| */ - if (is_fontfile(fd->fm) && is_included(fd->fm)) - write_fontfile(pdf, fd); /* this will set |fd->ff_found| if font file is found */ + cidset = 0; /* possibly updated by |write_fontfile| */ + if (is_fontfile(fd->fm) && is_included(fd->fm)) { + /* this will set |fd->ff_found| if font file is found */ + write_fontfile(pdf, fd); + } if (fd->fd_objnum == 0) fd->fd_objnum = pdf_create_obj(pdf, obj_type_others, 0); pdf_begin_obj(pdf, fd->fd_objnum, OBJSTM_ALWAYS); @@ -572,10 +581,11 @@ static void write_fontdescriptor(PDF pdf, fd_entry * fd) if ((! pdf->omit_cidset) && (cidset != 0)) { pdf_dict_add_ref(pdf, "CIDSet", cidset); } - /* TODO: Other optional keys for CID fonts. - The most interesting one is - \.{/Style << /Panose <12-byte string>>>} - */ + /* + Currently we don't export the optional keys for CID fonts like + \.{/Style << /Panose <12-byte string> >>} and we probably never + will. + */ pdf_end_dict(pdf); pdf_end_obj(pdf); } @@ -587,8 +597,7 @@ static void write_fontdescriptors(PDF pdf) if (fd_tree == NULL) return; avl_t_init(&t, fd_tree); - for (fd = (fd_entry *) avl_t_first(&t, fd_tree); fd != NULL; - fd = (fd_entry *) avl_t_next(&t)) + for (fd = (fd_entry *) avl_t_first(&t, fd_tree); fd != NULL; fd = (fd_entry *) avl_t_next(&t)) write_fontdescriptor(pdf, fd); } @@ -598,18 +607,16 @@ static void write_fontdictionary(PDF pdf, fo_entry * fo) { assert(fo != NULL); assert(fo->fm != NULL); - assert(fo->fo_objnum != 0); /* reserved as |pdf_font_num(f)| elsewhere */ + /* reserved as |pdf_font_num(f)| elsewhere: */ + assert(fo->fo_objnum != 0); /* write ToUnicode entry if needed */ if (pdf->gen_tounicode > 0 && fo->fd != NULL) { if (fo->fe != NULL) { - fo->tounicode_objnum = - write_tounicode(pdf, fo->fe->glyph_names, fo->fe->name); + fo->tounicode_objnum = write_tounicode(pdf, fo->fe->glyph_names, fo->fe->name); } else if (is_type1(fo->fm)) { assert(fo->fd->builtin_glyph_names != NULL); - fo->tounicode_objnum = - write_tounicode(pdf, fo->fd->builtin_glyph_names, - fo->fm->tfm_name); + fo->tounicode_objnum = write_tounicode(pdf, fo->fd->builtin_glyph_names, fo->fm->tfm_name); } } pdf_begin_obj(pdf, fo->fo_objnum, OBJSTM_ALWAYS); @@ -630,13 +637,11 @@ static void write_fontdictionary(PDF pdf, fo_entry * fo) pdf_dict_add_int(pdf, "FirstChar", (int) fo->first_char); pdf_dict_add_int(pdf, "LastChar", (int) fo->last_char); pdf_dict_add_ref(pdf, "Widths", (int) fo->cw_objnum); - if ((is_type1(fo->fm) || is_opentype(fo->fm)) && fo->fe != NULL - && fo->fe->fe_objnum != 0) + if ((is_type1(fo->fm) || is_opentype(fo->fm)) && fo->fe != NULL && fo->fe->fe_objnum != 0) pdf_dict_add_ref(pdf, "Encoding", (int) fo->fe->fe_objnum); if (fo->tounicode_objnum != 0) pdf_dict_add_ref(pdf, "ToUnicode", (int) fo->tounicode_objnum); - if (pdf_font_attr(fo->tex_font) != get_nullstr() && - pdf_font_attr(fo->tex_font) != 0) { + if (pdf_font_attr(fo->tex_font) != get_nullstr() && pdf_font_attr(fo->tex_font) != 0) { pdf_print(pdf, pdf_font_attr(fo->tex_font)); pdf_out(pdf, '\n'); } @@ -651,14 +656,12 @@ static void write_fontdictionaries(PDF pdf) if (fo_tree == NULL) return; avl_t_init(&t, fo_tree); - for (fo = (fo_entry *) avl_t_first(&t, fo_tree); fo != NULL; - fo = (fo_entry *) avl_t_next(&t)) + for (fo = (fo_entry *) avl_t_first(&t, fo_tree); fo != NULL; fo = (fo_entry *) avl_t_next(&t)) write_fontdictionary(pdf, fo); } -@ Final flush of all font related stuff by call from - \.{Output fonts definitions} elsewhere - +@ Final flush of all font related stuff by call from \.{Output fonts +definitions} elsewhere @c void write_fontstuff(PDF pdf) { @@ -673,23 +676,30 @@ static void create_fontdictionary(PDF pdf, internal_font_number f) { fo_entry *fo = new_fo_entry(); fm_entry *fm = font_map(f); - get_char_range(fo, f); /* set |fo->first_char| and |fo->last_char| from |f| */ + /* set |fo->first_char| and |fo->last_char| from |f| */ + get_char_range(fo, f); if (fo->last_char > 255) - fo->last_char = 255; /* added 9-4-2008, mantis \#25 */ + fo->last_char = 255; assert(fo->last_char >= fo->first_char); fo->fm = fm; fo->fo_objnum = pdf_font_num(f); fo->tex_font = f; - if (is_reencoded(fo->fm)) { /* at least the map entry tells so */ - fo->fe = get_fe_entry(fo->fm->encname); /* returns |NULL| if .enc file couldn't be opened */ - if (fo->fe != NULL && (is_type1(fo->fm) || is_opentype(fo->fm))) { /* not entered for truetype */ + if (is_reencoded(fo->fm)) { + /* + At least the map entry tells so but it returns |NULL| if the .enc + file couldn't be opened. + */ + fo->fe = get_fe_entry(fo->fm->encname); + if (fo->fe != NULL && (is_type1(fo->fm) || is_opentype(fo->fm))) { + /* We don't end up here for truetype fonts. */ if (fo->fe->fe_objnum == 0) fo->fe->fe_objnum = pdf_create_obj(pdf, obj_type_others, 0); /* then it will be written out */ - /* mark encoding pairs used by TeX to optimize encoding vector */ + /* Mark encoding pairs used by TeX to optimize encoding vector. */ fo->fe->tx_tree = mark_chars(fo, fo->fe->tx_tree, f); } } - fo->tx_tree = mark_chars(fo, fo->tx_tree, f); /* for |write_charwidth_array| */ + /* for |write_charwidth_array|: */ + fo->tx_tree = mark_chars(fo, fo->tx_tree, f); write_charwidth_array(pdf, fo, f); if (!is_builtin(fo->fm)) { if (is_type1(fo->fm)) { @@ -697,36 +707,42 @@ static void create_fontdictionary(PDF pdf, internal_font_number f) create_fontdescriptor(fo, f); register_fd_entry(fo->fd); } - } else + } else { create_fontdescriptor(fo, f); + } if (fo->fe != NULL) { mark_reenc_glyphs(fo, f); if (!is_type1(fo->fm)) { /* mark reencoded characters as chars on TeX level */ assert(fo->fd->tx_tree == NULL); fo->fd->tx_tree = mark_chars(fo, fo->fd->tx_tree, f); - if (is_truetype(fo->fm)) + if (is_truetype(fo->fm)) { fo->fd->write_ttf_glyph_names = true; + } } - } else + } else { /* mark non-reencoded characters as chars on TeX level */ fo->fd->tx_tree = mark_chars(fo, fo->fd->tx_tree, f); - if (!is_type1(fo->fm)) + } + if (!is_type1(fo->fm)) { write_fontdescriptor(pdf, fo->fd); + } } else { - /* builtin fonts still need the /Widths array and /FontDescriptor - * (to avoid error 'font FOO contains bad /BBox') - */ + /* + Builtin fonts still need the /Widths array and /FontDescriptor + (to avoid error 'font FOO contains bad /BBox'). + */ create_fontdescriptor(fo, f); write_fontdescriptor(pdf, fo->fd); - if (!is_std_t1font(fo->fm)) - formatted_warning("map file", "font '%s' is not a standard font; I suppose it is available to your PDF viewer then", - fo->fm->ps_name); + if (!is_std_t1font(fo->fm)) { + formatted_warning("map file", "font '%s' is not a standard font; I suppose it is available to your PDF viewer then", fo->fm->ps_name); + } } - if (is_type1(fo->fm)) + if (is_type1(fo->fm)) { register_fo_entry(fo); - else + } else { write_fontdictionary(pdf, fo); + } } @ @@ -751,32 +767,37 @@ void do_pdf_font(PDF pdf, internal_font_number f) { int del_file = 0; fm_entry *fm; - /* TODO This is not 100\% true: CID is actually needed whenever (and - only) there are more than 256 separate glyphs used. But for - now, just assume the user knows what he is doing; - */ + /* + This is not 100\% true: CID is actually needed whenever (and + only) there are more than 256 separate glyphs used. But for + now, we just assume the user knows what he is doing. In practice + this seems to be the case. + */ if (!font_has_subset(f)) return; if (font_encodingbytes(f) == 2) { - /* Create a virtual font map entry, as this is needed by the - rest of the font inclusion mechanism. - */ + /* + Create a virtual font map entry, as this is needed by the + rest of the font inclusion mechanism. + */ fm = font_map(f) = new_fm_entry(); fm->tfm_name = font_name(f); /* or whatever, not a real tfm */ fm->ff_name = font_filename(f); /* the actual file */ if (font_psname(f) != NULL) - fm->ps_name = font_psname(f); /* the true name */ + fm->ps_name = font_psname(f); /* the true name */ else - fm->ps_name = font_fullname(f); /* the true name */ + fm->ps_name = font_fullname(f); /* the true name */ if (fm->ff_name && strlen(fm->ff_name) >= 6 - && strstr(fm->ff_name, - ".dfont") == (fm->ff_name + strlen(fm->ff_name) - 6)) { - /* In case of a .dfont, we will extract the correct ttf here, - and adjust |fm->ff_name| to point to the temporary file. - This file will be deleted later. Todo: keep a nicer name - somewhere for the terminal message. + && strstr(fm->ff_name,".dfont") == (fm->ff_name + strlen(fm->ff_name) - 6)) { + /* + In case of a .dfont, we will extract the correct ttf here, + and adjust |fm->ff_name| to point to the temporary file. + This file will be deleted later. Todo: keep a nicer name + somewhere for the terminal message. + + Support for dfonts will be removed at some point anyhow. */ char *s = FindResourceTtfFont(fm->ff_name, fm->ps_name); if (s != NULL) { @@ -786,12 +807,14 @@ void do_pdf_font(PDF pdf, internal_font_number f) formatted_error("font","file '%s' does not contain font '%s'",fm->ff_name, fm->ps_name); } } - fm->encname = font_encodingname(f); /* for the CIDSystemInfo */ - fm->slant = font_slant(f); /* slant factor */ + /* Needed for the CIDSystemInfo: */ + fm->encname = font_encodingname(f); + fm->slant = font_slant(f); set_slantset(fm); - fm->extend = font_extend(f); /* extension factor */ + fm->extend = font_extend(f); set_extendset(fm); - fm->fd_flags = 4; /* can perhaps be done better */ + /* Flags can perhaps be done better. */ + fm->fd_flags = 4; set_inuse(fm); switch (font_format(f)) { @@ -826,7 +849,10 @@ void do_pdf_font(PDF pdf, internal_font_number f) unlink(fm->ff_name); } else { - /* by now |font_map(f)|, if any, should have been set via |pdf_init_font()| */ + /* + By now |font_map(f)|, if any, should have been set via + |pdf_init_font()|. + */ if ((fm = font_map(f)) == NULL || (fm->ps_name == NULL && fm->ff_name == NULL)) writet3(pdf, f); @@ -836,12 +862,12 @@ void do_pdf_font(PDF pdf, internal_font_number f) } @ The glyph width is included in |glw_entry|, because that width - depends on the value it has in the font where it is actually - typeset from, not the font that is the 'owner' of the fd entry. +depends on the value it has in the font where it is actually +typeset from, not the font that is the 'owner' of the fd entry. - TODO: It is possible that the user messes with the metric width, - but handling that properly would require access to the 'hmtx' table - at this point in the program. +TODO: It is possible that the user messes with the metric width, +but handling that properly would require access to the 'hmtx' table +at this point in the program. @c static int comp_glw_entry(const void *pa, const void *pb, void *p @@ -860,19 +886,19 @@ static void create_cid_fontdescriptor(fo_entry * fo, internal_font_number f) assert(fo != NULL); assert(fo->fm != NULL); assert(fo->fd == NULL); - fo->fd = new_fd_entry(); + fo->fd = new_fd_entry(f); preset_fontname(fo, f); preset_fontmetrics(fo->fd, f); - fo->fd->fe = fo->fe; /* encoding needed by TrueType writing */ - fo->fd->fm = fo->fm; /* map entry needed by TrueType writing */ + fo->fd->fe = fo->fe; /* encoding needed by TrueType writing */ + fo->fd->fm = fo->fm; /* map entry needed by TrueType writing */ fo->fd->gl_tree = avl_create(comp_glw_entry, NULL, &avl_xallocator); assert(fo->fd->gl_tree != NULL); } -@ The values |font_bc()| and |font_ec()| are potentially large - character ids, but the strings that are written out use CID - indexes, and those are limited to 16-bit values. +@ The values |font_bc()| and |font_ec()| are potentially large character +ids, but the strings that are written out use CID indexes, and those are +limited to 16-bit values. @c static void mark_cid_subset_glyphs(fo_entry * fo, internal_font_number f) @@ -900,17 +926,16 @@ static void mark_cid_subset_glyphs(fo_entry * fo, internal_font_number f) } } +@ It is possible to compress the widths array even better, by using the +alternate 'range' syntax and possibly even using /DW to set a default +value. -@ It is possible to compress the widths array even better, by using the - alternate 'range' syntax and possibly even using /DW to set - a default value. +There is a some optimization here already: glyphs that are not used do +not appear in the widths array at all. - There is a some optimization here already: glyphs that are - not used do not appear in the widths array at all. - - We have to make sure that we do not output an (incorrect!) - width for a character that exists in the font, but is not used - in typesetting. An enormous negative width is used as sentinel value +We have to make sure that we do not output an (incorrect!) width for a +character that exists in the font, but is not used in typesetting. An +enormous negative width is used as sentinel value @c static void write_cid_charwidth_array(PDF pdf, fo_entry * fo) @@ -977,10 +1002,10 @@ static void create_cid_fontdictionary(PDF pdf, internal_font_number f) mark_cid_subset_glyphs(fo, f); if (is_subsetted(fo->fm)) { /* - this is a bit sneaky. |make_subset_tag()| actually expects the glyph tree - to contain strings instead of |glw_entry| items. However, all calculations - are done using explicit typecasts, so it works out ok. - */ + This is a bit sneaky. |make_subset_tag()| actually expects the glyph + tree to contain strings instead of |glw_entry| items. However, all + calculations are done using explicit typecasts, so it works out ok. + */ make_subset_tag(fo->fd); } write_cid_charwidth_array(pdf, fo); @@ -1038,15 +1063,13 @@ void write_cid_fontdictionary(PDF pdf, fo_entry * fo, internal_font_number f) pdf_dict_add_ref(pdf, "W", (int) fo->cw_objnum); pdf_add_name(pdf, "CIDSystemInfo"); pdf_begin_dict(pdf); - pdf_dict_add_string(pdf, "Registry", - (font_cidregistry(f) ? font_cidregistry(f) : "Adobe")); - pdf_dict_add_string(pdf, "Ordering", - (font_cidordering(f) ? font_cidordering(f) : - "Identity")); + pdf_dict_add_string(pdf, "Registry", (font_cidregistry(f) ? font_cidregistry(f) : "Adobe")); + pdf_dict_add_string(pdf, "Ordering", (font_cidordering(f) ? font_cidordering(f) : "Identity")); pdf_dict_add_int(pdf, "Supplement", (int) font_cidsupplement(f)); pdf_end_dict(pdf); /* I doubt there is anything useful that could be written here */ + #if 0 if (pdf_font_attr(fo->tex_font) != get_nullstr()) { pdf_out(pdf, '\n'); @@ -1054,6 +1077,7 @@ void write_cid_fontdictionary(PDF pdf, fo_entry * fo, internal_font_number f) pdf_out(pdf, '\n'); } #endif + pdf_end_dict(pdf); pdf_end_obj(pdf); } diff --git a/source/texk/web2c/luatexdir/font/writettf.w b/source/texk/web2c/luatexdir/font/writettf.w index e1edea5e2ab0bc421fa3247dceabe720c0551df9..ff968eef9e218a858235130b0e386f81b5cc649f 100644 --- a/source/texk/web2c/luatexdir/font/writettf.w +++ b/source/texk/web2c/luatexdir/font/writettf.w @@ -1751,7 +1751,6 @@ void writettf(PDF pdf, fd_entry * fd) pdf_save_offset(pdf); pdf_flush(pdf); - if (is_subsetted(fd_cur->fm)) { ttf_copy_encoding(); ttf_subset_font(pdf); @@ -1795,9 +1794,13 @@ static void do_writeotf(PDF pdf, fd_entry * fd) if (ttf_name_lookup("post", false) != NULL) ttf_read_post(); /* copy font file */ - tab = ttf_seek_tab("CFF ", 0); - for (i = (long) tab->length; i > 0; i--) + if (ttf_name_lookup("CFF2", false) != NULL) /* HH */ + tab = ttf_seek_tab("CFF2", 0); /* HH */ + else /* HH */ + tab = ttf_seek_tab("CFF ", 0); + for (i = (long) tab->length; i > 0; i--) { copy_char(); + } xfree(dir_tab); if (tracefilenames) tex_printf(">>"); diff --git a/source/texk/web2c/luatexdir/font/writetype0.w b/source/texk/web2c/luatexdir/font/writetype0.w index 3053103c52465ad1198eb746531c8dbf4fbfee3c..ebf4be667232fd83d154a140e76b1ab1f666a474 100644 --- a/source/texk/web2c/luatexdir/font/writetype0.w +++ b/source/texk/web2c/luatexdir/font/writetype0.w @@ -19,13 +19,13 @@ @ @c - #include "ptexlib.h" #include "font/writettf.h" #include "font/writecff.h" @ @c extern unsigned char *ttf_buffer; + void writetype0(PDF pdf, fd_entry * fd) { int callback_id; @@ -76,14 +76,12 @@ void writetype0(PDF pdf, fd_entry * fd) if (sfont->type == SFNT_TYPE_TTC) i = ff_get_ttc_index(fd->fm->ff_name, fd->fm->ps_name); - if (is_subsetted(fd_cur->fm)) { report_start_file(filetype_subset, cur_file_name); } else { report_start_file(filetype_font, cur_file_name); } - if (sfont->type == SFNT_TYPE_TTC) otc_read_tabdir(i); else ttf_read_tabdir(); sfnt_close(sfont); @@ -99,7 +97,10 @@ void writetype0(PDF pdf, fd_entry * fd) ttf_read_post(); /* copy font file */ - tab = ttf_seek_tab("CFF ", 0); + if (ttf_name_lookup("CFF2", false) != NULL) /* HH */ + tab = ttf_seek_tab("CFF2", 0); /* HH */ + else /* HH */ + tab = ttf_seek_tab("CFF ", 0); /* TODO the next 0 is a subfont index */ cff = read_cff(ttf_buffer + ttf_curbyte, (long) tab->length, 0); diff --git a/source/texk/web2c/luatexdir/font/writetype2.w b/source/texk/web2c/luatexdir/font/writetype2.w index 950af9998799821a7cf0546973988205c7295636..dc1821c5e5f8da5ae2eb2d915b4e96eea6915986 100644 --- a/source/texk/web2c/luatexdir/font/writetype2.w +++ b/source/texk/web2c/luatexdir/font/writetype2.w @@ -344,7 +344,7 @@ boolean make_tt_subset(PDF pdf, fd_entry * fd, unsigned char *buff, int buflen) normal_error("type 2","there are no glyphs in the subset"); } - if (tt_build_tables(sfont, glyphs) < 0) { + if (tt_build_tables(sfont, glyphs, fd) < 0) { normal_error("type 2","the TTF buffer can't be parsed"); } diff --git a/source/texk/web2c/luatexdir/lua/helpers.w b/source/texk/web2c/luatexdir/lua/helpers.w index e3c787aa7f4427cd0f9ff38e3eec61a6563ec23a..d12e476909df5d2d834f528894bcdeb0658f2a40 100644 --- a/source/texk/web2c/luatexdir/lua/helpers.w +++ b/source/texk/web2c/luatexdir/lua/helpers.w @@ -17,7 +17,7 @@ % You should have received a copy of the GNU General Public License along % with LuaTeX; if not, see <http://www.gnu.org/licenses/>. -@ We will move her some helpers common to code that are now in weird places, +@ We will move here some helpers common to code that are now in weird places, probably organized in texhelpers, luahelpers, pdfhelpers. diff --git a/source/texk/web2c/luatexdir/lua/lcallbacklib.c b/source/texk/web2c/luatexdir/lua/lcallbacklib.c index 988d1e40c515d7d29448ebaefcc3f34fd3cf980f..7944fdfd8a51155a6144e9ac3f6cef7fef966549 100644 --- a/source/texk/web2c/luatexdir/lua/lcallbacklib.c +++ b/source/texk/web2c/luatexdir/lua/lcallbacklib.c @@ -74,6 +74,7 @@ static const char *const callbacknames[] = { "contribute_filter", "call_edit", "build_page_insert", + "glyph_stream_provider", NULL }; diff --git a/source/texk/web2c/luatexdir/lua/luatex-api.h b/source/texk/web2c/luatexdir/lua/luatex-api.h index 7d34607b9e0967018b984e0c7da66b88ace6d48f..2ec38e6b68662b43d59e661272c76a4e35fcc31f 100644 --- a/source/texk/web2c/luatexdir/lua/luatex-api.h +++ b/source/texk/web2c/luatexdir/lua/luatex-api.h @@ -782,6 +782,7 @@ make_lua_key(start);\ make_lua_key(step);\ make_lua_key(stream);\ make_lua_key(streamfile);\ +make_lua_key(streamprovider);\ make_lua_key(stretch);\ make_lua_key(stretch_order);\ make_lua_key(string);\ @@ -1143,6 +1144,7 @@ init_lua_key(start);\ init_lua_key(step);\ init_lua_key(stream);\ init_lua_key(streamfile);\ +init_lua_key(streamprovider);\ init_lua_key(stretch);\ init_lua_key(stretch_order);\ init_lua_key(string);\ @@ -1571,6 +1573,7 @@ use_lua_key(start); use_lua_key(step); use_lua_key(stream); use_lua_key(streamfile); +use_lua_key(streamprovider); use_lua_key(stretch); use_lua_key(stretch_order); use_lua_key(string); diff --git a/source/texk/web2c/luatexdir/luatexcallbackids.h b/source/texk/web2c/luatexdir/luatexcallbackids.h index 6ca9da7087e4ad82164f9b78c06112fe50cfdb48..927c4f1b2f1f66c45542fd9659c988781ccd295a 100644 --- a/source/texk/web2c/luatexdir/luatexcallbackids.h +++ b/source/texk/web2c/luatexdir/luatexcallbackids.h @@ -68,6 +68,7 @@ typedef enum { contribute_filter_callback, call_edit_callback, build_page_insert_callback, + glyph_stream_provider_callback, total_callbacks } callback_callback_types; diff --git a/source/texk/web2c/luatexdir/ptexlib.h b/source/texk/web2c/luatexdir/ptexlib.h index caded2b204ab9df97e99b654b4304eabe2bb57fe..21bb9348ce27f2ec89423eb2f3e175a6f696618e 100644 --- a/source/texk/web2c/luatexdir/ptexlib.h +++ b/source/texk/web2c/luatexdir/ptexlib.h @@ -291,7 +291,7 @@ void vf_out_image(PDF pdf, unsigned i); /* lua/ltexiolib.c */ void flush_loggable_info(void); -/* lua/luastuff.w and lua/luajitstuff.w */ +/* lua/luastuff.w */ void luafunctioncall(int slot); /* lua/luastuff.c */ diff --git a/source/texk/web2c/luatexdir/tex/dumpdata.w b/source/texk/web2c/luatexdir/tex/dumpdata.w index 0c4e51a759349a609d6aadc964b2c48e1379b0f8..aa0d1655d6dce960eee38bf71180f03efd350167 100644 --- a/source/texk/web2c/luatexdir/tex/dumpdata.w +++ b/source/texk/web2c/luatexdir/tex/dumpdata.w @@ -23,7 +23,7 @@ /* we start with 907: the sum of the values of the bytes of "don knuth" */ -#define FORMAT_ID (907+27) +#define FORMAT_ID (907+28) #if ((FORMAT_ID>=0) && (FORMAT_ID<=256)) #error Wrong value for FORMAT_ID. #endif diff --git a/source/texk/web2c/mplibdir/am/libmplib.am b/source/texk/web2c/mplibdir/am/libmplib.am index 238131b42b1a0838f08f0e98df57c9618ff8c626..3d57231194f0ae5e2ceef7f3a28325e69240ca6c 100644 --- a/source/texk/web2c/mplibdir/am/libmplib.am +++ b/source/texk/web2c/mplibdir/am/libmplib.am @@ -7,9 +7,6 @@ ## EXTRA_LIBRARIES += libmplibcore.a libmplibbackends.a -libmplib_a_CPPFLAGS = $(MPFR_INCLUDES) $(GMP_INCLUDES) $(CAIRO_INCLUDES) $(PIXMAN_INCLUDES) \ - $(LIBPNG_INCLUDES) $(ZLIB_INCLUDES) $(AM_CPPFLAGS) -I$(srcdir)/mplibdir - libmplibcore_a_CPPFLAGS = $(MPFR_INCLUDES) $(GMP_INCLUDES) $(LIBPNG_INCLUDES) $(ZLIB_INCLUDES) $(AM_CPPFLAGS) -I$(srcdir)/mplibdir libmplibbackends_a_CPPFLAGS = $(MPFR_INCLUDES) $(GMP_INCLUDES) $(CAIRO_INCLUDES) $(PIXMAN_INCLUDES) \ $(LIBPNG_INCLUDES) $(ZLIB_INCLUDES) $(AM_CPPFLAGS) -I$(srcdir)/mplibdir diff --git a/source/texk/web2c/mplibdir/mp.w b/source/texk/web2c/mplibdir/mp.w index df07b889e5c16b1015ad3c1035aa8cb22a70203e..adea5f18f17c08205c0345c2c4674fc8781d7ef3 100644 --- a/source/texk/web2c/mplibdir/mp.w +++ b/source/texk/web2c/mplibdir/mp.w @@ -1,4 +1,4 @@ -% $Id: mp.w 2124 2017-03-08 13:15:13Z luigi $ +% $Id: mp.w 2123 2017-03-08 12:49:56Z luigi $ % % This file is part of MetaPost; % the MetaPost program is in the public domain. diff --git a/source/texk/web2c/omegafonts/Makefile.in b/source/texk/web2c/omegafonts/Makefile.in index 8ab40abb3f0efc7b7756741d62fc3a5c491e9a81..f84997370f2c736ade270e58134e438a6d51a599 100644 --- a/source/texk/web2c/omegafonts/Makefile.in +++ b/source/texk/web2c/omegafonts/Makefile.in @@ -1330,9 +1330,13 @@ $(proglib): ${top_srcdir}/lib/*.c cd ../lib && $(MAKE) $(AM_MAKEFLAGS) @KPATHSEA_RULE@ + +# $Id: bin_links.am 43248 2017-02-16 21:38:29Z karl $ +# am/bin_links.am: Makefile fragment for bindir links. .PHONY: install-bin-links uninstall-bin-links install-bin-links: +@WIN32_FALSE@ $(MKDIR_P) $(DESTDIR)$(bindir) @WIN32_FALSE@ @cd $(DESTDIR)$(bindir) && \ @WIN32_FALSE@ for s in $(bin_links); do \ @WIN32_FALSE@ link=`echo $$s | sed 's,.*:,,'`; \ diff --git a/source/texk/web2c/web2c/Makefile.in b/source/texk/web2c/web2c/Makefile.in index 21d56d82390295f4ee2d937a01fe57800163eb84..064179d95ce9e1bf61e5b27e61106b4111cc90cf 100644 --- a/source/texk/web2c/web2c/Makefile.in +++ b/source/texk/web2c/web2c/Makefile.in @@ -239,12 +239,12 @@ am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/c-auto.in \ $(top_srcdir)/../../../build-aux/ltmain.sh \ $(top_srcdir)/../../../build-aux/missing \ $(top_srcdir)/../../../build-aux/ylwrap \ - ../../../build-aux/compile ../../../build-aux/config.guess \ - ../../../build-aux/config.sub ../../../build-aux/depcomp \ - ../../../build-aux/install-sh ../../../build-aux/ltmain.sh \ - ../../../build-aux/missing ../../../build-aux/texinfo.tex \ - ../../../build-aux/ylwrap ChangeLog README web2c-lexer.c \ - web2c-parser.c web2c-parser.h + ../../../build-aux/ar-lib ../../../build-aux/compile \ + ../../../build-aux/config.guess ../../../build-aux/config.sub \ + ../../../build-aux/depcomp ../../../build-aux/install-sh \ + ../../../build-aux/ltmain.sh ../../../build-aux/missing \ + ../../../build-aux/texinfo.tex ../../../build-aux/ylwrap \ + ChangeLog README web2c-lexer.c web2c-parser.c web2c-parser.h DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) diff --git a/source/utils/Makefile.in b/source/utils/Makefile.in index 01d1ee1de181993eafd4c68d933384aed10fa2b2..8d69888dbb584f2135b017ea1fbafb4bc92d8262 100644 --- a/source/utils/Makefile.in +++ b/source/utils/Makefile.in @@ -89,8 +89,7 @@ build_triplet = @build@ host_triplet = @host@ subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/../m4/kpse-cairo-flags.m4 \ - $(top_srcdir)/../m4/kpse-common.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/../m4/kpse-common.m4 \ $(top_srcdir)/../m4/kpse-cxx-hack.m4 \ $(top_srcdir)/../m4/kpse-gmp-flags.m4 \ $(top_srcdir)/../m4/kpse-kpathsea-flags.m4 \ @@ -99,7 +98,6 @@ am__aclocal_m4_deps = $(top_srcdir)/../m4/kpse-cairo-flags.m4 \ $(top_srcdir)/../m4/kpse-mktex.m4 \ $(top_srcdir)/../m4/kpse-mpfr-flags.m4 \ $(top_srcdir)/../m4/kpse-options.m4 \ - $(top_srcdir)/../m4/kpse-pixman-flags.m4 \ $(top_srcdir)/../m4/kpse-pkgs.m4 \ $(top_srcdir)/../m4/kpse-poppler-flags.m4 \ $(top_srcdir)/../m4/kpse-setup.m4 \ @@ -117,8 +115,6 @@ am__aclocal_m4_deps = $(top_srcdir)/../m4/kpse-cairo-flags.m4 \ $(top_srcdir)/../libs/poppler/ac/withenable.ac \ $(top_srcdir)/../libs/mpfr/ac/withenable.ac \ $(top_srcdir)/../libs/gmp/ac/withenable.ac \ - $(top_srcdir)/../libs/cairo/ac/withenable.ac \ - $(top_srcdir)/../libs/pixman/ac/withenable.ac \ $(top_srcdir)/../libs/libpng/ac/withenable.ac \ $(top_srcdir)/../libs/luajit/ac/withenable.ac \ $(top_srcdir)/../libs/lua52/ac/withenable.ac \ @@ -196,11 +192,12 @@ am__DIST_COMMON = $(srcdir)/../am/dist_hook.am \ $(top_srcdir)/../build-aux/config.guess \ $(top_srcdir)/../build-aux/config.sub \ $(top_srcdir)/../build-aux/install-sh \ - $(top_srcdir)/../build-aux/missing ../build-aux/compile \ - ../build-aux/config.guess ../build-aux/config.sub \ - ../build-aux/depcomp ../build-aux/install-sh \ - ../build-aux/ltmain.sh ../build-aux/missing \ - ../build-aux/texinfo.tex ../build-aux/ylwrap ChangeLog README + $(top_srcdir)/../build-aux/missing ../build-aux/ar-lib \ + ../build-aux/compile ../build-aux/config.guess \ + ../build-aux/config.sub ../build-aux/depcomp \ + ../build-aux/install-sh ../build-aux/ltmain.sh \ + ../build-aux/missing ../build-aux/texinfo.tex \ + ../build-aux/ylwrap ChangeLog README DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) @@ -350,11 +347,18 @@ NEVER_NAMES_LT = -o -name .libs -o -name '*.lo' recurse_this = utils/ recurse_top = ../ -# We must configure all subdirs since 'make dist' needs the Makefile. -# For those not required for the current set of configure options +# $Id: recurse.am 43261 2017-02-17 22:37:44Z karl $ +# +# Requires $(recurse_this) and $(recurse_top). +# Uses CONF_SUBDIRS and MAKE_SUBDIRS (set by kpse-setup.m4). +# +# For subdirs not required for the current set of configure options # we append '--disable-build' so they can skip tests that would # fail because, e.g., some required libraries were not built. +# (By manually testing $enable_build in configure, e.g., dvisvgm/configure.) +# # Code inspired by automake's way to handle recursive targets. +# cf_silent = $(cf_silent_@AM_V@) cf_silent_ = $(cf_silent_@AM_DEFAULT_V@) cf_silent_0 = --silent diff --git a/source/utils/README b/source/utils/README index 0e7ebba3db1d1b0ab1f687b643878f5a7be92753..bd2ae8dfa07a4222b0104d4cff43be3932963dda 100644 --- a/source/utils/README +++ b/source/utils/README @@ -1,19 +1,18 @@ -$Id: README 42657 2016-12-09 07:19:10Z kakuto $ +$Id: README 43422 2017-03-07 18:10:02Z karl $ Public domain. Originally written 2005 by Karl Berry. Extra utilities we (optionally) compile for TeX Live. See comments in ../texk/README. -asymptote 2.38 - checked 13may16 - (this version for dev build testing only, not to be installed) +asymptote 2.40 - checked 7mar17 update to TL from CTAN, to include prebuilt doc. see http://tug.org/texlive/build.html#asymptote and tlpkg/bin/tl-update-asy -autosp 2016-01-30 - checked 7mar16 +autosp 2016-11-02 - checked 28feb17 http://ctan.org/pkg/autosp - + devnag - from devanagari package installed in texmf-dist. lacheck - maintained here, by us diff --git a/source/utils/aclocal.m4 b/source/utils/aclocal.m4 index 4415289d78cc49af68e39e5d25ba3298a5ac6650..aed27c46ff0b2d5593740bbd7e752acaf7529a91 100644 --- a/source/utils/aclocal.m4 +++ b/source/utils/aclocal.m4 @@ -1186,7 +1186,6 @@ AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR -m4_include([../m4/kpse-cairo-flags.m4]) m4_include([../m4/kpse-common.m4]) m4_include([../m4/kpse-cxx-hack.m4]) m4_include([../m4/kpse-gmp-flags.m4]) @@ -1196,7 +1195,6 @@ m4_include([../m4/kpse-lt-hack.m4]) m4_include([../m4/kpse-mktex.m4]) m4_include([../m4/kpse-mpfr-flags.m4]) m4_include([../m4/kpse-options.m4]) -m4_include([../m4/kpse-pixman-flags.m4]) m4_include([../m4/kpse-pkgs.m4]) m4_include([../m4/kpse-poppler-flags.m4]) m4_include([../m4/kpse-setup.m4]) diff --git a/source/utils/configure b/source/utils/configure index f30f1a698a03c62d29731f7b0a340c26e4ea6903..c84cc766bd669f1f2d8c86993506d9749d324918 100755 --- a/source/utils/configure +++ b/source/utils/configure @@ -589,8 +589,8 @@ ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS -CONF_SUBDIRS MAKE_SUBDIRS +CONF_SUBDIRS WARNING_CFLAGS MAINT MAINTAINER_MODE_FALSE @@ -749,8 +749,6 @@ with_mpfr_libdir with_system_gmp with_gmp_includes with_gmp_libdir -with_system_cairo -with_system_pixman with_system_libpng with_system_zlib with_zlib_includes @@ -1488,10 +1486,6 @@ Optional Packages: --with-system-gmp use installed gmp headers and library --with-gmp-includes=DIR gmp headers installed in DIR --with-gmp-libdir=DIR gmp library installed in DIR - --with-system-cairo use installed cairo headers and library (requires - pkg-config) - --with-system-pixman use installed pixman headers and library (requires - pkg-config) --with-system-libpng use installed libpng headers and library (requires pkg-config) --with-system-zlib use installed zlib headers and library @@ -3381,7 +3375,6 @@ esac test "x$enable_web2c:$enable_luatex" = xyes:yes && { need_poppler=yes need_mpfr=yes - need_cairo=yes need_libpng=yes need_zziplib=yes need_lua52=yes @@ -3400,7 +3393,6 @@ esac test "x$enable_web2c:$enable_luajittex" = xyes:yes && { need_poppler=yes need_mpfr=yes - need_cairo=yes need_libpng=yes need_zziplib=yes need_luajit=yes @@ -3767,60 +3759,6 @@ $as_echo "$as_me: Assuming installed \`gmp' headers and library" >&6;} ac_configure_args="$ac_configure_args '--with-system-gmp=$with_system_gmp'" fi -## libs/cairo/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/cairo/ -## configure options and TL libraries required for cairo - -# Check whether --with-system-cairo was given. -if test "${with_system_cairo+set}" = set; then : - withval=$with_system_cairo; -fi -if test "x$with_system_cairo" = x; then - if test -f $srcdir/../libs/cairo/configure; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Assuming \`cairo' headers and library from TL tree" >&5 -$as_echo "$as_me: Assuming \`cairo' headers and library from TL tree" >&6;} - with_system_cairo=no - else - { $as_echo "$as_me:${as_lineno-$LINENO}: Assuming installed \`cairo' headers and library" >&5 -$as_echo "$as_me: Assuming installed \`cairo' headers and library" >&6;} - with_system_cairo=yes - fi - ac_configure_args="$ac_configure_args '--with-system-cairo=$with_system_cairo'" -fi -if test "x$with_system_cairo" = xyes; then - if test "x$with_system_pixman" = x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: -> installed \`pixman' headers and library" >&5 -$as_echo "$as_me: -> installed \`pixman' headers and library" >&6;} - with_system_pixman=yes - ac_configure_args="$ac_configure_args '--with-system-pixman'" - elif test "x$with_system_pixman" != xyes; then - as_fn_error $? "Sorry, \`--with-system-cairo' requires \`--with-system-pixman'" "$LINENO" 5 - fi -fi - -test "x$need_cairo" = xyes && { - need_pixman=yes -} - -## libs/pixman/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/pixman/ -## configure options and TL libraries required for pixman - -# Check whether --with-system-pixman was given. -if test "${with_system_pixman+set}" = set; then : - withval=$with_system_pixman; -fi -if test "x$with_system_pixman" = x; then - if test -f $srcdir/../libs/pixman/configure; then - { $as_echo "$as_me:${as_lineno-$LINENO}: Assuming \`pixman' headers and library from TL tree" >&5 -$as_echo "$as_me: Assuming \`pixman' headers and library from TL tree" >&6;} - with_system_pixman=no - else - { $as_echo "$as_me:${as_lineno-$LINENO}: Assuming installed \`pixman' headers and library" >&5 -$as_echo "$as_me: Assuming installed \`pixman' headers and library" >&6;} - with_system_pixman=yes - fi - ac_configure_args="$ac_configure_args '--with-system-pixman=$with_system_pixman'" -fi - ## libs/libpng/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory libs/libpng/ ## configure options and TL libraries required for libpng @@ -4842,8 +4780,8 @@ WARNING_CFLAGS=$kpse_cv_warning_cflags { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Utils programs to build" >&5 $as_echo_n "checking for Utils programs to build... " >&6; } -MAKE_SUBDIRS= CONF_SUBDIRS= +MAKE_SUBDIRS= { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAKE_SUBDIRS" >&5 $as_echo "$MAKE_SUBDIRS" >&6; }